Skip to content
This repository has been archived by the owner on Mar 23, 2024. It is now read-only.

Commit

Permalink
Better spawn find algorithm (#67)
Browse files Browse the repository at this point in the history
* rework: `RandomSpawn()`

* change default last spawn index to `-1`
  • Loading branch information
SergeyShorokhov authored Nov 24, 2021
1 parent 721588c commit dba501e
Showing 1 changed file with 42 additions and 20 deletions.
62 changes: 42 additions & 20 deletions cstrike/addons/amxmodx/scripting/CSDM_ReAPI/csdm_spawn_manager.sma
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
#define FIND_ENT_IN_SPHERE(%1,%2,%3) engfunc(EngFunc_FindEntityInSphere, %1, %2, %3)

const MAX_SPAWNS = 64
const Float:MIN_SPAWN_RADIUS = 450.0 // beta

// spawn editor options
const MAX_SEARCH_DISTANCE = 2500
Expand Down Expand Up @@ -47,7 +46,7 @@ new Float:g_vecLastOrigin[MAX_CLIENTS + 1][coord_e],
Float:g_vecLastAngles[MAX_CLIENTS + 1][coord_e],
Float:g_vecLastVAngles[MAX_CLIENTS + 1][coord_e]

new g_pAimedEntity[MAX_CLIENTS + 1], g_iLastSpawnIndex[MAX_CLIENTS + 1], bool:g_bFirstSpawn[MAX_CLIENTS + 1]
new g_pAimedEntity[MAX_CLIENTS + 1], g_iLastSpawnIndex[MAX_CLIENTS + 1] = { -1, ... }, bool:g_bFirstSpawn[MAX_CLIENTS + 1]
new g_szSpawnDirectory[PLATFORM_MAX_PATH], g_szSpawnFile[PLATFORM_MAX_PATH + 32], g_szMapName[32]
new g_iTotalPoints, g_iEditorMenuID, bool:g_bEditSpawns, bool:g_bNotSaved
new g_iGravity
Expand Down Expand Up @@ -175,32 +174,55 @@ RandomSpawn(const pPlayer)
if(!g_iTotalPoints || g_bFirstSpawn[pPlayer])
return false

new iRand = random(g_iTotalPoints - 1), iAttempts, iLast = g_iLastSpawnIndex[pPlayer]
do
{
iAttempts++
/* && IsHullVacant(g_vecSpotOrigin[iRand], HULL_HUMAN, DONT_IGNORE_MONSTERS) */
if(iRand != iLast && !IsVectorZero(g_vecSpotOrigin[iRand]) && !CheckDistance(pPlayer, g_vecSpotOrigin[iRand]))
{
SetPlayerPosition(pPlayer, g_vecSpotOrigin[iRand], g_vecSpotVAngles[iRand])
g_iLastSpawnIndex[pPlayer] = iRand

return true
new iBestSpawnIdx = -1
for(new iAttempt; iAttempt <= 2 && iBestSpawnIdx == -1; iAttempt++) {
new iSpawnIdx
for( ;iSpawnIdx < g_iTotalPoints; iSpawnIdx++) {
if(CheckSpawn(pPlayer, iSpawnIdx, iAttempt)) {
iBestSpawnIdx = iSpawnIdx
break
} else if(iAttempt == 2)
break
}

if(++iRand >= g_iTotalPoints) {
iRand = random(g_iTotalPoints - 1)
}
if(iSpawnIdx == (g_iTotalPoints - 1))
iSpawnIdx = random(g_iTotalPoints - 1)
}

} while(iAttempts <= g_iTotalPoints)
if(iBestSpawnIdx == -1) {
g_iLastSpawnIndex[pPlayer] = -1
return false
}

return false
SetPlayerPosition(pPlayer, g_vecSpotOrigin[iBestSpawnIdx], g_vecSpotVAngles[iBestSpawnIdx])
g_iLastSpawnIndex[pPlayer] = iBestSpawnIdx

return true
}

bool:CheckSpawn(const pPlayer, const iSpawnIdx, const iAttempt) {
if(IsVectorZero(g_vecSpotOrigin[iSpawnIdx]))
return false

if((iAttempt < 1) && CheckDistance(pPlayer, g_vecSpotOrigin[iSpawnIdx], 450.0))
return false

if((iAttempt < 2) && g_iLastSpawnIndex[pPlayer] == iSpawnIdx)
return false

if((iAttempt == 1) && CheckDistance(pPlayer, g_vecSpotOrigin[iSpawnIdx], 100.0))
return false

if(iAttempt == 2) // not found, use default spawn
return false

return true
}

bool:CheckDistance(const pPlayer, const Float:vecOrigin[coord_e])
bool:CheckDistance(const pPlayer, const Float:vecOrigin[coord_e], const Float:fDistance)
{
new pEntity = NULLENT
while((pEntity = FIND_ENT_IN_SPHERE(pEntity, vecOrigin, MIN_SPAWN_RADIUS)))
while((pEntity = FIND_ENT_IN_SPHERE(pEntity, vecOrigin, fDistance)))
{
if(IsPlayer(pEntity) && pEntity != pPlayer && get_entvar(pEntity, var_deadflag) == DEAD_NO) {
// server_print("Client %i fount! skip...", pEntity)
Expand Down

0 comments on commit dba501e

Please sign in to comment.