Ejemplo n.º 1
0
void ai_miserys_bubble(Object *o)
{
    Object *target;

    switch(o->state)
    {
    case 0:
    {
        // find the Toroko object we are to home in on
        target = mbubble_find_target();
        if (!target)
        {
            o->state = 9999;
            return;
        }

        o->xmark = target->x - (6 << CSF);
        o->ymark = target->y - (6 << CSF);

        ThrowObject(o, o->xmark, o->ymark, 0, (2 << CSF));
        o->state = 1;

        // correct values: 0x3F0, 0xAE
        NX_LOG("Computed toss values xi: 0x%x, 0x%x\n", o->xinertia, o->yinertia);
        NX_LOG("Target x/y: 0x%x, 0x%x\n", target->x, target->y);
    }
    case 1:
        ANIMATE(1, 0, 1);

        if (abs(o->x - o->xmark) <= (3 << CSF) && \
                abs(o->y - o->ymark) <= (3 << CSF))
        {
            o->state = 2;
            o->frame = 2;
            sound(SND_BUBBLE);

            if ((target = mbubble_find_target()))
                target->invisible = true;
        }
        break;

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

        o->xinertia -= 0x20;
        o->yinertia -= 0x20;
        LIMITX(0x5FF);
        LIMITY(0x5FF);

        if (o->y < -1000)
            o->Delete();
    }
    break;
    }
}
Ejemplo n.º 2
0
// cutscene igor
void ai_npc_igor(Object *o)
{
	switch(o->state)
	{
		case 0:		// init, standing/panting
			o->xinertia = 0;
			o->frame = 0;
			o->animtimer = 0;
			o->state = 1;
		case 1:
			ANIMATE(5, 0, 1);
		break;
		
		case 2:		// walking
			o->state = 3;
			o->frame = 2;
			o->animtimer = 0;
		case 3:
			ANIMATE(3, 2, 5);
			XMOVE(0x200);
		break;
		
		case 4:		// punch
			o->xinertia = 0;
			o->state = 5;
			o->timer = 0;
		case 5:
			o->frame = 6;
			if (++o->timer > 10)
			{
				o->timer = 0;
				o->state = 6;
				sound(SND_EXPL_SMALL);
			}
		break;
		case 6:
			o->frame = 7;
			if (++o->timer > 8)
			{
				o->state = 0;
				o->frame = 0;
			}
		break;
		
		case 7:
			o->state = 1;
		break;
	}
	
	o->yinertia += 0x40;
	LIMITY(0x5FF);
}
Ejemplo n.º 3
0
void ai_mesa_block(Object *o)
{
        ANIMATE(0, 0, 1);

        switch(o->state) {
        case 0: {	// being held
                if (!o->linkedobject || o->linkedobject->type == OBJ_MESA_DYING) {
                        o->Delete();
                }
        }
        break;

        case 1: {	// launched
                if (++o->timer == 4)
                        o->flags &= ~FLAG_IGNORE_SOLID;

                o->yinertia += 0x2A;
                LIMITY(0x5ff);

                if (o->blockd && o->yinertia >= 0) {
                        sound(SND_BLOCK_DESTROY);
                        o->Delete();
                }
        }
        break;
        }

        if (o->deleted) {
                SmokeClouds(o, 3, 0, 0);
                effect(o->x, o->y, EFFECT_BOOMFLASH);
        }
}
Ejemplo n.º 4
0
void ai_ironh_shot(Object *o)
{
	if (!o->state)
	{
		if (++o->timer > 20)
		{
			o->state = 1;
			o->xinertia = o->yinertia = 0;
			o->timer2 = 0;
		}
	}
	else
	{
		o->xinertia += 0x20;
	}
	
	ANIMATE(0, 0, 2);
	
	if (++o->timer2 > 100 && !o->onscreen)
	{
		o->Delete();
	}
	
	if ((o->timer2 & 3)==1) sound(SND_IRONH_SHOT_FLY);
}
Ejemplo n.º 5
0
void ai_green_devil(Object *o)
{
	switch(o->state)
	{
		case 0:
		{
			o->flags |= FLAG_SHOOTABLE;
			o->ymark = o->y;
			o->yinertia = random(-5<<CSF, 5<<CSF);
			o->damage = 3;
			o->state = 1;
		}
		case 1:
		{
			ANIMATE(2, 0, 1);
			o->yinertia += (o->y < o->ymark) ? 0x80 : -0x80;
			
			XACCEL(0x20);
			LIMITX(0x400);
			
			if (o->dir == LEFT)
			{
				if (o->x < -o->Width())
					o->Delete();
			}
			else
			{
				if (o->x > ((map.xsize * TILE_W) << CSF) + o->Width())
					o->Delete();
			}
		}
		break;
	}
	
}
Ejemplo n.º 6
0
// targeter for lightning strikes
void ai_ballos_target(Object *o)
{
	switch(o->state)
	{
		case 0:
		{
			// position to shoot lightning at passed as x,y
			o->xmark = o->CenterX() - ((sprites[SPR_LIGHTNING].w / 2) << CSF);
			o->ymark = o->CenterY();
			
			// adjust our Y coordinate to match player's
			o->y = player->CenterY();
			
			sound(SND_CHARGE_GUN);
			o->state = 1;
		}
		case 1:
		{
			ANIMATE(1, 0, 1);
			o->timer++;
			
			if (o->timer == 20 && o->dir == LEFT)
			{	// lightning attack
				// setting lightning dir=left: tells it do not flash screen
				CreateObject(o->xmark, o->ymark, OBJ_LIGHTNING)->dir = LEFT;
			}
			
			if (o->timer > 40)
				o->Delete();
		}
		break;
	}
	
}
Ejemplo n.º 7
0
void ai_doctor(Object *o)
{
	switch(o->state)
	{
		case 10:	// he chuckles
			o->state = 11;
			o->timer2 = 0;
			o->frame = 1;
			o->animtimer = 0;
		case 11:
			ANIMATE(6, 0, 1);
			if (++o->timer2 > 8*6) { o->frame = 0; o->state = 1; }
		break;
		
		case 20:	// he rises up and hovers
		{
			o->state = 21;
			o->timer = 0;
			o->frame = 2;
			o->ymark = o->y - (32 << CSF);
		}
		case 21:
		{
			o->yinertia += (o->y > o->ymark) ? -0x20 : 0x20;
			LIMITY(0x200);
		}
		break;
		
		case 30:	// he teleports away
		{
			o->timer = 0;
			o->frame = 2;
			o->yinertia = 0;
			o->state++;
		}
		case 31:
		{
			if (DoTeleportOut(o, 1))
				o->Delete();
		}
		break;
		
		case 40:	// he teleports in and hovers
		{
			o->timer = 0;
			o->state = 41;
			o->frame = 2;
		}
		case 41:
		{
			if (DoTeleportIn(o, 1))
			{
				o->state = 20;
				o->yinertia = -0x200;
			}
		}
		break;
	}
}
Ejemplo n.º 8
0
void ai_ballos_skull(Object *o)
{
	ANIMATE(8, 0, 3);
	
	switch(o->state)
	{
		case 0:
		{
			o->state = 100;
			o->frame = random(0, 16) & 3;
		}
		case 100:
		{
			o->yinertia += 0x40;
			LIMITY(0x700);
			
			if (o->timer++ & 2)
			{
				(SmokePuff(o->x, o->y))->PushBehind(o);
			}
			
			if (o->y > 0x10000)
			{
				o->flags &= ~FLAG_IGNORE_SOLID;
				
				if (o->blockd)
				{
					o->yinertia = -0x200;
					o->state = 110;
					o->flags |= FLAG_IGNORE_SOLID;
					
					quake(10, SND_BLOCK_DESTROY);
					
					for(int i=0;i<4;i++)
					{
						Object *s = SmokePuff(o->x + random(-12<<CSF, 12<<CSF), \
											  o->y + 0x2000);
						
						s->xinertia = random(-0x155, 0x155);
						s->yinertia = random(-0x600, 0);
						s->PushBehind(o);
					}
				}
			}
		}
		break;
		
		case 110:
		{
			o->yinertia += 0x40;
			
			if (o->Top() >= (map.ysize * TILE_H) << CSF)
			{
				o->Delete();
			}
		}
		break;
	}
}
Ejemplo n.º 9
0
void ai_bute_flying(Object *o)
{
        //AIDEBUG;
        if (run_bute_defeated(o, BUTE_HP))
                return;

        switch(o->state) {
        case 0: {
                o->invisible = true;
                o->state = 1;
        }
        case 1: {
                if (o->dir == LEFT) {
                        if (player->x > (o->x - (288<<CSF)) && \
                                        player->x < (o->x - (272<<CSF))) {
                                o->state = 10;
                        }
                } else {
                        if (player->x < (o->x + (288<<CSF)) && \
                                        player->x > (o->x + (272<<CSF))) {
                                o->state = 10;
                        }
                }
        }
        break;

        case 10: {
                o->state = 11;
                o->invisible = false;
                o->flags |= FLAG_SHOOTABLE;
                o->damage = 5;
        }
        case 11: {
                FACEPLAYER;
                ANIMATE(1, 0, 1);

                XACCEL(0x10);
                o->yinertia += (o->y > player->y) ? -0x10 : 0x10;

                LIMITX(0x5ff);
                LIMITY(0x5ff);

                if ((o->blockl && o->xinertia < 0) || \
                                (o->blockr && o->xinertia > 0)) {
                        o->xinertia = -o->xinertia;
                }

                if ((o->blockd && o->yinertia > 0) || \
                                (o->blocku && o->yinertia < 0)) {
                        o->yinertia = -o->yinertia;
                }


        }
        break;
        }

}
Ejemplo n.º 10
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;
	}
}
Ejemplo n.º 11
0
void ai_bute_falling(Object *o)
{
        ANIMATE(3, 0, 3);

        switch(o->state) {
        case 0: {
                o->state = 1;
                o->MoveAtDir(o->dir, 0x600);
                o->flags |= FLAG_IGNORE_SOLID;
        }
        case 1: {
                o->timer++;

                if (o->timer == 16) {
                        o->flags &= ~FLAG_IGNORE_SOLID;
                } else if (o->timer > 16 && o->block[o->dir]) {
                        o->state = 10;
                }

                if (o->timer > 20) {
                        switch(o->dir) {
                        case LEFT:
                                if (o->CenterX() <= player->CenterX() + (32<<CSF))
                                        o->state = 10;
                                break;

                        case RIGHT:
                                if (o->CenterX() >= player->CenterX() - (32<<CSF))
                                        o->state = 10;
                                break;

                        case UP:
                                if (o->CenterY() <= player->CenterY() + (32<<CSF))
                                        o->state = 10;
                                break;

                        case DOWN:
                                if (o->CenterY() >= player->CenterY() - (32<<CSF))
                                        o->state = 10;
                                break;
                        }
                }
        }
        break;

        case 10: {
                o->y += (4 << CSF);
                o->ChangeType(OBJ_BUTE_FLYING);
                o->state = 10;	// trigger flight immediately

                o->frame = 0;
                o->xinertia = 0;
                o->yinertia = 0;
        }
        break;
        }
}
Ejemplo n.º 12
0
void ai_misery_ring(Object *o)
{
	if (!o->linkedobject)
	{
		SmokeClouds(o, 3, 2, 2);
		o->Delete();
		return;
	}
	
	switch(o->state)
	{
		case 0:
		{
			o->state = 1;
			o->timer = 0;
		}
		case 1:
		{
			// distance from misery
			if (o->timer < 192)
				o->timer++;
			
			// turn to bats when misery teleports
			if (o->linkedobject->state >= STATE_TP_AWAY && \
				o->linkedobject->state < STATE_TP_AWAY+10)
			{
				o->state = 10;
			}
		}
		break;
		
		case 10:	// transform to bat
		{
			o->flags |= FLAG_SHOOTABLE;
			o->flags &= ~FLAG_INVULNERABLE;
			
			ThrowObjectAtPlayer(o, 3, 0x200);
			FACEPLAYER;
			
			o->sprite = SPR_ORANGE_BAT_FINAL;
			o->state = 11;
		}
		case 11:
		{
			ANIMATE(4, 0, 2);
			
			if ((o->dir == LEFT && o->blockl) || \
				(o->dir == RIGHT && o->blockr) || \
				o->blocku || o->blockd)
			{
				SmokeClouds(o, 3, 2, 2);
				o->Delete();
			}
		}
		break;
	}
}
Ejemplo n.º 13
0
void ai_mannan_shot(Object *o)
{
	XACCEL(0x20);
	ANIMATE(0, 1, 2);
	
	if ((o->timer & 3) == 1)
		sound(SND_IRONH_SHOT_FLY);
	
	if (++o->timer > 100)
		o->Delete();
}
Ejemplo n.º 14
0
void ai_black_lightning(Object *o)
{
	ANIMATE(0, 0, 1);
	o->yinertia = 0x1000;
	
	if (o->blockd)
	{
		effect(o->CenterX(), o->Bottom(), EFFECT_BOOMFLASH);
		SmokeXY(o->CenterX(), o->Bottom(), 3, o->Width()>>CSF, 4);
		o->Delete();
	}
Ejemplo n.º 15
0
void ai_firewhirr_shot(Object *o)
{
    ANIMATE(1, 0, 2);
    o->x += (o->dir==LEFT) ? -0x200 : 0x200;

    if ((o->dir==LEFT && o->blockl) || (o->dir==RIGHT && o->blockr))
    {
        if (o->dir == RIGHT) o->x += o->Width();
        effect(o->x, o->CenterY(), EFFECT_FISHY);
        o->Delete();
    }
}
Ejemplo n.º 16
0
void aftermove_blade_l12_shot(Object *o)
{
    int level = (o->shot.btype - B_BLADE_L1);
    ANIMATE(1, 0, 3);

    if (--o->shot.ttl < 0)
    {
        shot_dissipate(o);
        return;
    }

    // only start damaging enemies after we've passed the player
    // as it starts slightly behind him
    if (++o->timer >= 4)
    {
        Object *enemy;
        if ((enemy = damage_enemies(o)))
        {
            // on level 2 we can deal damage up to 3 times (18 max)
            if (level == 0 || \
                    ++o->timer2 >= 3 || (enemy->flags & FLAG_INVULNERABLE))
            {
                o->Delete();
                return;
            }
        }
        else if (IsBlockedInShotDir(o))
        {
            if (!shot_destroy_blocks(o))
                sound(SND_SHOT_HIT);

            shot_dissipate(o, EFFECT_STARSOLID);
            return;
        }
    }

    switch(level)
    {
    case 0:
        if ((o->timer % 5) == 1)
            sound(SND_FIREBALL);
        break;

    case 1:
        if ((o->timer % 7) == 1)
            sound(SND_SLASH);
        break;
    }
}
Ejemplo n.º 17
0
void ai_ironh_fishy(Object *o)
{
	switch(o->state)
	{
		case 0:
		{
			o->state = 10;
			o->animtimer = 0;
			o->yinertia = random(-0x200, 0x200);
			o->xinertia = 0x800;
		}
		case 10:			// harmless fishy
		{
			ANIMATE(2, 0, 1);
			if (o->xinertia < 0)
			{
				o->damage = 3;
				o->state = 20;
			}
		}
		break;
		
		case 20:			// puffer fish
		{
			ANIMATE(2, 2, 3);
			
			if (o->x < (48<<CSF))
				o->Delete();
		}
		break;
	}
	
	if (o->blocku) o->yinertia = 0x200;
	if (o->blockd) o->yinertia = -0x200;
	o->xinertia -= 0x0c;
}
Ejemplo n.º 18
0
void ai_fuzz_core(Object *o)
{
    ANIMATE(2, 0, 1);

    switch(o->state)
    {
    case 0:
    {
        // spawn mini-fuzzes
        int angle = 120;
        for(int i=0; i<5; i++)
        {
            Object *f = CreateObject(o->CenterX(), o->CenterY(), OBJ_FUZZ);
            f->linkedobject = o;
            f->angle = angle;
            angle += (256 / 5);
        }

        o->timer = random(1, 50);
        o->state = 1;
    }
    case 1:		// de-syncs the Y positions when multiple cores are present at once
    {
        if (--o->timer <= 0)
        {
            o->state = 2;
            o->yinertia = 0x300;
            o->ymark = o->y;
        }
    }
    break;

    case 2:
    {
        FACEPLAYER;

        if (o->y > o->ymark) o->yinertia -= 0x10;
        if (o->y < o->ymark) o->yinertia += 0x10;
        LIMITY(0x355);
    }
    break;
    }
}
Ejemplo n.º 19
0
void ai_toroko_teleport_in(Object *o)
{
	switch(o->state)
	{
		case 0:
		{
			o->state = 1;
			o->timer = 0;
			o->flags &= ~FLAG_IGNORE_SOLID;		// this is set in npc.tbl, but uh, why?
		}
		case 1:
		{
			if (DoTeleportIn(o, 2))
			{
				o->frame = 1;
				o->state = 2;
				o->animtimer = 0;
			}
		}
		break;
		
		case 2:
			ANIMATE(2, 1, 4);
			
			if (o->blockd)
			{
				o->state = 4;
				o->frame = 6;		// tripping frame
				sound(SND_THUD);
			}
		break;
		
		case 4: break;			// knocked out
	}
	
	// fall unless teleporting
	if (o->state >= 2)
	{
		o->yinertia += 0x20;
		LIMITY(0x5ff);
	}
}
Ejemplo n.º 20
0
void ai_bute_dying(Object *o)
{

	switch(o->state)
	{
		case 0:
		{
			o->flags &= ~(FLAG_SHOOTABLE | FLAG_IGNORE_SOLID | FLAG_SHOW_FLOATTEXT);
			o->damage = 0;
			o->frame = 0;
			o->animtimer = 0;
			o->state = 1;
			
			o->yinertia = -0x200;
		}
		case 1:
		{
			if (o->blockd && o->yinertia >= 0)
			{
				o->state = 2;
				o->timer = 0;
				o->frame = 1;
			}
		}
		break;
		
		case 2:
		{
			o->xinertia *= 8;
			o->xinertia /= 9;
			
			ANIMATE(3, 1, 2);
			
			if (++o->timer > 50)
				o->DealDamage(10000);
		}
		break;
	}
	
	o->yinertia += 0x20;
	LIMITY(0x5ff);
}
Ejemplo n.º 21
0
// The Doctor's red crystal.
// There are actually two, one is behind him and one is in front
// and they alternate visibility as they spin around him so it looks 3D.
//
// This function has to be an aftermove, otherwise, because one is in front
// and the other behind, one will be checking crystal_xmark before the Doctor
// updates it, and the other afterwards, and they will get out of sync.
void aftermove_red_crystal(Object *o)
{
	ANIMATE(3, 0, 1);
	
	switch(o->state)
	{
		case 0:
		{
			if (crystal_xmark != 0)
			{
				o->state = 1;
				crystal_tofront = true;
			}
		}
		break;
		
		case 1:
		{
			o->xinertia += (o->x < crystal_xmark) ? 0x55 : -0x55;
			o->yinertia += (o->y < crystal_ymark) ? 0x55 : -0x55;
			LIMITX(0x400);
			LIMITY(0x400);
			
			if ((o->dir == LEFT && o->xinertia > 0) || \
				(o->dir == RIGHT && o->xinertia < 0))
			{
				o->invisible = true;
			}
			else
			{
				o->invisible = false;
			}
		}
		break;
	}
	
	if (crystal_tofront && o->dir == LEFT)
	{
		o->BringToFront();
		crystal_tofront = false;
	}
}
Ejemplo n.º 22
0
void ai_misery_ball(Object *o)
{
  switch (o->state)
  {
    case 0:
    {
      o->state    = 1;
      o->ymark    = o->y;
      o->xinertia = 0;
      o->yinertia = -0x200;
    }
    case 1:
    {
      ANIMATE(2, 0, 1);

      o->xinertia += (o->x < player->x) ? 0x10 : -0x10;
      o->yinertia += (o->y < o->ymark) ? 0x20 : -0x20;
      LIMITX(0x200);
      LIMITY(0x200);

      if (pdistlx(8 * CSFI) && player->y > o->y)
      {
        o->state = 10;
        o->timer = 0;
      }
    }
    break;

    case 10: // black lightning
    {
      if (++o->timer > 10)
      {
        NXE::Sound::SoundManager::getInstance()->playSfx(NXE::Sound::SFX::SND_LIGHTNING_STRIKE);
        CreateObject(o->x, o->y, OBJ_BLACK_LIGHTNING);
        o->Delete();
      }

      o->frame = (o->timer & 2) ? 2 : 1;
    }
    break;
  }
}
Ejemplo n.º 23
0
// bones emitted by bone spawner
void ai_ballos_bone(Object *o)
{
	ANIMATE(3, 0, 2);
	
	if (o->blockd && o->yinertia >= 0)
	{
		if (o->state == 0)
		{
			o->yinertia = -0x200;
			o->state = 1;
		}
		else
		{
			effect(o->CenterX(), o->CenterY(), EFFECT_FISHY);
			o->Delete();
		}
	}
	
	o->yinertia += 0x40;
	LIMITY(0x5ff);
}
Ejemplo n.º 24
0
// from his "explosion" attack
void ai_doctor_blast(Object *o)
{
	// they're bouncy
	if ((o->blockl && o->xinertia < 0) || \
		(o->blockr && o->xinertia > 0))
	{
		o->xinertia = -o->xinertia;
	}
	
	if (o->blockd && o->yinertia > 0)
		o->yinertia = -0x200;
	
	if (o->blocku && o->yinertia < 0)
		o->yinertia = 0x200;
	
	ANIMATE(0, 0, 1);
	
	if ((++o->timer % 4) == 1)
		CreateObject(o->x, o->y, OBJ_DOCTOR_SHOT_TRAIL)->PushBehind(o);
	
	if (o->timer > 250)
		o->Delete();
}
Ejemplo n.º 25
0
// white sparky thing that moves along floor throwing out bones,
// spawned he hits the ground.
// similar to the red smoke-spawning ones from Undead Core.
void ai_ballos_bone_spawner(Object *o)
{
	switch(o->state)
	{
		case 0:
		{
			sound(SND_MISSILE_HIT);
			o->state = 1;
			
			XMOVE(0x400);
		}
		case 1:
		{
			ANIMATE(1, 0, 2);
			o->timer++;
			
			if ((o->timer % 6) == 1)
			{
				int xi = (random(4, 16) << CSF) / 8;
				
				if (o->dir == LEFT)
					xi = -xi;
				
				CreateObject(o->x, o->y, OBJ_BALLOS_BONE, xi, -0x400);
				sound(SND_BLOCK_DESTROY);
			}
			
			if ((o->blockl && o->xinertia < 0) || \
				(o->blockr && o->xinertia > 0))
			{
				o->Delete();
			}
		}
		break;
	}
	
}
Ejemplo n.º 26
0
void ai_red_bat(Object *o)
{
	ANIMATE(1, 0, 2);
	
	switch(o->state)
	{
		case 0:
		{
			o->state = 1;
			o->ymark = o->y;
			o->timer = random(0, 50);
		}
		case 1:
		{
			if (--o->timer < 0)
			{
				o->state = 2;
				o->yinertia = 0x400;
			}
			else break;
		}
		case 2:
		{
			o->yinertia += (o->y < o->ymark) ? 0x10 : -0x10;
			LIMITY(0x300);
			XMOVE(0x100);
		}
		break;
	}
	
	if (o->x < 0 || o->x > (map.xsize * TILE_W) << CSF)
	{
		effect(o->CenterX(), o->CenterY(), EFFECT_BOOMFLASH);
		o->Delete();
	}
}
Ejemplo n.º 27
0
void ai_intro_doctor(Object *o)
{

	switch(o->state)
	{
		case 0:
		{
			o->y -= (8 << CSF);
			o->state = 1;
		}
		case 1:
		{
			o->frame = 0;
		}
		break;
		
		case 10:	// chuckle; facing screen
		{
			o->state = 11;
			o->frame = 0;
			o->animtimer = 0;
			o->timer2 = 0;
		}
		case 11:
		{
			ANIMATE_FWD(6);
			if (o->frame > 1)
			{
				o->frame = 0;
				if (++o->timer2 > 7)
					o->state = 1;
			}
		}
		break;
		
		case 20:	// walk
		{
			o->state = 21;
			o->frame = 2;
			o->animtimer = 0;
		}
		case 21:
		{
			ANIMATE(10, 2, 5);
			o->x += 0x100;
		}
		break;
		
		case 30:	// face away
		{
			o->frame = 6;
			o->state = 31;
		}
		break;
		
		case 40:	// chuckle; facing away
		{
			o->state = 41;
			o->frame = 6;
			o->animtimer = 0;
			o->timer2 = 0;
		}
		case 41:
		{
			ANIMATE_FWD(6);
			if (o->frame > 7)
			{
				o->frame = 6;
				if (++o->timer2 > 7)
					o->state = 30;
			}
		}
		break;
	}
}
Ejemplo n.º 28
0
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;
			}
		}
Ejemplo n.º 29
0
// 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);
	}
}
Ejemplo n.º 30
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);
	}
	
}