Exemplo n.º 1
0
void ai_bat_circle(Object *o)
{
	switch(o->state)
	{
		case 0:
		{
			uint8_t angle;
			o->state = 1;
			
			// set up initial direction and target x,y
			angle = random(0, 255);
			o->xinertia = sin_table[angle];
			
			angle += 64;
			o->xmark = (o->x + (sin_table[angle] * 8));
			
			angle = random(0, 255);
			o->yinertia = sin_table[angle];
			
			angle += 64;
			o->ymark = (o->y + (sin_table[angle] * 8));
		}
		case 1:
			// circle around our target point
			ANIMATE(1, 2, 4);
			FACEPLAYER;
			o->xinertia += (o->x > o->xmark) ? -0x10 : 0x10;
			o->yinertia += (o->y > o->ymark) ? -0x10 : 0x10;
			LIMITX(0x200);
			LIMITY(0x200);
			
			if (!o->timer2)
			{
				if (pdistlx(0x1000) && (player->y > o->y) && pdistly(0xC000))
				{	// dive attack
					o->xinertia /= 2;
					o->yinertia = 0;
					o->state = 2;
					o->frame = 5;		// mouth showing teeth
				}
			}
			else o->timer2--;
		break;
		
		case 2:	// dive attack
			o->yinertia += 0x40;
			LIMITY(0x5ff);
			
			if (o->blockd)
			{
				o->yinertia = 0;
				o->xinertia *= 2;
				o->timer2 = 120;		// delay before can dive again
				o->state = 1;
			}
		break;
	}
}
Exemplo n.º 2
0
void ai_firewhirr(Object *o)
{
    Object *shot;

    FACEPLAYER;

    switch(o->state)
    {
    case 0:
        o->state = 1;
        o->timer = random(0, 50);
        o->ymark = o->y;
    //o->yinertia = -0x200;
    case 1:

        if (!o->timer)
        {
            o->state = 10;
            o->yinertia = -0x200;
        }
        else o->timer--;

    case 10:
        o->frame ^= 1;

        o->yinertia += (o->y < o->ymark) ? 0x10 : -0x10;
        LIMITY(0x200);

        // inc time-to-fire while player near
        if (pdistly(80 << CSF))
        {
            if (o->dir==LEFT && player->x < o->x && pdistlx(160 << CSF)) o->timer2++;
            if (o->dir==RIGHT && player->x > o->x && pdistlx(160 << CSF)) o->timer2++;
        }

        // if time to fire, spawn a shot
        if (o->timer2 > 20)
        {
            shot = SpawnObjectAtActionPoint(o, OBJ_FIREWHIRR_SHOT);
            o->timer2 = -100 + random(0, 20);
            // tell Curly to acquire us as a target
            if (o->onscreen)
            {
                o->CurlyTargetHere();
            }
        }
        break;
    }
}
Exemplo n.º 3
0
void ai_block_moveh(Object *o)
{
	int px = player->CenterX();
	int objx = o->CenterX();
	
	switch(o->state)
	{
		case 0:
         NX_LOG("ai_block_moveh - state 0.\n");
			o->flags |= FLAG_SOLID_BRICK;
			o->smushdamage = 100;
			o->state = (o->dir == LEFT) ? 10:20;
		break;
		
		case 10:	// at right edge, ready to travel left
         NX_LOG("ai_block_moveh - state 10.\n");
			if (((px > objx) && (px - objx) < 0x3200) || \
				((px < objx) && (objx - px) < 0x32000))
			{
				if (pdistly(0x3200))
				{
					o->state = 30;
					o->timer = 0;
				}
			}
		break;
		
		case 20:	// at left edge, ready to travel right
         NX_LOG("ai_block_moveh - state 20.\n");
			if (((px > objx) && (px - objx) < 0x32000) || \
				((px < objx) && (objx - px) < 0x3200))
			{
				if (pdistly(0x3200))
				{
					o->state = 30;
					o->timer = 0;
				}
			}
		break;
		
		case 30:	// traveling
		{
         NX_LOG("ai_block_moveh - state 30.\n");
			XACCEL(0x20);
			LIMITX(0x200);
			
			// hit edge
			if ((o->dir == RIGHT && o->blockr) || (o->dir == LEFT && o->blockl))
			{
				SmokeSide(o, 4, o->dir);
				quake(10);
				
				o->xinertia = 0;
				o->dir ^= 1;
				o->state = (o->dir==LEFT) ? 10 : 20;
			}
			
			if ((++o->timer % 10) == 6)
				sound(SND_BLOCK_MOVE);
		}
		break;
	}
}
Exemplo n.º 4
0
void ai_bute_archer_red(Object *o)
{
	//DebugCrosshair(o->x, o->y, 0, 255, 255);
	
	switch(o->state)
	{
		case 0:
		{
			o->state = 1;
			
			o->xmark = o->x;
			o->ymark = o->y;
			
			if (o->dir == LEFT)
				o->xmark -= (128<<CSF);
			else
				o->xmark += (128<<CSF);
			
			o->xinertia = random(-0x400, 0x400);
			o->yinertia = random(-0x400, 0x400);
		}
		case 1:		// come on screen
		{
			ANIMATE(1, 0, 1);
			
			if ((o->dir == LEFT && o->x < o->xmark) || \
				(o->dir == RIGHT && o->x > o->xmark))
			{
				o->state = 20;
			}
		}
		break;
		
		case 20:	// aiming
		{
			o->state = 21;
			o->timer = random(0, 150);
			
			o->frame = 2;
			o->animtimer = 0;
		}
		case 21:
		{
			ANIMATE(2, 2, 3);
			
			if (++o->timer > 300 || \
				(pdistlx(112<<CSF) && pdistly(16<<CSF)))
			{
				o->state = 30;
			}
		}
		break;
		
		case 30:	// flashing to fire
		{
			o->state = 31;
			o->timer = 0;
			o->animtimer = 0;
			o->frame = 3;
		}
		case 31:
		{
			ANIMATE(1, 3, 4);
			
			if (++o->timer > 30)
			{
				o->state = 40;
				o->frame = 5;
				
				Object *arrow = CreateObject(o->x, o->y, OBJ_BUTE_ARROW);
				arrow->dir = o->dir;
				arrow->xinertia = (o->dir == RIGHT) ? 0x800 : -0x800;
			}
		}
		break;
		
		case 40:	// fired
		{
			o->state = 41;
			o->timer = 0;
			o->animtimer = 0;
		}
		case 41:
		{
			ANIMATE(2, 5, 6);
			
			if (++o->timer > 40)
			{
				o->state = 50;
				o->timer = 0;
				o->xinertia = 0;
				o->yinertia = 0;
			}
		}
		break;
		
		case 50:	// retreat offscreen
		{
			ANIMATE(1, 0, 1);
			XACCEL(-0x20);
			
			if (o->Right() < 0 || o->Left() > ((map.xsize * TILE_W) << CSF))
				o->Delete();
		}
		break;
	}
	
	// sinusoidal hover around set point
	if (o->state != 50)
	{
		o->xinertia += (o->x < o->xmark) ? 0x2A : -0x2A;
		o->yinertia += (o->y < o->ymark) ? 0x2A : -0x2A;
		LIMITX(0x400);
		LIMITY(0x400);
	}
	
}
Exemplo n.º 5
0
void ai_mesa(Object *o)
{
	if (run_bute_defeated(o, MESA_HP))
		return;
	
	switch(o->state)
	{
		case 0:
		{
			o->y += (4<<CSF);
			o->state = 1;
		}
		case 1:
		{
			ANIMATE(40, 0, 1);
			FACEPLAYER;
			
			if (pdistlx(320<<CSF) && pdistly(160<<CSF))
			{
				if (++o->timer > 50)
					o->state = 10;
			}
		}
		break;
		
		case 10:
		{
			o->state = 11;
			o->timer = 0;
			o->frame = 2;	// hand down
			
			int x = o->x + ((o->dir == LEFT) ? (7<<CSF) : -(7<<CSF));
			int y = o->y + (10<<CSF);
			
			o->linkedobject = CreateObject(x, y, OBJ_MESA_BLOCK);
			o->linkedobject->linkedobject = o;
		}
		case 11:
		{
			if (++o->timer > 50)
			{
				o->state = 20;
				o->timer = 0;
				o->frame = 3;	// hand up, throwing
				
				if (o->linkedobject)
				{
					Object *&block = o->linkedobject;
					
					block->y = (o->y - (4<<CSF));
					block->xinertia = (o->dir == RIGHT) ? 0x400 : -0x400;
					block->yinertia = -0x400;
					block->state = 1;
					
					sound(SND_EM_FIRE);
					block->linkedobject = NULL;
					o->linkedobject = NULL;
				}
			}
		}
		break;
		
		case 20:
		{
			if (++o->timer > 20)
			{	// throw again, if player still near
				o->state = 1;
				o->timer = 0;
			}
		}
		break;
	}
	
	o->yinertia += 0x55;
	LIMITY(0x5ff);
}
Exemplo n.º 6
0
void ai_bute_archer(Object *o)
{
	if (run_bute_defeated(o, BUTE_HP))
		return;
	
	switch(o->state)
	{
		case 0:		// waiting for player (when haven't seen him yet)
		{
			if ((o->dir == LEFT  && player->CenterX() < o->CenterX()) || \
				(o->dir == RIGHT && player->CenterX() > o->CenterX()))
			{
				if (pdistlx(320<<CSF) && pdistly(160<<CSF))
				{
					o->state = 10;
				}
			}
		}
		break;
		
		// aiming--can track player here for a brief period
		case 10:
		{
			FACEPLAYER;
			
			if (!pdistlx(224<<CSF) || player->y <= (o->y - (8<<CSF)))
			{
				o->frame = 4;	// shooting up
				o->timer2 = 1;
			}
			else
			{
				o->frame = 1;	// shooting straight
				o->timer2 = 0;
			}
			
			if (++o->timer > 10)
			{
				o->state = 20;
				o->timer = 0;
			}
		}
		break;
		
		// flashing to fire
		case 20:
		{
			if (o->timer2 == 0)
				ANIMATE(0, 1, 2)
			else
				ANIMATE(0, 4, 5)
			
			if (++o->timer > 30)
				o->state = 30;
		}
		break;
		
		// fire
		case 30:
		{
			o->state = 31;
			o->timer = 0;
			
			Object *arrow = CreateObject(o->CenterX(), o->CenterY(), OBJ_BUTE_ARROW);
			arrow->xinertia = (o->dir == RIGHT) ? 0x600 : -0x600;
			
			if (o->timer2 == 1)		// shooting up
				arrow->yinertia = -0x600;
			
			// frame: arrow away
			o->frame = (o->timer2 == 1) ? 6 : 3;
		}
		case 31:
		{
			if (++o->timer > 30)
			{
				o->state = 40;
				o->frame = 0;
				o->timer = random(50, 150);
			}
		}
		break;
		
		// after fire, and the "woken up" waiting-for-player state
		case 40:
		{
			if (pdistlx(352<<CSF) && pdistly(240<<CSF))
			{
				if (--o->timer < 0)
					o->state = 10;	// fire again
			}
			else
			{	// player got away, do nothing until he returns
				o->timer = 150;
			}
		}
		break;
	}
}
Exemplo n.º 7
0
void ai_critter_hopping_red(Object *o)
{
	switch(o->state)
	{
		case 0:
		{
			FACEPLAYER;
			o->frame = 0;
			
			if (o->shaketime)
			{
				o->state = 2;
				o->timer = 0;
			}
			else if (++o->timer >= 8)
			{
				if (pdistly((5 * TILE_H) << CSF))
				{
					if (pdistlx((6 * TILE_W) << CSF))
					{
						o->state = 1;
						o->timer = 0;
					}
					else if (pdistlx((9 * TILE_W) << CSF))
					{
						o->frame = 1;
					}
				}
			}
		}
		break;
		
		case 1:		// prepare to jump
		{
			if (++o->timer > 8)
			{
				o->state = 2;
				o->frame = 2;
				sound(SND_ENEMY_JUMP);
				
				o->yinertia = -0x5ff;
				o->xinertia = (o->dir == RIGHT) ? 0x200 : -0x200;
			}
		}
		break;
		
		case 2:		// in air
		{
			if (o->blockd && o->yinertia > 0)
			{
				sound(SND_THUD);
				o->xinertia = 0;
				
				o->state = 0;
				o->timer = 0;
				o->frame = 1;
			}
		}
		break;
	}
	
	o->yinertia += 0x55;
	LIMITY(0x5ff);
}
Exemplo n.º 8
0
void ai_buyobuyo(Object *o)
{
    bool deleteme = false;
    ANIMATE(6, 0, 1);

    switch(o->state)
    {
    case 0:
    {
        // shoot up down at player...
        o->yinertia = (o->dir == LEFT) ? -0x600 : 0x600;
        o->state = 1;
        o->timer = 0;
    }
    case 1:
    {
        o->timer++;		// inc fly time
        // reached height of player yet?
        if (pdistly(0x2000))
        {
            o->state = 2;
            ai_buyobuyo(o);
            return;
        }
    }
    break;

    case 2:
    {
        // this slight "minimum fly time" keeps the underwater ones from
        // smacking into the floor if the player is underwater with them
        if (++o->timer > 3)
        {
            FACEPLAYER;
            o->xmark = o->x;
            o->ymark = o->y;

            o->xinertia = random(0, 1) ? 0x200 : -0x200;
            o->yinertia = random(0, 1) ? 0x200 : -0x200;

            o->state = 3;
        }
    }
    break;

    case 3:
    {
        if (o->x > o->xmark) o->xinertia -= 0x20;
        if (o->x < o->xmark) o->xinertia += 0x20;
        if (o->y > o->ymark) o->yinertia -= 0x20;
        if (o->y < o->ymark) o->yinertia += 0x20;
        LIMITX(0x400);
        LIMITY(0x400);

        // move the point we are bobbling around
        o->xmark += (o->dir == LEFT) ? -(1 << CSF) : (1 << CSF);
        //debugVline(o->xmark, 0, 0xff, 0);

        if (++o->timer > 300)
            deleteme = true;
    }
    break;
    }

    if ((o->blockl && o->xinertia < 0) || \
            (o->blockr && o->xinertia > 0) || \
            (o->blocku && o->yinertia < 0) || \
            (o->blockd && o->yinertia > 0))
    {
        deleteme = true;
    }

    if (deleteme)
    {
        effect(o->CenterX(), o->CenterY(), EFFECT_STARPOOF);
        o->Delete();
        return;
    }
}
Exemplo n.º 9
0
// handles his "looping" flight/rush attacks
static void run_flight(Object *o)
{
	switch(o->state)
	{
		// flying left or right
		case BP_FLY_LR:
		{
			o->state++;
			o->animtimer = 0;
			o->frame = 6;		// flying horizontally
			
			o->yinertia = 0;
			o->damage = DMG_RUSH;
			
			FACEPLAYER;
			XMOVE(RUSH_SPEED);
		}
		case BP_FLY_LR+1:
		{
			ANIMATE(1, 6, 7);
			
			// smacked into wall?
			if ((o->blockl && o->dir == LEFT) || \
				(o->blockr && o->dir == RIGHT))
			{
				o->xinertia = 0;
				o->state = BP_HIT_WALL;
				o->damage = DMG_NORMAL;
				o->timer = 0;
				megaquake(10);
			}
			
			// reached player?
			// this has to be AFTER smacked-into-wall check for proper behavior
			// if player stands in spikes at far left/right of arena.
			if (pdistlx(RUSH_DIST))
				o->state = BP_PREPARE_FLY_UD;
		}
		break;
		
		// smacked into wall while flying L/R
		case BP_HIT_WALL:
		{
			o->frame = 6;
			
			if (++o->timer > 30)
			{
				if (o->timer2 <= 3)
					o->state = BP_PREPARE_FLY_LR;
				else
					o->state = BP_RETURN_TO_GROUND;
			}
		}
		break;
		
		
		// flying up
		case BP_FLY_UP:
		{
			o->state++;
			o->timer = 0;
			o->animtimer = 0;
			
			o->frame = 8;		// vertical flight
			o->dir = LEFT;		// up-facing frame
			
			o->yinertia = -RUSH_SPEED;
			o->xinertia = 0;
			o->damage = DMG_RUSH;
		}
		case BP_FLY_UP+1:
		{
			ANIMATE(1, 8, 9);
			
			// hit ceiling? (to make this happen, break his loop and jump ABOVE him
			// while he is in the air, at the part where he would normally be
			// coming back down at you).
			if (o->blocku)
			{
				o->state = BP_HIT_CEILING;
				o->damage = DMG_NORMAL;
				o->timer = 0;
				
				SmokeXY(o->CenterX(), o->Top(), 8);
				megaquake(10);
				
				spawn_bones(o, UP);
			}
			
			// reached player? (this check here isn't exactly the same as pdistly;
			// it's important that it checks the player's top and not his center).
			if ((abs(player->y - o->y) < RUSH_DIST) && o->timer2 < 4)
				o->state = BP_PREPARE_FLY_LR;
		}
		break;
		
		case BP_HIT_CEILING:	// hit ceiling
		{
			o->frame = 8;
			
			if (++o->timer > 30)
			{
				if (o->timer2 <= 3)
					o->state = BP_PREPARE_FLY_LR;
				else
					o->state = BP_RETURN_TO_GROUND;
			}
		}
		break;
		
		
		// flying down
		case BP_FLY_DOWN:
		{
			o->state++;
			o->timer = 0;
			o->animtimer = 0;
			
			o->frame = 8;		// vertical flight
			o->dir = RIGHT;		// down-facing frame
			
			o->yinertia = RUSH_SPEED;
			o->xinertia = 0;
			o->damage = DMG_RUSH;
		}
		case BP_FLY_DOWN+1:
		{
			ANIMATE(1, 8, 9);
			
			if (o->blockd)
			{
				o->state = BP_HIT_FLOOR;
				o->damage = DMG_NORMAL;
				o->timer = 0;
				
				SmokeXY(o->CenterX(), o->Bottom(), 8);
				megaquake(10);
				
				spawn_bones(o, DOWN);
				FACEPLAYER;
			}
			
			if (pdistly(RUSH_DIST) && o->timer2 < 4)
				o->state = BP_PREPARE_FLY_LR;
		}
		break;
		
		case BP_HIT_FLOOR:	// hit floor
		{
			o->frame = 3;
			
			if (++o->timer > 30)
			{
				o->state = BP_FIGHTING_STANCE;
				o->timer = 120;
			}
		}
		break;
		
		
		// come back to ground while facing head on
		case BP_RETURN_TO_GROUND:
		{
			o->frame = 4;		// face screen frame
			o->dir = LEFT;		// non-flashing version
			
			o->state++;
		}
		case BP_RETURN_TO_GROUND+1:
		{
			ANIMATE(1, 4, 5);
			
			o->yinertia += 0x40;
			LIMITY(0x5ff);
			
			if (o->blockd && o->yinertia >= 0)
			{
				o->state++;
				o->timer = 0;
				o->frame = 3; 	// landed
				
				FACEPLAYER;
			}
		}
		break;
		
		case BP_RETURN_TO_GROUND+2:
		{
			o->xinertia *= 3;
			o->xinertia /= 4;
			
			if (++o->timer > 10)
			{
				o->state = BP_FIGHTING_STANCE;
				o->timer = 140;
			}
		}
		break;
	}
}
Exemplo n.º 10
0
// there is an apparent bug on the sprite sheet for this monster:
//	right-facing frame 1 is a duplicate of frame 0,
//	so the mouth-twitch animation does not work when
//	the frog is facing right.
void ai_frog(Object *o)
{
	switch(o->state)
	{
		case 0:
		{
			o->timer = 0;
			o->xinertia = 0;
			o->yinertia = 0;
			
			// non-normal dirs are used to indicate that this frog was
			// spawned by balfrog: we are falling out of ceiling during fight
			if (o->dir != LEFT && o->dir != RIGHT)
			{
				o->dir = random(0, 1) ? LEFT : RIGHT;
				o->flags |= FLAG_IGNORE_SOLID;
				
				o->state = 3;
				o->frame = 2;
			}
			else
			{
				o->flags &= ~FLAG_IGNORE_SOLID;
				o->state = 1;
			}
		}
		case 1:		// standing
		{
			o->timer++;
			
			if (!random(0, 50))
			{	// mouth-flitter animation
				o->state = 2;
				o->frame = 0;
				o->timer = 0;
				o->animtimer = 0;
			}
		}
		break;
		
		case 2:		// mouth flitter
		{
			ANIMATE(2, 0, 1);
			
			if (++o->timer > 18)
				o->state = 1;
		}
		break;
		
		case 3:		// falling out of ceiling during balfrog fight
		{
			if (++o->timer > 40)
			{
				o->flags &= ~FLAG_IGNORE_SOLID;
				
				if (o->blockd)
				{
					o->state = 0;
					o->frame = 0;
					o->timer = 0;
				}
			}
		}
		break;
		
		case 10:	// jumping
		case 11:
		{
			if (o->blockl && o->xinertia < 0)
			{
				o->dir = RIGHT;
				o->xinertia = -o->xinertia;
			}
			
			if (o->blockr && o->xinertia > 0)
			{
				o->dir = LEFT;
				o->xinertia = -o->xinertia;
			}
			
			if (o->blockd)
			{
				o->state = 0;
				o->frame = 0;
				o->timer = 0;
			}
		}
		break;
	}
	
	// random jumping, and jump when shot
	if (o->state < 3 && o->timer > 10)
	{
		bool dojump = false;
		
		if (o->shaketime)
		{
			dojump = true;
		}
		else if (pdistlx(0x14000) && pdistly(0x8000))
		{
			if (!random(0, 50))
			{
				dojump = true;
			}
		}
		
		if (dojump)
		{
			FACEPLAYER;
			o->state = 10;
			o->frame = 2;
			o->yinertia = -0x5ff;
			
			// no jumping sound in cutscenes at ending
			if (!player->inputs_locked && !player->disabled)
				sound(SND_ENEMY_JUMP);
			
			XMOVE(0x200);
		}
	}
	
	o->yinertia += 0x80;
	LIMITY(0x5ff);
}
Exemplo n.º 11
0
void ai_balrog_boss_running(Object *o)
{
	// try to catch player
	if (o->state == STATE_CHARGE+1 || o->state == STATE_JUMP)
	{
		if ((pdistlx(12 << CSF) && pdistly(8 << CSF)) && o->timer > 8)
		{
			hurtplayer(2);
			balrog_grab_player(o);
			o->state = STATE_CAUGHT_PLAYER;
		}
	}
	
	switch(o->state)
	{
		case 0:
		{
			FACEPLAYER;
			o->flags |= FLAG_SHOOTABLE;
			o->frame = 0;
			o->state = 1;
		}
		case 1:
		{
			if (++o->timer > 30)
			{
				o->state = STATE_CHARGE;
				o->timer2++;
			}
		}
		break;
		
		// running towards player
		case STATE_CHARGE:
		{
			o->state++;
			o->timer = 0;
			o->frame = 9;
			o->animtimer = 0;
		}
		case STATE_CHARGE+1:
		{
			XACCEL(0x10);
			walking_animation(o);
			
			if (++o->timer > 75 || \
				(o->dir == LEFT && o->blockl) ||
				(o->dir == RIGHT && o->blockr))
			{
				o->frame = 0;
				o->state = STATE_SLOW_DOWN;
				break;
			}
			
			// can jump every 3rd time, but if he catches the player
			// before he gets a chance to he does NOT jump on the next charge.
			if ((o->timer2 & 3) == 0)
			{
				if (o->timer > 25)
				{	// initiate jump
					o->frame = 3;
					o->yinertia = -0x400;
					o->state = STATE_JUMP;
				}
			}
		}
		break;
		
		// jumping
		case STATE_JUMP:
		{
			if (o->blockd && o->yinertia >= 0)
			{
				o->frame = 2;		// <-- Landed frame.
				quake(30);
				o->state = STATE_SLOW_DOWN;
			}
		}
		break;
		
		// slowing down after charging or jumping
		case STATE_SLOW_DOWN:
		{
			o->xinertia *= 4;
			o->xinertia /= 5;
			
			if (o->xinertia == 0)
				o->state = 0;
		}
		break;
		
		// caught player
		case STATE_CAUGHT_PLAYER:
		{
			if (balrog_toss_player_away(o))
				o->state = 0;
		}
		break;
	}
	
	o->yinertia += 0x20;
	LIMITX(0x400);
	LIMITY(0x5FF);
}