mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2026-08-31 07:44:30 +00:00
TARGET Scenery & PyBridge
This commit is contained in:
@@ -952,9 +952,19 @@ end
|
|||||||
function TARGET:OnEventUnitDeadOrLost(EventData)
|
function TARGET:OnEventUnitDeadOrLost(EventData)
|
||||||
|
|
||||||
local Name=EventData and EventData.IniUnitName or nil
|
local Name=EventData and EventData.IniUnitName or nil
|
||||||
|
|
||||||
|
local isElement=false
|
||||||
|
local isCasualty=nil
|
||||||
|
if Name then
|
||||||
|
isElement=self:IsElement(Name)
|
||||||
|
isCasualty=self:IsCasualty(Name)
|
||||||
|
printf("Dead/unit lost event for %s: isElement=%s, isCascualty=%s", tostring(Name), tostring(isElement), tostring(isCasualty))
|
||||||
|
else
|
||||||
|
self:E(self.lid..string.format("ERROR: Could not get name of Dead Unit"))
|
||||||
|
end
|
||||||
|
|
||||||
-- Check that this is the right group.
|
-- Check that this is the right group.
|
||||||
if self:IsElement(Name) and not self:IsCasualty(Name) then
|
if isElement and not isCasualty then
|
||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
self:T(self.lid..string.format("EVENT ID=%d: Unit %s dead or lost!", EventData.id, tostring(Name)))
|
self:T(self.lid..string.format("EVENT ID=%d: Unit %s dead or lost!", EventData.id, tostring(Name)))
|
||||||
@@ -1081,6 +1091,7 @@ function TARGET:_AddObject(Object)
|
|||||||
|
|
||||||
target.N0=target.N0+1
|
target.N0=target.N0+1
|
||||||
|
|
||||||
|
printf("FF target adding element %s", tostring(target.Name))
|
||||||
table.insert(self.elements, target.Name)
|
table.insert(self.elements, target.Name)
|
||||||
|
|
||||||
elseif Object:IsInstanceOf("AIRBASE") then
|
elseif Object:IsInstanceOf("AIRBASE") then
|
||||||
@@ -1957,7 +1968,7 @@ function TARGET:GetTargetByName(ObjectName)
|
|||||||
|
|
||||||
for _,_target in pairs(self.targets) do
|
for _,_target in pairs(self.targets) do
|
||||||
local target=_target --#TARGET.Object
|
local target=_target --#TARGET.Object
|
||||||
if ObjectName==target.Name then
|
if tostring(ObjectName)==tostring(target.Name) then
|
||||||
return target
|
return target
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -2165,7 +2176,7 @@ function TARGET:IsElement(Name)
|
|||||||
end
|
end
|
||||||
|
|
||||||
for _,name in pairs(self.elements) do
|
for _,name in pairs(self.elements) do
|
||||||
if name==Name then
|
if tostring(name)==tostring(Name) then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -309,7 +309,7 @@ function MOOSE_BRIDGE:_ResolveCoordinateFromInputs(inputs)
|
|||||||
local longitude = inputs.longitude ~= nil and tonumber(inputs.longitude) or nil
|
local longitude = inputs.longitude ~= nil and tonumber(inputs.longitude) or nil
|
||||||
if latitude and longitude then
|
if latitude and longitude then
|
||||||
if not coord or not coord.LLtoLO then return nil, "coord.LLtoLO is not available" end
|
if not coord or not coord.LLtoLO then return nil, "coord.LLtoLO is not available" end
|
||||||
local point = coord.LLtoLO({lat=latitude, lon=longitude, alt=0})
|
local point = coord.LLtoLO(latitude, longitude, 0)
|
||||||
if point then
|
if point then
|
||||||
x = tonumber(point.x)
|
x = tonumber(point.x)
|
||||||
z = tonumber(point.z)
|
z = tonumber(point.z)
|
||||||
@@ -441,6 +441,47 @@ function MOOSE_BRIDGE:_ResolveCoordinateAuftragTarget(inputs)
|
|||||||
return self:_ResolveCoordinateFromInputs(inputs)
|
return self:_ResolveCoordinateFromInputs(inputs)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function MOOSE_BRIDGE:_ResolveSceneryAuftragTarget(inputs)
|
||||||
|
local prefix, name = bridge_split_object_id(inputs.target_id)
|
||||||
|
if prefix ~= "SCENERY" or not name then return nil, "Invalid SCENERY target id" end
|
||||||
|
if not SCENERY or not SCENERY.Register then return nil, "MOOSE SCENERY wrapper is not available" end
|
||||||
|
|
||||||
|
local scenery_id = tonumber(name) or name
|
||||||
|
if SCENERY.FindByID then
|
||||||
|
local existing = SCENERY:FindByID(scenery_id)
|
||||||
|
local dcs_object = existing and existing.GetDCSObject and existing:GetDCSObject() or nil
|
||||||
|
if dcs_object then return existing, nil end
|
||||||
|
end
|
||||||
|
|
||||||
|
local coordinate, coordinate_err = self:_ResolveCoordinateFromInputs(inputs)
|
||||||
|
if not coordinate then return nil, coordinate_err end
|
||||||
|
if not world or not world.searchObjects or not world.VolumeType then
|
||||||
|
return nil, "DCS world.searchObjects is not available"
|
||||||
|
end
|
||||||
|
if not Object or not Object.Category or Object.Category.SCENERY == nil then
|
||||||
|
return nil, "DCS scenery object category is not available"
|
||||||
|
end
|
||||||
|
|
||||||
|
local center = coordinate.GetVec3 and coordinate:GetVec3() or nil
|
||||||
|
if not center then return nil, "SCENERY target coordinate is unavailable" end
|
||||||
|
local found = nil
|
||||||
|
local volume = {id=world.VolumeType.SPHERE, params={point=center, radius=150}}
|
||||||
|
world.searchObjects(Object.Category.SCENERY, volume, function(object)
|
||||||
|
local object_name = self:_DcsCall(object, "getName")
|
||||||
|
if object_name ~= nil and bridge_safe_tostring(object_name) == name then
|
||||||
|
found = object
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end)
|
||||||
|
if not found then return nil, "SCENERY target is not live-queryable: " .. name end
|
||||||
|
|
||||||
|
local scenery = SCENERY:Register(name, found)
|
||||||
|
local dcs_object = scenery and scenery.GetDCSObject and scenery:GetDCSObject() or nil
|
||||||
|
if not dcs_object then return nil, "SCENERY wrapper has no DCS object: " .. name end
|
||||||
|
return scenery, nil
|
||||||
|
end
|
||||||
|
|
||||||
function MOOSE_BRIDGE:_CommonAuftragCommandInputs(cmd)
|
function MOOSE_BRIDGE:_CommonAuftragCommandInputs(cmd)
|
||||||
local p = self:_CommandParams(cmd)
|
local p = self:_CommandParams(cmd)
|
||||||
local legacy_params = type(p.params) == "table" and p.params or {}
|
local legacy_params = type(p.params) == "table" and p.params or {}
|
||||||
@@ -644,6 +685,22 @@ function MOOSE_BRIDGE:_ResolveArtyTarget(inputs)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function MOOSE_BRIDGE:_ResolveStrikeTarget(inputs)
|
function MOOSE_BRIDGE:_ResolveStrikeTarget(inputs)
|
||||||
|
local prefix = inputs.target_id and bridge_split_object_id(inputs.target_id) or nil
|
||||||
|
if prefix == "SCENERY" then
|
||||||
|
local scenery, scenery_err = self:_ResolveSceneryAuftragTarget(inputs)
|
||||||
|
if scenery then
|
||||||
|
inputs.target_resolution = "scenery_object"
|
||||||
|
return scenery, nil
|
||||||
|
end
|
||||||
|
local coordinate, coordinate_err = self:_ResolveCoordinateFromInputs(inputs)
|
||||||
|
if coordinate then
|
||||||
|
inputs.target_resolution = "coordinate_fallback"
|
||||||
|
inputs.target_resolution_error = scenery_err
|
||||||
|
return coordinate, nil
|
||||||
|
end
|
||||||
|
return nil, scenery_err or coordinate_err
|
||||||
|
end
|
||||||
|
inputs.target_resolution = "coordinate"
|
||||||
return self:_ResolveCoordinateAuftragTarget(inputs)
|
return self:_ResolveCoordinateAuftragTarget(inputs)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1053,6 +1110,8 @@ function MOOSE_BRIDGE:_BuildAuftragCommandResult(action, auftrag, inputs)
|
|||||||
required_assets_max=inputs.required_assets_max,
|
required_assets_max=inputs.required_assets_max,
|
||||||
weapon_type=inputs.weapon_type,
|
weapon_type=inputs.weapon_type,
|
||||||
target=inputs.target_id,
|
target=inputs.target_id,
|
||||||
|
target_resolution=inputs.target_resolution,
|
||||||
|
target_resolution_error=inputs.target_resolution_error,
|
||||||
opszone=inputs.opszone_id,
|
opszone=inputs.opszone_id,
|
||||||
capture_coalition=inputs.capture_coalition,
|
capture_coalition=inputs.capture_coalition,
|
||||||
stay_in_zone_time_s=inputs.stay_in_zone_time_s,
|
stay_in_zone_time_s=inputs.stay_in_zone_time_s,
|
||||||
|
|||||||
@@ -85,6 +85,21 @@ function MOOSE_BRIDGE:_StartDcsEventForwarding()
|
|||||||
self.DcsRegisteredEvents[#self.DcsRegisteredEvents + 1] = EVENTS.Kill
|
self.DcsRegisteredEvents[#self.DcsRegisteredEvents + 1] = EVENTS.Kill
|
||||||
self:_Log("DCS Kill event forwarding enabled")
|
self:_Log("DCS Kill event forwarding enabled")
|
||||||
end
|
end
|
||||||
|
if bridge_event_available(EVENTS.MarkAdded) then
|
||||||
|
self:HandleEvent(EVENTS.MarkAdded)
|
||||||
|
self.DcsRegisteredEvents[#self.DcsRegisteredEvents + 1] = EVENTS.MarkAdded
|
||||||
|
self:_Log("DCS MarkAdded event forwarding enabled")
|
||||||
|
end
|
||||||
|
if bridge_event_available(EVENTS.MarkChange) then
|
||||||
|
self:HandleEvent(EVENTS.MarkChange)
|
||||||
|
self.DcsRegisteredEvents[#self.DcsRegisteredEvents + 1] = EVENTS.MarkChange
|
||||||
|
self:_Log("DCS MarkChange event forwarding enabled")
|
||||||
|
end
|
||||||
|
if bridge_event_available(EVENTS.MarkRemoved) then
|
||||||
|
self:HandleEvent(EVENTS.MarkRemoved)
|
||||||
|
self.DcsRegisteredEvents[#self.DcsRegisteredEvents + 1] = EVENTS.MarkRemoved
|
||||||
|
self:_Log("DCS MarkRemoved event forwarding enabled")
|
||||||
|
end
|
||||||
if bridge_event_available(EVENTS.MissionEnd) then
|
if bridge_event_available(EVENTS.MissionEnd) then
|
||||||
self:HandleEvent(EVENTS.MissionEnd)
|
self:HandleEvent(EVENTS.MissionEnd)
|
||||||
self.DcsRegisteredEvents[#self.DcsRegisteredEvents + 1] = EVENTS.MissionEnd
|
self.DcsRegisteredEvents[#self.DcsRegisteredEvents + 1] = EVENTS.MissionEnd
|
||||||
@@ -297,6 +312,49 @@ function MOOSE_BRIDGE:OnEventKill(EventData)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Forward one DCS F10 map-marker event without interpreting its text.
|
||||||
|
-- Marker commands remain a Python concern so the Lua bridge stays semantic
|
||||||
|
-- and does not couple mission scripts to verification workflows.
|
||||||
|
function MOOSE_BRIDGE:_ForwardMapMarker(EventData, event_name, dcs_event_name)
|
||||||
|
local ok, err = pcall(function()
|
||||||
|
if type(EventData) ~= "table" then error("Map marker event data is missing") end
|
||||||
|
local marker_id = EventData.MarkID or EventData.idx
|
||||||
|
if marker_id == nil then error("Map marker event has no marker ID") end
|
||||||
|
local point = EventData.MarkVec3 or EventData.pos
|
||||||
|
local coordinates = point and self:_CoordinatesForPoint(point, "ll") or {}
|
||||||
|
self:SendEvent(event_name, {
|
||||||
|
dcs_event_id=EventData.id,
|
||||||
|
dcs_event_name=dcs_event_name,
|
||||||
|
dcs_event_time=EventData.time,
|
||||||
|
marker_id=marker_id,
|
||||||
|
text=EventData.MarkText or EventData.text,
|
||||||
|
coalition=self:_CoalitionToName(EventData.MarkCoalition or EventData.coalition),
|
||||||
|
group_id=EventData.MarkGroupID or EventData.groupID,
|
||||||
|
player_name=EventData.PlayerName,
|
||||||
|
x=coordinates.x,
|
||||||
|
y=coordinates.y,
|
||||||
|
z=coordinates.z,
|
||||||
|
latitude=coordinates.latitude,
|
||||||
|
longitude=coordinates.longitude,
|
||||||
|
})
|
||||||
|
end)
|
||||||
|
if not ok then
|
||||||
|
self:_Log("Failed to forward " .. tostring(dcs_event_name) .. " event: " .. tostring(err))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function MOOSE_BRIDGE:OnEventMarkAdded(EventData)
|
||||||
|
self:_ForwardMapMarker(EventData, "map.marker.added", "S_EVENT_MARK_ADDED")
|
||||||
|
end
|
||||||
|
|
||||||
|
function MOOSE_BRIDGE:OnEventMarkChange(EventData)
|
||||||
|
self:_ForwardMapMarker(EventData, "map.marker.changed", "S_EVENT_MARK_CHANGE")
|
||||||
|
end
|
||||||
|
|
||||||
|
function MOOSE_BRIDGE:OnEventMarkRemoved(EventData)
|
||||||
|
self:_ForwardMapMarker(EventData, "map.marker.removed", "S_EVENT_MARK_REMOVED")
|
||||||
|
end
|
||||||
|
|
||||||
--- Forward DCS S_EVENT_MISSION_END as the authoritative Python session boundary.
|
--- Forward DCS S_EVENT_MISSION_END as the authoritative Python session boundary.
|
||||||
-- Flush immediately because normal bridge scheduling stops with the mission.
|
-- Flush immediately because normal bridge scheduling stops with the mission.
|
||||||
-- @param Core.Event#EVENTDATA EventData MOOSE-normalized DCS event data.
|
-- @param Core.Event#EVENTDATA EventData MOOSE-normalized DCS event data.
|
||||||
|
|||||||
@@ -60,7 +60,10 @@ function SCENERY:Register( SceneryName, SceneryObject, SceneryZone )
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if _SCENERY[ID] then return _SCENERY[ID] end
|
if _SCENERY[ID] then
|
||||||
|
BASE:I("Returning DCS scenery object found in _SCENERY table with ID")
|
||||||
|
return _SCENERY[ID]
|
||||||
|
end
|
||||||
|
|
||||||
local self = BASE:Inherit( self, POSITIONABLE:New( SceneryName ) )
|
local self = BASE:Inherit( self, POSITIONABLE:New( SceneryName ) )
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user