Exemple #1
0
void ondeath_omega_body(Object *o)
{
	o->flags &= ~FLAG_SHOOTABLE;
	KillObjectsOfType(OBJ_OMEGA_SHOT);
	
	game.stageboss.SetState(OMG_EXPLODING);
}
Exemple #2
0
// defeated states--they're all run by the ondeath script.
static void run_defeated(Object *o)
{
  // these states are all script-triggered and must be constant.
  switch (o->state)
  {
    // defeated! "gaah" in air
    case 1000:
    {
      o->flags &= ~FLAG_SHOOTABLE;
      KillObjectsOfType(OBJ_MISERY_RING);
      SmokeClouds(o, 3, 2, 2);

      o->xinertia = 0;
      o->yinertia = 0;

      o->state = 1001;
      o->timer = 0;
      o->frame = 4;
      o->xmark = o->x;
    }
    case 1001: // shake until script tells us otherwise
    {
      o->x = o->xmark;
      if (++o->timer & 2)
        o->x += (1 * CSFI);
    }
    break;

    case 1010: // fall to ground and do defeated frame: "ergh"
    {
      o->yinertia += 10;
      if (o->blockd)
      {
        o->frame = 7;
        o->state = 1011;
      }
    }
    break;
  }
}
Exemple #3
0
void XBoss::Run()
{
Object *o = mainobject;
int i;

	if (!mainobject) return;
	if (o->state == 0 || (!X.initilized && o->state != STATE_X_APPEAR))
	{
		o->hp = 1;
		o->x = -(Graphics::SCREEN_WIDTH << CSF);
		return;
	}
	
	switch(o->state)
	{
		// script triggered us to initilize/appear
		// (there is a hvtrigger, right before player first walks by us
		// and sees us inactive, which sends us this ANP).
		case STATE_X_APPEAR:
		{
			if (!X.initilized)
			{
				Init();
				X.initilized = true;
			}
		}
		break;
		
		// script has triggered the fight to begin
		case STATE_X_FIGHT_BEGIN:
		{
			o->timer = 0;
			o->state++;
		}
		case STATE_X_FIGHT_BEGIN+1:
		{
			if (++o->timer > 100)
			{
				FACEPLAYER;
				o->timer = 0;
				o->state = STATE_X_TRAVEL;
			}
		}
		break;
		
		// starts the treads and moves us in the currently-facing direction
		case STATE_X_TRAVEL:
		{
			// count number of times we've traveled, we brake
			// and attack every third time.
			o->timer2++;
			
			o->timer = 0;
			o->state++;
		}
		case STATE_X_TRAVEL+1:
		{
			o->timer++;
			
			// trigger the treads to start moving,
			// and put them slightly out of sync with each-other.
			for(int i=0;i<4;i++)
			{
				if (o->timer == tread_turnon_times[i])
				{
					treads[i]->state = STATE_TREAD_RUN;
					treads[i]->dir = o->dir;
				}
			}
			
			if (o->timer > 120)
			{
				// time to attack? we attack every 3rd travel
				// if so skid to a stop, that's the first step.
				if (o->timer2 >= 3)
				{
					o->timer2 = 0;
					
					o->dir ^= 1;
					o->state = STATE_X_BRAKE;
					o->timer = 0;
				}
				else
				{
					// passed player? skid and turn around.
					if ((o->dir == RIGHT && o->x > player->x) || \
					 	(o->dir == LEFT  && o->x < player->x))
					{
						o->dir ^= 1;
						o->state = STATE_X_TRAVEL;
					}
				}
			}
		}
		break;
		
		// skidding to a stop in preparation to attack
		case STATE_X_BRAKE:
		{
			o->timer = 0;
			o->state++;
		}
		case STATE_X_BRAKE+1:
		{
			o->timer++;
			
			// trigger the treads to start braking,
			// and put them slightly out of sync with each-other.
			for(int i=0;i<4;i++)
			{
				if (o->timer == tread_turnon_times[i])
				{
					treads[i]->state = STATE_TREAD_BRAKE;
					treads[i]->dir = o->dir;
				}
			}
			
			if (o->timer > 50)
			{
				o->state = STATE_X_OPEN_DOORS;
				o->timer = 0;
			}
		}
		break;
		
		// doors opening to attack
		case STATE_X_OPEN_DOORS:
		{
			o->timer = 0;
			o->savedhp = o->hp;
			
			// select type of attack depending on where we are in the battle
			if (!AllTargetsDestroyed())
			{
				SetStates(doors, 2, STATE_DOOR_OPENING);
				o->state = STATE_X_FIRE_TARGETS;
			}
			else
			{
				SetStates(doors, 2, STATE_DOOR_OPENING_PARTIAL);
				o->state = STATE_X_FIRE_FISHIES;
			}
		}
		break;
		
		// firing targets (early battle)
		case STATE_X_FIRE_TARGETS:
		{
			if (doors[0]->state == STATE_DOOR_FINISHED)
			{
				doors[0]->state = 0;
				SetStates(targets, 4, STATE_TARGET_FIRE);
			}
			
			if (++o->timer > 300 || AllTargetsDestroyed())
			{
				o->state = STATE_X_CLOSE_DOORS;
				o->timer = 0;
			}
		}
		break;
		
		// firing fishy missiles (late battle)
		case STATE_X_FIRE_FISHIES:
		{
			if (doors[0]->state == STATE_DOOR_FINISHED)
			{
				doors[0]->state = 0;
				
				SetStates(fishspawners, 4, STATE_FISHSPAWNER_FIRE);
				internals->flags |= FLAG_SHOOTABLE;
			}
			
			if (++o->timer > 300 || (o->savedhp - o->hp) > 200)
			{
				o->state = STATE_X_CLOSE_DOORS;
				o->timer = 0;
			}
		}
		break;
		
		// doors closing after attack
		case STATE_X_CLOSE_DOORS:
		{
			o->timer = 0;
			o->state++;
			
			SetStates(doors, 2, STATE_DOOR_CLOSING);
		}
		case STATE_X_CLOSE_DOORS+1:
		{
			if (doors[0]->state == STATE_DOOR_FINISHED)
			{
				doors[0]->state = 0;
				
				// just turn off everything for both types of attacks;
				// turning off the attack type that wasn't enabled isn't harmful.
				SetStates(targets, 4, 0);
				SetStates(fishspawners, 4, 0);
				internals->flags &= ~FLAG_SHOOTABLE;
			}
			
			if (++o->timer > 50)
			{
				FACEPLAYER;
				o->state = STATE_X_TRAVEL;
				o->timer = 0;
			}
		}
		break;
		
		// exploding
		case STATE_X_EXPLODING:
		{
			SetStates(fishspawners, 4, 0);
			KillObjectsOfType(OBJ_X_FISHY_MISSILE);
			
			StartScript(1000);
			o->timer = 0;
			o->state++;
		}
		case STATE_X_EXPLODING+1:
		{
			game.quaketime = 2;
			o->timer++;
			
			if ((o->timer % 8) == 0)
				sound(SND_ENEMY_HURT_BIG);
			
			SmokePuff(o->CenterX() + (random(-72, 72) << CSF),
					  o->CenterY() + (random(-64, 64) << CSF));
			
			if (o->timer > 100)
			{
				starflash.Start(o->CenterX(), o->CenterY());
				sound(SND_EXPLOSION1);
				o->timer = 0;
				o->state++;
			}
		}
		break;
		case STATE_X_EXPLODING+2:
		{
			game.quaketime = 40;
			if (++o->timer > 50)
			{
				CreateObject(o->x, o->y - (24 << CSF), OBJ_X_DEFEATED);
				DeleteMonster();
				return;
			}
		}
		break;
	}
	
	// call AI for all tread pieces
	for(i=0;i<4;i++)
	{
		run_tread(i);
		run_fishy_spawner(i);
	}
}
void ai_ma_pignon(Object *o)
{
	/*debug("state: %d", o->state);
	debug("timer: %d", o->timer);
	debug("timer2: %d", o->timer2);
	debug("timer3: %d", o->timer3);
	debug("xinertia: %d", o->xinertia);
	debug("yinertia: %d", o->yinertia);
	debug("frame: %d", o->frame);
	*/
	
	switch(o->state)
	{
		case 0:
		{
			o->SnapToGround();
			o->state = 1;
		}
		case 1:
		{
			FACEPLAYER;
			o->frame = 0;
			randblink(o);
		}
		break;
		
		case MP_Fight_Start:		// set by script
		{
			o->state = MP_BaseState;
			o->timer = 0;
			o->timer2 = 0;
			o->flags |= FLAG_SHOOTABLE;
		}
		case MP_BaseState:
		{
			FACEPLAYER;
			o->damage = 1;
			o->frame = 0;
			
			if (++o->timer > 4)
			{
				o->timer = 0;
				o->state = MP_Jump;
				
				if (++o->timer3 > 12)
				{
					o->timer3 = 0;
					o->state = MP_CloneAttack;
				}
			}
		}
		break;
		
		case MP_Jump:		// pause a moment and jump
		{
			o->frame = 2;
			if (++o->timer > 4)
			{
				o->state = MP_In_Air;
				o->frame = 3;
				
				o->xinertia = random(-0x400, 0x400);
				o->yinertia = -0x800;
				
				sound(SND_ENEMY_JUMP);
				o->timer2++;
			}
		}
		break;
		
		case MP_In_Air:		// jumping or falling after clone attack
		{
			o->yinertia += 0x80;
			
			// for when falling back onscreen after clone attack
			if (o->y > (8 * TILE_H) << CSF)
				o->flags &= ~FLAG_IGNORE_SOLID;
			else
				o->blockd = false;
			
			// bounce off walls
			if ((o->blockl && o->xinertia < 0) || \
				(o->blockr && o->xinertia > 0))
			{
				o->xinertia = -o->xinertia;
			}
			
			FACEPLAYER;
			
			// select frame
			if (o->yinertia < -0x200)
			{
				o->frame = 3;
			}
			else if (o->yinertia > 0x200)
			{
				o->frame = 4;
			}
			else
			{
				o->frame = 0;
			}
			
			if (o->blockd && o->yinertia > 0)
			{
				o->state = MP_Landed;
				o->timer = 0;
				o->frame = 2;
				o->xinertia = 0;
			}
			
			if (o->timer2 > 4)
			{
				if (player->y < (o->y + 0x800))
				{
					o->state = MP_ChargeAttack;
					o->timer = 0;
					o->xinertia = 0;
					o->yinertia = 0;
				}
			}
		}
		break;
		
		case MP_Landed:
		{
			o->frame = 2;
			if (++o->timer > 4)
			{
				o->state = MP_BaseState;
			}
		}
		break;
		
		
		case MP_ChargeAttack:		// charge attack
		{
			o->frame = 5;
			if (++o->timer > 10)
			{
				o->state = MP_ChargeAttack+1;
				o->frame = 6;
				
				XMOVE(0x5ff);
				sound(SND_FUNNY_EXPLODE);
				
				o->flags &= ~FLAG_SHOOTABLE;
				o->flags |= FLAG_INVULNERABLE;
				o->damage = 10;
			}
		}
		break;
		case MP_ChargeAttack+1:		// in-air during charge attack
		{
			ANIMATE(0, 6, 7);
			
			if ((o->xinertia < 0 && o->blockl) || \
				(o->xinertia > 0 && o->blockr))
			{
				o->state = MP_Hit_Wall;
			}
		}
		break;
		
		case MP_Hit_Wall:		// hit wall
		{
			o->state++;
			o->timer = 0;
			quake(16);
		}
		case MP_Hit_Wall+1:
		{
			o->damage = 4;
			ANIMATE(0, 6, 7);
			
			if ((++o->timer % 6) == 0)
			{
				int x = (random(4, 16) * TILE_W) << CSF;
				CreateObject(x, (16 << CSF), OBJ_MA_PIGNON_ROCK);
			}
			
			if (o->timer > 30)
			{
				o->timer2 = 0;
				o->state = MP_In_Air;
				
				o->flags |= FLAG_SHOOTABLE;
				o->flags &= ~FLAG_INVULNERABLE;
				
				o->damage = 3;
			}
		}
		break;
		
		
		case MP_CloneAttack:	// begin clone-attack sequence
		{
			o->state++;
			o->frame = 9;
			FACEPLAYER;
		}
		case MP_CloneAttack+1:	// walk at player before attack
		{
			ANIMATE(0, 9, 11);
			
			XMOVE(0x400);
			if (pdistlx(3 << CSF))
			{
				o->state = MP_Fly_Up;
				o->timer = 0;
				o->frame = 2;
				o->xinertia = 0;
			}
		}
		break;
		
		case MP_Fly_Up:		// jump and fly up for clone attack
		{
			o->frame = 2;
			if (++o->timer > 4)
			{
				o->state++;
				o->frame = 12;
				o->yinertia = -0x800;
				sound(SND_FUNNY_EXPLODE);
				
				o->flags |= FLAG_IGNORE_SOLID;
				o->flags &= ~FLAG_SHOOTABLE;
				o->flags |= FLAG_INVULNERABLE;
				
				o->damage = 10;
			}
		}
		break;
		case MP_Fly_Up+1:		// flying up
		{
			ANIMATE(0, 12, 13);
			
			if (o->y < (16<<CSF))
				o->state = MP_Spawn_Clones;
		}
		break;
		
		case MP_Spawn_Clones:	// offscreen, spawning clones
		{
			o->yinertia = 0;
			o->state++;
			o->timer = 0;
			
			quake(10);
		}
		case MP_Spawn_Clones+1:
		{
			ANIMATE(0, 12, 13);
			
			if ((++o->timer % 6) == 0)
			{
				int x = (random(4, 16) * TILE_W) << CSF;
				CreateObject(x, (16 << CSF), OBJ_MA_PIGNON_CLONE);
			}
			
			if (o->timer > 30)
			{
				o->timer2 = 0;
				o->state = MP_In_Air;	// fall back down to ground
				
				o->flags |= FLAG_SHOOTABLE;
				o->flags &= ~FLAG_INVULNERABLE;
			}
		}
		break;
		
		case MP_Defeated:			// defeated -- set by script
		{
			KillObjectsOfType(OBJ_MA_PIGNON_CLONE);
			o->flags &= ~FLAG_SHOOTABLE;
			o->state++;
			o->timer = 0;
			o->frame = 8;
			o->damage = 0;
		}
		case MP_Defeated+1:
		{
			o->yinertia += 0x20;
			if (o->blockd)
			{
				o->xinertia *= 7;
				o->xinertia /= 8;
			}
			
			o->display_xoff = (++o->timer & 1);
		}
		break;
	}
	
	// ma pignon is invulnerable to missiles and Blade.
	if (o->state >= MP_Fight_Start && o->state < MP_Defeated)
	{
		// ....he's invulnerable anyway during these two states so don't mess with that.
		if (o->state != MP_ChargeAttack+1 && o->state != MP_Fly_Up+1)
		{
			bool found_weapons = false;
			if (o->type != OBJ_MA_PIGNON_CLONE)
			{
				Object *c;
				FOREACH_OBJECT(c)
				{
					if (c->type == OBJ_MISSILE_SHOT || \
						c->type == OBJ_SUPERMISSILE_SHOT || \
						c->type == OBJ_MISSILE_BOOM_SPAWNER || \
						c->type == OBJ_BLADE12_SHOT || \
						c->type == OBJ_BLADE3_SHOT || \
						c->type == OBJ_BLADE_SLASH)
					{
						found_weapons = true;
						break;
					}
				}
			}
			
			if (found_weapons)
			{
				o->flags &= ~FLAG_SHOOTABLE;
				o->flags |= FLAG_INVULNERABLE;
			}
			else
			{
				o->flags |= FLAG_SHOOTABLE;
				o->flags &= ~FLAG_INVULNERABLE;
			}
		}
Exemple #5
0
void IronheadBoss::Run(void)
{
	if (!o) return;
	
	switch(o->state)
	{
		case IRONH_SPAWN_FISHIES:
		{
			o->timer = 0;
			o->state++;
		}
		case IRONH_SPAWN_FISHIES+1:		// wave of fishies comes in
		{
			if (++o->timer > 50)
			{
				o->timer = 0;
				o->state = IRONH_SWIM;
			}
			
			if ((o->timer & 3)==0)
			{
				CreateObject((random(15, 18) * TILE_W) << CSF, \
						  	(random(ARENA_TOP, ARENA_BOTTOM) * TILE_H) << CSF, \
						  	OBJ_IRONH_FISHY);
			}
		}
		break;
		
		case IRONH_SWIM:		// swimming attack
		{
			o->state++;
			
			if (o->dir==RIGHT)
			{	// coming up on player from left
				o->x = 0x1e000;
				o->y = player->y;
			}
			else
			{	// returning from right side of screen
				o->x = 0x5a000;
				o->y = (random(ARENA_TOP, ARENA_BOTTOM) * TILE_H) << CSF;
			}
			
			o->xmark = o->x;
			o->ymark = o->y;
			
			o->yinertia = random(-0x200, 0x200);
			o->xinertia = random(-0x200, 0x200);
			
			o->flags |= FLAG_SHOOTABLE;
		}
		case IRONH_SWIM+1:
		{
			ANIMATE(2, 0, 7);
			
			if (o->dir==RIGHT)
			{
				o->xmark += 0x400;
			}
			else
			{
				o->xmark -= 0x200;
				o->ymark += (o->ymark < player->y) ? 0x200: -0x200;
			}
			
			//debugXline(o->xmark, 255,0,0);
			//debugYline(o->ymark, 0,255,0);
			o->xinertia += (o->x > o->xmark) ? -8 : 8;
			o->yinertia += (o->y > o->ymark) ? -8 : 8;
			
			LIMITY(0x200);
			
			if (o->dir==RIGHT)
			{
				if (o->x > 0x5a000)
				{
					o->dir = LEFT;
					o->state = IRONH_SPAWN_FISHIES;
				}
			}
			else
			{
				if (o->x < 0x22000)
				{
					o->dir = RIGHT;
					o->state = IRONH_SPAWN_FISHIES;
				}
			}
			
			if (o->dir==LEFT)
			{
				// fire bullets at player when retreating
				switch(++o->timer)
				{
					case 300:
					case 310:
					case 320:
					{
						Object *shot = SpawnObjectAtActionPoint(o, OBJ_IRONH_SHOT);
						shot->xinertia = (random(-3, 0) << CSF);
						shot->yinertia = (random(-3, 3) << CSF);
						sound(SND_EM_FIRE);
					}
					break;
				}
			}
		}
		break;
		
		case IRONH_DEFEATED:
		{
			sound(SND_EXPL_SMALL);
			o->state = IRONH_DEFEATED+1;
			o->flags &= ~FLAG_SHOOTABLE;
			o->frame = 8;
			o->damage = 0;
			o->xmark = o->x;
			o->ymark = o->y;
			o->xinertia = o->yinertia = 0;
			o->timer = 0;
			KillObjectsOfType(OBJ_IRONH_FISHY);
			KillObjectsOfType(OBJ_IRONH_BRICK);
			KillObjectsOfType(OBJ_BRICK_SPAWNER);
			game.quaketime = 20;
			
			for(int i=0;i<32;i++)
				ironh_smokecloud(o);
		}
		case IRONH_DEFEATED+1:			// retreat back to left...
		{
			o->xmark -= (1<<CSF);
			
			o->x = o->xmark + (random(-1, 1) << CSF);
			o->y = o->ymark + (random(-1, 1) << CSF);
			
			o->timer++;
			if ((o->timer & 3)==0) ironh_smokecloud(o);
		}
		break;
	}
	
	// show pink "hit" frame when he's taking damage
	o->sprite = SPR_IRONH;
	if (o->shaketime)
	{
		this->hittimer++;
		if (this->hittimer & 2)
		{
			o->sprite = SPR_IRONH_HURT;
		}
	}
	else
	{
		this->hittimer = 0;
	}
}