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 "../collisions.h"
23 #include "../entity.h"
24 #include "../graphics/animation.h"
25 #include "../graphics/graphics.h"
26 #include "../hud.h"
27 #include "../inventory.h"
28 #include "../player.h"
29 #include "../system/error.h"
30 #include "../system/properties.h"
31 
32 extern Entity *self;
33 extern Input input;
34 
35 static void entityWait(void);
36 static void touch(Entity *);
37 static void activate(int);
38 static int energyBarDraw(void);
39 static void energyBarWait(void);
40 static void init(void);
41 static void reprogram(void);
42 
addSoulMergerControlPanel(int x,int y,char * name)43 Entity *addSoulMergerControlPanel(int x, int y, char *name)
44 {
45 	Entity *e = getFreeEntity();
46 
47 	if (e == NULL)
48 	{
49 		showErrorAndExit("No free slots to add a Soul Merger Control Panel");
50 	}
51 
52 	loadProperties(name, e);
53 
54 	e->x = x;
55 	e->y = y;
56 
57 	e->type = KEY_ITEM;
58 
59 	e->action = &init;
60 	e->touch = &touch;
61 
62 	e->draw = &drawLoopingAnimationToMap;
63 
64 	setEntityAnimation(e, "STAND");
65 
66 	return e;
67 }
68 
entityWait()69 static void entityWait()
70 {
71 	self->thinkTime--;
72 
73 	if (self->thinkTime <= 0)
74 	{
75 		self->thinkTime = 0;
76 	}
77 
78 	checkToMap(self);
79 }
80 
touch(Entity * other)81 static void touch(Entity *other)
82 {
83 	if (self->damage == 1 && self->mental == 0 && self->thinkTime == 0)
84 	{
85 		setInfoBoxMessage(0, 255, 255, 255, _("Press Action to reprogram the Soul Merger"));
86 	}
87 }
88 
activate(int val)89 static void activate(int val)
90 {
91 	if (getInventoryItemByObjectiveName("Spanner") == NULL)
92 	{
93 		setInfoBoxMessage(120, 255, 255, 255, _("Spanner is required"));
94 	}
95 
96 	else
97 	{
98 		self->action = &reprogram;
99 
100 		self->touch = NULL;
101 
102 		self->activate = NULL;
103 
104 		setPlayerLocked(TRUE);
105 	}
106 }
107 
reprogram()108 static void reprogram()
109 {
110 	Entity *temp;
111 
112 	if (input.interact == 1 || isPlayerLocked() == FALSE || self->health <= 0)
113 	{
114 		self->action = &entityWait;
115 
116 		self->activate = &activate;
117 
118 		self->touch = &touch;
119 
120 		setPlayerLocked(FALSE);
121 
122 		input.interact = 0;
123 	}
124 
125 	else
126 	{
127 		self->health--;
128 
129 		if (self->health <= 0)
130 		{
131 			self->activate = NULL;
132 
133 			self->health = 0;
134 
135 			self->mental = 1;
136 
137 			self->target->mental = 1 - self->target->mental;
138 
139 			temp = self;
140 
141 			self = self->target;
142 
143 			self->activate(-1);
144 
145 			self = temp;
146 		}
147 
148 		self->thinkTime = 5;
149 
150 		setInfoBoxMessage(0, 255, 255, 255, _("Press Action to Cancel"));
151 	}
152 }
153 
init()154 static void init()
155 {
156 	Entity *e;
157 
158 	if (self->mental == 0)
159 	{
160 		e = getFreeEntity();
161 
162 		if (e == NULL)
163 		{
164 			showErrorAndExit("No free slots to add the Soul Merger Control Panel Energy Bar");
165 		}
166 
167 		loadProperties("boss/awesome_boss_energy_bar", e);
168 
169 		e->action = &energyBarWait;
170 
171 		e->draw = &energyBarDraw;
172 
173 		e->type = ENEMY;
174 
175 		e->head = self;
176 
177 		setEntityAnimation(e, "STAND");
178 
179 		self->action = &entityWait;
180 
181 		self->target = getEntityByObjectiveName(self->requires);
182 
183 		if (self->target == NULL)
184 		{
185 			showErrorAndExit("Control Panel cannot find Soul Merger %s", self->requires);
186 		}
187 
188 		self->activate = &activate;
189 	}
190 }
191 
energyBarWait()192 static void energyBarWait()
193 {
194 	self->x = self->head->x - (self->w - self->head->w) / 2;
195 	self->y = self->head->y - self->head->h;
196 
197 	if (self->health < self->head->health)
198 	{
199 		self->health += (self->head->health / 100);
200 
201 		if (self->health > self->head->health)
202 		{
203 			self->health = self->head->health;
204 		}
205 	}
206 
207 	else if (self->head->health < self->health)
208 	{
209 		self->health -= 3;
210 
211 		if (self->health < self->head->health)
212 		{
213 			self->health = self->head->health;
214 		}
215 	}
216 }
217 
energyBarDraw()218 static int energyBarDraw()
219 {
220 	int width;
221 	float percentage;
222 
223 	if (self->head->thinkTime != 0)
224 	{
225 		drawLoopingAnimationToMap();
226 
227 		percentage = self->health;
228 		percentage /= self->head->maxHealth;
229 
230 		width = self->w - 2;
231 
232 		width *= percentage;
233 
234 		drawBoxToMap(self->x + 1, self->y + 1, width, self->h - 2, 0, 220, 0);
235 	}
236 
237 	return TRUE;
238 }
239