* Add vwre vwre intro for Fang Clone Fighter battle. (Still skipped with presence of MTF_AMBUSH)

* https://cdn.discordapp.com/attachments/428262628893261828/626792815451701259/srb20006.gif
* Add fadeout instead of slapstick for Fang Clone Fighter death.
* Allow placed Fang and Metal Sonic objects to be marked as Clone Fighters always through presence of MTF_EXTRA.
This commit is contained in:
toaster 2019-09-26 17:06:29 +01:00
parent 313fed2a59
commit ec1712064c
8 changed files with 248 additions and 17 deletions

View File

@ -4786,6 +4786,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
// Boss 5
"S_FANG_SETUP",
"S_FANG_INTRO0",
"S_FANG_INTRO1",
"S_FANG_INTRO2",
"S_FANG_INTRO3",
@ -4798,6 +4799,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_FANG_INTRO10",
"S_FANG_INTRO11",
"S_FANG_INTRO12",
"S_FANG_CLONE1",
"S_FANG_CLONE2",
"S_FANG_CLONE3",
"S_FANG_CLONE4",
"S_FANG_IDLE0",
"S_FANG_IDLE1",
"S_FANG_IDLE2",
@ -4881,6 +4886,15 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_ALART1",
"S_ALART2",
"S_VWREF",
"S_VWREB",
"S_PROJECTORLIGHT1",
"S_PROJECTORLIGHT2",
"S_PROJECTORLIGHT3",
"S_PROJECTORLIGHT4",
"S_PROJECTORLIGHT5",
"S_FBOMB1",
"S_FBOMB2",
"S_FBOMB_EXPL1",
@ -7291,6 +7305,9 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
// Boss 5
"MT_FANG",
"MT_BROKENROBOT",
"MT_VWREF",
"MT_VWREB",
"MT_PROJECTORLIGHT",
"MT_FBOMB",
"MT_TNTDUST", // also used by barrel
"MT_FSGNA",

View File

@ -204,13 +204,15 @@ light_t *t_lspr[NUMSPRITES] =
&lspr[NOLIGHT], // SPR_EGR1
// Boss 5 (Arid Canyon)
&lspr[NOLIGHT], //SPR_FANG // replaces EGGQ
&lspr[NOLIGHT], //SPR_BRKN
&lspr[NOLIGHT], //SPR_WHAT
&lspr[NOLIGHT], //SPR_FBOM
&lspr[NOLIGHT], //SPR_FSGN
&lspr[REDBALL_L], //SPR_BARX // bomb explosion (also used by barrel)
&lspr[NOLIGHT], //SPR_BARD // bomb dust (also used by barrel)
&lspr[NOLIGHT], // SPR_FANG // replaces EGGQ
&lspr[NOLIGHT], // SPR_BRKN
&lspr[NOLIGHT], // SPR_WHAT
&lspr[INVINCIBLE_L], // SPR_VWRE
&lspr[INVINCIBLE_L], // SPR_PROJ
&lspr[NOLIGHT], // SPR_FBOM
&lspr[NOLIGHT], // SPR_FSGN
&lspr[REDBALL_L], // SPR_BARX // bomb explosion (also used by barrel)
&lspr[NOLIGHT], // SPR_BARD // bomb dust (also used by barrel)
// Boss 6 (Red Volcano)
&lspr[NOLIGHT], // SPR_EEGR

View File

@ -95,6 +95,8 @@ char sprnames[NUMSPRITES + 1][5] =
"FANG", // replaces EGGQ
"BRKN", // broken robot chunk
"WHAT", // alart
"VWRE",
"PROJ", // projector light
"FBOM",
"FSGN",
"BARX", // bomb explosion (also used by barrel)
@ -1350,9 +1352,10 @@ state_t states[NUMSTATES] =
{SPR_EFIR, FF_FULLBRIGHT|2, -1, {NULL}, 0, 0, S_NULL}, // S_EGGROBOJET
// Boss 5
{SPR_NULL, 0, 2, {A_CheckFlags2}, MF2_AMBUSH, S_FANG_IDLE0, S_FANG_INTRO1}, // S_FANG_SETUP
{SPR_NULL, 0, 2, {A_CheckFlags2}, MF2_AMBUSH, S_FANG_IDLE0, S_FANG_INTRO0}, // S_FANG_SETUP
{SPR_NULL, 0, 2, {A_Boss5MakeJunk}, 0, 0, S_FANG_INTRO2}, // S_FANG_INTRO1
{SPR_NULL, 0, 2, {NULL}, 0, 0, S_FANG_INTRO1}, // S_FANG_INTRO0
{SPR_NULL, 0, 2, {A_Boss5MakeJunk}, -S_FANG_CLONE1, 0, S_FANG_INTRO2}, // S_FANG_INTRO1
{SPR_NULL, 0, 0, {A_Repeat}, 25, S_FANG_INTRO1, S_FANG_INTRO3}, // S_FANG_INTRO2
{SPR_NULL, 0, 0, {A_Boss5MakeJunk}, 0, 1, S_FANG_INTRO4}, // S_FANG_INTRO3
{SPR_FANG, 30, 1, {A_ZThrust}, 9, (1<<16)|1, S_FANG_INTRO5}, // S_FANG_INTRO4
@ -1365,6 +1368,11 @@ state_t states[NUMSTATES] =
{SPR_FANG, 26, 2, {A_Boss5MakeJunk}, S_BROKENROBOTD, 2, S_FANG_INTRO12}, // S_FANG_INTRO11
{SPR_FANG, 31|FF_ANIMATE, 50, {NULL}, 3, 4, S_FANG_IDLE1}, // S_FANG_INTRO12
{SPR_FANG, 11, 2, {A_Boss5MakeJunk}, 0, -1, S_FANG_CLONE2}, // S_FANG_CLONE1
{SPR_FANG, 11, 0, {A_Repeat}, 49, S_FANG_CLONE1, S_FANG_CLONE3}, // S_FANG_INTRO2
{SPR_FANG, 12, 0, {A_SetObjectFlags}, MF_NOGRAVITY, 1, S_FANG_CLONE4}, // S_FANG_CLONE3
{SPR_FANG, 12, 1, {A_Boss5CheckOnGround}, S_FANG_IDLE0, 0, S_FANG_CLONE4}, // S_FANG_CLONE4
{SPR_FANG, 0, 0, {A_SetObjectFlags}, MF_NOCLIPTHING, 1, S_FANG_IDLE1}, // S_FANG_IDLE0
{SPR_FANG, 2, 16, {A_Look}, 1, 0, S_FANG_IDLE2}, // S_FANG_IDLE1
{SPR_FANG, 3, 16, {A_Look}, 1, 0, S_FANG_IDLE3}, // S_FANG_IDLE2
@ -1440,8 +1448,8 @@ state_t states[NUMSTATES] =
{SPR_FANG, 21, 0, {A_DoNPCPain}, 0, 0, S_FANG_DIE2}, // S_FANG_DIE1
{SPR_FANG, 21, 1, {A_Boss5CheckOnGround}, S_FANG_DIE3, 0, S_FANG_DIE2}, // S_FANG_DIE2
{SPR_FANG, 22, 0, {A_Scream}, 0, 0, S_FANG_DIE4}, // S_FANG_DIE3
{SPR_FANG, 22, 104, {NULL}, 0, 0, S_FANG_DIE5}, // S_FANG_DIE4
{SPR_FANG, 22, 0, {A_Scream}, 0, 0, S_FANG_DIE4}, // S_FANG_DIE3
{SPR_FANG, 22, -1, {A_SetFuse}, 70, 0, S_FANG_DIE5}, // S_FANG_DIE4
{SPR_FANG, 11, 0, {A_PlaySound}, sfx_jump, 0, S_FANG_DIE6}, // S_FANG_DIE5
{SPR_FANG, 11, 1, {A_ZThrust}, 6, (1<<16)|1, S_FANG_DIE7}, // S_FANG_DIE6
@ -1466,6 +1474,15 @@ state_t states[NUMSTATES] =
{SPR_WHAT, FF_ANIMATE|FF_FULLBRIGHT, 4, {NULL}, 1, 2, S_ALART2}, // S_ALART1
{SPR_WHAT, 2|FF_ANIMATE|FF_FULLBRIGHT, -1, {NULL}, 1, 2, S_NULL}, // S_ALART2
{SPR_VWRE, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_VWREF
{SPR_VWRE, 1|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_VWREB
{SPR_PROJ, FF_TRANS20|FF_FULLBRIGHT, 4, {NULL}, 0, 0, S_PROJECTORLIGHT2}, // S_PROJECTORLIGHT1
{SPR_PROJ, 1|FF_TRANS40|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_PROJECTORLIGHT3}, // S_PROJECTORLIGHT2
{SPR_PROJ, 2|FF_TRANS20|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_PROJECTORLIGHT4}, // S_PROJECTORLIGHT3
{SPR_PROJ, 3|FF_TRANS40|FF_FULLBRIGHT, 2, {A_Repeat}, 39, S_PROJECTORLIGHT2, S_PROJECTORLIGHT5}, // S_PROJECTORLIGHT4
{SPR_PROJ, 4|FF_TRANS60|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_PROJECTORLIGHT5
{SPR_FBOM, 0, 1, {A_GhostMe}, 0, 0, S_FBOMB2}, // S_FBOMB1
{SPR_FBOM, 1, 1, {A_GhostMe}, 0, 0, S_FBOMB1}, // S_FBOMB2
{SPR_BARX, 0|FF_FULLBRIGHT, 3, {A_SetObjectFlags}, MF_NOCLIP|MF_NOGRAVITY|MF_NOBLOCKMAP, 0, S_FBOMB_EXPL2}, // S_FBOMB_EXPL1
@ -5706,6 +5723,87 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
{ // MT_VWREF
-1, // doomednum
S_VWREF, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
3, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
42*FRACUNIT, // radius
12*FRACUNIT, // height
1, // display offset
1000, // mass
8, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_SCENERY, // flags
S_NULL // raisestate
},
{ // MT_VWREB
-1, // doomednum
S_VWREB, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
3, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
42*FRACUNIT, // radius
12*FRACUNIT, // height
-1, // display offset
1000, // mass
8, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_SCENERY, // flags
S_NULL // raisestate
},
{ // MT_PROJECTORLIGHT
-1, // doomednum
S_PROJECTORLIGHT1, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
3, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
42*FRACUNIT, // radius
52*FRACUNIT, // height
-1, // display offset
1000, // mass
8, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_SCENERY, // flags
S_NULL // raisestate
},
{ // MT_FBOMB
-1, // doomednum
S_FBOMB1, // spawnstate

View File

@ -342,6 +342,8 @@ typedef enum sprite
SPR_FANG, // replaces EGGQ
SPR_BRKN,
SPR_WHAT,
SPR_VWRE,
SPR_PROJ, // projector light
SPR_FBOM,
SPR_FSGN,
SPR_BARX, // bomb explosion (also used by barrel)
@ -1499,6 +1501,7 @@ typedef enum state
// Boss 5
S_FANG_SETUP,
S_FANG_INTRO0,
S_FANG_INTRO1,
S_FANG_INTRO2,
S_FANG_INTRO3,
@ -1511,6 +1514,10 @@ typedef enum state
S_FANG_INTRO10,
S_FANG_INTRO11,
S_FANG_INTRO12,
S_FANG_CLONE1,
S_FANG_CLONE2,
S_FANG_CLONE3,
S_FANG_CLONE4,
S_FANG_IDLE0,
S_FANG_IDLE1,
S_FANG_IDLE2,
@ -1594,6 +1601,15 @@ typedef enum state
S_ALART1,
S_ALART2,
S_VWREF,
S_VWREB,
S_PROJECTORLIGHT1,
S_PROJECTORLIGHT2,
S_PROJECTORLIGHT3,
S_PROJECTORLIGHT4,
S_PROJECTORLIGHT5,
S_FBOMB1,
S_FBOMB2,
S_FBOMB_EXPL1,
@ -4026,6 +4042,9 @@ typedef enum mobj_type
// Boss 5
MT_FANG,
MT_BROKENROBOT,
MT_VWREF,
MT_VWREB,
MT_PROJECTORLIGHT,
MT_FBOMB,
MT_TNTDUST, // also used by barrel
MT_FSGNA,

View File

@ -4026,13 +4026,17 @@ bossjustdie:
}
case MT_FANG:
{
if (mo->flags2 & MF2_SLIDEPUSH)
{
P_RemoveMobj(mo);
return;
}
if (mo->tracer)
{
var1 = var2 = 0;
A_Boss5Jump(mo);
mo->momx = ((16 - 1)*mo->momx)/16;
mo->momy = ((16 - 1)*mo->momy)/16;
if (!(mo->spawnpoint && mo->spawnpoint->options & MTF_EXTRA))
{
const fixed_t time = FixedHypot(mo->tracer->x - mo->x, mo->tracer->y - mo->y)/FixedHypot(mo->momx, mo->momy);
const fixed_t speed = 64*FRACUNIT;
@ -12980,8 +12984,8 @@ void A_Boss5MakeItRain(mobj_t *actor)
//
// Description: Make a mess.
//
// var1 = state # to set on MT_BROKENROBOT (if 0 do nothing)
// var2 = mode (0 = make 1, & 1 make 8, & 2 alart mode)
// var1 = state # to set on MT_BROKENROBOT (if 0 do nothing, if -1 go to if colorized)
// var2 = mode (-1 = spin, 0 = make 1, & 1 make 8, & 2 alart mode)
//
void A_Boss5MakeJunk(mobj_t *actor)
{
@ -12995,8 +12999,45 @@ void A_Boss5MakeJunk(mobj_t *actor)
return;
#endif
if (leveltime < 2)
if (locvar1 < 0 && (actor->flags2 & MF2_SLIDEPUSH)) // this entire action is a hack, don't judge me
{
INT32 curextravalue2 = actor->extravalue2;
P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_PROJECTORLIGHT);
actor->z += P_MobjFlip(actor)*actor->height;
actor->flags |= MF_NOGRAVITY;
S_StartSound(actor, sfx_vwre);
actor->extravalue2 = 49;
P_SetMobjState(actor, -locvar1);
actor->extravalue2 = curextravalue2;
actor->angle -= FixedAngle((49*45)<<FRACBITS);
return;
}
if (locvar2 == -1)
{
INT32 trans = (10*actor->extravalue2)/50;
if (trans > 9)
trans = 9;
if (trans < 0)
trans = 0;
if (!(actor->extravalue2 & 1))
{
if (actor->extravalue2 > 10)
{
mobj_t *front = P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_VWREF);
broked = P_SpawnMobjFromMobj(front, 0, 0, 0, MT_VWREB);
front->z = broked->z = front->z - broked->height;
P_SetObjectMomZ(front, (4<<FRACBITS), false);
broked->momz = front->momz;
broked->fuse = front->fuse = (actor->height+(2*front->height))/front->momz;
}
if (!(actor->colorized = !actor->colorized))
actor->frame |= FF_FULLBRIGHT;
}
actor->angle += ANGLE_45;
actor->frame = (actor->frame & ~FF_TRANSMASK)|(trans<<FF_TRANSSHIFT);
return;
}
ang = FixedAngle((P_RandomKey(36)*10)<<FRACBITS);
while (i--)
@ -13009,7 +13050,7 @@ void A_Boss5MakeJunk(mobj_t *actor)
broked->angle = ang;
P_InstaThrust(broked, ang, ((locvar2 & 2) ? 8 : 5)*actor->scale);
P_SetObjectMomZ(broked, (((locvar2) ? 4 : 0) + P_RandomRange(2, 5))<<FRACBITS, false);
if (locvar1 != 0)
if (locvar1 > 0)
P_SetMobjState(broked, locvar1);
if (!P_MobjWasRemoved(broked))
P_TeleportMove(broked, broked->x + broked->momx, broked->y + broked->momy, broked->z);

View File

@ -5063,6 +5063,24 @@ static void P_Boss5Thinker(mobj_t *mobj)
{
if (!mobj->health)
{
if (mobj->fuse)
{
if (mobj->flags2 & MF2_SLIDEPUSH)
{
INT32 trans = 10-((10*mobj->fuse)/70);
if (trans > 9)
trans = 9;
if (trans < 0)
trans = 0;
mobj->frame = (mobj->frame & ~FF_TRANSMASK)|(trans<<FF_TRANSSHIFT);
if (!(mobj->fuse & 1))
{
mobj->colorized = !mobj->colorized;
mobj->frame ^= FF_FULLBRIGHT;
}
}
return;
}
if (mobj->state == &states[mobj->info->xdeathstate])
mobj->momz -= (2*FRACUNIT)/3;
else if (mobj->tracer && P_AproxDistance(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y) < 2*mobj->radius)
@ -7649,6 +7667,17 @@ void P_MobjThinker(mobj_t *mobj)
if (mobj->movedir)
mobj->angle += mobj->movedir;
break;
case MT_VWREF:
case MT_VWREB:
{
INT32 strength;
++mobj->movedir;
mobj->frame &= ~FF_TRANSMASK;
strength = min(mobj->fuse, mobj->movedir)*3;
if (strength < 10)
mobj->frame |= ((10-strength)<<(FF_TRANSSHIFT));
}
/* FALLTHRU */
default:
if (mobj->fuse)
{ // Scenery object fuse! Very basic!
@ -9269,6 +9298,18 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s
}
P_RemoveMobj(mobj);
return;
case MT_FANG:
if (mobj->flags2 & MF2_SLIDEPUSH)
{
var1 = 0;
var2 = 0;
A_BossDeath(mobj);
return;
}
P_SetMobjState(mobj, mobj->state->nextstate);
if (P_MobjWasRemoved(mobj))
return;
break;
case MT_METALSONIC_BATTLE:
break; // don't remove
case MT_SPIKE:
@ -9867,7 +9908,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
break;
}
if (sc != -1)
if (sc != -1 && !(mobj->flags2 & MF2_SLIDEPUSH))
{
UINT8 i;
for (i = 0; i < MAXPLAYERS; i++)
@ -9879,6 +9920,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
{
mobj->color = SKINCOLOR_SILVER;
mobj->colorized = true;
mobj->flags2 |= MF2_SLIDEPUSH;
break;
}
}
@ -11225,6 +11267,16 @@ You should think about modifying the deathmatch starts to take full advantage of
else
mobj->health = FixedMul(ss->sector->ceilingheight-ss->sector->floorheight, 3*(FRACUNIT/4))>>FRACBITS;
break;
case MT_FANG:
case MT_METALSONIC_RACE:
case MT_METALSONIC_BATTLE:
if (mthing->options & MTF_EXTRA)
{
mobj->color = SKINCOLOR_SILVER;
mobj->colorized = true;
mobj->flags2 |= MF2_SLIDEPUSH;
}
break;
case MT_BALLOON:
if (mthing->angle > 0)
mobj->color = ((mthing->angle-1) % (MAXSKINCOLORS-1))+1;

View File

@ -213,6 +213,7 @@ sfxinfo_t S_sfx[NUMSFX] =
{"corkp", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Cork fired"},
{"corkh", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Cork hit"},
{"alart", false, 200, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Caught red handed!"},
{"vwre", false, 200, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Clone fighter!"},
{"bowl", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bowling"},
{"chuchu", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Train horn"},
{"bsnipe", false, 200, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Home-run smash"},

View File

@ -262,6 +262,7 @@ typedef enum
sfx_corkp,
sfx_corkh,
sfx_alart,
sfx_vwre,
sfx_bowl,
sfx_chuchu,
sfx_bsnipe,