diff --git a/Moose Development/Moose/Core/Database.lua b/Moose Development/Moose/Core/Database.lua index db54e8dc2..dec6bd64c 100644 --- a/Moose Development/Moose/Core/Database.lua +++ b/Moose Development/Moose/Core/Database.lua @@ -1271,7 +1271,11 @@ end -- @param #string ClientName Name of the Client. -- @return #number Coalition ID. function DATABASE:GetCoalitionFromClientTemplate( ClientName ) - return self.Templates.ClientsByName[ClientName].CoalitionID + if self.Templates.ClientsByName[ClientName] then + return self.Templates.ClientsByName[ClientName].CoalitionID + end + self:E("ERROR: Template does not exist for client "..tostring(ClientName)) + return nil end --- Get category ID from client name. @@ -1279,7 +1283,11 @@ end -- @param #string ClientName Name of the Client. -- @return #number Category ID. function DATABASE:GetCategoryFromClientTemplate( ClientName ) - return self.Templates.ClientsByName[ClientName].CategoryID + if self.Templates.ClientsByName[ClientName] then + return self.Templates.ClientsByName[ClientName].CategoryID + end + self:E("ERROR: Template does not exist for client "..tostring(ClientName)) + return nil end --- Get country ID from client name. @@ -1287,7 +1295,11 @@ end -- @param #string ClientName Name of the Client. -- @return #number Country ID. function DATABASE:GetCountryFromClientTemplate( ClientName ) - return self.Templates.ClientsByName[ClientName].CountryID + if self.Templates.ClientsByName[ClientName] then + return self.Templates.ClientsByName[ClientName].CountryID + end + self:E("ERROR: Template does not exist for client "..tostring(ClientName)) + return nil end --- Airbase diff --git a/Moose Development/Moose/Core/Point.lua b/Moose Development/Moose/Core/Point.lua index 3fe748904..a18dcce96 100644 --- a/Moose Development/Moose/Core/Point.lua +++ b/Moose Development/Moose/Core/Point.lua @@ -2250,7 +2250,7 @@ do -- COORDINATE -- local MarkGroup = GROUP:FindByName( "AttackGroup" ) -- local MarkID = TargetCoord:MarkToGroup( "This is a target for the attack group", AttackGroup ) -- <<< logic >>> - -- RemoveMark( MarkID ) -- The mark is now removed + -- TargetCoord:RemoveMark( MarkID ) -- The mark is now removed function COORDINATE:RemoveMark( MarkID ) trigger.action.removeMark( MarkID ) end @@ -2764,7 +2764,10 @@ do -- COORDINATE local sunrise=UTILS.GetSunRiseAndSet(DayOfYear, Latitude, Longitude, true, Tdiff) local sunset=UTILS.GetSunRiseAndSet(DayOfYear, Latitude, Longitude, false, Tdiff) - + + if sunrise == "N/R" then return false end + if sunrise == "N/S" then return true end + local time=UTILS.ClockToSeconds(clock) -- Check if time is between sunrise and sunset. diff --git a/Moose Development/Moose/Core/Set.lua b/Moose Development/Moose/Core/Set.lua index 43812c1e1..ca82b1ada 100644 --- a/Moose Development/Moose/Core/Set.lua +++ b/Moose Development/Moose/Core/Set.lua @@ -4729,8 +4729,11 @@ do -- SET_CLIENT local MClientCoalition = false for CoalitionID, CoalitionName in pairs( self.Filter.Coalitions ) do local ClientCoalitionID = _DATABASE:GetCoalitionFromClientTemplate( MClientName ) + if ClientCoalitionID==nil and MClient:IsAlive()~=nil then + ClientCoalitionID=MClient:GetCoalition() + end self:T3( { "Coalition:", ClientCoalitionID, self.FilterMeta.Coalitions[CoalitionName], CoalitionName } ) - if self.FilterMeta.Coalitions[CoalitionName] and self.FilterMeta.Coalitions[CoalitionName] == ClientCoalitionID then + if self.FilterMeta.Coalitions[CoalitionName] and ClientCoalitionID and self.FilterMeta.Coalitions[CoalitionName] == ClientCoalitionID then MClientCoalition = true end end @@ -4742,8 +4745,11 @@ do -- SET_CLIENT local MClientCategory = false for CategoryID, CategoryName in pairs( self.Filter.Categories ) do local ClientCategoryID = _DATABASE:GetCategoryFromClientTemplate( MClientName ) + if ClientCategoryID==nil and MClient:IsAlive()~=nil then + ClientCategoryID=MClient:GetCategory() + end self:T3( { "Category:", ClientCategoryID, self.FilterMeta.Categories[CategoryName], CategoryName } ) - if self.FilterMeta.Categories[CategoryName] and self.FilterMeta.Categories[CategoryName] == ClientCategoryID then + if self.FilterMeta.Categories[CategoryName] and ClientCategoryID and self.FilterMeta.Categories[CategoryName] == ClientCategoryID then MClientCategory = true end end @@ -4767,8 +4773,11 @@ do -- SET_CLIENT local MClientCountry = false for CountryID, CountryName in pairs( self.Filter.Countries ) do local ClientCountryID = _DATABASE:GetCountryFromClientTemplate( MClientName ) + if ClientCountryID==nil and MClient:IsAlive()~=nil then + ClientCountryID=MClient:GetCountry() + end self:T3( { "Country:", ClientCountryID, country.id[CountryName], CountryName } ) - if country.id[CountryName] and country.id[CountryName] == ClientCountryID then + if country.id[CountryName] and ClientCountryID and country.id[CountryName] == ClientCountryID then MClientCountry = true end end diff --git a/Moose Development/Moose/Functional/Artillery.lua b/Moose Development/Moose/Functional/Artillery.lua index 7425d3212..c1745cac0 100644 --- a/Moose Development/Moose/Functional/Artillery.lua +++ b/Moose Development/Moose/Functional/Artillery.lua @@ -45,6 +45,7 @@ -- @field #table currentMove Holds the current commanded move, if there is one assigned. -- @field #number Nammo0 Initial amount total ammunition (shells+rockets+missiles) of the whole group. -- @field #number Nshells0 Initial amount of shells of the whole group. +-- @field #number Narty0 Initial amount of artillery shells of the whole group. -- @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. @@ -415,7 +416,7 @@ -- 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" +-- arty set, battery "Mortar Bravo", rearming group "Ammo Truck M939" -- Note that the name of the rearming group has to be given in quotation marks and spelt exactly as the group name defined in the mission editor. -- -- ## Transporting @@ -453,7 +454,7 @@ -- -- Creat a new ARTY object from a Paladin group. -- paladin=ARTY:New(GROUP:FindByName("Blue Paladin")) -- --- -- Define a rearming group. This is a Transport M818 truck. +-- -- Define a rearming group. This is a Transport M939 truck. -- paladin:SetRearmingGroup(GROUP:FindByName("Blue Ammo Truck")) -- -- -- Set the max firing range. A Paladin unit has a range of 20 km. @@ -694,7 +695,7 @@ ARTY.db={ --- Arty script version. -- @field #string version -ARTY.version="1.3.0" +ARTY.version="1.3.1" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -707,7 +708,7 @@ ARTY.version="1.3.0" -- DONE: Add user defined rearm weapon types. -- DONE: Check if target is in range. Maybe this requires a data base with the ranges of all arty units. -- DONE: Make ARTY move to rearming position. --- DONE: Check that right rearming vehicle is specified. Blue M818, Red Ural-375. Are there more? +-- DONE: Check that right rearming vehicle is specified. Blue M939, Red Ural-375. Are there more? -- DONE: Check if ARTY group is still alive. -- DONE: Handle dead events. -- DONE: Abort firing task if no shooting event occured with 5(?) minutes. Something went wrong then. Min/max range for example. @@ -1532,7 +1533,7 @@ end --- Assign a group, which is responsible for rearming the ARTY group. If the group is too far away from the ARTY group it will be guided towards the ARTY group. -- @param #ARTY self --- @param Wrapper.Group#GROUP group Group that is supposed to rearm the ARTY group. For the blue coalition, this is often a unarmed M818 transport whilst for red an unarmed Ural-375 transport can be used. +-- @param Wrapper.Group#GROUP group Group that is supposed to rearm the ARTY group. For the blue coalition, this is often a unarmed M939 transport whilst for red an unarmed Ural-375 transport can be used. -- @return self function ARTY:SetRearmingGroup(group) self:F({group=group}) @@ -1887,7 +1888,7 @@ function ARTY:onafterStart(Controllable, From, Event, To) MESSAGE:New(text, 5):ToAllIf(self.Debug) -- Get Ammo. - self.Nammo0, self.Nshells0, self.Nrockets0, self.Nmissiles0=self:GetAmmo(self.Debug) + self.Nammo0, self.Nshells0, self.Nrockets0, self.Nmissiles0, self.Narty0=self:GetAmmo(self.Debug) -- Init nuclear explosion parameters if they were not set by user. if self.nukerange==nil then @@ -2093,7 +2094,7 @@ function ARTY:_StatusReport(display) end -- Get Ammo. - local Nammo, Nshells, Nrockets, Nmissiles=self:GetAmmo() + local Nammo, Nshells, Nrockets, Nmissiles, Narty=self:GetAmmo() local Nnukes=self.Nukes local Nillu=self.Nillu local Nsmoke=self.Nsmoke @@ -2106,7 +2107,7 @@ function ARTY:_StatusReport(display) text=text..string.format("Clock = %s\n", Clock) text=text..string.format("FSM state = %s\n", self:GetState()) text=text..string.format("Total ammo count = %d\n", Nammo) - text=text..string.format("Number of shells = %d\n", Nshells) + text=text..string.format("Number of shells = %d\n", Narty) 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) @@ -2293,7 +2294,7 @@ function ARTY:OnEventShot(EventData) end -- Get current ammo. - local _nammo,_nshells,_nrockets,_nmissiles=self:GetAmmo() + local _nammo,_nshells,_nrockets,_nmissiles,_narty=self:GetAmmo() -- Decrease available nukes because we just fired one. if self.currentTarget.weapontype==ARTY.WeaponType.TacticalNukes then @@ -2323,7 +2324,7 @@ function ARTY:OnEventShot(EventData) -- Weapon type name for current target. local _weapontype=self:_WeaponTypeName(self.currentTarget.weapontype) - self:T(self.lid..string.format("Group %s ammo: total=%d, shells=%d, rockets=%d, missiles=%d", self.groupname, _nammo, _nshells, _nrockets, _nmissiles)) + self:T(self.lid..string.format("Group %s ammo: total=%d, shells=%d, rockets=%d, missiles=%d", self.groupname, _nammo, _narty, _nrockets, _nmissiles)) self:T(self.lid..string.format("Group %s uses weapontype %s for current target.", self.groupname, _weapontype)) -- Default switches for cease fire and relocation. @@ -2771,7 +2772,7 @@ function ARTY:onafterStatus(Controllable, From, Event, To) self:_EventFromTo("onafterStatus", Event, From, To) -- Get ammo. - local nammo, nshells, nrockets, nmissiles=self:GetAmmo() + local nammo, nshells, nrockets, nmissiles, narty=self:GetAmmo() -- We have a cargo group ==> check if group was loaded into a carrier. if self.iscargo and self.cargogroup then @@ -2788,7 +2789,7 @@ function ARTY:onafterStatus(Controllable, From, Event, To) -- FSM state. local fsmstate=self:GetState() - self:T(self.lid..string.format("Status %s, Ammo total=%d: shells=%d [smoke=%d, illu=%d, nukes=%d*%.3f kT], rockets=%d, missiles=%d", fsmstate, nammo, nshells, self.Nsmoke, self.Nillu, self.Nukes, self.nukewarhead/1000000, nrockets, nmissiles)) + self:T(self.lid..string.format("Status %s, Ammo total=%d: shells=%d [smoke=%d, illu=%d, nukes=%d*%.3f kT], rockets=%d, missiles=%d", fsmstate, nammo, narty, self.Nsmoke, self.Nillu, self.Nukes, self.nukewarhead/1000000, nrockets, nmissiles)) if self.Controllable and self.Controllable:IsAlive() then @@ -2871,20 +2872,19 @@ function ARTY:onafterStatus(Controllable, From, Event, To) if self.currentTarget then self:CeaseFire(self.currentTarget) end - - -- Open fire on timed target. - self:OpenFire(_timedTarget) - + + if self:is("CombatReady") then + -- Open fire on timed target. + self:OpenFire(_timedTarget) + end elseif _normalTarget then - - -- Open fire on normal target. - self:OpenFire(_normalTarget) - + + if self:is("CombatReady") then + -- Open fire on normal target. + self:OpenFire(_normalTarget) + end end - -- Get ammo. - --local nammo, nshells, nrockets, nmissiles=self:GetAmmo() - -- Check if we have a target in the queue for which weapons are still available. local gotsome=false if #self.targets>0 then @@ -3045,14 +3045,14 @@ function ARTY:onafterOpenFire(Controllable, From, Event, To, target) local range=Controllable:GetCoordinate():Get2DDistance(target.coord) -- Get ammo. - local Nammo, Nshells, Nrockets, Nmissiles=self:GetAmmo() - local nfire=Nammo + local Nammo, Nshells, Nrockets, Nmissiles, Narty=self:GetAmmo() + local nfire=Narty local _type="shots" if target.weapontype==ARTY.WeaponType.Auto then - nfire=Nammo + nfire=Narty _type="shots" elseif target.weapontype==ARTY.WeaponType.Cannon then - nfire=Nshells + nfire=Narty _type="shells" elseif target.weapontype==ARTY.WeaponType.TacticalNukes then nfire=self.Nukes @@ -3337,7 +3337,7 @@ function ARTY:_CheckRearmed() self:F2() -- Get current ammo. - local nammo,nshells,nrockets,nmissiles=self:GetAmmo() + local nammo,nshells,nrockets,nmissiles,narty=self:GetAmmo() -- Number of units still alive. local units=self.Controllable:GetUnits() @@ -3603,7 +3603,11 @@ function ARTY:_FireAtCoord(coord, radius, nshells, weapontype) if weapontype==ARTY.WeaponType.TacticalNukes or weapontype==ARTY.WeaponType.IlluminationShells or weapontype==ARTY.WeaponType.SmokeShells then weapontype=ARTY.WeaponType.Cannon end - + + if group:HasTask() then + group:ClearTasks() + end + -- Set ROE to weapon free. group:OptionROEOpenFire() @@ -3614,7 +3618,7 @@ function ARTY:_FireAtCoord(coord, radius, nshells, weapontype) local fire=group:TaskFireAtPoint(vec2, radius, nshells, weapontype) -- Execute task. - group:SetTask(fire) + group:SetTask(fire,1) end --- Set task for attacking a group. @@ -3631,7 +3635,11 @@ function ARTY:_AttackGroup(target) if weapontype==ARTY.WeaponType.TacticalNukes or weapontype==ARTY.WeaponType.IlluminationShells or weapontype==ARTY.WeaponType.SmokeShells then weapontype=ARTY.WeaponType.Cannon end - + + if group:HasTask() then + group:ClearTasks() + end + -- Set ROE to weapon free. group:OptionROEOpenFire() @@ -3642,7 +3650,7 @@ function ARTY:_AttackGroup(target) local fire=group:TaskAttackGroup(targetgroup, weapontype, AI.Task.WeaponExpend.ONE, 1) -- Execute task. - group:SetTask(fire) + group:SetTask(fire,1) end @@ -3915,6 +3923,7 @@ end -- @return #number Number of shells the group has left. -- @return #number Number of rockets the group has left. -- @return #number Number of missiles the group has left. +-- @return #number Number of artillery shells the group has left. function ARTY:GetAmmo(display) self:F3({display=display}) @@ -3928,6 +3937,7 @@ function ARTY:GetAmmo(display) local nshells=0 local nrockets=0 local nmissiles=0 + local nartyshells=0 -- Get all units. local units=self.Controllable:GetUnits() @@ -4030,7 +4040,8 @@ function ARTY:GetAmmo(display) -- Add up all shells. nshells=nshells+Nammo - + local _,_,_,_,_,shells = unit:GetAmmunition() + nartyshells=nartyshells+shells -- Debug info. text=text..string.format("- %d shells of type %s\n", Nammo, _weaponName) @@ -4076,7 +4087,7 @@ function ARTY:GetAmmo(display) -- Total amount of ammunition. nammo=nshells+nrockets+nmissiles - return nammo, nshells, nrockets, nmissiles + return nammo, nshells, nrockets, nmissiles, nartyshells end --- Returns a name of a missile category. @@ -4827,7 +4838,10 @@ function ARTY:_CheckShootingStarted() -- Check if we waited long enough and no shot was fired. --if dt > self.WaitForShotTime and self.Nshots==0 then - if dt > self.WaitForShotTime and (self.Nshots==0 or self.currentTarget.nshells >= self.Nshots) then --https://github.com/FlightControl-Master/MOOSE/issues/1356 + + self:T(string.format("dt = %d WaitTime = %d | shots = %d TargetShells = %d",dt,self.WaitForShotTime,self.Nshots,self.currentTarget.nshells)) + + if (dt > self.WaitForShotTime and self.Nshots==0) or (self.currentTarget.nshells <= self.Nshots) then --https://github.com/FlightControl-Master/MOOSE/issues/1356 -- Debug info. self:T(self.lid..string.format("%s, no shot event after %d seconds. Removing current target %s from list.", self.groupname, self.WaitForShotTime, name)) @@ -4889,7 +4903,7 @@ end function ARTY:_CheckOutOfAmmo(targets) -- Get current ammo. - local _nammo,_nshells,_nrockets,_nmissiles=self:GetAmmo() + local _nammo,_nshells,_nrockets,_nmissiles,_narty=self:GetAmmo() -- Special weapon type requested ==> Check if corresponding ammo is empty. local _partlyoutofammo=false @@ -4901,7 +4915,7 @@ function ARTY:_CheckOutOfAmmo(targets) self:T(self.lid..string.format("Group %s, auto weapon requested for target %s but all ammo is empty.", self.groupname, Target.name)) _partlyoutofammo=true - elseif Target.weapontype==ARTY.WeaponType.Cannon and _nshells==0 then + elseif Target.weapontype==ARTY.WeaponType.Cannon and _narty==0 then self:T(self.lid..string.format("Group %s, cannons requested for target %s but shells empty.", self.groupname, Target.name)) _partlyoutofammo=true @@ -4945,14 +4959,14 @@ end function ARTY:_CheckWeaponTypeAvailable(target) -- Get current ammo of group. - local Nammo, Nshells, Nrockets, Nmissiles=self:GetAmmo() + local Nammo, Nshells, Nrockets, Nmissiles, Narty=self:GetAmmo() -- Check if enough ammo is there for the selected weapon type. local nfire=Nammo if target.weapontype==ARTY.WeaponType.Auto then nfire=Nammo elseif target.weapontype==ARTY.WeaponType.Cannon then - nfire=Nshells + nfire=Narty elseif target.weapontype==ARTY.WeaponType.TacticalNukes then nfire=self.Nukes elseif target.weapontype==ARTY.WeaponType.IlluminationShells then diff --git a/Moose Development/Moose/Functional/Warehouse.lua b/Moose Development/Moose/Functional/Warehouse.lua index 4a2910d59..cab1d0899 100644 --- a/Moose Development/Moose/Functional/Warehouse.lua +++ b/Moose Development/Moose/Functional/Warehouse.lua @@ -7946,10 +7946,12 @@ function WAREHOUSE:_FindParkingForAssets(airbase, assets) local clients=_DATABASE.CLIENTS for clientname, client in pairs(clients) do local template=_DATABASE:GetGroupTemplateFromUnitName(clientname) - local units=template.units - for i,unit in pairs(units) do - local coord=COORDINATE:New(unit.x, unit.alt, unit.y) - coords[unit.name]=coord + if template then + local units=template.units + for i,unit in pairs(units) do + local coord=COORDINATE:New(unit.x, unit.alt, unit.y) + coords[unit.name]=coord + end end end end diff --git a/Moose Development/Moose/Ops/FlightGroup.lua b/Moose Development/Moose/Ops/FlightGroup.lua index 886ac9c23..28c99e7eb 100644 --- a/Moose Development/Moose/Ops/FlightGroup.lua +++ b/Moose Development/Moose/Ops/FlightGroup.lua @@ -3898,18 +3898,9 @@ function FLIGHTGROUP:_InitGroup(Template) -- Group object. local group=self.group --Wrapper.Group#GROUP - -- Get template of group. - local template=Template or self:_GetTemplate() - -- Helo group. self.isHelo=group:IsHelicopter() - -- Is (template) group uncontrolled. - self.isUncontrolled=template.uncontrolled - - -- Is (template) group late activated. - self.isLateActivated=template.lateActivation - -- Max speed in km/h. self.speedMax=group:GetSpeedMax() @@ -3929,25 +3920,38 @@ function FLIGHTGROUP:_InitGroup(Template) -- Group ammo. self.ammo=self:GetAmmoTot() + + -- Get template of group. + local template=Template or self:_GetTemplate() - -- Radio parameters from template. Default is set on spawn if not modified by user. - self.radio.Freq=tonumber(template.frequency) - self.radio.Modu=tonumber(template.modulation) - self.radio.On=template.communication + -- Is (template) group uncontrolled. + self.isUncontrolled=template~=nil and template.uncontrolled or false - -- Set callsign. Default is set on spawn if not modified by user. - local callsign=template.units[1].callsign - --self:I({callsign=callsign}) - if type(callsign)=="number" then -- Sometimes callsign is just "101". - local cs=tostring(callsign) - callsign={} - callsign[1]=cs:sub(1,1) - callsign[2]=cs:sub(2,2) - callsign[3]=cs:sub(3,3) + -- Is (template) group late activated. + self.isLateActivated=template~=nil and template.lateActivation or false + + if template then + + -- Radio parameters from template. Default is set on spawn if not modified by user. + self.radio.Freq=tonumber(template.frequency) + self.radio.Modu=tonumber(template.modulation) + self.radio.On=template.communication + + -- Set callsign. Default is set on spawn if not modified by user. + local callsign=template.units[1].callsign + --self:I({callsign=callsign}) + if type(callsign)=="number" then -- Sometimes callsign is just "101". + local cs=tostring(callsign) + callsign={} + callsign[1]=cs:sub(1,1) + callsign[2]=cs:sub(2,2) + callsign[3]=cs:sub(3,3) + end + self.callsign.NumberSquad=tonumber(callsign[1]) + self.callsign.NumberGroup=tonumber(callsign[2]) + self.callsign.NameSquad=UTILS.GetCallsignName(self.callsign.NumberSquad) + end - self.callsign.NumberSquad=tonumber(callsign[1]) - self.callsign.NumberGroup=tonumber(callsign[2]) - self.callsign.NameSquad=UTILS.GetCallsignName(self.callsign.NumberSquad) -- Set default formation. if self.isHelo then diff --git a/Moose Development/Moose/Ops/OpsGroup.lua b/Moose Development/Moose/Ops/OpsGroup.lua index 99a6af3fe..4db2e974d 100644 --- a/Moose Development/Moose/Ops/OpsGroup.lua +++ b/Moose Development/Moose/Ops/OpsGroup.lua @@ -11378,11 +11378,19 @@ end -- @return #OPSGROUP self function OPSGROUP:_InitWaypoints(WpIndexMin, WpIndexMax) - -- Template waypoints. - self.waypoints0=UTILS.DeepCopy(_DATABASE:GetGroupTemplate(self.groupname).route.points) --self.group:GetTemplateRoutePoints() - -- Waypoints empty! self.waypoints={} + self.waypoints0={} + + -- Get group template + local template=_DATABASE:GetGroupTemplate(self.groupname) + + if template==nil then + return self + end + + -- Template waypoints. + self.waypoints0=UTILS.DeepCopy(template.route.points) --self.group:GetTemplateRoutePoints() WpIndexMin=WpIndexMin or 1 WpIndexMax=WpIndexMax or #self.waypoints0 @@ -13641,11 +13649,7 @@ function OPSGROUP:_AddElementByName(unitname) local unit=UNIT:FindByName(unitname) if unit then - - -- Get unit template. - local unittemplate=unit:GetTemplate() - --local unittemplate=_DATABASE:GetUnitTemplateFromUnitName(unitname) - + -- Element table. local element=self:GetElementByName(unitname) @@ -13672,8 +13676,18 @@ function OPSGROUP:_AddElementByName(unitname) element.Nhit=0 element.opsgroup=self + -- Get unit template. + local unittemplate=unit:GetTemplate() + + if unittemplate==nil then + if element.DCSunit:getPlayerName() then + element.skill="Client" + end + else + element.skill=unittemplate~=nil and unittemplate.skill or "Unknown" + end + -- Skill etc. - element.skill=unittemplate.skill or "Unknown" if element.skill=="Client" or element.skill=="Player" then element.ai=false element.client=CLIENT:FindByName(unitname) @@ -13732,24 +13746,22 @@ function OPSGROUP:_AddElementByName(unitname) element.weightCargo=0 end element.weight=element.weightEmpty+element.weightCargo - + -- FLIGHTGROUP specific. - if self.isFlightgroup then - element.callsign=element.unit:GetCallsign() + element.callsign=element.unit:GetCallsign() + element.fuelmass=element.fuelmass0 or 99999 + element.fuelrel=element.unit:GetFuel() or 1 + + if self.isFlightgroup and unittemplate then element.modex=unittemplate.onboard_num element.payload=unittemplate.payload element.pylons=unittemplate.payload and unittemplate.payload.pylons or nil element.fuelmass0=unittemplate.payload and unittemplate.payload.fuel or 0 - element.fuelmass=element.fuelmass0 - element.fuelrel=element.unit:GetFuel() else element.callsign="Peter-1-1" element.modex="000" element.payload={} element.pylons={} - element.fuelmass0=99999 - element.fuelmass =99999 - element.fuelrel=1 end -- Debug text. diff --git a/Moose Development/Moose/Ops/OpsZone.lua b/Moose Development/Moose/Ops/OpsZone.lua index ee83650aa..e97b0688d 100644 --- a/Moose Development/Moose/Ops/OpsZone.lua +++ b/Moose Development/Moose/Ops/OpsZone.lua @@ -604,6 +604,14 @@ function OPSZONE:GetAttackDuration() return nil end +--- Find an OPSZONE using the Zone Name. +-- @param #OPSZONE self +-- @param #string ZoneName The zone name. +-- @return #OPSZONE The OPSZONE or nil if not found. +function OPSZONE:FindByName( ZoneName ) + local Found = _DATABASE:FindOpsZone( ZoneName ) + return Found +end --- Check if the red coalition is currently owning the zone. -- @param #OPSZONE self diff --git a/Moose Development/Moose/Utilities/Utils.lua b/Moose Development/Moose/Utilities/Utils.lua index 827627aca..a8d9677da 100644 --- a/Moose Development/Moose/Utilities/Utils.lua +++ b/Moose Development/Moose/Utilities/Utils.lua @@ -197,6 +197,45 @@ CALLSIGN={ Cargo=11, Ascot=12, }, + AH64={ + Army_Air = 9, + Apache = 10, + Crow = 11, + Sioux = 12, + Gatling = 13, + Gunslinger = 14, + Hammerhead = 15, + Bootleg = 16, + Palehorse = 17, + Carnivor = 18, + Saber = 19, + }, + Kiowa = { + Anvil = 1, + Azrael = 2, + BamBam = 3, + Blackjack = 4, + Bootleg = 5, + BurninStogie = 6, + Chaos = 7, + CrazyHorse = 8, + Crusader = 9, + Darkhorse = 10, + Eagle = 11, + Lighthorse = 12, + Mustang = 13, + Outcast = 14, + Palehorse = 15, + Pegasus = 16, + Pistol = 17, + Roughneck = 18, + Saber = 19, + Shamus = 20, + Spur = 21, + Stetson = 22, + Wrath = 23, + }, + } --#CALLSIGN --- Utilities static class. @@ -1998,7 +2037,19 @@ function UTILS.GetCallsignName(Callsign) return name end end - + + for name, value in pairs(CALLSIGN.AH64) do + if value==Callsign then + return name + end + end + + for name, value in pairs(CALLSIGN.Kiowa) do + if value==Callsign then + return name + end + end + return "Ghostrider" end diff --git a/Moose Development/Moose/Wrapper/Unit.lua b/Moose Development/Moose/Wrapper/Unit.lua index 781c71d48..497d9fb1a 100644 --- a/Moose Development/Moose/Wrapper/Unit.lua +++ b/Moose Development/Moose/Wrapper/Unit.lua @@ -445,7 +445,11 @@ function UNIT:IsPlayer() if not group then return false end -- Units of template group. - local units=group:GetTemplate().units + local template = group:GetTemplate() + + if (template == nil) or (template.units == nil ) then return false end + + local units=template.units -- Get numbers. for _,unit in pairs(units) do @@ -789,11 +793,13 @@ end --- Get the number of ammunition and in particular the number of shells, rockets, bombs and missiles a unit currently has. -- @param #UNIT self -- @return #number Total amount of ammo the unit has left. This is the sum of shells, rockets, bombs and missiles. --- @return #number Number of shells left. +-- @return #number Number of shells left. Shells include MG ammunition, AP and HE shells, and artillery shells where applicable. -- @return #number Number of rockets left. -- @return #number Number of bombs left. -- @return #number Number of missiles left. --- @return #number Number of artillery shells left (with explosive mass, included in shells; shells can also be machine gun ammo) +-- @return #number Number of artillery shells left (with explosive mass, included in shells; HE will also be reported as artillery shells for tanks) +-- @return #number Number of tank AP shells left (for tanks, if applicable) +-- @return #number Number of tank HE shells left (for tanks, if applicable) function UNIT:GetAmmunition() -- Init counter. @@ -803,6 +809,8 @@ function UNIT:GetAmmunition() local nmissiles=0 local nbombs=0 local narti=0 + local nAPshells = 0 + local nHEshells = 0 local unit=self @@ -844,6 +852,14 @@ function UNIT:GetAmmunition() narti=narti+Nammo end + if ammotable[w].desc.typeName and string.find(ammotable[w].desc.typeName,"_AP",1,true) then + nAPshells = nAPshells+Nammo + end + + if ammotable[w].desc.typeName and string.find(ammotable[w].desc.typeName,"_HE",1,true) then + nHEshells = nHEshells+Nammo + end + elseif Category==Weapon.Category.ROCKET then -- Add up all rockets. @@ -880,7 +896,55 @@ function UNIT:GetAmmunition() -- Total amount of ammunition. nammo=nshells+nrockets+nmissiles+nbombs - return nammo, nshells, nrockets, nbombs, nmissiles, narti + return nammo, nshells, nrockets, nbombs, nmissiles, narti, nAPshells, nHEshells +end + +--- Checks if a tank still has AP shells. +-- @param #UNIT self +-- @return #boolean HasAPShells +function UNIT:HasAPShells() + local _,_,_,_,_,_,shells = self:GetAmmunition() + if shells > 0 then return true else return false end +end + +--- Get number of AP shells from a tank. +-- @param #UNIT self +-- @return #number Number of AP shells +function UNIT:GetAPShells() + local _,_,_,_,_,_,shells = self:GetAmmunition() + return shells or 0 +end + +--- Get number of HE shells from a tank. +-- @param #UNIT self +-- @return #number Number of HE shells +function UNIT:GetHEShells() + local _,_,_,_,_,_,_,shells = self:GetAmmunition() + return shells or 0 +end + +--- Checks if a tank still has HE shells. +-- @param #UNIT self +-- @return #boolean HasHEShells +function UNIT:HasHEShells() + local _,_,_,_,_,_,_,shells = self:GetAmmunition() + if shells > 0 then return true else return false end +end + +--- Checks if an artillery unit still has artillery shells. +-- @param #UNIT self +-- @return #boolean HasArtiShells +function UNIT:HasArtiShells() + local _,_,_,_,_,shells = self:GetAmmunition() + if shells > 0 then return true else return false end +end + +--- Get number of artillery shells from an artillery unit. +-- @param #UNIT self +-- @return #number Number of artillery shells +function UNIT:GetArtiShells() + local _,_,_,_,_,shells = self:GetAmmunition() + return shells or 0 end --- Returns the unit sensors. @@ -1192,17 +1256,17 @@ function UNIT:GetThreatLevel() if self:IsGround() then local ThreatLevels = { - "Unarmed", - "Infantry", - "Old Tanks & APCs", - "Tanks & IFVs without ATGM", - "Tanks & IFV with ATGM", - "Modern Tanks", - "AAA", - "IR Guided SAMs", - "SR SAMs", - "MR SAMs", - "LR SAMs" + [1] = "Unarmed", + [2] = "Infantry", + [3] = "Old Tanks & APCs", + [4] = "Tanks & IFVs without ATGM", + [5] = "Tanks & IFV with ATGM", + [6] = "Modern Tanks", + [7] = "AAA", + [8] = "IR Guided SAMs", + [9] = "SR SAMs", + [10] = "MR SAMs", + [11] = "LR SAMs" } @@ -1228,17 +1292,17 @@ function UNIT:GetThreatLevel() if self:IsAir() then local ThreatLevels = { - "Unarmed", - "Tanker", - "AWACS", - "Transport Helicopter", - "UAV", - "Bomber", - "Strategic Bomber", - "Attack Helicopter", - "Battleplane", - "Multirole Fighter", - "Fighter" + [1] = "Unarmed", + [2] = "Tanker", + [3] = "AWACS", + [4] = "Transport Helicopter", + [5] = "UAV", + [6] = "Bomber", + [7] = "Strategic Bomber", + [8] = "Attack Helicopter", + [9] = "Battleplane", + [10] = "Multirole Fighter", + [11] = "Fighter" } @@ -1272,17 +1336,17 @@ function UNIT:GetThreatLevel() --["Unarmed ships"] = {"Ships","HeavyArmoredUnits",}, local ThreatLevels = { - "Unarmed ship", - "Light armed ships", - "Corvettes", - "", - "Frigates", - "", - "Cruiser", - "", - "Destroyer", - "", - "Aircraft Carrier" + [1] = "Unarmed ship", + [2] = "Light armed ships", + [3] = "Corvettes", + [4] = "", + [5] = "Frigates", + [6] = "", + [7] = "Cruiser", + [8] = "", + [9] = "Destroyer", + [10] = "", + [11] = "Aircraft Carrier" }