Allow P_CanPickupItem to be hooked and unmagic it

This commit is contained in:
NepDisk 2025-11-17 21:50:03 -05:00
parent cbe6aad38c
commit e9d7843b91
7 changed files with 98 additions and 55 deletions

View file

@ -1715,5 +1715,11 @@ struct int_const_s const INT_CONST[] = {
{"SCOREBOARDMOD_INACTIVE", SCOREBOARDMOD_INACTIVE},
{"SCOREBOARDMOD_ACTIVE", SCOREBOARDMOD_ACTIVE},
// pickupitem_e
{"PICKUPITEM_RING", PICKUPITEM_RING},
{"PICKUPITEM_ITEM", PICKUPITEM_ITEM},
{"PICKUPITEM_EGGMAN", PICKUPITEM_EGGMAN},
{"PICKUPITEM_FLOATING", PICKUPITEM_FLOATING},
{NULL,0}
};

View file

@ -477,7 +477,7 @@ static BlockItReturn_t K_FindObjectsForNudging(mobj_t *thing)
break;
}
if (P_CanPickupItem(g_nudgeSearch.botmo->player, 1))
if (P_CanPickupItem(g_nudgeSearch.botmo->player, PICKUPITEM_ITEM))
{
K_AddAttackObject(thing, side, 20);
}
@ -488,7 +488,7 @@ static BlockItReturn_t K_FindObjectsForNudging(mobj_t *thing)
break;
}
if (P_CanPickupItem(g_nudgeSearch.botmo->player, 1)) // Can pick up an actual item
if (P_CanPickupItem(g_nudgeSearch.botmo->player, PICKUPITEM_ITEM)) // Can pick up an actual item
{
const UINT8 stealth = K_EggboxStealth(thing->x, thing->y);
const UINT8 requiredstealth = (g_nudgeSearch.botmo->player->botvars.difficulty * g_nudgeSearch.botmo->player->botvars.difficulty);
@ -509,7 +509,7 @@ static BlockItReturn_t K_FindObjectsForNudging(mobj_t *thing)
break;
}
if (P_CanPickupItem(g_nudgeSearch.botmo->player, 3))
if (P_CanPickupItem(g_nudgeSearch.botmo->player, PICKUPITEM_FLOATING))
{
K_AddAttackObject(thing, side, 20);
}
@ -522,7 +522,7 @@ static BlockItReturn_t K_FindObjectsForNudging(mobj_t *thing)
}
if ((RINGTOTAL(g_nudgeSearch.botmo->player) < g_nudgeSearch.botmo->player->ringmax && !(g_nudgeSearch.botmo->player->pflags & PF_RINGLOCK)
&& P_CanPickupItem(g_nudgeSearch.botmo->player, 0))
&& P_CanPickupItem(g_nudgeSearch.botmo->player, PICKUPITEM_RING))
&& !thing->extravalue1
&& (g_nudgeSearch.botmo->player->itemtype != KITEM_THUNDERSHIELD))
{

View file

@ -245,7 +245,7 @@ boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2)
if (t1->health <= 0 || t2->health <= 0)
return true;
if (!P_CanPickupItem(t2->player, 2))
if (!P_CanPickupItem(t2->player, PICKUPITEM_EGGMAN))
return true;
if ((gametyperules & GTR_BUMPERS) && t2->player->bumper <= 0)

View file

@ -91,6 +91,7 @@ automatically.
X (KartSneaker),/*SRB2KART*/\
X (KartStripItems),/*SRB2KART*/\
X (KartStripOther),/*SRB2KART*/\
X (CanPickupItem),/*SRB2KART*/\
#define STRING_HOOK_LIST(X) \
X (SpecialExecute),\
@ -183,6 +184,7 @@ boolean LUA_HookMobjScaleChange(mobj_t *target, fixed_t newscale, fixed_t oldsca
boolean LUA_HookKartSneaker(player_t *player, int type); // SRB2Kart: Hook for K_DoSneaker.
boolean LUA_HookKartStripItems(player_t *player, UINT8 item); // SRB2Kart: Hook for K_StripItems.
boolean LUA_HookKartStripOther(player_t *player); // SRB2Kart: Hook for K_StripOther.
boolean LUA_HookCanPickupItem(player_t *player, UINT8 weapon, boolean *force); // SRB2Kart: Hook for P_CanPickupItem.
#ifdef __cplusplus
} // extern "C"

View file

@ -1399,3 +1399,22 @@ boolean LUA_HookKartStripOther(player_t* player)
return hook.status;
}
boolean LUA_HookCanPickupItem(player_t *player, UINT8 weapon, boolean *force)
{
Hook_State hook;
TrueForce_State state = {0};
if (prepare_hook(&hook, 0, HOOK(CanPickupItem)))
{
LUA_PushUserdata(gL, player, META_PLAYER);
lua_pushinteger(gL, weapon);
hook.userdata = &state;
call_hooks(&hook, 2, res_trueforce);
}
*force = state.force;
return state.override;
}

View file

@ -112,6 +112,13 @@ void P_RampConstant(const BasicFF_t *FFInfo, INT32 Start, INT32 End)
// Returns true if the player is in a state where they can pick up items.
//
boolean P_CanPickupItem(player_t *player, UINT8 weapon)
{
boolean force = false;
if (LUA_HookCanPickupItem(player, weapon, &force))
return true;
if (!force)
{
if (player->exiting || mapreset || (player->pflags & PF_ELIMINATED))
return false;
@ -162,6 +169,7 @@ boolean P_CanPickupItem(player_t *player, UINT8 weapon)
return false; // No stacking shields!
}
}
}
return true;
}
@ -335,7 +343,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
P_InstaThrust(player->mo, player->mo->angle, 20<<FRACBITS);
return;
case MT_FLOATINGITEM: // SRB2Kart
if (!P_CanPickupItem(player, 3) || (player->itemamount && player->itemtype != special->threshold))
if (!P_CanPickupItem(player, PICKUPITEM_FLOATING) || (player->itemamount && player->itemtype != special->threshold))
return;
if ((gametyperules & GTR_BUMPERS) && player->bumper <= 0)
@ -357,7 +365,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
special->flags &= ~MF_SPECIAL;
return;
case MT_RANDOMITEM:
if (!itembreaker && !P_CanPickupItem(player, 1))
if (!itembreaker && !P_CanPickupItem(player, PICKUPITEM_ITEM))
return;
if ((gametyperules & GTR_BUMPERS) && player->bumper <= 0)
@ -385,7 +393,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
return;
break;
default:
if (!P_CanPickupItem(player, 1))
if (!P_CanPickupItem(player, PICKUPITEM_ITEM))
return;
break;
}
@ -434,7 +442,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
special->target->player->karthud[khud_yougotem] = 2*TICRATE;
special->target->player->karmadelay = comebacktime;
}
else if (special->target->player->karmamode == 1 && P_CanPickupItem(player, 1))
else if (special->target->player->karmamode == 1 && P_CanPickupItem(player, PICKUPITEM_ITEM))
{
mobj_t *poof = P_SpawnMobj(special->x, special->y, special->z, MT_EXPLODE);
S_StartSound(poof, special->info->seesound);
@ -461,7 +469,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
K_StartRoulette(player, KROULETTETYPE_KARMA);
}
else if (special->target->player->karmamode == 2 && P_CanPickupItem(player, 2))
else if (special->target->player->karmamode == 2 && P_CanPickupItem(player, PICKUPITEM_EGGMAN))
{
mobj_t *poof = P_SpawnMobj(special->x, special->y, special->z, MT_EXPLODE);
UINT8 ptadd = 1; // No WANTED bonus for tricking
@ -583,7 +591,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
S_StartSound(special, sfx_s1a2);
return;
case MT_CDUFO: // SRB2kart
if (special->fuse || !P_CanPickupItem(player, 1) || ((gametyperules & GTR_BUMPERS) && player->bumper <= 0))
if (special->fuse || !P_CanPickupItem(player, PICKUPITEM_ITEM) || ((gametyperules & GTR_BUMPERS) && player->bumper <= 0))
return;
K_StartRoulette(player, KROULETTETYPE_KARMA);
@ -668,7 +676,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (special->threshold > 0 || P_PlayerInPain(player))
return;
if (!(P_CanPickupItem(player, 0)))
if (!(P_CanPickupItem(player, PICKUPITEM_RING)))
return;
// Reached the cap, don't waste 'em!
@ -690,14 +698,14 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
return;
case MT_COIN:
case MT_FLINGCOIN:
if (!(P_CanPickupItem(player, 0)))
if (!(P_CanPickupItem(player, PICKUPITEM_RING)))
return;
special->momx = special->momy = 0;
P_GivePlayerRings(player, 1);
break;
case MT_BLUEBALL:
if (!(P_CanPickupItem(player, 0)))
if (!(P_CanPickupItem(player, PICKUPITEM_RING)))
return;
P_GivePlayerRings(player, 1);

View file

@ -615,6 +615,14 @@ void P_CheckTimeLimit(void);
void P_CheckPointLimit(void);
boolean P_CheckRacers(void);
typedef enum
{
PICKUPITEM_RING,
PICKUPITEM_ITEM,
PICKUPITEM_EGGMAN,
PICKUPITEM_FLOATING,
} pickupitem_e;
boolean P_CanPickupItem(player_t *player, UINT8 weapon);
//