void MapNode::Deserialize(SerializedGameData& sgd, const unsigned numPlayers) { for(unsigned z = 0; z < roads.size(); ++z) { roads[z] = sgd.PopUnsignedChar(); RTTR_Assert(roads[z] < 4); } altitude = sgd.PopUnsignedChar(); shadow = sgd.PopUnsignedChar(); t1 = TerrainType(sgd.PopUnsignedChar()); RTTR_Assert(t1 < TT_COUNT); t2 = TerrainType(sgd.PopUnsignedChar()); RTTR_Assert(t2 < TT_COUNT); resources = sgd.PopUnsignedChar(); reserved = sgd.PopBool(); owner = sgd.PopUnsignedChar(); for(unsigned b = 0; b < boundary_stones.size(); ++b) boundary_stones[b] = sgd.PopUnsignedChar(); bq = BuildingQuality(sgd.PopUnsignedChar()); RTTR_Assert(numPlayers < fow.size()); for(unsigned z = 0; z < numPlayers; ++z) fow[z].Deserialize(sgd); obj = sgd.PopObject<noBase>(GOT_UNKNOWN); sgd.PopObjectContainer(figures, GOT_UNKNOWN); seaId = sgd.PopUnsignedShort(); harborId = sgd.PopUnsignedInt(); }
unsigned char TerrainData::GetEdgeType(LandscapeType landsCape, TerrainType t1, TerrainType t2) { static boost::array< boost::array< boost::array<unsigned char, TT_COUNT>, TT_COUNT >, LT_COUNT > EDGE_TABLE; static bool isInitialized = false; if(!isInitialized) { // Init table for faster access for(int lt = 0; lt < LT_COUNT; ++lt) for(int iT1 = 0; iT1 < TT_COUNT; ++iT1) for(int iT2 = 0; iT2<=iT1; ++iT2) { EdgeType et1 = GetEdgeType(LandscapeType(lt), TerrainType(iT1)); EdgeType et2 = GetEdgeType(LandscapeType(lt), TerrainType(iT2)); if(iT1 == iT2 || // Same terrain !TERRAIN_DRAW_PRIORITY[lt][iT1][iT2]) // Same priority { // -> No overdraw EDGE_TABLE[lt][iT1][iT2] = 0; EDGE_TABLE[lt][iT2][iT1] = 0; }else if(TERRAIN_DRAW_PRIORITY[lt][iT1][iT2] > 0) { // T1 over T2 EDGE_TABLE[lt][iT1][iT2] = et1; EDGE_TABLE[lt][iT2][iT1] = 0; }else { // T2 over T1 EDGE_TABLE[lt][iT1][iT2] = 0; EDGE_TABLE[lt][iT2][iT1] = et2; } } isInitialized = true; } return EDGE_TABLE[landsCape][t1][t2]; }
void MapNode::Deserialize(SerializedGameData& sgd, const unsigned numPlayers) { for(unsigned z = 0; z < roads.size(); ++z) { roads[z] = sgd.PopUnsignedChar(); RTTR_Assert(roads[z] < 4); roads_real[z] = roads[z] != 0; } altitude = sgd.PopUnsignedChar(); shadow = sgd.PopUnsignedChar(); t1 = TerrainType(sgd.PopUnsignedChar()); RTTR_Assert(t1 < TT_COUNT); t2 = TerrainType(sgd.PopUnsignedChar()); RTTR_Assert(t2 < TT_COUNT); resources = sgd.PopUnsignedChar(); reserved = sgd.PopBool(); owner = sgd.PopUnsignedChar(); for(unsigned b = 0; b < boundary_stones.size(); ++b) boundary_stones[b] = sgd.PopUnsignedChar(); bq = BuildingQuality(sgd.PopUnsignedChar()); bqVisual = BuildingQuality(sgd.PopUnsignedChar()); RTTR_Assert(numPlayers < fow.size()); for(unsigned z = 0; z < numPlayers; ++z) { MapNode::FoWData& curFoW = fow[z]; curFoW.visibility = Visibility(sgd.PopUnsignedChar()); // Only in FoW can be FoW objects if(curFoW.visibility == VIS_FOW) { curFoW.last_update_time = sgd.PopUnsignedInt(); curFoW.object = sgd.PopFOWObject(); for(unsigned r = 0; r < curFoW.roads.size(); ++r) curFoW.roads[r] = sgd.PopUnsignedChar(); curFoW.owner = sgd.PopUnsignedChar(); for(unsigned b = 0; b < curFoW.boundary_stones.size(); ++b) curFoW.boundary_stones[b] = sgd.PopUnsignedChar(); } else { curFoW.last_update_time = 0; curFoW.object = NULL; for(unsigned r = 0; r < curFoW.roads.size(); ++r) curFoW.roads[r] = 0; curFoW.owner = 0; for(unsigned b = 0; b < curFoW.boundary_stones.size(); ++b) curFoW.boundary_stones[b] = 0; } } obj = sgd.PopObject<noBase>(GOT_UNKNOWN); sgd.PopObjectContainer(figures, GOT_UNKNOWN); sea_id = sgd.PopUnsignedShort(); harbor_id = sgd.PopUnsignedInt(); }
void GameWorld::Deserialize(SerializedGameData& sgd) { // Headinformationen width_ = sgd.PopUnsignedShort(); height_ = sgd.PopUnsignedShort(); lt = LandscapeType(sgd.PopUnsignedChar()); // Initialisierungen Init(); // Obj-ID-Counter setzen GameObject::SetObjIDCounter(sgd.PopUnsignedInt()); // Trade graphs // Only if trade is enabled if(GAMECLIENT.GetGGS().isEnabled(ADDON_TRADE)) { tgs.resize(sgd.PopUnsignedChar()); for(unsigned i = 0; i < tgs.size(); ++i) tgs[i] = new TradeGraph(sgd, this); } // Alle Weltpunkte serialisieren for(unsigned i = 0; i < map_size; ++i) { for(unsigned z = 0; z < 3; ++z) { nodes[i].roads[z] = sgd.PopUnsignedChar(); nodes[i].roads_real[z] = nodes[i].roads[z] ? true : false; } nodes[i].altitude = sgd.PopUnsignedChar(); nodes[i].shadow = sgd.PopUnsignedChar(); nodes[i].t1 = TerrainType(sgd.PopUnsignedChar()); nodes[i].t2 = TerrainType(sgd.PopUnsignedChar()); nodes[i].resources = sgd.PopUnsignedChar(); nodes[i].reserved = sgd.PopBool(); nodes[i].owner = sgd.PopUnsignedChar(); for(unsigned b = 0; b < 4; ++b) nodes[i].boundary_stones[b] = sgd.PopUnsignedChar(); nodes[i].bq = BuildingQuality(sgd.PopUnsignedChar()); for(unsigned z = 0; z < GAMECLIENT.GetPlayerCount(); ++z) { MapNode::FoWData& fow = nodes[i].fow[z]; fow.visibility = Visibility(sgd.PopUnsignedChar()); // Nur im FoW können FOW-Objekte stehen if(fow.visibility == VIS_FOW) { fow.last_update_time = sgd.PopUnsignedInt(); fow.object = sgd.PopFOWObject(); for(unsigned r = 0; r < 3; ++r) fow.roads[r] = sgd.PopUnsignedChar(); fow.owner = sgd.PopUnsignedChar(); for(unsigned b = 0; b < 4; ++b) fow.boundary_stones[b] = sgd.PopUnsignedChar(); } else { fow.last_update_time = 0; fow.object = NULL; for(unsigned r = 0; r < 3; ++r) fow.roads[r] = 0; fow.owner = 0; for(unsigned b = 0; b < 4; ++b) fow.boundary_stones[b] = 0; } } nodes[i].obj = sgd.PopObject<noBase>(GOT_UNKNOWN); sgd.PopObjectContainer(nodes[i].figures, GOT_UNKNOWN); nodes[i].sea_id = sgd.PopUnsignedShort(); nodes[i].harbor_id = sgd.PopUnsignedInt(); if (nodes[i].harbor_id) { GameWorldBase::HarborPos p(MapPoint((MapCoord) (i % width_), (MapCoord) (i / width_))); harbor_pos.push_back(p); } } // Katapultsteine deserialisieren sgd.PopObjectContainer(catapult_stones, GOT_CATAPULTSTONE); // Meeresinformationen deserialisieren seas.resize(sgd.PopUnsignedInt()); for(unsigned i = 0; i < seas.size(); ++i) { seas[i].nodes_count = sgd.PopUnsignedInt(); } // Hafenpositionen serialisieren harbor_pos.resize(sgd.PopUnsignedInt()); for(unsigned i = 0; i < harbor_pos.size(); ++i) { harbor_pos[i].pos = sgd.PopMapPoint(); for(unsigned z = 0; z < 6; ++z) harbor_pos[i].cps[z].sea_id = sgd.PopUnsignedShort(); for(unsigned z = 0; z < 6; ++z) { harbor_pos[i].neighbors[z].resize(sgd.PopUnsignedInt()); for(unsigned c = 0; c < harbor_pos[i].neighbors[z].size(); ++c) { harbor_pos[i].neighbors[z][c].id = sgd.PopUnsignedInt(); harbor_pos[i].neighbors[z][c].distance = sgd.PopUnsignedInt(); } } } sgd.PopObjectContainer(harbor_building_sites_from_sea, GOT_BUILDINGSITE); // BQ neu berechnen for(unsigned y = 0; y < height_; ++y) { for(unsigned x = 0; x < width_; ++x) { SetBQ(MapPoint(x, y), GAMECLIENT.GetPlayerID()); } } tr.GenerateOpenGL(*this); // Zum HQ am Anfang springen, falls dieses existiert if(GetPlayer(GAMECLIENT.GetPlayerID()).hqPos.x != 0xFFFF) this->MoveToMapObject(GetPlayer(GAMECLIENT.GetPlayerID()).hqPos); }
/** * zeichnet den Kartenausschnitt. * * @author OLiver * @author FloSoft */ void TerrainRenderer::Draw(const GameWorldView& gwv, unsigned int* water) { assert(!gl_vertices.empty()); assert(!borders.empty()); /* if ((gwv.GetXOffset() == gwv.terrain_last_xoffset) && (gwv.GetYOffset() == gwv.terrain_last_yoffset) && (gwv.terrain_list != 0) && (GAMECLIENT.GetGlobalAnimation(4, 5, 4, 0) == gwv.terrain_last_global_animation)) { glCallList(gwv.terrain_list); *water = gwv.terrain_last_water; return; } gwv.terrain_last_xoffset = gwv.GetXOffset(); gwv.terrain_last_yoffset = gwv.GetYOffset(); gwv.terrain_last_global_animation = GAMECLIENT.GetGlobalAnimation(4, 5, 4, 0); if (gwv.terrain_list == 0) gwv.terrain_list = glGenLists(1); glNewList(gwv.terrain_list, GL_COMPILE_AND_EXECUTE);*/ // nach Texture in Listen sortieren boost::array< std::vector<MapTile>, TT_COUNT> sorted_textures; boost::array< std::vector<BorderTile>, 5> sorted_borders; PreparedRoads sorted_roads; Point<int> lastOffset(0, 0); // Beim zeichnen immer nur beginnen, wo man auch was sieht for(int y = gwv.GetFirstPt().y; y < gwv.GetLastPt().y; ++y) { unsigned char lastTerrain = 255; unsigned char lastBorder = 255; for(int x = gwv.GetFirstPt().x; x < gwv.GetLastPt().x; ++x) { Point<int> posOffset; MapPoint tP = ConvertCoords(Point<int>(x, y), &posOffset); TerrainType t = gwv.GetGameWorldViewer().GetNode(tP).t1; if(posOffset != lastOffset) lastTerrain = 255; if(t == lastTerrain && tP != MapPoint(0, 0)) ++sorted_textures[t].back().count; else { MapTile tmp(GetTriangleIdx(tP), posOffset); sorted_textures[t].push_back(tmp); lastTerrain = t; } t = gwv.GetGameWorldViewer().GetNode(tP).t2; if(t == lastTerrain) ++sorted_textures[t].back().count; else { MapTile tmp(GetTriangleIdx(tP) + 1, posOffset); sorted_textures[t].push_back(tmp); } lastTerrain = t; const Borders& curBorders = borders[GetVertexIdx(tP)]; boost::array<unsigned char, 6> tiles = {{ curBorders.left_right[0], curBorders.left_right[1], curBorders.right_left[0], curBorders.right_left[1], curBorders.top_down[0], curBorders.top_down[1] }}; // Offsets into gl_* arrays boost::array<unsigned, 6> offsets = {{ curBorders.left_right_offset[0], curBorders.left_right_offset[1], curBorders.right_left_offset[0], curBorders.right_left_offset[1], curBorders.top_down_offset[0], curBorders.top_down_offset[1] }}; for(unsigned char i = 0; i < 6; ++i) { if(!tiles[i]) continue; if(tiles[i] == lastBorder) { BorderTile& curTile = sorted_borders[lastBorder - 1].back(); // Check that we did not wrap around the map and the expected offset matches if(curTile.tileOffset + curTile.count == offsets[i]) { ++curTile.count; continue; } } lastBorder = tiles[i]; BorderTile tmp(offsets[i], posOffset); sorted_borders[lastBorder - 1].push_back(tmp); } PrepareWaysPoint(sorted_roads, gwv, tP, posOffset); lastOffset = posOffset; } } if (water) { unsigned water_count = 0; for(unsigned char t = 0; t < TT_COUNT; ++t){ if(!TerrainData::IsWater(TerrainType(t))) continue; for(std::vector<MapTile>::iterator it = sorted_textures[t].begin(); it != sorted_textures[t].end(); ++it) { water_count += it->count; } } PointI diff = gwv.GetLastPt() - gwv.GetFirstPt(); if( diff.x && diff.y ) *water = 50 * water_count / ( diff.x * diff.y ); else *water = 0; } lastOffset = PointI(0, 0); if(vboBuffersUsed) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_vertices); glVertexPointer(2, GL_FLOAT, 0, NULL); glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_texcoords); glTexCoordPointer(2, GL_FLOAT, 0, NULL); glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_colors); glColorPointer(3, GL_FLOAT, 0, NULL); } else { glVertexPointer(2, GL_FLOAT, 0, &gl_vertices.front()); glTexCoordPointer(2, GL_FLOAT, 0, &gl_texcoords.front()); glColorPointer(3, GL_FLOAT, 0, &gl_colors.front()); } // Arrays aktivieren glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_COLOR_ARRAY); // Modulate2x glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 2.0f); // Verschieben gem#ß x und y offset glTranslatef( float(-gwv.GetXOffset()), float(-gwv.GetYOffset()), 0.0f); // Alphablending aus glDisable(GL_BLEND); for(unsigned char t = 0; t < TT_COUNT; ++t) { if(sorted_textures[t].empty()) continue; unsigned animationFrame; TerrainType tt = TerrainType(t); if(TerrainData::IsLava(tt)) animationFrame = GAMECLIENT.GetGlobalAnimation(TerrainData::GetFrameCount(tt), 5, 4, 0); else if(TerrainData::IsWater(tt)) animationFrame = GAMECLIENT.GetGlobalAnimation(TerrainData::GetFrameCount(tt), 5, 2, 0); else animationFrame = 0; VIDEODRIVER.BindTexture(LOADER.GetTerrainTexture(tt, animationFrame).GetTexture()); for(std::vector<MapTile>::iterator it = sorted_textures[t].begin(); it != sorted_textures[t].end(); ++it) { if(it->posOffset != lastOffset) { PointI trans = it->posOffset - lastOffset; glTranslatef( float(trans.x), float(trans.y), 0.0f); lastOffset = it->posOffset; } assert(it->tileOffset + it->count <= width * height * 2u); glDrawArrays(GL_TRIANGLES, it->tileOffset * 3, it->count * 3); // Arguments are in Elements. 1 triangle has 3 values } } glEnable(GL_BLEND); glLoadIdentity(); glTranslatef( float(-gwv.GetXOffset()), float(-gwv.GetYOffset()), 0.0f); lastOffset = PointI(0, 0); for(unsigned short i = 0; i < 5; ++i) { if(sorted_borders[i].empty()) continue; VIDEODRIVER.BindTexture(GetImage(borders, i)->GetTexture()); for(std::vector<BorderTile>::iterator it = sorted_borders[i].begin(); it != sorted_borders[i].end(); ++it) { if(it->posOffset != lastOffset) { PointI trans = it->posOffset - lastOffset; glTranslatef( float(trans.x), float(trans.y), 0.0f); lastOffset = it->posOffset; } assert(it->tileOffset + it->count <= gl_vertices.size()); glDrawArrays(GL_TRIANGLES, it->tileOffset * 3, it->count * 3); // Arguments are in Elements. 1 triangle has 3 values } } glLoadIdentity(); DrawWays(sorted_roads); // Wieder zurück ins normale modulate glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); }