/** ** Draw the player resource in top line. ** ** @todo FIXME: make DrawResources more configurable (format, font). */ void DrawResources(void) { char tmp[128]; int totalproduction = 0; int totalrequested = 0; int i; int p = 0; for (i = 0; i < MaxCosts; ++i) { sprintf_s(tmp, sizeof(tmp), "%s:+%d-%d %d/%d", _(DefaultDisplayResourceNames[i].c_str()), ThisPlayer->ProductionRate[i], ThisPlayer->RequestedUtilizationRate[i], ThisPlayer->StoredResources[i] / CYCLES_PER_SECOND / 100, ThisPlayer->StorageCapacity[i] / CYCLES_PER_SECOND / 100); VideoDrawText(40 + 176 * i, 1, GameFont, tmp); totalproduction += ThisPlayer->ProductionRate[i]; totalrequested += ThisPlayer->RequestedUtilizationRate[i]; } if (totalproduction + totalrequested) { p = 100 - abs(totalproduction - totalrequested) * 100 / (totalproduction + totalrequested); } sprintf_s(tmp, sizeof(tmp), "%d%%", p); VideoDrawText(400, 1, GameFont, tmp); }
/** ** Draw info panel with more than one unit selected */ static void DrawInfoPanelMultipleSelected() { // Draw icons and a health bar for (int i = 0; i < std::min(NumSelected, (int)UI.SelectedButtons.size()); ++i) { CUIButton *button = &UI.SelectedButtons[i]; bool mouseOver = (ButtonAreaUnderCursor == ButtonAreaSelected && ButtonUnderCursor == i); Selected[i]->Type->Icon.Icon->DrawUnitIcon(ThisPlayer, button->Style, mouseOver ? (IconActive | (MouseButtons & LeftButton)) : 0, button->X, button->Y, ""); UiDrawLifeBar(Selected[i], button->X, button->Y); if (mouseOver) { UI.StatusLine.Set(Selected[i]->Type->Name); } } // Selected more than we can display if (NumSelected > (int)UI.SelectedButtons.size()) { std::ostringstream os; os << "+" << (unsigned)(NumSelected - UI.SelectedButtons.size()); VideoDrawText(UI.MaxSelectedTextX, UI.MaxSelectedTextY, UI.MaxSelectedFont, os.str()); } }
/** ** Draw formatted text with variable value. ** ** @param unit unit with variable to show. ** @param defaultfont default font if no specific font in extra data. ** ** @note text is limited to 256 chars. (enough?) ** @note text must have exactly 2 %d. ** @bug if text format is incorrect. */ void CContentTypeFormattedText2::Draw(const CUnit *unit, CFont *defaultfont) const { CFont *font; char buf[256]; UStrInt usi1, usi2; Assert(unit); font = this->Font ? this->Font : defaultfont; Assert(font); usi1 = GetComponent(unit, this->Index1, this->Component1, 0); usi2 = GetComponent(unit, this->Index2, this->Component2, 0); if (usi1.type == USTRINT_STR) { if (usi2.type == USTRINT_STR) { sprintf(buf, this->Format, usi1.s, usi2.s); } else { sprintf(buf, this->Format, usi1.s, usi2.i); } } else { if (usi2.type == USTRINT_STR) { sprintf(buf, this->Format, usi1.i, usi2.s); } else { sprintf(buf, this->Format, usi1.i, usi2.i); } } if (this->Centered) { VideoDrawTextCentered(this->PosX, this->PosY, font, buf); } else { VideoDrawText(this->PosX, this->PosY, font, buf); } }
/** ** Draw number with font at x,y unclipped. ** ** @param x X screen position ** @param y Y screen position ** @param font Font number ** @param number Number to be displayed. ** ** @return The length of the printed text. */ int VideoDrawNumber(int x, int y, CFont *font, int number) { char buf[sizeof(int) * 10 + 2]; FormatNumber(number, buf); return VideoDrawText(x, y, font, buf); }
/** ** Draw text with font at x,y centered. ** ** @see DoDrawText for full description. ** ** @param x X screen position ** @param y Y screen position ** @param font Font number ** @param text Text to be displayed. ** ** @return The length of the printed text. */ int VideoDrawTextCentered(int x, int y, CFont *font, const std::string &text) { int dx; dx = font->Width(text); VideoDrawText(x - dx / 2, y, font, text); return dx / 2; }
/** ** Draw info panel with no units selected */ static void DrawInfoPanelNoneSelected() { // Check if a unit is under the cursor if (UnitUnderCursor && UnitUnderCursor->IsVisible(ThisPlayer)) { DrawUnitInfo(UnitUnderCursor); return; } std::string nc; std::string rc; int x = UI.InfoPanel.X + 16; int y = UI.InfoPanel.Y + 8; VideoDrawText(x, y, GameFont, "Bos Wars"); y += 16; VideoDrawText(x, y, GameFont, "Cycle:"); VideoDrawNumber(x + 48, y, GameFont, GameCycle); VideoDrawNumber(x + 110, y, GameFont, CYCLES_PER_SECOND * VideoSyncSpeed / 100); y += 20; GetDefaultTextColors(nc, rc); for (int i = 0; i < PlayerMax - 1; ++i) { if (Players[i].Type != PlayerNobody) { if (ThisPlayer->Allied & (1 << Players[i].Index)) { SetDefaultTextColors(FontGreen, rc); } else if (ThisPlayer->Enemy & (1 << Players[i].Index)) { SetDefaultTextColors(FontRed, rc); } else { SetDefaultTextColors(nc, rc); } VideoDrawNumber(x + 15, y, GameFont, i); Video.DrawRectangle(ColorWhite,x, y, 12, 12); Video.FillRectangle(Players[i].Color, x + 1, y + 1, 10, 10); VideoDrawText(x + 27, y, GameFont,Players[i].Name); VideoDrawNumber(x + 117, y, GameFont,Players[i].Score); y += 14; } } SetDefaultTextColors(nc, rc); }
/** ** Draw reverse text with font at x,y unclipped. ** ** @see DoDrawText for full description. ** ** @param x X screen position ** @param y Y screen position ** @param font Font number ** @param text Text to be displayed. ** ** @return The length of the printed text. */ int VideoDrawReverseText(int x, int y, CFont *font, const std::string &text) { int width; FontColor = ReverseTextColor; width = VideoDrawText(x, y, font, text); FontColor = DefaultTextColor; return width; }
/** ** Draw text with font at x,y centered. ** ** @see VideoDrawText for full description. ** ** @param x X screen position ** @param y Y screen position ** @param font Font number ** @param text Text to be displayed. ** ** @return The length of the printed text. */ global int VideoDrawTextCentered(int x,int y,unsigned font, const unsigned char* text) { int dx; dx=VideoTextLength(font,text); VideoDrawText(x-dx/2,y,font,text); return dx/2; }
/** ** Draw reverse text with font at x,y unclipped. ** ** @see VideoDrawText for full description. ** ** @param x X screen position ** @param y Y screen position ** @param font Font number ** @param text Text to be displayed. ** ** @return The length of the printed text. */ global int VideoDrawReverseText(int x,int y,unsigned font, const unsigned char* text) { int w; TextColor=ReverseTextColor; w=VideoDrawText(x,y,font,text); TextColor=DefaultTextColor; return w; }
/** ** Draw the stat for an unit in top-panel. ** ** @param x Screen X position ** @param y Screen Y position ** @param modified The modified stat value ** @param original The original stat value */ local void DrawStats(int x,int y,int modified,int original) { char buf[64]; if( modified==original ) { VideoDrawNumber(x,y,GameFont,modified); } else { sprintf(buf,"%d~<+%d~>",original,modified-original); VideoDrawText(x,y,GameFont,buf); } }
/** ** Check video interrupt. ** ** Display and count too slow frames. */ global void CheckVideoInterrupts(void) { if( VideoInterrupts ) { //DebugLevel1("Slow frame\n"); IfDebug( if (InterfaceState == IfaceStateNormal) { VideoDrawText(TheUI.MapX+10,TheUI.MapY+10,GameFont,"SLOW FRAME!!"); } ); ++SlowFrameCounter; }
/** ** Draw completed bar into top-panel. ** ** @param full the 100% value ** @param ready how much till now completed */ local void UiDrawCompleted(int full,int ready) { int f; if( !full ) { return; } f=(100*ready)/full; f=(f*152)/100; VideoFillRectangleClip(TheUI.CompleteBarColor ,TheUI.CompleteBarX,TheUI.CompleteBarY,f,14); VideoDrawText(TheUI.CompleteTextX,TheUI.CompleteTextY,GameFont,"% Complete"); }
/** ** Draw number with font at x,y unclipped. ** ** @param x X screen position ** @param y Y screen position ** @param font Font number ** @param number Number to be displayed. ** ** @return The length of the printed text. */ global int VideoDrawNumber(int x, int y, unsigned font, int number) { char bufs[sizeof(int) * 10 + 2]; char bufd[sizeof(int) * 10 + 2]; int sl; int s; int d; sl = s = d = 0; sprintf(bufs, "%d", number); sl = strlen(bufs); do { if (s > 0 && s < sl && (s - (sl % 3)) % 3 == 0) { bufd[d++] = ','; } bufd[d++] = bufs[s++]; } while (s <= sl); return VideoDrawText(x, y, font, bufd); }
/** ** Draw the timer ** ** @todo FIXME : make DrawTimer more configurable (Pos, format). */ void DrawTimer(void) { if (!GameTimer.Init) { return; } int sec = GameTimer.Cycles / CYCLES_PER_SECOND % 60; int min = (GameTimer.Cycles / CYCLES_PER_SECOND / 60) % 60; int hour = (GameTimer.Cycles / CYCLES_PER_SECOND / 3600); char buf[30]; if (hour) { sprintf(buf, "%d:%02d:%02d", hour, min, sec); } else { sprintf(buf, "%d:%02d", min, sec); } VideoDrawText(UI.Timer.X, UI.Timer.Y, UI.Timer.Font, buf); }
/** ** Draw unit stats */ static void DrawUnitStats(const CUnit *unit) { int x = UI.InfoPanel.X; int y = UI.InfoPanel.Y; CUnitType *type = unit->Type; // Armor std::ostringstream armor; armor << _("Armor: ") << type->Variable[ARMOR_INDEX].Value; VideoDrawText(x + 16, y + 83, GameFont, armor.str()); if (type->Variable[RADAR_INDEX].Value) { // Radar Range std::ostringstream radarRange; radarRange << _("Radar Range: ") << type->Variable[RADAR_INDEX].Value; VideoDrawText(x + 16, y + 97, GameFont, radarRange.str()); } else { // Sight Range std::ostringstream sightRange; sightRange << _("Sight Range: ") << type->Variable[SIGHTRANGE_INDEX].Value; VideoDrawText(x + 16, y + 97, GameFont, sightRange.str()); } if (type->CanAttack) { // Kills std::ostringstream kills; kills << _("Kills: ") << "~<" << unit->Variable[KILL_INDEX].Value << "~>"; VideoDrawTextCentered(x + 114, y + 52, GameFont, kills.str()); // Attack Range std::ostringstream attackRange; attackRange << _("Attack Range: ") << type->Variable[ATTACKRANGE_INDEX].Value; VideoDrawText(x + 16, y + 111, GameFont, attackRange.str()); // Damage int min_damage = std::max(1, type->Variable[PIERCINGDAMAGE_INDEX].Value / 2); int max_damage = type->Variable[PIERCINGDAMAGE_INDEX].Value + type->Variable[BASICDAMAGE_INDEX].Value; std::ostringstream damage; damage << _("Damage: ") << min_damage << "-" << max_damage; VideoDrawText(x + 16, y + 125, GameFont, damage.str()); } else if (unit->Variable[MANA_INDEX].Max != 0) { // Mana std::ostringstream mana; mana << _("Mana: ") << unit->Variable[MANA_INDEX].Value; VideoDrawText(x + 16, y + 111, GameFont, mana.str()); } }
/** ** Draw the player resource in top line. ** ** @todo FIXME : make DrawResources more configurable (format, font). */ void DrawResources(void) { char tmp[128]; int i; int v; // Draw all icons of resource. for (i = 0; i <= ScoreCost; ++i) { if (UI.Resources[i].G) { UI.Resources[i].G->DrawFrameClip(UI.Resources[i].IconFrame, UI.Resources[i].IconX, UI.Resources[i].IconY); } } for (i = 0; i < MaxCosts; ++i) { if (UI.Resources[i].TextX != -1) { v = ThisPlayer->Resources[i]; VideoDrawNumber(UI.Resources[i].TextX, UI.Resources[i].TextY + (v > 99999) * 3, v > 99999 ? SmallFont : GameFont, v); } } if (UI.Resources[FoodCost].TextX != -1) { sprintf(tmp, "%d/%d", ThisPlayer->Demand, ThisPlayer->Supply); if (ThisPlayer->Supply < ThisPlayer->Demand) { VideoDrawReverseText(UI.Resources[FoodCost].TextX, UI.Resources[FoodCost].TextY, GameFont, tmp); } else { VideoDrawText(UI.Resources[FoodCost].TextX, UI.Resources[FoodCost].TextY, GameFont, tmp); } } if (UI.Resources[ScoreCost].TextX != -1) { v = ThisPlayer->Score; VideoDrawNumber(UI.Resources[ScoreCost].TextX, UI.Resources[ScoreCost].TextY + (v > 99999) * 3, v > 99999 ? SmallFont : GameFont, v); } }
/** ** Draw training units */ static void DrawTrainingUnits(const CUnit *unit) { if (unit->OrderCount == 1 || unit->Orders[1]->Action != UnitActionTrain) { if (!UI.SingleTrainingText.empty()) { VideoDrawText(UI.SingleTrainingTextX, UI.SingleTrainingTextY, UI.SingleTrainingFont, UI.SingleTrainingText); } if (UI.SingleTrainingButton) { CUIButton *button = UI.SingleTrainingButton; bool mouseOver = (ButtonAreaUnderCursor == ButtonAreaTraining && ButtonUnderCursor == 0); unit->Orders[0]->Type->Icon.Icon->DrawUnitIcon(unit->Player, button->Style, mouseOver ? (IconActive | (MouseButtons & LeftButton)) : 0, button->X, button->Y, ""); } } else { if (!UI.TrainingText.empty()) { VideoDrawTextCentered(UI.TrainingTextX, UI.TrainingTextY, UI.TrainingFont, UI.TrainingText); } if (!UI.TrainingButtons.empty()) { size_t currentButton = 0; for (int i = 0; i < unit->OrderCount; ++i) { if (unit->Orders[i]->Action == UnitActionTrain && currentButton < UI.TrainingButtons.size()) { CUIButton *button = &UI.TrainingButtons[i]; bool mouseOver = (ButtonAreaUnderCursor == ButtonAreaTraining && ButtonUnderCursor == i); unit->Orders[i]->Type->Icon.Icon->DrawUnitIcon(unit->Player, button->Style, mouseOver ? (IconActive | (MouseButtons & LeftButton)) : 0, button->X, button->Y, ""); currentButton++; } } } } }
/** ** Draw formatted text with variable value. ** ** @param unit unit with variable to show. ** @param defaultfont default font if no specific font in extra data. ** ** @note text is limited to 256 chars. (enough?) ** @note text must have exactly 1 %d. ** @bug if text format is incorrect. */ void CContentTypeFormattedText::Draw(const CUnit *unit, CFont *defaultfont) const { CFont *font; char buf[256]; UStrInt usi1; Assert(unit); font = this->Font ? this->Font : defaultfont; Assert(font); Assert(0 <= this->Index && this->Index < UnitTypeVar.NumberVariable); usi1 = GetComponent(unit, this->Index, this->Component, 0); if (usi1.type == USTRINT_STR) { sprintf(buf, this->Format, usi1.s); } else { sprintf(buf, this->Format, usi1.i); } if (this->Centered) { VideoDrawTextCentered(this->PosX, this->PosY, font, buf); } else { VideoDrawText(this->PosX, this->PosY, font, buf); } }
/** ** Draw the unit info into top-panel. ** ** @param unit Pointer to unit. */ static void DrawUnitInfo(CUnit *unit) { int i; CUnitType *type; const CUnitStats *stats; int x; int y; CUnit *uins; Assert(unit); UpdateUnitVariables(unit); for (i = 0; i < (int)UI.InfoPanelContents.size(); ++i) { if (CanShowContent(UI.InfoPanelContents[i]->Condition, unit)) { for (std::vector<CContentType *>::const_iterator content = UI.InfoPanelContents[i]->Contents.begin(); content != UI.InfoPanelContents[i]->Contents.end(); ++content) { if (CanShowContent((*content)->Condition, unit)) { (*content)->Draw(unit, UI.InfoPanelContents[i]->DefaultFont); } } } } type = unit->Type; stats = unit->Stats; Assert(type); Assert(stats); // Draw IconUnit #ifdef USE_MNG if (type->Portrait.Num) { type->Portrait.Mngs[type->Portrait.CurrMng]->Draw( UI.SingleSelectedButton->X, UI.SingleSelectedButton->Y); if (type->Portrait.Mngs[type->Portrait.CurrMng]->iteration == type->Portrait.NumIterations) { type->Portrait.Mngs[type->Portrait.CurrMng]->Reset(); // FIXME: should be configurable if (type->Portrait.CurrMng == 0) { type->Portrait.CurrMng = (SyncRand() % (type->Portrait.Num - 1)) + 1; type->Portrait.NumIterations = 1; } else { type->Portrait.CurrMng = 0; type->Portrait.NumIterations = SyncRand() % 16 + 1; } } } else #endif if (UI.SingleSelectedButton) { x = UI.SingleSelectedButton->X; y = UI.SingleSelectedButton->Y; type->Icon.Icon->DrawUnitIcon(unit->Player, UI.SingleSelectedButton->Style, (ButtonAreaUnderCursor == ButtonAreaSelected && ButtonUnderCursor == 0) ? (IconActive | (MouseButtons & LeftButton)) : 0, x, y, ""); } x = UI.InfoPanel.X; y = UI.InfoPanel.Y; // // Show progress if they are selected. // if (NumSelected == 1 && Selected[0] == unit) { // // Building training units. // if (unit->Orders[0]->Action == UnitActionTrain) { if (unit->OrderCount == 1 || unit->Orders[1]->Action != UnitActionTrain) { if (!UI.SingleTrainingText.empty()) { VideoDrawText(UI.SingleTrainingTextX, UI.SingleTrainingTextY, UI.SingleTrainingFont, UI.SingleTrainingText); } if (UI.SingleTrainingButton) { unit->Orders[0]->Type->Icon.Icon->DrawUnitIcon(unit->Player, UI.SingleTrainingButton->Style, (ButtonAreaUnderCursor == ButtonAreaTraining && ButtonUnderCursor == 0) ? (IconActive | (MouseButtons & LeftButton)) : 0, UI.SingleTrainingButton->X, UI.SingleTrainingButton->Y, ""); } } else { if (!UI.TrainingText.empty()) { VideoDrawTextCentered(UI.TrainingTextX, UI.TrainingTextY, UI.TrainingFont, UI.TrainingText); } if (!UI.TrainingButtons.empty()) { for (i = 0; i < unit->OrderCount && i < (int)UI.TrainingButtons.size(); ++i) { if (unit->Orders[i]->Action == UnitActionTrain) { unit->Orders[i]->Type->Icon.Icon->DrawUnitIcon(unit->Player, UI.TrainingButtons[i].Style, (ButtonAreaUnderCursor == ButtonAreaTraining && ButtonUnderCursor == i) ? (IconActive | (MouseButtons & LeftButton)) : 0, UI.TrainingButtons[i].X, UI.TrainingButtons[i].Y, ""); } } } } return; } // // Building upgrading to better type. // if (unit->Orders[0]->Action == UnitActionUpgradeTo) { if (UI.UpgradingButton) { unit->Orders[0]->Type->Icon.Icon->DrawUnitIcon(unit->Player, UI.UpgradingButton->Style, (ButtonAreaUnderCursor == ButtonAreaUpgrading && ButtonUnderCursor == 0) ? (IconActive | (MouseButtons & LeftButton)) : 0, UI.UpgradingButton->X, UI.UpgradingButton->Y, ""); } return; } // // Building research new technology. // if (unit->Orders[0]->Action == UnitActionResearch) { if (UI.ResearchingButton) { unit->Data.Research.Upgrade->Icon->DrawUnitIcon(unit->Player, UI.ResearchingButton->Style, (ButtonAreaUnderCursor == ButtonAreaResearching && ButtonUnderCursor == 0) ? (IconActive | (MouseButtons & LeftButton)) : 0, UI.ResearchingButton->X, UI.ResearchingButton->Y, ""); } return; } } // // Transporting units. // if (type->CanTransport && unit->BoardCount) { int j; uins = unit->UnitInside; for (i = j = 0; i < unit->InsideCount; ++i, uins = uins->NextContained) { if (uins->Boarded && j < (int)UI.TransportingButtons.size()) { uins->Type->Icon.Icon->DrawUnitIcon(unit->Player, UI.TransportingButtons[j].Style, (ButtonAreaUnderCursor == ButtonAreaTransporting && ButtonUnderCursor == j) ? (IconActive | (MouseButtons & LeftButton)) : 0, UI.TransportingButtons[j].X, UI.TransportingButtons[j].Y, ""); UiDrawLifeBar(uins, UI.TransportingButtons[j].X, UI.TransportingButtons[j].Y); if (uins->Type->CanCastSpell && uins->Variable[MANA_INDEX].Max) { UiDrawManaBar(uins, UI.TransportingButtons[j].X, UI.TransportingButtons[j].Y); } if (ButtonAreaUnderCursor == ButtonAreaTransporting && ButtonUnderCursor == j) { UI.StatusLine.Set(uins->Type->Name); } ++j; } } return; } }
/** ** Draw menu button 'button' on x,y ** ** @param style Button style ** @param flags State of Button (clicked, mouse over...) ** @param x X display position ** @param y Y display position ** @param text text to print on button */ void DrawMenuButton(ButtonStyle *style, unsigned flags, int x, int y, const std::string &text) { std::string *nc; std::string *rc; std::string oldnc; std::string oldrc; ButtonStyleProperties *p; ButtonStyleProperties *pimage; if (flags & MI_FLAGS_CLICKED) { p = &style->Clicked; } else if (flags & MI_FLAGS_ACTIVE) { p = &style->Hover; } else { p = &style->Default; } // // Image // pimage = p; if (!p->Sprite) { // No image. Try hover, selected, then default if ((flags & MI_FLAGS_ACTIVE) && style->Hover.Sprite) { pimage = &style->Hover; } else if (style->Default.Sprite) { pimage = &style->Default; } } if (pimage->Sprite) { pimage->Sprite->Load(); } if (pimage->Sprite) { pimage->Sprite->DrawFrame(pimage->Frame, x, y); } // // Text // if (!text.empty()) { GetDefaultTextColors(oldnc, oldrc); nc = !p->TextNormalColor.empty() ? &p->TextNormalColor : !style->TextNormalColor.empty() ? &style->TextNormalColor : &oldnc; rc = !p->TextReverseColor.empty() ? &p->TextReverseColor : !style->TextReverseColor.empty() ? &style->TextReverseColor : &oldrc; SetDefaultTextColors(*nc, *rc); if (p->TextAlign == TextAlignCenter || p->TextAlign == TextAlignUndefined) { VideoDrawTextCentered(x + p->TextX, y + p->TextY, style->Font, text); } else if (p->TextAlign == TextAlignLeft) { VideoDrawText(x + p->TextX, y + p->TextY, style->Font, text); } else { VideoDrawText(x + p->TextX - style->Font->Width(text), y + p->TextY, style->Font, text); } SetDefaultTextColors(oldnc, oldrc); } // // Border // if (!p->BorderColor) { p->BorderColor = Video.MapRGB(TheScreen->format, p->BorderColorRGB.r, p->BorderColorRGB.g, p->BorderColorRGB.b); } if (p->BorderSize) { for (int i = 0; i < p->BorderSize; ++i) { Video.DrawRectangleClip(p->BorderColor, x - i, y - i, style->Width + 2 * i, style->Height + 2 * i); } } }
/** ** Draw text with variable. ** ** @param unit unit with variable to show. ** @param defaultfont default font if no specific font in extra data. */ void CContentTypeText::Draw(const CUnit *unit, CFont *defaultfont) const { char *text; // Optional text to display. CFont *font; // Font to use. int x; // X coordinate to display. int y; // Y coordinate to display. x = this->PosX; y = this->PosY; font = this->Font ? this->Font : defaultfont; Assert(font); Assert(unit || this->Index == -1); Assert(this->Index == -1 || (0 <= this->Index && this->Index < UnitTypeVar.NumberVariable)); if (this->Text) { text = EvalString(this->Text); if (this->Centered) { VideoDrawTextCentered(x, y, font, text); } else { VideoDrawText(x, y, font, text); } x += font->Width(text); delete[] text; } if (this->ShowName) { VideoDrawTextCentered(x, y, font, unit->Type->Name); return; } if (this->Index != -1) { if (!this->Stat) { EnumVariable component = this->Component; switch (component) { case VariableValue: case VariableMax: case VariableIncrease: case VariableDiff: case VariablePercent: VideoDrawNumber(x, y, font, GetComponent(unit, this->Index, component, 0).i); break; case VariableName: VideoDrawText(x, y, font, GetComponent(unit, this->Index, component, 0).s); break; default: Assert(0); } } else { int value = unit->Type->Variable[this->Index].Value; int diff = unit->Stats->Variables[this->Index].Value - value; if (!diff) { VideoDrawNumber(x, y, font, value); } else { char buf[64]; sprintf(buf, diff > 0 ? "%d~<+%d~>" : "%d~<-%d~>", value, diff); VideoDrawText(x, y, font, buf); } } } }
/** ** Draw info panel. ** ** Panel: ** neutral - neutral or opponent ** normal - not 1,3,4 ** magic unit - magic units ** construction - under construction */ void CInfoPanel::Draw(void) { int i; if (NumSelected) { if (NumSelected > 1) { // // If there are more units selected draw their pictures and a health bar // DrawInfoPanelBackground(0); for (i = 0; i < (NumSelected > (int)UI.SelectedButtons.size() ? (int)UI.SelectedButtons.size() : NumSelected); ++i) { Selected[i]->Type->Icon.Icon->DrawUnitIcon(ThisPlayer, UI.SelectedButtons[i].Style, (ButtonAreaUnderCursor == ButtonAreaSelected && ButtonUnderCursor == i) ? (IconActive | (MouseButtons & LeftButton)) : 0, UI.SelectedButtons[i].X, UI.SelectedButtons[i].Y, ""); UiDrawLifeBar(Selected[i], UI.SelectedButtons[i].X, UI.SelectedButtons[i].Y); if (ButtonAreaUnderCursor == ButtonAreaSelected && ButtonUnderCursor == i) { UI.StatusLine.Set(Selected[i]->Type->Name); } } if (NumSelected > (int)UI.SelectedButtons.size()) { char buf[5]; sprintf(buf, "+%u", static_cast<unsigned int> (NumSelected - UI.SelectedButtons.size())); VideoDrawText(UI.MaxSelectedTextX, UI.MaxSelectedTextY, UI.MaxSelectedFont, buf); } return; } else { // FIXME: not correct for enemy's units if (Selected[0]->Player == ThisPlayer || ThisPlayer->IsTeamed(Selected[0]) || ThisPlayer->IsAllied(Selected[0]) || ReplayRevealMap) { if (Selected[0]->Orders[0]->Action == UnitActionBuilt || Selected[0]->Orders[0]->Action == UnitActionResearch || Selected[0]->Orders[0]->Action == UnitActionUpgradeTo || Selected[0]->Orders[0]->Action == UnitActionTrain) { i = 3; } else if (Selected[0]->Stats->Variables[MANA_INDEX].Max) { i = 2; } else { i = 1; } } else { i = 0; } DrawInfoPanelBackground(i); DrawUnitInfo(Selected[0]); if (ButtonAreaUnderCursor == ButtonAreaSelected && ButtonUnderCursor == 0) { UI.StatusLine.Set(Selected[0]->Type->Name); } return; } } // Nothing selected DrawInfoPanelBackground(0); if (UnitUnderCursor && UnitUnderCursor->IsVisible(ThisPlayer)) { // FIXME: not correct for enemies units DrawUnitInfo(UnitUnderCursor); } else { int x; int y; std::string nc; std::string rc; // FIXME: need some cool ideas for this. x = UI.InfoPanel.X + 16; y = UI.InfoPanel.Y + 8; VideoDrawText(x, y, GameFont, "Stratagus"); y += 16; VideoDrawText(x, y, GameFont, "Cycle:"); VideoDrawNumber(x + 48, y, GameFont, GameCycle); VideoDrawNumber(x + 110, y, GameFont, CYCLES_PER_SECOND * VideoSyncSpeed / 100); y += 20; GetDefaultTextColors(nc, rc); for (i = 0; i < PlayerMax - 1; ++i) { if (Players[i].Type != PlayerNobody) { if (ThisPlayer->Allied & (1 << Players[i].Index)) { SetDefaultTextColors(FontGreen, rc); } else if (ThisPlayer->Enemy & (1 << Players[i].Index)) { SetDefaultTextColors(FontRed, rc); } else { SetDefaultTextColors(nc, rc); } VideoDrawNumber(x + 15, y, GameFont, i); Video.DrawRectangle(ColorWhite,x, y, 12, 12); Video.FillRectangle(Players[i].Color, x + 1, y + 1, 10, 10); VideoDrawText(x + 27, y, GameFont,Players[i].Name); VideoDrawNumber(x + 117, y, GameFont,Players[i].Score); y += 14; } } SetDefaultTextColors(nc, rc); } }