Пример #1
0
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_));
}
Пример #2
0
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]);
    }
}
Пример #3
0
/// 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));
    }

}
Пример #4
0
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;
    }
}
Пример #5
0
/// 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);
        }
    }

}
Пример #6
0
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;
    }
}
Пример #7
0
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();
}
Пример #8
0
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);
}
Пример #9
0
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);
}
Пример #10
0
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());
    }
}
Пример #11
0
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;
}
Пример #12
0
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);
    }
}
Пример #13
0
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);
        }
    }
}
Пример #14
0
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;
	}
}
Пример #15
0
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);
    }
}
Пример #16
0
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)]);
}
Пример #17
0
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);
    }
}
Пример #18
0
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;
}
Пример #19
0
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;
    }
}
Пример #20
0
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;
    }
}
Пример #21
0
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);
    }
}
Пример #22
0
/// 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)
}
Пример #23
0
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();
    }
}
Пример #25
0
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;
}
Пример #26
0
/// 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);
}
Пример #27
0
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;
    }
}
Пример #28
0
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);
}
Пример #29
0
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);
    }
}
Пример #30
0
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();
}