-------- Registry of map actors - sorted as ActorRegistry[player.name][actortype] as actor[] -------- DO NOT AMEND ActorRegistry = { } -------- List of actors for periodic checking ActorNoTrigger = { } -------- MAIN FUNCTION TO ATTACH TO WorldLoaded() function InitialiseAI () if bdebug then UserInterface.SetMissionText("InitialiseAI() called at tick "..missiontick, MissionPlayer.Color) end SetupAIettings() SetupMapUnits() --called earlier to prevent AI units from moving out of position ActivateAI() end ------------------------------------------------------------------------------------------------------------------ function SetupAIettings () if bdebug then UserInterface.SetMissionText("SetupAIettings() called at tick "..missiontick, MissionPlayer.Color) end AIMaintainExcessPower = AIMaintainExcessPower or 100 AIStructureHPRepair = AIStructureHPRepair or 1 AIUnitHPPursuit = AIUnitHPPursuit or 1 AIHarvestersPerRefinery = AIHarvestersPerRefinery or 1 AILowCashThreshold = AILowCashThreshold or 10000 AIEmergencyCashThreshold = AIEmergencyCashThreshold or 2000 end -- Initial unit setup function SetupMapUnits () if bdebug then UserInterface.SetMissionText("SetupMapUnits() called at tick "..missiontick, MissionPlayer.Color) end Utils.Do(Map.ActorsInWorld, function(a) if a.IsDead then return end -- Act only on Bots Utils.Do(HouseGroups.Bots, function (bot) if a.Owner == bot then if a.Type == "dog" then a.Stance = "AttackAnything" elseif a.HasProperty("Stance") then a.Stance = "Defend" -- attack persistent attackers if a.HasProperty("AttackMove") and a.HasProperty("Health") then Trigger.OnDamaged(a, function(b) if b.Health < AIUnitHPPursuit * b.MaxHealth then b.Stance = "AttackAnything" end end) end end end end) -- convert all walls to neutral if (a.Type == "brik" or a.Type == "cycl" or a.Type == "fenc" or a.Type == "sbag") and a.Owner ~= NeutralPlayer then a.Owner = NeutralPlayer end end) end function ActivateAI () if bdebug then UserInterface.SetMissionText("ActivateAI() called at tick "..missiontick, MissionPlayer.Color) end ------ Search throughout the map instead of using pre-setup ActiveProductionTables --SetupFactories(0) --Utils.Do(ActiveProductionTable, function(apt) UnitProduction(apt.factory , GetFactoryTab(apt.factory.Type)) end) SetupConYards() Utils.Do(HouseGroups.Bots, function(h) HouseStructureRepair(h, AIStructureHPRepair) end) local cnt = 0 Utils.Do(Map.NamedActors, function(actor) if actor.IsDead then return end Utils.Do(HouseGroups.Bots, function (bot) if actor.Owner == bot and GetFactoryTab(actor.Type) ~= nil then cnt = cnt + 1 SetupProductionBuilding(actor, GetFactoryTab(actor.Type)) end end) end) Media.Debug(cnt .. " AI factory instances initialized") end -- All houses to repair structures function HouseStructureRepair (cty,n) -- cty is house, n is the fraction of health to start repairing if bdebug then UserInterface.SetMissionText("HouseStructureRepair() called at tick "..missiontick, MissionPlayer.Color) end Utils.Do(Map.ActorsInWorld, function(actor) if actor.IsDead then return end if actor.Owner == cty then SingleStructureRepair(actor,n) end end) end -- All houses to repair structures function SingleStructureRepair (actor,n) -- cty is house, n is the fraction of health to start repairing if bdebug then UserInterface.SetMissionText("SingleStructureRepair() called at tick "..missiontick, MissionPlayer.Color) end if actor.IsDead then return end if actor.HasProperty("StartBuildingRepairs") then -- ensure the actor can be repaired Trigger.OnDamaged(actor, function(building) if building.HasProperty("StartBuildingRepairs") and building.Health < n * building.MaxHealth then building.StartBuildingRepairs() end end) end end -- Placeholder function function AddActorToPool(actor) if bdebug then UserInterface.SetMissionText("AddActorToPool() called at tick "..missiontick, MissionPlayer.Color) end -- exempt units: if actor.Type == "harv" then return end if actor.Type == "dog" or actor.Type == "yak" or actor.Type == "mig" or actor.Type == "hind" or actor.Type == "heli" then actor.Stance = "AttackAnything" end AIActorGroups[actor.Owner.Name] = AIActorGroups[actor.Owner.Name] or { } AIActorGroups[actor.Owner.Name]["Pool"] = AIActorGroups[actor.Owner.Name]["Pool"] or { } table.insert(AIActorGroups[actor.Owner.Name]["Pool"], actor) end