From b3758e37d172f13bc49c5fb2bfb97637a801dcdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johnny=20Bergstr=C3=B6m?= Date: Fri, 20 Feb 2004 15:45:45 +0000 Subject: [PATCH] new natives for cstrike module --- dlls/cstrike/cstrike.cpp | 763 +++++++++++++++++++++++++++++++++++++++ dlls/cstrike/cstrike.def | 10 + dlls/cstrike/cstrike.dsp | 123 +++++++ dlls/cstrike/cstrike.dsw | 29 ++ dlls/cstrike/cstrike.h | 110 ++++++ 5 files changed, 1035 insertions(+) create mode 100755 dlls/cstrike/cstrike.cpp create mode 100755 dlls/cstrike/cstrike.def create mode 100755 dlls/cstrike/cstrike.dsp create mode 100755 dlls/cstrike/cstrike.dsw create mode 100755 dlls/cstrike/cstrike.h diff --git a/dlls/cstrike/cstrike.cpp b/dlls/cstrike/cstrike.cpp new file mode 100755 index 00000000..28dd1456 --- /dev/null +++ b/dlls/cstrike/cstrike.cpp @@ -0,0 +1,763 @@ +#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); +} \ No newline at end of file diff --git a/dlls/cstrike/cstrike.def b/dlls/cstrike/cstrike.def new file mode 100755 index 00000000..0b92601b --- /dev/null +++ b/dlls/cstrike/cstrike.def @@ -0,0 +1,10 @@ +LIBRARY cstrike +EXPORTS + GiveFnptrsToDll @1 + Meta_Attach @2 + Meta_Detach @3 + Meta_Query @4 + AMX_Attach @5 + AMX_Detach @7 +SECTIONS + .data READ WRITE diff --git a/dlls/cstrike/cstrike.dsp b/dlls/cstrike/cstrike.dsp new file mode 100755 index 00000000..84981f79 --- /dev/null +++ b/dlls/cstrike/cstrike.dsp @@ -0,0 +1,123 @@ +# Microsoft Developer Studio Project File - Name="cstrike" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=cstrike - 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 "cstrike.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 "cstrike.mak" CFG="cstrike - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "cstrike - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "cstrike - 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)" == "cstrike - 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 Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CSTRIKE_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CSTRIKE_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\cstrike.dll K:\S\cstrike\addons\amx\dlls echo Copying inc... copy cstrike.inc K:\S\cstrike\addons\amx\examples\include +# End Special Build Tool + +!ELSEIF "$(CFG)" == "cstrike - 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 Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CSTRIKE_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 "CSTRIKE_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 /out:"Debug/cstrike_mm_debug.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "cstrike - Win32 Release" +# Name "cstrike - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\cstrike.cpp +# End Source File +# Begin Source File + +SOURCE=.\cstrike.def +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\cstrike.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=.\cstrike.inc +# End Source File +# End Target +# End Project diff --git a/dlls/cstrike/cstrike.dsw b/dlls/cstrike/cstrike.dsw new file mode 100755 index 00000000..b045a9ba --- /dev/null +++ b/dlls/cstrike/cstrike.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "cstrike"=".\cstrike.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/dlls/cstrike/cstrike.h b/dlls/cstrike/cstrike.h new file mode 100755 index 00000000..7a27eee0 --- /dev/null +++ b/dlls/cstrike/cstrike.h @@ -0,0 +1,110 @@ +// cstrike MODULE TO DO HERE: http://www.amxmod.info/forums/viewtopic.php?p=187#187 + +#include +#include +#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 + NULL, // pfnGetEngineFunctions META; called before HL engine + NULL // pfnGetEngineFunctions_Post META; called after HL engine +}; */ + +pfnamx_engine_g* g_engAmxFunc; +pfnmodule_engine_g* g_engModuleFunc; + +#define NAME "Counter-strike module" +#define AUTHOR "JGHG" +#define VERSION "0.1" +#define URL "http://?" +#define LOGTAG "cstrike" +#define DATE __DATE__ + +// cstrike-specific defines below +#if defined __linux__ + #define OFFSET_WEAPONTYPE 43 + 5 + #define OFFSET_SILENCER_FIREMODE 74 + 5 + #define OFFSET_TEAM 114 + 5 + #define OFFSET_CSMONEY 115 + 5 + #define OFFSET_DEFUSE_PLANT 193 + 5 + #define OFFSET_VIP 215 + 5 + #define OFFSET_BUYZONE 241 + 5 + #define OFFSET_CSDEATHS 449 + 5 + #define OFFSET_HOSTAGEID 487 + 5 +#else + #define OFFSET_WEAPONTYPE 43 + #define OFFSET_SILENCER_FIREMODE 74 + #define OFFSET_TEAM 114 + #define OFFSET_CSMONEY 115 + #define OFFSET_DEFUSE_PLANT 193 + #define OFFSET_VIP 215 + #define OFFSET_BUYZONE 241 + #define OFFSET_CSDEATHS 449 + #define OFFSET_HOSTAGEID 487 +#endif // defined __linux__ + +#define CSW_FAMAS 15 +#define CSW_USP 16 +#define CSW_GLOCK18 17 +#define CSW_M4A1 22 + +#define M4A1_UNSILENCED 0 +#define M4A1_SILENCED 4 +#define USP_UNSILENCED 0 +#define USP_SILENCED 1 + +#define GLOCK_SEMIAUTOMATIC 0 +#define GLOCK_BURSTMODE 2 +#define FAMAS_AUTOMATIC 0 +#define FAMAS_BURSTMODE 16 + +#define PLAYER_IS_NOT_VIP 0 +#define PLAYER_IS_VIP 256 + +#define TEAM_T 1 +#define TEAM_CT 2 +#define TEAM_SPECTATOR 3 + +#define NO_DEFUSE_OR_PLANTSKILL 0 +#define CAN_PLANT_BOMB 256 +#define HAS_DEFUSE_KIT 65536 + +#define DEFUSER_COLOUR_R 0 +#define DEFUSER_COLOUR_G 160 +#define DEFUSER_COLOUR_B 0 + +// cstrike-specific defines above + +// Globals below +plugin_info_t Plugin_info = { + META_INTERFACE_VERSION, + NAME, + VERSION, + DATE, + AUTHOR, + URL, + LOGTAG, + PT_ANYPAUSE, + PT_ANYPAUSE, +}; +module_info_s module_info = { + NAME, + AUTHOR, + VERSION, + AMX_INTERFACE_VERSION, + RELOAD_MODULE, +}; +// Globals above