Jump to content
Coolinator

Anyone knows a good Anti Team Kill script that works for coop mission multiplayer?

Recommended Posts

Is there an anti team kill script that works for multiplayer coop missions? i want to add an anti team kill script for my mission but i cant find one that's working :(

Share this post


Link to post
Share on other sites

Something like this.

if (isDedicated) exitWith {};
waitUntil {!(isNull player)};
player addEventHandler ["fired", {
_unit = _this select 0;
if ((side cursorTarget) isEqualTo (side _unit)) exitWith {
	_unit setDamage 1;
	[format ["%1 is being punished for shooting friendlies", name _unit],"hintSilent"] call BIS_fnc_mp;
};		
}];

Edited by Iceman77

Share this post


Link to post
Share on other sites

Iceman, it may be easier to use the "HandleDamage" EH in this case. Clever use of an "if" statement can possibly disable friendly fire (untested).

if !(isDedicated) then
{
player addEventHandler ["HandleDamage",
{
	if ((side(_this select 0)) == (side(_this select 3))) then
	{
		[] execVM "myScript.sqf";
	};
	if ((side(_this select 0)) == (side(_this select 3))) then {damage (_this select 0)} else {(_this select 2)};
};
};

Edited by DreadedEntity

Share this post


Link to post
Share on other sites

Could also define some "trusted" player UIDs. People you know (clan mates etc) whom don't do dumb shit on purpose. Essentially filters out those, from general public lunatics.

if (isDedicated) exitWith {};
waitUntil {!(isNull player)};

TRUSTEDUIDS = []; // UID Strings

player addEventHandler ["fired", {
_unit = _this select 0;
if ((getPlayerUID _unit) in TRUSTEDUIDS) exitWith {};
if ((side cursorTarget) isEqualTo (side _unit)) exitWith {
	_unit setDamage 1;
	[format ["%1 is being punished for shooting friendlies", name _unit],"hintSilent"] call BIS_fnc_mp;
};		
}];

Iceman, it may be easier to use the "HandleDamage" EH in this case.

Yeah that works too :)

Share this post


Link to post
Share on other sites
Could also define some "trusted" player UIDs. People you know (clan mates etc) whom don't do dumb shit on purpose. Essentially filters out those, from general public lunatics.

if (isDedicated) exitWith {};
waitUntil {!(isNull player)};

TRUSTEDUIDS = []; // UID Strings

player addEventHandler ["fired", {
_unit = _this select 0;
if ((getPlayerUID _unit) in TRUSTEDUIDS) exitWith {};
if ((side cursorTarget) isEqualTo (side _unit)) exitWith {
	_unit setDamage 1;
	[format ["%1 is being punished for shooting friendlies", name _unit],"hintSilent"] call BIS_fnc_mp;
};		
}];

Yeah that works too :)

How do i execute or use this? could you explain step by step?sorry im not a pro scripter :(

Share this post


Link to post
Share on other sites

There's numerous options. Here are just a few.

- Put it at the bottom of your init.sqf.

- Put it under any pre-existing waitUntil {!isNull player}; that's in your init.sqf.

- Create a script called TKEH.sqf and put the code in there. Then in your init.sqf somewhere just execVM "TKEH.sqf";

- Really any way you want to initialize the script.

note: There are several ways to do a tk script. You may want to take a look at dread's. It would prevent damage aswell. My version simply punishes any would be tk'er immediately on his first shot. There are several ways to initialize a tk script. You could even compile it into a function.

Edited by Iceman77

Share this post


Link to post
Share on other sites
There's numerous options. Here are just a few.

- Put it at the bottom of your init.sqf.

- Put it under any pre-existing waitUntil {!isNull player}; that's in your init.sqf.

- Create a script called TKEH.sqf and put the code in there. Then in your init.sqf somewhere just execVM "TKEH.sqf";

- Really any way you want to initialize the script.

note: There are several ways to do a tk script. You may want to take a look at dread's. It would prevent damage aswell. My version simply punishes any would be tk'er immediately on his first shot. There are several ways to initialize a tk script. You could even compile it into a function.

THank you it worked!!!! but how do i adjust the damage? For example, i want 5 damage bullet hit to get kick, instead getting punished by 1 bullet hit damage.

Share this post


Link to post
Share on other sites

I'm not sure how to outright kick a player. I'm sure there's a way (??). Anyhow, maybe something like this could suffice in the mean time. Cheers.

if (isDedicated) exitWith {};
waitUntil {!(isNull player)};

TRUSTEDUIDS = []; // UID Strings
TKWARNINGS = 0;

player addEventHandler ["fired", {

   _unit = _this select 0;

   if ((getPlayerUID _unit) in TRUSTEDUIDS) exitWith {};

   if ((side cursorTarget) isEqualTo (side _unit)) then {

	TKWARNINGS = TKWARNINGS + 1;

       [
		format ["This is TK warning number %1 for %2", TKWARNINGS, name _unit],
		"hintSilent"
	] call BIS_fnc_mp;

	if (TKWARNINGS isEqualTo 4) exitWith {
		[
			format ["%1 is pulling on the final straw. One more TK and he will be punished.", name _unit],
			"hintSilent"
		] call BIS_fnc_mp;
	};

	if (TKWARNINGS isEqualTo 5) exitWith {
		disableUserInput true; 
		[
			format ["That's it for %1. His keyboard has been disabled. Please kick him asap.", name _unit],
			"hintSilent"
		] call BIS_fnc_mp;	

	};

   }; 

}];  

Edited by Iceman77

Share this post


Link to post
Share on other sites
I'm not sure how to outright kick a player. I'm sure there's a way (??). Anyhow, maybe something like this could suffice in the mean time. Cheers.

I wondered about this myself a while back, and put the ol' thinktank to work. Essentially what I came up with was ending the mission for a specific player if they screw up too much, which should drop them back in the lobby if I'm not mistaken. BIS_fnc_endMission

You could also take a look at endMission, but using the BIS function is recommended, on the wiki.

This is purely speculative, though, as it's widely known that I don't actually make any missions. So I've never experimented with mission endings :p

Share this post


Link to post
Share on other sites
I'm not sure how to outright kick a player. I'm sure there's a way (??). Anyhow, maybe something like this could suffice in the mean time. Cheers.

if (isDedicated) exitWith {};
waitUntil {!(isNull player)};

TRUSTEDUIDS = []; // UID Strings
TKWARNINGS = 0;

player addEventHandler ["fired", {

   _unit = _this select 0;

   if ((getPlayerUID _unit) in TRUSTEDUIDS) exitWith {};

   if ((side cursorTarget) isEqualTo (side _unit)) then {

	TKWARNINGS = TKWARNINGS + 1;

       [
		format ["This is TK warning number %1 for %2", TKWARNINGS, name _unit],
		"hintSilent"
	] call BIS_fnc_mp;

	if (TKWARNINGS isEqualTo 4) exitWith {
		[
			format ["%1 is pulling on the final straw. One more TK and he will be punished.", name _unit],
			"hintSilent"
		] call BIS_fnc_mp;
	};

	if (TKWARNINGS isEqualTo 5) exitWith {
		disableUserInput true; 
		[
			format ["That's it for %1. His keyboard has been disabled. Please kick him asap.", name _unit],
			"hintSilent"
		] call BIS_fnc_mp;	

	};

   }; 

}];  

Thank you so much!! i will test it out! and let you know if it works.

Share this post


Link to post
Share on other sites

I'd really suggest using "handleDamage" instead of "fired" otherwise you can easily get false accusations due to the use of cursorTarget.

For example when throwing a smokegrenade while looking at a teammate or when planting explosives or when using a weapon with indirect fire...

Share this post


Link to post
Share on other sites
I'm not sure how to outright kick a player. I'm sure there's a way (??). Anyhow, maybe something like this could suffice in the mean time. Cheers.

if (isDedicated) exitWith {};
waitUntil {!(isNull player)};

TRUSTEDUIDS = []; // UID Strings
TKWARNINGS = 0;

player addEventHandler ["fired", {

   _unit = _this select 0;

   if ((getPlayerUID _unit) in TRUSTEDUIDS) exitWith {};

   if ((side cursorTarget) isEqualTo (side _unit)) then {

	TKWARNINGS = TKWARNINGS + 1;

       [
		format ["This is TK warning number %1 for %2", TKWARNINGS, name _unit],
		"hintSilent"
	] call BIS_fnc_mp;

	if (TKWARNINGS isEqualTo 4) exitWith {
		[
			format ["%1 is pulling on the final straw. One more TK and he will be punished.", name _unit],
			"hintSilent"
		] call BIS_fnc_mp;
	};

	if (TKWARNINGS isEqualTo 5) exitWith {
		disableUserInput true; 
		[
			format ["That's it for %1. His keyboard has been disabled. Please kick him asap.", name _unit],
			"hintSilent"
		] call BIS_fnc_mp;	

	};

   }; 

}];  

it works!!! but i think its better it the player get punished for team kills not team damage. Do you know how to to change it to count as team kills instead of team damage?

For example, a player killed a teammate a twice or three times, then his keyboard will be disabled.

I also like the idea of disabling of the keyboard lol!

---------- Post added at 09:58 ---------- Previous post was at 09:57 ----------

I'd really suggest using "handleDamage" instead of "fired" otherwise you can easily get false accusations due to the use of cursorTarget.

For example when throwing a smokegrenade while looking at a teammate or when planting explosives or when using a weapon with indirect fire...

How do i use "handleDamage"? could you explain how to use it step by step? plz

Share this post


Link to post
Share on other sites

Dreaded already posted an example on the previous page. Anyway, here is another (untested):

TRUSTEDUIDS = []; // UID Strings
TEAMATTACKLIMIT = 5;

fnc_taPunish = {
private ["_s","_p","_ta"]; 
_s = _this select 0;
_p = _this select 1;
_ta = _this select 2;

if ((getPlayerUID _s) in TRUSTEDUIDS) exitWith {};

systemChat format["[Teamattack warning %1/%2]: %3 has attacked %4!", _ta, TEAMATTACKLIMIT, name _s, name _p];

if (_ta >= TEAMATTACKLIMIT) then {
	if (local _s) then {
		"end1" call BIS_fnc_endMission;
	};
	systemChat format["%1 has been removed for excessive teamattacks!",name _s];
}
};

if (!isDedicated) then {
   player addEventHandler ["HandleDamage", {
   	private ["_dmg","_p","_s","_pSide","_sSide","_ta"]; 
   	_dmg = _this select 2;
   	_p = _this select 0;
   	_s = _this select 3;
   	_pSide = side(_p);
   	_sSide = side(_s);

   	if(_pSide == _sSide) then {
   		_dmg = {};
   		_ta = (_s getVariable["teamattacks",0]) + 1;
   		_s setVariable["teamattacks",_ta,true];
   		[ [_s,_p,_ta], "fnc_taPunish", true] spawn BIS_fnc_MP;
   	};

   	_dmg
   };
};

In this example, teammates do not recieve any damage.

Share this post


Link to post
Share on other sites
Dreaded already posted an example on the previous page. Anyway, here is another (untested):

TRUSTEDUIDS = []; // UID Strings
TEAMATTACKLIMIT = 5;

fnc_taPunish = {
private ["_s","_p","_ta"]; 
_s = _this select 0;
_p = _this select 1;
_ta = _this select 2;

if ((getPlayerUID _s) in TRUSTEDUIDS) exitWith {};

systemChat format["[Teamattack warning %1/%2]: %3 has attacked %4!", _ta, TEAMATTACKLIMIT, name _s, name _p];

if (_ta >= TEAMATTACKLIMIT) then {
	if (local _s) then {
		"end1" call BIS_fnc_endMission;
	};
	systemChat format["%1 has been removed for excessive teamattacks!",name _s];
}
};

if (!isDedicated) then {
   player addEventHandler ["HandleDamage", {
   	private ["_dmg","_p","_s","_pSide","_sSide","_ta"]; 
   	_dmg = _this select 2;
   	_p = _this select 0;
   	_s = _this select 3;
   	_pSide = side(_p);
   	_sSide = side(_s);

   	if(_pSide == _sSide) then {
   		_dmg = {};
   		_ta = (_s getVariable["teamattacks",0]) + 1;
   		_s setVariable["teamattacks",_ta,true];
   		[ [_s,_p,_ta], "fnc_taPunish", true] spawn BIS_fnc_MP;
   	};

   	_dmg
   };
};

In this example, teammates do not recieve any damage.

Just tested it. It doesnt seem to work. I already killed 3 friendlies, nothing happened :(

Share this post


Link to post
Share on other sites

It only applies to players, not friendly KI.

Share this post


Link to post
Share on other sites
It only applies to players, not friendly KI.

Ah okay! Im almost done with my mission took me 4 days to finish it lol, this is my first mission for arma 3. I will start hosting my mission tommorow and see if the anti TK script works made by tajin. I let you know tommorow or the next day after. Im going to sleep now. Thank you guys for all your help, i really appreciate it :) i keep you guys updated tommorow if the latest TK script works :)

Share this post


Link to post
Share on other sites

S'all good. For now you'll just have to tolerate the publics killing all your Ais LOL. If you wanted to use the shitty code I posted, then just filter out thrown weapons... and set a more nice way of "dealing with the player" as we wouldn't want to freeze this nice guy's keyboard now would we? LOL

Edited by Iceman77

Share this post


Link to post
Share on other sites
Dreaded already posted an example on the previous page. Anyway, here is another (untested):

TRUSTEDUIDS = []; // UID Strings
TEAMATTACKLIMIT = 5;

fnc_taPunish = {
private ["_s","_p","_ta"]; 
_s = _this select 0;
_p = _this select 1;
_ta = _this select 2;

if ((getPlayerUID _s) in TRUSTEDUIDS) exitWith {};

systemChat format["[Teamattack warning %1/%2]: %3 has attacked %4!", _ta, TEAMATTACKLIMIT, name _s, name _p];

if (_ta >= TEAMATTACKLIMIT) then {
	if (local _s) then {
		"end1" call BIS_fnc_endMission;
	};
	systemChat format["%1 has been removed for excessive teamattacks!",name _s];
}
};

if (!isDedicated) then {
   player addEventHandler ["HandleDamage", {
   	private ["_dmg","_p","_s","_pSide","_sSide","_ta"]; 
   	_dmg = _this select 2;
   	_p = _this select 0;
   	_s = _this select 3;
   	_pSide = side(_p);
   	_sSide = side(_s);

   	if(_pSide == _sSide) then {
   		_dmg = {};
   		_ta = (_s getVariable["teamattacks",0]) + 1;
   		_s setVariable["teamattacks",_ta,true];
   		[ [_s,_p,_ta], "fnc_taPunish", true] spawn BIS_fnc_MP;
   	};

   	_dmg
   };
};

In this example, teammates do not recieve any damage.

I know this is a month old thread, I'm sorry for not posting the results, I've been busy making missions, and I totally forgot about the anti-kill script, because I was hosting my mission in private with my friends. But I want to try to host my missions on public, so I visited this thread again :)

I already tested the anti-team kill script by tajin on dedicated server, and the result is that it didn't work :(

Anyone know an alternative?

Share this post


Link to post
Share on other sites
Would you be a little more specific?

I killed my friend 3 times, i didn't get punished :(

Share this post


Link to post
Share on other sites

Well try something like this: (ALL UNTESTED - JUST THEORY)

ONLY SERVER RUNS THIS

trustedUIDs = [];
teamkillLimit = 5;

"unitConnected" addPublicVariableEventHandler
{
(_this select 1) addEventHandler ["killed", handleTeamkill];
};
["removeTeamkill", "onPlayerDisconnected",
{
//not really sure what happens when a player disconnects...does it turn into AI?
}] call BIS_fnc_addStackedEventHandler;

handleTeamkill = compileFinal
'
_unit = _this select 0;
_killer = _this select 1;
if (((side _unit) == (side _killer)) && {!((getPlayerUID _killer) in trustedUIDs)}) then
{
	missionNamespace setVariable [format ["TK_%1", name _killer], missionNamespace getVariable [format ["TK_%1", name _killer], 0] + 1];
	if (missionNamespace getVariable [format ["TK_%1", name _killer], 0] == teamkillLimit) then
	{
		["teamkillEnd", false] BIS_fnc_endMission;
	}else
	{
		[format ["Please do not kill teammates. You have been warned %1 times", missionNamespace getVariable [format ["TK_%1", name _killer], 0]], "systemChat", _killer] call BIS_fnc_MP;
	};
};
';

//{
//	if (isPlayer) then
//	{
//		_x addEventHandler ["killed", handleTeamkill];
//	};
//}forEach playableUnits; //commented this part out because I think it's not necessary anymore

ALL CLIENTS RUN THIS - Put in init.sqf somewhere

waitUntil {player == player};
unitConnected = player;
publicVariableServer "unitConnected";

Maybe that will work, dunno. Also, you're going to have to set up a mission ending, not sure if you've ever done that before, but it's not that hard. The class should be called "teamkillEnd".

EDIT: here's what you should put in description.ext for the mission end:

class CfgDebriefing
{  
class teamkillEnd
{
	title = "Mission Failed";
	subtitle = "You killed too many teammates.";
	description = "You killed too many of your teammates."; //intentionally different so you can see where the game puts both messages
};
};

Edited by DreadedEntity

Share this post


Link to post
Share on other sites
Well try something like this: (ALL UNTESTED - JUST THEORY)

ONLY SERVER RUNS THIS

trustedUIDs = [];
teamkillLimit = 5;

"unitConnected" addPublicVariableEventHandler
{
(_this select 1) addEventHandler ["killed", handleTeamkill];
};
["removeTeamkill", "onPlayerDisconnected",
{
//not really sure what happens when a player disconnects...does it turn into AI?
}] call BIS_fnc_addStackedEventHandler;

handleTeamkill = compileFinal
'
_unit = _this select 0;
_killer = _this select 1;
if (((side _unit) == (side _killer)) && {!((getPlayerUID _killer) in trustedUIDs)}) then
{
	missionNamespace setVariable [format ["TK_%1", name _killer], missionNamespace getVariable [format ["TK_%1", name _killer], 0] + 1];
	if (missionNamespace getVariable [format ["TK_%1", name _killer], 0] == teamkillLimit) then
	{
		["teamkillEnd", false] BIS_fnc_endMission;
	}else
	{
		[format ["Please do not kill teammates. You have been warned %1 times", missionNamespace getVariable [format ["TK_%1", name _killer], 0]], "systemChat", _killer] call BIS_fnc_MP;
	};
};
';

//{
//	if (isPlayer) then
//	{
//		_x addEventHandler ["killed", handleTeamkill];
//	};
//}forEach playableUnits; //commented this part out because I think it's not necessary anymore

ALL CLIENTS RUN THIS - Put in init.sqf somewhere

waitUntil {player == player};
unitConnected = player;
publicVariableServer "unitConnected";

Maybe that will work, dunno. Also, you're going to have to set up a mission ending, not sure if you've ever done that before, but it's not that hard. The class should be called "teamkillEnd".

EDIT: here's what you should put in description.ext for the mission end:

class CfgDebriefing
{  
class teamkillEnd
{
	title = "Mission Failed";
	subtitle = "You killed too many teammates.";
	description = "You killed too many of your teammates."; //intentionally different so you can see where the game puts both messages
};
};

I already have an ending in my description.ext, can i just add that extra ending "teamkillEnd"?

can i combine them, like this?

class CfgDebriefing
{  
       class End1
       {
               title = "Operation Rouge Fury";
               subtitle = "Mission accomplished!";
               description = "Credits: Special thanks to Jshock, Iceman77, Lala14, Persian MO, Tajin, DreadedEntity, Jigsor and Bohemia Interactive community. Also, special thanks to my long time friend Kutze, and G.O.A.T. clan members (Meats, Pvt. parts, Droopy, Kranor, and others).";
               pictureBackground = "Marines.jpg";
               duration = 19;
               picture = "Salute.jpg";
               pictureColor[] = {1.0,1.0,1.0,1};
       };
       class teamkillEnd 
       { 
       title = "Mission Failed"; 
       subtitle = "You killed too many teammates."; 
       description = "You killed too many of your teammates."; //intentionally different so you can see where the game puts both messages
       }; 
};  

---------- Post added at 05:19 ---------- Previous post was at 05:16 ----------

Do i put this in initServer.sqf? or do i need to call it as a script?

trustedUIDs = []; 
teamkillLimit = 5; 

"unitConnected" addPublicVariableEventHandler 
{ 
   (_this select 1) addEventHandler ["killed", handleTeamkill]; 
}; 
["removeTeamkill", "onPlayerDisconnected", 
{ 
   //not really sure what happens when a player disconnects...does it turn into AI? 
}] call BIS_fnc_addStackedEventHandler; 

handleTeamkill = compileFinal 
' 
   _unit = _this select 0; 
   _killer = _this select 1; 
   if (((side _unit) == (side _killer)) && {!((getPlayerUID _killer) in trustedUIDs)}) then 
   { 
       missionNamespace setVariable [format ["TK_%1", name _killer], missionNamespace getVariable [format ["TK_%1", name _killer], 0] + 1]; 
       if (missionNamespace getVariable [format ["TK_%1", name _killer], 0] == teamkillLimit) then 
       { 
           ["teamkillEnd", false] BIS_fnc_endMission; 
       }else 
       { 
           [format ["Please do not kill teammates. You have been warned %1 times", missionNamespace getVariable [format ["TK_%1", name _killer], 0]], "systemChat", _killer] call BIS_fnc_MP; 
       }; 
   }; 
'; 

//{ 
//    if (isPlayer) then 
//    { 
//        _x addEventHandler ["killed", handleTeamkill]; 
//    }; 
//}forEach playableUnits; //commented this part out because I think it's not necessary anymore  

Edited by Coolinator

Share this post


Link to post
Share on other sites
I already have an ending in my description.ext, can i just add that extra ending "teamkillEnd"?
Do i put this in initServer.sqf?

looks right

Share this post


Link to post
Share on other sites
looks right

Thank you so much Dreaded!!! i will test it later in dedicated server with my friends :)

Share this post


Link to post
Share on other sites
Thank you so much Dreaded!!! i will test it later in dedicated server with my friends :)

No problem, let me know if something doesn't work, but add details!

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

×