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
|
@ -4772,11 +4772,11 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
||||||
"S_METALSONIC_FLOAT",
|
"S_METALSONIC_FLOAT",
|
||||||
"S_METALSONIC_VECTOR",
|
"S_METALSONIC_VECTOR",
|
||||||
"S_METALSONIC_STUN",
|
"S_METALSONIC_STUN",
|
||||||
"S_METALSONIC_BLOCK",
|
|
||||||
"S_METALSONIC_RAISE",
|
"S_METALSONIC_RAISE",
|
||||||
"S_METALSONIC_GATHER",
|
"S_METALSONIC_GATHER",
|
||||||
"S_METALSONIC_DASH",
|
"S_METALSONIC_DASH",
|
||||||
"S_METALSONIC_BOUNCE",
|
"S_METALSONIC_BOUNCE",
|
||||||
|
"S_METALSONIC_BADBOUNCE",
|
||||||
"S_METALSONIC_SHOOT",
|
"S_METALSONIC_SHOOT",
|
||||||
"S_METALSONIC_PAIN",
|
"S_METALSONIC_PAIN",
|
||||||
"S_METALSONIC_DEATH",
|
"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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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
|
{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_PAIN, // painstate
|
||||||
S_METALSONIC_VECTOR,// painchance
|
S_METALSONIC_VECTOR,// painchance
|
||||||
sfx_dmpain, // painsound
|
sfx_dmpain, // painsound
|
||||||
S_METALSONIC_BLOCK, // meleestate
|
S_METALSONIC_BADBOUNCE, // meleestate
|
||||||
S_METALSONIC_SHOOT, // missilestate
|
S_METALSONIC_SHOOT, // missilestate
|
||||||
S_METALSONIC_DEATH, // deathstate
|
S_METALSONIC_DEATH, // deathstate
|
||||||
S_METALSONIC_FLEE1, // xdeathstate
|
S_METALSONIC_FLEE1, // xdeathstate
|
||||||
|
@ -4961,7 +4961,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
16*FRACUNIT, // radius
|
16*FRACUNIT, // radius
|
||||||
48*FRACUNIT, // height
|
48*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
sfx_mspogo, // mass
|
sfx_s3k5a, // mass
|
||||||
3, // damage
|
3, // damage
|
||||||
sfx_mswarp, // activesound
|
sfx_mswarp, // activesound
|
||||||
MF_NOGRAVITY|MF_BOSS|MF_SLIDEME, // flags
|
MF_NOGRAVITY|MF_BOSS|MF_SLIDEME, // flags
|
||||||
|
|
|
@ -1575,11 +1575,11 @@ typedef enum state
|
||||||
S_METALSONIC_FLOAT,
|
S_METALSONIC_FLOAT,
|
||||||
S_METALSONIC_VECTOR,
|
S_METALSONIC_VECTOR,
|
||||||
S_METALSONIC_STUN,
|
S_METALSONIC_STUN,
|
||||||
S_METALSONIC_BLOCK,
|
|
||||||
S_METALSONIC_RAISE,
|
S_METALSONIC_RAISE,
|
||||||
S_METALSONIC_GATHER,
|
S_METALSONIC_GATHER,
|
||||||
S_METALSONIC_DASH,
|
S_METALSONIC_DASH,
|
||||||
S_METALSONIC_BOUNCE,
|
S_METALSONIC_BOUNCE,
|
||||||
|
S_METALSONIC_BADBOUNCE,
|
||||||
S_METALSONIC_SHOOT,
|
S_METALSONIC_SHOOT,
|
||||||
S_METALSONIC_PAIN,
|
S_METALSONIC_PAIN,
|
||||||
S_METALSONIC_DEATH,
|
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
|
// Metal Sonic battle boss
|
||||||
// You CAN put multiple Metal Sonics in a single map
|
// You CAN put multiple Metal Sonics in a single map
|
||||||
// because I am a totally competent programmer who can do shit right.
|
// 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)
|
if (mobj->health <= 0)
|
||||||
return;
|
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->target || !(mobj->target->flags & MF_SHOOTABLE)))
|
||||||
{
|
{
|
||||||
|
if (mobj->tracer)
|
||||||
|
P_RemoveMobj(mobj->tracer);
|
||||||
P_BossTargetPlayer(mobj, false);
|
P_BossTargetPlayer(mobj, false);
|
||||||
if (mobj->target && (!P_IsObjectOnGround(mobj->target) || mobj->target->player->pflags & PF_SPINNING))
|
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
|
P_SetTarget(&mobj->target, NULL); // Wait for them to hit the ground first
|
||||||
if (!mobj->target) // Still no target, aww.
|
if (!mobj->target) // Still no target, aww.
|
||||||
{
|
{
|
||||||
// Reset the boss.
|
// Reset the boss.
|
||||||
|
if (mobj->tracer)
|
||||||
|
P_RemoveMobj(mobj->tracer);
|
||||||
P_SetMobjState(mobj, mobj->info->spawnstate);
|
P_SetMobjState(mobj, mobj->info->spawnstate);
|
||||||
mobj->fuse = 0;
|
mobj->fuse = 0;
|
||||||
mobj->momx = FixedDiv(mobj->momx, FRACUNIT + (FRACUNIT>>2));
|
mobj->momx = FixedDiv(mobj->momx, FRACUNIT + (FRACUNIT>>2));
|
||||||
mobj->momy = FixedDiv(mobj->momy, FRACUNIT + (FRACUNIT>>2));
|
mobj->momy = FixedDiv(mobj->momy, FRACUNIT + (FRACUNIT>>2));
|
||||||
mobj->momz = FixedDiv(mobj->momz, 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;
|
return;
|
||||||
}
|
}
|
||||||
else if (!mobj->fuse)
|
else if (!mobj->fuse)
|
||||||
|
@ -5745,7 +5776,8 @@ static void P_Boss9Thinker(mobj_t *mobj)
|
||||||
}
|
}
|
||||||
if (spawner) {
|
if (spawner) {
|
||||||
mobj_t *missile = P_SpawnMissile(spawner, mobj, MT_MSGATHER);
|
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)
|
if (dist == 0)
|
||||||
missile->fuse = 0;
|
missile->fuse = 0;
|
||||||
else
|
else
|
||||||
|
@ -5757,16 +5789,22 @@ static void P_Boss9Thinker(mobj_t *mobj)
|
||||||
|
|
||||||
// Pre-threshold reactiontime stuff for attack phases
|
// Pre-threshold reactiontime stuff for attack phases
|
||||||
if (mobj->reactiontime && mobj->movecount == 3) {
|
if (mobj->reactiontime && mobj->movecount == 3) {
|
||||||
|
mobj->reactiontime--;
|
||||||
|
|
||||||
if (mobj->movedir == 0 || mobj->movedir == 2) { // Pausing between bounces in the pinball phase
|
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?
|
if (mobj->target->player->powers[pw_tailsfly]) // Trying to escape, eh?
|
||||||
mobj->watertop = mobj->target->z + mobj->target->momz*6; // Readjust your aim. >:3
|
mobj->watertop = mobj->target->z + mobj->target->momz*6; // Readjust your aim. >:3
|
||||||
else
|
else
|
||||||
mobj->watertop = mobj->target->floorz + 16*FRACUNIT;
|
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);
|
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
|
// else -- Pausing between energy ball shots
|
||||||
mobj->reactiontime--;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5838,20 +5876,28 @@ static void P_Boss9Thinker(mobj_t *mobj)
|
||||||
P_InstaThrust(mobj, mobj->angle, 30*FRACUNIT);
|
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
|
if (!P_TryMove(mobj, mobj->x+mobj->momx, mobj->y+mobj->momy, true)) { // Hit a wall? Find a direction to bounce
|
||||||
mobj->threshold--;
|
mobj->threshold--;
|
||||||
if (mobj->threshold) {
|
P_SetMobjState(mobj, mobj->state->nextstate);
|
||||||
P_SetMobjState(mobj, mobj->state->nextstate);
|
if (!mobj->threshold) { // failed bounce!
|
||||||
if (mobj->info->mass)
|
S_StartSound(mobj, sfx_mspogo);
|
||||||
S_StartSound(mobj, mobj->info->mass);
|
P_BounceMove(mobj);
|
||||||
if (!(mobj->threshold%4)) { // We've decided to lock onto the player this bounce.
|
mobj->angle = R_PointToAngle2(mobj->momx, mobj->momy,0,0);
|
||||||
mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x + mobj->target->momx*4, mobj->target->y + mobj->target->momy*4);
|
mobj->momz = 4*FRACUNIT;
|
||||||
mobj->reactiontime = TICRATE; // targetting time
|
mobj->flags &= ~MF_PAIN;
|
||||||
} else { // No homing, just use P_BounceMove
|
mobj->fuse = 10*TICRATE;
|
||||||
P_BounceMove(mobj);
|
mobj->movecount = 0;
|
||||||
mobj->angle = R_PointToAngle2(0,0,mobj->momx,mobj->momy);
|
P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_CYBRAKDEMON_VILE_EXPLOSION);
|
||||||
mobj->reactiontime = TICRATE/4; // just a pause before you bounce away
|
P_SetMobjState(mobj, mobj->info->meleestate);
|
||||||
}
|
} else if (!(mobj->threshold%4)) { // We've decided to lock onto the player this bounce.
|
||||||
mobj->momx = mobj->momy = 0;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -5860,8 +5906,9 @@ static void P_Boss9Thinker(mobj_t *mobj)
|
||||||
mobj->angle += mobj->movedir;
|
mobj->angle += mobj->movedir;
|
||||||
P_InstaThrust(mobj, mobj->angle, -speed);
|
P_InstaThrust(mobj, mobj->angle, -speed);
|
||||||
while (!P_TryMove(mobj, mobj->x+mobj->momx, mobj->y+mobj->momy, true) && tries++ < 16) {
|
while (!P_TryMove(mobj, mobj->x+mobj->momx, mobj->y+mobj->momy, true) && tries++ < 16) {
|
||||||
mobj->angle += mobj->movedir;
|
S_StartSound(mobj, sfx_mspogo);
|
||||||
P_InstaThrust(mobj, mobj->angle, -speed);
|
P_BounceMove(mobj);
|
||||||
|
mobj->angle = R_PointToAngle2(mobj->momx, mobj->momy,0,0);
|
||||||
}
|
}
|
||||||
mobj->momx = mobj->momy = 0;
|
mobj->momx = mobj->momy = 0;
|
||||||
mobj->threshold--;
|
mobj->threshold--;
|
||||||
|
@ -5978,9 +6025,9 @@ static void P_Boss9Thinker(mobj_t *mobj)
|
||||||
S_StartSound(mobj, mobj->info->seesound);
|
S_StartSound(mobj, mobj->info->seesound);
|
||||||
P_SetMobjState(mobj, mobj->info->seestate);
|
P_SetMobjState(mobj, mobj->info->seestate);
|
||||||
if (mobj->movedir == 2)
|
if (mobj->movedir == 2)
|
||||||
mobj->threshold = 16; // bounce 16 times
|
mobj->threshold = 12; // bounce 12 times
|
||||||
else
|
else
|
||||||
mobj->threshold = 32; // bounce 32 times
|
mobj->threshold = 24; // bounce 24 times
|
||||||
mobj->watertop = mobj->target->floorz + 16*FRACUNIT;
|
mobj->watertop = mobj->target->floorz + 16*FRACUNIT;
|
||||||
P_LinedefExecute(LE_PINCHPHASE, mobj, NULL);
|
P_LinedefExecute(LE_PINCHPHASE, mobj, NULL);
|
||||||
} else {
|
} else {
|
||||||
|
@ -6063,14 +6110,7 @@ static void P_Boss9Thinker(mobj_t *mobj)
|
||||||
if (danger) {
|
if (danger) {
|
||||||
// An incoming attack is detected! What should we do?!
|
// An incoming attack is detected! What should we do?!
|
||||||
// Go into vector form!
|
// 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)));
|
vectorise;
|
||||||
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);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6085,6 +6125,7 @@ static void P_Boss9Thinker(mobj_t *mobj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#undef vectorise
|
||||||
|
|
||||||
//
|
//
|
||||||
// P_GetClosestAxis
|
// P_GetClosestAxis
|
||||||
|
|
Loading…
Reference in a new issue