Jump to content
Moon_chilD

Give an specific player an insignia

Recommended Posts

Hey guys,

 

we use a whitelisted Arsenal in our missions. Since Insignias do not work in these I want to give our members their Insignia via script. How can I do that, since I'm not the best in creating scripts.

The problem is, that I don't want to use object/unit names since our member do not always take the same role. I want to do that with their ingame name - if possible.

Thats what I tried:

[Moony,"INSIGNIA CLASS NAME"] call bis_fnc_setUnitInsignia;

but that does not work but if I use 

[Player,"INSIGNIA CLASS NAME"] call bis_fnc_setUnitInsignia;

it works!

 

Does anyone has an Idea how to accomplish what I try?

 

Many Greetings
Moony

Share this post


Link to post
Share on other sites

Okay, but how could I accomplish what I want with that command. As I'm said I'm sadly not that much into scripting (even though I try to learn each and every day ^^)

Share this post


Link to post
Share on other sites
if(getPlayerUID player isEqualTo player-id-here) then
{
       [Player,"INSIGNIA CLASS NAME"] call bis_fnc_setUnitInsignia;
};

player id's can be found inside the players user profile in the main menu of the game (its a number).

  • Like 2

Share this post


Link to post
Share on other sites

Mhhh, I tried that now

if(getplayerUID player isEqualTo 76561197971387924) then
{
       [player,"EF_Germany"] call bis_fnc_setUnitInsignia;
};

But its not working at all. Where and how would you recommend to call that code?

Share this post


Link to post
Share on other sites

Pretty sure the GUID needs to be in quotes? Not sure, but might work.

 

Call it in initPlayerLocal.sqf

if(getplayerUID player isEqualTo "76561197971387924") then
{
[player,"EF_Germany"] call bis_fnc_setUnitInsignia;
};
  • Like 2

Share this post


Link to post
Share on other sites

Okay, that works but what would be the best way to execute this code. 

I want to have several of these codes for differen PlayerIDs. Also please keep in mind that this should somehow work on a server where we use an Arsenal (meaning the insignia gets overwritten when the Arsenal is opened) and also that we can respawn or JIP! 

 

I thought maybe about a loop but I have no clue how I should do that. With a trigger? A script file? How does this have to look like?
Hope somebody can help me with that! ^^

Many Greetings
Moony

Share this post


Link to post
Share on other sites

Good starting point for you.

This isn't really efficient, but will update each ID's Insignia every 3 seconds with the one supplied. Even if they take a new one from the arsenal, it'll remove it and give the original one.

 

For each new ID, just make a new case.

_id = getplayerUID player;

while (true) do {

    sleep 3;
    
    switch (_id) do {

        case "76561197971387924": {
        
            [player,"EF_Germany"] call bis_fnc_setUnitInsignia;
        };
        case default: {
        
            [player,""] call bis_fnc_setUnitInsignia; // Should remove insignia if ID isn't supplied.
        };

    };
};
  • Like 1

Share this post


Link to post
Share on other sites

This seems not to work at all. 

I tried to call it in a sqf file and also directly from the init.sqf.
Its not working!

Share this post


Link to post
Share on other sites

Didnt test the old code, problem was I used ( )'s instead of {} on the while code, and messed up on the case Default lol.

Either way, this should work for you. (Wont work in Editor, since you don't have a GUID. It'll always return case Default and GUID will return _SP_PLAYER_)

 

Call for it in initPlayerLocal.sqf

 

[player] execVM "script.sqf";

_unit = _this select 0;
_id = (getplayerUID _unit);

while {true} do {

    sleep 3;
    
    switch (_id) do {

        case "76561197971387924": {
        
            [_unit,"EF_Germany"] call bis_fnc_setUnitInsignia;
            hint format ["UID: %1",_id];
        };
        case default {
        
            [_unit,""] call bis_fnc_setUnitInsignia; // Should remove insignia if ID isn't supplied.
            hint format ["UID: %1",_id];
        };

    };
};

If you plan on using the same Insignia for multiple people, I can set up a different script that'll check their UID's from a pre-set array of multiple people using the same insignia. That way it'll be easier to manage.

_unit = _this select 0;
_pid = (getplayerUID _unit);

_rank1 = ["76561197971387924", "76561197971387924"];
_rank2 = ["76561197971387924", "76561197971387924"];

while {true} do {

    sleep 3;
	_insignia = _unit call BIS_fnc_getUnitInsignia;
    
    if ((_pid in _rank1) && !(_insignia isEqualTo "EF_Germany")) then {
		
		[_unit,"EF_Germany"] call bis_fnc_setUnitInsignia;
		hint parsetext format ["Insignia:<br />%1<br /><br />UID:<br />%2", _insignia, _pid];
		
	};
	
	if ((_pid in _rank2) && !(_insignia isEqualTo "EF_Germany2")) then {
		
		[_unit,"EF_Germany2"] call bis_fnc_setUnitInsignia;
		hint parsetext format ["Insignia:<br />%1<br /><br />UID:<br />%2", _insignia, _pid];
		
	};
	
};

Just fix the GUIDs in the arrays for _rank1/2 and the names of the insignias in each statement.

You can remove the hints once your done checking the script. Helps to know when the if statement triggers properly.

 

Will only trigger IF GUID is in specified Array AND if player has the wrong insignia, upon which it just sets it to the correct insignia.

  • Like 2

Share this post


Link to post
Share on other sites

Thank you very much. The second code totally fits my needs and works like a charm. At first I did not noticed you said I should put it in initPlayerLocal.sqf. I never used it! (I'm so bad xD)

Share this post


Link to post
Share on other sites

Thank you very much. The second code totally fits my needs and works like a charm. At first I did not noticed you said I should put it in initPlayerLocal.sqf. I never used it! (I'm so bad xD)

 

Basically just makes sure it always runs local to the player, never on the server and always upon JIP.

Share this post


Link to post
Share on other sites

Okay...as I said, the script works now. But it does not work anymore if a unit respawns...what can I do about that?

Share this post


Link to post
Share on other sites

Okay...as I said, the script works now. But it does not work anymore if a unit respawns...what can I do about that?

 

In initPlayerLocal.sqf:

player addEventHandler ["Respawn", {[player] execVM "script.sqf"}];

Should work.

Share this post


Link to post
Share on other sites

Not really, or do I have to change "script.sqf" to something else? I run the Insignia Code directly from the initplayerlocal.sqf!

Share this post


Link to post
Share on other sites

Not really, or do I have to change "script.sqf" to something else? I run the Insignia Code directly from the initplayerlocal.sqf!

 

tbh, you should create a new script in your mission folder and call for it how I showed above. But if you wanna use initPlayerLocal, just add the code below to what you've already got.

 

If you wanna go the other route (which makes the mission look neater and easier to add more scripts) then let me know and I'll help you set it up.

player addEventHandler ["Respawn", {

	_unit = _this select 0;
	_pid = (getplayerUID _unit);

	_rank1 = ["76561197971387924", "76561197971387924"];
	_rank2 = ["76561197971387924", "76561197971387924"];

	while {true} do {

	sleep 3;
	_insignia = _unit call BIS_fnc_getUnitInsignia;

	if ((_pid in _rank1) && !(_insignia isEqualTo "EF_Germany")) then {
			
			[_unit,"EF_Germany"] call bis_fnc_setUnitInsignia;
			hint parsetext format ["Insignia:<br />%1<br /><br />UID:<br />%2", _insignia, _pid];
			
		};
		
	if ((_pid in _rank2) && !(_insignia isEqualTo "EF_Germany2")) then {
			
			[_unit,"EF_Germany2"] call bis_fnc_setUnitInsignia;
			hint parsetext format ["Insignia:<br />%1<br /><br />UID:<br />%2", _insignia, _pid];
			
		};
		
	};

}];

EDIT: Thinking about it, you might be able to just do:

player addEventHandler ["Respawn", {[player] execVM "initPlayerLocal.sqf"}];

Share this post


Link to post
Share on other sites

EDIT: Thinking about it, you might be able to just do:

 

player addEventHandler ["Respawn", {[player] execVM "initPlayerLocal.sqf"}];

 

Nope, does't work. >.< Anyway, I like it clean and easy so: Dow do I set it up, so the script goes in a separate file. I tried it before. The Code was in a separate file the same way it was in the initplayerlocal.sqf.

In the initplayerlocal.sqf the only thing was:

player addEventHandler ["Respawn", {[player] execVM "Insignia.sqf"}];

But this did not work at all. (Not even before a respawn).

 

As I said, I want to learn how this stuff works and the wiki sometimes is only for people who understand what they are talking about! :3

Share this post


Link to post
Share on other sites

initPlayerLocal.sqf:

[player] execVM "uid.sqf";
player addEventHandler ["Respawn", {[player] execVM "uid.sqf";}];

UID.sqf:

_unit = _this select 0;
_pid = (getplayerUID _unit);

_rank1 = ["76561197971387924", "76561197971387924"];
_rank2 = ["76561197971387924", "76561197971387924"];

while {true} do {

    sleep 3;

	_insignia = _unit call BIS_fnc_getUnitInsignia;
    
        if ((_pid in _rank1) && !(_insignia isEqualTo "EF_Germany")) then {
		
		[_unit,"EF_Germany"] call bis_fnc_setUnitInsignia;
		hint parsetext format ["Insignia:<br />%1<br /><br />UID:<br />%2", _insignia, _pid];
		
	};
	
	if ((_pid in _rank2) && !(_insignia isEqualTo "EF_Germany2")) then {
		
		[_unit,"EF_Germany2"] call bis_fnc_setUnitInsignia;
		hint parsetext format ["Insignia:<br />%1<br /><br />UID:<br />%2", _insignia, _pid];
		
	};
	
};

Share this post


Link to post
Share on other sites

Okay, this at least works fine so far but still not perfect. 
When respawning the script only runs when the insignia was changed once. That means:
I join the server and get my insignia after a time. then I access the Arsenal and the Insignia is taken away from me but will get assign pretty fast (due to the script). Then I die and respawn but I don't get an insignia. I walk up to the arsenal and only if I enter the arsenal I get assigned a new Insignia (means after respawn the script only kicks in when the insignia is somehow changed (even if its from "none" to "none")) 

But I think the easiest way would be to call the script via trigger on the respawn point, or do you have another idea?

Also one more thing: The script does not like to be in another folder. I like my mission folder tidy - thats why I have a "scripts" folder. But when I put the script file in this folder and call it with "scripts\uid.sqf" it does not work. Do you have an idea for that?

(But to this point, thank you so much for your help and time >.<)

Share this post


Link to post
Share on other sites

Try doing it this way instead of with eventHandlers.

 

Create onPlayerRespawn.sqf and enter the code below for that and initPlayerLocal

Drag the script where you want it and change the path to find it.

 

onPlayerRespawn.sqf & initPlayerLocal.sqf

[player] execVM "script.sqf";

Change your script.sqf file to look like this:

_unit = _this select 0;
_pid = (getplayerUID _unit);

_rank1 = ["_SP_PLAYER_"];
_rank2 = ["_SP_PLAYER_"];

while {true} do {

    sleep 3;

    _insignia = _unit call BIS_fnc_getUnitInsignia;

    if (!alive _unit) exitWith {
    
        [_unit,""] call bis_fnc_setUnitInsignia;
        hint parsetext format ["Insignia:<br />%1<br /><br />UID:<br />%2", _insignia, _pid];
        
    };
    
    if ((_pid in _rank1) && !(_insignia isEqualTo "111thID")) then {
        
        [_unit,"111thID"] call bis_fnc_setUnitInsignia;
        hint parsetext format ["Insignia:<br />%1<br /><br />UID:<br />%2", _insignia, _pid];
        
    };
    
    if ((_pid in _rank2) && !(_insignia isEqualTo "BI")) then {
        
        [_unit,"BI"] call bis_fnc_setUnitInsignia;
        hint parsetext format ["Insignia:<br />%1<br /><br />UID:<br />%2", _insignia, _pid];
        
    };
    
};

Added a check for if the player is alive, if not it will reset their insignia, which should help fix the issue on respawn.

 

Make sure to edit the insignias to the right ones, used vanilla ones on this to make sure it worked.

Share this post


Link to post
Share on other sites

You = my hero. Finally it works. 

Thanks for your awesome help man. Would you mind me asking you (via PM) about another problem I have?  :rolleyes: (Goes in kind of the same way like this here!)

  • Like 1

Share this post


Link to post
Share on other sites

hi @schadler17 i find out that your script 100% match my need for my server. The script works fine when i try it on hosted server, but did not run when i put it on dedicated server. If i use debug console and run this [Player] execVM "Insignia.sqf" the patch appear, it means the script is ok, but it just wont load it automatically.

 

Share this post


Link to post
Share on other sites

Well, first of all, let me say I'm glad you have a working solution. I would like to suggest an alternative here just to get rid/avoid using a while-loop that constantly checks for the conditions you want to check. This is somewhat an overburden on the CPU, which may or may not be noticeable, but I consider it good practice to be as efficient as you can (without greatly compromising the clarity and maintainability of your code of course).

 

An alternative to your approach could be to use only event handlers. For this to work more efficiently and make your life a wee bit easier (at least I see it as making life easier) is to do something like what @schadler17 has suggested in one of their posts. You could create a .sqf file (I think this also works with plain .txt files but I haven't tested it) which will include the arrays with the ranks of each UID. To make it clear let me provide an example (please note that the numbers and array names are "fictional")

// Let this file be called ranks.sqf

// Create the arrays with the UIDs
medics = ["07451192381387934", "76561197971387924"];
specOps = ["93105197971384560", "30161497968389202"];
airmen = ["04716835285690243"];
armor = ["10946288492635540", "37849283490283461", "10937485721991075"];
infantry = ["10928765134920552", 19003473827119563", "93740174231954242"];

// Make the arrays available to every client machine
missionNamespace setVariable["medics", medics, true];
missionNamespace setVariable["specOps", specOps, true];
missionNamespace setVariable["airmen", airmen, true];
missionNamespace setVariable["armor", armor, true];
missionNamespace setVariable["infantry", infantry, true];

So, in the initServer.sqf you can just call something like

// Create the arrays found in the ranks.sqf
// to make them available in the mission
call compileFinal preprocessFileLineNumbers "ranks.sqf";

So now, you have the arrays with the UIDs available in every client machine in-game since they are public and have been broadcasted. One thing to mention here is that if you intend to use the script on a persistent mission online you could (and most possibly should) change the compileFInal to compile in order to be able to change the UIDs and recompile in the future.

 

After that, you could create a script to hold the code for the insignia addition. I will use as a base the snippet provided by schadler17 to provide an example below.

// Let this script be called insignias.sqf

// Get the arguments provided to the script
params["_unit"];

// Get the insignia and id of the unit
private _pid = (getplayerUID _unit);
private _insig = _unit call BIS_fnc_getUnitInsignia;

if (_pid in (missionNamespace getVariable["medics", []]) && {!(_insig isEqualTo "SOME_MEDIC_INSIGNIA"}) then {
    [_unit,"SOME_MEDIC_INSIGNIA"] call bis_fnc_setUnitInsignia;
    hint parsetext format ["Insignia:<br />%1<br /><br />UID:<br />%2", _insignia, _pid];
};

if (_pid in (missionNamespace getVariable["specOps", []]) && !(_insignia isEqualTo "SOME_SPECOPS_INSIGNIA")) then {
    [_unit,"SOME_SPECOPS_INSIGNIA"] call bis_fnc_setUnitInsignia;
    hint parsetext format ["Insignia:<br />%1<br /><br />UID:<br />%2", _insignia, _pid];
};

if (_pid in (missionNamespace getVariable["airmen", []]) && !(_insignia isEqualTo "SOME_AIRMEN_INSIGNIA")) then {
    [_unit,"SOME_AIRMEN_INSIGNIA"] call bis_fnc_setUnitInsignia;
    hint parsetext format ["Insignia:<br />%1<br /><br />UID:<br />%2", _insignia, _pid];
};

if (_pid in (missionNamespace getVariable["armor", []]) && !(_insignia isEqualTo "SOME_ARMOR_INSIGNIA")) then {
    [_unit,"SOME_ARMOR_INSIGNIA"] call bis_fnc_setUnitInsignia;
    hint parsetext format ["Insignia:<br />%1<br /><br />UID:<br />%2", _insignia, _pid];
};

if (_pid in (missionNamespace getVariable["infantry", []]) && !(_insignia isEqualTo "SOME_INFANTRY_INSIGNIA")) then {
    [_unit,"SOME_INFANTRY_INSIGNIA"] call bis_fnc_setUnitInsignia;
    hint parsetext format ["Insignia:<br />%1<br /><br />UID:<br />%2", _insignia, _pid];
};

Then you could place the following code in the initPlayerLocal.sqf (using some sample code from schadler17's posts)

// Add the insignia to the player
[player] execVM "insignias.sqf";

// Add a respawn event handler to add insignias
player addEventHandler["Respawn", {
	params["_unit"]; // Get the unit
	[_unit] execVM "insignias.sqf"; // Call the script to add insignia
};]

Finally, inside the initServer.sqf you add the following code

// Add an event handler to re-add the insignia after the arsenal is closed
[missionNamespace, "arsenalClosed", {
	private _plrs = allPlayers - (entities "HeadlessClient_F"); // Get all players
	_plrs apply {[[_x], "insignias.sqf"] remoteExec["execVM", _x, false]; // Execute the script in each machine
}] call BIS_fnc_addScriptedEventHandler;

Just for completeness, I provide the "complete" initServer.sqf below

// Create the arrays found in the ranks.sqf
// to make them available in the mission
call compileFinal preprocessFileLineNumbers "ranks.sqf";

// Add an event handler to re-add the insignia after the arsenal is closed
[missionNamespace, "arsenalClosed", {
	private _plrs = allPlayers - (entities "HeadlessClient_F"); // Get all players
	_plrs apply {[[_x], "insignias.sqf"] remoteExec["execVM", _x, false]; // Execute the script in each machine
}] call BIS_fnc_addScriptedEventHandler;

In this way, you will execute the script every time a player joins the game to give them their insignia (initPlayerLoca.sqf), every time a player respawns (initPlayerLocal.sqf), to make sure they get it back and as a failsafe, every time someone closes the arsenal (initServer.sqf) you will re-run the script for every player. Unfortunately, the "arsenalClosed" event handler does not provide the person/client who closed the arsenal to be able to run the script only for them, so you will have to run the script for everyone, every time someone closes the arsenal. Hopefully, the checks being done in the insignias.sqf script will provide to be not-so-heavy and won't have an impact on your framerate. The good news is that you will have to run those checks only when someone joins (locally on their machine), respawn (locally on their machine) and someone closes the arsenal (also locally on their machines but at each and every machine).

 

Additionally, with this approach, it is easy to add more UIDs in each array or move UIDs from array to array to constitute changes in your roster and/or unit's/group's structure. All you have to do is to make the changes in the ranks.sqf and then recompile it (with the command shown in the initServer.sqf. Just make sure you will use compile instead of compileFinal if you intend to recompile without stopping the mission).

I do believe that the structure of the insignias.sqf could possibly be improved, but this may require a change in the ranks.sqf structure. So, I believe that this is clear enough for simple use and does not provide too much of an overhead.

 

It is important to note though that the provided solution is not tested and should be treated with caution. I have used the same approach before for a different purpose (provide benefits and penalties to players based on their ranks, specialisation, in-game training, etc.) but not to add and remove insignias.

 

Please let me know if something is not clear and/or you would require some help refining any of the presented snippets.

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×