diff --git a/mods/d2k/maps/atreides-02a/atreides02a-AI.lua b/mods/d2k/maps/atreides-02a/atreides02a-AI.lua new file mode 100644 index 0000000000..00e5e4dcc7 --- /dev/null +++ b/mods/d2k/maps/atreides-02a/atreides02a-AI.lua @@ -0,0 +1,122 @@ +IdlingUnits = { } + +AttackGroupSize = +{ + easy = 6, + normal = 8, + hard = 10 +} +AttackDelays = +{ + easy = { DateTime.Seconds(4), DateTime.Seconds(9) }, + normal = { DateTime.Seconds(2), DateTime.Seconds(7) }, + hard = { DateTime.Seconds(1), DateTime.Seconds(5) } +} + +HarkonnenInfantryTypes = { "light_inf" } + +AttackOnGoing = false +HoldProduction = false +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[Map.LobbyOption("difficulty")], 1 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, function(unit) + IdleHunt(unit) + end) + + Trigger.OnAllRemovedFromWorld(units, function() + Attacking = false + HoldProduction = false + end) +end + +DefendActor = function(unit) + Trigger.OnDamaged(unit, function(self, attacker) + if AttackOnGoing then + return + end + AttackOnGoing = true + + local Guards = SetupAttackGroup() + + if #Guards <= 0 then + AttackOnGoing = 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() AttackOnGoing = false end) + end) +end + +InitAIUnits = function() + Utils.Do(HarkonnenBase, function(actor) + DefendActor(actor) + Trigger.OnDamaged(actor, function(building) + if building.Health < building.MaxHealth * 3/4 then + building.StartBuildingRepairs() + end + end) + end) +end + +ProduceInfantry = function() + if HBarracks.IsDead then + return + end + + if HoldProduction then + Trigger.AfterDelay(DateTime.Minutes(1), ProduceInfantry) + return + end + + local delay = Utils.RandomInteger(AttackDelays[Map.LobbyOption("difficulty")][1], AttackDelays[Map.LobbyOption("difficulty")][2] + 1) + local toBuild = { Utils.Random(HarkonnenInfantryTypes) } + harkonnen.Build(toBuild, function(unit) + IdlingUnits[#IdlingUnits + 1] = unit[1] + Trigger.AfterDelay(delay, ProduceInfantry) + + if #IdlingUnits >= (AttackGroupSize[Map.LobbyOption("difficulty")] * 2.5) then + SendAttack() + end + end) +end + +ActivateAI = function() + InitAIUnits() + ProduceInfantry() +end diff --git a/mods/d2k/maps/atreides-02a/atreides02a.lua b/mods/d2k/maps/atreides-02a/atreides02a.lua index 606cf7aba4..df36ddf45e 100644 --- a/mods/d2k/maps/atreides-02a/atreides02a.lua +++ b/mods/d2k/maps/atreides-02a/atreides02a.lua @@ -94,6 +94,7 @@ WorldLoaded = function() end) SendHarkonnen() + Trigger.AfterDelay(0, ActivateAI) end InitObjectives = function() diff --git a/mods/d2k/maps/atreides-02a/map.bin b/mods/d2k/maps/atreides-02a/map.bin index 08ad5fc821..d91b94bc73 100644 Binary files a/mods/d2k/maps/atreides-02a/map.bin and b/mods/d2k/maps/atreides-02a/map.bin differ diff --git a/mods/d2k/maps/atreides-02a/rules.yaml b/mods/d2k/maps/atreides-02a/rules.yaml index 522afe9384..4518bb5e17 100644 --- a/mods/d2k/maps/atreides-02a/rules.yaml +++ b/mods/d2k/maps/atreides-02a/rules.yaml @@ -4,7 +4,7 @@ Player: World: LuaScript: - Scripts: atreides02a.lua + Scripts: atreides02a.lua, atreides02a-AI.lua MissionData: Briefing: Infiltrate the Imperial Basin and build up our forces until they are strong enough to eradicate the local Harkonnen presence.\n\nThe Harkonnen are reinforcing their troops by air, so be on your guard. Use the Outpost's radar to detect attacks from unexpected quarters.\n\nBe careful when mining the Spice. Spice mounds grow out of the sand. While a vital source of Spice, Spice mounds can damage or destroy any unit that blunders into them.\n\nGood luck.\n BriefingVideo: A_BR02_E.VQA diff --git a/mods/d2k/maps/atreides-02b/atreides02b-AI.lua b/mods/d2k/maps/atreides-02b/atreides02b-AI.lua new file mode 100644 index 0000000000..00e5e4dcc7 --- /dev/null +++ b/mods/d2k/maps/atreides-02b/atreides02b-AI.lua @@ -0,0 +1,122 @@ +IdlingUnits = { } + +AttackGroupSize = +{ + easy = 6, + normal = 8, + hard = 10 +} +AttackDelays = +{ + easy = { DateTime.Seconds(4), DateTime.Seconds(9) }, + normal = { DateTime.Seconds(2), DateTime.Seconds(7) }, + hard = { DateTime.Seconds(1), DateTime.Seconds(5) } +} + +HarkonnenInfantryTypes = { "light_inf" } + +AttackOnGoing = false +HoldProduction = false +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[Map.LobbyOption("difficulty")], 1 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, function(unit) + IdleHunt(unit) + end) + + Trigger.OnAllRemovedFromWorld(units, function() + Attacking = false + HoldProduction = false + end) +end + +DefendActor = function(unit) + Trigger.OnDamaged(unit, function(self, attacker) + if AttackOnGoing then + return + end + AttackOnGoing = true + + local Guards = SetupAttackGroup() + + if #Guards <= 0 then + AttackOnGoing = 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() AttackOnGoing = false end) + end) +end + +InitAIUnits = function() + Utils.Do(HarkonnenBase, function(actor) + DefendActor(actor) + Trigger.OnDamaged(actor, function(building) + if building.Health < building.MaxHealth * 3/4 then + building.StartBuildingRepairs() + end + end) + end) +end + +ProduceInfantry = function() + if HBarracks.IsDead then + return + end + + if HoldProduction then + Trigger.AfterDelay(DateTime.Minutes(1), ProduceInfantry) + return + end + + local delay = Utils.RandomInteger(AttackDelays[Map.LobbyOption("difficulty")][1], AttackDelays[Map.LobbyOption("difficulty")][2] + 1) + local toBuild = { Utils.Random(HarkonnenInfantryTypes) } + harkonnen.Build(toBuild, function(unit) + IdlingUnits[#IdlingUnits + 1] = unit[1] + Trigger.AfterDelay(delay, ProduceInfantry) + + if #IdlingUnits >= (AttackGroupSize[Map.LobbyOption("difficulty")] * 2.5) then + SendAttack() + end + end) +end + +ActivateAI = function() + InitAIUnits() + ProduceInfantry() +end diff --git a/mods/d2k/maps/atreides-02b/atreides02b.lua b/mods/d2k/maps/atreides-02b/atreides02b.lua index bb29c1f3ab..420b47b218 100644 --- a/mods/d2k/maps/atreides-02b/atreides02b.lua +++ b/mods/d2k/maps/atreides-02b/atreides02b.lua @@ -98,6 +98,7 @@ WorldLoaded = function() end) SendHarkonnen() + Trigger.AfterDelay(0, ActivateAI) end InitObjectives = function() diff --git a/mods/d2k/maps/atreides-02b/map.bin b/mods/d2k/maps/atreides-02b/map.bin index 0068202b5d..2005604fe1 100644 Binary files a/mods/d2k/maps/atreides-02b/map.bin and b/mods/d2k/maps/atreides-02b/map.bin differ diff --git a/mods/d2k/maps/atreides-02b/rules.yaml b/mods/d2k/maps/atreides-02b/rules.yaml index 772fad3900..51272370d3 100644 --- a/mods/d2k/maps/atreides-02b/rules.yaml +++ b/mods/d2k/maps/atreides-02b/rules.yaml @@ -4,7 +4,7 @@ Player: World: LuaScript: - Scripts: atreides02b.lua + Scripts: atreides02b.lua, atreides02b-AI.lua MissionData: Briefing: Infiltrate the Imperial Basin and build up our forces until they are strong enough to eradicate the local Harkonnen presence.\n\nThe Harkonnen are reinforcing their troops by air, so be on your guard. Use the Outpost's radar to detect attacks from unexpected quarters.\n\nBe careful when mining the Spice. Spice mounds grow out of the sand. While a vital source of Spice, Spice mounds can damage or destroy any unit that blunders into them.\n\nGood luck.\n BriefingVideo: A_BR02_E.VQA