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;
	}
}
Exemple #3
0
// 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
}
Exemple #4
0
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;
	}
}