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 "../entity.h"
25 #include "../graphics/animation.h"
26 #include "../system/error.h"
27 #include "../system/properties.h"
28 
29 extern Entity *self;
30 
31 static void move(void);
32 static void moveReckless(void);
33 static void creditsMove(void);
34 static void die(void);
35 
addGrub(int x,int y,char * name)36 Entity *addGrub(int x, int y, char *name)
37 {
38 	Entity *e = getFreeEntity();
39 
40 	if (e == NULL)
41 	{
42 		showErrorAndExit("No free slots to add a Grub");
43 	}
44 
45 	loadProperties(name, e);
46 
47 	e->x = x;
48 	e->y = y;
49 
50 	e->action = &move;
51 
52 	e->draw = &drawLoopingAnimationToMap;
53 	e->touch = &entityTouch;
54 	e->die = ¨
55 	e->takeDamage = &entityTakeDamageFlinch;
56 	e->reactToBlock = &changeDirection;
57 
58 	e->creditsAction = &creditsMove;
59 
60 	e->type = ENEMY;
61 
62 	setEntityAnimation(e, "STAND");
63 
64 	return e;
65 }
66 
die()67 static void die()
68 {
69 	playSoundToMap("sound/enemy/grub/grub_die", -1, self->x, self->y, 0);
70 
71 	entityDie();
72 }
73 
move()74 static void move()
75 {
76 	moveLeftToRight();
77 
78 	if (onSingleTile(self) == TRUE)
79 	{
80 		self->action = &moveReckless;
81 	}
82 }
83 
moveReckless()84 static void moveReckless()
85 {
86 	long onGround = self->flags & ON_GROUND;
87 
88 	if (self->dirX == 0)
89 	{
90 		self->x += self->face == LEFT ? self->box.x : -self->box.x;
91 
92 		self->face = self->face == RIGHT ? LEFT : RIGHT;
93 	}
94 
95 	if (self->standingOn == NULL || self->standingOn->dirX == 0)
96 	{
97 		self->dirX = (self->face == RIGHT ? self->speed : -self->speed);
98 	}
99 
100 	else
101 	{
102 		self->dirX += (self->face == RIGHT ? self->speed : -self->speed);
103 	}
104 
105 	checkToMap(self);
106 
107 	if (self->dirX == 0)
108 	{
109 		self->dirX = (self->face == RIGHT ? -self->speed : self->speed);
110 
111 		self->face = (self->face == RIGHT ? LEFT : RIGHT);
112 	}
113 
114 	if ((self->flags & ON_GROUND) || self->standingOn != NULL)
115 	{
116 		if (landedOnGround(onGround) == TRUE)
117 		{
118 			self->action = &move;
119 		}
120 	}
121 }
122 
creditsMove()123 static void creditsMove()
124 {
125 	self->thinkTime++;
126 
127 	if (self->thinkTime > 400)
128 	{
129 		self->mental = 1;
130 	}
131 
132 	setEntityAnimation(self, "STAND");
133 
134 	self->dirX = self->speed;
135 
136 	checkToMap(self);
137 
138 	if (self->dirX == 0)
139 	{
140 		self->inUse = FALSE;
141 	}
142 }
143