scottb613 285 Posted August 20 Hi Folks, For today's contribution - a stupid little status screen to help manage your SP Squad a little better. Copy the code into your own SQF - call it however you like (no args) - it should work fine... I gotta say - seeing a DOA Unit Status staring you in the face for the duration - especially if you did something to cause it - seems to add some gravity to the mission. // Overview: A basic status report of units in player squad - Fitness, First Aid Kits, and primary weapon Magazines. // Requires: Simply call SCOsquadStat.sqf by whatever means you choose - I use addAction to player. // Note: Only tested in single player. // Given: First Run - records all player units in a global variable for DOA reference. // Given: You should run SCOsquadStat.sqf once at mission start - before losses - or DOA records won't be valid. // Given: Queries the status of alive player units - for Fitness, First Aid Kits, and Magazines. // Given: Fit - statistic quantified so you don't focus on the numbers. // Given: Fit - based on damage - 100/75 AOK | 75/50 LGT | 50/25 SER | 25/0 CRT | 0/0 DOA. // Given: Fit - AOK = All Good or Just a Scratch | LGT = Lightly Injured | SER = Seriously Injured | CRT = Critically Injured | DOA = Dead On Arrival. // Given: Fit - LGT indicates in Green | SER indicates in Yellow | CRT indicates in Red status lines. // Given: Fit - DOA drops Fak/Mag count and dims status line - memorializes the unit's last name. // Given: Fak - pulled from "401" configFile entry (panther42). // Given: Mag - only counts Primary Weapon Magazines. // Given: Added Primary Weapon Name to alive units. // Suggestion: Place this in one of your initialization scripts to run it once at startup: [] execVM "Scripts\SCOsquadStat.sqf"; Hint Output looks like this: Regards, Scott FULL SCRIPT: Spoiler /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // FILE NAME: SCOsquadStat.sqf // ARGS: None // AUTHOR: Scottb613 // OVERVIEW: A basic status report of units in player squad - Health, Faks, and primary weapon Mags. // REQUIRES: Simply call SCOsquadStat.sqf by whatever means you choose - I use addAction to player. // NOTE: Only tested in single player. // GIVEN: First Run - records all player units in a global variable for DOA reference. // GIVEN: You should run SCOsquadStat once at mission start (init) - before losses - or DOA not valid. // GIVEN: Queries the status of alive player units - for Health, Faks, and Mags. // GIVEN: Fit - stat numbers rounded off so you don't focus on chasing numbers. // GIVEN: Fit - AOK = All Good or a Mere Scratch | LGT = Lightly Injured | SER = Seriously Injured. // GIVEN: Fit - CRT = Critically Injured | DOA = Dead On Arrival. // GIVEN: Fit - based on damage - 100/75 AOK | 75/50 LGT | 50/25 SER | 25/0 CRT | DOA. // GIVEN: Fit - LGT indicates in Green | SER indicates in Yellow | CRT indicates in Red - status lines. // GIVEN: Fit - DOA drops Fak/Mag count and dims the units status line - memorializes last name. // GIVEN: Fak - First Aid Kits pulled from 401 configFile entry (panther42). // GIVEN: Mag - only count Primary Weapon Magazines. // GIVEN: Added Primary Weapon Name to alive units. // SUGGESTION: Add to init file to validate squad members: [] execVM "Scripts\SCOsquadStat.sqf"; /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Check if the global variable `SCOplayerUnits` exists if (isNil "SCOplayerUnits") then { // On first run, store all player units in the global variable SCOplayerUnits = []; SCOplayerUnitsLastNames = []; // Add a global list to store last names // { SCOplayerUnits pushBack _x; // Extract the last name and store it private _fullName = name _x; private _nameParts = _fullName splitString " "; private _lastName = if (count _nameParts > 1) then {_nameParts select 1} else {_nameParts select 0}; SCOplayerUnitsLastNames pushBack _lastName; } forEach units group player; }; // Initialize local variables private _hint = ""; private _unitCnt = 0; // Function to pad numbers (as per your original) _fnc_stringPadding = { params[ [ "_string", "", [ "", 0 ] ], [ "_numDigits", 0, [ 0 ] ] ]; if (_string isEqualType 0) then { _string = str _string; }; private _padding = "000"; _padding select[0, _numDigits - count _string]; }; // Function to get unit position ID _fnc_getUnitPositionId = { params[ "_unit" ]; private _vvn = vehicleVarName _unit; _unit setVehicleVarName ""; private _str = str _unit; _unit setVehicleVarName _vvn; _str select[(_str find ":") + 1]; }; // Iterate over all units in the global list { _unit = _x; // Get unit's last name from the stored list private _lastName = SCOplayerUnitsLastNames select _forEachIndex; if (!alive _unit) then { // Only mark DOA and do not remove the unit from the list _unitCnt = _unitCnt + 1; // Format DOA status with padding and include last name private _unitFormPos = format["%1%2", [_unitCnt, 2] call _fnc_stringPadding, _unitCnt]; _hint = format[ "%1<t align='left' color='#474747'>%2 || Fit: DOA || %3</t><br/>%4", _hint, _unitFormPos, _lastName, "" ]; } else { // Fit - If the unit is alive, update the status _unitCnt = _unitCnt + 1; // Get unit health and convert to fitness label private _health = round((1 - damage _unit) * 100); private _fitLabel = switch true do { case (_health >= 75): { "AOK" }; case (_health >= 50): { "LGT" }; case (_health >= 25): { "SER" }; default { "CRT" }; }; // Set color based on fitness label private _fitColor = switch _fitLabel do { case "AOK": { "#7D7F7C" }; // Medium Grey case "LGT": { "#98fb98" }; // Pastel Green case "SER": { "#FFFF99" }; // Pastel Yellow case "CRT": { "#FF9999" }; // Pastel Red default { "#7D7F7C" }; // Default Medium Grey }; // Mag - Count Primary Weapon Magazines private _priWeapon = primaryWeapon _unit; private _compMags = compatibleMagazines _priWeapon; private _magCnt = { _x in _compMags } count magazines _unit; _magCnt = format["%1%2", [_magCnt, 2] call _fnc_stringPadding, _magCnt]; // Fak - Count FirstAidKits without using classnames private _fakCnt = {getNumber (configFile >> "cfgWeapons" >> _x >> "ItemInfo" >> "type") == 401} count (items _unit + assignedItems _unit); _fakCnt = format["%1%2", [_fakCnt, 2] call _fnc_stringPadding, _fakCnt]; // Get unit formation position private _unitFormPos = format["%1%2", [_unitCnt, 2] call _fnc_stringPadding, _unitCnt]; // Get the primary weapon's display name and process it private _priWeaponName = getText(configFile >> "cfgWeapons" >> _priWeapon >> "displayName"); // Remove any text after "(" and the "(" itself private _parenPos = _priWeaponName find "("; if (_parenPos > -1) then { _priWeaponName = _priWeaponName select [0, _parenPos]; }; // Split the display name into parts private _priWeaponNameParts = _priWeaponName splitString " "; // Take the first two parts and concatenate, limiting total length to 8 characters private _shortPriWeaponName = (_priWeaponNameParts select 0); if (count _priWeaponNameParts > 1) then { _shortPriWeaponName = format["%1 %2", _shortPriWeaponName, _priWeaponNameParts select 1]; }; _shortPriWeaponName = _shortPriWeaponName select [0, 8]; // Format Output with color and add the processed primary weapon name _hint = format[ "%1<t align='left' color='%2'>%3 || Fit: %4 || Fak: %5 || Mag: %6 || %7</t><br/>", _hint, _fitColor, _unitFormPos, _fitLabel, _fakCnt, _magCnt, _shortPriWeaponName ]; }; } forEach SCOplayerUnits; // Use the global list of player units // Display Status hint parseText _hint; 1 1 Share this post Link to post Share on other sites
pierremgi 4897 Posted August 21 20 hours ago, scottb613 said: Hi Folks, For today's contribution - a stupid little status screen to help manage your SP Squad a little better. At this time - I am only counting vanilla first aid kits. If someone gives me a complete list of valid class names of FAK's - from major DLC/Mods - I could count them as well. What I'm using for my Heal & revive module: allFAK = ["FirstAidKit","CSLA_Ob80","gm_ge_army_gauzeCompress","gm_gc_army_medkit","gm_gc_army_gauzeBandage","gm_ge_army_gauzeBandage","US85_FAK","vn_b_item_firstaidkit","vn_o_item_firstaidkit","gm_ge_army_burnBandage","r3f_soins_item_bandage","SPE_GER_FirstAidKit","SPE_US_FirstAidKit"]; allMedKit = ["Medikit","US85_MediKit","gm_ge_army_medkit_80","vn_b_item_medikit_01","gm_gc_army_medbox","r3f_soins_item_defibrillateur","CSLA_MediKit_Z80","r3f_soins_item_sang","SPE_GER_Medkit","SPE_US_Medkit"]; Covering all official DLCs so far, and mods like Unsung, CUP, RHS, R3F, IFA3 (some of them uses vanilla class names of these items) I'm also interested in other exotic FAK or Medikit, if any. 2 1 Share this post Link to post Share on other sites
scottb613 285 Posted August 21 Hi Pierre, Thank you kindly for your fine help. 😉 Updated the script in my first post. Added an array of FAK classnames - easily editable. Added DOA units last name - to make you feel even more responsible for them. They're just a number until you pull their dog tags. Regards, Scott Share this post Link to post Share on other sites
panther42 52 Posted August 24 You shouldn't need to keep arrays of fak or medikit. This becomes more labor than needed if/when names are changed or new DLC added. They should all inherit correctly in order to work properly and you can just read from the config: Spoiler lass ItemInfo: InventoryFirstAidKitItem_Base_F class InventoryFirstAidKitItem_Base_F: InventoryItem_Base_F { type = 401; }; class ItemInfo: MedikitItem class MedikitItem: InventoryItem_Base_F { type = 619; allowedSlots[] = {801, 701, 901}; }; Just use the following or similar. You can adjust as needed _hasFAK = ((((assignedItems _unit) + (items _unit)) findIf {getNumber (configFile >> "cfgWeapons" >> _x >> "ItemInfo" >> "type") == 401}) > -1); _hasMedikit = ((((assignedItems _unit) + (items _unit)) findIf {getNumber (configFile >> "cfgWeapons" >> _x >> "ItemInfo" >> "type") == 619}) > -1); 6 Share this post Link to post Share on other sites
scottb613 285 Posted August 24 1 hour ago, panther42 said: You shouldn't need to keep arrays of fak or medikit. This becomes more labor than needed if/when names are changed or new DLC added. They should all inherit correctly in order to work properly and you can just read from the config: Reveal hidden contents lass ItemInfo: InventoryFirstAidKitItem_Base_F class InventoryFirstAidKitItem_Base_F: InventoryItem_Base_F { type = 401; }; class ItemInfo: MedikitItem class MedikitItem: InventoryItem_Base_F { type = 619; allowedSlots[] = {801, 701, 901}; }; Just use the following or similar. You can adjust as needed _hasFAK = ((((assignedItems _unit) + (items _unit)) findIf {getNumber (configFile >> "cfgWeapons" >> _x >> "ItemInfo" >> "type") == 401}) > -1); _hasMedikit = ((((assignedItems _unit) + (items _unit)) findIf {getNumber (configFile >> "cfgWeapons" >> _x >> "ItemInfo" >> "type") == 619}) > -1); Hi... Thanks for the interest - let me look into this. I'm always looking for better ways of doing things. Regards, Scott Share this post Link to post Share on other sites
scottb613 285 Posted August 24 15 hours ago, panther42 said: You shouldn't need to keep arrays of fak or medikit. This becomes more labor than needed if/when names are changed or new DLC added. They should all inherit correctly in order to work properly and you can just read from the config: Reveal hidden contents lass ItemInfo: InventoryFirstAidKitItem_Base_F class InventoryFirstAidKitItem_Base_F: InventoryItem_Base_F { type = 401; }; class ItemInfo: MedikitItem class MedikitItem: InventoryItem_Base_F { type = 619; allowedSlots[] = {801, 701, 901}; }; Just use the following or similar. You can adjust as needed _hasFAK = ((((assignedItems _unit) + (items _unit)) findIf {getNumber (configFile >> "cfgWeapons" >> _x >> "ItemInfo" >> "type") == 401}) > -1); _hasMedikit = ((((assignedItems _unit) + (items _unit)) findIf {getNumber (configFile >> "cfgWeapons" >> _x >> "ItemInfo" >> "type") == 619}) > -1); Hi... Gracias Amigo - much better - tested on Vanilla and SOG - looks good to me. 😉 Eliminated FAK class names. Updated code in initial post. Regards, Scott 1 Share this post Link to post Share on other sites
pierremgi 4897 Posted August 25 10 hours ago, panther42 said: You shouldn't need to keep arrays of fak or medikit. This becomes more labor than needed if/when names are changed or new DLC added. They should all inherit correctly in order to work properly and you can just read from the config: Reveal hidden contents lass ItemInfo: InventoryFirstAidKitItem_Base_F class InventoryFirstAidKitItem_Base_F: InventoryItem_Base_F { type = 401; }; class ItemInfo: MedikitItem class MedikitItem: InventoryItem_Base_F { type = 619; allowedSlots[] = {801, 701, 901}; }; Just use the following or similar. You can adjust as needed _hasFAK = ((((assignedItems _unit) + (items _unit)) findIf {getNumber (configFile >> "cfgWeapons" >> _x >> "ItemInfo" >> "type") == 401}) > -1); _hasMedikit = ((((assignedItems _unit) + (items _unit)) findIf {getNumber (configFile >> "cfgWeapons" >> _x >> "ItemInfo" >> "type") == 619}) > -1); wow nice! Any list of itemInfo types? I didn't find that on web. Share this post Link to post Share on other sites
scottb613 285 Posted August 25 Hi Folks, Just a quick question - I can manipulate size and color - in hints - can I not use a "fixed width font" as well? I had tried and it failed - perhaps it was me? Not having perfectly aligned columns - does bother me. Thanks. Regards, Scott Share this post Link to post Share on other sites
panther42 52 Posted August 25 9 hours ago, pierremgi said: wow nice! Any list of itemInfo types? I didn't find that on web. There are multiple ways to do this. I use the following: Spoiler ItemInfoArrayHash = createHashMap; ItemInfoArray = []; "true" configClasses (configFile >>"cfgWeapons") apply { ItemInfoArrayHash insert [[configName _x, getNumber (_x >> "ItemInfo" >> "type")]]; ItemInfoArray pushBackUnique (getNumber (_x >> "ItemInfo" >> "type")); }; diag_log format ["types: %1",ItemInfoArray]; {if (_y == 401) then { diag_log format ["%1",[_x,_y]] }} forEach ItemInfoArrayHash; This can be used in the Debug console. I gave example of using "type" equals 401 (FAK). The reason I made a separate array with pushBackUnique just for the "type" is the immense number of cfgWeapons, especially if you have many mods/dlc's added. If you tried to list all it exceeds the clipboard and diag_log character limits. The code will make it easier for you to see the entire list of "type" numbers. I wanted to create the hashmap using the "type" number, as there are less, but this does not work as "Inserting an element with a key that already exists inside the HashMap will overwrite the existing key." You can still work multiple ways with the hashmap as created above. Sorry Scott, I see your post above but I normally don't mess around with what you are asking... 3 Share this post Link to post Share on other sites
pierremgi 4897 Posted August 27 On 8/25/2024 at 5:32 PM, panther42 said: There are multiple ways to do this. I use the following: This can be used in the Debug console. I gave example of using "type" equals 401 (FAK). What I didn't find, this list: cfgWeapons itemInfo types are : [0,620,619,401,616,801,701,605,101,201,301,302,621] 0: weapons + some itemRadio ... difficult to say 620: toolkits repairKits,US85 PRC77, R3F brouilleur, GM boltcutter, CSLA RF10 , so that repairs in most of the cases 619: MediKits most of the time + R3F thingies 😏 401: FAK bandages, CSLA_Documents_item 616: NVGs most of the time, but also several LIB_GER_Gloves, LIB_Mohawk or SPE_Flashlight_base... 801: uniforms... a lot! 701: vests 605: headgears , headsets, helmets... 101: silencers, suppressors, bayonets, and mounted pieces on muzzles 201: optics 301: lasers, flashlights 302: grips, bipods and miscelaneous items low mounted 621: UAV terminals So, 401, 616, 619 , 620 (mainly) are sometimes used for other item types than what you are waiting for, especially on mods (less for DLCs). If you don't want to keep some precise lists updated (as I did), aiming for a Swiss knife code, you risk to script some weird use for some inadequate item. 1 Share this post Link to post Share on other sites
scottb613 285 Posted October 20 Hi Folks, Added the primary weapon name to alive units - just to keep track of what you have. Script updated. Regards, Scott 1 Share this post Link to post Share on other sites
scottb613 285 Posted October 24 Hi Folks, Just an updated image on the current state of the status screen - 1 lightly injured - 1 critically injured - 1 dead. Code in first post updated. Regards, Scott 1 Share this post Link to post Share on other sites