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)
: 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;
@@ -69,7 +69,8 @@ namespace OpenRA.Mods.Cnc
foreach (var cargo in self.TraitsImplementing<INotifyDelivery>())
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);
}));

View File

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

View File

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

View File

@@ -22,19 +22,22 @@ namespace OpenRA.Mods.RA.Orders
readonly Actor Producer;
readonly string Building;
readonly BuildingInfo BuildingInfo;
IEnumerable<IRenderable> preview;
Sprite buildOk, buildBlocked;
bool initialized = false;
public PlaceBuildingOrderGenerator(Actor producer, string name)
public PlaceBuildingOrderGenerator(ProductionQueue queue, string name)
{
Producer = producer;
Producer = queue.Actor;
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);
buildBlocked = producer.World.Map.SequenceProvider.GetSequence("overlay", "build-invalid").GetSprite(0);
var map = Producer.World.Map;
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)
@@ -65,6 +68,7 @@ namespace OpenRA.Mods.RA.Orders
yield return new Order(isLineBuild ? "LineBuild" : "PlaceBuilding", Producer.Owner.PlayerActor, false)
{
TargetLocation = topLeft,
TargetActor = Producer,
TargetString = Building,
SuppressVisualFeedback = true
};

View File

@@ -90,7 +90,7 @@ namespace OpenRA.Mods.RA
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();
return true;

View File

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

View File

@@ -75,7 +75,6 @@ namespace OpenRA.Mods.RA
PowerManager playerPower;
PlayerResources playerResources;
DeveloperMode developerMode;
string race;
// A list of things we could possibly build
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 Enabled { get; private set; }
public string Race { get; private set; }
public ProductionQueue(ActorInitializer init, Actor playerActor, ProductionQueueInfo info)
{
self = init.self;
@@ -100,8 +101,8 @@ namespace OpenRA.Mods.RA
playerPower = playerActor.Trait<PowerManager>();
developerMode = playerActor.Trait<DeveloperMode>();
race = init.Contains<RaceInit>() ? init.Get<RaceInit, string>() : self.Owner.Country.Race;
Enabled = !info.Race.Any() || info.Race.Contains(race);
Race = init.Contains<RaceInit>() ? init.Get<RaceInit, string>() : self.Owner.Country.Race;
Enabled = !info.Race.Any() || info.Race.Contains(Race);
CacheProduceables(playerActor);
}
@@ -125,8 +126,8 @@ namespace OpenRA.Mods.RA
if (!Info.Sticky)
{
race = self.Owner.Country.Race;
Enabled = !Info.Race.Any() || Info.Race.Contains(race);
Race = self.Owner.Country.Race;
Enabled = !Info.Race.Any() || Info.Race.Contains(Race);
}
// Regenerate the produceables and tech tree state
@@ -153,7 +154,7 @@ namespace OpenRA.Mods.RA
var bi = a.Traits.Get<BuildableInfo>();
// 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
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));
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();
return true;

View File

@@ -53,7 +53,7 @@ namespace OpenRA.Mods.RA
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 spawn = self.CenterPosition + exitinfo.SpawnOffset;
@@ -68,13 +68,18 @@ namespace OpenRA.Mods.RA
self.World.AddFrameEndTask(w =>
{
var newUnit = self.World.CreateActor(producee.Name, new TypeDictionary
var td = new TypeDictionary
{
new OwnerInit(self.Owner),
new LocationInit(exit),
new CenterPositionInit(spawn),
new FacingInit(initialFacing)
});
};
if (raceVariant != null)
td.Add(new RaceInit(raceVariant));
var newUnit = self.World.CreateActor(producee.Name, td);
var move = newUnit.TraitOrDefault<IMove>();
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))
return false;
@@ -107,7 +112,7 @@ namespace OpenRA.Mods.RA
if (exit != null)
{
DoProduction(self, producee, exit);
DoProduction(self, producee, exit, raceVariant);
return true;
}

View File

@@ -28,13 +28,13 @@ namespace OpenRA.Mods.RA.Scripting
[ScriptActorPropertyActivity]
[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;
if (!self.World.Map.Rules.Actors.TryGetValue(actorType, out actorInfo))
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 (unit.Traits.Contains<BuildingInfo>())
world.OrderGenerator = new PlaceBuildingOrderGenerator(CurrentQueue.Actor, item);
world.OrderGenerator = new PlaceBuildingOrderGenerator(CurrentQueue, item);
else
StartProduction(world, item);
return;