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 "../audio/audio.h"
23 #include "../collisions.h"
24 #include "../custom_actions.h"
25 #include "../entity.h"
26 #include "../graphics/animation.h"
27 #include "../hud.h"
28 #include "../system/error.h"
29 #include "../system/properties.h"
30 #include "../system/random.h"
31 #include "item.h"
32 
33 extern Entity *self;
34 
35 static void touch(Entity *);
36 static void entityWait(void);
37 static void init(void);
38 static void die(void);
39 static void takeDamage(Entity *, int);
40 
addLavaDoor(int x,int y,char * name)41 Entity *addLavaDoor(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 Lava Door");
48 	}
49 
50 	loadProperties(name, e);
51 
52 	e->x = x;
53 	e->y = y;
54 
55 	e->draw = &drawLoopingAnimationToMap;
56 	e->touch = &touch;
57 	e->takeDamage = &takeDamage;
58 	e->action = &init;
59 
60 	setEntityAnimation(e, "STAND");
61 
62 	return e;
63 }
64 
init()65 static void init()
66 {
67 	setEntityAnimationByID(self, self->health);
68 
69 	self->action = &entityWait;
70 }
71 
entityWait()72 static void entityWait()
73 {
74 	self->thinkTime--;
75 
76 	if (self->thinkTime <= 0)
77 	{
78 		self->health--;
79 
80 		if (self->health <= 0)
81 		{
82 			self->health = 0;
83 		}
84 
85 		self->thinkTime = 600;
86 
87 		setEntityAnimationByID(self, self->health);
88 	}
89 
90 	checkToMap(self);
91 }
92 
touch(Entity * other)93 static void touch(Entity *other)
94 {
95 	if (other->type == PROJECTILE && other->element == FIRE)
96 	{
97 		self->health++;
98 
99 		if (self->health == 7)
100 		{
101 			setInfoBoxMessage(120, 255, 255, 255, _("One blow from the pickaxe should shatter it"));
102 		}
103 
104 		else if (self->health > 7)
105 		{
106 			self->health = 7;
107 		}
108 
109 		setEntityAnimationByID(self, self->health);
110 
111 		self->thinkTime = 600;
112 
113 		other->inUse = FALSE;
114 	}
115 
116 	else if (((other->flags & ATTACKING) || other->type == PROJECTILE) && !(self->flags & INVULNERABLE))
117 	{
118 		takeDamage(other, other->damage);
119 	}
120 
121 	else
122 	{
123 		pushEntity(other);
124 	}
125 }
126 
takeDamage(Entity * other,int damage)127 static void takeDamage(Entity *other, int damage)
128 {
129 	Entity *temp;
130 
131 	if (self->health < 7)
132 	{
133 		setCustomAction(self, &invulnerableNoFlash, HIT_INVULNERABLE_TIME, 0, 0);
134 
135 		playSoundToMap("sound/common/dink", -1, self->x, self->y, 0);
136 
137 		if (other->reactToBlock != NULL)
138 		{
139 			temp = self;
140 
141 			self = other;
142 
143 			self->reactToBlock(temp);
144 
145 			self = temp;
146 		}
147 
148 		if (other->type != PROJECTILE && prand() % 10 == 0)
149 		{
150 			setInfoBoxMessage(60, 255, 255, 255, _("This weapon is not having any effect..."));
151 		}
152 
153 		damage = 0;
154 	}
155 
156 	else if (strcmpignorecase(other->name, "weapon/pickaxe") == 0)
157 	{
158 		self->action = &die;
159 	}
160 }
161 
die()162 static void die()
163 {
164 	int i;
165 	Entity *e;
166 
167 	playSoundToMap("sound/common/shatter", -1, self->x, self->y, 0);
168 
169 	for (i=0;i<7;i++)
170 	{
171 		e = addTemporaryItem("item/lava_door_piece", self->x, self->y, RIGHT, 0, 0);
172 
173 		e->x += self->w / 2 - e->w / 2;
174 		e->y += self->h / 2 - e->h / 2;
175 
176 		e->dirX = (prand() % 10) * (prand() % 2 == 0 ? -1 : 1);
177 		e->dirY = ITEM_JUMP_HEIGHT + (prand() % ITEM_JUMP_HEIGHT);
178 
179 		setEntityAnimationByID(e, i);
180 
181 		e->thinkTime = 60 + (prand() % 60);
182 	}
183 
184 	self->inUse = FALSE;
185 }
186