Пример #1
0
void CatapultStone::Draw(const GameWorldView& gwv, const int xoffset, const int yoffset)
{
    // Stein überhaupt zeichnen (wenn Quelle und Ziel nicht sichtbar sind, dann nicht!)
    if(gwv.GetGameWorldViewer()->GetVisibility(dest_building) != VIS_VISIBLE &&
            gwv.GetGameWorldViewer()->GetVisibility(dest_map) != VIS_VISIBLE)
        return;

    int world_width = gwg->GetWidth() * TR_W;
    int world_height = gwg->GetHeight() * TR_H;

    if(explode)
    {
        // Stein explodierend am Ziel zeichnen
        LOADER.GetMapImageN(3102 + GAMECLIENT.Interpolate(4, event))->
        Draw((dest_x - xoffset + world_width) % world_width, (dest_y - yoffset + world_height) % world_height);
    }
    else
    {
        // Linear interpolieren zwischen Ausgangs- und Zielpunkt
        int x = GAMECLIENT.Interpolate(start_x, dest_x, event);
        int y = GAMECLIENT.Interpolate(start_y, dest_y, event);

        int whole = int(std::sqrt(double((dest_x - start_x) * (dest_x - start_x) + (dest_y - start_y) * (dest_y - start_y))));
        int s = GAMECLIENT.Interpolate(whole , event);


        double dx = double(s) / double(whole)  - 0.5;

        // Y-Verschiebung ausrechnen, damit die Nullpunkte beim Start- und Endpunkt liegen
        double y_diff = 0.5 * 0.5;

        // Verschiebung ausrechnen von Y
        int diff = int((dx * dx - y_diff) * 200);

        // Schatten auf linearer Linie zeichnen
        LOADER.GetMapImageN(3101)->Draw((x - xoffset + world_width) % world_width, (y - yoffset + world_height) % world_height, 0, 0, 0, 0, 0, 0, COLOR_SHADOW);
        // Stein auf Parabel zeichnen
        LOADER.GetMapImageN(3100)->Draw((x - xoffset + world_width) % world_width, (y - yoffset + world_height + diff) % world_height);
    }
}
Пример #2
0
iwMainMenu::iwMainMenu(GameWorldView& gwv, GameCommandFactory& gcFactory)
    : IngameWindow(CGI_MAINSELECTION, IngameWindow::posLastOrCenter, 190, 286, _("Main selection"), LOADER.GetImageN("io", 5)),
      gwv(gwv), gcFactory(gcFactory)
{
    // Verteilung
    AddImageButton( 0,  12,  22,  53, 44, TC_GREY, LOADER.GetImageN("io", 134), _("Distribution of goods"));
    // Transport
    AddImageButton( 1,  68,  22,  53, 44, TC_GREY, LOADER.GetImageN("io", 198), _("Transport"));
    // Werkzeugproduktion
    AddImageButton( 2, 124,  22,  53, 44, TC_GREY, LOADER.GetImageN("io", 137), _("Tools"));

    // Statistiken
    AddImageButton( 3,  12,  70,  39, 44, TC_GREY, LOADER.GetImageN("io", 166), _("General statistics"));
    AddImageButton( 4,  54,  70,  39, 44, TC_GREY, LOADER.GetImageN("io", 135), _("Merchandise statistics"));
    AddImageButton( 5,  96,  70,  39, 44, TC_GREY, LOADER.GetImageN("io", 132), _("Buildings"));

    // Inventur
    AddImageButton( 6, 138,  70,  39, 44, TC_GREY, LOADER.GetImageN("io", 214), _("Stock"));

    // Gebäude
    AddImageButton( 7,  12, 118,  53, 44, TC_GREY, LOADER.GetImageN("io", 136), _("Productivity"));
    // Militär
    AddImageButton( 8,  68, 118,  53, 44, TC_GREY, LOADER.GetImageN("io", 133), _("Military"));
    // Schiffe
    AddImageButton( 9, 124, 118,  53, 44, TC_GREY, LOADER.GetImageN("io", 175), _("Ship register"));

    // Baureihenfolge
    if(gwv.GetWorld().GetGGS().isEnabled(AddonId::CUSTOM_BUILD_SEQUENCE))
        AddImageButton( 10,  12, 166,  53, 44, TC_GREY, LOADER.GetImageN("io", 24), _("Building sequence"));

    // Diplomatie (todo: besseres Bild suchen)
    AddImageButton( 11,  68, 166,  53, 44, TC_GREY, LOADER.GetImageN("io", 190), _("Diplomacy"));

    // AI-Debug
    if(gwv.GetViewer().GetPlayer().isHost && gwv.GetWorld().GetGGS().isEnabled(AddonId::AI_DEBUG_WINDOW))
        AddImageButton( 13,  80, 210,  20, 20, TC_GREY, NULL, _("AI Debug Window"));

    // Optionen
    AddImageButton(30,  12, 231, 165, 32, TC_GREY, LOADER.GetImageN("io",  37), _("Options"));
}
Пример #3
0
iwBuildings::iwBuildings(GameWorldView& gwv, GameCommandFactory& gcFactory):
    IngameWindow(CGI_BUILDINGS, IngameWindow::posAtMouse,  185, 480, _("Buildings"), LOADER.GetImageN("resource", 41)),
    gwv(gwv), gcFactory(gcFactory)
{
    const Nation playerNation = gwv.GetViewer().GetPlayer().nation;
    // Symbole für die einzelnen Gebäude erstellen
    for(unsigned short y = 0; y < BUILDINGS_COUNT / 4 + (BUILDINGS_COUNT % 4 > 0 ? 1 : 0); ++y)
    {
        for(unsigned short x = 0; x < ((y == BUILDINGS_COUNT / 4) ? BUILDINGS_COUNT % 4 : 4); ++x)
        {
			if(bts[y*4+x] != BLD_CHARBURNER)
            {
                AddImageButton(y * 4 + x, iconPadding.x - 16 + iconSpacing.x * x, iconPadding.y - 16 + iconSpacing.y * y, 32, 32, TC_GREY, LOADER.GetImageN(NATION_ICON_IDS[playerNation], bts[y * 4 + x]), _(BUILDING_NAMES[bts[y * 4 + x]]));
            }
			else
				AddImageButton(y * 4 + x, iconPadding.x - 16 + iconSpacing.x * x, iconPadding.y - 16  + iconSpacing.y * y,32,32,TC_GREY,LOADER.GetImageN("charburner", playerNation * 8 + 8) , _(BUILDING_NAMES[bts[y * 4 + x]]));
        }
    }

    // Hilfe-Button
    AddImageButton(32, width_ - 14 - 30, height_ - 20 - 32, 30, 32, TC_GREY, LOADER.GetImageN("io", 225), _("Help"));

}
Пример #4
0
void TerrainRenderer::PrepareWaysPoint(PreparedRoads& sorted_roads, const GameWorldView& gwv, MapPoint t, const PointI& offset)
{
    PointI startPos = PointI(GetTerrain(t)) - gwv.GetOffset() + offset;

    GameWorldViewer& gwViewer = gwv.GetGameWorldViewer();
    Visibility visibility = gwViewer.GetVisibility(t);

	int totalWidth  = gwViewer.GetWidth()  * TR_W;
	int totalHeight = gwViewer.GetHeight() * TR_H;

    // Wegtypen für die drei Richtungen
    for(unsigned dir = 0; dir < 3; ++dir)
    {
        unsigned char type = gwViewer.GetVisibleRoad(t, dir, visibility);
        if (!type)
            continue;
        MapPoint ta = gwViewer.GetNeighbour(t, 3 + dir);

        PointI endPos = PointI(GetTerrain(ta)) - gwv.GetOffset() + offset;
        PointI diff = startPos - endPos;

        // Gehen wir über einen Kartenrand (horizontale Richung?)
        if(std::abs(diff.x) >= totalWidth / 2)
        {
            if(std::abs(endPos.x - totalWidth - startPos.x) < std::abs(diff.x))
                endPos.x -= totalWidth;
            else
                endPos.x += totalWidth;
        }
        // Und dasselbe für vertikale Richtung
        if(std::abs(diff.y) >= totalHeight / 2)
        {
            if(std::abs(endPos.y - totalHeight - startPos.y) < std::abs(diff.y))
                endPos.y -= totalHeight;
            else
                endPos.y += totalHeight;
        }

        --type;

        // Wegtypen "konvertieren"
        switch(type)
        {
            case RoadSegment::RT_DONKEY:
            case RoadSegment::RT_NORMAL:
            {
                TerrainType t1 = gwViewer.GetTerrainAround(t, dir + 2);
                TerrainType t2 = gwViewer.GetTerrainAround(t, dir + 3);

                // Prüfen, ob Bergwege gezeichnet werden müssen, indem man guckt, ob der Weg einen
                // Berg "streift" oder auch eine Bergwiese
                if(TerrainData::IsMountain(t1) || TerrainData::IsMountain(t2))
                    type = 3;

                break;
            }
            case RoadSegment::RT_BOAT:
                type = 2;
                break;
        }

        sorted_roads[type].push_back(
            PreparedRoad(type, startPos, endPos, GetColor(t), GetColor(ta), dir)
        );
    }
}
Пример #5
0
/**
 *  zeichnet den Kartenausschnitt.
 *
 *  @author OLiver
 *  @author FloSoft
 */
void TerrainRenderer::Draw(const GameWorldView& gwv, unsigned int* water)
{
    assert(!gl_vertices.empty());
    assert(!borders.empty());

    /*  if ((gwv.GetXOffset() == gwv.terrain_last_xoffset) && (gwv.GetYOffset() == gwv.terrain_last_yoffset) && (gwv.terrain_list != 0) && (GAMECLIENT.GetGlobalAnimation(4, 5, 4, 0) == gwv.terrain_last_global_animation))
        {
            glCallList(gwv.terrain_list);
            *water = gwv.terrain_last_water;
            return;
        }

        gwv.terrain_last_xoffset = gwv.GetXOffset();
        gwv.terrain_last_yoffset = gwv.GetYOffset();
        gwv.terrain_last_global_animation = GAMECLIENT.GetGlobalAnimation(4, 5, 4, 0);

        if (gwv.terrain_list == 0)
            gwv.terrain_list = glGenLists(1);

        glNewList(gwv.terrain_list, GL_COMPILE_AND_EXECUTE);*/

    // nach Texture in Listen sortieren
    boost::array< std::vector<MapTile>, TT_COUNT> sorted_textures;
    boost::array< std::vector<BorderTile>, 5> sorted_borders;
    PreparedRoads sorted_roads;

    Point<int> lastOffset(0, 0);
 
    // Beim zeichnen immer nur beginnen, wo man auch was sieht
    for(int y = gwv.GetFirstPt().y; y < gwv.GetLastPt().y; ++y)
    {
        unsigned char lastTerrain = 255;
        unsigned char lastBorder  = 255;

        for(int x = gwv.GetFirstPt().x; x < gwv.GetLastPt().x; ++x)
        {
            Point<int> posOffset;
            MapPoint tP = ConvertCoords(Point<int>(x, y), &posOffset);

            TerrainType t = gwv.GetGameWorldViewer().GetNode(tP).t1;
            if(posOffset != lastOffset)
                lastTerrain = 255;

            if(t == lastTerrain && tP != MapPoint(0, 0))
                ++sorted_textures[t].back().count;
            else
            {
                MapTile tmp(GetTriangleIdx(tP), posOffset);
                sorted_textures[t].push_back(tmp);
                lastTerrain = t;
            }

            t = gwv.GetGameWorldViewer().GetNode(tP).t2;

            if(t == lastTerrain)
                ++sorted_textures[t].back().count;
            else
            {
                MapTile tmp(GetTriangleIdx(tP) + 1, posOffset);
                sorted_textures[t].push_back(tmp);
            }

            lastTerrain = t;

            const Borders& curBorders = borders[GetVertexIdx(tP)];
            boost::array<unsigned char, 6> tiles =
            {{
                curBorders.left_right[0],
                curBorders.left_right[1],
                curBorders.right_left[0],
                curBorders.right_left[1],
                curBorders.top_down[0],
                curBorders.top_down[1]
            }};

            // Offsets into gl_* arrays
            boost::array<unsigned, 6> offsets = 
            {{
                curBorders.left_right_offset[0],
                curBorders.left_right_offset[1],
                curBorders.right_left_offset[0],
                curBorders.right_left_offset[1],
                curBorders.top_down_offset[0],
                curBorders.top_down_offset[1]
            }};

            for(unsigned char i = 0; i < 6; ++i)
            {
                if(!tiles[i])
                    continue;
                if(tiles[i] == lastBorder)
                {
                    BorderTile& curTile = sorted_borders[lastBorder - 1].back();
                    // Check that we did not wrap around the map and the expected offset matches
                    if(curTile.tileOffset + curTile.count == offsets[i])
                    {
                        ++curTile.count;
                        continue;
                    }
                }
                lastBorder = tiles[i];
                BorderTile tmp(offsets[i], posOffset);
                sorted_borders[lastBorder - 1].push_back(tmp);
            }

            PrepareWaysPoint(sorted_roads, gwv, tP, posOffset);

            lastOffset = posOffset;
        }
    }

    if (water)
    {
        unsigned water_count = 0;

        for(unsigned char t = 0; t < TT_COUNT; ++t){
            if(!TerrainData::IsWater(TerrainType(t)))
                continue;
            for(std::vector<MapTile>::iterator it = sorted_textures[t].begin(); it != sorted_textures[t].end(); ++it)
            {
                water_count += it->count;
            }
        }

        PointI diff = gwv.GetLastPt() - gwv.GetFirstPt();
        if( diff.x && diff.y )
            *water = 50 * water_count / ( diff.x * diff.y );
        else
            *water = 0;
    }

    lastOffset = PointI(0, 0);

    if(vboBuffersUsed)
    {
        glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_vertices);
        glVertexPointer(2, GL_FLOAT, 0, NULL);

        glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_texcoords);
        glTexCoordPointer(2, GL_FLOAT, 0, NULL);

        glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_colors);
        glColorPointer(3, GL_FLOAT, 0, NULL);
    }
    else
    {
        glVertexPointer(2, GL_FLOAT, 0, &gl_vertices.front());
        glTexCoordPointer(2, GL_FLOAT, 0, &gl_texcoords.front());
        glColorPointer(3, GL_FLOAT, 0, &gl_colors.front());
    }

    // Arrays aktivieren
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);

    // Modulate2x
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
    glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 2.0f);

    // Verschieben gem#ß x und y offset
    glTranslatef( float(-gwv.GetXOffset()), float(-gwv.GetYOffset()), 0.0f);

    // Alphablending aus
    glDisable(GL_BLEND);

    for(unsigned char t = 0; t < TT_COUNT; ++t)
    {
        if(sorted_textures[t].empty())
            continue;
        unsigned animationFrame;
        TerrainType tt = TerrainType(t);
        if(TerrainData::IsLava(tt))
            animationFrame = GAMECLIENT.GetGlobalAnimation(TerrainData::GetFrameCount(tt), 5, 4, 0);
        else if(TerrainData::IsWater(tt))
            animationFrame = GAMECLIENT.GetGlobalAnimation(TerrainData::GetFrameCount(tt), 5, 2, 0);
        else
            animationFrame = 0;

        VIDEODRIVER.BindTexture(LOADER.GetTerrainTexture(tt, animationFrame).GetTexture());

        for(std::vector<MapTile>::iterator it = sorted_textures[t].begin(); it != sorted_textures[t].end(); ++it)
        {
            if(it->posOffset != lastOffset)
            {
                PointI trans = it->posOffset - lastOffset;
                glTranslatef( float(trans.x), float(trans.y), 0.0f);
                lastOffset = it->posOffset;
            }

            assert(it->tileOffset + it->count <= width * height * 2u);
            glDrawArrays(GL_TRIANGLES, it->tileOffset * 3, it->count * 3); // Arguments are in Elements. 1 triangle has 3 values
        }
    }

    glEnable(GL_BLEND);

    glLoadIdentity();
    glTranslatef( float(-gwv.GetXOffset()), float(-gwv.GetYOffset()), 0.0f);

    lastOffset = PointI(0, 0);
    for(unsigned short i = 0; i < 5; ++i)
    {
        if(sorted_borders[i].empty())
            continue;
        VIDEODRIVER.BindTexture(GetImage(borders, i)->GetTexture());

        for(std::vector<BorderTile>::iterator it = sorted_borders[i].begin(); it != sorted_borders[i].end(); ++it)
        {
            if(it->posOffset != lastOffset)
            {
                PointI trans = it->posOffset - lastOffset;
                glTranslatef( float(trans.x), float(trans.y), 0.0f);
                lastOffset = it->posOffset;
            }
            assert(it->tileOffset + it->count <= gl_vertices.size());
            glDrawArrays(GL_TRIANGLES, it->tileOffset * 3, it->count * 3); // Arguments are in Elements. 1 triangle has 3 values
        }
    }
    glLoadIdentity();

    DrawWays(sorted_roads);

    // Wieder zurück ins normale modulate
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
Пример #6
0
iwAction::iwAction(GameInterface& gi, GameWorldView& gwv, const Tabs& tabs, MapPoint selectedPt, int mouse_x, int mouse_y, unsigned int params, bool military_buildings)
    : IngameWindow(CGI_ACTION, mouse_x, mouse_y, 200, 254, _("Activity window"), LOADER.GetImageN("io", 1)),
      gi(gi), gwv(gwv), selectedPt(selectedPt), mousePosAtOpen_(mouse_x, mouse_y)
{
    /*
        TAB_FLAG    1 = Land road
        TAB_FLAG    2 = Waterway
        TAB_FLAG    3 = Pull down flag
        TAB_FLAG    4 = Send geologist
        TAB_FLAG    5 = Send scout

        TAB_CUTROAD 1 = Cut Road

        TAB_BUILD   100-108, 200-212, 300-303, 400-403 = Buildings

        TAB_SETFLAG 1 = Erect flag

        TAB_WATCH   1 =
        TAB_WATCH   2 =
        TAB_WATCH   3 = zum HQ
		TAB_WATCH	4 = notify allies of location

        TAB_ATTACK  1 = Less soldiers
        TAB_ATTACK  2 = More soldiers
        TAB_ATTACK  3 = Option group: Better/Weaker
        TAB_ATTACK  4 = Angriff
        TAB_ATTACK  10-14 = Direktauswahl Anzahl
    */

    const GamePlayer& player = gwv.GetViewer().GetPlayer();

    /// Haupttab
    ctrlTab* main_tab = AddTabCtrl(0, 10, 20, 180);

    // Bau-main_tab
    if(tabs.build)
    {
        ctrlGroup* group =  main_tab->AddTab(LOADER.GetImageN("io", 18), _("-> Build house"), TAB_BUILD);

        ctrlTab* build_tab = group->AddTabCtrl(1, 0, 45, 180);

        // Building tabs
        if(tabs.build_tabs == Tabs::BT_MINE) //mines
            build_tab->AddTab(LOADER.GetImageN("io", 76), _("-> Dig mines"), Tabs::BT_MINE);
        else
        {
            build_tab->AddTab(LOADER.GetImageN("io", 67), _("-> Build hut"), Tabs::BT_HUT);
            if(tabs.build_tabs >= Tabs::BT_HOUSE)
                build_tab->AddTab(LOADER.GetImageN("io", 68), _("-> Build house"), Tabs::BT_HOUSE);
            if(tabs.build_tabs >= Tabs::BT_CASTLE) //castle & harbor
                build_tab->AddTab(LOADER.GetImageN("io", 69), _("-> Build castle"), Tabs::BT_CASTLE);
        }

        // add building icons to TabCtrl
        const unsigned char building_count_max = 14;
        const unsigned building_count[4] = { 9, 13, 6, 4 };
        const BuildingType building_icons[4][building_count_max] =
        {
            { /* 0 */
                /* 0 */ BLD_WOODCUTTER,
                /* 1 */ BLD_FORESTER,
                /* 2 */ BLD_QUARRY,
                /* 3 */ BLD_FISHERY,
                /* 4 */ BLD_HUNTER,
                /* 5 */ BLD_BARRACKS,
                /* 6 */ BLD_GUARDHOUSE,
                /* 7 */ BLD_LOOKOUTTOWER,
                /* 8 */ BLD_WELL
            },
            {/* 1 */
                /*  0 */ BLD_SAWMILL,
                /*  1 */ BLD_SLAUGHTERHOUSE,
                /*  2 */ BLD_MILL,
                /*  3 */ BLD_BAKERY,
                /*  4 */ BLD_IRONSMELTER,
                /*  5 */ BLD_METALWORKS,
                /*  6 */ BLD_ARMORY,
                /*  7 */ BLD_MINT,
                /*  8 */ BLD_SHIPYARD,
                /*  9 */ BLD_BREWERY,
                /* 10 */ BLD_STOREHOUSE,
                /* 11 */ BLD_WATCHTOWER,
                /* 12 */ BLD_CATAPULT
            },
            { /* 2 */
                /* 0 */ BLD_FARM,
                /* 1 */ BLD_PIGFARM,
                /* 2 */ BLD_DONKEYBREEDER,
                /* 3 */ BLD_CHARBURNER,
                /* 4 */ BLD_FORTRESS,
                /* 5 */ BLD_HARBORBUILDING
            },
            { /* 3 */
                /* 0 */ BLD_GOLDMINE,
                /* 1 */ BLD_IRONMINE,
                /* 2 */ BLD_COALMINE,
                /* 3 */ BLD_GRANITEMINE
            }
        };

        const unsigned TABS_COUNT[5] = {1, 2, 3, 1, 3};

        /// Flexible what-buildings-are-available handling
        bool building_available[4][building_count_max] ;

        // First enable all buildings
        for (unsigned char i = 0; i < 4; ++i)
        {
            for(unsigned char j = 0; j < building_count_max; ++j)
            {
                if (j < building_count[i])
                {
                    building_available[i][j] = player.IsBuildingEnabled(building_icons[i][j]);
                }
                else
                {
                    building_available[i][j] = false;
                }
            }
        }

        // Now deactivate those we don't want

        // Harbor
        if (tabs.build_tabs != Tabs::BT_HARBOR)
            building_available[2][5] = false;

        // Military buildings
        if (!military_buildings)
        {
            building_available[0][5] = false;
            building_available[0][6] = false;
            building_available[1][11] = false;
            building_available[2][4] = false;
        }

        // Mint and Goldmine
        if(gwv.GetWorld().GetGGS().isEnabled(AddonId::CHANGE_GOLD_DEPOSITS))
        {
            building_available[1][7] = false;
            building_available[3][0] = false;
        }

        // Catapult
        if (!player.CanBuildCatapult()) //-V807
            building_available[1][12] = false;

        // Charburner
        if(!gwv.GetWorld().GetGGS().isEnabled(AddonId::CHARBURNER))
            building_available[2][3] = false;

        for(unsigned char i = 0; i < TABS_COUNT[tabs.build_tabs]; ++i)
        {
            unsigned char k = 0;
            Tabs::BuildTab bt = (tabs.build_tabs == Tabs::BT_MINE) ? Tabs::BT_MINE : Tabs::BuildTab(i);

            for(unsigned char j = 0; j < building_count_max; ++j)
            {
                if (!building_available[bt][j])
                    continue;

                // Baukosten im Tooltip mit anzeigen
                std::stringstream tooltip;
                tooltip << _(BUILDING_NAMES[building_icons[bt][j]]);

                tooltip << _("\nCosts: ");
                if(BUILDING_COSTS[player.nation][building_icons[bt][j]].boards > 0)
                    tooltip << (int)BUILDING_COSTS[player.nation][building_icons[bt][j]].boards << _(" boards");
                if(BUILDING_COSTS[player.nation][building_icons[bt][j]].stones > 0)
                {
                    if(BUILDING_COSTS[player.nation][building_icons[bt][j]].boards > 0)
                        tooltip << ", ";
                    tooltip << (int)BUILDING_COSTS[player.nation][building_icons[bt][j]].stones << _(" stones");
                }

                build_tab->GetGroup(bt)->AddBuildingIcon(j, (k % 5) * 36, (k / 5) * 36 + 45, building_icons[bt][j], player.nation, 36, tooltip.str());

                ++k;
            }

            building_tab_heights[bt] = (k / 5 + ((k % 5 != 0) ? 1 : 0)) * 36 + 150;
        }

        build_tab->SetSelection(0, true);
    }

    // Wenn es einen Flaggen-main_tab gibt, dann entsprechend die Buttons anordnen, wie sie gebraucht werden
    if(tabs.flag)
    {
        ctrlGroup* group = main_tab->AddTab(LOADER.GetImageN("io", 70), _("Erect flag"), TAB_FLAG);

        switch(params)
        {
            case AWFT_NORMAL: // normal Flag
            {
                group->AddImageButton(1,  0, 45, 45, 36, TC_GREY, LOADER.GetImageN("io",  65), _("Build road"));
                group->AddImageButton(3,  45, 45, 45, 36, TC_GREY, LOADER.GetImageN("io", 118), _("Pull down flag"));
                group->AddImageButton(4, 90, 45, 45, 36, TC_GREY, LOADER.GetImageN("io",  20), _("Call in geologist"));
                group->AddImageButton(5, 135, 45, 45, 36, TC_GREY, LOADER.GetImageN("io",  96), _("Send out scout"));
            } break;
            case AWFT_WATERFLAG: // Water flag
            {
                group->AddImageButton(1,  0, 45, 36, 36, TC_GREY, LOADER.GetImageN("io",  65), _("Build road"));
                group->AddImageButton(2,  36, 45, 36, 36, TC_GREY, LOADER.GetImageN("io",  95), _("Build waterway"));
                group->AddImageButton(3,  72, 45, 36, 36, TC_GREY, LOADER.GetImageN("io", 118), _("Pull down flag"));
                group->AddImageButton(4, 108, 45, 36, 36, TC_GREY, LOADER.GetImageN("io",  20), _("Call in geologist"));
                group->AddImageButton(5, 144, 45, 36, 36, TC_GREY, LOADER.GetImageN("io",  96), _("Send out scout"));
            } break;
            case AWFT_HQ: // HQ
            {
                group->AddImageButton(1, 0, 45, 180, 36, TC_GREY, LOADER.GetImageN("io", 65), _("Build road"));
            } break;
            case AWFT_STOREHOUSE: // Storehouse
            {
                group->AddImageButton(1, 0, 45, 90, 36, TC_GREY, LOADER.GetImageN("io", 65), _("Build road"));
                group->AddImageButton(3, 90, 45, 90, 36, TC_GREY, LOADER.GetImageN("io", 118), _("Demolish house"));
            } break;
        }
    }

    // Flagge Setzen-main_tab
    if(tabs.setflag)
    {
        ctrlGroup* group = main_tab->AddTab(LOADER.GetImageN("io", 45), _("Erect flag"), TAB_SETFLAG);

        unsigned int nr = 70;
        if(params == AWFT_WATERFLAG)
            nr = 94;

        // Straße aufwerten ggf anzeigen
        unsigned int btWidth = 180, btPosX = 90;
        AddUpgradeRoad(group, btPosX, btWidth);

        group->AddImageButton(1, 0, 45, btWidth, 36, TC_GREY, LOADER.GetImageN("io", nr), _("Erect flag"));
    }

    // Cut-main_tab
    if(tabs.cutroad)
    {
        ctrlGroup* group = main_tab->AddTab(LOADER.GetImageN("io", 19), _("Dig up road"), TAB_CUTROAD);

        // Straße aufwerten ggf anzeigen
        unsigned int btWidth = 180, btPosX = 0;
        if(!tabs.setflag)
            AddUpgradeRoad(group, btPosX, btWidth);

        group->AddImageButton(1, btPosX, 45, btWidth, 36, TC_GREY, LOADER.GetImageN("io", 32), _("Dig up road"));
    }

    if(tabs.attack)
    {
        ctrlGroup* group = main_tab->AddTab(LOADER.GetImageN("io", 98), _("Attack options"), TAB_ATTACK);
        available_soldiers_count = params;
        AddAttackControls(group, params);
        selected_soldiers_count = 1;
    }

    if(tabs.sea_attack)
    {
        ctrlGroup* group = main_tab->AddTab(LOADER.GetImageN("io", 177), _("Attack options"), TAB_SEAATTACK);

        selected_soldiers_count_sea = 1;
        available_soldiers_count_sea = gwv.GetViewer().GetNumSoldiersForSeaAttack(selectedPt);

        AddAttackControls(group, available_soldiers_count_sea);
    }

    // Beobachten-main_tab
    if(tabs.watch)
    {
        ctrlGroup* group = main_tab->AddTab(LOADER.GetImageN("io", 36), _("Display options"), TAB_WATCH);

        group->AddImageButton(1, 0, 45,  45, 36, TC_GREY, LOADER.GetImageN("io", 108), _("Observation window"));
        group->AddImageButton(2,  45, 45,  45, 36, TC_GREY, LOADER.GetImageN("io", 179), _("House names"));
        group->AddImageButton(3, 90, 45,  45, 36, TC_GREY, LOADER.GetImageN("io", 180), _("Go to headquarters"));
		group->AddImageButton(4, 135, 45,  45, 36, TC_GREY, LOADER.GetImageN("io", 107), _("Notify allies of this location"));
    }

    main_tab->SetSelection(0, true);

    if(x_ + GetWidth() > VIDEODRIVER.GetScreenWidth())
        x_ = mouse_x - GetWidth() - 40;
    if(y_ + GetHeight() > VIDEODRIVER.GetScreenHeight())
        y_ = mouse_y - GetHeight() - 40;

    VIDEODRIVER.SetMousePos(GetX() + 20, GetY() + 75);
}