]> git.localhorst.tv Git - l2e.git/blob - src/menu/CapsuleFeedMenu.cpp
f2631b90aecad4b40fbf6fb305a3362f2a01355c
[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 geometry::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                 GetCapsule().Feed(itemMenu.Selected());
136                 parent->Game().state->inventory.Remove(itemMenu.Selected(), 1);
137                 LoadInventory();
138         } else {
139                 // beep
140         }
141 }
142
143
144 void CapsuleFeedMenu::UpdateWorld(float deltaT) {
145
146 }
147
148 void CapsuleFeedMenu::Render(SDL_Surface *screen) {
149         const Font &font(*parent->Res().statusFont);
150         const Vector<int> offset((screen->w - Width()) / 2, (screen->h - Height()) / 2);
151         const Vector<int> nameOffset(
152                         font.CharWidth(),
153                         2 * font.CharHeight() - font.CharHeight() / 8);
154         const Vector<int> spriteOffset(
155                                 3 * font.CharWidth() + font.CharWidth() * 3 / 4,
156                                 4 * font.CharHeight() + font.CharHeight() / 4);
157         const Vector<int> growthOffset(
158                         13 * font.CharWidth(),
159                         7 * font.CharHeight() + font.CharHeight() / 4);
160         const Vector<int> hungerOffset(
161                         13 * font.CharWidth(),
162                         9 * font.CharHeight() + font.CharHeight() / 8);
163         const Vector<int> menuOffset(
164                         font.CharWidth(),
165                         13 * font.CharHeight() + font.CharHeight() / 8);
166         const Vector<int> itemsOffset(
167                         font.CharWidth(),
168                         16 * font.CharHeight() + font.CharHeight() / 8);
169
170         parent->RenderBackground(screen);
171         RenderName(screen, offset + nameOffset);
172         RenderSprite(screen, offset + spriteOffset);
173         if (GetCapsule().IsHungry()) {
174                 RenderGrowth(screen, offset + growthOffset);
175         }
176         RenderHunger(screen, offset + hungerOffset);
177         RenderMenu(screen, offset + menuOffset);
178         RenderItems(screen, offset + itemsOffset);
179 }
180
181 void CapsuleFeedMenu::RenderName(SDL_Surface *screen, const Vector<int> &offset) const {
182         const Font &font(*parent->Res().statusFont);
183         const Vector<int> separatorOffset(5 * font.CharWidth(), 0);
184         const Vector<int> nameOffset(6 * font.CharWidth(), 0);
185
186         font.DrawString(parent->Res().capsuleNameLabel, screen, offset, 5);
187         font.DrawChar(':', screen, offset + separatorOffset);
188         font.DrawString(GetCapsule().Name(), screen, offset + nameOffset);
189 }
190
191 void CapsuleFeedMenu::RenderSprite(SDL_Surface *screen, const Vector<int> &offset) const {
192         // TODO: sitting ground
193         GetCapsule().BattleSprite()->Draw(screen, offset);
194 }
195
196 void CapsuleFeedMenu::RenderGrowth(SDL_Surface *screen, const Vector<int> &offset) const {
197         Vector<int> cursor(offset);
198         parent->Res().capsuleGrowthLabel->Draw(screen, offset);
199         cursor.X() += parent->Res().capsuleGrowthLabel->Width();
200
201         for (int i = 0; i < GetCapsule().HungerFull(); ++i) {
202                 parent->Res().capsuleGrowthBarFilled->Draw(screen, cursor);
203                 cursor.X() += parent->Res().capsuleGrowthBarFilled->Width();
204         }
205
206         for (int i = 0; i < GetCapsule().HungerEmpty(); ++i) {
207                 parent->Res().capsuleGrowthBar->Draw(screen, cursor);
208                 cursor.X() += parent->Res().capsuleGrowthBar->Width();
209         }
210 }
211
212 void CapsuleFeedMenu::RenderHunger(SDL_Surface *screen, const Vector<int> &offset) const {
213         const Font &font(*parent->Res().normalFont);
214         const Frame &frame(*parent->Res().statusFrame);
215         const Vector<int> textOffset(2 * font.CharWidth(), font.CharHeight());
216
217         frame.Draw(screen, offset, 18 * font.CharWidth(), 3 * font.CharHeight());
218         font.DrawString(parent->Res().capsuleNotHungryText, screen, offset + textOffset, 15);
219 }
220
221 void CapsuleFeedMenu::RenderMenu(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> labelOffset(2 * font.CharWidth(), font.CharHeight());
225         const Vector<int> menubgOffset(8 * font.CharWidth(), 0);
226         const Vector<int> menuOffset(11 * font.CharWidth(), font.CharHeight());
227
228         frame.Draw(screen, offset, 8 * font.CharWidth(), 3 * font.CharHeight());
229         font.DrawString(parent->Res().capsuleFeedLabel, screen, offset + labelOffset);
230         frame.Draw(screen, offset + menubgOffset, 22 * font.CharWidth(), 3 * font.CharHeight());
231         menu.Draw(screen, offset + menuOffset);
232 }
233
234 void CapsuleFeedMenu::RenderItems(SDL_Surface *screen, const Vector<int> &offset) const {
235         const Font &font(*parent->Res().normalFont);
236         const Frame &frame(*parent->Res().statusFrame);
237         const Vector<int> menuOffset(3 * font.CharWidth(), font.CharHeight() * 5 / 4);
238
239         frame.Draw(screen, offset, 30 * font.CharWidth(), 11 * font.CharHeight());
240         itemMenu.Draw(screen, offset + menuOffset);
241 }
242
243
244 int CapsuleFeedMenu::Width() const {
245         return parent->Width();
246 }
247
248 int CapsuleFeedMenu::Height() const {
249         return parent->Height();
250 }
251
252 Capsule &CapsuleFeedMenu::GetCapsule() {
253         return parent->GetCapsule();
254 }
255
256 const Capsule &CapsuleFeedMenu::GetCapsule() const {
257         return parent->GetCapsule();
258 }
259
260 }