/** * 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); }
void noFigure::WalkToGoal() { // Kein Ziel mehr --> Rumirren if(!goal) { StartWandering(); Wander(); return; } // Straße abgelaufen oder noch gar keine Straße vorhanden? if(((cur_rs) ? (rs_pos == cur_rs->GetLength()) : true)) { // Ziel erreicht? // Bei dem Träger können das beide Flaggen sein! MapPoint goal1, goal2; if(GetGOT() == GOT_NOF_CARRIER && fs == FS_GOTOGOAL) { goal1 = static_cast<nofCarrier*>(this)->GetFirstFlag() ? static_cast<nofCarrier*>(this)->GetFirstFlag()->GetPos() : MapPoint(0xFFFF, 0xFFFF); goal2 = static_cast<nofCarrier*>(this)->GetSecondFlag() ? static_cast<nofCarrier*>(this)->GetSecondFlag()->GetPos() : MapPoint(0xFFFF, 0xFFFF); } else { goal1 = goal->GetPos(); goal2 = MapPoint(0xFFFF, 0xFFFF); } if(goal1 == pos || goal2 == pos) { if(fs == FS_GOHOME) { // Mann im Lagerhaus angekommen gwg->RemoveFigure(this, pos); static_cast<nobBaseWarehouse*>(goal)->AddFigure(this); } else { // Zeug nullen cur_rs = NULL; rs_dir = 0; rs_pos = 0; goal = NULL; // abgeleiteter Klasse sagen, dass das Ziel erreicht wurde fs = FS_JOB; GoalReached(); } } else { MapPoint next_harbor; // Neuen Weg berechnen unsigned char route = gwg->FindHumanPathOnRoads(gwg->GetSpecObj<noRoadNode>(pos), goal, NULL, &next_harbor); // Kein Weg zum Ziel... nächstes Lagerhaus suchen if(route == 0xFF) { // Arbeisplatz oder Laghaus Bescheid sagen Abrogate(); // Wir gehen jetzt nach Hause GoHome(); // Evtl wurde kein Lagerhaus gefunden und wir sollen rumirren, dann tun wir das gleich if(fs == FS_WANDER) { Wander(); return; } // Nach Hause laufen... WalkToGoal(); return; } // Oder müssen wir das Schiff nehmen? else if(route == SHIP_DIR) { // Uns in den Hafen einquartieren noBase* nob; if((nob = gwg->GetNO(pos))->GetGOT() != GOT_NOB_HARBORBUILDING) { // Es gibt keinen Hafen mehr -> nach Hause gehen // Arbeisplatz oder Laghaus Bescheid sagen Abrogate(); // Wir gehen jetzt nach Hause GoHome(); // Evtl wurde kein Lagerhaus gefunden und wir sollen rumirren, dann tun wir das gleich if(fs == FS_WANDER) { Wander(); return; } // Nach Hause laufen... WalkToGoal(); return; } // Uns in den Hafen einquartieren cur_rs = NULL; // wir laufen nicht mehr auf einer Straße gwg->RemoveFigure(this, pos); static_cast<nobHarborBuilding*>(nob)->AddFigureForShip(this, next_harbor); return; } // Nächste Straße wollen, auf der man geht cur_rs = gwg->GetSpecObj<noRoadNode>(pos)->routes[route]; StartWalking(route); rs_pos = 0; rs_dir = (gwg->GetSpecObj<noRoadNode>(pos) == cur_rs->GetF1()) ? false : true; } } else { StartWalking(cur_rs->GetDir(rs_dir, rs_pos)); } }
void MapAnalysis::BeginTurn() { MapPoint pos; Army army; Unit city; Unit unit; sint32 i; m_piracyIncomeMatrix.assign(m_piracyIncomeMatrix.size(), 0); m_cityOnContinent.Reset(FALSE); m_armyOnContinent.Reset(FALSE); m_worldPopulation = 0; ComputeHandicapRatios(); size_t player; for (player = 0; player < m_threatGrid.size(); ++player) { m_threatGrid [player].Clear(); m_attackGrid [player].Clear(); m_defenseGrid [player].Clear(); m_rangedGrid [player].Clear(); m_bombardLandGrid [player].Clear(); m_bombardSeaGrid [player].Clear(); m_bombardAirGrid [player].Clear(); m_valueGrid [player].Clear(); m_tradeAtRiskGrid [player].Clear(); m_piracyLossGrid [player].Clear(); m_minCityThreat [player] = std::numeric_limits<sint32>::max(); m_maxCityThreat [player] = std::numeric_limits<sint32>::min(); m_movementTypeUnion[player] = 0x0; m_nuclearWeapons [player] = 0; m_bioWeapons [player] = 0; m_nanoWeapons [player] = 0; m_specialAttackers [player] = 0; m_continentSize [player] = 0; m_totalPopulation [player] = 0; m_landArea [player] = 0; m_totalTrade [player] = 0; Player * player_ptr = g_player[player]; if (player_ptr == NULL) continue; RecalcCityRanks(player); m_projectedScience[player] = player_ptr->m_advances->GetProjectedScience(); m_totalPopulation[player] = static_cast<sint16>(player_ptr->GetTotalPopulation()); m_landArea[player] = static_cast<sint16>(player_ptr->GetLandArea()); m_worldPopulation += m_totalPopulation[player]; sint32 num_units = player_ptr->m_all_units->Num(); for (i = 0; i < num_units; i++) { unit = player_ptr->m_all_units->Access(i); Assert(unit.IsValid()); if ( unit.IsValid() && unit.GetDBRec() && unit.GetDBRec()->GetNumSpecialAttacks() > 0 ) { m_specialAttackers[player]++; } } sint32 num_armies = player_ptr->m_all_armies->Num(); for (i = 0; i < num_armies; i++) { army = player_ptr->m_all_armies->Access(i); Assert(army.IsValid()); army->GetPos(pos); sint8 defense_count; sint8 ranged_count; float attack_strength; float defense_strength; float ranged_strength; float bombard_land_strength; float bombard_sea_strength; float bombard_air_strength; float total_value; army->ComputeStrength(attack_strength, defense_strength, ranged_strength, defense_count, ranged_count, bombard_land_strength, bombard_sea_strength, bombard_air_strength, total_value, false ); Assert(total_value >= 0); m_nuclearWeapons[player] += army->CountNuclearUnits(); m_bioWeapons[player] += army->CountBioUnits(); m_nanoWeapons[player] += army->CountNanoUnits(); if(m_empireCenter[player] == MapPoint()) { CalcEmpireCenter(player); } if(!m_empireBoundingRect[player].IsValid()) { UpdateBoundingRectangle(army); } m_threatGrid [player].AddValue(pos, static_cast<sint32>(attack_strength + ranged_strength)); m_attackGrid [player].AddValue(pos, static_cast<sint32>(attack_strength)); m_defenseGrid [player].AddValue(pos, static_cast<sint32>(defense_strength)); m_rangedGrid [player].AddValue(pos, static_cast<sint32>(ranged_strength)); m_bombardLandGrid [player].AddValue(pos, static_cast<sint32>(bombard_land_strength)); m_bombardSeaGrid [player].AddValue(pos, static_cast<sint32>(bombard_sea_strength)); m_bombardAirGrid [player].AddValue(pos, static_cast<sint32>(bombard_air_strength)); m_valueGrid [player].AddValue(pos, static_cast<sint32>(total_value)); bool is_land; sint16 cont; g_theWorld->GetContinent(pos, cont, is_land); if(is_land) { bool is_military = (attack_strength > 0 || ranged_strength > 0) && !army->IsCivilian(); if(is_military) { m_armyOnContinent.Set(player, cont, TRUE); } } m_movementTypeUnion[player] |= army.GetMovementType(); Assert(m_threatGrid [player].GetTotalValue() >= 0); Assert(m_attackGrid [player].GetTotalValue() >= 0); Assert(m_defenseGrid [player].GetTotalValue() >= 0); Assert(m_rangedGrid [player].GetTotalValue() >= 0); Assert(m_bombardLandGrid [player].GetTotalValue() >= 0); Assert(m_bombardSeaGrid [player].GetTotalValue() >= 0); Assert(m_bombardAirGrid [player].GetTotalValue() >= 0); Assert(m_valueGrid [player].GetTotalValue() >= 0); Assert(m_nuclearWeapons [player] >= 0); Assert(m_bioWeapons [player] >= 0); Assert(m_nanoWeapons [player] >= 0); Assert(m_specialAttackers[player] >= 0); Assert(m_continentSize [player] >= 0); Assert(m_totalPopulation [player] >= 0); Assert(m_landArea [player] >= 0); Assert(m_totalTrade [player] >= 0); } sint32 num_cities = player_ptr->m_all_cities->Num(); for (i = 0; i < num_cities; i++) { city = player_ptr->m_all_cities->Access(i); Assert(city.IsValid() && city->GetCityData()); city.GetPos(pos); sint32 total_value = city->GetCityData()->GetValue(); m_totalTrade[player] += city->GetCityData()->GetGoldFromTradeRoutes(); m_valueGrid[player].AddValue(pos, total_value); TradeDynamicArray * trade_routes = city.CD()->GetTradeSourceList(); Assert(trade_routes != NULL); sint32 tradeRouteCount = trade_routes ? trade_routes->Num() : 0; for (sint32 j = 0; j < tradeRouteCount; j++) { sint32 route_value = trade_routes->Get(j)->GetValue(); Army pirate_army = trade_routes->Get(j)->GetPiratingArmy(); if (pirate_army.IsValid()) { m_piracyLossGrid[player]. AddValue(pirate_army->RetPos(), route_value); AddPiracyIncome(pirate_army.GetOwner(), player, static_cast<sint16>(route_value)); m_valueGrid[pirate_army.GetOwner()]. AddValue(pirate_army->RetPos(), route_value); } const DynamicArray < MapPoint > * path = trade_routes->Get(j)->GetPath(); sint32 per_cell_value = (sint32)(((double)route_value / path->Num()) * 1000.0); for (sint32 k = 0; k < path->Num(); k++) { m_tradeAtRiskGrid[player].AddValue(path->Get(k), per_cell_value); } } bool is_land; sint16 cont; g_theWorld->GetContinent(pos, cont, is_land); if (is_land) { m_cityOnContinent.Set(player, cont, TRUE); m_continentSize[player] += g_theWorld->GetLandContinentSize(cont) / num_cities; } } } DPRINTF(k_DBG_MAPANALYSIS, ("BEFORE RELAX:\n")); DebugLog(); DPRINTF(k_DBG_MAPANALYSIS, ("\n")); const sint8 cycles = 1; const float coef = 0.95f; for (player = 0; player < m_threatGrid.size(); player++) { m_threatGrid [player].Relax(cycles, coef); m_attackGrid [player].Relax(cycles, coef); m_defenseGrid [player].Relax(cycles, coef); m_rangedGrid [player].Relax(cycles, coef); m_bombardLandGrid [player].Relax(cycles, coef); m_bombardSeaGrid [player].Relax(cycles, coef); m_bombardAirGrid [player].Relax(cycles, coef); m_valueGrid [player].Relax(cycles, coef); } for (player = 0; player < m_threatGrid.size(); player++) { if(Diplomat::HasDiplomat(player)) { Diplomat::GetDiplomat(player).ComputeAllDesireWarWith(); Diplomat::GetDiplomat(player).ComputeIncursionPermission(); } } for (player = 0; player < m_threatGrid.size(); player++) { Player * player_ptr = g_player[player]; if (player_ptr == NULL) continue; sint32 num_cities = player_ptr->m_all_cities->Num(); for (i = 0; i < num_cities; i++) { city = player_ptr->m_all_cities->Access(i); // Threat has to be calculated after relax sint32 threat = GetThreat(player, city.RetPos()); if (threat < m_minCityThreat[player]) m_minCityThreat[player] = threat; if (threat > m_maxCityThreat[player]) m_maxCityThreat[player] = threat; } } DPRINTF(k_DBG_MAPANALYSIS, ("RELAXED:\n")); DebugLog(); DPRINTF(k_DBG_MAPANALYSIS, ("\n")); }
void editMap (MapPoint point, int button) { if( !getGameView()->inCity( point ) ){ return; } int x = point.x; int y = point.y; int selected_module_group = get_group_of_type(selected_module_type); int size; // int x, y; /* mappoint */ int mod_x, mod_y; /* upper left coords of module clicked on */ int mps_result; if (MP_TYPE(x,y) == CST_USED) { mod_x = MP_INFO(x,y).int_1; mod_y = MP_INFO(x,y).int_2; } else { mod_x = x; mod_y = y; } /* Bring up mappoint_stats for any right mouse click */ if (button == SDL_BUTTON_RIGHT) { mps_set( x, y, MPS_ENV); return; } /* Handle bulldozing */ if (selected_module_type == CST_GREEN && button != SDL_BUTTON_RIGHT) { check_bulldoze_area (x, y); mps_result = mps_set( mod_x, mod_y, MPS_MAP ); // Update mps on bulldoze #ifdef DEBUG DBG_TileInfo(x, y); #endif return; } /* Bring up mappoint_stats for certain left mouse clicks */ /* Check market and port double-clicks here */ /* Check rocket launches */ if( !GROUP_IS_BARE(MP_GROUP( x,y )) ) { if(mapMPS) mapMPS->playBuildingSound( mod_x, mod_y ); mps_result = mps_set( mod_x, mod_y, MPS_MAP ); //query Tool #ifdef DEBUG DBG_TileInfo(x, y); #endif if( mps_result >= 1 ){ if( MP_GROUP( mod_x,mod_y ) == GROUP_MARKET ){ clicked_market_cb (mod_x, mod_y); return; } else if (MP_GROUP(mod_x,mod_y) == GROUP_PORT) { clicked_port_cb (mod_x, mod_y); return; } else if (MP_TYPE(mod_x,mod_y) >= CST_ROCKET_5 && MP_TYPE(mod_x,mod_y) <= CST_ROCKET_7){ //Dialogs delete themself new Dialog( ASK_LAUNCH_ROCKET, mod_x,mod_y ); return; } } //to be here we are not in bulldoze-mode and the tile //under the cursor is not empty. //to allow up/downgrading of Tracks,Roads,Rails and bridges we can't always return. if( ( selected_module_type != CST_TRACK_LR ) && ( selected_module_type != CST_ROAD_LR ) && ( selected_module_type != CST_RAIL_LR ) ) { return; //not building a transport } if( ( MP_GROUP(x,y) != GROUP_WATER ) && ( !( MP_INFO(x,y).flags & FLAG_IS_TRANSPORT ))){ return; //target area is neither water not a transport } if( selected_module_type == CST_TRACK_LR ) { if( MP_GROUP( x, y ) == GROUP_TRACK || MP_GROUP( x, y ) == GROUP_TRACK_BRIDGE || MP_GROUP( x, y ) == GROUP_ROAD || MP_GROUP( x, y ) == GROUP_ROAD_BRIDGE || MP_GROUP( x, y ) == GROUP_RAIL || MP_GROUP( x, y ) == GROUP_RAIL_BRIDGE ) return; } else if( selected_module_type == CST_ROAD_LR ) { if ( MP_GROUP( x, y ) == GROUP_ROAD || MP_GROUP( x, y ) == GROUP_ROAD_BRIDGE || MP_GROUP( x, y ) == GROUP_RAIL || MP_GROUP( x, y ) == GROUP_RAIL_BRIDGE ) return; } else if( selected_module_type == CST_RAIL_LR ) { if( MP_GROUP( x, y ) == GROUP_RAIL || MP_GROUP( x, y ) == GROUP_RAIL_BRIDGE ) return; } } //query Tool if(selected_module_type==CST_NONE) { if (mapMPS) { mapMPS->playBuildingSound( mod_x, mod_y ); mapMPS->setView(MapPoint( mod_x, mod_y )); } mps_result = mps_set( mod_x, mod_y, MPS_MAP ); //query Tool on CST_NONE #ifdef DEBUG DBG_TileInfo(x, y); #endif return; } /* OK, by now we are certain that the user wants to place the item. Set the origin based on the size of the selected_module_type, and see if the selected item will fit. */ size = main_groups[selected_module_group].size; /* if (px > (mw->x + mw->w) - size*16) px = (mw->x + mw->w) - size*16; if (py > (mw->y + mw->h) - size*16) py = (mw->y + mw->h) - size*16; pixel_to_mappoint(px, py, &x, &y); */ //Check if we are too close to the border if( x + size > WORLD_SIDE_LEN - 1 || y + size > WORLD_SIDE_LEN - 1 || x < 1 || y < 1 ) return; if (size >= 2) { if (!GROUP_IS_BARE(MP_GROUP(x + 1,y)) || !GROUP_IS_BARE(MP_GROUP(x,y + 1)) || !GROUP_IS_BARE(MP_GROUP(x + 1,y + 1))) return; } if (size >= 3) { if (!GROUP_IS_BARE(MP_GROUP(x + 2,y)) || !GROUP_IS_BARE(MP_GROUP(x + 2,y + 1)) || !GROUP_IS_BARE(MP_GROUP(x + 2,y + 2)) || !GROUP_IS_BARE(MP_GROUP(x + 1,y + 2)) || !GROUP_IS_BARE(MP_GROUP(x,y + 2))) return; } if (size == 4) { if (!GROUP_IS_BARE(MP_GROUP(x + 3,y)) || !GROUP_IS_BARE(MP_GROUP(x + 3,y + 1)) || !GROUP_IS_BARE(MP_GROUP(x + 3,y + 2)) || !GROUP_IS_BARE(MP_GROUP(x + 3,y + 3)) || !GROUP_IS_BARE(MP_GROUP(x + 2,y + 3)) || !GROUP_IS_BARE(MP_GROUP(x + 1,y + 3)) || !GROUP_IS_BARE(MP_GROUP(x,y + 3))) return; } //how to build a lake in the park? //just hold 'W' key on build ;-) if( selected_module_group == GROUP_PARKLAND ){ Uint8 *keystate = SDL_GetKeyState(NULL); if ( keystate[SDLK_w] ) selected_module_type = CST_PARKLAND_LAKE; else selected_module_type = CST_PARKLAND_PLANE; } /* Place the selected item . Warning messages are managed by place_item(...) */ last_message_group = place_item (x, y, selected_module_type); switch (last_message_group) { case 0: /* Success */ getSound()->playSound( "Build" ); mps_result = mps_set( mod_x, mod_y, MPS_MAP ); // Update mps on well-built #ifdef DEBUG DBG_TileInfo(x, y); #endif break; case -1000: /* ouch group does not exist */ case -1: /* Not enough money */ case -2: /* Improper port placement */ case -3: /* too many windmills/substations */ case -4: /* too many market */ case -5: /* previous tip here, cannot build tip here */ case -6: /* previous tip here, cannot build oremine */ case -7: /* no ore reserve. cannot build oremine here */ default: /* warning messages are managed by place item */ last_message_group = 0; } }
void GameWorld::Scan(glArchivItem_Map* map) { width = map->getHeader().getWidth(); height = map->getHeader().getHeight(); lt = LandscapeType(map->getHeader().getGfxSet()); Init(); // Dummy-Hafenpos für Index 0 einfügen // ask Oliverr why! // -> I just did, the dummy is so that the harbor "0" might be used for ships with no particular destination // poc: if you ever remove this dummy go to GameWorldBase::CalcDistanceToNearestHarbor and fix the loop to include the first harbor again (think Ive seen other instances of dummyadjusted loops as well...) GameWorldBase::HarborPos dummy(MapPoint(0, 0)); harbor_pos.push_back(dummy); // Andere Sachen setzen MapPoint pt(0, 0); for(pt.y = 0; pt.y < height; ++pt.y) { for(pt.x = 0; pt.x < width; ++pt.x) { MapNode& node = GetNode(pt); node.roads[2] = node.roads[1] = node.roads[0] = 0; node.roads_real[2] = node.roads_real[1] = node.roads_real[0] = false; node.altitude = map->GetMapDataAt(MAP_ALTITUDE, pt.x, pt.y); // Aufpassen, dass die Terrainindizes im Rahmen liegen, ansonsten 0 nehmen, unbekanntes Terrain (Bsp. // Karte "Drachenebene") unsigned char t1 = map->GetMapDataAt(MAP_TERRAIN1, pt.x, pt.y), t2 = map->GetMapDataAt(MAP_TERRAIN2, pt.x, pt.y); // Hafenplatz? if(t1 >= 0x40 && t1 <= 0x54) { t1 -= 0x40; GameWorldBase::HarborPos p(pt); node.harbor_id = harbor_pos.size(); harbor_pos.push_back(p); } else node.harbor_id = 0; node.t1 = (t1 < 20) ? TERRAIN_INDIZES[t1] : 0; node.t2 = (t2 < 20) ? TERRAIN_INDIZES[t2] : 0; node.resources = map->GetMapDataAt(MAP_RESOURCES, pt.x, pt.y); // Wasser? if(node.resources == 0x20 || node.resources == 0x21) { // TODO: Berge hatten komische Wasserbeeinflussung // ggf 0-4 Wasser setzen if( (node.t1 == TT_DESERT || node.t2 == TT_DESERT) || (node.t1 == TT_WATER || node.t2 == TT_WATER) ) node.resources = 0; // Kein Wasser, in der Wüste, da isses trocken! else if( (node.t1 == TT_STEPPE || node.t2 == TT_STEPPE) ) node.resources = 0x23; // 2 Wasser else if( (node.t1 == TT_SAVANNAH || node.t2 == TT_SAVANNAH) ) node.resources = 0x25; // 4 Wasser else node.resources = 0x27; // 7 Wasser } node.reserved = false; node.owner = 0; for(unsigned i = 0; i < 4; ++i) node.boundary_stones[i] = 0; node.sea_id = 0; // FOW-Zeug initialisieren for(unsigned i = 0; i < GAMECLIENT.GetPlayerCount(); ++i) { switch(GAMECLIENT.GetGGS().exploration) { case GlobalGameSettings::EXP_DISABLED: { node.fow[i].visibility = VIS_VISIBLE; } break; case GlobalGameSettings::EXP_CLASSIC: { node.fow[i].visibility = VIS_INVISIBLE; } break; case GlobalGameSettings::EXP_FOGOFWAR: { node.fow[i].visibility = VIS_INVISIBLE; } break; case GlobalGameSettings::EXP_FOGOFWARE_EXPLORED: { node.fow[i].visibility = VIS_FOW; } break; } node.fow[i].last_update_time = 0; node.fow[i].object = NULL; node.fow[i].roads[0] = node.fow[i].roads[1] = node.fow[i].roads[2] = 0; node.fow[i].owner = 0; for(unsigned z = 0; z < 4; ++z) node.fow[i].boundary_stones[z] = 0; } } } std::vector< MapPoint > headquarter_positions; // Objekte auslesen for(pt.y = 0; pt.y < height; ++pt.y) { for(pt.x = 0; pt.x < width; ++pt.x) { unsigned int pos = GetIdx(pt); unsigned char lc = map->GetMapDataAt(MAP_LANDSCAPE, pt.x, pt.y); switch(map->GetMapDataAt(MAP_TYPE, pt.x, pt.y)) { // Player Startpos (provisorisch) case 0x80: { headquarter_positions.push_back(pt); if(lc < GAMECLIENT.GetPlayerCount()) { GetPlayer(lc)->hqPos = pt; nodes[pos].obj = NULL; } } break; // Baum 1-4 case 0xC4: { if(lc >= 0x30 && lc <= 0x3D) nodes[pos].obj = new noTree(pt, 0, 3); else if(lc >= 0x70 && lc <= 0x7D) nodes[pos].obj = new noTree(pt, 1, 3); else if(lc >= 0xB0 && lc <= 0xBD) nodes[pos].obj = new noTree(pt, 2, 3); else if(lc >= 0xF0 && lc <= 0xFD) nodes[pos].obj = new noTree(pt, 3, 3); else { LOG.lprintf("Unbekannter Baum1-4 auf x=%d, y=%d: id=%d (0x%0X)\n", pt.x, pt.y, lc, lc); nodes[pos].obj = NULL; } } break; // Baum 5-8 case 0xC5: { if(lc >= 0x30 && lc <= 0x3D) nodes[pos].obj = new noTree(pt, 4, 3); else if(lc >= 0x70 && lc <= 0x7D) nodes[pos].obj = new noTree(pt, 5, 3); else if(lc >= 0xB0 && lc <= 0xBD) nodes[pos].obj = new noTree(pt, 6, 3); else if(lc >= 0xF0 && lc <= 0xFD) nodes[pos].obj = new noTree(pt, 7, 3); else { LOG.lprintf("Unbekannter Baum5-8 auf x=%d, y=%d: id=%d (0x%0X)\n", pt.x, pt.y, lc, lc); nodes[pos].obj = NULL; } } break; // Baum 9 case 0xC6: { if(lc >= 0x30 && lc <= 0x3D) nodes[pos].obj = new noTree(pt, 8, 3); else { LOG.lprintf("Unbekannter Baum9 auf x=%d, y=%d: id=%d (0x%0X)\n", pt.x, pt.y, lc, lc); nodes[pos].obj = NULL; } } break; // Sonstiges Naturzeug ohne Funktion, nur zur Dekoration case 0xC8: { /// @todo mis0bobs unvollständig (dieses lagerzelt), 4 und 5 überhaupt nicht erwähnt // mis1bobs, 2 und 3 sind vollständig eingebaut // Objekte aus der map_?_z.lst if(lc <= 0x0A) nodes[pos].obj = new noEnvObject(pt, 500 + lc); // "wasserstein" aus der map_?_z.lst else if(lc == 0x0B) nodes[pos].obj = new noStaticObject(pt, 500 + lc); // Objekte aus der map_?_z.lst else if(lc >= 0x0C && lc <= 0x0F) nodes[pos].obj = new noEnvObject(pt, 500 + lc); // Objekte aus der map.lst else if(lc >= 0x10 && lc <= 0x14) nodes[pos].obj = new noEnvObject(pt, 542 + lc - 0x10); // gestrandetes Schiff (mis0bobs, unvollständig) else if(lc == 0x15) nodes[pos].obj = new noStaticObject(pt, (lc - 0x15) * 2, 0, 1); // das Tor aus der map_?_z.lst else if(lc == 0x16) nodes[pos].obj = new noStaticObject(pt, 560, 0xFFFF, 2); // das geöffnete Tor aus map_?_z.lst else if(lc == 0x17) nodes[pos].obj = new noStaticObject(pt, 561, 0xFFFF, 2); // Stalagmiten (mis1bobs) else if(lc >= 0x18 && lc <= 0x1E) nodes[pos].obj = new noStaticObject(pt, (lc - 0x18) * 2, 1); // toter Baum (mis1bobs) else if(lc >= 0x1F && lc <= 0x20) nodes[pos].obj = new noStaticObject(pt, 20 + (lc - 0x1F) * 2, 1); // Gerippe (mis1bobs) else if(lc == 0x21) nodes[pos].obj = new noEnvObject(pt, 30, 1); // Objekte aus der map.lst else if(lc >= 0x22 && lc <= 0x27) nodes[pos].obj = new noEnvObject(pt, 550 + lc - 0x22); // Objekte aus der map.lst else if(lc >= 0x28 && lc <= 0x2B) nodes[pos].obj = new noEnvObject(pt, 556 + lc - 0x28); // die "kaputten" Gebäuderuinen usw (mis2bobs) else if(lc >= 0x2C && lc <= 0x2D) nodes[pos].obj = new noStaticObject(pt, (lc - 0x2C) * 2, 2); else if(lc == 0x2E) nodes[pos].obj = new noStaticObject(pt, (lc - 0x2C) * 2, 2, 1); else if(lc == 0x2F) nodes[pos].obj = new noStaticObject(pt, (lc - 0x2C) * 2, 2, 2); else if(lc == 0x30) nodes[pos].obj = new noEnvObject(pt, (lc - 0x2C) * 2, 2); // der Wikinger (mis3bobs) else if(lc == 0x31) nodes[pos].obj = new noStaticObject(pt, 0, 2); else { LOG.lprintf("Unbekanntes Naturzeug auf x=%d, y=%d: id=%d (0x%0X)\n", pt.x, pt.y, lc, lc); nodes[pos].obj = NULL; } } break; // Granit Typ 1 case 0xCC: { if(lc >= 0x01 && lc <= 0x06) nodes[pos].obj = new noGranite(GT_1, lc - 1); else { LOG.lprintf("Unbekannter Granit1 auf x=%d, y=%d: id=%d (0x%0X)\n", pt.x, pt.y, lc, lc); nodes[pos].obj = NULL; } } break; // Granit Typ 2 case 0xCD: { if(lc >= 0x01 && lc <= 0x06) nodes[pos].obj = new noGranite(GT_2, lc - 1); else { LOG.lprintf("Unbekannter Granit2 auf x=%d, y=%d: id=%d (0x%0X)\n", pt.x, pt.y, lc, lc); nodes[pos].obj = NULL; } } break; // Nichts case 0: { nodes[pos].obj = NULL; } break; default: { /*LOG.lprintf("Unbekanntes Objekt %d (0x%0X) auf x=%d, y=%d: id=%d (0x%0X)\n", map->map_type[y*width+x], map->map_type[y*width+x], x, y, lc, lc); */ nodes[pos].obj = NULL; } break; } } } // BQ mit nichts erstmal inititalisieren (HQ-Setzen berechnet diese neu und braucht sie) for(pt.y = 0; pt.y < height; ++pt.y) { for(pt.x = 0; pt.x < width; ++pt.x) { SetBQ(pt, BQ_NOTHING); } } //random locations? -> randomize them :) if (GAMECLIENT.GetGGS().random_location) { ptrdiff_t (*p_myrandom)(ptrdiff_t) = myRandom; std::random_shuffle(headquarter_positions.begin(), headquarter_positions.end(), p_myrandom); for (unsigned i = 0; i < GAMECLIENT.GetPlayerCount(); ++i) { GetPlayer(i)->hqPos = headquarter_positions.at(i); } } // HQ setzen for(unsigned i = 0; i < GAMECLIENT.GetPlayerCount(); ++i) { // Existiert überhaupt ein HQ? if(GetPlayer(i)->hqPos.x != 0xFFFF) { if(GetPlayer(i)->ps == PS_OCCUPIED || GetPlayer(i)->ps == PS_KI) { nobHQ* hq = new nobHQ(GetPlayer(i)->hqPos, i, GetPlayer(i)->nation); SetNO(hq, GetPlayer(i)->hqPos); GetPlayer(i)->AddWarehouse(reinterpret_cast<nobBaseWarehouse*>(hq)); } /*else GetNode(GetPlayer(i)->hqx,GetPlayer(i)->hqy).obj = 0;*/ } } // Tiere auslesen for(pt.y = 0; pt.y < height; ++pt.y) { for(pt.x = 0; pt.x < width; ++pt.x) { unsigned pos = GetIdx(pt); // Tiere setzen Species species; switch(map->GetMapDataAt(MAP_ANIMALS, pt.x, pt.y)) { // TODO: Welche ID ist Polarbär? case 1: species = Species(SPEC_RABBITWHITE+RANDOM.Rand(__FILE__, __LINE__, 0, 2)); break; // zufällige Hasenart nehmen case 2: species = SPEC_FOX; break; case 3: species = SPEC_STAG; break; case 4: species = SPEC_DEER; break; case 5: species = SPEC_DUCK; break; case 6: species = SPEC_SHEEP; break; default: species = SPEC_NOTHING; break; } if(species != SPEC_NOTHING) { noAnimal* animal = new noAnimal(species, pt); AddFigure(animal, pt); // Loslaufen animal->StartLiving(); } /// 4 Fische setzen if(map->GetMapDataAt(MAP_RESOURCES, pos) > 0x80 && map->GetMapDataAt(MAP_RESOURCES, pos) < 0x90) GetNode(pt).resources = 0x84; } } /// Weltmeere vermessen for(pt.y = 0; pt.y < height; ++pt.y) { for(pt.x = 0; pt.x < width; ++pt.x) { // Noch kein Meer an diesem Punkt? if(!GetNode(pt).sea_id) { // Aber trotzdem Teil eines noch nicht vermessenen Meeres? if(IsSeaPoint(pt)) { unsigned sea_size = MeasureSea(pt, seas.size()); seas.push_back(Sea(sea_size)); } } } } /// Die Meere herausfinden, an die die Hafenpunkte grenzen for(unsigned i = 0; i < harbor_pos.size(); ++i) { for(unsigned z = 0; z < 6; ++z) harbor_pos[i].cps[z].sea_id = IsCoastalPoint(GetNeighbour(harbor_pos[i].pos, z)); } // Nachbarn der einzelnen Hafenplätze ermitteln CalcHarborPosNeighbors(); /// Schatten und BQ berechnen for(pt.y = 0; pt.y < height; ++pt.y) { for(pt.x = 0; pt.x < width; ++pt.x) { RecalcShadow(pt); SetBQ(pt, GAMECLIENT.GetPlayerID()); } } /// Bei FoW und aufgedeckt müssen auch die ersten FoW-Objekte erstellt werden if(GAMECLIENT.GetGGS().exploration == GlobalGameSettings::EXP_FOGOFWARE_EXPLORED) { for(pt.y = 0; pt.y < height; ++pt.y) { for(pt.x = 0; pt.x < width; ++pt.x) { // Alle Spieler durchgehen for(unsigned i = 0; i < GAMECLIENT.GetPlayerCount(); ++i) { // An der Stelle FOW für diesen Spieler? if(GetNode(pt).fow[i].visibility == VIS_FOW) SaveFOWNode(pt, i); } } } } }
void TerrainRenderer::UpdateBorderTriangleColor(const MapPoint pt, const GameWorldViewer* gwv, const bool update) { unsigned int pos = GetTRIdx(pt); // Für VBO-Aktualisierung: // Erzeugte Ränder zählen unsigned count_borders = 0; // Erstes Offset merken unsigned first_offset = 0; // Rand links - rechts for(unsigned char i = 0; i < 2; ++i) { if(borders[pos].left_right[i]) { unsigned int offset = borders[pos].left_right_offset[i]; if(!first_offset) first_offset = offset; gl_colors[offset].colors[i ? 0 : 2].r = gl_colors[offset].colors[i ? 0 : 2].g = gl_colors[offset].colors[i ? 0 : 2].b = GetColor(pt); gl_colors[offset].colors[1 ].r = gl_colors[offset].colors[1 ].g = gl_colors[offset].colors[1 ].b = GetColor(gwv->GetNeighbour(pt, 4)); gl_colors[offset].colors[i ? 2 : 0].r = gl_colors[offset].colors[i ? 2 : 0].g = gl_colors[offset].colors[i ? 2 : 0].b = GetBColor(pt, i); ++count_borders; } } // Rand rechts - links for(unsigned char i = 0; i < 2; ++i) { if(borders[pos].right_left[i]) { unsigned int offset = borders[pos].right_left_offset[i]; if(!first_offset) first_offset = offset; gl_colors[offset].colors[i ? 2 : 0].r = gl_colors[offset].colors[i ? 2 : 0].g = gl_colors[offset].colors[i ? 2 : 0].b = GetColor(gwv->GetNeighbour(pt, 4)); gl_colors[offset].colors[1 ].r = gl_colors[offset].colors[1 ].g = gl_colors[offset].colors[1 ].b = GetColor(gwv->GetNeighbour(pt, 3)); gl_colors[offset].colors[i ? 0 : 2].r = gl_colors[offset].colors[i ? 0 : 2].g = gl_colors[offset].colors[i ? 0 : 2].b = GetBColor(MapPoint(pt.x + i, pt.y), i ? 0 : 1); ++count_borders; } } // Rand oben - unten for(unsigned char i = 0; i < 2; ++i) { if(borders[pos].top_down[i]) { unsigned int offset = borders[pos].top_down_offset[i]; if(!first_offset) first_offset = offset; gl_colors[offset].colors[i ? 2 : 0].r = gl_colors[offset].colors[i ? 2 : 0].g = gl_colors[offset].colors[i ? 2 : 0].b = GetColor(gwv->GetNeighbour(pt, 5)); gl_colors[offset].colors[1 ].r = gl_colors[offset].colors[1 ].g = gl_colors[offset].colors[1 ].b = GetColor(gwv->GetNeighbour(pt, 4)); if(i == 0) gl_colors[offset].colors[2].r = gl_colors[offset].colors[2].g = gl_colors[offset].colors[2].b = GetBColor(pt, i); else gl_colors[offset].colors[0].r = gl_colors[offset].colors[0].g = gl_colors[offset].colors[0].b = GetBColor(gwv->GetNeighbour(pt, 5), i); ++count_borders; } } /// Bei Vertexbuffern das die Daten aktualisieren if(update && SETTINGS.video.vbo) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_colors); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, first_offset * 3 * 3 * sizeof(float), count_borders * 3 * 3 * sizeof(float), &gl_colors[first_offset]); } }
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 = sgd->PopUnsignedChar(); nodes[i].t2 = 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) { nodes[i].fow[z].visibility = Visibility(sgd->PopUnsignedChar()); // Nur im FoW können FOW-Objekte stehen if(nodes[i].fow[z].visibility == VIS_FOW) { nodes[i].fow[z].last_update_time = sgd->PopUnsignedInt(); nodes[i].fow[z].object = sgd->PopFOWObject(); for(unsigned r = 0; r < 3; ++r) nodes[i].fow[z].roads[r] = sgd->PopUnsignedChar(); nodes[i].fow[z].owner = sgd->PopUnsignedChar(); for(unsigned b = 0; b < 4; ++b) nodes[i].fow[z].boundary_stones[b] = sgd->PopUnsignedChar(); } else { nodes[i].fow[z].last_update_time = 0; nodes[i].fow[z].object = NULL; for(unsigned r = 0; r < 3; ++r) nodes[i].fow[z].roads[r] = 0; nodes[i].fow[z].owner = 0; for(unsigned b = 0; b < 4; ++b) nodes[i].fow[z].boundary_stones[b] = 0; } } nodes[i].obj = sgd->PopObject<noBase>(GOT_UNKNOWN); sgd->PopObjectList<noBase>(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->PopObjectList(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->PopObjectList<noBuildingSite>(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); }
void nobMilitary::Capture(const unsigned char new_owner) { RTTR_Assert(IsCaptured()); captured_not_built = true; mAutoTrain = false; mAutoTrainVirtual = false; // Goldmünzen in der Inventur vom alten Spieler abziehen und dem neuen hinzufügen gwg->GetPlayer(player).DecreaseInventoryWare(GD_COINS, coins); gwg->GetPlayer(new_owner).IncreaseInventoryWare(GD_COINS, coins); // Soldaten, die auf Mission sind, Bescheid sagen for(std::list<nofActiveSoldier*>::iterator it = troops_on_mission.begin(); it != troops_on_mission.end(); ++it) (*it)->HomeDestroyed(); // Bestellungen die hierher unterwegs sind canceln CancelOrders(); // Aggressiv-Verteidigenden Soldaten Bescheid sagen, dass sie nach Hause gehen können for(std::list<nofAggressiveDefender*>::iterator it = aggressive_defenders.begin(); it != aggressive_defenders.end(); ++it) (*it)->AttackedGoalDestroyed(); troops_on_mission.clear(); aggressive_defenders.clear(); // In der Wirtschaftsverwaltung dieses Gebäude jetzt zum neuen Spieler zählen und beim alten raushauen gwg->GetPlayer(player).RemoveMilitaryBuilding(this); gwg->GetPlayer(new_owner).AddMilitaryBuilding(this); // Alten Besitzer merken unsigned char old_player = player; // neuer Spieler player = new_owner; // Flagge davor auch übernehmen GetFlag()->Capture(new_owner); // Territorium neu berechnen gwg->RecalcTerritory(*this, false, false); // Sichtbarkeiten berechnen für alten Spieler gwg->RecalcVisibilitiesAroundPoint(pos, GetMilitaryRadius() + VISUALRANGE_MILITARY + 1, old_player, NULL); // Grenzflagge entsprechend neu setzen von den Feinden LookForEnemyBuildings(); // und von den Verbündeten (da ja ein Feindgebäude weg ist)! sortedMilitaryBlds buildings = gwg->LookForMilitaryBuildings(pos, 4); for(sortedMilitaryBlds::iterator it = buildings.begin(); it != buildings.end(); ++it) { // verbündetes Gebäude? if(gwg->GetPlayer((*it)->GetPlayer()).IsPlayerAttackable(old_player) && (*it)->GetBuildingType() >= BLD_BARRACKS && (*it)->GetBuildingType() <= BLD_FORTRESS) // Grenzflaggen von dem neu berechnen static_cast<nobMilitary*>(*it)->LookForEnemyBuildings(); } // ehemalige Leute dieses Gebäudes nach Hause schicken, die ggf. grad auf dem Weg rein/raus waren MapPoint coords[2] = {pos, MapPoint(gwg->GetNeighbour(pos, 4))}; for(unsigned short i = 0; i < 2; ++i) { const std::list<noBase*>& figures = gwg->GetFigures(coords[i]); for(std::list<noBase*>::const_iterator it = figures.begin(); it != figures.end(); ++it) { if((*it)->GetType() == NOP_FIGURE) { if(static_cast<noFigure*>(*it)->GetCurrentRoad() == routes[4] && static_cast<noFigure*>(*it)->GetPlayer() != new_owner) { static_cast<noFigure*>(*it)->Abrogate(); static_cast<noFigure*>(*it)->StartWandering(); } } } } // Send all allied aggressors home (we own the building now!) for(std::list<nofAttacker*>::iterator it = aggressors.begin(); it != aggressors.end();) { nofAttacker* attacker = *it; // dont remove attackers owned by players not allied with the new owner! unsigned char attPlayer = attacker->GetPlayer(); if(attPlayer != player && !gwg->GetPlayer(attPlayer).IsPlayerAttackable(player)) { it = aggressors.erase(it); attacker->CapturedBuildingFull(); }else ++it; } // Fanfarensound abspieln, falls das Militärgebäude im Sichtbereich ist und unseres ist gwg->MilitaryBuildingCaptured(pos, player); // Post verschicken, an den alten Besitzer und an den neuen Besitzer SendPostMessage(old_player, new PostMsgWithBuilding(GetEvMgr().GetCurrentGF(), _("Military building lost"), PMC_MILITARY, *this)); SendPostMessage(player, new PostMsgWithBuilding(GetEvMgr().GetCurrentGF(), _("Military building captured"), PMC_MILITARY, *this)); // ggf. Fenster schließen vom alten Spieler gwg->ImportantObjectDestroyed(pos); gwg->GetNotifications().publish(BuildingNote(BuildingNote::Captured, player, pos, type_)); gwg->GetNotifications().publish(BuildingNote(BuildingNote::Lost, old_player, pos, type_)); }
void GameWorldView::Draw(const RoadBuildState& rb, const bool draw_selected, const MapPoint selected, unsigned* water) { SetNextZoomFactor(); int shortestDistToMouse = 100000; Point<int> mousePos(VIDEODRIVER.GetMouseX(), VIDEODRIVER.GetMouseY()); mousePos -= Point<int>(pos); glScissor(pos.x, VIDEODRIVER.GetScreenHeight() - pos.y - height, width, height); if(zoomFactor_ != 1.f) { glMatrixMode(GL_PROJECTION); glPushMatrix(); glScalef(zoomFactor_, zoomFactor_, 1); // Offset to center view Point<float> diff(width - width / zoomFactor_, height - height / zoomFactor_); diff = diff / 2.f; glTranslatef(-diff.x, -diff.y, 0.f); // Also adjust mouse mousePos = Point<int>(Point<float>(mousePos) / zoomFactor_ + diff); glMatrixMode(GL_MODELVIEW); } glTranslatef(static_cast<GLfloat>(pos.x) / zoomFactor_, static_cast<GLfloat>(pos.y) / zoomFactor_, 0.0f); glTranslatef(static_cast<GLfloat>(-offset.x), static_cast<GLfloat>(-offset.y), 0.0f); const TerrainRenderer& terrainRenderer = gwv.GetTerrainRenderer(); terrainRenderer.Draw(GetFirstPt(), GetLastPt(), gwv, water); glTranslatef(static_cast<GLfloat>(offset.x), static_cast<GLfloat>(offset.y), 0.0f); for(int y = firstPt.y; y <= lastPt.y; ++y) { // Figuren speichern, die in dieser Zeile gemalt werden müssen // und sich zwischen zwei Zeilen befinden, da sie dazwischen laufen std::vector<ObjectBetweenLines> between_lines; for(int x = firstPt.x; x <= lastPt.x; ++x) { Point<int> curOffset; const MapPoint curPt = terrainRenderer.ConvertCoords(Point<int>(x, y), &curOffset); DrawPoint curPos = GetWorld().GetNodePos(curPt) - offset + curOffset; const Point<int> mouseDist = mousePos - curPos; if(std::abs(mouseDist.x) + std::abs(mouseDist.y) < shortestDistToMouse) { selPt = curPt; selPtOffset = curOffset; shortestDistToMouse = std::abs(mouseDist.x) + std::abs(mouseDist.y); } Visibility visibility = gwv.GetVisibility(curPt); DrawBoundaryStone(curPt, curPos, visibility); if(visibility == VIS_VISIBLE) { DrawObject(curPt, curPos); DrawFigures(curPt, curPos, between_lines); //Construction aid mode if(show_bq) DrawConstructionAid(curPt, curPos); } else if(visibility == VIS_FOW) { const FOWObject* fowobj = gwv.GetYoungestFOWObject(MapPoint(curPt)); if(fowobj) fowobj->Draw(curPos); } if(debugNodePrinter) debugNodePrinter->print(curPt, curPos); if (d_active) DrawAIDebug(curPt, curPos); } // Figuren zwischen den Zeilen zeichnen for(unsigned i = 0; i < between_lines.size(); ++i) between_lines[i].obj->Draw(between_lines[i].pos); } if(show_names || show_productivity) DrawNameProductivityOverlay(terrainRenderer); DrawGUI(rb, terrainRenderer, draw_selected, selected); // Umherfliegende Katapultsteine zeichnen for(std::list<CatapultStone*>::const_iterator it = GetWorld().catapult_stones.begin(); it != GetWorld().catapult_stones.end(); ++it) { if(gwv.GetVisibility((*it)->dest_building) == VIS_VISIBLE || gwv.GetVisibility((*it)->dest_map) == VIS_VISIBLE) (*it)->Draw(offset); } if(zoomFactor_ != 1.f) { glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); } glTranslatef(-static_cast<GLfloat>(pos.x) / zoomFactor_, -static_cast<GLfloat>(pos.y) / zoomFactor_, 0.0f); glScissor(0, 0, VIDEODRIVER.GetScreenWidth(), VIDEODRIVER.GetScreenWidth()); }
// Weglängen schätzen für beide Punkte, indem man den bisherigen Weg mit der Luftlinie vom aktullen // Punkt zum Ziel addiert und auf diese Weise den kleinsten Weg auswählt unsigned way1 = pf_nodes[id].way + distance; unsigned way2 = pf_nodes[two.id].way + two.distance; // Wenn die Wegkosten gleich sind, vergleichen wir die Koordinaten, da wir für std::set eine streng // monoton steigende Folge brauchen if(way1 == way2) return (id < two.id); else return (way1 < way2); } /// Definitionen siehe oben MapPoint PathfindingPoint::dst = MapPoint(); const GameWorldBase* PathfindingPoint::gwb = NULL; /// Wegfinden ( A* ), O(v lg v) --> Wegfindung auf allgemeinen Terrain (ohne Straßen), für Wegbau und frei herumlaufende Berufe bool GameWorldBase::FindFreePath(const MapPoint start, const MapPoint dest, const bool random_route, const unsigned max_route, std::vector<unsigned char>* route, unsigned* length, unsigned char* first_dir, FP_Node_OK_Callback IsNodeOK, FP_Node_OK_Callback IsNodeToDestOk, const void* param, const bool record) const { // increase currentVisit, so we don't have to clear the visited-states at every run currentVisit++; // if the counter reaches its maxium, tidy up if (currentVisit == std::numeric_limits<unsigned>::max() - 1) { for (unsigned i = 0; i < (maxMapSize * maxMapSize); ++i)
void PropColumnMenu::onTouchEnded(Touch *pTouch, Event *pEvent) { Point point = pTouch->getLocation(); Rect rect = Rect::ZERO; rect.origin = m_propColumn->convertToWorldSpace(Point::ZERO); rect.size = m_propColumn->getContentSize(); if (rect.containsPoint(point)) { point = m_propColumn->convertToNodeSpace(point); int x = (int)point.x / GRID_WIDTH; int y = (int)point.y / GRID_HEIGHT; y = ROW - y - 1; m_propVec[m_editProp->getTag()]->setVisible(true); this->swapProp(m_editProp->getTag(), y*COL+x); } else { if (m_editProp->getOpacity() == 255) { GAME_UILAYER->getOperationMenu()->addDrugs(2001); ControlButton* btn = GAME_UILAYER->getOperationMenu()->getDrugsBtn(); btn->stopAllActions(); ScaleTo* scaleTo = ScaleTo::create(0.1f, 1.0f); btn->runAction(scaleTo); m_propVec[m_editProp->getTag()]->removeFromParent(); m_propVec[m_editProp->getTag()] = NULL; } else { float r = CCRANDOM_0_1(); if (r ==1) r = 0; BgMap* bgMap = GAME_SCENE->getCurrBgMap(); MapPoint playerPosition = MapPoint(Player::sharePlayer()->getPosition()); MapPoint point = MapPointZero; std::vector<MapPoint> mapVec; M_INT lenght = 1; do { mapVec = playerPosition.getMapPointVectorForDistance(lenght); unsigned int index = 0; for (; index<mapVec.size(); index++) { if (GAME_SCENE->getMapPointForProp(MapPoint(mapVec.at(index))) == NULL) { point = MapPoint(mapVec.at(index)); } } CC_BREAK_IF(!point.equals(MapPointZero)); lenght++; } while (1); PropIconShow* show = m_propVec[m_editProp->getTag()]; m_propVec[m_editProp->getTag()] = NULL; show->setVisible(true); show->retain(); show->removeFromParent(); show->setPosition(point.getCCPointValue()); bgMap->addChild(show, BgMap::getZOrderZero(bgMap)); show->release(); show->setScale(0.8f); GAME_SCENE->insterMapPointForProp(show, point); show->setOpacity(0); FadeIn* fadeIn = FadeIn::create(0.1f); JumpBy* jumpBy = JumpBy::create(0.3f, Point::ZERO, 30, 1); Spawn* spawn = Spawn::create(fadeIn, jumpBy, NULL); show->runAction(spawn); } } m_editProp->removeFromParent(); m_editProp = NULL; }