DeathThreshold = { Easy = 200, Normal = 100, } TanyaType = "e7" TanyaStance = "AttackAnything" if Map.Difficulty ~= "Easy" then TanyaType = "e7.noautotarget" TanyaStance = "HoldFire" end RepairTriggerThreshold = { Easy = 50, Normal = 75, } Sams = { Sam1, Sam2, Sam3, Sam4 } TownUnits = { Einstein, Engineer, TownUnit01, TownUnit02, TownUnit03, TownUnit04, TownUnit05, TownUnit06, TownUnit07, TownUnit08, TownUnit09, TownUnit10, TownUnit11, TownUnit12, TownUnit13, TownUnit14, } ParabombDelay = DateTime.Seconds(30) ParatroopersDelay = DateTime.Minutes(5) Paratroopers = { { proxy = "powerproxy.paras1", entry = BadgerEntryPoint1.Location, drop = BadgerDropPoint1.Location, }, { proxy = "powerproxy.paras2", entry = BadgerEntryPoint1.Location + CVec.New(3, 0), drop = BadgerDropPoint2.Location, }, { proxy = "powerproxy.paras2", entry = BadgerEntryPoint1.Location + CVec.New(6, 0), drop = BadgerDropPoint3.Location, }, } AttackGroup = { } AttackGroupSize = 5 SovietInfantry = { "e1", "e2", "e3" } SovietVehiclesUpgradeDelay = DateTime.Minutes(4) SovietVehicleType = "Normal" SovietVehicles = { Normal = { "3tnk" }, Upgraded = { "3tnk", "v2rl" }, } ProductionInterval = { Easy = DateTime.Seconds(10), Normal = DateTime.Seconds(2), } ReinforcementsDelay = DateTime.Minutes(16) ReinforcementsUnits = { "2tnk", "2tnk", "2tnk", "2tnk", "2tnk", "2tnk", "1tnk", "1tnk", "jeep", "e1", "e1", "e1", "e1", "e3", "e3", "mcv", "truk", "truk", "truk", "truk", "truk", "truk" } SpawnAlliedReinforcements = function() if allies2.IsLocalPlayer then UserInterface.SetMissionText("") Media.PlaySpeechNotification(allies2, "AlliedReinforcementsArrived") end Reinforcements.Reinforce(allies2, ReinforcementsUnits, { ReinforcementsEntryPoint.Location, Allies2BasePoint.Location }) end Yak = nil YakAttack = function(yak) local targets = Map.ActorsInCircle(YakAttackPoint.CenterPosition, WDist.FromCells(10), function(a) return a.Owner == allies1 and not a.IsDead and a ~= Einstein and a ~= Tanya and a ~= Engineer end) if (#targets > 0) then yak.Attack(Utils.Random(targets)) end yak.Move(Map.ClosestEdgeCell(yak.Location)) yak.Destroy() Trigger.OnRemovedFromWorld(Yak, function() Yak = nil end) end SovietTownAttack = function() local units = Utils.Shuffle(Utils.Where(Map.ActorsWithTag("TownAttacker"), function(a) return not a.IsDead end)) Utils.Do(Utils.Take(5, units), function(unit) unit.AttackMove(TownPoint.Location) Trigger.OnIdle(unit, unit.Hunt) end) end SendParabombs = function() local proxy = Actor.Create("powerproxy.parabombs", false, { Owner = soviets }) proxy.SendAirstrikeFrom(BadgerEntryPoint2.Location, ParabombPoint1.Location) proxy.SendAirstrikeFrom(BadgerEntryPoint2.Location + CVec.New(0, 3), ParabombPoint2.Location) proxy.Destroy() end SendParatroopers = function() Utils.Do(Paratroopers, function(para) local proxy = Actor.Create(para.proxy, false, { Owner = soviets }) local units = proxy.SendParatroopersFrom(para.entry, para.drop) proxy.Destroy() Utils.Do(units, function(unit) Trigger.OnIdle(unit, function(a) if a.IsInWorld then a.Hunt() end end) end) end) end SendAttackGroup = function() if #AttackGroup < AttackGroupSize then return end Utils.Do(AttackGroup, function(unit) if not unit.IsDead then Trigger.OnIdle(unit, unit.Hunt) end end) AttackGroup = { } end ProduceInfantry = function() if SovietBarracks.IsDead or SovietBarracks.Owner ~= soviets then return end soviets.Build({ Utils.Random(SovietInfantry) }, function(units) table.insert(AttackGroup, units[1]) SendAttackGroup() Trigger.AfterDelay(ProductionInterval[Map.Difficulty], ProduceInfantry) end) end ProduceVehicles = function() if SovietWarFactory.IsDead or SovietWarFactory.Owner ~= soviets then return end soviets.Build({ Utils.Random(SovietVehicles[SovietVehicleType]) }, function(units) table.insert(AttackGroup, units[1]) SendAttackGroup() Trigger.AfterDelay(ProductionInterval[Map.Difficulty], ProduceVehicles) end) end NumBaseBuildings = function() local buildings = Map.ActorsInBox(AlliedBaseTopLeft.CenterPosition, AlliedBaseBottomRight.CenterPosition, function(a) return not a.IsDead and a.Owner == allies2 and a.HasProperty("StartBuildingRepairs") end) return #buildings end Tick = function() if DateTime.GameTime > 1 and DateTime.GameTime % 25 == 0 and NumBaseBuildings() == 0 then allies2.MarkFailedObjective(objHoldPosition) end if not allies2.IsObjectiveCompleted(objCutSovietPower) and soviets.PowerState ~= "Normal" then allies2.MarkCompletedObjective(objCutSovietPower) end if not allies2.IsObjectiveCompleted(objLimitLosses) and allies2.UnitsLost > DeathThreshold[Map.Difficulty] then allies2.MarkFailedObjective(objLimitLosses) end if allies2.IsLocalPlayer and DateTime.GameTime <= ReinforcementsDelay then UserInterface.SetMissionText("Allied reinforcements arrive in " .. Utils.FormatTime(ReinforcementsDelay - DateTime.GameTime)) else UserInterface.SetMissionText("") end end SetupSoviets = function() soviets.Cash = 1000 if Map.Difficulty == "Easy" then Utils.Do(Sams, function(sam) local camera = Actor.Create("Camera.SAM", true, { Owner = allies1, Location = sam.Location }) Trigger.OnKilledOrCaptured(sam, function() camera.Destroy() end) end) end local buildings = Utils.Where(Map.ActorsInWorld, function(self) return self.Owner == soviets and self.HasProperty("StartBuildingRepairs") end) Utils.Do(buildings, function(actor) Trigger.OnDamaged(actor, function(building) if building.Owner == soviets and building.Health < (building.MaxHealth * RepairTriggerThreshold[Map.Difficulty] / 100) then building.StartBuildingRepairs() end end) end) SovietBarracks.IsPrimaryBuilding = true SovietBarracks.RallyPoint = SovietRallyPoint.Location SovietWarFactory.IsPrimaryBuilding = true SovietWarFactory.RallyPoint = SovietRallyPoint.Location Trigger.AfterDelay(SovietVehiclesUpgradeDelay, function() SovietVehicleType = "Upgraded" end) Trigger.AfterDelay(0, function() ProduceInfantry() ProduceVehicles() end) end SetupTriggers = function() Trigger.OnKilled(Tanya, function() allies1.MarkFailedObjective(objTanyaMustSurvive) end) Trigger.OnAllKilledOrCaptured(Sams, function() allies1.MarkCompletedObjective(objDestroySamSites) objExtractEinstein = allies1.AddPrimaryObjective("Wait for a helicopter at the LZ and extract Einstein.") Actor.Create("flare", true, { Owner = allies1, Location = ExtractionLZ.Location + CVec.New(1, -1) }) Beacon.New(allies1, ExtractionLZ.CenterPosition) Media.PlaySpeechNotification(allies1, "SignalFlareNorth") ExtractionHeli = Reinforcements.ReinforceWithTransport(allies1, "tran", nil, { ExtractionLZEntryPoint.Location, ExtractionLZ.Location })[1] Trigger.OnKilled(ExtractionHeli, function() allies1.MarkFailedObjective(objExtractEinstein) end) Trigger.OnPassengerEntered(ExtractionHeli, function(heli, passenger) if passenger == Einstein then heli.Move(ExtractionLZEntryPoint.Location) heli.Destroy() Trigger.OnRemovedFromWorld(heli, function() allies2.MarkCompletedObjective(objLimitLosses) allies2.MarkCompletedObjective(objHoldPosition) allies1.MarkCompletedObjective(objTanyaMustSurvive) allies1.MarkCompletedObjective(objEinsteinSurvival) allies1.MarkCompletedObjective(objExtractEinstein) end) end end) end) Trigger.OnEnteredProximityTrigger(TownPoint.CenterPosition, WDist.FromCells(15), function(actor, trigger) if actor.Owner == allies1 then ReassignActors(TownUnits, neutral, allies1) Utils.Do(TownUnits, function(a) a.Stance = "Defend" end) allies1.MarkCompletedObjective(objFindEinstein) objEinsteinSurvival = allies1.AddPrimaryObjective("Keep Einstein alive at all costs.") Trigger.OnKilled(Einstein, function() allies1.MarkFailedObjective(objEinsteinSurvival) end) Trigger.RemoveProximityTrigger(trigger) SovietTownAttack() end end) Trigger.OnEnteredProximityTrigger(YakAttackPoint.CenterPosition, WDist.FromCells(5), function(actor, trigger) if not (Yak == nil or Yak.IsDead) or actor.Owner ~= allies1 then return end Yak = Reinforcements.Reinforce(soviets, { "yak" }, { YakEntryPoint.Location, YakAttackPoint.Location + CVec.New(0, -10) }, 0, YakAttack)[1] end) Trigger.AfterDelay(ParabombDelay, SendParabombs) Trigger.AfterDelay(ParatroopersDelay, SendParatroopers) Trigger.AfterDelay(ReinforcementsDelay, SpawnAlliedReinforcements) end SpawnTanya = function() Tanya = Actor.Create(TanyaType, true, { Owner = allies1, Location = TanyaLocation.Location }) Tanya.Stance = TanyaStance if Map.Difficulty ~= "Easy" and allies1.IsLocalPlayer then Trigger.AfterDelay(DateTime.Seconds(2), function() Media.DisplayMessage("According to the rules of engagement I need your explicit orders to fire, Commander!", "Tanya") end) end end ReassignActors = function(actors, from, to) Utils.Do(actors, function(a) if a.Owner == from then a.Owner = to a.Stance = "Defend" end end) end WorldLoaded = function() neutral = Player.GetPlayer("Neutral") -- Allies is the pre-set owner of units that get assigned to either the second player, if any, or the first player otherwise. allies = Player.GetPlayer("Allies") -- Allies1 is the player starting on the right, controlling Tanya allies1 = Player.GetPlayer("Allies1") -- Allies2 is the player starting on the left, defending the base allies2 = Player.GetPlayer("Allies2") soviets = Player.GetPlayer("Soviets") Utils.Do({ allies1, allies2 }, function(player) if player and player.IsLocalPlayer then Trigger.OnObjectiveAdded(player, function(p, id) Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") end) Trigger.OnObjectiveCompleted(player, function(p, id) Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") end) Trigger.OnObjectiveFailed(player, function(p, id) Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") end) Trigger.OnPlayerWon(player, function() Media.PlaySpeechNotification(player, "MissionAccomplished") end) Trigger.OnPlayerLost(player, function() Media.PlaySpeechNotification(player, "MissionFailed") end) end end) if not allies2 or allies2.IsLocalPlayer then Camera.Position = Allies2BasePoint.CenterPosition else Camera.Position = ChinookHusk.CenterPosition end if not allies2 then allies2 = allies1 end ReassignActors(Map.ActorsInWorld, allies, allies2) SpawnTanya() objTanyaMustSurvive = allies1.AddPrimaryObjective("Tanya must survive.") objFindEinstein = allies1.AddPrimaryObjective("Find Einstein's crashed helicopter.") objDestroySamSites = allies1.AddPrimaryObjective("Destroy the SAM sites.") objHoldPosition = allies2.AddPrimaryObjective("Hold your position and protect the base.") objLimitLosses = allies2.AddSecondaryObjective("Do not lose more than " .. DeathThreshold[Map.Difficulty] .. " units.") objCutSovietPower = allies2.AddSecondaryObjective("Take out the Soviet power grid.") SetupTriggers() SetupSoviets() end