Beispiel #1
0
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);
}
Beispiel #2
0
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;
}
Beispiel #3
0
void nobMilitary::TakeWare(Ware* ware)
{
    // Goldmünze in Bestellliste aufnehmen
    RTTR_Assert(!helpers::contains(ordered_coins, ware));
    ordered_coins.push_back(ware);
}
Beispiel #4
0
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_));
}
Beispiel #5
0
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);
}
Beispiel #9
0
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);
            }
        }
    }
}
Beispiel #10
0
void WindowManager::ShowAfterSwitch(IngameWindow* window)
{
    RTTR_Assert(window);
    nextWnds.push_back(window);
}