K_PopPlayerShield

- Split out from K_DropHnextList to make its handling more explicit, and to permit K_DropItems scenarioes to *not* drop shields.
- Always called on P_DamageMobj on any non DMG_STUMBLE damagetype, so shields always get digested on true pain.
    - Todo: Should shields be popped even on DMG_STING..?
- NOT called on Eggman Mark pickup.
- Add to Lua (alongside K_DropHnextList, which was inexplicably missing).
This commit is contained in:
toaster 2023-03-21 13:48:30 +00:00
parent ae9a0b3ba2
commit 01dbbc34d1
6 changed files with 66 additions and 28 deletions

View file

@ -576,7 +576,7 @@ boolean K_DropTargetCollide(mobj_t *t1, mobj_t *t2)
{
// The following removes t1, be warned
// (its newly assigned properties are moved across)
K_DropHnextList(draggeddroptarget->player, true);
K_DropHnextList(draggeddroptarget->player);
// Do NOT modify or reference t1 after this line
// I mean it! Do not even absentmindedly try it
}

View file

@ -6097,24 +6097,22 @@ void K_UpdateHnextList(player_t *player, boolean clean)
}
// For getting hit!
void K_DropHnextList(player_t *player, boolean keepshields)
void K_PopPlayerShield(player_t *player)
{
mobj_t *work = player->mo, *nextwork, *dropwork;
INT32 flip;
mobjtype_t type;
boolean orbit, ponground, dropall = true;
INT32 shield = K_GetShieldFromItem(player->itemtype);
if (work == NULL || P_MobjWasRemoved(work))
// Doesn't apply if player is invalid.
if (player->mo == NULL || P_MobjWasRemoved(player->mo))
{
return;
}
flip = P_MobjFlip(player->mo);
ponground = P_IsObjectOnGround(player->mo);
if (shield != KSHIELD_NONE && shield != KSHIELD_TOP && !keepshields)
// Doesn't apply to non-S3K shields.
if (shield == KSHIELD_NONE || shield == KSHIELD_TOP)
{
return;
}
if (shield == KSHIELD_LIGHTNING)
{
K_DoLightningShield(player);
@ -6124,8 +6122,23 @@ void K_DropHnextList(player_t *player, boolean keepshields)
player->itemtype = KITEM_NONE;
player->itemamount = 0;
K_UnsetItemOut(player);
}
void K_DropHnextList(player_t *player)
{
mobj_t *work = player->mo, *nextwork, *dropwork;
INT32 flip;
mobjtype_t type;
boolean orbit, ponground, dropall = true;
if (work == NULL || P_MobjWasRemoved(work))
{
return;
}
flip = P_MobjFlip(player->mo);
ponground = P_IsObjectOnGround(player->mo);
nextwork = work->hnext;
while ((work = nextwork) && !(work == NULL || P_MobjWasRemoved(work)))
@ -6415,7 +6428,7 @@ mobj_t *K_CreatePaperItem(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8
// For getting EXTRA hit!
void K_DropItems(player_t *player)
{
K_DropHnextList(player, true);
K_DropHnextList(player);
if (player->mo && !P_MobjWasRemoved(player->mo) && player->itemamount > 0)
{
@ -11153,7 +11166,10 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
K_trickPanelTimingVisual(player, momz); // fail trick visual
P_SetPlayerMobjState(player->mo, S_KART_SPINOUT);
if (player->pflags & (PF_ITEMOUT|PF_EGGMANOUT))
K_DropHnextList(player, true);
{
//K_PopPlayerShield(player); // shield is just being yeeted, don't pop
K_DropHnextList(player);
}
}
else if (!(player->pflags & PF_TRICKDELAY)) // don't allow tricking at the same frame you tumble obv

View file

@ -123,7 +123,7 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound);
void K_DoInvincibility(player_t *player, tic_t time);
void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source);
void K_UpdateHnextList(player_t *player, boolean clean);
void K_DropHnextList(player_t *player, boolean keepshields);
void K_DropHnextList(player_t *player);
void K_RepairOrbitChain(mobj_t *orbit);
void K_CalculateBananaSlope(mobj_t *mobj, fixed_t x, fixed_t y, fixed_t z, fixed_t radius, fixed_t height, boolean flip, boolean player);
mobj_t *K_FindJawzTarget(mobj_t *actor, player_t *source, angle_t range);
@ -142,6 +142,7 @@ void K_KartUpdatePosition(player_t *player);
void K_UpdateAllPlayerPositions(void);
SINT8 K_GetTotallyRandomResult(UINT8 useodds);
mobj_t *K_CreatePaperItem(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 flip, UINT8 type, UINT8 amount);
void K_PopPlayerShield(player_t *player);
void K_DropItems(player_t *player);
void K_DropRocketSneaker(player_t *player);
void K_DropKitchenSink(player_t *player);

View file

@ -3733,6 +3733,26 @@ static int lib_kKartUpdatePosition(lua_State *L)
return 0;
}
static int lib_kPopPlayerShield(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
NOHUD
if (!player)
return LUA_ErrInvalid(L, "player_t");
K_PopPlayerShield(player);
return 0;
}
static int lib_kDropHnextList(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
NOHUD
if (!player)
return LUA_ErrInvalid(L, "player_t");
K_DropHnextList(player);
return 0;
}
static int lib_kDropItems(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
@ -4153,6 +4173,8 @@ static luaL_Reg lib[] = {
{"K_FindJawzTarget",lib_kFindJawzTarget},
{"K_GetKartDriftSparkValue",lib_kGetKartDriftSparkValue},
{"K_KartUpdatePosition",lib_kKartUpdatePosition},
{"K_PopPlayerShield",lib_kPopPlayerShield},
{"K_DropHnextList",lib_kDropHnextList},
{"K_DropItems",lib_kDropItems},
{"K_StripItems",lib_kStripItems},
{"K_StripOther",lib_kStripOther},

View file

@ -1058,7 +1058,8 @@ void Obj_SPBTouch(mobj_t *spb, mobj_t *toucher)
if (player->bubbleblowup > 0)
{
// Stun the SPB, and remove the shield.
K_DropHnextList(player, false);
K_PopPlayerShield(player);
K_DropHnextList(player);
spb_mode(spb) = SPB_MODE_WAIT;
spb_modetimer(spb) = 55; // Slightly over the respawn timer length
return;

View file

@ -2438,9 +2438,12 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
P_PlayRinglossSound(target);
P_PlayerRingBurst(player, ringburst);
}
K_PopPlayerShield(player);
player->instashield = 15;
K_PlayPainSound(target, source);
}
if ((hardhit == true) || cv_kartdebughuddrop.value)
{
@ -2448,12 +2451,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
}
else
{
K_DropHnextList(player, (type == DMG_STUMBLE));
}
if (type != DMG_STUMBLE)
{
player->instashield = 15;
K_DropHnextList(player);
}
if (inflictor && !P_MobjWasRemoved(inflictor) && inflictor->type == MT_BANANA)