void ai_proximity_press_vert(Object *o)
{
	switch(o->state)
	{
		case 0:
		{
			if (pdistlx(8<<CSF) && pdistly2(8<<CSF, 128<<CSF) && \
				!o->blockd)
			{
				o->state = 10;
				o->animtimer = 0;
				o->frame = 1;
			}
		}
		break;
		
		case 10:
		{
			if (o->frame < 2)
				ANIMATE_FWD(2);
			
			if (o->blockd)
			{
				if (o->frame >= 2)	// make sure eye fully open
				{
					SmokeSide(o, 4, DOWN);
					quake(10);
				}
				
				o->flags |= FLAG_SOLID_BRICK;
				o->damage = 0;
				
				o->state = 11;
				o->frame = 0;
			}
			else
			{
				if (player->Top() > o->CenterY())
				{
					o->flags &= ~FLAG_SOLID_BRICK;
					o->damage = 127;
				}
				else
				{
					o->flags |= FLAG_SOLID_BRICK;
					o->damage = 0;
				}
			}
		}
		break;
	}
	
	if (o->state >= 5)
	{
		o->yinertia += 0x80;
		LIMITY(0x5ff);
	}
}
void ai_press_vert(Object *o)
{
	switch(o->state)
	{
		case 0:
		{
			o->state = 1;
			o->y -= (4 << CSF);
			
			if (pdistlx((8<<CSF)) && pdistly2((8<<CSF), (128<<CSF)))
			{
				o->state = 5;
			}
		}
		break;
		
		case 5:
		{
			if (o->blockd)
			{
				o->state = 10;
				o->animtimer = 0;
				o->frame = 1;
			}
		}
		break;
		
		case 10:
		{
			ANIMATE_FWD(2);
			if (o->frame > 2)
				o->frame = 2;
			
			if (player->y > o->y)
				o->flags |= FLAG_SOLID_BRICK;
		}
		break;
	}
}
// used only for purple ones in maze
void ai_critter_shooting_purple(Object *o)
{

	switch(o->state)
	{
		case 0:
			o->state = STATE_IDLE;
			o->damage = CRITTER_DAMAGE;
		case STATE_IDLE:
		{
			o->frame = 0;		// assume not at attention
			if (o->timer >= 8)
			{
				if (pdistlx(96<<CSF) && pdistly2(96<<CSF, 32<<CSF))
				{
					FACEPLAYER;
					
					// close enough to attack?
					if (pdistlx(48<<CSF))
					{
						o->state = STATE_PREPARE_JUMP;
						o->frame = 0;
						o->timer = 0;
					}
					else
					{	// no, but stand at "attention"
						o->frame = 1;
					}
				}
			}
			else
			{
				o->timer++;
			}
			
			// also attack if shot
			if (o->shaketime)
			{
				o->state = STATE_PREPARE_JUMP;
				o->frame = 0;
				o->timer = 0;
			}
		}
		break;
		
		case STATE_PREPARE_JUMP:
		{
			o->frame = 1;
			if (++o->timer > 8)
			{
				FACEPLAYER;
				
				o->state = STATE_JUMP;
				o->timer = 0;
				o->frame = 2;
				
				sound(SND_ENEMY_JUMP);
				o->yinertia = -0x5ff;
			}
		}
		break;
		
		case STATE_JUMP:
		{
			if (o->yinertia > 0x100 || \
				(o->blockd && ++o->timer > 16))		// failsafe
			{
				o->ymark = o->y;
				
				o->state = STATE_HOVER;
				o->frame = 3;
				o->timer = 0;
				
				o->CurlyTargetHere(60, 100);
			}
		}
		break;
		
		case STATE_HOVER:
		{	// sinusoidal hover
			o->yinertia += (o->y > o->ymark) ? -0x10 : 0x10;
			LIMITY(0x200);
			
			FACEPLAYER;
			ANIMATE(0, 3, 5);
			
			// time to end flight?
			if (++o->timer > 60 || o->blocku)
			{
				o->damage = CRITTER_FALL_DAMAGE;
				o->state = STATE_END_JUMP;
				o->frame = 2;
				break;
			}
			
			if ((o->timer % 4) == 1)
				sound(SND_CRITTER_FLY);
			
			if ((o->timer % 30) == 6)
			{
				EmFireAngledShot(o, OBJ_CRITTER_SHOT, 6, 0x600);
				sound(SND_EM_FIRE);
			}
			
			if (o->blockd)
				o->yinertia = -0x200;
		}
		break;
		
		case STATE_END_JUMP:
		{
			if (o->blockd)
			{
				o->damage = 2;
				o->xinertia = 0;
				o->timer = 0;
				o->frame = 0;
				o->state = 0;
				sound(SND_THUD);
			}
		}
		break;
	}
	
	if (o->state != STATE_HOVER)
	{
		o->yinertia += 0x20;
		LIMITY(0x5ff);
	}
}
Exemple #4
0
void ai_bute_sword(Object *o)
{
	if (run_bute_defeated(o, BUTE_HP))
		return;
	
	switch(o->state)
	{
		case 0:
		{
			o->flags |= (FLAG_SHOOTABLE | FLAG_INVULNERABLE);
			o->nxflags |= NXFLAG_FOLLOW_SLOPE;
			o->damage = 0;
			o->state = 1;
		}
		case 1:		// lying in wait
		{
			FACEPLAYER;
			
			if (pdistlx(128<<CSF) && \
				pdistly2(128<<CSF, 16<<CSF))
			{
				o->state = 10;
			}
		}
		break;
		
		// wait a moment, then start running at player
		case 10:
		{
			o->flags |= FLAG_INVULNERABLE;
			o->damage = 0;
			o->frame = 0;
			
			o->state = 11;
			o->timer = 0;
		}
		case 11:
		{
			if (++o->timer > 30)
			{
				o->state = 20;
				o->timer = 0;
			}
		}
		break;
		
		// run at player and jump
		case 20:
		{
			o->flags &= ~FLAG_INVULNERABLE;
			o->state = 21;
			FACEPLAYER;
		}
		case 21:
		{
			ANIMATE(3, 0, 1);
			XMOVE(0x400);
			
			if (pdistlx(40<<CSF))
			{
				o->xinertia /= 2;
				o->yinertia = -0x300;
				
				o->state = 30;
				o->frame = 2;	// sword back, jumping
				sound(SND_ENEMY_JUMP);
			}
			else if (++o->timer > 50)
			{	// timeout, p got away
				o->state = 10;
				o->xinertia = 0;
			}
		}
		break;
		
		// jumping up
		case 30:
		{
			if (o->yinertia > -0x80)
			{
				o->frame = 3;	// sword swipe fwd
				o->damage = 9;
				
				o->state = 31;
				o->timer = 0;
			}
		}
		break;
		
		// swiping sword, in air
		case 31:
		{
			if (++o->timer > 2)
			{
				o->timer = 0;
				o->frame = 4;	// sword down, in front
			}
			
			if (o->blockd && o->yinertia > 0)
			{
				o->xinertia = 0;
				o->damage = 3;
				
				o->state = 32;
				o->timer = 0;
			}
		}
		break;
		
		case 32:
		{
			if (++o->timer > 30)
			{
				o->state = 10;
				o->timer = 0;
			}
		}
		break;
	}
	
	o->yinertia += 0x20;
	LIMITY(0x5ff);
}
Exemple #5
0
void ai_buyobuyo_base(Object *o)
{
    /*if (o->onscreen) {
    	debug("state: %d", o->state);
    	debug("timer: %d", o->timer);
    	debug("timer2: %d", o->timer2);
    }*/

    if (o->state < 3 && o->hp < (1000 - BUYOBUYO_BASE_HP))
    {
        SmokeClouds(o, objprop[o->type].death_smoke_amt, 8, 8);
        effect(o->CenterX(), o->CenterY(), EFFECT_BOOMFLASH);
        o->SpawnPowerups();

        o->flags &= ~FLAG_SHOOTABLE;
        o->damage = 0;

        o->state = 10;
        o->frame = 2;
    }

    switch(o->state)
    {
    case 0:
    {
        // ceiling has different bounding box and action point
        if (o->dir == RIGHT)
            o->sprite = SPR_BUYOBUYO_BASE_CEILING;

        o->state = 1;
        o->timer = 10;
    }
    case 1:
    {
        if (pdistlx(0x14000))
        {
            if ((o->dir == LEFT && pdistly2(0x14000, 0x2000)) || \
                    (o->dir == RIGHT && pdistly2(0x2000, 0x14000)))
            {
                if (--o->timer < 0)
                {
                    o->state = 2;
                    o->timer = 0;
                    o->animtimer = 0;
                }
            }
        }
    }
    break;

    case 2:
    {
        ANIMATE(3, 0, 1);

        if (++o->timer > 10)
        {
            Object *buyo = SpawnObjectAtActionPoint(o, OBJ_BUYOBUYO);
            buyo->dir = o->dir;

            sound(SND_EM_FIRE);
            o->frame = 0;
            o->CurlyTargetHere();

            // cyclic: three firings then pause
            o->state = 1;
            if (++o->timer2 > 2)
            {
                o->timer = 100;
                o->timer2 = 0;
            }
            else
            {
                o->timer = 20;
            }
        }
    }
    break;
    }
}
Exemple #6
0
void ai_critter(Object *o)
{
	switch(o->state)
	{
		case 0:
		{
			if (o->type == OBJ_POWER_CRITTER)
			{	// altered physics for Power Critter
				o->critter.jumpheight = 0x2800;
				o->critter.jumpgrav = 0x1C;
				o->critter.falldmg = 12;
			}
			else
			{
				o->critter.jumpheight = 0;
				o->critter.jumpgrav = 0x40;
				o->critter.falldmg = 3;
				
				if (o->type == OBJ_CRITTER_HOPPING_BLUE || 			// first cave
					o->type == OBJ_CRITTER_HOPPING_GREEN || 		// egg 1
					o->type == OBJ_CRITTER_HOPPING_AQUA ||			// egg 2
					o->type == OBJ_CRITTER_HOPPING_RED)				// last cave
				{
					o->critter.canfly = false;
					
					// critters in egg1 only 2 dmg
					if (o->type == OBJ_CRITTER_HOPPING_GREEN)
						o->critter.falldmg = 2;
					
					// critters in First Cave don't jump as high
					if (o->type != OBJ_CRITTER_HOPPING_BLUE)
					{
						o->critter.jumpgrav = 0x2C;
					}
				}
				else
				{
					// critters are purple in Maze
					o->sprite = SPR_CRITTER_FLYING_CYAN;
					
					o->critter.canfly = true;
				}
			}
			
			o->state = 1;
		} //fall thru
		case 1:
		{
			o->frame = 0;
			
			if (o->timer >= 8)
			{
				int attack_dist = (o->critter.canfly) ? (96 << CSF) : (64 << CSF);
				
				// close enough to attack?
				if (pdistlx(attack_dist) && pdistly2(96<<CSF, 48<<CSF))
				{
					o->state = 2;
					o->frame = 0;
					o->timer = 0;
				}
				else if (pdistlx(attack_dist + (32<<CSF)) && pdistly2(128<<CSF, 48<<CSF))
				{	// no, but close enough to look up at "attention" and watch player
					FACEPLAYER;
					o->frame = 1;
					o->timer = 8;	// reset timer to stop watching
				}
				else
				{
					// once a little time has passed stop watching him if he turns his back
					if ((o->x > player->x && player->dir==LEFT) || \
						(o->x < player->x && player->dir==RIGHT))
					{
						if (++o->timer >= 150)
						{
							o->frame = 0;
							o->timer = 8;
						}
					}
					else o->timer = 8;
				}
			}
			else
			{
				o->timer++;
			}
			
			if (o->shaketime)
			{	// attack if shot
				o->state = 2;
				o->frame = 0;
				o->timer = 0;
			}
		}
		break;
		
		case 2:		// start jump
		{
			if (++o->timer > 8)
			{
				o->state = 3;
				o->frame = 2;
				o->yinertia = -1228;
				sound(SND_ENEMY_JUMP);
				
				FACEPLAYER;
				XMOVE(0x100);
			}
		}
		break;
		
		case 3:		// jumping
		{
			// enter flying phase as we start to come down or
			// if we hit the ceiling.
			if (o->yinertia > 0x100 || o->blocku)
			{
				// during flight we will sine-wave oscilliate around this position
				o->ymark = (o->y - o->critter.jumpheight);
				
				o->state = 4;
				o->frame = 3;
				o->timer = 0;
			}
			else
			{
				if (o->blockd && o->yinertia >= 0)
				{	// jumped onto a platform before we got to fly--land immediately
					goto landed;
				}
				break;
			}
		}	// fall-thru
		case 4:		// flying
		{
			FACEPLAYER;
			
			// time to come down yet?
			// (come down immediately if we are not one of the flying critters)
			if (!o->critter.canfly || \
				o->blockl || o->blockr || o->blocku || \
				++o->timer > 100)
			{
				o->damage = o->critter.falldmg;			// increased damage if falls on player
				o->state = 5;
				o->frame = 2;
				o->yinertia /= 2;
			}
			else
			{
				// run the propeller
				ANIMATE(0, 3, 5);
				if ((o->timer & 3)==1) sound(SND_CRITTER_FLY);
				
				if (o->blockd) o->yinertia = -0x200;
			}
		}
		break;
		
		case 5:		// coming down from flight
		{
			if (o->blockd)
			{	// landed
landed: ;
				o->damage = 2;			// reset to normal damage
				o->state = 1;
				
				o->frame = 0;
				o->timer = 0;
				o->xinertia = 0;
				
				sound(SND_THUD);
			}
		}
		break;
	}
	
	if (o->state == 4)		// flying
	{
		// fly towards player
		o->xinertia += (o->x > player->x) ? -0x20 : 0x20;
		// sine-wave oscillate
		o->yinertia += (o->y > o->ymark) ? -0x10 : 0x10;
		
		LIMITX(0x200);
		LIMITY(0x200);
	}
	else if (o->state == 3 && o->yinertia < 0)	// jumping up
	{
		o->yinertia += o->critter.jumpgrav;
	}
	else
	{
		o->yinertia += 0x40;
	}
	
	LIMITY(0x5ff);
}
Exemple #7
0
void ai_bat_hang(Object *o)
{
	switch(o->state)
	{
		case 0:
			o->state = 1;
		case 1:		// hanging and waiting
			if (!random(0, 100))
			{
				o->state = 2;
				o->timer = 0;
				o->frame = 1;
			}
			
			if (pdistlx(0x1000) && pdistly2(0x1000, 0x9000))
			{
				o->frame = 0;
				o->state = 3;
			}
		break;
		
		case 2:		// blinking
			if (++o->timer > 8)
			{
				o->state = 1;
				o->frame = 0;
			}
		break;
		
		case 3:		// at attention
			o->frame = 0;
			if (o->shaketime || pdistlx(0x2800))
			{
				o->frame = 1;
				o->animtimer = 0;
				o->state = 4;
				o->timer = 0;
			}
		break;
		
		case 4:		// falling
			o->yinertia += 0x20;
			LIMITY(0x5ff);
			
			o->timer++;
			if (o->timer > 20 || o->blockd)
			{
				if (o->blockd || ((player->y - 0x2000) < o->y))
				{	// start flying
					o->animtimer = 0;
					o->frame = 2;
					o->state = 5;
					o->ymark = o->y;
					if (o->blockd) o->yinertia = -0x200;
				}
			}
		break;
		
		case 5:		// flying
			ANIMATE(1, 2, 4);
			FACEPLAYER;
			
			o->xinertia += (o->x > player->x) ? -0x20 : 0x20;
			o->yinertia += (o->y > o->ymark) ? -0x10 : 0x10;
			
			LIMITX(0x200);
			LIMITY(0x200);
			
			if (o->blockd) o->yinertia = -0x200;
			if (o->blockr) o->yinertia = 0x200;
		break;
	}
}