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