Jump to content
Sign in to follow this  
riten

[FIXED] Weapon limitation problem

Recommended Posts

Hi

 

So I've created script that limits ammount of weapons per team.

[] spawn {

while {true} do {

if ({primaryWeapon _x == "CUP_srifle_CZ550_rail" && side _x == east} count allunits > 1) then {player removeweaponglobal "CUP_srifle_CZ550_rail" };
if ({primaryWeapon _x == "CUP_arifle_Sa58RIS2" && side _x == east} count allunits > 1) then {player removeweaponglobal "CUP_arifle_Sa58RIS2" };
if ({primaryWeapon _x == "CUP_lmg_UK59" && side _x == east} count allunits > 1) then {player removeweaponglobal "CUP_lmg_UK59" };
if ({primaryWeapon _x == "CUP_arifle_RPK74" && side _x == east} count allunits > 1) then {player removeweaponglobal "CUP_arifle_RPK74" };
if ({primaryWeapon _x == "CUP_launch_RPG7V"  && side _x == east} count allunits > 2) then {player removeweaponglobal "CUP_launch_RPG7V"  };
if ({primaryWeapon _x == "CUP_launch_9K32Strela"  && side _x == east} count allunits > 2) then {player removeweaponglobal "CUP_launch_9K32Strela"  };

sleep 0.5;
	}; 
};

It works pretty good, but it get bugs sometimes.

 

For example:

 

One player takes sniper rifle (which limit is x1) and then when second player try to pick sniper rifle it gets deleted from his hands.

 

Problems:

 

Sometimes weapon gets deleted to first player instead of second player that attempts to pick weapon after limit is reached and I don't know how to fix it. 

 

How it should works:

 

Weapon gets deleted to the guy that attempts to pick weapon after limit is reached.

Share this post


Link to post
Share on other sites

idk really but it could be a problem with spawn because u dont really know when spawned code is executed. 2nd thing is that ur script needs fast equalizing over network to proper work. the information that player A took the last weapon within the limit has to reach player B before he takes same weapon again. If that information is not arrived at player B plus the spawning method could cauze weird behavior.

 

I would suggest to do that stuff server side and delete the weapons with remoteExec.

Share this post


Link to post
Share on other sites

I'd say don't use player in MP games, even if you execute the code locally (and are 100% sure of it, ie through !isServer or something similar) because return value of 'player' can be non local sometimes (although quite frankly I don't know how rare that is). How are you executing the code? init.sqf?

Share this post


Link to post
Share on other sites

@sarogahtyp

 

With remoteExec it's removing weapons to all players when limit is reached.

cz = {player removeweapon "CUP_srifle_CZ550_rail"};


[] spawn {

while {isServer} do {

if ({primaryWeapon _x == "CUP_srifle_CZ550_rail" && side _x == east} count allunits > 1) then { remoteExec ["cz", east, true];};


sleep 0.5;
	}; 
};

@tryteyker

Yes init.sqf.

Share this post


Link to post
Share on other sites

okay. remotexec could work with correct code but isnt neccessary. all of that can be done server side because the command u r using have global effects and arguments.

i ll think bout a server side solution and post it if its not done already then

Share this post


Link to post
Share on other sites

I suggest not to check each player weapon all the time, but only when he will pick up anything. Also, put weapon limitations to the table and separate from code:

// in init.sqf
WeaponLimitations = [
	["CUP_srifle_CZ550_rail",	1],
	["CUP_arifle_Sa58RIS2",		1],
	["CUP_lmg_UK59",			1],
	["CUP_arifle_RPK74",		1],
	["CUP_launch_RPG7V",		1],
	["CUP_launch_9K32Strela",	1]];

Fn_CheckWeaponLimitations = {
	private _unt = _this;
	private _wpn = primaryWeapon _unt;
	private _lmt = {if (_x select 0 isEqualTo _wpn) exitWith {_x select 1}} forEach WeaponLimits;
	
	// here _lmt variable contains limit count for player primary weapon or nil if weapon count not limited	
	if (not isNil {_lmt}) then {
		private _sde = side _unt;
		if ({side _x isEqualTo _sde and primaryWeapon _x isEqualTo _wpn} count allPlayers > _lmt) then {
			_unt removeWeapon _wpn}
	}
};
	
//at each player initialization
this addEventHandler ["InventoryClosed", {(_this select 0) call Fn_CheckWeaponLimitations}];

UPD: It is at the same time solves your problem with the removal of excess weapons from player who pick it up earlier.

UPD: Fixed code

UPD: Updated to use allPlayers instead  of allUnits

Share this post


Link to post
Share on other sites

@serena
 
That code looks much better then mine, but still same problem. Weapon gets deleted to first player instead of second player that attempts to pick weapon after limit is reached - but with ur script that happens only when I try to pick weapon 2-3 times, pretty quick (this is what players will for sure try to do). EDIT: After while it messed up at all, when A picked weapon, B weapon was deleted, even with 1 time attempt to pick.

 

Maybe we should add player that picked weapon before limit is reached to some "Exceptions" tabele to make sure that it will be deleted to correct player? What do you think?

 

Also I need to do same for items like ACRE radios.

Share this post


Link to post
Share on other sites

I think serenas code should be adapted for server side use because I think its a network problem.

 

could u try to put this in

initServer.sqf:

WeaponLimitations = [
	["CUP_srifle_CZ550_rail",	1],
	["CUP_arifle_Sa58RIS2",		1],
	["CUP_lmg_UK59",			1],
	["CUP_arifle_RPK74",		1],
	["CUP_launch_RPG7V",		1],
	["CUP_launch_9K32Strela",	1]];

Fn_CheckWeaponLimitations = {
	private _unt = _this;
	private _wpn = primaryWeapon _unt;
	private _lmt = {if (_x select 0 isEqualTo _wpn) exitWith {_x select 1}} forEach WeaponLimits;
	
	// here _lmt variable contains limit count for player primary weapon or nil if weapon count not limited	
	if (not isNil {_lmt}) then {
		private _sde = side _unt;
		if ({side _x isEqualTo _sde and primaryWeapon _x isEqualTo _wpn} count allPlayers > _lmt) then {
			_unt removeWeapon _wpn}
	}
};

and this to each players init line:

if(isServer)then{this addEventHandler ["InventoryClosed", {(_this select 0) call Fn_CheckWeaponLimitations}];};

I ve not checked that deeply but it would be server side. maybe it works

  • Like 1

Share this post


Link to post
Share on other sites

Weapon gets deleted to first player instead of second player that attempts to pick weapon after limit is reached - but with ur script that happens only when I try to pick weapon 2-3 times, pretty quick (this is what players will for sure try to do). EDIT: After while it messed up at all, when A picked weapon, B weapon was deleted, even with 1 time attempt to pick.

 

 

Try this:

Fn_CheckWeaponLimitations = {
	private _unt = _this;
	private _wpn = primaryWeapon _unt;
	
	if (not (_wpn isEqualTo (_unt getVariable ["LastCheckedWeapon", "NoWeapon"]))) then {
		private _lmt = {if (_x select 0 isEqualTo _wpn) exitWith {_x select 1}} forEach WeaponLimits;
	
		if (not isNil {_lmt}) then {
			private _sde = side _unt;
			if ({_x != _unt and side _x isEqualTo _sde and primaryWeapon _x isEqualTo _wpn} count allPlayers >= _lmt) then {
				_unt removeWeapon _wpn}
		};
		_unt setVariable ["LastCheckedWeapon", primaryWeapon _unt]
	}
}; 

UPD: Need workaround for weapons in launcher slot, because it is secondaryWeapon

Share this post


Link to post
Share on other sites

@up 

 

Still same - unpredictable, sometimes it works, two seconds later it's broken.

 

This time when I started:

 

1. A picked weapon, then B picked and A weapon was deleted.

 

Few attempts later:

 

2. A picked weapon, then B picked and B weapon was deleted

 

and then after few attempts it's again step #1, but it's not always correct - #2/buggy #1 sequence, it's unpredictable

 

@sarogahtyp

 

nothing new, same result as up.

Share this post


Link to post
Share on other sites

Extended version with secondary weapon and handgun limitation support, fixed some bugs:

// in initServer.sqf:
WeaponLimitations = [
	[	// primary weapon limitations
		["CUP_srifle_CZ550_rail",	1],
		["CUP_arifle_Sa58RIS2",		1],
		["CUP_lmg_UK59",			1],
		["CUP_arifle_RPK74",		1]],
		
	[	// secondary weapon limitations
		["CUP_launch_RPG7V",		1],
		["CUP_launch_9K32Strela",	1]],
		
	[	// handgun limitations
	]];

Fn_CheckWeaponLimitations = {
	private _unt = _this;
	private _vrn = ["LastCheckedPrimaryWeapon", "LastCheckedSecondaryWeapon", "LastCheckedHandgunWeapon"];
	
	{	private _wpn = _x;
		private _var = _vrn select _forEachIndex;
		
		if (_wpn isEqualTo "") then {
			// unit has no weapon of this type
			_unt setVariable [_var, nil];
		} else {		
			if (_wpn isEqualTo (_unt getVariable [_var, "Unchecked"])) then {
				// unit has his weapon allready checked, do nothing
			} else {
				private _lmt = {if (_x select 0 isEqualTo _wpn) exitWith {_x select 1}} forEach (WeaponLimits select _forEachIndex);
				
				if (isNil {_lmt}) then {
					// unit weapon not limited
					_unt setVariable [_var, _wpn];
				} else {
					private _sde = side _unt;
					if ({side _x isEqualTo _sde and _x hasWeapon _wpn} count allPlayers > _lmt) then {
						_unt removeWeapon _wpn;
						_unt setVariable [_var, nil];
					} else {
						_unt setVariable [_var, _wpn]}
				}
			}		
		}	
	} forEach [primaryWeapon _unt, secondaryWeapon _unt, handgunWeapon _unt]
};

UPD: Fixed error

UPD: Fixed error

UPD: Added code to handle unit has no weapon case

  • Like 2

Share this post


Link to post
Share on other sites

I really appreciate your work, but I have to say that it is even more bugged now.

 

 

1. A picked weapon, then B picked and A weapon was deleted.

2. A picked weapon, then B picked and B weapon was deleted

+

3. A picked weapon then B picked weapon and B+A weapons are deleted

 

EDIT 1: "UPD: Added code to handle unit has no weapon case" - checking

Share this post


Link to post
Share on other sites

My code is just idea, not tested and ready to use solution. I have no arma installed here. So, if you got errors (-showScriptErrors / *.rpt files) post it here please

 

 

3. A picked weapon then B picked weapon and B+A weapons are deleted

 

LOL, this script makes you more peaceful 

 

  • Like 1

Share this post


Link to post
Share on other sites

It's better, but still if u go arsenal and try to get limited weapon too quick it gets deleted from first guy anyway :P Also I'm not getting any script errors, I think we won't fix deleteing thing for 100% (tricky players will just mess up everything).

 

Your code is beautifull, but we get same effect as in my test code hehe :D

Share this post


Link to post
Share on other sites

Why do you have arsenal active in a mission where you want to limit weapons?  Just use respawn templates and delete bodies/weapons on death.  Or just have a crate with only the weapons you want available, track who gets one and when they die/lose the weapon replace it in the box.

Share this post


Link to post
Share on other sites

It's better, but still if u go arsenal and try to get limited weapon too quick it gets deleted from first guy anyway

 

I suppose when you open and close arsenal instead of gear dialog, Fn_CheckWeaponLimitations function is not called. Check this please.

systemChat "Fn_CheckWeaponLimitations is executing..."

Share this post


Link to post
Share on other sites
waitUntil { isnull ( uinamespace getvariable "RSCDisplayArsenal" ) };

There's another way of checking too, but that code isn't at my fingertips at the moment.  I suppose if you limit arsenal item availability and block loading and check that would be good too, but free-for-all arsenal + checking seems excessive.

 

Code from this post.

Share this post


Link to post
Share on other sites

Maybe: 

// in initClient.sqf
while {true} do {
	waitUntil {sleep 1; not isNull (uiNamespace getVariable "RSCDisplayArsenal")}; // here arsenal opened
	waitUntil {isNull (uiNamespace getVariable "RSCDisplayArsenal")}; // here arsenal closed
	player remoteExec ["Fn_CheckWeaponLimitations", 2]; // execute by server only
};

Also, in Fn_CheckWeaponLimitations, removeWeapon seem need to be replaced with removeWeaponGlobal

Share this post


Link to post
Share on other sites

I've now created something that 100% works how I want:

 

1. It deletes weapon if limit is reached.

2. It always deletes weapon of player that tried to pick it after limit is reached

 

btw. Is there any better way to fix my loop part of code? I mean is it possible to chcek wpn tabele one by one without loop?

wpn = [	
		["CUP_srifle_CZ550_rail",	1],
		["CUP_arifle_Sa58RIS2",     1],
		["CUP_lmg_UK59",            1],
		["CUP_arifle_RPK74",	    1]
	];
		
wpn2 =	
	[	
		["CUP_launch_RPG7V",		2],
		["CUP_launch_9K32Strela",	2]
	];
	
	
_primarywpn = primaryWeapon Player;	
_secondarywpn = secondaryWeapon Player;
_limit1 = {primaryWeapon _x == _primarywpn && side _x == east} count allPlayers;	
_limit2 = {secondaryWeapon _x == _secondarywpn && side _x == east} count allPlayers;	

_a=0;

while {_a < 4} do
{
				if (_primarywpn in (wpn select _a)) then {limitx = (wpn select _a) select 1; };

				if (_a < 3) then {
									if (_secondarywpn in (wpn2 select _a)) then {limitx2 = (wpn2 select _a) select 1; };
								};
_a=_a+1;	
};	
	
if (side player == east && primaryWeapon player == _primarywpn && _limit1 > limitx) then { 
																						  player removeWeaponGlobal _primarywpn; 
																						  ["<t color='#ff0000' size = '1.5'>Warning!<br />Limit for this weapons has been reached!<br /> Deleting your weapon.</t>",-1,-1,4,1,0,789] spawn BIS_fnc_dynamicText; 
																						 };


if (side player == east && secondaryWeapon player == _secondarywpn && _limit2 > limitx2) then { 
																							   player removeWeaponGlobal _secondarywpn; 
																							   ["<t color='#ff0000' size = '1.5'>Warning!<br />Limit for this weapons has been reached!<br /> Deleting your weapon.</t>",-1,-1,4,1,0,789] spawn BIS_fnc_dynamicText;
																							  };

and I'm executing this code via eventhandler

player addEventHandler  ["take","this = [] execVM 'limit.sqf'"];

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
Sign in to follow this  

×