1 /*
2 Copyright (C) 2009-2021 Parallel Realities
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18 */
19
20 #include "../headers.h"
21
22 #include "../custom_actions.h"
23 #include "../entity.h"
24 #include "../graphics/animation.h"
25 #include "../hud.h"
26 #include "../inventory.h"
27 #include "../item/item.h"
28 #include "../item/key_items.h"
29 #include "../player.h"
30 #include "../system/error.h"
31 #include "../system/properties.h"
32
33 extern Entity *self, player;
34 extern Game game;
35
36 static void useHealthPotion(int);
37 static void useSlimePotion(int);
38 static void useInvisibilityPotion(int);
39 static void useFlamingArrowPotion(int);
40
addHealthPotion(int x,int y,char * name)41 Entity *addHealthPotion(int x, int y, char *name)
42 {
43 Entity *e = getFreeEntity();
44
45 if (e == NULL)
46 {
47 showErrorAndExit("No free slots to add a Health Potion");
48 }
49
50 loadProperties(name, e);
51
52 e->x = x;
53 e->y = y;
54
55 e->thinkTime = 0;
56 e->type = KEY_ITEM;
57
58 e->face = RIGHT;
59
60 e->action = &doNothing;
61 e->touch = &keyItemTouch;
62 e->draw = &drawLoopingAnimationToMap;
63 e->activate = &useHealthPotion;
64
65 setEntityAnimation(e, "STAND");
66
67 return e;
68 }
69
useHealthPotion(int val)70 static void useHealthPotion(int val)
71 {
72 if (player.health != player.maxHealth)
73 {
74 if (game.status == IN_INVENTORY)
75 {
76 setInventoryDialogMessage(_("Used %s"), _(self->objectiveName));
77 }
78
79 player.health += 5;
80
81 if (player.health > player.maxHealth)
82 {
83 player.health = player.maxHealth;
84 }
85
86 self->health--;
87
88 if (self->health <= 0)
89 {
90 self->inUse = FALSE;
91 }
92 }
93 }
94
addSlimePotion(int x,int y,char * name)95 Entity *addSlimePotion(int x, int y, char *name)
96 {
97 Entity *e = getFreeEntity();
98
99 if (e == NULL)
100 {
101 showErrorAndExit("No free slots to add a Slime Potion");
102 }
103
104 loadProperties(name, e);
105
106 e->x = x;
107 e->y = y;
108
109 e->thinkTime = 0;
110 e->type = KEY_ITEM;
111
112 e->face = RIGHT;
113
114 e->action = &doNothing;
115 e->touch = &keyItemTouch;
116 e->draw = &drawLoopingAnimationToMap;
117 e->activate = &useSlimePotion;
118
119 setEntityAnimation(e, "STAND");
120
121 return e;
122 }
123
useSlimePotion(int val)124 static void useSlimePotion(int val)
125 {
126 if (game.status == IN_GAME)
127 {
128 becomeJumpingSlime(self->health);
129
130 if (player.element == WATER)
131 {
132 loadProperties("item/empty_potion", self);
133
134 self->activate = NULL;
135
136 self->health = 0;
137 }
138 }
139 }
140
addInvisibilityPotion(int x,int y,char * name)141 Entity *addInvisibilityPotion(int x, int y, char *name)
142 {
143 Entity *e = getFreeEntity();
144
145 if (e == NULL)
146 {
147 showErrorAndExit("No free slots to add an Invisibility Potion");
148 }
149
150 loadProperties(name, e);
151
152 e->x = x;
153 e->y = y;
154
155 e->thinkTime = 0;
156 e->type = KEY_ITEM;
157
158 e->face = RIGHT;
159
160 e->action = &doNothing;
161 e->touch = &keyItemTouch;
162 e->draw = &drawLoopingAnimationToMap;
163 e->activate = &useInvisibilityPotion;
164
165 setEntityAnimation(e, "STAND");
166
167 return e;
168 }
169
useInvisibilityPotion(int val)170 static void useInvisibilityPotion(int val)
171 {
172 if (game.status == IN_GAME && player.element != WATER)
173 {
174 setCustomAction(&player, &invisible, 60 * 5, 0, 0);
175 }
176 }
177
addFlamingArrowPotion(int x,int y,char * name)178 Entity *addFlamingArrowPotion(int x, int y, char *name)
179 {
180 Entity *e = getFreeEntity();
181
182 if (e == NULL)
183 {
184 showErrorAndExit("No free slots to add a Flaming Arrow Potion");
185 }
186
187 loadProperties(name, e);
188
189 e->x = x;
190 e->y = y;
191
192 e->thinkTime = 0;
193 e->type = KEY_ITEM;
194
195 e->face = RIGHT;
196
197 e->action = &doNothing;
198 e->touch = &keyItemTouch;
199 e->draw = &drawLoopingAnimationToMap;
200 e->activate = &useFlamingArrowPotion;
201
202 setEntityAnimation(e, "STAND");
203
204 return e;
205 }
206
useFlamingArrowPotion(int val)207 static void useFlamingArrowPotion(int val)
208 {
209 int addNew, maxArrows;
210 Entity *arrow, *fireArrow;
211
212 arrow = getInventoryItemByName("weapon/normal_arrow");
213
214 if (arrow == NULL)
215 {
216 if (game.status == IN_INVENTORY)
217 {
218 setInventoryDialogMessage(_("Normal Arrow is required"));
219 }
220
221 else
222 {
223 setInfoBoxMessage(60, 255, 255, 255, _("Normal Arrow is required"));
224 }
225
226 return;
227 }
228
229 addNew = FALSE;
230
231 fireArrow = getInventoryItemByName("weapon/flaming_arrow");
232
233 if (fireArrow == NULL)
234 {
235 addNew = TRUE;
236
237 fireArrow = addPermanentItem("weapon/flaming_arrow", 0, 0);
238
239 fireArrow->health = 0;
240 }
241
242 maxArrows = MAX_STACKABLES - fireArrow->health;
243
244 maxArrows = arrow->health > maxArrows ? maxArrows : arrow->health;
245
246 fireArrow->health += maxArrows;
247
248 arrow->health -= maxArrows;
249
250 if (game.status == IN_INVENTORY)
251 {
252 setInventoryDialogMessage(_("Created %d Flaming Arrows"), maxArrows);
253 }
254
255 else
256 {
257 setInfoBoxMessage(60, 255, 255, 255, _("Created %d Flaming Arrows"), maxArrows);
258 }
259
260 if (arrow->health <= 0)
261 {
262 removeInventoryItemByName("weapon/normal_arrow");
263 }
264
265 if (addNew == TRUE)
266 {
267 addToInventory(fireArrow);
268 }
269 }
270