mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Fast medical item replacement (#7224)
* Add item replacement framework * Correctance of English Co-Authored-By: Dedmen Miller <dedmen@users.noreply.github.com> * Remove unecessary code * Use new item replacement framework for medical items * minor fixes, support GVAR(convertItems) setting * use forEach, convert atropine to epi * replace with adenosine
This commit is contained in:
parent
6ca4b2075d
commit
bb0461be16
@ -138,6 +138,7 @@ PREP(positionToASL);
|
||||
PREP(progressBar);
|
||||
PREP(readSettingFromModule);
|
||||
PREP(receiveRequest);
|
||||
PREP(registerItemReplacement);
|
||||
PREP(removeCanInteractWithCondition);
|
||||
PREP(removeSpecificMagazine);
|
||||
PREP(requestCallback);
|
||||
|
112
addons/common/functions/fnc_registerItemReplacement.sqf
Normal file
112
addons/common/functions/fnc_registerItemReplacement.sqf
Normal file
@ -0,0 +1,112 @@
|
||||
#include "script_component.hpp"
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Registers an event handler that replaces an item or item type with one or
|
||||
* more other items.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Item or item type ID to replace <STRING or NUMBER>
|
||||
* 1: Item or list of items <STRING or ARRAY>
|
||||
* 2: Replace items that inherit from original item (only if 0 is STRING) (Optional)<BOOL>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* ["FirstAidKit", "ACE_fieldDressing"] call ace_common_fnc_registerItemReplacement
|
||||
*
|
||||
* Public: Yes
|
||||
*/
|
||||
params [["_oldItem", "", [0,""]], ["_newItems", "", ["", []]], ["_replaceInherited", false, [false]]];
|
||||
TRACE_3("registerItemReplacement",_oldItem,_newItems,_replaceInherited);
|
||||
|
||||
// CBA player event handler function
|
||||
private _fnc_replaceItems = {
|
||||
params ["_unit"];
|
||||
|
||||
private _items = items _unit;
|
||||
if (_items isEqualTo GVAR(oldItems)) exitWith {};
|
||||
|
||||
private _newItems = _items - GVAR(oldItems);
|
||||
if (_newItems isEqualTo []) exitWith {
|
||||
GVAR(oldItems) = _items;
|
||||
};
|
||||
|
||||
_newItems sort true; // Sort so all items of current class can be replaced at once
|
||||
private _cfgWeapons = configFile >> "CfgWeapons"; // Microoptimization
|
||||
|
||||
for "_i" from 0 to count _newItems - 1 do {
|
||||
private _item = _newItems#_i;
|
||||
|
||||
// Determine replacement items: direct replacements, ...
|
||||
private _replacements = GVAR(itemReplacements) getVariable [_item, []];
|
||||
|
||||
// ... item type replacements ...
|
||||
private _type = getNumber (_cfgWeapons >> _item >> "ItemInfo" >> "type");
|
||||
private _typeReplacements = GVAR(itemReplacements) getVariable ["$" + str _type, []];
|
||||
_replacements append _typeReplacements;
|
||||
|
||||
// ... and inherited replacements
|
||||
{
|
||||
if (_item isKindOf [_x, _cfgWeapons]) then {
|
||||
private _inheritedReplacements = GVAR(itemReplacements) getVariable [_x, []];
|
||||
_replacements append _inheritedReplacements;
|
||||
};
|
||||
} forEach GVAR(inheritedReplacements);
|
||||
|
||||
// Skip lookup for all following items of this class
|
||||
private _count = 1;
|
||||
while {_newItems#(_i + 1) == _item} do { // (i+1) can be out of bounds, but should fail safely
|
||||
_count = _count + 1;
|
||||
_i = _i + 1;
|
||||
};
|
||||
|
||||
// Replace all items of current class in list
|
||||
if !(_replacements isEqualTo []) then {
|
||||
TRACE_3("replace",_item,_count,_replacements);
|
||||
_unit removeItems _item;
|
||||
|
||||
for "_j" from 1 to _count do {
|
||||
{ [_unit, _x] call FUNC(addToInventory) } forEach _replacements;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
GVAR(oldItems) = items _unit;
|
||||
};
|
||||
|
||||
// Setup on first run
|
||||
if (isNil QGVAR(itemReplacements)) then {
|
||||
GVAR(itemReplacements) = [] call CBA_fnc_createNamespace;
|
||||
GVAR(inheritedReplacements) = [];
|
||||
GVAR(oldItems) = [];
|
||||
["loadout", _fnc_replaceItems] call CBA_fnc_addPlayerEventHandler;
|
||||
};
|
||||
|
||||
// Save item replacement
|
||||
// $ prefix is used for types (numbers) and replacements with inheritance
|
||||
if (_replaceInherited) then {
|
||||
_oldItem = "$" + _oldItem;
|
||||
GVAR(inheritedReplacements) pushBack _oldItem;
|
||||
};
|
||||
if (_oldItem isEqualType 0) then {
|
||||
_oldItem = "$" + str _oldItem;
|
||||
};
|
||||
if (_newItems isEqualType "") then {
|
||||
_newItems = [_newItems];
|
||||
};
|
||||
|
||||
private _oldReplacements = GVAR(itemReplacements) getVariable [_oldItem, []];
|
||||
_oldReplacements append _newItems;
|
||||
GVAR(itemReplacements) setVariable [_oldItem, _newItems];
|
||||
|
||||
// Force item scan when new replacement was registered in PostInit
|
||||
if (!isNull ACE_player) then {
|
||||
GVAR(oldItems) = [];
|
||||
|
||||
// Exec next frame to ensure full scan only runs once per frame
|
||||
// For example, if item replacements are registred in PostInit (due to CBA
|
||||
// settings) by different addons, the inventory is only scanned once in the
|
||||
// next frame, not once per addon.
|
||||
[_fnc_replaceItems, [ACE_player]] call CBA_fnc_execNextFrame;
|
||||
};
|
@ -1,11 +1,14 @@
|
||||
// This config accepts both item type numbers and item class names
|
||||
// Item type numbers need the prefix ItemType_, so for example ItemType_401
|
||||
// Class names need no special prefix
|
||||
class EGVAR(medical,replacementItems) {
|
||||
FirstAidKit[] = {
|
||||
DOUBLES(ItemType,TYPE_FIRST_AID_KIT)[] = {
|
||||
{"ACE_fieldDressing", 1},
|
||||
{"ACE_packingBandage", 1},
|
||||
{"ACE_morphine", 1},
|
||||
{"ACE_tourniquet", 1}
|
||||
};
|
||||
Medikit[] = {
|
||||
DOUBLES(ItemType,TYPE_MEDIKIT)[] = {
|
||||
{"ACE_fieldDressing", 1},
|
||||
{"ACE_packingBandage", 2},
|
||||
{"ACE_epinephrine", 1},
|
||||
@ -14,5 +17,7 @@ class EGVAR(medical,replacementItems) {
|
||||
{"ACE_tourniquet", 1},
|
||||
{"ACE_splint", 2}
|
||||
};
|
||||
// todo: add GM medical items
|
||||
ACE_atropine[] = {
|
||||
{"ACE_adenosine", 1}
|
||||
};
|
||||
};
|
||||
|
@ -13,7 +13,6 @@ PREP(canTreatCached);
|
||||
PREP(canTreat_holsterCheck);
|
||||
PREP(checkBloodPressure);
|
||||
PREP(checkBloodPressureLocal);
|
||||
PREP(checkItems);
|
||||
PREP(checkPulse);
|
||||
PREP(checkPulseLocal);
|
||||
PREP(checkResponse);
|
||||
|
@ -9,12 +9,8 @@
|
||||
} forEach (_unit getVariable [QEGVAR(medical,allLogs), []]);
|
||||
|
||||
_unit setVariable [QEGVAR(medical,allLogs), [], true];
|
||||
|
||||
[_unit] call FUNC(checkItems);
|
||||
}] call CBA_fnc_addEventHandler;
|
||||
|
||||
["loadout", LINKFUNC(checkItems)] call CBA_fnc_addPlayerEventHandler;
|
||||
|
||||
// Handle body removal and litter on server
|
||||
if (isServer) then {
|
||||
[QGVAR(createLitterServer), LINKFUNC(createLitterServer)] call CBA_fnc_addEventHandler;
|
||||
@ -36,3 +32,32 @@ if (isServer) then {
|
||||
// Logging events
|
||||
[QGVAR(addToLog), LINKFUNC(addToLog)] call CBA_fnc_addEventHandler;
|
||||
[QGVAR(addToTriageCard), LINKFUNC(addToTriageCard)] call CBA_fnc_addEventHandler;
|
||||
|
||||
// replace medical items with their ACE equivalents
|
||||
["ace_settingsInitialized", {
|
||||
TRACE_1("ace_settingsInitialized EH",GVAR(convertItems)); // 0: Enabled 1: RemoveOnly 2:Disabled
|
||||
if (GVAR(convertItems) == 2) exitWith {};
|
||||
{
|
||||
// turn [["stuff", 2], ...] into ["stuff", "stuff", ...]
|
||||
private _replacements = [];
|
||||
if (GVAR(convertItems) == 0) then {
|
||||
{
|
||||
_x params ["_item", "_count"];
|
||||
for "_i" from 1 to _count do {
|
||||
_replacements pushBack _item;
|
||||
};
|
||||
} forEach getArray _x;
|
||||
};
|
||||
|
||||
// check if replacement is for item type or class name
|
||||
private _configName = configName _x;
|
||||
private _toReplace = if ((_configName select [0,9]) == "ItemType_") then {
|
||||
parseNumber (_configName select [9])
|
||||
} else {
|
||||
_configName
|
||||
};
|
||||
|
||||
// register replacement
|
||||
[_toReplace, _replacements] call EFUNC(common,registerItemReplacement);
|
||||
} forEach (configProperties [configFile >> QEGVAR(medical,replacementItems), "isArray _x"]);
|
||||
}] call CBA_fnc_addEventHandler;
|
||||
|
@ -44,9 +44,4 @@ GVAR(facilityClasses) = [];
|
||||
} forEach getArray _x;
|
||||
} forEach configProperties [configFile >> QEGVAR(medical,facilities), "isArray _x"];
|
||||
|
||||
// array of medical items to replace and their ACE equivalents
|
||||
GVAR(replacementItems) = configProperties [configFile >> QEGVAR(medical,replacementItems), "isArray _x"] apply {
|
||||
[configName _x, getArray _x]
|
||||
};
|
||||
|
||||
ADDON = true;
|
||||
|
@ -1,47 +0,0 @@
|
||||
#include "script_component.hpp"
|
||||
/*
|
||||
* Author: KoffeinFlummi, commy2, mharis001
|
||||
* Handles converting vanilla medical items with ACE equivalents.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [player] call ace_medical_treatment_fnc_checkItems
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
if (GVAR(convertItems) == 2) exitWith {};
|
||||
|
||||
params ["_unit"];
|
||||
|
||||
private _fnc_loop = if (GVAR(convertItems) == 0) then {
|
||||
{
|
||||
_x params ["_itemToRemove", "_replacementItems"];
|
||||
|
||||
private _count = [_unit, _itemToRemove] call EFUNC(common,getCountOfItem);
|
||||
|
||||
if (_count > 0) then {
|
||||
_unit removeItems _itemToRemove;
|
||||
|
||||
{
|
||||
_x params ["_item", "_amount"];
|
||||
|
||||
for "_i" from 1 to (_amount * _count) do {
|
||||
_unit addItem _item;
|
||||
};
|
||||
} forEach _replacementItems;
|
||||
};
|
||||
}
|
||||
} else {
|
||||
{
|
||||
_x params ["_itemToRemove"];
|
||||
_unit removeItems _itemToRemove;
|
||||
}
|
||||
};
|
||||
|
||||
_fnc_loop forEach GVAR(replacementItems);
|
Loading…
Reference in New Issue
Block a user