diff --git a/OpenRA.sln b/OpenRA.sln index a006c71a39..c296c63e8f 100644 --- a/OpenRA.sln +++ b/OpenRA.sln @@ -124,6 +124,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dune 2000 Lua scripts", "Du mods\d2k\maps\harkonnen-03a\harkonnen03a.lua = mods\d2k\maps\harkonnen-03a\harkonnen03a.lua mods\d2k\maps\harkonnen-03b\harkonnen03b-AI.lua = mods\d2k\maps\harkonnen-03b\harkonnen03b-AI.lua mods\d2k\maps\harkonnen-03b\harkonnen03b.lua = mods\d2k\maps\harkonnen-03b\harkonnen03b.lua + mods\d2k\maps\harkonnen-04\harkonnen04-AI.lua = mods\d2k\maps\harkonnen-04\harkonnen04-AI.lua + mods\d2k\maps\harkonnen-04\harkonnen04.lua = mods\d2k\maps\harkonnen-04\harkonnen04.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.lua = mods\d2k\maps\ordos-02a\ordos02a.lua diff --git a/mods/d2k/maps/harkonnen-04/harkonnen04-AI.lua b/mods/d2k/maps/harkonnen-04/harkonnen04-AI.lua new file mode 100644 index 0000000000..a647f84f6d --- /dev/null +++ b/mods/d2k/maps/harkonnen-04/harkonnen04-AI.lua @@ -0,0 +1,185 @@ +IdlingUnits = { } + +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) } +} + +AtreidesInfantryTypes = { "light_inf", "light_inf", "trooper", "trooper", "trooper" } +AtreidesVehicleTypes = { "trike", "trike", "quad" } +AtreidesTankType = { "combat_tank_a" } + +HarvesterKilled = true + +IdleHunt = function(unit) if not unit.IsDead then Trigger.OnIdle(unit, unit.Hunt) end end + +SetupAttackGroup = function() + local units = { } + + for i = 0, AttackGroupSize[Difficulty] do + if #IdlingUnits == 0 then + return units + end + + local number = Utils.RandomInteger(1, #IdlingUnits + 1) + + if IdlingUnits[number] and not IdlingUnits[number].IsDead then + units[i] = IdlingUnits[number] + table.remove(IdlingUnits, number) + end + end + + return units +end + +SendAttack = function() + if Attacking then + return + end + Attacking = true + HoldProduction = true + + local units = SetupAttackGroup() + Utils.Do(units, IdleHunt) + + Trigger.OnAllRemovedFromWorld(units, function() + Attacking = false + HoldProduction = false + end) +end + +ProtectHarvester = function(unit) + DefendActor(unit) + Trigger.OnKilled(unit, function() HarvesterKilled = true end) +end + +DefendActor = function(unit) + Trigger.OnDamaged(unit, function(self, attacker) + if Defending then + return + end + Defending = true + + -- Don't try to attack spiceblooms + if attacker and attacker.Type == "spicebloom" then + return + end + + local Guards = SetupAttackGroup() + + if #Guards <= 0 then + Defending = false + return + end + + Utils.Do(Guards, function(unit) + if not self.IsDead then + unit.AttackMove(self.Location) + end + IdleHunt(unit) + end) + + Trigger.OnAllRemovedFromWorld(Guards, function() Defending = false end) + end) +end + +InitAIUnits = function() + IdlingUnits = Reinforcements.Reinforce(atreides, InitialAtreidesReinforcements[1], AtreidesPaths[2]), Reinforcements.Reinforce(atreides, InitialAtreidesReinforcements[2], AtreidesPaths[3]) +end + +RepairBase = function(house) + Utils.Do(Base[house.Name], function(actor) + DefendActor(actor) + Trigger.OnDamaged(actor, function(building) + if building.Owner == house and building.Health < building.MaxHealth * 3/4 then + building.StartBuildingRepairs() + end + end) + end) +end + +ProduceInfantry = function() + if ABarracks.IsDead then + return + end + + if HoldProduction then + Trigger.AfterDelay(DateTime.Seconds(30), ProduceInfantry) + return + end + + local delay = Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1) + local toBuild = { Utils.Random(AtreidesInfantryTypes) } + atreides.Build(toBuild, function(unit) + IdlingUnits[#IdlingUnits + 1] = unit[1] + Trigger.AfterDelay(delay, ProduceInfantry) + + if #IdlingUnits >= (AttackGroupSize[Difficulty] * 2.5) then + SendAttack() + end + end) +end + +ProduceVehicles = function() + if ALightFactory.IsDead then + return + end + + if HoldProduction then + Trigger.AfterDelay(DateTime.Seconds(30), ProduceVehicles) + return + end + + local delay = Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1) + local toBuild = { Utils.Random(AtreidesVehicleTypes) } + atreides.Build(toBuild, function(unit) + IdlingUnits[#IdlingUnits + 1] = unit[1] + Trigger.AfterDelay(delay, ProduceVehicles) + + if #IdlingUnits >= (AttackGroupSize[Difficulty] * 2.5) then + SendAttack() + end + end) +end + +ProduceTanks = function() + if AHeavyFactory.IsDead then + return + end + + if HoldProduction then + Trigger.AfterDelay(DateTime.Seconds(30), ProduceTanks) + return + end + + local delay = Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1) + atreides.Build(AtreidesTankType, function(unit) + IdlingUnits[#IdlingUnits + 1] = unit[1] + Trigger.AfterDelay(delay, ProduceTanks) + + if #IdlingUnits >= (AttackGroupSize[Difficulty] * 2.5) then + SendAttack() + end + end) +end + +ActivateAI = function() + InitAIUnits() + FremenProduction() + + RepairBase(atreides) + RepairBase(fremen) + + ProduceInfantry() + ProduceVehicles() + ProduceTanks() +end diff --git a/mods/d2k/maps/harkonnen-04/harkonnen04.lua b/mods/d2k/maps/harkonnen-04/harkonnen04.lua new file mode 100644 index 0000000000..16947d4bca --- /dev/null +++ b/mods/d2k/maps/harkonnen-04/harkonnen04.lua @@ -0,0 +1,252 @@ +Base = +{ + Atreides = { AConyard, AOutpost, ARefinery, AHeavyFactory, ALightFactory, AGunt1, AGunt2, ABarracks, ASilo, APower1, APower2, APower3, APower4, APower5, APower6 }, + Fremen = { FGunt1, FGunt2 } +} + +BaseAreaTriggers = +{ + { CPos.New(27, 38), CPos.New(26, 38), CPos.New(26, 39), CPos.New(25, 39), CPos.New(25, 40), CPos.New(25, 41), CPos.New(24, 41), CPos.New(24, 42) }, + { CPos.New(19, 81), CPos.New(19, 82), CPos.New(19, 83), CPos.New(19, 84), CPos.New(19, 85), CPos.New(19, 86), CPos.New(19, 87), CPos.New(19, 88), CPos.New(19, 89), CPos.New(19, 90), CPos.New(19, 91) }, + { CPos.New(10, 78), CPos.New(11, 78), CPos.New(12, 78), CPos.New(13, 78), CPos.New(14, 78), CPos.New(15, 78) } +} + +Sietches = { FSietch1, FSietch2 } + +FremenReinforcements = +{ + easy = + { + { "combat_tank_a", "combat_tank_a" }, + { "trooper", "trooper", "trooper" }, + { "combat_tank_a", "combat_tank_a" }, + { "combat_tank_a", "light_inf", "light_inf", "trooper", "trooper" }, + { "combat_tank_a", "trike", "trike", "quad", "trooper", "nsfremen" } + }, + + normal = + { + { "combat_tank_a", "combat_tank_a" }, + { "trooper", "trooper", "trooper" }, + { "combat_tank_a", "combat_tank_a" }, + { "combat_tank_a", "light_inf", "light_inf", "trooper", "trooper" }, + { "combat_tank_a", "trike", "trike", "quad", "trooper", "nsfremen" }, + { "combat_tank_a", "trike", "combat_tank_a", "quad", "nsfremen", "nsfremen" }, + { "fremen", "fremen", "fremen", "fremen", "trooper", "trooper", "trooper", "trooper" } + }, + + hard = + { + { "combat_tank_a", "combat_tank_a" }, + { "trooper", "trooper", "trooper" }, + { "combat_tank_a", "combat_tank_a" }, + { "combat_tank_a", "light_inf", "light_inf", "trooper", "trooper" }, + { "combat_tank_a", "trike", "trike", "quad", "trooper", "nsfremen" }, + { "combat_tank_a", "trike", "combat_tank_a", "quad", "nsfremen", "nsfremen" }, + { "fremen", "fremen", "fremen", "fremen", "trooper", "trooper", "trooper", "trooper" }, + { "combat_tank_a", "combat_tank_a", "combat_tank_a", "combat_tank_a", "missile_tank" }, + { "combat_tank_a", "combat_tank_a", "quad", "quad", "trike", "trike", "trooper", "trooper", "light_inf", "light_inf" } + } +} + +FremenAttackDelay = +{ + easy = DateTime.Minutes(3), + normal = DateTime.Minutes(2) + DateTime.Seconds(20), + hard = DateTime.Minutes(1) +} + +FremenAttackWaves = +{ + easy = 5, + normal = 7, + hard = 9 +} + +AtreidesHunters = { "trooper", "trooper", "trooper", "trooper", "trooper", "trooper", "trooper", "trooper", "trooper", "trooper" } + +FremenHunters = +{ + { "fremen", "fremen", "fremen" }, + { "combat_tank_a", "combat_tank_a", "combat_tank_a" }, + { "missile_tank", "missile_tank", "missile_tank" } +} + +InitialAtreidesReinforcements = +{ + { "trooper", "trooper", "trooper", "trooper", "light_inf", "light_inf", "light_inf", "light_inf" }, + { "combat_tank_a", "combat_tank_a", "quad", "trike" } +} + +AtreidesPaths = +{ + { AtreidesEntry1.Location, AtreidesRally1.Location }, + { AtreidesEntry2.Location, AtreidesRally2.Location }, + { AtreidesEntry3.Location, AtreidesRally3.Location } +} + +FremenPaths = +{ + { FremenEntry4.Location, FremenRally4.Location }, + { FremenEntry5.Location, FremenRally5.Location }, + { FremenEntry6.Location, FremenRally6.Location } +} + +FremenHunterPaths = +{ + { FremenEntry1.Location, FremenRally1.Location }, + { FremenEntry2.Location, FremenRally2.Location }, + { FremenEntry3.Location, FremenRally3.Location } +} + +HarkonnenReinforcements = { "combat_tank_h", "combat_tank_h" } + +HarkonnenPath = { HarkonnenEntry.Location, HarkonnenRally.Location } + +FremenInterval = +{ + easy = { DateTime.Minutes(1) + DateTime.Seconds(30), DateTime.Minutes(2) }, + normal = { DateTime.Minutes(2) + DateTime.Seconds(20), DateTime.Minutes(2) + DateTime.Seconds(40) }, + hard = { DateTime.Minutes(3) + DateTime.Seconds(40), DateTime.Minutes(4) } +} + +wave = 0 +SendFremen = function() + Trigger.AfterDelay(FremenAttackDelay[Difficulty], function() + if player.IsObjectiveCompleted(KillFremen) then + return + end + + wave = wave + 1 + if wave > FremenAttackWaves[Difficulty] then + return + end + + local entryPath = Utils.Random(FremenPaths) + local units = Reinforcements.ReinforceWithTransport(fremen, "carryall.reinforce", FremenReinforcements[Difficulty][wave], entryPath, { entryPath[1] })[2] + Utils.Do(units, function(unit) + unit.AttackMove(FremenAttackLocation) + IdleHunt(unit) + end) + + SendFremen() + end) +end + +SendHunters = function(areaTrigger, unit, path, house, objective, check) + Trigger.OnEnteredFootprint(areaTrigger, function(a, id) + if player.IsObjectiveCompleted(objective) then + return + end + + if not check and a.Owner == player then + local units = Reinforcements.ReinforceWithTransport(house, "carryall.reinforce", unit, path, { path[1] })[2] + Utils.Do(units, IdleHunt) + check = true + end + end) +end + +FremenProduction = function() + Trigger.OnAllKilled(Sietches, function() + SietchesAreDestroyed = true + end) + + if SietchesAreDestroyed then + return + end + + local delay = Utils.RandomInteger(FremenInterval[Difficulty][1], FremenInterval[Difficulty][2] + 1) + fremen.Build({ "nsfremen" }, function() + Trigger.AfterDelay(delay, ProduceInfantry) + end) +end + +Tick = function() + if player.HasNoRequiredUnits() then + atreides.MarkCompletedObjective(KillHarkonnen) + end + + if atreides.HasNoRequiredUnits() and not player.IsObjectiveCompleted(KillAtreides) then + Media.DisplayMessage("The Atreides have been annihilated!", "Mentat") + player.MarkCompletedObjective(KillAtreides) + end + + if fremen.HasNoRequiredUnits() and not player.IsObjectiveCompleted(KillFremen) then + Media.DisplayMessage("The Fremen have been annihilated!", "Mentat") + player.MarkCompletedObjective(KillFremen) + end + + if DateTime.GameTime % DateTime.Seconds(30) and HarvesterKilled then + local units = atreides.GetActorsByType("harvester") + + if #units > 0 then + HarvesterKilled = false + ProtectHarvester(units[1]) + end + end +end + +WorldLoaded = function() + atreides = Player.GetPlayer("Atreides") + fremen = Player.GetPlayer("Fremen") + player = Player.GetPlayer("Harkonnen") + + Difficulty = Map.LobbyOption("difficulty") + + InitObjectives() + + Camera.Position = HConyard.CenterPosition + FremenAttackLocation = HConyard.Location + + Trigger.OnAllKilledOrCaptured(Base[atreides.Name], function() + Utils.Do(atreides.GetGroundAttackers(), IdleHunt) + end) + + SendFremen() + Actor.Create("upgrade.barracks", true, { Owner = atreides }) + Actor.Create("upgrade.light", true, { Owner = atreides }) + Trigger.AfterDelay(0, ActivateAI) + + Trigger.AfterDelay(DateTime.Minutes(1) + DateTime.Seconds(15), function() + Media.PlaySpeechNotification(player, "Reinforce") + Reinforcements.Reinforce(player, HarkonnenReinforcements, HarkonnenPath) + end) + + Trigger.AfterDelay(DateTime.Seconds(15), function() + Media.DisplayMessage("Fremen concentrations spotted to the North and Southwest.", "Mentat") + end) + + SendHunters(BaseAreaTriggers[1], AtreidesHunters, AtreidesPaths[1], atreides, KillAtreides, HuntersSent1) + SendHunters(BaseAreaTriggers[1], FremenHunters[1], FremenHunterPaths[3], fremen, KillFremen, HuntersSent2) + SendHunters(BaseAreaTriggers[2], FremenHunters[2], FremenHunterPaths[2], fremen, KillFremen, HuntersSent3) + SendHunters(BaseAreaTriggers[3], FremenHunters[3], FremenHunterPaths[1], fremen, KillFremen, HuntersSent4) +end + +InitObjectives = function() + Trigger.OnObjectiveAdded(player, function(p, id) + Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") + end) + + KillAtreides = player.AddPrimaryObjective("Destroy the Atreiedes.") + KillFremen = player.AddPrimaryObjective("Destroy the Fremen.") + KillHarkonnen = atreides.AddPrimaryObjective("Kill all Harkonnen units.") + + 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.OnPlayerLost(player, function() + Trigger.AfterDelay(DateTime.Seconds(1), function() + Media.PlaySpeechNotification(player, "Lose") + end) + end) + Trigger.OnPlayerWon(player, function() + Trigger.AfterDelay(DateTime.Seconds(1), function() + Media.PlaySpeechNotification(player, "Win") + end) + end) +end diff --git a/mods/d2k/maps/harkonnen-04/map.bin b/mods/d2k/maps/harkonnen-04/map.bin new file mode 100644 index 0000000000..6e291a952c Binary files /dev/null and b/mods/d2k/maps/harkonnen-04/map.bin differ diff --git a/mods/d2k/maps/harkonnen-04/map.png b/mods/d2k/maps/harkonnen-04/map.png new file mode 100644 index 0000000000..5eec3acc2e Binary files /dev/null and b/mods/d2k/maps/harkonnen-04/map.png differ diff --git a/mods/d2k/maps/harkonnen-04/map.yaml b/mods/d2k/maps/harkonnen-04/map.yaml new file mode 100644 index 0000000000..cd6e527b48 --- /dev/null +++ b/mods/d2k/maps/harkonnen-04/map.yaml @@ -0,0 +1,382 @@ +MapFormat: 11 + +RequiresMod: d2k + +Title: Harkonnen 04 + +Author: Westwood Studios + +Tileset: ARRAKIS + +MapSize: 74,94 + +Bounds: 2,2,70,90 + +Visibility: MissionSelector + +Categories: Campaign + +LockPreview: True + +Players: + PlayerReference@Neutral: + Name: Neutral + OwnsWorld: True + NonCombatant: True + PlayerReference@Creeps: + Name: Creeps + NonCombatant: True + Enemies: Harkonnen, Atreides + PlayerReference@Harkonnen: + Name: Harkonnen + Playable: True + LockFaction: True + Faction: harkonnen + LockColor: True + Color: FE0000 + Enemies: Atreides, Fremen, Creeps + PlayerReference@Atreides: + Name: Atreides + LockFaction: True + Faction: atreides + LockColor: True + Color: 9191FF + Allies: Fremen + Enemies: Harkonnen + PlayerReference@Fremen: + Name: Fremen + LockFaction: True + Faction: fremen + LockColor: True + Color: DDDDDD + Allies: Atreides + Enemies: Harkonnen + +Actors: + Actor0: spicebloom.spawnpoint + Location: 52,4 + Owner: Neutral + Actor1: spicebloom.spawnpoint + Location: 13,5 + Owner: Neutral + Actor2: wormspawner + Location: 48,5 + Owner: Creeps + Actor3: spicebloom.spawnpoint + Location: 66,6 + Owner: Neutral + Actor4: nsfremen + Location: 26,11 + Owner: Fremen + Actor5: nsfremen + Location: 27,12 + Owner: Fremen + FSietch1: sietch + Location: 24,13 + Owner: Fremen + Actor7: wall + Location: 59,14 + Owner: Fremen + FGunt1: medium_gun_turret + Location: 61,14 + Owner: Fremen + TurretFacing: 0 + Actor9: wall + Location: 63,14 + Owner: Fremen + Actor10: wall + Location: 59,15 + Owner: Fremen + Actor11: wall + Location: 60,15 + Owner: Fremen + Actor12: wall + Location: 61,15 + Owner: Fremen + Actor13: wall + Location: 62,15 + Owner: Fremen + Actor14: wall + Location: 63,15 + Owner: Fremen + Actor15: spicebloom.spawnpoint + Location: 19,16 + Owner: Neutral + Actor16: nsfremen + Location: 23,16 + Owner: Fremen + Actor17: nsfremen + Location: 27,16 + Owner: Fremen + Actor18: nsfremen + Location: 22,17 + Owner: Fremen + Actor19: nsfremen + Location: 25,17 + Owner: Fremen + Actor20: spicebloom.spawnpoint + Location: 28,19 + Owner: Neutral + Actor21: spicebloom.spawnpoint + Location: 4,20 + Owner: Neutral + Actor22: spicebloom.spawnpoint + Location: 52,20 + Owner: Neutral + Actor23: spicebloom.spawnpoint + Location: 70,22 + Owner: Neutral + Actor24: spicebloom.spawnpoint + Location: 33,24 + Owner: Neutral + Actor25: spicebloom.spawnpoint + Location: 58,30 + Owner: Neutral + Actor26: spicebloom.spawnpoint + Location: 34,39 + Owner: Neutral + Actor27: wormspawner + Location: 41,40 + Owner: Creeps + Actor28: combat_tank_h + Location: 66,43 + Owner: Harkonnen + Actor29: light_inf + Location: 63,44 + Owner: Harkonnen + Actor30: combat_tank_h + Location: 68,44 + Owner: Harkonnen + Actor31: trooper + Location: 64,46 + Owner: Harkonnen + HConyard: construction_yard + Location: 66,46 + Owner: Harkonnen + Actor33: light_inf + Location: 61,47 + Owner: Harkonnen + Actor34: light_inf + Location: 63,49 + Owner: Harkonnen + Actor35: spicebloom.spawnpoint + Location: 34,50 + Owner: Neutral + Actor36: light_inf + Location: 65,50 + Owner: Harkonnen + Actor37: spicebloom.spawnpoint + Location: 6,52 + Owner: Neutral + Actor38: spicebloom.spawnpoint + Location: 28,57 + Owner: Neutral + ALightFactory: light_factory + Location: 39,69 + Owner: Atreides + AConyard: construction_yard + Location: 11,70 + Owner: Atreides + Actor41: wind_trap + Location: 16,70 + Owner: Atreides + Actor42: wall + Location: 33,70 + Owner: Atreides + Actor43: wall + Location: 34,70 + Owner: Atreides + Actor44: wall + Location: 35,70 + Owner: Atreides + Actor45: wall + Location: 21,71 + Owner: Atreides + Actor46: wall + Location: 33,71 + Owner: Atreides + ASilo: silo + Location: 43,71 + Owner: Atreides + Actor48: wall + Location: 21,72 + Owner: Atreides + Actor49: wall + Location: 22,72 + Owner: Atreides + AGunt1: medium_gun_turret + Location: 23,72 + Owner: Atreides + TurretFacing: 0 + AGunt2: medium_gun_turret + Location: 29,72 + Owner: Atreides + TurretFacing: 0 + Actor52: wall + Location: 30,72 + Owner: Atreides + Actor53: wall + Location: 31,72 + Owner: Atreides + Actor54: wall + Location: 32,72 + Owner: Atreides + Actor55: wall + Location: 33,72 + Owner: Atreides + AOutpost: outpost + Location: 42,73 + Owner: Atreides + APower1: wind_trap + Location: 4,74 + Owner: Atreides + APower2: wind_trap + Location: 6,74 + Owner: Atreides + ABarracks: barracks + Location: 9,74 + Owner: Atreides + AHeavyFactory: heavy_factory + Location: 12,74 + Owner: Atreides + APower3: wind_trap + Location: 16,74 + Owner: Atreides + Actor62: harvester + Location: 30,74 + Owner: Atreides + ARefinery: refinery + Location: 32,75 + Owner: Atreides + Actor64: light_inf + Location: 29,76 + Owner: Atreides + APower4: wind_trap + Location: 37,76 + Owner: Atreides + APower5: wind_trap + Location: 39,76 + Owner: Atreides + Actor67: light_inf + Location: 46,76 + Owner: Atreides + APower6: wind_trap + Location: 42,78 + Owner: Atreides + Actor69: light_inf + Location: 44,79 + Owner: Atreides + FSietch2: sietch + Location: 13,82 + Owner: Fremen + Actor71: wall + Location: 19,82 + Owner: Fremen + Actor72: wall + Location: 20,82 + Owner: Fremen + Actor73: wall + Location: 21,82 + Owner: Fremen + Actor74: fremen + Location: 19,83 + Owner: Fremen + Actor75: wall + Location: 21,83 + Owner: Fremen + Actor76: wall + Location: 21,84 + Owner: Fremen + Actor77: fremen + Location: 16,85 + Owner: Fremen + Actor78: wall + Location: 21,85 + Owner: Fremen + Actor79: wall + Location: 20,86 + Owner: Fremen + FGunt2: medium_gun_turret + Location: 21,86 + Owner: Fremen + TurretFacing: 0 + Actor81: fremen + Location: 14,87 + Owner: Fremen + Actor82: fremen + Location: 19,88 + Owner: Fremen + Actor83: spicebloom.spawnpoint + Location: 29,88 + Owner: Neutral + Actor84: spicebloom.spawnpoint + Location: 5,89 + Owner: Neutral + Actor85: fremen + Location: 13,90 + Owner: Fremen + Actor86: fremen + Location: 22,90 + Owner: Fremen + HarkonnenRally: waypoint + Owner: Neutral + Location: 70,42 + HarkonnenEntry: waypoint + Owner: Neutral + Location: 71,42 + FremenRally1: waypoint + Owner: Neutral + Location: 11,86 + FremenEntry1: waypoint + Owner: Neutral + Location: 11,91 + FremenRally2: waypoint + Owner: Neutral + Location: 24,82 + FremenEntry2: waypoint + Owner: Neutral + Location: 24,91 + FremenRally3: waypoint + Owner: Neutral + Location: 17,39 + FremenEntry3: waypoint + Owner: Neutral + Location: 2,39 + FremenRally4: waypoint + Owner: Neutral + Location: 69,14 + FremenEntry4: waypoint + Owner: Neutral + Location: 71,14 + FremenRally5: waypoint + Owner: Neutral + Location: 62,24 + FremenEntry5: waypoint + Owner: Neutral + Location: 71,24 + FremenRally6: waypoint + Owner: Neutral + Location: 58,28 + FremenEntry6: waypoint + Owner: Neutral + Location: 71,28 + AtreidesRally1: waypoint + Owner: Neutral + Location: 22,38 + AtreidesEntry1: waypoint + Owner: Neutral + Location: 2,38 + AtreidesRally2: waypoint + Owner: Neutral + Location: 26,74 + AtreidesEntry2: waypoint + Owner: Neutral + Location: 39,91 + AtreidesRally3: waypoint + Owner: Neutral + Location: 22,76 + AtreidesEntry3: waypoint + Owner: Neutral + Location: 22,91 + +Rules: d2k|rules/campaign-rules.yaml, rules.yaml diff --git a/mods/d2k/maps/harkonnen-04/rules.yaml b/mods/d2k/maps/harkonnen-04/rules.yaml new file mode 100644 index 0000000000..353897b4c0 --- /dev/null +++ b/mods/d2k/maps/harkonnen-04/rules.yaml @@ -0,0 +1,77 @@ +Player: + PlayerResources: + DefaultCash: 5000 + +World: + LuaScript: + Scripts: harkonnen04.lua, harkonnen04-AI.lua + MissionData: + Briefing: The native Fremen must be dealt with. Assemble a strike force to lead a sweep through the mountains. Seek out the Fremen hold, and destroy it. If any House responds, destroy it.\n\nTanks have been deployed to grind the Fremen beneath their treads. Demonstrate the power of House Harkonnen. + BriefingVideo: H_BR04_E.VQA + MapOptions: + TechLevel: low + ScriptLobbyDropdown@difficulty: + ID: difficulty + Label: Difficulty + Values: + easy: Easy + normal: Normal + hard: Hard + Default: easy + +carryall.reinforce: + Cargo: + MaxWeight: 10 + +sietch: + Exit: + ExitCell: 0,2 + Production: + Produces: Infantry + +nsfremen: + Buildable: + Prerequisites: ~sietch + AutoTarget: + InitialStanceAI: AttackAnything + +concreteb: + Buildable: + Prerequisites: ~disabled + +medium_gun_turret: + Buildable: + Prerequisites: ~disabled + +outpost: + Buildable: + Prerequisites: barracks + +quad: + Buildable: + Prerequisites: upgrade.light + +trooper: + Buildable: + Prerequisites: upgrade.barracks + +engineer: + Buildable: + Prerequisites: upgrade.barracks + +repair_pad: + Buildable: + Prerequisites: heavy_factory, upgrade.heavy + +mcv: + Buildable: + Prerequisites: repair_pad, upgrade.heavy + +upgrade.conyard: + Buildable: + Prerequisites: ~disabled + +fremen: + AutoTarget: + InitialStanceAI: AttackAnything + MustBeDestroyed: diff --git a/mods/d2k/missions.yaml b/mods/d2k/missions.yaml index 6ed0825041..ced5c22530 100644 --- a/mods/d2k/missions.yaml +++ b/mods/d2k/missions.yaml @@ -24,3 +24,4 @@ Harkonnen Campaign: ./mods/d2k/maps/harkonnen-02b ./mods/d2k/maps/harkonnen-03a ./mods/d2k/maps/harkonnen-03b + ./mods/d2k/maps/harkonnen-04