Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

monster.cpp

Go to the documentation of this file.
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);    // reset old position on the board
00071     actualPosition = lastPosition = pos;        // set position of monster
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) {               // during the arrest, only up and down
00144           if (!board->isWay(actualPosition, d, empty) &&
00145               !board->isWay(actualPosition, d, tunnel))
00146             d = board->turn(actualDirection);
00147     }
00148 
00149     if (arrestLeft == 1) {              // going out of the prison
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) {       // on the way to prison
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)       // if new direction is not possible,
00178                     d = actualDirection;        // try current direction first.
00179                 else
00180                     d = rand() % 4;
00181             }
00182 
00183         } else {                                // dangerous or harmless movement
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                              // try new direction, but not the opposite
00190                     d = rand() % 4;             // direction, to prevent hectic movement.
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)       // if new direction is not possible,
00197                     d = actualDirection;        // try current direction first.
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 

Generated on Sat Nov 5 16:17:21 2005 for OPIE by  doxygen 1.4.2