Fun (x) version 0.2
This commit is contained in:
parent
9dabd0cdc4
commit
3546840e92
658
dlls/fun/fun.cpp
Executable file
658
dlls/fun/fun.cpp
Executable file
|
@ -0,0 +1,658 @@
|
||||||
|
#include "fun.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
JGHG says:
|
||||||
|
|
||||||
|
Ok this is what I use below, it may probably not be right with all natives etc but I try to maintain this style to natives.
|
||||||
|
Note that this is still very much subject to change, regarding return values etc!
|
||||||
|
(Ok I haven't checked all natives that they comply with this yet, this is just a model I'm working on and which I might implement soon.)
|
||||||
|
|
||||||
|
static cell AMX_NATIVE_CALL nativename(AMX *amx, cell *params) // nativename(argument1, argument2); = 2 params
|
||||||
|
{
|
||||||
|
// Description what this native does. <--- Description what this native does
|
||||||
|
// params[1] = argument1 <--- Description of each argument, so we don't have to allocate new variables and can
|
||||||
|
// params[2] = argument2 <--- use the ones in params[n] directly, to save some time.
|
||||||
|
|
||||||
|
// Check receiver and sender validity. <--- Check ents, maybe need to do this better and more proper later?
|
||||||
|
if (params[1] < 1 || params[1] > gpGlobals->maxClients
|
||||||
|
|| params[2] < 1 || params[2] > gpGlobals->maxClients)
|
||||||
|
{
|
||||||
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE); <--- Call this, it will end up as RUN TIME ERROR 10 in server console.
|
||||||
|
return -1; <--- Standard return -1 with run time errors?
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1 <--- If native succeeded, return 1, if the native isn't supposed to return a specific value.
|
||||||
|
Note: Should be able to do: if (thenative()) and it should return false when it fails, and true when succeeds... is -1 treated as false, or is 0 a must?
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static cell AMX_NATIVE_CALL get_client_listening(AMX *amx, cell *params) // get_client_listening(receiver, sender); = 2 params
|
||||||
|
{
|
||||||
|
// Gets who can listen to who.
|
||||||
|
// params[1] = receiver
|
||||||
|
// params[2] = sender
|
||||||
|
|
||||||
|
// Check receiver and sender validity.
|
||||||
|
if (params[1] < 1 || params[1] > gpGlobals->maxClients
|
||||||
|
|| params[2] < 1 || params[2] > gpGlobals->maxClients)
|
||||||
|
{
|
||||||
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET- AND SETCLIENTLISTENING returns "qboolean", an int, probably 0 or 1...
|
||||||
|
return GETCLIENTLISTENING(params[1], params[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell AMX_NATIVE_CALL set_client_listening(AMX *amx, cell *params) // set_client_listening(receiver, sender, listen); = 3 params
|
||||||
|
{
|
||||||
|
// Sets who can listen to who.
|
||||||
|
// params[1] = receiver
|
||||||
|
// params[2] = sender
|
||||||
|
// params[3] = listen
|
||||||
|
|
||||||
|
// Check receiver and sender validity.
|
||||||
|
if (params[1] < 1 || params[1] > gpGlobals->maxClients
|
||||||
|
|| params[2] < 1 || params[2] > gpGlobals->maxClients)
|
||||||
|
{
|
||||||
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make a check on params[3] here later, and call run time error when it's wrong.
|
||||||
|
// To do: find out the possible values to set (0, 1?)
|
||||||
|
|
||||||
|
// GET- AND SETCLIENTLISTENING returns "qboolean", an int, probably 0 or 1...
|
||||||
|
return SETCLIENTLISTENING(params[1], params[2], params[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell AMX_NATIVE_CALL set_user_godmode(AMX *amx, cell *params) // set_user_godmode(index, godmode = 0); = 2 params
|
||||||
|
{
|
||||||
|
/* Sets player godmode. If you want to disable godmode set only first parameter. */
|
||||||
|
// params[1] = index
|
||||||
|
// params[2] = godmode = 0
|
||||||
|
|
||||||
|
// Check index.
|
||||||
|
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
||||||
|
{
|
||||||
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get player pointer.
|
||||||
|
edict_t *pPlayer = INDEXENT(params[1]);
|
||||||
|
|
||||||
|
// HERE: ADD PROPER CHECKING OF pPlayer LATER
|
||||||
|
|
||||||
|
if (params[2] == 1) {
|
||||||
|
// Enable godmode
|
||||||
|
pPlayer->v.takedamage = 0.0; // 0.0, the player doesn't seem to be able to get hurt.
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Disable godmode
|
||||||
|
pPlayer->v.takedamage = 2.0; // 2.0 seems to be standard value?
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell AMX_NATIVE_CALL get_user_godmode(AMX *amx, cell *params) // get_user_godmode(index); = 1 param
|
||||||
|
{
|
||||||
|
/* Returns 1 if godmode is set. */
|
||||||
|
// params[1] = index
|
||||||
|
|
||||||
|
// Check index.
|
||||||
|
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
||||||
|
{
|
||||||
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get player pointer.
|
||||||
|
edict_t *pPlayer = INDEXENT(params[1]);
|
||||||
|
|
||||||
|
// HERE: ADD PROPER CHECKING OF pPlayer LATER
|
||||||
|
|
||||||
|
int godmode = 0;
|
||||||
|
|
||||||
|
if (pPlayer->v.takedamage == 0.0) {
|
||||||
|
// God mode is enabled
|
||||||
|
godmode = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return godmode;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell AMX_NATIVE_CALL give_item(AMX *amx, cell *params) // native give_item(index, const item[]); = 2 params
|
||||||
|
{
|
||||||
|
/* Gives item to player, name of item can start
|
||||||
|
* with weapon_, ammo_ and item_. This event
|
||||||
|
* is announced with proper message to all players. */
|
||||||
|
// params[1] = index
|
||||||
|
// params[2] = item...
|
||||||
|
|
||||||
|
// Check index.
|
||||||
|
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
||||||
|
{
|
||||||
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get player pointer.
|
||||||
|
edict_t *pPlayer = INDEXENT(params[1]);
|
||||||
|
|
||||||
|
// Create item entity pointer
|
||||||
|
edict_t *pItemEntity;
|
||||||
|
|
||||||
|
// Make an "intstring" out of 2nd parameter
|
||||||
|
int length;
|
||||||
|
char *szItem = GET_AMXSTRING(amx, params[2], 1, length);
|
||||||
|
|
||||||
|
int item = MAKE_STRING(szItem);
|
||||||
|
|
||||||
|
// Create the entity, returns to pointer
|
||||||
|
pItemEntity = CREATE_NAMED_ENTITY(item);
|
||||||
|
|
||||||
|
// Check entity validity
|
||||||
|
if (FNullEnt(pItemEntity))
|
||||||
|
{
|
||||||
|
ALERT(at_console, "NULL Ent in GiveNamedItem!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
VARS(pItemEntity)->origin = VARS(pPlayer)->origin; // nice to do VARS(ent)->origin instead of ent->v.origin? :-I
|
||||||
|
pItemEntity->v.spawnflags |= SF_NORESPAWN;
|
||||||
|
|
||||||
|
MDLL_Spawn(pItemEntity);
|
||||||
|
MDLL_Touch(pItemEntity, ENT(pPlayer)); // unnecessary to do ENT(pPlayer) maybe, could've just used params[1] perhaps???
|
||||||
|
|
||||||
|
// HERE: ADD PROPER CHECKING OF pPlayer LATER
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell AMX_NATIVE_CALL spawn(AMX *amx, cell *params) // spawn(id) = 1 param
|
||||||
|
{
|
||||||
|
// Spawns an entity, this can be a user/player -> spawns at spawnpoints, or created entities seems to need this as a final "kick" into the game? :-)
|
||||||
|
// params[1] = entity to spawn
|
||||||
|
|
||||||
|
if (params[1] < 1 || params[1] > gpGlobals->maxEntities)
|
||||||
|
{
|
||||||
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
edict_t *pEnt = INDEXENT(params[1]);
|
||||||
|
|
||||||
|
MDLL_Spawn(pEnt);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell AMX_NATIVE_CALL set_user_money(AMX *amx, cell *params) // set_user_money(index, money, flash = 1); = 3 arguments
|
||||||
|
{
|
||||||
|
// Give money to user
|
||||||
|
// params[1] = user
|
||||||
|
// params[2] = money
|
||||||
|
// params[3] = flash money? (NYI)
|
||||||
|
|
||||||
|
// Check index
|
||||||
|
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
||||||
|
{
|
||||||
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch player pointer
|
||||||
|
edict_t *pPlayer = INDEXENT(params[1]);
|
||||||
|
|
||||||
|
// Give money
|
||||||
|
(int)*((int *)pPlayer->pvPrivateData + CSMONEYOFFSET) = params[2];
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell AMX_NATIVE_CALL get_user_money(AMX *amx, cell *params) // get_user_money(index); = 1 argument
|
||||||
|
{
|
||||||
|
// Give money to user
|
||||||
|
// params[1] = user
|
||||||
|
|
||||||
|
// Check index
|
||||||
|
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
||||||
|
{
|
||||||
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch player pointer
|
||||||
|
edict_t *pPlayer = INDEXENT(params[1]);
|
||||||
|
|
||||||
|
// Return money
|
||||||
|
return (int)*((int *)pPlayer->pvPrivateData + CSMONEYOFFSET);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell AMX_NATIVE_CALL set_user_deaths_cs(AMX *amx, cell *params) // set_user_deaths_cs(index, newdeaths); = 2 arguments
|
||||||
|
{
|
||||||
|
// Sets user deaths in cs.
|
||||||
|
// params[1] = user
|
||||||
|
// params[2] = new deaths
|
||||||
|
|
||||||
|
// Check index
|
||||||
|
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
||||||
|
{
|
||||||
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch player pointer
|
||||||
|
edict_t *pPlayer = INDEXENT(params[1]);
|
||||||
|
|
||||||
|
// Set deaths
|
||||||
|
(int)*((int *)pPlayer->pvPrivateData + CSDEATHSOFFSET) = params[2];
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell AMX_NATIVE_CALL set_user_health(AMX *amx, cell *params) // set_user_health(index, health); = 2 arguments
|
||||||
|
{
|
||||||
|
// Sets user health. If health is 0 and below, also kill...
|
||||||
|
// params[1] = index
|
||||||
|
// params[2] = health
|
||||||
|
|
||||||
|
// Check index
|
||||||
|
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
||||||
|
{
|
||||||
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch player pointer
|
||||||
|
edict_t *pPlayer = INDEXENT(params[1]);
|
||||||
|
|
||||||
|
|
||||||
|
if (FNullEnt(pPlayer)) {
|
||||||
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kill if health too low.
|
||||||
|
if (params[2] > 0)
|
||||||
|
pPlayer->v.health = float(params[2]);
|
||||||
|
else
|
||||||
|
MDLL_ClientKill(pPlayer);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell AMX_NATIVE_CALL set_user_frags(AMX *amx, cell *params) // set_user_frags(index, frags); = 2 arguments
|
||||||
|
{
|
||||||
|
// Sets user frags.
|
||||||
|
// params[1] = index
|
||||||
|
// params[2] = frags
|
||||||
|
|
||||||
|
// Check index
|
||||||
|
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
||||||
|
{
|
||||||
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch player pointer
|
||||||
|
edict_t *pPlayer = INDEXENT(params[1]);
|
||||||
|
|
||||||
|
if (FNullEnt(pPlayer)) {
|
||||||
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pPlayer->v.frags = params[2];
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell AMX_NATIVE_CALL set_user_armor(AMX *amx, cell *params) // set_user_armor(index, armor); = 2 arguments
|
||||||
|
{
|
||||||
|
// Sets user armor.
|
||||||
|
// params[1] = index
|
||||||
|
// params[2] = armor
|
||||||
|
|
||||||
|
// Check index
|
||||||
|
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
||||||
|
{
|
||||||
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch player pointer
|
||||||
|
edict_t *pPlayer = INDEXENT(params[1]);
|
||||||
|
|
||||||
|
if (FNullEnt(pPlayer)) {
|
||||||
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pPlayer->v.armorvalue = params[2];
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell AMX_NATIVE_CALL set_user_origin(AMX *amx, cell *params) // set_user_origin(index, origin[3]); = 2 arguments
|
||||||
|
{
|
||||||
|
// Sets user origin.
|
||||||
|
// params[1] = index
|
||||||
|
// params[2] = origin
|
||||||
|
|
||||||
|
// Check index
|
||||||
|
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
||||||
|
{
|
||||||
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch player pointer
|
||||||
|
edict_t *pPlayer = INDEXENT(params[1]);
|
||||||
|
|
||||||
|
if (FNullEnt(pPlayer)) {
|
||||||
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cell *newVectorCell = GET_AMXADDR(amx, params[3]);
|
||||||
|
|
||||||
|
float newX = *(float *)((void *)&newVectorCell[0]); // JGHG: I cast a spell on you.....
|
||||||
|
float newY = *(float *)((void *)&newVectorCell[1]);
|
||||||
|
float newZ = *(float *)((void *)&newVectorCell[2]);
|
||||||
|
|
||||||
|
Vector newVector = Vector(newX, newY, newZ);
|
||||||
|
|
||||||
|
SET_SIZE(pPlayer, pPlayer->v.mins, pPlayer->v.maxs);
|
||||||
|
SET_ORIGIN(pPlayer, newVector);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell AMX_NATIVE_CALL set_user_rendering(AMX *amx, cell *params) // set_user_rendering(index, fx = kRenderFxNone, r = 255, g = 255, b = 255, render = kRenderNormal, amount = 16); = 7 arguments
|
||||||
|
{
|
||||||
|
// Sets user rendering.
|
||||||
|
// params[1] = index
|
||||||
|
// params[2] = fx
|
||||||
|
// params[3] = r
|
||||||
|
// params[4] = g
|
||||||
|
// params[5] = b
|
||||||
|
// params[6] = render
|
||||||
|
// params[7] = amount
|
||||||
|
|
||||||
|
// Check index
|
||||||
|
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
||||||
|
{
|
||||||
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch player pointer
|
||||||
|
edict_t *pPlayer = INDEXENT(params[1]);
|
||||||
|
|
||||||
|
if (FNullEnt(pPlayer)) {
|
||||||
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pPlayer->v.renderfx = params[2];
|
||||||
|
Vector newVector = Vector(float(params[3]), float(params[4]), float(params[5]));
|
||||||
|
pPlayer->v.rendercolor = newVector;
|
||||||
|
pPlayer->v.rendermode = params[6];
|
||||||
|
pPlayer->v.renderamt = params[7];
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static cell AMX_NATIVE_CALL set_user_maxspeed(AMX *amx, cell *params) // set_user_maxspeed(index, Float:speed = -1.0) = 2 arguments
|
||||||
|
{
|
||||||
|
// Sets user maxspeed.
|
||||||
|
// params[1] = index
|
||||||
|
// params[2] = speed (should be -1.0 if not specified) (JGHG: unspecified parameters seems to always be -1.0!)
|
||||||
|
|
||||||
|
// Check index
|
||||||
|
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
||||||
|
{
|
||||||
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch player pointer
|
||||||
|
edict_t *pPlayer = INDEXENT(params[1]);
|
||||||
|
|
||||||
|
if (FNullEnt(pPlayer)) {
|
||||||
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pPlayer->v.maxspeed = *(float *)((void *)¶ms[2]); // JGHG: Gotta love the way to get floats from parameters :-P
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell AMX_NATIVE_CALL get_user_maxspeed(AMX *amx, cell *params) // Float:get_user_maxspeed(index) = 1 argument
|
||||||
|
{
|
||||||
|
// Gets user maxspeed.
|
||||||
|
// params[1] = index
|
||||||
|
|
||||||
|
// Check index
|
||||||
|
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
||||||
|
{
|
||||||
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch player pointer
|
||||||
|
edict_t *pPlayer = INDEXENT(params[1]);
|
||||||
|
|
||||||
|
if (FNullEnt(pPlayer)) {
|
||||||
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *(cell*)((void *)&(pPlayer->v.maxspeed)); // The way to return floats... (sigh)
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell AMX_NATIVE_CALL set_user_gravity(AMX *amx, cell *params) // set_user_gravity(index, Float:gravity = 1.0) = 2 arguments
|
||||||
|
{
|
||||||
|
// Sets user gravity.
|
||||||
|
// params[1] = index
|
||||||
|
// params[2] = gravity (=-1.0)
|
||||||
|
// Check index
|
||||||
|
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
||||||
|
{
|
||||||
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch player pointer
|
||||||
|
edict_t *pPlayer = INDEXENT(params[1]);
|
||||||
|
|
||||||
|
if (FNullEnt(pPlayer)) {
|
||||||
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pPlayer->v.gravity = *(float *)((void *)¶ms[2]); // JGHG: Gotta love the way to get floats from parameters :-P
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell AMX_NATIVE_CALL get_user_gravity(AMX *amx, cell *params) // Float:get_user_gravity(index) = 1 argument
|
||||||
|
{
|
||||||
|
// Gets user gravity.
|
||||||
|
// params[1] = index
|
||||||
|
|
||||||
|
// Check index
|
||||||
|
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
||||||
|
{
|
||||||
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch player pointer
|
||||||
|
edict_t *pPlayer = INDEXENT(params[1]);
|
||||||
|
|
||||||
|
if (FNullEnt(pPlayer)) {
|
||||||
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *(cell*)((void *)&(pPlayer->v.gravity)); // The way to return floats... (sigh)
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell AMX_NATIVE_CALL set_hitzones(AMX *amx, cell *params) // set_hitzones(body = 255) = 1 argument
|
||||||
|
{
|
||||||
|
// Gets user gravity.
|
||||||
|
// params[1] = body hitzones
|
||||||
|
|
||||||
|
LOG_CONSOLE(PLID, "body is %d", params[1]);
|
||||||
|
// Fetch player pointer
|
||||||
|
g_body = params[1];
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell AMX_NATIVE_CALL get_hitzones(AMX *amx, cell *params) // get_hitzones() = 0 arguments
|
||||||
|
{
|
||||||
|
// Gets hitzones.
|
||||||
|
return g_body;
|
||||||
|
}
|
||||||
|
|
||||||
|
AMX_NATIVE_INFO fun_Exports[] = {
|
||||||
|
{"get_client_listen", get_client_listening},
|
||||||
|
{"set_client_listen", set_client_listening},
|
||||||
|
{"set_user_godmode", set_user_godmode},
|
||||||
|
{"get_user_godmode", get_user_godmode},
|
||||||
|
{"set_user_health", set_user_health},
|
||||||
|
{"give_item", give_item},
|
||||||
|
{"spawn", spawn},
|
||||||
|
{"user_spawn", spawn}, // No, it's not a typo! Uses the same as "spawn", because they do the same stuff! This is made only to maintain comp. with old plugins!
|
||||||
|
{"set_user_money", set_user_money},
|
||||||
|
{"get_user_money", get_user_money},
|
||||||
|
{"set_user_deaths_cs", set_user_deaths_cs},
|
||||||
|
{"set_user_frags", set_user_frags},
|
||||||
|
{"set_user_armor", set_user_armor},
|
||||||
|
{"set_user_origin", set_user_origin},
|
||||||
|
{"set_user_rendering", set_user_rendering},
|
||||||
|
{"set_user_maxspeed", set_user_maxspeed},
|
||||||
|
{"get_user_maxspeed", get_user_maxspeed},
|
||||||
|
{"set_user_gravity", set_user_gravity},
|
||||||
|
{"get_user_gravity", get_user_gravity},
|
||||||
|
{"set_hitzones", set_hitzones},
|
||||||
|
{"get_hitzones", get_hitzones},
|
||||||
|
/////////////////// <--- 19 chars max in current small version
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************************/
|
||||||
|
|
||||||
|
void TraceLine(const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr)
|
||||||
|
{
|
||||||
|
if (g_body == 255) {
|
||||||
|
RETURN_META(MRES_IGNORED);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
TRACE_LINE(v1, v2, fNoMonsters, pentToSkip, ptr);
|
||||||
|
|
||||||
|
if ( !(g_body & (1 << ptr->iHitgroup)) )
|
||||||
|
ptr->flFraction = 1.0;
|
||||||
|
|
||||||
|
// pentToSkip seems to be the user that is aiming (shooting), so it doesn't accidentally hit himself?
|
||||||
|
|
||||||
|
RETURN_META(MRES_SUPERCEDE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enginefuncs_t meta_engfuncs;
|
||||||
|
C_DLLEXPORT int GetEngineFunctions(enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion ) {
|
||||||
|
meta_engfuncs.pfnTraceLine = TraceLine;
|
||||||
|
memcpy(pengfuncsFromEngine, &meta_engfuncs, sizeof(enginefuncs_t));
|
||||||
|
return(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************************/
|
||||||
|
|
||||||
|
C_DLLEXPORT int Meta_Query(char *ifvers, plugin_info_t **pPlugInfo, mutil_funcs_t *pMetaUtilFuncs) {
|
||||||
|
*pPlugInfo = &Plugin_info;
|
||||||
|
gpMetaUtilFuncs = pMetaUtilFuncs;
|
||||||
|
|
||||||
|
return(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, meta_globals_t *pMGlobals, gamedll_funcs_t *pGamedllFuncs) {
|
||||||
|
if(!pMGlobals) {
|
||||||
|
LOG_ERROR(PLID, "Meta_Attach called with null pMGlobals");
|
||||||
|
return(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
gpMetaGlobals = pMGlobals;
|
||||||
|
|
||||||
|
if(!pFunctionTable) {
|
||||||
|
LOG_ERROR(PLID, "Meta_Attach called with null pFunctionTable");
|
||||||
|
return(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(pFunctionTable, &gMetaFunctionTable, sizeof(META_FUNCTIONS));
|
||||||
|
gpGamedllFuncs = pGamedllFuncs;
|
||||||
|
|
||||||
|
|
||||||
|
// JGHG added stuff below
|
||||||
|
g_body = (1<<HITGROUP_GENERIC) | (1<<HITGROUP_HEAD) | (1<<HITGROUP_CHEST) | (1<<HITGROUP_STOMACH) | (1<<HITGROUP_LEFTARM) | (1<<HITGROUP_RIGHTARM)| (1<<HITGROUP_LEFTLEG) | (1<<HITGROUP_RIGHTLEG); // init hs_body
|
||||||
|
// generic is needed or bots go crazy... don't know what its for otherwise. You can still kill people.
|
||||||
|
// these hitzones never affect CS knife? ie you can always hit with knife no matter what you set here
|
||||||
|
//hs_body = (1<<HITGROUP_GENERIC) | (1<<HITGROUP_LEFTLEG) | (1<<HITGROUP_LEFTARM); // init hs_body
|
||||||
|
// JGHG added stuff above
|
||||||
|
|
||||||
|
/*
|
||||||
|
#define HITGROUP_GENERIC 0 // none
|
||||||
|
#define HITGROUP_HEAD 1
|
||||||
|
#define HITGROUP_CHEST 2
|
||||||
|
#define HITGROUP_STOMACH 3
|
||||||
|
#define HITGROUP_LEFTARM 4
|
||||||
|
#define HITGROUP_RIGHTARM 5
|
||||||
|
#define HITGROUP_LEFTLEG 6
|
||||||
|
#define HITGROUP_RIGHTLEG 7
|
||||||
|
*/
|
||||||
|
|
||||||
|
LOG_CONSOLE(PLID, "!!!!!!!!!!!!!!!!g_body is originally %d", g_body);
|
||||||
|
|
||||||
|
return(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
C_DLLEXPORT int Meta_Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason) {
|
||||||
|
if(now && reason) {
|
||||||
|
return(TRUE);
|
||||||
|
} else {
|
||||||
|
return(FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WINAPI GiveFnptrsToDll( enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals ) {
|
||||||
|
memcpy(&g_engfuncs, pengfuncsFromEngine, sizeof(enginefuncs_t));
|
||||||
|
gpGlobals = pGlobals;
|
||||||
|
}
|
||||||
|
|
||||||
|
C_DLLEXPORT int AMX_Query(module_info_s** info) {
|
||||||
|
*info = &module_info;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
C_DLLEXPORT int AMX_Attach(pfnamx_engine_g* amxeng,pfnmodule_engine_g* meng) {
|
||||||
|
g_engAmxFunc = amxeng;
|
||||||
|
g_engModuleFunc = meng;
|
||||||
|
|
||||||
|
if(!gpMetaGlobals) REPORT_ERROR(1, "[AMX] fun is not attached to metamod (module \"%s\")\n", LOGTAG);
|
||||||
|
|
||||||
|
ADD_AMXNATIVES(&module_info, fun_Exports);
|
||||||
|
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
C_DLLEXPORT int AMX_Detach() {
|
||||||
|
return(1);
|
||||||
|
}
|
10
dlls/fun/fun.def
Executable file
10
dlls/fun/fun.def
Executable file
|
@ -0,0 +1,10 @@
|
||||||
|
LIBRARY fun
|
||||||
|
EXPORTS
|
||||||
|
GiveFnptrsToDll @1
|
||||||
|
Meta_Attach @2
|
||||||
|
Meta_Detach @3
|
||||||
|
Meta_Query @4
|
||||||
|
AMX_Attach @5
|
||||||
|
AMX_Detach @7
|
||||||
|
SECTIONS
|
||||||
|
.data READ WRITE
|
121
dlls/fun/fun.dsp
Executable file
121
dlls/fun/fun.dsp
Executable file
|
@ -0,0 +1,121 @@
|
||||||
|
# Microsoft Developer Studio Project File - Name="fun" - Package Owner=<4>
|
||||||
|
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||||
|
# ** DO NOT EDIT **
|
||||||
|
|
||||||
|
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||||
|
|
||||||
|
CFG=fun - Win32 Debug
|
||||||
|
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||||
|
!MESSAGE use the Export Makefile command and run
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE NMAKE /f "fun.mak".
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE You can specify a configuration when running NMAKE
|
||||||
|
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE NMAKE /f "fun.mak" CFG="fun - Win32 Debug"
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE Possible choices for configuration are:
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE "fun - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||||
|
!MESSAGE "fun - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||||
|
!MESSAGE
|
||||||
|
|
||||||
|
# Begin Project
|
||||||
|
# PROP AllowPerConfigDependencies 0
|
||||||
|
# PROP Scc_ProjName ""
|
||||||
|
# PROP Scc_LocalPath ""
|
||||||
|
CPP=cl.exe
|
||||||
|
MTL=midl.exe
|
||||||
|
RSC=rc.exe
|
||||||
|
|
||||||
|
!IF "$(CFG)" == "fun - Win32 Release"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 0
|
||||||
|
# PROP BASE Output_Dir "Release"
|
||||||
|
# PROP BASE Intermediate_Dir "Release"
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 0
|
||||||
|
# PROP Output_Dir "Release"
|
||||||
|
# PROP Intermediate_Dir "Release"
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FUN_EXPORTS" /YX /FD /c
|
||||||
|
# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FUN_EXPORTS" /FR /YX /FD /c
|
||||||
|
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
|
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
|
# ADD BASE RSC /l 0x41d /d "NDEBUG"
|
||||||
|
# ADD RSC /l 0x41d /d "NDEBUG"
|
||||||
|
BSC32=bscmake.exe
|
||||||
|
# ADD BASE BSC32 /nologo
|
||||||
|
# ADD BSC32 /nologo
|
||||||
|
LINK32=link.exe
|
||||||
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||||
|
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||||
|
# Begin Special Build Tool
|
||||||
|
SOURCE="$(InputPath)"
|
||||||
|
PostBuild_Cmds=echo Copying dll... copy Release\fun.dll K:\S\cstrike\addons\amx\dlls\fun_mm.dll echo Copying inc... copy fun.inc K:\S\cstrike\addons\amx\examples\include copy fun.inc K:\S\cstrike\addons\amx\plugins\include
|
||||||
|
# End Special Build Tool
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "fun - Win32 Debug"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 1
|
||||||
|
# PROP BASE Output_Dir "Debug"
|
||||||
|
# PROP BASE Intermediate_Dir "Debug"
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 1
|
||||||
|
# PROP Output_Dir "Debug"
|
||||||
|
# PROP Intermediate_Dir "Debug"
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FUN_EXPORTS" /YX /FD /GZ /c
|
||||||
|
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FUN_EXPORTS" /FR /YX /FD /GZ /c
|
||||||
|
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
|
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
|
# ADD BASE RSC /l 0x41d /d "_DEBUG"
|
||||||
|
# ADD RSC /l 0x41d /d "_DEBUG"
|
||||||
|
BSC32=bscmake.exe
|
||||||
|
# ADD BASE BSC32 /nologo
|
||||||
|
# ADD BSC32 /nologo
|
||||||
|
LINK32=link.exe
|
||||||
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||||
|
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||||
|
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Begin Target
|
||||||
|
|
||||||
|
# Name "fun - Win32 Release"
|
||||||
|
# Name "fun - Win32 Debug"
|
||||||
|
# Begin Group "Source Files"
|
||||||
|
|
||||||
|
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\fun.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\fun.def
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Header Files"
|
||||||
|
|
||||||
|
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\fun.h
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Resource Files"
|
||||||
|
|
||||||
|
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||||
|
# End Group
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\fun.inc
|
||||||
|
# End Source File
|
||||||
|
# End Target
|
||||||
|
# End Project
|
29
dlls/fun/fun.dsw
Executable file
29
dlls/fun/fun.dsw
Executable file
|
@ -0,0 +1,29 @@
|
||||||
|
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||||
|
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
Project: "fun"=".\fun.dsp" - Package Owner=<4>
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<4>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
Global:
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<3>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
80
dlls/fun/fun.h
Executable file
80
dlls/fun/fun.h
Executable file
|
@ -0,0 +1,80 @@
|
||||||
|
// FUN MODULE TO DO HERE: http://www.amxmod.info/forums/viewtopic.php?t=37
|
||||||
|
//#define FUN_LINUX // UNCOMMENT WHEN COMPILING FOR LINUX, OR PDATA OFFSETS WILL CRASH SERVER
|
||||||
|
|
||||||
|
#include <extdll.h>
|
||||||
|
#include <meta_api.h>
|
||||||
|
#include "amx/modules.h"
|
||||||
|
|
||||||
|
// Check later if all of these really are needed!
|
||||||
|
meta_globals_t *gpMetaGlobals; // Variables provided to plugins.
|
||||||
|
gamedll_funcs_t *gpGamedllFuncs; // Pair of function tables provided by game DLL.
|
||||||
|
mutil_funcs_t *gpMetaUtilFuncs; // Meta Utility Function table type.
|
||||||
|
enginefuncs_t g_engfuncs; // Engine hands this to DLLs for functionality callbacks
|
||||||
|
globalvars_t *gpGlobals; // JGHG says: contains info on server, like maxclients, (time?) etc, stringbase is here :-) seems to be used with entity classnames...
|
||||||
|
|
||||||
|
// Must provide at least one of these...
|
||||||
|
static META_FUNCTIONS gMetaFunctionTable = {
|
||||||
|
NULL, // pfnGetEntityAPI HL SDK; called before game DLL
|
||||||
|
NULL, // pfnGetEntityAPI_Post META; called after game DLL
|
||||||
|
NULL, // pfnGetEntityAPI2 HL SDK2; called before game DLL
|
||||||
|
NULL, // pfnGetEntityAPI2_Post META; called after game DLL
|
||||||
|
NULL, // pfnGetNewDLLFunctions HL SDK2; called before game DLL
|
||||||
|
NULL, // pfnGetNewDLLFunctions_Post META; called after game DLL
|
||||||
|
GetEngineFunctions, // pfnGetEngineFunctions META; called before HL engine
|
||||||
|
NULL // pfnGetEngineFunctions_Post META; called after HL engine
|
||||||
|
};
|
||||||
|
|
||||||
|
pfnamx_engine_g* g_engAmxFunc; // These seem to be meta/amxmod related
|
||||||
|
pfnmodule_engine_g* g_engModuleFunc; // These seem to be meta/amxmod related
|
||||||
|
|
||||||
|
#define NAME "fun"
|
||||||
|
#define AUTHOR "JGHG"
|
||||||
|
#define VERSION "0.2"
|
||||||
|
#define URL "http://?"
|
||||||
|
#define LOGTAG "fun"
|
||||||
|
#define DATE __DATE__
|
||||||
|
|
||||||
|
// Fun-specific defines below
|
||||||
|
#define GETCLIENTLISTENING (*g_engfuncs.pfnVoice_GetClientListening)
|
||||||
|
#define SETCLIENTLISTENING (*g_engfuncs.pfnVoice_SetClientListening)
|
||||||
|
#define SF_NORESPAWN ( 1 << 30 )// !!!set this bit on guns and stuff that should never respawn.
|
||||||
|
|
||||||
|
#if defined FUN_LINUX
|
||||||
|
#define CSMONEYOFFSET 115 + 5
|
||||||
|
#define CSDEATHSOFFSET 449 + 5
|
||||||
|
#else
|
||||||
|
#define CSMONEYOFFSET 115 // Note that linux offsets need to be 5 higher (120 in this case)
|
||||||
|
#define CSDEATHSOFFSET 449
|
||||||
|
#endif // defined LINUX
|
||||||
|
|
||||||
|
#define HITGROUP_GENERIC 0 // none
|
||||||
|
#define HITGROUP_HEAD 1
|
||||||
|
#define HITGROUP_CHEST 2
|
||||||
|
#define HITGROUP_STOMACH 3
|
||||||
|
#define HITGROUP_LEFTARM 4
|
||||||
|
#define HITGROUP_RIGHTARM 5
|
||||||
|
#define HITGROUP_LEFTLEG 6
|
||||||
|
#define HITGROUP_RIGHTLEG 7
|
||||||
|
// Fun-specific defines above
|
||||||
|
|
||||||
|
// Globals below
|
||||||
|
plugin_info_t Plugin_info = {
|
||||||
|
META_INTERFACE_VERSION,
|
||||||
|
NAME,
|
||||||
|
VERSION,
|
||||||
|
DATE,
|
||||||
|
AUTHOR,
|
||||||
|
URL,
|
||||||
|
LOGTAG,
|
||||||
|
PT_ANYTIME,
|
||||||
|
PT_ANYTIME,
|
||||||
|
};
|
||||||
|
module_info_s module_info = {
|
||||||
|
NAME,
|
||||||
|
AUTHOR,
|
||||||
|
VERSION,
|
||||||
|
AMX_INTERFACE_VERSION,
|
||||||
|
RELOAD_MODULE,
|
||||||
|
};
|
||||||
|
int g_body = 0; // bits of parts of body to hit
|
||||||
|
// Globals above
|
Loading…
Reference in New Issue
Block a user