void CASW_Encounter::LoadFromKeyValues( KeyValues *pKeys ) { m_SpawnDefs.Purge(); m_vecPosition.x = pKeys->GetFloat( "PosX" ); m_vecPosition.y = pKeys->GetFloat( "PosY" ); m_vecPosition.z = 0; m_flEncounterRadius = pKeys->GetFloat( "Radius" ); for ( KeyValues *pKey = pKeys->GetFirstSubKey(); pKey; pKey = pKey->GetNextKey() ) { if ( !Q_stricmp( pKey->GetName(), "SpawnDef" ) ) { CASW_Spawn_Definition* pSpawnDef = SpawnSelection()->GetSpawnDefByID( pKey->GetInt() ); if ( pSpawnDef ) { m_SpawnDefs.AddToTail( pSpawnDef ); } else { Msg( "Failed to load spawn def %d for encounter.\n", pKey->GetInt() ); } } } }
void CASWMissionChooserNPCs::InitFixedSpawns( CLayoutSystem *pLayoutSystem, CMapLayout *pLayout ) { // init the spawn set for this mission KeyValues *pGenerationOptions = pLayout->GetGenerationOptions(); if ( !pGenerationOptions ) { Warning( "Error placed fixed alien spawns, no generation options in this layout." ); return; } bool bChosenSpawnSet = false; const char *szNamedSpawnSet = pGenerationOptions->GetString( "AlienSpawnSet" ); if ( szNamedSpawnSet && szNamedSpawnSet[0] ) { bChosenSpawnSet = SpawnSelection()->SetCurrentSpawnSet( szNamedSpawnSet ); } if ( !bChosenSpawnSet ) { SpawnSelection()->SetCurrentSpawnSet( pGenerationOptions->GetInt( "Difficulty", 5 ) ); } // if we have any rooms with the alien encounter tag, then just use those for fixed spawn locations bool bAlienEncounterTag = false; int iRooms = pLayout->m_PlacedRooms.Count(); for ( int i = 0; i < iRooms; i++ ) { CRoom *pRoom = pLayout->m_PlacedRooms[i]; if ( pRoom && pRoom->m_pRoomTemplate && pRoom->m_pRoomTemplate->HasTag( "AlienEncounter" ) ) { bAlienEncounterTag = true; CASW_Encounter *pEncounter = new CASW_Encounter(); // pick a random spot in this room Vector vecWorldMins, vecWorldMaxs; pRoom->GetWorldBounds( &vecWorldMins, &vecWorldMaxs ); Vector vecPos = vecWorldMins + pLayoutSystem->GetRandomFloat( 0, 1 ) * ( vecWorldMaxs - vecWorldMins ); vecPos.z = 0; pEncounter->SetEncounterPosition( vecPos ); pEncounter->SetEncounterRadius( pLayoutSystem->GetRandomFloat( asw_encounter_radius_min.GetFloat(), asw_encounter_radius_max.GetFloat() ) ); // add spawn defs // TODO: more spawns in bigger rooms? or rooms with higher weights? int iSpawnsPerEncounter = pLayoutSystem->GetRandomInt( CurrentSpawnSet()->GetMinSpawnsPerEncounter(), CurrentSpawnSet()->GetMaxSpawnsPerEncounter() ); for ( int i = 0; i < iSpawnsPerEncounter; i++ ) { CASW_Spawn_Definition* pSpawnDef = CurrentSpawnSet()->GetSpawnDef( ASW_NPC_SPAWN_TYPE_FIXED ); if ( !pSpawnDef ) continue; pEncounter->AddSpawnDef( pSpawnDef ); } pLayout->m_Encounters.AddToTail( pEncounter ); } } if ( bAlienEncounterTag ) { pLayout->MarkEncounterRooms(); return; } // find area of the mission int iTotalArea = 0; for ( int i = 0; i < iRooms; i++ ) { CRoom *pRoom = pLayout->m_PlacedRooms[i]; iTotalArea += ( pRoom->m_pRoomTemplate->GetTilesX() * ASW_TILE_SIZE ) * ( pRoom->m_pRoomTemplate->GetTilesY() * ASW_TILE_SIZE ); } // decide how many encounters we want int iEncounters = pLayoutSystem->GetRandomInt( CurrentSpawnSet()->GetMinEncounters(), CurrentSpawnSet()->GetMaxEncounters() ); // distance between encounters //float flMinDistance = asw_encounters_distance_min.GetFloat(); // randomly pick rooms for the encounters to be in, using the room weights CUtlVector<CRoom*> candidates; float flTotalWeight = 0; for ( int i = 0; i < iRooms; i++ ) { CRoom *pRoom = pLayout->m_PlacedRooms[i]; if ( pRoom->GetSpawnWeight() > 0 && !pRoom->m_pRoomTemplate->IsEscapeRoom() && !pRoom->m_pRoomTemplate->IsStartRoom() && !pRoom->m_pRoomTemplate->IsBorderRoom() ) { flTotalWeight += pRoom->GetSpawnWeight(); candidates.AddToTail( pRoom ); } } for ( int e = 0; e < iEncounters; e++ ) { float flChosen = pLayoutSystem->GetRandomFloat( 0, flTotalWeight ); CRoom *pChosenRoom = NULL; for ( int i = 0; i < candidates.Count(); i++ ) { CRoom *pRoom = candidates[i]; flChosen -= pRoom->GetSpawnWeight(); if ( flChosen <= 0 ) { pChosenRoom = pRoom; break; } } if ( !pChosenRoom ) continue; CASW_Encounter *pEncounter = new CASW_Encounter(); // pick a random spot in this room Vector vecWorldMins, vecWorldMaxs; pChosenRoom->GetWorldBounds( &vecWorldMins, &vecWorldMaxs ); //Vector vecPos = vecWorldMins + pLayoutSystem->GetRandomFloat( 0, 1 ) * ( vecWorldMaxs - vecWorldMins ); Vector vecPos = ( vecWorldMins + vecWorldMaxs ) * 0.5f; // center of the room vecPos.z = 0; pEncounter->SetEncounterPosition( vecPos ); pEncounter->SetEncounterRadius( pLayoutSystem->GetRandomFloat( asw_encounter_radius_min.GetFloat(), asw_encounter_radius_max.GetFloat() ) ); // add spawn defs // TODO: more spawns in bigger rooms? or rooms with higher weights? int iSpawnsPerEncounter = pLayoutSystem->GetRandomInt( CurrentSpawnSet()->GetMinSpawnsPerEncounter(), CurrentSpawnSet()->GetMaxSpawnsPerEncounter() ); for ( int i = 0; i < iSpawnsPerEncounter; i++ ) { CASW_Spawn_Definition* pSpawnDef = CurrentSpawnSet()->GetSpawnDef( ASW_NPC_SPAWN_TYPE_FIXED ); if ( !pSpawnDef ) continue; pEncounter->AddSpawnDef( pSpawnDef ); } pLayout->m_Encounters.AddToTail( pEncounter ); } PushEncountersApart( pLayout ); pLayout->MarkEncounterRooms(); }