00001 #include "monster.h"
00002
00003 Monster::Monster(Board *b, int mid)
00004 {
00005 board = b;
00006 ID = mid;
00007
00008 setREM(0);
00009 setHarmless(0, 0, 0);
00010 setArrested(0, 0);
00011 setFreedom(board->position(prisonexit));
00012 if (mid == 0)
00013 setPrison(board->position(prisonentry));
00014 else
00015 setPrison(board->position(monsterhome, mid));
00016
00017 actualPosition = lastPosition = OUT;
00018 feetPosition = 0;
00019 IQ = 0;
00020 maxBodyPixmaps = 0;
00021 maxEyesPixmaps = 0;
00022 }
00023
00024 void Monster::setMaxPixmaps(int maxBody, int maxEyes)
00025 {
00026 if (feetPosition >= (maxBody/10))
00027 feetPosition = 0;
00028 maxBodyPixmaps = maxBody;
00029 maxEyesPixmaps = maxEyes;
00030 }
00031
00032 void Monster::setArrested(int ticks, int duration)
00033 {
00034 actualState = dangerous;
00035 pauseDuration = ticks;
00036 pause = 0;
00037 arrestDuration = arrestLeft = duration;
00038 arrestPause = ticks;
00039 harmlessLeft = 0;
00040 }
00041
00042 void Monster::setDangerous(int ticks, int iq)
00043 {
00044 actualState = dangerous;
00045 pauseDuration = ticks;
00046 pause = 0;
00047 dangerousPause = ticks;
00048 harmlessLeft = 0;
00049 IQ = iq;
00050 }
00051
00052 void Monster::setHarmless(int ticks, int hDuration, int wDuration)
00053 {
00054 actualState = harmless;
00055 pauseDuration = ticks;
00056 pause = 0;
00057 harmlessDuration = harmlessLeft = hDuration;
00058 warningDuration = wDuration;
00059 }
00060
00061 void Monster::setREM(int ticks)
00062 {
00063 actualState = rem;
00064 pauseDuration = ticks;
00065 pause = 0;
00066 }
00067
00068 void Monster::setPosition(int pos)
00069 {
00070 board->reset(lastPosition, monster, ID);
00071 actualPosition = lastPosition = pos;
00072 board->set(actualPosition, monster, ID);
00073 feetPosition = 0;
00074 }
00075
00076 void Monster::setPrison(int pos)
00077 {
00078 prisonPosition = pos;
00079 }
00080
00081 void Monster::setFreedom(int pos)
00082 {
00083 freedomPosition = pos;
00084 }
00085
00086 void Monster::setDirection(int dir)
00087 {
00088 if (dir == X)
00089 lastDirection = actualDirection;
00090 actualDirection = dir;
00091 }
00092
00093 monsterState Monster::state()
00094 {
00095 return actualState;
00096 }
00097
00098 int Monster::position()
00099 {
00100 return actualPosition;
00101 }
00102
00103 int Monster::direction()
00104 {
00105 return actualDirection;
00106 }
00107
00108 int Monster::id()
00109 {
00110 return ID;
00111 }
00112
00113 bool Monster::move()
00114 {
00115 if (arrestLeft > 1)
00116 arrestLeft--;
00117
00118 if (harmlessLeft > 0) {
00119 harmlessLeft--;
00120 if (harmlessLeft == 0 && actualState == harmless) {
00121 actualState = dangerous;
00122 pauseDuration = dangerousPause;
00123 }
00124 }
00125
00126 if (pause-- > 0)
00127 return FALSE;
00128 else
00129 pause = pauseDuration;
00130
00131 if (actualPosition == OUT)
00132 return FALSE;
00133
00134 if (actualDirection == X) {
00135 if (++feetPosition >= (maxBodyPixmaps/10))
00136 feetPosition = 0;
00137 return TRUE;
00138 }
00139
00140 lastPosition = actualPosition;
00141 int d = actualDirection;
00142
00143 if (arrestLeft > 1) {
00144 if (!board->isWay(actualPosition, d, empty) &&
00145 !board->isWay(actualPosition, d, tunnel))
00146 d = board->turn(actualDirection);
00147 }
00148
00149 if (arrestLeft == 1) {
00150 if (((d == W || d == E) &&
00151 board->x(actualPosition) == board->x(freedomPosition)) ||
00152 ((d == S || d == N) &&
00153 board->y(actualPosition) == board->y(freedomPosition)) ||
00154 board->isWay(actualPosition, d, brick) ||
00155 board->isWay(actualPosition, d, prison)) {
00156 d = board->closeup(actualPosition, d, freedomPosition);
00157 }
00158 while (board->isWay(actualPosition, d, brick) ||
00159 board->isWay(actualPosition, d, prison)) {
00160 if (d == actualDirection)
00161 d = rand() % 4;
00162 else
00163 d = actualDirection;
00164 }
00165 if (actualState == dangerous)
00166 pauseDuration = dangerousPause;
00167
00168 }
00169
00170 if (arrestLeft == 0)
00171 if (actualState == rem) {
00172
00173 d = board->closeup(actualPosition, d, prisonPosition);
00174
00175 while (board->isWay(actualPosition, d, brick) ||
00176 board->isWay(actualPosition, d, prison)) {
00177 if (d != actualDirection)
00178 d = actualDirection;
00179 else
00180 d = rand() % 4;
00181 }
00182
00183 } else {
00184 if (rand() % (int) ((190-IQ)/10) == 0) {
00185 d = board->closeup(actualPosition, d, board->position(pacman));
00186 if (actualState == harmless)
00187 d = board->turn(d);
00188 } else
00189 do
00190 d = rand() % 4;
00191 while (d == board->turn(actualDirection));
00192
00193 while ((!board->isWay(actualPosition, d, empty) &&
00194 !board->isWay(actualPosition, d, tunnel)) ||
00195 d == board->turn(actualDirection)) {
00196 if (d != actualDirection)
00197 d = actualDirection;
00198 else
00199 d = rand() % 4;
00200 }
00201 }
00202
00203 actualDirection = d;
00204 actualPosition = board->move(actualPosition, actualDirection);
00205
00206 if (arrestLeft == 1 && actualPosition == freedomPosition)
00207 arrestLeft = 0;
00208
00209 if (actualState == rem && actualPosition == prisonPosition) {
00210 actualState = dangerous;
00211 pauseDuration = arrestPause;
00212 arrestLeft = arrestDuration+1;
00213 actualDirection = S;
00214 }
00215
00216 if (actualPosition != lastPosition) {
00217 board->reset(lastPosition, monster, ID);
00218 board->set(actualPosition, monster, ID);
00219 }
00220
00221 if (++feetPosition >= (maxBodyPixmaps/10))
00222 feetPosition = 0;
00223
00224 return TRUE;
00225 }
00226
00227 int Monster::body()
00228 {
00229 if (actualState == rem || actualPosition == OUT)
00230 return -1;
00231 else
00232 if (actualState == harmless)
00233 if (harmlessLeft > warningDuration ||
00234 harmlessLeft % (int) (warningDuration/4.5) > (int) (warningDuration/9))
00235 return ((maxBodyPixmaps/10)*8)+feetPosition;
00236 else
00237 return ((maxBodyPixmaps/10)*9)+feetPosition;
00238 else
00239 return ((maxBodyPixmaps/10)*ID)+feetPosition;
00240 }
00241
00242 int Monster::eyes()
00243 {
00244 if (actualState == harmless || actualPosition == OUT)
00245 return -1;
00246 else
00247 switch (actualDirection) {
00248 case N : return 0;
00249 case E : return 1;
00250 case S : return 2;
00251 case W : return 3;
00252 case X : switch (lastDirection) {
00253 case N : return 0;
00254 case E : return 1;
00255 case S : return 2;
00256 default : return 3;
00257 }
00258 default : return -1;
00259 }
00260 }
00261