--[[ Copyright (c) The OpenRA Developers and Contributors 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, either version 3 of the License, or (at your option) any later version. For more information, see COPYING. ]] HarkonnenBase = { HarkonnenConstructionYard, HarkonnenWindTrap1, HarkonnenWindTrap2, HarkonnenWindTrap3, HarkonnenWindTrap4, HarkonnenWindTrap5, HarkonnenWindTrap6, HarkonnenWindTrap7, HarkonnenWindTrap8, HarkonnenSilo1, HarkonnenSilo2, HarkonnenSilo3, HarkonnenSilo4, HarkonnenGunTurret1, HarkonnenGunTurret2, HarkonnenGunTurret3, HarkonnenGunTurret4, HarkonnenGunTurret5, HarkonnenGunTurret6, HarkonnenGunTurret7, HarkonnenHeavyFactory, HarkonnenRefinery, HarkonnenOutpost, HarkonnenLightFactory } SmugglerBase = { SmugglerWindTrap1, SmugglerWindTrap2 } HarkonnenReinforcements = { easy = { { "combat_tank_h", "trooper", "trooper", "trooper", "trooper" }, { "trooper", "trooper", "trooper", "trooper", "trooper" }, { "combat_tank_h", "light_inf", "light_inf", "trooper", "trooper" }, { "combat_tank_h", "light_inf", "light_inf", "light_inf", "trooper", "trooper" }, { "combat_tank_h", "trike", "light_inf", "light_inf", "trooper", "trooper" } }, normal = { { "combat_tank_h", "trooper", "trooper", "trooper", "trooper" }, { "trooper", "trooper", "trooper", "trooper", "trooper" }, { "combat_tank_h", "light_inf", "light_inf", "trooper", "trooper" }, { "combat_tank_h", "light_inf", "light_inf", "light_inf", "trooper", "trooper" }, { "combat_tank_h", "trike", "light_inf", "light_inf", "trooper", "trooper" }, { "combat_tank_h", "trike", "combat_tank_h", "light_inf", "trooper", "trooper", "quad" }, { "combat_tank_h", "trike", "light_inf", "light_inf", "trooper", "trooper", "quad", "quad" } }, hard = { { "combat_tank_h", "trooper", "trooper", "trooper", "trooper" }, { "trooper", "trooper", "trooper", "trooper", "trooper" }, { "combat_tank_h", "light_inf", "light_inf", "trooper", "trooper" }, { "combat_tank_h", "light_inf", "light_inf", "light_inf", "trooper", "trooper" }, { "combat_tank_h", "trike", "light_inf", "light_inf", "trooper", "trooper" }, { "combat_tank_h", "trike", "combat_tank_h", "light_inf", "trooper", "trooper", "quad" }, { "combat_tank_h", "trike", "light_inf", "light_inf", "trooper", "trooper", "quad", "quad" }, { "combat_tank_h", "combat_tank_h", "trike", "light_inf", "light_inf", "trooper", "trooper", "quad", "quad" }, { "combat_tank_h", "combat_tank_h", "combat_tank_h", "combat_tank_h", "combat_tank_h", "combat_tank_h" } } } HarkonnenInfantryReinforcements = { normal = { { "light_inf", "light_inf", "light_inf", "trooper", "trooper", "trooper", "trooper", "trooper" } }, hard = { { "light_inf", "light_inf", "light_inf", "light_inf", "trooper", "trooper", "trooper", "trooper", "trooper", "trooper", "trooper", "trooper" }, { "light_inf", "light_inf", "light_inf", "light_inf", "light_inf", "light_inf", "light_inf", "light_inf", "light_inf", "trooper", "trooper", "trooper", "trooper", "trooper" } } } InfantryPath = { HarkonnenEntry3.Location } HarkonnenAttackDelay = { easy = DateTime.Minutes(3), normal = DateTime.Minutes(2) + DateTime.Seconds(20), hard = DateTime.Minutes(1) } HarkonnenAttackWaves = { easy = 5, normal = 7, hard = 9 } MercenaryReinforcements = { easy = { { "combat_tank_o", "combat_tank_o", "quad", "quad", "light_inf", "light_inf", "light_inf", "light_inf" }, { "trike", "trike", "quad", "quad", "quad", "trike", "trike", "trike" }, { "combat_tank_o", "combat_tank_o", "combat_tank_o", "combat_tank_o", "light_inf", "light_inf", "light_inf", "trooper", "trooper", "trooper", "trooper" } }, normal = { { "trike", "trike", "quad", "quad", "quad", "trike", "trike", "trike" }, { "combat_tank_o", "combat_tank_o", "quad", "quad", "light_inf", "light_inf", "light_inf", "light_inf" }, { "combat_tank_o", "combat_tank_o", "combat_tank_o", "combat_tank_o", "light_inf", "light_inf", "light_inf", "trooper", "trooper", "trooper", "trooper" }, { "combat_tank_o", "combat_tank_o", "quad", "quad", "light_inf", "light_inf", "light_inf", "light_inf", "trooper", "trooper", "trooper" }, { "trike", "trike", "quad", "quad", "quad", "trike", "trike", "trike", "trike", "trike", "trike" }, { "combat_tank_o", "combat_tank_o", "combat_tank_o", "combat_tank_o", "combat_tank_o", "combat_tank_o", "light_inf", "light_inf", "light_inf", "trooper", "trooper", "trooper", "trooper" } }, hard = { { "combat_tank_o", "combat_tank_o", "quad", "quad", "light_inf", "light_inf", "light_inf", "light_inf" }, { "trike", "trike", "quad", "quad", "quad", "trike", "trike", "trike" }, { "combat_tank_o", "combat_tank_o", "combat_tank_o", "combat_tank_o", "light_inf", "light_inf", "light_inf", "trooper", "trooper", "trooper", "trooper" }, { "trike", "trike", "quad", "quad", "quad", "trike", "trike", "trike", "trike", "trike", "trike" }, { "combat_tank_o", "combat_tank_o", "quad", "quad", "light_inf", "light_inf", "light_inf", "light_inf", "trooper", "trooper", "trooper" }, { "combat_tank_o", "combat_tank_o", "combat_tank_o", "combat_tank_o", "combat_tank_o", "combat_tank_o", "light_inf", "light_inf", "light_inf", "trooper", "trooper", "trooper", "trooper" }, { "combat_tank_o", "combat_tank_o", "quad", "quad", "trike", "trike", "light_inf", "light_inf", "light_inf", "light_inf", "trooper", "trooper", "trooper" }, { "trike", "trike", "quad", "quad", "quad", "trike", "trike", "trike", "trike", "trike", "trike", "quad", "quad" }, { "combat_tank_o", "combat_tank_o", "combat_tank_o", "combat_tank_o", "combat_tank_o", "combat_tank_o", "trike", "trike", "quad", "quad", "light_inf", "light_inf", "light_inf", "trooper", "trooper", "trooper", "trooper" } } } MercenaryAttackDelay = { easy = DateTime.Minutes(2) + DateTime.Seconds(40), normal = DateTime.Minutes(1) + DateTime.Seconds(50), hard = DateTime.Minutes(1) + DateTime.Seconds(10) } MercenaryAttackWaves = { easy = 3, normal = 6, hard = 9 } MercenarySpawn = { HarkonnenRally4.Location + CVec.New(2, -2) } -- Ordos tanks because those were intended for the Smugglers not the Atreides ContrabandReinforcements = { "mcv", "quad", "quad", "combat_tank_o", "combat_tank_o", "combat_tank_o" } SmugglerReinforcements = { "quad", "quad", "trike", "trike" } InitialHarkonnenReinforcements = { "trooper", "trooper", "quad", "quad", "trike", "trike", "trike", "light_inf" } HarkonnenPaths = { { HarkonnenEntry1.Location, HarkonnenRally1.Location }, { HarkonnenEntry1.Location, HarkonnenRally3.Location }, { HarkonnenEntry1.Location, HarkonnenRally2.Location }, { HarkonnenEntry1.Location, HarkonnenRally4.Location }, { HarkonnenEntry2.Location } } AtreidesReinforcements = { "trike", "combat_tank_a" } AtreidesPath = { AtreidesEntry.Location, AtreidesRally.Location } ContrabandTimes = { easy = DateTime.Minutes(10), normal = DateTime.Minutes(5), hard = DateTime.Minutes(2) + DateTime.Seconds(30) } wave = 0 SendHarkonnen = function() Trigger.AfterDelay(HarkonnenAttackDelay[Difficulty], function() if player.IsObjectiveCompleted(KillHarkonnen) then return end wave = wave + 1 if InfantryReinforcements and wave % 4 == 0 then local inf = Reinforcements.Reinforce(harkonnen, HarkonnenInfantryReinforcements[Difficulty][wave/4], InfantryPath) Utils.Do(inf, function(unit) unit.AttackMove(HarkonnenAttackLocation) IdleHunt(unit) end) end local entryPath = Utils.Random(HarkonnenPaths) local units = Reinforcements.ReinforceWithTransport(harkonnen, "carryall.reinforce", HarkonnenReinforcements[Difficulty][wave], entryPath, { entryPath[1] })[2] Utils.Do(units, function(unit) unit.AttackMove(HarkonnenAttackLocation) IdleHunt(unit) end) if wave < HarkonnenAttackWaves[Difficulty] then SendHarkonnen() return end Trigger.AfterDelay(DateTime.Seconds(3), function() LastHarkonnenArrived = true end) end) end mercWave = 0 SendMercenaries = function() Trigger.AfterDelay(MercenaryAttackDelay[Difficulty], function() mercWave = mercWave + 1 Media.DisplayMessage(UserInterface.Translate("incoming-mercenary-force"), Mentat) local units = Reinforcements.Reinforce(mercenary, MercenaryReinforcements[Difficulty][mercWave], MercenarySpawn) Utils.Do(units, function(unit) unit.AttackMove(MercenaryAttackLocation1) unit.AttackMove(MercenaryAttackLocation2) IdleHunt(unit) end) if mercWave < MercenaryAttackWaves[Difficulty] then SendMercenaries() return end Trigger.AfterDelay(DateTime.Seconds(3), function() LastMercenariesArrived = true end) end) end SendContraband = function(owner) ContrabandArrived = true UserInterface.SetMissionText(UserInterface.Translate("contraband-has-arrived"), player.Color) local units = SmugglerReinforcements if owner == player then units = ContrabandReinforcements end Reinforcements.ReinforceWithTransport(owner, "frigate", units, { ContrabandEntry.Location, Starport.Location + CVec.New(1, 1) }, { ContrabandExit.Location }) Trigger.AfterDelay(DateTime.Seconds(3), function() if owner == player then player.MarkCompletedObjective(CaptureStarport) Media.DisplayMessage(UserInterface.Translate("contraband-confiscated"), Mentat) else player.MarkFailedObjective(CaptureStarport) Media.DisplayMessage(UserInterface.Translate("contraband-not-confiscated"), Mentat) end end) Trigger.AfterDelay(DateTime.Seconds(5), function() UserInterface.SetMissionText("") end) end SmugglersAttack = function() Utils.Do(SmugglerBase, function(building) if not building.IsDead and building.Owner == smuggler then building.Sell() end end) Trigger.AfterDelay(DateTime.Seconds(1), function() Utils.Do(smuggler.GetGroundAttackers(), function(unit) IdleHunt(unit) end) end) end AttackNotifier = 0 Tick = function() if player.HasNoRequiredUnits() then harkonnen.MarkCompletedObjective(KillAtreides) end if LastHarkonnenArrived and not player.IsObjectiveCompleted(KillHarkonnen) and harkonnen.HasNoRequiredUnits() then Media.DisplayMessage(UserInterface.Translate("atreides-05"), Mentat) player.MarkCompletedObjective(KillHarkonnen) end if LastMercenariesArrived and not player.IsObjectiveCompleted(KillSmuggler) and smuggler.HasNoRequiredUnits() and mercenary.HasNoRequiredUnits() then Media.DisplayMessage(UserInterface.Translate("smugglers-annihilated"), Mentat) player.MarkCompletedObjective(KillSmuggler) end if LastHarvesterEaten[harkonnen] and DateTime.GameTime % DateTime.Seconds(10) == 0 then local units = harkonnen.GetActorsByType("harvester") if #units > 0 then LastHarvesterEaten[harkonnen] = false ProtectHarvester(units[1], harkonnen, AttackGroupSize[Difficulty]) end end AttackNotifier = AttackNotifier - 1 if TimerTicks and not ContrabandArrived then TimerTicks = TimerTicks - 1 if (TimerTicks % DateTime.Seconds(1)) == 0 then local contrabandArrivesIn = UserInterface.Translate("contraband-arrives-in", { ["time"] = Utils.FormatTime(TimerTicks)}) UserInterface.SetMissionText(contrabandArrivesIn, player.Color) end if TimerTicks <= 0 then SendContraband(smuggler) end end end WorldLoaded = function() harkonnen = Player.GetPlayer("Harkonnen") smuggler = Player.GetPlayer("Smugglers") mercenary = Player.GetPlayer("Mercenaries") player = Player.GetPlayer("Atreides") InfantryReinforcements = Difficulty ~= "easy" InitObjectives(player) KillAtreides = AddPrimaryObjective(harkonnen, "") CaptureBarracks = AddPrimaryObjective(player, "capture-barracks-sietch-tabr") KillHarkonnen = AddSecondaryObjective(player, "annihilate-harkonnen-units-reinforcements") CaptureStarport = AddSecondaryObjective(player, "capture-smuggler-starport-confiscate-contraband") Camera.Position = ARefinery.CenterPosition HarkonnenAttackLocation = AtreidesRally.Location MercenaryAttackLocation1 = Starport.Location + CVec.New(-16, 0) MercenaryAttackLocation2 = Starport.Location Trigger.AfterDelay(DateTime.Seconds(2), function() TimerTicks = ContrabandTimes[Difficulty] local time = { ["time"] = Utils.FormatTime(TimerTicks) } local contrabandApproaching = UserInterface.Translate("contraband-approaching-starport-north-in", time) Media.DisplayMessage(contrabandApproaching, Mentat) end) Trigger.OnAllKilledOrCaptured(HarkonnenBase, function() Utils.Do(harkonnen.GetGroundAttackers(), IdleHunt) end) Trigger.OnKilled(Starport, function() if not player.IsObjectiveCompleted(CaptureStarport) then ContrabandArrived = true UserInterface.SetMissionText(UserInterface.Translate("starport-destroyed-no-contraband"), player.Color) player.MarkFailedObjective(CaptureStarport) SmugglersAttack() Trigger.AfterDelay(DateTime.Seconds(15), function() UserInterface.SetMissionText("") end) end if DefendStarport then player.MarkFailedObjective(DefendStarport) end end) Trigger.OnDamaged(Starport, function() if Starport.Owner ~= smuggler then return end if AttackNotifier <= 0 then AttackNotifier = DateTime.Seconds(10) Media.DisplayMessage(UserInterface.Translate("do-not-destroy-starport"), Mentat) local defenders = smuggler.GetGroundAttackers() if #defenders > 0 then Utils.Do(defenders, function(unit) unit.Guard(Starport) end) end end end) Trigger.OnCapture(Starport, function() DefendStarport = AddSecondaryObjective(player, "defend-captured-starport") Trigger.ClearAll(Starport) Trigger.AfterDelay(0, function() Trigger.OnRemovedFromWorld(Starport, function() player.MarkFailedObjective(DefendStarport) end) end) if not ContrabandArrived then SendContraband(player) end SmugglersAttack() end) Trigger.OnKilled(HarkonnenBarracks, function() player.MarkFailedObjective(CaptureBarracks) end) Trigger.OnDamaged(HarkonnenBarracks, function() if AttackNotifier <= 0 and HarkonnenBarracks.Health < HarkonnenBarracks.MaxHealth * 3/4 then AttackNotifier = DateTime.Seconds(10) Media.DisplayMessage(UserInterface.Translate("do-not-destroy-barracks"), Mentat) end end) Trigger.OnCapture(HarkonnenBarracks, function() Media.DisplayMessage(UserInterface.Translate("hostages-released"), Mentat) if DefendStarport then player.MarkCompletedObjective(DefendStarport) end Trigger.AfterDelay(DateTime.Seconds(3), function() player.MarkCompletedObjective(CaptureBarracks) end) end) SendHarkonnen() Actor.Create("upgrade.barracks", true, { Owner = harkonnen }) Actor.Create("upgrade.light", true, { Owner = harkonnen }) Actor.Create("upgrade.heavy", true, { Owner = harkonnen }) Trigger.AfterDelay(0, ActivateAI) Trigger.AfterDelay(DateTime.Minutes(1), function() Media.PlaySpeechNotification(player, "Reinforce") Reinforcements.ReinforceWithTransport(player, "carryall.reinforce", AtreidesReinforcements, AtreidesPath, { AtreidesPath[1] }) end) local smugglerWaypoint = SmugglerWaypoint1.Location Trigger.OnEnteredFootprint({ smugglerWaypoint + CVec.New(-2, 0), smugglerWaypoint + CVec.New(-1, 0), smugglerWaypoint, smugglerWaypoint + CVec.New(1, -1), smugglerWaypoint + CVec.New(2, -1), SmugglerWaypoint3.Location }, function(a, id) if not warned and a.Owner == player and a.Type ~= "carryall" then warned = true Trigger.RemoveFootprintTrigger(id) Media.DisplayMessage(UserInterface.Translate("stay-away-from-starport"), UserInterface.Translate("smuggler-leader")) end end) Trigger.OnEnteredFootprint({ SmugglerWaypoint2.Location }, function(a, id) if not paid and a.Owner == player and a.Type ~= "carryall" then paid = true Trigger.RemoveFootprintTrigger(id) Media.DisplayMessage(UserInterface.Translate("were-warned-will-pay"), UserInterface.Translate("smuggler-leader")) Utils.Do(smuggler.GetGroundAttackers(), function(unit) unit.AttackMove(SmugglerWaypoint2.Location) end) Trigger.AfterDelay(DateTime.Seconds(3), function() KillSmuggler = AddSecondaryObjective(player, "destroy-smugglers-mercenaries") SendMercenaries() end) end end) Trigger.OnEnteredProximityTrigger(HarkonnenBarracks.CenterPosition, WDist.New(5 * 1024), function(a, id) if a.Owner == player and a.Type ~= "carryall" then Trigger.RemoveProximityTrigger(id) Media.DisplayMessage(UserInterface.Translate("capture-harkonnen-barracks-release-hostages"), Mentat) StopInfantryProduction = true end end) end