void nobMilitary::WareLost(Ware* ware) { // Ein Goldstück konnte nicht kommen --> aus der Bestellliste entfernen RTTR_Assert(helpers::contains(ordered_coins, ware)); ordered_coins.remove(ware); }
void nobMilitary::RegulateTroops() { RTTR_Assert(helpers::contains(gwg->GetPlayer(player).GetMilitaryBuildings(), this)); // If this fails, the building is beeing destroyed! // Wenn das Gebäude eingenommen wird, erstmal keine neuen Truppen und warten, wieviele noch reinkommen if(IsCaptured()) return; // Already regulate its troops => Don't call this method again if(is_regulating_troops) return; is_regulating_troops = true; if( mAutoTrain ) { RegulateTrainTroops(); is_regulating_troops = false; return; } // Zu viele oder zu wenig Truppen? int diff = CalcTroopsCount() - static_cast<int>(GetTotalSoldiers()); if(diff < 0) //poc: this should only be >0 if we are being captured. capturing should be true until its the last soldier and this last one would count twice here and result in a returning soldier that shouldnt return. { // Zu viel --> überflüssige Truppen nach Hause schicken // Zuerst die bestellten Soldaten wegschicken // Weak ones first std::vector<nofPassiveSoldier*> notNeededSoldiers; GameClientPlayer& owner = gwg->GetPlayer(player); if (owner.militarySettings_[1] > MILITARY_SETTINGS_SCALE[1] / 2) { for(SortedTroops::iterator it = ordered_troops.begin(); diff && !ordered_troops.empty(); ++diff) { notNeededSoldiers.push_back(*it); it = helpers::erase(ordered_troops, it); } } // Strong ones first else { for(SortedTroops::reverse_iterator it = ordered_troops.rbegin(); diff && !ordered_troops.empty(); ++diff) { notNeededSoldiers.push_back(*it); it = helpers::erase(ordered_troops, it); } } // send the not-needed-soldiers away for (std::vector<nofPassiveSoldier*>::iterator it = notNeededSoldiers.begin(); it != notNeededSoldiers.end(); ++it) { (*it)->NotNeeded(); } // Nur rausschicken, wenn es einen Weg zu einem Lagerhaus gibt! if(owner.FindWarehouse(*this, FW::NoCondition(), true, false)) { // Dann den Rest (einer muss immer noch drinbleiben!) // erst die schwachen Soldaten raus if (owner.militarySettings_[1] > MILITARY_SETTINGS_SCALE[1] / 2) { for(SortedTroops::iterator it = troops.begin(); diff && troops.size() > 1; ++diff) { (*it)->LeaveBuilding(); AddLeavingFigure(*it); it = helpers::erase(troops, it); } } // erst die starken Soldaten raus else { for(SortedTroops::reverse_iterator it = troops.rbegin(); diff && troops.size() > 1; ++diff) { (*it)->LeaveBuilding(); AddLeavingFigure(*it); it = helpers::erase(troops, it); } } } } else if(diff > 0) { // Zu wenig Truppen // Gebäude wird angegriffen und // Addon aktiv, nur soviele Leute zum Nachbesetzen schicken wie Verteidiger eingestellt if (IsUnderAttack() && gwg->GetGGS().getSelection(AddonId::DEFENDER_BEHAVIOR) == 2) { diff = (gwg->GetPlayer(player).militarySettings_[2] * diff) / MILITARY_SETTINGS_SCALE[2]; } //only order new troops if there is a chance that there is a path - pathfinding from each warehouse with soldiers to this mil building will start at the warehouse and cost time bool mightHaveRoad=false; for(unsigned i=2; i<7; i++) //every direction but 1 because 1 is the building connection so it doesnt count for this check { if(GetFlag()->routes[i%6]) { mightHaveRoad=true; break; } } if(mightHaveRoad) gwg->GetPlayer(player).OrderTroops(this, diff); } is_regulating_troops = false; }
void nobMilitary::TakeWare(Ware* ware) { // Goldmünze in Bestellliste aufnehmen RTTR_Assert(!helpers::contains(ordered_coins, ware)); ordered_coins.push_back(ware); }
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 nobMilitary::NeedOccupyingTroops() { RTTR_Assert(IsCaptured()); // Only valid during capturing // Check if we need more soldiers from the attacking soldiers // Choose the closest ones first to avoid having them walk a long way nofAttacker* best_attacker = NULL; unsigned best_radius = std::numeric_limits<unsigned>::max(); unsigned needed_soldiers = unsigned(CalcTroopsCount()); unsigned currentSoldiers = troops.size() + capturing_soldiers + troops_on_mission.size(); if(needed_soldiers > currentSoldiers) { // Soldaten absuchen for(std::list<nofAttacker*>::iterator it = aggressors.begin(); it != aggressors.end(); ++it) { // Is the soldier standing around and owned by the player? if(!(*it)->IsAttackerReady() || (*it)->GetPlayer() != player) continue; // Näher als der bisher beste? if((*it)->GetRadius() >= best_radius) continue; // Und kommt er überhaupt zur Flagge (könnte ja in der 2. Reihe stehen, sodass die vor ihm ihn den Weg versperren)? if(gwg->FindHumanPath((*it)->GetPos(), gwg->GetNeighbour(pos, 4), 10, false) != 0xFF) { // Dann is das der bisher beste best_attacker = *it; best_radius = best_attacker->GetRadius(); } } // Einen gefunden? if(best_attacker) { // Dann soll der hingehen best_attacker->CaptureBuilding(); ++capturing_soldiers; // und raus hier return; } // If necessary look for further soldiers who are not standing around the building for(std::list<nofAttacker*>::iterator it = aggressors.begin(); it != aggressors.end() && needed_soldiers > currentSoldiers + far_away_capturers.size(); ) { nofAttacker* attacker = *it; if(attacker->GetPlayer() == player) { // Ask attacker if this is possible if(attacker->TryToStartFarAwayCapturing(this)) { it = aggressors.erase(it); far_away_capturers.push_back(attacker); continue; } } ++it; } } // At this point agressors contains only soldiers, that cannot capture the building (from other player or without a path to flag), // the one(s) that is currently walking to capture the building and possibly some more from other (non-allied) players // So send those home, who cannot capture the building for(std::list<nofAttacker*>::iterator it = aggressors.begin(); it != aggressors.end();) { nofAttacker* attacker = *it; // Nicht gerade Soldaten löschen, die das Gebäude noch einnehmen! //also: dont remove attackers owned by players not allied with the new owner! if(attacker->GetState() != nofActiveSoldier::STATE_ATTACKING_CAPTURINGNEXT && !gwg->GetPlayer(attacker->GetPlayer()).IsPlayerAttackable(player)) { it = aggressors.erase(it); attacker->CapturedBuildingFull(); }else ++it; } }
nofBuildingWorker::nofBuildingWorker(const Job job, const MapPoint pos, const unsigned char player, nobUsual* workplace) : noFigure(job, pos, player, workplace), state(STATE_FIGUREWORK), workplace(workplace), ware(GD_NOTHING), was_sounding(false) { RTTR_Assert(dynamic_cast<nobUsual*>( static_cast<GameObject*>(workplace))); // Assume we have at least a GameObject and check if it is a valid workplace }
GameObject* SerializedGameData::Create_GameObject(const GO_Type got, const unsigned obj_id) { switch(got) { case GOT_NOB_HQ: return new nobHQ(*this, obj_id); case GOT_NOB_MILITARY: return new nobMilitary(*this, obj_id); case GOT_NOB_STOREHOUSE: return new nobStorehouse(*this, obj_id); case GOT_NOB_USUAL: return new nobUsual(*this, obj_id); case GOT_NOB_SHIPYARD: return new nobShipYard(*this, obj_id); case GOT_NOB_HARBORBUILDING: return new nobHarborBuilding(*this, obj_id); case GOT_NOF_AGGRESSIVEDEFENDER: return new nofAggressiveDefender(*this, obj_id); case GOT_NOF_ATTACKER: return new nofAttacker(*this, obj_id); case GOT_NOF_DEFENDER: return new nofDefender(*this, obj_id); case GOT_NOF_PASSIVESOLDIER: return new nofPassiveSoldier(*this, obj_id); case GOT_NOF_PASSIVEWORKER: return new nofPassiveWorker(*this, obj_id); case GOT_NOF_WELLGUY: return new nofWellguy(*this, obj_id); case GOT_NOF_CARRIER: return new nofCarrier(*this, obj_id); case GOT_NOF_WOODCUTTER: return new nofWoodcutter(*this, obj_id); case GOT_NOF_FISHER: return new nofFisher(*this, obj_id); case GOT_NOF_FORESTER: return new nofForester(*this, obj_id); case GOT_NOF_CARPENTER: return new nofCarpenter(*this, obj_id); case GOT_NOF_STONEMASON: return new nofStonemason(*this, obj_id); case GOT_NOF_HUNTER: return new nofHunter(*this, obj_id); case GOT_NOF_FARMER: return new nofFarmer(*this, obj_id); case GOT_NOF_MILLER: return new nofMiller(*this, obj_id); case GOT_NOF_BAKER: return new nofBaker(*this, obj_id); case GOT_NOF_BUTCHER: return new nofButcher(*this, obj_id); case GOT_NOF_MINER: return new nofMiner(*this, obj_id); case GOT_NOF_BREWER: return new nofBrewer(*this, obj_id); case GOT_NOF_PIGBREEDER: return new nofPigbreeder(*this, obj_id); case GOT_NOF_DONKEYBREEDER: return new nofDonkeybreeder(*this, obj_id); case GOT_NOF_IRONFOUNDER: return new nofIronfounder(*this, obj_id); case GOT_NOF_MINTER: return new nofMinter(*this, obj_id); case GOT_NOF_METALWORKER: return new nofMetalworker(*this, obj_id); case GOT_NOF_ARMORER: return new nofArmorer(*this, obj_id); case GOT_NOF_BUILDER: return new nofBuilder(*this, obj_id); case GOT_NOF_PLANER: return new nofPlaner(*this, obj_id); case GOT_NOF_GEOLOGIST: return new nofGeologist(*this, obj_id); case GOT_NOF_SHIPWRIGHT: return new nofShipWright(*this, obj_id); case GOT_NOF_SCOUT_FREE: return new nofScout_Free(*this, obj_id); case GOT_NOF_SCOUT_LOOKOUTTOWER: return new nofScout_LookoutTower(*this, obj_id); case GOT_NOF_WAREHOUSEWORKER: return new nofWarehouseWorker(*this, obj_id); case GOT_NOF_CATAPULTMAN: return new nofCatapultMan(*this, obj_id); case GOT_NOF_CHARBURNER: return new nofCharburner(*this, obj_id); case GOT_NOF_TRADEDONKEY: return new nofTradeDonkey(*this, obj_id); case GOT_NOF_TRADELEADER: return new nofTradeLeader(*this, obj_id); case GOT_EXTENSION: return new noExtension(*this, obj_id); case GOT_BUILDINGSITE: return new noBuildingSite(*this, obj_id); case GOT_ENVOBJECT: return new noEnvObject(*this, obj_id); case GOT_FIRE: return new noFire(*this, obj_id); case GOT_BURNEDWAREHOUSE: return new BurnedWarehouse(*this, obj_id); case GOT_FLAG: return new noFlag(*this, obj_id); case GOT_GRAINFIELD: return new noGrainfield(*this, obj_id); case GOT_GRANITE: return new noGranite(*this, obj_id); case GOT_SIGN: return new noSign(*this, obj_id); case GOT_SKELETON: return new noSkeleton(*this, obj_id); case GOT_STATICOBJECT: return new noStaticObject(*this, obj_id); case GOT_DISAPPEARINGMAPENVOBJECT: return new noDisappearingMapEnvObject(*this, obj_id); case GOT_TREE: return new noTree(*this, obj_id); case GOT_ANIMAL: return new noAnimal(*this, obj_id); case GOT_FIGHTING: return new noFighting(*this, obj_id); case GOT_EVENT: return em->AddEvent(*this, obj_id); case GOT_ROADSEGMENT: return new RoadSegment(*this, obj_id); case GOT_WARE: return new Ware(*this, obj_id); case GOT_CATAPULTSTONE: return new CatapultStone(*this, obj_id); case GOT_SHIP: return new noShip(*this, obj_id); case GOT_SHIPBUILDINGSITE: return new noShipBuildingSite(*this, obj_id); case GOT_CHARBURNERPILE: return new noCharburnerPile(*this, obj_id); case GOT_NOTHING: case GOT_UNKNOWN: RTTR_Assert(false); break; } throw Error("Invalid GameObjectType " + helpers::toString(got) + " for objId=" + helpers::toString(obj_id) + " found!"); }
bool SerializedGameData::IsObjectSerialized(const unsigned obj_id) const { RTTR_Assert(!isReading); RTTR_Assert(obj_id < GameObject::GetObjIDCounter()); return helpers::contains(writtenObjIds, obj_id); }
void GameWorldView::DrawGUI(const RoadBuildState& rb, const TerrainRenderer& terrainRenderer, const bool draw_selected, const MapPoint& selectedPt) { // Falls im Straßenbaumodus: Punkte um den aktuellen Straßenbaupunkt herum ermitteln MapPoint road_points[6]; unsigned maxWaterWayLen = 0; if(rb.mode != RM_DISABLED) { for(unsigned i = 0; i < 6; ++i) road_points[i] = GetWorld().GetNeighbour(rb.point, i); const unsigned index = GetWorld().GetGGS().getSelection(AddonId::MAX_WATERWAY_LENGTH); RTTR_Assert(index < waterwayLengths.size()); maxWaterWayLen = waterwayLengths[index]; } for(int x = firstPt.x; x <= lastPt.x; ++x) { for(int y = firstPt.y; y <= lastPt.y; ++y) { // Coordinates transform Point<int> curOffset; MapPoint curPt = terrainRenderer.ConvertCoords(Point<int>(x, y), &curOffset); Point<int> curPos = GetWorld().GetNodePos(curPt) - offset + curOffset; /// Current point indicated by Mouse if(selPt == curPt) { // Mauszeiger am boden unsigned mid = 22; if(rb.mode == RM_DISABLED){ switch(gwv.GetBQ(curPt)) { case BQ_FLAG: mid = 40; break; case BQ_MINE: mid = 41; break; case BQ_HUT: mid = 42; break; case BQ_HOUSE: mid = 43; break; case BQ_CASTLE: mid = 44; break; case BQ_HARBOR: mid = 45; break; default: break; } } LOADER.GetMapImageN(mid)->Draw(curPos); } // Currently selected point if(draw_selected && selectedPt == curPt) LOADER.GetMapImageN(20)->Draw(curPos); // Wegbauzeug if(rb.mode == RM_DISABLED) continue; if(rb.point == curPt) LOADER.GetMapImageN(21)->Draw(curPos); int altitude = GetWorld().GetNode(rb.point).altitude; for(unsigned i = 0; i < 6; ++i) { if(road_points[i] != curPt) continue; // test on maximal water way length if(rb.mode == RM_BOAT && maxWaterWayLen != 0 && rb.route.size() >= maxWaterWayLen) continue; if((gwv.IsRoadAvailable(rb.mode == RM_BOAT, curPt) && gwv.IsOwner(curPt) && GetWorld().IsPlayerTerritory(curPt)) || (gwv.GetBQ(curPt) == BQ_FLAG)) { unsigned id; switch(int(GetWorld().GetNode(curPt).altitude) - altitude) { case 1: id = 61; break; case 2: case 3: id = 62; break; case 4: case 5: id = 63; break; case -1: id = 64; break; case -2: case -3: id = 65; break; case -4: case -5: id = 66; break; default: id = 60; break; } LOADER.GetMapImageN(id)->Draw(curPos); } // Flaggenanschluss? --> extra zeichnen if(GetWorld().GetNO(curPt)->GetType() == NOP_FLAG && curPt != rb.start) LOADER.GetMapImageN(20)->Draw(curPos); if(!rb.route.empty() && unsigned(rb.route.back() + 3) % 6 == i) LOADER.GetMapImageN(67)->Draw(curPos); } } } }
void WindowManager::ShowAfterSwitch(IngameWindow* window) { RTTR_Assert(window); nextWnds.push_back(window); }