mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Merge branch 'FF/Ops' into FF/OpsDev
This commit is contained in:
commit
0400f1a23e
@ -540,7 +540,7 @@ do -- COORDINATE
|
||||
local gotscenery=false
|
||||
|
||||
local function EvaluateZone(ZoneObject)
|
||||
|
||||
BASE:T({ZoneObject})
|
||||
if ZoneObject then
|
||||
|
||||
-- Get category of scanned object.
|
||||
@ -1324,7 +1324,15 @@ do -- COORDINATE
|
||||
self.y=alt
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Set altitude to be at land height (i.e. on the ground!)
|
||||
-- @param #COORDINATE self
|
||||
function COORDINATE:SetAtLandheight()
|
||||
local alt=self:GetLandHeight()
|
||||
self.y=alt
|
||||
return self
|
||||
end
|
||||
|
||||
--- Build an air type route point.
|
||||
-- @param #COORDINATE self
|
||||
-- @param #COORDINATE.WaypointAltType AltType The altitude type.
|
||||
@ -1950,7 +1958,6 @@ do -- COORDINATE
|
||||
-- @param #COORDINATE self
|
||||
-- @param #string name (Optional) Name of the fire to stop it, if not using the same COORDINATE object.
|
||||
function COORDINATE:StopBigSmokeAndFire( name )
|
||||
self:F2( { name = name } )
|
||||
name = name or self.firename
|
||||
trigger.action.effectSmokeStop( name )
|
||||
end
|
||||
|
||||
@ -873,8 +873,10 @@ end
|
||||
function SCORING:OnEventBirth( Event )
|
||||
|
||||
if Event.IniUnit then
|
||||
Event.IniUnit.ThreatLevel, Event.IniUnit.ThreatType = Event.IniUnit:GetThreatLevel()
|
||||
if Event.IniObjectCategory == 1 then
|
||||
local PlayerName = Event.IniUnit:GetPlayerName()
|
||||
Event.IniUnit.BirthTime = timer.getTime()
|
||||
if PlayerName then
|
||||
self:_AddPlayerFromUnit( Event.IniUnit )
|
||||
self:SetScoringMenu( Event.IniGroup )
|
||||
@ -1005,7 +1007,18 @@ function SCORING:_EventOnHit( Event )
|
||||
PlayerHit.PenaltyHit = PlayerHit.PenaltyHit or 0
|
||||
PlayerHit.TimeStamp = PlayerHit.TimeStamp or 0
|
||||
PlayerHit.UNIT = PlayerHit.UNIT or TargetUNIT
|
||||
-- After an instant kill we can't compute the thread level anymore. To fix this we compute at OnEventBirth
|
||||
if PlayerHit.UNIT.ThreatType == nil then
|
||||
PlayerHit.ThreatLevel, PlayerHit.ThreatType = PlayerHit.UNIT:GetThreatLevel()
|
||||
-- if this fails for some reason, set a good default value
|
||||
if PlayerHit.ThreatType == nil then
|
||||
PlayerHit.ThreatLevel = 1
|
||||
PlayerHit.ThreatType = "Unknown"
|
||||
end
|
||||
else
|
||||
PlayerHit.ThreatLevel = PlayerHit.UNIT.ThreatLevel
|
||||
PlayerHit.ThreatType = PlayerHit.UNIT.ThreatType
|
||||
end
|
||||
|
||||
-- Only grant hit scores if there was more than one second between the last hit.
|
||||
if timer.getTime() - PlayerHit.TimeStamp > 1 then
|
||||
@ -1021,19 +1034,20 @@ function SCORING:_EventOnHit( Event )
|
||||
|
||||
if InitCoalition then -- A coalition object was hit.
|
||||
if InitCoalition == TargetCoalition then
|
||||
Player.Penalty = Player.Penalty + 10
|
||||
PlayerHit.Penalty = PlayerHit.Penalty + 10
|
||||
local Penalty = 10
|
||||
Player.Penalty = Player.Penalty + Penalty
|
||||
PlayerHit.Penalty = PlayerHit.Penalty + Penalty
|
||||
PlayerHit.PenaltyHit = PlayerHit.PenaltyHit + 1
|
||||
|
||||
if TargetPlayerName ~= nil then -- It is a player hitting another player ...
|
||||
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit friendly player '" .. TargetPlayerName .. "' " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. PlayerHit.PenaltyHit .. " times. " ..
|
||||
"Penalty: -" .. PlayerHit.Penalty .. ". Score Total:" .. Player.Score - Player.Penalty,
|
||||
"Penalty: -" .. Penalty .. ". Score Total:" .. Player.Score - Player.Penalty,
|
||||
MESSAGE.Type.Update )
|
||||
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
|
||||
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
|
||||
else
|
||||
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit friendly target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. PlayerHit.PenaltyHit .. " times. " ..
|
||||
"Penalty: -" .. PlayerHit.Penalty .. ". Score Total:" .. Player.Score - Player.Penalty,
|
||||
"Penalty: -" .. Penalty .. ". Score Total:" .. Player.Score - Player.Penalty,
|
||||
MESSAGE.Type.Update )
|
||||
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
|
||||
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
|
||||
@ -1104,7 +1118,18 @@ function SCORING:_EventOnHit( Event )
|
||||
PlayerHit.PenaltyHit = PlayerHit.PenaltyHit or 0
|
||||
PlayerHit.TimeStamp = PlayerHit.TimeStamp or 0
|
||||
PlayerHit.UNIT = PlayerHit.UNIT or TargetUNIT
|
||||
-- After an instant kill we can't compute the thread level anymore. To fix this we compute at OnEventBirth
|
||||
if PlayerHit.UNIT.ThreatType == nil then
|
||||
PlayerHit.ThreatLevel, PlayerHit.ThreatType = PlayerHit.UNIT:GetThreatLevel()
|
||||
-- if this fails for some reason, set a good default value
|
||||
if PlayerHit.ThreatType == nil then
|
||||
PlayerHit.ThreatLevel = 1
|
||||
PlayerHit.ThreatType = "Unknown"
|
||||
end
|
||||
else
|
||||
PlayerHit.ThreatLevel = PlayerHit.UNIT.ThreatLevel
|
||||
PlayerHit.ThreatType = PlayerHit.UNIT.ThreatType
|
||||
end
|
||||
|
||||
-- Only grant hit scores if there was more than one second between the last hit.
|
||||
if timer.getTime() - PlayerHit.TimeStamp > 1 then
|
||||
@ -1115,14 +1140,15 @@ function SCORING:_EventOnHit( Event )
|
||||
if InitCoalition then -- A coalition object was hit, probably a static.
|
||||
if InitCoalition == TargetCoalition then
|
||||
-- TODO: Penalty according scale
|
||||
Player.Penalty = Player.Penalty + 10 --* self.ScaleDestroyPenalty
|
||||
PlayerHit.Penalty = PlayerHit.Penalty + 10 --* self.ScaleDestroyPenalty
|
||||
local Penalty = 10
|
||||
Player.Penalty = Player.Penalty + Penalty --* self.ScaleDestroyPenalty
|
||||
PlayerHit.Penalty = PlayerHit.Penalty + Penalty --* self.ScaleDestroyPenalty
|
||||
PlayerHit.PenaltyHit = PlayerHit.PenaltyHit + 1 * self.ScaleDestroyPenalty
|
||||
|
||||
MESSAGE
|
||||
:NewType( self.DisplayMessagePrefix .. "Player '" .. Event.WeaponPlayerName .. "' hit friendly target " ..
|
||||
TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
|
||||
"Penalty: -" .. PlayerHit.Penalty .. " = " .. Player.Score - Player.Penalty,
|
||||
"Penalty: -" .. Penalty .. " = " .. Player.Score - Player.Penalty,
|
||||
MESSAGE.Type.Update
|
||||
)
|
||||
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
|
||||
@ -1133,7 +1159,7 @@ function SCORING:_EventOnHit( Event )
|
||||
PlayerHit.Score = PlayerHit.Score + 1
|
||||
PlayerHit.ScoreHit = PlayerHit.ScoreHit + 1
|
||||
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. Event.WeaponPlayerName .. "' hit enemy target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
|
||||
"Score: +" .. PlayerHit.Score .. " = " .. Player.Score - Player.Penalty,
|
||||
"Score: " .. PlayerHit.Score .. ". Score Total:" .. Player.Score - Player.Penalty,
|
||||
MESSAGE.Type.Update )
|
||||
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
|
||||
:ToCoalitionIf( Event.WeaponCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
|
||||
@ -1211,7 +1237,7 @@ function SCORING:_EventOnDeadOrCrash( Event )
|
||||
local Destroyed = false
|
||||
|
||||
-- What is the player destroying?
|
||||
if Player and Player.Hit and Player.Hit[TargetCategory] and Player.Hit[TargetCategory][TargetUnitName] and Player.Hit[TargetCategory][TargetUnitName].TimeStamp ~= 0 then -- Was there a hit for this unit for this player before registered???
|
||||
if Player and Player.Hit and Player.Hit[TargetCategory] and Player.Hit[TargetCategory][TargetUnitName] and Player.Hit[TargetCategory][TargetUnitName].TimeStamp ~= 0 and (TargetUnit.BirthTime == nil or Player.Hit[TargetCategory][TargetUnitName].TimeStamp > TargetUnit.BirthTime) then -- Was there a hit for this unit for this player before registered???
|
||||
|
||||
local TargetThreatLevel = Player.Hit[TargetCategory][TargetUnitName].ThreatLevel
|
||||
local TargetThreatType = Player.Hit[TargetCategory][TargetUnitName].ThreatType
|
||||
@ -1240,13 +1266,13 @@ function SCORING:_EventOnDeadOrCrash( Event )
|
||||
|
||||
if Player.HitPlayers[TargetPlayerName] then -- A player destroyed another player
|
||||
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' destroyed friendly player '" .. TargetPlayerName .. "' " .. TargetUnitCategory .. " ( " .. ThreatTypeTarget .. " ) " ..
|
||||
"Penalty: -" .. TargetDestroy.Penalty .. " = " .. Player.Score - Player.Penalty,
|
||||
"Penalty: -" .. ThreatPenalty .. " = " .. Player.Score - Player.Penalty,
|
||||
MESSAGE.Type.Information )
|
||||
:ToAllIf( self:IfMessagesDestroy() and self:IfMessagesToAll() )
|
||||
:ToCoalitionIf( InitCoalition, self:IfMessagesDestroy() and self:IfMessagesToCoalition() )
|
||||
else
|
||||
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' destroyed friendly target " .. TargetUnitCategory .. " ( " .. ThreatTypeTarget .. " ) " ..
|
||||
"Penalty: -" .. TargetDestroy.Penalty .. " = " .. Player.Score - Player.Penalty,
|
||||
"Penalty: -" .. ThreatPenalty .. " = " .. Player.Score - Player.Penalty,
|
||||
MESSAGE.Type.Information )
|
||||
:ToAllIf( self:IfMessagesDestroy() and self:IfMessagesToAll() )
|
||||
:ToCoalitionIf( InitCoalition, self:IfMessagesDestroy() and self:IfMessagesToCoalition() )
|
||||
@ -1268,13 +1294,13 @@ function SCORING:_EventOnDeadOrCrash( Event )
|
||||
TargetDestroy.ScoreDestroy = TargetDestroy.ScoreDestroy + 1
|
||||
if Player.HitPlayers[TargetPlayerName] then -- A player destroyed another player
|
||||
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' destroyed enemy player '" .. TargetPlayerName .. "' " .. TargetUnitCategory .. " ( " .. ThreatTypeTarget .. " ) " ..
|
||||
"Score: +" .. TargetDestroy.Score .. " = " .. Player.Score - Player.Penalty,
|
||||
"Score: +" .. ThreatScore .. " = " .. Player.Score - Player.Penalty,
|
||||
MESSAGE.Type.Information )
|
||||
:ToAllIf( self:IfMessagesDestroy() and self:IfMessagesToAll() )
|
||||
:ToCoalitionIf( InitCoalition, self:IfMessagesDestroy() and self:IfMessagesToCoalition() )
|
||||
else
|
||||
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' destroyed enemy " .. TargetUnitCategory .. " ( " .. ThreatTypeTarget .. " ) " ..
|
||||
"Score: +" .. TargetDestroy.Score .. " = " .. Player.Score - Player.Penalty,
|
||||
"Score: +" .. ThreatScore .. " = " .. Player.Score - Player.Penalty,
|
||||
MESSAGE.Type.Information )
|
||||
:ToAllIf( self:IfMessagesDestroy() and self:IfMessagesToAll() )
|
||||
:ToCoalitionIf( InitCoalition, self:IfMessagesDestroy() and self:IfMessagesToCoalition() )
|
||||
|
||||
@ -715,7 +715,7 @@ do -- ZONE_CAPTURE_COALITION
|
||||
|
||||
local UnitHit = EventData.TgtUnit
|
||||
|
||||
if UnitHit.ClassName ~= "SCENERY" then
|
||||
if UnitHit and UnitHit.ClassName ~= "SCENERY" then
|
||||
-- Check if unit is inside the capture zone and that it is of the defending coalition.
|
||||
if UnitHit and UnitHit:IsInZone(self) and UnitHit:GetCoalition()==self.Coalition then
|
||||
|
||||
|
||||
@ -524,7 +524,7 @@ function AIRWING:FetchPayloadFromStock(UnitType, MissionType, Payloads)
|
||||
if a and b then -- I had the case that a or b were nil even though the self.payloads table was looking okay. Very strange! Seems to be solved by pre-selecting valid payloads.
|
||||
local performanceA=self:GetPayloadPeformance(a, MissionType)
|
||||
local performanceB=self:GetPayloadPeformance(b, MissionType)
|
||||
return (performanceA>performanceB) or (performanceA==performanceB and a.unlimited==true) or (performanceA==performanceB and a.unlimited==true and b.unlimited==true and a.navail>b.navail)
|
||||
return (performanceA>performanceB) or (performanceA==performanceB and a.unlimited==true and b.unlimited~=true) or (performanceA==performanceB and a.unlimited==true and b.unlimited==true and a.navail>b.navail)
|
||||
elseif not a then
|
||||
self:I(self.lid..string.format("FF ERROR in sortpayloads: a is nil"))
|
||||
return false
|
||||
|
||||
@ -713,8 +713,9 @@ do
|
||||
-- my_ctld.placeCratesAhead = false -- place crates straight ahead of the helicopter, in a random way. If true, crates are more neatly sorted.
|
||||
-- my_ctld.nobuildinloadzones = true -- forbid players to build stuff in LOAD zones if set to `true`
|
||||
-- my_ctld.movecratesbeforebuild = true -- crates must be moved once before they can be build. Set to false for direct builds.
|
||||
-- my_ctld.surfacetypes = {land.SurfaceType.LAND,land.SurfaceType.ROAD,land.SurfaceType.RUNWAY,land.SurfaceType.SHALLOW_WATER} -- surfaces for loading back objects
|
||||
--
|
||||
-- my_ctld.surfacetypes = {land.SurfaceType.LAND,land.SurfaceType.ROAD,land.SurfaceType.RUNWAY,land.SurfaceType.SHALLOW_WATER} -- surfaces for loading back objects.
|
||||
-- my_ctld.nobuildmenu = false -- if set to true effectively enforces to have engineers build/repair stuff for you.
|
||||
--
|
||||
-- ## 2.1 User functions
|
||||
--
|
||||
-- ### 2.1.1 Adjust or add chopper unit-type capabilities
|
||||
@ -732,6 +733,7 @@ do
|
||||
-- ["SA342Minigun"] = {type="SA342Minigun", crates=false, troops=true, cratelimit = 0, trooplimit = 2, length = 12, cargoweightlimit = 400},
|
||||
-- ["UH-1H"] = {type="UH-1H", crates=true, troops=true, cratelimit = 1, trooplimit = 8, length = 15, cargoweightlimit = 700},
|
||||
-- ["Mi-8MT"] = {type="Mi-8MT", crates=true, troops=true, cratelimit = 2, trooplimit = 12, length = 15, cargoweightlimit = 3000},
|
||||
-- ["Mi-8MTV2"] = {type="Mi-8MTV2", crates=true, troops=true, cratelimit = 2, trooplimit = 12, length = 15, cargoweightlimit = 3000},
|
||||
-- ["Ka-50"] = {type="Ka-50", crates=false, troops=false, cratelimit = 0, trooplimit = 0, length = 15, cargoweightlimit = 0},
|
||||
-- ["Mi-24P"] = {type="Mi-24P", crates=true, troops=true, cratelimit = 2, trooplimit = 8, length = 18, cargoweightlimit = 700},
|
||||
-- ["Mi-24V"] = {type="Mi-24V", crates=true, troops=true, cratelimit = 2, trooplimit = 8, length = 18, cargoweightlimit = 700},
|
||||
@ -1180,7 +1182,7 @@ CTLD.UnitTypes = {
|
||||
["SA342Minigun"] = {type="SA342Minigun", crates=false, troops=true, cratelimit = 0, trooplimit = 2, length = 12, cargoweightlimit = 400},
|
||||
["UH-1H"] = {type="UH-1H", crates=true, troops=true, cratelimit = 1, trooplimit = 8, length = 15, cargoweightlimit = 700},
|
||||
["Mi-8MTV2"] = {type="Mi-8MTV2", crates=true, troops=true, cratelimit = 2, trooplimit = 12, length = 15, cargoweightlimit = 3000},
|
||||
["Mi-8MT"] = {type="Mi-8MTV2", crates=true, troops=true, cratelimit = 2, trooplimit = 12, length = 15, cargoweightlimit = 3000},
|
||||
["Mi-8MT"] = {type="Mi-8MT", crates=true, troops=true, cratelimit = 2, trooplimit = 12, length = 15, cargoweightlimit = 3000},
|
||||
["Ka-50"] = {type="Ka-50", crates=false, troops=false, cratelimit = 0, trooplimit = 0, length = 15, cargoweightlimit = 0},
|
||||
["Ka-50_3"] = {type="Ka-50_3", crates=false, troops=false, cratelimit = 0, trooplimit = 0, length = 15, cargoweightlimit = 0},
|
||||
["Mi-24P"] = {type="Mi-24P", crates=true, troops=true, cratelimit = 2, trooplimit = 8, length = 18, cargoweightlimit = 700},
|
||||
@ -1194,7 +1196,7 @@ CTLD.UnitTypes = {
|
||||
|
||||
--- CTLD class version.
|
||||
-- @field #string version
|
||||
CTLD.version="1.0.27"
|
||||
CTLD.version="1.0.30"
|
||||
|
||||
--- Instantiate a new CTLD.
|
||||
-- @param #CTLD self
|
||||
@ -1306,6 +1308,7 @@ function CTLD:New(Coalition, Prefixes, Alias)
|
||||
self.Engineers = 0 -- #number use as counter
|
||||
self.EngineersInField = {} -- #table holds #CTLD_ENGINEERING objects
|
||||
self.EngineerSearch = 2000 -- #number search distance for crates to build or repair
|
||||
self.nobuildmenu = false -- enfore engineer build only?
|
||||
|
||||
-- setup
|
||||
self.CrateDistance = 35 -- list/load crates in this radius
|
||||
@ -1773,6 +1776,22 @@ function CTLD:_FindTroopsCargoObject(Name)
|
||||
return nil
|
||||
end
|
||||
|
||||
--- (Internal) Find a crates CTLD_CARGO object in stock
|
||||
-- @param #CTLD self
|
||||
-- @param #string Name of the object
|
||||
-- @return #CTLD_CARGO Cargo object, nil if it cannot be found
|
||||
function CTLD:_FindCratesCargoObject(Name)
|
||||
self:T(self.lid .. " _FindCratesCargoObject")
|
||||
local cargo = nil
|
||||
for _,_cargo in pairs(self.Cargo_Crates)do
|
||||
local cargo = _cargo -- #CTLD_CARGO
|
||||
if cargo.Name == Name then
|
||||
return cargo
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
--- (User) Pre-load troops into a helo, e.g. for airstart. Unit **must** be alive in-game, i.e. player has taken the slot!
|
||||
-- @param #CTLD self
|
||||
-- @param Wrapper.Unit#UNIT Unit The unit to load into, can be handed as Wrapper.Client#CLIENT object
|
||||
@ -1798,6 +1817,84 @@ function CTLD:PreloadTroops(Unit,Troopname)
|
||||
return self
|
||||
end
|
||||
|
||||
--- (Internal) Pre-load crates into a helo. Do not use standalone!
|
||||
-- @param #CTLD self
|
||||
-- @param Wrapper.Group#GROUP Group The group to load into, can be handed as Wrapper.Client#CLIENT object
|
||||
-- @param Wrapper.Unit#UNIT Unit The unit to load into, can be handed as Wrapper.Client#CLIENT object
|
||||
-- @param #CTLD_CARGO Cargo The Cargo crate object to load
|
||||
-- @param #number NumberOfCrates (Optional) Number of crates to be loaded. Default - all necessary to build this object. Might overload the helo!
|
||||
-- @return #CTLD self
|
||||
function CTLD:_PreloadCrates(Group, Unit, Cargo, NumberOfCrates)
|
||||
-- load crate into heli
|
||||
local group = Group -- Wrapper.Group#GROUP
|
||||
local unit = Unit -- Wrapper.Unit#UNIT
|
||||
local unitname = unit:GetName()
|
||||
-- see if this heli can load crates
|
||||
local unittype = unit:GetTypeName()
|
||||
local capabilities = self:_GetUnitCapabilities(Unit) -- #CTLD.UnitCapabilities
|
||||
local cancrates = capabilities.crates -- #boolean
|
||||
local cratelimit = capabilities.cratelimit -- #number
|
||||
if not cancrates then
|
||||
self:_SendMessage("Sorry this chopper cannot carry crates!", 10, false, Group)
|
||||
return self
|
||||
else
|
||||
-- have we loaded stuff already?
|
||||
local numberonboard = 0
|
||||
local massonboard = 0
|
||||
local loaded = {}
|
||||
if self.Loaded_Cargo[unitname] then
|
||||
loaded = self.Loaded_Cargo[unitname] -- #CTLD.LoadedCargo
|
||||
numberonboard = loaded.Cratesloaded or 0
|
||||
massonboard = self:_GetUnitCargoMass(Unit)
|
||||
else
|
||||
loaded = {} -- #CTLD.LoadedCargo
|
||||
loaded.Troopsloaded = 0
|
||||
loaded.Cratesloaded = 0
|
||||
loaded.Cargo = {}
|
||||
end
|
||||
local crate = Cargo -- #CTLD_CARGO
|
||||
local numbercrates = NumberOfCrates or crate:GetCratesNeeded()
|
||||
for i=1,numbercrates do
|
||||
loaded.Cratesloaded = loaded.Cratesloaded + 1
|
||||
crate:SetHasMoved(true)
|
||||
crate:SetWasDropped(false)
|
||||
table.insert(loaded.Cargo, crate)
|
||||
crate.Positionable = nil
|
||||
self:_SendMessage(string.format("Crate ID %d for %s loaded!",crate:GetID(),crate:GetName()), 10, false, Group)
|
||||
--self:__CratesPickedUp(1, Group, Unit, crate)
|
||||
self.Loaded_Cargo[unitname] = loaded
|
||||
self:_UpdateUnitCargoMass(Unit)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- (User) Pre-load crates into a helo, e.g. for airstart. Unit **must** be alive in-game, i.e. player has taken the slot!
|
||||
-- @param #CTLD self
|
||||
-- @param Wrapper.Unit#UNIT Unit The unit to load into, can be handed as Wrapper.Client#CLIENT object
|
||||
-- @param #string Cratesname The name of the cargo to be loaded. Must be created prior in the CTLD setup!
|
||||
-- @param #number NumberOfCrates (Optional) Number of crates to be loaded. Default - all necessary to build this object. Might overload the helo!
|
||||
-- @return #CTLD self
|
||||
-- @usage
|
||||
-- local client = UNIT:FindByName("Helo-1-1")
|
||||
-- if client and client:IsAlive() then
|
||||
-- myctld:PreloadCrates(client,"Humvee")
|
||||
-- end
|
||||
function CTLD:PreloadCrates(Unit,Cratesname,NumberOfCrates)
|
||||
self:T(self.lid .. " PreloadCrates")
|
||||
local name = Cratesname or "Unknown"
|
||||
if Unit and Unit:IsAlive() then
|
||||
local cargo = self:_FindCratesCargoObject(name)
|
||||
local group = Unit:GetGroup()
|
||||
if cargo then
|
||||
self:_PreloadCrates(group,Unit,cargo,NumberOfCrates)
|
||||
else
|
||||
self:E(self.lid.." Crates preload - Cargo Object "..name.." not found!")
|
||||
end
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- (Internal) Function to load troops into a heli.
|
||||
-- @param #CTLD self
|
||||
-- @param Wrapper.Group#GROUP Group
|
||||
@ -3323,6 +3420,12 @@ function CTLD:_RefreshF10Menus()
|
||||
self.subcats[entry.Subcategory] = entry.Subcategory
|
||||
end
|
||||
end
|
||||
for _id,_cargo in pairs(self.Cargo_Statics) do
|
||||
local entry = _cargo -- #CTLD_CARGO
|
||||
if not self.subcats[entry.Subcategory] then
|
||||
self.subcats[entry.Subcategory] = entry.Subcategory
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- build unit menus
|
||||
@ -3386,6 +3489,13 @@ function CTLD:_RefreshF10Menus()
|
||||
local menutext = string.format("Crate %s (%dkg)",entry.Name,entry.PerCrateMass or 0)
|
||||
menus[menucount] = MENU_GROUP_COMMAND:New(_group,menutext,subcatmenus[subcat],self._GetCrates, self, _group, _unit, entry)
|
||||
end
|
||||
for _,_entry in pairs(self.Cargo_Statics) do
|
||||
local entry = _entry -- #CTLD_CARGO
|
||||
local subcat = entry.Subcategory
|
||||
menucount = menucount + 1
|
||||
local menutext = string.format("Crate %s (%dkg)",entry.Name,entry.PerCrateMass or 0)
|
||||
menus[menucount] = MENU_GROUP_COMMAND:New(_group,menutext,subcatmenus[subcat],self._GetCrates, self, _group, _unit, entry)
|
||||
end
|
||||
else
|
||||
for _,_entry in pairs(self.Cargo_Crates) do
|
||||
local entry = _entry -- #CTLD_CARGO
|
||||
@ -3393,17 +3503,21 @@ function CTLD:_RefreshF10Menus()
|
||||
local menutext = string.format("Crate %s (%dkg)",entry.Name,entry.PerCrateMass or 0)
|
||||
menus[menucount] = MENU_GROUP_COMMAND:New(_group,menutext,cratesmenu,self._GetCrates, self, _group, _unit, entry)
|
||||
end
|
||||
end
|
||||
for _,_entry in pairs(self.Cargo_Statics) do
|
||||
local entry = _entry -- #CTLD_CARGO
|
||||
menucount = menucount + 1
|
||||
local menutext = string.format("Crate %s (%dkg)",entry.Name,entry.PerCrateMass or 0)
|
||||
menus[menucount] = MENU_GROUP_COMMAND:New(_group,menutext,cratesmenu,self._GetCrates, self, _group, _unit, entry)
|
||||
for _,_entry in pairs(self.Cargo_Statics) do
|
||||
local entry = _entry -- #CTLD_CARGO
|
||||
menucount = menucount + 1
|
||||
local menutext = string.format("Crate %s (%dkg)",entry.Name,entry.PerCrateMass or 0)
|
||||
menus[menucount] = MENU_GROUP_COMMAND:New(_group,menutext,cratesmenu,self._GetCrates, self, _group, _unit, entry)
|
||||
end
|
||||
end
|
||||
listmenu = MENU_GROUP_COMMAND:New(_group,"List crates nearby",topcrates, self._ListCratesNearby, self, _group, _unit)
|
||||
local unloadmenu = MENU_GROUP_COMMAND:New(_group,"Drop crates",topcrates, self._UnloadCrates, self, _group, _unit)
|
||||
local buildmenu = MENU_GROUP_COMMAND:New(_group,"Build crates",topcrates, self._BuildCrates, self, _group, _unit)
|
||||
local repairmenu = MENU_GROUP_COMMAND:New(_group,"Repair",topcrates, self._RepairCrates, self, _group, _unit):Refresh()
|
||||
if not self.nobuildmenu then
|
||||
local buildmenu = MENU_GROUP_COMMAND:New(_group,"Build crates",topcrates, self._BuildCrates, self, _group, _unit)
|
||||
local repairmenu = MENU_GROUP_COMMAND:New(_group,"Repair",topcrates, self._RepairCrates, self, _group, _unit):Refresh()
|
||||
else
|
||||
unloadmenu:Refresh()
|
||||
end
|
||||
end
|
||||
if self:IsHercules(_unit) then
|
||||
local hoverpars = MENU_GROUP_COMMAND:New(_group,"Show flight parameters",topmenu, self._ShowFlightParams, self, _group, _unit):Refresh()
|
||||
@ -3488,13 +3602,14 @@ end
|
||||
-- @param #string Name Unique name of this type of cargo as set in the mission editor (note: UNIT name!), e.g. "Ammunition-1".
|
||||
-- @param #number Mass Mass in kg of each static in kg, e.g. 100.
|
||||
-- @param #number Stock Number of groups in stock. Nil for unlimited.
|
||||
function CTLD:AddStaticsCargo(Name,Mass,Stock)
|
||||
-- @param #string SubCategory Name of sub-category (optional).
|
||||
function CTLD:AddStaticsCargo(Name,Mass,Stock,SubCategory)
|
||||
self:T(self.lid .. " AddStaticsCargo")
|
||||
self.CargoCounter = self.CargoCounter + 1
|
||||
local type = CTLD_CARGO.Enum.STATIC
|
||||
local template = STATIC:FindByName(Name,true):GetTypeName()
|
||||
-- Crates are not directly loadable
|
||||
local cargo = CTLD_CARGO:New(self.CargoCounter,Name,template,type,false,false,1,nil,nil,Mass,Stock)
|
||||
local cargo = CTLD_CARGO:New(self.CargoCounter,Name,template,type,false,false,1,nil,nil,Mass,Stock,SubCategory)
|
||||
table.insert(self.Cargo_Statics,cargo)
|
||||
return self
|
||||
end
|
||||
@ -5252,7 +5367,7 @@ CTLD_HERCULES = {
|
||||
ClassName = "CTLD_HERCULES",
|
||||
lid = "",
|
||||
Name = "",
|
||||
Version = "0.0.2",
|
||||
Version = "0.0.3",
|
||||
}
|
||||
|
||||
--- Define cargo types.
|
||||
@ -5570,8 +5685,8 @@ function CTLD_HERCULES:Cargo_SpawnObjects(Cargo_Drop_initiator,Cargo_Drop_Direct
|
||||
|
||||
if offload_cargo == true or ParatrooperGroupSpawn == true then
|
||||
if ParatrooperGroupSpawn == true then
|
||||
self:Soldier_SpawnGroup(Cargo_Drop_initiator,Cargo_Content_position, Cargo_Type_name, CargoHeading, Cargo_Country, 0)
|
||||
self:Soldier_SpawnGroup(Cargo_Drop_initiator,Cargo_Content_position, Cargo_Type_name, CargoHeading, Cargo_Country, 5)
|
||||
--self:Soldier_SpawnGroup(Cargo_Drop_initiator,Cargo_Content_position, Cargo_Type_name, CargoHeading, Cargo_Country, 0)
|
||||
--self:Soldier_SpawnGroup(Cargo_Drop_initiator,Cargo_Content_position, Cargo_Type_name, CargoHeading, Cargo_Country, 5)
|
||||
self:Soldier_SpawnGroup(Cargo_Drop_initiator,Cargo_Content_position, Cargo_Type_name, CargoHeading, Cargo_Country, 10)
|
||||
else
|
||||
self:Cargo_SpawnGroup(Cargo_Drop_initiator,Cargo_Content_position, Cargo_Type_name, CargoHeading, Cargo_Country)
|
||||
|
||||
@ -104,7 +104,7 @@ PLAYERRECCE = {
|
||||
ClassName = "PLAYERRECCE",
|
||||
verbose = true,
|
||||
lid = nil,
|
||||
version = "0.0.16",
|
||||
version = "0.0.17",
|
||||
ViewZone = {},
|
||||
ViewZoneVisual = {},
|
||||
ViewZoneLaser = {},
|
||||
@ -149,7 +149,8 @@ PLAYERRECCE.LaserRelativePos = {
|
||||
["SA342Mistral"] = { x = 1.7, y = 1.2, z = 0 },
|
||||
["SA342Minigun"] = { x = 1.7, y = 1.2, z = 0 },
|
||||
["SA342L"] = { x = 1.7, y = 1.2, z = 0 },
|
||||
["Ka-50"] = { x = 6.1, y = -0.85 , z = 0 }
|
||||
["Ka-50"] = { x = 6.1, y = -0.85 , z = 0 },
|
||||
["Ka-50_3"] = { x = 6.1, y = -0.85 , z = 0 }
|
||||
}
|
||||
|
||||
---
|
||||
@ -161,6 +162,7 @@ PLAYERRECCE.MaxViewDistance = {
|
||||
["SA342Minigun"] = 8000,
|
||||
["SA342L"] = 8000,
|
||||
["Ka-50"] = 8000,
|
||||
["Ka-50_3"] = 8000,
|
||||
}
|
||||
|
||||
---
|
||||
@ -172,6 +174,7 @@ PLAYERRECCE.Cameraheight = {
|
||||
["SA342Minigun"] = 2.85,
|
||||
["SA342L"] = 2.85,
|
||||
["Ka-50"] = 0.5,
|
||||
["Ka-50_3"] = 0.5,
|
||||
}
|
||||
|
||||
---
|
||||
@ -182,7 +185,8 @@ PLAYERRECCE.CanLase = {
|
||||
["SA342Mistral"] = true,
|
||||
["SA342Minigun"] = false, -- no optics
|
||||
["SA342L"] = true,
|
||||
["Ka-50"] = true,
|
||||
["Ka-50"] = true,
|
||||
["Ka-50_3"] = true,
|
||||
}
|
||||
|
||||
---
|
||||
@ -337,11 +341,7 @@ function PLAYERRECCE:_GetClockDirection(unit, target)
|
||||
clock = 12+hours
|
||||
clock = UTILS.Round(clock,0)
|
||||
if clock > 12 then clock = clock-12 end
|
||||
end
|
||||
--if self.debug then
|
||||
--local text = string.format("Heading = %d, Angle = %d, Hours= %d, Clock = %d",_heading,Angle,hours,clock)
|
||||
--self:I(self.lid .. text)
|
||||
--end
|
||||
end
|
||||
return clock
|
||||
end
|
||||
|
||||
@ -411,7 +411,7 @@ function PLAYERRECCE:_CameraOn(client,playername)
|
||||
if vivihorizontal < -0.7 or vivihorizontal > 0.7 then
|
||||
camera = false
|
||||
end
|
||||
elseif typename == "Ka-50" then
|
||||
elseif string.find(typename,"Ka-50") then
|
||||
camera = true
|
||||
end
|
||||
end
|
||||
@ -653,7 +653,7 @@ function PLAYERRECCE:_GetTargetSet(unit,camera,laser)
|
||||
angle=10
|
||||
-- Model nod and actual TV view don't compute
|
||||
maxview = self.MaxViewDistance[typename] or 5000
|
||||
elseif typename == "Ka-50" and camera then
|
||||
elseif string.find(typename,"Ka-50") and camera then
|
||||
heading = unit:GetHeading()
|
||||
nod,maxview,camon = 10,1000,true
|
||||
angle = 10
|
||||
|
||||
@ -43,6 +43,7 @@ Wrapper/Static.lua
|
||||
Wrapper/Airbase.lua
|
||||
Wrapper/Scenery.lua
|
||||
Wrapper/Marker.lua
|
||||
Wrapper/Weapon.lua
|
||||
|
||||
Cargo/Cargo.lua
|
||||
Cargo/CargoUnit.lua
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user