15.07.2013, 13:38
Добрый день!
В общем данное решение позволит использовать такие каллбэки как OnPlayer(Weapon/Ammo)Change
Функции скрипта
Говорю сразу, есть функции, которые вам покажутся пабликовскими и т.д., но писал я их сам лично, используя лишь сборку моделек, т.к. у меня небыло инета 2 недели)
Важно:
Сам скрипт:
При использовании данной системы следует заменить все GivePlayerWeapon | ResetPlayerWeapons | SetPlayerAmmo на giveWeapon | resetWeapons | setAmmo соответственно!
Автор: Seregamil
В общем данное решение позволит использовать такие каллбэки как OnPlayer(Weapon/Ammo)Change
Функции скрипта
PHP Code:
OnPlayerWeaponChange - проверяет, когда игрок сменил оружие
OnPlayerAmmoChange - проверяет, когда игрок изменил патроны
giveWeapon - выдать игроку то или иное оружие
getAmmo - узнать кол-во патронов по ID оружия
giveAmmo - выдать то или иное кол-во патронов игроку по ID оружия
setAmmo - установить то или иное кол-во патронов игроку по ID оружия
resetWeapons - аннулировать оружие у игрока
weapon_slot - узнать слот оружия по его ID
Важно:
PHP Code:
Одна недоработка - неуспевает определить скорость смены патронов с точностью до 1
у минигана, огнемета, теков
При коннекте следует обнулять оружие у игроков
И советую не делать что-то подобное: #define GivePlayerWeapon giveWeapon,
т.к. чит использует именно стандартные функции,
а в данной ситуации вы приравняете серверные к стандартным и все пойдет не по плану
PHP Code:
#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);
}
Автор: Seregamil