/* * Author: Needles * https://steamcommunity.com/profiles/76561198026257137/ */ ::Debug.Print("*** SPAWN_CONTEXT"); ::SpawnContext <- {}; ::SpawnContext.playerSpawnResponseList <- []; ::SpawnContext.lastSpawnedPlayer <- null; ::SpawnContext.spawnTracker <- {}; ::SpawnContext.spawnPointList <- []; ::SpawnContext.uniqueSpawnPointMap <- {}; /* * Reset the spawn context. */ function SpawnContext::ClearSpawnContext() { ::SpawnContext.playerSpawnResponseList = []; ::SpawnContext.lastSpawnedPlayer = null; ::SpawnContext.spawnTracker = {}; } /* * Add a spawn point */ function SpawnContext::AddSpawnPoint(position, angles, filterList, startEnabled = true) { local spawnPoint = { position = position, angles = angles, filterList = filterList, isEnabled = startEnabled, }; ::SpawnContext.spawnPointList.append(spawnPoint); return spawnPoint; } /* * Remove a spawn point */ function SpawnContext::RemoveSpawnPoint(spawnPoint) { local index = ::SpawnContext.spawnPointList.find(spawnPoint); if (index == null) return; ::SpawnContext.spawnPointList.remove(index); } /* * Delete all spawn points and unique spawn points */ function SpawnContext::ClearSpawnPoints() { ::SpawnContext.spawnPointList.clear(); ::SpawnContext.uniqueSpawnPointMap.clear(); } /* * Enable or disable a spawn point */ function SpawnContext::SetSpawnPointEnabled(spawnPoint, isEnabled) { spawnPoint.isEnabled = isEnabled; } /* * Add a temporary spawn point for the specified player. The spawnpoint will expire after a certain number of spawns. Set to -1 for infinite. */ function SpawnContext::SetUniqueSpawnPoint(player, origin, angles, validCount) { ::SpawnContext.uniqueSpawnPointMap[player] <- { origin = origin, angles = angles, validCount = validCount, }; } /* * */ function SpawnContext::RemoveUniqueSpawnPoint(player) { if (player in ::SpawnContext.uniqueSpawnPointMap) { ::SpawnContext.uniqueSpawnPointMap.rawdelete(player); } } function SpawnContext::MovePlayerToSpawnPoint(player) { local validSpawnPointList = []; foreach(spawnPoint in ::SpawnContext.spawnPointList) { if (spawnPoint.isEnabled == false) continue; if (spawnPoint.filterList != null && ::Filter.FilterAll(player, spawnPoint.filterList) == false) continue; validSpawnPointList.append(spawnPoint); } if (validSpawnPointList.len() > 0) { local randomIndex = RandomInt(0, validSpawnPointList.len()-1); player.Teleport(true, validSpawnPointList[randomIndex].position, true, validSpawnPointList[randomIndex].angles, true, Vector(0.0, 0.0,0.0)); ::Debug.Print("*** SPAWN CONTEXT - moving player to custom spawn point: " + player); } } /* * Add a new spawn context action that will be executed whenever a player spawns. */ function SpawnContext::AddSpawnResponse(filterList, callback) { ::SpawnContext.playerSpawnResponseList.append({ filterList = filterList, callback = callback, }); } /* * Get the last spawned player. */ function SpawnContext::GetLastSpawnedPlayer() { return ::SpawnContext.lastSpawnedPlayer; } /* * Track a spawned player so that it can be retrieved later. */ function SpawnContext::AddTrackedPlayer(name, player) { if (name in ::SpawnContext.spawnTracker) ::SpawnContext.spawnTracker[name] = player; else ::SpawnContext.spawnTracker[name] <- player; } /* * Retrieve a spawned player that was previously being tracked. */ function SpawnContext::GetTrackedPlayer(name) { if (!(name in ::SpawnContext.spawnTracker)) return null; return ::SpawnContext.spawnTracker[name]; } /* * Called after a player has spawned. */ function SpawnContext::PostPlayerSpawn(player) { ::Debug.Print("*** SPAWN CONTEXT - Post player spawn: " + player); if (!::Players.IsPlayerValid(player)) { return; } // Move to a unique spawn point if one has been assigned for this player if (player in ::SpawnContext.uniqueSpawnPointMap) { local uniqueSpawnPoint = ::SpawnContext.uniqueSpawnPointMap[player]; if (uniqueSpawnPoint.validCount > 0) { uniqueSpawnPoint.validCount--; player.Teleport(true, uniqueSpawnPoint.origin, true, uniqueSpawnPoint.angles, true, Vector(0.0, 0.0,0.0)); ::Debug.Print("*** SPAWN CONTEXT - moving player to unique spawn point: " + player); } if (uniqueSpawnPoint.validCount == 0) { ::SpawnContext.RemoveUniqueSpawnPoint(player); } } else { // Move to a custom spawn point if one exists (and this player doesn't have a unique spawn point) // If this player meets the criterea for multiple spawn points, then pick one at random ::SpawnContext.MovePlayerToSpawnPoint(player); } // Execute spawn responses foreach(playerSpawnResponse in ::SpawnContext.playerSpawnResponseList) { if (playerSpawnResponse.filterList != null && ::Filter.FilterAll(player, playerSpawnResponse.filterList) == false) continue; ::Debug.Print("*** SPAWN CONTEXT - firing spawn context action: " + player); playerSpawnResponse.callback.call(this, player); } ::SpawnContext.lastSpawnedPlayer = player; } ::Events.GetGlobalEvent(EVENT.PLAYER_SPAWN_POST).AddListener( function(params) { ::SpawnContext.PostPlayerSpawn(params.player); } ); /* ::Events.AddHandler({ OnEvent_PlayerSpawn = function(params) { local player = GetPlayerFromUserID(params.userid); if (player == null) return; if (!::Players.IsPlayerBot(player)) return; EntFireByHandle(player, "RunScriptCode", "::SpawnContext.PostPlayerSpawn(self)", 0.0, null, null); // We need this redirection in order to see the player tags. // This is because entFire is not processed until the end of the frame. So any code that is executed here will be able to see the tags. }, }); */