Coolinator 10 Posted November 8, 2014 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
iceman77 19 Posted November 9, 2014 (edited) 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 November 9, 2014 by Iceman77 Share this post Link to post Share on other sites
dreadedentity 278 Posted November 9, 2014 (edited) 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 November 9, 2014 by DreadedEntity Share this post Link to post Share on other sites
iceman77 19 Posted November 9, 2014 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
Coolinator 10 Posted November 9, 2014 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
iceman77 19 Posted November 9, 2014 (edited) 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 November 9, 2014 by Iceman77 Share this post Link to post Share on other sites
Coolinator 10 Posted November 10, 2014 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
iceman77 19 Posted November 10, 2014 (edited) 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 November 10, 2014 by Iceman77 Share this post Link to post Share on other sites
dreadedentity 278 Posted November 10, 2014 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
Coolinator 10 Posted November 10, 2014 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
Tajin 349 Posted November 10, 2014 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
Coolinator 10 Posted November 10, 2014 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
Tajin 349 Posted November 10, 2014 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
Coolinator 10 Posted November 10, 2014 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
Tajin 349 Posted November 10, 2014 It only applies to players, not friendly KI. Share this post Link to post Share on other sites
Coolinator 10 Posted November 10, 2014 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
iceman77 19 Posted November 10, 2014 (edited) 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 November 10, 2014 by Iceman77 Share this post Link to post Share on other sites
Coolinator 10 Posted December 19, 2014 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
dreadedentity 278 Posted December 19, 2014 didn't work Would you be a little more specific? Share this post Link to post Share on other sites
Coolinator 10 Posted December 19, 2014 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
dreadedentity 278 Posted December 20, 2014 (edited) 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 December 20, 2014 by DreadedEntity Share this post Link to post Share on other sites
Coolinator 10 Posted December 20, 2014 (edited) 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 December 20, 2014 by Coolinator Share this post Link to post Share on other sites
dreadedentity 278 Posted December 20, 2014 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
Coolinator 10 Posted December 20, 2014 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
dreadedentity 278 Posted December 20, 2014 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