mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-03-23 19:31:05 +00:00
Merge branch 'metal_unsuck' into 'master'
Making Metal's pinch cues suck less Does what it says on the tin. Give it a shot with <root>/toaster/metaltest.wad to skip the race and go directly to the boss to see what it does! See merge request !70
This commit is contained in:
commit
4f80bd82a5
4 changed files with 77 additions and 36 deletions
|
@ -4772,11 +4772,11 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_METALSONIC_FLOAT",
|
||||
"S_METALSONIC_VECTOR",
|
||||
"S_METALSONIC_STUN",
|
||||
"S_METALSONIC_BLOCK",
|
||||
"S_METALSONIC_RAISE",
|
||||
"S_METALSONIC_GATHER",
|
||||
"S_METALSONIC_DASH",
|
||||
"S_METALSONIC_BOUNCE",
|
||||
"S_METALSONIC_BADBOUNCE",
|
||||
"S_METALSONIC_SHOOT",
|
||||
"S_METALSONIC_PAIN",
|
||||
"S_METALSONIC_DEATH",
|
||||
|
|
10
src/info.c
10
src/info.c
|
@ -1369,14 +1369,14 @@ state_t states[NUMSTATES] =
|
|||
{SPR_METL, 4, -1, {NULL}, 0, 0, S_NULL}, // S_METALSONIC_FLOAT
|
||||
{SPR_METL, 12, -1, {NULL}, 0, 0, S_METALSONIC_STUN}, // S_METALSONIC_VECTOR
|
||||
{SPR_METL, 0, -1, {NULL}, 0, 0, S_METALSONIC_FLOAT}, // S_METALSONIC_STUN
|
||||
{SPR_METL, 13, -1, {NULL}, 0, 0, S_NULL}, // S_METALSONIC_BLOCK
|
||||
{SPR_METL, 13, 40, {NULL}, 0, 0, S_METALSONIC_GATHER},// S_METALSONIC_RAISE
|
||||
{SPR_METL, 14, -1, {NULL}, 0, 0, S_NULL}, // S_METALSONIC_GATHER
|
||||
{SPR_METL, 9, -1, {NULL}, 0, 0, S_METALSONIC_BOUNCE},// S_METALSONIC_DASH
|
||||
{SPR_METL, 15, -1, {NULL}, 0, 0, S_METALSONIC_BOUNCE},// S_METALSONIC_DASH
|
||||
{SPR_METL, 14, -1, {NULL}, 0, 0, S_NULL}, // S_METALSONIC_BOUNCE
|
||||
{SPR_METL, 16, -1, {NULL}, 0, 0, S_NULL}, // S_METALSONIC_BADBOUNCE
|
||||
{SPR_METL, 13, -1, {NULL}, 0, 0, S_METALSONIC_GATHER},// S_METALSONIC_SHOOT
|
||||
{SPR_METL, 11, 40, {A_Pain}, 0, 0, S_METALSONIC_FLOAT}, // S_METALSONIC_PAIN
|
||||
{SPR_METL, 0, -1, {A_BossDeath}, 0, 0, S_NULL}, // S_METALSONIC_DEATH
|
||||
{SPR_METL, 11, -1, {A_BossDeath}, 0, 0, S_NULL}, // S_METALSONIC_DEATH
|
||||
{SPR_METL, 3, 4, {NULL}, 0, 0, S_METALSONIC_FLEE2}, // S_METALSONIC_FLEE1
|
||||
{SPR_METL, 4, 4, {A_BossScream}, 0, 0, S_METALSONIC_FLEE3}, // S_METALSONIC_FLEE2
|
||||
{SPR_METL, 5, 4, {NULL}, 0, 0, S_METALSONIC_FLEE4}, // S_METALSONIC_FLEE3
|
||||
|
@ -4952,7 +4952,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_METALSONIC_PAIN, // painstate
|
||||
S_METALSONIC_VECTOR,// painchance
|
||||
sfx_dmpain, // painsound
|
||||
S_METALSONIC_BLOCK, // meleestate
|
||||
S_METALSONIC_BADBOUNCE, // meleestate
|
||||
S_METALSONIC_SHOOT, // missilestate
|
||||
S_METALSONIC_DEATH, // deathstate
|
||||
S_METALSONIC_FLEE1, // xdeathstate
|
||||
|
@ -4961,7 +4961,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
16*FRACUNIT, // radius
|
||||
48*FRACUNIT, // height
|
||||
0, // display offset
|
||||
sfx_mspogo, // mass
|
||||
sfx_s3k5a, // mass
|
||||
3, // damage
|
||||
sfx_mswarp, // activesound
|
||||
MF_NOGRAVITY|MF_BOSS|MF_SLIDEME, // flags
|
||||
|
|
|
@ -1575,11 +1575,11 @@ typedef enum state
|
|||
S_METALSONIC_FLOAT,
|
||||
S_METALSONIC_VECTOR,
|
||||
S_METALSONIC_STUN,
|
||||
S_METALSONIC_BLOCK,
|
||||
S_METALSONIC_RAISE,
|
||||
S_METALSONIC_GATHER,
|
||||
S_METALSONIC_DASH,
|
||||
S_METALSONIC_BOUNCE,
|
||||
S_METALSONIC_BADBOUNCE,
|
||||
S_METALSONIC_SHOOT,
|
||||
S_METALSONIC_PAIN,
|
||||
S_METALSONIC_DEATH,
|
||||
|
|
99
src/p_mobj.c
99
src/p_mobj.c
|
@ -5641,6 +5641,15 @@ static void P_Boss7Thinker(mobj_t *mobj)
|
|||
|
||||
}
|
||||
|
||||
#define vectorise mobj->movedir = ANGLE_11hh - FixedAngle(FixedMul(AngleFixed(ANGLE_11hh), FixedDiv((mobj->info->spawnhealth - mobj->health)<<FRACBITS, (mobj->info->spawnhealth-1)<<FRACBITS)));\
|
||||
if (P_RandomChance(FRACUNIT/2))\
|
||||
mobj->movedir = InvAngle(mobj->movedir);\
|
||||
mobj->threshold = 6 + (FixedMul(24<<FRACBITS, FixedDiv((mobj->info->spawnhealth - mobj->health)<<FRACBITS, (mobj->info->spawnhealth-1)<<FRACBITS))>>FRACBITS);\
|
||||
if (mobj->info->activesound)\
|
||||
S_StartSound(mobj, mobj->info->activesound);\
|
||||
if (mobj->info->painchance)\
|
||||
P_SetMobjState(mobj, mobj->info->painchance)
|
||||
|
||||
// Metal Sonic battle boss
|
||||
// You CAN put multiple Metal Sonics in a single map
|
||||
// because I am a totally competent programmer who can do shit right.
|
||||
|
@ -5685,19 +5694,41 @@ static void P_Boss9Thinker(mobj_t *mobj)
|
|||
if (mobj->health <= 0)
|
||||
return;
|
||||
|
||||
if ((statenum_t)(mobj->state-states) == mobj->info->meleestate)
|
||||
{
|
||||
P_InstaThrust(mobj, mobj->angle, -4*FRACUNIT);
|
||||
P_TryMove(mobj, mobj->x+mobj->momx, mobj->y+mobj->momy, true);
|
||||
mobj->momz -= gravity;
|
||||
if (mobj->z < mobj->watertop)
|
||||
{
|
||||
mobj->watertop = mobj->target->floorz + 32*FRACUNIT;
|
||||
P_SetMobjState(mobj, mobj->info->spawnstate);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ((!mobj->target || !(mobj->target->flags & MF_SHOOTABLE)))
|
||||
{
|
||||
if (mobj->tracer)
|
||||
P_RemoveMobj(mobj->tracer);
|
||||
P_BossTargetPlayer(mobj, false);
|
||||
if (mobj->target && (!P_IsObjectOnGround(mobj->target) || mobj->target->player->pflags & PF_SPINNING))
|
||||
P_SetTarget(&mobj->target, NULL); // Wait for them to hit the ground first
|
||||
if (!mobj->target) // Still no target, aww.
|
||||
{
|
||||
// Reset the boss.
|
||||
if (mobj->tracer)
|
||||
P_RemoveMobj(mobj->tracer);
|
||||
P_SetMobjState(mobj, mobj->info->spawnstate);
|
||||
mobj->fuse = 0;
|
||||
mobj->momx = FixedDiv(mobj->momx, FRACUNIT + (FRACUNIT>>2));
|
||||
mobj->momy = FixedDiv(mobj->momy, FRACUNIT + (FRACUNIT>>2));
|
||||
mobj->momz = FixedDiv(mobj->momz, FRACUNIT + (FRACUNIT>>2));
|
||||
mobj->watertop = mobj->floorz + 32*FRACUNIT;
|
||||
mobj->momz = (mobj->watertop - mobj->z)>>3;
|
||||
mobj->threshold = 0;
|
||||
mobj->movecount = 0;
|
||||
mobj->flags = mobj->info->flags;
|
||||
return;
|
||||
}
|
||||
else if (!mobj->fuse)
|
||||
|
@ -5745,7 +5776,8 @@ static void P_Boss9Thinker(mobj_t *mobj)
|
|||
}
|
||||
if (spawner) {
|
||||
mobj_t *missile = P_SpawnMissile(spawner, mobj, MT_MSGATHER);
|
||||
missile->momz = FixedDiv(missile->momz, 7*FRACUNIT/4);
|
||||
if (mobj->health > mobj->info->damage)
|
||||
missile->momz = FixedDiv(missile->momz, 7*FRACUNIT/5);
|
||||
if (dist == 0)
|
||||
missile->fuse = 0;
|
||||
else
|
||||
|
@ -5757,16 +5789,22 @@ static void P_Boss9Thinker(mobj_t *mobj)
|
|||
|
||||
// Pre-threshold reactiontime stuff for attack phases
|
||||
if (mobj->reactiontime && mobj->movecount == 3) {
|
||||
mobj->reactiontime--;
|
||||
|
||||
if (mobj->movedir == 0 || mobj->movedir == 2) { // Pausing between bounces in the pinball phase
|
||||
if (mobj->target->player->powers[pw_tailsfly]) // Trying to escape, eh?
|
||||
mobj->watertop = mobj->target->z + mobj->target->momz*6; // Readjust your aim. >:3
|
||||
else
|
||||
mobj->watertop = mobj->target->floorz + 16*FRACUNIT;
|
||||
if (!(mobj->threshold%4))
|
||||
|
||||
if (!(mobj->threshold%4)) {
|
||||
mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x + mobj->target->momx*4, mobj->target->y + mobj->target->momy*4);
|
||||
if (!mobj->reactiontime)
|
||||
S_StartSound(mobj, sfx_zoom); // zoom!
|
||||
}
|
||||
}
|
||||
// Pausing between energy ball shots
|
||||
mobj->reactiontime--;
|
||||
// else -- Pausing between energy ball shots
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -5838,20 +5876,28 @@ static void P_Boss9Thinker(mobj_t *mobj)
|
|||
P_InstaThrust(mobj, mobj->angle, 30*FRACUNIT);
|
||||
if (!P_TryMove(mobj, mobj->x+mobj->momx, mobj->y+mobj->momy, true)) { // Hit a wall? Find a direction to bounce
|
||||
mobj->threshold--;
|
||||
if (mobj->threshold) {
|
||||
P_SetMobjState(mobj, mobj->state->nextstate);
|
||||
if (mobj->info->mass)
|
||||
S_StartSound(mobj, mobj->info->mass);
|
||||
if (!(mobj->threshold%4)) { // We've decided to lock onto the player this bounce.
|
||||
mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x + mobj->target->momx*4, mobj->target->y + mobj->target->momy*4);
|
||||
mobj->reactiontime = TICRATE; // targetting time
|
||||
} else { // No homing, just use P_BounceMove
|
||||
P_BounceMove(mobj);
|
||||
mobj->angle = R_PointToAngle2(0,0,mobj->momx,mobj->momy);
|
||||
mobj->reactiontime = TICRATE/4; // just a pause before you bounce away
|
||||
}
|
||||
mobj->momx = mobj->momy = 0;
|
||||
P_SetMobjState(mobj, mobj->state->nextstate);
|
||||
if (!mobj->threshold) { // failed bounce!
|
||||
S_StartSound(mobj, sfx_mspogo);
|
||||
P_BounceMove(mobj);
|
||||
mobj->angle = R_PointToAngle2(mobj->momx, mobj->momy,0,0);
|
||||
mobj->momz = 4*FRACUNIT;
|
||||
mobj->flags &= ~MF_PAIN;
|
||||
mobj->fuse = 10*TICRATE;
|
||||
mobj->movecount = 0;
|
||||
P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_CYBRAKDEMON_VILE_EXPLOSION);
|
||||
P_SetMobjState(mobj, mobj->info->meleestate);
|
||||
} else if (!(mobj->threshold%4)) { // We've decided to lock onto the player this bounce.
|
||||
S_StartSound(mobj, sfx_s3k5a);
|
||||
mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x + mobj->target->momx*4, mobj->target->y + mobj->target->momy*4);
|
||||
mobj->reactiontime = TICRATE - 5*(mobj->info->damage - mobj->health); // targetting time
|
||||
} else { // No homing, just use P_BounceMove
|
||||
S_StartSound(mobj, sfx_s3kaa); // make the bounces distinct...
|
||||
P_BounceMove(mobj);
|
||||
mobj->angle = R_PointToAngle2(0,0,mobj->momx,mobj->momy);
|
||||
mobj->reactiontime = 1; // TICRATE/4; // just a pause before you bounce away
|
||||
}
|
||||
mobj->momx = mobj->momy = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -5860,8 +5906,9 @@ static void P_Boss9Thinker(mobj_t *mobj)
|
|||
mobj->angle += mobj->movedir;
|
||||
P_InstaThrust(mobj, mobj->angle, -speed);
|
||||
while (!P_TryMove(mobj, mobj->x+mobj->momx, mobj->y+mobj->momy, true) && tries++ < 16) {
|
||||
mobj->angle += mobj->movedir;
|
||||
P_InstaThrust(mobj, mobj->angle, -speed);
|
||||
S_StartSound(mobj, sfx_mspogo);
|
||||
P_BounceMove(mobj);
|
||||
mobj->angle = R_PointToAngle2(mobj->momx, mobj->momy,0,0);
|
||||
}
|
||||
mobj->momx = mobj->momy = 0;
|
||||
mobj->threshold--;
|
||||
|
@ -5978,9 +6025,9 @@ static void P_Boss9Thinker(mobj_t *mobj)
|
|||
S_StartSound(mobj, mobj->info->seesound);
|
||||
P_SetMobjState(mobj, mobj->info->seestate);
|
||||
if (mobj->movedir == 2)
|
||||
mobj->threshold = 16; // bounce 16 times
|
||||
mobj->threshold = 12; // bounce 12 times
|
||||
else
|
||||
mobj->threshold = 32; // bounce 32 times
|
||||
mobj->threshold = 24; // bounce 24 times
|
||||
mobj->watertop = mobj->target->floorz + 16*FRACUNIT;
|
||||
P_LinedefExecute(LE_PINCHPHASE, mobj, NULL);
|
||||
} else {
|
||||
|
@ -6063,14 +6110,7 @@ static void P_Boss9Thinker(mobj_t *mobj)
|
|||
if (danger) {
|
||||
// An incoming attack is detected! What should we do?!
|
||||
// Go into vector form!
|
||||
mobj->movedir = ANGLE_11hh - FixedAngle(FixedMul(AngleFixed(ANGLE_11hh), FixedDiv((mobj->info->spawnhealth - mobj->health)<<FRACBITS, (mobj->info->spawnhealth-1)<<FRACBITS)));
|
||||
if (P_RandomChance(FRACUNIT/2))
|
||||
mobj->movedir = InvAngle(mobj->movedir);
|
||||
mobj->threshold = 6 + (FixedMul(24<<FRACBITS, FixedDiv((mobj->info->spawnhealth - mobj->health)<<FRACBITS, (mobj->info->spawnhealth-1)<<FRACBITS))>>FRACBITS);
|
||||
if (mobj->info->activesound)
|
||||
S_StartSound(mobj, mobj->info->activesound);
|
||||
if (mobj->info->painchance)
|
||||
P_SetMobjState(mobj, mobj->info->painchance);
|
||||
vectorise;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -6085,6 +6125,7 @@ static void P_Boss9Thinker(mobj_t *mobj)
|
|||
}
|
||||
}
|
||||
}
|
||||
#undef vectorise
|
||||
|
||||
//
|
||||
// P_GetClosestAxis
|
||||
|
|
Loading…
Reference in a new issue