mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Merge branch 'master' into funkyfranky
This commit is contained in:
commit
1e2a84608f
565
Moose Development/Documentation/DCS_ControlAPI.txt
Normal file
565
Moose Development/Documentation/DCS_ControlAPI.txt
Normal file
@ -0,0 +1,565 @@
|
||||
DCS Simulation Control User Scripts
|
||||
====================================
|
||||
|
||||
The behaviour of the DCS can be altered using the *GameGUI.lua scripts.
|
||||
You define the hooks to the DCS events, and then do what you want using the provided API.
|
||||
===================================================================================================
|
||||
|
||||
When loading, DCS searches for Saved Games\DCS\Scripts\*GameGUI.lua files,
|
||||
sorts them by name and then loads into the GUI Lua-state.
|
||||
Each user script is loaded into an isolated environment, so the only
|
||||
thing they share is the state of the simulator.
|
||||
|
||||
Each script defines a set of callbacks to the DCS events and sets them with the call
|
||||
DCS.setUserCallbacks(cb_table)
|
||||
For each callback type the hooks of all user scripts will be called in order of loading.
|
||||
|
||||
For callbacks which are supposed to returning a value, currently there are 3 of them:
|
||||
onPlayerTryConnect
|
||||
onPlayerTrySendChat
|
||||
onPlayerTryChangeSlot
|
||||
returning a value means breaking the hook call chain.
|
||||
Returning nothing (or nil) means continuing the hook chain, which ends with the default allow-all handlers.
|
||||
|
||||
The example user script 'testGameGUI.lua':
|
||||
----------------------------------------------------------------------------------------------
|
||||
local test = {}
|
||||
|
||||
function test.onPlayerTryConnect(ipaddr, name, ucid, playerID)
|
||||
print('onPlayerTryConnect(%s, %s, %s, %d)', ipaddr, name, ucid, playerID)
|
||||
-- if you want to gently intercept the call, allowing other user scripts to get it,
|
||||
-- you better return nothing here
|
||||
return true -- allow the player to connect
|
||||
end
|
||||
|
||||
function test.onSimulationStart()
|
||||
print('Current mission is '..DCS.getMissionName())
|
||||
end
|
||||
|
||||
DCS.setUserCallbacks(test) -- here we set our callbacks
|
||||
----------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
The available API are documented below.
|
||||
The full list of the callbacks is at the end of this document.
|
||||
|
||||
In addition, all standard lua 5.1 libraries are available as well, namely:
|
||||
base api, like print, etc,
|
||||
math.*
|
||||
table.*
|
||||
string.*
|
||||
io.*
|
||||
os.*
|
||||
debug.*
|
||||
|
||||
===================================================================================================
|
||||
|
||||
|
||||
|
||||
Lua File System (lfs) API
|
||||
-------------------------------
|
||||
lfs.currentdir() -> string
|
||||
Returns the path of the DCS install folder
|
||||
|
||||
lfs.writedir() -> string
|
||||
Returns the path of the current 'Saved Games\DCS' folder.
|
||||
|
||||
lfs.tempdir() -> string
|
||||
Returns the pat of the DCS Temp folder (AppData\Local\Temp\DCS).
|
||||
|
||||
lfs.mkdir()
|
||||
lfs.rmdir()
|
||||
lfs.attributes()
|
||||
lfs.dir()
|
||||
lfs.normpath()
|
||||
lfs.realpath()
|
||||
|
||||
|
||||
|
||||
DCS Control API, table 'DCS.*'
|
||||
-------------------------------
|
||||
|
||||
DCS.setPause(bool)
|
||||
Pauses/resumes the simulation. Server-side only.
|
||||
|
||||
DCS.getPause() -> bool
|
||||
true if simulation is paused
|
||||
|
||||
DCS.stopMission()
|
||||
stops current mission
|
||||
|
||||
DCS.exitProcess()
|
||||
Exits the DCS process.
|
||||
|
||||
DCS.isMultiplayer() -> bool
|
||||
True when running in the multiplayer mode.
|
||||
|
||||
DCS.isServer() -> bool
|
||||
True when running as a server or in the single-player mode.
|
||||
|
||||
DCS.getModelTime() -> number
|
||||
returns current DCS simulation time in seconds.
|
||||
|
||||
DCS.getRealTime() -> number
|
||||
returns current DCS real time in seconds relative to the DCS start time.
|
||||
|
||||
DCS.getMissionOptions() -> table
|
||||
Returns the value of 'mission.options'
|
||||
|
||||
DCS.getMissionDescription() -> string
|
||||
translated mission.descriptionText string
|
||||
|
||||
DCS.getAvailableCoalitions() -> table {
|
||||
[coalition_id] = { name = "coalition name", }
|
||||
...
|
||||
}
|
||||
Returns a list of coalitions which have available slots.
|
||||
|
||||
DCS.getAvailableSlots(coalitionID) -> array of {unitId, type, role, callsign, groupName, country}
|
||||
Returns the list of available slots.
|
||||
NOTE: the returned unitID is actually a slotID, which for multi-seat units is 'unitID_seatID'
|
||||
|
||||
DCS.getCurrentMission() -> table with the currently loaded mission
|
||||
NOTE: to get valid mission.options use DCS.getMissionOptions()
|
||||
|
||||
DCS.getMissionName() -> string
|
||||
Returns the name of the current mission
|
||||
|
||||
DCS.getMissionFilename() -> string
|
||||
Returns the file name of the current mission (returns nil when acting as a multiplayer client).
|
||||
|
||||
DCS.getMissionResult(string side) -> integer [0, 100]
|
||||
Gets missin result for either 'red' or 'blue'
|
||||
|
||||
DCS.getUnitProperty(missionId, propertyId) -> string
|
||||
propertyId:
|
||||
DCS.UNIT_RUNTIME_ID, // unique within runtime mission. int
|
||||
DCS.UNIT_MISSION_ID, // unique within mission file. int>0
|
||||
DCS.UNIT_NAME, // unit name, as assigned by mission designer.
|
||||
DCS.UNIT_TYPE, // unit type (Ural, ZU-23, etc)
|
||||
DCS.UNIT_CATEGORY,
|
||||
DCS.UNIT_GROUP_MISSION_ID, // group ID, unique within mission file. int>0
|
||||
DCS.UNIT_GROUPNAME, // group name, as assigned by mission designer.
|
||||
DCS.UNIT_GROUPCATEGORY,
|
||||
DCS.UNIT_CALLSIGN,
|
||||
DCS.UNIT_HIDDEN,// ME hiding
|
||||
DCS.UNIT_COALITION,// "blue", "red" or "unknown"
|
||||
DCS.UNIT_COUNTRY_ID,
|
||||
DCS.UNIT_TASK, //"unit.group.task"
|
||||
DCS.UNIT_PLAYER_NAME, // valid for network "humanable" units
|
||||
DCS.UNIT_ROLE,//"artillery_commander", "instructor", etc
|
||||
DCS.UNIT_INVISIBLE_MAP_ICON,//ME invisible map icon
|
||||
|
||||
DCS.getUnitType(missionId) -> typeId
|
||||
a shortcut for DCS.getUnitProperty(missionId, DCS.UNIT_TYPE)
|
||||
|
||||
DCS.getUnitTypeAttribute(typeId, attr) -> string
|
||||
Returns a value from Database: Objects[typeId][attr],
|
||||
for example DCS.getUnitTypeAttribute("Ural", "DisplayName")
|
||||
|
||||
DCS.writeDebriefing(str)
|
||||
Writes a custom string to the debriefing file
|
||||
|
||||
DCS.setUserCallbacks(cb_table)
|
||||
Hooks the callbacks using the handlers from the provided table.
|
||||
See: "GameGUI scripts" section.
|
||||
|
||||
|
||||
|
||||
Logging API 'log.*'
|
||||
------------------------
|
||||
Logging works as follows:
|
||||
a) each log message is accompanied with 2 attributes: a subsystem, and level.
|
||||
b) after each messages gets into a logger it passes (asynchronously) through
|
||||
a series of output filters which decide where the message will be written to.
|
||||
|
||||
Writing to log is done by:
|
||||
|
||||
log.write(SUBSYSTEM_NAME, LOG_LEVEL, message, ...)
|
||||
if there are any arguments after 'message',
|
||||
the actual string is formed as string.format(message, ...)
|
||||
|
||||
SUBSYSTEM_NAME is a string
|
||||
LOG_LEVEL is one of the values, listed below
|
||||
see log.set_output()
|
||||
|
||||
log.set_output(log_file_name_wo_ext, rule_subsystem_name, rule_level_mask, rule_output_mode)
|
||||
|
||||
the args:
|
||||
log_file_name_wo_ext: resulting log will be written to $WRITE_DIR/Logs/<log_file_name_wo_ext>.log
|
||||
|
||||
rule_subsytem_name: the name of the subsystem whose messages to write or empty string to match all subsystems
|
||||
|
||||
rule_level_mask: a sum of log-level bit flags to match messages
|
||||
valid flags are:
|
||||
log.ALERT
|
||||
log.ERROR
|
||||
log.WARNING
|
||||
log.INFO
|
||||
log.DEBUG
|
||||
log.ALL - includes all of the above
|
||||
log.TRACE - a special level which is excluded from dcs.log file
|
||||
|
||||
rule_output_mode: a sum of output flags:
|
||||
log.MESSAGE
|
||||
log.TIME
|
||||
log.MODULE - this is a 'subsystem', not a dlc
|
||||
log.LEVEL
|
||||
log.FULL - all of the above
|
||||
|
||||
So, in order to save net.trace(msg) messages to a file, you should issue a call:
|
||||
log.set_output('lua-net', 'LuaNET', log.TRACE, log.MESSAGE + log.TIME)
|
||||
|
||||
This will write to a Logs/lua-net.log file
|
||||
|
||||
Or, to save everything lua-network-related:
|
||||
log.set_output('lua-net', 'LuaNET', log.TRACE + log.ALL, log.MESSAGE + log.TIME + log.LEVEL)
|
||||
|
||||
To close the log file, you must use
|
||||
log.set_output('lua-net', '', 0, 0)
|
||||
|
||||
log.* API is available in the 'Saved Games\DCS\Config\autoexec.cfg' file as well so you can control log output in you local machine.
|
||||
|
||||
|
||||
|
||||
Network specific API, available through the table 'net.'
|
||||
----------------------------------------------------------------
|
||||
|
||||
net.log(msg) -- equivalent to log.write('LuaNET', log.INFO, msg)
|
||||
net.trace(msg) -- equivalent to log.write('LuaNET', log.TRACE, msg)
|
||||
|
||||
What is the difference: log() always writes to dcs.log, but may lose messages if the output rate is too high.
|
||||
trace() output never appears in the dcs.log file, it must be explicitly directed to a log file.
|
||||
It never loses messages when there's an active output, but it may block if output rate is higher than writing to the log file.
|
||||
To control logger output you can use $WRITE_DIR/Config/autoexec.cfg file, or call this from your network script
|
||||
(log.* API, see above)
|
||||
|
||||
|
||||
net.dostring_in(state, string) -> string
|
||||
Executes a lua-string in a given internal lua-state and returns a string result
|
||||
Valid state names are:
|
||||
'config': the state in which $INSTALL_DIR/Config/main.cfg is executed, as well as $WRITE_DIR/Config/autoexec.cfg
|
||||
used for configuration settings
|
||||
'mission': holds current mission
|
||||
'export': runs $WRITE_DIR/Scripts/Export.lua and the relevant export API
|
||||
|
||||
net.send_chat(string message, bool all)
|
||||
Send chat message. If not all, then send to my coalition (side) only.
|
||||
|
||||
net.send_chat_to(string message, playerID to)
|
||||
Send direct chat message to a player
|
||||
Server-side only:
|
||||
net.send_chat_to(string message, playerID to[, playerID from])
|
||||
|
||||
net.recv_chat(message[, int from=0])
|
||||
Receive chat message locally[, pretending it was sent by another player].
|
||||
from = 0 means from the system
|
||||
|
||||
net.load_mission(miz_filename)
|
||||
Loads a specified mission, temporarily overriding the server mission list.
|
||||
SERVER ONLY
|
||||
|
||||
net.load_next_mission() -> bool
|
||||
Load the next mission from the server mission list. Returns false if list end is reached
|
||||
SERVER ONLY
|
||||
|
||||
net.get_player_list() -> array of playerID
|
||||
Returns the list of currently connected players
|
||||
|
||||
net.get_my_player_id() -> playerID
|
||||
Returns the playerID of the local player. Currently always 1 for the server.
|
||||
|
||||
net.get_server_id() -> playerID
|
||||
Returns playerID of the server. Currently, always 1.
|
||||
|
||||
net.get_player_info(playerID) -> table
|
||||
Returns a table of all player attributes or nil if playerID is invalid
|
||||
|
||||
net.get_player_info(playerID, attrName) -> value
|
||||
Returns a value of a given attribute for the playerID.
|
||||
|
||||
Currently defined attributes are:
|
||||
'id': playerID
|
||||
'name': player name
|
||||
'side': 0 - spectators, 1 - red, 2 - blue
|
||||
'slot': slotID of the player or ''
|
||||
'ping': ping of the player in ms
|
||||
'ipaddr': IP address of the player, SERVER ONLY
|
||||
'ucid': Unique Client Identifier, SERVER ONLY
|
||||
|
||||
net.kick(id, message)
|
||||
Kick a player.
|
||||
|
||||
net.get_stat(playerID, statID) -> integer
|
||||
Get statistics for player. statIDs are:
|
||||
net.PS_PING (0) - ping (in ms)
|
||||
net.PS_CRASH (1) - number of crashes
|
||||
net.PS_CAR (2) - number of destroyed vehicles
|
||||
net.PS_PLANE (3) - ... planes/helicopters
|
||||
net.PS_SHIP (4) - ... ships
|
||||
net.PS_SCORE (5) - total score
|
||||
net.PS_LAND (6) - number of landings
|
||||
net.PS_EJECT (7) - of ejects
|
||||
|
||||
|
||||
net.get_name(playerID) -> string
|
||||
The same as net.get_player_info(playerID, 'name')
|
||||
FIXME: implement in ServMan_compat.lua ?
|
||||
|
||||
net.get_slot(playerID) -> sideID, slotID
|
||||
The same as:
|
||||
net.get_player_info(playerID, 'side'), net.get_player_info(playerID, 'slot')
|
||||
FIXME: implement in ServMan_compat.lua ?
|
||||
|
||||
|
||||
|
||||
net.set_slot(sideID, slotID)
|
||||
Try to set the local player's slot. Empty slotID ('') puts the player into spectators.
|
||||
|
||||
net.force_player_slot(playerID, sideID, slotID) -> boolean
|
||||
Forces a player to occupy a set slot. Slot '' means no slot (moves player to spectators)
|
||||
SideID: 0 - spectators, 1 - red, 2 - blue
|
||||
|
||||
net.set_name(playerID, name) -- OBSOLETE, works only locally
|
||||
|
||||
|
||||
net.lua2json(value) -> string
|
||||
Convert a Lua value to JSON string
|
||||
|
||||
net.json2lua(json_string) -> value
|
||||
Convert JSON string to a Lua value
|
||||
|
||||
|
||||
LuaExport API 'Export.Lo*'
|
||||
----------------------------------------------------------------
|
||||
See Scripts/Export.lua for the documentation. Note that all export
|
||||
API functions are available here in the Export. namespace, not the global one.
|
||||
In multiplayer the availability of the API on clients depends on the server setting.
|
||||
|
||||
The calls to check export capabilities:
|
||||
Export.LoIsObjectExportAllowed() -- returns the value of server.advanced.allow_object_export
|
||||
Export.LoIsSensorExportAllowed() -- returns the value of server.advanced.allow_sensor_export
|
||||
Export.LoIsOwnshipExportAllowed() -- returns the value of server.advanced.allow_ownship_export
|
||||
|
||||
These calls are only available on clients when LoIsObjectExportAllowed() is true:
|
||||
Export.LoGetObjectById
|
||||
Export.LoGetWorldObjects
|
||||
|
||||
These calls are only available on clients when LoIsSensorExportAllowed() is true:
|
||||
Export.LoGetTWSInfo
|
||||
Export.LoGetTargetInformation
|
||||
Export.LoGetLockedTargetInformation
|
||||
Export.LoGetF15_TWS_Contacts
|
||||
Export.LoGetSightingSystemInfo
|
||||
Export.LoGetWingTargets
|
||||
|
||||
These calls are only available on clients when LoIsOwnshipExportAllowed() is true:
|
||||
Export.LoGetPlayerPlaneId
|
||||
Export.LoGetIndicatedAirSpeed
|
||||
Export.LoGetAngleOfAttack
|
||||
Export.LoGetAngleOfSideSlip
|
||||
Export.LoGetAccelerationUnits
|
||||
Export.LoGetVerticalVelocity
|
||||
Export.LoGetADIPitchBankYaw
|
||||
Export.LoGetTrueAirSpeed
|
||||
Export.LoGetAltitudeAboveSeaLevel
|
||||
Export.LoGetAltitudeAboveGroundLevel
|
||||
Export.LoGetMachNumber
|
||||
Export.LoGetRadarAltimeter
|
||||
Export.LoGetMagneticYaw
|
||||
Export.LoGetGlideDeviation
|
||||
Export.LoGetSideDeviation
|
||||
Export.LoGetSlipBallPosition
|
||||
Export.LoGetBasicAtmospherePressure
|
||||
Export.LoGetControlPanel_HSI
|
||||
Export.LoGetEngineInfo
|
||||
Export.LoGetSelfData
|
||||
Export.LoGetCameraPosition
|
||||
Export.LoSetCameraPosition
|
||||
Export.LoSetCommand
|
||||
Export.LoGetMCPState
|
||||
Export.LoGetRoute
|
||||
Export.LoGetNavigationInfo
|
||||
Export.LoGetPayloadInfo
|
||||
Export.LoGetWingInfo
|
||||
Export.LoGetMechInfo
|
||||
Export.LoGetRadioBeaconsStatus
|
||||
Export.LoGetVectorVelocity
|
||||
Export.LoGetVectorWindVelocity
|
||||
Export.LoGetSnares
|
||||
Export.LoGetAngularVelocity
|
||||
Export.LoGetHeightWithObjects
|
||||
Export.LoGetFMData
|
||||
|
||||
These functions are always available:
|
||||
Export.LoGetPilotName
|
||||
Export.LoGetAltitude
|
||||
Export.LoGetNameByType
|
||||
Export.LoGeoCoordinatesToLoCoordinates
|
||||
Export.LoCoordinatesToGeoCoordinates
|
||||
Export.LoGetVersionInfo
|
||||
Export.LoGetWindAtPoint
|
||||
Export.LoGetModelTime
|
||||
Export.LoGetMissionStartTime
|
||||
|
||||
These are not available in the *GameGUI state:
|
||||
-- Export.LoSetSharedTexture
|
||||
-- Export.LoRemoveSharedTexture
|
||||
-- Export.LoUpdateSharedTexture
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------------------
|
||||
--- The Callbacks.
|
||||
-------------------------------------------------------------------------------------------
|
||||
|
||||
function onMissionLoadBegin()
|
||||
end
|
||||
|
||||
function onMissionLoadProgress(progress, message)
|
||||
end
|
||||
|
||||
function onMissionLoadEnd()
|
||||
end
|
||||
|
||||
|
||||
function onSimulationStart()
|
||||
end
|
||||
|
||||
function onSimulationStop()
|
||||
end
|
||||
|
||||
function onSimulationFrame()
|
||||
end
|
||||
|
||||
function onSimulationPause()
|
||||
end
|
||||
|
||||
function onSimulationResume()
|
||||
end
|
||||
|
||||
|
||||
function onGameEvent(eventName,arg1,arg2,arg3,arg4)
|
||||
--"friendly_fire", playerID, weaponName, victimPlayerID
|
||||
--"mission_end", winner, msg
|
||||
--"kill", killerPlayerID, killerUnitType, killerSide, victimPlayerID, victimUnitType, victimSide, weaponName
|
||||
--"self_kill", playerID
|
||||
--"change_slot", playerID, slotID, prevSide
|
||||
--"connect", playerID, name
|
||||
--"disconnect", playerID, name, playerSide, reason_code
|
||||
--"crash", playerID, unit_missionID
|
||||
--"eject", playerID, unit_missionID
|
||||
--"takeoff", playerID, unit_missionID, airdromeName
|
||||
--"landing", playerID, unit_missionID, airdromeName
|
||||
--"pilot_death", playerID, unit_missionID
|
||||
end
|
||||
|
||||
function onNetConnect(localPlayerID)
|
||||
end
|
||||
|
||||
function onNetMissionChanged(newMissionName)
|
||||
end
|
||||
|
||||
function onNetDisconnect(reason_msg, err_code)
|
||||
end
|
||||
|
||||
-- disconnect reason codes:
|
||||
net.ERR_INVALID_ADDRESS
|
||||
net.ERR_CONNECT_FAILED
|
||||
net.ERR_WRONG_VERSION
|
||||
net.ERR_PROTOCOL_ERROR
|
||||
net.ERR_TAINTED_CLIENT
|
||||
net.ERR_INVALID_PASSWORD
|
||||
net.ERR_BANNED
|
||||
net.ERR_BAD_CALLSIGN
|
||||
|
||||
net.ERR_TIMEOUT
|
||||
net.ERR_KICKED
|
||||
|
||||
|
||||
function onPlayerConnect(id)
|
||||
end
|
||||
|
||||
function onPlayerDisconnect(id, err_code)
|
||||
-- this is never called for local playerID
|
||||
end
|
||||
|
||||
function onPlayerStart(id)
|
||||
-- a player entered the simulation
|
||||
-- this is never called for local playerID
|
||||
end
|
||||
|
||||
function onPlayerStop(id)
|
||||
-- a player left the simulation (happens right before a disconnect, if player exited by desire)
|
||||
-- this is never called for local playerID
|
||||
end
|
||||
|
||||
function onPlayerChangeSlot(id)
|
||||
-- a player successfully changed the slot
|
||||
-- this will also come as onGameEvent('change_slot', playerID, slotID),
|
||||
-- if allowed by server.advanced.event_Connect setting
|
||||
end
|
||||
|
||||
|
||||
--- These 3 functions are different from the rest:
|
||||
--- 1. they are called directly from the network code, so try to make them as fast as possible
|
||||
--- 2. they return a result
|
||||
-- The code shows the default implementations.
|
||||
|
||||
function onPlayerTryConnect(addr, name, ucid, playerID) --> true | false, "disconnect reason"
|
||||
return true
|
||||
end
|
||||
|
||||
function onPlayerTrySendChat(playerID, msg, all) -- -> filteredMessage | "" - empty string drops the message
|
||||
return msg
|
||||
end
|
||||
|
||||
function onPlayerTryChangeSlot(playerID, side, slotID) -- -> true | false
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- GUI callbacks
|
||||
function onChatMessage(message, from)
|
||||
-- this one may be useful for chat archiving
|
||||
end
|
||||
|
||||
function onShowRadioMenu(a_h)
|
||||
end
|
||||
|
||||
function onShowPool()
|
||||
end
|
||||
|
||||
function onShowGameMenu()
|
||||
end
|
||||
|
||||
function onShowBriefing()
|
||||
end
|
||||
|
||||
function onShowChatAll()
|
||||
end
|
||||
|
||||
function onShowChatTeam()
|
||||
end
|
||||
|
||||
function onShowChatRead()
|
||||
end
|
||||
|
||||
function onShowMessage(a_text, a_duration)
|
||||
end
|
||||
|
||||
function onTriggerMessage(message, duration, clearView)
|
||||
end
|
||||
|
||||
function onRadioMessage(message, duration)
|
||||
end
|
||||
|
||||
function onRadioCommand(command_message)
|
||||
end
|
||||
|
||||
===================================================================================================
|
||||
|
||||
Happy hacking!
|
||||
|
||||
Sincerely,
|
||||
dsb at eagle dot ru
|
||||
@ -529,7 +529,7 @@ do -- CARGO_REPRESENTABLE
|
||||
-- @extends #CARGO
|
||||
-- @field test
|
||||
|
||||
---
|
||||
--- Models CARGO that is representable by a Unit.
|
||||
-- @field #CARGO_REPRESENTABLE CARGO_REPRESENTABLE
|
||||
CARGO_REPRESENTABLE = {
|
||||
ClassName = "CARGO_REPRESENTABLE"
|
||||
@ -549,6 +549,18 @@ do -- CARGO_REPRESENTABLE
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- CARGO_REPRESENTABLE Destructor.
|
||||
-- @param #CARGO_REPRESENTABLE self
|
||||
-- @return #CARGO_REPRESENTABLE
|
||||
function CARGO_REPRESENTABLE:Destroy()
|
||||
|
||||
-- Cargo objects are deleted from the _DATABASE and SET_CARGO objects.
|
||||
self:F( { CargoName = self:GetName() } )
|
||||
_EVENTDISPATCHER:CreateEventDeleteCargo( self )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Route a cargo unit to a PointVec2.
|
||||
-- @param #CARGO_REPRESENTABLE self
|
||||
@ -678,7 +690,7 @@ end
|
||||
|
||||
do -- CARGO_UNIT
|
||||
|
||||
--- Hello
|
||||
--- Models CARGO in the form of units, which can be boarded, unboarded, loaded, unloaded.
|
||||
-- @type CARGO_UNIT
|
||||
-- @extends #CARGO_REPRESENTABLE
|
||||
|
||||
@ -695,346 +707,425 @@ do -- CARGO_UNIT
|
||||
ClassName = "CARGO_UNIT"
|
||||
}
|
||||
|
||||
--- CARGO_UNIT Constructor.
|
||||
-- @param #CARGO_UNIT self
|
||||
-- @param Wrapper.Unit#UNIT CargoUnit
|
||||
-- @param #string Type
|
||||
-- @param #string Name
|
||||
-- @param #number Weight
|
||||
-- @param #number ReportRadius (optional)
|
||||
-- @param #number NearRadius (optional)
|
||||
-- @return #CARGO_UNIT
|
||||
function CARGO_UNIT:New( CargoUnit, Type, Name, Weight, NearRadius )
|
||||
local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoUnit, Type, Name, Weight, NearRadius ) ) -- #CARGO_UNIT
|
||||
self:F( { Type, Name, Weight, NearRadius } )
|
||||
|
||||
self:T( CargoUnit )
|
||||
self.CargoObject = CargoUnit
|
||||
|
||||
self:T( self.ClassName )
|
||||
|
||||
-- self:HandleEvent( EVENTS.Dead,
|
||||
-- --- @param #CARGO Cargo
|
||||
-- -- @param Core.Event#EVENTDATA EventData
|
||||
-- function( Cargo, EventData )
|
||||
-- if Cargo:GetObjectName() == EventData.IniUnit:GetName() then
|
||||
-- self:E( { "Cargo destroyed", Cargo } )
|
||||
-- Cargo:Destroyed()
|
||||
-- end
|
||||
-- end
|
||||
-- )
|
||||
|
||||
self:SetEventPriority( 5 )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- CARGO_UNIT Destructor.
|
||||
-- @param #CARGO_UNIT self
|
||||
-- @return #CARGO_UNIT
|
||||
function CARGO_UNIT:Destroy()
|
||||
|
||||
-- Cargo objects are deleted from the _DATABASE and SET_CARGO objects.
|
||||
self:F( { CargoName = self:GetName() } )
|
||||
_EVENTDISPATCHER:CreateEventDeleteCargo( self )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Enter UnBoarding State.
|
||||
-- @param #CARGO_UNIT self
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
||||
function CARGO_UNIT:onenterUnBoarding( From, Event, To, ToPointVec2, NearRadius )
|
||||
self:F( { From, Event, To, ToPointVec2, NearRadius } )
|
||||
|
||||
NearRadius = NearRadius or 25
|
||||
|
||||
local Angle = 180
|
||||
local Speed = 60
|
||||
local DeployDistance = 9
|
||||
local RouteDistance = 60
|
||||
|
||||
if From == "Loaded" then
|
||||
|
||||
local CargoCarrier = self.CargoCarrier -- Wrapper.Controllable#CONTROLLABLE
|
||||
|
||||
local CargoCarrierPointVec2 = CargoCarrier:GetPointVec2()
|
||||
local CargoCarrierHeading = self.CargoCarrier:GetHeading() -- Get Heading of object in degrees.
|
||||
local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle )
|
||||
|
||||
|
||||
local CargoRoutePointVec2 = CargoCarrierPointVec2:Translate( RouteDistance, CargoDeployHeading )
|
||||
|
||||
|
||||
-- if there is no ToPointVec2 given, then use the CargoRoutePointVec2
|
||||
ToPointVec2 = ToPointVec2 or CargoRoutePointVec2
|
||||
local DirectionVec3 = CargoCarrierPointVec2:GetDirectionVec3(ToPointVec2)
|
||||
local Angle = CargoCarrierPointVec2:GetAngleDegrees(DirectionVec3)
|
||||
|
||||
local CargoDeployPointVec2 = CargoCarrierPointVec2:Translate( DeployDistance, Angle )
|
||||
|
||||
local FromPointVec2 = CargoCarrierPointVec2
|
||||
|
||||
-- Respawn the group...
|
||||
if self.CargoObject then
|
||||
self.CargoObject:ReSpawn( CargoDeployPointVec2:GetVec3(), CargoDeployHeading )
|
||||
self:F( { "CargoUnits:", self.CargoObject:GetGroup():GetName() } )
|
||||
self.CargoCarrier = nil
|
||||
|
||||
local Points = {}
|
||||
Points[#Points+1] = CargoCarrierPointVec2:WaypointGround( Speed )
|
||||
|
||||
Points[#Points+1] = ToPointVec2:WaypointGround( Speed )
|
||||
--- CARGO_UNIT Constructor.
|
||||
-- @param #CARGO_UNIT self
|
||||
-- @param Wrapper.Unit#UNIT CargoUnit
|
||||
-- @param #string Type
|
||||
-- @param #string Name
|
||||
-- @param #number Weight
|
||||
-- @param #number ReportRadius (optional)
|
||||
-- @param #number NearRadius (optional)
|
||||
-- @return #CARGO_UNIT
|
||||
function CARGO_UNIT:New( CargoUnit, Type, Name, Weight, NearRadius )
|
||||
local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoUnit, Type, Name, Weight, NearRadius ) ) -- #CARGO_UNIT
|
||||
self:F( { Type, Name, Weight, NearRadius } )
|
||||
|
||||
local TaskRoute = self.CargoObject:TaskRoute( Points )
|
||||
self.CargoObject:SetTask( TaskRoute, 1 )
|
||||
|
||||
|
||||
self:__UnBoarding( 1, ToPointVec2, NearRadius )
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- Leave UnBoarding State.
|
||||
-- @param #CARGO_UNIT self
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
||||
function CARGO_UNIT:onleaveUnBoarding( From, Event, To, ToPointVec2, NearRadius )
|
||||
self:F( { From, Event, To, ToPointVec2, NearRadius } )
|
||||
|
||||
NearRadius = NearRadius or 25
|
||||
|
||||
local Angle = 180
|
||||
local Speed = 10
|
||||
local Distance = 5
|
||||
|
||||
if From == "UnBoarding" then
|
||||
if self:IsNear( ToPointVec2, NearRadius ) then
|
||||
return true
|
||||
else
|
||||
|
||||
self:__UnBoarding( 1, ToPointVec2, NearRadius )
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- UnBoard Event.
|
||||
-- @param #CARGO_UNIT self
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
||||
function CARGO_UNIT:onafterUnBoarding( From, Event, To, ToPointVec2, NearRadius )
|
||||
self:F( { From, Event, To, ToPointVec2, NearRadius } )
|
||||
|
||||
NearRadius = NearRadius or 25
|
||||
|
||||
self.CargoInAir = self.CargoObject:InAir()
|
||||
|
||||
self:T( self.CargoInAir )
|
||||
|
||||
-- Only unboard the cargo when the carrier is not in the air.
|
||||
-- (eg. cargo can be on a oil derrick, moving the cargo on the oil derrick will drop the cargo on the sea).
|
||||
if not self.CargoInAir then
|
||||
|
||||
end
|
||||
|
||||
self:__UnLoad( 1, ToPointVec2, NearRadius )
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Enter UnLoaded State.
|
||||
-- @param #CARGO_UNIT self
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
-- @param Core.Point#POINT_VEC2
|
||||
function CARGO_UNIT:onenterUnLoaded( From, Event, To, ToPointVec2 )
|
||||
self:F( { ToPointVec2, From, Event, To } )
|
||||
|
||||
local Angle = 180
|
||||
local Speed = 10
|
||||
local Distance = 5
|
||||
|
||||
if From == "Loaded" then
|
||||
local StartPointVec2 = self.CargoCarrier:GetPointVec2()
|
||||
local CargoCarrierHeading = self.CargoCarrier:GetHeading() -- Get Heading of object in degrees.
|
||||
local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle )
|
||||
local CargoDeployCoord = StartPointVec2:Translate( Distance, CargoDeployHeading )
|
||||
|
||||
ToPointVec2 = ToPointVec2 or POINT_VEC2:New( CargoDeployCoord.x, CargoDeployCoord.z )
|
||||
|
||||
-- Respawn the group...
|
||||
if self.CargoObject then
|
||||
self.CargoObject:ReSpawn( ToPointVec2:GetVec3(), 0 )
|
||||
self.CargoCarrier = nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if self.OnUnLoadedCallBack then
|
||||
self.OnUnLoadedCallBack( self, unpack( self.OnUnLoadedParameters ) )
|
||||
self.OnUnLoadedCallBack = nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- Board Event.
|
||||
-- @param #CARGO_UNIT self
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function CARGO_UNIT:onafterBoard( From, Event, To, CargoCarrier, NearRadius, ... )
|
||||
self:F( { From, Event, To, CargoCarrier, NearRadius } )
|
||||
|
||||
local NearRadius = NearRadius or 25
|
||||
self:T( CargoUnit )
|
||||
self.CargoObject = CargoUnit
|
||||
|
||||
self:T( self.ClassName )
|
||||
|
||||
self:SetEventPriority( 5 )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Enter UnBoarding State.
|
||||
-- @param #CARGO_UNIT self
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
||||
function CARGO_UNIT:onenterUnBoarding( From, Event, To, ToPointVec2, NearRadius )
|
||||
self:F( { From, Event, To, ToPointVec2, NearRadius } )
|
||||
|
||||
NearRadius = NearRadius or 25
|
||||
|
||||
local Angle = 180
|
||||
local Speed = 60
|
||||
local DeployDistance = 9
|
||||
local RouteDistance = 60
|
||||
|
||||
if From == "Loaded" then
|
||||
|
||||
local CargoCarrier = self.CargoCarrier -- Wrapper.Controllable#CONTROLLABLE
|
||||
|
||||
self.CargoInAir = self.CargoObject:InAir()
|
||||
|
||||
self:T( self.CargoInAir )
|
||||
|
||||
-- Only move the group to the carrier when the cargo is not in the air
|
||||
-- (eg. cargo can be on a oil derrick, moving the cargo on the oil derrick will drop the cargo on the sea).
|
||||
if not self.CargoInAir then
|
||||
if self:IsNear( CargoCarrier:GetPointVec2(), NearRadius ) then
|
||||
self:Load( CargoCarrier, NearRadius, ... )
|
||||
else
|
||||
local Speed = 90
|
||||
local Angle = 180
|
||||
local Distance = 5
|
||||
|
||||
NearRadius = NearRadius or 25
|
||||
|
||||
local CargoCarrierPointVec2 = CargoCarrier:GetPointVec2()
|
||||
local CargoCarrierHeading = CargoCarrier:GetHeading() -- Get Heading of object in degrees.
|
||||
local CargoCarrierHeading = self.CargoCarrier:GetHeading() -- Get Heading of object in degrees.
|
||||
local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle )
|
||||
local CargoDeployPointVec2 = CargoCarrierPointVec2:Translate( Distance, CargoDeployHeading )
|
||||
|
||||
|
||||
local CargoRoutePointVec2 = CargoCarrierPointVec2:Translate( RouteDistance, CargoDeployHeading )
|
||||
|
||||
|
||||
-- if there is no ToPointVec2 given, then use the CargoRoutePointVec2
|
||||
ToPointVec2 = ToPointVec2 or CargoRoutePointVec2
|
||||
local DirectionVec3 = CargoCarrierPointVec2:GetDirectionVec3(ToPointVec2)
|
||||
local Angle = CargoCarrierPointVec2:GetAngleDegrees(DirectionVec3)
|
||||
|
||||
local CargoDeployPointVec2 = CargoCarrierPointVec2:Translate( DeployDistance, Angle )
|
||||
|
||||
local FromPointVec2 = CargoCarrierPointVec2
|
||||
|
||||
-- Respawn the group...
|
||||
if self.CargoObject then
|
||||
self.CargoObject:ReSpawn( CargoDeployPointVec2:GetVec3(), CargoDeployHeading )
|
||||
self:F( { "CargoUnits:", self.CargoObject:GetGroup():GetName() } )
|
||||
self.CargoCarrier = nil
|
||||
|
||||
local Points = {}
|
||||
Points[#Points+1] = CargoCarrierPointVec2:WaypointGround( Speed )
|
||||
|
||||
Points[#Points+1] = ToPointVec2:WaypointGround( Speed )
|
||||
|
||||
local Points = {}
|
||||
|
||||
local PointStartVec2 = self.CargoObject:GetPointVec2()
|
||||
|
||||
Points[#Points+1] = PointStartVec2:WaypointGround( Speed )
|
||||
Points[#Points+1] = CargoDeployPointVec2:WaypointGround( Speed )
|
||||
|
||||
local TaskRoute = self.CargoObject:TaskRoute( Points )
|
||||
self.CargoObject:SetTask( TaskRoute, 2 )
|
||||
self:__Boarding( -1, CargoCarrier, NearRadius )
|
||||
self.RunCount = 0
|
||||
local TaskRoute = self.CargoObject:TaskRoute( Points )
|
||||
self.CargoObject:SetTask( TaskRoute, 1 )
|
||||
|
||||
|
||||
self:__UnBoarding( 1, ToPointVec2, NearRadius )
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- Boarding Event.
|
||||
-- @param #CARGO_UNIT self
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||
-- @param #number NearRadius
|
||||
function CARGO_UNIT:onafterBoarding( From, Event, To, CargoCarrier, NearRadius, ... )
|
||||
self:F( { From, Event, To, CargoCarrier.UnitName, NearRadius } )
|
||||
--- Leave UnBoarding State.
|
||||
-- @param #CARGO_UNIT self
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
||||
function CARGO_UNIT:onleaveUnBoarding( From, Event, To, ToPointVec2, NearRadius )
|
||||
self:F( { From, Event, To, ToPointVec2, NearRadius } )
|
||||
|
||||
NearRadius = NearRadius or 25
|
||||
|
||||
if CargoCarrier and CargoCarrier:IsAlive() then
|
||||
if CargoCarrier:InAir() == false then
|
||||
if self:IsNear( CargoCarrier:GetPointVec2(), NearRadius ) then
|
||||
self:__Load( 1, CargoCarrier, ... )
|
||||
local Angle = 180
|
||||
local Speed = 10
|
||||
local Distance = 5
|
||||
|
||||
if From == "UnBoarding" then
|
||||
if self:IsNear( ToPointVec2, NearRadius ) then
|
||||
return true
|
||||
else
|
||||
self:__Boarding( -1, CargoCarrier, NearRadius, ... )
|
||||
self.RunCount = self.RunCount + 1
|
||||
if self.RunCount >= 20 then
|
||||
self.RunCount = 0
|
||||
local Speed = 90
|
||||
local Angle = 180
|
||||
local Distance = 5
|
||||
|
||||
self:__UnBoarding( 1, ToPointVec2, NearRadius )
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- UnBoard Event.
|
||||
-- @param #CARGO_UNIT self
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
||||
function CARGO_UNIT:onafterUnBoarding( From, Event, To, ToPointVec2, NearRadius )
|
||||
self:F( { From, Event, To, ToPointVec2, NearRadius } )
|
||||
|
||||
NearRadius = NearRadius or 25
|
||||
|
||||
self.CargoInAir = self.CargoObject:InAir()
|
||||
|
||||
self:T( self.CargoInAir )
|
||||
|
||||
-- Only unboard the cargo when the carrier is not in the air.
|
||||
-- (eg. cargo can be on a oil derrick, moving the cargo on the oil derrick will drop the cargo on the sea).
|
||||
if not self.CargoInAir then
|
||||
|
||||
end
|
||||
|
||||
self:__UnLoad( 1, ToPointVec2, NearRadius )
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Enter UnLoaded State.
|
||||
-- @param #CARGO_UNIT self
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
-- @param Core.Point#POINT_VEC2
|
||||
function CARGO_UNIT:onenterUnLoaded( From, Event, To, ToPointVec2 )
|
||||
self:F( { ToPointVec2, From, Event, To } )
|
||||
|
||||
local Angle = 180
|
||||
local Speed = 10
|
||||
local Distance = 5
|
||||
|
||||
if From == "Loaded" then
|
||||
local StartPointVec2 = self.CargoCarrier:GetPointVec2()
|
||||
local CargoCarrierHeading = self.CargoCarrier:GetHeading() -- Get Heading of object in degrees.
|
||||
local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle )
|
||||
local CargoDeployCoord = StartPointVec2:Translate( Distance, CargoDeployHeading )
|
||||
|
||||
ToPointVec2 = ToPointVec2 or COORDINATE:New( CargoDeployCoord.x, CargoDeployCoord.z )
|
||||
|
||||
-- Respawn the group...
|
||||
if self.CargoObject then
|
||||
self.CargoObject:ReSpawn( ToPointVec2:GetVec3(), 0 )
|
||||
self.CargoCarrier = nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if self.OnUnLoadedCallBack then
|
||||
self.OnUnLoadedCallBack( self, unpack( self.OnUnLoadedParameters ) )
|
||||
self.OnUnLoadedCallBack = nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- Board Event.
|
||||
-- @param #CARGO_UNIT self
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function CARGO_UNIT:onafterBoard( From, Event, To, CargoCarrier, NearRadius, ... )
|
||||
self:F( { From, Event, To, CargoCarrier, NearRadius } )
|
||||
|
||||
local NearRadius = NearRadius or 25
|
||||
|
||||
self.CargoInAir = self.CargoObject:InAir()
|
||||
|
||||
self:T( self.CargoInAir )
|
||||
|
||||
-- Only move the group to the carrier when the cargo is not in the air
|
||||
-- (eg. cargo can be on a oil derrick, moving the cargo on the oil derrick will drop the cargo on the sea).
|
||||
if not self.CargoInAir then
|
||||
if self:IsNear( CargoCarrier:GetPointVec2(), NearRadius ) then
|
||||
self:Load( CargoCarrier, NearRadius, ... )
|
||||
else
|
||||
local Speed = 90
|
||||
local Angle = 180
|
||||
local Distance = 5
|
||||
|
||||
NearRadius = NearRadius or 25
|
||||
|
||||
local CargoCarrierPointVec2 = CargoCarrier:GetPointVec2()
|
||||
local CargoCarrierHeading = CargoCarrier:GetHeading() -- Get Heading of object in degrees.
|
||||
local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle )
|
||||
local CargoDeployPointVec2 = CargoCarrierPointVec2:Translate( Distance, CargoDeployHeading )
|
||||
|
||||
local Points = {}
|
||||
|
||||
local PointStartVec2 = self.CargoObject:GetPointVec2()
|
||||
|
||||
Points[#Points+1] = PointStartVec2:WaypointGround( Speed )
|
||||
Points[#Points+1] = CargoDeployPointVec2:WaypointGround( Speed )
|
||||
|
||||
local TaskRoute = self.CargoObject:TaskRoute( Points )
|
||||
self.CargoObject:SetTask( TaskRoute, 2 )
|
||||
self:__Boarding( -1, CargoCarrier, NearRadius )
|
||||
self.RunCount = 0
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- Boarding Event.
|
||||
-- @param #CARGO_UNIT self
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||
-- @param #number NearRadius
|
||||
function CARGO_UNIT:onafterBoarding( From, Event, To, CargoCarrier, NearRadius, ... )
|
||||
self:F( { From, Event, To, CargoCarrier.UnitName, NearRadius } )
|
||||
|
||||
|
||||
if CargoCarrier and CargoCarrier:IsAlive() then
|
||||
if CargoCarrier:InAir() == false then
|
||||
if self:IsNear( CargoCarrier:GetPointVec2(), NearRadius ) then
|
||||
self:__Load( 1, CargoCarrier, ... )
|
||||
else
|
||||
self:__Boarding( -1, CargoCarrier, NearRadius, ... )
|
||||
self.RunCount = self.RunCount + 1
|
||||
if self.RunCount >= 20 then
|
||||
self.RunCount = 0
|
||||
local Speed = 90
|
||||
local Angle = 180
|
||||
local Distance = 5
|
||||
|
||||
NearRadius = NearRadius or 25
|
||||
|
||||
NearRadius = NearRadius or 25
|
||||
|
||||
local CargoCarrierPointVec2 = CargoCarrier:GetPointVec2()
|
||||
local CargoCarrierHeading = CargoCarrier:GetHeading() -- Get Heading of object in degrees.
|
||||
local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle )
|
||||
local CargoDeployPointVec2 = CargoCarrierPointVec2:Translate( Distance, CargoDeployHeading )
|
||||
|
||||
local Points = {}
|
||||
|
||||
local PointStartVec2 = self.CargoObject:GetPointVec2()
|
||||
|
||||
Points[#Points+1] = PointStartVec2:WaypointGround( Speed )
|
||||
Points[#Points+1] = CargoDeployPointVec2:WaypointGround( Speed )
|
||||
|
||||
local TaskRoute = self.CargoObject:TaskRoute( Points )
|
||||
self.CargoObject:SetTask( TaskRoute, 0.2 )
|
||||
local CargoCarrierPointVec2 = CargoCarrier:GetPointVec2()
|
||||
local CargoCarrierHeading = CargoCarrier:GetHeading() -- Get Heading of object in degrees.
|
||||
local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle )
|
||||
local CargoDeployPointVec2 = CargoCarrierPointVec2:Translate( Distance, CargoDeployHeading )
|
||||
|
||||
local Points = {}
|
||||
|
||||
local PointStartVec2 = self.CargoObject:GetPointVec2()
|
||||
|
||||
Points[#Points+1] = PointStartVec2:WaypointGround( Speed )
|
||||
Points[#Points+1] = CargoDeployPointVec2:WaypointGround( Speed )
|
||||
|
||||
local TaskRoute = self.CargoObject:TaskRoute( Points )
|
||||
self.CargoObject:SetTask( TaskRoute, 0.2 )
|
||||
end
|
||||
end
|
||||
else
|
||||
self.CargoObject:MessageToGroup( "Cancelling Boarding... Get back on the ground!", 5, CargoCarrier:GetGroup(), self:GetName() )
|
||||
self:CancelBoarding( CargoCarrier, NearRadius, ... )
|
||||
self.CargoObject:SetCommand( self.CargoObject:CommandStopRoute( true ) )
|
||||
end
|
||||
else
|
||||
self.CargoObject:MessageToGroup( "Cancelling Boarding... Get back on the ground!", 5, CargoCarrier:GetGroup(), self:GetName() )
|
||||
self:CancelBoarding( CargoCarrier, NearRadius, ... )
|
||||
self.CargoObject:SetCommand( self.CargoObject:CommandStopRoute( true ) )
|
||||
self:E("Something is wrong")
|
||||
end
|
||||
else
|
||||
self:E("Something is wrong")
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- Enter Boarding State.
|
||||
-- @param #CARGO_UNIT self
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||
function CARGO_UNIT:onenterBoarding( From, Event, To, CargoCarrier, NearRadius, ... )
|
||||
self:F( { From, Event, To, CargoCarrier.UnitName, NearRadius } )
|
||||
|
||||
local Speed = 90
|
||||
local Angle = 180
|
||||
local Distance = 5
|
||||
|
||||
local NearRadius = NearRadius or 25
|
||||
|
||||
if From == "UnLoaded" or From == "Boarding" then
|
||||
--- Enter Boarding State.
|
||||
-- @param #CARGO_UNIT self
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||
function CARGO_UNIT:onenterBoarding( From, Event, To, CargoCarrier, NearRadius, ... )
|
||||
self:F( { From, Event, To, CargoCarrier.UnitName, NearRadius } )
|
||||
|
||||
local Speed = 90
|
||||
local Angle = 180
|
||||
local Distance = 5
|
||||
|
||||
local NearRadius = NearRadius or 25
|
||||
|
||||
if From == "UnLoaded" or From == "Boarding" then
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- Loaded State.
|
||||
-- @param #CARGO_UNIT self
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||
function CARGO_UNIT:onenterLoaded( From, Event, To, CargoCarrier )
|
||||
self:F( { From, Event, To, CargoCarrier } )
|
||||
|
||||
self.CargoCarrier = CargoCarrier
|
||||
--- Loaded State.
|
||||
-- @param #CARGO_UNIT self
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||
function CARGO_UNIT:onenterLoaded( From, Event, To, CargoCarrier )
|
||||
self:F( { From, Event, To, CargoCarrier } )
|
||||
|
||||
-- Only destroy the CargoObject is if there is a CargoObject (packages don't have CargoObjects).
|
||||
if self.CargoObject then
|
||||
self:T("Destroying")
|
||||
self.CargoObject:Destroy()
|
||||
self.CargoCarrier = CargoCarrier
|
||||
|
||||
-- Only destroy the CargoObject is if there is a CargoObject (packages don't have CargoObjects).
|
||||
if self.CargoObject then
|
||||
self:T("Destroying")
|
||||
self.CargoObject:Destroy()
|
||||
end
|
||||
end
|
||||
|
||||
end -- CARGO_UNIT
|
||||
|
||||
|
||||
do -- CARGO_CRATE
|
||||
|
||||
--- Models the behaviour of cargo crates, which can be slingloaded and boarded on helicopters using the DCS menus.
|
||||
-- @type CARGO_CRATE
|
||||
-- @extends #CARGO_REPRESENTABLE
|
||||
|
||||
--- # CARGO\_CRATE class, extends @{#CARGO_REPRESENTABLE}
|
||||
--
|
||||
-- The CARGO\_CRATE class defines a cargo that is represented by a UNIT object within the simulator, and can be transported by a carrier.
|
||||
-- Use the event functions as described above to Load, UnLoad, Board, UnBoard the CARGO\_CRATE objects to and from carriers.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #CARGO_CRATE
|
||||
CARGO_CRATE = {
|
||||
ClassName = "CARGO_CRATE"
|
||||
}
|
||||
|
||||
--- CARGO_CRATE Constructor.
|
||||
-- @param #CARGO_CRATE self
|
||||
-- @param #string CrateName
|
||||
-- @param #string Type
|
||||
-- @param #string Name
|
||||
-- @param #number Weight
|
||||
-- @param #number ReportRadius (optional)
|
||||
-- @param #number NearRadius (optional)
|
||||
-- @return #CARGO_CRATE
|
||||
function CARGO_CRATE:New( CargoCrateName, Type, Name, NearRadius )
|
||||
local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoCrateName, Type, Name, nil, NearRadius ) ) -- #CARGO_CRATE
|
||||
self:F( { Type, Name, NearRadius } )
|
||||
|
||||
self:T( CargoCrateName )
|
||||
_DATABASE:AddStatic( CargoCrateName )
|
||||
|
||||
self.CargoObject = STATIC:FindByName( CargoCrateName )
|
||||
|
||||
self:T( self.ClassName )
|
||||
|
||||
self:SetEventPriority( 5 )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Enter UnLoaded State.
|
||||
-- @param #CARGO_CRATE self
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
-- @param Core.Point#POINT_VEC2
|
||||
function CARGO_CRATE:onenterUnLoaded( From, Event, To, ToPointVec2 )
|
||||
self:F( { ToPointVec2, From, Event, To } )
|
||||
|
||||
local Angle = 180
|
||||
local Speed = 10
|
||||
local Distance = 10
|
||||
|
||||
if From == "Loaded" then
|
||||
local StartCoordinate = self.CargoCarrier:GetCoordinate()
|
||||
local CargoCarrierHeading = self.CargoCarrier:GetHeading() -- Get Heading of object in degrees.
|
||||
local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle )
|
||||
local CargoDeployCoord = StartCoordinate:Translate( Distance, CargoDeployHeading )
|
||||
|
||||
ToPointVec2 = ToPointVec2 or COORDINATE:NewFromVec2( { x= CargoDeployCoord.x, y = CargoDeployCoord.z } )
|
||||
|
||||
-- Respawn the group...
|
||||
if self.CargoObject then
|
||||
self.CargoObject:ReSpawn( ToPointVec2, 0 )
|
||||
self.CargoCarrier = nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if self.OnUnLoadedCallBack then
|
||||
self.OnUnLoadedCallBack( self, unpack( self.OnUnLoadedParameters ) )
|
||||
self.OnUnLoadedCallBack = nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- Loaded State.
|
||||
-- @param #CARGO_CRATE self
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||
function CARGO_CRATE:onenterLoaded( From, Event, To, CargoCarrier )
|
||||
self:F( { From, Event, To, CargoCarrier } )
|
||||
|
||||
self.CargoCarrier = CargoCarrier
|
||||
|
||||
-- Only destroy the CargoObject is if there is a CargoObject (packages don't have CargoObjects).
|
||||
if self.CargoObject then
|
||||
self:T("Destroying")
|
||||
self.CargoObject:Destroy()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
do -- CARGO_GROUP
|
||||
|
||||
--- @type CARGO_GROUP
|
||||
|
||||
@ -522,7 +522,7 @@ function DATABASE:_RegisterStaticTemplate( StaticTemplate, CoalitionID, Category
|
||||
|
||||
|
||||
TraceTable[#TraceTable+1] = "Static"
|
||||
TraceTable[#TraceTable+1] = self.Templates.Statics[StaticTemplateName].GroupName
|
||||
TraceTable[#TraceTable+1] = self.Templates.Statics[StaticTemplateName].StaticName
|
||||
|
||||
TraceTable[#TraceTable+1] = "Coalition"
|
||||
TraceTable[#TraceTable+1] = self.Templates.Statics[StaticTemplateName].CoalitionID
|
||||
@ -649,6 +649,7 @@ end
|
||||
function DATABASE:_RegisterStatics()
|
||||
|
||||
local CoalitionsData = { GroupsRed = coalition.getStaticObjects( coalition.side.RED ), GroupsBlue = coalition.getStaticObjects( coalition.side.BLUE ) }
|
||||
self:E( { Statics = CoalitionsData } )
|
||||
for CoalitionId, CoalitionData in pairs( CoalitionsData ) do
|
||||
for DCSStaticId, DCSStatic in pairs( CoalitionData ) do
|
||||
|
||||
|
||||
@ -157,8 +157,13 @@ function SPAWNSTATIC:SpawnFromPointVec2( PointVec2, Heading, NewName ) --R2.1
|
||||
|
||||
local StaticTemplate = _DATABASE:GetStaticUnitTemplate( self.SpawnTemplatePrefix )
|
||||
|
||||
StaticTemplate.x = PointVec2:GetLat()
|
||||
StaticTemplate.y = PointVec2:GetLon()
|
||||
StaticTemplate.x = PointVec2.x
|
||||
StaticTemplate.y = PointVec2.z
|
||||
|
||||
StaticTemplate.units = nil
|
||||
StaticTemplate.route = nil
|
||||
StaticTemplate.groupId = nil
|
||||
|
||||
|
||||
StaticTemplate.name = NewName or string.format("%s#%05d", self.SpawnTemplatePrefix, self.SpawnIndex )
|
||||
StaticTemplate.heading = ( Heading / 180 ) * math.pi
|
||||
|
||||
@ -108,6 +108,8 @@ function AIRBASEPOLICE_BASE:New( SetClient, Airbases )
|
||||
)
|
||||
|
||||
self.AirbaseMonitor = SCHEDULER:New( self, self._AirbaseMonitor, {}, 0, 2, 0.05 )
|
||||
|
||||
trigger.action.setUserFlag("SSB",100)
|
||||
|
||||
return self
|
||||
end
|
||||
@ -181,22 +183,9 @@ function AIRBASEPOLICE_BASE:_AirbaseMonitor()
|
||||
Client:Message( "You are speeding on the taxiway! Slow down or you will be removed from this airbase! Your current velocity is " .. string.format( "%2.0f km/h", Velocity ), 5, "Warning " .. SpeedingWarnings .. " / 3" )
|
||||
Client:SetState( self, "Warnings", SpeedingWarnings + 1 )
|
||||
else
|
||||
MESSAGE:New( "Player " .. Client:GetPlayerName() .. " is being damaged at the airbase, due to a speeding violation ...", 10, "Airbase Police" ):ToAll()
|
||||
MESSAGE:New( "Player " .. Client:GetPlayerName() .. " is being kicked from the airbase, due to a speeding violation ...", 10, "Airbase Police" ):ToAll()
|
||||
--- @param Wrapper.Client#CLIENT Client
|
||||
local function DestroyUntilHeavilyDamaged( Client )
|
||||
local ClientCoord = Client:GetCoordinate()
|
||||
ClientCoord:Explosion( 100 )
|
||||
local Damage = Client:GetLife()
|
||||
local InitialLife = Client:GetLife0()
|
||||
MESSAGE:New( "Player " .. Client:GetPlayerName() .. " Damage ... " .. Damage, 5, "Airbase Police" ):ToAll()
|
||||
if ( Damage / InitialLife ) * 100 < 80 then
|
||||
Client:ScheduleStop( DestroyUntilHeavilyDamaged )
|
||||
end
|
||||
end
|
||||
Client:ScheduleOnce( 1, DestroyUntilHeavilyDamaged, Client )
|
||||
--Client:ScheduleRepeat( 1, 1, 0, nil, DestroyUntilHeavilyDamaged, Client )
|
||||
--Client:Destroy()
|
||||
trigger.action.setUserFlag( "AIRCRAFT_"..Client:GetID(), 100)
|
||||
Client:Destroy()
|
||||
Client:SetState( self, "Speeding", false )
|
||||
Client:SetState( self, "Warnings", 0 )
|
||||
end
|
||||
|
||||
452
Moose Development/Moose/Functional/ZoneGoalCargo.lua
Normal file
452
Moose Development/Moose/Functional/ZoneGoalCargo.lua
Normal file
@ -0,0 +1,452 @@
|
||||
--- **Functional (WIP)** -- Base class that models processes to achieve goals involving a Zone and Cargo.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- ZONE_GOAL_CARGO models processes that have a Goal with a defined achievement involving a Zone and Cargo.
|
||||
-- Derived classes implement the ways how the achievements can be realized.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- @module ZoneGoalCargo
|
||||
|
||||
do -- ZoneGoal
|
||||
|
||||
--- @type ZONE_GOAL_CARGO
|
||||
-- @extends Functional.ZoneGoal#ZONE_GOAL
|
||||
|
||||
|
||||
--- # ZONE_GOAL_CARGO class, extends @{ZoneGoal#ZONE_GOAL}
|
||||
--
|
||||
-- ZONE_GOAL_CARGO models processes that have a Goal with a defined achievement involving a Zone and Cargo.
|
||||
-- Derived classes implement the ways how the achievements can be realized.
|
||||
--
|
||||
-- ## 1. ZONE_GOAL_CARGO constructor
|
||||
--
|
||||
-- * @{#ZONE_GOAL_CARGO.New}(): Creates a new ZONE_GOAL_CARGO object.
|
||||
--
|
||||
-- ## 2. ZONE_GOAL_CARGO is a finite state machine (FSM).
|
||||
--
|
||||
-- ### 2.1 ZONE_GOAL_CARGO States
|
||||
--
|
||||
-- * **Deployed**: The Zone has been captured by an other coalition.
|
||||
-- * **Airborne**: The Zone is currently intruded by an other coalition. There are units of the owning coalition and an other coalition in the Zone.
|
||||
-- * **Loaded**: The Zone is guarded by the owning coalition. There is no other unit of an other coalition in the Zone.
|
||||
-- * **Empty**: The Zone is empty. There is not valid unit in the Zone.
|
||||
--
|
||||
-- ### 2.2 ZONE_GOAL_CARGO Events
|
||||
--
|
||||
-- * **Capture**: The Zone has been captured by an other coalition.
|
||||
-- * **Attack**: The Zone is currently intruded by an other coalition. There are units of the owning coalition and an other coalition in the Zone.
|
||||
-- * **Guard**: The Zone is guarded by the owning coalition. There is no other unit of an other coalition in the Zone.
|
||||
-- * **Empty**: The Zone is empty. There is not valid unit in the Zone.
|
||||
--
|
||||
-- ### 2.3 ZONE_GOAL_CARGO State Machine
|
||||
--
|
||||
-- @field #ZONE_GOAL_CARGO
|
||||
ZONE_GOAL_CARGO = {
|
||||
ClassName = "ZONE_GOAL_CARGO",
|
||||
}
|
||||
|
||||
--- @field #table ZONE_GOAL_CARGO.States
|
||||
ZONE_GOAL_CARGO.States = {}
|
||||
|
||||
--- ZONE_GOAL_CARGO Constructor.
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
-- @param Core.Zone#ZONE Zone A @{Zone} object with the goal to be achieved.
|
||||
-- @param DCSCoalition.DCSCoalition#coalition Coalition The initial coalition owning the zone.
|
||||
-- @return #ZONE_GOAL_CARGO
|
||||
function ZONE_GOAL_CARGO:New( Zone, Coalition )
|
||||
|
||||
local self = BASE:Inherit( self, ZONE_GOAL:New( Zone ) ) -- #ZONE_GOAL_CARGO
|
||||
self:F( { Zone = Zone, Coalition = Coalition } )
|
||||
|
||||
self:SetCoalition( Coalition )
|
||||
|
||||
do
|
||||
|
||||
--- Captured State Handler OnLeave for ZONE_GOAL_CARGO
|
||||
-- @function [parent=#ZONE_GOAL_CARGO] OnLeaveCaptured
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @return #boolean
|
||||
|
||||
--- Captured State Handler OnEnter for ZONE_GOAL_CARGO
|
||||
-- @function [parent=#ZONE_GOAL_CARGO] OnEnterCaptured
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
|
||||
end
|
||||
|
||||
|
||||
do
|
||||
|
||||
--- Attacked State Handler OnLeave for ZONE_GOAL_CARGO
|
||||
-- @function [parent=#ZONE_GOAL_CARGO] OnLeaveAttacked
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @return #boolean
|
||||
|
||||
--- Attacked State Handler OnEnter for ZONE_GOAL_CARGO
|
||||
-- @function [parent=#ZONE_GOAL_CARGO] OnEnterAttacked
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
|
||||
end
|
||||
|
||||
do
|
||||
|
||||
--- Guarded State Handler OnLeave for ZONE_GOAL_CARGO
|
||||
-- @function [parent=#ZONE_GOAL_CARGO] OnLeaveGuarded
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @return #boolean
|
||||
|
||||
--- Guarded State Handler OnEnter for ZONE_GOAL_CARGO
|
||||
-- @function [parent=#ZONE_GOAL_CARGO] OnEnterGuarded
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
|
||||
end
|
||||
|
||||
|
||||
do
|
||||
|
||||
--- Empty State Handler OnLeave for ZONE_GOAL_CARGO
|
||||
-- @function [parent=#ZONE_GOAL_CARGO] OnLeaveEmpty
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @return #boolean
|
||||
|
||||
--- Empty State Handler OnEnter for ZONE_GOAL_CARGO
|
||||
-- @function [parent=#ZONE_GOAL_CARGO] OnEnterEmpty
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
|
||||
end
|
||||
|
||||
self:AddTransition( "*", "Guard", "Guarded" )
|
||||
|
||||
--- Guard Handler OnBefore for ZONE_GOAL_CARGO
|
||||
-- @function [parent=#ZONE_GOAL_CARGO] OnBeforeGuard
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @return #boolean
|
||||
|
||||
--- Guard Handler OnAfter for ZONE_GOAL_CARGO
|
||||
-- @function [parent=#ZONE_GOAL_CARGO] OnAfterGuard
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
|
||||
--- Guard Trigger for ZONE_GOAL_CARGO
|
||||
-- @function [parent=#ZONE_GOAL_CARGO] Guard
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
|
||||
--- Guard Asynchronous Trigger for ZONE_GOAL_CARGO
|
||||
-- @function [parent=#ZONE_GOAL_CARGO] __Guard
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
-- @param #number Delay
|
||||
|
||||
self:AddTransition( "*", "Empty", "Empty" )
|
||||
|
||||
--- Empty Handler OnBefore for ZONE_GOAL_CARGO
|
||||
-- @function [parent=#ZONE_GOAL_CARGO] OnBeforeEmpty
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @return #boolean
|
||||
|
||||
--- Empty Handler OnAfter for ZONE_GOAL_CARGO
|
||||
-- @function [parent=#ZONE_GOAL_CARGO] OnAfterEmpty
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
|
||||
--- Empty Trigger for ZONE_GOAL_CARGO
|
||||
-- @function [parent=#ZONE_GOAL_CARGO] Empty
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
|
||||
--- Empty Asynchronous Trigger for ZONE_GOAL_CARGO
|
||||
-- @function [parent=#ZONE_GOAL_CARGO] __Empty
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
-- @param #number Delay
|
||||
|
||||
|
||||
self:AddTransition( { "Guarded", "Empty" }, "Attack", "Attacked" )
|
||||
|
||||
--- Attack Handler OnBefore for ZONE_GOAL_CARGO
|
||||
-- @function [parent=#ZONE_GOAL_CARGO] OnBeforeAttack
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @return #boolean
|
||||
|
||||
--- Attack Handler OnAfter for ZONE_GOAL_CARGO
|
||||
-- @function [parent=#ZONE_GOAL_CARGO] OnAfterAttack
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
|
||||
--- Attack Trigger for ZONE_GOAL_CARGO
|
||||
-- @function [parent=#ZONE_GOAL_CARGO] Attack
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
|
||||
--- Attack Asynchronous Trigger for ZONE_GOAL_CARGO
|
||||
-- @function [parent=#ZONE_GOAL_CARGO] __Attack
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
-- @param #number Delay
|
||||
|
||||
self:AddTransition( { "Guarded", "Attacked", "Empty" }, "Capture", "Captured" )
|
||||
|
||||
--- Capture Handler OnBefore for ZONE_GOAL_CARGO
|
||||
-- @function [parent=#ZONE_GOAL_CARGO] OnBeforeCapture
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @return #boolean
|
||||
|
||||
--- Capture Handler OnAfter for ZONE_GOAL_CARGO
|
||||
-- @function [parent=#ZONE_GOAL_CARGO] OnAfterCapture
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
|
||||
--- Capture Trigger for ZONE_GOAL_CARGO
|
||||
-- @function [parent=#ZONE_GOAL_CARGO] Capture
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
|
||||
--- Capture Asynchronous Trigger for ZONE_GOAL_CARGO
|
||||
-- @function [parent=#ZONE_GOAL_CARGO] __Capture
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
-- @param #number Delay
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Set the owning coalition of the zone.
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
-- @param DCSCoalition.DCSCoalition#coalition Coalition
|
||||
function ZONE_GOAL_CARGO:SetCoalition( Coalition )
|
||||
self.Coalition = Coalition
|
||||
end
|
||||
|
||||
|
||||
--- Get the owning coalition of the zone.
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
-- @return DCSCoalition.DCSCoalition#coalition Coalition.
|
||||
function ZONE_GOAL_CARGO:GetCoalition()
|
||||
return self.Coalition
|
||||
end
|
||||
|
||||
|
||||
--- Get the owning coalition name of the zone.
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
-- @return #string Coalition name.
|
||||
function ZONE_GOAL_CARGO:GetCoalitionName()
|
||||
|
||||
if self.Coalition == coalition.side.BLUE then
|
||||
return "Blue"
|
||||
end
|
||||
|
||||
if self.Coalition == coalition.side.RED then
|
||||
return "Red"
|
||||
end
|
||||
|
||||
if self.Coalition == coalition.side.NEUTRAL then
|
||||
return "Neutral"
|
||||
end
|
||||
|
||||
return ""
|
||||
end
|
||||
|
||||
|
||||
function ZONE_GOAL_CARGO:IsGuarded()
|
||||
|
||||
local IsGuarded = self.Zone:IsAllInZoneOfCoalition( self.Coalition )
|
||||
self:E( { IsGuarded = IsGuarded } )
|
||||
return IsGuarded
|
||||
end
|
||||
|
||||
|
||||
function ZONE_GOAL_CARGO:IsEmpty()
|
||||
|
||||
local IsEmpty = self.Zone:IsNoneInZone()
|
||||
self:E( { IsEmpty = IsEmpty } )
|
||||
return IsEmpty
|
||||
end
|
||||
|
||||
|
||||
function ZONE_GOAL_CARGO:IsCaptured()
|
||||
|
||||
local IsCaptured = self.Zone:IsAllInZoneOfOtherCoalition( self.Coalition )
|
||||
self:E( { IsCaptured = IsCaptured } )
|
||||
return IsCaptured
|
||||
end
|
||||
|
||||
|
||||
function ZONE_GOAL_CARGO:IsAttacked()
|
||||
|
||||
local IsAttacked = self.Zone:IsSomeInZoneOfCoalition( self.Coalition )
|
||||
self:E( { IsAttacked = IsAttacked } )
|
||||
return IsAttacked
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Mark.
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
function ZONE_GOAL_CARGO:Mark()
|
||||
|
||||
local Coord = self.Zone:GetCoordinate()
|
||||
local ZoneName = self:GetZoneName()
|
||||
local State = self:GetState()
|
||||
|
||||
if self.MarkRed and self.MarkBlue then
|
||||
self:E( { MarkRed = self.MarkRed, MarkBlue = self.MarkBlue } )
|
||||
Coord:RemoveMark( self.MarkRed )
|
||||
Coord:RemoveMark( self.MarkBlue )
|
||||
end
|
||||
|
||||
if self.Coalition == coalition.side.BLUE then
|
||||
self.MarkBlue = Coord:MarkToCoalitionBlue( "Guard Zone: " .. ZoneName .. "\nStatus: " .. State )
|
||||
self.MarkRed = Coord:MarkToCoalitionRed( "Capture Zone: " .. ZoneName .. "\nStatus: " .. State )
|
||||
else
|
||||
self.MarkRed = Coord:MarkToCoalitionRed( "Guard Zone: " .. ZoneName .. "\nStatus: " .. State )
|
||||
self.MarkBlue = Coord:MarkToCoalitionBlue( "Capture Zone: " .. ZoneName .. "\nStatus: " .. State )
|
||||
end
|
||||
end
|
||||
|
||||
--- Bound.
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
function ZONE_GOAL_CARGO:onenterGuarded()
|
||||
|
||||
--self:GetParent( self ):onenterGuarded()
|
||||
|
||||
if self.Coalition == coalition.side.BLUE then
|
||||
--elf.ProtectZone:BoundZone( 12, country.id.USA )
|
||||
else
|
||||
--self.ProtectZone:BoundZone( 12, country.id.RUSSIA )
|
||||
end
|
||||
|
||||
self:Mark()
|
||||
|
||||
end
|
||||
|
||||
function ZONE_GOAL_CARGO:onenterCaptured()
|
||||
|
||||
--self:GetParent( self ):onenterCaptured()
|
||||
|
||||
local NewCoalition = self.Zone:GetCoalition()
|
||||
self:E( { NewCoalition = NewCoalition } )
|
||||
self:SetCoalition( NewCoalition )
|
||||
|
||||
self:Mark()
|
||||
end
|
||||
|
||||
|
||||
function ZONE_GOAL_CARGO:onenterEmpty()
|
||||
|
||||
--self:GetParent( self ):onenterEmpty()
|
||||
|
||||
self:Mark()
|
||||
end
|
||||
|
||||
|
||||
function ZONE_GOAL_CARGO:onenterAttacked()
|
||||
|
||||
--self:GetParent( self ):onenterAttacked()
|
||||
|
||||
self:Mark()
|
||||
end
|
||||
|
||||
|
||||
--- When started, check the Coalition status.
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
function ZONE_GOAL_CARGO:onafterGuard()
|
||||
|
||||
--self:E({BASE:GetParent( self )})
|
||||
--BASE:GetParent( self ).onafterGuard( self )
|
||||
|
||||
if not self.SmokeScheduler then
|
||||
self.SmokeScheduler = self:ScheduleRepeat( 1, 1, 0.1, nil, self.StatusSmoke, self )
|
||||
end
|
||||
if not self.ScheduleStatusZone then
|
||||
self.ScheduleStatusZone = self:ScheduleRepeat( 15, 15, 0.1, nil, self.StatusZone, self )
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function ZONE_GOAL_CARGO:IsCaptured()
|
||||
|
||||
local IsCaptured = self.Zone:IsAllInZoneOfOtherCoalition( self.Coalition )
|
||||
self:E( { IsCaptured = IsCaptured } )
|
||||
return IsCaptured
|
||||
end
|
||||
|
||||
|
||||
function ZONE_GOAL_CARGO:IsAttacked()
|
||||
|
||||
local IsAttacked = self.Zone:IsSomeInZoneOfCoalition( self.Coalition )
|
||||
self:E( { IsAttacked = IsAttacked } )
|
||||
return IsAttacked
|
||||
end
|
||||
|
||||
--- Check status Coalition ownership.
|
||||
-- @param #ZONE_GOAL_CARGO self
|
||||
function ZONE_GOAL_CARGO:StatusZone()
|
||||
|
||||
local State = self:GetState()
|
||||
self:E( { State = self:GetState() } )
|
||||
|
||||
self.Zone:Scan()
|
||||
|
||||
if State ~= "Guarded" and self:IsGuarded() then
|
||||
self:Guard()
|
||||
end
|
||||
|
||||
if State ~= "Empty" and self:IsEmpty() then
|
||||
self:Empty()
|
||||
end
|
||||
|
||||
if State ~= "Attacked" and self:IsAttacked() then
|
||||
self:Attack()
|
||||
end
|
||||
|
||||
if State ~= "Captured" and self:IsCaptured() then
|
||||
self:Capture()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -206,6 +206,7 @@ do -- TASK_ZONE_CAPTURE
|
||||
ClassName = "TASK_ZONE_CAPTURE",
|
||||
}
|
||||
|
||||
|
||||
--- Instantiates a new TASK_ZONE_CAPTURE.
|
||||
-- @param #TASK_ZONE_CAPTURE self
|
||||
-- @param Tasking.Mission#MISSION Mission
|
||||
@ -236,6 +237,7 @@ do -- TASK_ZONE_CAPTURE
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Instantiates a new TASK_ZONE_CAPTURE.
|
||||
-- @param #TASK_ZONE_CAPTURE self
|
||||
function TASK_ZONE_CAPTURE:UpdateTaskInfo()
|
||||
@ -247,6 +249,7 @@ do -- TASK_ZONE_CAPTURE
|
||||
self:SetInfo( "Zone Coalition", self.ZoneGoal:GetCoalitionName(), 11 )
|
||||
end
|
||||
|
||||
|
||||
function TASK_ZONE_CAPTURE:ReportOrder( ReportGroup )
|
||||
local Coordinate = self:GetInfo( "Coordinate" )
|
||||
--local Coordinate = self.TaskInfo.Coordinates.TaskInfoText
|
||||
|
||||
@ -224,6 +224,7 @@ function GROUP:Destroy()
|
||||
for Index, UnitData in pairs( DCSGroup:getUnits() ) do
|
||||
self:CreateEventCrash( timer.getTime(), UnitData )
|
||||
end
|
||||
USERFLAG:New( self:GetName() ):Set( 100 )
|
||||
DCSGroup:destroy()
|
||||
DCSGroup = nil
|
||||
end
|
||||
@ -231,6 +232,7 @@ function GROUP:Destroy()
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- Returns category of the DCS Group.
|
||||
-- @param #GROUP self
|
||||
-- @return Dcs.DCSWrapper.Group#Group.Category The category ID
|
||||
|
||||
@ -79,7 +79,7 @@ function OBJECT:Destroy()
|
||||
local DCSObject = self:GetDCSObject()
|
||||
|
||||
if DCSObject then
|
||||
|
||||
--BASE:CreateEventCrash( timer.getTime(), DCSObject )
|
||||
DCSObject:destroy()
|
||||
end
|
||||
|
||||
|
||||
@ -61,7 +61,6 @@ function STATIC:FindByName( StaticName, RaiseError )
|
||||
|
||||
if StaticFound then
|
||||
StaticFound:F3( { StaticName } )
|
||||
|
||||
return StaticFound
|
||||
end
|
||||
|
||||
@ -92,4 +91,18 @@ end
|
||||
function STATIC:GetThreatLevel()
|
||||
|
||||
return 1, "Static"
|
||||
end
|
||||
end
|
||||
|
||||
--- Respawn the @{Unit} using a (tweaked) template of the parent Group.
|
||||
-- @param #UNIT self
|
||||
-- @param Core.Point#COORDINATE Coordinate The coordinate where to spawn the new Static.
|
||||
-- @param #number Heading The heading of the unit respawn.
|
||||
function STATIC:ReSpawn( Coordinate, Heading )
|
||||
|
||||
|
||||
-- todo: need to fix country
|
||||
local SpawnStatic = SPAWNSTATIC:NewFromStatic( self.StaticName, country.id.USA )
|
||||
|
||||
SpawnStatic:SpawnFromPointVec2( Coordinate, Heading, self.StaticName )
|
||||
end
|
||||
|
||||
|
||||
@ -159,6 +159,24 @@ function UNIT:GetDCSObject()
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Destroys the UNIT.
|
||||
-- @param #UNIT self
|
||||
-- @return #nil The DCS Unit is not existing or alive.
|
||||
function UNIT:Destroy()
|
||||
self:F2( self.ObjectName )
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
|
||||
if DCSObject then
|
||||
USERFLAG:New( self:GetGroup():GetName() ):Set( 100 )
|
||||
--BASE:CreateEventCrash( timer.getTime(), DCSObject )
|
||||
DCSObject:destroy()
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- Respawn the @{Unit} using a (tweaked) template of the parent Group.
|
||||
--
|
||||
-- This function will:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user