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