void CPlayer::walkbehindexitdoor() { int xb, diff, width; const int ep = g_pBehaviorEngine->getEpisode(); // don't draw keen as he walks through the door (past exitXpos) // X pixel position of right side of player xb = (getXRightPos())>>(STC); diff = (xb - exitXpos) + 6; // dist between keen and door if (diff > 0) // past exitXpos? { width = (w>>(STC)) - diff; // get new width of sprite if (width < 0) width = 0; // don't set to negative int frame = playerbaseframe; if(ep == 3) frame++; // set new width of all player walk frames g_pGfxEngine->getSprite(frame+0).setWidth(width); g_pGfxEngine->getSprite(frame+1).setWidth(width); g_pGfxEngine->getSprite(frame+2).setWidth(width); g_pGfxEngine->getSprite(frame+3).setWidth(width); }
void CAmpton::processPoleSlide() { int l_x_l = getXLeftPos(); int l_x = getXMidPos(); int l_x_r = getXRightPos(); int l_y_mid = getYMidPos(); int l_y_down = getYDownPos(); // Move normally in the direction if( yDirection == UP ) { // Check for the upper side and don't let him move if the pole ends if( hitdetectWithTileProperty(1, l_x_l, l_y_mid) || hitdetectWithTileProperty(1, l_x, l_y_mid) || hitdetectWithTileProperty(1, l_x_r, l_y_mid) ) { moveUp( SLIDE_SPEED ); } else { yDirection = DOWN; } } else // Down { // Check for the upper side and don't let him move if the pole ends if( hitdetectWithTileProperty(1, l_x_l, l_y_down) || hitdetectWithTileProperty(1, l_x, l_y_down) || hitdetectWithTileProperty(1, l_x_r, l_y_down) ) { moveDown( SLIDE_SPEED ); } else { yDirection = UP; } } mTimer++; if(mTimer < UMOUNT_TIME) return; mTimer = 0; // Check for Floor here! const int fall1 = mp_Map->getPlaneDataAt(1, l_x, l_y_down+(1<<CSF)); //const int fall1 = mp_Map->getPlaneDataAt(1, l_x, l_y_down); const CTileProperties &TileProp1 = g_pBehaviorEngine->getTileProperties(1)[fall1]; const bool leavePole = (TileProp1.bup != 0); if(leavePole) { setAction(A_AMPTON_STOP_POLE); moveXDir(2*xDirection*WALK_SPEED); moveUp(1<<CSF); solid = true; blockedd = true; } }
void CRoboRed::processShoot() { // Shoot many times. if(mTimer%16 == 0) { playSound(SOUND_ROBORED_SHOOT); direction_t newXDir = xDirection<0 ? LEFT : RIGHT; direction_t newYDir = swapYDir ? UP : DOWN; swapYDir = !swapYDir; int newX = xDirection == RIGHT ? getXRightPos() : getXLeftPos(); int newY = getYPosition() + 0x300; spawnObj( new CRedShot( getMapPtr(), 0, newX, newY, newXDir, newYDir ) ); } mTimer++; if(mTimer < TIME_SHOOTING) return; mTimer = 0; setAction(A_RED_PAUSE); }
void CPlatform::process() { CCarrier::process(); sprite = (gpBehaviorEngine->getEpisode()==2) ? OBJ_PLATFORM_DEFSPRITE_EP2 : OBJ_PLATFORM_DEFSPRITE_EP3; sprite += animframe; if (animtimer > PLATFORM_ANIM_RATE) { animframe ^= 1; animtimer = 0; } else animtimer++; switch(state) { case PLATFORM_MOVE: if (movedir==RIGHT) { if (blockedr || getXRightPos() > (mp_Map->m_width<<CSF) ) { movedir = LEFT; waittimer = 0; state = PLATFORM_WAIT; } else { moveCarrierRight(PLATFORM_MOVE_SPD); } } else if (movedir==LEFT) { if (blockedl || getXLeftPos() < (2<<CSF) ) { movedir = RIGHT; waittimer = 0; state = PLATFORM_WAIT; } else { moveCarrierLeft(PLATFORM_MOVE_SPD); } } break; case PLATFORM_WAIT: if (waittimer > PLATFORM_WAITTIME) { state = PLATFORM_MOVE; } else waittimer++; break; } }
void CWaterMine::processMove() { performCollisions(); if(yDirection) { const Uint16 blockerUp = mp_Map->getPlaneDataAt(2, getXMidPos(), getYUpPos()); const Uint16 blockerDown = mp_Map->getPlaneDataAt(2, getXMidPos(), getYDownPos()); // If there is a blocker, block the Watermine if( blockerUp == 31 ) blockedu = true; if( blockerDown == 31 ) blockedd = true; // If the mine is really blocked, change the direction if(blockedd) yDirection = UP; else if(blockedu) yDirection = DOWN; if(yDirection == DOWN) moveDown(MINE_SPEED); else moveUp(MINE_SPEED); } else { const Uint16 blockerLeft = mp_Map->getPlaneDataAt(2, getXLeftPos(), getYMidPos()); const Uint16 blockerRight = mp_Map->getPlaneDataAt(2, getXRightPos(), getYMidPos()); // If there is a blocker, block the Watermine if( blockerLeft == 31 ) blockedl = true; if( blockerRight == 31 ) blockedr = true; // If the mine is really blocked, change the direction if(blockedl) xDirection = RIGHT; else if(blockedr) xDirection = LEFT; if(xDirection == LEFT) moveLeft(MINE_SPEED); else moveRight(MINE_SPEED); } }
void CScrub::process() { CCarrier::process(); if (canbezapped) { // die if shot if (mHealthPoints <= 0 && state!=SCRUB_DYING ) { solid=true; state = SCRUB_DYING; dietimer = 0; moveUp(10); scrubdie_inertia_y = SCRUBDIE_START_INERTIA; playSound(SOUND_SHOT_HIT); } } CPhysicsSettings &Physics = g_pBehaviorEngine->getPhysicsSettings(); switch(state) { case SCRUB_DYING: sprite = SCRUB_FRY_FRAME; moveYDir(scrubdie_inertia_y); if ( scrubdie_inertia_y < Physics.max_fallspeed ) scrubdie_inertia_y += Physics.fallspeed_increase; dietimer = 0; if (scrubdie_inertia_y >= 0 && blockedd) { sprite = SCRUB_DEAD_FRAME; state = SCRUB_DEAD; dead = true; } return; break; case SCRUB_WALK: if(xDirection < 0) walkLeft( (getXLeftPos())>>CSF, (getYMidPos())>>CSF); else if(xDirection > 0) walkRight( (getXRightPos())>>CSF, (getYMidPos())>>CSF); else if(yDirection < 0)
void CVorticonElite::process() { if (HealthPoints <= 0 && state != VORTELITE_DYING) { animtimer = 0; frame = 0; state = VORTELITE_DYING; dying = true; if (onscreen) playSound(SOUND_VORT_DIE); } if(state == VORTELITE_CHARGE) { m_speed = CHARGE_SPEED; } else if(state == VORTELITE_WALK) { m_speed = WALK_SPEED; } reprocess: ; switch(state) { case VORTELITE_CHARGE: case VORTELITE_WALK: dist_traveled++; state = VORTELITE_WALK; // If Player is nearby, make vorticon go faster if(getYDownPos() > m_Player[0].getYDownPos()-(1<<CSF) and getYDownPos() < m_Player[0].getYDownPos()+(1<<CSF) ) { int dist; if(getXMidPos() > m_Player[0].getXMidPos()) dist = getXMidPos()-m_Player[0].getXMidPos(); else dist = m_Player[0].getXMidPos()-getXMidPos(); if(dist < PLAYER_DISTANCE) state = VORTELITE_CHARGE; } if (getProbability(VORTELITE_JUMP_PROB) && !mp_Map->m_Dark && !blockedu) { // let's jump. initiatejump(); goto reprocess; } else { if (timesincefire > VORTELITE_MIN_TIME_BETWEEN_FIRE) { if (getProbability(VORTELITE_FIRE_PROB)) { // let's fire // usually shoot toward keen if (rand()%5 != 0) { if (getXPosition() < m_Player[0].getXPosition()) { movedir = RIGHT; } else { movedir = LEFT; } } timer = 0; state = VORTELITE_ABOUTTOFIRE; } } else timesincefire++; } if (movedir==LEFT) { // move left sprite = VORTELITE_WALK_LEFT_FRAME + frame; if (!blockedl) { xinertia = -m_speed; } else { movedir = RIGHT; // if we only traveled a tiny amount before hitting a wall, we've // probably fallen into a small narrow area, and we need to try // to jump out of it if (dist_traveled < VORTELITE_TRAPPED_DIST && !mp_Map->m_Dark && blockedd) { initiatejump(); goto reprocess; } else dist_traveled = 0; } } else { // move right sprite = VORTELITE_WALK_RIGHT_FRAME + frame; if (!blockedr) { xinertia = m_speed; } else { movedir = LEFT; // if we only traveled a tiny amount before hitting a wall, we've // probably fallen into a small narrow area, and we need to try // to jump out of it if (dist_traveled < VORTELITE_TRAPPED_DIST && !mp_Map->m_Dark && blockedd) { initiatejump(); goto reprocess; } else dist_traveled = 0; } } // walk animation if (animtimer > VORTELITE_WALK_ANIM_TIME) { if (frame>=3) frame=0; else frame++; animtimer = 0; } else animtimer++; break; case VORTELITE_JUMP: if (movedir == RIGHT) { if (!blockedr) moveRight(m_speed); } else { if (!blockedl) moveLeft(m_speed); } if (blockedd && yinertia >= 0) { // The Vorticon Has landed after the jump! state = VORTELITE_WALK; goto reprocess; } break; case VORTELITE_ABOUTTOFIRE: if (movedir==RIGHT) { sprite = VORTELITE_FIRE_RIGHT_FRAME; } else { sprite = VORTELITE_FIRE_LEFT_FRAME; } if (timer > VORTELITE_HOLD_GUN_OUT_TIME) { timer = 0; state = VORTELITE_FIRED; CRay *newobject; if (movedir==RIGHT) newobject = new CRay(mp_Map, getXRightPos()+1, getYPosition()+(9<<STC), RIGHT); else newobject = new CRay(mp_Map, getXLeftPos()-1, getYPosition()+(9<<STC), LEFT); newobject->setOwner( m_type, m_index); newobject->sprite = ENEMYRAYEP2; // don't shoot other vorticon elite m_Object.push_back(newobject); if (onscreen) playSound(SOUND_KEEN_FIRE); } else timer++; break; case VORTELITE_FIRED: if (movedir==RIGHT) { sprite = VORTELITE_FIRE_RIGHT_FRAME; } else { sprite = VORTELITE_FIRE_LEFT_FRAME; } if (timer > VORTELITE_HOLD_GUN_AFTER_FIRE_TIME) { timer = 0; frame = 0; timesincefire = 0; state = VORTELITE_WALK; // head toward keen if (getXPosition() < m_Player[0].getXPosition()) { movedir = RIGHT; } else { movedir = LEFT; } } else timer++; break; case VORTELITE_DYING: sprite = VORTELITE_DYING_FRAME; if (animtimer > VORTELITE_DIE_ANIM_TIME) { sprite = VORTELITE_DEAD_FRAME; dead = true; } else { animtimer++; } break; default: break; } }
void CRocket::processFlying() { int xBlockPos = target.x - getXPosition(); int yBlockPos = target.y - getYPosition(); const int xBlockPosAbs = (xBlockPos<0) ? -xBlockPos : xBlockPos; const int yBlockPosAbs = (yBlockPos<0) ? -yBlockPos : yBlockPos; if( xBlockPosAbs < MOVE_SPEED && yBlockPosAbs < MOVE_SPEED ) { const Uint16 object = mp_Map->getPlaneDataAt(2, target.x, target.y); Vector2D<int> speed(xBlockPos, yBlockPos); moveDir(speed); playSound(SOUND_ROCKET_DRIVE); // Happens when the rocket find a place where to stop if(object == 0x6A || object == 0x69) { xDirection = CENTER; yDirection = UP; setAction(A_ROCKET_SIT); detectNextTarget(target, xDirection, yDirection); Vector2D<int> newPlayerPos = m_Pos; newPlayerPos.y = getYDownPos(); newPlayerPos.x = getXRightPos(); mpCarriedPlayer->moveToForce(newPlayerPos); mpCarriedPlayer->solid = true; mpCarriedPlayer->dontdraw = false; mpCarriedPlayer = nullptr; return; } readDirection(object, xDirection, yDirection ); // If there is an object that changes the direction of the rocket, apply it! detectNextTarget(target, xDirection, yDirection); } Vector2D<int> speed; if(yDirection == UP) { speed.y = -MOVE_SPEED; } else if(yDirection == DOWN) { speed.y = MOVE_SPEED; } if(xDirection == RIGHT) { speed.x = MOVE_SPEED; } else if(xDirection == LEFT) { speed.x = -MOVE_SPEED; } if(mpCarriedPlayer != nullptr) { mpCarriedPlayer->moveDir(speed); } moveDir(speed); }
void CGuardRobot::process() { switch(state) { case LOOK: // animation if (animtimer > LOOK_ANIM_TIME) { frame ^= 1; animtimer = 0; } else animtimer++; sprite = LOOK_FRAME + frame; // when time is up go back to moving if (timer > LOOK_TOTALTIME) { timetillcanfire = (rnd()%(MAX_TIME_TILL_CAN_FIRE-MIN_TIME_TILL_CAN_FIRE))+MIN_TIME_TILL_CAN_FIRE; timetillcanfirecauseonsamelevel = TIME_BEFORE_FIRE_WHEN_SEE; firetimes = 0; state = WALK; frame = 0; animtimer = 0; timer = 0; dist_to_travel = TRAVELDIST; } else timer++; break; case WALK: // hover animation if (animtimer > WALK_ANIM_TIME) { if (frame>=3) frame=0; else frame++; animtimer = 0; } else animtimer++; if (movedir==LEFT) sprite = WALK_LEFT_FRAME + frame; else sprite = WALK_RIGHT_FRAME + frame; // if we're about to, or just did, fire a volley, don't move if (!hardmode) { if (pausetime) { pausetime--; return; } } else pausetime = 0; // are we firing a volley? if (firetimes) { // is it time to fire the next shot in the volley? if (!timetillnextshot) { CRay *newobject; if (onscreen) playSound(SOUND_TANK_FIRE); if (movedir==RIGHT) newobject = new CRay(mp_Map,getXRightPos()+(8<<STC), getYUpPos()+(5<<STC), RIGHT); else newobject = new CRay(mp_Map,getXPosition(), getYUpPos()+(5<<STC), LEFT); newobject->setOwner(OBJ_GUARDROBOT, m_index); newobject->sprite = ENEMYRAYEP2; m_ObjectVect.push_back(newobject); timetillnextshot = TIME_BETWEEN_SHOTS; if (!--firetimes) { pausetime = FIRE_PAUSE_TIME; } } else { timetillnextshot--; } // don't move when firing except on hard mode if (hardmode) return; } else { // not firing a volley if (!timetillcanfire) { guard_fire(); } else { timetillcanfire--; } } turnaroundtimer = 0; if (movedir==LEFT) { // move left if (!blockedl) { xinertia = -WALK_SPEED; dist_to_travel--; } else { frame = 0; timer = 0; animtimer = 0; state = LOOK; movedir = RIGHT; } } else { // move right sprite = WALK_RIGHT_FRAME + frame; if (!blockedr) { xinertia = WALK_SPEED; dist_to_travel--; } else { frame = 0; timer = 0; animtimer = 0; state = LOOK; movedir = LEFT; } } break; default : break; } }
void CAmpton::processWalking() { //play tic toc sound if(getActionStatus(A_AMPTON_WALK)) playSound(SOUND_AMPTONWALK0); else if(getActionStatus(A_AMPTON_WALK+1)) playSound(SOUND_AMPTONWALK1); int l_x_l = getXLeftPos(); int l_x_r = getXRightPos(); int l_w = getXRightPos() - getXLeftPos(); int l_h = getYDownPos() - getYUpPos(); int l_y = getYMidPos(); int l_x_mid = getXMidPos(); if ( (l_x_mid & 0x1FF) <= WALK_SPEED) { if(hitdetectWithTilePropertyRectRO(31, l_x_mid, l_y, l_w, l_h, 1<<CSF)) { setAction(A_AMPTON_FLIP_SWITCH); } if(hitdetectWithTilePropertyRectRO(1, l_x_mid, l_y, l_w, l_h, 1<<CSF)) { if( getProbability(600) ) //if (rand() < 0xC4) { bool polebelow = hitdetectWithTilePropertyHor(1, l_x_l, l_x_r, getYDownPos(), 1<<CSF); bool poleabove = hitdetectWithTilePropertyHor(1, l_x_l, l_x_r, getYUpPos(), 1<<CSF); if( getProbability(400) ) //if (rand() < 0x80) poleabove = false; else polebelow = false; //climb up if (poleabove) { setAction(A_AMPTON_START_POLE); yDirection = UP; return; } else if (polebelow) { setAction(A_AMPTON_START_POLE); yDirection = DOWN; return; } } } } // Move normally in the direction if( xDirection == RIGHT ) { moveRight( WALK_SPEED ); } else { moveLeft( WALK_SPEED ); } }
// Process the touching of certain tile, like items and hazards... void CPlayerBase::processLevelMiscFlagsCheck() { // Item which are taken must go into a data structure // animation should also be triggered stItemGalaxy &m_Item = m_Inventory.Item; int l_x = getXLeftPos(); int l_y = getYUpPos(); int l_w = getXRightPos() - getXLeftPos(); int l_h = getYDownPos() - getYUpPos(); // Deadly hazards! Here Keen dying routine will be triggered if(hitdetectWithTilePropertyRect(3, l_x, l_y, l_w, l_h, 2<<STC)) { kill(); return; } // Another property of the tiles may kill keen, also in god mode std::vector<CTileProperties> &Tile = g_pBehaviorEngine->getTileProperties(1); // TODO: Workaround! It seems that the deadly tiles are 17 tiles behind. Not sure, why! const int tileIDl = mp_Map->getPlaneDataAt(1, l_x, (l_y+l_h)+(1<<STC)); const int tileIDr = mp_Map->getPlaneDataAt(1, l_x+l_w, (l_y+l_h)+(1<<STC)); if(Tile[tileIDl].bup == 9 && Tile[tileIDr].bup == 9 ) { if(!m_Cheatmode.god) { kill(true); } } if(hitdetectWithTilePropertyRect(4, l_x, l_y, l_w, l_h, 2<<STC)) { int dropanimation_sprite = 215; const int ep = g_pBehaviorEngine->getEpisode(); if(ep == 5) { dropanimation_sprite = 225; } else if(ep == 6) { dropanimation_sprite = 224; } const int lc_x = l_x>>CSF; const int lc_y = l_y>>CSF; mp_Map->setTile( lc_x, lc_y, 0, true, 1 ); CItemEffect *iEffect = new CItemEffect(mp_Map, 0, lc_x<<CSF, lc_y<<CSF, dropanimation_sprite, ANIMATE); g_pBehaviorEngine->m_EventList.spawnObj( iEffect ); m_Item.m_drops++; if(m_Item.m_drops >= 100) { m_Item.m_drops = 0; getAnotherLife(lc_x, lc_y, true, true); } g_pSound->playSound( SOUND_GET_DROP ); }
void CVorticonElite::process() { if (mHealthPoints <= 0 && state != VORTELITE_DYING) { animtimer = 0; frame = 0; state = VORTELITE_DYING; dying = true; if (onscreen) playSound(SOUND_VORT_DIE); } if(state == VORTELITE_CHARGE) { m_speed = CHARGE_SPEED; } else if(state == VORTELITE_WALK) { m_speed = WALK_SPEED; } reprocess: ; switch(state) { case VORTELITE_CHARGE: case VORTELITE_WALK: if (movedir==LEFT) { // move left sprite = VORTELITE_WALK_LEFT_FRAME + frame; if (!blockedl) { xinertia = -m_speed; } else { movedir = RIGHT; // if we only traveled a tiny amount before hitting a wall, we've // probably fallen into a small narrow area, and we need to try // to jump out of it if (dist_traveled < VORTELITE_TRAPPED_DIST && !mp_Map->m_Dark && blockedd) { initiatejump(); goto reprocess; } else if(mp_Map->m_Dark) { dist_traveled = 0; } } } else { // move right sprite = VORTELITE_WALK_RIGHT_FRAME + frame; if (!blockedr) { xinertia = m_speed; } else { movedir = LEFT; // if we only traveled a tiny amount before hitting a wall, we've // probably fallen into a small narrow area, and we need to try // to jump out of it if (dist_traveled < VORTELITE_TRAPPED_DIST && !mp_Map->m_Dark && blockedd) { initiatejump(); goto reprocess; } else if(mp_Map->m_Dark) { dist_traveled = 0; } } } // walk animation if (animtimer > VORTELITE_WALK_ANIM_TIME) { if (frame>=3) frame=0; else frame++; animtimer = 0; } else animtimer++; break; case VORTELITE_JUMP: if (movedir == RIGHT) { if (!blockedr) moveRight(m_speed); } else { if (!blockedl) moveLeft(m_speed); } if (blockedd && yinertia >= 0) { // The Vorticon Has landed after the jump! state = VORTELITE_WALK; goto reprocess; } break; case VORTELITE_ABOUTTOFIRE: if (movedir==RIGHT) { sprite = VORTELITE_FIRE_RIGHT_FRAME; } else { sprite = VORTELITE_FIRE_LEFT_FRAME; } if (timer > VORTELITE_HOLD_GUN_OUT_TIME) { timer = 0; state = VORTELITE_FIRED; CRay *newobject; if (movedir==RIGHT) newobject = new CRay(mp_Map, getXRightPos()+1, getYPosition()+(9<<STC), RIGHT, CENTER, getSpriteVariantId()); else newobject = new CRay(mp_Map, getXLeftPos()-1, getYPosition()+(9<<STC), LEFT, CENTER, getSpriteVariantId()); newobject->setOwner( m_type, m_index); newobject->sprite = ENEMYRAYEP2; // don't shoot other vorticon elite spawnObj(newobject); if (onscreen) playSound(SOUND_KEEN_FIRE); } else timer++; break; case VORTELITE_FIRED: if (movedir==RIGHT) { sprite = VORTELITE_FIRE_RIGHT_FRAME; } else { sprite = VORTELITE_FIRE_LEFT_FRAME; } if (timer > VORTELITE_HOLD_GUN_AFTER_FIRE_TIME) { timer = 0; frame = 0; timesincefire = 0; state = VORTELITE_WALK; } else timer++; break; case VORTELITE_DYING: sprite = VORTELITE_DYING_FRAME; if (animtimer > VORTELITE_DIE_ANIM_TIME) { sprite = VORTELITE_DEAD_FRAME; dead = true; } else { animtimer++; } break; default: break; } }
#include <base/utils/StringUtils.h> #include <fileio/KeenFiles.h> #define DOOR_YELLOW 2 #define DOOR_RED 3 #define DOOR_GREEN 4 #define DOOR_BLUE 5 // let's have keen be able to pick up goodies void CPlayer::getgoodies() { if( getGoodie((getXLeftPos())>>CSF, (getYUpPos())>>CSF) ) return; // Upper-Left else if(getGoodie((getXRightPos())>>CSF, (getYUpPos())>>CSF) ) return; // Upper-Right else if(getGoodie(((getXLeftPos())>>CSF), ((getYDownPos())>>CSF)) ) return; // Lower-Left else if(getGoodie(((getXRightPos())>>CSF), ((getYDownPos())>>CSF)) ) return; // Lower-Right } // have keen pick up the goodie at screen pixel position (px, py) bool CPlayer::getGoodie(int px, int py) { std::vector<CTileProperties> &TileProperty = gpBehaviorEngine->getTileProperties(); Uint16 tile = mp_Map->at(px, py); auto behaviour = TileProperty[tile].behaviour; if (behaviour>0 && behaviour<31)