Propagate race to produced actors.

This commit is contained in:
Paul Chote
2014-06-21 21:29:14 +12:00
parent 4b2663015b
commit 4db2cf6b2b
10 changed files with 48 additions and 34 deletions

View File

@@ -32,7 +32,7 @@ namespace OpenRA.Mods.Cnc
public ProductionAirdrop(ProductionAirdropInfo info, Actor self) public ProductionAirdrop(ProductionAirdropInfo info, Actor self)
: base(info, self) { } : base(info, self) { }
public override bool Produce(Actor self, ActorInfo producee) public override bool Produce(Actor self, ActorInfo producee, string raceVariant)
{ {
var owner = self.Owner; var owner = self.Owner;
@@ -69,7 +69,8 @@ namespace OpenRA.Mods.Cnc
foreach (var cargo in self.TraitsImplementing<INotifyDelivery>()) foreach (var cargo in self.TraitsImplementing<INotifyDelivery>())
cargo.Delivered(self); cargo.Delivered(self);
self.World.AddFrameEndTask(ww => DoProduction(self, producee, exit));
self.World.AddFrameEndTask(ww => DoProduction(self, producee, exit, raceVariant));
Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", info.ReadyAudio, self.Owner.Country.Race); Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", info.ReadyAudio, self.Owner.Country.Race);
})); }));

View File

@@ -125,7 +125,7 @@ namespace OpenRA.Mods.Cnc.Widgets
if (first != null && first.Done && actor.Traits.Contains<BuildingInfo>()) if (first != null && first.Done && actor.Traits.Contains<BuildingInfo>())
{ {
Sound.Play(TabClick); Sound.Play(TabClick);
World.OrderGenerator = new PlaceBuildingOrderGenerator(CurrentQueue.Actor, icon.Name); World.OrderGenerator = new PlaceBuildingOrderGenerator(CurrentQueue, icon.Name);
} }
else if (first != null && first.Paused) else if (first != null && first.Paused)
{ {

View File

@@ -85,6 +85,7 @@ namespace OpenRA.Mods.RA.AI
{ {
TargetLocation = location.Value, TargetLocation = location.Value,
TargetString = currentBuilding.Item, TargetString = currentBuilding.Item,
TargetActor = queue.Actor,
SuppressVisualFeedback = true SuppressVisualFeedback = true
}); });
} }

View File

@@ -22,19 +22,22 @@ namespace OpenRA.Mods.RA.Orders
readonly Actor Producer; readonly Actor Producer;
readonly string Building; readonly string Building;
readonly BuildingInfo BuildingInfo; readonly BuildingInfo BuildingInfo;
IEnumerable<IRenderable> preview; IEnumerable<IRenderable> preview;
Sprite buildOk, buildBlocked; Sprite buildOk, buildBlocked;
bool initialized = false; bool initialized = false;
public PlaceBuildingOrderGenerator(Actor producer, string name) public PlaceBuildingOrderGenerator(ProductionQueue queue, string name)
{ {
Producer = producer; Producer = queue.Actor;
Building = name; Building = name;
var tileset = producer.World.TileSet.Id.ToLowerInvariant();
BuildingInfo = producer.World.Map.Rules.Actors[Building].Traits.Get<BuildingInfo>();
buildOk = producer.World.Map.SequenceProvider.GetSequence("overlay", "build-valid-{0}".F(tileset)).GetSprite(0); var map = Producer.World.Map;
buildBlocked = producer.World.Map.SequenceProvider.GetSequence("overlay", "build-invalid").GetSprite(0); var tileset = Producer.World.TileSet.Id.ToLowerInvariant();
BuildingInfo = map.Rules.Actors[Building].Traits.Get<BuildingInfo>();
buildOk = map.SequenceProvider.GetSequence("overlay", "build-valid-{0}".F(tileset)).GetSprite(0);
buildBlocked = map.SequenceProvider.GetSequence("overlay", "build-invalid").GetSprite(0);
} }
public IEnumerable<Order> Order(World world, CPos xy, MouseInput mi) public IEnumerable<Order> Order(World world, CPos xy, MouseInput mi)
@@ -65,6 +68,7 @@ namespace OpenRA.Mods.RA.Orders
yield return new Order(isLineBuild ? "LineBuild" : "PlaceBuilding", Producer.Owner.PlayerActor, false) yield return new Order(isLineBuild ? "LineBuild" : "PlaceBuilding", Producer.Owner.PlayerActor, false)
{ {
TargetLocation = topLeft, TargetLocation = topLeft,
TargetActor = Producer,
TargetString = Building, TargetString = Building,
SuppressVisualFeedback = true SuppressVisualFeedback = true
}; };

View File

@@ -90,7 +90,7 @@ namespace OpenRA.Mods.RA
foreach (var p in producers.Where(p => !p.Actor.IsDisabled())) foreach (var p in producers.Where(p => !p.Actor.IsDisabled()))
{ {
if (p.Trait.Produce(p.Actor, self.World.Map.Rules.Actors[name])) if (p.Trait.Produce(p.Actor, self.World.Map.Rules.Actors[name], Race))
{ {
FinishProduction(); FinishProduction();
return true; return true;

View File

@@ -28,19 +28,17 @@ namespace OpenRA.Mods.RA
{ {
var prevItems = GetNumBuildables(self.Owner); var prevItems = GetNumBuildables(self.Owner);
// Find the queue with the target actor if (order.TargetActor.IsDead())
var queue = w.ActorsWithTrait<ProductionQueue>() return;
.Where(p => p.Actor.Owner == self.Owner &&
p.Trait.CurrentItem() != null && var unit = self.World.Map.Rules.Actors[order.TargetString];
p.Trait.CurrentItem().Item == order.TargetString && var queue = order.TargetActor.TraitsImplementing<ProductionQueue>()
p.Trait.CurrentItem().RemainingTime == 0) .FirstOrDefault(q => q.CanBuild(unit));
.Select(p => p.Trait)
.FirstOrDefault();
if (queue == null) if (queue == null)
return; return;
var unit = self.World.Map.Rules.Actors[order.TargetString];
var buildingInfo = unit.Traits.Get<BuildingInfo>(); var buildingInfo = unit.Traits.Get<BuildingInfo>();
if (order.OrderString == "LineBuild") if (order.OrderString == "LineBuild")
@@ -52,11 +50,13 @@ namespace OpenRA.Mods.RA
{ {
new LocationInit(t), new LocationInit(t),
new OwnerInit(order.Player), new OwnerInit(order.Player),
new RaceInit(queue.Race)
}); });
if (playSounds) if (playSounds)
foreach (var s in buildingInfo.BuildSounds) foreach (var s in buildingInfo.BuildSounds)
Sound.PlayToPlayer(order.Player, s, building.CenterPosition); Sound.PlayToPlayer(order.Player, s, building.CenterPosition);
playSounds = false; playSounds = false;
} }
} }
@@ -72,7 +72,9 @@ namespace OpenRA.Mods.RA
{ {
new LocationInit(order.TargetLocation), new LocationInit(order.TargetLocation),
new OwnerInit(order.Player), new OwnerInit(order.Player),
new RaceInit(queue.Race),
}); });
foreach (var s in buildingInfo.BuildSounds) foreach (var s in buildingInfo.BuildSounds)
Sound.PlayToPlayer(order.Player, s, building.CenterPosition); Sound.PlayToPlayer(order.Player, s, building.CenterPosition);
} }

View File

@@ -75,7 +75,6 @@ namespace OpenRA.Mods.RA
PowerManager playerPower; PowerManager playerPower;
PlayerResources playerResources; PlayerResources playerResources;
DeveloperMode developerMode; DeveloperMode developerMode;
string race;
// A list of things we could possibly build // A list of things we could possibly build
Dictionary<ActorInfo, ProductionState> produceable; Dictionary<ActorInfo, ProductionState> produceable;
@@ -92,6 +91,8 @@ namespace OpenRA.Mods.RA
[Sync] public bool CurrentDone { get { return QueueLength != 0 && queue[0].Done; } } [Sync] public bool CurrentDone { get { return QueueLength != 0 && queue[0].Done; } }
[Sync] public bool Enabled { get; private set; } [Sync] public bool Enabled { get; private set; }
public string Race { get; private set; }
public ProductionQueue(ActorInitializer init, Actor playerActor, ProductionQueueInfo info) public ProductionQueue(ActorInitializer init, Actor playerActor, ProductionQueueInfo info)
{ {
self = init.self; self = init.self;
@@ -100,8 +101,8 @@ namespace OpenRA.Mods.RA
playerPower = playerActor.Trait<PowerManager>(); playerPower = playerActor.Trait<PowerManager>();
developerMode = playerActor.Trait<DeveloperMode>(); developerMode = playerActor.Trait<DeveloperMode>();
race = init.Contains<RaceInit>() ? init.Get<RaceInit, string>() : self.Owner.Country.Race; Race = init.Contains<RaceInit>() ? init.Get<RaceInit, string>() : self.Owner.Country.Race;
Enabled = !info.Race.Any() || info.Race.Contains(race); Enabled = !info.Race.Any() || info.Race.Contains(Race);
CacheProduceables(playerActor); CacheProduceables(playerActor);
} }
@@ -125,8 +126,8 @@ namespace OpenRA.Mods.RA
if (!Info.Sticky) if (!Info.Sticky)
{ {
race = self.Owner.Country.Race; Race = self.Owner.Country.Race;
Enabled = !Info.Race.Any() || Info.Race.Contains(race); Enabled = !Info.Race.Any() || Info.Race.Contains(Race);
} }
// Regenerate the produceables and tech tree state // Regenerate the produceables and tech tree state
@@ -153,7 +154,7 @@ namespace OpenRA.Mods.RA
var bi = a.Traits.Get<BuildableInfo>(); var bi = a.Traits.Get<BuildableInfo>();
// Can our race build this by satisfying normal prerequisites? // Can our race build this by satisfying normal prerequisites?
var buildable = !Info.RequireOwner || bi.Owner.Contains(race); var buildable = !Info.RequireOwner || bi.Owner.Contains(Race);
// Checks if Prerequisites want to hide the Actor from buildQueue if they are false // Checks if Prerequisites want to hide the Actor from buildQueue if they are false
produceable.Add(a, new ProductionState { Visible = buildable }); produceable.Add(a, new ProductionState { Visible = buildable });
@@ -370,7 +371,7 @@ namespace OpenRA.Mods.RA
} }
var sp = self.TraitsImplementing<Production>().FirstOrDefault(p => p.Info.Produces.Contains(Info.Type)); var sp = self.TraitsImplementing<Production>().FirstOrDefault(p => p.Info.Produces.Contains(Info.Type));
if (sp != null && !self.IsDisabled() && sp.Produce(self, self.World.Map.Rules.Actors[name])) if (sp != null && !self.IsDisabled() && sp.Produce(self, self.World.Map.Rules.Actors[name], Race))
{ {
FinishProduction(); FinishProduction();
return true; return true;

View File

@@ -53,7 +53,7 @@ namespace OpenRA.Mods.RA
rp = Exts.Lazy(() => self.IsDead() ? null : self.TraitOrDefault<RallyPoint>()); rp = Exts.Lazy(() => self.IsDead() ? null : self.TraitOrDefault<RallyPoint>());
} }
public void DoProduction(Actor self, ActorInfo producee, ExitInfo exitinfo) public void DoProduction(Actor self, ActorInfo producee, ExitInfo exitinfo, string raceVariant)
{ {
var exit = self.Location + exitinfo.ExitCell; var exit = self.Location + exitinfo.ExitCell;
var spawn = self.CenterPosition + exitinfo.SpawnOffset; var spawn = self.CenterPosition + exitinfo.SpawnOffset;
@@ -68,13 +68,18 @@ namespace OpenRA.Mods.RA
self.World.AddFrameEndTask(w => self.World.AddFrameEndTask(w =>
{ {
var newUnit = self.World.CreateActor(producee.Name, new TypeDictionary var td = new TypeDictionary
{ {
new OwnerInit(self.Owner), new OwnerInit(self.Owner),
new LocationInit(exit), new LocationInit(exit),
new CenterPositionInit(spawn), new CenterPositionInit(spawn),
new FacingInit(initialFacing) new FacingInit(initialFacing)
}); };
if (raceVariant != null)
td.Add(new RaceInit(raceVariant));
var newUnit = self.World.CreateActor(producee.Name, td);
var move = newUnit.TraitOrDefault<IMove>(); var move = newUnit.TraitOrDefault<IMove>();
if (move != null) if (move != null)
@@ -96,7 +101,7 @@ namespace OpenRA.Mods.RA
}); });
} }
public virtual bool Produce(Actor self, ActorInfo producee) public virtual bool Produce(Actor self, ActorInfo producee, string raceVariant)
{ {
if (Reservable.IsReserved(self)) if (Reservable.IsReserved(self))
return false; return false;
@@ -107,7 +112,7 @@ namespace OpenRA.Mods.RA
if (exit != null) if (exit != null)
{ {
DoProduction(self, producee, exit); DoProduction(self, producee, exit, raceVariant);
return true; return true;
} }

View File

@@ -28,13 +28,13 @@ namespace OpenRA.Mods.RA.Scripting
[ScriptActorPropertyActivity] [ScriptActorPropertyActivity]
[Desc("Build a unit, ignoring the production queue. The activity will wait if the exit is blocked")] [Desc("Build a unit, ignoring the production queue. The activity will wait if the exit is blocked")]
public void Produce(string actorType) public void Produce(string actorType, string raceVariant = null)
{ {
ActorInfo actorInfo; ActorInfo actorInfo;
if (!self.World.Map.Rules.Actors.TryGetValue(actorType, out actorInfo)) if (!self.World.Map.Rules.Actors.TryGetValue(actorType, out actorInfo))
throw new LuaException("Unknown actor type '{0}'".F(actorType)); throw new LuaException("Unknown actor type '{0}'".F(actorType));
self.QueueActivity(new WaitFor(() => p.Produce(self, actorInfo))); self.QueueActivity(new WaitFor(() => p.Produce(self, actorInfo, raceVariant)));
} }
} }
} }

View File

@@ -366,7 +366,7 @@ namespace OpenRA.Mods.RA.Widgets
if (producing.Done) if (producing.Done)
{ {
if (unit.Traits.Contains<BuildingInfo>()) if (unit.Traits.Contains<BuildingInfo>())
world.OrderGenerator = new PlaceBuildingOrderGenerator(CurrentQueue.Actor, item); world.OrderGenerator = new PlaceBuildingOrderGenerator(CurrentQueue, item);
else else
StartProduction(world, item); StartProduction(world, item);
return; return;