diff --git a/OpenRA.sln b/OpenRA.sln index ef50a47e49..3d784dc682 100644 --- a/OpenRA.sln +++ b/OpenRA.sln @@ -137,6 +137,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dune 2000 Lua scripts", "Du mods\d2k\maps\harkonnen-07\harkonnen07.lua = mods\d2k\maps\harkonnen-07\harkonnen07.lua mods\d2k\maps\harkonnen-09a\harkonnen09a-AI.lua = mods\d2k\maps\harkonnen-09a\harkonnen09a-AI.lua mods\d2k\maps\harkonnen-09a\harkonnen09a.lua = mods\d2k\maps\harkonnen-09a\harkonnen09a.lua + mods\d2k\maps\harkonnen-08\harkonnen08-AI.lua = mods\d2k\maps\harkonnen-08\harkonnen08-AI.lua + mods\d2k\maps\harkonnen-08\harkonnen08.lua = mods\d2k\maps\harkonnen-08\harkonnen08.lua mods\d2k\maps\ordos-01a\ordos01a.lua = mods\d2k\maps\ordos-01a\ordos01a.lua mods\d2k\maps\ordos-01b\ordos01b.lua = mods\d2k\maps\ordos-01b\ordos01b.lua mods\d2k\maps\ordos-02a\ordos02a-AI.lua = mods\d2k\maps\ordos-02a\ordos02a-AI.lua diff --git a/mods/d2k/bits/scripts/campaign-global.lua b/mods/d2k/bits/scripts/campaign-global.lua index 4ad46fc046..44f519e47c 100644 --- a/mods/d2k/bits/scripts/campaign-global.lua +++ b/mods/d2k/bits/scripts/campaign-global.lua @@ -10,7 +10,7 @@ Difficulty = Map.LobbyOption("difficulty") IdleHunt = function(actor) - if not actor.IsDead then + if actor.HasProperty("Hunt") and not actor.IsDead then Trigger.OnIdle(actor, actor.Hunt) end end @@ -179,6 +179,10 @@ end DefendAndRepairBase = function(owner, baseBuildings, modifier, defenderCount) Utils.Do(baseBuildings, function(actor) + if actor.IsDead then + return + end + DefendActor(actor, owner, defenderCount) RepairBuilding(owner, actor, modifier) end) diff --git a/mods/d2k/maps/harkonnen-08/harkonnen08-AI.lua b/mods/d2k/maps/harkonnen-08/harkonnen08-AI.lua new file mode 100644 index 0000000000..0a8a919e73 --- /dev/null +++ b/mods/d2k/maps/harkonnen-08/harkonnen08-AI.lua @@ -0,0 +1,69 @@ +--[[ + Copyright 2007-2017 The OpenRA Developers (see AUTHORS) + 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. +]] + +AttackGroupSize = +{ + easy = 6, + normal = 8, + hard = 10 +} + +AttackDelays = +{ + easy = { DateTime.Seconds(4), DateTime.Seconds(7) }, + normal = { DateTime.Seconds(2), DateTime.Seconds(5) }, + hard = { DateTime.Seconds(1), DateTime.Seconds(3) } +} + +EnemyInfantryTypes = { "light_inf", "light_inf", "trooper", "trooper", "trooper" } + +OrdosVehicleTypes = { "raider", "raider", "quad" } +OrdosTankTypes = { "combat_tank_o", "combat_tank_o", "siege_tank", "deviator" } +OrdosStarportTypes = { "trike.starport", "trike.starport", "quad.starport", "combat_tank_o.starport", "combat_tank_o.starport", "siege_tank.starport", "missile_tank.starport" } + +AtreidesVehicleTypes = { "trike", "trike", "quad" } +AtreidesTankTypes = { "combat_tank_a", "combat_tank_a", "siege_tank" } +AtreidesStarportTypes = { "trike.starport", "trike.starport", "quad.starport", "combat_tank_a.starport", "combat_tank_a.starport", "siege_tank.starport", "missile_tank.starport" } + +MercenaryTankTypes = { "combat_tank_o", "combat_tank_o", "siege_tank" } + +ActivateAI = function() + IdlingUnits[ordos] = Reinforcements.Reinforce(ordos, InitialOrdosReinforcements[1], InitialOrdosPaths[1]), Reinforcements.Reinforce(ordos, InitialOrdosReinforcements[2], InitialOrdosPaths[2]) + IdlingUnits[atreides_enemy] = Reinforcements.Reinforce(atreides_enemy, InitialAtreidesReinforcements, InitialAtreidesPath) + IdlingUnits[atreides_neutral] = { } + IdlingUnits[mercenary_enemy] = Reinforcements.Reinforce(mercenary_enemy, InitialMercenaryReinforcements, InitialMercenaryPath) + IdlingUnits[mercenary_ally] = { } + + DefendAndRepairBase(ordos, OrdosBase, 0.75, AttackGroupSize[Difficulty]) + DefendAndRepairBase(atreides_enemy, AtreidesBase, 0.75, AttackGroupSize[Difficulty]) + DefendAndRepairBase(mercenary_enemy, MercenaryBase, 0.75, AttackGroupSize[Difficulty]) + + local delay = function() return Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1) end + local infantryToBuild = function() return { Utils.Random(EnemyInfantryTypes) } end + local vehilcesToBuildOrdos = function() return { Utils.Random(OrdosVehicleTypes) } end + local vehilcesToBuildAtreides = function() return { Utils.Random(AtreidesVehicleTypes) } end + local tanksToBuildOrdos = function() return { Utils.Random(OrdosTankTypes) } end + local tanksToBuildAtreides = function() return { Utils.Random(AtreidesTankTypes) } end + local tanksToBuildMercenary = function() return { Utils.Random(MercenaryTankTypes) } end + local unitsToBuyOrdos = function() return { Utils.Random(OrdosStarportTypes) } end + local unitsToBuyAtreides = function() return { Utils.Random(AtreidesStarportTypes) } end + local attackThresholdSize = AttackGroupSize[Difficulty] * 2.5 + + ProduceUnits(ordos, OBarracks1, delay, infantryToBuild, AttackGroupSize[Difficulty], attackThresholdSize) + ProduceUnits(ordos, OLightFactory, delay, vehilcesToBuildOrdos, AttackGroupSize[Difficulty], attackThresholdSize) + ProduceUnits(ordos, OHeavyFactory, delay, tanksToBuildOrdos, AttackGroupSize[Difficulty], attackThresholdSize) + ProduceUnits(ordos, OStarport, delay, unitsToBuyOrdos, AttackGroupSize[Difficulty], attackThresholdSize) + + ProduceUnits(atreides_enemy, ABarracks1, delay, infantryToBuild, AttackGroupSize[Difficulty], attackThresholdSize) + ProduceUnits(atreides_enemy, ALightFactory, delay, vehilcesToBuildAtreides, AttackGroupSize[Difficulty], attackThresholdSize) + ProduceUnits(atreides_enemy, AHeavyFactory, delay, tanksToBuildAtreides, AttackGroupSize[Difficulty], attackThresholdSize) + ProduceUnits(atreides_enemy, AStarport, delay, unitsToBuyAtreides, AttackGroupSize[Difficulty], attackThresholdSize) + + ProduceUnits(mercenary_enemy, MHeavyFactory, delay, tanksToBuildMercenary, AttackGroupSize[Difficulty], attackThresholdSize) +end diff --git a/mods/d2k/maps/harkonnen-08/harkonnen08.lua b/mods/d2k/maps/harkonnen-08/harkonnen08.lua new file mode 100644 index 0000000000..c81ee24c46 --- /dev/null +++ b/mods/d2k/maps/harkonnen-08/harkonnen08.lua @@ -0,0 +1,340 @@ +--[[ + Copyright 2007-2017 The OpenRA Developers (see AUTHORS) + 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. +]] + +OrdosBase = { OConYard, OOutpost, OPalace, ORefinery1, ORefinery2, OHeavyFactory, OLightFactory, OHiTechFactory, OResearch, ORepair, OStarport, OGunt1, OGunt2, OGunt3, OGunt4, OGunt5, OGunt6, ORock1, ORock2, ORock3, ORock4, OBarracks1, OBarracks2, OPower1, OPower2, OPower3, OPower4, OPower5, OPower6, OPower7, OPower8, OPower9, OPower10, OPower11, OPower12, OPower13 } +AtreidesBase = { AConYard, AOutpost, ARefinery1, ARefinery2, AHeavyFactory, ALightFactory, AHiTechFactory, ARepair, AStarport, AGunt1, AGunt2, ARock1, ARock2, APower1, APower2, APower3, APower4, APower5, APower6, APower7, APower8, APower9 } +MercenaryBase = { MHeavyFactory, MStarport, MGunt, MPower1, MPower2 } + +OrdosReinforcements = +{ + easy = + { + { "trooper", "trooper", "quad", "quad" }, + { "light_inf", "light_inf", "light_inf", "light_inf", "light_inf" }, + { "light_inf", "light_inf", "light_inf", "raider", "raider" }, + { "combat_tank_o", "quad" } + }, + + normal = + { + { "trooper", "trooper", "trooper", "quad", "quad" }, + { "light_inf", "light_inf", "light_inf", "light_inf", "light_inf", "light_inf" }, + { "light_inf", "light_inf", "light_inf", "light_inf", "raider", "raider" }, + { "combat_tank_o", "combat_tank_o" }, + { "raider", "raider", "quad", "quad", "deviator" } + }, + + hard = + { + { "trooper", "trooper", "trooper", "trooper", "quad", "quad" }, + { "light_inf", "light_inf", "light_inf", "light_inf", "light_inf", "light_inf", "light_inf" }, + { "light_inf", "light_inf", "light_inf", "light_inf", "light_inf", "raider", "raider" }, + { "combat_tank_o", "combat_tank_o", "quad" }, + { "raider", "raider", "raider", "quad", "quad", "deviator" }, + { "siege_tank", "combat_tank_o", "combat_tank_o", "raider" } + } +} + +MercenaryStarportReinforcements = +{ + { "trooper", "trooper", "trooper", "trooper", "trooper", "trooper", "quad", "quad" }, + { "quad", "combat_tank_o", "trike", "quad", "trooper", "trooper" }, + { "trooper", "trooper", "trooper", "trooper", "siege_tank", "siege_tank" }, + { "quad", "quad", "combat_tank_o", "combat_tank_o", "combat_tank_o" } +} + +OrdosAttackDelay = +{ + easy = DateTime.Minutes(3), + normal = DateTime.Minutes(2) + DateTime.Seconds(20), + hard = DateTime.Minutes(1) +} + +MercenaryStarportDelay = DateTime.Minutes(1) + DateTime.Seconds(20) + +OrdosAttackWaves = +{ + easy = 4, + normal = 5, + hard = 6 +} + +InitialOrdosReinforcements = +{ + { "trooper", "trooper", "trooper", "trooper", "light_inf", "light_inf", "light_inf" }, + { "trooper", "trooper", "trooper", "trooper", "trooper", "combat_tank_o", "combat_tank_o" } +} + +InitialAtreidesReinforcements = { "combat_tank_a", "combat_tank_a", "quad", "quad", "trike" } + +InitialMercenaryReinforcements = { "trooper", "trooper", "trooper", "trooper", "quad", "quad" } + +OrdosPaths = +{ + { OrdosEntry1.Location, OrdosRally1.Location }, + { OrdosEntry2.Location, OrdosRally2.Location }, + { OrdosEntry3.Location, OrdosRally3.Location }, + { OrdosEntry4.Location, OrdosRally4.Location } +} + +InitialOrdosPaths = +{ + { OLightFactory.Location, OrdosRally5.Location }, + { OHiTechFactory.Location, OrdosRally6.Location } +} + +SaboteurPaths = +{ + { SaboteurWaypoint1.Location, SaboteurWaypoint2.Location, SaboteurWaypoint3.Location }, + { SaboteurWaypoint4.Location, SaboteurWaypoint5.Location, SaboteurWaypoint6.Location } +} + +InitialAtreidesPath = { AStarport.Location, AtreidesRally.Location } + +InitialMercenaryPath = { MStarport.Location, MercenaryRally.Location } + +SendStarportReinforcements = function(faction) + Trigger.AfterDelay(MercenaryStarportDelay, function() + if MStarport.IsDead or MStarport.Owner ~= faction then + return + end + + reinforcements = Utils.Random(MercenaryStarportReinforcements) + + local units = Reinforcements.ReinforceWithTransport(faction, "frigate", reinforcements, { MercenaryStarportEntry.Location, MStarport.Location + CVec.New(1, 1) }, { MercenaryStarportExit.Location })[2] + Utils.Do(units, function(unit) + unit.AttackMove(MercenaryAttackLocation) + IdleHunt(unit) + end) + + SendStarportReinforcements(faction) + end) +end + +SendAirStrike = function() + if AHiTechFactory.IsDead or AHiTechFactory.Owner ~= atreides_enemy then + return + end + + local targets = Utils.Where(player.GetActors(), function(actor) + return + actor.HasProperty("Sell") and + actor.Type ~= "wall" and + actor.Type ~= "medium_gun_turret" and + actor.Type ~= "large_gun_turret" and + actor.Type ~= "wind_trap" + end) + + if #targets > 0 then + AHiTechFactory.SendAirstrike(Utils.Random(targets).CenterPosition, true, 0) + end + + Trigger.AfterDelay(DateTime.Minutes(5), SendAirStrike) +end + +GetSaboteurTargets = function(player) + return Utils.Where(player.GetActors(), function(actor) + return + actor.HasProperty("Sell") + and actor.Type ~= "wall" + end) +end + +BuildSaboteur = function() + if OPalace.IsDead or OPalace.Owner ~= ordos then + return + end + + local targets = GetSaboteurTargets(player) + if #targets > 0 then + local saboteur = Actor.Create("saboteur", true, { Owner = ordos, Location = OPalace.Location + CVec.New(0, 2) }) + saboteur.Move(saboteur.Location + CVec.New(0, 1)) + saboteur.Wait(DateTime.Seconds(5)) + + local path = Utils.Random(SaboteurPaths) + saboteur.Move(path[1]) + saboteur.Move(path[2]) + saboteur.Move(path[3]) + + SendSaboteur(saboteur) + end + + Trigger.AfterDelay(DateTime.Minutes(1) + DateTime.Seconds(30), BuildSaboteur) +end + +SendSaboteur = function(saboteur) + local targets = GetSaboteurTargets(player) + if #targets < 1 then + return + end + + local target = Utils.Random(targets) + saboteur.Demolish(target) + + -- 'target' got removed from the world in the meantime + saboteur.CallFunc(function() + SendSaboteur(saboteur) + end) +end + +CheckAttackToAtreides = function() + AtreidesUnits = atreides_neutral.GetActors() + + Utils.Do(AtreidesUnits, function(unit) + Trigger.OnDamaged(unit, function(self, attacker) + if attacker.Owner == player and not check then + ChangeOwner(atreides_neutral, atreides_enemy) + + -- Ensure that harvesters that was on a carryall switched sides. + Trigger.AfterDelay(DateTime.Seconds(15), function() + ChangeOwner(atreides_neutral, atreides_enemy) + end) + + check = true + Media.DisplayMessage("The Atreides are now hostile!", "Mentat") + end + end) + end) +end + +ChangeOwner = function(old_owner, new_owner) + local units = old_owner.GetActors() + Utils.Do(units, function(unit) + if not unit.IsDead then + unit.Owner = new_owner + end + end) +end + +Tick = function() + if player.HasNoRequiredUnits() then + ordos.MarkCompletedObjective(KillHarkonnen1) + atreides_enemy.MarkCompletedObjective(KillHarkonnen2) + end + + if ordos.HasNoRequiredUnits() and not player.IsObjectiveCompleted(KillOrdos) then + Media.DisplayMessage("The Ordos have been annihilated!", "Mentat") + player.MarkCompletedObjective(KillOrdos) + end + + if atreides_enemy.HasNoRequiredUnits() and atreides_neutral.HasNoRequiredUnits() and not player.IsObjectiveCompleted(KillAtreides) then + Media.DisplayMessage("The Atreides have been annihilated!", "Mentat") + player.MarkCompletedObjective(KillAtreides) + end + + if mercenary_enemy.HasNoRequiredUnits() and mercenary_ally.HasNoRequiredUnits() and not MercenariesDestroyed then + Media.DisplayMessage("The Mercenaries have been annihilated!", "Mentat") + MercenariesDestroyed = true + end + + if DateTime.GameTime % DateTime.Seconds(10) == 0 and LastHarvesterEaten[ordos] then + local units = ordos.GetActorsByType("harvester") + + if #units > 0 then + LastHarvesterEaten[ordos] = false + ProtectHarvester(units[1], ordos, AttackGroupSize[Difficulty]) + end + end + + if DateTime.GameTime % DateTime.Seconds(10) == 0 and LastHarvesterEaten[atreides_enemy] then + local units = atreides_enemy.GetActorsByType("harvester") + + if #units > 0 then + LastHarvesterEaten[atreides_enemy] = false + ProtectHarvester(units[1], atreides_enemy, AttackGroupSize[Difficulty]) + end + end +end + +WorldLoaded = function() + ordos = Player.GetPlayer("Ordos") + atreides_enemy = Player.GetPlayer("Ordos Aligned Atreides") + atreides_neutral = Player.GetPlayer("Neutral Atreides") + mercenary_enemy = Player.GetPlayer("Ordos Aligned Mercenaries") + mercenary_ally = Player.GetPlayer("Harkonnen Aligned Mercenaries") + player = Player.GetPlayer("Harkonnen") + + InitObjectives(player) + KillOrdos = player.AddPrimaryObjective("Destroy the Ordos.") + KillAtreides = player.AddSecondaryObjective("Destroy the Atreides.") + AllyWithMercenaries = player.AddSecondaryObjective("Persuade the Mercenaries to fight with\nHouse Harkonnen.") + KillHarkonnen1 = ordos.AddPrimaryObjective("Kill all Harkonnen units.") + KillHarkonnen2 = atreides_enemy.AddPrimaryObjective("Kill all Harkonnen units.") + + Camera.Position = HMCV.CenterPosition + OrdosAttackLocation = HMCV.Location + MercenaryAttackLocation = HMCV.Location + + Trigger.AfterDelay(DateTime.Minutes(5), SendAirStrike) + Trigger.AfterDelay(DateTime.Minutes(1) + DateTime.Seconds(30), BuildSaboteur) + + Trigger.OnCapture(MHeavyFactory, function() + player.MarkCompletedObjective(AllyWithMercenaries) + Media.DisplayMessage("Leader Captured. Mercenaries have been persuaded to fight with House Harkonnen.", "Mentat") + MercenaryAttackLocation = OPalace.Location + + ChangeOwner(mercenary_enemy, mercenary_ally) + SendStarportReinforcements(mercenary_ally) + DefendAndRepairBase(mercenary_ally, MercenaryBase, 0.75, AttackGroupSize[Difficulty]) + IdlingUnits[mercenary_ally] = IdlingUnits[mercenary_enemy] + end) + + Trigger.OnKilled(MHeavyFactory, function() + if not player.IsObjectiveCompleted(AllyWithMercenaries) then + player.MarkFailedObjective(AllyWithMercenaries) + end + end) + + Trigger.OnKilledOrCaptured(OPalace, function() + Media.DisplayMessage("We cannot stand against the Harkonnen. We must become neutral.", "Atreides Commander") + + ChangeOwner(atreides_enemy, atreides_neutral) + DefendAndRepairBase(atreides_neutral, AtreidesBase, 0.75, AttackGroupSize[Difficulty]) + IdlingUnits[atreides_neutral] = IdlingUnits[atreides_enemy] + + -- Ensure that harvesters that was on a carryall switched sides. + Trigger.AfterDelay(DateTime.Seconds(15), function() + ChangeOwner(atreides_enemy, atreides_neutral) + CheckAttackToAtreides() + end) + end) + + Trigger.OnAllKilledOrCaptured(OrdosBase, function() + Utils.Do(ordos.GetGroundAttackers(), IdleHunt) + end) + + Trigger.OnAllKilledOrCaptured(AtreidesBase, function() + Utils.Do(atreides_enemy.GetGroundAttackers(), IdleHunt) + end) + + Trigger.OnAllKilledOrCaptured(MercenaryBase, function() + Utils.Do(mercenary_enemy.GetGroundAttackers(), IdleHunt) + Utils.Do(mercenary_ally.GetGroundAttackers(), IdleHunt) + end) + + local path = function() return Utils.Random(OrdosPaths) end + local waveCondition = function() return player.IsObjectiveCompleted(KillOrdos) end + local huntFunction = function(unit) + unit.AttackMove(OrdosAttackLocation) + IdleHunt(unit) + end + SendCarryallReinforcements(ordos, 0, OrdosAttackWaves[Difficulty], OrdosAttackDelay[Difficulty], path, OrdosReinforcements[Difficulty], waveCondition, huntFunction) + + SendStarportReinforcements(mercenary_enemy) + + Actor.Create("upgrade.barracks", true, { Owner = ordos }) + Actor.Create("upgrade.light", true, { Owner = ordos }) + Actor.Create("upgrade.heavy", true, { Owner = ordos }) + Actor.Create("upgrade.barracks", true, { Owner = atreides_enemy }) + Actor.Create("upgrade.light", true, { Owner = atreides_enemy }) + Actor.Create("upgrade.heavy", true, { Owner = atreides_enemy }) + Actor.Create("upgrade.hightech", true, { Owner = atreides_enemy }) + Actor.Create("upgrade.heavy", true, { Owner = mercenary_enemy }) + Trigger.AfterDelay(0, ActivateAI) +end diff --git a/mods/d2k/maps/harkonnen-08/map.bin b/mods/d2k/maps/harkonnen-08/map.bin new file mode 100644 index 0000000000..8c67251255 Binary files /dev/null and b/mods/d2k/maps/harkonnen-08/map.bin differ diff --git a/mods/d2k/maps/harkonnen-08/map.png b/mods/d2k/maps/harkonnen-08/map.png new file mode 100644 index 0000000000..7902754506 Binary files /dev/null and b/mods/d2k/maps/harkonnen-08/map.png differ diff --git a/mods/d2k/maps/harkonnen-08/map.yaml b/mods/d2k/maps/harkonnen-08/map.yaml new file mode 100644 index 0000000000..39bc0c26b1 --- /dev/null +++ b/mods/d2k/maps/harkonnen-08/map.yaml @@ -0,0 +1,647 @@ +MapFormat: 11 + +RequiresMod: d2k + +Title: Harkonnen 08 + +Author: Westwood Studios + +Tileset: ARRAKIS + +MapSize: 84,94 + +Bounds: 2,2,80,90 + +Visibility: MissionSelector + +Categories: Campaign + +LockPreview: True + +Players: + PlayerReference@Neutral: + Name: Neutral + OwnsWorld: True + NonCombatant: True + PlayerReference@Creeps: + Name: Creeps + NonCombatant: True + Enemies: Harkonnen, Ordos Aligned Atreides, Neutral Atreides, Ordos, Harkonnen Aligned Mercenaries, Ordos Aligned Mercenaries + PlayerReference@Harkonnen: + Name: Harkonnen + Playable: True + LockFaction: True + Faction: harkonnen + LockColor: True + Color: FE0000 + Allies: Harkonnen Aligned Mercenaries + Enemies: Ordos Aligned Atreides, Ordos, Ordos Aligned Mercenaries, Creeps + PlayerReference@Ordos Aligned Atreides: + Name: Ordos Aligned Atreides + LockFaction: True + Faction: atreides + LockColor: True + Color: 9191FF + Allies: Ordos, Ordos Aligned Mercenaries + Enemies: Harkonnen, Harkonnen Aligned Mercenaries + PlayerReference@Neutral Atreides: + Name: Neutral Atreides + LockFaction: True + Faction: atreides + LockColor: True + Color: 9191FF + PlayerReference@Ordos: + Name: Ordos + LockFaction: True + Faction: ordos + LockColor: True + Color: B3EAA5 + Allies: Ordos Aligned Atreides, Ordos Aligned Mercenaries + Enemies: Harkonnen, Harkonnen Aligned Mercenaries + PlayerReference@Ordos Aligned Mercenaries: + Name: Ordos Aligned Mercenaries + LockFaction: True + Faction: mercenary + LockColor: True + Color: DDDD00 + Allies: Ordos, Ordos Aligned Atreides + Enemies: Harkonnen + PlayerReference@Harkonnen Aligned Mercenaries: + Name: Harkonnen Aligned Mercenaries + LockFaction: True + Faction: mercenary + LockColor: True + Color: DDDD00 + Allies: Harkonnen + Enemies: Ordos, Ordos Aligned Atreides + +Actors: + AOutpost: outpost + Location: 3,3 + Owner: Ordos Aligned Atreides + AConYard: construction_yard + Location: 7,3 + Owner: Ordos Aligned Atreides + AHiTechFactory: high_tech_factory + Location: 11,3 + Owner: Ordos Aligned Atreides + APower1: wind_trap + Location: 16,3 + Owner: Ordos Aligned Atreides + APower2: wind_trap + Location: 20,3 + Owner: Ordos Aligned Atreides + APower3: wind_trap + Location: 26,3 + Owner: Ordos Aligned Atreides + Actor6: light_inf + Location: 30,3 + Owner: Ordos Aligned Atreides + ASilo: silo + Location: 24,4 + Owner: Ordos Aligned Atreides + Actor8: light_inf + Location: 29,4 + Owner: Ordos Aligned Atreides + APower4: wind_trap + Location: 22,5 + Owner: Ordos Aligned Atreides + ABarracks1: barracks + Location: 13,6 + Owner: Ordos Aligned Atreides + APower5: wind_trap + Location: 15,6 + Owner: Ordos Aligned Atreides + ALightFactory: light_factory + Location: 17,6 + Owner: Ordos Aligned Atreides + APower6: wind_trap + Location: 2,7 + Owner: Ordos Aligned Atreides + AStarport: starport + Location: 5,7 + Owner: Ordos Aligned Atreides + ABarracks2: barracks + Location: 10,7 + Owner: Ordos Aligned Atreides + AGunt1: medium_gun_turret + Location: 13,9 + Owner: Ordos Aligned Atreides + Actor17: wall + Location: 14,9 + Owner: Ordos Aligned Atreides + Actor18: wall + Location: 15,9 + Owner: Ordos Aligned Atreides + Actor19: wall + Location: 16,9 + Owner: Ordos Aligned Atreides + Actor20: wall + Location: 17,9 + Owner: Ordos Aligned Atreides + Actor21: wall + Location: 18,9 + Owner: Ordos Aligned Atreides + Actor22: wall + Location: 19,9 + Owner: Ordos Aligned Atreides + Actor23: wall + Location: 20,9 + Owner: Ordos Aligned Atreides + Actor24: wormspawner + Location: 51,9 + Owner: Creeps + APower7: wind_trap + Location: 3,10 + Owner: Ordos Aligned Atreides + ARefinery1: refinery + Location: 9,10 + Owner: Ordos Aligned Atreides + Actor27: wall + Location: 13,10 + Owner: Ordos Aligned Atreides + Actor28: wall + Location: 20,10 + Owner: Ordos Aligned Atreides + ARock1: large_gun_turret + Location: 13,11 + Owner: Ordos Aligned Atreides + Actor30: harvester + Location: 12,12 + Owner: Ordos Aligned Atreides + Actor31: spicebloom.spawnpoint + Location: 33,12 + Owner: Neutral + Actor32: spicebloom.spawnpoint + Location: 34,12 + Owner: Neutral + Actor33: spicebloom.spawnpoint + Location: 74,12 + Owner: Neutral + APower8: wind_trap + Location: 2,13 + Owner: Ordos Aligned Atreides + Actor35: carryall + Location: 11,13 + Owner: Ordos Aligned Atreides + AHeavyFactory: heavy_factory + Location: 4,14 + Owner: Ordos Aligned Atreides + APower9: wind_trap + Location: 7,14 + Owner: Ordos Aligned Atreides + Actor38: light_inf + Location: 15,14 + Owner: Ordos Aligned Atreides + Actor39: light_inf + Location: 12,15 + Owner: Ordos Aligned Atreides + Actor40: harvester + Location: 12,17 + Owner: Ordos Aligned Atreides + ARepair: repair_pad + Location: 4,18 + Owner: Ordos Aligned Atreides + ARefinery2: refinery + Location: 9,18 + Owner: Ordos Aligned Atreides + ARock2: large_gun_turret + Location: 13,18 + Owner: Ordos Aligned Atreides + Actor44: spicebloom.spawnpoint + Location: 48,18 + Owner: Neutral + Actor45: light_inf + Location: 2,19 + Owner: Ordos Aligned Atreides + Actor46: wall + Location: 13,19 + Owner: Ordos Aligned Atreides + Actor47: spicebloom.spawnpoint + Location: 26,19 + Owner: Neutral + Actor48: carryall + Location: 12,20 + Owner: Ordos Aligned Atreides + Actor49: wall + Location: 13,20 + Owner: Ordos Aligned Atreides + Actor50: spicebloom.spawnpoint + Location: 42,20 + Owner: Neutral + Actor51: wall + Location: 13,21 + Owner: Ordos Aligned Atreides + Actor52: siege_tank + Location: 11,22 + Owner: Ordos Aligned Atreides + Actor53: wall + Location: 13,22 + Owner: Ordos Aligned Atreides + Actor54: wall + Location: 11,23 + Owner: Ordos Aligned Atreides + Actor55: wall + Location: 12,23 + Owner: Ordos Aligned Atreides + AGunt2: medium_gun_turret + Location: 13,23 + Owner: Ordos Aligned Atreides + Actor57: wall + Location: 50,25 + Owner: Ordos + Actor58: wall + Location: 50,26 + Owner: Ordos + Actor59: wall + Location: 51,26 + Owner: Ordos + Actor60: wall + Location: 52,26 + Owner: Ordos + OGunt1: medium_gun_turret + Location: 53,26 + Owner: Ordos + OGunt2: medium_gun_turret + Location: 58,26 + Owner: Ordos + Actor63: wall + Location: 59,26 + Owner: Ordos + Actor64: wall + Location: 60,26 + Owner: Ordos + Actor65: wall + Location: 61,26 + Owner: Ordos + Actor66: spicebloom.spawnpoint + Location: 75,27 + Owner: Neutral + OPower1: wind_trap + Location: 53,29 + Owner: Ordos + OPower2: wind_trap + Location: 60,29 + Owner: Ordos + OPower3: wind_trap + Location: 51,30 + Owner: Ordos + OPower4: wind_trap + Location: 63,30 + Owner: Ordos + Actor71: spicebloom.spawnpoint + Location: 9,33 + Owner: Neutral + OPower5: wind_trap + Location: 44,33 + Owner: Ordos + Actor73: trooper + Location: 46,33 + Owner: Ordos + OPower6: wind_trap + Location: 60,33 + Owner: Ordos + Actor75: spicebloom.spawnpoint + Location: 6,34 + Owner: Neutral + OBarracks1: barracks + Location: 47,34 + Owner: Ordos + OResearch: research_centre + Location: 51,34 + Owner: Ordos + OHeavyFactory: heavy_factory + Location: 55,34 + Owner: Ordos + OPower7: wind_trap + Location: 62,35 + Owner: Ordos + Actor80: wall + Location: 42,37 + Owner: Ordos + Actor81: light_inf + Location: 50,37 + Owner: Ordos + Actor82: wall + Location: 42,38 + Owner: Ordos + ORepair: repair_pad + Location: 49,38 + Owner: Ordos + OPalace: palace + Location: 53,38 + Owner: Ordos + OHiTechFactory: high_tech_factory + Location: 57,38 + Owner: Ordos + ORock1: large_gun_turret + Location: 42,39 + Owner: Ordos + OPower8: wind_trap + Location: 62,39 + Owner: Ordos + Actor88: spicebloom.spawnpoint + Location: 30,40 + Owner: Neutral + OPower9: wind_trap + Location: 45,40 + Owner: Ordos + Actor90: deviator + Location: 52,40 + Owner: Ordos + ORefinery1: refinery + Location: 66,41 + Owner: Ordos + Actor92: wall + Location: 71,41 + Owner: Ordos + OGunt3: medium_gun_turret + Location: 72,41 + Owner: Ordos + Actor94: harvester + Location: 43,42 + Owner: Ordos + OStarport: starport + Location: 51,42 + Owner: Ordos + OLightFactory: light_factory + Location: 55,42 + Owner: Ordos + Actor97: harvester + Location: 69,42 + Owner: Ordos + Actor98: wall + Location: 72,42 + Owner: Ordos + ORefinery2: refinery + Location: 44,43 + Owner: Ordos + Actor100: carryall + Location: 65,43 + Owner: Ordos + Actor101: wall + Location: 72,43 + Owner: Ordos + ORock2: large_gun_turret + Location: 42,44 + Owner: Ordos + Actor103: wall + Location: 72,44 + Owner: Ordos + Actor104: wall + Location: 42,45 + Owner: Ordos + Actor105: wall + Location: 72,45 + Owner: Ordos + Actor106: wall + Location: 42,46 + Owner: Ordos + Actor107: carryall + Location: 44,46 + Owner: Ordos + OPower10: wind_trap + Location: 46,46 + Owner: Ordos + OBarracks2: barracks + Location: 51,46 + Owner: Ordos + OOutpost: outpost + Location: 54,46 + Owner: Ordos + OConYard: construction_yard + Location: 58,46 + Owner: Ordos + OPower11: wind_trap + Location: 62,46 + Owner: Ordos + ORock3: large_gun_turret + Location: 66,46 + Owner: Ordos + ORock4: large_gun_turret + Location: 70,46 + Owner: Ordos + Actor115: wall + Location: 71,46 + Owner: Ordos + Actor116: wall + Location: 72,46 + Owner: Ordos + Actor117: wall + Location: 42,47 + Owner: Ordos + Actor118: wall + Location: 66,47 + Owner: Ordos + Actor119: wall + Location: 70,47 + Owner: Ordos + Actor120: wall + Location: 65,48 + Owner: Ordos + OGunt4: medium_gun_turret + Location: 66,48 + Owner: Ordos + OGunt5: medium_gun_turret + Location: 70,48 + Owner: Ordos + OPower12: wind_trap + Location: 50,49 + Owner: Ordos + Actor124: wall + Location: 65,49 + Owner: Ordos + OSilo1: silo + Location: 52,50 + Owner: Ordos + OSilo2: silo + Location: 54,50 + Owner: Ordos + OSilo3: silo + Location: 56,50 + Owner: Ordos + OPower13: wind_trap + Location: 59,50 + Owner: Ordos + Actor129: wall + Location: 65,50 + Owner: Ordos + Actor130: wall + Location: 64,51 + Owner: Ordos + Actor131: wall + Location: 65,51 + Owner: Ordos + Actor132: wall + Location: 66,51 + Owner: Ordos + Actor133: spicebloom.spawnpoint + Location: 32,52 + Owner: Neutral + Actor134: wall + Location: 65,52 + Owner: Ordos + Actor135: spicebloom.spawnpoint + Location: 39,53 + Owner: Neutral + Actor136: wall + Location: 65,53 + Owner: Ordos + Actor137: wall + Location: 64,54 + Owner: Ordos + OGunt6: medium_gun_turret + Location: 65,54 + Owner: Ordos + Actor139: wall + Location: 66,54 + Owner: Ordos + Actor140: spicebloom.spawnpoint + Location: 26,57 + Owner: Neutral + Actor141: spicebloom.spawnpoint + Location: 70,60 + Owner: Neutral + MPower1: wind_trap + Location: 30,63 + Owner: Ordos Aligned Mercenaries + MPower2: wind_trap + Location: 32,63 + Owner: Ordos Aligned Mercenaries + MHeavyFactory: heavy_factory + Location: 36,65 + Owner: Ordos Aligned Mercenaries + Actor145: spicebloom.spawnpoint + Location: 14,69 + Owner: Neutral + Actor146: wall + Location: 31,69 + Owner: Ordos Aligned Mercenaries + MStarport: starport + Location: 37,69 + Owner: Ordos Aligned Mercenaries + Actor148: wall + Location: 31,70 + Owner: Ordos Aligned Mercenaries + Actor149: wall + Location: 31,71 + Owner: Ordos Aligned Mercenaries + MGunt: medium_gun_turret + Location: 32,71 + Owner: Ordos Aligned Mercenaries + Actor151: wall + Location: 31,72 + Owner: Ordos Aligned Mercenaries + Actor152: wall + Location: 32,72 + Owner: Ordos Aligned Mercenaries + Actor153: wall + Location: 33,72 + Owner: Ordos Aligned Mercenaries + Actor154: wall + Location: 34,72 + Owner: Ordos Aligned Mercenaries + Actor155: spicebloom.spawnpoint + Location: 50,77 + Owner: Neutral + Actor156: light_inf + Location: 69,79 + Owner: Harkonnen + Actor157: combat_tank_h + Location: 71,79 + Owner: Harkonnen + Actor158: spicebloom.spawnpoint + Location: 24,80 + Owner: Neutral + Actor159: combat_tank_h + Location: 66,80 + Owner: Harkonnen + Actor160: trooper + Location: 74,80 + Owner: Harkonnen + HMCV: mcv + Location: 68,81 + Owner: Harkonnen + Actor162: combat_tank_h + Location: 64,82 + Owner: Harkonnen + Actor163: combat_tank_h + Location: 66,82 + Owner: Harkonnen + Actor164: trooper + Location: 71,82 + Owner: Harkonnen + Actor165: trike + Location: 65,84 + Owner: Harkonnen + Actor166: siege_tank + Location: 67,84 + Owner: Harkonnen + Actor167: spicebloom.spawnpoint + Location: 8,90 + Owner: Neutral + Actor168: spicebloom.spawnpoint + Location: 36,90 + Owner: Neutral + OrdosRally1: waypoint + Owner: Neutral + Location: 43,88 + OrdosEntry1: waypoint + Owner: Neutral + Location: 43,91 + OrdosRally2: waypoint + Owner: Neutral + Location: 48,88 + OrdosEntry2: waypoint + Owner: Neutral + Location: 48,91 + OrdosRally3: waypoint + Owner: Neutral + Location: 76,59 + OrdosEntry3: waypoint + Owner: Neutral + Location: 81,59 + OrdosRally4: waypoint + Owner: Neutral + Location: 39,41 + OrdosEntry4: waypoint + Owner: Neutral + Location: 81,41 + OrdosRally5: waypoint + Owner: Neutral + Location: 58,43 + OrdosRally6: waypoint + Owner: Neutral + Location: 61,41 + AtreidesRally: waypoint + Owner: Neutral + Location: 9,8 + MercenaryRally: waypoint + Owner: Neutral + Location: 33,68 + MercenaryStarportEntry: waypoint + Owner: Neutral + Location: 81,70 + MercenaryStarportExit: waypoint + Owner: Neutral + Location: 2,70 + SaboteurWaypoint1: waypoint + Owner: Neutral + Location: 68,48 + SaboteurWaypoint2: waypoint + Owner: Neutral + Location: 81,51 + SaboteurWaypoint3: waypoint + Owner: Neutral + Location: 81,78 + SaboteurWaypoint4: waypoint + Owner: Neutral + Location: 18,59 + SaboteurWaypoint5: waypoint + Owner: Neutral + Location: 31,91 + SaboteurWaypoint6: waypoint + Owner: Neutral + Location: 64,91 + +Rules: d2k|rules/campaign-rules.yaml, d2k|rules/campaign-tooltips.yaml, d2k|rules/campaign-palettes.yaml, rules.yaml diff --git a/mods/d2k/maps/harkonnen-08/rules.yaml b/mods/d2k/maps/harkonnen-08/rules.yaml new file mode 100644 index 0000000000..1f9b8a210d --- /dev/null +++ b/mods/d2k/maps/harkonnen-08/rules.yaml @@ -0,0 +1,53 @@ +Player: + PlayerResources: + DefaultCash: 7000 + +World: + LuaScript: + Scripts: campaign-global.lua, harkonnen08.lua, harkonnen08-AI.lua + MissionData: + Briefing: The Ordos continue to grow in strength, thanks to their acquisition of new weaponry. The Ordos know that the wrath of the Harkonnen will soon fall upon them, and have allied with the Atreides.\n\nThis will not protect them from our Atomics. Eliminate any Atreides you encounter, but focus upon the Ordos as the main target. Smash their army, burn their structures and bring back the spoils to decorate the walls of the Palace! Capturing or destroying the Ordos Palace will show the Atreides the true might of House of Harkonnen and will throw the Ordos allegiance into disarray.\n\nOur scouts report a Mercenary leader inspecting a nearby Heavy Factory. If the Heavy Factory can be captured, the Mercenaries could be persuaded to fight for the Harkonnen. The mercenaries receive reinforcements via the Starport, so this must remain in their possession for them to be of any use. + BriefingVideo: H_BR08_E.VQA + MapOptions: + TechLevel: unrestricted + ScriptLobbyDropdown@difficulty: + ID: difficulty + Label: Difficulty + Values: + easy: Easy + normal: Normal + hard: Hard + Default: easy + +^Palettes: + IndexedPlayerPalette: + PlayerIndex: + Ordos Aligned Atreides: 143, 142, 141, 140, 139, 138, 137, 136, 135, 134, 133, 132, 131, 130, 129, 128 + Neutral Atreides: 143, 142, 141, 140, 139, 138, 137, 136, 135, 134, 133, 132, 131, 130, 129, 128 + Ordos Aligned Mercenaries: 239, 238, 237, 236, 235, 234, 233, 232, 231, 230, 229, 228, 227, 226, 225, 224 + Harkonnen Aligned Mercenaries: 239, 238, 237, 236, 235, 234, 233, 232, 231, 230, 229, 228, 227, 226, 225, 224 + +carryall.reinforce: + Cargo: + MaxWeight: 10 + +frigate: + Aircraft: + LandableTerrainTypes: Sand, Rock, Transition, Spice, SpiceSand, Dune, Concrete + VTOL: true # The frigate would teleport to land otherwise + +sardaukar: + Buildable: + Prerequisites: ~disabled + +stealth_raider: + Buildable: + Prerequisites: ~disabled + +grenadier: + Buildable: + Prerequisites: ~disabled + +thumper: + Buildable: + Prerequisites: ~disabled diff --git a/mods/d2k/missions.yaml b/mods/d2k/missions.yaml index 0e41d095c9..cb00fd9b31 100644 --- a/mods/d2k/missions.yaml +++ b/mods/d2k/missions.yaml @@ -29,4 +29,5 @@ Harkonnen Campaign: ./mods/d2k/maps/harkonnen-06a ./mods/d2k/maps/harkonnen-06b ./mods/d2k/maps/harkonnen-07 + ./mods/d2k/maps/harkonnen-08 ./mods/d2k/maps/harkonnen-09a diff --git a/mods/d2k/rules/misc.yaml b/mods/d2k/rules/misc.yaml index f3a52b0490..2bc5abd3da 100644 --- a/mods/d2k/rules/misc.yaml +++ b/mods/d2k/rules/misc.yaml @@ -211,6 +211,7 @@ wormspawner: upgrade.conyard: AlwaysVisible: Interactable: + ScriptTriggers: Tooltip: Name: Construction Yard Upgrade Buildable: @@ -235,6 +236,7 @@ upgrade.conyard: upgrade.barracks: AlwaysVisible: Interactable: + ScriptTriggers: Tooltip: Name: Barracks Upgrade Buildable: @@ -259,6 +261,7 @@ upgrade.barracks: upgrade.light: AlwaysVisible: Interactable: + ScriptTriggers: Tooltip: Name: Light Factory Upgrade Buildable: @@ -283,6 +286,7 @@ upgrade.light: upgrade.heavy: AlwaysVisible: Interactable: + ScriptTriggers: Tooltip: Name: Heavy Factory Upgrade Buildable: @@ -308,6 +312,7 @@ upgrade.heavy: upgrade.hightech: AlwaysVisible: Interactable: + ScriptTriggers: Tooltip: Name: High Tech Factory Upgrade Buildable: diff --git a/mods/d2k/rules/structures.yaml b/mods/d2k/rules/structures.yaml index 987e9a752f..f48397f1b5 100644 --- a/mods/d2k/rules/structures.yaml +++ b/mods/d2k/rules/structures.yaml @@ -686,6 +686,7 @@ wall: Interactable: CombatDebugOverlay: HiddenUnderShroud: + ScriptTriggers: Buildable: Queue: Building Prerequisites: barracks