WIP: pick-me-up

This commit is contained in:
Antonio Martinez 2025-05-16 11:44:57 -04:00
parent 088950f793
commit dcbbea4c4b
7 changed files with 150 additions and 0 deletions

View file

@ -779,6 +779,8 @@ struct player_t
// Item held stuff
SINT8 itemtype; // KITEM_ constant for item number
UINT8 itemamount; // Amount of said item
SINT8 backupitemtype;
UINT8 backupitemamount;
SINT8 throwdir; // Held dir of controls; 1 = forward, 0 = none, -1 = backward (was "player->heldDir")
UINT8 itemscale; // Item scale value, from when an item was taken out. (0 for normal, 1 for grow, 2 for shrink.)

View file

@ -72,6 +72,9 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2)
if (t1->type == MT_BALLHOG && t2->type == MT_BALLHOG)
return true; // Ballhogs don't collide with eachother
if (K_TryPickMeUp(t1, t2))
return true;
if (t2->player)
{
if (t2->player->flashing > 0 && t2->hitlag == 0)
@ -164,6 +167,9 @@ boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2)
return true;
}
if (K_TryPickMeUp(t1, t2))
return true;
if (t2->player)
{
if ((t1->target == t2 || t1->target == t2->target) && (t1->threshold > 0))
@ -425,6 +431,9 @@ boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2)
if (t1->health <= 0 || t2->health <= 0)
return true;
if (K_TryPickMeUp(t1, t2))
return true;
if (t2->player)
{
const INT32 oldhitlag = t2->hitlag;
@ -532,6 +541,9 @@ boolean K_DropTargetCollide(mobj_t *t1, mobj_t *t2)
if (t2->player && (t2->player->hyudorotimer || t2->player->justbumped))
return true;
if (K_TryPickMeUp(t1, t2))
return true;
if (draggeddroptarget && P_MobjWasRemoved(draggeddroptarget))
draggeddroptarget = NULL; // Beware order-of-execution on crushers, I guess?!
@ -839,6 +851,9 @@ boolean K_BubbleShieldReflect(mobj_t *t1, mobj_t *t2)
boolean K_BubbleShieldCollide(mobj_t *t1, mobj_t *t2)
{
if (K_TryPickMeUp(t1, t2))
return true;
if (t2->type == MT_PLAYER)
{
// Counter desyncs
@ -1053,6 +1068,9 @@ boolean K_KitchenSinkCollide(mobj_t *t1, mobj_t *t2)
if (((t1->target == t2) || (!(t2->flags & (MF_ENEMY|MF_BOSS)) && (t1->target == t2->target))) && (t1->threshold > 0 || (t2->type != MT_PLAYER && t2->threshold > 0)))
return true;
if (K_TryPickMeUp(t1, t2))
return true;
if (t2->player)
{
if (t2->player->flashing > 0 && t2->hitlag == 0)

View file

@ -9158,6 +9158,17 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
if (player->itemtype == KITEM_NONE)
player->itemflags &= ~IF_HOLDREADY;
if (player->itemtype == KITEM_NONE && player->backupitemtype)
{
player->itemtype = player->backupitemtype;
player->itemamount = player->backupitemamount;
player->backupitemtype = 0;
player->backupitemamount = 0;
S_StartSound(player->mo, sfx_mbs54);
}
if (onground || player->transfer < 10*player->mo->scale)
{
player->transfer = 0;
@ -15453,4 +15464,110 @@ UINT32 K_GetNumGradingPoints(void)
return numlaps * (1 + Obj_GetCheckpointCount());
}
static SINT8 K_PickUp(player_t *player, mobj_t *picked)
{
SINT8 type = -1;
SINT8 amount = 1;
switch (picked->type)
{
case MT_ORBINAUT:
case MT_ORBINAUT_SHIELD:
type = KITEM_ORBINAUT;
break;
case MT_JAWZ:
case MT_JAWZ_SHIELD:
type = KITEM_JAWZ;
break;
case MT_BALLHOG:
type = KITEM_BALLHOG;
break;
case MT_LANDMINE:
type = KITEM_LANDMINE;
break;
case MT_EGGMANITEM:
case MT_EGGMANITEM_SHIELD:
type = KITEM_EGGMAN;
break;
case MT_BANANA:
case MT_BANANA_SHIELD:
type = KITEM_BANANA;
break;
case MT_DROPTARGET:
case MT_DROPTARGET_SHIELD:
type = KITEM_DROPTARGET;
break;
default:
type = KITEM_SAD;
break;
}
if (player->itemtype == type && player->itemamount && !player->itemflags & IF_ITEMOUT)
{
// We have this item in main slot but not deployed, just add it
player->itemamount += amount;
}
else if (player->backupitemamount && player->backupitemtype)
{
// We already have a backup item, stack it if it can be stacked or discard it
if (player->backupitemtype == type)
{
player->backupitemamount += amount;
}
else
{
K_DropPaperItem(player, player->backupitemtype, player->backupitemamount);
player->backupitemtype = type;
player->backupitemamount = amount;
}
}
else
{
// We have no backup item, load one up
player->backupitemtype = type;
player->backupitemamount = amount;
}
S_StartSound(player->mo, sfx_gsha7);
}
// ACHTUNG this destroys items when returning true, make sure to bail out
boolean K_TryPickMeUp(mobj_t *m1, mobj_t *m2)
{
if (!m1 || P_MobjWasRemoved(m1))
return false;
if (!m2 || P_MobjWasRemoved(m2))
return false;
if (m1->type != MT_PLAYER && m2->type != MT_PLAYER)
return false;
if (m1->type == MT_PLAYER && m2->type == MT_PLAYER)
return false;
CONS_Printf("player check passed\n");
mobj_t *victim = m1;
mobj_t *inflictor = m2;
// Convenience for collision functions where arg order is freaky
if (m2->type == MT_PLAYER)
{
victim = m2;
inflictor = m1;
}
if (inflictor->target != victim)
return false;
CONS_Printf("target check passed\n");
K_AddHitLag(victim, 2, false);
K_PickUp(victim->player, inflictor);
P_RemoveMobj(inflictor);
return true;
}
//}

View file

@ -314,6 +314,8 @@ UINT16 K_GetDisplayEXP(player_t *player);
UINT32 K_GetNumGradingPoints(void);
boolean K_TryPickMeUp(mobj_t *m1, mobj_t *m2);
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -434,6 +434,10 @@ static int player_get(lua_State *L)
lua_pushinteger(L, plr->itemtype);
else if (fastcmp(field,"itemamount"))
lua_pushinteger(L, plr->itemamount);
else if (fastcmp(field,"backupitemtype"))
lua_pushinteger(L, plr->backupitemtype);
else if (fastcmp(field,"backupitemamount"))
lua_pushinteger(L, plr->backupitemamount);
else if (fastcmp(field,"throwdir"))
lua_pushinteger(L, plr->throwdir);
else if (fastcmp(field,"sadtimer"))

View file

@ -190,6 +190,9 @@ boolean Obj_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2)
return true;
}
if (K_TryPickMeUp(t1, t2))
return true;
if (t1->type == MT_GARDENTOP)
{
tumbleitem = true;

View file

@ -508,6 +508,8 @@ static void P_NetArchivePlayers(savebuffer_t *save)
WRITESINT8(save->p, players[i].itemtype);
WRITEUINT8(save->p, players[i].itemamount);
WRITESINT8(save->p, players[i].backupitemtype);
WRITEUINT8(save->p, players[i].backupitemamount);
WRITESINT8(save->p, players[i].throwdir);
WRITEUINT8(save->p, players[i].sadtimer);
@ -1148,6 +1150,8 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
players[i].itemtype = READSINT8(save->p);
players[i].itemamount = READUINT8(save->p);
players[i].backupitemtype = READSINT8(save->p);
players[i].backupitemamount = READUINT8(save->p);
players[i].throwdir = READSINT8(save->p);
players[i].sadtimer = READUINT8(save->p);