mirror of
https://github.com/alliedmodders/amxmodx.git
synced 2024-12-27 07:15:37 +03:00
568 lines
17 KiB
C++
568 lines
17 KiB
C++
|
/* AMX Mod X
|
||
|
* Sven Co-op Module
|
||
|
*
|
||
|
* by the AMX Mod X Development Team
|
||
|
*
|
||
|
* This file is part of AMX Mod X.
|
||
|
*
|
||
|
*
|
||
|
* This program is free software; you can redistribute it and/or modify it
|
||
|
* under the terms of the GNU General Public License as published by the
|
||
|
* Free Software Foundation; either version 2 of the License, or (at
|
||
|
* your option) any later version.
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful, but
|
||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
* General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this program; if not, write to the Free Software Foundation,
|
||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
|
*
|
||
|
* In addition, as a special exception, the author gives permission to
|
||
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||
|
* respects for all of the code used other than the HL Engine and MODs
|
||
|
* from Valve. If you modify this file, you may extend this exception
|
||
|
* to your version of the file, but you are not obligated to do so. If
|
||
|
* you do not wish to do so, delete this exception statement from your
|
||
|
* version.
|
||
|
*/
|
||
|
|
||
|
#include "svencoop.h"
|
||
|
|
||
|
//
|
||
|
// GLOBALS
|
||
|
//
|
||
|
|
||
|
const char g_weapon_names[24][24] =
|
||
|
{
|
||
|
"",
|
||
|
"weapon_crowbar",
|
||
|
"weapon_9mmhandgun",
|
||
|
"weapon_357",
|
||
|
"weapon_9mmAR",
|
||
|
"",
|
||
|
"weapon_crossbow",
|
||
|
"weapon_shotgun",
|
||
|
"weapon_rpg",
|
||
|
"weapon_gauss",
|
||
|
"weapon_egon",
|
||
|
"weapon_hornetgun",
|
||
|
"weapon_handgrenade",
|
||
|
"weapon_tripmine",
|
||
|
"weapon_satchel",
|
||
|
"weapon_snark",
|
||
|
"weapon_uziakimbo",
|
||
|
"weapon_uzi",
|
||
|
"weapon_medkit",
|
||
|
"weapon_crowbar_electric",
|
||
|
"weapon_pipewrench",
|
||
|
"weapon_minigun",
|
||
|
"weapon_grapple",
|
||
|
"weapon_sniperrifle"
|
||
|
};
|
||
|
|
||
|
const int g_ammo_offsets[25] =
|
||
|
{
|
||
|
-1, // NONE = 0
|
||
|
0, // SCW_CROWBAR = 1
|
||
|
OFFSET_9MM_AMMO, // SCW_9MMHANDGUN = 2
|
||
|
OFFSET_357_AMMO, // SCW_357 = 3
|
||
|
OFFSET_9MM_AMMO, // SCW_9MMAR = 4
|
||
|
-1, // NONE = 5
|
||
|
OFFSET_CROSSBOW_AMMO, // SCW_CROSSBOW = 6
|
||
|
OFFSET_SHOTGUN_AMMO, // SCW_SHOTGUN = 7
|
||
|
OFFSET_RPG_AMMO, // SCW_RPG = 8
|
||
|
OFFSET_ENERGY_AMMO, // SCW_GAUSS = 9
|
||
|
OFFSET_ENERGY_AMMO, // SCW_EGON = 10
|
||
|
OFFSET_HORNETGUN_AMMO, // SCW_HORNETGUN = 11
|
||
|
OFFSET_HANDGRENADE_AMMO,// SCW_HANDGRENADE = 12
|
||
|
OFFSET_TRIPMINE_AMMO, // SCW_TRIPMINE = 13
|
||
|
OFFSET_SATCHEL_AMMO, // SCW_SATCHEL = 14
|
||
|
OFFSET_SNARK_AMMO, // SCW_SNARK = 15
|
||
|
OFFSET_9MM_AMMO, // SCW_UZIAKIMBO = 16
|
||
|
OFFSET_9MM_AMMO, // SCW_UZI = 17
|
||
|
OFFSET_MEDKIT_AMMO, // SCW_MEDKIT = 18
|
||
|
0, // SCW_CROWBAR_ELECTRIC = 19
|
||
|
0, // SCW_PIPEWRENCH = 20
|
||
|
OFFSET_MINIGUN_AMMO, // SCW_MINIGUN = 21
|
||
|
0, // SCW_GRAPPLE = 22
|
||
|
OFFSET_SNIPERRIFLE_AMMO,// SCW_SNIPERRIFLE = 23
|
||
|
OFFSET_ARGRENADE_AMMO // SCW_ARGRENADE = 24
|
||
|
};
|
||
|
|
||
|
//
|
||
|
// MONSTER NATIVES
|
||
|
//
|
||
|
|
||
|
static cell AMX_NATIVE_CALL sc_get_frags(AMX *amx, cell *params) // sc_get_frags(index); = 1 arguments
|
||
|
{
|
||
|
// Gets a monster's or player's frags
|
||
|
// params[1] = monster/player index
|
||
|
|
||
|
// not CHECK_MONSTER because this works for players
|
||
|
CHECK_ENTITY(params[1]);
|
||
|
edict_t *pEdict = GETEDICT(params[1]);
|
||
|
|
||
|
if(!UTIL_IsPlayer(pEdict) && !UTIL_IsMonster(pEdict))
|
||
|
{
|
||
|
MF_LogError(amx, AMX_ERR_NATIVE, "Entity %d (\"%s\") is not a player or monster_* entity", params[1], STRING(pEdict->v.classname));
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return amx_ftoc(*((float *)pEdict->pvPrivateData + OFFSET_MONSTER_FRAGS));
|
||
|
}
|
||
|
|
||
|
static cell AMX_NATIVE_CALL sc_set_frags(AMX *amx, cell *params) // sc_set_frags(index, Float:value); = 2 arguments
|
||
|
{
|
||
|
// Sets a monster's or player's frags
|
||
|
// params[1] = index = monster/player index
|
||
|
// params[2] = (float) new frags
|
||
|
|
||
|
// not CHECK_MONSTER because this works for players
|
||
|
CHECK_ENTITY(params[1]);
|
||
|
edict_t *pEdict = GETEDICT(params[1]);
|
||
|
|
||
|
if(!UTIL_IsPlayer(pEdict) && !UTIL_IsMonster(pEdict))
|
||
|
{
|
||
|
MF_LogError(amx, AMX_ERR_NATIVE, "Entity %d (\"%s\") is not a player or monster_* entity", params[1], STRING(pEdict->v.classname));
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
float fValue = amx_ctof(params[2]);
|
||
|
*((float *)pEdict->pvPrivateData + OFFSET_MONSTER_FRAGS) = fValue;
|
||
|
|
||
|
if(UTIL_IsPlayer(pEdict))
|
||
|
{
|
||
|
pEdict->v.frags = fValue;
|
||
|
|
||
|
// update scoreboard
|
||
|
if(gmsgScoreInfo)
|
||
|
{
|
||
|
MESSAGE_BEGIN(MSG_ALL, gmsgScoreInfo);
|
||
|
WRITE_BYTE(params[1]);
|
||
|
WRITE_SHORT((int)fValue);
|
||
|
WRITE_SHORT(*((int *)pEdict->pvPrivateData + OFFSET_PLAYER_DEATHS));
|
||
|
MESSAGE_END();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static cell AMX_NATIVE_CALL sc_get_displayname(AMX *amx, cell *params) // sc_get_displayname(index, displayname[], len); = 3 arguments
|
||
|
{
|
||
|
// Gets a monster's displayname
|
||
|
// params[1] = monster index
|
||
|
// params[2] = return variable
|
||
|
// params[3] = variable len
|
||
|
|
||
|
// check non-player (could be squadmaker)
|
||
|
CHECK_NONPLAYER(params[1]);
|
||
|
edict_t *pEdict = INDEXENT(params[1]);
|
||
|
|
||
|
// check valid types
|
||
|
const char *classname = STRING(pEdict->v.classname);
|
||
|
if(strcmp(classname, "squadmaker") != 0 && strncmp(classname, "monster", 7) != 0)
|
||
|
{
|
||
|
MF_LogError(amx, AMX_ERR_NATIVE, "Entity %d (\"%s\") is not a monstermaker, squadmaker, or monster_* entity", params[1], classname);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// check for a custom one
|
||
|
const char *displayname = STRING(pEdict->v.message);
|
||
|
if(displayname[0])
|
||
|
{
|
||
|
MF_SetAmxString(amx, params[2], displayname, params[3]);
|
||
|
return 1; // 1 means custom displayname
|
||
|
}
|
||
|
|
||
|
// maybe from a monstermaker? use its displayname.
|
||
|
if(!strncmp(classname, "monster_", 8) && !FNullEnt(pEdict->v.owner))
|
||
|
{
|
||
|
const char *ownerclass = STRING(pEdict->v.owner->v.classname);
|
||
|
if(!strcmp(ownerclass, "squadmaker") || !strcmp(ownerclass, "monstermaker"))
|
||
|
{
|
||
|
displayname = STRING(pEdict->v.owner->v.message);
|
||
|
if(displayname[0])
|
||
|
{
|
||
|
return MF_SetAmxString(amx, params[2], displayname, params[3]);
|
||
|
return 1; // 1 means custom displayname
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
String *name = NULL;
|
||
|
|
||
|
if(*((int *)pEdict->pvPrivateData + OFFSET_MONSTER_ALLY))
|
||
|
name = g_allyNameTrie.Retrieve(classname, strlen(classname));
|
||
|
else
|
||
|
name = g_enemyNameTrie.Retrieve(classname, strlen(classname));
|
||
|
|
||
|
if(name != NULL)
|
||
|
{
|
||
|
MF_SetAmxString(amx, params[2], name->c_str(), params[3]);
|
||
|
return -1; // -1 means default displayname
|
||
|
}
|
||
|
|
||
|
return 0; // invalid monster
|
||
|
}
|
||
|
|
||
|
static cell AMX_NATIVE_CALL sc_set_displayname(AMX *amx, cell *params) // sc_set_displayname(index, displayname[], {Float,Sql,Result,_}:...); = 2 arguments
|
||
|
{
|
||
|
// Sets a monster's displayname
|
||
|
// params[1] = monster index
|
||
|
// params[2] = new displayname
|
||
|
// params[3...] = formatting
|
||
|
|
||
|
// check non-player (could be squadmaker)
|
||
|
CHECK_NONPLAYER(params[1]);
|
||
|
edict_t *pEdict = INDEXENT(params[1]);
|
||
|
|
||
|
// check valid types
|
||
|
const char *classname = STRING(pEdict->v.classname);
|
||
|
if(strcmp(classname, "squadmaker") != 0 && strncmp(classname, "monster", 7) != 0)
|
||
|
{
|
||
|
MF_LogError(amx, AMX_ERR_NATIVE, "Entity %d (\"%s\") is not a monstermaker, squadmaker, or monster_* entity", params[1], classname);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// fetch string
|
||
|
int len = 0;
|
||
|
char *displayname = MF_FormatAmxString(amx, params, 2, &len);
|
||
|
|
||
|
// set_kvd
|
||
|
KeyValueData *kvd = &g_kvd;
|
||
|
kvd->szClassName = const_cast<char *>(classname);
|
||
|
kvd->szKeyName = const_cast<char *>("displayname");
|
||
|
kvd->szValue = const_cast<char *>(displayname);
|
||
|
kvd->fHandled = 0;
|
||
|
gpGamedllFuncs->dllapi_table->pfnKeyValue(pEdict, kvd);
|
||
|
|
||
|
// remember it
|
||
|
pEdict->v.message = ALLOC_STRING(displayname);
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static cell AMX_NATIVE_CALL sc_is_player_ally(AMX *amx, cell *params) // sc_is_player_ally(index); = 1 arguments
|
||
|
{
|
||
|
// Checks if a monster is a player ally
|
||
|
// params[1] = monster index
|
||
|
|
||
|
CHECK_MONSTER(params[1]);
|
||
|
edict_t *pEdict = INDEXENT(params[1]);
|
||
|
|
||
|
return *((int *)pEdict->pvPrivateData + OFFSET_MONSTER_ALLY);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// PLAYER NATIVES
|
||
|
// (ammo excluded)
|
||
|
//
|
||
|
|
||
|
static cell AMX_NATIVE_CALL sc_get_user_longjump(AMX *amx, cell *params) // sc_get_user_longjump(index); = 1 arguments
|
||
|
{
|
||
|
// Checks if a player can longjump
|
||
|
// params[1] = player index
|
||
|
|
||
|
CHECK_PLAYER(params[1]);
|
||
|
edict_t *pEdict = MF_GetPlayerEdict(params[1]);
|
||
|
|
||
|
const char *buffer = (*g_engfuncs.pfnGetPhysicsKeyValue)(pEdict, "slj");
|
||
|
if(buffer[0] == '1') return 1;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static cell AMX_NATIVE_CALL sc_set_user_longjump(AMX *amx, cell *params) // sc_set_user_longjump(index, value); = 2 arguments
|
||
|
{
|
||
|
// Sets if a player can longjump
|
||
|
// params[1] = player index
|
||
|
// params[2] = new value
|
||
|
|
||
|
CHECK_PLAYER(params[1]);
|
||
|
edict_t *pEdict = MF_GetPlayerEdict(params[1]);
|
||
|
|
||
|
if(params[2]) (*g_engfuncs.pfnSetPhysicsKeyValue)(pEdict, "slj", "1");
|
||
|
else (*g_engfuncs.pfnSetPhysicsKeyValue)(pEdict, "slj", "0");
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static cell AMX_NATIVE_CALL sc_get_user_deaths(AMX *amx, cell *params) // sc_get_user_deaths(index); = 1 arguments
|
||
|
{
|
||
|
// Gets the number of times a player has died (duh!)
|
||
|
// params[1] = player index
|
||
|
|
||
|
CHECK_PLAYER(params[1]);
|
||
|
edict_t *pEdict = MF_GetPlayerEdict(params[1]);
|
||
|
|
||
|
return *((int *)pEdict->pvPrivateData + OFFSET_PLAYER_DEATHS);
|
||
|
}
|
||
|
|
||
|
static cell AMX_NATIVE_CALL sc_set_user_deaths(AMX *amx, cell *params) // sc_set_user_deaths(index, value); = 2 arguments
|
||
|
{
|
||
|
// Sets the number of times a player has died
|
||
|
// params[1] = player index
|
||
|
// params[2] = new death amount
|
||
|
|
||
|
CHECK_PLAYER(params[1]);
|
||
|
edict_t *pEdict = MF_GetPlayerEdict(params[1]);
|
||
|
|
||
|
*((int *)pEdict->pvPrivateData + OFFSET_PLAYER_DEATHS) = params[2];
|
||
|
|
||
|
// update scoreboard
|
||
|
if(gmsgScoreInfo)
|
||
|
{
|
||
|
MESSAGE_BEGIN(MSG_ALL, gmsgScoreInfo);
|
||
|
WRITE_BYTE(params[1]);
|
||
|
WRITE_SHORT((int)pEdict->v.frags);
|
||
|
WRITE_SHORT(params[2]);
|
||
|
MESSAGE_END();
|
||
|
}
|
||
|
|
||
|
*static_cast<int *>(MF_PlayerPropAddr(params[1], Player_Deaths)) = params[2];
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// AMMO NATIVES
|
||
|
//
|
||
|
|
||
|
static cell AMX_NATIVE_CALL sc_get_wbox_ammo(AMX *amx, cell *params) // sc_get_wbox_ammo(index); = 1 arguments
|
||
|
{
|
||
|
// Gets the amount of ammo in dropped ammo weaponbox
|
||
|
// params[1] = weaponbox entity index
|
||
|
|
||
|
CHECK_NONPLAYER(params[1]);
|
||
|
edict_t *pEdict = INDEXENT(params[1]);
|
||
|
|
||
|
if(strcmp(STRING(pEdict->v.classname), "weaponbox") != 0)
|
||
|
{
|
||
|
MF_LogError(amx, AMX_ERR_NATIVE, "Entity %d (\"%s\") is not a weaponbox entity", params[1], STRING(pEdict->v.classname));
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return *((int *)pEdict->pvPrivateData + OFFSET_WBOX_AMMO);
|
||
|
}
|
||
|
|
||
|
static cell AMX_NATIVE_CALL sc_set_wbox_ammo(AMX *amx, cell *params) // sc_set_wbox_ammo(index, value); = 1 arguments
|
||
|
{
|
||
|
// Sets the amount of ammo in dropped ammo weaponbox
|
||
|
// params[1] = weaponbox entity index
|
||
|
// params[2] = new ammo amount
|
||
|
|
||
|
CHECK_NONPLAYER(params[1]);
|
||
|
edict_t *pEdict = INDEXENT(params[1]);
|
||
|
|
||
|
if(strcmp(STRING(pEdict->v.classname), "weaponbox") != 0)
|
||
|
{
|
||
|
MF_LogError(amx, AMX_ERR_NATIVE, "Entity %d (\"%s\") is not a weaponbox entity", params[1], STRING(pEdict->v.classname));
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
*((int *)pEdict->pvPrivateData + OFFSET_WBOX_AMMO) = params[2];
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static cell AMX_NATIVE_CALL sc_get_weapon_id(AMX *amx, cell *params) // sc_get_weapon_id(index); = 1 arguments
|
||
|
{
|
||
|
// Gets the SCW_* constant of a weapon_* entity
|
||
|
// params[1] = weapon_* entity index
|
||
|
|
||
|
CHECK_NONPLAYER(params[1]);
|
||
|
edict_t *pEdict = INDEXENT(params[1]);
|
||
|
|
||
|
// not a valid weapon_*
|
||
|
if(strncmp(STRING(pEdict->v.classname), "weapon_", 7) != 0)
|
||
|
{
|
||
|
MF_LogError(amx, AMX_ERR_NATIVE, "Entity %d (\"%s\") is not a weapon_* entity", params[1], STRING(pEdict->v.classname));
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return *((int *)pEdict->pvPrivateData + OFFSET_WEAPON_TYPE);
|
||
|
}
|
||
|
|
||
|
static cell AMX_NATIVE_CALL sc_get_weapon_ammo(AMX *amx, cell *params) // sc_get_weapon_ammo(index1, index2=0); = 2 arguments
|
||
|
{
|
||
|
// Gets the amount of ammo in weapon's clip
|
||
|
// params[1] = weapon_* entity index OR player index
|
||
|
// params[2] = (optional) SCW_* constant if using player index
|
||
|
|
||
|
CHECK_ENTITY(params[1]);
|
||
|
edict_t *pEdict = GETEDICT(params[1]);
|
||
|
|
||
|
// sc_get_weapon_ammo(id, SCW_9MMAR);
|
||
|
if(params[2])
|
||
|
{
|
||
|
if(params[2] < 1 || params[2] > 23 || params[2] == 5)
|
||
|
{
|
||
|
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid weapon index %d", params[2]);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
CHECK_PLAYER(params[1]);
|
||
|
edict_t *pWeapon = NULL;
|
||
|
|
||
|
const char *weaponname = g_weapon_names[params[2]];
|
||
|
|
||
|
while(true)
|
||
|
{
|
||
|
pWeapon = FIND_ENTITY_BY_STRING(pWeapon, "classname", weaponname);
|
||
|
if(FNullEnt(pWeapon) || pWeapon->v.owner == pEdict) break;
|
||
|
}
|
||
|
|
||
|
if(FNullEnt(pWeapon))
|
||
|
{
|
||
|
MF_LogError(amx, AMX_ERR_NATIVE, "Player %d does not have a \"%s\" (index %d)", params[1], weaponname, params[2]);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return *((int *)pWeapon->pvPrivateData + OFFSET_WEAPON_CLIP);
|
||
|
}
|
||
|
|
||
|
if(strncmp(STRING(pEdict->v.classname), "weapon_", 7) != 0)
|
||
|
{
|
||
|
MF_LogError(amx, AMX_ERR_NATIVE, "Entity %d (\"%s\") is not a weapon_* entity", params[1], STRING(pEdict->v.classname));
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return *((int *)pEdict->pvPrivateData + OFFSET_WEAPON_CLIP);
|
||
|
}
|
||
|
|
||
|
static cell AMX_NATIVE_CALL sc_set_weapon_ammo(AMX *amx, cell *params) // sc_set_weapon_ammo(index1, value, index2=0); = 3 arguments
|
||
|
{
|
||
|
// Sets the amount of ammo in weapon's clip
|
||
|
// params[1] = weapon_* entity index OR player index
|
||
|
// params[2] = new clip ammo
|
||
|
// params[3] = (optional) SCW_* constant if using player index
|
||
|
|
||
|
CHECK_ENTITY(params[1]);
|
||
|
edict_t *pEdict = GETEDICT(params[1]);
|
||
|
|
||
|
// sc_set_weapon_ammo(id, SCW_9MMAR, 50);
|
||
|
if(params[3])
|
||
|
{
|
||
|
if(params[3] < 1 || params[3] > 23 || params[3] == 5)
|
||
|
{
|
||
|
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid weapon index %d", params[3]);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
CHECK_PLAYER(params[1]);
|
||
|
edict_t *pWeapon = NULL;
|
||
|
|
||
|
const char *weaponname = g_weapon_names[params[3]];
|
||
|
|
||
|
while(true)
|
||
|
{
|
||
|
pWeapon = FIND_ENTITY_BY_STRING(pWeapon, "classname", weaponname);
|
||
|
if(FNullEnt(pWeapon) || pWeapon->v.owner == pEdict) break;
|
||
|
}
|
||
|
|
||
|
if(FNullEnt(pWeapon))
|
||
|
{
|
||
|
MF_LogError(amx, AMX_ERR_NATIVE, "Player %d does not have a \"%s\" (index %d)", params[1], weaponname, params[3]);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
*((int *)pWeapon->pvPrivateData + OFFSET_WEAPON_CLIP) = params[2];
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
if(strncmp(STRING(pEdict->v.classname), "weapon_", 7) != 0)
|
||
|
{
|
||
|
MF_LogError(amx, AMX_ERR_NATIVE, "Entity %d (\"%s\") is not a weapon_* entity", params[1], STRING(pEdict->v.classname));
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
*((int *)pEdict->pvPrivateData + OFFSET_WEAPON_CLIP) = params[2];
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static cell AMX_NATIVE_CALL sc_get_user_bpammo(AMX *amx, cell *params) // sc_get_user_bpammo(index, weapon); = 2 arguments
|
||
|
{
|
||
|
// Gets the amount of ammo in player's backpack for a specific weapon
|
||
|
// params[1] = player index
|
||
|
// params[2] = SCW_* constant
|
||
|
|
||
|
CHECK_PLAYER(params[1]);
|
||
|
edict_t *pEdict = MF_GetPlayerEdict(params[1]);
|
||
|
|
||
|
if(params[2] < 1 || params[2] > 23 || params[2] == 5)
|
||
|
{
|
||
|
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid weapon index %d", params[2]);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// invalid weapon or no bpammo
|
||
|
if(g_ammo_offsets[params[2]] <= 0)
|
||
|
return 0;
|
||
|
|
||
|
return *((int *)pEdict->pvPrivateData + g_ammo_offsets[params[2]]);
|
||
|
}
|
||
|
|
||
|
static cell AMX_NATIVE_CALL sc_set_user_bpammo(AMX *amx, cell *params) // sc_set_user_bpammo(index, weapon, value); = 3 arguments
|
||
|
{
|
||
|
// Gets the amount of ammo in player's backpack for a specific weapon
|
||
|
// params[1] = player index
|
||
|
// params[2] = SCW_* constant
|
||
|
// params[3] = new backpack ammo
|
||
|
|
||
|
CHECK_PLAYER(params[1]);
|
||
|
edict_t *pEdict = MF_GetPlayerEdict(params[1]);
|
||
|
|
||
|
if(params[2] < 1 || params[2] > 23 || params[2] == 5)
|
||
|
{
|
||
|
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid weapon index %d", params[2]);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// invalid weapon or no bpammo
|
||
|
if(g_ammo_offsets[params[2]] <= 0)
|
||
|
return 0;
|
||
|
|
||
|
*((int *)pEdict->pvPrivateData + g_ammo_offsets[params[2]]) = params[3];
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// EXPORT LIST
|
||
|
//
|
||
|
|
||
|
AMX_NATIVE_INFO svencoop_Exports[] =
|
||
|
{
|
||
|
// monster natives
|
||
|
{"sc_get_frags", sc_get_frags},
|
||
|
{"sc_set_frags", sc_set_frags},
|
||
|
{"sc_get_displayname", sc_get_displayname},
|
||
|
{"sc_set_displayname", sc_set_displayname},
|
||
|
{"sc_is_player_ally", sc_is_player_ally},
|
||
|
|
||
|
// player natives
|
||
|
{"sc_get_user_longjump", sc_get_user_longjump},
|
||
|
{"sc_set_user_longjump", sc_set_user_longjump},
|
||
|
{"sc_get_user_deaths", sc_get_user_deaths},
|
||
|
{"sc_set_user_deaths", sc_set_user_deaths},
|
||
|
|
||
|
// ammo natives
|
||
|
{"sc_get_wbox_ammo", sc_get_wbox_ammo},
|
||
|
{"sc_set_wbox_ammo", sc_set_wbox_ammo},
|
||
|
{"sc_get_weapon_id", sc_get_weapon_id},
|
||
|
{"sc_get_weapon_ammo", sc_get_weapon_ammo},
|
||
|
{"sc_set_weapon_ammo", sc_set_weapon_ammo},
|
||
|
{"sc_get_user_bpammo", sc_get_user_bpammo},
|
||
|
{"sc_set_user_bpammo", sc_set_user_bpammo},
|
||
|
//------------------- <-- max 19 characters?? bleh!
|
||
|
{NULL, NULL}
|
||
|
};
|