void nobMilitary::Destroy_nobMilitary() { // Remove from military square and buildings first, to avoid e.g. sending canceled soldiers back to this building gwg->GetPlayer(player).RemoveMilitaryBuilding(this); gwg->GetMilitarySquares().Remove(this); // Bestellungen stornieren CancelOrders(); // Soldaten rausschicken for(SortedTroops::iterator it = troops.begin(); it != troops.end(); ++it) (*it)->InBuildingDestroyed(); troops.clear(); // Inform far-away capturers for(std::list<nofAttacker*>::iterator it = far_away_capturers.begin(); it != far_away_capturers.end(); ++it) (*it)->AttackedGoalDestroyed(); far_away_capturers.clear(); // Events ggf. entfernen GetEvMgr().RemoveEvent(goldorder_event); GetEvMgr().RemoveEvent(upgrade_event); // übriggebliebene Goldmünzen in der Inventur abmelden gwg->GetPlayer(player).DecreaseInventoryWare(GD_COINS, coins); Destroy_nobBaseMilitary(); // Land drumherum neu berechnen (nur wenn es schon besetzt wurde!) // Nach dem BaseDestroy erst, da in diesem erst das Feuer gesetzt, die Straße gelöscht wird usw. if(!new_built) gwg->RecalcTerritory(*this, true, false); gwg->GetNotifications().publish(BuildingNote(BuildingNote::Lost, player, pos, type_)); }
void nobUsual::DestroyBuilding() { // Arbeiter Bescheid sagen if(worker) { worker->LostWork(); worker = nullptr; } else gwg->GetPlayer(player).JobNotWanted(this); // Bestellte Waren Bescheid sagen for(std::list<Ware*>& orderedWare : ordered_wares) { for(Ware* ware : orderedWare) WareNotNeeded(ware); orderedWare.clear(); } // Events löschen GetEvMgr().RemoveEvent(orderware_ev); GetEvMgr().RemoveEvent(productivity_ev); // Inventur entsprechend verringern wegen den Waren, die vernichtetet werden for(unsigned i = 0; i < BLD_WORK_DESC[bldType_].waresNeeded.size(); ++i) { GoodType ware = BLD_WORK_DESC[bldType_].waresNeeded[i]; if(ware == GD_NOTHING) break; gwg->GetPlayer(player).DecreaseInventoryWare(ware, numWares[i]); } }
/// Das Schiff wird um eine Stufe weitergebaut void noShipBuildingSite::MakeBuildStep() { ++progress; // Schiff fertiggestellt? if(progress > PROGRESS_PARTS[0] + PROGRESS_PARTS[1] + PROGRESS_PARTS[2]) { // Replace me by ship GetEvMgr().AddToKillList(this); gwg->SetNO(pos, NULL); noShip* ship = new noShip(pos, player); gwg->AddFigure(ship, pos); // Schiff registrieren lassen gwg->GetPlayer(player).RegisterShip(ship); // BQ neu berechnen, da Schiff nicht mehr blockiert gwg->RecalcBQAroundPointBig(pos); // Spieler über Fertigstellung benachrichtigen SendPostMessage(player, new ShipPostMsg(GetEvMgr().GetCurrentGF(), _("A new ship is ready"), PostCategory::Economy, *ship)); gwg->GetNotifications().publish(ShipNote(ShipNote::Constructed, player, pos)); } }
void noShip::Driven() { MapPoint enemy_territory_discovered(MapPoint::Invalid()); gwg->RecalcMovingVisibilities(pos, player, GetVisualRange(), GetCurMoveDir(), &enemy_territory_discovered); // Feindliches Territorium entdeckt? if(enemy_territory_discovered.isValid()) { // Send message if necessary if(gwg->GetPlayer(player).ShipDiscoveredHostileTerritory(enemy_territory_discovered)) SendPostMessage(player, new PostMsg(GetEvMgr().GetCurrentGF(), _("A ship disovered an enemy territory"), PostCategory::Military, enemy_territory_discovered)); } switch(state) { case STATE_GOTOHARBOR: HandleState_GoToHarbor(); break; case STATE_EXPEDITION_DRIVING: HandleState_ExpeditionDriving(); break; case STATE_EXPLORATIONEXPEDITION_DRIVING: HandleState_ExplorationExpeditionDriving(); break; case STATE_TRANSPORT_DRIVING: HandleState_TransportDriving(); break; case STATE_SEAATTACK_DRIVINGTODESTINATION: HandleState_SeaAttackDriving(); break; case STATE_SEAATTACK_RETURN_DRIVING: HandleState_SeaAttackReturn(); break; default: RTTR_Assert(false); break; } }
/// Sagt Bescheid, dass ein Schiffsangreifer nicht mehr mit nach Hause fahren will void noShip::SeaAttackerWishesNoReturn() { RTTR_Assert(remaining_sea_attackers); RTTR_Assert(state == STATE_SEAATTACK_WAITING); --remaining_sea_attackers; // Alle Soldaten an Bord if(remaining_sea_attackers == 0) { // Andere Events ggf. erstmal abmelden GetEvMgr().RemoveEvent(current_ev); if(!figures.empty()) { // Go back home. Note: home_harbor can be 0 if it was destroyed, allow this and let the state handlers handle that case later goal_harborId = home_harbor; state = STATE_SEAATTACK_RETURN_DRIVING; StartDrivingToHarborPlace(); HandleState_SeaAttackReturn(); } else { // Wenn keine Soldaten mehr da sind können wir auch erstmal idlen StartIdling(); gwg->GetPlayer(player).GetJobForShip(this); } } }
void nofPlaner::Walked() { /// Zur Baustelle zurückgelaufen? (=fertig) if(pos == building_site->GetPos()) { // Baustelle Bescheid sagen building_site->PlaningFinished(); state = STATE_FIGUREWORK; // Nach Hause laufen bzw. auch rumirren rs_pos = 0; rs_dir = true; cur_rs = gwg->GetSpecObj<noRoadNode>(pos)->routes[4]; building_site = 0; GoHome(); StartWalking(4); } else { /// Anfangen zu arbeiten current_ev = GetEvMgr().AddEvent(this, JOB_CONSTS[JOB_PLANER].work_length, 1); state = STATE_PLANING; } }
void nobMilitary::AddActiveSoldier(nofActiveSoldier* soldier) { // aktiver Soldat, eingetroffen werden --> dieser muss erst in einen passiven Soldaten // umoperiert werden (neu erzeugt und alter zerstört) werden nofPassiveSoldier* passive_soldier = new nofPassiveSoldier(*soldier); // neuen Soldaten einhängen AddPassiveSoldier(passive_soldier); // alten Soldaten später vernichten soldier->ResetHome(); GetEvMgr().AddToKillList(soldier); RTTR_Assert(soldier->GetPlayer() == player); // Returned home if(soldier == defender_) NoDefender(); else if(helpers::contains(troops_on_mission, soldier)) { troops_on_mission.remove(soldier); }else if(IsCaptured() || IsFarAwayCapturer(dynamic_cast<nofAttacker*>(soldier))) { RTTR_Assert(dynamic_cast<nofAttacker*>(soldier)); return; } // Do only if not capturing RegulateTroops(); }
void nobMilitary::PrepareUpgrading() { // Goldmünzen da? if(!coins) return; // Gibts auch noch kein Beförderungsevent? if(upgrade_event) return; // Noch Soldaten, die befördert werden können? bool soldiers_available = false; for(SortedTroops::iterator it = troops.begin(); it != troops.end(); ++it) { if((*it)->GetRank() < gwg->GetGGS().GetMaxMilitaryRank()) { // es wurde ein Soldat gefunden, der befördert werden kann soldiers_available = true; break; } } if(!soldiers_available) return; // Alles da --> Beförderungsevent anmelden upgrade_event = GetEvMgr().AddEvent(this, UPGRADE_TIME + RANDOM.Rand(__FILE__, __LINE__, GetObjId(), UPGRADE_TIME_RANDOM), 2); }
CatapultStone::CatapultStone(const MapPoint dest_building, const MapPoint dest_map, const int start_x, const int start_y, const int dest_x, const int dest_y, const unsigned fly_duration) : dest_building(dest_building), dest_map(dest_map), start_x(start_x), start_y(start_y), dest_x(dest_x), dest_y(dest_y), explode(false) { event = GetEvMgr().AddEvent(this, fly_duration); }
void nobUsual::OnOutOfResources() { // Post verschicken, keine Rohstoffe mehr da if(outOfRessourcesMsgSent) return; outOfRessourcesMsgSent = true; productivity = 0; std::fill(last_productivities.begin(), last_productivities.end(), 0); const char* error; if(GetBuildingType() == BLD_WELL) error = _("This well has dried out"); else if(BuildingProperties::IsMine(GetBuildingType())) error = _("This mine is exhausted"); else if(GetBuildingType() == BLD_QUARRY) error = _("No more stones in range"); else if(GetBuildingType() == BLD_FISHERY) error = _("No more fishes in range"); else return; SendPostMessage(player, new PostMsgWithBuilding(GetEvMgr().GetCurrentGF(), error, PostCategory::Economy, *this)); gwg->GetNotifications().publish(BuildingNote(BuildingNote::NoRessources, player, GetPos(), GetBuildingType())); if(GAMECLIENT.GetPlayerId() == player && gwg->GetGGS().isEnabled(AddonId::DEMOLISH_BLD_WO_RES)) { GAMECLIENT.DestroyBuilding(GetPos()); } }
GoodType nofMetalworker::GetOrderedTool() { // qx:tools int prio = -1; int tool = -1; GameClientPlayer& owner = gwg->GetPlayer(player); for (unsigned i = 0; i < TOOL_COUNT; ++i) { if (owner.tools_ordered[i] > 0 && (owner.toolsSettings_[i] > prio) ) { prio = owner.toolsSettings_[i]; tool = i; } } if (tool != -1) { --owner.tools_ordered[tool]; if (ToolsOrderedTotal() == 0) SendPostMessage(player, new PostMsg(GetEvMgr().GetCurrentGF(), _("Completed the ordered amount of tools."), PMC_GENERAL)); gwg->GetNotifications().publish(ToolNote(ToolNote::OrderCompleted, player)); return TOOLS_SETTINGS_IDS[tool]; } return GD_NOTHING; }
void nofShipWright::WalkToWorkpoint() { // Sind wir am Ziel angekommen? if(pos == dest) { // Anfangen zu arbeiten state = STATE_WORK; current_ev = GetEvMgr().AddEvent(this, WORKING_TIME_SHIPS, 1); return; } unsigned char dir = gwg->FindHumanPath(pos, dest, 20); // Weg suchen und gucken ob der Punkt noch in Ordnung ist if(dir == 0xFF || (!IsPointGood(dest) && gwg->GetGOT(dest) != GOT_SHIPBUILDINGSITE)) { // Punkt freigeben gwg->SetReserved(dest, false); // Kein Weg führt mehr zum Ziel oder Punkt ist nich mehr in Ordnung --> wieder nach Hause gehen StartWalkingHome(); } else { // Alles ok, wir können hinlaufen StartWalking(dir); } }
void nobMilitary::SearchCoins() { // Brauche ich überhaupt Goldmünzen bzw. hab ich vielleicht schon ein Event angemeldet? if(WantCoins() && !goldorder_event) { // Lagerhaus mit Goldmünzen suchen nobBaseWarehouse* wh = gwg->GetPlayer(player).FindWarehouse(*this, FW::HasMinWares(GD_COINS), false, false); if(wh) { // Wenns eins gibt, dort eine Goldmünze bestellen Ware* ware = wh->OrderWare(GD_COINS, this); if(!ware) { RTTR_Assert(false); // Ware dürfte nicht 0 werden, da ja ein Lagerhaus MIT GOLDMÜNZEN bereits gesucht wird LOG.lprintf("nobMilitary::SearchCoins: WARNING: ware = NULL. Bug alarm!\n"); return; } RTTR_Assert(helpers::contains(ordered_coins, ware)); // Nach einer Weile nochmal nach evtl neuen Goldmünzen gucken goldorder_event = GetEvMgr().AddEvent(this, 200 + RANDOM.Rand(__FILE__, __LINE__, GetObjId(), 400), 1); } } }
void nofArmorer::HandleDerivedEvent(const unsigned int /*id*/) { switch(state) { case STATE_WAITING1: { if(!gwg->GetGGS().isEnabled(AddonId::HALF_COST_MIL_EQUIP) || !sword_shield) { //LOG.write(("armorer handlewait1 - consume wares %i \n",player); nofWorkman::HandleStateWaiting1(); } else { // Nach 1. Warten wird gearbeitet current_ev = GetEvMgr().AddEvent(this, JOB_CONSTS[job_].work_length, 1); state = STATE_WORK; workplace->is_working = true; //LOG.write(("armorer handlewait1 - no consume wares %i \n",player); } } break; case STATE_WORK: { HandleStateWork(); } break; case STATE_WAITING2: { HandleStateWaiting2(); } break; default: break; } }
void nofAttacker::AttackedGoalDestroyed() { attacked_goal = nullptr; bool was_waiting_for_defender = (state == STATE_ATTACKING_WAITINGFORDEFENDER); // Wenn man gerade rumsteht, muss man sich bewegen if(state == STATE_ATTACKING_WAITINGFORDEFENDER || state == STATE_ATTACKING_WAITINGAROUNDBUILDING || state == STATE_WAITINGFORFIGHT) ReturnHomeMissionAttacking(); else if(state == STATE_SEAATTACKING_WAITINHARBOR) { // We don't need to wait anymore, target was destroyed auto* harbor = gwg->GetSpecObj<nobHarborBuilding>(harborPos); RTTR_Assert(harbor); // go home goal_ = building; state = STATE_FIGUREWORK; fs = FS_GOTOGOAL; harbor->CancelSeaAttacker(this); return; } if(was_waiting_for_defender) { // Block-Event ggf abmelden GetEvMgr().RemoveEvent(blocking_event); gwg->RoadNodeAvailable(pos); } }
noFire::noFire(const MapPoint pos, bool isBig) : noCoordBase(NOP_FIRE, pos), isBig(isBig), was_sounding(false), last_sound(0), next_interval(0) { // Bestimmte Zeit lang brennen const std::array<unsigned, 7> FIREDURATION = {3700, 2775, 1850, 925, 370, 5550, 7400}; dead_event = GetEvMgr().AddEvent(this, FIREDURATION[gwg->GetGGS().getSelection(AddonId::BURN_DURATION)]); }
nofMetalworker::nofMetalworker(SerializedGameData& sgd, const unsigned obj_id) : nofWorkman(sgd, obj_id), nextProducedTool(GoodType(sgd.PopUnsignedChar())) { if(state == STATE_ENTERBUILDING && current_ev == NULL && ware == GD_NOTHING && nextProducedTool == GD_NOTHING) { LOG.lprintf("Found invalid metalworker. Assuming corrupted savegame -> Trying to fix this. If you encounter this with a new game, report this!"); state = STATE_WAITINGFORWARES_OR_PRODUCTIONSTOPPED; current_ev = GetEvMgr().AddEvent(this, 1000, 2); } }
bool nofMetalworker::ReadyForWork() { nextProducedTool = GetOrderedTool(); if(nextProducedTool == GD_NOTHING) nextProducedTool = GetRandomTool(); if(current_ev) { RTTR_Assert(current_ev->id == 2 && state == STATE_WAITINGFORWARES_OR_PRODUCTIONSTOPPED); GetEvMgr().RemoveEvent(current_ev); } if(nextProducedTool != GD_NOTHING) return true; // Try again in some time (3000GF ~= 2min at 40ms/GF) current_ev = GetEvMgr().AddEvent(this, 3000, 2); return false; }
void nobUsual::StopNotWorking() { // Falls wir vorher nicht gearbeitet haben, diese Zeit merken für die Produktivität if(since_not_working != 0xFFFFFFFF) { numGfNotWorking += static_cast<unsigned short>(GetEvMgr().GetCurrentGF() - since_not_working); since_not_working = 0xFFFFFFFF; } }
void noShip::HandleState_ExpeditionDriving() { Result res; // Zum Heimathafen fahren? if(home_harbor == goal_harborId) res = DriveToHarbour(); else res = DriveToHarbourPlace(); switch(res) { case DRIVING: return; case GOAL_REACHED: { // Haben wir unsere Expedition beendet? if(home_harbor == goal_harborId) { // Sachen wieder in den Hafen verladen state = STATE_EXPEDITION_UNLOADING; current_ev = GetEvMgr().AddEvent(this, UNLOADING_TIME, 1); } else { // Warten auf weitere Anweisungen state = STATE_EXPEDITION_WAITING; // Spieler benachrichtigen SendPostMessage(player, new ShipPostMsg(GetEvMgr().GetCurrentGF(), _("A ship has reached the destination of its expedition."), PostCategory::Economy, *this)); gwg->GetNotifications().publish(ExpeditionNote(ExpeditionNote::Waiting, player, pos)); } } break; case NO_ROUTE_FOUND: case HARBOR_DOESNT_EXIST: //should only happen when an expedition is cancelled and the home harbor no longer exists { if(home_harbor != goal_harborId && home_harbor != 0) { // Try to go back goal_harborId = home_harbor; HandleState_ExpeditionDriving(); }else FindUnloadGoal(STATE_EXPEDITION_DRIVING); // Unload anywhere! } break; } }
void nobUsual::HandleEvent(const unsigned id) { if(id) { const unsigned short current_productivity = CalcProductivity(); // Sum over all last productivities and current (as start value) productivity = std::accumulate(last_productivities.begin(), last_productivities.end(), current_productivity); // Produktivität "verrücken" for(unsigned short i = last_productivities.size() - 1; i >= 1; --i) last_productivities[i] = last_productivities[i - 1]; last_productivities[0] = current_productivity; // Durschnitt ausrechnen der letzten Produktivitäten PLUS der aktuellen! productivity /= (last_productivities.size() + 1); // Event für nächste Abrechnung productivity_ev = GetEvMgr().AddEvent(this, 400, 1); } else { // Ware bestellen (falls noch Platz ist) und nicht an Betriebe, die stillgelegt wurden! if(!disable_production) { const BldWorkDescription& workDesc = BLD_WORK_DESC[bldType_]; RTTR_Assert(workDesc.waresNeeded[last_ordered_ware] != GD_NOTHING); // How many wares can we have of each type? unsigned wareSpaces = workDesc.numSpacesPerWare; if(numWares[last_ordered_ware] + ordered_wares[last_ordered_ware].size() < wareSpaces) { Ware* w = gwg->GetPlayer(player).OrderWare(workDesc.waresNeeded[last_ordered_ware], this); if(w) RTTR_Assert(helpers::contains(ordered_wares[last_ordered_ware], w)); } ++last_ordered_ware; if(last_ordered_ware >= workDesc.waresNeeded.size() || workDesc.waresNeeded[last_ordered_ware] == GD_NOTHING) last_ordered_ware = 0; } // Nach ner bestimmten Zeit dann nächste Ware holen orderware_ev = GetEvMgr().AddEvent(this, 210); } }
/// Startet eine Expedition void noShip::StartExpedition(unsigned homeHarborId) { /// Schiff wird "beladen", also kurze Zeit am Hafen stehen, bevor wir bereit sind state = STATE_EXPEDITION_LOADING; current_ev = GetEvMgr().AddEvent(this, LOADING_TIME, 1); RTTR_Assert(homeHarborId); RTTR_Assert(pos == gwg->GetCoastalPoint(homeHarborId, seaId_)); home_harbor = homeHarborId; goal_harborId = homeHarborId; // This is current goal (commands are relative to current goal) }
void nobUsual::WorkerLost() { // Check if worker is or was here (e.g. hunter could currently be outside) if(HasWorker()) { // If we have a worker, we must be producing something RTTR_Assert(productivity_ev); // Open the door till we get a new worker OpenDoor(); } // Produktivitätsevent ggf. abmelden GetEvMgr().RemoveEvent(productivity_ev); // Waren-Bestell-Event abmelden GetEvMgr().RemoveEvent(orderware_ev); // neuen Arbeiter bestellen worker = nullptr; gwg->GetPlayer(player).AddJobWanted(BLD_WORK_DESC[bldType_].job, this); }
void nofBuildingWorker::ProductionStopped() { // Wenn ich gerade warte und schon ein Arbeitsevent angemeldet habe, muss das wieder abgemeldet werden if(state == STATE_WAITING1) { GetEvMgr().RemoveEvent(current_ev); current_ev = nullptr; state = STATE_WAITINGFORWARES_OR_PRODUCTIONSTOPPED; workplace->StartNotWorking(); } }
unsigned short nobUsual::CalcProductivity() { if(outOfRessourcesMsgSent) return 0; // Gucken, ob bis jetzt gearbeitet wurde/wird oder nicht, je nachdem noch was dazuzählen if(since_not_working != 0xFFFFFFFF) { // Es wurde bis jetzt nicht mehr gearbeitet, das also noch dazuzählen numGfNotWorking += static_cast<unsigned short>(GetEvMgr().GetCurrentGF() - since_not_working); // Zähler zurücksetzen since_not_working = GetEvMgr().GetCurrentGF(); } // Produktivität ausrechnen unsigned short curProductivity = (400 - numGfNotWorking) / 4; // Zähler zurücksetzen numGfNotWorking = 0; return curProductivity; }
/// Startet eine Erkundungs-Expedition void noShip::StartExplorationExpedition(unsigned homeHarborId) { /// Schiff wird "beladen", also kurze Zeit am Hafen stehen, bevor wir bereit sind state = STATE_EXPLORATIONEXPEDITION_LOADING; current_ev = GetEvMgr().AddEvent(this, LOADING_TIME, 1); covered_distance = 0; RTTR_Assert(homeHarborId); RTTR_Assert(pos == gwg->GetCoastalPoint(homeHarborId, seaId_)); home_harbor = homeHarborId; goal_harborId = homeHarborId; // This is current goal (commands are relative to current goal) // Sichtbarkeiten neu berechnen gwg->SetVisibilitiesAroundPoint(pos, GetVisualRange(), player); }
void noShip::HandleState_ExplorationExpeditionDriving() { Result res; // Zum Heimathafen fahren? if(home_harbor == goal_harborId && covered_distance >= MAX_EXPLORATION_EXPEDITION_DISTANCE) res = DriveToHarbour(); else res = DriveToHarbourPlace(); switch(res) { case DRIVING: return; case GOAL_REACHED: { // Haben wir unsere Expedition beendet? if(home_harbor == goal_harborId && covered_distance >= MAX_EXPLORATION_EXPEDITION_DISTANCE) { // Dann sind wir fertig -> wieder entladen state = STATE_EXPLORATIONEXPEDITION_UNLOADING; current_ev = GetEvMgr().AddEvent(this, UNLOADING_TIME, 1); } else { // Strecke, die wir gefahren sind, draufaddieren covered_distance += route_.size(); // Erstmal kurz ausruhen an diesem Punkt und das Rohr ausfahren, um ein bisschen // auf der Insel zu gucken state = STATE_EXPLORATIONEXPEDITION_WAITING; current_ev = GetEvMgr().AddEvent(this, EXPLORATION_EXPEDITION_WAITING_TIME, 1); } } break; case NO_ROUTE_FOUND: case HARBOR_DOESNT_EXIST: gwg->RecalcVisibilitiesAroundPoint(pos, GetVisualRange(), player, NULL); StartIdling(); break; } }
void nofWarehouseWorker::Walked() { // Wieder im Schloss angekommen if(!shouldBringWareIn) { // If I still cary a ware than either the flag was full or I should not bring it there (goal=warehouse or goal destroyed -> goal=location) // So re-add it to waiting wares or to inventory if(carried_ware) { // Ware ins Lagerhaus einlagern (falls es noch existiert und nicht abgebrannt wurde) if(gwg->GetNO(pos)->GetType() == NOP_BUILDING) { nobBaseWarehouse* wh = gwg->GetSpecObj<nobBaseWarehouse>(pos); if(carried_ware->GetGoal() == carried_ware->GetLocation() || carried_ware->GetGoal() == wh) wh->AddWare(carried_ware); else wh->AddWaitingWare(carried_ware); } else { // Lagerhaus abgebrannt --> Ware vernichten LooseWare(); } // Ich trage keine Ware mehr RTTR_Assert(carried_ware == NULL); } } else { if(carried_ware) { // Ware ins Lagerhaus einlagern (falls es noch existiert und nicht abgebrannt wurde) if(gwg->GetNO(pos)->GetType() == NOP_BUILDING) gwg->GetSpecObj<nobBaseWarehouse>(pos)->AddWare(carried_ware); else { // Lagerhaus abgebrannt --> Ware vernichten LooseWare(); } // Ich trage keine Ware mehr RTTR_Assert(carried_ware == NULL); } } // dann mich killen gwg->RemoveFigure(this, pos); GetEvMgr().AddToKillList(this); // Von der Inventur wieder abziehen gwg->GetPlayer(player).DecreaseInventoryJob(JOB_HELPER, 1); }
void noShip::AbortSeaAttack() { RTTR_Assert(state != STATE_SEAATTACK_WAITING); // figures are not aboard if this fails! RTTR_Assert(remaining_sea_attackers == 0); // Some soldiers are still not aboard if ((state == STATE_SEAATTACK_LOADING || state == STATE_SEAATTACK_DRIVINGTODESTINATION) && goal_harborId != home_harbor && home_harbor != 0) { // We did not start the attack yet and we can (possibly) go back to our home harbor // -> tell the soldiers we go back (like after an attack) goal_harborId = home_harbor; for (std::list<noFigure*>::iterator it = figures.begin(); it != figures.end(); ++it) { RTTR_Assert(dynamic_cast<nofAttacker*>(*it)); static_cast<nofAttacker*>(*it)->StartReturnViaShip(*this); } if(state == STATE_SEAATTACK_LOADING) { // We are still loading (loading event must be active) // -> Use it to unload RTTR_Assert(current_ev); state = STATE_SEAATTACK_UNLOADING; }else { // Else start driving back state = STATE_SEAATTACK_RETURN_DRIVING; HandleState_SeaAttackReturn(); } }else { // attack failed and we cannot go back to our home harbor // -> Tell figures that they won't go to their planned destination for (std::list<noFigure*>::iterator it = figures.begin(); it != figures.end(); ++it) { RTTR_Assert(dynamic_cast<nofAttacker*>(*it)); static_cast<nofAttacker*>(*it)->CancelSeaAttack(); } if (state == STATE_SEAATTACK_LOADING) { // Abort loading RTTR_Assert(current_ev); GetEvMgr().RemoveEvent(current_ev); } // Das Schiff muss einen Notlandeplatz ansteuern FindUnloadGoal(STATE_SEAATTACK_RETURN_DRIVING); } }
void noFire::Destroy_noFire() { // Just in case GetEvMgr().RemoveEvent(dead_event); // nix mehr hier gwg->SetNO(pos, nullptr); // Bauplätze drumrum neu berechnen gwg->RecalcBQAroundPoint(pos); // Evtl Sounds vernichten SOUNDMANAGER.WorkingFinished(this); Destroy_noCoordBase(); }