menuResources.heroCursor = &heroCursor;
menuResources.heroCursorBlinkTime = 532;
+ menuResources.noEquipmentText = "No equip";
+
+ graphics::Sprite shoulderNav(IMG_Load("test-data/shoulder-nav.png"), 160, 16);
+ menuResources.shoulderNav = &shoulderNav;
+
InitScreen screen(width, height);
app::State *state(0);
int HeroStatus::Width() const {
- return hero->BattleSprite()->Width() + res->statusFont->CharWidth() * 10;
+ return hero->BattleSprite()->Width() + res->statusFont->CharWidth() * 11;
}
int HeroStatus::Height() const {
- return hero->BattleSprite()->Height();
+ return hero->BattleSprite()->Height() + res->statusFont->CharWidth();
}
void HeroStatus::Render(SDL_Surface *screen, const Vector<int> &offset) const {
if (!hero) return;
- hero->BattleSprite()->Draw(screen, position + offset, 0, 0);
+ hero->BattleSprite()->Draw(screen, offset, 0, 0);
// for some reason, fonts are shifted by one pixel in the original
Vector<int> nameOffset(
hero->BattleSprite()->Width(),
res->statusFont->CharHeight() * 7 / 8);
- nameOffset += position + offset;
+ nameOffset += offset;
res->statusFont->DrawString(hero->Name(), screen, nameOffset, 5);
Vector<int> levelLabelOffset(nameOffset.X() + 6 * res->statusFont->CharWidth(), nameOffset.Y());
public:
void SetResources(const Resources *r) { res = r; }
void SetHero(const common::Hero *h) { hero = h; }
- void SetPosition(const geometry::Vector<int> &p) { position = p; }
int Width() const;
int Height() const;
geometry::Vector<int> Size() const { return geometry::Vector<int>(Width(), Height()); }
- const geometry::Vector<int> &Position() const { return position; }
void Render(SDL_Surface *screen, const geometry::Vector<int> &offset) const;
private:
const Resources *res;
const common::Hero *hero;
- geometry::Vector<int> position;
};
status[i].SetHero(game->state->party[i]);
status[i].SetResources(game->menuResources);
}
- status[1].SetPosition(Vector<int>(status[0].Width() + Res().normalFont->CharWidth(), 0));
- status[2].SetPosition(Vector<int>(0, status[0].Height() + Res().normalFont->CharHeight()));
- status[3].SetPosition(Vector<int>(status[0].Width() + Res().normalFont->CharWidth(), status[0].Height() + Res().normalFont->CharHeight()));
+ statusPositions[0] = Vector<int>(0, 0);
+ statusPositions[1] = Vector<int>(status[0].Width(), 0);
+ statusPositions[2] = Vector<int>(0, status[0].Height());
+ statusPositions[3] = Vector<int>(status[0].Width(), status[0].Height());
mainMenu.Add(Res().mainMenuItemText, 0);
mainMenu.Add(Res().mainMenuStatusText, 4);
}
void PartyMenu::Render(SDL_Surface *screen) {
+ Vector<int> offset((screen->w - Width()) / 2, (screen->h - Height()) / 2);
+
RenderBackground(screen);
- RenderHeros(screen, StatusOffset());
- RenderMenu(screen, Vector<int>(8 * Res().normalFont->CharWidth(), 13 * Res().normalFont->CharHeight() + Res().normalFont->CharHeight() / 8));
- RenderInfo(screen, Vector<int>(14 * Res().normalFont->CharWidth(), 21 * Res().normalFont->CharHeight() + Res().normalFont->CharHeight() / 8));
+ RenderHeros(screen, offset);
+ RenderMenu(screen, offset + Vector<int>(8 * Res().normalFont->CharWidth(), 13 * Res().normalFont->CharHeight() + Res().normalFont->CharHeight() / 8));
+ RenderInfo(screen, offset + Vector<int>(14 * Res().normalFont->CharWidth(), 21 * Res().normalFont->CharHeight() + Res().normalFont->CharHeight() / 8));
+}
+
+int PartyMenu::Width() const {
+ return 2 * (status[0].Width() + Res().normalFont->CharWidth());
}
-Vector<int> PartyMenu::StatusOffset() const {
- return Vector<int>(Res().normalFont->CharWidth(), 2 * Res().normalFont->CharHeight());
+int PartyMenu::Height() const {
+ return 2 * Res().normalFont->CharHeight()
+ + 2 * status[0].Height()
+ + Res().normalFont->CharHeight()
+ + 8 * Res().normalFont->CharHeight()
+ + 5 * Res().normalFont->CharHeight()
+ + 2 * Res().normalFont->CharHeight();
}
void PartyMenu::RenderBackground(SDL_Surface *screen) const {
void PartyMenu::RenderHeros(SDL_Surface *screen, const Vector<int> &offset) const {
for (int i(0); i < 4; ++i) {
- status[i].Render(screen, offset);
+ status[i].Render(screen, offset + StatusOffset(i));
}
}
+Vector<int> PartyMenu::StatusOffset(int index) const {
+ return statusPositions[index] + Vector<int>(Res().normalFont->CharWidth(), 2 * Res().normalFont->CharHeight());
+}
+
void PartyMenu::RenderMenu(SDL_Surface *screen, const Vector<int> &offset) const {
Vector<int> menuOffset(3 * Res().normalFont->CharWidth(), Res().normalFont->CharHeight() + Res().normalFont->CharHeight() / 4);
}
void PartyMenu::OnStatusSelect(PartyMenu *self, int index) {
- self->Ctrl().ChangeState(new StatusMenu(self));
+ self->Ctrl().ChangeState(new StatusMenu(self, index));
}
}
Resources &Res();
const Resources &Res() const;
+ int Width() const;
+ int Height() const;
+
public:
void RenderBackground(SDL_Surface *screen) const;
void RenderHeros(SDL_Surface *screen, const geometry::Vector<int> &offset) const;
void RenderMenu(SDL_Surface *screen, const geometry::Vector<int> &offset) const;
void RenderInfo(SDL_Surface *screen, const geometry::Vector<int> &offset) const;
- geometry::Vector<int> StatusOffset() const;
+ geometry::Vector<int> StatusOffset(int index) const;
const HeroStatus &GetHeroStatus(int index) const { return status[index]; }
static void OnStatusSelect(PartyMenu *, int);
private:
HeroStatus status[4];
+ geometry::Vector<int> statusPositions[4];
common::GameConfig *game;
graphics::Menu<int> mainMenu;
, mainMenuGoldText(0)
, heroCursor(0)
-, heroCursorBlinkTime(0) {
+, heroCursorBlinkTime(0)
+
+, noEquipmentText(0)
+
+, shoulderNav(0) {
}
graphics::Sprite *heroCursor;
int heroCursorBlinkTime;
+ const char *noEquipmentText;
+
+ graphics::Sprite *shoulderNav;
+
Resources();
};
}
void SelectHero::RenderCursor(SDL_Surface *screen) const {
- const HeroStatus &status(parent->GetHeroStatus(cursor));
Vector<int> position(
0, Game().state->party[cursor]->BattleSprite()->Height());
- position += status.Position() + parent->StatusOffset();
+ position += parent->StatusOffset(cursor);
Res().heroCursor->Draw(screen, position);
}
#include "StatusMenu.h"
+#include "HeroStatus.h"
#include "PartyMenu.h"
+#include "Resources.h"
#include "../app/Application.h"
#include "../app/Input.h"
+#include "../common/GameConfig.h"
+#include "../common/GameState.h"
+#include "../common/Hero.h"
+#include "../common/Item.h"
+#include "../graphics/Font.h"
using app::Input;
+using common::Hero;
+using common::Item;
+using geometry::Vector;
+using graphics::Font;
namespace menu {
-StatusMenu::StatusMenu(PartyMenu *parent)
-: parent(parent) {
+StatusMenu::StatusMenu(PartyMenu *parent, int cursor)
+: parent(parent)
+, cursor(cursor) {
}
if (input.JustPressed(Input::ACTION_B)) {
Ctrl().PopState();
}
+
+ if (input.JustPressed(Input::SHOULDER_RIGHT)) {
+ NextHero();
+ }
+ if (input.JustPressed(Input::SHOULDER_LEFT)) {
+ PreviousHero();
+ }
}
void StatusMenu::UpdateWorld(float deltaT) {
}
void StatusMenu::Render(SDL_Surface *screen) {
+ Vector<int> offset((screen->w - Width()) / 2, (screen->h - Height()) / 2);
+ Vector<int> shoulderNavOffset(
+ 5 * parent->Res().statusFont->CharWidth(),
+ parent->Res().statusFont->CharHeight());
+ Vector<int> statsOffset(
+ 17 * parent->Res().statusFont->CharWidth(),
+ 4 * parent->Res().statusFont->CharHeight() - parent->Res().statusFont->CharHeight() / 8);
+
parent->RenderBackground(screen);
+ parent->Res().shoulderNav->Draw(screen, offset + shoulderNavOffset);
+ RenderStatus(screen, offset + parent->StatusOffset(0));
+ RenderEquipment(screen, offset + statsOffset);
+}
+
+int StatusMenu::Width() const {
+ return parent->Width();
+}
+
+int StatusMenu::Height() const {
+ return parent->Height();
+}
+
+void StatusMenu::RenderStatus(SDL_Surface *screen, const Vector<int> &offset) const {
+ parent->GetHeroStatus(cursor).Render(screen, offset);
+}
+
+void StatusMenu::RenderEquipment(SDL_Surface *screen, const geometry::Vector<int> &offset) const {
+ const Hero &hero(*parent->Game().state->party[cursor]);
+ Vector<int> lineBreak(0, 2 * parent->Res().statusFont->CharHeight());
+
+ Vector<int> position(offset);
+ RenderEquipmentLine(hero.Weapon(), screen, position);
+
+ position += lineBreak;
+ RenderEquipmentLine(hero.Armor(), screen, position);
+
+ position += lineBreak;
+ RenderEquipmentLine(hero.Shield(), screen, position);
+
+ position += lineBreak;
+ RenderEquipmentLine(hero.Helmet(), screen, position);
+
+ position += lineBreak;
+ RenderEquipmentLine(hero.Ring(), screen, position);
+
+ position += lineBreak;
+ RenderEquipmentLine(hero.Jewel(), screen, position);
+}
+
+void StatusMenu::RenderEquipmentLine(const Item *item, SDL_Surface *screen, const Vector<int> &position) const {
+ const Font &font(*parent->Res().statusFont);
+ const Vector<int> textOffset(font.CharWidth(), 0);
+ if (item) {
+ if (item->MenuIcon()) {
+ item->MenuIcon()->Draw(screen, position);
+ }
+ font.DrawString(item->Name(), screen, position + textOffset);
+ } else {
+ font.DrawString(parent->Res().noEquipmentText, screen, position + textOffset);
+ }
+}
+
+
+void StatusMenu::NextHero() {
+ cursor = (cursor + 1) % parent->Game().state->partySize;
+}
+
+void StatusMenu::PreviousHero() {
+ cursor = (cursor + parent->Game().state->partySize - 1) % parent->Game().state->partySize;
}
}
#include "fwd.h"
#include "../app/State.h"
+#include "../common/fwd.h"
+#include "../geometry/Vector.h"
namespace menu {
: public app::State {
public:
- explicit StatusMenu(PartyMenu *parent);
+ StatusMenu(PartyMenu *parent, int heroIndex);
public:
virtual void HandleEvents(const app::Input &);
virtual void UpdateWorld(float deltaT);
virtual void Render(SDL_Surface *);
+public:
+ int Width() const;
+ int Height() const;
+
private:
virtual void OnEnterState(SDL_Surface *screen);
virtual void OnExitState(SDL_Surface *screen);
virtual void OnResize(int width, int height);
+ void NextHero();
+ void PreviousHero();
+
+ void RenderStatus(SDL_Surface *screen, const geometry::Vector<int> &offset) const;
+ void RenderEquipment(SDL_Surface *screen, const geometry::Vector<int> &offset) const;
+ void RenderEquipmentLine(const common::Item *, SDL_Surface *screen, const geometry::Vector<int> &position) const;
+
private:
PartyMenu *parent;
+ int cursor;
};