New item list + shrink destroys items

This commit is contained in:
Latapostrophe 2019-10-26 17:08:22 +02:00
parent 55c2fe31be
commit 58bed7d923
6 changed files with 164 additions and 21 deletions

View file

@ -2011,7 +2011,7 @@ void K_RespawnChecker(player_t *player)
{
while (lasersteps)
{
stepha = R_PointToAngle2(laserx, lasery, destx, desty);
stepva = R_PointToAngle2(0, laserz, P_AproxDistance(laserx - destx, lasery - desty), destz);
@ -4109,6 +4109,7 @@ void K_DoSneaker(player_t *player, INT32 type)
static void K_DoShrink(player_t *user)
{
INT32 i;
mobj_t *mobj, *next;
S_StartSound(user->mo, sfx_kc46); // Sound the BANG!
user->pflags |= PF_ATTACKDOWN;
@ -4146,6 +4147,43 @@ static void K_DoShrink(player_t *user)
}
}
}
// kill everything in the kitem list while we're at it:
for (mobj = kitemcap; mobj; mobj = next)
{
next = mobj->itnext;
// check if the item is being held by a player behind us before removing it.
// check if the item is a "shield" first, bc i'm p sure thrown items keep the player that threw em as target anyway
if (mobj->type == MT_BANANA_SHIELD || mobj->type == MT_JAWZ_SHIELD ||
mobj->type == MT_SSMINE_SHIELD || mobj->type == MT_EGGMANITEM_SHIELD ||
mobj->type == MT_SINK_SHIELD || mobj->type == MT_ORBINAUT_SHIELD)
{
if (mobj->target && mobj->target->player)
{
if (mobj->target->player->kartstuff[k_position] > user->kartstuff[k_position])
continue; // this guy's behind us, don't take his stuff away!
}
}
// @TODO: This should probably go into the P_KillMobj code for items?
if (mobj->eflags & MFE_VERTICALFLIP)
mobj->z -= mobj->height;
else
mobj->z += mobj->height;
S_StartSound(mobj, mobj->info->deathsound);
P_KillMobj(mobj, user->mo, user->mo);
P_SetObjectMomZ(mobj, 8*FRACUNIT, false);
P_InstaThrust(mobj, (angle_t)P_RandomRange(0, 359)*ANG1, 16*FRACUNIT);
if (mobj->type == MT_SPB)
spbplace = -1;
}
}
@ -4318,6 +4356,7 @@ void K_DropHnextList(player_t *player)
dropwork = P_SpawnMobj(work->x, work->y, work->z, type);
P_SetTarget(&dropwork->target, player->mo);
P_AddKartItem(dropwork); // needs to be called here so shrink can bust items off players in front of the user.
dropwork->angle = work->angle;
dropwork->flags2 = work->flags2;
dropwork->flags |= MF_NOCLIPTHING;
@ -5105,9 +5144,6 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
K_UpdateDraft(player);
K_UpdateEngineSounds(player, cmd); // Thanks, VAda!
if (spbplace == -1) // no spb
player->axis1 = NULL; // remove this
// update boost angle if not spun out
if (!player->kartstuff[k_spinouttimer] && !player->kartstuff[k_wipeoutslow])
player->kartstuff[k_boostangle] = (INT32)player->mo->angle;
@ -9394,7 +9430,8 @@ static void K_drawKartMinimap(void)
UINT8 skin = 0;
UINT8 *colormap = NULL;
SINT8 localplayers[4];
SINT8 numlocalplayers = 0;
SINT8 numlocalplayers = 0;
mobj_t *mobj, *next; // for SPB drawing (or any other item(s) we may wanna draw, I dunno!)
// Draw the HUD only when playing in a level.
// hu_stuff needs this, unlike st_stuff.
@ -9545,11 +9582,7 @@ static void K_drawKartMinimap(void)
// Target reticule
if ((G_RaceGametype() && players[i].kartstuff[k_position] == spbplace)
|| (G_BattleGametype() && K_IsPlayerWanted(&players[i])))
K_drawKartMinimapIcon(players[i].mo->x, players[i].mo->y, x, y, splitflags, kp_wantedreticle, NULL, AutomapPic);
if (players[i].axis1 && !P_MobjWasRemoved(players[i].axis1)) // SPB after the player?
K_drawKartMinimapIcon(players[i].axis1->x, players[i].axis1->y, x, y, splitflags, kp_ringspblocksmall[14 + leveltime%4 /2], NULL, AutomapPic);
K_drawKartMinimapIcon(players[i].mo->x, players[i].mo->y, x, y, splitflags, kp_wantedreticle, NULL, AutomapPic);
}
}
@ -9582,12 +9615,17 @@ static void K_drawKartMinimap(void)
// Target reticule
if ((G_RaceGametype() && players[localplayers[i]].kartstuff[k_position] == spbplace)
|| (G_BattleGametype() && K_IsPlayerWanted(&players[localplayers[i]])))
K_drawKartMinimapIcon(players[localplayers[i]].mo->x, players[localplayers[i]].mo->y, x, y, splitflags, kp_wantedreticle, NULL, AutomapPic);
K_drawKartMinimapIcon(players[localplayers[i]].mo->x, players[localplayers[i]].mo->y, x, y, splitflags, kp_wantedreticle, NULL, AutomapPic);
}
if (players[localplayers[i]].axis1 && !P_MobjWasRemoved(players[localplayers[i]].axis1)) // SPB after the player?
K_drawKartMinimapIcon(players[localplayers[i]].axis1->x, players[localplayers[i]].axis1->y, x, y, splitflags, kp_ringspblocksmall[14 + leveltime%4 /2], NULL, AutomapPic);
// draw SPB(s?)
for (mobj = kitemcap; mobj; mobj = next)
{
next = mobj->itnext;
if (mobj->type == MT_SPB)
K_drawKartMinimapIcon(mobj->x, mobj->y, x, y, splitflags, kp_ringspblocksmall[14 + leveltime%4 /2], NULL, AutomapPic);
}
}
}
static void K_drawKartStartCountdown(void)

View file

@ -8543,9 +8543,6 @@ void A_SPBChase(mobj_t *actor)
}
}
if (player)
P_SetTarget(&player->axis1, actor); // axis is the SPB trailing the player.
// lastlook = last player num targetted
// cvmem = stored speed
// cusval = next waypoint heap index

View file

@ -48,6 +48,7 @@ actioncache_t actioncachehead;
static mobj_t *overlaycap = NULL;
static mobj_t *shadowcap = NULL;
mobj_t *kitemcap = NULL; // Used for Kart offensive items (the ones that can get removed by sizedown)
mobj_t *waypointcap = NULL;
void P_InitCachedActions(void)
@ -6101,6 +6102,71 @@ static boolean P_AddShield(mobj_t *thing)
return true;
}*/
// Kartitem stuff.
boolean P_IsKartItem(INT32 type)
{
if (type == MT_EGGMANITEM || type == MT_EGGMANITEM_SHIELD ||
type == MT_BANANA || type == MT_BANANA_SHIELD ||
type == MT_ORBINAUT || type == MT_ORBINAUT_SHIELD ||
type == MT_JAWZ || type == MT_JAWZ_DUD || type == MT_JAWZ_SHIELD ||
type == MT_SSMINE || type == MT_SSMINE_SHIELD ||
type == MT_SINK || type == MT_SINK_SHIELD ||
type == MT_FLOATINGITEM || type == MT_SPB)
return true;
else
return false;
}
// Called when a kart item "thinks"
void P_AddKartItem(mobj_t *thing)
{
I_Assert(thing != NULL);
if (kitemcap == NULL)
P_SetTarget(&kitemcap, thing);
else {
mobj_t *mo;
for (mo = kitemcap; mo && mo->itnext; mo = mo->itnext)
;
I_Assert(mo != NULL);
I_Assert(mo->itnext == NULL);
P_SetTarget(&mo->itnext, thing);
}
P_SetTarget(&thing->itnext, NULL);
}
// Called only when a kart item is removed
// Keeps the hnext list from corrupting.
static void P_RemoveKartItem(mobj_t *thing)
{
mobj_t *mo;
for (mo = kitemcap; mo; mo = mo->itnext)
if (mo->itnext == thing)
{
P_SetTarget(&mo->itnext, thing->itnext);
P_SetTarget(&thing->itnext, NULL);
return;
}
}
// Doesn't actually do anything since items have their own thinkers,
// but this is necessary for the sole purpose of updating kitemcap
void P_RunKartItems(void)
{
mobj_t *mobj, *next;
for (mobj = kitemcap; mobj; mobj = next)
{
next = mobj->itnext;
P_SetTarget(&mobj->itnext, NULL);
}
P_SetTarget(&kitemcap, NULL);
}
void P_RunOverlays(void)
{
// run overlays
@ -9961,6 +10027,12 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s
}
}
if (P_MobjWasRemoved(mobj))
return; // obligatory paranoia check
if (P_IsKartItem(mobj->type)) // mobj is a kart item we want on the list:
P_AddKartItem(mobj); // add to kitem list
// Can end up here if a player dies.
if (mobj->player)
P_CyclePlayerMobjState(mobj);
@ -10887,6 +10959,9 @@ void P_RemoveMobj(mobj_t *mobj)
if (mobj->type == MT_SPB)
spbplace = -1;
if (P_IsKartItem(mobj->type))
P_RemoveKartItem(mobj);
mobj->health = 0; // Just because
// unlink from sector and block lists

View file

@ -321,6 +321,9 @@ typedef struct mobj_s
struct mobj_s *hnext;
struct mobj_s *hprev;
// One last pointer for kart item lists
struct mobj_s *itnext;
mobjtype_t type;
const mobjinfo_t *info; // &mobjinfo[mobj->type]
@ -436,12 +439,18 @@ typedef struct actioncache_s
extern actioncache_t actioncachehead;
extern mobj_t *kitemcap;
extern mobj_t *waypointcap;
void P_InitCachedActions(void);
void P_RunCachedActions(void);
void P_AddCachedAction(mobj_t *mobj, INT32 statenum);
// kartitem stuff: Returns true if the specified 'type' is one of the kart item constants we want in the kitemcap list
boolean P_IsKartItem(INT32 type);
void P_AddKartItem(mobj_t *thing); // needs to be called in k_kart.c
void P_RunKartItems(void);
// check mobj against water content, before movement code
void P_MobjCheckWater(mobj_t *mobj);

View file

@ -957,9 +957,11 @@ typedef enum
MD2_HNEXT = 1<<7,
MD2_HPREV = 1<<8,
MD2_COLORIZED = 1<<9,
MD2_WAYPOINTCAP = 1<<10
MD2_WAYPOINTCAP = 1<<10,
MD2_KITEMCAP = 1<<11,
MD2_ITNEXT = 1<<12
#ifdef ESLOPE
, MD2_SLOPE = 1<<11
, MD2_SLOPE = 1<<13
#endif
} mobj_diff2_t;
@ -1151,6 +1153,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
diff2 |= MD2_HNEXT;
if (mobj->hprev)
diff2 |= MD2_HPREV;
if (mobj->itnext)
diff2 |= MD2_ITNEXT;
#ifdef ESLOPE
if (mobj->standingslope)
diff2 |= MD2_SLOPE;
@ -1159,6 +1163,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
diff2 |= MD2_COLORIZED;
if (mobj == waypointcap)
diff2 |= MD2_WAYPOINTCAP;
if (mobj == kitemcap)
diff2 |= MD2_KITEMCAP;
if (diff2 != 0)
diff |= MD_MORE;
@ -1274,6 +1280,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
WRITEUINT32(save_p, mobj->hnext->mobjnum);
if (diff2 & MD2_HPREV)
WRITEUINT32(save_p, mobj->hprev->mobjnum);
if (diff2 & MD2_ITNEXT)
WRITEUINT32(save_p, mobj->itnext->mobjnum);
#ifdef ESLOPE
if (diff2 & MD2_SLOPE)
WRITEUINT16(save_p, mobj->standingslope->id);
@ -2151,6 +2159,8 @@ static void LoadMobjThinker(actionf_p1 thinker)
mobj->hnext = (mobj_t *)(size_t)READUINT32(save_p);
if (diff2 & MD2_HPREV)
mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p);
if (diff2 & MD2_ITNEXT)
mobj->itnext = (mobj_t *)(size_t)READUINT32(save_p);
#ifdef ESLOPE
if (diff2 & MD2_SLOPE)
{
@ -2192,6 +2202,9 @@ static void LoadMobjThinker(actionf_p1 thinker)
if (diff2 & MD2_WAYPOINTCAP)
P_SetTarget(&waypointcap, mobj);
if (diff2 & MD2_KITEMCAP)
P_SetTarget(&kitemcap, mobj);
mobj->info = (mobjinfo_t *)next; // temporarily, set when leave this function
}
@ -3044,6 +3057,13 @@ static void P_RelinkPointers(void)
if (!(mobj->hprev = P_FindNewPosition(temp)))
CONS_Debug(DBG_GAMELOGIC, "hprev not found on %d\n", mobj->type);
}
if (mobj->itnext)
{
temp = (UINT32)(size_t)mobj->itnext;
mobj->itnext = NULL;
if (!(mobj->itnext = P_FindNewPosition(temp)))
CONS_Debug(DBG_GAMELOGIC, "itnext not found on %d\n", mobj->type);
}
if (mobj->player && mobj->player->capsule)
{
temp = (UINT32)(size_t)mobj->player->capsule;
@ -3324,7 +3344,7 @@ static void P_NetArchiveMisc(void)
WRITEUINT32(save_p, hyubgone);
WRITEUINT32(save_p, mapreset);
for (i = 0; i < MAXPLAYERS; i++)
for (i = 0; i < MAXPLAYERS; i++)
WRITEINT16(save_p, nospectategrief[i]);
WRITEUINT8(save_p, thwompsactive);
@ -3447,7 +3467,7 @@ static inline boolean P_NetUnArchiveMisc(void)
hyubgone = READUINT32(save_p);
mapreset = READUINT32(save_p);
for (i = 0; i < MAXPLAYERS; i++)
for (i = 0; i < MAXPLAYERS; i++)
nospectategrief[i] = READINT16(save_p);
thwompsactive = (boolean)READUINT8(save_p);

View file

@ -183,6 +183,7 @@ void P_InitThinkers(void)
{
thinkercap.prev = thinkercap.next = &thinkercap;
waypointcap = NULL;
kitemcap = NULL;
}
//
@ -639,6 +640,9 @@ void P_Ticker(boolean run)
if (runemeraldmanager)
P_EmeraldManager(); // Power stone mode*/
// formality so kitemcap gets updated properly each frame.
P_RunKartItems();
if (run)
{
P_RunThinkers();