14.11.2012, 19:50
Hi, I'm trying to script a gamemode and obviously one of the very first things it needs is a basic script that detects forbidden weapons. I have made it as an include with ALS callback hooks. Also, I have intended to make it in a way that allows me a certain flexibility, so I can change what weapons are forbidden and what others aren't by just making small changes in the script and recompiling again. However, my doubt comes because I don't know if the way I have chosen to do this is a good one: what I have done is creating a boolean array with as many slots as weapons there are in the game, and in the OnGameModeInit hook I just set as true the array slots corresponding to the weapons I want to be forbidden. So my question is: is there a better way to do this, for example with defines or any other thing to do it in compile time instead of in execution time?
pawn Код:
#if defined _forbiddenweapons_included
#endinput
#endif
#define _forbiddenweapons_included
#include <a_samp>
#define fist 0
#define brass 1
#define golf 2
#define nightstick 3
#define knife 4
#define baseball 5
#define shovel 6
#define pool 7
#define katana 8
#define chainsaw 9
#define bigdildo 10
#define dildo 11
#define vibrator 12
#define vibrator2 13
#define flowers 14
#define cane 15
#define grenade 16
#define teargas 17
#define molotov 18
#define colt 22
#define silenced 23
#define deagle 24
#define shotgun 25
#define sawnoff 26
#define combat 27
#define uzi 28
#define mp5 29
#define ak47 30
#define m4 31
#define tec9 32
#define rifle 33
#define sniper 34
#define rocketlauncher 35
#define heatseeker 36
#define flamethrower 37
#define minigun 38
#define satchel 39
#define detonator 40
#define spray 41
#define extinguisher 42
#define camera 43
#define nightvision 44
#define thermal 45
#define parachute 46
#define vehiclehit 49
#define helikill 50
#define explosion 51
new stock bool:forbidden[55];
// This array determines if each weapon is forbidden or not. It has 55 slots because the last
// weapon id is 54, so in an array with 55 slots the last one is the number 54.
stock checkforbiddenattack(playerid, weaponid)
// This function is called in OnPlayerTakeDamage and in OnPlayerDeath. It's for things like
// helikill or car kill for example. It doesn't affect hacked weapons (like minigun)
// because they are already detected in OnPlayerUpdate, whereas this function is for ways
// of attacking that are not made with weapons that a player can hold and therefore can't
// be detected by OnPlayerUpdate.
{
if(forbidden[weaponid] == true)
{
Kick(playerid);
return 1;
}
return 0;
}
static gforwea_HasCB[3];
public OnGameModeInit()
{
// Here is where I set what weapons I want to be forbidden:
forbidden[minigun] = true;
forbidden[teargas] = true;
forbidden[heatseeker] = true;
forbidden[satchel] = true;
forbidden[detonator] = true;
forbidden[nightvision] = true;
forbidden[thermal] = true;
gforwea_HasCB[0] = funcidx("forwea_OnPlayerDeath") != -1;
gforwea_HasCB[1] = funcidx("forwea_OnPlayerTakeDamage") != -1;
gforwea_HasCB[2] = funcidx("forwea_OnPlayerUpdate") != -1;
if (funcidx("forwea_OnGameModeInit") != -1)
{
return CallLocalFunction("forwea_OnGameModeInit", "");
}
return 1;
}
#if defined _ALS_OnGameModeInit
#undef OnGameModeInit
#else
#define _ALS_OnGameModeInit
#endif
#define OnGameModeInit forwea_OnGameModeInit
forward forwea_OnGameModeInit();
public OnPlayerDeath(playerid, killerid, reason)
{
if(killerid != INVALID_PLAYER_ID)
// The victim has been killed by another player, not by suicide.
{
checkforbiddenattack(killerid, reason);
}
if (gforwea_HasCB[0])
{
return CallLocalFunction("forwea_OnPlayerDeath", "iii",playerid, killerid, reason);
}
return 1;
}
#if defined _ALS_OnPlayerDeath
#undef OnPlayerDeath
#else
#define _ALS_OnPlayerDeath
#endif
#define OnPlayerDeath forwea_OnPlayerDeath
forward forwea_OnPlayerDeath(playerid, killerid, reason);
public OnPlayerTakeDamage(playerid, issuerid, Float:amount, weaponid)
{
if(issuerid != INVALID_PLAYER_ID)
// The victim has been attacked by another player.
{
checkforbiddenattack(issuerid, weaponid);
}
if (gforwea_HasCB[1])
{
return CallLocalFunction("forwea_OnPlayerTakeDamage", "iifi",playerid, issuerid, Float:amount, weaponid);
}
return 1;
}
#if defined _ALS_OnPlayerTakeDamage
#undef OnPlayerTakeDamage
#else
#define _ALS_OnPlayerTakeDamage
#endif
#define OnPlayerTakeDamage forwea_OnPlayerTakeDamage
forward forwea_OnPlayerTakeDamage(playerid, issuerid, Float:amount, weaponid);
public OnPlayerUpdate(playerid)
{
if(forbidden[GetPlayerWeapon(playerid)] == true)
{
Kick(playerid);
}
if (gforwea_HasCB[2])
{
return CallLocalFunction("forwea_OnPlayerUpdate", "i",playerid);
}
return 1;
}
#if defined _ALS_OnPlayerUpdate
#undef OnPlayerUpdate
#else
#define _ALS_OnPlayerUpdate
#endif
#define OnPlayerUpdate forwea_OnPlayerUpdate
forward forwea_OnPlayerUpdate(playerid);