From 96216494bbdc4a588530f7f4ac35a6f6d7a6b032 Mon Sep 17 00:00:00 2001 From: FlightControl_Master Date: Thu, 1 Mar 2018 11:48:24 +0100 Subject: [PATCH 1/3] Added Respawning to GROUP, first draft version. --- Moose Development/Moose/Core/Zone.lua | 20 ++- Moose Development/Moose/Wrapper/Group.lua | 162 +++++++++++++++------- 2 files changed, 127 insertions(+), 55 deletions(-) diff --git a/Moose Development/Moose/Core/Zone.lua b/Moose Development/Moose/Core/Zone.lua index 12fca41cc..4d5512147 100644 --- a/Moose Development/Moose/Core/Zone.lua +++ b/Moose Development/Moose/Core/Zone.lua @@ -861,13 +861,29 @@ end function ZONE_RADIUS:GetRandomPointVec2( inner, outer ) self:F( self.ZoneName, inner, outer ) - local PointVec2 = POINT_VEC2:NewFromVec2( self:GetRandomVec2() ) + local PointVec2 = POINT_VEC2:NewFromVec2( self:GetRandomVec2( inner, outer ) ) self:T3( { PointVec2 } ) return PointVec2 end +--- Returns Returns a random Vec3 location within the zone. +-- @param #ZONE_RADIUS self +-- @param #number inner (optional) Minimal distance from the center of the zone. Default is 0. +-- @param #number outer (optional) Maximal distance from the outer edge of the zone. Default is the radius of the zone. +-- @return Dcs.DCSTypes#Vec3 The random location within the zone. +function ZONE_RADIUS:GetRandomVec3( inner, outer ) + self:F( self.ZoneName, inner, outer ) + + local Vec2 = self:GetRandomVec2( inner, outer ) + + self:T3( { x = Vec2.x, y = self.y, z = Vec2.y } ) + + return { x = Vec2.x, y = self.y, z = Vec2.y } +end + + --- Returns a @{Point#POINT_VEC3} object reflecting a random 3D location within the zone. -- @param #ZONE_RADIUS self -- @param #number inner (optional) Minimal distance from the center of the zone. Default is 0. @@ -876,7 +892,7 @@ end function ZONE_RADIUS:GetRandomPointVec3( inner, outer ) self:F( self.ZoneName, inner, outer ) - local PointVec3 = POINT_VEC3:NewFromVec2( self:GetRandomVec2() ) + local PointVec3 = POINT_VEC3:NewFromVec2( self:GetRandomVec2( inner, outer ) ) self:T3( { PointVec3 } ) diff --git a/Moose Development/Moose/Wrapper/Group.lua b/Moose Development/Moose/Wrapper/Group.lua index 267326066..e4d70663a 100644 --- a/Moose Development/Moose/Wrapper/Group.lua +++ b/Moose Development/Moose/Wrapper/Group.lua @@ -917,59 +917,7 @@ function GROUP:GetMaxHeight() end --- SPAWNING - ---- Respawn the @{GROUP} using a (tweaked) template of the Group. --- The template must be retrieved with the @{Group#GROUP.GetTemplate}() function. --- The template contains all the definitions as declared within the mission file. --- To understand templates, do the following: --- --- * unpack your .miz file into a directory using 7-zip. --- * browse in the directory created to the file **mission**. --- * open the file and search for the country group definitions. --- --- Your group template will contain the fields as described within the mission file. --- --- This function will: --- --- * Get the current position and heading of the group. --- * When the group is alive, it will tweak the template x, y and heading coordinates of the group and the embedded units to the current units positions. --- * Then it will destroy the current alive group. --- * And it will respawn the group using your new template definition. --- @param Wrapper.Group#GROUP self --- @param #table Template The template of the Group retrieved with GROUP:GetTemplate() -function GROUP:Respawn( Template ) - - if self:IsAlive() then - local Vec3 = self:GetVec3() - Template.x = Vec3.x - Template.y = Vec3.z - --Template.x = nil - --Template.y = nil - - self:E( #Template.units ) - for UnitID, UnitData in pairs( self:GetUnits() ) do - local GroupUnit = UnitData -- Wrapper.Unit#UNIT - self:E( GroupUnit:GetName() ) - if GroupUnit:IsAlive() then - local GroupUnitVec3 = GroupUnit:GetVec3() - local GroupUnitHeading = GroupUnit:GetHeading() - Template.units[UnitID].alt = GroupUnitVec3.y - Template.units[UnitID].x = GroupUnitVec3.x - Template.units[UnitID].y = GroupUnitVec3.z - Template.units[UnitID].heading = GroupUnitHeading - self:E( { UnitID, Template.units[UnitID], Template.units[UnitID] } ) - end - end - - end - - self:Destroy() - _DATABASE:Spawn( Template ) - - self:ResetEvents() - -end +-- RESPAWNING --- Returns the group template from the @{DATABASE} (_DATABASE object). -- @param #GROUP self @@ -1017,6 +965,114 @@ function GROUP:SetTemplateCoalition( Template, CoalitionID ) end +--- Set the heading for the units in degrees within the respawned group. +-- @param #GROUP self +-- @param #number Heading The heading in meters. +-- @return #GROUP self +function GROUP:InitHeading( Heading ) + self.InitRespawnHeading = Heading + return self +end + + +--- Set the height for the units in meters for the respawned group. (This is applicable for air units). +-- @param #GROUP self +-- @param #number Height The height in meters. +-- @return #GROUP self +function GROUP:InitHeight( Height ) + self.InitRespawnHeight = Height + return self +end + + +--- Set the respawn @{Zone} for the respawned group. +-- @param #GROUP self +-- @param Core.Zone#ZONE Zone The zone in meters. +-- @return #GROUP self +function GROUP:InitZone( Zone ) + self.InitRespawnZone = Zone + return self +end + + +--- Randomize the unit positions for the units of the respawned group. +-- @param #GROUP self +-- @param #boolean Positions true will randomize the positions. +-- @return #GROUP self +function GROUP:InitRandomizePositions( Positions ) + self.InitRespawnRandomizePositions = Positions + return self +end + + +--- Respawn the @{Group} at a @{Point}. +-- The method will setup the new group template according the Init(Respawn) settings provided for the group. +-- These settings can be provided by calling the relevant Init...() methods of the Group. +-- +-- - @{#GROUP.InitHeading}: Set the heading for the units in degrees within the respawned group. +-- - @{#GROUP.InitHeight}: Set the height for the units in meters for the respawned group. (This is applicable for air units). +-- - @{#GROUP.InitRandomizeHeading}: Randomize the headings for the units within the respawned group. +-- - @{#GROUP.InitZone}: Set the respawn @{Zone} for the respawned group. +-- - @{#GROUP.InitRandomizeZones}: Randomize the respawn @{Zone} between one of the @{Zone}s given for the respawned group. +-- - @{#GROUP.InitRandomizePositions}: Randomize the unit positions for the units of the respawned group. +-- - @{#GROUP.InitRandomizeTemplates}: Randomize the Template for the respawned group. +-- +-- +-- Notes: +-- +-- - When InitZone or InitRandomizeZones is not used, the position of the respawned group will be its current position. +-- - The current alive group will always be destroyed and respawned using the template definition. +-- +-- @param Wrapper.Group#GROUP 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. +function GROUP:Respawn( Template ) + + if not Template then + Template = self:GetTemplate() + end + + if self:IsAlive() then + local Zone = self.InitRespawnZone -- Core.Zone#ZONE + local Vec3 = Zone and Zone:GetVec3() or self:GetVec3() + local From = { x = Template.x, y = Template.y } + Template.x = Vec3.x + Template.y = Vec3.z + --Template.x = nil + --Template.y = nil + + self:E( #Template.units ) + for UnitID, UnitData in pairs( self:GetUnits() ) do + local GroupUnit = UnitData -- Wrapper.Unit#UNIT + self:E( GroupUnit:GetName() ) + if GroupUnit:IsAlive() then + local GroupUnitVec3 = GroupUnit:GetVec3() + if Zone then + if self.InitRespawnRandomizePositions then + GroupUnitVec3 = Zone:GetRandomVec3() + else + GroupUnitVec3 = Zone:GetVec3() + end + end + + Template.units[UnitID].alt = self.InitRespawnHeight and self.InitRespawnHeight or GroupUnitVec3.y + Template.units[UnitID].x = ( Template.units[UnitID].x - From.x ) + GroupUnitVec3.x -- Keep the original x position of the template and translate to the new position. + Template.units[UnitID].y = ( Template.units[UnitID].y - From.y ) + GroupUnitVec3.z -- Keep the original z position of the template and translate to the new position. + Template.units[UnitID].heading = self.InitRespawnHeading and self.InitRespawnHeading or GroupUnit:GetHeading() + self:E( { UnitID, Template.units[UnitID], Template.units[UnitID] } ) + end + end + + end + + self:Destroy() + _DATABASE:Spawn( Template ) + + self:ResetEvents() + +end + + + --- Return the mission template of the group. From 2620927146eb0ef5d2fb9d21d178e89eb6444061 Mon Sep 17 00:00:00 2001 From: FlightControl_Master Date: Thu, 1 Mar 2018 17:42:50 +0100 Subject: [PATCH 2/3] Group Updates --- Moose Development/Moose/Wrapper/Group.lua | 30 +++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/Moose Development/Moose/Wrapper/Group.lua b/Moose Development/Moose/Wrapper/Group.lua index e4d70663a..3e8a3188a 100644 --- a/Moose Development/Moose/Wrapper/Group.lua +++ b/Moose Development/Moose/Wrapper/Group.lua @@ -996,11 +996,33 @@ end --- Randomize the unit positions for the units of the respawned group. +-- When a Respawn happens, the units of the group will be placed at random positions within the Zone (selected). -- @param #GROUP self --- @param #boolean Positions true will randomize the positions. +-- @param #boolean Positions true will randomize the positions within the Zone. -- @return #GROUP self function GROUP:InitRandomizePositions( Positions ) + self.InitRespawnRandomizePositions = Positions + self.InitRespawnRandomizePositionsInner = nil + self.InitRespawnRandomizePositionsOuter = nil + + return self +end + + +--- Randomize the unit positions for the units in a circle band. +-- When a Respawn happens, the units of the group will be positioned at random places within the Outer and Inner radius. +-- Thus, a band is created around the respawn location where the units will be placed at random positions. +-- @param #GROUP self +-- @param #boolean OuterRadius Outer band in meters from the center. +-- @param #boolean InnerRadius Inner band in meters from the center. +-- @return #GROUP self +function GROUP:InitRandomizePositionsRadius( OuterRadius, InnerRadius ) + + self.InitRespawnRandomizePositions = nil + self.InitRespawnRandomizePositionsInner = Inner + self.InitRespawnRandomizePositionsOuter = Outer + return self end @@ -1050,7 +1072,11 @@ function GROUP:Respawn( Template ) if self.InitRespawnRandomizePositions then GroupUnitVec3 = Zone:GetRandomVec3() else - GroupUnitVec3 = Zone:GetVec3() + if self.InitRespawnRandomizePositionsInner and self.InitRespawnRandomizePositionsOuter then + GroupUnitVec3 = POINT_VEC3:NewFromVec2( From ):GetRandomPointVec3InRadius( self.InitRespawnRandomizePositionsOuter, self.InitRespawnRandomizePositionsInner ) + else + GroupUnitVec3 = Zone:GetVec3() + end end end From 733b4940f8c13442905d5c47c0f65c0972367581 Mon Sep 17 00:00:00 2001 From: FlightControl_Master Date: Thu, 1 Mar 2018 20:41:26 +0100 Subject: [PATCH 3/3] Updated function names --- Moose Development/Moose/Wrapper/Group.lua | 70 ++++++++++++++++------- 1 file changed, 48 insertions(+), 22 deletions(-) diff --git a/Moose Development/Moose/Wrapper/Group.lua b/Moose Development/Moose/Wrapper/Group.lua index 3e8a3188a..2c3f8f271 100644 --- a/Moose Development/Moose/Wrapper/Group.lua +++ b/Moose Development/Moose/Wrapper/Group.lua @@ -995,33 +995,33 @@ function GROUP:InitZone( Zone ) end ---- Randomize the unit positions for the units of the respawned group. +--- Randomize the positions of the units of the respawned group within the @{Zone}. -- When a Respawn happens, the units of the group will be placed at random positions within the Zone (selected). -- @param #GROUP self --- @param #boolean Positions true will randomize the positions within the Zone. +-- @param #boolean PositionZone true will randomize the positions within the Zone. -- @return #GROUP self -function GROUP:InitRandomizePositions( Positions ) +function GROUP:InitRandomizePositionZone( PositionZone ) - self.InitRespawnRandomizePositions = Positions - self.InitRespawnRandomizePositionsInner = nil - self.InitRespawnRandomizePositionsOuter = nil + self.InitRespawnRandomizePositionZone = PositionZone + self.InitRespawnRandomizePositionInner = nil + self.InitRespawnRandomizePositionOuter = nil return self end ---- Randomize the unit positions for the units in a circle band. +--- Randomize the positions of the units of the respawned group in a circle band. -- When a Respawn happens, the units of the group will be positioned at random places within the Outer and Inner radius. -- Thus, a band is created around the respawn location where the units will be placed at random positions. -- @param #GROUP self -- @param #boolean OuterRadius Outer band in meters from the center. -- @param #boolean InnerRadius Inner band in meters from the center. -- @return #GROUP self -function GROUP:InitRandomizePositionsRadius( OuterRadius, InnerRadius ) +function GROUP:InitRandomizePositionRadius( OuterRadius, InnerRadius ) - self.InitRespawnRandomizePositions = nil - self.InitRespawnRandomizePositionsInner = Inner - self.InitRespawnRandomizePositionsOuter = Outer + self.InitRespawnRandomizePositionZone = nil + self.InitRespawnRandomizePositionOuter = OuterRadius + self.InitRespawnRandomizePositionInner = InnerRadius return self end @@ -1036,7 +1036,8 @@ end -- - @{#GROUP.InitRandomizeHeading}: Randomize the headings for the units within the respawned group. -- - @{#GROUP.InitZone}: Set the respawn @{Zone} for the respawned group. -- - @{#GROUP.InitRandomizeZones}: Randomize the respawn @{Zone} between one of the @{Zone}s given for the respawned group. --- - @{#GROUP.InitRandomizePositions}: Randomize the unit positions for the units of the respawned group. +-- - @{#GROUP.InitRandomizePositionZone}: Randomize the positions of the units of the respawned group within the @{Zone}. +-- - @{#GROUP.InitRandomizePositionRadius}: Randomize the positions of the units of the respawned group in a circle band. -- - @{#GROUP.InitRandomizeTemplates}: Randomize the Template for the respawned group. -- -- @@ -1047,7 +1048,7 @@ end -- -- @param Wrapper.Group#GROUP 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. -function GROUP:Respawn( Template ) +function GROUP:Respawn( Template, Reset ) if not Template then Template = self:GetTemplate() @@ -1063,16 +1064,41 @@ function GROUP:Respawn( Template ) --Template.y = nil self:E( #Template.units ) - for UnitID, UnitData in pairs( self:GetUnits() ) do - local GroupUnit = UnitData -- Wrapper.Unit#UNIT - self:E( GroupUnit:GetName() ) - if GroupUnit:IsAlive() then - local GroupUnitVec3 = GroupUnit:GetVec3() + if Reset == true then + for UnitID, UnitData in pairs( self:GetUnits() ) do + local GroupUnit = UnitData -- Wrapper.Unit#UNIT + self:E( GroupUnit:GetName() ) + if GroupUnit:IsAlive() then + self:E( "Alive" ) + local GroupUnitVec3 = GroupUnit:GetVec3() + if Zone then + if self.InitRespawnRandomizePositionZone then + GroupUnitVec3 = Zone:GetRandomVec3() + else + if self.InitRespawnRandomizePositionInner and self.InitRespawnRandomizePositionOuter then + GroupUnitVec3 = POINT_VEC3:NewFromVec2( From ):GetRandomPointVec3InRadius( self.InitRespawnRandomizePositionsOuter, self.InitRespawnRandomizePositionsInner ) + else + GroupUnitVec3 = Zone:GetVec3() + end + end + end + + Template.units[UnitID].alt = self.InitRespawnHeight and self.InitRespawnHeight or GroupUnitVec3.y + Template.units[UnitID].x = ( Template.units[UnitID].x - From.x ) + GroupUnitVec3.x -- Keep the original x position of the template and translate to the new position. + Template.units[UnitID].y = ( Template.units[UnitID].y - From.y ) + GroupUnitVec3.z -- Keep the original z position of the template and translate to the new position. + Template.units[UnitID].heading = self.InitRespawnHeading and self.InitRespawnHeading or GroupUnit:GetHeading() + self:E( { UnitID, Template.units[UnitID], Template.units[UnitID] } ) + end + end + else + for UnitID, TemplateUnitData in pairs( Template.units ) do + self:E( "Reset" ) + local GroupUnitVec3 = { x = TemplateUnitData.x, y = TemplateUnitData.alt, z = TemplateUnitData.z } if Zone then - if self.InitRespawnRandomizePositions then + if self.InitRespawnRandomizePositionZone then GroupUnitVec3 = Zone:GetRandomVec3() else - if self.InitRespawnRandomizePositionsInner and self.InitRespawnRandomizePositionsOuter then + if self.InitRespawnRandomizePositionInner and self.InitRespawnRandomizePositionOuter then GroupUnitVec3 = POINT_VEC3:NewFromVec2( From ):GetRandomPointVec3InRadius( self.InitRespawnRandomizePositionsOuter, self.InitRespawnRandomizePositionsInner ) else GroupUnitVec3 = Zone:GetVec3() @@ -1083,10 +1109,10 @@ function GROUP:Respawn( Template ) Template.units[UnitID].alt = self.InitRespawnHeight and self.InitRespawnHeight or GroupUnitVec3.y Template.units[UnitID].x = ( Template.units[UnitID].x - From.x ) + GroupUnitVec3.x -- Keep the original x position of the template and translate to the new position. Template.units[UnitID].y = ( Template.units[UnitID].y - From.y ) + GroupUnitVec3.z -- Keep the original z position of the template and translate to the new position. - Template.units[UnitID].heading = self.InitRespawnHeading and self.InitRespawnHeading or GroupUnit:GetHeading() + Template.units[UnitID].heading = self.InitRespawnHeading and self.InitRespawnHeading or TemplateUnitData.heading self:E( { UnitID, Template.units[UnitID], Template.units[UnitID] } ) end - end + end end