u16 GetSpawnInfo(NET_Packet &P, u16 &parent_id) { u16 dummy16, id; P.r_begin(dummy16); shared_str s_name; P.r_stringZ(s_name); CSE_Abstract* E = F_entity_Create(*s_name); E->Spawn_Read(P); if (E->s_flags.is(M_SPAWN_UPDATE)) E->UPDATE_Read(P); id = E->ID; parent_id = E->ID_Parent; F_entity_Destroy(E); P.r_pos = 0; return id; }
CSE_Abstract *CLevelSpawnConstructor::create_object (IReader *chunk) { NET_Packet net_packet; net_packet.B.count = chunk->length(); chunk->r (net_packet.B.data,net_packet.B.count); // we do not need to close chunk since we iterate on them // chunk->close (); u16 ID; net_packet.r_begin (ID); R_ASSERT2 (M_SPAWN==ID,"ID doesn't match to the spawn-point ID!"); string64 section_name; net_packet.r_stringZ (section_name); CSE_Abstract *abstract = F_entity_Create(section_name); if (!abstract) { string256 temp; sprintf (temp,"Can't create entity '%s' !\n",section_name); R_ASSERT2 (abstract,temp); } abstract->Spawn_Read (net_packet); return (abstract); }
void CLevel::cl_Process_Spawn(NET_Packet& P) { // Begin analysis shared_str s_name; P.r_stringZ (s_name); // Create DC (xrSE) CSE_Abstract* E = F_entity_Create (*s_name); R_ASSERT2(E, *s_name); E->Spawn_Read (P); if (E->s_flags.is(M_SPAWN_UPDATE)) E->UPDATE_Read (P); if (!E->match_configuration()) { F_entity_Destroy(E); return; } //------------------------------------------------- //. Msg ("M_SPAWN - %s[%d][%x] - %d %d", *s_name, E->ID, E,E->ID_Parent, Device.dwFrame); //------------------------------------------------- //force object to be local for server client if (OnServer()) { E->s_flags.set(M_SPAWN_OBJECT_LOCAL, TRUE); }; /* game_spawn_queue.push_back(E); if (g_bDebugEvents) ProcessGameSpawns(); /*/ g_sv_Spawn (E); F_entity_Destroy (E); //*/ };
CLevelGameGraph ( LPCSTR graph_file_name, LPCSTR raw_cross_table_file_name, CGameGraph::SLevel *tLevel, LPCSTR S, u32 dwOffset, u32 dwLevelID, CInifile *Ini ) { m_tLevel = *tLevel; m_dwOffset = dwOffset; m_tpLevelPoints.clear (); FILE_NAME caFileName; // loading graph strcpy_s (caFileName,graph_file_name); m_tpGraph = new CGameGraph(caFileName); strcpy_s (caFileName,raw_cross_table_file_name); CGameLevelCrossTable *l_tpCrossTable = new CGameLevelCrossTable(caFileName); CLevelGraph *l_tpAI_Map = new CLevelGraph(S); VERIFY2 (l_tpCrossTable->header().level_guid() == l_tpAI_Map->header().guid(), "cross table doesn't correspond to the AI-map, rebuild graph!"); VERIFY2 (l_tpCrossTable->header().game_guid() == m_tpGraph->header().guid(), "cross table doesn't correspond to the graph, rebuild graph!"); VERIFY2 (m_tpGraph->header().level(GameGraph::_LEVEL_ID(0)).guid() == l_tpAI_Map->header().guid(), "cross table doesn't correspond to the AI-map, rebuild graph!"); VERIFY (l_tpAI_Map->header().vertex_count() == l_tpCrossTable->header().level_vertex_count()); VERIFY (m_tpGraph->header().vertex_count() == l_tpCrossTable->header().game_vertex_count()); tLevel->m_guid = l_tpAI_Map->header().guid(); { for (GameGraph::_GRAPH_ID i=0, n = m_tpGraph->header().vertex_count(); i<n; ++i) if ((!l_tpAI_Map->valid_vertex_id(m_tpGraph->vertex(i)->level_vertex_id()) || (l_tpCrossTable->vertex(m_tpGraph->vertex(i)->level_vertex_id()).game_vertex_id() != i) || !l_tpAI_Map->inside(m_tpGraph->vertex(i)->level_vertex_id(),m_tpGraph->vertex(i)->level_point()))) { Msg ("! Graph doesn't correspond to the cross table"); R_ASSERT2 (false,"Graph doesn't correspond to the cross table"); } } m_tpVertices.resize (m_tpGraph->header().vertex_count()); GRAPH_VERTEX_IT B = m_tpVertices.begin(); GRAPH_VERTEX_IT I = B; GRAPH_VERTEX_IT E = m_tpVertices.end(); for ( ; I != E; I++) { (*I).tLocalPoint = m_tpGraph->vertex(int(I - B))->level_point(); (*I).tGlobalPoint.add (m_tpGraph->vertex(int(I - B))->game_point(),m_tLevel.offset()); (*I).tLevelID = dwLevelID; (*I).tNodeID = m_tpGraph->vertex(int(I - B))->level_vertex_id(); Memory.mem_copy ((*I).tVertexTypes,m_tpGraph->vertex(int(I - B))->vertex_type(),GameGraph::LOCATION_TYPE_COUNT*sizeof(GameGraph::_LOCATION_ID)); (*I).tNeighbourCount = m_tpGraph->vertex(int(I - B))->edge_count(); CGameGraph::const_iterator b,i,e; m_tpGraph->begin (int(I - B),i,e); (*I).tpaEdges = (CGameGraph::CEdge*)xr_malloc((*I).tNeighbourCount*sizeof(CGameGraph::CEdge)); b = i; for ( ; i != e; ++i) { GameGraph::CEdge &edge = (*I).tpaEdges[i - b]; edge = *i; VERIFY ((edge.vertex_id() + dwOffset) < (u32(1) << (8*sizeof(GameGraph::_GRAPH_ID)))); edge.m_vertex_id = (GameGraph::_GRAPH_ID)(edge.m_vertex_id + dwOffset); } (*I).dwPointOffset = 0; vfGenerateDeathPoints (int(I - B),l_tpCrossTable,l_tpAI_Map,(*I).tDeathPointCount); } xr_delete (l_tpCrossTable); xr_delete (l_tpAI_Map); // updating cross-table { strcpy_s (caFileName,raw_cross_table_file_name); CGameLevelCrossTable *tpCrossTable = new CGameLevelCrossTable(caFileName); xr_vector<CGameLevelCrossTable::CCell> tCrossTableUpdate; tCrossTableUpdate.resize(tpCrossTable->header().level_vertex_count()); for (int i=0; i<(int)tpCrossTable->header().level_vertex_count(); i++) { tCrossTableUpdate[i] = tpCrossTable->vertex(i); VERIFY (u32(tCrossTableUpdate[i].tGraphIndex) < tpCrossTable->header().game_vertex_count()); tCrossTableUpdate[i].tGraphIndex = tCrossTableUpdate[i].tGraphIndex + (GameGraph::_GRAPH_ID)dwOffset; } CGameLevelCrossTable::CHeader tCrossTableHeader; tCrossTableHeader.dwVersion = XRAI_CURRENT_VERSION; tCrossTableHeader.dwNodeCount = tpCrossTable->m_tCrossTableHeader.dwNodeCount; tCrossTableHeader.dwGraphPointCount = tpCrossTable->m_tCrossTableHeader.dwGraphPointCount; tCrossTableHeader.m_level_guid = tpCrossTable->m_tCrossTableHeader.m_level_guid; tCrossTableHeader.m_game_guid = tGraphHeader.m_guid; xr_delete (tpCrossTable); m_cross_table.w(&tCrossTableHeader,sizeof(tCrossTableHeader)); for (int i=0; i<(int)tCrossTableHeader.dwNodeCount; i++) m_cross_table.w(&(tCrossTableUpdate[i]),sizeof(tCrossTableUpdate[i])); } // fill vertex map { string_path fName; strconcat (sizeof(fName),fName,S,"level.spawn"); IReader *F = FS.r_open(fName); u32 id; IReader *O = F->open_chunk_iterator(id); for (int i=0; O; O = F->open_chunk_iterator(id,O)) { NET_Packet P; P.B.count = O->length(); O->r (P.B.data,P.B.count); u16 ID; P.r_begin (ID); R_ASSERT (M_SPAWN==ID); P.r_stringZ (fName); CSE_Abstract *E = F_entity_Create(fName); R_ASSERT3 (E,"Can't create entity.",fName); // E->Spawn_Read (P); CSE_ALifeGraphPoint *tpGraphPoint = smart_cast<CSE_ALifeGraphPoint*>(E); if (tpGraphPoint) { E->Spawn_Read (P); Fvector tVector; tVector = tpGraphPoint->o_Position; GameGraph::_GRAPH_ID tGraphID = GameGraph::_GRAPH_ID(-1); float fMinDistance = 1000000.f; { GRAPH_VERTEX_IT B = m_tpVertices.begin(); GRAPH_VERTEX_IT I = B; GRAPH_VERTEX_IT E = m_tpVertices.end(); for ( ; I != E; I++) { float fDistance = (*I).tLocalPoint.distance_to(tVector); if (fDistance < fMinDistance) { fMinDistance = fDistance; tGraphID = GameGraph::_GRAPH_ID(I - B); if (fMinDistance < EPS_L) break; } } } if (fMinDistance < EPS_L) { SConnectionVertex T; LPSTR S; S = xr_strdup(tpGraphPoint->name_replace()); T.caConnectName = xr_strdup(*tpGraphPoint->m_caConnectionPointName); T.dwLevelID = dwfGetIDByLevelName(Ini,*tpGraphPoint->m_caConnectionLevelName); // T.tGraphID = (GameGraph::_GRAPH_ID)i; // T.tOldGraphID = tGraphID; T.tOldGraphID = (GameGraph::_GRAPH_ID)i; T.tGraphID = tGraphID; bool ok = true; VERTEX_MAP::const_iterator II = m_tVertexMap.begin(); VERTEX_MAP::const_iterator EE = m_tVertexMap.end(); for ( ; II != EE; ++II) if (T.tOldGraphID == (*II).second.tOldGraphID) { ok = false; Msg ("Graph point %s is removed,because it has the same position as some another graph point",E->name_replace()); break; } if (ok) { m_tVertexMap.insert (mk_pair(S,T)); i++; } } } F_entity_Destroy (E); } if (i != m_tpGraph->header().vertex_count()) Msg ("Graph for the level %s doesn't correspond to the graph points from Level Editor! (%d : %d)",*m_tLevel.name(),i,m_tpGraph->header().vertex_count()); VERTEX_MAP::const_iterator I = m_tVertexMap.begin(); VERTEX_MAP::const_iterator E = m_tVertexMap.end(); for ( ; I != E; ++I) { R_ASSERT3 (!xr_strlen((*I).second.caConnectName) || ((*I).second.tGraphID < m_tpVertices.size()),"Rebuild graph for the level",*m_tLevel.name()); } // VERIFY3 (i == m_tpGraph->header().vertex_count(), "Rebuild graph for the level ",m_tLevel.name()); O->close (); FS.r_close (F); } };
void CGameGraphBuilder::load_graph_point (NET_Packet &net_packet) { string256 section_id; u16 id; net_packet.r_begin (id); R_ASSERT (M_SPAWN == id); net_packet.r_stringZ (section_id); // if (xr_strcmp("graph_point",section_id)) // return; CSE_Abstract *entity = F_entity_Create(section_id); if (!entity) { Msg ("Cannot create entity from section %s, skipping",section_id); return; } CSE_ALifeGraphPoint *graph_point = smart_cast<CSE_ALifeGraphPoint*>(entity); if (!graph_point) { F_entity_Destroy (entity); return; } entity->Spawn_Read (net_packet); vertex_type vertex; vertex.tLocalPoint = graph_point->o_Position; // check for duplicate graph point positions { graph_type::const_vertex_iterator I = graph().vertices().begin(); graph_type::const_vertex_iterator E = graph().vertices().end(); for ( ; I != E; ++I) { if ((*I).second->data().tLocalPoint.distance_to_sqr(vertex.tLocalPoint) < EPS_L) { Msg ("! removing graph point [%s][%f][%f][%f] because it is too close to the another graph point",entity->name_replace(),VPUSH(entity->o_Position)); return; } } } vertex.tGlobalPoint = graph_point->o_Position; vertex.tNodeID = level_graph().valid_vertex_position(vertex.tLocalPoint) ? level_graph().vertex_id(vertex.tLocalPoint) : u32(-1); if (!level_graph().valid_vertex_id(vertex.tNodeID)) { Msg ("! removing graph point [%s][%f][%f][%f] because it is outside of the AI map",entity->name_replace(),VPUSH(entity->o_Position)); return; } { graph_type::const_vertex_iterator I = graph().vertices().begin(); graph_type::const_vertex_iterator E = graph().vertices().end(); for ( ; I != E; ++I) { if ((*I).second->data().tNodeID == vertex.tNodeID) { Msg ("! removing graph point [%s][%f][%f][%f] because it has the same AI node as another graph point",entity->name_replace(),VPUSH(entity->o_Position)); return; } } } vertex.tNeighbourCount = 0; Memory.mem_copy (vertex.tVertexTypes,graph_point->m_tLocations,GameGraph::LOCATION_TYPE_COUNT*sizeof(GameGraph::_LOCATION_ID)); vertex.tLevelID = 0; vertex.tDeathPointCount = 0; vertex.dwPointOffset = 0; graph().add_vertex (vertex,graph().vertices().size()); F_entity_Destroy (entity); }