LAxemann / RR_mapStuff

5 stars 3 forks source link

Non-standard map objects not working (eg. S.O.G. Prairie Fire CDLC) #13

Open Grezvany13 opened 1 year ago

Grezvany13 commented 1 year ago

Some mods and CDLC's add custom map items which replace the default ItemMap. This results in not being able to use the features of this mod, since all checks are based around having the object ItemMap in the inventory.

eg. S.O.G. Prairie Fire has the following classnames for their maps:

A solution could be to replace all checks for ItemMap (usually "ItemMap" in assignedItems ace_player) to check for multiple items instead:

assignedItems ace_player findAny ["ItemMap", "vn_b_item_map", "vn_o_item_map", "..."]

It could even be a CBA setting where a custom list can be added, in case it's not a DLC/CDLC item.

Grezvany13 commented 1 year ago

Another solution would be to check for any map item, however this requires Arma 3 version 2.14 (not released at this time).

// check for any item in the Map slot
(ace_player getSlotItemName 608) !== ''

source: https://community.bistudio.com/wiki/getSlotItemName

Grezvany13 commented 1 year ago

Simple function to check for valid map items:

/*
 * Author: Grezvany13
 * Check if the current player has a valid map item in his/her inventory
 *
 * Arguments:
 * None
 *
 * Return Value:
 * True when a map item has been found, false if not
 *
 * Example:
 * call RR_mapStuff_fnc_hasMapItem
 *
 * Public: No
 */

// get the list of object names from CBA Settings, and make it an Array
private _mapItemList = "RR_mapStuff_mapItemList" call CBA_settings_fnc_get;
_mapItemList = [_mapItemList, ","] call CBA_fnc_split;

// add the vanilla map
_mapItemList pushBackUnique "ItemMap";
// add S.O.G. Prairie Fire maps
_mapItemList pushBackUnique "vn_b_item_map";
_mapItemList pushBackUnique "vn_o_item_map";

// check if the current player has a map item assigned in the map slot
if ((assignedItems ace_player findAny _mapItemList) > -1) then { 
    true
} else {
    false
}

Requires CBA setting:

[
    "RR_mapStuff_mapItemList",
    "EDITBOX",
    ["STR_RR_mapStuff_cba_mapItemList", "STR_RR_mapStuff_cba_mapItemList_Desc"],
    "RR Immersive Maps",
    "",
    true,
    {
        // not sure if needed due to 'CBA_settings_fnc_get'
        params ["_value"];
        RR_mapStuff_mapItemList = _value;
    }
] call CBA_Settings_fnc_init;

Is untested, and obviously more files need to be modified to call the function properly.

Dystopian commented 1 year ago

@Grezvany13 looks like you don't need to use setting to find all suitable map items. Check this code (not tested): _mapItemList = "getText (_x >> 'simulation') == 'ItemMap'" configClasses (configFile >> "CfgWeapons") apply {configName _x};

Grezvany13 commented 1 year ago

@Dystopian Looking at performance my code is a lot faster:

Result: 0.0103 ms

Cycles: 10000/10000

Code:

private _mapItemList = ""; 
_mapItemList = [_mapItemList, ","] call CBA_fnc_split; 

_mapItemList pushBackUnique "ItemMap"; 
_mapItemList pushBackUnique "vn_b_item_map"; 
_mapItemList pushBackUnique "vn_o_item_map"; 

if ((assignedItems ace_player findAny _mapItemList) > -1) then { 
    true
} else { 
    false
};

Slightly modified to not check for CBA Setting, so instead just check against empty string.

Compared to:

Result: 13.8082 ms

Cycles: 73/10000

Code:

_mapItemList = "getText (_x >> 'simulation') == 'ItemMap'" configClasses (configFile >> "CfgWeapons") apply {configName _x}; 

if ((assignedItems ace_player findAny _mapItemList) > -1) then { 
    true
} else { 
    false
};
Dystopian commented 1 year ago

If you need performance you should cache array at mission start and use it from variable. Also my code would support any map item from any mod not only vanilla/sog one.