Ejemplo n.º 1
0
void GameWorldView::DrawFigures(const MapPoint& pt, const DrawPoint&curPos, std::vector<ObjectBetweenLines>& between_lines)
{
    const std::list<noBase*>& figures = GetWorld().GetNode(pt).figures;
    for(std::list<noBase*>::const_iterator it = figures.begin(); it != figures.end(); ++it)
    {
        // Bewegt er sich oder ist es ein Schiff?
        if((*it)->IsMoving() || (*it)->GetGOT() == GOT_SHIP)
            // Dann nach der gesamten Zeile zeichnen
            between_lines.push_back(ObjectBetweenLines(*it, curPos));
        else
            // Ansonsten jetzt schon zeichnen
            (*it)->Draw(curPos);
    }
}
Ejemplo n.º 2
0
void GameWorldView::Draw(const unsigned char player, unsigned* water, const bool draw_selected, const MapCoord selected_x, const MapCoord selected_y, const RoadsBuilding& rb)
{

    int shortest_len = 100000;
    //if(//GUIResources::inst().action.IsActive())
    //  shortest_len = 0;

    glScissor(x, VideoDriverWrapper::inst().GetScreenHeight() - y - height, width, height);

    gwv->GetTerrainRenderer()->Draw(this, water);

    glTranslatef((GLfloat) this->x, (GLfloat) this->y, 0.0f);

    // Draw-Counter der Bäume zurücksetzen vor jedem Zeichnen
    noTree::ResetDrawCounter();

    for(int y = fy; y < ly; ++y)
    {
        // Figuren speichern, die in dieser Zeile gemalt werden müssen
        // und sich zwischen zwei Zeilen befinden, da sie dazwischen laufen
        std::vector<ObjectBetweenLines> between_lines;

        for(int x = fx; x < lx; ++x)
        {
            unsigned short tx, ty;
            int xo, yo;
            gwv->GetTerrainRenderer()->ConvertCoords(x, y, tx, ty, &xo, &yo);


            int xpos = int(gwv->GetTerrainRenderer()->GetTerrainX(tx, ty)) - xoffset + xo;
            int ypos = int(gwv->GetTerrainRenderer()->GetTerrainY(tx, ty)) - yoffset + yo;

            if(abs(VideoDriverWrapper::inst().GetMouseX() - static_cast<int>(xpos)) + abs(VideoDriverWrapper::inst().GetMouseY() - static_cast<int>(ypos)) < shortest_len)
            {
                selx = tx;
                sely = ty;
                selxo = xo;
                selyo = yo;
                shortest_len = abs(VideoDriverWrapper::inst().GetMouseX() - static_cast<int>(xpos)) + abs(VideoDriverWrapper::inst().GetMouseY() - static_cast<int>(ypos));
            }

            Visibility visibility = gwv->GetVisibility(tx, ty);

            DrawBoundaryStone(x, y, tx, ty, xpos, ypos, visibility);

            /// Nur bei Sichtbaren Stellen zeichnen
            // Visible terrain
            if(visibility == VIS_VISIBLE)
            {
                ////////////////////////////////////////////////

                ///////////////////////////////////////
                // Draw objects and people

                // Draw objects - buildings, trees, stones, decoration sprites, etc.
                MapNode& mn = gwv->GetNode(tx, ty);
                if(mn.obj)
                {
                    mn.obj->Draw(static_cast<int>(xpos), static_cast<int>(ypos));
                    if (false) //TODO: military aid - display icon overlay of attack possibility
                    {
                        noBuilding* building = gwv->GetSpecObj<noBuilding>(tx, ty);
                        if (mn.owner != GAMECLIENT.GetPlayerID() + 1 //not belonging to current player
                                && gwv->GetNO(tx, ty)->GetType() == NOP_BUILDING //is a building
                                && !GameClient::inst().GetLocalPlayer()->IsAlly(building->GetPlayer())) //not an ally
                        {
                            BuildingType bt = building->GetBuildingType();
                            if ((bt >= BLD_BARRACKS && bt <= BLD_FORTRESS)
                                    || bt == BLD_HEADQUARTERS
                                    || bt == BLD_HARBORBUILDING) //is it a military building?
                            {
                                if(gwv->GetAvailableSoldiersForAttack(GAMECLIENT.GetPlayerID(), tx, ty)) //soldiers available for attack?
                                    LOADER.GetImageN("map_new", 20000)->Draw(static_cast<int>(xpos) + 1, static_cast<int>(ypos) - 5, 0, 0, 0, 0, 0, 0);;
                            }
                        }
                    }
                }


                // People
                if(mn.figures.size())
                {
                    for(list<noBase*>::iterator it = mn.figures.begin(); it.valid(); ++it)
                    {
                        // Bewegt er sich oder ist es ein Schiff?
                        if((*it)->IsMoving() || (*it)->GetGOT() == GOT_SHIP)
                            // Dann nach der gesamten Zeile zeichnen
                            between_lines.push_back(ObjectBetweenLines(*it, Point<int>(static_cast<int>(xpos), static_cast<int>(ypos))));
                        else
                            // Ansonsten jetzt schon zeichnen
                            (*it)->Draw(static_cast<int>(xpos), static_cast<int>(ypos));
                    }
                }

                ////////////////////////////////////////////////

                //Construction aid mode
                if(show_bq && gwv->GetNode(tx, ty).bq && gwv->GetNode(tx, ty).bq < 7)
                {
                    BuildingQuality bq = gwv->GetNode(tx, ty).bq;
                    glArchivItem_Bitmap* bm = LOADER.GetMapImageN(49 + bq);
                    //Draw building quality icon
                    bm->Draw(static_cast<int>(xpos), static_cast<int>(ypos), 0, 0, 0, 0, 0, 0);
                    //Show ability to construct military buildings
                    if(GameClient::inst().GetGGS().isEnabled(ADDON_MILITARY_AID))
                    {
                        if(!gwv->IsMilitaryBuildingNearNode(tx, ty, GAMECLIENT.GetPlayerID()) && (bq == BQ_HUT || bq == BQ_HOUSE || bq == BQ_CASTLE || bq == BQ_HARBOR))
                            LOADER.GetImageN("map_new", 20000)->Draw(static_cast<int>(xpos) + (1), static_cast<int>(ypos) - bm->getHeight() - 5, 0, 0, 0, 0, 0, 0);
                    }
                }
            }
            // im Nebel die FOW-Objekte zeichnen
            // Fog of war
            else if(visibility == VIS_FOW)
            {
                const FOWObject* fowobj = gwv->GetYoungestFOWObject(Point<MapCoord>(tx, ty));
                if(fowobj)
                    fowobj->Draw(static_cast<int>(xpos), static_cast<int>(ypos));
            }


            if(show_coordinates)
            {
                char high[32];
                //*sprintf(high,"%d",unsigned(GetNode(tx,ty).altitude));*/
                sprintf(high, "%d;%d", tx, ty);
                //*sprintf(high,"%X",unsigned(GetNode(tx,ty))).resources;*/
                //sprintf(high,"%u",GetNode(tx,ty)).reserved;
                NormalFont->Draw(static_cast<int>(xpos), static_cast<int>(ypos), high, 0, 0xFFFFFF00);

                if(gwv->GetNode(tx, ty).reserved)
                {
                    NormalFont->Draw(static_cast<int>(xpos), static_cast<int>(ypos), "R", 0, 0xFFFF0000);
                }

            }

            if (d_active)
            {
                std::stringstream ss;
                AIPlayerJH* ai = dynamic_cast<AIPlayerJH*>(GameServer::inst().GetAIPlayer(d_player));
                if (ai)
                {
                    if (d_what == 1)
                    {
                        if(ai->GetAINode(tx, ty).bq && ai->GetAINode(tx, ty).bq  < 7)
                            LOADER.GetMapImageN(49 + ai->GetAINode(tx, ty).bq)->Draw(static_cast<int>(xpos), static_cast<int>(ypos), 0, 0, 0, 0, 0, 0);
                    }
                    else if (d_what == 2)
                    {
                        if (ai->GetAINode(tx, ty).reachable)
                            LOADER.GetImageN("io", 32)->Draw(static_cast<int>(xpos), static_cast<int>(ypos), 0, 0, 0, 0, 0, 0);
                        else
                            LOADER.GetImageN("io", 40)->Draw(static_cast<int>(xpos), static_cast<int>(ypos), 0, 0, 0, 0, 0, 0);
                    }
                    else if (d_what == 3)
                    {
                        if (ai->GetAINode(tx, ty).farmed)
                            LOADER.GetImageN("io", 32)->Draw(static_cast<int>(xpos), static_cast<int>(ypos), 0, 0, 0, 0, 0, 0);
                        else
                            LOADER.GetImageN("io", 40)->Draw(static_cast<int>(xpos), static_cast<int>(ypos), 0, 0, 0, 0, 0, 0);
                    }
                    else if (d_what > 3 && d_what < 13)
                    {
                        ss << ai->GetResMapValue(tx, ty, AIJH::Resource(d_what - 4));
                        NormalFont->Draw(static_cast<int>(xpos), static_cast<int>(ypos), ss.str().c_str(), 0, 0xFFFFFF00);
                    }
                }
            }
        }

        // Figuren zwischen den Zeilen zeichnen
        for(unsigned i = 0; i < between_lines.size(); ++i)
            between_lines[i].obj->Draw(between_lines[i].pos.x, between_lines[i].pos.y);
    }

    // Names & Productivity overlay
    if(show_names || show_productivity)
    {
        for(int x = fx; x < lx; ++x)
        {
            for(int y = fy; y < ly; ++y)
            {
                // Coordinate transform
                unsigned short tx, ty;
                int xo, yo;
                gwv->GetTerrainRenderer()->ConvertCoords(x, y, tx, ty, &xo, &yo);

                int xpos = (int)(gwv->GetTerrainRenderer()->GetTerrainX(tx, ty) - xoffset + xo);
                int ypos = (int)(gwv->GetTerrainRenderer()->GetTerrainY(tx, ty) - yoffset + yo);

                // Name bzw Produktivität anzeigen
                GO_Type got = gwv->GetNO(tx, ty)->GetGOT();
                if(IsBaseBuilding(got))
                {
                    noBaseBuilding* no = gwv->GetSpecObj<noBaseBuilding>(tx, ty);

                    // Is object not belonging to local player?
                    if(no->GetPlayer() != GAMECLIENT.GetPlayerID())
                        continue;

                    int py = ypos - 10;

                    // Draw object name
                    if(show_names)
                    {
                        unsigned int color = (no->GetGOT() == GOT_BUILDINGSITE) ? COLOR_GREY : COLOR_YELLOW;
                        SmallFont->Draw(xpos, py, _(BUILDING_NAMES[no->GetBuildingType()]), glArchivItem_Font::DF_CENTER | glArchivItem_Font::DF_VCENTER, color);
                        py += SmallFont->getHeight();
                    }

                    //Draw productivity/soldiers
                    if(show_productivity)
                    {
                        switch(got)
                        {
                            case GOT_BUILDINGSITE: // Is object a building construction site?
                            {
                                noBuildingSite* n = static_cast<noBuildingSite*>(no);
                                if(n)
                                {
                                    char text[256];
                                    unsigned int color = COLOR_GREY;

                                    unsigned short p = n->GetBuildProgress();
                                    snprintf(text, 256, "(%d %%)", p);
                                    SmallFont->Draw(xpos, py, text, glArchivItem_Font::DF_CENTER | glArchivItem_Font::DF_VCENTER, color);
                                }
                            }
                            break;

                            case GOT_NOB_USUAL: // Is it a normal building or shipyard?
                            case GOT_NOB_SHIPYARD:
                            {
                                nobUsual* n = dynamic_cast<nobUsual*>(no);
                                if(n)
                                {
                                    char text[256];
                                    unsigned int color = COLOR_RED;

                                    if(!n->HasWorker())
                                        snprintf(text, 256, "%s", _("(House unoccupied)"));
                                    else if(n->IsProductionDisabledVirtual())
                                        snprintf(text, 256, "%s", _("(stopped)"));
                                    else
                                    {
                                        // Catapult and Lookout tower doesn't have productivity!
                                        if(n->GetBuildingType() == BLD_CATAPULT || n->GetBuildingType() == BLD_LOOKOUTTOWER)
                                            text[0] = 0;
                                        else
                                        {
                                            unsigned short p = *n->GetProduktivityPointer();
                                            snprintf(text, 256, "(%d %%)", p);
                                            if(p >= 60)
                                                color = 0xFF00E000;
                                            else if(p >= 30)
                                                color = 0xFFFFFF00;
                                            else if(p >= 20)
                                                color = 0xFFFF8000;
                                        }
                                    }
                                    SmallFont->Draw(xpos, py, text, glArchivItem_Font::DF_CENTER | glArchivItem_Font::DF_VCENTER, color);
                                }
                            }
                            break;

                            case GOT_NOB_MILITARY: // Is it a military building?
                            {
                                // Display amount of soldiers
                                unsigned soldiers_count = static_cast<nobMilitary*>(no)->GetTroopsCount();
                                char str[64];
                                if(soldiers_count == 1)
                                    strcpy(str, _("(1 soldier)"));
                                else
                                    sprintf(str, _("(%d soldiers)"), soldiers_count);


                                SmallFont->Draw(xpos, py, str, glArchivItem_Font::DF_CENTER | glArchivItem_Font::DF_VCENTER,
                                                (soldiers_count > 0) ? COLOR_YELLOW : COLOR_RED);
                                py += SmallFont->getHeight();
                            }
                            break;

                            default:
                                break;
                        }
                    }
                }
            }
        }
    }

    // GUI-Symbole auf der Map zeichnen

    // Falls im Straßenbaumodus: Punkte um den aktuellen Straßenbaupunkt herum ermitteln
    unsigned short road_points[6 * 2];

    if(rb.mode)
    {
        for(unsigned i = 0; i < 6; ++i)
        {
            road_points[i * 2] = gwv->GetXA(rb.point_x, rb.point_y, i);
            road_points[i * 2 + 1] = gwv->GetYA(rb.point_x, rb.point_y, i);
        }
    }

    for(int x = fx; x < lx; ++x)
    {
        for(int y = fy; y < ly; ++y)
        {
            // Coordinates transform
            unsigned short tx, ty;
            int xo, yo;
            gwv->GetTerrainRenderer()->ConvertCoords(x, y, tx, ty, &xo, &yo);

            int xpos = (int)(gwv->GetTerrainRenderer()->GetTerrainX(tx, ty) - xoffset + xo);
            int ypos = (int)(gwv->GetTerrainRenderer()->GetTerrainY(tx, ty) - yoffset + yo);

            /// Current point indicated by Mouse
            if(selx == tx && sely == ty)
            {
                // Mauszeiger am boten
                unsigned mid = 22;
                switch(gwv->GetNode(tx, ty).bq)
                {
                    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;
                }

                if(rb.mode)
                    mid = 22;

                LOADER.GetMapImageN(mid)->Draw(xpos, ypos, 0, 0, 0, 0, 0, 0);
            }

            // Currently selected point
            if(draw_selected && selected_x == tx && selected_y == ty)
                LOADER.GetMapImageN(20)->Draw(xpos, ypos, 0, 0, 0, 0, 0, 0);

            // Wegbauzeug
            if(rb.mode)
            {
                if(rb.point_x == tx && rb.point_y == ty)
                    LOADER.GetMapImageN(21)->Draw(xpos, ypos, 0, 0, 0, 0, 0, 0);



                int altitude = gwv->GetNode(rb.point_x, rb.point_y).altitude;

                const unsigned char waterway_lengthes[] = {3, 5, 9, 13, 21, 0}; // these are written into dskGameInterface.cpp, too
                const unsigned char index = GameClient::inst().GetGGS().getSelection(ADDON_MAX_WATERWAY_LENGTH);
                assert(index <= sizeof(waterway_lengthes) - 1);
                const unsigned char max_length = waterway_lengthes[index];

                for(unsigned i = 0; i < 6; ++i)
                {
                    if(road_points[i * 2] == tx  && road_points[i * 2 + 1] == ty)
                    {
                        // test on maximal water way length
                        if(rb.mode != RM_BOAT || rb.route.size() < max_length || max_length == 0 )
                        {
                            if( ( (gwv->RoadAvailable(rb.mode == RM_BOAT, tx, ty, i)
                                    && gwv->GetNode(tx, ty).owner - 1 == (signed)GAMECLIENT.GetPlayerID())
                                    || (gwv->GetNode(tx, ty).bq == BQ_FLAG) )
                                    && gwv->IsPlayerTerritory(tx, ty) )
                            {
                                unsigned short id = 60;
                                switch(int(gwv->GetNode(tx, ty).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;
                                }

                                LOADER.GetMapImageN(id)->Draw(xpos, ypos, 0, 0, 0, 0, 0, 0);
                            }

                            if(gwv->GetNO(tx, ty))
                            {
                                // Flaggenanschluss? --> extra zeichnen
                                if(gwv->GetNO(tx, ty)->GetType() == NOP_FLAG && !(tx == rb.start_x && ty == rb.start_y))
                                    LOADER.GetMapImageN(20)->Draw(xpos, ypos, 0, 0, 0, 0, 0, 0);
                            }
                        }

                        if(rb.route.size())
                        {
                            if(unsigned(rb.route.back() + 3) % 6 == i)
                                LOADER.GetMapImageN(67)->Draw(xpos, ypos, 0, 0, 0, 0, 0, 0);
                        }
                    }
                }
            }
        }
    }

    // Umherfliegende Katapultsteine zeichnen
    for(std::list<CatapultStone*>::iterator it = gwv->catapult_stones.begin(); it != gwv->catapult_stones.end(); ++it)
        (*it)->Draw(*this, xoffset, yoffset);

    glTranslatef((GLfloat) - this->x, (GLfloat) - this->y, 0.0f);

    glScissor(0, 0, VideoDriverWrapper::inst().GetScreenWidth(), VideoDriverWrapper::inst().GetScreenWidth());

    SoundManager::inst().PlayBirdSounds(noTree::QueryDrawCounter());
}