void CAI_Space::validate (const u32 level_id) const { VERIFY (level_graph().header().vertex_count() == cross_table().header().level_vertex_count()); for (GameGraph::_GRAPH_ID i=0, n = game_graph().header().vertex_count(); i<n; ++i) if ((level_id == game_graph().vertex(i)->level_id()) && (!level_graph().valid_vertex_id(game_graph().vertex(i)->level_vertex_id()) || (cross_table().vertex(game_graph().vertex(i)->level_vertex_id()).game_vertex_id() != i) || !level_graph().inside(game_graph().vertex(i)->level_vertex_id(),game_graph().vertex(i)->level_point()))) { Msg ("! Graph doesn't correspond to the cross table"); R_ASSERT2 (false,"Graph doesn't correspond to the cross table"); } // Msg ("death graph point id : %d",cross_table().vertex(455236).game_vertex_id()); for (u32 i=0, n=game_graph().header().vertex_count(); i<n; ++i) { if (level_id != game_graph().vertex(i)->level_id()) continue; CGameGraph::const_spawn_iterator I, E; game_graph().begin_spawn (i,I,E); // Msg ("vertex [%d] has %d death points",i,game_graph().vertex(i)->death_point_count()); for ( ; I != E; ++I) { VERIFY (cross_table().vertex((*I).level_vertex_id()).game_vertex_id() == i); } } // Msg ("* Graph corresponds to the cross table"); }
void CLevelSpawnConstructor::correct_level_changers () { LEVEL_CHANGER_STORAGE::const_iterator I = m_level_changers.begin(); LEVEL_CHANGER_STORAGE::const_iterator E = m_level_changers.end(); for ( ; I != E; ++I) { Fvector position = (*I)->o_Position; position.y += y_shift_correction; (*I)->m_tNodeID = level_graph().vertex(u32(-1),position); VERIFY (level_graph().valid_vertex_id((*I)->m_tNodeID)); u32 dwBest = cross_table().vertex((*I)->m_tNodeID).game_vertex_id(); VERIFY (game_graph().vertex(dwBest)->level_id() == m_level.id()); (*I)->m_tGraphID = (GameGraph::_GRAPH_ID)dwBest; (*I)->m_fDistance = cross_table().vertex((*I)->m_tNodeID).distance(); } }
void CAI_Space::load (LPCSTR level_name) { // Msg ("level %s",level_name); unload (true); #ifdef DEBUG Memory.mem_compact (); u32 mem_usage = Memory.mem_usage(); CTimer timer; timer.Start (); #endif m_level_graph = xr_new<CLevelGraph>(); m_cross_table = xr_new<CGameLevelCrossTable>(); R_ASSERT2 (cross_table().header().level_guid() == level_graph().header().guid(), "cross_table doesn't correspond to the AI-map"); R_ASSERT2 (cross_table().header().game_guid() == game_graph().header().guid(), "graph doesn't correspond to the cross table"); m_graph_engine = xr_new<CGraphEngine>( _max( game_graph().header().vertex_count(), level_graph().header().vertex_count() ) ); const CGameGraph::SLevel ¤t_level = game_graph().header().level(level_name); R_ASSERT2 (current_level.guid() == level_graph().header().guid(), "graph doesn't correspond to the AI-map"); #ifdef DEBUG if (!xr_strcmp(current_level.name(),level_name)) validate (current_level.id()); #endif level_graph().level_id (current_level.id()); game_graph().set_current_level(current_level.id()); m_cover_manager->compute_static_cover (); #ifdef DEBUG Msg ("* Loading ai space is successfully completed (%.3fs, %7.3f Mb)",timer.GetElapsed_sec(),float(Memory.mem_usage() - mem_usage)/1048576.0); #endif }
void CLevelSpawnConstructor::init () { // loading level graph string_path file_name; FS.update_path (file_name,"$game_levels$",*m_level.name()); strcat_s (file_name,"\\"); m_level_graph = new CLevelGraph(file_name); // loading cross table m_game_spawn_constructor->game_graph().set_current_level (game_graph().header().level(*m_level.name()).id()); m_cross_table = &game_graph().cross_table(); // loading patrol paths FS.update_path (file_name,"$game_levels$",*m_level.name()); strcat (file_name,"\\level.game"); if (FS.exist(file_name)) { IReader *stream = FS.r_open(file_name); VERIFY (stream); m_game_spawn_constructor->patrol_path_storage().load_raw(&level_graph(),&cross_table(),&game_graph(),*stream); FS.r_close (stream); } }
void CLevelSpawnConstructor::generate_artefact_spawn_positions () { // create graph engine VERIFY (!m_graph_engine); m_graph_engine = new CGraphEngine(m_level_graph->header().vertex_count()); xr_vector<u32> l_tpaStack; SPAWN_STORAGE zones; l_tpaStack.reserve (1024); SPAWN_STORAGE::iterator I = m_spawns.begin(); SPAWN_STORAGE::iterator E = m_spawns.end(); for ( ; I != E; I++) { CSE_ALifeAnomalousZone *zone = smart_cast<CSE_ALifeAnomalousZone*>(*I); if (!zone) continue; // if (!level_graph().valid_vertex_position(zone->o_Position)) { // zone->m_artefact_spawn_count = 0; // zone->m_artefact_position_offset = m_level_points.size(); // continue; // } zone->m_tNodeID = level_graph().vertex(zone->m_tNodeID,zone->o_Position); if (!level_graph().valid_vertex_position(zone->o_Position) || !level_graph().inside(zone->m_tNodeID,zone->o_Position)) zone->m_tNodeID = level_graph().vertex(u32(-1),zone->o_Position); const CGameLevelCrossTable::CCell &cell = cross_table().vertex(zone->m_tNodeID); zone->m_tGraphID = cell.game_vertex_id(); zone->m_fDistance = cell.distance(); graph_engine().search ( level_graph(), zone->m_tNodeID, zone->m_tNodeID, &l_tpaStack, SFlooder< float, u32, u32 >( zone->m_offline_interactive_radius, u32(-1), u32(-1) ) ); l_tpaStack.erase ( std::remove_if( l_tpaStack.begin(), l_tpaStack.end(), remove_too_far_predicate( &level_graph(), zone->o_Position, zone->m_offline_interactive_radius ) ), l_tpaStack.end() ); /* if (zone->m_artefact_spawn_count >= l_tpaStack.size()) { zone->m_artefact_spawn_count = (u16)l_tpaStack.size(); #ifndef IGNORE_ZERO_SPAWN_POSITIONS if (!zone->m_artefact_spawn_count) { Msg ("! CANNOT GENERATE ARTEFACT SPAWN POSITIONS FOR ZONE [%s] ON LEVEL [%s]",zone->name_replace(),*level().name()); Msg ("! ZONE [%s] ON LEVEL [%s] IS REMOVED BY AI COMPILER",zone->name_replace(),*level().name()); R_ASSERT3 (zone->m_story_id == INVALID_STORY_ID,"Cannot remove story object",zone->name_replace()); R_ASSERT3 (!zone->m_spawn_control,"Cannot remove spawn control object",zone->name_replace()); zones.push_back (zone); l_tpaStack.clear (); continue; } #endif } else */ std::random_shuffle (l_tpaStack.begin(),l_tpaStack.end()); zone->m_artefact_position_offset= m_level_points.size(); m_level_points.resize (zone->m_artefact_position_offset + zone->m_artefact_spawn_count); // Msg ("%s %f [%f][%f][%f] : artefact spawn positions",zone->name_replace(),zone->m_fRadius,VPUSH(zone->o_Position)); LEVEL_POINT_STORAGE::iterator I = m_level_points.begin() + zone->m_artefact_position_offset; LEVEL_POINT_STORAGE::iterator E = m_level_points.end(); xr_vector<u32>::iterator i = l_tpaStack.begin(); for ( ; I != E; ++I, ++i) { (*I).tNodeID = *i; (*I).tPoint = level_graph().vertex_position(*i); (*I).fDistance = cross_table().vertex(*i).distance(); // Msg (" [%f][%f][%f] : %f",VPUSH((*I).tPoint),zone->o_Position.distance_to((*I).tPoint)); } l_tpaStack.clear (); } #ifndef IGNORE_ZERO_SPAWN_POSITIONS I = std::remove_if(m_spawns.begin(),m_spawns.end(),remove_invalid_zones_predicate(this,&zones)); m_spawns.erase (I,m_spawns.end()); #endif }
void CLevelSpawnConstructor::correct_objects () { u32 m_level_graph_vertex_id = u32(-1); u32 dwStart = game_graph().header().vertex_count(), dwFinish = game_graph().header().vertex_count(), dwCount = 0; for (u32 i=0; i<game_graph().header().vertex_count(); ++i) if (game_graph().vertex(i)->level_id() == m_level.id()) { if (m_level_graph_vertex_id == u32(-1)) m_level_graph_vertex_id = i; dwCount++; } for (int i=0; i<(int)game_graph().header().vertex_count(); i++) if (game_graph().vertex(i)->level_id() == m_level.id()) { if (dwStart > (u32)i) dwStart = (u32)i; } else { if ((dwStart <= (u32)i) && (dwFinish > (u32)i)) { dwFinish = i; break; } } if (dwStart >= dwFinish) { string4096 S; sprintf (S,"There are no graph vertices in the game graph for the level '%s' !\n",*m_level.name()); R_ASSERT2 (dwStart < dwFinish,S); } for (int i=0; i<(int)m_spawns.size(); i++) { if (!m_spawns[i]->used_ai_locations()) { m_spawns[i]->m_tGraphID = (GameGraph::_GRAPH_ID)m_level_graph_vertex_id; m_spawns[i]->m_fDistance = 0.f; m_spawns[i]->m_tNodeID = game_graph().vertex(m_level_graph_vertex_id)->level_vertex_id(); continue; } Fvector position = m_spawns[i]->o_Position; position.y += y_shift_correction; m_spawns[i]->m_tNodeID = level_graph().vertex(u32(-1),position); VERIFY (level_graph().valid_vertex_id(m_spawns[i]->m_tNodeID)); if (m_spawns[i]->used_ai_locations() && !level_graph().inside(level_graph().vertex(m_spawns[i]->m_tNodeID),position)) { Fvector new_position = level_graph().vertex_position(m_spawns[i]->m_tNodeID); clMsg ("[%s][%s][%s] : position changed from [%f][%f][%f] -> [%f][%f][%f]",*m_level.name(),*m_spawns[i]->s_name,m_spawns[i]->name_replace(),VPUSH(position),VPUSH(new_position)); m_spawns[i]->o_Position = new_position; } u32 dwBest = cross_table().vertex(m_spawns[i]->m_tNodeID).game_vertex_id(); if (game_graph().vertex(dwBest)->level_id() != m_level.id()) { string4096 S1; char *S = S1; S += sprintf(S,"Corresponding graph vertex for the spawn point is located on the ANOTHER level\n",m_spawns[i]->name_replace()); S += sprintf(S,"Current level : [%d][%s]\n",m_level.id(),*game_graph().header().level(m_level.id()).name()); S += sprintf(S,"Conflict level : [%d][%s]\n",game_graph().vertex(dwBest)->level_id(),*game_graph().header().level(game_graph().vertex(dwBest)->level_id()).name()); S += sprintf(S,"Probably, you filled offsets in \"game_levels.ltx\" incorrect"); R_ASSERT2 (game_graph().vertex(dwBest)->level_id() == m_level.id(),S1); } float fCurrentBestDistance = cross_table().vertex(m_spawns[i]->m_tNodeID).distance(); if (dwBest == u32(-1)) { string4096 S1; char *S = S1; S += sprintf(S,"Can't find a corresponding GRAPH VERTEX for the spawn-point %s\n",m_spawns[i]->name_replace()); S += sprintf(S,"Level ID : %d\n",m_level.id()); S += sprintf(S,"Spawn index : %d\n",i); S += sprintf(S,"Spawn node : %d\n",m_spawns[i]->m_tNodeID); S += sprintf(S,"Spawn point : [%7.2f][%7.2f][%7.2f]\n",m_spawns[i]->o_Position.x,m_spawns[i]->o_Position.y,m_spawns[i]->o_Position.z); R_ASSERT2 (dwBest != -1,S1); } m_spawns[i]->m_tGraphID = (GameGraph::_GRAPH_ID)dwBest; m_spawns[i]->m_fDistance = fCurrentBestDistance; } }