From f4cb6df8d4bb7cc9c1b3a8e92a1671b8d550273b Mon Sep 17 00:00:00 2001 From: Frank Date: Tue, 19 Jan 2021 16:53:22 +0100 Subject: [PATCH] Ops respawn --- Moose Development/Moose/Ops/ArmyGroup.lua | 39 ++++++- Moose Development/Moose/Ops/FlightGroup.lua | 20 ---- Moose Development/Moose/Ops/OpsGroup.lua | 119 +++++++++++++++++++- 3 files changed, 152 insertions(+), 26 deletions(-) diff --git a/Moose Development/Moose/Ops/ArmyGroup.lua b/Moose Development/Moose/Ops/ArmyGroup.lua index a5754efd9..de31c0a03 100644 --- a/Moose Development/Moose/Ops/ArmyGroup.lua +++ b/Moose Development/Moose/Ops/ArmyGroup.lua @@ -394,11 +394,43 @@ function ARMYGROUP:onafterStatus(From, Event, To) else -- Info text. - local text=string.format("State %s: Alive=%s", fsmstate, tostring(self:IsAlive())) - self:T2(self.lid..text) + if self.verbose>=1 then + local text=string.format("State %s: Alive=%s", fsmstate, tostring(self:IsAlive())) + self:I(self.lid..text) + end end + --- + -- Elements + --- + + if self.verbose>=2 then + local text="Elements:" + for i,_element in pairs(self.elements) do + local element=_element --#ARMYGROUP.Element + + local name=element.name + local status=element.status + local unit=element.unit + --local life=unit:GetLifeRelative() or 0 + local life,life0=self:GetLifePoints(element) + + local life0=element.life0 + + -- Get ammo. + local ammo=self:GetAmmoElement(element) + + -- Output text for element. + text=text..string.format("\n[%d] %s: status=%s, life=%.1f/%.1f, guns=%d, rockets=%d, bombs=%d, missiles=%d", + i, name, status, life, life0, ammo.Guns, ammo.Rockets, ammo.Bombs, ammo.Missiles) + end + if #self.elements==0 then + text=text.." none!" + end + self:I(self.lid..text) + end + --- -- Tasks & Missions @@ -965,8 +997,11 @@ function ARMYGROUP:OnEventBirth(EventData) if self.respawning then + self:I(self.lid.."Respawning unit "..tostring(unitname)) + local function reset() self.respawning=nil + self:_CheckGroupDone() end -- Reset switch in 1 sec. This should allow all birth events of n>1 groups to have passed. diff --git a/Moose Development/Moose/Ops/FlightGroup.lua b/Moose Development/Moose/Ops/FlightGroup.lua index ce641b949..92f7e4edc 100644 --- a/Moose Development/Moose/Ops/FlightGroup.lua +++ b/Moose Development/Moose/Ops/FlightGroup.lua @@ -2025,26 +2025,6 @@ function FLIGHTGROUP:onafterUpdateRoute(From, Event, To, n) end ---- On after "Respawn" event. --- @param #FLIGHTGROUP self --- @param #string From From state. --- @param #string Event Event. --- @param #string To To state. --- @param #table Template The template used to respawn the group. -function FLIGHTGROUP:onafterRespawn(From, Event, To, Template) - - self:T(self.lid.."Respawning group!") - - local template=UTILS.DeepCopy(Template or self.template) - - if self.group and self.group:InAir() then - template.lateActivation=false - self.respawning=true - self.group=self.group:Respawn(template) - end - -end - --- Check if flight is done, i.e. -- -- * passed the final waypoint, diff --git a/Moose Development/Moose/Ops/OpsGroup.lua b/Moose Development/Moose/Ops/OpsGroup.lua index c202ab0ff..bdc8d445d 100644 --- a/Moose Development/Moose/Ops/OpsGroup.lua +++ b/Moose Development/Moose/Ops/OpsGroup.lua @@ -399,6 +399,7 @@ function OPSGROUP:New(Group) -- Add FSM transitions. -- From State --> Event --> To State self:AddTransition("InUtero", "Spawned", "Spawned") -- The whole group was spawned. + self:AddTransition("*", "Respawn", "*") -- Respawn group. self:AddTransition("*", "Dead", "Dead") -- The whole group is dead. self:AddTransition("*", "Stop", "Stopped") -- Stop FSM. @@ -408,7 +409,6 @@ function OPSGROUP:New(Group) self:AddTransition("*", "Damaged", "*") -- Someone in the group took damage. self:AddTransition("*", "UpdateRoute", "*") -- Update route of group. Only if airborne. - self:AddTransition("*", "Respawn", "*") -- Respawn group. self:AddTransition("*", "PassingWaypoint", "*") -- Passing waypoint. self:AddTransition("*", "DetectedUnit", "*") -- Unit was detected (again) in this detection cycle. @@ -497,12 +497,34 @@ end --- Returns the absolute (average) life points of the group. -- @param #OPSGROUP self +-- @param #OPSGROUP.Element Element (Optional) Only get life points of this element. -- @return #number Life points. If group contains more than one element, the average is given. -- @return #number Initial life points. -function OPSGROUP:GetLifePoints() - if self.group then - return self.group:GetLife(), self.group:GetLife0() +function OPSGROUP:GetLifePoints(Element) + + local life=0 + local life0=0 + + if Element then + + local unit=Element.unit + + if unit then + life=unit:GetLife() + life0=unit:GetLife0() + end + + else + + for _,element in pairs(self.elements) do + local l,l0=self:GetLifePoints(element) + life=life+l + life0=life+l0 + end + end + + return life, life0 end @@ -3800,6 +3822,95 @@ function OPSGROUP:onafterElementDead(From, Event, To, Element) end +--- On after "Respawn" event. +-- @param #OPSGROUP self +-- @param #string From From state. +-- @param #string Event Event. +-- @param #string To To state. +-- @param #table Template The template used to respawn the group. +function OPSGROUP:onafterRespawn(From, Event, To, Template) + + self:I(self.lid.."Respawning group!") + + local template=UTILS.DeepCopy(Template or self.template) + + template.lateActivation=false + + self:_Respawn(template,Reset) + +end + +--- Respawn the group. +-- @param #OPSGROUP self +-- @param #table Template (optional) The template of the Group retrieved with GROUP:GetTemplate(). If the template is not provided, the template will be retrieved of the group itself. +-- @param #boolean Reset Reset positions if TRUE. +-- @return #OPSGROUP self +function OPSGROUP:_Respawn(Template, Reset) + + env.info("FF _Respawn") + + -- Given template or get old. + Template=Template or UTILS.DeepCopy(self.template) + + -- Get correct heading. + local function _Heading(course) + local h + if course<=180 then + h=math.rad(course) + else + h=-math.rad(360-course) + end + return h + end + + if self:IsAlive() then + + --- + -- Group is ALIVE + + -- Get units. + local units=self.group:GetUnits() + + -- Loop over template units. + for UnitID, Unit in pairs(Template.units) do + + for _,_unit in pairs(units) do + local unit=_unit --Wrapper.Unit#UNIT + + if unit:GetName()==Unit.name then + local vec3=unit:GetVec3() + local heading=unit:GetHeading() + Unit.x=vec3.x + Unit.y=vec3.z + Unit.alt=vec3.y + Unit.heading=math.rad(heading) + Unit.psi=-Unit.heading + end + end + + end + + -- Despawn old group. Dont trigger any remove unit event since this is a respawn. + self:Despawn(0, true) + + else + + end + + -- Currently respawning. + self.respawning=true + + self:I({Template=Template}) + + -- Spawn new group. + _DATABASE:Spawn(Template) + + -- Reset events. + --self:ResetEvents() + + return self +end + --- On before "Dead" event. -- @param #OPSGROUP self -- @param #string From From state.