mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
#PLAYERRECCE
* Added switchable smoking of own position * Changed smoking - now laser target single, other targets as combined coordinate * Added battle field illumination * Added support for the KA-50. Note - camera is seen as "always on". For lasing, target needs to be head-on 12 o'clock
This commit is contained in:
parent
220e530bf3
commit
8279ac79c8
@ -2639,7 +2639,9 @@ do -- SET_UNIT
|
||||
-- @return Core.Point#COORDINATE The center coordinate of all the units in the set, including heading in degrees and speed in mps in case of moving units.
|
||||
function SET_UNIT:GetCoordinate()
|
||||
|
||||
local Coordinate = self:GetFirst():GetCoordinate()
|
||||
local Coordinate = self:GetRandom():GetCoordinate()
|
||||
--self:F({Coordinate:GetVec3()})
|
||||
|
||||
|
||||
local x1 = Coordinate.x
|
||||
local x2 = Coordinate.x
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
-- PLAYERRECCE
|
||||
-- TODO: PLAYERRECCE
|
||||
-- DONE: No messages when no targets to flare or smoke
|
||||
-- TODO: Flare smoke group, not all targets
|
||||
-- DONE: Flare not all targets
|
||||
-- DONE: Messages to Attack Group, use client settings
|
||||
-- DONE: Lasing dist 8km
|
||||
-- DONE: Reference Point RP
|
||||
@ -75,6 +75,8 @@
|
||||
-- @field Wrapper.Marker#MARKER RPMarker
|
||||
-- @field #number TForget
|
||||
-- @field Utilities.FiFo#FIFO TargetCache
|
||||
-- @field #boolean smokeownposition
|
||||
-- @field #table SmokeOwn
|
||||
-- @extends Core.Fsm#FSM
|
||||
|
||||
---
|
||||
@ -97,14 +99,14 @@ PLAYERRECCE = {
|
||||
ClassName = "PLAYERRECCE",
|
||||
verbose = true,
|
||||
lid = nil,
|
||||
version = "0.0.12",
|
||||
version = "0.0.15",
|
||||
ViewZone = {},
|
||||
ViewZoneVisual = {},
|
||||
ViewZoneLaser = {},
|
||||
LaserFOV = {},
|
||||
LaserTarget = {},
|
||||
PlayerSet = nil,
|
||||
debug = true,
|
||||
debug = false,
|
||||
LaserSpots = {},
|
||||
UnitLaserCodes = {},
|
||||
LaserCodes = {},
|
||||
@ -123,6 +125,8 @@ PLAYERRECCE = {
|
||||
ReferencePoint = nil,
|
||||
TForget = 600,
|
||||
TargetCache = nil,
|
||||
smokeownposition = true,
|
||||
SmokeOwn = {},
|
||||
}
|
||||
|
||||
---
|
||||
@ -140,6 +144,7 @@ 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 }
|
||||
}
|
||||
|
||||
---
|
||||
@ -150,6 +155,7 @@ PLAYERRECCE.MaxViewDistance = {
|
||||
["SA342Mistral"] = 8000,
|
||||
["SA342Minigun"] = 8000,
|
||||
["SA342L"] = 8000,
|
||||
["Ka-50"] = 8000,
|
||||
}
|
||||
|
||||
---
|
||||
@ -160,6 +166,7 @@ PLAYERRECCE.Cameraheight = {
|
||||
["SA342Mistral"] = 2.85,
|
||||
["SA342Minigun"] = 2.85,
|
||||
["SA342L"] = 2.85,
|
||||
["Ka-50"] = 0.5,
|
||||
}
|
||||
|
||||
---
|
||||
@ -170,6 +177,7 @@ PLAYERRECCE.CanLase = {
|
||||
["SA342Mistral"] = true,
|
||||
["SA342Minigun"] = false, -- no optics
|
||||
["SA342L"] = true,
|
||||
["Ka-50"] = true,
|
||||
}
|
||||
|
||||
---
|
||||
@ -230,6 +238,7 @@ function PLAYERRECCE:New(Name, Coalition, PlayerSet)
|
||||
self:AddTransition("*", "TargetDetected", "*")
|
||||
self:AddTransition("*", "TargetsSmoked", "*")
|
||||
self:AddTransition("*", "TargetsFlared", "*")
|
||||
self:AddTransition("*", "Illumination", "*")
|
||||
self:AddTransition("*", "TargetLasing", "*")
|
||||
self:AddTransition("*", "TargetLOSLost", "*")
|
||||
self:AddTransition("*", "TargetReport", "*")
|
||||
@ -387,10 +396,15 @@ function PLAYERRECCE:_CameraOn(client,playername)
|
||||
local camera = true
|
||||
local unit = client -- Wrapper.Unit#UNIT
|
||||
if unit and unit:IsAlive() then
|
||||
local dcsunit = Unit.getByName(client:GetName())
|
||||
local vivihorizontal = dcsunit:getDrawArgumentValue(215) or 0 -- (not in MiniGun) 1 to -1 -- zero is straight ahead, 1/-1 = 180 deg
|
||||
if vivihorizontal < -0.7 or vivihorizontal > 0.7 then
|
||||
camera = false
|
||||
local typename = unit:GetTypeName()
|
||||
if string.find(typename,"SA342") then
|
||||
local dcsunit = Unit.getByName(client:GetName())
|
||||
local vivihorizontal = dcsunit:getDrawArgumentValue(215) or 0 -- (not in MiniGun) 1 to -1 -- zero is straight ahead, 1/-1 = 180 deg
|
||||
if vivihorizontal < -0.7 or vivihorizontal > 0.7 then
|
||||
camera = false
|
||||
end
|
||||
elseif typename == "Ka-50" then
|
||||
camera = true
|
||||
end
|
||||
end
|
||||
return camera
|
||||
@ -537,7 +551,7 @@ function PLAYERRECCE:_GetViewZone(unit, vheading, minview, maxview, angle, camon
|
||||
local startp = unit:GetCoordinate()
|
||||
local heading1 = (vheading+90)%360
|
||||
local heading2 = (vheading-90)%360
|
||||
self:I({heading1,heading2})
|
||||
self:T({heading1,heading2})
|
||||
local startpos = startp:Translate(minview,vheading)
|
||||
local pos1 = startpos:Translate(10,heading1)
|
||||
local pos2 = startpos:Translate(10,heading2)
|
||||
@ -612,7 +626,7 @@ end
|
||||
--@param #PLAYERRECCE self
|
||||
--@param Wrapper.Unit#UNIT unit The FACA unit
|
||||
--@param #boolean camera If true, use the unit's camera for targets in sight
|
||||
--@param #laser Use laser zone
|
||||
--@param #laser laser Use laser zone
|
||||
--@return Core.Set#SET_UNIT Set of targets, can be empty!
|
||||
--@return #number count Count of targets
|
||||
function PLAYERRECCE:_GetTargetSet(unit,camera,laser)
|
||||
@ -631,6 +645,11 @@ 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
|
||||
heading = unit:GetHeading()
|
||||
nod,maxview,camon = 10,1000,true
|
||||
angle = 10
|
||||
maxview = self.MaxViewDistance[typename] or 5000
|
||||
else
|
||||
-- visual
|
||||
heading = unit:GetHeading()
|
||||
@ -741,7 +760,7 @@ function PLAYERRECCE:_LaseTarget(client,targetset)
|
||||
-- still looking at target?
|
||||
local target=self.LaserTarget[playername] -- Ops.Target#TARGET
|
||||
local oldtarget = target:GetObject() --or laser.Target
|
||||
self:I("Targetstate: "..target:GetState())
|
||||
self:T("Targetstate: "..target:GetState())
|
||||
if not oldtarget or targetset:IsNotInSet(oldtarget) or target:IsDead() or target:IsDestroyed() then
|
||||
-- lost LOS or dead
|
||||
laser:LaseOff()
|
||||
@ -805,6 +824,28 @@ function PLAYERRECCE:_SwitchOnStation(client,group,playername)
|
||||
return self
|
||||
end
|
||||
|
||||
--- [Internal]
|
||||
-- @param #PLAYERRECCE self
|
||||
-- @param Wrapper.Client#CLIENT client
|
||||
-- @param Wrapper.Group#GROUP group
|
||||
-- @param #string playername
|
||||
-- @return #PLAYERRECCE self
|
||||
function PLAYERRECCE:_SwitchSmoke(client,group,playername)
|
||||
self:T(self.lid.."_SwitchLasing")
|
||||
if not self.SmokeOwn[playername] then
|
||||
self.SmokeOwn[playername] = true
|
||||
MESSAGE:New("Smoke self is now ON",10,self.Name or "FACA"):ToClient(client)
|
||||
else
|
||||
self.SmokeOwn[playername] = false
|
||||
MESSAGE:New("Smoke self is now OFF",10,self.Name or "FACA"):ToClient(client)
|
||||
end
|
||||
if self.ClientMenus[playername] then
|
||||
self.ClientMenus[playername]:Remove()
|
||||
self.ClientMenus[playername]=nil
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- [Internal]
|
||||
-- @param #PLAYERRECCE self
|
||||
-- @param Wrapper.Client#CLIENT client
|
||||
@ -863,7 +904,7 @@ end
|
||||
-- @param #string playername
|
||||
-- @return #PLAYERRECCE self
|
||||
function PLAYERRECCE:_WIP(client,group,playername)
|
||||
self:I(self.lid.."_WIP")
|
||||
self:T(self.lid.."_WIP")
|
||||
return self
|
||||
end
|
||||
|
||||
@ -878,14 +919,17 @@ function PLAYERRECCE:_SmokeTargets(client,group,playername)
|
||||
local cameraset = self:_GetTargetSet(client,true) -- Core.Set#SET_UNIT
|
||||
local visualset = self:_GetTargetSet(client,false) -- Core.Set#SET_UNIT
|
||||
cameraset:AddSet(visualset)
|
||||
|
||||
if cameraset:CountAlive() > 0 then
|
||||
self:__TargetsSmoked(-1,client,playername,cameraset)
|
||||
end
|
||||
|
||||
local highsmoke = self.SmokeColor.highsmoke
|
||||
local medsmoke = self.SmokeColor.medsmoke
|
||||
local lowsmoke = self.SmokeColor.lowsmoke
|
||||
local lasersmoke = self.SmokeColor.lasersmoke
|
||||
local laser = self.LaserSpots[playername] -- Core.Spot#SPOT
|
||||
|
||||
-- laser targer gets extra smoke
|
||||
if laser and laser.Target and laser.Target:IsAlive() then
|
||||
laser.Target:GetCoordinate():Smoke(lasersmoke)
|
||||
@ -893,23 +937,27 @@ function PLAYERRECCE:_SmokeTargets(client,group,playername)
|
||||
cameraset:Remove(laser.Target:GetName(),true)
|
||||
end
|
||||
end
|
||||
|
||||
-- smoke everything else
|
||||
for _,_unit in pairs(cameraset.Set) do
|
||||
local unit = _unit --Wrapper.Unit#UNIT
|
||||
if unit then
|
||||
local coord = unit:GetCoordinate()
|
||||
local threat = unit:GetThreatLevel()
|
||||
if coord then
|
||||
local color = lowsmoke
|
||||
if threat > 7 then
|
||||
color = medsmoke
|
||||
elseif threat > 2 then
|
||||
color = lowsmoke
|
||||
end
|
||||
coord:Smoke(color)
|
||||
end
|
||||
local coordinate = cameraset:GetCoordinate()
|
||||
local setthreat = cameraset:CalculateThreatLevelA2G()
|
||||
|
||||
if coordinate then
|
||||
local color = lowsmoke
|
||||
if setthreat > 7 then
|
||||
color = medsmoke
|
||||
elseif setthreat > 2 then
|
||||
color = lowsmoke
|
||||
end
|
||||
coordinate:Smoke(color)
|
||||
end
|
||||
|
||||
if self.SmokeOwn[playername] then
|
||||
local cc = client:GetCoordinate()
|
||||
local color = self.SmokeColor.ownsmoke
|
||||
cc:Smoke(color)
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
@ -959,6 +1007,24 @@ function PLAYERRECCE:_FlareTargets(client,group,playername)
|
||||
return self
|
||||
end
|
||||
|
||||
--- [Internal]
|
||||
-- @param #PLAYERRECCE self
|
||||
-- @param Wrapper.Client#CLIENT client
|
||||
-- @param Wrapper.Group#GROUP group
|
||||
-- @param #string playername
|
||||
-- @return #PLAYERRECCE self
|
||||
function PLAYERRECCE:_IlluTargets(client,group,playername)
|
||||
self:T(self.lid.."_IlluTargets")
|
||||
local totalset, count = self:_GetKnownTargets(client) -- Core.Set#SET_UNIT
|
||||
if count > 0 then
|
||||
local coord = totalset:GetCoordinate() -- Core.Point#COORDINATE
|
||||
coord.y = coord.y + 200
|
||||
coord:IlluminationBomb(nil,1)
|
||||
self:__Illumination(1,client,playername,totalset)
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- [Internal]
|
||||
-- @param #PLAYERRECCE self
|
||||
-- @param Wrapper.Client#CLIENT client
|
||||
@ -1080,6 +1146,9 @@ function PLAYERRECCE:_BuildMenus()
|
||||
if not self.UnitLaserCodes[playername] then
|
||||
self:_SetClientLaserCode(nil,nil,playername,1688)
|
||||
end
|
||||
if not self.SmokeOwn[playername] then
|
||||
self.SmokeOwn[playername] = self.smokeownposition
|
||||
end
|
||||
local group = client:GetGroup()
|
||||
if not self.ClientMenus[playername] then
|
||||
local canlase = self.CanLase[client:GetTypeName()]
|
||||
@ -1088,8 +1157,13 @@ function PLAYERRECCE:_BuildMenus()
|
||||
local text = string.format("Switch On-Station (%s)",txtonstation)
|
||||
local onstationmenu = MENU_GROUP_COMMAND:New(group,text,self.ClientMenus[playername],self._SwitchOnStation,self,client,group,playername)
|
||||
if self.OnStation[playername] then
|
||||
local smokemenu = MENU_GROUP_COMMAND:New(group,"Smoke Targets",self.ClientMenus[playername],self._SmokeTargets,self,client,group,playername)
|
||||
local smokemenu = MENU_GROUP_COMMAND:New(group,"Flare Targets",self.ClientMenus[playername],self._FlareTargets,self,client,group,playername)
|
||||
local smoketopmenu = MENU_GROUP:New(group,"Visual Markers",self.ClientMenus[playername])
|
||||
local smokemenu = MENU_GROUP_COMMAND:New(group,"Smoke Targets",smoketopmenu,self._SmokeTargets,self,client,group,playername)
|
||||
local flaremenu = MENU_GROUP_COMMAND:New(group,"Flare Targets",smoketopmenu,self._FlareTargets,self,client,group,playername)
|
||||
local illumenu = MENU_GROUP_COMMAND:New(group,"Illuminate Area",smoketopmenu,self._IlluTargets,self,client,group,playername)
|
||||
local ownsm = self.SmokeOwn[playername] and "ON" or "OFF"
|
||||
local owntxt = string.format("Switch smoke self (%s)",ownsm)
|
||||
local ownsmoke = MENU_GROUP_COMMAND:New(group,owntxt,smoketopmenu,self._SwitchSmoke,self,client,group,playername)
|
||||
if canlase then
|
||||
local txtonstation = self.AutoLase[playername] and "ON" or "OFF"
|
||||
local text = string.format("Switch Lasing (%s)",txtonstation)
|
||||
@ -1195,7 +1269,7 @@ function PLAYERRECCE:_CheckNewTargets(targetset,client,playername)
|
||||
table.insert(targetsbyclock[clock],obj)
|
||||
end
|
||||
)
|
||||
self:I("Known target Count: "..self.TargetCache:Count())
|
||||
self:T("Known target Count: "..self.TargetCache:Count())
|
||||
if tempset:CountAlive() > 0 then
|
||||
self:TargetDetected(targetsbyclock,client,playername)
|
||||
end
|
||||
@ -1267,6 +1341,24 @@ function PLAYERRECCE:SetMenuName(Name)
|
||||
return self
|
||||
end
|
||||
|
||||
--- [User] Enable smoking of own position
|
||||
-- @param #PLAYERRECCE self
|
||||
-- @return #PLAYERRECCE self
|
||||
function PLAYERRECCE:EnableSmokeOwnPosition()
|
||||
self:T(self.lid.."ENableSmokeOwnPosition")
|
||||
self.smokeownposition = true
|
||||
return self
|
||||
end
|
||||
|
||||
--- [User] Disable smoking of own position
|
||||
-- @param #PLAYERRECCE self
|
||||
-- @return #PLAYERRECCE
|
||||
function PLAYERRECCE:DisableSmokeOwnPosition()
|
||||
self:T(self.lid.."DisableSmokeOwnPosition")
|
||||
self.smokeownposition = false
|
||||
return self
|
||||
end
|
||||
|
||||
--- [Internal] Get text for text-to-speech.
|
||||
-- Numbers are spaced out, e.g. "Heading 180" becomes "Heading 1 8 0 ".
|
||||
-- @param #PLAYERRECCE self
|
||||
@ -1351,7 +1443,7 @@ function PLAYERRECCE:onafterStatus(From, Event, To)
|
||||
self.ViewZoneLaser[playername]=lzone:DrawZone(self.Coalition,{0,1,0},nil,nil,nil,1)
|
||||
end
|
||||
end
|
||||
self:I({lasercount=targetcount})
|
||||
self:T({lasercount=targetcount})
|
||||
end
|
||||
-- visual targets
|
||||
vistargetset, vistargetcount, viszone = self:_GetTargetSet(client,false)
|
||||
@ -1489,9 +1581,18 @@ function PLAYERRECCE:onafterTargetDetected(From, Event, To, Targetsbyclock, Clie
|
||||
end
|
||||
if Settings:IsMetric() then
|
||||
targetdistance = UTILS.Round(targetdistance,-2)
|
||||
if targetdistance >= 1000 then
|
||||
targetdistance = UTILS.Round(targetdistance/1000,0)
|
||||
dunits = "kilometer"
|
||||
end
|
||||
else
|
||||
targetdistance = UTILS.Round(UTILS.MetersToFeet(targetdistance),-2)
|
||||
dunits = "feet"
|
||||
if UTILS.MetersToNM(targetdistance) >=1 then
|
||||
targetdistance = UTILS.Round(UTILS.MetersToNM(targetdistance),0)
|
||||
dunits = "miles"
|
||||
else
|
||||
targetdistance = UTILS.Round(UTILS.MetersToFeet(targetdistance),-2)
|
||||
dunits = "feet"
|
||||
end
|
||||
end
|
||||
local text = string.format("Target! %s! %s o\'clock, %d %s!", ThreatTxt,i, targetdistance, dunits)
|
||||
local ttstext = string.format("Target! %s! %s oh clock, %d %s!", ThreatTxt, i, targetdistance, dunits)
|
||||
@ -1516,9 +1617,18 @@ function PLAYERRECCE:onafterTargetDetected(From, Event, To, Targetsbyclock, Clie
|
||||
local targetdistance = GetNearest(targets)
|
||||
if Settings:IsMetric() then
|
||||
targetdistance = UTILS.Round(targetdistance,-2)
|
||||
if targetdistance >= 1000 then
|
||||
targetdistance = UTILS.Round(targetdistance/1000,0)
|
||||
dunits = "kilometer"
|
||||
end
|
||||
else
|
||||
targetdistance = UTILS.Round(UTILS.MetersToFeet(targetdistance),-2)
|
||||
dunits = "feet"
|
||||
if UTILS.MetersToNM(targetdistance) >=1 then
|
||||
targetdistance = UTILS.Round(UTILS.MetersToNM(targetdistance),0)
|
||||
dunits = "miles"
|
||||
else
|
||||
targetdistance = UTILS.Round(UTILS.MetersToFeet(targetdistance),-2)
|
||||
dunits = "feet"
|
||||
end
|
||||
end
|
||||
local text = string.format(" %d targets! %s o\'clock, %d %s!", targetno, i, targetdistance, dunits)
|
||||
local ttstext = string.format("%d targets! %s oh clock, %d %s!", targetno, i, targetdistance, dunits)
|
||||
@ -1533,6 +1643,45 @@ function PLAYERRECCE:onafterTargetDetected(From, Event, To, Targetsbyclock, Clie
|
||||
return self
|
||||
end
|
||||
|
||||
--- [Internal] Targets Illuminated
|
||||
-- @param #PLAYERRECCE self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @param Wrapper.Client#CLIENT Client
|
||||
-- @param #string Playername
|
||||
-- @param Core.Set#SET_UNIT TargetSet
|
||||
-- @return #PLAYERRECCE self
|
||||
function PLAYERRECCE:onafterIllumination(From, Event, To, Client, Playername, TargetSet)
|
||||
self:T({From, Event, To})
|
||||
local callsign = Client:GetGroup():GetCustomCallSign(self.ShortCallsign,self.Keepnumber,self.CallsignTranslations)
|
||||
local coord = Client:GetCoordinate()
|
||||
local coordtext = coord:ToStringBULLS(self.Coalition)
|
||||
if self.AttackSet then
|
||||
for _,_client in pairs(self.AttackSet.Set) do
|
||||
local client = _client --Wrapper.Client#CLIENT
|
||||
if client and client:IsAlive() then
|
||||
local Settings = client and _DATABASE:GetPlayerSettings(client:GetPlayerName()) or _SETTINGS
|
||||
local coordtext = coord:ToStringA2G(client,Settings)
|
||||
if self.ReferencePoint then
|
||||
coordtext = coord:ToStringFromRPShort(self.ReferencePoint,self.RPName,client,Settings)
|
||||
end
|
||||
local text = string.format("All stations, %s fired illumination\nat %s!",callsign, coordtext)
|
||||
MESSAGE:New(text,15,self.Name or "FACA"):ToClient(client)
|
||||
end
|
||||
end
|
||||
end
|
||||
local text = "Sunshine!"
|
||||
local ttstext = "Sunshine!"
|
||||
if self.UseSRS then
|
||||
local grp = Client:GetGroup()
|
||||
self.SRSQueue:NewTransmission(ttstext,nil,self.SRS,nil,1,{grp},text,10)
|
||||
else
|
||||
MESSAGE:New(text,10,self.Name or "FACA"):ToClient(Client)
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- [Internal] Targets Smoked
|
||||
-- @param #PLAYERRECCE self
|
||||
-- @param #string From
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user