/* =========================================================================== IceTech GPL Source Code Copyright (C) 2026 Justin Marshall This file is part of the IceTech GPL Source Code (?IceTech Source Code?). IceTech Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. IceTech Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with IceTech Source Code. If not, see . In addition, the IceTech Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the IceTech Source Code. If not, please request a copy in writing from id Software at the address below. If you have questions concerning this license or the applicable additional terms, you may contact in writing Justin Marshall, justinmarshall20@gmail.com =========================================================================== */ /* game_worldspawn.cpp Worldspawn class. Each map has one worldspawn which handles global spawnargs. */ #include "precompiled.h" #pragma hdrstop #include "Game_local.h" /* ================ idWorldspawn Every map should have exactly one worldspawn. ================ */ static renderGlobalFogMode_t ParseGlobalFogMode( const char *mode ) { if ( !idStr::Icmp( mode, "linear" ) ) { return RENDER_GLOBAL_FOG_LINEAR; } if ( !idStr::Icmp( mode, "exp2" ) ) { return RENDER_GLOBAL_FOG_EXP2; } return RENDER_GLOBAL_FOG_EXP; } static void SetWorldspawnGlobalFogParms( const idDict &spawnArgs ) { idVec3 color; idStr mode; memset( &gameLocal.globalFogParms, 0, sizeof( gameLocal.globalFogParms ) ); gameLocal.globalFogParms.mode = RENDER_GLOBAL_FOG_EXP; gameLocal.globalFogParms.density = 1.0f; gameLocal.globalFogParms.end = 1.0f; gameLocal.globalFogParms.color.Set( 0.0f, 0.0f, 0.0f, 1.0f ); gameLocal.globalFogParms.enabled = spawnArgs.GetBool( "globalFog", spawnArgs.GetString( "fog_global", "0" ) ); if ( spawnArgs.GetString( "globalFogMode", "", mode ) || spawnArgs.GetString( "fog_mode", "", mode ) ) { gameLocal.globalFogParms.mode = ParseGlobalFogMode( mode.c_str() ); } gameLocal.globalFogParms.density = spawnArgs.GetFloat( "globalFogDensity", spawnArgs.GetString( "fog_density", va( "%f", gameLocal.globalFogParms.density ) ) ); gameLocal.globalFogParms.start = spawnArgs.GetFloat( "globalFogStart", spawnArgs.GetString( "fog_start", va( "%f", gameLocal.globalFogParms.start ) ) ); gameLocal.globalFogParms.end = spawnArgs.GetFloat( "globalFogEnd", spawnArgs.GetString( "fog_end", va( "%f", gameLocal.globalFogParms.end ) ) ); if ( spawnArgs.GetVector( "globalFogColor", spawnArgs.GetString( "fog_color", "0 0 0" ), color ) ) { gameLocal.globalFogParms.color.Set( color.x, color.y, color.z, spawnArgs.GetFloat( "globalFogAlpha", spawnArgs.GetString( "fog_alpha", "1" ) ) ); } } /* ================ idWorldspawn::Spawn ================ */ void idWorldspawn::Spawn( void ) { idStr scriptname; idThread *thread; const function_t *func; const idKeyValue *kv; assert( gameLocal.world == NULL ); gameLocal.world = this; g_gravity.SetFloat( spawnArgs.GetFloat( "gravity", va( "%f", DEFAULT_GRAVITY ) ) ); SetWorldspawnGlobalFogParms( spawnArgs ); // disable stamina on hell levels if ( spawnArgs.GetBool( "no_stamina" ) ) { pm_stamina.SetFloat( 0.0f ); } skydomeMaterial = declManager->FindMaterial(spawnArgs.GetString("skydome", "textures/skies/mars1")); // load script scriptname = gameLocal.GetMapName(); scriptname.SetFileExtension( ".script" ); if ( fileSystem->ReadFile( scriptname, NULL, NULL ) > 0 ) { gameLocal.program.CompileFile( scriptname ); // call the main function by default func = gameLocal.program.FindFunction( "main" ); if ( func != NULL ) { thread = new idThread( func ); thread->DelayedStart( 0 ); } } // call any functions specified in worldspawn kv = spawnArgs.MatchPrefix( "call" ); while( kv != NULL ) { func = gameLocal.program.FindFunction( kv->GetValue() ); if ( func == NULL ) { gameLocal.Error( "Function '%s' not found in script for '%s' key on worldspawn", kv->GetValue().c_str(), kv->GetKey().c_str() ); } thread = new idThread( func ); thread->DelayedStart( 0 ); kv = spawnArgs.MatchPrefix( "call", kv ); } } /* ================= idWorldspawn::Save ================= */ void idWorldspawn::Save( idRestoreGame *savefile ) { } /* ================= idWorldspawn::Restore ================= */ void idWorldspawn::Restore( idRestoreGame *savefile ) { assert( gameLocal.world == this ); g_gravity.SetFloat( spawnArgs.GetFloat( "gravity", va( "%f", DEFAULT_GRAVITY ) ) ); SetWorldspawnGlobalFogParms( spawnArgs ); // disable stamina on hell levels if ( spawnArgs.GetBool( "no_stamina" ) ) { pm_stamina.SetFloat( 0.0f ); } } /* ================ idWorldspawn::~idWorldspawn ================ */ idWorldspawn::~idWorldspawn() { if ( gameLocal.world == this ) { gameLocal.world = NULL; } } /* ================ idWorldspawn::Event_Remove ================ */ void idWorldspawn::Event_Remove( void ) { gameLocal.Error( "Tried to remove world" ); }