Пример #1
0
void ai_gaudi_egg(Object *o)
{
    if (!o->state)
    {
        if (o->dir==LEFT)
        {   // on floor
            // align properly with ground
            o->y -= (4<<CSF);
            o->x -= (4<<CSF);
        }
        else
        {   // on ceiling
            // for the egg @ entrance point that is on a ceiling slope
            if (!o->blocku)
            {
                o->y -= (14 << CSF);
            }
        }
        o->state = 1;
    }
    else if (o->state == 1)
    {
        if (o->hp < 90)
        {
            o->frame = 1;
            o->damage = 0;
            o->flags &= ~FLAG_SHOOTABLE;
            SmokeSide(o, 6, (o->dir==LEFT)?DOWN:UP);
            o->SpawnPowerups();
            sound(objprop[o->type].death_sound);
            o->state = 2;
        }
    }
}
Пример #2
0
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);
	}
}
Пример #3
0
void ai_block_movev(Object *o)
{
	int py = player->CenterY();
	int objy = o->CenterY();
	
	switch(o->state)
	{
		case 0:
         NX_LOG("ai_block_movev - state 0.\n");
			o->flags |= FLAG_SOLID_BRICK;
			o->smushdamage = 100;
			o->dir = (o->dir == LEFT) ? UP : DOWN;
			o->state = (o->dir == DOWN) ? 10 : 20;
		break;
		
		case 10:	// at top edge, ready to travel down
         NX_LOG("ai_block_movev - state 10.\n");
			if (((py > objy) && (py - objy) < 0x32000) || \
				((py < objy) && (objy - py) < 0x3200))
			{
				if (pdistlx(0x3200))
				{
					o->state = 30;
					o->timer = 0;
				}
			}
		break;
		
		case 20:	// at bottom edge, ready to travel up
         NX_LOG("ai_block_movev - state 20.\n");
			if (((py > objy) && (py - objy) < 0x3200) || \
				((py < objy) && (objy - py) < 0x32000))
			{
				if (pdistlx(0x3200))
				{
					o->state = 30;
					o->timer = 0;
				}
			}
		break;
		
		case 30:	// traveling
         NX_LOG("ai_block_movev - state 30.\n");
		{
			YACCEL(0x20);
			LIMITY(0x200);
			
			// hit edge
			if ((o->dir == DOWN && o->blockd) || (o->dir == UP && o->blocku))
			{
				SmokeSide(o, 4, o->dir);
				quake(10);
				
				o->yinertia = 0;
				o->dir ^= 1;
				o->state = (o->dir==DOWN) ? 10 : 20;
			}
			
			if ((++o->timer % 10) == 6)
				sound(SND_BLOCK_MOVE);
		}
		break;
	}
}
Пример #4
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;
	}
}
Пример #5
0
// boss-fight igor
void ai_boss_igor(Object *o)
{
	enum
	{
		STATE_INIT = 0,
		STATE_STAND,
		
		STATE_BEGIN_ATTACK,
		STATE_WALK,
		
		STATE_JUMPING,
		STATE_LANDED,
		
		STATE_PUNCH,
		STATE_PUNCH_2,
		STATE_PUNCH_3,
		
		STATE_MOUTH_BLAST,
		STATE_MOUTH_BLAST_2
	};
	
	switch(o->state)
	{
		case STATE_INIT:
		{
			o->damage = 0;
			o->xinertia = 0;
			
			o->state = STATE_STAND;
			o->frame = 0;
			o->animtimer = 0;
		}
		case STATE_STAND:
		{
			ANIMATE(5, 0, 1);
			if (++o->timer > 50)
			{
				o->state = STATE_BEGIN_ATTACK;
			}
		}
		break;
		
		case STATE_BEGIN_ATTACK:
		{
			o->state = STATE_WALK;
			o->frame = 2;
			o->animtimer = 0;
			o->timer = 0;
			
			FACEPLAYER;
			o->igor.fireattack = false;
			
			// when health is less than halfway, then use
			// the mouth blast attack every third time.
			if (++o->timer2 >= 3 && \
				o->hp <= (objprop[o->type].initial_hp / 2))
			{
				o->timer2 = 0;
				o->igor.fireattack = true;
				o->dir ^= 1;	// walk away from player
			}
			
		}	// fall thru
		case STATE_WALK:
		{
			ANIMATE(3, 2, 5);
			XMOVE(0x200);
			
			if (o->igor.fireattack)
			{	// begin mouth-blast attack
				if (++o->timer > 16)
				{
					o->state = STATE_MOUTH_BLAST;
					o->xinertia = 0;
					o->frame = 10;
				}
			}
			else
			{
				if (o->dir == LEFT)
				{
					if (o->x <= player->x + player->Width())
						o->state = STATE_PUNCH;
				}
				else
				{
					if (o->x + o->Width() >= player->x)
						o->state = STATE_PUNCH;
				}
				
				// if we don't reach him after a while, do a jump
				if (++o->timer > 50)
				{
					o->frame = 10;
					o->yinertia = -0x400;
					o->state = STATE_JUMPING;
					o->timer = 0;
					
					o->xinertia *= 2;
					o->xinertia /= 3;
					
					o->damage = 2;
				}
			}
		}
		break;
		
		case STATE_PUNCH:
		{
			o->xinertia = 0;
			
			o->state = STATE_PUNCH_2;
			o->frame = 6;
			o->timer = 0;
		}
		case STATE_PUNCH_2:
		{
			if (++o->timer > 12)
			{
				sound(SND_EXPL_SMALL);
				
				// sprite appears identical, but has a wider bounding box.
				o->sprite = SPR_IGOR_PUNCHING;
				o->damage = 5;
				
				o->state = STATE_PUNCH_3;
				o->frame = 7;
				o->timer = 0;
			}
		}
		break;
		case STATE_PUNCH_3:
		{
			if (++o->timer > 10)
			{
				o->state = STATE_INIT;
				o->frame = 0;
				o->damage = 0;
				
				// return to normal-size bounding box
				o->sprite = SPR_IGOR;
			}
		}
		break;
		
		case STATE_JUMPING:
		{
			if (o->blockd)
			{
				sound(SND_QUAKE);
				SmokeSide(o, 4, DOWN);
				
				o->state = STATE_LANDED;
				o->frame = 11;
				o->timer = 0;
			}
		}
		break;
		
		case STATE_LANDED:
		{
			o->xinertia = 0;
			if (++o->timer > 10)
			{
				o->state = STATE_INIT;
				o->frame = 0;
				o->damage = 0;
			}
		}
		break;
		
		case STATE_MOUTH_BLAST:
		{
			FACEPLAYER;
			o->timer = 0;
			o->state++;
		}
		case STATE_MOUTH_BLAST_2:
		{
			o->timer++;
			
			// flash mouth
			o->frame = 8;
			if (o->timer > 50 && (o->timer & 2))
				o->frame = 9;
			
			// fire shots
			if (o->timer > 100)
			{
				if ((o->timer % 6) == 1)
				{
					sound(SND_BLOCK_DESTROY);
					Object *shot = SpawnObjectAtActionPoint(o, OBJ_IGOR_SHOT);
					
					int angle = (o->dir == LEFT) ? 136 : 248;
					angle += random(-16, 16);
					ThrowObjectAtAngle(shot, angle, 0x580);
				}
				
				if (o->timer > 132)		// fires 6 shots
				{
					o->state = STATE_INIT;
					o->timer = 0;
				}
			}
		}
		break;
	}
	
	o->yinertia += 0x40;
	LIMITY(0x5ff);
}