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