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