Singleplayer campaign support: player/world init

This commit is contained in:
Paul Chote
2010-08-16 15:19:53 +12:00
parent d6f0a03270
commit 56b0da0b13
13 changed files with 155 additions and 49 deletions

View File

@@ -250,6 +250,7 @@ namespace OpenRA
public static event Action ConnectionStateChanged = () => { }; public static event Action ConnectionStateChanged = () => { };
static ConnectionState lastConnectionState = ConnectionState.PreConnecting; static ConnectionState lastConnectionState = ConnectionState.PreConnecting;
public static int LocalClientId { get { return orderManager.Connection.LocalClientId; } }
static void Tick() static void Tick()
{ {

View File

@@ -161,7 +161,8 @@ namespace OpenRA.Traits
public interface INotifySelection { void SelectionChanged(); } public interface INotifySelection { void SelectionChanged(); }
public interface ILoadWorldHook { void WorldLoaded(World w); } public interface ILoadWorldHook { void WorldLoaded(World w); }
public interface IGameStarted { void GameStarted(World w); } public interface IGameStarted { void GameStarted(World w); }
public interface ICreatePlayers { void CreatePlayers(World w); }
public interface IActivity public interface IActivity
{ {
IActivity NextActivity { get; set; } IActivity NextActivity { get; set; }

View File

@@ -93,43 +93,18 @@ namespace OpenRA
WorldActor = CreateActor( "World", new TypeDictionary() ); WorldActor = CreateActor( "World", new TypeDictionary() );
// Add Map Players // Add players
int mapPlayerIndex = -1; foreach (var cmp in WorldActor.TraitsImplementing<ICreatePlayers>())
Dictionary<string, Player> MapPlayers = new Dictionary<string, Player>(); cmp.CreatePlayers(this);
foreach (var kv in Map.Players) // Set defaults for any unset stances
{
var player = new Player(this, kv.Value, mapPlayerIndex--);
AddPlayer(player);
MapPlayers.Add(kv.Key,player);
if (kv.Value.OwnsWorld)
WorldActor.Owner = player;
}
foreach(var p in MapPlayers)
{
foreach(var q in Map.Players[p.Key].Allies)
p.Value.Stances[MapPlayers[q]] = Stance.Ally;
foreach(var q in Map.Players[p.Key].Enemies)
p.Value.Stances[MapPlayers[q]] = Stance.Enemy;
}
// Add real players
SetLocalPlayer(Game.orderManager.Connection.LocalClientId);
foreach (var c in Game.LobbyInfo.Clients)
AddPlayer(new Player(this, c));
foreach (var p in players.Values) foreach (var p in players.Values)
foreach (var q in players.Values) foreach (var q in players.Values)
{
if (!p.Stances.ContainsKey(q)) if (!p.Stances.ContainsKey(q))
p.Stances[q] = Game.ChooseInitialStance(p, q); p.Stances[q] = Stance.Neutral;
}
Timer.Time( "worldActor, players: {0}" );
Timer.Time( "worldActor: {0}" );
foreach (var wlh in WorldActor.TraitsImplementing<ILoadWorldHook>()) foreach (var wlh in WorldActor.TraitsImplementing<ILoadWorldHook>())
wlh.WorldLoaded(this); wlh.WorldLoaded(this);

View File

@@ -0,0 +1,39 @@
#region Copyright & License Information
/*
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see LICENSE.
*/
#endregion
using System.Collections.Generic;
using System.Linq;
using OpenRA.Traits;
namespace OpenRA.Mods.RA
{
public class CreateMPPlayersInfo : TraitInfo<CreateMPPlayers> { }
public class CreateMPPlayers : ICreatePlayers
{
public Dictionary<string, Player> Players = new Dictionary<string, Player>();
public void CreatePlayers(World w)
{
// Add real players
w.SetLocalPlayer(Game.LocalClientId);
foreach (var c in Game.LobbyInfo.Clients)
w.AddPlayer(new Player(w, c));
foreach (var p in w.players.Values)
foreach (var q in w.players.Values)
{
if (!p.Stances.ContainsKey(q))
p.Stances[q] = Game.ChooseInitialStance(p, q);
}
}
}
}

View File

@@ -0,0 +1,46 @@
#region Copyright & License Information
/*
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see LICENSE.
*/
#endregion
using System.Collections.Generic;
using System.Linq;
using OpenRA.Traits;
namespace OpenRA.Mods.RA
{
public class CreateMapPlayersInfo : TraitInfo<CreateMapPlayers> { }
public class CreateMapPlayers : ICreatePlayers
{
public Dictionary<string, Player> Players = new Dictionary<string, Player>();
public void CreatePlayers(World w)
{
int mapPlayerIndex = -1;
foreach (var kv in w.Map.Players)
{
var player = new Player(w, kv.Value, mapPlayerIndex--);
w.AddPlayer(player);
Players.Add(kv.Key,player);
if (kv.Value.OwnsWorld)
w.WorldActor.Owner = player;
}
foreach(var p in Players)
{
foreach(var q in w.Map.Players[p.Key].Allies)
p.Value.Stances[Players[q]] = Stance.Ally;
foreach(var q in w.Map.Players[p.Key].Enemies)
p.Value.Stances[Players[q]] = Stance.Enemy;
}
}
}
}

View File

@@ -18,12 +18,12 @@ namespace OpenRA.Mods.RA
class DefaultShellmapScript: ILoadWorldHook, ITick class DefaultShellmapScript: ILoadWorldHook, ITick
{ {
Dictionary<string, Actor> MapActors; Dictionary<string, Actor> Actors;
public void WorldLoaded(World w) public void WorldLoaded(World w)
{ {
Game.MoveViewport((.5f * (w.Map.TopLeft + w.Map.BottomRight).ToFloat2()).ToInt2()); Game.MoveViewport((.5f * (w.Map.TopLeft + w.Map.BottomRight).ToFloat2()).ToInt2());
MapActors = w.WorldActor.Trait<SpawnMapActors>().MapActors; Actors = w.WorldActor.Trait<SpawnMapActors>().Actors;
} }
int ticks = 0; int ticks = 0;
@@ -31,15 +31,15 @@ namespace OpenRA.Mods.RA
{ {
if (ticks == 250) if (ticks == 250)
{ {
MapActors["pdox"].Trait<Chronosphere>().Teleport(MapActors["ca1"], new int2(90, 70)); Actors["pdox"].Trait<Chronosphere>().Teleport(Actors["ca1"], new int2(90, 70));
MapActors["pdox"].Trait<Chronosphere>().Teleport(MapActors["ca2"], new int2(92, 71)); Actors["pdox"].Trait<Chronosphere>().Teleport(Actors["ca2"], new int2(92, 71));
} }
if (ticks == 100) if (ticks == 100)
MapActors["mslo1"].Trait<NukeSilo>().Attack(new int2(96,53)); Actors["mslo1"].Trait<NukeSilo>().Attack(new int2(96,53));
if (ticks == 110) if (ticks == 110)
MapActors["mslo2"].Trait<NukeSilo>().Attack(new int2(92,53)); Actors["mslo2"].Trait<NukeSilo>().Attack(new int2(92,53));
if (ticks == 120) if (ticks == 120)
MapActors["mslo3"].Trait<NukeSilo>().Attack(new int2(94,50)); Actors["mslo3"].Trait<NukeSilo>().Attack(new int2(94,50));
ticks++; ticks++;
} }

View File

@@ -0,0 +1,36 @@
#region Copyright & License Information
/*
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see LICENSE.
*/
#endregion
using System.Collections.Generic;
using System.Linq;
using OpenRA.Traits;
namespace OpenRA.Mods.RA
{
class LocalPlayerFromMapInfo : TraitInfo<LocalPlayerFromMap>, ITraitPrerequisite<CreateMapPlayersInfo>
{
public readonly string Player = "GoodGuy";
}
class LocalPlayerFromMap: ICreatePlayers
{
public void CreatePlayers(World w)
{
var name = w.WorldActor.Info.Traits.Get<LocalPlayerFromMapInfo>().Player;
var player = w.WorldActor.Trait<CreateMapPlayers>().Players[name];
// Hack: the player *must* be keyed by LocalClientId for orders to be processed correctly
var local = w.players.FirstOrDefault(p => p.Value == player);
w.players.Remove(local.Key);
w.players.Add(Game.LocalClientId,local.Value);
w.SetLocalPlayer(Game.LocalClientId);
}
}
}

View File

@@ -185,7 +185,6 @@
<Compile Include="SelfHealing.cs" /> <Compile Include="SelfHealing.cs" />
<Compile Include="ShroudPalette.cs" /> <Compile Include="ShroudPalette.cs" />
<Compile Include="SupportPowers\SonarPulsePower.cs" /> <Compile Include="SupportPowers\SonarPulsePower.cs" />
<Compile Include="SpawnDefaultUnits.cs" />
<Compile Include="SpawnMapActors.cs" /> <Compile Include="SpawnMapActors.cs" />
<Compile Include="Spy.cs" /> <Compile Include="Spy.cs" />
<Compile Include="SupportPowers\SpyPlanePower.cs" /> <Compile Include="SupportPowers\SpyPlanePower.cs" />
@@ -235,6 +234,10 @@
<Compile Include="ColorPickerPaletteModifier.cs" /> <Compile Include="ColorPickerPaletteModifier.cs" />
<Compile Include="Crates\RevealMapCrateAction.cs" /> <Compile Include="Crates\RevealMapCrateAction.cs" />
<Compile Include="TargetableCloaked.cs" /> <Compile Include="TargetableCloaked.cs" />
<Compile Include="SpawnMPUnits.cs" />
<Compile Include="CreateMapPlayers.cs" />
<Compile Include="CreateMPPlayers.cs" />
<Compile Include="LocalPlayerFromMap.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj"> <ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">

View File

@@ -16,12 +16,12 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA namespace OpenRA.Mods.RA
{ {
class SpawnDefaultUnitsInfo : TraitInfo<SpawnDefaultUnits> class SpawnMPUnitsInfo : TraitInfo<SpawnMPUnits>
{ {
public readonly int InitialExploreRange = 5; public readonly int InitialExploreRange = 5;
} }
class SpawnDefaultUnits : IGameStarted class SpawnMPUnits : IGameStarted
{ {
public void GameStarted(World world) public void GameStarted(World world)
{ {
@@ -49,7 +49,7 @@ namespace OpenRA.Mods.RA
if (p == p.World.LocalPlayer || p.Stances[p.World.LocalPlayer] == Stance.Ally) if (p == p.World.LocalPlayer || p.Stances[p.World.LocalPlayer] == Stance.Ally)
p.World.WorldActor.Trait<Shroud>().Explore(p.World, sp, p.World.WorldActor.Trait<Shroud>().Explore(p.World, sp,
p.World.WorldActor.Info.Traits.Get<SpawnDefaultUnitsInfo>().InitialExploreRange); p.World.WorldActor.Info.Traits.Get<SpawnMPUnitsInfo>().InitialExploreRange);
} }
static int2 ChooseSpawnPoint(World world, List<int2> available, List<int2> taken) static int2 ChooseSpawnPoint(World world, List<int2> available, List<int2> taken)

View File

@@ -18,14 +18,14 @@ namespace OpenRA.Mods.RA
public class SpawnMapActors : IGameStarted public class SpawnMapActors : IGameStarted
{ {
public Dictionary<string, Actor> MapActors = new Dictionary<string, Actor>(); public Dictionary<string, Actor> Actors = new Dictionary<string, Actor>();
public void GameStarted(World world) public void GameStarted(World world)
{ {
Game.skipMakeAnims = true; // rude hack Game.skipMakeAnims = true; // rude hack
foreach (var actorReference in world.Map.Actors) foreach (var actorReference in world.Map.Actors)
MapActors[actorReference.Key] = world.CreateActor(actorReference.Value.Type, actorReference.Value.InitDict); Actors[actorReference.Key] = world.CreateActor(actorReference.Value.Type, actorReference.Value.InitDict);
Game.skipMakeAnims = false; Game.skipMakeAnims = false;
} }

View File

@@ -115,8 +115,10 @@ World:
Type:Crater Type:Crater
Types:cr1,cr2,cr3,cr4,cr5,cr6 Types:cr1,cr2,cr3,cr4,cr5,cr6
Depths:5,5,5,5,5,5 Depths:5,5,5,5,5,5
CreateMapPlayers:
SpawnMapActors: SpawnMapActors:
SpawnDefaultUnits: CreateMPPlayers:
SpawnMPUnits:
EvaAlerts: EvaAlerts:
RadarUp: comcntr1.aud RadarUp: comcntr1.aud
RadarDown: powrdn1.aud RadarDown: powrdn1.aud

View File

@@ -1235,4 +1235,5 @@ Smudges:
Rules: Rules:
World: World:
DefaultShellmapScript: DefaultShellmapScript:
-CreateMPPlayers:
-SpawnMPUnits:

View File

@@ -171,8 +171,10 @@ World:
Type:Crater Type:Crater
Types:cr1,cr2,cr3,cr4,cr5,cr6 Types:cr1,cr2,cr3,cr4,cr5,cr6
Depths:5,5,5,5,5,5 Depths:5,5,5,5,5,5
CreateMapPlayers:
SpawnMapActors: SpawnMapActors:
SpawnDefaultUnits: CreateMPPlayers:
SpawnMPUnits:
EvaAlerts: EvaAlerts:
SpatialBins: SpatialBins:
BinSize: 4 BinSize: 4