Casio91Fin 31 Posted August 20, 2018 Hey. I have one problem. How to make Insignia work properly. this works just fine as long as you're alive. But when the player dies and then spawn again that insignia is gone. how to fix this bug? Share this post Link to post Share on other sites
pierremgi 4850 Posted August 20, 2018 You need to add a respawn EH. The Bis_fnc_setUnitInsignia is rotten, false persistent on respawn but displaying nuts. So, one possibility, in init field of the player: [this,"MANW"] call BIS_fnc_setUnitInsignia; this addEventHandler ["respawn", { [_this select 0,""] call BIS_fnc_setUnitInsignia; comment "you need to discard the previous invisible one!"; [_this select 0,"MANW"] call BIS_fnc_setUnitInsignia }]; In MP, not tested on clients. Not sure the setObjectTextureGlobal is OK now. So, should work as is, or try to add a locality condition: if (local (this) then {<the code here>} Never remoteExec this function. 1 Share this post Link to post Share on other sites
Casio91Fin 31 Posted August 20, 2018 I did not get to work in Multiplayer. Is it possible for it to build a script into a file? Share this post Link to post Share on other sites
tRiKy_ch 26 Posted August 20, 2018 while {true} do { _insignia = "YourInsignia"; _texture = getText(configFile >> "CfgUnitInsignia" >> _insignia >> "texture"); [player, ""] call BIS_fnc_setUnitInsignia; //need first to manual unset insignia 'cause BIS_fnc_setUnitInsignia is broken [player, _insignia] call BIS_fnc_setUnitInsignia; waitUntil {uiSleep 1;(((getObjectTextures player) find _texture) == -1)}; }; put this on init.sqf this should also work on multiplayer, just pass your desired insignia class name as _insignia it cycle continuosly because there are other situations than respawn where insignia could got reset (i.e.: entering virtual arsenal and changin the uniform) Share this post Link to post Share on other sites
HazJ 1289 Posted August 21, 2018 ^^ Noo... A while loop is not needed. You should never use waitUntil inside a while loop. This is actually the first time I've seen it. You can add a conditional check instead if needed. It is also a good idea to have a sleep inside there. It is also pointless to define those variables over and over (loop) since they do not change. Define them before, above the while loop. As for the arsenal, you can detect when closed. Use InventoryClosed EH. https://community.bistudio.com/wiki/Arma_3:_Event_Handlers#InventoryClosed 1 Share this post Link to post Share on other sites
pierremgi 4850 Posted August 21, 2018 12 hours ago, Casio91Fin said: I did not get to work in Multiplayer. Is it possible for it to build a script into a file? MP should work. Did you disable AI in lobby? What insignia did U test? Are U on dedicated or hosted server? What is the problem? What players can see , when? Share this post Link to post Share on other sites
pierremgi 4850 Posted August 21, 2018 2 hours ago, HazJ said: ^^ Noo... A while loop is not needed. You should never use waitUntil inside a while loop. This is actually the first time I've seen it. You can add a conditional check instead if needed. It is also a good idea to have a sleep inside there. Disagree. If no EH available a loop can be mandatory. Then one (or two if reverse condition is needed) waitUntil with pause inside its code is better than a running loop with several if then. This kind of endless loop is already scheduled anyway. Share this post Link to post Share on other sites
tRiKy_ch 26 Posted August 21, 2018 4 hours ago, HazJ said: It is also pointless to define those variables over and over (loop) since they do not change. Define them before, above the while loop. you're right, i took this from script where i needed dynamic insignias without knowing OP intentions, consider it as a concept, but actually if you have static insignias it is a good advice Quote As for the arsenal, you can detect when closed. Use InventoryClosed EH. yes, this is a valid alternative i proposed a cycle 'cause as said there are various situations where insignia get lost, with this you're sure to cover every possibility with a single solution Quote You should never use waitUntil inside a while loop. i'm self-educated on sqf and still learning, but i've seen this on various scripts so, why this should be not used? how do you would rewrite my function? 1 Share this post Link to post Share on other sites
Casio91Fin 31 Posted August 21, 2018 (edited) @pierremgi 1. Dedicated server. 2. Player cant see. 3. I forgot to remove it "disable AI". but did not help much. @tRiKy_ch 1. I need at least two teams with their own insignia's (Blue team / Red Team) 2.(If it is possible to add to a third party (Green team) optional) And I forgot to mention that I use my own Insignia image. Name "Blue_Team" and "Red_Team". Edited August 21, 2018 by Casio91Fin Insignia image and name Share this post Link to post Share on other sites
Muzzleflash 111 Posted August 21, 2018 Since the original BIS function does not work in MP with non-addon based insignia image, I have modified them for proper MP/JIP. I have split them into a local and a global function: /* MF_fnc_setUnitInsignia Argument: Global Effect: Local Description: Sets unit insignia (e.g., shoulder insignia on soldiers) Parameter(s): 0: OBJECT - unit 1: STRING - CfgUnitInsignia class. Use an empty string to remove current insignia. Returns: BOOL - true if insignia was set */ #define DEFAULT_MATERIAL "\a3\data_f\default.rvmat" #define DEFAULT_TEXTURE "#(rgb,8,8,3)color(0,0,0,0)" params ["_unit", "_class", ["_forceLoad", false]]; private _isRefresh = _class isEqualTo "REFRESH"; if (_isRefresh) then { _class = _unit getVariable ["MF_fnc_setUnitInsignia_class", ""]; }; // --- load texture from config.cpp or description.ext private _cfgInsignia = [["CfgUnitInsignia", _class], configNull] call BIS_fnc_loadClass; // --- check if insignia exists if (configName _cfgInsignia != _class) exitWith { [ "'%1' is not found in CfgUnitInsignia. Available classes: %2", _class, ("true" configClasses (configFile >> "CfgUnitInsignia") apply {configName _x}) + ("true" configClasses (missionConfigFile >> "CfgUnitInsignia") apply {configName _x}) + ("true" configClasses (campaignConfigFile >> "CfgUnitInsignia") apply {configName _x}) ] call BIS_fnc_error; false }; private _set = false; // --- find insignia index in hidden textures { if (_x == "insignia") exitWith { // --- make it safe in scheduled isNil { // --- set insignia if not set if (_isRefresh or {_forceLoad} or {(_unit getVariable ["MF_fnc_setUnitInsignia_class", ""]) != _class}) then { _unit setVariable ["MF_fnc_setUnitInsignia_class", [_class, nil] select (_class isEqualTo ""), false]; _unit setObjectMaterial [_forEachIndex, getText (_cfgInsignia >> "material") call {[_this, DEFAULT_MATERIAL] select (_this isEqualTo "")}]; _unit setObjectTexture [_forEachIndex, getText (_cfgInsignia >> "texture") call {[_this, DEFAULT_TEXTURE] select (_this isEqualTo "")}]; _set = true; }; }; }; } forEach getArray (configFile >> "CfgVehicles" >> getText (configFile >> "CfgWeapons" >> uniform _unit >> "ItemInfo" >> "uniformClass") >> "hiddenSelections"); _set The global function: /* Argument: Global Effect: Global Description: Sets unit insignia (e.g., shoulder insignia on soldiers) Parameter(s): 0: OBJECT - unit 1: STRING - CfgUnitInsignia class. Use an empty string to remove current insignia. Returns: BOOL - true if insignia was set */ params ["_unit", "_class", ["_force", true]]; if (_class isEqualTo "REFRESH") then { _class = _unit getVariable ["MF_fnc_setUnitInsignia_class", ""]; }; // For remotes [_unit, _class, _force] remoteExecCall ["MF_fnc_SetUnitInsignia", -clientOwner]; // For JIPs _unit setVariable ["MF_fnc_setUnitInsignia_class", _class, true]; // We run it locally manually to get return value. // using REFRESH here after setVariable to ensure _force is respected. [_unit, "REFRESH", _force] call MF_fnc_SetUnitInsignia; To ensure proper loading for JIPs and also for player changing uniform, I run the following post-init: // Updates client insignias from broadcast data { private _insignia = _x getVariable ["MF_fnc_setUnitInsignia_class", ""]; if (not (_insignia isEqualTo "")) then { [_x, _insignia, true] call MF_fnc_setUnitInsignia; }; } forEach allUnits; // For simplicity only handle local player changing loadouts. E.g. not AI's that has later been changed by scripting. if (hasInterface) then { [] spawn { waitUntil {sleep 0.1; local player}; MF_fnc_setUnitInsignia_lastUniform = uniformContainer player; player addEventHandler ["InventoryClosed", { params ["_unit", "_targetContainer"]; private _curUniform = uniformContainer _unit; if (_curUniform != MF_fnc_setUnitInsignia_lastUniform) then { MF_fnc_setUnitInsignia_lastUniform = _curUniform; if (not (isNull _curUniform)) then { [_unit, "REFRESH", true] call MF_fnc_setUnitInsigniaGlobal; }; }; }]; }; }; The corresponding CfgFunction entry is: class CfgFunctions { class MF_Insignia { tag = "MF"; class Insignia { file = "functions"; class setUnitInsignia {}; class UnitInsignia_PostInit { postInit = 1; }; class setUnitInsigniaGlobal {}; }; }; }; 1 Share this post Link to post Share on other sites
HazJ 1289 Posted August 21, 2018 @pierremgi There is no need for while loop in this case. Why use waitUntil in while loop when you can make the waitUntil loop itself by returning false at the end. There is an EH available as well as stated in my post above. Share this post Link to post Share on other sites
pierremgi 4850 Posted August 22, 2018 15 hours ago, HazJ said: @pierremgi There is no need for while loop in this case. Why use waitUntil in while loop when you can make the waitUntil loop itself by returning false at the end. There is an EH available as well as stated in my post above. Yes, but I answered at your general consideration about "never" using that: You should never use waitUntil inside a while loop. This is actually the first time I've seen it. Share this post Link to post Share on other sites
HazJ 1289 Posted August 22, 2018 Are you referring to the waitUntil inside the while loop? It isn't good practice, imo. Especially since there are other ways. The way @tRiKy_ch was using the waitUntil inside the while loop was pointless and not worth it. 20 hours ago, pierremgi said: is better than a running loop with several if then. This kind of endless loop is already scheduled anyway. Not always true. I did mention using a sleep in there. A singular if statement would of sufficed, if needed but as I said. None of it was was needed. EHs are available to both of the questions. Also... I don't reply in a general consideration to threads unless needed. My reply was directly to his reply. Share this post Link to post Share on other sites
Casio91Fin 31 Posted August 22, 2018 I found some kind of "maybe" solution to the spawn problem and pictures, but the problem is that everyone get the same pictures. I do not know if this page is anything useful: . Share this post Link to post Share on other sites
HazJ 1289 Posted August 22, 2018 Maybe their rank is the same? Use the setRank command to change this. https://community.bistudio.com/wiki/setUnitRank Alternative would be: player setVariable ["unitInsignia", "path/filename.paa"]; // set on each player { [_x, (player getVariable "unitInsignia")] call BIS_fnc_setUnitInsignia; } forEach allUnits; You can also make a nested array with something like: _units = [ [unit1, "insigniaIcons/icon1.paa"], [unit2, "insigniaIcons/icon2.paa"], [unit3, "insigniaIcons/icon3.paa"] ]; { _unit = _x select 0; _insignia = _x select 1; [_unit, _insignia] call BIS_fnc_setUnitInsignia; } forEach _units; 1 Share this post Link to post Share on other sites
tRiKy_ch 26 Posted August 22, 2018 @Casio91Fin it depends on your scenario, you have a defined rank for every player (i.e: clan) or ranks are defined mission by mission? tell us more about your needs in my case (clan) i used to read them from squad.xml setUnitRank could be very useful but consider its limited to 7 ranks 20 hours ago, HazJ said: @pierremgi ...when you can make the waitUntil loop itself by returning false at the end ok, right, now i see it ;) btw it has to not be a so bad practice as you can see it on the wiki (example 4) 1 Share this post Link to post Share on other sites
Dedmen 2696 Posted August 23, 2018 I don't see the point of the waitUntil discussion. You want to replace it by a condition and a sleep to make sure the script only runs once per frame. Well that's exactly what waitUntil does. Just more compact and easier to read. Share this post Link to post Share on other sites
Casio91Fin 31 Posted August 23, 2018 @tRiKy_ch: Skenario type: TVT 1. (Ranks) I know it is very limited but also useful, but not in this case. (maybe in the future) 2. squad.xml is pretty good and works, but if the players do not have squad.xml. That's why Insignia should be good. https://community.bistudio.com/wiki/File:A3_insignia_infantry.jpg Share this post Link to post Share on other sites
Casio91Fin 31 Posted August 23, 2018 @HazJ player name is (unit_x) I understood this but where i put this On 22.8.2018 at 9:38 AM, HazJ said: { [_x, (player getVariable "unitInsignia")] call BIS_fnc_setUnitInsignia; } forEach allUnits; and On 22.8.2018 at 9:38 AM, HazJ said: _units = [ [unit1, "insigniaIcons/icon1.paa"], [unit2, "insigniaIcons/icon2.paa"], [unit3, "insigniaIcons/icon3.paa"] ]; { _unit = _x select 0; _insignia = _x select 1; [_unit, _insignia] call BIS_fnc_setUnitInsignia; } forEach _units; Share this post Link to post Share on other sites
HazJ 1289 Posted August 23, 2018 unit1, unit2, etc is the var name of the unit. You can set this in the Editor. Share this post Link to post Share on other sites
HazJ 1289 Posted August 25, 2018 On 8/23/2018 at 5:14 PM, Casio91Fin said: all scripts? What? Where are you stuck? Re-read my post and let me know if you still need help. Share this post Link to post Share on other sites