2
0
mirror of https://github.com/rehlds/reapi.git synced 2025-01-29 23:17:57 +03:00

Added natives rg_set_user_team, rg_set_user_model, rg_reset_user_model

Added argument AccountSet type to rg_add_account
Update CSSDK of regamedll
This commit is contained in:
s1lentq 2016-05-31 22:12:44 +06:00 committed by asmodai
parent 3e2c6386e2
commit 63502fa028
20 changed files with 701 additions and 2157 deletions

View File

@ -19,6 +19,7 @@
#include <reapi_gamedll.inc> // NOTE: only for gamedll Counter-Strike (ReGameDLL_CS)
#include <reapi_addons.inc> // NOTE: 3-rd party addons
#include <reapi_version.inc>
#include <hlsdk_const.inc>
// hookchain return type
enum

View File

@ -82,7 +82,7 @@ native rg_set_animation(const index, PLAYER_ANIM:playerAnim);
*
* @noreturn
*/
native rg_add_account(const index, amount, bool:bTrackChange = true);
native rg_add_account(const index, amount, AccountSet:typeSet = AS_ADD, bool:bTrackChange = true);
/*
* Gives item to player
@ -354,3 +354,39 @@ native rg_get_user_armor(const index, &ArmorType:armortype);
*
*/
native rg_set_user_armor(const index, armorvalue, ArmorType:armortype);
/*
* Sets the client's team without killing the player, and sets the client model.
*
* @param index Client index
* @param team Team id
* @param model Internal model
*
* @param send_teaminfo If true, a TeamInfo message will be sent
*
* @noreturn
*
*/
native rg_set_user_team(const index, {TeamName,_}:team, {ModelName,_}:model = MODEL_UNASSIGNED, bool:send_teaminfo = true);
/*
* Sets the client's player model.
*
* @param index Client index
* @param model Model name
* @param update_index If true, the modelindex is updated as well
*
* @noreturn
*
*/
native rg_set_user_model(const index, const model[], bool:update_index = false);
/*
* Reset model user
*
* @param index Client index
*
* @noreturn
*
*/
native rg_reset_user_model(const index);

View File

@ -61,6 +61,49 @@ enum ArmorType
ARMOR_VESTHELM, // vest and helmet
};
enum AccountSet { AS_SET, AS_ADD };
enum RewardType
{
RT_NONE,
RT_ROUND_BONUS,
RT_PLAYER_RESET,
RT_PLAYER_BOUGHT_SOMETHING,
RT_HOSTAGE_TOOK,
RT_HOSTAGE_RESCUED,
RT_HOSTAGE_DAMAGED,
RT_HOSTAGE_KILLED,
RT_TEAMMATES_KILLED,
RT_ENEMY_KILLED,
RT_INTO_GAME,
RT_VIP_KILLED,
RT_VIP_RESCUED_MYSELF
};
enum TeamName
{
TEAM_UNASSIGNED,
TEAM_TERRORIST,
TEAM_CT,
TEAM_SPECTATOR
};
enum ModelName
{
MODEL_UNASSIGNED,
MODEL_CT_URBAN,
MODEL_T_TERROR,
MODEL_T_LEET,
MODEL_T_ARCTIC,
MODEL_CT_GSG9,
MODEL_CT_GIGN,
MODEL_CT_SAS,
MODEL_T_GUERILLA,
MODEL_CT_VIP,
MODEL_T_MILITIA,
MODEL_CT_SPETSNAZ
};
enum
{
GR_NONE = 0,
@ -517,7 +560,7 @@ enum GamedllFunc_CBasePlayer
/*
* Description: -
* Params: (const this, amount, bool:bTrackChange)
* Params: (const this, amount, RewardType:type, bool:bTrackChange)
*/
RG_CBasePlayer_AddAccount,

View File

@ -37,6 +37,7 @@ class CBaseEntity;
class CBaseMonster;
class CBasePlayerItem;
class CSquadMonster;
class CCSEntity;
class CBaseEntity {
public:
@ -135,8 +136,9 @@ public:
EOFFSET eoffset() { return OFFSET(pev); }
int entindex() { return ENTINDEX(edict()); }
public:
CCSEntity *m_pEntity;
// We use this variables to store each ammo count.
int *current_ammo;
float currentammo;
int maxammo_buckshot;
int ammo_buckshot;

View File

@ -27,8 +27,6 @@
*/
#pragma once
//#include "weapons.h"
#include "pm_materials.h"
#include "hintmessage.h"
#include "unisignals.h"
@ -132,6 +130,24 @@
#define SOUND_FLASHLIGHT_ON "items/flashlight1.wav"
#define SOUND_FLASHLIGHT_OFF "items/flashlight1.wav"
// custom enum
enum RewardType
{
RT_NONE,
RT_ROUND_BONUS,
RT_PLAYER_RESET,
RT_PLAYER_BOUGHT_SOMETHING,
RT_HOSTAGE_TOOK,
RT_HOSTAGE_RESCUED,
RT_HOSTAGE_DAMAGED,
RT_HOSTAGE_KILLED,
RT_TEAMMATES_KILLED,
RT_ENEMY_KILLED,
RT_INTO_GAME,
RT_VIP_KILLED,
RT_VIP_RESCUED_MYSELF
};
typedef enum
{
PLAYER_IDLE,
@ -262,6 +278,8 @@ typedef enum
} MusicState;
class CCSPlayer;
class CStripWeapons: public CPointEntity {
public:
virtual void Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value) = 0;
@ -338,21 +356,14 @@ public:
int IsObserver() { return pev->iuser1; }
void SetWeaponAnimType(const char *szExtention) { strcpy(m_szAnimExtention, szExtention); }
bool IsProtectedByShield() { return m_bOwnsShield && m_bShieldDrawn; }
bool IsReloading()
{
CBasePlayerWeapon *weapon = static_cast<CBasePlayerWeapon *>(m_pActiveItem);
if (weapon != NULL && weapon->m_fInReload)
return true;
return false;
}
bool IsReloading() const;
bool IsBlind() const { return (m_blindUntilTime > gpGlobals->time); }
bool IsAutoFollowAllowed() const { return (gpGlobals->time > m_allowAutoFollowTime); }
void InhibitAutoFollow(float duration) { m_allowAutoFollowTime = gpGlobals->time + duration; }
void AllowAutoFollow() { m_allowAutoFollowTime = 0; }
void SetObserverAutoDirector(bool val) { m_bObserverAutoDirector = val; }
bool CanSwitchObserverModes() const { return m_canSwitchObserverModes; }
CCSPlayer *CSPlayer() const;
public:
enum { MaxLocationLen = 32 };
@ -556,3 +567,17 @@ public:
EHANDLE m_hEntToIgnoreTouchesFrom;
float m_flTimeToIgnoreTouches;
};
inline bool CBasePlayer::IsReloading() const
{
CBasePlayerWeapon *weapon = static_cast<CBasePlayerWeapon *>(m_pActiveItem);
if (weapon != NULL && weapon->m_fInReload)
return true;
return false;
}
inline CCSPlayer *CBasePlayer::CSPlayer() const {
return reinterpret_cast<CCSPlayer *>(this->m_pEntity);
}

View File

@ -31,8 +31,8 @@
#include "hookchains.h"
#include "interface.h"
#define REGAMEDLL_API_VERSION_MAJOR 1
#define REGAMEDLL_API_VERSION_MINOR 0
#define REGAMEDLL_API_VERSION_MAJOR 2
#define REGAMEDLL_API_VERSION_MINOR 1
// CBasePlayer::Spawn hook
typedef IVoidHookChain<> IReGameHook_CBasePlayer_Spawn;
@ -124,8 +124,8 @@ typedef IVoidHookChainRegistryClass<class CBasePlayer, float, float, float, int>
// CBasePlayer::Observer_IsValidTarget hook
typedef IHookChain<class CBaseEntity *, int, bool> IReGameHook_CBasePlayer_Observer_IsValidTarget;
typedef IHookChainRegistryClass<class CBaseEntity *, class CBasePlayer, int, bool> IReGameHookRegistry_CBasePlayer_Observer_IsValidTarget;
typedef IHookChain<class CBasePlayer *, int, bool> IReGameHook_CBasePlayer_Observer_IsValidTarget;
typedef IHookChainRegistryClass<class CBasePlayer *, class CBasePlayer, int, bool> IReGameHookRegistry_CBasePlayer_Observer_IsValidTarget;
// CBasePlayer::SetAnimation hook
typedef IVoidHookChain<PLAYER_ANIM> IReGameHook_CBasePlayer_SetAnimation;
@ -140,14 +140,16 @@ typedef IVoidHookChain<const char *> IReGameHook_CBasePlayer_GiveNamedItem;
typedef IVoidHookChainRegistryClass<class CBasePlayer, const char *> IReGameHookRegistry_CBasePlayer_GiveNamedItem;
// CBasePlayer::AddAccount hook
typedef IVoidHookChain<int, bool> IReGameHook_CBasePlayer_AddAccount;
typedef IVoidHookChainRegistryClass<class CBasePlayer, int, bool> IReGameHookRegistry_CBasePlayer_AddAccount;
typedef IVoidHookChain<int, enum RewardType, bool> IReGameHook_CBasePlayer_AddAccount;
typedef IVoidHookChainRegistryClass<class CBasePlayer, int, enum RewardType, bool> IReGameHookRegistry_CBasePlayer_AddAccount;
// CBasePlayer::GiveShield hook
typedef IVoidHookChain<bool> IReGameHook_CBasePlayer_GiveShield;
typedef IVoidHookChainRegistryClass<class CBasePlayer, bool> IReGameHookRegistry_CBasePlayer_GiveShield;
// CBasePlayer:SetClientUserInfoModel hook
typedef IVoidHookChain<char *, char *> IReGameHook_CBasePlayer_SetClientUserInfoModel;
typedef IVoidHookChainRegistryClass<class CBasePlayer, char *, char *> IReGameHookRegistry_CBasePlayer_SetClientUserInfoModel;
// CBaseAnimating::ResetSequenceInfo hook
@ -194,6 +196,22 @@ typedef IVoidHookChainRegistry<struct playermove_s *, int> IReGameHookRegistry_P
typedef IVoidHookChain<int> IReGameHook_PM_AirMove;
typedef IVoidHookChainRegistry<int> IReGameHookRegistry_PM_AirMove;
// HandleMenu_ChooseAppearance hook
typedef IVoidHookChain<class CBasePlayer *, int> IReGameHook_HandleMenu_ChooseAppearance;
typedef IVoidHookChainRegistry<class CBasePlayer *, int> IReGameHookRegistry_HandleMenu_ChooseAppearance;
// HandleMenu_ChooseTeam hook
typedef IHookChain<BOOL, class CBasePlayer *, int> IReGameHook_HandleMenu_ChooseTeam;
typedef IHookChainRegistry<BOOL, class CBasePlayer *, int> IReGameHookRegistry_HandleMenu_ChooseTeam;
// ShowMenu hook
typedef IVoidHookChain<class CBasePlayer *, int, int, BOOL, char *> IReGameHook_ShowMenu;
typedef IVoidHookChainRegistry<class CBasePlayer *, int, int, BOOL, char *> IReGameHookRegistry_ShowMenu;
// ShowVGUIMenu hook
typedef IVoidHookChain<class CBasePlayer *, int, int, char *> IReGameHook_ShowVGUIMenu;
typedef IVoidHookChainRegistry<class CBasePlayer *, int, int, char *> IReGameHookRegistry_ShowVGUIMenu;
// CHalfLifeMultiplay::FShouldSwitchWeapon hook
typedef IHookChain<BOOL, class CBasePlayer *, class CBasePlayerItem *> IReGameHook_CSGameRules_FShouldSwitchWeapon;
typedef IHookChainRegistry<BOOL, class CBasePlayer *, class CBasePlayerItem *> IReGameHookRegistry_CSGameRules_FShouldSwitchWeapon;
@ -315,6 +333,7 @@ public:
virtual IReGameHookRegistry_CBasePlayer_GiveNamedItem* CBasePlayer_GiveNamedItem() = 0;
virtual IReGameHookRegistry_CBasePlayer_AddAccount* CBasePlayer_AddAccount() = 0;
virtual IReGameHookRegistry_CBasePlayer_GiveShield* CBasePlayer_GiveShield() = 0;
virtual IReGameHookRegistry_CBasePlayer_SetClientUserInfoModel* CBasePlayer_SetClientUserInfoModel() = 0;
virtual IReGameHookRegistry_CBaseAnimating_ResetSequenceInfo* CBaseAnimating_ResetSequenceInfo() = 0;
virtual IReGameHookRegistry_GetForceCamera* GetForceCamera() = 0;
@ -326,6 +345,10 @@ public:
virtual IReGameHookRegistry_PM_Init* PM_Init() = 0;
virtual IReGameHookRegistry_PM_Move* PM_Move() = 0;
virtual IReGameHookRegistry_PM_AirMove* PM_AirMove() = 0;
virtual IReGameHookRegistry_HandleMenu_ChooseAppearance* HandleMenu_ChooseAppearance() = 0;
virtual IReGameHookRegistry_HandleMenu_ChooseTeam* HandleMenu_ChooseTeam() = 0;
virtual IReGameHookRegistry_ShowMenu* ShowMenu() = 0;
virtual IReGameHookRegistry_ShowVGUIMenu* ShowVGUIMenu() = 0;
virtual IReGameHookRegistry_CSGameRules_FShouldSwitchWeapon* CSGameRules_FShouldSwitchWeapon() = 0;
virtual IReGameHookRegistry_CSGameRules_GetNextBestWeapon* CSGameRules_GetNextBestWeapon() = 0;
@ -353,11 +376,7 @@ public:
};
struct ReGameFuncs_t {
class CBaseEntity *(*UTIL_PlayerByIndex)(int playerIndex);
class ICSPlayer *(*CBASE_TO_CSPLAYER)(class CBaseEntity *pEntity);
class ICSEntity *(*CBASE_TO_CSENTITY)(class CBaseEntity *pEntity);
class ICSPlayer *(*INDEX_TO_CSPLAYER)(int iPlayerIndex);
class ICSEntity *(*INDEX_TO_CSENTITY)(int iEntityIndex);
class CBasePlayer *(*UTIL_PlayerByIndex)(int playerIndex);
struct edict_s *(*CREATE_NAMED_ENTITY2)(string_t iClass);
void (*ChangeString)(char *&dest, const char *source);

File diff suppressed because it is too large Load Diff

View File

@ -105,7 +105,7 @@ static struct funcreq_t
//DECLARE_REQ(RegisterFunction),
//DECLARE_REQ(RequestFunction),
//DECLARE_REQ(amx_Push),
//DECLARE_REQ(SetTeamInfo),
DECLARE_REQ(SetPlayerTeamInfo),
//DECLARE_REQ(PlayerPropAddr),
//DECLARE_REQ(RegAuthFunc),
//DECLARE_REQ(UnregAuthFunc),

View File

@ -476,7 +476,7 @@ struct amxxapi_t
PFN_REGISTERFUNCTION RegisterFunction;
PFN_REQ_FNPTR RequestFunction;
PFN_AMX_PUSH amx_Push;
PFN_SET_TEAM_INFO SetTeamInfo;
PFN_SET_TEAM_INFO SetPlayerTeamInfo;
PFN_PLAYER_PROP_ADDR PlayerPropAddr;
PFN_REG_AUTH_FUNC RegAuthFunc;
PFN_UNREG_AUTH_FUNC UnregAuthFunc;

View File

@ -4,7 +4,7 @@ DLL_FUNCTIONS *g_pFunctionTable;
DLL_FUNCTIONS gFunctionTable =
{
NULL, // pfnGameInit
Spawn, // pfnSpawn
&DispatchSpawn, // pfnSpawn
NULL, // pfnThink
NULL, // pfnUse
NULL, // pfnTouch

View File

@ -270,14 +270,14 @@ void CBasePlayer_Blind(IReGameHook_CBasePlayer_Blind *chain, CBasePlayer *pthis,
callVoidForward(RG_CBasePlayer_Blind, original, indexOfEdict(pthis->pev), flUntilTime, flHoldTime, flFadeTime, iAlpha);
}
CBaseEntity *CBasePlayer_Observer_IsValidTarget(IReGameHook_CBasePlayer_Observer_IsValidTarget *chain, CBasePlayer *pthis, int iPlayerIndex, bool bSameTeam)
CBasePlayer *CBasePlayer_Observer_IsValidTarget(IReGameHook_CBasePlayer_Observer_IsValidTarget *chain, CBasePlayer *pthis, int iPlayerIndex, bool bSameTeam)
{
auto original = [chain](int _pthis, int _iPlayerIndex, bool _bSameTeam)
{
return chain->callNext(_iPlayerIndex, _bSameTeam);
};
return callForward<CBaseEntity *>(RG_CBasePlayer_Observer_IsValidTarget, original, indexOfEdict(pthis->pev), iPlayerIndex, bSameTeam);
return callForward<CBasePlayer *>(RG_CBasePlayer_Observer_IsValidTarget, original, indexOfEdict(pthis->pev), iPlayerIndex, bSameTeam);
}
void CBasePlayer_SetAnimation(IReGameHook_CBasePlayer_SetAnimation *chain, CBasePlayer *pthis, PLAYER_ANIM playerAnim)
@ -310,14 +310,14 @@ void CBasePlayer_GiveNamedItem(IReGameHook_CBasePlayer_GiveNamedItem *chain, CBa
callVoidForward(RG_CBasePlayer_GiveNamedItem, original, indexOfEdict(pthis->pev), pszName);
}
void CBasePlayer_AddAccount(IReGameHook_CBasePlayer_AddAccount *chain, CBasePlayer *pthis, int amount, bool bTrackChange)
void CBasePlayer_AddAccount(IReGameHook_CBasePlayer_AddAccount *chain, CBasePlayer *pthis, int amount, RewardType type, bool bTrackChange)
{
auto original = [chain](int _pthis, int _amount, bool _bTrackChange)
auto original = [chain](int _pthis, int _amount, RewardType _type, bool _bTrackChange)
{
chain->callNext(_amount, _bTrackChange);
chain->callNext(_amount, _type, _bTrackChange);
};
callVoidForward(RG_CBasePlayer_AddAccount, original, indexOfEdict(pthis->pev), amount, bTrackChange);
callVoidForward(RG_CBasePlayer_AddAccount, original, indexOfEdict(pthis->pev), amount, type, bTrackChange);
}
void CBasePlayer_GiveShield(IReGameHook_CBasePlayer_GiveShield *chain, CBasePlayer *pthis, bool bDeploy)
@ -501,7 +501,7 @@ void CSGameRules_PlayerKilled(IReGameHook_CSGameRules_PlayerKilled *chain, CBase
chain->callNext(getPrivate<CBasePlayer>(_pVictim), PEV(_pKiller), PEV(_pInflictor));
};
callVoidForward(RG_CSGameRules_ClientUserInfoChanged, original, indexOfEdict(pVictim->pev), indexOfEdict(pKiller), indexOfEdict(pInflictor));
callVoidForward(RG_CSGameRules_PlayerKilled, original, indexOfEdict(pVictim->pev), indexOfEdict(pKiller), indexOfEdict(pInflictor));
}
void CSGameRules_DeathNotice(IReGameHook_CSGameRules_DeathNotice *chain, CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pevInflictor)

View File

@ -234,11 +234,11 @@ void CBasePlayer_ImpulseCommands(IReGameHook_CBasePlayer_ImpulseCommands *chain,
void CBasePlayer_RoundRespawn(IReGameHook_CBasePlayer_RoundRespawn *chain, CBasePlayer *pthis);
void CBasePlayer_Blind(IReGameHook_CBasePlayer_Blind *chain, CBasePlayer *pthis, float flUntilTime, float flHoldTime, float flFadeTime, int iAlpha);
CBaseEntity *CBasePlayer_Observer_IsValidTarget(IReGameHook_CBasePlayer_Observer_IsValidTarget *chain, CBasePlayer *pthis, int iPlayerIndex, bool bSameTeam);
CBasePlayer *CBasePlayer_Observer_IsValidTarget(IReGameHook_CBasePlayer_Observer_IsValidTarget *chain, CBasePlayer *pthis, int iPlayerIndex, bool bSameTeam);
void CBasePlayer_SetAnimation(IReGameHook_CBasePlayer_SetAnimation *chain, CBasePlayer *pthis, PLAYER_ANIM playerAnim);
void CBasePlayer_GiveDefaultItems(IReGameHook_CBasePlayer_GiveDefaultItems *chain, CBasePlayer *pthis);
void CBasePlayer_GiveNamedItem(IReGameHook_CBasePlayer_GiveNamedItem *chain, CBasePlayer *pthis, const char *pszName);
void CBasePlayer_AddAccount(IReGameHook_CBasePlayer_AddAccount *chain, CBasePlayer *pthis, int amount, bool bTrackChange);
void CBasePlayer_AddAccount(IReGameHook_CBasePlayer_AddAccount *chain, CBasePlayer *pthis, int amount, RewardType type, bool bTrackChange);
void CBasePlayer_GiveShield(IReGameHook_CBasePlayer_GiveShield *chain, CBasePlayer *pthis, bool bDeploy);
void CBaseAnimating_ResetSequenceInfo(IReGameHook_CBaseAnimating_ResetSequenceInfo *chain, CBaseAnimating *pthis);

View File

@ -4,6 +4,7 @@ inline size_t getFwdParamType(void(*)(int)) { return FP_CELL; }
inline size_t getFwdParamType(void(*)(bool)) { return FP_CELL; }
inline size_t getFwdParamType(void(*)(Vector&)) { return FP_ARRAY; }
inline size_t getFwdParamType(void(*)(PLAYER_ANIM)) { return FP_CELL; }
inline size_t getFwdParamType(void(*)(RewardType)) { return FP_CELL; }
inline size_t getFwdParamType(void(*)(ScenarioEventEndRound)) { return FP_CELL; }
inline size_t getFwdParamType(void(*)(float)) { return FP_FLOAT; }
inline size_t getFwdParamType(void(*)(float&)) { return FP_FLOAT; }

View File

@ -1,7 +1,20 @@
#include "precompiled.h"
edict_t* g_pEdicts;
int gmsgSendAudio, gmsgTeamScore, gmsgStatusIcon, gmsgArmorType;
int gmsgSendAudio, gmsgTeamScore, gmsgStatusIcon, gmsgArmorType, gmsgTeamInfo, gmsgItemStatus;
struct
{
const char* pszName;
int& id;
} g_RegUserMsg[] = {
{ "SendAudio", gmsgSendAudio },
{ "TeamScore", gmsgTeamScore },
{ "StatusIcon", gmsgStatusIcon },
{ "ArmorType", gmsgArmorType },
{ "TeamInfo", gmsgTeamInfo },
{ "ItemStatus", gmsgItemStatus },
};
void OnAmxxAttach()
{
@ -31,10 +44,9 @@ void OnMetaDetach()
void ServerActivate_Post(edict_t *pEdictList, int edictCount, int clientMax)
{
gmsgSendAudio = GET_USER_MSG_ID(PLID, "SendAudio", NULL);
gmsgTeamScore = GET_USER_MSG_ID(PLID, "TeamScore", NULL);
gmsgStatusIcon = GET_USER_MSG_ID(PLID, "StatusIcon", NULL);
gmsgArmorType = GET_USER_MSG_ID(PLID, "ArmorType", NULL);
for (auto& msg : g_RegUserMsg) {
msg.id = GET_USER_MSG_ID(PLID, msg.pszName, NULL);
}
SET_META_RESULT(MRES_IGNORED);
}
@ -43,7 +55,7 @@ void ServerDeactivate_Post()
{
api_cfg.ServerDeactivate();
g_hookManager.clearHandlers();
g_pFunctionTable->pfnSpawn = Spawn;
g_pFunctionTable->pfnSpawn = DispatchSpawn;
SET_META_RESULT(MRES_IGNORED);
}
@ -53,7 +65,7 @@ CGameRules *InstallGameRules(IReGameHook_InstallGameRules *chain)
return g_pGameRules = chain->callNext();
}
int Spawn(edict_t* pEntity)
int DispatchSpawn(edict_t* pEntity)
{
g_pEdicts = g_engfuncs.pfnPEntityOfEntIndex(0);
g_pFunctionTable->pfnSpawn = nullptr;

View File

@ -5,6 +5,8 @@ extern int gmsgSendAudio;
extern int gmsgTeamScore;
extern int gmsgStatusIcon;
extern int gmsgArmorType;
extern int gmsgTeamInfo;
extern int gmsgItemStatus;
void OnAmxxAttach();
bool OnMetaAttach();
@ -12,6 +14,6 @@ void OnMetaDetach();
void ServerActivate_Post(edict_t *pEdictList, int edictCount, int clientMax);
void ServerDeactivate_Post();
int Spawn(edict_t* pEntity);
int DispatchSpawn(edict_t* pEntity);
CGameRules *InstallGameRules(IReGameHook_InstallGameRules *chain);

View File

@ -42,16 +42,11 @@ public:
{
if (m_value < 0)
return nullptr;
return static_cast<CBasePlayer *>(g_ReGameFuncs->UTIL_PlayerByIndex(m_value));
}
operator PLAYER_ANIM() const
{
return static_cast<PLAYER_ANIM>(m_value);
}
operator ICSEntity*() const
{
return g_ReGameFuncs->INDEX_TO_CSENTITY(m_value);
return g_ReGameFuncs->UTIL_PlayerByIndex(m_value);
}
operator TeamName() const { return static_cast<TeamName>(m_value); }
operator ModelName() const { return static_cast<ModelName>(m_value); }
operator PLAYER_ANIM() const { return static_cast<PLAYER_ANIM>(m_value); }
Vector& vector() const
{
return operator Vector&();

View File

@ -16,16 +16,18 @@ cell AMX_NATIVE_CALL rg_set_animation(AMX *amx, cell *params)
CHECK_ISPLAYER(arg_index);
ICSPlayer *pPlayer = g_ReGameFuncs->INDEX_TO_CSPLAYER(params[arg_index]);
if (pPlayer == nullptr || !pPlayer->IsConnected()) {
CBasePlayer *pPlayer = g_ReGameFuncs->UTIL_PlayerByIndex(params[arg_index]);
if (pPlayer == nullptr || pPlayer->has_disconnected) {
MF_LogError(amx, AMX_ERR_NATIVE, "%s: player %i is not connected", __FUNCTION__, params[arg_index]);
return FALSE;
}
pPlayer->SetAnimation(CAmxArg(amx, params[arg_anim]));
pPlayer->CSPlayer()->SetAnimation(CAmxArg(amx, params[arg_anim]));
return TRUE;
}
enum AccountSet { AS_SET, AS_ADD };
/*
* Adds money to player's account.
*
@ -35,21 +37,25 @@ cell AMX_NATIVE_CALL rg_set_animation(AMX *amx, cell *params)
*
* @noreturn
*
* native rg_add_account(index, amount, bool:bTrackChange = true);
* native rg_add_account(index, amount, AccountSet:typeSet = AS_ADD, bool:bTrackChange = true);
*/
cell AMX_NATIVE_CALL rg_add_account(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_index, arg_amount, arg_track_change };
enum args_e { arg_count, arg_index, arg_amount, arg_typeSet, arg_track_change };
CHECK_ISPLAYER(arg_index);
ICSPlayer *pPlayer = g_ReGameFuncs->INDEX_TO_CSPLAYER(params[arg_index]);
if (pPlayer == nullptr || !pPlayer->IsConnected()) {
CBasePlayer *pPlayer = g_ReGameFuncs->UTIL_PlayerByIndex(params[arg_index]);
if (pPlayer == nullptr || pPlayer->has_disconnected) {
MF_LogError(amx, AMX_ERR_NATIVE, "%s: player %i is not connected", __FUNCTION__, params[arg_index]);
return FALSE;
}
pPlayer->AddAccount(params[arg_amount], params[arg_track_change] != 0);
if (static_cast<AccountSet>(params[arg_typeSet]) == AS_SET) {
pPlayer->m_iAccount = 0;
}
pPlayer->CSPlayer()->AddAccount(params[arg_amount], RT_NONE, params[arg_track_change] != 0);
return TRUE;
}
@ -71,8 +77,8 @@ cell AMX_NATIVE_CALL rg_give_item(AMX *amx, cell *params)
CHECK_ISPLAYER(arg_index);
ICSPlayer *pPlayer = g_ReGameFuncs->INDEX_TO_CSPLAYER(params[arg_index]);
if (pPlayer == nullptr || !pPlayer->IsConnected()) {
CBasePlayer *pPlayer = g_ReGameFuncs->UTIL_PlayerByIndex(params[arg_index]);
if (pPlayer == nullptr || pPlayer->has_disconnected) {
MF_LogError(amx, AMX_ERR_NATIVE, "%s: player %i is not connected", __FUNCTION__, params[arg_index]);
return FALSE;
}
@ -81,10 +87,9 @@ cell AMX_NATIVE_CALL rg_give_item(AMX *amx, cell *params)
const char *itemName = getAmxString(amx, params[arg_item]);
if (type > GT_APPEND) {
CBasePlayer *player = static_cast<CBasePlayer *>(pPlayer->GetEntity());
auto pInfo = g_ReGameApi->GetWeaponSlot(itemName);
auto pItem = player->m_rgpPlayerItems[ pInfo->slot ];
auto pItem = pPlayer->m_rgpPlayerItems[ pInfo->slot ];
while (pItem != nullptr) {
if (pItem->m_iId == pInfo->id) {
@ -95,11 +100,11 @@ cell AMX_NATIVE_CALL rg_give_item(AMX *amx, cell *params)
switch (type)
{
case GT_DROP_AND_REPLACE:
pPlayer->DropPlayerItem(STRING(pItem->pev->classname));
pPlayer->CSPlayer()->DropPlayerItem(STRING(pItem->pev->classname));
break;
case GT_REPLACE:
player->pev->weapons &= ~(1 << pItem->m_iId);
player->RemovePlayerItem(pItem);
pPlayer->pev->weapons &= ~(1 << pItem->m_iId);
pPlayer->RemovePlayerItem(pItem);
pItem->Kill();
break;
}
@ -108,7 +113,7 @@ cell AMX_NATIVE_CALL rg_give_item(AMX *amx, cell *params)
}
}
pPlayer->GiveNamedItemEx(itemName);
pPlayer->CSPlayer()->GiveNamedItemEx(itemName);
return TRUE;
}
@ -127,13 +132,13 @@ cell AMX_NATIVE_CALL rg_give_default_items(AMX *amx, cell *params)
CHECK_ISPLAYER(arg_index);
ICSPlayer *pPlayer = g_ReGameFuncs->INDEX_TO_CSPLAYER(params[arg_index]);
if (pPlayer == nullptr || !pPlayer->IsConnected()) {
CBasePlayer *pPlayer = g_ReGameFuncs->UTIL_PlayerByIndex(params[arg_index]);
if (pPlayer == nullptr || pPlayer->has_disconnected) {
MF_LogError(amx, AMX_ERR_NATIVE, "%s: player %i is not connected", __FUNCTION__, params[arg_index]);
return FALSE;
}
pPlayer->GiveDefaultItems();
pPlayer->CSPlayer()->GiveDefaultItems();
return TRUE;
}
@ -153,13 +158,13 @@ cell AMX_NATIVE_CALL rg_give_shield(AMX *amx, cell *params)
CHECK_ISPLAYER(arg_index);
ICSPlayer *pPlayer = g_ReGameFuncs->INDEX_TO_CSPLAYER(params[arg_index]);
if (pPlayer == nullptr || !pPlayer->IsConnected()) {
CBasePlayer *pPlayer = g_ReGameFuncs->UTIL_PlayerByIndex(params[arg_index]);
if (pPlayer == nullptr || pPlayer->has_disconnected) {
MF_LogError(amx, AMX_ERR_NATIVE, "%s: player %i is not connected", __FUNCTION__, params[arg_index]);
return FALSE;
}
pPlayer->GiveShield(params[arg_deploy] != 0);
pPlayer->CSPlayer()->GiveShield(params[arg_deploy] != 0);
return TRUE;
}
@ -283,9 +288,9 @@ cell AMX_NATIVE_CALL rg_fire_bullets(AMX *amx, cell *params)
CHECK_ISENTITY(arg_attacker);
CAmxArgs args(amx, params);
ICSEntity *pInflictor = args[arg_inflictor];
CBaseEntity *pInflictor = args[arg_inflictor];
pInflictor->FireBullets
pInflictor->m_pEntity->FireBullets
(
args[arg_shots],
args[arg_vecSrc],
@ -329,10 +334,10 @@ cell AMX_NATIVE_CALL rg_fire_bullets3(AMX *amx, cell *params)
CHECK_ISENTITY(arg_attacker);
CAmxArgs args(amx, params);
ICSEntity *pInflictor = args[arg_inflictor];
CBaseEntity *pInflictor = args[arg_inflictor];
entvars_t *pAttacker = args[arg_attacker];
args[arg_out].vector() = pInflictor->FireBullets3
args[arg_out].vector() = pInflictor->m_pEntity->FireBullets3
(
args[arg_vecSrc],
args[arg_dir],
@ -671,13 +676,13 @@ cell AMX_NATIVE_CALL rg_remove_all_items(AMX *amx, cell *params)
CHECK_ISPLAYER(arg_index);
ICSPlayer *pPlayer = g_ReGameFuncs->INDEX_TO_CSPLAYER(params[arg_index]);
if (pPlayer == nullptr || !pPlayer->IsConnected()) {
CBasePlayer *pPlayer = g_ReGameFuncs->UTIL_PlayerByIndex(params[arg_index]);
if (pPlayer == nullptr || pPlayer->has_disconnected) {
MF_LogError(amx, AMX_ERR_NATIVE, "%s: player %i is not connected", __FUNCTION__, params[arg_index]);
return FALSE;
}
pPlayer->RemoveAllItems(params[arg_suit] != 0);
pPlayer->CSPlayer()->RemoveAllItems(params[arg_suit] != 0);
return TRUE;
}
@ -697,32 +702,15 @@ cell AMX_NATIVE_CALL rg_remove_item(AMX *amx, cell *params)
CHECK_ISPLAYER(arg_index);
CBasePlayer *pPlayer = (CBasePlayer *)g_ReGameFuncs->UTIL_PlayerByIndex(params[arg_index]);
CBasePlayer *pPlayer = g_ReGameFuncs->UTIL_PlayerByIndex(params[arg_index]);
if (pPlayer == nullptr || pPlayer->has_disconnected) {
MF_LogError(amx, AMX_ERR_NATIVE, "%s: player %i is not connected", __FUNCTION__, params[arg_index]);
return FALSE;
}
const char* szItemName = getAmxString(amx, params[arg_item_name]);
for (auto pItem : pPlayer->m_rgpPlayerItems)
{
while (pItem != nullptr)
{
if (FClassnameIs(pItem->pev, szItemName))
{
CBasePlayerWeapon *pWeapon = static_cast<CBasePlayerWeapon *>(pItem);
if (pWeapon->IsWeapon()) {
pWeapon->RetireWeapon();
}
pPlayer->pev->weapons &= ~(1 << pItem->m_iId);
pPlayer->RemovePlayerItem(pItem);
pItem->Kill();
return TRUE;
}
pItem = pItem->m_pNext;
}
if (RemovePlayerItem(pPlayer, szItemName)) {
return TRUE;
}
return FALSE;
@ -744,7 +732,7 @@ cell AMX_NATIVE_CALL rg_get_user_bpammo(AMX *amx, cell *params)
CHECK_ISPLAYER(arg_index);
CBasePlayer *pPlayer = (CBasePlayer *)g_ReGameFuncs->UTIL_PlayerByIndex(params[arg_index]);
CBasePlayer *pPlayer = g_ReGameFuncs->UTIL_PlayerByIndex(params[arg_index]);
if (pPlayer == nullptr || pPlayer->has_disconnected) {
MF_LogError(amx, AMX_ERR_NATIVE, "%s: player %i is not connected", __FUNCTION__, params[arg_index]);
return FALSE;
@ -789,7 +777,7 @@ cell AMX_NATIVE_CALL rg_set_user_bpammo(AMX *amx, cell *params)
CHECK_ISPLAYER(arg_index);
CBasePlayer *pPlayer = (CBasePlayer *)g_ReGameFuncs->UTIL_PlayerByIndex(params[arg_index]);
CBasePlayer *pPlayer = g_ReGameFuncs->UTIL_PlayerByIndex(params[arg_index]);
if (pPlayer == nullptr || pPlayer->has_disconnected) {
MF_LogError(amx, AMX_ERR_NATIVE, "%s: player %i is not connected", __FUNCTION__, params[arg_index]);
return FALSE;
@ -837,7 +825,7 @@ cell AMX_NATIVE_CALL rg_give_defusekit(AMX *amx, cell *params)
CHECK_ISPLAYER(arg_index);
CBasePlayer *pPlayer = (CBasePlayer *)g_ReGameFuncs->UTIL_PlayerByIndex(params[arg_index]);
CBasePlayer *pPlayer = g_ReGameFuncs->UTIL_PlayerByIndex(params[arg_index]);
if (pPlayer == nullptr || pPlayer->has_disconnected) {
MF_LogError(amx, AMX_ERR_NATIVE, "%s: player %i is not connected", __FUNCTION__, params[arg_index]);
return FALSE;
@ -891,7 +879,7 @@ cell AMX_NATIVE_CALL rg_get_user_armor(AMX *amx, cell *params)
CHECK_ISPLAYER(arg_index);
CBasePlayer *pPlayer = (CBasePlayer *)g_ReGameFuncs->UTIL_PlayerByIndex(params[arg_index]);
CBasePlayer *pPlayer = g_ReGameFuncs->UTIL_PlayerByIndex(params[arg_index]);
if (pPlayer == nullptr || pPlayer->has_disconnected) {
MF_LogError(amx, AMX_ERR_NATIVE, "%s: player %i is not connected", __FUNCTION__, params[arg_index]);
return FALSE;
@ -918,7 +906,7 @@ cell AMX_NATIVE_CALL rg_set_user_armor(AMX *amx, cell *params)
CHECK_ISPLAYER(arg_index);
CBasePlayer *pPlayer = (CBasePlayer *)g_ReGameFuncs->UTIL_PlayerByIndex(params[arg_index]);
CBasePlayer *pPlayer = g_ReGameFuncs->UTIL_PlayerByIndex(params[arg_index]);
if (pPlayer == nullptr || pPlayer->has_disconnected) {
MF_LogError(amx, AMX_ERR_NATIVE, "%s: player %i is not connected", __FUNCTION__, params[arg_index]);
return FALSE;
@ -938,6 +926,169 @@ cell AMX_NATIVE_CALL rg_set_user_armor(AMX *amx, cell *params)
return TRUE;
}
/*
* Sets the client's team without killing the player, and sets the client model.
*
* @param index Client index
* @param team Team id
* @param model Internal model
*
* @param send_teaminfo If true, a TeamInfo message will be sent
*
* @noreturn
*
* native rg_set_user_team(const index, {TeamName,_}:team, {ModelName,_}:model = MODEL_UNASSIGNED, bool:send_teaminfo = true);
*/
cell AMX_NATIVE_CALL rg_set_user_team(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_index, arg_team, arg_model, arg_sendinfo };
CHECK_ISPLAYER(arg_index);
CBasePlayer *pPlayer = g_ReGameFuncs->UTIL_PlayerByIndex(params[arg_index]);
if (pPlayer == nullptr || pPlayer->has_disconnected) {
MF_LogError(amx, AMX_ERR_NATIVE, "%s: player %i is not connected", __FUNCTION__, params[arg_index]);
return FALSE;
}
CAmxArgs args(amx, params);
TeamName prevTeam = pPlayer->m_iTeam;
pPlayer->m_iTeam = args[arg_team];
if (prevTeam != args[arg_team]) {
// next team
switch (pPlayer->m_iTeam) {
case TERRORIST:
CSGameRules()->m_iNumTerrorist++;
break;
case CT:
CSGameRules()->m_iNumCT++;
break;
}
// previous team
switch (prevTeam) {
case TERRORIST:
CSGameRules()->m_iNumTerrorist--;
if (pPlayer->m_bHasC4 && !CSGameRules()->m_fTeamCount && CSGameRules()->m_bMapHasBombTarget)
{
if (RemovePlayerItem(pPlayer, "weapon_c4")) {
pPlayer->m_bHasC4 = false;
pPlayer->pev->body = 0;
MESSAGE_BEGIN(MSG_ONE, gmsgStatusIcon, NULL, pPlayer->pev);
WRITE_BYTE(STATUSICON_HIDE);
WRITE_STRING("c4");
MESSAGE_END();
CSGameRules()->GiveC4();
}
}
break;
case CT:
CSGameRules()->m_iNumCT--;
if (pPlayer->m_bHasDefuser) {
pPlayer->m_bHasDefuser = false;
pPlayer->pev->body = 0;
MESSAGE_BEGIN(MSG_ONE, gmsgStatusIcon, NULL, pPlayer->pev);
WRITE_BYTE(STATUSICON_HIDE);
WRITE_STRING("defuser");
MESSAGE_END();
SendItemStatus(pPlayer);
}
break;
}
}
if (args[arg_model] != MODEL_UNASSIGNED) {
pPlayer->m_iModelName = args[arg_model];
}
pPlayer->CSPlayer()->SetPlayerModel(pPlayer->m_bHasC4);
if (params[arg_sendinfo] != 0) {
MESSAGE_BEGIN(MSG_ALL, gmsgTeamInfo);
WRITE_BYTE(args[arg_index]);
WRITE_STRING(GetTeamName(args[arg_team]));
MESSAGE_END();
}
g_amxxapi.SetPlayerTeamInfo(args[arg_index], args[arg_team], GetTeamName(args[arg_team]));
return TRUE;
}
/*
* Sets the client's player model.
*
* @param index Client index
* @param model Model name
* @param update_index If true, the modelindex is updated as well
*
* @noreturn
*
* native rg_set_user_model(const index, const model[], bool:update_index = false);
*/
cell AMX_NATIVE_CALL rg_set_user_model(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_index, arg_model, arg_update };
CHECK_ISPLAYER(arg_index);
CBasePlayer *pPlayer = g_ReGameFuncs->UTIL_PlayerByIndex(params[arg_index]);
if (pPlayer == nullptr || pPlayer->has_disconnected) {
MF_LogError(amx, AMX_ERR_NATIVE, "%s: player %i is not connected", __FUNCTION__, params[arg_index]);
return FALSE;
}
const char* newModel = getAmxString(amx, params[arg_model]);
if (*newModel == '\0') {
MF_LogError(amx, AMX_ERR_NATIVE, "Model can not be empty");
return FALSE;
}
pPlayer->CSPlayer()->SetPlayerModelEx(newModel);
pPlayer->CSPlayer()->SetPlayerModel(pPlayer->m_bHasC4);
if (params[arg_update] != 0)
{
char model[260];
snprintf(model, sizeof(model), "models/player/%s/%s.mdl", newModel, newModel);
pPlayer->CSPlayer()->SetNewPlayerModel(model);
}
return TRUE;
}
/*
* Reset model user
*
* @param index Client index
*
* @noreturn
*
* native rg_reset_user_model(const index);
*/
cell AMX_NATIVE_CALL rg_reset_user_model(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_index, arg_team, arg_model };
CHECK_ISPLAYER(arg_index);
CBasePlayer *pPlayer = g_ReGameFuncs->UTIL_PlayerByIndex(params[arg_index]);
if (pPlayer == nullptr || pPlayer->has_disconnected) {
MF_LogError(amx, AMX_ERR_NATIVE, "%s: player %i is not connected", __FUNCTION__, params[arg_index]);
return FALSE;
}
pPlayer->CSPlayer()->SetPlayerModelEx("");
pPlayer->CSPlayer()->SetPlayerModel(pPlayer->m_bHasC4);
return TRUE;
}
AMX_NATIVE_INFO Misc_Natives_RG[] =
{
{ "rg_set_animation", rg_set_animation },
@ -975,6 +1126,11 @@ AMX_NATIVE_INFO Misc_Natives_RG[] =
{ "rg_get_user_armor", rg_get_user_armor },
{ "rg_set_user_armor", rg_set_user_armor },
{ "rg_set_user_team", rg_set_user_team },
{ "rg_set_user_model", rg_set_user_model },
{ "rg_reset_user_model", rg_reset_user_model },
{ nullptr, nullptr }
};

View File

@ -24,3 +24,42 @@ void UpdateTeamScores()
g_pengfuncsTable->pfnWriteShort(CSGameRules()->m_iNumTerroristWins);
g_pengfuncsTable->pfnMessageEnd();
}
bool RemovePlayerItem(CBasePlayer *pPlayer, const char* szItemName)
{
for (auto pItem : pPlayer->m_rgpPlayerItems) {
while (pItem != nullptr)
{
if (FClassnameIs(pItem->pev, szItemName))
{
CBasePlayerWeapon *pWeapon = static_cast<CBasePlayerWeapon *>(pItem);
if (pWeapon->IsWeapon()) {
pWeapon->RetireWeapon();
}
pPlayer->pev->weapons &= ~(1 << pItem->m_iId);
pPlayer->RemovePlayerItem(pItem);
pItem->Kill();
return true;
}
pItem = pItem->m_pNext;
}
}
return false;
}
void SendItemStatus(CBasePlayer *pPlayer)
{
int itemStatus = 0;
if (pPlayer->m_bHasNightVision)
itemStatus |= ITEM_STATUS_NIGHTVISION;
if (pPlayer->m_bHasDefuser)
itemStatus |= ITEM_STATUS_DEFUSER;
MESSAGE_BEGIN(MSG_ONE, gmsgItemStatus, NULL, pPlayer->pev);
WRITE_BYTE(itemStatus);
MESSAGE_END();
}

View File

@ -102,7 +102,24 @@ inline bool GetWeaponInfoRange(WeaponIdType wpnid)
return false;
}
inline const char *GetTeamName(TeamName team)
{
switch (team)
{
case CT:
return "CT";
case TERRORIST:
return "TERRORIST";
case SPECTATOR:
return "SPECTATOR";
default:
return "UNASSIGNED";
}
}
void Broadcast(const char *sentence);
void UpdateTeamScores();
bool RemovePlayerItem(CBasePlayer *pPlayer, const char* szItemName);
void SendItemStatus(CBasePlayer *pPlayer);
extern void __declspec(noreturn) UTIL_SysError(const char *fmt, ...);

View File

@ -4,5 +4,5 @@
#define _reapi_version_included
// reapi version
#define REAPI_VERSION_MAJOR 1
#define REAPI_VERSION_MAJOR 2
#define REAPI_VERSION_MINOR 0