static cell_t GetClientEyePosition(IPluginContext *pContext, const cell_t *params) { IGamePlayer *player = playerhelpers->GetGamePlayer(params[1]); if (player == NULL) { return pContext->ThrowNativeError("Invalid client index %d", params[1]); } if (!player->IsInGame()) { return pContext->ThrowNativeError("Client %d is not in game", params[1]); } Vector pos; #if SOURCE_ENGINE == SE_DOTA serverClients->ClientEarPosition(params[1], &pos); #else serverClients->ClientEarPosition(player->GetEdict(), &pos); #endif cell_t *addr; pContext->LocalToPhysAddr(params[2], &addr); addr[0] = sp_ftoc(pos.x); addr[1] = sp_ftoc(pos.y); addr[2] = sp_ftoc(pos.z); return 1; }
static cell_t DisplayTopMenu(IPluginContext *pContext, const cell_t *params) { HandleError err; ITopMenu *pMenu; HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); if ((err = handlesys->ReadHandle(params[1], hTopMenuType, &sec, (void **)&pMenu)) != HandleError_None) { return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err); } int client = params[2]; IGamePlayer *player = playerhelpers->GetGamePlayer(client); if (!player) { return pContext->ThrowNativeError("Invalid client index %d", client); } else if (!player->IsInGame()) { return pContext->ThrowNativeError("Client %d is not in game", client); } return pMenu->DisplayMenu(client, 0, (TopMenuPosition)params[3]); }
bool InitialiseConditionChecks() { sm_sendprop_info_t prop; if (!gamehelpers->FindSendPropInfo("CTFPlayer", "m_nPlayerCond", &prop)) { g_pSM->LogError(myself, "Failed to find m_nPlayerCond prop offset"); return false; } playerCondOffset = prop.actual_offset; if (!gamehelpers->FindSendPropInfo("CTFPlayer", "_condition_bits", &prop)) { g_pSM->LogError(myself, "Failed to find _condition_bits prop offset"); return false; } conditionBitsOffset = prop.actual_offset; if (!gamehelpers->FindSendPropInfo("CTFPlayer", "m_nPlayerCondEx", &prop)) { g_pSM->LogError(myself, "Failed to find m_nPlayerCondEx prop offset"); return false; } playerCondExOffset = prop.actual_offset; if (!gamehelpers->FindSendPropInfo("CTFPlayer", "m_nPlayerCondEx2", &prop)) { g_pSM->LogError(myself, "Failed to find m_nPlayerCondEx2 prop offset"); return false; } playerCondEx2Offset = prop.actual_offset; if (!gamehelpers->FindSendPropInfo("CTFPlayer", "m_nPlayerCondEx3", &prop)) { g_pSM->LogError(myself, "Failed to find m_nPlayerCondEx3 prop offset"); return false; } playerCondEx3Offset = prop.actual_offset; if (playerCondOffset == -1 || playerCondExOffset == -1 || conditionBitsOffset == -1 || playerCondEx2Offset == -1 || playerCondEx3Offset == -1) return false; int maxClients = gpGlobals->maxClients; for (int i = 1; i <= maxClients; i++) { IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(i); if (!pPlayer || !pPlayer->IsInGame()) continue; GetPlayerConds(gamehelpers->ReferenceToEntity(i), &g_PlayerActiveConds[i]); } g_pSM->AddGameFrameHook(Conditions_OnGameFrame); return true; }
static cell_t SetClientViewEntity(IPluginContext *pContext, const cell_t *params) { IGamePlayer *player = playerhelpers->GetGamePlayer(params[1]); if (player == NULL) { return pContext->ThrowNativeError("Invalid client index %d", params[1]); } if (!player->IsInGame()) { return pContext->ThrowNativeError("Client %d is not in game", params[1]); } edict_t *pEdict = PEntityOfEntIndex(gamehelpers->ReferenceToIndex(params[2])); if (!pEdict || pEdict->IsFree()) { return pContext->ThrowNativeError("Entity %d is not valid", params[2]); } #if SOURCE_ENGINE == SE_DOTA engine->SetView(params[1], params[2]); #else engine->SetView(player->GetEdict(), pEdict); #endif return 1; }
static cell_t GetPlayerMaxs(IPluginContext *pContext, const cell_t *params) { int client = params[1]; IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client); if (!pPlayer) { return pContext->ThrowNativeError("Client index %d is invalid", client); } else if (!pPlayer->IsInGame()) { return pContext->ThrowNativeError("Client %d is not in game", client); } IPlayerInfo *pInfo = pPlayer->GetPlayerInfo(); if (!pInfo) { return pContext->ThrowNativeError("IPlayerInfo not supported by game"); } cell_t *pVec; pContext->LocalToPhysAddr(params[2], &pVec); float x, y, z; bridge->playerInfo->GetPlayerMaxs(pInfo, &x, &y, &z); pVec[0] = sp_ftoc(x); pVec[1] = sp_ftoc(y); pVec[2] = sp_ftoc(z); return 1; }
static cell_t FadeClientVolume(IPluginContext *pContext, const cell_t *params) { int client = params[1]; if (client < 1 || client > playerhelpers->GetMaxClients()) { return pContext->ThrowNativeError("Client index %d is not valid", client); } IGamePlayer *player = playerhelpers->GetGamePlayer(client); if (!player->IsInGame()) { return pContext->ThrowNativeError("Client index %d is not in game", client); } engine->FadeClientVolume( #if SOURCE_ENGINE == SE_DOTA player->GetIndex(), #else player->GetEdict(), #endif sp_ctof(params[2]), sp_ctof(params[3]), sp_ctof(params[4]), sp_ctof(params[5])); return 1; }
static cell_t GetPlayerDecalFile(IPluginContext *pContext, const cell_t *params) { IGamePlayer *player = playerhelpers->GetGamePlayer(params[1]); if (player == NULL) { return pContext->ThrowNativeError("Invalid client index %d", params[1]); } if (!player->IsInGame()) { return pContext->ThrowNativeError("Client %d is not in game", params[1]); } player_info_t info; char *buffer; if (!GetPlayerInfo(params[1], &info) || !info.customFiles[0]) { return 0; } pContext->LocalToString(params[2], &buffer); Q_binarytohex((byte *)&info.customFiles[0], sizeof(info.customFiles[0]), buffer, params[3]); return 1; }
bool PlayerConditionsMgr::Init() { memset(m_BackupProxyFns, 0, sizeof(m_BackupProxyFns)); bool bFoundProps = SetupProp<m_nPlayerCond>("m_nPlayerCond") && SetupProp<_condition_bits>("_condition_bits") && SetupProp<m_nPlayerCondEx>("m_nPlayerCondEx") && SetupProp<m_nPlayerCondEx2>("m_nPlayerCondEx2") && SetupProp<m_nPlayerCondEx3>("m_nPlayerCondEx3") && SetupProp<m_nPlayerCondEx4>("m_nPlayerCondEx4"); if (!bFoundProps) return false; playerhelpers->AddClientListener(this); int maxClients = gpGlobals->maxClients; for (int i = 1; i <= maxClients; i++) { IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(i); if (!pPlayer || !pPlayer->IsInGame()) continue; CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(i); for (size_t j = 0; j < CondVar_Count; ++j) { m_OldConds[i][j] = *(int *)((intp) pEntity + GetPropOffs((CondVar)j)); } } return true; }
bool BaseBuiltinVoteStyle::DoClientVote(int clients[], unsigned int num_clients, IBaseBuiltinVote *vote, IBuiltinVoteHandler *bvh) { unsigned int totalPlayers = 0; int realClients[256+1]; for (unsigned int i=0; i<num_clients;i++) { IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(clients[i]); CBaseBuiltinVotePlayer *player = GetVotePlayer(clients[i]); vote_states_t &states = player->states; if (!pPlayer || pPlayer->IsFakeClient() || !pPlayer->IsInGame()) { states.vote = NULL; states.bvh = NULL; continue; } states.vote = vote; states.bvh = bvh; states.apiVers = SMINTERFACE_BUILTINVOTES_VERSION; realClients[totalPlayers++] = clients[i]; } if (totalPlayers > 0) { vote->Display(realClients, totalPlayers); //SendDisplay(realClients, totalPlayers, vote); return true; } else { return false; } }
static cell_t GetClientEyeAngles(IPluginContext *pContext, const cell_t *params) { IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(params[1]); if (!pPlayer) { return pContext->ThrowNativeError("Invalid client index %d", params[1]); } else if (!pPlayer->IsInGame()) { return pContext->ThrowNativeError("Client %d is not in game", params[1]); } edict_t *pEdict = pPlayer->GetEdict(); CBaseEntity *pEntity = pEdict->GetUnknown() ? pEdict->GetUnknown()->GetBaseEntity() : NULL; /* We always set the angles for backwards compatibility -- * The original function had no return value. */ QAngle angles; bool got_angles = false; if (pEntity != NULL) { got_angles = GetEyeAngles(pEntity, &angles); } cell_t *addr; pContext->LocalToPhysAddr(params[2], &addr); addr[0] = sp_ftoc(angles.x); addr[1] = sp_ftoc(angles.y); addr[2] = sp_ftoc(angles.z); return got_angles ? 1 : 0; }
bool TopMenu::DisplayMenu(int client, unsigned int hold_time, TopMenuPosition position) { if (m_clients == NULL) { return false; } IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client); if (!pPlayer->IsInGame()) { return false; } UpdateClientRoot(client, pPlayer); /* This is unfortunate but it's the best solution. */ for (size_t i = 0; i < m_Categories.size(); i++) { UpdateClientCategory(client, i, true); } topmenu_player_t *pClient = &m_clients[client]; if (pClient->root == NULL) { return false; } if (!m_bCacheTitles) { char renderbuf[128]; m_pTitle->OnTopMenuDisplayTitle(this, client, 0, renderbuf, sizeof(renderbuf)); pClient->root->SetDefaultTitle(renderbuf); } bool return_value = false; if (position == TopMenuPosition_LastCategory && pClient->last_category < m_Categories.size()) { return_value = DisplayCategory(client, pClient->last_category, hold_time, true); if (!return_value) { return_value = pClient->root->DisplayAtItem(client, hold_time, pClient->last_root_pos); } } else if (position == TopMenuPosition_LastRoot) { pClient->root->DisplayAtItem(client, hold_time, pClient->last_root_pos); } else if (position == TopMenuPosition_Start) { pClient->last_position = 0; pClient->last_category = 0; return_value = pClient->root->Display(client, hold_time); } return return_value; }
int GetClientAimTarget(edict_t *pEdict, bool only_players) { CBaseEntity *pEntity = pEdict->GetUnknown() ? pEdict->GetUnknown()->GetBaseEntity() : NULL; if (pEntity == NULL) { return -1; } Vector eye_position; QAngle eye_angles; /* Get the private information we need */ #if SOURCE_ENGINE == SE_DOTA serverClients->ClientEarPosition(IndexOfEdict(pEdict), &eye_position); #else serverClients->ClientEarPosition(pEdict, &eye_position); #endif if (!GetEyeAngles(pEntity, &eye_angles)) { return -2; } Vector aim_dir; AngleVectors(eye_angles, &aim_dir); VectorNormalize(aim_dir); Vector vec_end = eye_position + aim_dir * 8000; Ray_t ray; ray.Init(eye_position, vec_end); trace_t tr; CTraceFilterSimple simple(pEdict->GetIServerEntity()); enginetrace->TraceRay(ray, MASK_SOLID|CONTENTS_DEBRIS|CONTENTS_HITBOX, &simple, &tr); if (tr.fraction == 1.0f || tr.m_pEnt == NULL) { return -1; } int ent_ref = gamehelpers->EntityToBCompatRef(tr.m_pEnt); int ent_index = gamehelpers->ReferenceToIndex(ent_ref); IGamePlayer *pTargetPlayer = playerhelpers->GetGamePlayer(ent_index); if (pTargetPlayer != NULL && !pTargetPlayer->IsInGame()) { return -1; } else if (only_players && pTargetPlayer == NULL) { return -1; } return ent_ref; }
static cell_t sm_GetClientAimTarget(IPluginContext *pContext, const cell_t *params) { IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(params[1]); if (!pPlayer) { return pContext->ThrowNativeError("Invalid client index %d", params[1]); } else if (!pPlayer->IsInGame()) { return pContext->ThrowNativeError("Client %d is not in game", params[1]); } return GetClientAimTarget(pPlayer->GetEdict(), params[2] ? true : false); }
DETOUR_DECL_MEMBER1(GetEventChangeAttributes, int, char const*, attribute) { int index = gamehelpers->EntityToBCompatRef(reinterpret_cast<CBaseEntity *>(this)); if (index > 0 && index <= playerhelpers->GetMaxClients()) { IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(index); if (pPlayer->IsConnected() && pPlayer->IsInGame() && !pPlayer->IsFakeClient()) { return 0; } } return DETOUR_MEMBER_CALL(GetEventChangeAttributes)(attribute); }
void Conditions_OnGameFrame(bool simulating) { if (!simulating) return; static condbitvec_t newconds; static condbitvec_t addedconds; static condbitvec_t removedconds; int maxClients = gpGlobals->maxClients; for (int i = 1; i <= maxClients; i++) { IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(i); if (!pPlayer->IsInGame() || pPlayer->IsSourceTV() || pPlayer->IsReplay()) continue; CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(i); condbitvec_t &oldconds = g_PlayerActiveConds[i]; GetPlayerConds(pEntity, &newconds); if (oldconds == newconds) continue; CondBitVecAndNot(newconds, oldconds, &addedconds); CondBitVecAndNot(oldconds, newconds, &removedconds); int bit; bit = -1; while ((bit = addedconds.FindNextSetBit(bit + 1)) != -1) { g_addCondForward->PushCell(i); g_addCondForward->PushCell(bit); g_addCondForward->Execute(NULL, NULL); } bit = -1; while ((bit = removedconds.FindNextSetBit(bit + 1)) != -1) { g_removeCondForward->PushCell(i); g_removeCondForward->PushCell(bit); g_removeCondForward->Execute(NULL, NULL); } g_PlayerActiveConds[i] = newconds; } }
bool TopMenu::DisplayMenuAtCategory(int client, unsigned int object_id) { if (m_clients == NULL) { return false; } IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client); if (!pPlayer->IsInGame()) { return false; } // Get the category this object is in. size_t category_id; if (!FindCategoryByObject(object_id, &category_id)) { return false; } topmenu_category_t *category = m_Categories[category_id]; UpdateClientRoot(client, pPlayer); topmenu_player_t *pClient = &m_clients[client]; if (pClient->root == NULL) { return false; } if (!m_bCacheTitles) { char renderbuf[128]; m_pTitle->OnTopMenuDisplayTitle(this, client, 0, renderbuf, sizeof(renderbuf)); pClient->root->SetDefaultTitle(renderbuf); } bool return_value = false; return_value = DisplayCategory(client, category_id, 0, true); if (!return_value) { return_value = pClient->root->DisplayAtItem(client, 0, pClient->last_root_pos); } return return_value; }
cell_t GetSurvivorScore(IPluginContext *pContext, const cell_t *params) { CBaseEntity *pPlayer = gamehelpers->ReferenceToEntity(params[1]); if (!pPlayer) return pContext->ThrowNativeError("Invalid client index %d", params[1]); cell_t client = gamehelpers->ReferenceToIndex(params[1]); IGamePlayer *pGamePlayer = playerhelpers->GetGamePlayer(client); if (!pGamePlayer || !pGamePlayer->IsInGame()) return pContext->ThrowNativeError("Client index %d not in game", params[1]); IPlayerInfo* pInfo = pGamePlayer->GetPlayerInfo(); if(!pInfo || pInfo->IsObserver() || pInfo->GetTeamIndex() != 2) return -1; return Detours::g_scores[client]; }
static void ReplicateConVar(ConVar *pConVar) { int maxClients = g_Interfaces.GlobalVarsInstance->maxClients; char data[256]; bf_write buffer(data, sizeof(data)); buffer.WriteUBitLong(NET_SETCONVAR, NETMSG_BITS); buffer.WriteByte(1); buffer.WriteString(pConVar->GetName()); buffer.WriteString(pConVar->GetString()); for(int i = 1; i <= maxClients; i++) { IGamePlayer *gamePlayer = playerhelpers->GetGamePlayer(i); if (gamePlayer->IsConnected() && gamePlayer->IsInGame() && !gamePlayer->IsFakeClient()) { if (INetChannel *netchan = static_cast<INetChannel *>(engine->GetPlayerNetInfo(i))) netchan->SendData(buffer); } } }
static cell_t sm_GetClientCount(IPluginContext *pCtx, const cell_t *params) { if (params[1]) { return playerhelpers->GetNumPlayers(); } int maxplayers = playerhelpers->GetMaxClients(); int count = 0; for (int i = 1; i <= maxplayers; ++i) { IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(i); if ((pPlayer->IsConnected()) && !(pPlayer->IsInGame())) { count++; } } return (playerhelpers->GetNumPlayers() + count); }
static cell_t smn_TESend(IPluginContext *pContext, const cell_t *params) { if (!g_TEManager.IsAvailable()) { return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report"); } if (!g_CurrentTE) { return pContext->ThrowNativeError("No TempEntity call is in progress"); } cell_t *cl_array; unsigned int numClients; int client; IGamePlayer *pPlayer = NULL; pContext->LocalToPhysAddr(params[1], &cl_array); numClients = params[2]; /* Client validation */ for (unsigned int i = 0; i < numClients; i++) { client = cl_array[i]; pPlayer = playerhelpers->GetGamePlayer(client); if (!pPlayer) { return pContext->ThrowNativeError("Client index %d is invalid", client); } else if (!pPlayer->IsInGame()) { return pContext->ThrowNativeError("Client %d is not connected", client); } } g_TERecFilter.Reset(); g_TERecFilter.Initialize(cl_array, numClients); g_CurrentTE->Send(g_TERecFilter, sp_ctof(params[3])); g_CurrentTE = NULL; return 1; }
static cell_t NotifyPostAdminCheck(IPluginContext *pContext, const cell_t *params) { int client = params[1]; IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client); if (!pPlayer) { return pContext->ThrowNativeError("Client index %d is invalid", client); } else if (!pPlayer->IsInGame()) { return pContext->ThrowNativeError("Client %d is not in game", client); } else if (!pPlayer->IsAuthorized()) { return pContext->ThrowNativeError("Client %d is not authorized", client); } pPlayer->NotifyPostAdminChecks(); return 1; }
static cell_t GetArmorValue(IPluginContext *pContext, const cell_t *params) { int client = params[1]; IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client); if (!pPlayer) { return pContext->ThrowNativeError("Client index %d is invalid", client); } else if (!pPlayer->IsInGame()) { return pContext->ThrowNativeError("Client %d is not in game", client); } IPlayerInfo *pInfo = pPlayer->GetPlayerInfo(); if (!pInfo) { return pContext->ThrowNativeError("IPlayerInfo not supported by game"); } return bridge->playerInfo->GetArmorValue(pInfo); }
static cell_t GetWeaponName(IPluginContext *pContext, const cell_t *params) { int client = params[1]; IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client); if (!pPlayer) { return pContext->ThrowNativeError("Client index %d is invalid", client); } else if (!pPlayer->IsInGame()) { return pContext->ThrowNativeError("Client %d is not in game", client); } IPlayerInfo *pInfo = pPlayer->GetPlayerInfo(); if (!pInfo) { return pContext->ThrowNativeError("IPlayerInfo not supported by game"); } const char *weapon = bridge->playerInfo->GetWeaponName(pInfo); pContext->StringToLocalUTF8(params[2], static_cast<size_t>(params[3]), weapon ? weapon : "", NULL); return 1; }
DataStatus DecodeValveParam(IPluginContext *pContext, cell_t param, const ValveCall *pCall, const ValvePassInfo *data, void *_buffer) { void *buffer = (unsigned char *)_buffer + data->offset; switch (data->vtype) { case Valve_Vector: { cell_t *addr; int err; err = pContext->LocalToPhysAddr(param, &addr); unsigned char *mem = (unsigned char *)buffer; if (data->type == PassType_Basic) { /* Store the object in the next N bytes, and store * a pointer to that object right beforehand. */ Vector **realPtr = (Vector **)buffer; if (addr == pContext->GetNullRef(SP_NULL_VECTOR)) { if (data->decflags & VDECODE_FLAG_ALLOWNULL) { *realPtr = NULL; return Data_Okay; } else { pContext->ThrowNativeError("NULL not allowed"); return Data_Fail; } } else { mem = (unsigned char *)_buffer + pCall->stackEnd + data->obj_offset; *realPtr = (Vector *)mem; } } if (err != SP_ERROR_NONE) { pContext->ThrowNativeErrorEx(err, "Could not read plugin data"); return Data_Fail; } /* Use placement new to initialize the object cleanly * This has no destructor so we don't need to do * DestroyValveParam() or something :] */ Vector *v = new (mem) Vector( sp_ctof(addr[0]), sp_ctof(addr[1]), sp_ctof(addr[2])); return Data_Okay; } case Valve_QAngle: { cell_t *addr; int err; err = pContext->LocalToPhysAddr(param, &addr); unsigned char *mem = (unsigned char *)buffer; if (data->type == PassType_Basic) { /* Store the object in the next N bytes, and store * a pointer to that object right beforehand. */ QAngle **realPtr = (QAngle **)buffer; if (addr == pContext->GetNullRef(SP_NULL_VECTOR)) { if (!(data->decflags & VDECODE_FLAG_ALLOWNULL)) { pContext->ThrowNativeError("NULL not allowed"); return Data_Fail; } else { *realPtr = NULL; return Data_Okay; } } else { mem = (unsigned char *)_buffer + pCall->stackEnd + data->obj_offset; *realPtr = (QAngle *)mem; } } if (err != SP_ERROR_NONE) { pContext->ThrowNativeErrorEx(err, "Could not read plugin data"); return Data_Fail; } /* Use placement new to initialize the object cleanly * This has no destructor so we don't need to do * DestroyValveParam() or something :] */ QAngle *v = new (mem) QAngle( sp_ctof(addr[0]), sp_ctof(addr[1]), sp_ctof(addr[2])); return Data_Okay; } case Valve_CBasePlayer: { CBaseEntity *pEntity = NULL; if (data->decflags & VDECODE_FLAG_BYREF) { cell_t *addr; pContext->LocalToPhysAddr(param, &addr); param = *addr; } int index = gamehelpers->ReferenceToIndex(param); if ((unsigned)index == INVALID_EHANDLE_INDEX && param != -1) { return Data_Fail; } if (index >= 1 && index <= playerhelpers->GetMaxClients()) { IGamePlayer *player = playerhelpers->GetGamePlayer(index); if ((data->decflags & VDECODE_FLAG_ALLOWNOTINGAME) && !player->IsConnected()) { pContext->ThrowNativeError("Client %d is not connected", param); return Data_Fail; } else if (!player->IsInGame()) { pContext->ThrowNativeError("Client %d is not in game", param); return Data_Fail; } pEntity = gamehelpers->ReferenceToEntity(param); } else if (param == -1) { if (data->decflags & VDECODE_FLAG_ALLOWNULL) { pEntity = NULL; } else { pContext->ThrowNativeError("NULL not allowed"); return Data_Fail; } } else { pContext->ThrowNativeError("Entity index %d is not a valid client", param); return Data_Fail; } CBaseEntity **ebuf = (CBaseEntity **)buffer; *ebuf = pEntity; return Data_Okay; } case Valve_CBaseEntity: { CBaseEntity *pEntity = NULL; if (data->decflags & VDECODE_FLAG_BYREF) { cell_t *addr; pContext->LocalToPhysAddr(param, &addr); param = *addr; } int index = gamehelpers->ReferenceToIndex(param); if ((unsigned)index == INVALID_EHANDLE_INDEX && param != -1) { return Data_Fail; } if (index >= 1 && index <= playerhelpers->GetMaxClients()) { IGamePlayer *player = playerhelpers->GetGamePlayer(index); if ((data->decflags & VDECODE_FLAG_ALLOWNOTINGAME) && !player->IsConnected()) { pContext->ThrowNativeError("Client %d is not connected", param); return Data_Fail; } else if (!player->IsInGame()) { pContext->ThrowNativeError("Client %d is not in game", param); return Data_Fail; } pEntity = gamehelpers->ReferenceToEntity(param); } else if (param == -1) { if (data->decflags & VDECODE_FLAG_ALLOWNULL) { pEntity = NULL; } else { pContext->ThrowNativeError("NULL not allowed"); return Data_Fail; } } else if (index == 0) { if (data->decflags & VDECODE_FLAG_ALLOWWORLD) { pEntity = gamehelpers->ReferenceToEntity(0); } else { pContext->ThrowNativeError("World not allowed"); return Data_Fail; } } else { pEntity = gamehelpers->ReferenceToEntity(param); if (!pEntity) { pContext->ThrowNativeError("Entity %d is not valid", param); return Data_Fail; } } CBaseEntity **ebuf = (CBaseEntity **)buffer; *ebuf = pEntity; return Data_Okay; } case Valve_Edict: { edict_t *pEdict; if (data->decflags & VDECODE_FLAG_BYREF) { cell_t *addr; pContext->LocalToPhysAddr(param, &addr); param = *addr; } if (param >= 1 && param <= playerhelpers->GetMaxClients()) { IGamePlayer *player = playerhelpers->GetGamePlayer(param); if ((data->decflags & VDECODE_FLAG_ALLOWNOTINGAME) && !player->IsConnected()) { pContext->ThrowNativeError("Client %d is not connected", param); return Data_Fail; } else if (!player->IsInGame()) { pContext->ThrowNativeError("Client %d is not in game", param); return Data_Fail; } pEdict = player->GetEdict(); } else if (param == -1) { if (data->decflags & VDECODE_FLAG_ALLOWNULL) { pEdict = NULL; } else { pContext->ThrowNativeError("NULL not allowed"); return Data_Fail; } } else if (param == 0) { if (data->decflags & VDECODE_FLAG_ALLOWWORLD) { pEdict = PEntityOfEntIndex(0); } else { pContext->ThrowNativeError("World not allowed"); return Data_Fail; } } else { pEdict = PEntityOfEntIndex(param); if (!pEdict || pEdict->IsFree()) { pContext->ThrowNativeError("Entity %d is not valid or is freed", param); return Data_Fail; } } edict_t **ebuf = (edict_t **)buffer; *ebuf = pEdict; return Data_Okay; } case Valve_POD: case Valve_Float: { if (data->decflags & VDECODE_FLAG_BYREF) { cell_t *addr; pContext->LocalToPhysAddr(param, &addr); param = *addr; } if (data->flags & PASSFLAG_ASPOINTER) { *(void **)buffer = (unsigned char *)_buffer + pCall->stackEnd + data->obj_offset; buffer = *(void **)buffer; } *(cell_t *)buffer = param; return Data_Okay; } case Valve_Bool: { if (data->decflags & VDECODE_FLAG_BYREF) { cell_t *addr; pContext->LocalToPhysAddr(param, &addr); param = *addr; } if (data->flags & PASSFLAG_ASPOINTER) { *(bool **)buffer = (bool *)((unsigned char *)_buffer + pCall->stackEnd + data->obj_offset); buffer = *(bool **)buffer; } *(bool *)buffer = param ? true : false; return Data_Okay; } case Valve_String: { char *addr; pContext->LocalToString(param, &addr); *(char **)buffer = addr; return Data_Okay; } } return Data_Fail; }
static cell_t EmitSound(IPluginContext *pContext, const cell_t *params) { cell_t *addr, *cl_array; CellRecipientFilter crf; unsigned int numClients; int client; IGamePlayer *pPlayer = NULL; pContext->LocalToPhysAddr(params[1], &cl_array); numClients = params[2]; /* Client validation */ for (unsigned int i = 0; i < numClients; i++) { client = cl_array[i]; pPlayer = playerhelpers->GetGamePlayer(client); if (!pPlayer) { return pContext->ThrowNativeError("Client index %d is invalid", client); } else if (!pPlayer->IsInGame()) { return pContext->ThrowNativeError("Client %d is not connected", client); } } crf.Initialize(cl_array, numClients); char *sample; pContext->LocalToString(params[3], &sample); int entity = SoundReferenceToIndex(params[4]); int channel = params[5]; int level = params[6]; int flags = params[7]; float vol = sp_ctof(params[8]); int pitch = params[9]; int speakerentity = params[10]; Vector *pOrigin = NULL, origin; Vector *pDir = NULL, dir; pContext->LocalToPhysAddr(params[11], &addr); if (addr != pContext->GetNullRef(SP_NULL_VECTOR)) { pOrigin = &origin; origin.x = sp_ctof(addr[0]); origin.y = sp_ctof(addr[1]); origin.z = sp_ctof(addr[2]); } pContext->LocalToPhysAddr(params[12], &addr); if (addr != pContext->GetNullRef(SP_NULL_VECTOR)) { pDir = &dir; dir.x = sp_ctof(addr[0]); dir.y = sp_ctof(addr[1]); dir.z = sp_ctof(addr[2]); } bool updatePos = params[13] ? true : false; float soundtime = sp_ctof(params[14]); CUtlVector<Vector> *pOrigVec = NULL; CUtlVector<Vector> origvec; if (params[0] > 14) { pOrigVec = &origvec; for (cell_t i = 15; i <= params[0]; i++) { Vector vec; pContext->LocalToPhysAddr(params[i], &addr); vec.x = sp_ctof(addr[0]); vec.y = sp_ctof(addr[1]); vec.z = sp_ctof(addr[2]); origvec.AddToTail(vec); } } /* If we're going to a "local player" and this is a dedicated server, * intelligently redirect each sound. */ if (entity == -2 && engine->IsDedicatedServer()) { for (unsigned int i = 0; i < numClients; i++) { cell_t player[1]; player[0] = cl_array[i]; crf.Reset(); crf.Initialize(player, 1); #if SOURCE_ENGINE >= SE_PORTAL2 if (g_InSoundHook) { SH_CALL(enginesoundPatch, static_cast<int (IEngineSound::*)(IRecipientFilter &, int, int, const char*, unsigned int, const char*, float, soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)> (&IEngineSound::EmitSound)) (crf, player[0], channel, sample, -1, sample, vol, (soundlevel_t)level, 0, flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } else { engsound->EmitSound(crf, player[0], channel, sample, -1, sample, vol, (soundlevel_t)level, 0, flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } #elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 \ || SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_TF2 if (g_InSoundHook) { SH_CALL(enginesoundPatch, static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char*, float, soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)> (&IEngineSound::EmitSound)) (crf, player[0], channel, sample, vol, (soundlevel_t)level, flags, pitch, 0, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } else { engsound->EmitSound(crf, player[0], channel, sample, vol, (soundlevel_t)level, flags, pitch, 0, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } #else if (g_InSoundHook) { SH_CALL(enginesoundPatch, static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char*, float, soundlevel_t, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)> (&IEngineSound::EmitSound)) (crf, player[0], channel, sample, vol, (soundlevel_t)level, flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } else { engsound->EmitSound(crf, player[0], channel, sample, vol, (soundlevel_t)level, flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } #endif } } else { #if SOURCE_ENGINE >= SE_PORTAL2 if (g_InSoundHook) { SH_CALL(enginesoundPatch, static_cast<int (IEngineSound::*)(IRecipientFilter &, int, int, const char*, unsigned int, const char*, float, soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)> (&IEngineSound::EmitSound)) (crf, entity, channel, sample, -1, sample, vol, (soundlevel_t)level, 0, flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } else { engsound->EmitSound(crf, entity, channel, sample, -1, sample, vol, (soundlevel_t)level, 0, flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } #elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 \ || SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_TF2 if (g_InSoundHook) { SH_CALL(enginesoundPatch, static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char*, float, soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)> (&IEngineSound::EmitSound)) (crf, entity, channel, sample, vol, (soundlevel_t)level, flags, pitch, 0, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } else { engsound->EmitSound(crf, entity, channel, sample, vol, (soundlevel_t)level, flags, pitch, 0, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } #else if (g_InSoundHook) { SH_CALL(enginesoundPatch, static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char*, float, soundlevel_t, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)> (&IEngineSound::EmitSound)) (crf, entity, channel, sample, vol, (soundlevel_t)level, flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } else { engsound->EmitSound(crf, entity, channel, sample, vol, (soundlevel_t)level, flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } #endif } return 1; }
void SoundHooks::OnEmitSound2(IRecipientFilter &filter, int iEntIndex, int iChannel, const char *pSample, float flVolume, float flAttenuation, int iFlags, int iPitch, const Vector *pOrigin, const Vector *pDirection, CUtlVector<Vector> *pUtlVecOrigins, bool bUpdatePositions, float soundtime, int speakerentity) #endif { SoundHookIter iter; IPluginFunction *pFunc; cell_t res = static_cast<ResultType>(Pl_Continue); cell_t sndlevel = static_cast<cell_t>(ATTN_TO_SNDLVL(flAttenuation)); char buffer[PLATFORM_MAX_PATH]; strcpy(buffer, pSample); char soundEntry[PLATFORM_MAX_PATH] = ""; #if SOURCE_ENGINE >= SE_PORTAL2 Q_strncpy(soundEntry, pSoundEntry, sizeof(soundEntry)); #endif #if SOURCE_ENGINE < SE_PORTAL2 int nSeed = 0; #endif for (iter=m_NormalFuncs.begin(); iter!=m_NormalFuncs.end(); iter++) { int players[SM_MAXPLAYERS], size; size = _FillInPlayers(players, &filter); pFunc = (*iter); pFunc->PushArray(players, SM_ARRAYSIZE(players), SM_PARAM_COPYBACK); pFunc->PushCellByRef(&size); pFunc->PushStringEx(buffer, sizeof(buffer), SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK); pFunc->PushCellByRef(&iEntIndex); pFunc->PushCellByRef(&iChannel); pFunc->PushFloatByRef(&flVolume); pFunc->PushCellByRef(&sndlevel); pFunc->PushCellByRef(&iPitch); pFunc->PushCellByRef(&iFlags); pFunc->PushStringEx(soundEntry, sizeof(soundEntry), SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK); pFunc->PushCellByRef(&nSeed); g_InSoundHook = true; pFunc->Execute(&res); g_InSoundHook = false; switch (res) { case Pl_Handled: case Pl_Stop: { #if SOURCE_ENGINE >= SE_PORTAL2 RETURN_META_VALUE(MRES_SUPERCEDE, -1); #else RETURN_META(MRES_SUPERCEDE); #endif } case Pl_Changed: { /* Client validation */ for (int i = 0; i < size; i++) { int client = players[i]; IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client); if (!pPlayer) { pFunc->GetParentContext()->BlamePluginError(pFunc, "Client index %d is invalid", client); } else if (!pPlayer->IsInGame()) { pFunc->GetParentContext()->BlamePluginError(pFunc, "Client %d is not connected", client); } else { continue; } #if SOURCE_ENGINE >= SE_PORTAL2 RETURN_META_VALUE(MRES_IGNORED, -1 ); #else return; #endif } #if SOURCE_ENGINE >= SE_PORTAL2 if (strcmp(pSoundEntry, soundEntry) != 0 || strcmp(pSample, buffer) != 0) { if (strcmp(soundEntry, buffer) == 0) nSoundEntryHash = -1; else if (strcmp(soundEntry, "") != 0) nSoundEntryHash = GenerateSoundEntryHash(soundEntry); } #endif CellRecipientFilter crf; crf.Initialize(players, size); #if SOURCE_ENGINE >= SE_PORTAL2 RETURN_META_VALUE_NEWPARAMS( MRES_IGNORED, -1, static_cast<int (IEngineSound::*)(IRecipientFilter &, int, int, const char *, unsigned int, const char *, float, float, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>(&IEngineSound::EmitSound), (crf, iEntIndex, iChannel, soundEntry, nSoundEntryHash, buffer, flVolume, SNDLVL_TO_ATTN(static_cast<soundlevel_t>(sndlevel)), nSeed, iFlags, iPitch, pOrigin, pDirection, pUtlVecOrigins, bUpdatePositions, soundtime, speakerentity) ); #elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 \ || SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_TF2 RETURN_META_NEWPARAMS( MRES_IGNORED, static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char *, float, float, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>(&IEngineSound::EmitSound), (crf, iEntIndex, iChannel, buffer, flVolume, SNDLVL_TO_ATTN(static_cast<soundlevel_t>(sndlevel)), iFlags, iPitch, iSpecialDSP, pOrigin, pDirection, pUtlVecOrigins, bUpdatePositions, soundtime, speakerentity) ); #else RETURN_META_NEWPARAMS( MRES_IGNORED, static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char *, float, float, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>(&IEngineSound::EmitSound), (crf, iEntIndex, iChannel, buffer, flVolume, SNDLVL_TO_ATTN(static_cast<soundlevel_t>(sndlevel)), iFlags, iPitch, pOrigin, pDirection, pUtlVecOrigins, bUpdatePositions, soundtime, speakerentity) ); #endif } } } #if SOURCE_ENGINE >= SE_PORTAL2 RETURN_META_VALUE(MRES_IGNORED, -1 ); #endif }
static cell_t EmitSentence(IPluginContext *pContext, const cell_t *params) { cell_t *addr; CellRecipientFilter crf; unsigned int numClients; int client; IGamePlayer *pPlayer = NULL; pContext->LocalToPhysAddr(params[1], &addr); numClients = params[2]; /* Client validation */ for (unsigned int i = 0; i < numClients; i++) { client = addr[i]; pPlayer = playerhelpers->GetGamePlayer(client); if (!pPlayer) { return pContext->ThrowNativeError("Client index %d is invalid", client); } else if (!pPlayer->IsInGame()) { return pContext->ThrowNativeError("Client %d is not connected", client); } } crf.Initialize(addr, numClients); int sentence = params[3]; int entity = SoundReferenceToIndex(params[4]); int channel = params[5]; int level = params[6]; int flags = params[7]; float vol = sp_ctof(params[8]); int pitch = params[9]; int speakerentity = params[10]; Vector *pOrigin = NULL, origin; Vector *pDir = NULL, dir; pContext->LocalToPhysAddr(params[11], &addr); if (addr != pContext->GetNullRef(SP_NULL_VECTOR)) { pOrigin = &origin; origin.x = sp_ctof(addr[0]); origin.y = sp_ctof(addr[1]); origin.z = sp_ctof(addr[2]); } pContext->LocalToPhysAddr(params[12], &addr); if (addr != pContext->GetNullRef(SP_NULL_VECTOR)) { pDir = &dir; dir.x = sp_ctof(addr[0]); dir.y = sp_ctof(addr[1]); dir.z = sp_ctof(addr[2]); } bool updatePos = params[13] ? true : false; float soundtime = sp_ctof(params[14]); CUtlVector<Vector> *pOrigVec = NULL; CUtlVector<Vector> origvec; if (params[0] > 14) { pOrigVec = &origvec; for (cell_t i = 15; i <= params[0]; i++) { Vector vec; pContext->LocalToPhysAddr(params[i], &addr); vec.x = sp_ctof(addr[0]); vec.y = sp_ctof(addr[1]); vec.z = sp_ctof(addr[2]); origvec.AddToTail(vec); } } engsound->EmitSentenceByIndex(crf, entity, channel, sentence, vol, (soundlevel_t)level, #if SOURCE_ENGINE >= SE_PORTAL2 0, #endif flags, pitch, #if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 \ || SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_TF2 0, #endif pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); return 1; }
static cell_t EmitSoundEntry(IPluginContext *pContext, const cell_t *params) { #if SOURCE_ENGINE < SE_PORTAL2 return pContext->ThrowNativeError("EmitSoundEntry is not available in this game."); #else cell_t *addr, *cl_array; CellRecipientFilter crf; unsigned int numClients; int client; IGamePlayer *pPlayer = NULL; pContext->LocalToPhysAddr(params[1], &cl_array); numClients = params[2]; /* Client validation */ for (unsigned int i = 0; i < numClients; i++) { client = cl_array[i]; pPlayer = playerhelpers->GetGamePlayer(client); if (!pPlayer) { return pContext->ThrowNativeError("Client index %d is invalid", client); } else if (!pPlayer->IsInGame()) { return pContext->ThrowNativeError("Client %d is not connected", client); } } crf.Initialize(cl_array, numClients); char *soundEntry; pContext->LocalToString(params[3], &soundEntry); char *sample; pContext->LocalToString(params[4], &sample); // By default, we want the hash to equal maxint unsigned int soundEntryHash = -1; // We only generate a hash if the sample is not the same as the sound entry and the sound entry is not empty. if (strcmp(soundEntry, sample) != 0 && strcmp(soundEntry, "") != 0) soundEntryHash = GenerateSoundEntryHash(soundEntry); int entity = SoundReferenceToIndex(params[5]); int channel = params[6]; int level = params[7]; int seed = params[8]; int flags = params[9]; float vol = sp_ctof(params[10]); int pitch = params[11]; int speakerentity = params[12]; Vector *pOrigin = NULL, origin; Vector *pDir = NULL, dir; pContext->LocalToPhysAddr(params[13], &addr); if (addr != pContext->GetNullRef(SP_NULL_VECTOR)) { pOrigin = &origin; origin.x = sp_ctof(addr[0]); origin.y = sp_ctof(addr[1]); origin.z = sp_ctof(addr[2]); } pContext->LocalToPhysAddr(params[14], &addr); if (addr != pContext->GetNullRef(SP_NULL_VECTOR)) { pDir = &dir; dir.x = sp_ctof(addr[0]); dir.y = sp_ctof(addr[1]); dir.z = sp_ctof(addr[2]); } bool updatePos = params[15] ? true : false; float soundtime = sp_ctof(params[16]); CUtlVector<Vector> *pOrigVec = NULL; CUtlVector<Vector> origvec; if (params[0] > 16) { pOrigVec = &origvec; for (cell_t i = 17; i <= params[0]; i++) { Vector vec; pContext->LocalToPhysAddr(params[i], &addr); vec.x = sp_ctof(addr[0]); vec.y = sp_ctof(addr[1]); vec.z = sp_ctof(addr[2]); origvec.AddToTail(vec); } } /* If we're going to a "local player" and this is a dedicated server, * intelligently redirect each sound. */ if (entity == -2 && engine->IsDedicatedServer()) { for (unsigned int i = 0; i < numClients; i++) { cell_t player[1]; player[0] = cl_array[i]; crf.Reset(); crf.Initialize(player, 1); if (g_InSoundHook) { SH_CALL(enginesoundPatch, static_cast<int (IEngineSound::*)(IRecipientFilter &, int, int, const char*, unsigned int, const char*, float, soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)> (&IEngineSound::EmitSound))(crf, player[0], channel, soundEntry, soundEntryHash, sample, vol, (soundlevel_t)level, seed, flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } else { engsound->EmitSound(crf, player[0], channel, soundEntry, soundEntryHash, sample, vol, (soundlevel_t)level, seed, flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } } } else { if (g_InSoundHook) { SH_CALL(enginesoundPatch, static_cast<int (IEngineSound::*)(IRecipientFilter &, int, int, const char*, unsigned int, const char*, float, soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)> (&IEngineSound::EmitSound))(crf, entity, channel, soundEntry, soundEntryHash, sample, vol, (soundlevel_t)level, seed, flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } else { engsound->EmitSound(crf, entity, channel, soundEntry, soundEntryHash, sample, vol, (soundlevel_t)level, seed, flags, pitch, pOrigin, pDir, pOrigVec, updatePos, soundtime, speakerentity); } } return 1; #endif }
static cell_t SlapPlayer(IPluginContext *pContext, const cell_t *params) { static bool s_slap_supported = false; static bool s_slap_setup = false; static ICallWrapper *s_teleport = NULL; static int s_health_offs = 0; static int s_sound_count = 0; static int s_frag_offs = 0; if (!s_slap_setup) { int tries = 0; s_slap_setup = true; if (IsTeleportSupported()) { tries++; } if (IsGetVelocitySupported()) { tries++; } /* Setup health */ if (g_pGameConf->GetOffset("m_iHealth", &s_health_offs) && s_health_offs) { tries++; } if (tries == 3) { s_slap_supported = true; const char *key; if ((key = g_pGameConf->GetKeyValue("SlapSoundCount")) != NULL) { s_sound_count = atoi(key); } } } if (!s_slap_supported) { return pContext->ThrowNativeError("This function is not supported on this mod"); } /* First check if the client is valid */ int client = params[1]; IGamePlayer *player = playerhelpers->GetGamePlayer(client); if (!player) { return pContext->ThrowNativeError("Client %d is not valid", client); } else if (!player->IsInGame()) { return pContext->ThrowNativeError("Client %d is not in game", client); } edict_t *pEdict = player->GetEdict(); CBaseEntity *pEntity = pEdict->GetUnknown()->GetBaseEntity(); /* See if we should be taking away health */ bool should_slay = false; if (params[2]) { #if SOURCE_ENGINE != SE_DARKMESSIAH int *health = (int *)((char *)pEntity + s_health_offs); if (*health - params[2] <= 0) { *health = 1; should_slay = true; } else { *health -= params[2]; } #else float *health = (float *)((char *)pEntity + s_health_offs); if (*health - (float)params[2] <= 0) { *health = 1.0f; should_slay = true; } else { *health -= (float)params[2]; } #endif } /* Teleport in a random direction - thank you, Mani!*/ Vector velocity; GetVelocity(pEntity, &velocity, NULL); velocity.x += ((rand() % 180) + 50) * (((rand() % 2) == 1) ? -1 : 1); velocity.y += ((rand() % 180) + 50) * (((rand() % 2) == 1) ? -1 : 1); velocity.z += rand() % 200 + 100; Teleport(pEntity, NULL, NULL, &velocity); /* Play a random sound */ if (params[3] && s_sound_count > 0) { char name[48]; const char *sound_name; cell_t player_list[256], total_players = 0; int maxClients = playerhelpers->GetMaxClients(); int r = (rand() % s_sound_count) + 1; snprintf(name, sizeof(name), "SlapSound%d", r); if ((sound_name = g_pGameConf->GetKeyValue(name)) != NULL) { IGamePlayer *other; for (int i=1; i<=maxClients; i++) { other = playerhelpers->GetGamePlayer(i); if (other->IsInGame()) { player_list[total_players++] = i; } } const Vector & pos = pEdict->GetCollideable()->GetCollisionOrigin(); CellRecipientFilter rf; rf.SetToReliable(true); rf.Initialize(player_list, total_players); engsound->EmitSound(rf, client, CHAN_AUTO, sound_name, VOL_NORM, ATTN_NORM, 0, PITCH_NORM, &pos); } } if (!s_frag_offs) { const char *frag_prop = g_pGameConf->GetKeyValue("m_iFrags"); if (frag_prop) { datamap_t *pMap = gamehelpers->GetDataMap(pEntity); typedescription_t *pType = gamehelpers->FindInDataMap(pMap, frag_prop); if (pType != NULL) { s_frag_offs = pType->fieldOffset[TD_OFFSET_NORMAL]; } } if (!s_frag_offs) { s_frag_offs = -1; } } int old_frags = 0; if (s_frag_offs > 0) { old_frags = *(int *)((char *)pEntity + s_frag_offs); } /* Force suicide */ if (should_slay) { pluginhelpers->ClientCommand(pEdict, "kill\n"); } if (s_frag_offs > 0) { *(int *)((char *)pEntity + s_frag_offs) = old_frags; } return 1; }
bool SDKTools::ProcessCommandTarget(cmd_target_info_t *info) { IGamePlayer *pAdmin = info->admin ? playerhelpers->GetGamePlayer(info->admin) : NULL; if (strcmp(info->pattern, "@aim") == 0) { /* The server can't aim, of course. */ if (pAdmin == NULL) { return false; } int player_index; if ((player_index = GetClientAimTarget(pAdmin->GetEdict(), true)) < 1) { info->reason = COMMAND_TARGET_NONE; info->num_targets = 0; return true; } IGamePlayer *pTarget = playerhelpers->GetGamePlayer(player_index); if (pTarget == NULL) { info->reason = COMMAND_TARGET_NONE; info->num_targets = 0; return true; } info->reason = playerhelpers->FilterCommandTarget(pAdmin, pTarget, info->flags); if (info->reason != COMMAND_TARGET_VALID) { info->num_targets = 0; return true; } info->targets[0] = player_index; info->num_targets = 1; info->reason = COMMAND_TARGET_VALID; info->target_name_style = COMMAND_TARGETNAME_RAW; snprintf(info->target_name, info->target_name_maxlength, "%s", pTarget->GetName()); return true; } else if (strcmp(info->pattern, "@spec") == 0) { const char *teamname = tools_GetTeamName(1); if (strcasecmp(teamname, "spectator") != 0) return false; info->num_targets = 0; for (int i = 1; i <= playerhelpers->GetMaxClients(); i++) { IGamePlayer *player = playerhelpers->GetGamePlayer(i); if (player == NULL || !player->IsInGame()) continue; IPlayerInfo *plinfo = player->GetPlayerInfo(); if (plinfo == NULL) continue; if (plinfo->GetTeamIndex() == 1 && playerhelpers->FilterCommandTarget(pAdmin, player, info->flags) == COMMAND_TARGET_VALID) { info->targets[info->num_targets++] = i; } } info->reason = info->num_targets > 0 ? COMMAND_TARGET_VALID : COMMAND_TARGET_EMPTY_FILTER; info->target_name_style = COMMAND_TARGETNAME_ML; snprintf(info->target_name, info->target_name_maxlength, "all spectators"); return true; } return false; }