Copy first mapthing tag to their mobjs

Allows the ThingCount and ThingSound ACS functions to fully work now, and adds significantly more possibilities for scripting later.
This commit is contained in:
Sally Coolatta 2023-01-01 16:55:39 -05:00
parent a602530811
commit 345e7f83b0
8 changed files with 154 additions and 19 deletions

View file

@ -130,6 +130,11 @@ mapformat_udmf
include("RingRacers_misc.cfg", "linedefflags_udmf"); include("RingRacers_misc.cfg", "linedefflags_udmf");
} }
linedefactivations
{
include("RingRacers_misc.cfg", "linedefactivations_udmf");
}
linedefflagstranslation linedefflagstranslation
{ {
include("RingRacers_misc.cfg", "linedefflagstranslation"); include("RingRacers_misc.cfg", "linedefflagstranslation");

View file

@ -1,5 +1,7 @@
udmf udmf
{ {
requiresactivation = false;
misc misc
{ {
title = "Miscellaneous"; title = "Miscellaneous";
@ -1556,6 +1558,7 @@ udmf
linedefexecsector linedefexecsector
{ {
title = "Linedef Executor (sector)"; title = "Linedef Executor (sector)";
requiresactivation = true;
400 400
{ {
@ -1894,6 +1897,7 @@ udmf
linedefexecplane linedefexecplane
{ {
title = "Linedef Executor (plane movement)"; title = "Linedef Executor (plane movement)";
requiresactivation = true;
403 403
{ {
@ -2031,6 +2035,7 @@ udmf
linedefexecplayer linedefexecplayer
{ {
title = "Linedef Executor (player/object)"; title = "Linedef Executor (player/object)";
requiresactivation = true;
412 412
{ {
@ -2357,6 +2362,7 @@ udmf
linedefexecmisc linedefexecmisc
{ {
title = "Linedef Executor (misc.)"; title = "Linedef Executor (misc.)";
requiresactivation = true;
413 413
{ {
@ -3014,6 +3020,7 @@ udmf
linedefexecpoly linedefexecpoly
{ {
title = "Linedef Executor (polyobject)"; title = "Linedef Executor (polyobject)";
requiresactivation = true;
480 480
{ {

View file

@ -368,18 +368,21 @@ bool CallFunc_ThingCount(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::
if (tid != 0) if (tid != 0)
{ {
// TODO: Even in SRB2 next's UDMF, tag lists mobj_t *mobj = nullptr;
// still aren't attached to mobj_t, only
// mapthing_t. Fix this. while ((mobj = P_FindMobjFromTID(tid, mobj, nullptr)) != nullptr)
CONS_Alert(CONS_WARNING, {
"ThingCount TID field not implemented -- waiting for mobj tags.\n" if (ACS_CountThing(mobj, type) == true)
); {
++count;
}
}
} }
else else
{ {
// Search thinkers instead of tag lists. // Search thinkers instead of tag lists.
thinker_t *th = NULL; thinker_t *th = nullptr;
mobj_t *mobj = NULL; mobj_t *mobj = nullptr;
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{ {
@ -862,6 +865,8 @@ bool CallFunc_SetLineSpecial(ACSVM::Thread *thread, const ACSVM::Word *argV, ACS
--------------------------------------------------*/ --------------------------------------------------*/
bool CallFunc_ThingSound(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) bool CallFunc_ThingSound(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
{ {
auto info = &static_cast<Thread *>(thread)->info;
ACSVM::MapScope *map = nullptr; ACSVM::MapScope *map = nullptr;
ACSVM::String *str = nullptr; ACSVM::String *str = nullptr;
@ -872,6 +877,8 @@ bool CallFunc_ThingSound(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::
sfxenum_t sfxId = sfx_None; sfxenum_t sfxId = sfx_None;
INT32 vol = 0; INT32 vol = 0;
mobj_t *mobj = nullptr;
(void)argC; (void)argC;
tag = argV[0]; tag = argV[0];
@ -901,19 +908,10 @@ bool CallFunc_ThingSound(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::
vol = argV[2]; vol = argV[2];
#if 0 while ((mobj = P_FindMobjFromTID(tag, mobj, info->mo)) != nullptr)
TAG_ITER_MOBJS(tag, mobj)
{ {
S_StartSoundAtVolume(mobj, sfxId, vol); S_StartSoundAtVolume(mobj, sfxId, vol);
} }
#else
CONS_Alert(CONS_WARNING,
"ThingSound not implemented -- waiting for mobj tags.\n"
);
(void)tag;
(void)vol;
#endif
return false; return false;
} }

View file

@ -582,6 +582,11 @@ fixed_t P_GetMobjFeet(const mobj_t *);
fixed_t P_GetMobjGround(const mobj_t *); fixed_t P_GetMobjGround(const mobj_t *);
fixed_t P_GetMobjZMovement(mobj_t *mo); fixed_t P_GetMobjZMovement(mobj_t *mo);
void P_InitTIDHash(void);
void P_SetThingTID(mobj_t *mo, mtag_t tid);
void P_RemoveThingTID(mobj_t *mo);
mobj_t *P_FindMobjFromTID(mtag_t tid, mobj_t *i, mobj_t *activator);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif #endif

View file

@ -11085,6 +11085,7 @@ void P_RemoveMobj(mobj_t *mobj)
memset((UINT8 *)mobj + sizeof(thinker_t), 0xff, sizeof(mobj_t) - sizeof(thinker_t)); memset((UINT8 *)mobj + sizeof(thinker_t), 0xff, sizeof(mobj_t) - sizeof(thinker_t));
#endif #endif
P_RemoveThingTID(mobj);
R_RemoveMobjInterpolator(mobj); R_RemoveMobjInterpolator(mobj);
// free block // free block
@ -13270,6 +13271,8 @@ static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y,
mobj->pitch = FixedAngle(mthing->pitch << FRACBITS); mobj->pitch = FixedAngle(mthing->pitch << FRACBITS);
mobj->roll = FixedAngle(mthing->roll << FRACBITS); mobj->roll = FixedAngle(mthing->roll << FRACBITS);
P_SetThingTID(mobj, Tag_FGet(&mthing->tags));
mthing->mobj = mobj; mthing->mobj = mobj;
// Generic reverse gravity for individual objects flag. // Generic reverse gravity for individual objects flag.
@ -14141,3 +14144,109 @@ fixed_t P_GetMobjZMovement(mobj_t *mo)
return P_ReturnThrustY(mo, slope->zangle, P_ReturnThrustX(mo, angDiff, speed)); return P_ReturnThrustY(mo, slope->zangle, P_ReturnThrustX(mo, angDiff, speed));
} }
//
// Thing IDs / tags
//
// TODO: Replace this system with taglist_t instead.
// The issue is that those require a static numbered ID
// to determine which struct it belongs to, which mobjs
// don't really have.
//
#define TID_HASH_CHAINS (131)
static mobj_t *TID_Hash[TID_HASH_CHAINS];
//
// P_InitTIDHash
// Initializes mobj tag hash array
//
void P_InitTIDHash(void)
{
memset(TID_Hash, 0, TID_HASH_CHAINS * sizeof(mobj_t *));
}
//
// P_SetThingTID
// Adds a mobj to the hash array
//
void P_SetThingTID(mobj_t *mo, mtag_t tid)
{
INT32 key = 0;
if (tid == 0)
{
if (mo->tid != 0)
{
P_RemoveThingTID(mo);
}
return;
}
mo->tid = tid;
// Insert at the head of this chain
key = tid % TID_HASH_CHAINS;
mo->tid_next = TID_Hash[key];
mo->tid_prev = &TID_Hash[key];
TID_Hash[key] = mo;
// Connect to any existing things in chain
if (mo->tid_next != NULL)
{
mo->tid_next->tid_prev = &(mo->tid_next);
}
}
//
// P_RemoveThingTID
// Removes a mobj from the hash array
//
void P_RemoveThingTID(mobj_t *mo)
{
if (mo->tid != 0 && mo->tid_prev != NULL)
{
// Fix the gap this would leave.
*(mo->tid_prev) = mo->tid_next;
if (mo->tid_next != NULL)
{
mo->tid_next->tid_prev = mo->tid_prev;
}
}
// Remove TID.
mo->tid = 0;
}
//
// P_FindMobjFromTID
// Mobj tag search function.
//
mobj_t *P_FindMobjFromTID(mtag_t tid, mobj_t *i, mobj_t *activator)
{
if (tid == 0)
{
// 0 grabs the activator, if applicable,
// for some ACS functions.
if (i != NULL)
{
// Don't do more than once.
return NULL;
}
return activator;
}
i = (i != NULL) ? i->tid_next : TID_Hash[tid % TID_HASH_CHAINS];
while (i != NULL && i->tid != tid)
{
i = i->tid_next;
}
return i;
}

View file

@ -338,6 +338,10 @@ struct mobj_t
UINT32 flags2; // MF2_ flags UINT32 flags2; // MF2_ flags
UINT16 eflags; // extra flags UINT16 eflags; // extra flags
mtag_t tid;
mobj_t *tid_next;
mobj_t **tid_prev; // killough 8/11/98: change to ptr-to-ptr
void *skin; // overrides 'sprite' when non-NULL (for player bodies to 'remember' the skin) void *skin; // overrides 'sprite' when non-NULL (for player bodies to 'remember' the skin)
// Player and mobj sprites in multiplayer modes are modified // Player and mobj sprites in multiplayer modes are modified
// using an internal color lookup table for re-indexing. // using an internal color lookup table for re-indexing.

View file

@ -1856,7 +1856,7 @@ typedef enum
MD2_ROLLANGLE = 1<<14, MD2_ROLLANGLE = 1<<14,
MD2_SHADOWSCALE = 1<<15, MD2_SHADOWSCALE = 1<<15,
MD2_RENDERFLAGS = 1<<16, MD2_RENDERFLAGS = 1<<16,
// 1<<17 was taken out, maybe reuse later MD2_TID = 1<<17,
MD2_SPRITEXSCALE = 1<<18, MD2_SPRITEXSCALE = 1<<18,
MD2_SPRITEYSCALE = 1<<19, MD2_SPRITEYSCALE = 1<<19,
MD2_SPRITEXOFFSET = 1<<20, MD2_SPRITEXOFFSET = 1<<20,
@ -2084,6 +2084,8 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
diff2 |= MD2_SHADOWSCALE; diff2 |= MD2_SHADOWSCALE;
if (mobj->renderflags) if (mobj->renderflags)
diff2 |= MD2_RENDERFLAGS; diff2 |= MD2_RENDERFLAGS;
if (mobj->tid != 0)
diff2 |= MD2_TID;
if (mobj->spritexscale != FRACUNIT) if (mobj->spritexscale != FRACUNIT)
diff2 |= MD2_SPRITEXSCALE; diff2 |= MD2_SPRITEXSCALE;
if (mobj->spriteyscale != FRACUNIT) if (mobj->spriteyscale != FRACUNIT)
@ -2285,6 +2287,8 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
WRITEUINT32(save->p, rf); WRITEUINT32(save->p, rf);
} }
if (diff2 & MD2_TID)
WRITEINT16(save->p, mobj->tid);
if (diff2 & MD2_SPRITEXSCALE) if (diff2 & MD2_SPRITEXSCALE)
WRITEFIXED(save->p, mobj->spritexscale); WRITEFIXED(save->p, mobj->spritexscale);
if (diff2 & MD2_SPRITEYSCALE) if (diff2 & MD2_SPRITEYSCALE)
@ -3406,6 +3410,8 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker)
} }
if (diff2 & MD2_RENDERFLAGS) if (diff2 & MD2_RENDERFLAGS)
mobj->renderflags = READUINT32(save->p); mobj->renderflags = READUINT32(save->p);
if (diff2 & MD2_TID)
P_SetThingTID(mobj, READINT16(save->p));
if (diff2 & MD2_SPRITEXSCALE) if (diff2 & MD2_SPRITEXSCALE)
mobj->spritexscale = READFIXED(save->p); mobj->spritexscale = READFIXED(save->p);
else else

View file

@ -7474,6 +7474,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
R_InitializeLevelInterpolators(); R_InitializeLevelInterpolators();
P_InitThinkers(); P_InitThinkers();
P_InitTIDHash();
R_InitMobjInterpolators(); R_InitMobjInterpolators();
P_InitCachedActions(); P_InitCachedActions();