#pragma newdecls required #include #include #include Handle hSelectSpawnPoint; //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Plugin myinfo = { name = "RandomizeSpawns", author = "zaCade", description = "Randomize player spawns.", version = "1.0.0" }; //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnPluginStart() { Handle hGameConf; if ((hGameConf = LoadGameConfigFile("RandomizeSpawns.games")) == INVALID_HANDLE) { SetFailState("Couldn't load \"RandomizeSpawns.games\" game config!"); return; } // int iOffset; if ((iOffset = GameConfGetOffset(hGameConf, "SelectSpawnPoint")) == -1) { CloseHandle(hGameConf); SetFailState("GameConfGetOffset(hGameConf, \"SelectSpawnPoint\") failed!"); return; } if ((hSelectSpawnPoint = DHookCreate(iOffset, HookType_Entity, ReturnType_CBaseEntity, ThisPointer_CBaseEntity, OnPlayerSelectSpawnPoint)) == INVALID_HANDLE) { CloseHandle(hGameConf); SetFailState("DHookCreate(iOffset, HookType_Entity, ReturnType_CBaseEntity, ThisPointer_CBaseEntity, OnPlayerSelectSpawnPoint) failed!"); return; } // Late load. for (int client = 1; client <= MaxClients; client++) { if (IsClientInGame(client)) { OnClientPutInServer(client); } } CloseHandle(hGameConf); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnClientPutInServer(int client) { DHookEntity(hSelectSpawnPoint, false, client); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public int RandomizeSpawnPoints(int elem1, int elem2, int[] array, Handle hndl) { return GetRandomInt(-1, 1); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public MRESReturn OnPlayerSelectSpawnPoint(int client, Handle hReturn) { if (IsValidEntity(client) && !IsClientInGame(client)) return MRES_Ignored; static int spawnPoints[128]; static int spawnCount; if (!spawnCount) { int spawnPoint = INVALID_ENT_REFERENCE; while ((spawnPoint = FindEntityByClassname(spawnPoint, "info_player_*")) != INVALID_ENT_REFERENCE) { char sClassname[64]; GetEntityClassname(spawnPoint, sClassname, sizeof(sClassname)); if (StrEqual(sClassname, "info_player_terrorist", true) || StrEqual(sClassname, "info_player_counterterrorist", true)) { spawnPoints[spawnCount++] = spawnPoint; } } } if (spawnCount) { int spawnCountAttempts; while (spawnCountAttempts >= spawnCount) { SortCustom1D(spawnPoints, spawnCount, RandomizeSpawnPoints); int spawnPoint = spawnPoints[0]; if (IsValidEntity(spawnPoint) && IsValidPlayerSpawn(client, spawnPoint)) { DHookSetReturn(hReturn, spawnPoint); return MRES_Supercede; } spawnCountAttempts++; } } return MRES_Ignored; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- stock bool IsValidPlayerSpawn(int client, int spawnPoint) { float clientMins[3]; float clientMaxs[3]; GetClientMins(client, clientMins); GetClientMaxs(client, clientMaxs); float spawnPointOrigin[3]; GetEntPropVector(spawnPoint, Prop_Send, "m_vecOrigin", spawnPointOrigin); TR_TraceHullFilter(spawnPointOrigin, spawnPointOrigin, clientMins, clientMaxs, MASK_PLAYERSOLID, IsValidPlayerSpawnFilter); return !TR_DidHit(); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public bool IsValidPlayerSpawnFilter(int entity, int contentsMask) { return view_as(entity); }