[Tutorial] OnPlayerWeaponChange::OnPlayerAmmoChange::Weapon_A C
#1

Добрый день!

В общем данное решение позволит использовать такие каллбэки как OnPlayer(Weapon/Ammo)Change

Функции скрипта

PHP Code:
    OnPlayerWeaponChange проверяеткогда игрок сменил оружие
    OnPlayerAmmoChange 
проверяеткогда игрок изменил патроны
    giveWeapon 
выдать игроку то или иное оружие
    getAmmo 
узнать кол-во патронов по ID оружия
    giveAmmo 
выдать то или иное кол-во патронов игроку по ID оружия
    setAmmo 
установить то или иное кол-во патронов игроку по ID оружия
    resetWeapons 
аннулировать оружие у игрока
    weapon_slot 
узнать слот оружия по его ID 
Говорю сразу, есть функции, которые вам покажутся пабликовскими и т.д., но писал я их сам лично, используя лишь сборку моделек, т.к. у меня небыло инета 2 недели)

Важно:

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(playeridold_weaponnew_weapon);
forward OnPlayerAmmoChange(playeridold_ammonew_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) == || 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(playeridammo_slot[playerid][weapon_slot(GetPlayerWeapon(playerid))], GetPlayerAmmo(playerid));
    }
}
public 
OnPlayerAmmoChange(playeridold_ammonew_ammo){//by Seregamil
    //  playerid - игрок, у которого сменились патроны в слоте
    //  old_ammo - прошлое кол-во патронов
    //  new_ammo - новое кол-во патронов
    
    
new str[128];
    
format(str,128,"{00ff00}OnPlayerAmmoChange: Игрок: %d | Оружие: %d (Слот: %d) | Старое значение: %d | Новое: %d",playeridGetPlayerWeapon(playerid), weapon_slot(GetPlayerWeapon(playerid)), old_ammonew_ammo);
    
SendClientMessageToAll(-1,str);
    
    
ammo_slot[playerid][weapon_slot(GetPlayerWeapon(playerid))] = new_ammo;
}
public 
OnPlayerWeaponChange(playeridold_weaponnew_weapon){//by Seregamil
    //    playerid - игрок, сменивший оружие
     //    old_weapon - оружие, которое сменили
    //  new_weapon - оружие, на которое сменили
    
new ammo_oldokda;
    
GetPlayerWeaponData(playeridweapon_slot(old_weapon), okdaammo_old);
    
giveAmmo(playeridold_weapon, -((getAmmo(playeridold_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(playeridcmdtext[])
{
    
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(playeridweaponidammo){//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,weaponidammo);
}
getAmmo(playeridweaponid){ //by Seregamil
    
new use_weap[100];
    
format(use_weap,100,"ac_weapon_%d",weapon_slot(weaponid));
    return 
GetPVarInt(playerid,use_weap);
}
giveAmmo(playeridweaponidammo){//by Seregamil
    
new use_weap[100];
    
format(use_weap,100,"ac_weapon_%d",weapon_slot(weaponid));
    
SetPVarInt(playerid,use_weap,GetPVarInt(playeriduse_weap)+ammo);
}
setAmmo(playerid,weaponidammo){//by Seregamil
    
new use_weap[100];
    
format(use_weap,100,"ac_weapon_%d",weapon_slot(weaponid));
    
SetPVarInt(playerid,use_weap,ammo);
    return 
SetPlayerAmmo(playerid,weaponidammo);
}
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);

При использовании данной системы следует заменить все GivePlayerWeapon | ResetPlayerWeapons | SetPlayerAmmo на giveWeapon | resetWeapons | setAmmo соответственно!

Автор: Seregamil
Reply


Messages In This Thread

Forum Jump:


Users browsing this thread: 3 Guest(s)