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 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; } }
// AI for the Spark object in the Tantalus Ray Machine's of ep2 void CSpark::process() { int mx,my,x,y; mx = getXPosition() >> CSF; my = getYPosition() >> CSF; if (state==SPARK_ANIMATE) { sprite = SPARK_BASEFRAME + frame; } else { sprite = BLANKSPRITE; } switch(state) { case SPARK_ANIMATE: if (timer > SPARK_ANIMRATE) { frame++; if (frame > 3) frame = 0; timer = 0; } else timer++; if ( mHealthPoints <= 0 && state == SPARK_ANIMATE ) { playSound(SOUND_SHOT_HIT); // break the glass and blow out the electric arcs mp_Map->setTile(mx - 2, my, 492, true); mp_Map->setTile(mx - 1, my, 546, true); mp_Map->setTile(mx, my, 547, true); mp_Map->setTile(mx + 1, my, 548, true); mp_Map->setTile(mx + 2, my, 492, true); // remove the unneeded dome tiles mp_Map->setTile(mx - 1, my-1, BG_GREY, true); mp_Map->setTile(mx, my-1, BG_GREY, true); mp_Map->setTile(mx + 1, my-1, BG_GREY, true); // break the switch mp_Map->setTile(mx - 3, my + 4, 506, true); // meltdown! state = SPARK_BLOWUP1; timer = 0; blowy = 0; } break; case SPARK_BLOWUP1: // one by one blow out the purple thingies below the device if (timer > SPARK_BLOW_DELAY) { timer = 0; my = my+3+blowy; mp_Map->setTile(mx, my, 505, true); // spawn a ZAP! or a ZOT! CRay *newobject = new CRay(mp_Map, mx<<CSF, my<<CSF, CENTER, DOWN, getSpriteVariantId()); newobject->state = CRay::RAY_STATE_SETZAPZOT; newobject->setOwner(m_type, m_index); gEventManager.add( new EventSpawnObject(newobject) ); playSound(SOUND_SHOT_HIT); blowy++; if (blowy >= 3) { state = SPARK_BLOWUP2; blowx = 0; } } else timer++; break; case SPARK_BLOWUP2: // blow out the glowing cells if (timer > SPARK_BLOW_DELAY) { if (blowx >= 4) { // done blowing up the glowcells // static the targeting display mx = mx - 7; my = my + 2; for(y=0;y<3;y++) { for(x=0;x<3;x++) { mp_Map->setTile(mx+x,my+y,533, true); } } exists = false; return; } timer = 0; mx = mx + blowx + 3; for(y=3;y<6;y++) { //my = my+3+y; //my = my+y; mp_Map->setTile(mx, my+y, 549, true); // spawn a ZAP! or a ZOT! CRay *newobject = new CRay(mp_Map, mx<<CSF, (my+y)<<CSF, CENTER, DOWN, getSpriteVariantId()); newobject->setOwner(m_type ,m_index); newobject->state = CRay::RAY_STATE_SETZAPZOT; playSound(SOUND_SHOT_HIT); gEventManager.add(new EventSpawnObject(newobject)); } blowx++; } else timer++; break; default: break; } // end of state switch for SE_SPARK }
void CTank::process() { switch(state) { case TANK_WALK: // Walk in a direction { // is keen on same level? if (movedir==LEFT) { // move left sprite = TANK_WALK_LEFT_FRAME + frame; xinertia = -TANK_WALK_SPEED; if( blockedl ) { movedir = RIGHT; frame = 0; timer = 0; animtimer = 0; state = TANK_TURN; } dist_to_travel--; } else { // move right sprite = TANK_WALK_RIGHT_FRAME + frame; xinertia = TANK_WALK_SPEED; if ( blockedr ) { movedir = LEFT; frame = 0; timer = 0; animtimer = 0; state = TANK_TURN; } dist_to_travel--; } // walk animation if (animtimer > TANK_WALK_ANIM_TIME) { if (frame>=3) frame=0; else frame++; animtimer = 0; } else animtimer++; if(dist_to_travel==0) { frame = 0; timer = 0; animtimer = 0; state = TANK_WAIT; } default: break; } break; case TANK_WAIT: if ( (timer > TANK_PREPAREFIRE_TIME) || (timer > TANK_PREPAREFIRE_TIME_FAST && hardmode) ) { timer = 0; state = TANK_FIRE; } else timer++; break; case TANK_TURN: // If it gets stuck somewhere turn around sprite = TANK_LOOK_FRAME + frame; // animation if (animtimer > TANK_LOOK_ANIM_TIME) { frame ^= 1; animtimer = 0; } else animtimer++; // when time is up go back to moving if (timer > TANK_LOOK_TOTALTIME) { // decide what direction to go state = TANK_WALK; animtimer = 0; timer = 0; } else timer++; break; case TANK_FIRE: { int height_top = g_pBehaviorEngine->getPhysicsSettings().tankbot.shot_height_from_top<<STC; if(height_top!=0) { CRay *newobject; if (onscreen) playSound(SOUND_TANK_FIRE); if (movedir==RIGHT) newobject = new CRay(mp_Map, getXMidPos(), getYUpPos()+height_top, RIGHT); else newobject = new CRay(mp_Map, getXMidPos(), getYUpPos()+height_top, LEFT); newobject->setOwner(OBJ_TANK, m_index); newobject->setSpeed(108); newobject->sprite = ENEMYRAY; newobject->canbezapped = true; m_Object.push_back(newobject); } state = TANK_WAIT_LOOK; frame = 0; timer = 0; animtimer = 0; dist_to_travel = TANK_MINTRAVELDIST + (rnd()%10)*(TANK_MAXTRAVELDIST-TANK_MINTRAVELDIST)/10; } break; case TANK_WAIT_LOOK: // Happens after Robot has fired if ( timer > TANK_WAITAFTER_FIRE ) { timer = 0; state = TANK_LOOK; } else timer++; break; case TANK_LOOK: sprite = TANK_LOOK_FRAME + frame; // animation if (animtimer > TANK_LOOK_ANIM_TIME) { frame ^= 1; animtimer = 0; } else animtimer++; // when time is up go back to moving if (timer > TANK_LOOK_TOTALTIME) { // decide what direction to go if(m_Player[0].getXMidPos() < getXMidPos()) { movedir = LEFT; sprite = TANK_WALK_LEFT_FRAME; } else if(m_Player[0].getXMidPos() > getXMidPos()) { movedir = RIGHT; sprite = TANK_WALK_RIGHT_FRAME; } state = TANK_WALK; animtimer = 0; timer = 0; } else timer++; break; } }
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; } }