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