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 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; } }
bool CThunderCloud::isNearby(CSpriteObject &theObject) { if( CPlayerLevel *player = dynamic_cast<CPlayerLevel*>(&theObject) ) { const unsigned int cloudX = getXMidPos(); const unsigned int playXLeft = player->getXMidPos() - DIST_TO_AWAKE; const unsigned int playXRight = player->getXMidPos() + DIST_TO_AWAKE; if( playXLeft < cloudX && playXRight > cloudX ) { if( getActionStatus(A_CLOUD_ASLEEP) && getProbability(180) ) setAction(A_CLOUD_WAKING); } else { if( !getActionStatus(A_CLOUD_ASLEEP) ) { setAction(A_CLOUD_ASLEEP); setActionSprite(); return true; } } if( getActionStatus(A_CLOUD_WAKING) ) { if( player->getXMidPos() < getXMidPos() ) xDirection = LEFT; else xDirection = RIGHT; } if( getActionStatus(A_CLOUD_MOVING) ) { if( mpBolt == nullptr && player->getYMidPos() > getYMidPos() ) { const unsigned int playXStrikeLeft = player->getXMidPos() - DIST_TO_STRIKE; const unsigned int playXStrikeRight = player->getXMidPos() + DIST_TO_STRIKE; if( playXStrikeLeft < cloudX && playXStrikeRight > cloudX && (mTimer>TIME_TO_STRIKE_2 || (mSecondTry && mTimer>TIME_TO_STRIKE_1) ) ) { mTimer = 0; mSecondTry = !mSecondTry; setAction(A_CLOUD_STRIKING); playSound(SOUND_THUNDERCLOUD_STRIKE); mpBolt = new CThunderBolt( mp_Map, getXLeftPos() + (12<<STC), getYDownPos() + (32<<STC), mSprVar ); spawnObj( mpBolt ); } } } } return true; }
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 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; } }
// 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