summaryrefslogtreecommitdiff
path: root/noncore/games/kpacman/monster.cpp
Unidiff
Diffstat (limited to 'noncore/games/kpacman/monster.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/games/kpacman/monster.cpp262
1 files changed, 262 insertions, 0 deletions
diff --git a/noncore/games/kpacman/monster.cpp b/noncore/games/kpacman/monster.cpp
new file mode 100644
index 0000000..2f402b4
--- a/dev/null
+++ b/noncore/games/kpacman/monster.cpp
@@ -0,0 +1,262 @@
1#include "monster.h"
2#include "board.h"
3
4Monster::Monster(Board *b, int mid)
5{
6 board = b;
7 ID = mid;
8
9 setREM(0);
10 setHarmless(0, 0, 0);
11 setArrested(0, 0);
12 setFreedom(board->position(prisonexit));
13 if (mid == 0)
14 setPrison(board->position(prisonentry));
15 else
16 setPrison(board->position(monsterhome, mid));
17
18 actualPosition = lastPosition = OUT;
19 feetPosition = 0;
20 IQ = 0;
21 maxBodyPixmaps = 0;
22 maxEyesPixmaps = 0;
23}
24
25void Monster::setMaxPixmaps(int maxBody, int maxEyes)
26{
27 if (feetPosition >= (maxBody/10))
28 feetPosition = 0;
29 maxBodyPixmaps = maxBody;
30 maxEyesPixmaps = maxEyes;
31}
32
33void Monster::setArrested(int ticks, int duration)
34{
35 actualState = dangerous;
36 pauseDuration = ticks;
37 pause = 0;
38 arrestDuration = arrestLeft = duration;
39 arrestPause = ticks;
40 harmlessLeft = 0;
41}
42
43void Monster::setDangerous(int ticks, int iq)
44{
45 actualState = dangerous;
46 pauseDuration = ticks;
47 pause = 0;
48 dangerousPause = ticks;
49 harmlessLeft = 0;
50 IQ = iq;
51}
52
53void Monster::setHarmless(int ticks, int hDuration, int wDuration)
54{
55 actualState = harmless;
56 pauseDuration = ticks;
57 pause = 0;
58 harmlessDuration = harmlessLeft = hDuration;
59 warningDuration = wDuration;
60}
61
62void Monster::setREM(int ticks)
63{
64 actualState = rem;
65 pauseDuration = ticks;
66 pause = 0;
67}
68
69void Monster::setPosition(int pos)
70{
71 board->reset(lastPosition, monster, ID); // reset old position on the board
72 actualPosition = lastPosition = pos; // set position of monster
73 board->set(actualPosition, monster, ID);
74 feetPosition = 0;
75}
76
77void Monster::setPrison(int pos)
78{
79 prisonPosition = pos;
80}
81
82void Monster::setFreedom(int pos)
83{
84 freedomPosition = pos;
85}
86
87void Monster::setDirection(int dir)
88{
89 if (dir == X)
90 lastDirection = actualDirection;
91 actualDirection = dir;
92}
93
94monsterState Monster::state()
95{
96 return actualState;
97}
98
99int Monster::position()
100{
101 return actualPosition;
102}
103
104int Monster::direction()
105{
106 return actualDirection;
107}
108
109int Monster::id()
110{
111 return ID;
112}
113
114bool Monster::move()
115{
116 if (arrestLeft > 1)
117 arrestLeft--;
118
119 if (harmlessLeft > 0) {
120 harmlessLeft--;
121 if (harmlessLeft == 0 && actualState == harmless) {
122 actualState = dangerous;
123 pauseDuration = dangerousPause;
124 }
125 }
126
127 if (pause-- > 0)
128 return FALSE;
129 else
130 pause = pauseDuration;
131
132 if (actualPosition == OUT)
133 return FALSE;
134
135 if (actualDirection == X) {
136 if (++feetPosition >= (maxBodyPixmaps/10))
137 feetPosition = 0;
138 return TRUE;
139 }
140
141 lastPosition = actualPosition;
142 int d = actualDirection;
143
144 if (arrestLeft > 1) { // during the arrest, only up and down
145 if (!board->isWay(actualPosition, d, empty) &&
146 !board->isWay(actualPosition, d, tunnel))
147 d = board->turn(actualDirection);
148 }
149
150 if (arrestLeft == 1) { // going out of the prison
151 if (((d == W || d == E) &&
152 board->x(actualPosition) == board->x(freedomPosition)) ||
153 ((d == S || d == N) &&
154 board->y(actualPosition) == board->y(freedomPosition)) ||
155 board->isWay(actualPosition, d, brick) ||
156 board->isWay(actualPosition, d, prison)) {
157 d = board->closeup(actualPosition, d, freedomPosition);
158 }
159 while (board->isWay(actualPosition, d, brick) ||
160 board->isWay(actualPosition, d, prison)) {
161 if (d == actualDirection)
162 d = rand() % 4;
163 else
164 d = actualDirection;
165 }
166 if (actualState == dangerous)
167 pauseDuration = dangerousPause;
168
169 }
170
171 if (arrestLeft == 0)
172 if (actualState == rem) { // on the way to prison
173
174 d = board->closeup(actualPosition, d, prisonPosition);
175
176 while (board->isWay(actualPosition, d, brick) ||
177 board->isWay(actualPosition, d, prison)) {
178 if (d != actualDirection) // if new direction is not possible,
179 d = actualDirection; // try current direction first.
180 else
181 d = rand() % 4;
182 }
183
184 } else { // dangerous or harmless movement
185 if (rand() % (int) ((190-IQ)/10) == 0) {
186 d = board->closeup(actualPosition, d, board->position(pacman));
187 if (actualState == harmless)
188 d = board->turn(d);
189 } else
190 do // try new direction, but not the opposite
191 d = rand() % 4; // direction, to prevent hectic movement.
192 while (d == board->turn(actualDirection));
193
194 while ((!board->isWay(actualPosition, d, empty) &&
195 !board->isWay(actualPosition, d, tunnel)) ||
196 d == board->turn(actualDirection)) {
197 if (d != actualDirection) // if new direction is not possible,
198 d = actualDirection; // try current direction first.
199 else
200 d = rand() % 4;
201 }
202 }
203
204 actualDirection = d;
205 actualPosition = board->move(actualPosition, actualDirection);
206
207 if (arrestLeft == 1 && actualPosition == freedomPosition)
208 arrestLeft = 0;
209
210 if (actualState == rem && actualPosition == prisonPosition) {
211 actualState = dangerous;
212 pauseDuration = arrestPause;
213 arrestLeft = arrestDuration+1;
214 actualDirection = S;
215 }
216
217 if (actualPosition != lastPosition) {
218 board->reset(lastPosition, monster, ID);
219 board->set(actualPosition, monster, ID);
220 }
221
222 if (++feetPosition >= (maxBodyPixmaps/10))
223 feetPosition = 0;
224
225 return TRUE;
226}
227
228int Monster::body()
229{
230 if (actualState == rem || actualPosition == OUT)
231 return -1;
232 else
233 if (actualState == harmless)
234 if (harmlessLeft > warningDuration ||
235 harmlessLeft % (int) (warningDuration/4.5) > (int) (warningDuration/9))
236 return ((maxBodyPixmaps/10)*8)+feetPosition;
237 else
238 return ((maxBodyPixmaps/10)*9)+feetPosition;
239 else
240 return ((maxBodyPixmaps/10)*ID)+feetPosition;
241}
242
243int Monster::eyes()
244{
245 if (actualState == harmless || actualPosition == OUT)
246 return -1;
247 else
248 switch (actualDirection) {
249 case N : return 0;
250 case E : return 1;
251 case S : return 2;
252 case W : return 3;
253 case X : switch (lastDirection) {
254 case N : return 0;
255 case E : return 1;
256 case S : return 2;
257 default : return 3;
258 }
259 default : return -1;
260 }
261}
262