From 6c9c4432cc09c37b2c0087bb9027b97c01c191e8 Mon Sep 17 00:00:00 2001 From: funkyfranky Date: Wed, 13 Jun 2018 00:12:26 +0200 Subject: [PATCH 1/4] ARTY v1.0.3 Added "set" mark commands for rearming place and rearming group. --- .../Moose/Functional/Artillery.lua | 106 +++++++++++++----- 1 file changed, 77 insertions(+), 29 deletions(-) diff --git a/Moose Development/Moose/Functional/Artillery.lua b/Moose Development/Moose/Functional/Artillery.lua index fa5d346d9..79fbbdabd 100644 --- a/Moose Development/Moose/Functional/Artillery.lua +++ b/Moose Development/Moose/Functional/Artillery.lua @@ -1980,6 +1980,14 @@ function ARTY:_OnEventMarkChange(Event) -- Check if marker has a text and the "arty" keyword. if Event.text~=nil and Event.text:lower():find("arty") then + + -- Convert (wrong x-->z, z-->x) vec3 + -- TODO: This needs to be "fixed", once DCS gives the correct numbers for x and z. + -- local vec3={y=Event.pos.y, x=Event.pos.x, z=Event.pos.z} + local vec3={y=Event.pos.y, x=Event.pos.z, z=Event.pos.x} + + -- Get coordinate from vec3. + local _coord=COORDINATE:NewFromVec3(vec3) -- Get battery coalition and name. local batterycoalition=self.Controllable:GetCoalition() @@ -1992,8 +2000,8 @@ function ARTY:_OnEventMarkChange(Event) local _assign=self:_Markertext(Event.text) -- Check if ENGAGE or MOVE or REQUEST keywords were found. - if _assign==nil or not (_assign.engage or _assign.move or _assign.request or _assign.cancel) then - self:T(ARTY.id..string.format("WARNING: %s, no keyword ENGAGE, MOVE, REQUEST or CANCEL in mark text! Command will not be executed. Text:\n%s", self.groupname, Event.text)) + if _assign==nil or not (_assign.engage or _assign.move or _assign.request or _assign.cancel or _assign.set) then + self:T(ARTY.id..string.format("WARNING: %s, no keyword ENGAGE, MOVE, REQUEST, CANCEL or SET in mark text! Command will not be executed. Text:\n%s", self.groupname, Event.text)) return end @@ -2001,9 +2009,11 @@ function ARTY:_OnEventMarkChange(Event) local _assigned=false -- If any array is filled something has been assigned. - if _assign.everyone then + if _assign.everyone then + -- Everyone was addressed. _assigned=true + else --#_assign.battery>0 or #_assign.aliases>0 or #_assign.cluster>0 then -- Loop over batteries. @@ -2036,7 +2046,12 @@ function ARTY:_OnEventMarkChange(Event) self:T3(ARTY.id..string.format("INFO: ARTY group %s was not addressed! Mark text:\n%s", self.groupname, Event.text)) return end - + + -- Coordinate was given in text, e.g. as lat, long. + if _assign.coord then + _coord=_assign.coord + end + -- Check if the authorization key is required and if it is valid. local _validkey=self:_MarkerKeyAuthentification(Event.text) @@ -2061,7 +2076,7 @@ function ARTY:_OnEventMarkChange(Event) return end - -- Cancel current target and return. + -- Cancel stuff and return. if _assign.cancel and _validkey then if _assign.cancelmove and self.currentMove then self.Controllable:ClearTasks() @@ -2080,27 +2095,37 @@ function ARTY:_OnEventMarkChange(Event) -- Cancels Done ==> End of story! return end + + -- Set stuff and return. + if _assign.set and _validkey then + if _assign.setrearmingplace then + self:SetRearmingPlace(_coord) + _coord:RemoveMark(Event.idx) + _coord:MarkToCoalition(string.format("Rearming place for battery %s", self.groupname), self.Controllable:GetCoalition(), false, string.format("New rearming place for battery %s defined.", self.groupname)) + if self.Debug then + _coord:SmokeOrange() + end + end + if _assign.setrearminggroup then + _coord:RemoveMark(Event.idx) + local rearminggroupcoord=_assign.setrearminggroup:GetCoordinate() + rearminggroupcoord:MarkToCoalition(string.format("Rearming group for battery %s", self.groupname), self.Controllable:GetCoalition(), false, string.format("New rearming group for battery %s defined.", self.groupname)) + self:SetRearmingGroup(_assign.setrearminggroup) + if self.Debug then + rearminggroupcoord:SmokeOrange() + end + end + -- Set stuff Done ==> End of story! + return + end -- Handle engagements and relocations. if _validkey then - - -- Convert (wrong x-->z, z-->x) vec3 - -- TODO: This needs to be "fixed", once DCS gives the correct numbers for x and z. - -- local vec3={y=Event.pos.y, x=Event.pos.x, z=Event.pos.z} - local vec3={y=Event.pos.y, x=Event.pos.z, z=Event.pos.x} - - -- Get coordinate from vec3. - local _coord=COORDINATE:NewFromVec3(vec3) -- Remove old mark because it might contain confidential data such as the key. -- Also I don't know who can see the mark which was created. _coord:RemoveMark(Event.idx) - -- Coordinate was given in text, e.g. as lat, long. - if _assign.coord then - _coord=_assign.coord - end - -- Anticipate marker ID. -- WARNING: Make sure, no marks are set until the COORDINATE:MarkToCoalition() is called or the target/move name will be wrong and target cannot be removed by deleting its marker. local _id=UTILS._MarkID+1 @@ -3486,11 +3511,14 @@ function ARTY:_Markertext(text) assignment.engage=false assignment.request=false assignment.cancel=false + assignment.set=false assignment.readonly=false assignment.movecanceltarget=false assignment.cancelmove=false assignment.canceltarget=false assignment.cancelrearm=false + assignment.setrearmingplace=false + assignment.setrearminggroup=false -- Check for correct keywords. if text:lower():find("arty engage") or text:lower():find("arty attack") then @@ -3500,9 +3528,11 @@ function ARTY:_Markertext(text) elseif text:lower():find("arty request") then assignment.request=true elseif text:lower():find("arty cancel") then - assignment.cancel=true + assignment.cancel=true + elseif text:lower():find("arty set") then + assignment.set=true else - self:E(ARTY.id..'ERROR: Neither "ARTY ENGAGE" nor "ARTY MOVE" nor "ARTY RELOCATE" nor "ARTY REQUEST" nor "ARTY CANCEL" keyword specified!') + self:E(ARTY.id..'ERROR: Neither "ARTY ENGAGE" nor "ARTY MOVE" nor "ARTY RELOCATE" nor "ARTY REQUEST" nor "ARTY CANCEL" nor "ARTY SET" keyword specified!') return nil end @@ -3551,8 +3581,13 @@ function ARTY:_Markertext(text) elseif keyphrase:lower():find("everyone") or keyphrase:lower():find("all batteries") or keyphrase:lower():find("allbatteries") then assignment.everyone=true - self:T(ARTY.id..string.format("Key Everyone=true.")) - + self:T(ARTY.id..string.format("Key Everyone=true.")) + + elseif keyphrase:lower():find("irrevocable") or keyphrase:lower():find("readonly") then + + assignment.readonly=true + self:T2(ARTY.id..string.format("Key Readonly=true.")) + elseif (assignment.engage or assignment.move) and key:lower():find("time") then if val:lower():find("now") then @@ -3597,21 +3632,16 @@ function ARTY:_Markertext(text) end self:T2(ARTY.id..string.format("Key Weapon=%s.", val)) - elseif assignment.move and key:lower():find("speed") then + elseif (assignment.move or assignment.set) and key:lower():find("speed") then assignment.speed=tonumber(val) self:T2(ARTY.id..string.format("Key Speed=%s.", val)) - elseif assignment.move and (keyphrase:lower():find("on road") or keyphrase:lower():find("onroad") or keyphrase:lower():find("use road")) then + elseif (assignment.move or assignment.set) and (keyphrase:lower():find("on road") or keyphrase:lower():find("onroad") or keyphrase:lower():find("use road")) then assignment.onroad=true self:T2(ARTY.id..string.format("Key Onroad=true.")) - elseif keyphrase:lower():find("irrevocable") or keyphrase:lower():find("readonly") then - - assignment.readonly=true - self:T2(ARTY.id..string.format("Key Readonly=true.")) - elseif assignment.move and (keyphrase:lower():find("cancel target") or keyphrase:lower():find("canceltarget")) then assignment.movecanceltarget=true @@ -3656,6 +3686,24 @@ function ARTY:_Markertext(text) assignment.cancelrearm=true self:T2(ARTY.id..string.format("Key Cancel Rearm=true.")) + + elseif assignment.set and keyphrase:lower():find("rearming place") then + + assignment.setrearmingplace=true + self:T(ARTY.id..string.format("Key Set Rearming Place=true.")) + + elseif assignment.set and keyphrase:lower():find("rearming group") then + + local v=self:_split(keyphrase, '"') + local groupname=v[2] + env.info("FF v2 groupname = "..tostring(v[2])) + + local group=GROUP:FindByName(groupname) + if group and group:IsAlive() then + assignment.setrearminggroup=group + end + + self:T2(ARTY.id..string.format("Key Set Rearming Group = %s.", tostring(groupname))) elseif key:lower():find("lldms") then From 851c55e9854af7f09680392724bd723b8351fe1c Mon Sep 17 00:00:00 2001 From: funkyfranky Date: Wed, 13 Jun 2018 23:00:05 +0200 Subject: [PATCH 2/4] ARTY v1.0.3 buggy something wrong with nuke, illu smoke --- Moose Development/Moose/Core/Point.lua | 5 +- .../Moose/Functional/Artillery.lua | 192 ++++++++++++++++-- 2 files changed, 180 insertions(+), 17 deletions(-) diff --git a/Moose Development/Moose/Core/Point.lua b/Moose Development/Moose/Core/Point.lua index b7688ad82..35eb6566d 100644 --- a/Moose Development/Moose/Core/Point.lua +++ b/Moose Development/Moose/Core/Point.lua @@ -998,9 +998,10 @@ do -- COORDINATE --- Creates an illumination bomb at the point. -- @param #COORDINATE self - function COORDINATE:IlluminationBomb() + -- @param #number power + function COORDINATE:IlluminationBomb(power) self:F2() - trigger.action.illuminationBomb( self:GetVec3() ) + trigger.action.illuminationBomb( self:GetVec3(), power ) end diff --git a/Moose Development/Moose/Functional/Artillery.lua b/Moose Development/Moose/Functional/Artillery.lua index 79fbbdabd..a8f8758a0 100644 --- a/Moose Development/Moose/Functional/Artillery.lua +++ b/Moose Development/Moose/Functional/Artillery.lua @@ -55,6 +55,8 @@ -- @field #number Nrockets0 Initial amount of rockets of the whole group. -- @field #number Nmissiles0 Initial amount of missiles of the whole group. -- @field #number Nukes0 Initial amount of tactical nukes of the whole group. Default is 0. +-- @field #number Nillu0 Initial amount of illumination shells of the whole group. Default is 0. +-- @field #number Nsmoke0 Initial amount of smoke shells of the whole group. Default is 0. -- @field #number StatusInterval Update interval in seconds between status updates. Default 10 seconds. -- @field #number WaitForShotTime Max time in seconds to wait until fist shot event occurs after target is assigned. If time is passed without shot, the target is deleted. Default is 300 seconds. -- @field #table DCSdesc DCS descriptors of the ARTY group. @@ -84,7 +86,9 @@ -- @field #number minrange Minimum firing range in kilometers. Targets closer than this distance are not engaged. Default 0.1 km. -- @field #number maxrange Maximum firing range in kilometers. Targets further away than this distance are not engaged. Default 10000 km. -- @field #number nukewarhead Explosion strength of tactical nuclear warhead in kg TNT. Default 75000. --- @field #number Nukes Number of nuclear shells, the group has available. Default is same number as normal shells. Note that if normal shells are empty, firing nukes is also not possible any more. +-- @field #number Nukes Number of nuclear shells, the group has available. Note that if normal shells are empty, firing nukes is also not possible any more. +-- @field #number Nillu Number of illumination shells the group has available. Note that if normal shells are empty, firing illumination shells is also not possible any more. +-- @filed #number Nsmoke Number of smoke shells the group has available. Note that if normal shells are empty, firing smoke shells is also not possible any more. -- @field #number nukerange Demolition range of tactical nuclear explostions. -- @field #boolean nukefire Ignite additional fires and smoke for nuclear explosions Default true. -- @field #number nukefires Number of nuclear fires and subexplosions. @@ -226,6 +230,8 @@ -- * @{#ARTY.WeaponType}.Rockets: Only unguided are used during the attack. Corresponding ammo type are rockets/nurs and can be defined by @{#ARTY.SetRocketTypes}. -- * @{#ARTY.WeaponType}.CruiseMissile: Only cruise missiles are used during the attack. Corresponding ammo type are missiles and can be defined by @{#ARTY.SetMissileTypes}. -- * @{#ARTY.WeaponType}.TacticalNukes: Use tactical nuclear shells. This works only with units that have shells and is described below. +-- * @{#ARTY.WeaponType}.IlluminationShells: Use illumination shells. This works only with units that have shells and is described below. +-- * @{#ARTY.WeaponType}.SmokeShells: Use smoke shells. This works only with units that have shells and is described below. -- -- ## Assigning Moves -- The ARTY group can be commanded to move. This is done by the @{#ARTY.AssignMoveCoord}(*coord*,*time*,*speed*,*onroad*,*cancel*,*name*) function. @@ -471,6 +477,8 @@ ARTY={ Nrockets0=0, Nmissiles0=0, Nukes0=0, + Nillu0=0, + Nsmoke0=0, StatusInterval=10, WaitForShotTime=300, DCSdesc=nil, @@ -499,6 +507,8 @@ ARTY={ maxrange=1000000, nukewarhead=75000, Nukes=nil, + Nillu=nil, + Nsmoke=nil, nukefire=false, nukefires=nil, nukerange=nil, @@ -519,11 +529,10 @@ ARTY.WeaponType={ Auto=1073741822, Cannon=805306368, Rockets=30720, - --UnguidedAny=805339120, - --GuidedMissile=268402688, CruiseMissile=2097152, - --AntiShipMissile=65536, TacticalNukes=666, + IlluminationShells=667, + SmokeShells=668, } --- Database of common artillery unit properties. @@ -1440,6 +1449,22 @@ function ARTY:SetTacNukeWarhead(strength) self.nukewarhead=self.nukewarhead*1000*1000 -- convert to kg TNT. end +--- Set number of illumination shells available to the group. +-- Note that it can be max the number of normal shells. Also if all normal shells are empty, firing illumination shells is also not possible any more until group gets rearmed. +-- @param #ARTY self +-- @param #number n Number of warheads for the whole group. +function ARTY:SetIlluminationShells(n) + self.Nillu=n +end + +--- Set number of smoke shells available to the group. +-- Note that it can be max the number of normal shells. Also if all normal shells are empty, firing smoke shells is also not possible any more until group gets rearmed. +-- @param #ARTY self +-- @param #number n Number of warheads for the whole group. +function ARTY:SetSmokeShells(n) + self.Nsmoke=n +end + --- Set nuclear fires and extra demolition explosions. -- @param #ARTY self -- @param #number nfires (Optional) Number of big smoke and fire objects created in the demolition zone. @@ -1497,6 +1522,8 @@ function ARTY:onafterStart(Controllable, From, Event, To) if self.nukefires==nil then self.nukefires=20/1000/1000*self.nukerange*self.nukerange end + + -- Init nuclear shells. if self.Nukes~=nil then self.Nukes0=math.min(self.Nukes, self.Nshells0) else @@ -1504,6 +1531,22 @@ function ARTY:onafterStart(Controllable, From, Event, To) self.Nukes0=0 end + -- Init illumination shells. + if self.Nillu~=nil then + self.Nillu0=math.min(self.Nillu, self.Nshells0) + else + self.Nillu=0 + self.Nillu0=0 + end + + -- Init smoke shells. + if self.Nsmoke~=nil then + self.Nsmoke0=math.min(self.Nsmoke, self.Nshells0) + else + self.Nsmoke=0 + self.Nsmoke0=0 + end + -- Check if we have and arty type that is in the DB. local _dbproperties=self:_CheckDB(self.DisplayName) self:T({dbproperties=_dbproperties}) @@ -1561,6 +1604,8 @@ function ARTY:onafterStart(Controllable, From, Event, To) text=text..string.format("Nuclear warhead = %d tons TNT\n", self.nukewarhead/1000) text=text..string.format("Nuclear demolition = %d m\n", self.nukerange) text=text..string.format("Nuclear fires = %d (active=%s)\n", self.nukefires, tostring(self.nukefire)) + text=text..string.format("Number of illum. = %d\n", self.Nillu0) + text=text..string.format("Number of smoke = %d\n", self.Nsmoke0) if self.RearmingGroup or self.RearmingPlaceCoord then text=text..string.format("Rearming safe dist. = %d m\n", self.RearmingDistance) end @@ -1668,6 +1713,8 @@ function ARTY:_StatusReport(display) -- Get Ammo. local Nammo, Nshells, Nrockets, Nmissiles=self:GetAmmo() local Nnukes=self.Nukes + local Nillu=self.Nillu + local Nsmoke=self.Nsmoke local Tnow=timer.getTime() local Clock=self:_SecondsToClock(timer.getAbsTime()) @@ -1681,6 +1728,8 @@ function ARTY:_StatusReport(display) text=text..string.format("Number of rockets = %d\n", Nrockets) text=text..string.format("Number of missiles = %d\n", Nmissiles) text=text..string.format("Number of nukes = %d\n", Nnukes) + text=text..string.format("Number of illum. = %d\n", Nillu) + text=text..string.format("Number of smoke = %d\n", Nsmoke) if self.currentTarget then text=text..string.format("Current Target = %s\n", tostring(self.currentTarget.name)) text=text..string.format("Curr. Tgt assigned = %d\n", Tnow-self.currentTarget.Tassigned) @@ -1747,10 +1796,16 @@ function ARTY:_OnEventShot(EventData) -- Last known position of the weapon fired. local _lastpos={x=0, y=0, z=0} - --- Track the position of the weapon if it is supposed to model a tac nuke. + --- Track the position of the weapon if it is supposed to model a tac nuke, illumination or smoke shell. -- @param #table _weapon local function _TrackWeapon(_weapon) + -- Coordinate of the target + local _targetcoord=self.currentTarget.coord -- Core.Point#COORDINATE + self.illuMinalt=400 + self.illuMaxalt=1000 + self.illuPower=1000 + -- When the pcall status returns false the weapon has hit. local _status,_currpos = pcall( function() @@ -1758,31 +1813,94 @@ function ARTY:_OnEventShot(EventData) end) self:T(ARTY.id..string.format("ARTY %s: Weapon still in air: %s", self.groupname, tostring(_status))) + local _destroyweapon=false if _status then -- Update last position. _lastpos={x=_currpos.x, y=_currpos.y, z=_currpos.z} +--[[ + -- Coordinate and distance to target. + local _coord=COORDINATE:NewFromVec3(_lastpos) + local _dist=_coord:Get2DDistance(self.currentTarget.coord) - -- Check again in 0.05 seconds. - --return timer.getTime() + self.dtBombtrack + env.info("FF dist = ".._dist) + + if self.currentTarget.weapontype==ARTY.WeaponType.IlluminationShells then + + -- Check if within distace. + if _dist0 then - self:T(ARTY.id..string.format("ARTY %s: Tracking of weapon starts in two seconds.", self.groupname)) - timer.scheduleFunction(_TrackWeapon, EventData.weapon, timer.getTime() + 2.0) + local _tracknuke = self.currentTarget.weapontype==ARTY.WeaponType.TacticalNukes and self.Nukes>0 + local _trackillu = self.currentTarget.weapontype==ARTY.WeaponType.IlluminationShells and self.Nillu>0 + local _tracksmoke = self.currentTarget.weapontype==ARTY.WeaponType.SmokeShells and self.Nsmoke>0 + if _tracknuke or _trackillu or _tracksmoke then + self:T(ARTY.id..string.format("ARTY %s: Tracking of weapon starts in one second.", self.groupname)) + timer.scheduleFunction(_TrackWeapon, EventData.weapon, timer.getTime() + 1.0) end -- Get current ammo. @@ -1792,6 +1910,16 @@ function ARTY:_OnEventShot(EventData) if self.currentTarget.weapontype==ARTY.WeaponType.TacticalNukes then self.Nukes=self.Nukes-1 end + + -- Decrease available illuminatin shells because we just fired one. + if self.currentTarget.weapontype==ARTY.WeaponType.IlluminationShells then + self.Nillu=self.Nillu-1 + end + + -- Decrease available illuminatin shells because we just fired one. + if self.currentTarget.weapontype==ARTY.WeaponType.SmokeShells then + self.Nsmoke=self.Nsmoke-1 + end -- Check if we are completely out of ammo. local _outofammo=false @@ -2463,6 +2591,12 @@ function ARTY:onafterOpenFire(Controllable, From, Event, To, target) elseif target.weapontype==ARTY.WeaponType.TacticalNukes then nfire=self.Nukes _type="nuclear shells" + elseif target.weapontype==ARTY.WeaponType.IlluminationShells then + nfire=self.Nillu + _type="illumination shells" + elseif target.weapontype==ARTY.WeaponType.SmokeShells then + nfire=self.Nsmoke + _type="smoke shells" elseif target.weapontype==ARTY.WeaponType.Rockets then nfire=Nrockets _type="rockets" @@ -2704,6 +2838,8 @@ function ARTY:onafterRearmed(Controllable, From, Event, To) -- "Rearm" tactical nukes as well. self.Nukes=self.Nukes0 + self.Nillu=self.Nillu0 + self.Nsmoke=self.Nsmoke0 -- Route ARTY group back to where it came from (if distance is > 100 m). local dist=self.Controllable:GetCoordinate():Get2DDistance(self.InitialCoord) @@ -2960,7 +3096,7 @@ function ARTY:_FireAtCoord(coord, radius, nshells, weapontype) local group=self.Controllable --Wrapper.Group#GROUP -- Tactical nukes are actually cannon shells. - if weapontype==ARTY.WeaponType.TacticalNukes then + if weapontype==ARTY.WeaponType.TacticalNukes or weapontype==ARTY.WeaponType.IlluminationShells or weapontype==ARTY.WeaponType.SmokeShells then weapontype=ARTY.WeaponType.Cannon end @@ -3627,6 +3763,10 @@ function ARTY:_Markertext(text) assignment.weapontype=ARTY.WeaponType.CruiseMissile elseif val:lower():find("nuke") then assignment.weapontype=ARTY.WeaponType.TacticalNukes + elseif val:lower():find("illu") then + assignment.weapontype=ARTY.WeaponType.IlluminationShells + elseif val:lower():find("smoke") then + assignment.weapontype=ARTY.WeaponType.SmokeShells else assignment.weapontype=ARTY.WeaponType.Auto end @@ -4223,6 +4363,16 @@ function ARTY:_CheckOutOfAmmo(targets) self:T(ARTY.id..string.format("Group %s, tactical nukes requested for target %s but nukes empty.", self.groupname, Target.name)) _partlyoutofammo=true + + elseif Target.weapontype==ARTY.WeaponType.IlluminationShells and self.Nillu<=0 then + + self:T(ARTY.id..string.format("Group %s, illumination shells requested for target %s but illumination shells empty.", self.groupname, Target.name)) + _partlyoutofammo=true + + elseif Target.weapontype==ARTY.WeaponType.SmokeShells and self.Nsmoke<=0 then + + self:T(ARTY.id..string.format("Group %s, smoke shells requested for target %s but smoke shells empty.", self.groupname, Target.name)) + _partlyoutofammo=true elseif Target.weapontype==ARTY.WeaponType.Rockets and _nrockets==0 then @@ -4258,6 +4408,10 @@ function ARTY:_CheckWeaponTypeAvailable(target) nfire=Nshells elseif target.weapontype==ARTY.WeaponType.TacticalNukes then nfire=self.Nukes + elseif target.weapontype==ARTY.WeaponType.IlluminationShells then + nfire=self.Nillu + elseif target.weapontype==ARTY.WeaponType.SmokeShells then + nfire=self.Nsmoke elseif target.weapontype==ARTY.WeaponType.Rockets then nfire=Nrockets elseif target.weapontype==ARTY.WeaponType.CruiseMissile then @@ -4280,6 +4434,10 @@ function ARTY:_CheckWeaponTypePossible(target) possible=self.Nshells0>0 elseif target.weapontype==ARTY.WeaponType.TacticalNukes then possible=self.Nukes0>0 + elseif target.weapontype==ARTY.WeaponType.IlluminationShells then + possible=self.Nillus0>0 + elseif target.weapontype==ARTY.WeaponType.SmokeShells then + possible=self.Nsmoke0>0 elseif target.weapontype==ARTY.WeaponType.Rockets then possible=self.Nrockets0>0 elseif target.weapontype==ARTY.WeaponType.CruiseMissile then @@ -4420,7 +4578,11 @@ function ARTY:_WeaponTypeName(tnumber) elseif tnumber==ARTY.WeaponType.CruiseMissile then name="Cruise Missiles" elseif tnumber==ARTY.WeaponType.TacticalNukes then - name="Tactical Nukes" + name="Tactical Nukes" + elseif tnumber==ARTY.WeaponType.IlluminationShells then + name="Illumination Shells" + elseif tnumber==ARTY.WeaponType.SmokeShells then + name="Smoke Shells" end return name end From ca2eec88780a9da7cb538f25fb426efaf52a13f4 Mon Sep 17 00:00:00 2001 From: funkyfranky Date: Fri, 15 Jun 2018 00:07:35 +0200 Subject: [PATCH 3/4] ARTY v1.0.3 Fixed bug in illu and smoke shell impementation. --- .../Moose/Functional/Artillery.lua | 147 +++++++++++------- 1 file changed, 92 insertions(+), 55 deletions(-) diff --git a/Moose Development/Moose/Functional/Artillery.lua b/Moose Development/Moose/Functional/Artillery.lua index a8f8758a0..c3e03b6f7 100644 --- a/Moose Development/Moose/Functional/Artillery.lua +++ b/Moose Development/Moose/Functional/Artillery.lua @@ -88,7 +88,11 @@ -- @field #number nukewarhead Explosion strength of tactical nuclear warhead in kg TNT. Default 75000. -- @field #number Nukes Number of nuclear shells, the group has available. Note that if normal shells are empty, firing nukes is also not possible any more. -- @field #number Nillu Number of illumination shells the group has available. Note that if normal shells are empty, firing illumination shells is also not possible any more. --- @filed #number Nsmoke Number of smoke shells the group has available. Note that if normal shells are empty, firing smoke shells is also not possible any more. +-- @field #number illuPower Power of illumination warhead in mega candela. Default 1 mcd. +-- @field #number illuMinalt Minimum altitude in meters the illumination warhead will detonate. +-- @field #number illuMaxalt Maximum altitude in meters the illumination warhead will detonate. +-- @field #number Nsmoke Number of smoke shells the group has available. Note that if normal shells are empty, firing smoke shells is also not possible any more. +-- @field Utilities.Utils#SMOKECOLOR Smoke color of smoke shells. Default SMOKECOLOR.red. -- @field #number nukerange Demolition range of tactical nuclear explostions. -- @field #boolean nukefire Ignite additional fires and smoke for nuclear explosions Default true. -- @field #number nukefires Number of nuclear fires and subexplosions. @@ -320,11 +324,11 @@ -- arty engage, cluster "All Mortas" -- arty engage, cluster "Northern Batteries" "Southern Batteries" -- arty engage, cluster "Northern Batteries", cluster "Southern Batteries" --- arty engage, shots 20, prio 10, time 08:15, weapon cannons +-- arty engage, cluster "Horwitzers", shots 20, prio 10, time 08:15, weapon cannons -- arty engage, battery "Blue Paladin 1" "Blue MRLS 1", shots 10, time 10:15 -- arty engage, battery "Blue MRLS 1", key 666 -- arty engage, battery "Paladin Alpha", weapon nukes, shots 1, time 20:15 --- arty engage, lldms 41:51:00N 41:47:58E +-- arty engage, battery "Horwitzer 1", lldms 41:51:00N 41:47:58E -- -- Note that the keywords and parameters are *case insensitve*. Only exception are the battery, alias and cluster names. -- These must be exactly the same as the names of the goups defined in the mission editor or the aliases and cluster names defined in the script. @@ -376,7 +380,7 @@ -- -- For example -- arty cancel, target, battery "Paladin Bravo" --- arty cancel, move +-- arty cancel, everyone, move -- arty cancel, rearming, battery "MRLS Charly" -- -- @@ -507,11 +511,15 @@ ARTY={ maxrange=1000000, nukewarhead=75000, Nukes=nil, - Nillu=nil, - Nsmoke=nil, nukefire=false, nukefires=nil, nukerange=nil, + Nillu=nil, + illuPower=1000000, + illuMinalt=500, + illuMaxalt=1500, + Nsmoke=nil, + smokeColor=SMOKECOLOR.Red, relocateafterfire=false, relocateRmin=300, relocateRmax=800, @@ -626,10 +634,10 @@ ARTY.version="1.0.2" -- DONE: Improve handling of special weapons. When winchester if using selected weapons? -- TODO: Handle rearming for ships. How? -- DONE: Make coordinate after rearming general, i.e. also work after the group has moved to anonther location. --- TODO: Add set commands via markers. E.g. set rearming place. +-- DONE: Add set commands via markers. E.g. set rearming place. -- DONE: Test stationary types like mortas ==> rearming etc. -- TODO: Add hit event and make the arty group relocate. --- TODO: Add illumination and smoke. +-- DONE: Add illumination and smoke. --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -1452,17 +1460,36 @@ end --- Set number of illumination shells available to the group. -- Note that it can be max the number of normal shells. Also if all normal shells are empty, firing illumination shells is also not possible any more until group gets rearmed. -- @param #ARTY self --- @param #number n Number of warheads for the whole group. -function ARTY:SetIlluminationShells(n) +-- @param #number n Number of illumination shells for the whole group. +-- @param #number power (Optional) Power of illumination warhead in mega candela. Default 1.0 mcd. +function ARTY:SetIlluminationShells(n, power) self.Nillu=n + self.illuPower=power or 1.0 + self.illuPower=self.illuPower * 1000000 +end + +--- Set minimum and maximum detotation altitude for illumination shells. A value between min/max is selected randomly. +-- The illumination bomb will burn for 300 seconds (5 minutes). Assuming a descent rate of 5 m/s the "optimal" altitude would be 1500 m. +-- @param #ARTY self +-- @param #number minalt (Optional) Minium altitude in meters. Default 500 m. +-- @param #number maxalt (Optional) Maximum altitude in meters. Default 1500 m. +function ARTY:SetIlluminationMinMaxAlt(minalt, maxalt) + self.illuMinalt=minalt or 500 + self.illuMaxalt=maxalt or 1500 + + if self.illuMinalt>self.illuMaxalt then + self.illuMinalt=self.illuMaxalt + end end --- Set number of smoke shells available to the group. -- Note that it can be max the number of normal shells. Also if all normal shells are empty, firing smoke shells is also not possible any more until group gets rearmed. -- @param #ARTY self --- @param #number n Number of warheads for the whole group. -function ARTY:SetSmokeShells(n) +-- @param #number n Number of smoke shells for the whole group. +-- @param Utilities.Utils#SMOKECOLOR color (Optional) Color of the smoke. Default SMOKECOLOR.Red. +function ARTY:SetSmokeShells(n, color) self.Nsmoke=n + self.smokeColor=color or SMOKECOLOR.Red end --- Set nuclear fires and extra demolition explosions. @@ -1605,7 +1632,11 @@ function ARTY:onafterStart(Controllable, From, Event, To) text=text..string.format("Nuclear demolition = %d m\n", self.nukerange) text=text..string.format("Nuclear fires = %d (active=%s)\n", self.nukefires, tostring(self.nukefire)) text=text..string.format("Number of illum. = %d\n", self.Nillu0) + text=text..string.format("Illuminaton Power = %.3f mcd\n", self.illuPower/1000000) + text=text..string.format("Illuminaton Minalt = %d m\n", self.illuMinalt) + text=text..string.format("Illuminaton Maxalt = %d m\n", self.illuMaxalt) text=text..string.format("Number of smoke = %d\n", self.Nsmoke0) + text=text..string.format("Smoke color = %d\n", self.smokeColor) if self.RearmingGroup or self.RearmingPlaceCoord then text=text..string.format("Rearming safe dist. = %d m\n", self.RearmingDistance) end @@ -1798,45 +1829,42 @@ function ARTY:_OnEventShot(EventData) --- Track the position of the weapon if it is supposed to model a tac nuke, illumination or smoke shell. -- @param #table _weapon - local function _TrackWeapon(_weapon) - - -- Coordinate of the target - local _targetcoord=self.currentTarget.coord -- Core.Point#COORDINATE - self.illuMinalt=400 - self.illuMaxalt=1000 - self.illuPower=1000 + local function _TrackWeapon(_data) -- When the pcall status returns false the weapon has hit. - local _status,_currpos = pcall( + local _weaponalive,_currpos = pcall( function() - return _weapon:getPoint() + return _data.weapon:getPoint() end) - self:T(ARTY.id..string.format("ARTY %s: Weapon still in air: %s", self.groupname, tostring(_status))) + -- Debug + self:T3(ARTY.id..string.format("ARTY %s: Weapon still in air: %s", self.groupname, tostring(_weaponalive))) + + -- Destroy weapon before impact. local _destroyweapon=false - if _status then + if _weaponalive then -- Update last position. _lastpos={x=_currpos.x, y=_currpos.y, z=_currpos.z} ---[[ + -- Coordinate and distance to target. local _coord=COORDINATE:NewFromVec3(_lastpos) - local _dist=_coord:Get2DDistance(self.currentTarget.coord) + local _dist=_coord:Get2DDistance(_data.target.coord) - env.info("FF dist = ".._dist) + -- Debug + self:T3(ARTY.id..string.format("ARTY %s weapon to target dist = %d m", self.groupname,_dist)) - if self.currentTarget.weapontype==ARTY.WeaponType.IlluminationShells then + if _data.target.weapontype==ARTY.WeaponType.IlluminationShells then -- Check if within distace. - if _dist0 local _tracksmoke = self.currentTarget.weapontype==ARTY.WeaponType.SmokeShells and self.Nsmoke>0 if _tracknuke or _trackillu or _tracksmoke then - self:T(ARTY.id..string.format("ARTY %s: Tracking of weapon starts in one second.", self.groupname)) - timer.scheduleFunction(_TrackWeapon, EventData.weapon, timer.getTime() + 1.0) + + self:T(ARTY.id..string.format("ARTY %s: Tracking of weapon starts in two seconds.", self.groupname)) + + local _peter={} + _peter.weapon=EventData.weapon + _peter.target=UTILS.DeepCopy(self.currentTarget) + + timer.scheduleFunction(_TrackWeapon, _peter, timer.getTime() + 2.0) end -- Get current ammo. @@ -1970,12 +2013,6 @@ function ARTY:_OnEventShot(EventData) if _ceasefire then self:CeaseFire(self.currentTarget) end - - -- Group is out of ammo (or partly and can rearm) ==> Winchester (==> Rearm). - if _outofammo or (_partlyoutofammo and self.RearmingGroup ~=nil) then - --self:Winchester() - --return - end else self:E(ARTY.id..string.format("WARNING: No current target for group %s?!", self.groupname)) @@ -4435,7 +4472,7 @@ function ARTY:_CheckWeaponTypePossible(target) elseif target.weapontype==ARTY.WeaponType.TacticalNukes then possible=self.Nukes0>0 elseif target.weapontype==ARTY.WeaponType.IlluminationShells then - possible=self.Nillus0>0 + possible=self.Nillu0>0 elseif target.weapontype==ARTY.WeaponType.SmokeShells then possible=self.Nsmoke0>0 elseif target.weapontype==ARTY.WeaponType.Rockets then From 79d8113df33a84d614116da9c3795ac5d3ef2cca Mon Sep 17 00:00:00 2001 From: funkyfranky Date: Sat, 16 Jun 2018 19:03:44 +0200 Subject: [PATCH 4/4] ARTY v1.0.4 Minor adjustments. Fixed bug that coordinates from mark points are always at an altitude of 5 meters. --- Moose Development/Moose/Core/Point.lua | 2 ++ .../Moose/Functional/Artillery.lua | 28 +++++++++++++------ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/Moose Development/Moose/Core/Point.lua b/Moose Development/Moose/Core/Point.lua index 35eb6566d..b98159460 100644 --- a/Moose Development/Moose/Core/Point.lua +++ b/Moose Development/Moose/Core/Point.lua @@ -268,6 +268,8 @@ do -- COORDINATE -- Adjust height if altitude==nil then _coord.y=altitude + else + _coord.y=self:GetLandHeight() end return _coord diff --git a/Moose Development/Moose/Functional/Artillery.lua b/Moose Development/Moose/Functional/Artillery.lua index c3e03b6f7..c2ab7b275 100644 --- a/Moose Development/Moose/Functional/Artillery.lua +++ b/Moose Development/Moose/Functional/Artillery.lua @@ -14,7 +14,7 @@ -- * Automatic rearming once the artillery is out of ammo (optional). -- * Automatic relocation after each firing engagement to prevent counter strikes (optional). -- * Automatic relocation movements to get the battery within firing range (optional). --- * Simulation of tactical nuclear shells. +-- * Simulation of tactical nuclear shells as well as illumination and smoke shells. -- * New targets can be added during the mission, e.g. when they are detected by recon units. -- * Targets and relocations can be assigned by placing markers on the F10 map. -- * Finite state machine implementation. Mission designer can interact when certain events occur. @@ -383,6 +383,16 @@ -- arty cancel, everyone, move -- arty cancel, rearming, battery "MRLS Charly" -- +-- ### Settings +-- +-- A few options can be set by marks. The corresponding keyword is **arty set**. This can be used to define the rearming place and group for a battery. +-- +-- To set the reamring place of a group at the marker position type +-- arty set, battery "Paladin Alpha", rearming place +-- +-- Setting the rearming group is independent of the position of the mark. Just create one anywhere on the map and type +-- arty set, battery "Mortar Bravo", rearming group "Ammo Truck M818" +-- Note that the name of the rearming group has to be given in quotation marks and spellt exactly as the group name defined in the mission editor. -- -- ## Fine Tuning -- @@ -517,7 +527,7 @@ ARTY={ Nillu=nil, illuPower=1000000, illuMinalt=500, - illuMaxalt=1500, + illuMaxalt=1000, Nsmoke=nil, smokeColor=SMOKECOLOR.Red, relocateafterfire=false, @@ -609,7 +619,7 @@ ARTY.id="ARTY | " --- Arty script version. -- @field #string version -ARTY.version="1.0.2" +ARTY.version="1.0.4" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -1469,13 +1479,13 @@ function ARTY:SetIlluminationShells(n, power) end --- Set minimum and maximum detotation altitude for illumination shells. A value between min/max is selected randomly. --- The illumination bomb will burn for 300 seconds (5 minutes). Assuming a descent rate of 5 m/s the "optimal" altitude would be 1500 m. +-- The illumination bomb will burn for 300 seconds (5 minutes). Assuming a descent rate of ~3 m/s the "optimal" altitude would be 900 m. -- @param #ARTY self -- @param #number minalt (Optional) Minium altitude in meters. Default 500 m. --- @param #number maxalt (Optional) Maximum altitude in meters. Default 1500 m. +-- @param #number maxalt (Optional) Maximum altitude in meters. Default 1000 m. function ARTY:SetIlluminationMinMaxAlt(minalt, maxalt) self.illuMinalt=minalt or 500 - self.illuMaxalt=maxalt or 1500 + self.illuMaxalt=maxalt or 1000 if self.illuMinalt>self.illuMaxalt then self.illuMinalt=self.illuMaxalt @@ -2153,6 +2163,9 @@ function ARTY:_OnEventMarkChange(Event) -- Get coordinate from vec3. local _coord=COORDINATE:NewFromVec3(vec3) + + -- Adjust y component to actual land height. When a coordinate is create it uses y=5 m! + _coord.y=_coord:GetLandHeight() -- Get battery coalition and name. local batterycoalition=self.Controllable:GetCoalition() @@ -2263,7 +2276,7 @@ function ARTY:_OnEventMarkChange(Event) -- Set stuff and return. if _assign.set and _validkey then - if _assign.setrearmingplace then + if _assign.setrearmingplace and self.ismobile then self:SetRearmingPlace(_coord) _coord:RemoveMark(Event.idx) _coord:MarkToCoalition(string.format("Rearming place for battery %s", self.groupname), self.Controllable:GetCoalition(), false, string.format("New rearming place for battery %s defined.", self.groupname)) @@ -3873,7 +3886,6 @@ function ARTY:_Markertext(text) local v=self:_split(keyphrase, '"') local groupname=v[2] - env.info("FF v2 groupname = "..tostring(v[2])) local group=GROUP:FindByName(groupname) if group and group:IsAlive() then