More MonsterTankMadness work. Add routines for super tanks, civilian evacuees, proving grounds camera, base transfer, Demitri extraction

This commit is contained in:
Scott_NZ
2013-02-04 22:33:21 +13:00
parent 3c5967a623
commit 03f03ff501
2 changed files with 143 additions and 59 deletions

View File

@@ -25,6 +25,7 @@ namespace OpenRA.Mods.RA.Missions
public readonly string[] SecondStartUnits = null;
public readonly string[] ThirdStartUnits = null;
public readonly string[] FirstBaseUnits = null;
public readonly string[] CivilianEvacuees = null;
public object Create(ActorInitializer init) { return new MonsterTankMadnessScript(this); }
}
@@ -78,16 +79,29 @@ namespace OpenRA.Mods.RA.Missions
Actor demitriLZFlare;
Actor demitriChinook;
Actor provingGroundsCameraPoint;
Actor[] superTanks;
Actor hospital;
Actor hospitalCivilianSpawnPoint;
Actor hospitalSuperTankPoint;
bool demitriExtracted;
bool hospitalEvacuated;
bool superTanksAttackingGreece;
int baseTransferredTick = -1;
void MissionAccomplished(string text)
{
MissionUtils.CoopMissionAccomplished(world, text, ussr);
MissionUtils.CoopMissionAccomplished(world, text, greece);
}
void MissionFailed(string text)
{
MissionUtils.CoopMissionFailed(world, text, ussr);
MissionUtils.CoopMissionFailed(world, text, greece);
}
public void Tick(Actor self)
@@ -95,21 +109,20 @@ namespace OpenRA.Mods.RA.Missions
if (greece.WinState != WinState.Undefined) return;
if (world.FrameNumber == 1)
{
Sound.Play("reinfor1.aud");
SpawnAndMoveBridgeUnits(info.FirstStartUnits);
}
else if (world.FrameNumber == 25 * 3)
{
Sound.Play("reinfor1.aud");
SpawnAndMoveBridgeUnits(info.SecondStartUnits);
}
else if (world.FrameNumber == 25 * 8)
{
Sound.Play("reinfor1.aud");
SpawnAndMoveBridgeUnits(info.ThirdStartUnits);
MissionUtils.CapOre(ussr);
if (!hospitalEvacuated && !hospital.IsDead() && MissionUtils.AreaSecuredWithUnits(world, greece, hospital.CenterLocation, 5))
{
EvacuateCivilians();
hospitalEvacuated = true;
}
if (baseTransferredTick == -1)
@@ -118,69 +131,129 @@ namespace OpenRA.Mods.RA.Missions
if (actorsInBase.Any(a => a.Owner == greece))
{
foreach (var actor in actorsInBase)
{
// hack hack hack
actor.ChangeOwner(greece);
if (actor.Info.Name == "pbox")
{
actor.AddTrait(new TransformedAction(s => s.Trait<Cargo>().Load(s,
world.CreateActor(false, "e1", new TypeDictionary { new OwnerInit(greece) }))));
actor.QueueActivity(new Transform(actor, "hbox.e1") { SkipMakeAnims = true });
}
else if (actor.Info.Name == "proc.nofreeactor")
{
actor.QueueActivity(new Transform(actor, "proc") { SkipMakeAnims = true });
}
var building = actor.TraitOrDefault<Building>();
if (building != null)
building.OnCapture(actor, actor, neutral, greece);
}
TransferActorToAllies(actor);
baseTransferredTick = world.FrameNumber;
}
}
else
{
if (world.FrameNumber == baseTransferredTick + 25 * 120)
foreach (var tank in superTanks.Where(t => !t.IsDead() && t.IsInWorld))
tank.QueueActivity(false, new Move.Move(hospitalSuperTankPoint.Location, 2));
}
if (demitri == null)
{
if (demitriChurch.IsDead())
MissionFailed("Dr. Demitri was killed.");
else if (world.FrameNumber == baseTransferredTick + 25 * 200)
foreach (var tank in superTanks.Where(t => !t.IsDead() && t.IsInWorld))
tank.QueueActivity(false, new Move.Move(alliedBaseBottomRight.Location, 2));
else if (world.FindAliveCombatantActorsInCircle(demitriTriggerAreaCenter.CenterLocation, 3).Any(a => a.Owner == greece))
{
demitri = world.CreateActor("demitri", new TypeDictionary
else if (world.FrameNumber == baseTransferredTick + 25 * 260)
foreach (var tank in superTanks.Where(t => !t.IsDead() && t.IsInWorld))
tank.QueueActivity(false, new Move.Move(demitriTriggerAreaCenter.Location, 2));
else if (world.FrameNumber == baseTransferredTick + 25 * 500)
foreach (var tank in superTanks.Where(t => !t.IsDead() && t.IsInWorld))
{
new OwnerInit(greece),
new LocationInit(demitriChurchSpawnPoint.Location)
});
demitri.QueueActivity(new Move.Move(demitriTriggerAreaCenter.Location, 0));
demitriLZFlare = world.CreateActor("flare", new TypeDictionary { new OwnerInit(greece), new LocationInit(demitriLZ.Location) });
Sound.Play("flaren1.aud");
var chinookEntry = new CPos(demitriLZ.Location.X, 0);
demitriChinook = MissionUtils.ExtractUnitWithChinook(world, greece, demitri, chinookEntry, demitriLZ.Location, chinookEntry);
tank.QueueActivity(false, new AttackMove.AttackMoveActivity(tank, new Move.Move(demitriLZ.Location, 2)));
superTanksAttackingGreece = true;
}
if (superTanksAttackingGreece)
foreach (var tank in superTanks.Where(t => !t.IsDead() && t.IsInWorld && t.IsIdle))
AttackNearestAlliedActor(tank);
}
if (!demitriExtracted)
{
if (demitri == null)
{
if (demitriChurch.IsDead())
{
objectives[BriefingID].Status = ObjectiveStatus.Failed;
OnObjectivesUpdated(true);
MissionFailed("Dr. Demitri was killed.");
}
else if (MissionUtils.AreaSecuredWithUnits(world, greece, demitriTriggerAreaCenter.CenterLocation, 3))
{
demitri = world.CreateActor("demitri", greece, demitriChurchSpawnPoint.Location, null);
demitri.QueueActivity(new Move.Move(demitriTriggerAreaCenter.Location, 0));
demitriLZFlare = world.CreateActor("flare", greece, demitriLZ.Location, null);
Sound.Play("flaren1.aud");
var chinookEntry = new CPos(demitriLZ.Location.X, 0);
demitriChinook = MissionUtils.ExtractUnitWithChinook(world, greece, demitri, chinookEntry, demitriLZ.Location, chinookEntry);
}
}
else if (demitri.IsDead())
{
objectives[BriefingID].Status = ObjectiveStatus.Failed;
OnObjectivesUpdated(true);
MissionFailed("Dr. Demitri was killed.");
}
else if (demitriChinook != null && !demitriChinook.IsDead() && !world.Map.IsInMap(demitriChinook.Location) && demitriChinook.Trait<Cargo>().Passengers.Contains(demitri))
{
demitriLZFlare.Destroy();
SpawnAndMoveAlliedBaseUnits(info.FirstBaseUnits);
demitriExtracted = true;
}
}
else if (demitri.IsDead())
MissionFailed("Dr. Demitri was killed.");
else if (demitriChinook != null && !demitriChinook.IsDead() && !world.Map.IsInMap(demitriChinook.Location) && demitriChinook.Trait<Cargo>().Passengers.Contains(demitri))
if (!world.Actors.Any(a => a.Owner == greece && a.IsInWorld && !a.IsDead()
&& ((a.HasTrait<Building>() && !a.HasTrait<Wall>()) || a.HasTrait<BaseBuilding>())))
{
demitriLZFlare.Destroy();
Sound.Play("reinfor1.aud");
SpawnAndMoveAlliedBaseUnits(info.FirstBaseUnits);
objectives[BriefingID].Status = ObjectiveStatus.Failed;
OnObjectivesUpdated(true);
MissionFailed("The remaining Allied forces in the area have been wiped out.");
}
}
void AttackNearestAlliedActor(Actor self)
{
var enemies = world.Actors.Where(u => u.AppearsHostileTo(self) && u.Owner == greece
&& ((u.HasTrait<Building>() && !u.HasTrait<Wall>()) || u.HasTrait<Mobile>()) && u.IsInWorld && !u.IsDead());
var enemy = enemies.OrderBy(u => (self.CenterLocation - u.CenterLocation).LengthSquared).FirstOrDefault();
if (enemy != null)
self.QueueActivity(new AttackMove.AttackMoveActivity(self, new Attack(Target.FromActor(enemy), 3)));
}
void TransferActorToAllies(Actor actor)
{
// hack hack hack
actor.ChangeOwner(greece);
if (actor.Info.Name == "pbox")
{
actor.AddTrait(new TransformedAction(s => s.Trait<Cargo>().Load(s, world.CreateActor(false, "e1", greece, null, null))));
actor.QueueActivity(new Transform(actor, "hbox.e1") { SkipMakeAnims = true });
}
else if (actor.Info.Name == "proc.nofreeactor")
actor.QueueActivity(new Transform(actor, "proc") { SkipMakeAnims = true });
var building = actor.TraitOrDefault<Building>();
if (building != null)
building.OnCapture(actor, actor, neutral, greece);
}
void EvacuateCivilians()
{
foreach (var unit in info.CivilianEvacuees)
{
var actor = world.CreateActor(unit, neutral, hospitalCivilianSpawnPoint.Location, null);
actor.Trait<Mobile>().Nudge(actor, actor, true);
actor.QueueActivity(new Move.Move(alliedBaseEntryPoint.Location, 0));
actor.QueueActivity(new RemoveSelf());
}
}
void SpawnAndMoveBridgeUnits(string[] units)
{
MissionUtils.SpawnAndMoveActors(world, greece, units, startEntryPoint.Location, startMovePoint.Location,
Util.GetFacing(startBridgeEndPoint.CenterLocation - startEntryPoint.CenterLocation, 0));
Sound.Play("reinfor1.aud");
foreach (var unit in units)
world.CreateActor(unit, greece, startEntryPoint.Location, Util.GetFacing(startBridgeEndPoint.CenterLocation - startEntryPoint.CenterLocation, 0))
.QueueActivity(new Move.Move(startMovePoint.Location, 0));
}
void SpawnAndMoveAlliedBaseUnits(string[] units)
{
MissionUtils.SpawnAndMoveActors(world, greece, units, alliedBaseEntryPoint.Location, alliedBaseMovePoint.Location,
Util.GetFacing(alliedBaseMovePoint.CenterLocation - alliedBaseEntryPoint.CenterLocation, 0));
Sound.Play("reinfor1.aud");
foreach (var unit in units)
world.CreateActor(unit, greece, alliedBaseEntryPoint.Location, Util.GetFacing(alliedBaseMovePoint.CenterLocation - alliedBaseEntryPoint.CenterLocation, 0))
.QueueActivity(new Move.Move(alliedBaseMovePoint.Location, 0));
}
public void WorldLoaded(World w)
@@ -210,6 +283,15 @@ namespace OpenRA.Mods.RA.Missions
demitriTriggerAreaCenter = actors["DemitriTriggerAreaCenter"];
demitriLZ = actors["DemitriLZ"];
hospital = actors["Hospital"];
hospitalCivilianSpawnPoint = actors["HospitalCivilianSpawnPoint"];
hospitalSuperTankPoint = actors["HospitalSuperTankPoint"];
superTanks = actors.Values.Where(a => a.Info.Name == "5tnk" && a.Owner == turkey).ToArray();
provingGroundsCameraPoint = actors["ProvingGroundsCameraPoint"];
world.CreateActor("camera", greece, provingGroundsCameraPoint.Location, null);
Game.MoveViewport(startEntryPoint.Location.ToFloat2());
MissionUtils.PlayMissionMusic();
}