Add K_SpawnBrolyKi, green circle shrinks during explosion hitlag

This commit is contained in:
James R 2022-12-12 20:56:34 -08:00
parent b9f277df66
commit 34dec00539
10 changed files with 107 additions and 12 deletions

View file

@ -313,6 +313,7 @@ actionpointer_t actionpointers[] =
{{A_JawzExplode}, "A_JAWZEXPLODE"},
{{A_SSMineSearch}, "A_SSMINESEARCH"},
{{A_SSMineExplode}, "A_SSMINEEXPLODE"},
{{A_SSMineFlash}, "A_SSMINEFLASH"},
{{A_LandMineExplode}, "A_LANDMINEEXPLODE"},
{{A_BallhogExplode}, "A_BALLHOGEXPLODE"},
{{A_LightningFollowPlayer}, "A_LIGHTNINGFOLLOWPLAYER"},
@ -4529,6 +4530,10 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
"S_JANKSPARK2",
"S_JANKSPARK3",
"S_JANKSPARK4",
// Broly Ki Orb
"S_BROLY1",
"S_BROLY2",
};
// RegEx to generate this from info.h: ^\tMT_([^,]+), --> \t"MT_\1",

View file

@ -495,6 +495,7 @@ char sprnames[NUMSPRITES + 1][5] =
"BOM3", // Boss Explosion 2
"BOM4", // Underwater Explosion
"BMNB", // Mine Explosion
"LSSJ", // My ki is overflowing!!
// Crumbly rocks
"ROIA",
@ -5141,6 +5142,10 @@ state_t states[NUMSTATES] =
{SPR_JANK, FF_PAPERSPRITE|FF_FULLBRIGHT|FF_ANIMATE, 4, {NULL}, 3, 1, S_JANKSPARK3}, // S_JANKSPARK2
{SPR_JANK, 0, 0, {A_SetCustomValue}, -1, 5, S_JANKSPARK4}, // S_JANKSPARK3
{SPR_JANK, 0, 0, {A_ChangeAngleRelative}, 180, 180, S_JANKSPARK2}, // S_JANKSPARK4
// Broly Ki Orb
{SPR_LSSJ, FF_REVERSESUBTRACT|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_BROLY2}, // S_BROLY1
{SPR_NULL, 0, 1, {A_SSMineFlash}, 0, 0, S_NULL}, // S_BROLY2
};
mobjinfo_t mobjinfo[NUMMOBJTYPES] =

View file

@ -549,6 +549,7 @@ void A_ItemPop();
void A_JawzExplode();
void A_SSMineSearch();
void A_SSMineExplode();
void A_SSMineFlash();
void A_LandMineExplode();
void A_LandMineExplode();
void A_BallhogExplode();
@ -1041,6 +1042,7 @@ typedef enum sprite
SPR_BOM3, // Boss Explosion 2
SPR_BOM4, // Underwater Explosion
SPR_BMNB, // Mine Explosion
SPR_LSSJ, // My ki is overflowing!!
// Crumbly rocks
SPR_ROIA,
@ -5563,6 +5565,10 @@ typedef enum state
S_JANKSPARK3,
S_JANKSPARK4,
// Broly Ki Orb
S_BROLY1,
S_BROLY2,
S_FIRSTFREESLOT,
S_LASTFREESLOT = S_FIRSTFREESLOT + NUMSTATEFREESLOTS - 1,
NUMSTATES

View file

@ -206,6 +206,7 @@ boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2)
static mobj_t *grenade;
static fixed_t explodedist;
static boolean explodespin;
static tic_t minehitlag;
static inline boolean PIT_SSMineChecks(mobj_t *thing)
{
@ -284,17 +285,22 @@ static inline BlockItReturn_t PIT_SSMineExplode(mobj_t *thing)
if (PIT_SSMineChecks(thing) == true)
return BMIT_CONTINUE;
P_DamageMobj(thing, grenade, grenade->target, 1, (explodespin ? DMG_NORMAL : DMG_EXPLODE));
if (P_DamageMobj(thing, grenade, grenade->target, 1, (explodespin ? DMG_NORMAL : DMG_EXPLODE)))
{
minehitlag = thing->hitlag;
}
return BMIT_CONTINUE;
}
void K_MineExplodeAttack(mobj_t *actor, fixed_t size, boolean spin)
tic_t K_MineExplodeAttack(mobj_t *actor, fixed_t size, boolean spin)
{
INT32 bx, by, xl, xh, yl, yh;
explodespin = spin;
explodedist = FixedMul(size, actor->scale);
grenade = actor;
minehitlag = 0;
// Use blockmap to check for nearby shootables
yh = (unsigned)(actor->y + explodedist - bmaporgy)>>MAPBLOCKSHIFT;
@ -310,6 +316,15 @@ void K_MineExplodeAttack(mobj_t *actor, fixed_t size, boolean spin)
// Set this flag to ensure that the inital action won't be triggered twice.
actor->flags2 |= MF2_DEBRIS;
if (!spin)
{
K_SpawnBrolyKi(actor, minehitlag);
return minehitlag;
}
return 0;
}
boolean K_MineCollide(mobj_t *t1, mobj_t *t2)
@ -396,6 +411,7 @@ boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2)
P_DamageMobj(t2, t1, t1->target, 1, DMG_TUMBLE);
}
t1->reactiontime = t2->hitlag;
P_KillMobj(t1, t2, t2, DMG_NORMAL);
}
else if (t2->type == MT_BANANA || t2->type == MT_BANANA_SHIELD
@ -419,6 +435,7 @@ boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2)
P_SpawnMobj(t2->x/2 + t1->x/2, t2->y/2 + t1->y/2, t2->z/2 + t1->z/2, MT_ITEMCLASH);
t1->reactiontime = t2->hitlag;
P_KillMobj(t1, t2, t2, DMG_NORMAL);
}
else if (t2->type == MT_SSMINE_SHIELD || t2->type == MT_SSMINE || t2->type == MT_LANDMINE)
@ -431,6 +448,8 @@ boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2)
{
// Shootable damage
P_DamageMobj(t2, t1, t1->target, 1, DMG_NORMAL);
t1->reactiontime = t2->hitlag;
P_KillMobj(t1, t2, t2, DMG_NORMAL);
}

View file

@ -10,7 +10,7 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2);
boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2);
void K_DoMineSearch(mobj_t *actor, fixed_t size);
void K_MineExplodeAttack(mobj_t *actor, fixed_t size, boolean spin);
tic_t K_MineExplodeAttack(mobj_t *actor, fixed_t size, boolean spin);
boolean K_MineCollide(mobj_t *t1, mobj_t *t2);
boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2);

View file

@ -5122,7 +5122,7 @@ void K_MineFlashScreen(mobj_t *source)
}
// Spawns the purely visual explosion
void K_SpawnMineExplosion(mobj_t *source, UINT8 color)
void K_SpawnMineExplosion(mobj_t *source, UINT8 color, tic_t delay)
{
INT32 i, radius, height;
mobj_t *smoldering = P_SpawnMobj(source->x, source->y, source->z, MT_SMOLDERING);
@ -5130,10 +5130,9 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color)
mobj_t *truc;
INT32 speed, speed2;
K_MineFlashScreen(source);
K_MatchGenericExtraFlags(smoldering, source);
smoldering->tics = TICRATE*3;
smoldering->hitlag += delay;
radius = source->radius>>FRACBITS;
height = source->height>>FRACBITS;
@ -5151,6 +5150,8 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color)
dust->destscale = source->scale*10;
dust->scalespeed = source->scale/12;
P_InstaThrust(dust, dust->angle, FixedMul(20*FRACUNIT, source->scale));
dust->hitlag += delay;
dust->renderflags |= RF_DONTDRAW;
truc = P_SpawnMobj(source->x + P_RandomRange(PR_EXPLOSION, -radius, radius)*FRACUNIT,
source->y + P_RandomRange(PR_EXPLOSION, -radius, radius)*FRACUNIT,
@ -5167,6 +5168,8 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color)
if (truc->eflags & MFE_UNDERWATER)
truc->momz = (117 * truc->momz) / 200;
truc->color = color;
truc->hitlag += delay;
truc->renderflags |= RF_DONTDRAW;
}
for (i = 0; i < 16; i++)
@ -5180,6 +5183,8 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color)
dust->scalespeed = source->scale/12;
dust->tics = 30;
dust->momz = P_RandomRange(PR_EXPLOSION, FixedMul(3*FRACUNIT, source->scale)>>FRACBITS, FixedMul(7*FRACUNIT, source->scale)>>FRACBITS)*FRACUNIT;
dust->hitlag += delay;
dust->renderflags |= RF_DONTDRAW;
truc = P_SpawnMobj(source->x + P_RandomRange(PR_EXPLOSION, -radius, radius)*FRACUNIT,
source->y + P_RandomRange(PR_EXPLOSION, -radius, radius)*FRACUNIT,
@ -5200,9 +5205,40 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color)
truc->momz = (117 * truc->momz) / 200;
truc->tics = TICRATE*2;
truc->color = color;
truc->hitlag += delay;
truc->renderflags |= RF_DONTDRAW;
}
}
void K_SpawnBrolyKi(mobj_t *source, tic_t duration)
{
mobj_t *x;
if (duration == 0)
{
return;
}
x = P_SpawnMobjFromMobj(source, 0, 0, 0, MT_THOK);
// Shrink into center of source object.
x->z = (source->z + source->height / 2);
x->height = 0;
P_SetMobjState(x, S_BROLY1);
x->hitlag = 0; // do not copy source hitlag
P_SetScale(x, 64 * mapobjectscale);
x->scalespeed = x->scale / duration;
// The last tic doesn't actually get rendered so in order
// to show scale = destscale, add one buffer tic.
x->tics = (duration + 1);
x->destscale = 1; // 0 also doesn't work
K_ReduceVFX(x, NULL);
}
#undef MINEQUAKEDIST
fixed_t K_ItemScaleForPlayer(player_t *player)

View file

@ -106,7 +106,8 @@ void K_HandleBumperChanges(player_t *player, UINT8 prevBumpers);
void K_DestroyBumpers(player_t *player, UINT8 amount);
void K_TakeBumpersFromPlayer(player_t *player, player_t *victim, UINT8 amount);
void K_MineFlashScreen(mobj_t *source);
void K_SpawnMineExplosion(mobj_t *source, UINT8 color);
void K_SpawnMineExplosion(mobj_t *source, UINT8 color, tic_t delay);
void K_SpawnBrolyKi(mobj_t *source, tic_t duration);
void K_RunFinishLineBeam(void);
UINT16 K_DriftSparkColor(player_t *player, INT32 charge);
void K_SpawnBoostTrail(player_t *player);

View file

@ -3601,10 +3601,11 @@ static int lib_kSpawnMineExplosion(lua_State *L)
{
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
UINT8 color = (UINT8)luaL_optinteger(L, 2, SKINCOLOR_KETCHUP);
tic_t delay = (tic_t)luaL_optinteger(L, 3, 0);
NOHUD
if (!source)
return LUA_ErrInvalid(L, "mobj_t");
K_SpawnMineExplosion(source, color);
K_SpawnMineExplosion(source, color, delay);
return 0;
}

View file

@ -315,6 +315,7 @@ void A_ItemPop(mobj_t *actor);
void A_JawzExplode(mobj_t *actor);
void A_SSMineSearch(mobj_t *actor);
void A_SSMineExplode(mobj_t *actor);
void A_SSMineFlash(mobj_t *actor);
void A_LandMineExplode(mobj_t *actor);
void A_BallhogExplode(mobj_t *actor);
void A_LightningFollowPlayer(mobj_t *actor);
@ -13117,14 +13118,21 @@ void A_SSMineExplode(mobj_t *actor)
{
INT32 locvar1 = var1;
tic_t delay;
if (LUA_CallAction(A_SSMINEEXPLODE, actor))
return;
if (actor->flags2 & MF2_DEBRIS)
return;
K_SpawnMineExplosion(actor, (actor->target && actor->target->player) ? actor->target->player->skincolor : SKINCOLOR_KETCHUP);
K_MineExplodeAttack(actor, (3*actor->info->painchance)>>1, (boolean)locvar1);
delay = K_MineExplodeAttack(actor, (3*actor->info->painchance)>>1, (boolean)locvar1);
K_SpawnMineExplosion(actor, (actor->target && actor->target->player) ? actor->target->player->skincolor : SKINCOLOR_KETCHUP, delay);
}
void A_SSMineFlash(mobj_t *actor)
{
K_MineFlashScreen(actor);
}
void A_LandMineExplode(mobj_t *actor)
@ -13135,21 +13143,27 @@ void A_LandMineExplode(mobj_t *actor)
INT32 i;
mobj_t *smoldering;
tic_t delay = actor->reactiontime;
if (LUA_CallAction(A_LANDMINEEXPLODE, actor))
return;
if (delay == 0)
{
delay = 8;
}
// we'll base the explosion "timer" off of some stupid variable like uh... cvmem!
// Yeah let's use cvmem since nobody uses that
if (actor->target && !P_MobjWasRemoved(actor->target))
colour = actor->target->color;
K_MineFlashScreen(actor);
// Spawn smoke remains:
smoldering = P_SpawnMobj(actor->x, actor->y, actor->z, MT_SMOLDERING);
P_SetScale(smoldering, actor->scale);
smoldering->tics = TICRATE*3;
smoldering->hitlag = delay;
actor->fuse = actor->tics; // disappear when this state ends.
@ -13159,6 +13173,8 @@ void A_LandMineExplode(mobj_t *actor)
expl = P_SpawnMobj(actor->x, actor->y, actor->z + actor->scale, MT_BOOMEXPLODE);
expl->color = colour;
expl->tics = (i+1);
expl->hitlag = delay;
expl->renderflags |= RF_DONTDRAW;
//K_MatchGenericExtraFlags(expl, actor);
P_SetScale(expl, actor->scale*4);
@ -13169,6 +13185,8 @@ void A_LandMineExplode(mobj_t *actor)
// 100/45 = 2.22 fu/t
expl->momz = ((i+1)*actor->scale*5/2)*P_MobjFlip(expl);
}
K_SpawnBrolyKi(actor, delay);
}
void A_BallhogExplode(mobj_t *actor)

View file

@ -5889,6 +5889,10 @@ static void P_MobjSceneryThink(mobj_t *mobj)
smoke->momz = P_RandomRange(PR_SMOLDERING, 4, 9)*mobj->scale*P_MobjFlip(smoke);
}
break;
case MT_SMOKE:
case MT_BOOMEXPLODE:
mobj->renderflags &= ~(RF_DONTDRAW);
break;
case MT_BOOMPARTICLE:
{
fixed_t x = P_RandomRange(PR_EXPLOSION, -16, 16)*mobj->scale;