]> git.localhorst.tv Git - l2e.git/blob - src/menu/CapsuleFeedMenu.cpp
07808f65b49b8f9a34b031eb07ad6ad777cc6ab4
[l2e.git] / src / menu / CapsuleFeedMenu.cpp
1 #include "CapsuleFeedMenu.h"
2
3 #include "CapsuleMenu.h"
4 #include "Resources.h"
5 #include "../app/Application.h"
6 #include "../app/Input.h"
7 #include "../common/Inventory.h"
8 #include "../common/Item.h"
9 #include "../common/GameConfig.h"
10 #include "../common/GameState.h"
11 #include "../graphics/Font.h"
12 #include "../graphics/Frame.h"
13 #include "../math/Vector.h"
14
15 using app::Input;
16 using common::Capsule;
17 using common::Inventory;
18 using common::Item;
19 using math::Vector;
20 using graphics::Font;
21 using graphics::Frame;
22
23 namespace menu {
24
25 CapsuleFeedMenu::CapsuleFeedMenu(CapsuleMenu *parent)
26 : parent(parent)
27 , menu(*parent->Res().capsuleFeedMenuProperties)
28 , itemMenu(*parent->Res().inventoryMenuProperties) {
29         menu.Add(parent->Res().itemMenuSelectText, CHOICE_SELECT);
30         menu.Add(parent->Res().itemMenuSortText, CHOICE_SORT);
31         LoadInventory();
32 }
33
34
35 void CapsuleFeedMenu::OnEnterState(SDL_Surface *) {
36         menu.SetSelected();
37         itemMenu.SetActive();
38 }
39
40 void CapsuleFeedMenu::LoadInventory() {
41         const Inventory &inv(parent->Game().state->inventory);
42         itemMenu.Clear();
43         itemMenu.Reserve(inv.MaxItems());
44         for (int i(0); i < inv.MaxItems(); ++i) {
45                 const Item *item(inv.ItemAt(i));
46                 if (item) {
47                         // TODO: find out which items are impossible to feed to a capsule
48                         itemMenu.Add(item->Name(), item, true, item->MenuIcon(), inv.ItemCountAt(i));
49                 } else {
50                         itemMenu.AddEmptyEntry();
51                 }
52         }
53 }
54
55 void CapsuleFeedMenu::OnExitState(SDL_Surface *) {
56
57 }
58
59 void CapsuleFeedMenu::OnResumeState(SDL_Surface *) {
60
61 }
62
63 void CapsuleFeedMenu::OnPauseState(SDL_Surface *) {
64
65 }
66
67
68 void CapsuleFeedMenu::OnResize(int width, int height) {
69
70 }
71
72
73 void CapsuleFeedMenu::HandleEvents(const Input &input) {
74         if (menu.IsActive()) {
75                 if (input.JustPressed(Input::PAD_LEFT)) {
76                         menu.PreviousItem();
77                 }
78                 if (input.JustPressed(Input::PAD_RIGHT)) {
79                         menu.NextItem();
80                 }
81         } else {
82                 if (input.JustPressed(Input::PAD_UP)) {
83                         itemMenu.PreviousItem();
84                 }
85                 if (input.JustPressed(Input::PAD_DOWN)) {
86                         itemMenu.NextItem();
87                 }
88         }
89
90         if (input.JustPressed(Input::ACTION_A)) {
91                 if (menu.IsActive()) {
92                         if (menu.Selected() == CHOICE_SORT) {
93                                 parent->Game().state->inventory.Sort();
94                                 LoadInventory();
95                         } else {
96                                 menu.SetSelected();
97                                 itemMenu.SetActive();
98                         }
99                 } else if (itemMenu.IsActive()) {
100                         itemMenu.SetDualSelection();
101                 } else if (itemMenu.SelectedIndex() == itemMenu.SecondaryIndex()) {
102                         switch (menu.Selected()) {
103                                 case CHOICE_SELECT:
104                                         FeedSelected();
105                                         itemMenu.SetActive();
106                                         break;
107                                 case CHOICE_SORT:
108                                         // invalid state, recover
109                                         menu.SetActive();
110                                         itemMenu.SetInactive();
111                                         break;
112                         }
113                 } else {
114                         parent->Game().state->inventory.SwapEntriesAt(
115                                         itemMenu.SelectedIndex(),
116                                         itemMenu.SecondaryIndex());
117                         itemMenu.SwapSelected();
118                         itemMenu.SetActive();
119                 }
120         }
121         if (input.JustPressed(Input::ACTION_B)) {
122                 if (menu.IsActive()) {
123                         Ctrl().PopState();
124                 } else if (itemMenu.IsActive()) {
125                         menu.SetActive();
126                         itemMenu.SetInactive();
127                 } else {
128                         itemMenu.SetActive();
129                 }
130         }
131 }
132
133 void CapsuleFeedMenu::FeedSelected() {
134         if (itemMenu.Selected()) {
135                 // TODO: feed and grow animations
136                 if (GetCapsule().IsHungry()) {
137                         GetCapsule().Feed(itemMenu.Selected());
138                         parent->Game().state->inventory.Remove(itemMenu.Selected(), 1);
139                         LoadInventory();
140                 } else if (itemMenu.Selected() == GetCapsule().UpgradeItem()) {
141                         GetCapsule().UpgradeSpecial();
142                         parent->Game().state->inventory.Remove(itemMenu.Selected(), 1);
143                         LoadInventory();
144                 } else {
145                         // error beep
146                 }
147         } else {
148                 // also beep
149         }
150 }
151
152
153 void CapsuleFeedMenu::UpdateWorld(Uint32 deltaT) {
154
155 }
156
157 void CapsuleFeedMenu::Render(SDL_Surface *screen) {
158         const Font &font(*parent->Res().statusFont);
159         const Vector<int> offset((screen->w - Width()) / 2, (screen->h - Height()) / 2);
160         const Vector<int> nameOffset(
161                         font.CharWidth(),
162                         2 * font.CharHeight() - font.CharHeight() / 8);
163         const Vector<int> spriteOffset(
164                                 3 * font.CharWidth() + font.CharWidth() * 3 / 4,
165                                 4 * font.CharHeight() + font.CharHeight() / 4);
166         const Vector<int> growthOffset(
167                         13 * font.CharWidth(),
168                         7 * font.CharHeight() + font.CharHeight() / 4);
169         const Vector<int> hungerOffset(
170                         13 * font.CharWidth(),
171                         9 * font.CharHeight() + font.CharHeight() / 8);
172         const Vector<int> menuOffset(
173                         font.CharWidth(),
174                         13 * font.CharHeight() + font.CharHeight() / 8);
175         const Vector<int> itemsOffset(
176                         font.CharWidth(),
177                         16 * font.CharHeight() + font.CharHeight() / 8);
178
179         parent->RenderBackground(screen);
180         RenderName(screen, offset + nameOffset);
181         RenderSprite(screen, offset + spriteOffset);
182         if (GetCapsule().IsHungry()) {
183                 RenderGrowth(screen, offset + growthOffset);
184         }
185         RenderHunger(screen, offset + hungerOffset);
186         RenderMenu(screen, offset + menuOffset);
187         RenderItems(screen, offset + itemsOffset);
188 }
189
190 void CapsuleFeedMenu::RenderName(SDL_Surface *screen, const Vector<int> &offset) const {
191         const Font &font(*parent->Res().statusFont);
192         const Vector<int> separatorOffset(5 * font.CharWidth(), 0);
193         const Vector<int> nameOffset(6 * font.CharWidth(), 0);
194
195         font.DrawString(parent->Res().capsuleNameLabel, screen, offset, 5);
196         font.DrawChar(':', screen, offset + separatorOffset);
197         font.DrawString(GetCapsule().Name(), screen, offset + nameOffset);
198 }
199
200 void CapsuleFeedMenu::RenderSprite(SDL_Surface *screen, const Vector<int> &offset) const {
201         // TODO: sitting ground
202         GetCapsule().BattleSprite()->Draw(screen, offset);
203 }
204
205 void CapsuleFeedMenu::RenderGrowth(SDL_Surface *screen, const Vector<int> &offset) const {
206         Vector<int> cursor(offset);
207         parent->Res().capsuleGrowthLabel->Draw(screen, offset);
208         cursor.X() += parent->Res().capsuleGrowthLabel->Width();
209
210         for (int i = 0; i < GetCapsule().HungerFull(); ++i) {
211                 parent->Res().capsuleGrowthBarFilled->Draw(screen, cursor);
212                 cursor.X() += parent->Res().capsuleGrowthBarFilled->Width();
213         }
214
215         for (int i = 0; i < GetCapsule().HungerEmpty(); ++i) {
216                 parent->Res().capsuleGrowthBar->Draw(screen, cursor);
217                 cursor.X() += parent->Res().capsuleGrowthBar->Width();
218         }
219 }
220
221 void CapsuleFeedMenu::RenderHunger(SDL_Surface *screen, const Vector<int> &offset) const {
222         const Font &font(*parent->Res().normalFont);
223         const Frame &frame(*parent->Res().statusFrame);
224         const Vector<int> textOffset(2 * font.CharWidth(), font.CharHeight());
225
226         frame.Draw(screen, offset, 18 * font.CharWidth(), 3 * font.CharHeight());
227         font.DrawString(parent->Res().capsuleNotHungryText, screen, offset + textOffset, 15);
228 }
229
230 void CapsuleFeedMenu::RenderMenu(SDL_Surface *screen, const Vector<int> &offset) const {
231         const Font &font(*parent->Res().normalFont);
232         const Frame &frame(*parent->Res().statusFrame);
233         const Vector<int> labelOffset(2 * font.CharWidth(), font.CharHeight());
234         const Vector<int> menubgOffset(8 * font.CharWidth(), 0);
235         const Vector<int> menuOffset(11 * font.CharWidth(), font.CharHeight());
236
237         frame.Draw(screen, offset, 8 * font.CharWidth(), 3 * font.CharHeight());
238         font.DrawString(parent->Res().capsuleFeedLabel, screen, offset + labelOffset);
239         frame.Draw(screen, offset + menubgOffset, 22 * font.CharWidth(), 3 * font.CharHeight());
240         menu.Draw(screen, offset + menuOffset);
241 }
242
243 void CapsuleFeedMenu::RenderItems(SDL_Surface *screen, const Vector<int> &offset) const {
244         const Font &font(*parent->Res().normalFont);
245         const Frame &frame(*parent->Res().statusFrame);
246         const Vector<int> menuOffset(3 * font.CharWidth(), font.CharHeight() * 5 / 4);
247
248         frame.Draw(screen, offset, 30 * font.CharWidth(), 11 * font.CharHeight());
249         itemMenu.Draw(screen, offset + menuOffset);
250 }
251
252
253 int CapsuleFeedMenu::Width() const {
254         return parent->Width();
255 }
256
257 int CapsuleFeedMenu::Height() const {
258         return parent->Height();
259 }
260
261 Capsule &CapsuleFeedMenu::GetCapsule() {
262         return parent->GetCapsule();
263 }
264
265 const Capsule &CapsuleFeedMenu::GetCapsule() const {
266         return parent->GetCapsule();
267 }
268
269 }