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());
    }
}
BuildingIndicator::BuildingIndicator(GG::X w, const std::string& building_type,
                                     double turns_completed, double total_turns) :
    GG::Wnd(GG::X0, GG::Y0, w, GG::Y(Value(w)), GG::INTERACTIVE),
    m_graphic(0),
    m_scrap_indicator(0),
    m_progress_bar(0),
    m_building_id(INVALID_OBJECT_ID),
    m_order_issuing_enabled(true)
{
    boost::shared_ptr<GG::Texture> texture = ClientUI::BuildingIcon(building_type);

    const BuildingType* type = GetBuildingType(building_type);
    const std::string& desc = type ? type->Description() : "";

    SetBrowseInfoWnd(boost::shared_ptr<GG::BrowseInfoWnd>(
        new IconTextBrowseWnd(texture, UserString(building_type), UserString(desc))));

    m_graphic = new GG::StaticGraphic(texture, GG::GRAPHIC_FITGRAPHIC | GG::GRAPHIC_PROPSCALE);
    AttachChild(m_graphic);

    m_progress_bar = new MultiTurnProgressBar(total_turns, turns_completed, GG::LightColor(ClientUI::TechWndProgressBarBackgroundColor()),
                                              ClientUI::TechWndProgressBarColor(), GG::LightColor(ClientUI::ResearchableTechFillColor()));
    AttachChild(m_progress_bar);

    Refresh();
}
Beispiel #3
0
std::string Building::Dump() const {
    std::stringstream os;
    os << UniverseObject::Dump();
    os << " building type: " << m_building_type
       << " produced by empire id: " << m_produced_by_empire_id
       << " \n characteristics " << GetBuildingType(m_building_type)->Dump();
    return os.str();
}
Beispiel #4
0
double Planet::BuildingCosts() const {
    double retval = 0.0;
    const ObjectMap& objects = GetMainObjectMap();
    for (std::set<int>::const_iterator it = m_buildings.begin(); it != m_buildings.end(); ++it) {
        const Building* building = objects.Object<Building>(*it);
//        if (building->Operating()) {
            const BuildingType* bulding_type = GetBuildingType(building->BuildingTypeName());
            retval += bulding_type->MaintenanceCost();
//        }
    }
    return retval;
}
Beispiel #5
0
void Planet::Conquer(int conquerer) {
    m_just_conquered = true;

    // deal with things on production queue located at this planet
    Empire::ConquerProductionQueueItemsAtLocation(ID(), conquerer);

    // deal with UniverseObjects (eg. buildings) located on this planet
    std::vector<TemporaryPtr<Building> > buildings = Objects().FindObjects<Building>(m_buildings);
    for (std::vector<TemporaryPtr<Building> >::iterator it = buildings.begin();
         it != buildings.end(); ++it)
    {
        TemporaryPtr<Building> building = *it;
        const BuildingType* type = GetBuildingType(building->BuildingTypeName());

        // determine what to do with building of this type...
        const CaptureResult cap_result = type->GetCaptureResult(building->Owner(), conquerer, this->ID(), false);

        if (cap_result == CR_CAPTURE) {
            // replace ownership
            building->SetOwner(conquerer);
        } else if (cap_result == CR_DESTROY) {
            // destroy object
            //DebugLogger() << "Planet::Conquer destroying object: " << building->Name();
            this->RemoveBuilding(building->ID());
            if (TemporaryPtr<System> system = GetSystem(this->SystemID()))
                system->Remove(building->ID());
            GetUniverse().Destroy(building->ID());
        } else if (cap_result == CR_RETAIN) {
            // do nothing
        }
    }

    // replace ownership
    SetOwner(conquerer);

    GetMeter(METER_SUPPLY)->SetCurrent(0.0f);
    GetMeter(METER_SUPPLY)->BackPropagate();
    GetMeter(METER_INDUSTRY)->SetCurrent(0.0f);
    GetMeter(METER_INDUSTRY)->BackPropagate();
    GetMeter(METER_RESEARCH)->SetCurrent(0.0f);
    GetMeter(METER_RESEARCH)->BackPropagate();
    GetMeter(METER_TRADE)->SetCurrent(0.0f);
    GetMeter(METER_TRADE)->BackPropagate();
    GetMeter(METER_CONSTRUCTION)->SetCurrent(0.0f);
    GetMeter(METER_CONSTRUCTION)->BackPropagate();
    GetMeter(METER_DEFENSE)->SetCurrent(0.0f);
    GetMeter(METER_DEFENSE)->BackPropagate();
    GetMeter(METER_SHIELD)->SetCurrent(0.0f);
    GetMeter(METER_SHIELD)->BackPropagate();
    GetMeter(METER_HAPPINESS)->SetCurrent(0.0f);
    GetMeter(METER_HAPPINESS)->BackPropagate();
}
Beispiel #6
0
/////////////////////////////////////////////////
// Building                                    //
/////////////////////////////////////////////////
Building::Building(int empire_id, const std::string& building_type,
                   int produced_by_empire_id/* = ALL_EMPIRES*/) :
    m_building_type(building_type),
    m_produced_by_empire_id(produced_by_empire_id)
{
    UniverseObject::SetOwner(empire_id);
    const BuildingType* type = GetBuildingType(m_building_type);
    if (type)
        Rename(UserString(type->Name()));
    else
        Rename(UserString("ENC_BUILDING"));

    UniverseObject::Init();
}
void BuildingIndicator::Refresh() {
    if (!s_scanline_shader && GetOptionsDB().Get<bool>("UI.system-fog-of-war")) {
        boost::filesystem::path shader_path = GetRootDataDir() / "default" / "shaders" / "scanlines.frag";
        std::string shader_text;
        ReadFile(shader_path, shader_text);
        s_scanline_shader = boost::shared_ptr<ShaderProgram>(
            ShaderProgram::shaderProgramFactory("", shader_text));
    }

    SetBrowseModeTime(GetOptionsDB().Get<int>("UI.tooltip-delay"));

    TemporaryPtr<const Building> building = GetBuilding(m_building_id);
    if (!building)
        return;

    ClearBrowseInfoWnd();

    if (m_graphic) {
        delete m_graphic;
        m_graphic = 0;
    }
    if (m_scrap_indicator) {
        delete m_scrap_indicator;
        m_scrap_indicator = 0;
    }

    if (const BuildingType* type = GetBuildingType(building->BuildingTypeName())) {
        boost::shared_ptr<GG::Texture> texture = ClientUI::BuildingIcon(type->Name());
        m_graphic = new GG::StaticGraphic(texture, GG::GRAPHIC_FITGRAPHIC | GG::GRAPHIC_PROPSCALE);
        AttachChild(m_graphic);

        std::string desc = UserString(type->Description());
        if (building->GetMeter(METER_STEALTH))
            desc = UserString("METER_STEALTH") + boost::io::str(boost::format(": %3.1f\n\n") % building->GetMeter(METER_STEALTH)->Current()) + desc;
        if (GetOptionsDB().Get<bool>("UI.autogenerated-effects-descriptions") && !type->Effects().empty())
            desc += boost::io::str(FlexibleFormat(UserString("ENC_EFFECTS_STR")) % AutoGeneratedDescription(type->Effects()));

        SetBrowseInfoWnd(boost::shared_ptr<GG::BrowseInfoWnd>(
            new IconTextBrowseWnd(texture, UserString(type->Name()), desc)));
    }

    if (building && building->OrderedScrapped()) {
        boost::shared_ptr<GG::Texture> scrap_texture = ClientUI::GetTexture(ClientUI::ArtDir() / "misc" / "scrapped.png", true);
        m_scrap_indicator = new GG::StaticGraphic(scrap_texture, GG::GRAPHIC_FITGRAPHIC | GG::GRAPHIC_PROPSCALE);
        AttachChild(m_scrap_indicator);
    }

    DoLayout();
}
void nobBaseWarehouse::Destroy_nobBaseWarehouse()
{
    if(GetBuildingType() != BLD_HARBORBUILDING)
    {
        // Aus der Warenhausliste entfernen
        gwg->GetPlayer(player).RemoveWarehouse(this);
    }else
    {
        // Harbors should also remove the warehouse
        RTTR_Assert(!helpers::contains(gwg->GetPlayer(player).GetStorehouses(), this));
    }

    // Den Waren und Figuren Bescheid sagen, die zu uns auf den Weg sind, dass wir nun nicht mehr existieren
    for(std::list<noFigure*>::iterator it = dependent_figures.begin(); it != dependent_figures.end(); ++it)
        (*it)->GoHome();
    dependent_figures.clear();
	for(std::list<Ware*>::iterator it = dependent_wares.begin(); it!=dependent_wares.end(); ++it)
        WareNotNeeded(*it);
    dependent_wares.clear();

    // ggf. Events abmelden
    em->RemoveEvent(recruiting_event);
    em->RemoveEvent(producinghelpers_event);
    em->RemoveEvent(empty_event);
    em->RemoveEvent(store_event);

    // Waiting Wares löschen
    for(std::list<Ware*>::iterator it = waiting_wares.begin(); it != waiting_wares.end(); ++it)
    {
        (*it)->WareLost(player);
        delete (*it);
    }
    waiting_wares.clear();

    // restliche Warenbestände von der Inventur wieder abziehen
    for(unsigned int i = 0; i < WARE_TYPES_COUNT; ++i)
        gwg->GetPlayer(player).DecreaseInventoryWare(GoodType(i), inventory[GoodType(i)]);

    // Objekt, das die flüchtenden Leute nach und nach ausspuckt, erzeugen
    new BurnedWarehouse(pos, player, inventory.real.people);

    Destroy_nobBaseMilitary();
}
Beispiel #9
0
void Planet::Conquer(int conquerer) {
    m_just_conquered = true;

    // deal with things on production queue located at this planet
    Empire::ConquerProductionQueueItemsAtLocation(ID(), conquerer);

    // deal with UniverseObjects (eg. buildings) located on this planet
    std::vector<UniverseObject*> contained_objects = this->FindObjects();
    for (std::vector<UniverseObject*>::iterator it = contained_objects.begin(); it != contained_objects.end(); ++it) {
        UniverseObject* obj = *it;

        // Buildings:
        if (Building* building = universe_object_cast<Building*>(obj)) {
            const BuildingType* type = GetBuildingType(building->BuildingTypeName());

            // determine what to do with building of this type...
            const CaptureResult cap_result = type->GetCaptureResult(obj->Owner(), conquerer, this->ID(), false);

            if (cap_result == CR_CAPTURE) {
                // replace ownership
                obj->SetOwner(conquerer);
            } else if (cap_result == CR_DESTROY) {
                // destroy object
                Logger().debugStream() << "Planet::Conquer destroying object: " << obj->Name();
                GetUniverse().Destroy(obj->ID());
                obj = 0;
            } else if (cap_result == CR_RETAIN) {
                // do nothing
            }
        }

        // TODO: deal with any other UniverseObject subclasses...?
    }

    // replace ownership
    SetOwner(conquerer);
}
Beispiel #10
0
bool Building::HasTag(const std::string& name) const {
    const BuildingType* type = GetBuildingType(m_building_type);

    return type && type->Tags().count(name);
}
Beispiel #11
0
void BuildingIndicator::RClick(const GG::Pt& pt, GG::Flags<GG::ModKey> mod_keys) {
    // verify that this indicator represents an existing building, and not a
    // queued production item, and that the owner of the building is this
    // client's player's empire
    int empire_id = HumanClientApp::GetApp()->EmpireID();
    TemporaryPtr<Building> building = GetBuilding(m_building_id);
    if (!building)
        return;

    const MapWnd* map_wnd = ClientUI::GetClientUI()->GetMapWnd();
    if (ClientPlayerIsModerator() && map_wnd->GetModeratorActionSetting() != MAS_NoAction) {
        RightClickedSignal(m_building_id);  // response handled in MapWnd
        return;
    }

    GG::MenuItem menu_contents;

    if (!building->OrderedScrapped()) {
        // create popup menu with "Scrap" option
        menu_contents.next_level.push_back(GG::MenuItem(UserString("ORDER_BUIDLING_SCRAP"), 3, false, false));
    } else {
        // create popup menu with "Cancel Scrap" option
        menu_contents.next_level.push_back(GG::MenuItem(UserString("ORDER_CANCEL_BUIDLING_SCRAP"), 4, false, false));
    }

    const std::string& building_type = building->BuildingTypeName();
    const BuildingType* bt = GetBuildingType(building_type);
    if (bt) {
        std::string popup_label = boost::io::str(FlexibleFormat(UserString("ENC_LOOKUP")) % UserString(building_type));
        menu_contents.next_level.push_back(GG::MenuItem(popup_label, 5, false, false));
    }


    GG::PopupMenu popup(pt.x, pt.y, ClientUI::GetFont(), menu_contents, ClientUI::TextColor(),
                        ClientUI::WndOuterBorderColor(), ClientUI::WndColor(), ClientUI::EditHiliteColor());
    if (popup.Run()) {
        switch (popup.MenuID()) {
        case 3: { // scrap building
            if (m_order_issuing_enabled)
                HumanClientApp::GetApp()->Orders().IssueOrder(
                    OrderPtr(new ScrapOrder(empire_id, m_building_id)));
            break;
        }

        case 4: { // un-scrap building
            if (!m_order_issuing_enabled)
                break;

            // find order to scrap this building, and recind it
            std::map<int, int> pending_scrap_orders = PendingScrapOrders();
            std::map<int, int>::const_iterator it = pending_scrap_orders.find(building->ID());
            if (it != pending_scrap_orders.end()) {
                HumanClientApp::GetApp()->Orders().RecindOrder(it->second);
            break;
            }
        }

        case 5: { // pedia lookup building type
            ClientUI::GetClientUI()->ZoomToBuildingType(building_type);
            break;
        }

        default:
            break;
        }
    }
}
void nobUsual::Draw(DrawPoint drawPt)
{
    // Gebäude an sich zeichnen
    DrawBaseBuilding(drawPt);

    // Wenn Produktion gestoppt ist, Schild außen am Gebäude zeichnen zeichnen
    if(disable_production_virtual)
        LOADER.GetMapImageN(46)->DrawFull(drawPt + BUILDING_SIGN_CONSTS[nation][bldType_]);

    // Rauch zeichnen

    // Raucht dieses Gebäude und ist es in Betrieb? (nur arbeitende Gebäude rauchen schließlich)
    if(is_working && BUILDING_SMOKE_CONSTS[nation][bldType_].type)
    {
        // Dann Qualm zeichnen (damit Qualm nicht synchron ist, x- und y- Koordinate als Unterscheidung
        LOADER
          .GetMapImageN(692 + BUILDING_SMOKE_CONSTS[nation][bldType_].type * 8
                        + GAMECLIENT.GetGlobalAnimation(8, 5, 2, (GetX() + GetY()) * 100))
          ->DrawFull(drawPt + BUILDING_SMOKE_CONSTS[nation][bldType_].offset, 0x99EEEEEE);
    }

    // TODO: zusätzliche Dinge wie Mühlenräder, Schweinchen etc bei bestimmten Gebäuden zeichnen

    // Bei Mühle, wenn sie nicht arbeitet, immer Mühlenräder (nichtdrehend) zeichnen
    if(bldType_ == BLD_MILL && !is_working)
    {
        // Flügel der Mühle
        LOADER.GetNationImage(nation, 250 + 5 * 49)->DrawFull(drawPt);
        // Schatten der Flügel
        LOADER.GetNationImage(nation, 250 + 5 * 49 + 1)->DrawFull(drawPt, COLOR_SHADOW);
    }
    // Esel in den Kammer bei Eselzucht zeichnen
    else if(bldType_ == BLD_DONKEYBREEDER)
    {
        // Für alle Völker jeweils
        // X-Position der Esel
        const helpers::MultiArray<DrawPoint, NUM_NATS, 3> DONKEY_OFFSETS = {{{{13, -9}, {26, -9}, {39, -9}},
                                                                             {{3, -17}, {16, -17}, {30, -17}},
                                                                             {{2, -21}, {15, -21}, {29, -21}},
                                                                             {{7, -17}, {18, -17}, {30, -17}},
                                                                             {{3, -22}, {16, -22}, {30, -22}}}};
        // Animations-IDS des Esels
        const std::array<unsigned char, 25> DONKEY_ANIMATION = {
          {0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 6, 5, 4, 4, 5, 6, 5, 7, 6, 5, 4, 3, 2, 1, 0}};

        // Die drei Esel zeichnen mithilfe von Globalanimation
        // Anzahl hängt von Produktivität der Eselzucht ab:
        // 0-29 - kein Esel
        // 30-60 - 1 Esel
        // 60-90 - 2 Esel
        // 90-100 - 3 Esel
        if(productivity >= 30)
            LOADER
              .GetMapImageN(2180 + DONKEY_ANIMATION[GAMECLIENT.GetGlobalAnimation(DONKEY_ANIMATION.size(), 5, 2, GetX() * (player + 2))])
              ->DrawFull(drawPt + DONKEY_OFFSETS[nation][0]);
        if(productivity >= 60)
            LOADER.GetMapImageN(2180 + DONKEY_ANIMATION[GAMECLIENT.GetGlobalAnimation(DONKEY_ANIMATION.size(), 5, 2, GetY())])
              ->DrawFull(drawPt + DONKEY_OFFSETS[nation][1]);
        if(productivity >= 90)
            LOADER
              .GetMapImageN(
                2180 + DONKEY_ANIMATION[GAMECLIENT.GetGlobalAnimation(DONKEY_ANIMATION.size(), 5, 2, GetX() + GetY() * (nation + 1))])
              ->DrawFull(drawPt + DONKEY_OFFSETS[nation][2]);
    }
    // Bei Katapulthaus Katapult oben auf dem Dach zeichnen, falls er nicht "arbeitet"
    else if(bldType_ == BLD_CATAPULT && !is_working)
    {
        LOADER.GetPlayerImage("rom_bobs", 1776)->DrawFull(drawPt - DrawPoint(7, 19));
    }

    // Bei Schweinefarm Schweinchen auf dem Hof zeichnen
    else if(bldType_ == BLD_PIGFARM && this->HasWorker())
    {
        // Position der 5 Schweinchen für alle 4 Völker (1. ist das große Schwein)
        const helpers::MultiArray<DrawPoint, NUM_NATS, 5> PIG_POSITIONS = {{
          //  gr. S. 1.klS 2. klS usw
          {{3, -8}, {17, 3}, {-12, 4}, {-2, 10}, {-22, 11}},    // Afrikaner
          {{-16, 0}, {-37, 0}, {-32, 8}, {-16, 10}, {-22, 18}}, // Japaner
          {{-15, 0}, {-4, 9}, {-22, 10}, {2, 19}, {-15, 20}},   // Römer
          {{5, -5}, {25, -12}, {-7, 7}, {-23, 11}, {-10, 14}},  // Wikinger
          {{-16, 5}, {-37, 5}, {-32, -1}, {-16, 15}, {-27, 18}} // Babylonier
        }};

        /// Großes Schwein zeichnen
        LOADER.GetMapImageN(2160)->DrawFull(drawPt + PIG_POSITIONS[nation][0], COLOR_SHADOW);
        LOADER.GetMapImageN(2100 + GAMECLIENT.GetGlobalAnimation(12, 3, 1, GetX() + GetY() + GetObjId()))
          ->DrawFull(drawPt + PIG_POSITIONS[nation][0]);

        // Die 4 kleinen Schweinchen, je nach Produktivität
        for(unsigned i = 1; i < min<unsigned>(unsigned(productivity) / 20 + 1, 5); ++i)
        {
            // A random (really, dice-rolled by hand:) ) order of the four possible pig animations, with eating three times as much as the
            // others ones  To get random-looking, non synchronous, sweet little pigs
            const std::array<unsigned char, 63> smallpig_animations = {0, 0, 3, 2, 0, 0, 1, 3, 0, 3, 1, 3, 2, 0, 0, 1, 0, 0, 1, 3, 2,
                                                                       0, 1, 1, 0, 0, 2, 1, 0, 1, 0, 2, 2, 0, 0, 2, 2, 0, 1, 0, 3, 1,
                                                                       2, 0, 1, 2, 2, 0, 0, 0, 3, 0, 2, 0, 3, 0, 3, 0, 1, 1, 0, 3, 0};
            const unsigned short animpos =
              GAMECLIENT.GetGlobalAnimation(63 * 12, 63 * 4 - i * 5, 1, 183 * i + GetX() * GetObjId() + GetY() * i);
            LOADER.GetMapImageN(2160)->DrawFull(drawPt + PIG_POSITIONS[nation][i], COLOR_SHADOW);
            LOADER.GetMapImageN(2112 + smallpig_animations[animpos / 12] * 12 + animpos % 12)->DrawFull(drawPt + PIG_POSITIONS[nation][i]);
        }

        // Ggf. Sounds abspielen (oink oink), da soll sich der Schweinezüchter drum kümmen
        dynamic_cast<nofPigbreeder*>(worker)->MakePigSounds(); //-V522
    }
    // Bei nubischen Bergwerken das Feuer vor dem Bergwerk zeichnen
    else if(BuildingProperties::IsMine(GetBuildingType()) && worker && nation == NAT_AFRICANS)
        LOADER.GetMapPlayerImage(740 + GAMECLIENT.GetGlobalAnimation(8, 5, 2, GetObjId() + GetX() + GetY()))
          ->DrawFull(drawPt + NUBIAN_MINE_FIRE[bldType_ - BLD_GRANITEMINE]);
}
Beispiel #13
0
void noBuildingSite::Draw(DrawPoint drawPt)
{
    if(state == STATE_PLANING)
    {
        // Baustellenschild mit Schatten zeichnen
        LOADER.GetNationImage(gwg->GetPlayer(player).nation, 450)->Draw(drawPt);
        LOADER.GetNationImage(gwg->GetPlayer(player).nation, 451)->Draw(drawPt, 0, 0, 0, 0, 0, 0, COLOR_SHADOW);
    }
    else
    {
        // Baustellenstein und -schatten zeichnen
        LOADER.GetNationImage(gwg->GetPlayer(player).nation, 455)->Draw(drawPt);
        LOADER.GetNationImage(gwg->GetPlayer(player).nation, 456)->Draw(drawPt, 0, 0, 0, 0, 0, 0, COLOR_SHADOW);


        // Waren auf der Baustelle

        // Bretter
        DrawPoint doorPos = drawPt + DrawPoint(GetDoorPointX(), GetDoorPointY());
        for(unsigned char i = 0; i < boards; ++i)
            LOADER.GetMapImageN(2200 + GD_BOARDS)->Draw(doorPos - DrawPoint(5, 10 + i * 4));
        // Steine
        for(unsigned char i = 0; i < stones; ++i)
            LOADER.GetMapImageN(2200 + GD_STONES)->Draw(doorPos + DrawPoint(8, -12 - i * 4));

        // bis dahin gebautes Haus zeichnen

        // Rohbau

        // ausrechnen, wie weit er ist
        unsigned int p1 = 0, p2 = 0;

        if(BUILDING_COSTS[nation][GetBuildingType()].stones)
        {
            // Haus besteht aus Steinen und Brettern
            p1 = min<unsigned int>(build_progress, BUILDING_COSTS[nation][GetBuildingType()].boards * 8);
            p2 = BUILDING_COSTS[nation][GetBuildingType()].boards * 8;
        }
        else
        {
            // Haus besteht nur aus Brettern, dann 50:50
            p1 = min<unsigned int>(build_progress, BUILDING_COSTS[nation][GetBuildingType()].boards * 4);
            p2 = BUILDING_COSTS[nation][GetBuildingType()].boards * 4;
        }

        LOADER.building_cache[nation][type_][1].drawPercent(drawPt, p1 * 100 / p2);

        // Das richtige Haus
        if(BUILDING_COSTS[nation][GetBuildingType()].stones)
        {
            // Haus besteht aus Steinen und Brettern
            p1 = ((build_progress >  BUILDING_COSTS[nation][GetBuildingType()].boards * 8) ? (build_progress - BUILDING_COSTS[nation][GetBuildingType()].boards * 8) : 0);
            p2 = BUILDING_COSTS[nation][GetBuildingType()].stones * 8;
        }
        else
        {
            // Haus besteht nur aus Brettern, dann 50:50
            p1 = ((build_progress >  BUILDING_COSTS[nation][GetBuildingType()].boards * 4) ? (build_progress - BUILDING_COSTS[nation][GetBuildingType()].boards * 4) : 0);
            p2 = BUILDING_COSTS[nation][GetBuildingType()].boards * 4;
        }

        LOADER.building_cache[nation][type_][0].drawPercent(drawPt, p1 * 100 / p2);
    }

    //char number[256];
    //sprintf(number,"%u",obj_id);
    //NormalFont->Draw(x,y,number,0,0xFFFF0000);
}