763 lines
19 KiB
C++
Executable File
763 lines
19 KiB
C++
Executable File
#include "cstrike.h"
|
|
|
|
/*
|
|
|
|
*/
|
|
|
|
/*
|
|
Utils first
|
|
*/
|
|
|
|
bool isplayer(AMX* amx, edict_t* pPlayer) {
|
|
bool player = false;
|
|
// Check entity validity
|
|
if (FNullEnt(pPlayer)) {
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
if (strcmp(STRING(pPlayer->v.classname), "player") == 0)
|
|
player = true;
|
|
|
|
return player;
|
|
}
|
|
|
|
|
|
static cell AMX_NATIVE_CALL cs_set_user_money(AMX *amx, cell *params) // cs_set_user_money(index, money, flash = 1); = 3 arguments
|
|
{
|
|
// Give money to user
|
|
// params[1] = user
|
|
// params[2] = money
|
|
// params[3] = flash money?
|
|
|
|
// Check index
|
|
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
|
{
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
// Fetch player pointer
|
|
edict_t *pPlayer = INDEXENT(params[1]);
|
|
|
|
// Check entity validity
|
|
if (FNullEnt(pPlayer)) {
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
// Give money
|
|
(int)*((int *)pPlayer->pvPrivateData + OFFSET_CSMONEY) = params[2];
|
|
|
|
// Update display
|
|
MESSAGE_BEGIN(MSG_ONE, GET_USER_MSG_ID(PLID, "Money", NULL), NULL, pPlayer);
|
|
WRITE_LONG(params[2]);
|
|
WRITE_BYTE(params[3] ? 1 : 0); // if params[3] is 0, there will be no +/- flash of money in display...
|
|
MESSAGE_END();
|
|
|
|
return 1;
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL cs_get_user_money(AMX *amx, cell *params) // cs_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 0;
|
|
}
|
|
|
|
// Fetch player pointer
|
|
edict_t *pPlayer = INDEXENT(params[1]);
|
|
|
|
// Check entity validity
|
|
if (FNullEnt(pPlayer)) {
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
// Return money
|
|
return (int)*((int *)pPlayer->pvPrivateData + OFFSET_CSMONEY);
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL cs_set_user_deaths(AMX *amx, cell *params) // cs_set_user_deaths(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 0;
|
|
}
|
|
|
|
// Fetch player pointer
|
|
edict_t *pPlayer = INDEXENT(params[1]);
|
|
|
|
// Check entity validity
|
|
if (FNullEnt(pPlayer)) {
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
// Set deaths
|
|
(int)*((int *)pPlayer->pvPrivateData + OFFSET_CSDEATHS) = params[2];
|
|
|
|
return 1;
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL cs_get_hostage_id(AMX *amx, cell *params) // cs_get_hostage_id(index) = 1 param
|
|
{
|
|
// Gets unique id of a CS hostage.
|
|
// params[1] = hostage entity index
|
|
|
|
// Valid entity should be within range
|
|
if (params[1] < 1 || params[1] > gpGlobals->maxEntities)
|
|
{
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
// Make into class pointer
|
|
edict_t *pEdict = INDEXENT(params[1]);
|
|
|
|
// Check entity validity
|
|
if (FNullEnt(pEdict)) {
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
// Return value at offset
|
|
return (int)*((int *)pEdict->pvPrivateData + OFFSET_HOSTAGEID);
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL cs_get_weapon_silenced(AMX *amx, cell *params) // cs_get_weapon_silenced(index); = 1 param
|
|
{
|
|
// Is weapon silenced? Does only work on M4A1 and USP.
|
|
// params[1] = weapon index
|
|
|
|
// Valid entity should be within range
|
|
if (params[1] < 1 || params[1] > gpGlobals->maxEntities)
|
|
{
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
// Make into edict pointer
|
|
edict_t *pWeapon = INDEXENT(params[1]);
|
|
|
|
// Check entity validity
|
|
if (FNullEnt(pWeapon)) {
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
int weapontype = (int)*((int *)pWeapon->pvPrivateData + OFFSET_WEAPONTYPE);
|
|
int *silencemode = &(int)*((int *)pWeapon->pvPrivateData + OFFSET_SILENCER_FIREMODE);
|
|
switch (weapontype) {
|
|
case CSW_M4A1:
|
|
if (*silencemode == M4A1_SILENCED)
|
|
return 1;
|
|
case CSW_USP:
|
|
if (*silencemode == USP_SILENCED)
|
|
return 1;
|
|
}
|
|
|
|
// All else return 0.
|
|
return 0;
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL cs_set_weapon_silenced(AMX *amx, cell *params) // cs_set_weapon_silenced(index, silence = 1); = 2 params
|
|
{
|
|
// Silence/unsilence gun. Does only work on M4A1 and USP.
|
|
// params[1] = weapon index
|
|
// params[2] = 1, and we silence the gun, 0 and we unsilence gun-
|
|
|
|
// Valid entity should be within range
|
|
if (params[1] < 1 || params[1] > gpGlobals->maxEntities)
|
|
{
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
// Make into edict pointer
|
|
edict_t *pWeapon = INDEXENT(params[1]);
|
|
|
|
// Check entity validity
|
|
if (FNullEnt(pWeapon)) {
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
int weapontype = (int)*((int *)pWeapon->pvPrivateData + OFFSET_WEAPONTYPE);
|
|
int *silencemode = &(int)*((int *)pWeapon->pvPrivateData + OFFSET_SILENCER_FIREMODE);
|
|
|
|
switch (weapontype) {
|
|
case CSW_M4A1:
|
|
if (params[2])
|
|
*silencemode = M4A1_SILENCED;
|
|
else
|
|
*silencemode = M4A1_UNSILENCED;
|
|
break;
|
|
case CSW_USP:
|
|
if (params[2])
|
|
*silencemode = USP_SILENCED;
|
|
else
|
|
*silencemode = USP_UNSILENCED;
|
|
break;
|
|
default:
|
|
return 0;
|
|
}
|
|
|
|
|
|
return 1;
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL cs_get_weapon_burstmode(AMX *amx, cell *params) // cs_get_weapon_burstmode(index); = 1 param
|
|
{
|
|
// Is weapon in burst mode? Does only work with FAMAS and GLOCK.
|
|
// params[1] = weapon index
|
|
|
|
// Valid entity should be within range
|
|
if (params[1] < 1 || params[1] > gpGlobals->maxEntities)
|
|
{
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
// Make into edict pointer
|
|
edict_t *pWeapon = INDEXENT(params[1]);
|
|
|
|
// Check entity validity
|
|
if (FNullEnt(pWeapon)) {
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
int weapontype = (int)*((int *)pWeapon->pvPrivateData + OFFSET_WEAPONTYPE);
|
|
int* firemode = &(int)*((int *)pWeapon->pvPrivateData + OFFSET_SILENCER_FIREMODE);
|
|
switch (weapontype) {
|
|
case CSW_GLOCK18:
|
|
if (*firemode == GLOCK_BURSTMODE)
|
|
return 1;
|
|
case CSW_FAMAS:
|
|
if (*firemode == FAMAS_BURSTMODE)
|
|
return 1;
|
|
}
|
|
|
|
// All else return 0.
|
|
return 0;
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL cs_set_weapon_burstmode(AMX *amx, cell *params) // cs_set_weapon_burstmode(index, burstmode = 1); = 2 params
|
|
{
|
|
// Set/unset burstmode. Does only work with FAMAS and GLOCK.
|
|
// params[1] = weapon index
|
|
// params[2] = 1, and we set burstmode, 0 and we unset it.
|
|
|
|
// Valid entity should be within range
|
|
if (params[1] < 1 || params[1] > gpGlobals->maxEntities)
|
|
{
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
// Make into edict pointer
|
|
edict_t *pWeapon = INDEXENT(params[1]);
|
|
|
|
// Check entity validity
|
|
if (FNullEnt(pWeapon)) {
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
int weapontype = (int)*((int *)pWeapon->pvPrivateData + OFFSET_WEAPONTYPE);
|
|
|
|
int* firemode = &(int)*((int *)pWeapon->pvPrivateData + OFFSET_SILENCER_FIREMODE);
|
|
int previousMode = *firemode;
|
|
|
|
switch (weapontype) {
|
|
case CSW_GLOCK18:
|
|
if (params[2]) {
|
|
if (previousMode != GLOCK_BURSTMODE) {
|
|
*firemode = GLOCK_BURSTMODE;
|
|
|
|
// Is this weapon's owner a player? If so send this message...
|
|
if (isplayer(amx, pWeapon->v.owner)) {
|
|
MESSAGE_BEGIN(MSG_ONE, GET_USER_MSG_ID(PLID, "TextMsg", NULL), NULL, pWeapon->v.owner);
|
|
WRITE_BYTE(4); // dunno really what this 4 is for :-)
|
|
WRITE_STRING("#Switch_To_BurstFire");
|
|
MESSAGE_END();
|
|
}
|
|
}
|
|
}
|
|
else if (previousMode != GLOCK_SEMIAUTOMATIC) {
|
|
*firemode = GLOCK_SEMIAUTOMATIC;
|
|
|
|
// Is this weapon's owner a player? If so send this message...
|
|
if (isplayer(amx, pWeapon->v.owner)) {
|
|
MESSAGE_BEGIN(MSG_ONE, GET_USER_MSG_ID(PLID, "TextMsg", NULL), NULL, pWeapon->v.owner);
|
|
WRITE_BYTE(4); // dunno really what this 4 is for :-)
|
|
WRITE_STRING("#Switch_To_SemiAuto");
|
|
MESSAGE_END();
|
|
}
|
|
}
|
|
break;
|
|
case CSW_FAMAS:
|
|
if (params[2]) {
|
|
if (previousMode != FAMAS_BURSTMODE) {
|
|
*firemode = FAMAS_BURSTMODE;
|
|
|
|
// Is this weapon's owner a player? If so send this message...
|
|
if (isplayer(amx, pWeapon->v.owner)) {
|
|
MESSAGE_BEGIN(MSG_ONE, GET_USER_MSG_ID(PLID, "TextMsg", NULL), NULL, pWeapon->v.owner);
|
|
WRITE_BYTE(4); // dunno really what this 4 is for :-)
|
|
WRITE_STRING("#Switch_To_BurstFire");
|
|
MESSAGE_END();
|
|
}
|
|
}
|
|
}
|
|
else if (previousMode != FAMAS_AUTOMATIC) {
|
|
*firemode = FAMAS_AUTOMATIC;
|
|
|
|
// Is this weapon's owner a player? If so send this message...
|
|
if (isplayer(amx, pWeapon->v.owner)) {
|
|
MESSAGE_BEGIN(MSG_ONE, GET_USER_MSG_ID(PLID, "TextMsg", NULL), NULL, pWeapon->v.owner);
|
|
WRITE_BYTE(4); // dunno really what this 4 is for :-)
|
|
WRITE_STRING("#Switch_To_FullAuto");
|
|
MESSAGE_END();
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL cs_get_user_vip(AMX *amx, cell *params) // cs_get_user_vip(index); = 1 param
|
|
{
|
|
// Is user vip?
|
|
// params[1] = user index
|
|
|
|
// Valid entity should be within range
|
|
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
|
{
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
// Make into edict pointer
|
|
edict_t *pPlayer = INDEXENT(params[1]);
|
|
|
|
// Check entity validity
|
|
if (FNullEnt(pPlayer)) {
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
if ((int)*((int *)pPlayer->pvPrivateData + OFFSET_VIP) == PLAYER_IS_VIP)
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL cs_set_user_vip(AMX *amx, cell *params) // cs_set_user_vip(index, vip = 1); = 2 params
|
|
{
|
|
// Set user vip
|
|
// params[1] = user index
|
|
// params[2] = if 1, activate vip, else deactivate vip.
|
|
|
|
// Valid entity should be within range
|
|
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
|
{
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
// Make into edict pointer
|
|
edict_t *pPlayer = INDEXENT(params[1]);
|
|
|
|
// Check entity validity
|
|
if (FNullEnt(pPlayer)) {
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
if (params[2])
|
|
(int)*((int *)pPlayer->pvPrivateData + OFFSET_VIP) = PLAYER_IS_VIP;
|
|
else
|
|
(int)*((int *)pPlayer->pvPrivateData + OFFSET_VIP) = PLAYER_IS_NOT_VIP;
|
|
|
|
return 1;
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL cs_get_user_team(AMX *amx, cell *params) // cs_get_user_team(index); = 1 param
|
|
{
|
|
// Get user team
|
|
// params[1] = user index
|
|
|
|
// Valid entity should be within range
|
|
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
|
{
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
// Make into edict pointer
|
|
edict_t *pPlayer = INDEXENT(params[1]);
|
|
|
|
// Check entity validity
|
|
if (FNullEnt(pPlayer)) {
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
return (int)*((int *)pPlayer->pvPrivateData + OFFSET_TEAM);
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL cs_set_user_team(AMX *amx, cell *params) // cs_set_user_team(index, team); = 2 params
|
|
{
|
|
// Set user team
|
|
// params[1] = user index
|
|
// params[2] = team
|
|
|
|
// Valid entity should be within range
|
|
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
|
{
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
// Make into edict pointer
|
|
edict_t *pPlayer = INDEXENT(params[1]);
|
|
|
|
// Check entity validity
|
|
if (FNullEnt(pPlayer)) {
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
// Just set team. Removed check of 1-2-3, because maybe scripters want to create new teams, 4, 5 etc?
|
|
(int)*((int *)pPlayer->pvPrivateData + OFFSET_TEAM) = params[2];
|
|
|
|
/*switch (params[2]) {
|
|
case TEAM_T:
|
|
case TEAM_CT:
|
|
case TEAM_SPECTATOR:
|
|
(int)*((int *)pPlayer->pvPrivateData + OFFSET_TEAM) = params[2];
|
|
break;
|
|
default:
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
*/
|
|
|
|
return 1;
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL cs_get_user_inside_buyzone(AMX *amx, cell *params) // cs_get_user_inside_buyzone(index); = 1 param
|
|
{
|
|
// Is user inside buy zone?
|
|
// params[1] = user index
|
|
|
|
// Valid entity should be within range
|
|
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
|
{
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
// Make into edict pointer
|
|
edict_t *pPlayer = INDEXENT(params[1]);
|
|
|
|
// Check entity validity
|
|
if (FNullEnt(pPlayer)) {
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
return (int)*((int *)pPlayer->pvPrivateData + OFFSET_BUYZONE); // This offset is 0 when outside, 1 when inside.
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL cs_get_user_plant(AMX *amx, cell *params) // cs_get_user_plant(index); = 1 param
|
|
{
|
|
// Can user plant a bomb if he has one?
|
|
// params[1] = user index
|
|
|
|
// Valid entity should be within range
|
|
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
|
{
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
// Make into edict pointer
|
|
edict_t *pPlayer = INDEXENT(params[1]);
|
|
|
|
// Check entity validity
|
|
if (FNullEnt(pPlayer)) {
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
if ((int)*((int *)pPlayer->pvPrivateData + OFFSET_DEFUSE_PLANT) == CAN_PLANT_BOMB)
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL cs_set_user_plant(AMX *amx, cell *params) // cs_set_user_plant(index, plant = 1, showbombicon = 1); = 1 param
|
|
{
|
|
// Set user plant "skill".
|
|
// params[1] = user index
|
|
// params[2] = 1 = able to
|
|
// params[3] = show bomb icon?
|
|
|
|
// Valid entity should be within range
|
|
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
|
{
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
// Make into edict pointer
|
|
edict_t *pPlayer = INDEXENT(params[1]);
|
|
|
|
// Check entity validity
|
|
if (FNullEnt(pPlayer)) {
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
int* plantskill = &(int)*((int *)pPlayer->pvPrivateData + OFFSET_DEFUSE_PLANT);
|
|
|
|
if (params[2]) {
|
|
*plantskill = CAN_PLANT_BOMB;
|
|
if (params[3]) {
|
|
MESSAGE_BEGIN(MSG_ONE, GET_USER_MSG_ID(PLID, "StatusIcon", NULL), NULL, pPlayer);
|
|
WRITE_BYTE(1); // show
|
|
WRITE_STRING("c4");
|
|
WRITE_BYTE(DEFUSER_COLOUR_R);
|
|
WRITE_BYTE(DEFUSER_COLOUR_G);
|
|
WRITE_BYTE(DEFUSER_COLOUR_B);
|
|
MESSAGE_END();
|
|
}
|
|
}
|
|
else {
|
|
*plantskill = NO_DEFUSE_OR_PLANTSKILL;
|
|
MESSAGE_BEGIN(MSG_ONE, GET_USER_MSG_ID(PLID, "StatusIcon", NULL), NULL, pPlayer);
|
|
WRITE_BYTE(0); // hide
|
|
WRITE_STRING("c4");
|
|
MESSAGE_END();
|
|
}
|
|
|
|
/*
|
|
L 02/20/2004 - 16:58:00: [JGHG Trace] {MessageBegin type=StatusIcon(107), dest=MSG_ONE(1), classname=player netname=JGHG
|
|
L 02/20/2004 - 16:58:00: [JGHG Trace] WriteByte byte=2
|
|
L 02/20/2004 - 16:58:00: [JGHG Trace] WriteString string=c4
|
|
L 02/20/2004 - 16:58:00: [JGHG Trace] WriteByte byte=0
|
|
L 02/20/2004 - 16:58:00: [JGHG Trace] WriteByte byte=160
|
|
L 02/20/2004 - 16:58:00: [JGHG Trace] WriteByte byte=0
|
|
L 02/20/2004 - 16:58:00: [JGHG Trace] MessageEnd}
|
|
*/
|
|
|
|
return 1;
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL cs_get_user_defusekit(AMX *amx, cell *params) // cs_get_user_defusekit(index); = 1 param
|
|
{
|
|
// Does user have defusekit?
|
|
// params[1] = user index
|
|
|
|
// Valid entity should be within range
|
|
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
|
{
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
// Make into edict pointer
|
|
edict_t *pPlayer = INDEXENT(params[1]);
|
|
|
|
// Check entity validity
|
|
if (FNullEnt(pPlayer)) {
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
if ((int)*((int *)pPlayer->pvPrivateData + OFFSET_DEFUSE_PLANT) == HAS_DEFUSE_KIT)
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL cs_set_user_defusekit(AMX *amx, cell *params) // cs_set_user_defusekit(index, defusekit = 1, r = 0, g = 160, b = 0, icon[] = "defuser", flash = 0); = 7 params
|
|
{
|
|
// Give/take defusekit.
|
|
// params[1] = user index
|
|
// params[2] = 1 = give
|
|
// params[3] = r
|
|
// params[4] = g
|
|
// params[5] = b
|
|
// params[6] = icon[]
|
|
// params[7] = flash = 0
|
|
|
|
// Valid entity should be within range
|
|
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
|
{
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
// Make into edict pointer
|
|
edict_t *pPlayer = INDEXENT(params[1]);
|
|
|
|
// Check entity validity
|
|
if (FNullEnt(pPlayer)) {
|
|
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
int* defusekit = &(int)*((int *)pPlayer->pvPrivateData + OFFSET_DEFUSE_PLANT);
|
|
|
|
if (params[2]) {
|
|
int colour[3] = {DEFUSER_COLOUR_R, DEFUSER_COLOUR_G, DEFUSER_COLOUR_B};
|
|
for (int i = 0; i < 3; i++) {
|
|
if (params[i + 3] != -1)
|
|
colour[i] = params[i + 3];
|
|
}
|
|
|
|
char* icon;
|
|
if (params[6] != -1) {
|
|
int len;
|
|
icon = GET_AMXSTRING(amx, params[6], 1, len);
|
|
}
|
|
else
|
|
icon = "defuser";
|
|
|
|
*defusekit = HAS_DEFUSE_KIT;
|
|
MESSAGE_BEGIN(MSG_ONE, GET_USER_MSG_ID(PLID, "StatusIcon", NULL), NULL, pPlayer);
|
|
WRITE_BYTE(params[7] == 1 ? 2 : 1); // show
|
|
WRITE_STRING(icon);
|
|
WRITE_BYTE(colour[0]);
|
|
WRITE_BYTE(colour[1]);
|
|
WRITE_BYTE(colour[2]);
|
|
MESSAGE_END();
|
|
}
|
|
else {
|
|
*defusekit = NO_DEFUSE_OR_PLANTSKILL;
|
|
MESSAGE_BEGIN(MSG_ONE, GET_USER_MSG_ID(PLID, "StatusIcon", NULL), NULL, pPlayer);
|
|
WRITE_BYTE(0); // hide
|
|
WRITE_STRING("defuser");
|
|
MESSAGE_END();
|
|
}
|
|
|
|
/*
|
|
to show:
|
|
L 02/20/2004 - 16:10:26: [JGHG Trace] {MessageBegin type=StatusIcon(107), dest=MSG_ONE(1), classname=player netname=JGHG
|
|
L 02/20/2004 - 16:10:26: [JGHG Trace] WriteByte byte=1
|
|
L 02/20/2004 - 16:10:26: [JGHG Trace] WriteString string=defuser
|
|
L 02/20/2004 - 16:10:26: [JGHG Trace] WriteByte byte=0
|
|
L 02/20/2004 - 16:10:26: [JGHG Trace] WriteByte byte=160
|
|
L 02/20/2004 - 16:10:26: [JGHG Trace] WriteByte byte=0
|
|
L 02/20/2004 - 16:10:26: [JGHG Trace] MessageEnd}
|
|
|
|
to hide:
|
|
L 02/20/2004 - 16:10:31: [JGHG Trace] {MessageBegin type=StatusIcon(107), dest=MSG_ONE(1), classname=player netname=JGHG
|
|
L 02/20/2004 - 16:10:31: [JGHG Trace] WriteByte byte=0
|
|
L 02/20/2004 - 16:10:31: [JGHG Trace] WriteString string=defuser
|
|
L 02/20/2004 - 16:10:31: [JGHG Trace] MessageEnd}
|
|
*/
|
|
return 1;
|
|
}
|
|
|
|
AMX_NATIVE_INFO cstrike_Exports[] = {
|
|
{"cs_set_user_money", cs_set_user_money},
|
|
{"cs_get_user_money", cs_get_user_money},
|
|
{"cs_set_user_deaths", cs_set_user_deaths},
|
|
{"cs_get_hostage_id", cs_get_hostage_id},
|
|
{"cs_get_weapon_silenced", cs_get_weapon_silenced},
|
|
{"cs_set_weapon_silenced", cs_set_weapon_silenced},
|
|
{"cs_get_weapon_burstmode", cs_get_weapon_burstmode},
|
|
{"cs_set_weapon_burstmode", cs_set_weapon_burstmode},
|
|
{"cs_get_user_vip", cs_get_user_vip},
|
|
{"cs_set_user_vip", cs_set_user_vip},
|
|
{"cs_get_user_team", cs_get_user_team},
|
|
{"cs_set_user_team", cs_set_user_team},
|
|
{"cs_get_user_inside_buyzone", cs_get_user_inside_buyzone},
|
|
{"cs_get_user_plant", cs_get_user_plant},
|
|
{"cs_set_user_plant", cs_set_user_plant},
|
|
{"cs_get_user_defusekit", cs_get_user_defusekit},
|
|
{"cs_set_user_defusekit", cs_set_user_defusekit},
|
|
{NULL, NULL}
|
|
};
|
|
|
|
/******************************************************************************************/
|
|
|
|
|
|
/******************************************************************************************/
|
|
|
|
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;
|
|
|
|
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] %s is not attached to metamod (module \"%s\")\n", NAME, LOGTAG);
|
|
|
|
ADD_AMXNATIVES(&module_info, cstrike_Exports);
|
|
|
|
return(1);
|
|
}
|
|
|
|
C_DLLEXPORT int AMX_Detach() {
|
|
return(1);
|
|
} |