OnPlayerWeaponChange - проверяет, когда игрок сменил оружие
OnPlayerAmmoChange - проверяет, когда игрок изменил патроны
giveWeapon - выдать игроку то или иное оружие
getAmmo - узнать кол-во патронов по ID оружия
giveAmmo - выдать то или иное кол-во патронов игроку по ID оружия
setAmmo - установить то или иное кол-во патронов игроку по ID оружия
resetWeapons - аннулировать оружие у игрока
weapon_slot - узнать слот оружия по его ID
Одна недоработка - неуспевает определить скорость смены патронов с точностью до 1
у минигана, огнемета, теков
При коннекте следует обнулять оружие у игроков
И советую не делать что-то подобное: #define GivePlayerWeapon giveWeapon,
т.к. чит использует именно стандартные функции,
а в данной ситуации вы приравняете серверные к стандартным и все пойдет не по плану
#include a_samp
#define dcmd(%1,%2,%3) if((strcmp((%3)[1],#%1,true,(%2))==0)&&((((%3)[(%2)+1]==0)&&(dcmd_%1(playerid,"")))||(((%3)[(%2)+1]==32)&&(dcmd_%1(playerid,(%3)[(%2)+2]))))) return 1
#define CMD(%0) if (strcmp(%0, cmdtext, true, strlen(%0)) == 0)
forward OnPlayerWeaponChange(playerid, old_weapon, new_weapon);
forward OnPlayerAmmoChange(playerid, old_ammo, new_ammo);
forward AC_Detect();
main(){}
new last_weapons[MAX_PLAYERS char];
new ammo_slot[MAX_PLAYERS][13];
public OnGameModeInit(){
SetTimer("AC_Detect",20,true);
return 1;
}
public AC_Detect(){
for(new playerid;playerid!=GetMaxPlayers();playerid++){
if(IsPlayerConnected(playerid) == 0 || IsPlayerNPC(playerid)) continue;
if(GetPlayerAmmo(playerid) > getAmmo(playerid,GetPlayerWeapon(playerid))) resetWeapons(playerid);//weapon_anti-cheat
if(GetPlayerWeapon(playerid) != last_weapons{playerid}) OnPlayerWeaponChange(playerid,last_weapons{playerid}, GetPlayerWeapon(playerid));
if(GetPlayerWeapon(playerid) == last_weapons{playerid} && GetPlayerAmmo(playerid) != ammo_slot[playerid][weapon_slot(GetPlayerWeapon(playerid))]) OnPlayerAmmoChange(playerid, ammo_slot[playerid][weapon_slot(GetPlayerWeapon(playerid))], GetPlayerAmmo(playerid));
}
}
public OnPlayerAmmoChange(playerid, old_ammo, new_ammo){//by Seregamil
// playerid - игрок, у которого сменились патроны в слоте
// old_ammo - прошлое кол-во патронов
// new_ammo - новое кол-во патронов
new str[128];
format(str,128,"{00ff00}OnPlayerAmmoChange: Игрок: %d | Оружие: %d (Слот: %d) | Старое значение: %d | Новое: %d",playerid, GetPlayerWeapon(playerid), weapon_slot(GetPlayerWeapon(playerid)), old_ammo, new_ammo);
SendClientMessageToAll(-1,str);
ammo_slot[playerid][weapon_slot(GetPlayerWeapon(playerid))] = new_ammo;
}
public OnPlayerWeaponChange(playerid, old_weapon, new_weapon){//by Seregamil
// playerid - игрок, сменивший оружие
// old_weapon - оружие, которое сменили
// new_weapon - оружие, на которое сменили
new ammo_old, okda;
GetPlayerWeaponData(playerid, weapon_slot(old_weapon), okda, ammo_old);
giveAmmo(playerid, old_weapon, -((getAmmo(playerid, old_weapon)-ammo_old)));
new str[128];
format(str,128,"OnPlayerWeaponChange: Игрок: %d, Старое оружие: %d, Новое оружие: %d, Значение патронов в анти-чите: %d",playerid,old_weapon,new_weapon,getAmmo(playerid,old_weapon));
SendClientMessageToAll(-1,str);
last_weapons{playerid} = new_weapon;//установим на старое оружие то, которое сейчас в руках
}
public OnPlayerConnect(playerid){
resetWeapons(playerid);
return 1;
}
public OnPlayerCommandText(playerid, cmdtext[])
{
CMD("/gun_1") return giveWeapon(playerid,random(39),500);
CMD("/ammo") return setAmmo(playerid,24,375);
dcmd(gun,3,cmdtext);
return 0;
}
dcmd_gun(playerid,params[]) return GivePlayerWeapon(playerid,strval(params),random(435));
giveWeapon(playerid, weaponid, ammo){//by Seregamil
new use_weap[100];
format(use_weap,100,"ac_weapon_%d",weapon_slot(weaponid));
SetPVarInt(playerid,use_weap,GetPVarInt(playerid,use_weap)+ammo);
return GivePlayerWeapon(playerid,weaponid, ammo);
}
getAmmo(playerid, weaponid){ //by Seregamil
new use_weap[100];
format(use_weap,100,"ac_weapon_%d",weapon_slot(weaponid));
return GetPVarInt(playerid,use_weap);
}
giveAmmo(playerid, weaponid, ammo){//by Seregamil
new use_weap[100];
format(use_weap,100,"ac_weapon_%d",weapon_slot(weaponid));
SetPVarInt(playerid,use_weap,GetPVarInt(playerid, use_weap)+ammo);
}
setAmmo(playerid,weaponid, ammo){//by Seregamil
new use_weap[100];
format(use_weap,100,"ac_weapon_%d",weapon_slot(weaponid));
SetPVarInt(playerid,use_weap,ammo);
return SetPlayerAmmo(playerid,weaponid, ammo);
}
weapon_slot(weaponid){//by Seregamil
switch(weaponid){
case 0,1: return 0;
case 2..9: return 1;
case 22..24: return 2;
case 25..27: return 3;
case 28,29,32: return 4;
case 30,31: return 5;
case 33,34: return 6;
case 35..38: return 7;
case 16..18: return 8;
case 41..43: return 9;
case 10..15: return 10;
case 44..46: return 11;
case 40: return 12;
}
return -1;
}
resetWeapons(playerid){//by Seregamil
new clear[128];
for(new i;i!=13;i++){
format(clear,sizeof clear,"ac_weapon_%d",i);
SetPVarInt(playerid,clear,0);
}
return ResetPlayerWeapons(playerid);
}
... OnPlayerWeaponChange - проверяет, когда игрок сменил оружие OnPlayerAmmoChange - проверяет, когда игрок изменил патроны ... |
public OnPlayerUpdate(playerid)
{
static Ammo[MAX_PLAYERS], Weap[MAX_PLAYERS], dammo = GetPlayerAmmo(playerid), dweap = GetPlayerWeapon(playerid);
if(Ammo[playerid] != dammo && Weap[playerid] == dweap[playerid])
{
CallLocalFunction("OnPlayerAmmoChange", "dddd", playerid, Weap[playerid], Ammo[playerid], dammo[playerid]);
Ammo[playerid] = dammo;
}
if(Weap[playerid] != dweap)
{
CallLocalFunction("OnPlayerWeaponChange", "ddddd", playerid, Weap[playerid], Ammo[playerid], dweap[playerid], dammo[playerid]);
Ammo[playerid] = dammo, Weap[playerid] = dweap;
}
}
forward OnPlayerAmmoChange(const playerid, const weapon, const oldammo, const newammo);
public OnPlayerAmmoChange(const playerid, const weapon, const oldammo, const newammo)
{
}
forward OnPlayerWeaponChange(const playerid, const oldweapon, const oldammo, const newweapon, const newammo);
public OnPlayerWeaponChange(const playerid, const oldweapon, const oldammo, const newweapon, const newammo)
{
}
public OnPlayerUpdate(playerid) |
Может это колбеки? И если это так, то они ничего не проверяют а вызываться когда происходит событие... |
использовать такие каллбэки как OnPlayer(Weapon/Ammo)Change |
public OnPlayerUpdate(playerid) |