From 2be38c493c647caa5962fb45b0519402be54dce8 Mon Sep 17 00:00:00 2001 From: jaynus Date: Fri, 17 Apr 2015 10:21:41 -0700 Subject: [PATCH 01/12] ACE JIP synchronized event infastructure. --- addons/common/XEH_postInit.sqf | 7 ++- addons/common/XEH_preInit.sqf | 12 +++++ .../fnc__handleRequestSyncedEvent.sqf | 37 +++++++++++++ .../functions/fnc__handleSyncedEvent.sqf | 36 +++++++++++++ .../functions/fnc_addSyncedEventHandler.sqf | 32 ++++++++++++ .../fnc_removeSyncedEventHandler.sqf | 24 +++++++++ .../functions/fnc_requestSyncedEvent.sqf | 17 ++++++ addons/common/functions/fnc_syncedEvent.sqf | 31 +++++++++++ .../common/functions/fnc_syncedEventPFH.sqf | 52 +++++++++++++++++++ 9 files changed, 247 insertions(+), 1 deletion(-) create mode 100644 addons/common/functions/fnc__handleRequestSyncedEvent.sqf create mode 100644 addons/common/functions/fnc__handleSyncedEvent.sqf create mode 100644 addons/common/functions/fnc_addSyncedEventHandler.sqf create mode 100644 addons/common/functions/fnc_removeSyncedEventHandler.sqf create mode 100644 addons/common/functions/fnc_requestSyncedEvent.sqf create mode 100644 addons/common/functions/fnc_syncedEvent.sqf create mode 100644 addons/common/functions/fnc_syncedEventPFH.sqf diff --git a/addons/common/XEH_postInit.sqf b/addons/common/XEH_postInit.sqf index e470e91c95..96b0f34356 100644 --- a/addons/common/XEH_postInit.sqf +++ b/addons/common/XEH_postInit.sqf @@ -87,7 +87,7 @@ enableCamShake true; // Set the name for the current player ["playerChanged", { EXPLODE_2_PVT(_this,_newPlayer,_oldPlayer); - + diag_log text format["PLAYER CHANGED!", _this]; if (alive _newPlayer) then { [_newPlayer] call FUNC(setName) }; @@ -188,3 +188,8 @@ GVAR(OldPlayerWeapon) = currentWeapon ACE_player; // Players can always interact with passengers of the same vehicle {!((_this select 0) isEqualTo (_this select 1)) && {vehicle (_this select 0) == vehicle (_this select 1)}} }] call FUNC(addCanInteractWithCondition); + +// Synced ACE events +["SEH", FUNC(_handleSyncedEvent)] call FUNC(addEventHandler); +["SEH_s", FUNC(_handleRequestSyncedEvent)] call FUNC(addEventHandler); +[FUNC(syncedEventPFH), 0.5, []] call cba_fnc_addPerFrameHandler; diff --git a/addons/common/XEH_preInit.sqf b/addons/common/XEH_preInit.sqf index b5382d0b5e..5bacea7505 100644 --- a/addons/common/XEH_preInit.sqf +++ b/addons/common/XEH_preInit.sqf @@ -269,6 +269,18 @@ PREP(hashListSelect); PREP(hashListSet); PREP(hashListPush); +// Synchronized Events +PREP(syncedEventPFH); +PREP(addSyncedEventHandler); +PREP(removeSyncedEventHandler); +PREP(syncedEvent); +PREP(_handleSyncedEvent); +PREP(_handleRequestSyncedEvent); +PREP(requestSyncedEvent); +GVAR(syncedEvents) = HASH_CREATE; + +// @TODO: Generic local-managed global-synced objects (createVehicleLocal) + //Debug ACE_COUNTERS = []; diff --git a/addons/common/functions/fnc__handleRequestSyncedEvent.sqf b/addons/common/functions/fnc__handleRequestSyncedEvent.sqf new file mode 100644 index 0000000000..643ce40916 --- /dev/null +++ b/addons/common/functions/fnc__handleRequestSyncedEvent.sqf @@ -0,0 +1,37 @@ +/* + * Author: jaynus + * + * + * Argument: + * + * Return value: + * Boolean of success + */ + #define DEBUG_MODE_FULL +#include "script_component.hpp" + +//SEH_s +if(isServer) then { + // Find the event name, and shovel out the events to the client + PARAMS_2(_eventName,_client); + private["_eventEntry", "_eventLog"]; + + if(!HASH_HASKEY(GVAR(syncedEvents),_eventName)) exitWith { + diag_log text format["[ACE] Error, request for synced event - key not found."]; + false + }; + _eventEntry = HASH_GET(GVAR(syncedEvents),_eventName); + _eventLog = _eventEntry select 1; + + ["SEH_s", _client, [_eventName, _eventLog] ] call FUNC(targetEvent); +} else { + PARAMS_2(_eventName,_eventLog); + // This is the client handling the response from the server + // Start running the events + { + _eventArgs = _x select 1; + [_eventName, _eventArgs, (_x select 2)] call FUNC(_handleSyncedEvent); + } forEach _eventLog; +}; + +true \ No newline at end of file diff --git a/addons/common/functions/fnc__handleSyncedEvent.sqf b/addons/common/functions/fnc__handleSyncedEvent.sqf new file mode 100644 index 0000000000..14dfc32bae --- /dev/null +++ b/addons/common/functions/fnc__handleSyncedEvent.sqf @@ -0,0 +1,36 @@ +/* + * Author: jaynus + * + * Call and propegate a synced event + * + * Argument: + * 0: Name (String) + * 1: Arguments (Array) + * 2: TTL (Number or Code) [Optional] + * + * Return value: + * Boolean of success + */ +#define DEBUG_MODE_FULL +#include "script_component.hpp" +PARAMS_3(_name,_args,_ttl); +private["_internalData", "_eventLog", "_eventCode"]; + +if(!HASH_HASKEY(GVAR(syncedEvents),_name)) exitWith { + diag_log text format["[ACE] Error, synced event key not found."]; + false +}; + +_internalData = HASH_GET(GVAR(syncedEvents),_name); + +if(isServer) then { + // Server needs to internally log it for synchronization + if(_ttl > -1) then { + _internalData = HASH_GET(GVAR(syncedEvents),_name); + _eventLog = _internalData select 1; + _eventLog pushback [diag_tickTime, _args, _ttl]; + }; +}; + +_eventCode = _internalData select 0; +_args call _eventCode; \ No newline at end of file diff --git a/addons/common/functions/fnc_addSyncedEventHandler.sqf b/addons/common/functions/fnc_addSyncedEventHandler.sqf new file mode 100644 index 0000000000..ab9d8bb829 --- /dev/null +++ b/addons/common/functions/fnc_addSyncedEventHandler.sqf @@ -0,0 +1,32 @@ +/* + * Author: jaynus + * + * Register an event handler for an ACE synced event + * + * Argument: + * 0: Name (String) + * 1: Handler (Code) + * 2: TTL (Number or Code) [Optional] + * + * Return value: + * Boolean of success + */ +#define DEBUG_MODE_FULL +#include "script_component.hpp" +PARAMS_2(_name,_handler); + +private["_ttl", "_eventId", "_data"]; +if( (count _this) > 2) then { + _ttl = _this select 2; +} else { + _ttl = 0; +}; + +if(HASH_HASKEY(GVAR(syncedEvents),_name)) exitWith { + diag_log text format["[ACE] Error, duplicate synced event creation."]; + false +}; + +_eventId = [_name, FUNC(_handleSyncedEvent)] call FUNC(addEventHandler); +_data = [_handler,[],_ttl,_eventId]; +HASH_SET(GVAR(syncedEvents),_name,_data); \ No newline at end of file diff --git a/addons/common/functions/fnc_removeSyncedEventHandler.sqf b/addons/common/functions/fnc_removeSyncedEventHandler.sqf new file mode 100644 index 0000000000..6429120bbe --- /dev/null +++ b/addons/common/functions/fnc_removeSyncedEventHandler.sqf @@ -0,0 +1,24 @@ +/* + * Author: jaynus + * + * Remove a synced event handler + * + * Argument: + * 0: Name (String) + * + * Return value: + * Boolean of success + */ +#include "script_component.hpp" +PARAMS_1(_name); + +if(!HASH_HASKEY(GVAR(syncedEvents),_name)) exitWith { + diag_log text format["[ACE] Error, synced event key not found."]; + false +}; + +_data = HASH_GET(GVAR(syncedEvents),_name); +_eventId = _data select 3; + +[_eventId] call ace_common_fnc_removeEventHandler; +HASH_REM(GVAR(syncedEvents),_name); \ No newline at end of file diff --git a/addons/common/functions/fnc_requestSyncedEvent.sqf b/addons/common/functions/fnc_requestSyncedEvent.sqf new file mode 100644 index 0000000000..f18c3542b5 --- /dev/null +++ b/addons/common/functions/fnc_requestSyncedEvent.sqf @@ -0,0 +1,17 @@ +/* + * Author: jaynus + * + * + * Argument: + * + * Return value: + * Boolean of success + */ +#define DEBUG_MODE_FULL +#include "script_component.hpp" +PARAMS_1(_eventName); + +// Only JIP machines on initialization send this off, requesting sync on events with the serverCommand +if(isServer) exitWith { false }; + +["SEH_s", [_eventName, ACE_player] ] call ace_common_fnc_serverEvent; \ No newline at end of file diff --git a/addons/common/functions/fnc_syncedEvent.sqf b/addons/common/functions/fnc_syncedEvent.sqf new file mode 100644 index 0000000000..43f4feb5bd --- /dev/null +++ b/addons/common/functions/fnc_syncedEvent.sqf @@ -0,0 +1,31 @@ +/* + * Author: jaynus + * + * Call and propegate a synced event + * + * Argument: + * 0: Name (String) + * 1: Arguments (Array) + * 2: TTL (Number or Code) [Optional] for this specific event call + * + * Return value: + * Boolean of success + */ +#define DEBUG_MODE_FULL +#include "script_component.hpp" +PARAMS_2(_name,_args); +private["_ttl", "_eventData", "_internalData", "_eventLog"]; + +if( (count _this) > 2) then { + _ttl = _this select 2; +} else { + _ttl = 0; +}; + +if(!HASH_HASKEY(GVAR(syncedEvents),_name)) exitWith { + diag_log text format["[ACE] Error, synced event key not found."]; + false +}; + +_eventData = [_name, _args,_ttl]; +["SEH", _eventData] call FUNC(globalEvent); \ No newline at end of file diff --git a/addons/common/functions/fnc_syncedEventPFH.sqf b/addons/common/functions/fnc_syncedEventPFH.sqf new file mode 100644 index 0000000000..e8a21202ab --- /dev/null +++ b/addons/common/functions/fnc_syncedEventPFH.sqf @@ -0,0 +1,52 @@ +//#define DEBUG_MODE_FULL +#include "script_component.hpp" + +if(!isServer) exitWith { false }; + +// Walk through the local synced events and clean up anything thats already EOL +// @TODO: This should be iteration limited to prevent FPS lag +private["_data"]; +{ + private["_data", "_ttl", "_eventLog", "_newEventLog", "_name"]; + _name = _x; + + _data = HASH_GET(GVAR(syncedEvents),_name); + _eventLog = _data select 1; + _globalEventTTL = _data select 2; + _newEventLog = []; + + // @TODO: This should be iteration limited to prevent FPS lag + { + private["_eventEntry", "_ttlReturn"]; + _eventEntry = _x; + + _ttlReturn = true; + if(typeName _globalEventTTL == "CODE") then { + _ttlReturn = [(_data select 0),_eventEntry] call _globalEventTTL; + } else { + _ttlReturn = call { _globalEventTTL < 1 || {diag_tickTime < (_eventEntry select 0) + _globalEventTTL} }; + }; + + if(_ttlReturn) then { + // Do event based TTL check + private["_eventTTL"]; + _eventTTL = _eventEntry select 2; + + if(typeName _eventTTL == "CODE") then { + _ttlReturn = [(_data select 0),_eventEntry] call _eventTTL; + } else { + _ttlReturn = call { _eventTTL < 1 || {diag_tickTime < (_eventEntry select 0) + _eventTTL} }; + }; + }; + + // Finally drop it if the TTL check fails + if(_ttlReturn) then { + _newEventLog pushBack _x; + }; + } forEach _eventLog; + + _data set[1, _newEventLog]; +} forEach (GVAR(syncedEvents) select 0); + + +// @TODO: Next, detect if we had a new request from a JIP player, and we need to continue syncing events From 8fa0c91632289fbae1138da693f038e5fe234884 Mon Sep 17 00:00:00 2001 From: jaynus Date: Fri, 17 Apr 2015 18:23:26 -0700 Subject: [PATCH 02/12] Added PlayerJIP event, handled full requests on JIP. --- addons/common/XEH_postInit.sqf | 27 ++++++++++++++++++- .../fnc__handleRequestAllSyncedEvents.sqf | 23 ++++++++++++++++ .../fnc__handleRequestSyncedEvent.sqf | 2 +- 3 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 addons/common/functions/fnc__handleRequestAllSyncedEvents.sqf diff --git a/addons/common/XEH_postInit.sqf b/addons/common/XEH_postInit.sqf index 96b0f34356..d228d77d7b 100644 --- a/addons/common/XEH_postInit.sqf +++ b/addons/common/XEH_postInit.sqf @@ -107,7 +107,6 @@ GVAR(OldPlayerWeapon) = currentWeapon ACE_player; // PFH to raise varios events [{ - // "playerInventoryChanged" event _newPlayerInventory = [ACE_player] call FUNC(getAllGear); if !(_newPlayerInventory isEqualTo GVAR(OldPlayerInventory)) then { @@ -190,6 +189,32 @@ GVAR(OldPlayerWeapon) = currentWeapon ACE_player; }] call FUNC(addCanInteractWithCondition); // Synced ACE events +// Handle JIP scenario +if(!isServer) then{ + ["PlayerJip", { + diag_log text format["[ACE] - JIP event synchronization initialized"]; + ["SEH_all", [player]] call FUNC(serverEvent); + }] call FUNC(addEventHandler); +} else { + ["SEH_all", FUNC(_handleRequestAllSyncedEvents)] call FUNC(addEventHandler); +}; ["SEH", FUNC(_handleSyncedEvent)] call FUNC(addEventHandler); ["SEH_s", FUNC(_handleRequestSyncedEvent)] call FUNC(addEventHandler); [FUNC(syncedEventPFH), 0.5, []] call cba_fnc_addPerFrameHandler; + + +// JIP Detection and event trigger. Run this at the very end, just in case anything uses it +if(isNull player) then { + // We are jipping! Get ready and wait, and throw the event + [{ + PARAMS_2(_args,_handle); + + if(!isNull player) then { + ["PlayerJip", [player] ] call FUNC(localEvent); + [_handle] call cba_fnc_removePerFrameHandler; + }; + }, 0, []] call cba_fnc_addPerFrameHandler; +}; + + + diff --git a/addons/common/functions/fnc__handleRequestAllSyncedEvents.sqf b/addons/common/functions/fnc__handleRequestAllSyncedEvents.sqf new file mode 100644 index 0000000000..62981092fb --- /dev/null +++ b/addons/common/functions/fnc__handleRequestAllSyncedEvents.sqf @@ -0,0 +1,23 @@ +/* + * Author: jaynus + * + * + * Argument: + * + * Return value: + * Boolean of success + */ +#define DEBUG_MODE_FULL +#include "script_component.hpp" +PARAMS_1(_client); + +{ + private["_eventName", "_eventEntry", "_eventLog"]; + _eventName = _x; + _eventEntry = HASH_GET(GVAR(syncedEvents),_eventName); + _eventLog = _eventEntry select 1; + + ["SEH_s", _client, [_eventName, _eventLog] ] call FUNC(targetEvent); +} forEach (GVAR(syncedEvents) select 0); + +true \ No newline at end of file diff --git a/addons/common/functions/fnc__handleRequestSyncedEvent.sqf b/addons/common/functions/fnc__handleRequestSyncedEvent.sqf index 643ce40916..c9b81f8ef7 100644 --- a/addons/common/functions/fnc__handleRequestSyncedEvent.sqf +++ b/addons/common/functions/fnc__handleRequestSyncedEvent.sqf @@ -7,7 +7,7 @@ * Return value: * Boolean of success */ - #define DEBUG_MODE_FULL +#define DEBUG_MODE_FULL #include "script_component.hpp" //SEH_s From da09b74fe4bfcdc663f5c977e451f9c5c8b5b90e Mon Sep 17 00:00:00 2001 From: jaynus Date: Fri, 17 Apr 2015 18:27:35 -0700 Subject: [PATCH 03/12] Don't JIP check server side, but still have it fire for HC. --- addons/common/XEH_postInit.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/common/XEH_postInit.sqf b/addons/common/XEH_postInit.sqf index d228d77d7b..34ada15480 100644 --- a/addons/common/XEH_postInit.sqf +++ b/addons/common/XEH_postInit.sqf @@ -204,7 +204,7 @@ if(!isServer) then{ // JIP Detection and event trigger. Run this at the very end, just in case anything uses it -if(isNull player) then { +if(!isServer && {isNull player}) then { // We are jipping! Get ready and wait, and throw the event [{ PARAMS_2(_args,_handle); From 93d03b404fdef3153a6d689cf8c87e2e713340db Mon Sep 17 00:00:00 2001 From: jaynus Date: Fri, 17 Apr 2015 19:26:27 -0700 Subject: [PATCH 04/12] JIP Sync events complete. --- addons/common/XEH_postInit.sqf | 49 +++++++++++-------- addons/common/XEH_preInit.sqf | 5 +- .../fnc__handleRequestAllSyncedEvents.sqf | 4 +- .../fnc__handleRequestSyncedEvent.sqf | 14 ++++-- .../functions/fnc__handleSyncedEvent.sqf | 14 +++--- .../functions/fnc_addSyncedEventHandler.sqf | 2 +- .../functions/fnc_requestSyncedEvent.sqf | 4 +- addons/common/functions/fnc_syncedEvent.sqf | 2 +- 8 files changed, 58 insertions(+), 36 deletions(-) diff --git a/addons/common/XEH_postInit.sqf b/addons/common/XEH_postInit.sqf index 34ada15480..2a20c0204d 100644 --- a/addons/common/XEH_postInit.sqf +++ b/addons/common/XEH_postInit.sqf @@ -65,9 +65,31 @@ if (_currentVersion != _previousVersion) then { 0 spawn COMPILE_FILE(scripts\Version\checkVersionNumber); +// ACE events "ACEg" addPublicVariableEventHandler { _this call FUNC(_handleNetEvent); }; "ACEc" addPublicVariableEventHandler { _this call FUNC(_handleNetEvent); }; +// Synced ACE events +// Handle JIP scenario +if(!isServer) then { + ["PlayerJip", { + diag_log text format["[ACE] * JIP event synchronization initialized"]; + ["SEH_all", [player]] call FUNC(serverEvent); + }] call FUNC(addEventHandler); +} else { + ["SEH_all", FUNC(_handleRequestAllSyncedEvents)] call FUNC(addEventHandler); +}; +["SEH", FUNC(_handleSyncedEvent)] call FUNC(addEventHandler); +["SEH_s", FUNC(_handleRequestSyncedEvent)] call FUNC(addEventHandler); +[FUNC(syncedEventPFH), 0.5, []] call cba_fnc_addPerFrameHandler; + + +/***************************************************************/ +/***************************************************************/ +/***************************************************************/ +/***************************************************************/ +/***************************************************************/ + // everything that only player controlled machines need, goes below this if (!hasInterface) exitWith {}; @@ -87,7 +109,7 @@ enableCamShake true; // Set the name for the current player ["playerChanged", { EXPLODE_2_PVT(_this,_newPlayer,_oldPlayer); - diag_log text format["PLAYER CHANGED!", _this]; + if (alive _newPlayer) then { [_newPlayer] call FUNC(setName) }; @@ -188,30 +210,15 @@ GVAR(OldPlayerWeapon) = currentWeapon ACE_player; {!((_this select 0) isEqualTo (_this select 1)) && {vehicle (_this select 0) == vehicle (_this select 1)}} }] call FUNC(addCanInteractWithCondition); -// Synced ACE events -// Handle JIP scenario -if(!isServer) then{ - ["PlayerJip", { - diag_log text format["[ACE] - JIP event synchronization initialized"]; - ["SEH_all", [player]] call FUNC(serverEvent); - }] call FUNC(addEventHandler); -} else { - ["SEH_all", FUNC(_handleRequestAllSyncedEvents)] call FUNC(addEventHandler); -}; -["SEH", FUNC(_handleSyncedEvent)] call FUNC(addEventHandler); -["SEH_s", FUNC(_handleRequestSyncedEvent)] call FUNC(addEventHandler); -[FUNC(syncedEventPFH), 0.5, []] call cba_fnc_addPerFrameHandler; - - +// Lastly, do JIP events // JIP Detection and event trigger. Run this at the very end, just in case anything uses it -if(!isServer && {isNull player}) then { +if(isMultiplayer && { time > 0 || isNull player } ) then { // We are jipping! Get ready and wait, and throw the event [{ - PARAMS_2(_args,_handle); - - if(!isNull player) then { + diag_log text format["JIP Detected, waiting"]; + if(!(isNull player)) then { ["PlayerJip", [player] ] call FUNC(localEvent); - [_handle] call cba_fnc_removePerFrameHandler; + [(_this select 1)] call cba_fnc_removePerFrameHandler; }; }, 0, []] call cba_fnc_addPerFrameHandler; }; diff --git a/addons/common/XEH_preInit.sqf b/addons/common/XEH_preInit.sqf index 5bacea7505..077d69578b 100644 --- a/addons/common/XEH_preInit.sqf +++ b/addons/common/XEH_preInit.sqf @@ -273,10 +273,13 @@ PREP(hashListPush); PREP(syncedEventPFH); PREP(addSyncedEventHandler); PREP(removeSyncedEventHandler); +PREP(requestSyncedEvent); PREP(syncedEvent); + PREP(_handleSyncedEvent); PREP(_handleRequestSyncedEvent); -PREP(requestSyncedEvent); +PREP(_handleRequestAllSyncedEvents); + GVAR(syncedEvents) = HASH_CREATE; // @TODO: Generic local-managed global-synced objects (createVehicleLocal) diff --git a/addons/common/functions/fnc__handleRequestAllSyncedEvents.sqf b/addons/common/functions/fnc__handleRequestAllSyncedEvents.sqf index 62981092fb..7c566ce4d1 100644 --- a/addons/common/functions/fnc__handleRequestAllSyncedEvents.sqf +++ b/addons/common/functions/fnc__handleRequestAllSyncedEvents.sqf @@ -1,13 +1,15 @@ /* * Author: jaynus * + * Handles a server-side request for synchronization ALL events on JIP to a client. * * Argument: + * 0: client (object) * * Return value: * Boolean of success */ -#define DEBUG_MODE_FULL +//#define DEBUG_MODE_FULL #include "script_component.hpp" PARAMS_1(_client); diff --git a/addons/common/functions/fnc__handleRequestSyncedEvent.sqf b/addons/common/functions/fnc__handleRequestSyncedEvent.sqf index c9b81f8ef7..2d58aae869 100644 --- a/addons/common/functions/fnc__handleRequestSyncedEvent.sqf +++ b/addons/common/functions/fnc__handleRequestSyncedEvent.sqf @@ -1,13 +1,20 @@ /* * Author: jaynus + * + * Receives either requests for synchronization from clients, or the synchronization data from the server. * - * - * Argument: + * Arguments [Client] : + * 0: eventName (String) + * 1: eventLog (Array) + * + * Arguments [Server] : + * 0: eventName (String) + * 1: client (Object) * * Return value: * Boolean of success */ -#define DEBUG_MODE_FULL +//#define DEBUG_MODE_FULL #include "script_component.hpp" //SEH_s @@ -32,6 +39,7 @@ if(isServer) then { _eventArgs = _x select 1; [_eventName, _eventArgs, (_x select 2)] call FUNC(_handleSyncedEvent); } forEach _eventLog; + diag_log text format["[ACE] + [%1] synchronized", _eventName]; }; true \ No newline at end of file diff --git a/addons/common/functions/fnc__handleSyncedEvent.sqf b/addons/common/functions/fnc__handleSyncedEvent.sqf index 14dfc32bae..9807896358 100644 --- a/addons/common/functions/fnc__handleSyncedEvent.sqf +++ b/addons/common/functions/fnc__handleSyncedEvent.sqf @@ -1,17 +1,17 @@ /* * Author: jaynus + * + * Handles synced events being received. Server will log them, and server/client will execute them. * - * Call and propegate a synced event - * - * Argument: - * 0: Name (String) - * 1: Arguments (Array) - * 2: TTL (Number or Code) [Optional] + * Arguments [Client] : + * 0: eventName (String) + * 1: arguments (Array) + * 2: ttl (Scalar) * * Return value: * Boolean of success */ -#define DEBUG_MODE_FULL +//#define DEBUG_MODE_FULL #include "script_component.hpp" PARAMS_3(_name,_args,_ttl); private["_internalData", "_eventLog", "_eventCode"]; diff --git a/addons/common/functions/fnc_addSyncedEventHandler.sqf b/addons/common/functions/fnc_addSyncedEventHandler.sqf index ab9d8bb829..5d2b221178 100644 --- a/addons/common/functions/fnc_addSyncedEventHandler.sqf +++ b/addons/common/functions/fnc_addSyncedEventHandler.sqf @@ -11,7 +11,7 @@ * Return value: * Boolean of success */ -#define DEBUG_MODE_FULL +//#define DEBUG_MODE_FULL #include "script_component.hpp" PARAMS_2(_name,_handler); diff --git a/addons/common/functions/fnc_requestSyncedEvent.sqf b/addons/common/functions/fnc_requestSyncedEvent.sqf index f18c3542b5..dea0c7adef 100644 --- a/addons/common/functions/fnc_requestSyncedEvent.sqf +++ b/addons/common/functions/fnc_requestSyncedEvent.sqf @@ -1,13 +1,15 @@ /* * Author: jaynus * + * Send a request to synchronize an event name from the client->server. Execute on client only. * * Argument: + * 0: eventName (String) * * Return value: * Boolean of success */ -#define DEBUG_MODE_FULL +//#define DEBUG_MODE_FULL #include "script_component.hpp" PARAMS_1(_eventName); diff --git a/addons/common/functions/fnc_syncedEvent.sqf b/addons/common/functions/fnc_syncedEvent.sqf index 43f4feb5bd..70c30a19da 100644 --- a/addons/common/functions/fnc_syncedEvent.sqf +++ b/addons/common/functions/fnc_syncedEvent.sqf @@ -11,7 +11,7 @@ * Return value: * Boolean of success */ -#define DEBUG_MODE_FULL +//#define DEBUG_MODE_FULL #include "script_component.hpp" PARAMS_2(_name,_args); private["_ttl", "_eventData", "_internalData", "_eventLog"]; From 32df4a2adcd827eff4b0cf3cff08f2b240571c9f Mon Sep 17 00:00:00 2001 From: jaynus Date: Fri, 17 Apr 2015 19:33:07 -0700 Subject: [PATCH 05/12] synced events implemented into litter. --- addons/medical/XEH_postInit.sqf | 4 + addons/medical/XEH_preInit.sqf | 5 +- .../functions/fnc__handleCreateLitter.sqf | 115 ++++++++++++++++++ addons/medical/functions/fnc_createLitter.sqf | 103 +--------------- 4 files changed, 127 insertions(+), 100 deletions(-) create mode 100644 addons/medical/functions/fnc__handleCreateLitter.sqf diff --git a/addons/medical/XEH_postInit.sqf b/addons/medical/XEH_postInit.sqf index 309bb2a888..68e3b7965b 100644 --- a/addons/medical/XEH_postInit.sqf +++ b/addons/medical/XEH_postInit.sqf @@ -265,3 +265,7 @@ if (USE_WOUND_EVENT_SYNC) then { ["playerInventoryChanged", { [ACE_player] call FUNC(itemCheck); }] call EFUNC(common,addEventHandler); + + +// Synchronized litter creation +[QGVAR(createLitter), FUNC(_handleCreateLitter)] call EFUNC(common,addEventHandler); \ No newline at end of file diff --git a/addons/medical/XEH_preInit.sqf b/addons/medical/XEH_preInit.sqf index f15b4ec109..bdfbedb429 100644 --- a/addons/medical/XEH_preInit.sqf +++ b/addons/medical/XEH_preInit.sqf @@ -21,7 +21,6 @@ PREP(adjustPainLevel); PREP(canAccessMedicalEquipment); PREP(canTreat); PREP(canTreatCached); -PREP(createLitter); PREP(determineIfFatal); PREP(getBloodLoss); PREP(getBloodPressure); @@ -98,6 +97,10 @@ PREP(moduleTreatmentConfiguration); PREP(copyDeadBody); PREP(requestWoundSync); +// Litter handling functionality test +PREP(createLitter); +PREP(_handleCreateLitter); + GVAR(injuredUnitCollection) = []; GVAR(IVBags) = []; diff --git a/addons/medical/functions/fnc__handleCreateLitter.sqf b/addons/medical/functions/fnc__handleCreateLitter.sqf new file mode 100644 index 0000000000..e7751e153b --- /dev/null +++ b/addons/medical/functions/fnc__handleCreateLitter.sqf @@ -0,0 +1,115 @@ +/* + * Author: Glowbal + * Spawns litter for the treatment action on the ground around the target + * + * Arguments: + * 0: The target + * 1: The treatment classname + * + * Return Value: + * + * + * Public: No + */ + +#include "script_component.hpp" + +#define MIN_ENTRIES_LITTER_CONFIG 3 + +if(hasInterface) then { + private ["_config", "_litter", "_createLitter", "_litterObject", "_position", "_createdLitter"]; + PARAMS_6(_caller,_target,_selectionName,_className,_usersOfItems); + + _caller = _this select 0; + _target = _this select 1; + _selectionName = _this select 2; + _className = _this select 3; + _usersOfItems = _this select 5; + + if !(GVAR(allowLitterCreation)) exitwith {}; + if (vehicle _caller != _caller || vehicle _target != _target) exitwith {}; + + _config = (configFile >> "ACE_Medical_Actions" >> "Basic" >> _className); + if (GVAR(level) >= 2) then { + _config = (configFile >> "ACE_Medical_Actions" >> "Advanced" >> _className); + }; + if !(isClass _config) exitwith {false}; + + + if !(isArray (_config >> "litter")) exitwith {}; + _litter = getArray (_config >> "litter"); + + _createLitter = { + _position = getPos (_this select 0); + _litterClass = _this select 1; + _litterObject = createVehicle [_litterClass, _position, [], 0, "NONE"]; + if (random(1) >= 0.5) then { + _litterObject setPos [(_position select 0) + random 2, (_position select 1) + random 2, _position select 2]; + } else { + _litterObject setPos [(_position select 0) - random 2, (_position select 1) - random 2, _position select 2]; + }; + _litterObject setDir (random 360); + _litterObject; + }; + + if (isnil QGVAR(allCreatedLitter)) then { + GVAR(allCreatedLitter) = []; + GVAR(litterPFHRunning) = false; + }; + + _createdLitter = []; + { + if (typeName _x == "ARRAY") then { + if (count _x < MIN_ENTRIES_LITTER_CONFIG) exitwith {}; + private ["_selection", "_litterCondition", "_litterOptions"]; + _selection = _x select 0; + if (toLower _selection in [toLower _selectionName, "all"]) then { // in is case sensitve. We can be forgiving here, so lets use toLower. + _litterCondition = _x select 1; + _litterOptions = _x select 2; + + if (isnil _litterCondition) then { + _litterCondition = if (_litterCondition != "") then {compile _litterCondition} else {{true}}; + } else { + _litterCondition = missionNamespace getvariable _litterCondition; + }; + if !([_caller, _target, _selectionName, _className, _usersOfItems] call _litterCondition) exitwith {}; + + if (typeName _litterOptions == "ARRAY") then { + // Loop through through the litter options and place the litter + { + if (typeName _x == "ARRAY" && {(count _x > 0)}) then { + _createdLitter pushback ([_target, _x select (floor(random(count _x)))] call _createLitter); + }; + if (typeName _x == "STRING") then { + _createdLitter pushback ([_target, _x] call _createLitter); + }; + }foreach _litterOptions; + }; + }; + }; + }foreach _litter; + + if (GVAR(litterCleanUpDelay) >= 0) then { + GVAR(allCreatedLitter) pushback [time, GVAR(litterCleanUpDelay), _createdLitter]; + }; + + if !(GVAR(litterPFHRunning)) then { + GVAR(litterPFHRunning) = true; + [{ + { + if (time - (_x select 0) >= (_x select 1)) then { + { + deleteVehicle _x; + }foreach (_this select 2); + GVAR(allCreatedLitter) set[_foreachIndex, objNull]; + }; + }foreach GVAR(allCreatedLitter); + GVAR(allCreatedLitter) = GVAR(allCreatedLitter) - [objNull]; + + if (count GVAR(allCreatedLitter) == 0) exitwith { + GVAR(litterPFHRunning) = false; + [_this select 1] call CBA_fnc_removePerFrameHandler; + }; + }, 30, []] call CBA_fnc_addPerFrameHandler; + }; +}; \ No newline at end of file diff --git a/addons/medical/functions/fnc_createLitter.sqf b/addons/medical/functions/fnc_createLitter.sqf index 570c6d63d3..edc16c186e 100644 --- a/addons/medical/functions/fnc_createLitter.sqf +++ b/addons/medical/functions/fnc_createLitter.sqf @@ -1,10 +1,8 @@ /* - * Author: Glowbal - * Spawns litter for the treatment action on the ground around the target + * Author: jaynus * * Arguments: - * 0: The target - * 1: The treatment classname + * * * Return Value: * @@ -14,98 +12,5 @@ #include "script_component.hpp" -#define MIN_ENTRIES_LITTER_CONFIG 3 - -private ["_target", "_className", "_config", "_litter", "_createLitter", "_litterObject", "_position", "_createdLitter"]; -_caller = _this select 0; -_target = _this select 1; -_selectionName = _this select 2; -_className = _this select 3; -_usersOfItems = _this select 5; - -if !(GVAR(allowLitterCreation)) exitwith {}; -if (vehicle _caller != _caller || vehicle _target != _target) exitwith {}; - -_config = (configFile >> "ACE_Medical_Actions" >> "Basic" >> _className); -if (GVAR(level) >= 2) then { - _config = (configFile >> "ACE_Medical_Actions" >> "Advanced" >> _className); -}; -if !(isClass _config) exitwith {false}; - - -if !(isArray (_config >> "litter")) exitwith {}; -_litter = getArray (_config >> "litter"); - -_createLitter = { - _position = getPos (_this select 0); - _litterClass = _this select 1; - _litterObject = createVehicle [_litterClass, _position, [], 0, "NONE"]; - if (random(1) >= 0.5) then { - _litterObject setPos [(_position select 0) + random 2, (_position select 1) + random 2, _position select 2]; - } else { - _litterObject setPos [(_position select 0) - random 2, (_position select 1) - random 2, _position select 2]; - }; - _litterObject setDir (random 360); - _litterObject; -}; - -if (isnil QGVAR(allCreatedLitter)) then { - GVAR(allCreatedLitter) = []; - GVAR(litterPFHRunning) = false; -}; - -_createdLitter = []; -{ - if (typeName _x == "ARRAY") then { - if (count _x < MIN_ENTRIES_LITTER_CONFIG) exitwith {}; - private ["_selection", "_litterCondition", "_litterOptions"]; - _selection = _x select 0; - if (toLower _selection in [toLower _selectionName, "all"]) then { // in is case sensitve. We can be forgiving here, so lets use toLower. - _litterCondition = _x select 1; - _litterOptions = _x select 2; - - if (isnil _litterCondition) then { - _litterCondition = if (_litterCondition != "") then {compile _litterCondition} else {{true}}; - } else { - _litterCondition = missionNamespace getvariable _litterCondition; - }; - if !([_caller, _target, _selectionName, _className, _usersOfItems] call _litterCondition) exitwith {}; - - if (typeName _litterOptions == "ARRAY") then { - // Loop through through the litter options and place the litter - { - if (typeName _x == "ARRAY" && {(count _x > 0)}) then { - _createdLitter pushback ([_target, _x select (floor(random(count _x)))] call _createLitter); - }; - if (typeName _x == "STRING") then { - _createdLitter pushback ([_target, _x] call _createLitter); - }; - }foreach _litterOptions; - }; - }; - }; -}foreach _litter; - -if (GVAR(litterCleanUpDelay) >= 0) then { - GVAR(allCreatedLitter) pushback [time, GVAR(litterCleanUpDelay), _createdLitter]; -}; - -if !(GVAR(litterPFHRunning)) then { - GVAR(litterPFHRunning) = true; - [{ - { - if (time - (_x select 0) >= (_x select 1)) then { - { - deleteVehicle _x; - }foreach (_this select 2); - GVAR(allCreatedLitter) set[_foreachIndex, objNull]; - }; - }foreach GVAR(allCreatedLitter); - GVAR(allCreatedLitter) = GVAR(allCreatedLitter) - [objNull]; - - if (count GVAR(allCreatedLitter) == 0) exitwith { - GVAR(litterPFHRunning) = false; - [_this select 1] call CBA_fnc_removePerFrameHandler; - }; - }, 30, []] call CBA_fnc_addPerFrameHandler; -}; +// Create a synchronized, 30 second TTL event for litter +[QGVAR(createLitter), _this, 30] call EFUNC(common,syncedEvent); \ No newline at end of file From c952a97de83ba462ffcb76630af1addfe6e2ba40 Mon Sep 17 00:00:00 2001 From: jaynus Date: Fri, 17 Apr 2015 19:38:05 -0700 Subject: [PATCH 06/12] Revert "synced events implemented into litter." This reverts commit 32df4a2adcd827eff4b0cf3cff08f2b240571c9f. --- addons/medical/XEH_postInit.sqf | 4 - addons/medical/XEH_preInit.sqf | 5 +- .../functions/fnc__handleCreateLitter.sqf | 115 ------------------ addons/medical/functions/fnc_createLitter.sqf | 103 +++++++++++++++- 4 files changed, 100 insertions(+), 127 deletions(-) delete mode 100644 addons/medical/functions/fnc__handleCreateLitter.sqf diff --git a/addons/medical/XEH_postInit.sqf b/addons/medical/XEH_postInit.sqf index 68e3b7965b..309bb2a888 100644 --- a/addons/medical/XEH_postInit.sqf +++ b/addons/medical/XEH_postInit.sqf @@ -265,7 +265,3 @@ if (USE_WOUND_EVENT_SYNC) then { ["playerInventoryChanged", { [ACE_player] call FUNC(itemCheck); }] call EFUNC(common,addEventHandler); - - -// Synchronized litter creation -[QGVAR(createLitter), FUNC(_handleCreateLitter)] call EFUNC(common,addEventHandler); \ No newline at end of file diff --git a/addons/medical/XEH_preInit.sqf b/addons/medical/XEH_preInit.sqf index bdfbedb429..f15b4ec109 100644 --- a/addons/medical/XEH_preInit.sqf +++ b/addons/medical/XEH_preInit.sqf @@ -21,6 +21,7 @@ PREP(adjustPainLevel); PREP(canAccessMedicalEquipment); PREP(canTreat); PREP(canTreatCached); +PREP(createLitter); PREP(determineIfFatal); PREP(getBloodLoss); PREP(getBloodPressure); @@ -97,10 +98,6 @@ PREP(moduleTreatmentConfiguration); PREP(copyDeadBody); PREP(requestWoundSync); -// Litter handling functionality test -PREP(createLitter); -PREP(_handleCreateLitter); - GVAR(injuredUnitCollection) = []; GVAR(IVBags) = []; diff --git a/addons/medical/functions/fnc__handleCreateLitter.sqf b/addons/medical/functions/fnc__handleCreateLitter.sqf deleted file mode 100644 index e7751e153b..0000000000 --- a/addons/medical/functions/fnc__handleCreateLitter.sqf +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Author: Glowbal - * Spawns litter for the treatment action on the ground around the target - * - * Arguments: - * 0: The target - * 1: The treatment classname - * - * Return Value: - * - * - * Public: No - */ - -#include "script_component.hpp" - -#define MIN_ENTRIES_LITTER_CONFIG 3 - -if(hasInterface) then { - private ["_config", "_litter", "_createLitter", "_litterObject", "_position", "_createdLitter"]; - PARAMS_6(_caller,_target,_selectionName,_className,_usersOfItems); - - _caller = _this select 0; - _target = _this select 1; - _selectionName = _this select 2; - _className = _this select 3; - _usersOfItems = _this select 5; - - if !(GVAR(allowLitterCreation)) exitwith {}; - if (vehicle _caller != _caller || vehicle _target != _target) exitwith {}; - - _config = (configFile >> "ACE_Medical_Actions" >> "Basic" >> _className); - if (GVAR(level) >= 2) then { - _config = (configFile >> "ACE_Medical_Actions" >> "Advanced" >> _className); - }; - if !(isClass _config) exitwith {false}; - - - if !(isArray (_config >> "litter")) exitwith {}; - _litter = getArray (_config >> "litter"); - - _createLitter = { - _position = getPos (_this select 0); - _litterClass = _this select 1; - _litterObject = createVehicle [_litterClass, _position, [], 0, "NONE"]; - if (random(1) >= 0.5) then { - _litterObject setPos [(_position select 0) + random 2, (_position select 1) + random 2, _position select 2]; - } else { - _litterObject setPos [(_position select 0) - random 2, (_position select 1) - random 2, _position select 2]; - }; - _litterObject setDir (random 360); - _litterObject; - }; - - if (isnil QGVAR(allCreatedLitter)) then { - GVAR(allCreatedLitter) = []; - GVAR(litterPFHRunning) = false; - }; - - _createdLitter = []; - { - if (typeName _x == "ARRAY") then { - if (count _x < MIN_ENTRIES_LITTER_CONFIG) exitwith {}; - private ["_selection", "_litterCondition", "_litterOptions"]; - _selection = _x select 0; - if (toLower _selection in [toLower _selectionName, "all"]) then { // in is case sensitve. We can be forgiving here, so lets use toLower. - _litterCondition = _x select 1; - _litterOptions = _x select 2; - - if (isnil _litterCondition) then { - _litterCondition = if (_litterCondition != "") then {compile _litterCondition} else {{true}}; - } else { - _litterCondition = missionNamespace getvariable _litterCondition; - }; - if !([_caller, _target, _selectionName, _className, _usersOfItems] call _litterCondition) exitwith {}; - - if (typeName _litterOptions == "ARRAY") then { - // Loop through through the litter options and place the litter - { - if (typeName _x == "ARRAY" && {(count _x > 0)}) then { - _createdLitter pushback ([_target, _x select (floor(random(count _x)))] call _createLitter); - }; - if (typeName _x == "STRING") then { - _createdLitter pushback ([_target, _x] call _createLitter); - }; - }foreach _litterOptions; - }; - }; - }; - }foreach _litter; - - if (GVAR(litterCleanUpDelay) >= 0) then { - GVAR(allCreatedLitter) pushback [time, GVAR(litterCleanUpDelay), _createdLitter]; - }; - - if !(GVAR(litterPFHRunning)) then { - GVAR(litterPFHRunning) = true; - [{ - { - if (time - (_x select 0) >= (_x select 1)) then { - { - deleteVehicle _x; - }foreach (_this select 2); - GVAR(allCreatedLitter) set[_foreachIndex, objNull]; - }; - }foreach GVAR(allCreatedLitter); - GVAR(allCreatedLitter) = GVAR(allCreatedLitter) - [objNull]; - - if (count GVAR(allCreatedLitter) == 0) exitwith { - GVAR(litterPFHRunning) = false; - [_this select 1] call CBA_fnc_removePerFrameHandler; - }; - }, 30, []] call CBA_fnc_addPerFrameHandler; - }; -}; \ No newline at end of file diff --git a/addons/medical/functions/fnc_createLitter.sqf b/addons/medical/functions/fnc_createLitter.sqf index edc16c186e..570c6d63d3 100644 --- a/addons/medical/functions/fnc_createLitter.sqf +++ b/addons/medical/functions/fnc_createLitter.sqf @@ -1,8 +1,10 @@ /* - * Author: jaynus + * Author: Glowbal + * Spawns litter for the treatment action on the ground around the target * * Arguments: - * + * 0: The target + * 1: The treatment classname * * Return Value: * @@ -12,5 +14,98 @@ #include "script_component.hpp" -// Create a synchronized, 30 second TTL event for litter -[QGVAR(createLitter), _this, 30] call EFUNC(common,syncedEvent); \ No newline at end of file +#define MIN_ENTRIES_LITTER_CONFIG 3 + +private ["_target", "_className", "_config", "_litter", "_createLitter", "_litterObject", "_position", "_createdLitter"]; +_caller = _this select 0; +_target = _this select 1; +_selectionName = _this select 2; +_className = _this select 3; +_usersOfItems = _this select 5; + +if !(GVAR(allowLitterCreation)) exitwith {}; +if (vehicle _caller != _caller || vehicle _target != _target) exitwith {}; + +_config = (configFile >> "ACE_Medical_Actions" >> "Basic" >> _className); +if (GVAR(level) >= 2) then { + _config = (configFile >> "ACE_Medical_Actions" >> "Advanced" >> _className); +}; +if !(isClass _config) exitwith {false}; + + +if !(isArray (_config >> "litter")) exitwith {}; +_litter = getArray (_config >> "litter"); + +_createLitter = { + _position = getPos (_this select 0); + _litterClass = _this select 1; + _litterObject = createVehicle [_litterClass, _position, [], 0, "NONE"]; + if (random(1) >= 0.5) then { + _litterObject setPos [(_position select 0) + random 2, (_position select 1) + random 2, _position select 2]; + } else { + _litterObject setPos [(_position select 0) - random 2, (_position select 1) - random 2, _position select 2]; + }; + _litterObject setDir (random 360); + _litterObject; +}; + +if (isnil QGVAR(allCreatedLitter)) then { + GVAR(allCreatedLitter) = []; + GVAR(litterPFHRunning) = false; +}; + +_createdLitter = []; +{ + if (typeName _x == "ARRAY") then { + if (count _x < MIN_ENTRIES_LITTER_CONFIG) exitwith {}; + private ["_selection", "_litterCondition", "_litterOptions"]; + _selection = _x select 0; + if (toLower _selection in [toLower _selectionName, "all"]) then { // in is case sensitve. We can be forgiving here, so lets use toLower. + _litterCondition = _x select 1; + _litterOptions = _x select 2; + + if (isnil _litterCondition) then { + _litterCondition = if (_litterCondition != "") then {compile _litterCondition} else {{true}}; + } else { + _litterCondition = missionNamespace getvariable _litterCondition; + }; + if !([_caller, _target, _selectionName, _className, _usersOfItems] call _litterCondition) exitwith {}; + + if (typeName _litterOptions == "ARRAY") then { + // Loop through through the litter options and place the litter + { + if (typeName _x == "ARRAY" && {(count _x > 0)}) then { + _createdLitter pushback ([_target, _x select (floor(random(count _x)))] call _createLitter); + }; + if (typeName _x == "STRING") then { + _createdLitter pushback ([_target, _x] call _createLitter); + }; + }foreach _litterOptions; + }; + }; + }; +}foreach _litter; + +if (GVAR(litterCleanUpDelay) >= 0) then { + GVAR(allCreatedLitter) pushback [time, GVAR(litterCleanUpDelay), _createdLitter]; +}; + +if !(GVAR(litterPFHRunning)) then { + GVAR(litterPFHRunning) = true; + [{ + { + if (time - (_x select 0) >= (_x select 1)) then { + { + deleteVehicle _x; + }foreach (_this select 2); + GVAR(allCreatedLitter) set[_foreachIndex, objNull]; + }; + }foreach GVAR(allCreatedLitter); + GVAR(allCreatedLitter) = GVAR(allCreatedLitter) - [objNull]; + + if (count GVAR(allCreatedLitter) == 0) exitwith { + GVAR(litterPFHRunning) = false; + [_this select 1] call CBA_fnc_removePerFrameHandler; + }; + }, 30, []] call CBA_fnc_addPerFrameHandler; +}; From f31e3c1fd4b335c6a2785af15c8edc1d999da7b3 Mon Sep 17 00:00:00 2001 From: jaynus Date: Sat, 18 Apr 2015 08:31:03 -0700 Subject: [PATCH 07/12] litter simulation createVehicleLocal /w temporal network sync. --- addons/medical/ACE_Settings.hpp | 6 +++ addons/medical/XEH_postInit.sqf | 4 ++ addons/medical/XEH_preInit.sqf | 5 +- addons/medical/functions/fnc_createLitter.sqf | 48 +++++-------------- .../functions/fnc_handleCreateLitter.sqf | 23 +++++++++ 5 files changed, 48 insertions(+), 38 deletions(-) create mode 100644 addons/medical/functions/fnc_handleCreateLitter.sqf diff --git a/addons/medical/ACE_Settings.hpp b/addons/medical/ACE_Settings.hpp index 56e5a531ec..81dd34a01a 100644 --- a/addons/medical/ACE_Settings.hpp +++ b/addons/medical/ACE_Settings.hpp @@ -124,4 +124,10 @@ class ACE_Settings { values[] = {"$STR_ACE_Medical_painEffect_Flash", "$STR_ACE_Medical_painEffect_Chroma"}; isClientSettable = 1; }; + + class GVAR(litterSimulationDetail) { + typeName = "SCALAR"; + value = 2; + values[] = {"None", "500", "All"}; + }; }; diff --git a/addons/medical/XEH_postInit.sqf b/addons/medical/XEH_postInit.sqf index 309bb2a888..c7390c18be 100644 --- a/addons/medical/XEH_postInit.sqf +++ b/addons/medical/XEH_postInit.sqf @@ -265,3 +265,7 @@ if (USE_WOUND_EVENT_SYNC) then { ["playerInventoryChanged", { [ACE_player] call FUNC(itemCheck); }] call EFUNC(common,addEventHandler); + + +// Networked litter +[QGVAR(createLitter), FUNC(handleCreateLitter)] call EFUNC(common,addSyncedEventHandler); \ No newline at end of file diff --git a/addons/medical/XEH_preInit.sqf b/addons/medical/XEH_preInit.sqf index f15b4ec109..78a2e7f71b 100644 --- a/addons/medical/XEH_preInit.sqf +++ b/addons/medical/XEH_preInit.sqf @@ -21,7 +21,6 @@ PREP(adjustPainLevel); PREP(canAccessMedicalEquipment); PREP(canTreat); PREP(canTreatCached); -PREP(createLitter); PREP(determineIfFatal); PREP(getBloodLoss); PREP(getBloodPressure); @@ -98,6 +97,10 @@ PREP(moduleTreatmentConfiguration); PREP(copyDeadBody); PREP(requestWoundSync); +// Networked litter +PREP(createLitter); +PREP(handleCreateLitter); + GVAR(injuredUnitCollection) = []; GVAR(IVBags) = []; diff --git a/addons/medical/functions/fnc_createLitter.sqf b/addons/medical/functions/fnc_createLitter.sqf index 570c6d63d3..cc3e32eb5e 100644 --- a/addons/medical/functions/fnc_createLitter.sqf +++ b/addons/medical/functions/fnc_createLitter.sqf @@ -37,21 +37,19 @@ if !(isArray (_config >> "litter")) exitwith {}; _litter = getArray (_config >> "litter"); _createLitter = { + private["_position", "_litterClass", "_direction"]; _position = getPos (_this select 0); _litterClass = _this select 1; - _litterObject = createVehicle [_litterClass, _position, [], 0, "NONE"]; if (random(1) >= 0.5) then { - _litterObject setPos [(_position select 0) + random 2, (_position select 1) + random 2, _position select 2]; + _position = [(_position select 0) + random 2, (_position select 1) + random 2, _position select 2]; } else { - _litterObject setPos [(_position select 0) - random 2, (_position select 1) - random 2, _position select 2]; + _position = [(_position select 0) - random 2, (_position select 1) - random 2, _position select 2]; }; - _litterObject setDir (random 360); - _litterObject; -}; - -if (isnil QGVAR(allCreatedLitter)) then { - GVAR(allCreatedLitter) = []; - GVAR(litterPFHRunning) = false; + _direction = (random 360); + + [QGVAR(createLitter), [_litterClass,_position,_direction], 0] call EFUNC(common,syncedEvent); + + true }; _createdLitter = []; @@ -75,37 +73,13 @@ _createdLitter = []; // Loop through through the litter options and place the litter { if (typeName _x == "ARRAY" && {(count _x > 0)}) then { - _createdLitter pushback ([_target, _x select (floor(random(count _x)))] call _createLitter); + [_target, _x select (floor(random(count _x)))] call _createLitter; }; if (typeName _x == "STRING") then { - _createdLitter pushback ([_target, _x] call _createLitter); + [_target, _x] call _createLitter; }; }foreach _litterOptions; }; }; }; -}foreach _litter; - -if (GVAR(litterCleanUpDelay) >= 0) then { - GVAR(allCreatedLitter) pushback [time, GVAR(litterCleanUpDelay), _createdLitter]; -}; - -if !(GVAR(litterPFHRunning)) then { - GVAR(litterPFHRunning) = true; - [{ - { - if (time - (_x select 0) >= (_x select 1)) then { - { - deleteVehicle _x; - }foreach (_this select 2); - GVAR(allCreatedLitter) set[_foreachIndex, objNull]; - }; - }foreach GVAR(allCreatedLitter); - GVAR(allCreatedLitter) = GVAR(allCreatedLitter) - [objNull]; - - if (count GVAR(allCreatedLitter) == 0) exitwith { - GVAR(litterPFHRunning) = false; - [_this select 1] call CBA_fnc_removePerFrameHandler; - }; - }, 30, []] call CBA_fnc_addPerFrameHandler; -}; +}foreach _litter; \ No newline at end of file diff --git a/addons/medical/functions/fnc_handleCreateLitter.sqf b/addons/medical/functions/fnc_handleCreateLitter.sqf new file mode 100644 index 0000000000..f6bd821831 --- /dev/null +++ b/addons/medical/functions/fnc_handleCreateLitter.sqf @@ -0,0 +1,23 @@ +#include "script_component.hpp" +PARAMS_3(_litterClass,_position,_direction); +private["_litterObject"]; + + + +if (isnil QGVAR(allCreatedLitter)) then { + GVAR(allCreatedLitter) = []; + GVAR(litterPFHRunning) = false; +}; + +if((count GVAR(allCreatedLitter)) <= GVAR(litterSimulationDetail) )then { + _litterObject = createVehicleLocal [_litterClass, _position, [], 0, "NONE"]; + _litterObject setDir _direction; +} else { + // @TODO: We hit max litter items, remove a few of them to work with what we have. + // Basically, we should just start FIFO'ing these +}; + +GVAR(allCreatedLitter) pushBack _litterObject; +//GVAR(allCreatedLitter) = GVAR(allCreatedLitter) - [objNull]; + +true \ No newline at end of file From c5f5b11d31e4c1a9820eae60b3fc08b0ced480b6 Mon Sep 17 00:00:00 2001 From: jaynus Date: Sat, 18 Apr 2015 08:37:21 -0700 Subject: [PATCH 08/12] strings. --- addons/medical/ACE_Settings.hpp | 6 ++++-- addons/medical/stringtable.xml | 6 ++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/addons/medical/ACE_Settings.hpp b/addons/medical/ACE_Settings.hpp index 81dd34a01a..51ff72f465 100644 --- a/addons/medical/ACE_Settings.hpp +++ b/addons/medical/ACE_Settings.hpp @@ -126,8 +126,10 @@ class ACE_Settings { }; class GVAR(litterSimulationDetail) { + displayName = "$STR_ACE_Medical_litterSimulationDetail"; + description = "$STR_ACE_Medical_litterSimulationDetail_Desc"; typeName = "SCALAR"; - value = 2; - values[] = {"None", "500", "All"}; + value = 500; + isClientSettable = 1; }; }; diff --git a/addons/medical/stringtable.xml b/addons/medical/stringtable.xml index 9f651e90b7..b77649a072 100644 --- a/addons/medical/stringtable.xml +++ b/addons/medical/stringtable.xml @@ -1,6 +1,12 @@  + + Litter Simulation Detail + + + Litter simulation detail level sets the number of litter items which will be locally spawned in the client. Excessive amounts in local areas could cause FPS lag, so this is a client only setting. + Inject Atropine Atropin injizieren From 852b4df61df411717f4fbfe057f90af7a31b2398 Mon Sep 17 00:00:00 2001 From: jaynus Date: Sat, 18 Apr 2015 11:16:18 -0700 Subject: [PATCH 09/12] Settings changes. createVehicleLocal derp. --- addons/medical/ACE_Settings.hpp | 19 +++++++++---------- .../functions/fnc_handleCreateLitter.sqf | 8 +++----- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/addons/medical/ACE_Settings.hpp b/addons/medical/ACE_Settings.hpp index 51ff72f465..a4c4e8dd04 100644 --- a/addons/medical/ACE_Settings.hpp +++ b/addons/medical/ACE_Settings.hpp @@ -73,11 +73,18 @@ class ACE_Settings { }; class GVAR(allowLitterCreation) { typeName = "BOOL"; - value = true; + value = 1; + }; + class GVAR(litterSimulationDetail) { + displayName = "$STR_ACE_Medical_litterSimulationDetail"; + description = "$STR_ACE_Medical_litterSimulationDetail_Desc"; + typeName = "SCALAR"; + value = 500; + isClientSettable = 1; }; class GVAR(litterCleanUpDelay) { typeName = "SCALAR"; - value = 1800; + value = -1; }; class GVAR(medicSetting_PAK) { typeName = "SCALAR"; @@ -124,12 +131,4 @@ class ACE_Settings { values[] = {"$STR_ACE_Medical_painEffect_Flash", "$STR_ACE_Medical_painEffect_Chroma"}; isClientSettable = 1; }; - - class GVAR(litterSimulationDetail) { - displayName = "$STR_ACE_Medical_litterSimulationDetail"; - description = "$STR_ACE_Medical_litterSimulationDetail_Desc"; - typeName = "SCALAR"; - value = 500; - isClientSettable = 1; - }; }; diff --git a/addons/medical/functions/fnc_handleCreateLitter.sqf b/addons/medical/functions/fnc_handleCreateLitter.sqf index f6bd821831..ac3ce5da5c 100644 --- a/addons/medical/functions/fnc_handleCreateLitter.sqf +++ b/addons/medical/functions/fnc_handleCreateLitter.sqf @@ -2,15 +2,13 @@ PARAMS_3(_litterClass,_position,_direction); private["_litterObject"]; - - -if (isnil QGVAR(allCreatedLitter)) then { +if (isNil QGVAR(allCreatedLitter)) then { GVAR(allCreatedLitter) = []; GVAR(litterPFHRunning) = false; }; -if((count GVAR(allCreatedLitter)) <= GVAR(litterSimulationDetail) )then { - _litterObject = createVehicleLocal [_litterClass, _position, [], 0, "NONE"]; +if((count GVAR(allCreatedLitter)) <= GVAR(litterSimulationDetail) ) then { + _litterObject = _litterClass createVehicleLocal _position; _litterObject setDir _direction; } else { // @TODO: We hit max litter items, remove a few of them to work with what we have. From e54c68f7f905c490f8f23d1c07750970aba85467 Mon Sep 17 00:00:00 2001 From: jaynus Date: Sat, 18 Apr 2015 11:37:06 -0700 Subject: [PATCH 10/12] handle cleanup --- .../functions/fnc_handleCreateLitter.sqf | 42 +++++++++++++++---- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/addons/medical/functions/fnc_handleCreateLitter.sqf b/addons/medical/functions/fnc_handleCreateLitter.sqf index ac3ce5da5c..b46f4397cf 100644 --- a/addons/medical/functions/fnc_handleCreateLitter.sqf +++ b/addons/medical/functions/fnc_handleCreateLitter.sqf @@ -1,4 +1,8 @@ +//#define DEBUG_MODE_FULL #include "script_component.hpp" + +if(!hasInterface) exitWith { false }; + PARAMS_3(_litterClass,_position,_direction); private["_litterObject"]; @@ -7,15 +11,37 @@ if (isNil QGVAR(allCreatedLitter)) then { GVAR(litterPFHRunning) = false; }; -if((count GVAR(allCreatedLitter)) <= GVAR(litterSimulationDetail) ) then { - _litterObject = _litterClass createVehicleLocal _position; - _litterObject setDir _direction; -} else { - // @TODO: We hit max litter items, remove a few of them to work with what we have. - // Basically, we should just start FIFO'ing these +_litterObject = _litterClass createVehicleLocal _position; +_litterObject setDir _direction; + +if((count GVAR(allCreatedLitter)) > GVAR(litterSimulationDetail) ) then { + // gank the first litter object, and spawn ours. + private["_oldLitter"]; + _oldLitter = GVAR(allCreatedLitter) deleteAt 0; + { + deleteVehicle _x; + } forEach (_oldLitter select 1); }; -GVAR(allCreatedLitter) pushBack _litterObject; -//GVAR(allCreatedLitter) = GVAR(allCreatedLitter) - [objNull]; +GVAR(allCreatedLitter) pushBack [time, [_litterObject]]; + +if(!GVAR(litterPFHRunning) && {GVAR(litterCleanUpDelay) > 0}) then { + [{ + { + if (time - (_x select 0) >= GVAR(litterCleanUpDelay)) then { + { + deleteVehicle _x; + } foreach (_this select 1); + GVAR(allCreatedLitter) set[_foreachIndex, objNull]; + }; + }foreach GVAR(allCreatedLitter); + GVAR(allCreatedLitter) = GVAR(allCreatedLitter) - [objNull]; + + if ( (count GVAR(allCreatedLitter)) == 0) exitwith { + [(_this select 1)] call CBA_fnc_removePerFrameHandler; + GVAR(litterPFHRunning) = false; + }; + }, 30, []] call cba_fnc_addPerFrameHandler; +}; true \ No newline at end of file From ca74ce721d8eb61aa7278bb69df78a1f8a3ffe11 Mon Sep 17 00:00:00 2001 From: jaynus Date: Sat, 18 Apr 2015 11:48:44 -0700 Subject: [PATCH 11/12] Use cleanup settings, and force server TTL on the events. --- addons/medical/ACE_Settings.hpp | 2 +- addons/medical/XEH_postInit.sqf | 2 +- addons/medical/functions/fnc_createLitter.sqf | 2 ++ addons/medical/functions/fnc_handleCreateLitter.sqf | 4 ++-- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/addons/medical/ACE_Settings.hpp b/addons/medical/ACE_Settings.hpp index a4c4e8dd04..b42d5bc5a6 100644 --- a/addons/medical/ACE_Settings.hpp +++ b/addons/medical/ACE_Settings.hpp @@ -84,7 +84,7 @@ class ACE_Settings { }; class GVAR(litterCleanUpDelay) { typeName = "SCALAR"; - value = -1; + value = 0; }; class GVAR(medicSetting_PAK) { typeName = "SCALAR"; diff --git a/addons/medical/XEH_postInit.sqf b/addons/medical/XEH_postInit.sqf index b4d7d30d7a..9b384c67b7 100644 --- a/addons/medical/XEH_postInit.sqf +++ b/addons/medical/XEH_postInit.sqf @@ -268,4 +268,4 @@ if (USE_WOUND_EVENT_SYNC) then { // Networked litter -[QGVAR(createLitter), FUNC(handleCreateLitter)] call EFUNC(common,addSyncedEventHandler); +[QGVAR(createLitter), FUNC(handleCreateLitter), GVAR(litterCleanUpDelay)] call EFUNC(common,addSyncedEventHandler); diff --git a/addons/medical/functions/fnc_createLitter.sqf b/addons/medical/functions/fnc_createLitter.sqf index cc3e32eb5e..5299fbb244 100644 --- a/addons/medical/functions/fnc_createLitter.sqf +++ b/addons/medical/functions/fnc_createLitter.sqf @@ -47,6 +47,8 @@ _createLitter = { }; _direction = (random 360); + // Create the litter, and timeout the event based on the cleanup delay + // The cleanup delay for events in MP is handled by the server side [QGVAR(createLitter), [_litterClass,_position,_direction], 0] call EFUNC(common,syncedEvent); true diff --git a/addons/medical/functions/fnc_handleCreateLitter.sqf b/addons/medical/functions/fnc_handleCreateLitter.sqf index b46f4397cf..aca47250cd 100644 --- a/addons/medical/functions/fnc_handleCreateLitter.sqf +++ b/addons/medical/functions/fnc_handleCreateLitter.sqf @@ -31,10 +31,10 @@ if(!GVAR(litterPFHRunning) && {GVAR(litterCleanUpDelay) > 0}) then { if (time - (_x select 0) >= GVAR(litterCleanUpDelay)) then { { deleteVehicle _x; - } foreach (_this select 1); + } forEach (_x select 1); GVAR(allCreatedLitter) set[_foreachIndex, objNull]; }; - }foreach GVAR(allCreatedLitter); + } forEach GVAR(allCreatedLitter); GVAR(allCreatedLitter) = GVAR(allCreatedLitter) - [objNull]; if ( (count GVAR(allCreatedLitter)) == 0) exitwith { From f5705a91e637148a45160ff4a3559c10e03056de Mon Sep 17 00:00:00 2001 From: jaynus Date: Sat, 18 Apr 2015 12:04:48 -0700 Subject: [PATCH 12/12] oops. --- addons/common/XEH_postInit.sqf | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/common/XEH_postInit.sqf b/addons/common/XEH_postInit.sqf index 2a20c0204d..27f234970e 100644 --- a/addons/common/XEH_postInit.sqf +++ b/addons/common/XEH_postInit.sqf @@ -215,7 +215,6 @@ GVAR(OldPlayerWeapon) = currentWeapon ACE_player; if(isMultiplayer && { time > 0 || isNull player } ) then { // We are jipping! Get ready and wait, and throw the event [{ - diag_log text format["JIP Detected, waiting"]; if(!(isNull player)) then { ["PlayerJip", [player] ] call FUNC(localEvent); [(_this select 1)] call cba_fnc_removePerFrameHandler;