From 1f90c0c766d06cf30ba70ef83221b3b84d3515e3 Mon Sep 17 00:00:00 2001 From: FlightControl Date: Sun, 8 Jan 2017 03:53:05 +0100 Subject: [PATCH] Fixed respawn bug in AI_BALANCER + Scheduler bug AI_BALANCER respawns back the AI. Bug was in the FSM. In a transition, when states are the same, the events SHOULD execute. Added spawn delay interval option API SetSpawnInterval(). Bug that prevented AI_BALANCER to start if multiple AI_BALANCERs is also fixed. Fixed bug in scheduler dispatcher. Multiple schedules for the same scheduler work now too! --- Moose Development/Moose/AI/AI_Balancer.lua | 69 ++++++++++++++++-- Moose Development/Moose/Core/Fsm.lua | 4 +- .../Moose/Core/ScheduleDispatcher.lua | 2 +- Moose Development/Moose/Functional/Spawn.lua | 1 + Moose Development/Moose/Wrapper/Group.lua | 1 - Moose Development/Moose/Wrapper/Object.lua | 4 +- ...pawned AI.miz => AIB-001 - Spawned AI.miz} | Bin .../AIB-004 - Respawn Test when Destroyed.lua | 46 ++++++++++++ .../AIB-004 - Respawn Test when Destroyed.miz | Bin 0 -> 32113 bytes 9 files changed, 113 insertions(+), 14 deletions(-) rename Moose Test Missions/AIB - AI Balancing/AIB-001 - Spawned AI/{AIB-001 -Spawned AI.miz => AIB-001 - Spawned AI.miz} (100%) create mode 100644 Moose Test Missions/AIB - AI Balancing/AIB-004 - Respawn Test when Destroyed/AIB-004 - Respawn Test when Destroyed.lua create mode 100644 Moose Test Missions/AIB - AI Balancing/AIB-004 - Respawn Test when Destroyed/AIB-004 - Respawn Test when Destroyed.miz diff --git a/Moose Development/Moose/AI/AI_Balancer.lua b/Moose Development/Moose/AI/AI_Balancer.lua index d4259d722..4d8c22909 100644 --- a/Moose Development/Moose/AI/AI_Balancer.lua +++ b/Moose Development/Moose/AI/AI_Balancer.lua @@ -74,30 +74,35 @@ --- AI_BALANCER class -- @type AI_BALANCER -- @field Core.Set#SET_CLIENT SetClient +-- @field Functional.Spawn#SPAWN SpawnAI +-- @field Wrapper.Group#GROUP Test -- @extends Core.Fsm#FSM_SET AI_BALANCER = { ClassName = "AI_BALANCER", PatrolZones = {}, AIGroups = {}, + Earliest = 5, -- Earliest a new AI can be spawned is in 5 seconds. + Latest = 60, -- Latest a new AI can be spawned is in 60 seconds. } + + --- Creates a new AI_BALANCER object -- @param #AI_BALANCER self -- @param Core.Set#SET_CLIENT SetClient A SET\_CLIENT object that will contain the CLIENT objects to be monitored if they are alive or not (joined by a player). -- @param Functional.Spawn#SPAWN SpawnAI The default Spawn object to spawn new AI Groups when needed. -- @return #AI_BALANCER --- @usage --- -- Define a new AI_BALANCER Object. function AI_BALANCER:New( SetClient, SpawnAI ) -- Inherits from BASE - self = BASE:Inherit( self, FSM_SET:New( SET_GROUP:New() ) ) -- Core.Fsm#FSM_SET + local self = BASE:Inherit( self, FSM_SET:New( SET_GROUP:New() ) ) -- AI.AI_Balancer#AI_BALANCER self:SetStartState( "None" ) self:AddTransition( "*", "Start", "Monitoring" ) self:AddTransition( "*", "Monitor", "Monitoring" ) self:AddTransition( "*", "Spawn", "Spawning" ) self:AddTransition( "Spawning", "Spawned", "Spawned" ) + self:AddTransition( "*", "Destroyed", "Destroyed" ) self:AddTransition( "*", "Destroy", "Destroying" ) self:AddTransition( "*", "Return", "Returning" ) self:AddTransition( "*", "End", "End" ) @@ -105,6 +110,9 @@ function AI_BALANCER:New( SetClient, SpawnAI ) self.SetClient = SetClient self.SpawnAI = SpawnAI + + self.SpawnQueue = {} + self.ToNearestAirbase = false self.ToHomeAirbase = false @@ -113,6 +121,20 @@ function AI_BALANCER:New( SetClient, SpawnAI ) return self end +--- Sets the earliest to the latest interval in seconds how long AI_BALANCER will wait to spawn a new AI. +-- Provide 2 identical seconds if the interval should be a fixed amount of seconds. +-- @param #AI_BALANCER self +-- @param #number Earliest The earliest a new AI can be spawned in seconds. +-- @param #number Latest The latest a new AI can be spawned in seconds. +-- @return self +function AI_BALANCER:InitSpawnInterval( Earliest, Latest ) + + self.Earliest = Earliest + self.Latest = Latest + + return self +end + --- Returns the AI to the nearest friendly @{Wrapper.Airbase#AIRBASE}. -- @param #AI_BALANCER self -- @param Dcs.DCSTypes#Distance ReturnTresholdRange If there is an enemy @{Wrapper.Client#CLIENT} within the ReturnTresholdRange given in meters, the AI will not return to the nearest @{Wrapper.Airbase#AIRBASE}. @@ -140,15 +162,34 @@ end function AI_BALANCER:onenterSpawning( SetGroup, From, Event, To, ClientName ) -- OK, Spawn a new group from the default SpawnAI object provided. - local AIGroup = self.SpawnAI:Spawn() + local AIGroup = self.SpawnAI:Spawn() -- Wrapper.Group#GROUP AIGroup:E( "Spawning new AIGroup" ) --TODO: need to rework UnitName thing ... SetGroup:Add( ClientName, AIGroup ) + self.SpawnQueue[ClientName] = nil + + +-- --- @param Wrapper.Group#GROUP AIGroup +-- -- @param Core.Event#EVENTDATA EventData +-- local function Respawn( AIGroup, EventData ) +-- if EventData.IniUnit then +-- local CheckGroup = EventData.IniUnit:GetGroup() +-- if CheckGroup:GetName() == AIGroup:GetName() then +-- if CheckGroup:GetUnits() == nil then +-- AIGroup:Respawn( AIGroup:GetTemplate() ) +-- end +-- end +-- end +-- end +-- +-- +-- AIGroup:EventOnDead( Respawn ) +-- AIGroup:EventOnEjection( Respawn ) -- Fire the Spawned event. The first parameter is the AIGroup just Spawned. -- Mission designers can catch this event to bind further actions to the AIGroup. - self:Spawned( AIGroup ) + self:Spawned( AIGroup ) end --- @param #AI_BALANCER self @@ -159,6 +200,14 @@ function AI_BALANCER:onenterDestroying( SetGroup, From, Event, To, AIGroup ) AIGroup:Destroy() end +--- @param #AI_BALANCER self +-- @param Core.Set#SET_GROUP SetGroup +-- @param Wrapper.Group#GROUP AIGroup +function AI_BALANCER:onenterDestroyed( SetGroup, From, Event, To, AIGroup ) + + AIGroup:Destroy() +end + --- @param #AI_BALANCER self -- @param Core.Set#SET_GROUP SetGroup -- @param Wrapper.Group#GROUP AIGroup @@ -240,9 +289,13 @@ function AI_BALANCER:onenterMonitoring( SetGroup ) end else if not AIGroup or not AIGroup:IsAlive() == true then - self:E("client not alive") - self:Spawn( Client.UnitName ) - self:E("text after spawn") + self:E( "Client " .. Client.UnitName .. " not alive." ) + if not self.SpawnQueue[Client.UnitName] then + -- Spawn a new AI taking into account the spawn interval Earliest, Latest + self:__Spawn( math.random( self.Earliest, self.Latest ), Client.UnitName ) + self.SpawnQueue[Client.UnitName] = true + self:E( "New AI Spawned for Client " .. Client.UnitName ) + end end end return true diff --git a/Moose Development/Moose/Core/Fsm.lua b/Moose Development/Moose/Core/Fsm.lua index 25ac72ad7..6e6387b60 100644 --- a/Moose Development/Moose/Core/Fsm.lua +++ b/Moose Development/Moose/Core/Fsm.lua @@ -582,10 +582,10 @@ do -- FSM if execute then -- only execute the call if the From state is not equal to the To state! Otherwise this function should never execute! - if from ~= to then + --if from ~= to then self:_call_handler("onenter" .. to, params) self:_call_handler("OnEnter" .. to, params) - end + --end self:_call_handler("onafter" .. EventName, params) self:_call_handler("OnAfter" .. EventName, params) diff --git a/Moose Development/Moose/Core/ScheduleDispatcher.lua b/Moose Development/Moose/Core/ScheduleDispatcher.lua index d61e2cab7..18ac50a5a 100644 --- a/Moose Development/Moose/Core/ScheduleDispatcher.lua +++ b/Moose Development/Moose/Core/ScheduleDispatcher.lua @@ -75,7 +75,7 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr end self.Schedule = self.Schedule or setmetatable( {}, { __mode = "k" } ) - self.Schedule[Scheduler] = {} + self.Schedule[Scheduler] = self.Schedule[Scheduler] or {} self.Schedule[Scheduler][self.CallID] = {} self.Schedule[Scheduler][self.CallID].Function = ScheduleFunction self.Schedule[Scheduler][self.CallID].Arguments = ScheduleArguments diff --git a/Moose Development/Moose/Functional/Spawn.lua b/Moose Development/Moose/Functional/Spawn.lua index b5812fffa..843b12f0e 100644 --- a/Moose Development/Moose/Functional/Spawn.lua +++ b/Moose Development/Moose/Functional/Spawn.lua @@ -207,6 +207,7 @@ SPAWN = { SpawnAliasPrefix = nil, } + --- @type SPAWN.SpawnZoneTable -- @list SpawnZone diff --git a/Moose Development/Moose/Wrapper/Group.lua b/Moose Development/Moose/Wrapper/Group.lua index a5ba2121e..1115e8869 100644 --- a/Moose Development/Moose/Wrapper/Group.lua +++ b/Moose Development/Moose/Wrapper/Group.lua @@ -883,4 +883,3 @@ function GROUP:CalculateThreatLevelA2G() end - diff --git a/Moose Development/Moose/Wrapper/Object.lua b/Moose Development/Moose/Wrapper/Object.lua index 3ac441fbd..ed00a0cfe 100644 --- a/Moose Development/Moose/Wrapper/Object.lua +++ b/Moose Development/Moose/Wrapper/Object.lua @@ -34,7 +34,6 @@ OBJECT = { ObjectName = "", } - --- A DCSObject -- @type DCSObject -- @field id_ The ID of the controllable in DCS @@ -43,10 +42,11 @@ OBJECT = { -- @param #OBJECT self -- @param Dcs.DCSWrapper.Object#Object ObjectName The Object name -- @return #OBJECT self -function OBJECT:New( ObjectName ) +function OBJECT:New( ObjectName, Test ) local self = BASE:Inherit( self, BASE:New() ) self:F2( ObjectName ) self.ObjectName = ObjectName + return self end diff --git a/Moose Test Missions/AIB - AI Balancing/AIB-001 - Spawned AI/AIB-001 -Spawned AI.miz b/Moose Test Missions/AIB - AI Balancing/AIB-001 - Spawned AI/AIB-001 - Spawned AI.miz similarity index 100% rename from Moose Test Missions/AIB - AI Balancing/AIB-001 - Spawned AI/AIB-001 -Spawned AI.miz rename to Moose Test Missions/AIB - AI Balancing/AIB-001 - Spawned AI/AIB-001 - Spawned AI.miz diff --git a/Moose Test Missions/AIB - AI Balancing/AIB-004 - Respawn Test when Destroyed/AIB-004 - Respawn Test when Destroyed.lua b/Moose Test Missions/AIB - AI Balancing/AIB-004 - Respawn Test when Destroyed/AIB-004 - Respawn Test when Destroyed.lua new file mode 100644 index 000000000..a13f9ce66 --- /dev/null +++ b/Moose Test Missions/AIB - AI Balancing/AIB-004 - Respawn Test when Destroyed/AIB-004 - Respawn Test when Destroyed.lua @@ -0,0 +1,46 @@ +-- Name: Respawn Test when Destroyed +-- Author: FlightControl +-- Date Created: 7 January 2017 +-- +-- # Situation: +-- +-- For the red coalition, 2 client slots are foreseen. +-- For those players that have not joined the mission, red AI is spawned. +-- The red AI should start patrolling an area. +-- +-- The blue side has SAMs nearby. +-- Once the red AI takes off, the red AI is attacked by the blue SAMs. +-- Red AI should be killed and once that happens, a Respawn of the group should happen! +-- The Respawn happens through the InitCleanUp() API of SPAWN. +-- +-- # Test cases: +-- +-- 1. If no player is logging into the red slots, 2 red AI planes should be alive. +-- 2. If a player joins one red slot, one red AI plane should return to the nearest home base. +-- 3. If two players join the red slots, no AI plane should be spawned, and all airborne AI planes should return to the nearest home base. +-- 4. Monitor that once a red AI is destroyed, that it ReSpawns... +-- + +-- Define the SET of CLIENTs from the red coalition. This SET is filled during startup. +local RU_PlanesClientSet = SET_CLIENT:New():FilterCountries( "RUSSIA" ):FilterCategories( "plane" ):FilterStart() + +-- Define the SPAWN object for the red AI plane template. +-- We use InitCleanUp to check every 20 seconds, if there are no planes blocked at the airbase, waithing for take-off. +-- If a blocked plane exists, this red plane will be ReSpawned. +local RU_PlanesSpawn = SPAWN:New( "AI RU" ):InitCleanUp( 20 ) + +-- Start the AI_BALANCER, using the SET of red CLIENTs, and the SPAWN object as a parameter. +local RU_AI_Balancer = AI_BALANCER:New( RU_PlanesClientSet, RU_PlanesSpawn ) + +function RU_AI_Balancer:OnAfterSpawned( SetGroup, From, Event, To, AIGroup ) + + local PatrolZoneGroup = GROUP:FindByName( "PatrolZone" ) + local PatrolZone = ZONE_POLYGON:New( "PatrolZone", PatrolZoneGroup ) + + + local Patrol = AI_PATROLZONE:New( PatrolZone, 3000, 6000, 400, 600 ) + Patrol:ManageFuel( 0.2, 60 ) + Patrol:SetControllable( AIGroup ) + Patrol:__Start( 5 ) + +end diff --git a/Moose Test Missions/AIB - AI Balancing/AIB-004 - Respawn Test when Destroyed/AIB-004 - Respawn Test when Destroyed.miz b/Moose Test Missions/AIB - AI Balancing/AIB-004 - Respawn Test when Destroyed/AIB-004 - Respawn Test when Destroyed.miz new file mode 100644 index 0000000000000000000000000000000000000000..d6792748a418e1f5205f19ca81da492244aae60c GIT binary patch literal 32113 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 HpS}MFan6*{ literal 0 HcmV?d00001