IdlingUnits = { } AttackGroupSize = 6 Barracks = { Barracks2, Barracks3 } Rallypoints = { VehicleRallypoint1, VehicleRallypoint2, VehicleRallypoint3, VehicleRallypoint4, VehicleRallypoint5 } WaterLZs = { WaterLZ1, WaterLZ2 } Airfields = { Airfield1, Airfield2 } Yaks = { } SovietInfantryTypes = { "e1", "e1", "e2", "e4" } SovietVehicleTypes = { "3tnk", "3tnk", "3tnk", "v2rl", "v2rl", "apc" } SovietAircraftType = { "yak" } HoldProduction = true BuildVehicles = true TrainInfantry = true IdleHunt = function(unit) if not unit.IsDead then Trigger.OnIdle(unit, unit.Hunt) end end SetupAttackGroup = function() local units = { } for i = 0, AttackGroupSize, 1 do if #IdlingUnits == 0 then return units end local number = Utils.RandomInteger(1, #IdlingUnits) 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 = { } if SendWaterTransports and Utils.RandomInteger(0,2) == 1 then units = WaterAttack() Utils.Do(units, function(unit) Trigger.OnAddedToWorld(unit, function() Trigger.OnIdle(unit, unit.Hunt) end) end) Trigger.AfterDelay(DateTime.Seconds(20), function() Attacking = false HoldProduction = false end) else units = SetupAttackGroup() Utils.Do(units, function(unit) IdleHunt(unit) end) Trigger.AfterDelay(DateTime.Minutes(1), function() Attacking = false end) Trigger.AfterDelay(DateTime.Minutes(2), function() HoldProduction = false end) end end WaterAttack = function() local types = { } for i = 1, 5, 1 do types[i] = Utils.Random(SovietInfantryTypes) end return Reinforcements.ReinforceWithTransport(ussr, InsertionTransport, types, { WaterTransportSpawn.Location, Utils.Random(WaterLZs).Location }, { WaterTransportSpawn.Location })[2] end ProtectHarvester = function(unit) Trigger.OnDamaged(unit, function(self, attacker) -- TODO: Send the Harvester to the service depo if AttackOnGoing then return end AttackOnGoing = true local Guards = SetupAttackGroup() 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) Trigger.OnKilled(unit, function() HarvesterKilled = true end) end InitAIUnits = function() IdlingUnits = Map.ActorsInBox(MainBaseTopLeft.CenterPosition, Map.BottomRight, function(self) return self.Owner == ussr and self.HasProperty("Hunt") end) local buildings = Map.ActorsInBox(MainBaseTopLeft.CenterPosition, Map.BottomRight, function(self) return self.Owner == ussr and self.HasProperty("StartBuildingRepairs") end) Utils.Do(buildings, function(actor) Trigger.OnDamaged(actor, function(building) if building.Owner == ussr and building.Health < building.MaxHealth * 3/4 then building.StartBuildingRepairs() end end) end) end InitAIEconomy = function() ussr.Cash = 6000 if not Harvester.IsDead then Harvester.FindResources() ProtectHarvester(Harvester) end end InitProductionBuildings = function() if not Warfactory2.IsDead then Warfactory2.IsPrimaryBuilding = true Trigger.OnKilled(Warfactory2, function() BuildVehicles = false end) else BuildVehicles = false end if not Barracks2.IsDead then Barracks2.IsPrimaryBuilding = true Trigger.OnKilled(Barracks2, function() if not Barracks3.IsDead then Barracks3.IsPrimaryBuilding = true else TrainInfantry = false end end) elseif not Barracks3.IsDead then Barracks3.IsPrimaryBuilding = true else TrainInfantry = false end if not Barracks3.IsDead then Trigger.OnKilled(Barracks3, function() if Barracks2.IsDead then TrainInfantry = false end end) end if Map.Difficulty ~= "Easy" then if not Airfield1.IsDead then Trigger.OnKilled(Airfield1, function() if Airfield2.IsDead then AirAttacks = false else Airfield2.IsPrimaryBuilding = true Trigger.OnKilled(Airfield2, function() AirAttacks = false end) end end) Airfield1.IsPrimaryBuilding = true AirAttacks = true elseif not Airfield2.IsDead then Trigger.OnKilled(Airfield2, function() AirAttacks = false end) Airfield2.IsPrimaryBuilding = true AirAttacks = true end end end ProduceInfantry = function() if not TrainInfantry then return end if HoldProduction then Trigger.AfterDelay(DateTime.Minutes(1), ProduceInfantry) return end local delay = Utils.RandomInteger(DateTime.Seconds(3), DateTime.Seconds(9)) local toBuild = { Utils.Random(SovietInfantryTypes) } ussr.Build(toBuild, function(unit) IdlingUnits[#IdlingUnits + 1] = unit[1] Trigger.AfterDelay(delay, ProduceInfantry) if #IdlingUnits >= (AttackGroupSize * 2.5) then SendAttack() end end) end ProduceVehicles = function() if not BuildVehicles then return end if HoldProduction then Trigger.AfterDelay(DateTime.Minutes(1), ProduceVehicles) return end local delay = Utils.RandomInteger(DateTime.Seconds(5), DateTime.Seconds(9)) if HarvesterKilled then HarvesterKilled = false ussr.Build({ "harv" }, function(harv) harv[1].FindResources() ProtectHarvester(harv[1]) Trigger.AfterDelay(delay, ProduceVehicles) end) return end Warfactory2.RallyPoint = Utils.Random(Rallypoints).Location local toBuild = { Utils.Random(SovietVehicleTypes) } ussr.Build(toBuild, function(unit) IdlingUnits[#IdlingUnits + 1] = unit[1] Trigger.AfterDelay(delay, ProduceVehicles) if #IdlingUnits >= (AttackGroupSize * 2.5) then SendAttack() end end) end ProduceAircraft = function() if not AirAttacks then return end ussr.Build(SovietAircraftType, function(units) Yaks[#Yaks + 1] = units[1] if #Yaks == 2 then Trigger.OnKilled(units[1], ProduceAircraft) else Trigger.AfterDelay(DateTime.Minutes(1), ProduceAircraft) end local target = nil Trigger.OnIdle(units[1], function() if not target or target.IsDead or (not target.IsInWorld) then local enemies = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(self) return self.Owner == greece and self.HasProperty("Health") end) if #enemies > 0 then target = Utils.Random(enemies) units[1].Attack(target) end else units[1].Attack(target) end end) end) end ActivateAI = function() InitAIUnits() InitAIEconomy() InitProductionBuildings() Trigger.AfterDelay(DateTime.Minutes(5), function() ProduceInfantry() ProduceVehicles() if AirAttacks then Trigger.AfterDelay(DateTime.Minutes(3), ProduceAircraft) end end) end