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:
parent
ed025e5428
commit
1f6574e9a3
6 changed files with 141 additions and 18 deletions
|
|
@ -368,18 +368,21 @@ bool CallFunc_ThingCount(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::
|
|||
|
||||
if (tid != 0)
|
||||
{
|
||||
// TODO: Even in SRB2 next's UDMF, tag lists
|
||||
// still aren't attached to mobj_t, only
|
||||
// mapthing_t. Fix this.
|
||||
CONS_Alert(CONS_WARNING,
|
||||
"ThingCount TID field not implemented -- waiting for mobj tags.\n"
|
||||
);
|
||||
mobj_t *mobj = nullptr;
|
||||
|
||||
while ((mobj = P_FindMobjFromTID(tid, mobj, nullptr)) != nullptr)
|
||||
{
|
||||
if (ACS_CountThing(mobj, type) == true)
|
||||
{
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Search thinkers instead of tag lists.
|
||||
thinker_t *th = NULL;
|
||||
mobj_t *mobj = NULL;
|
||||
thinker_t *th = nullptr;
|
||||
mobj_t *mobj = nullptr;
|
||||
|
||||
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)
|
||||
{
|
||||
auto info = &static_cast<Thread *>(thread)->info;
|
||||
|
||||
ACSVM::MapScope *map = 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;
|
||||
INT32 vol = 0;
|
||||
|
||||
mobj_t *mobj = nullptr;
|
||||
|
||||
(void)argC;
|
||||
|
||||
tag = argV[0];
|
||||
|
|
@ -901,19 +908,10 @@ bool CallFunc_ThingSound(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::
|
|||
|
||||
vol = argV[2];
|
||||
|
||||
#if 0
|
||||
TAG_ITER_MOBJS(tag, mobj)
|
||||
while ((mobj = P_FindMobjFromTID(tag, mobj, info->mo)) != nullptr)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -589,6 +589,11 @@ fixed_t P_GetMobjFeet(const mobj_t *);
|
|||
fixed_t P_GetMobjGround(const mobj_t *);
|
||||
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
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
109
src/p_mobj.c
109
src/p_mobj.c
|
|
@ -10155,6 +10155,7 @@ void P_RemoveMobj(mobj_t *mobj)
|
|||
memset((UINT8 *)mobj + sizeof(thinker_t), 0xff, sizeof(mobj_t) - sizeof(thinker_t));
|
||||
#endif
|
||||
|
||||
P_RemoveThingTID(mobj);
|
||||
R_RemoveMobjInterpolator(mobj);
|
||||
|
||||
// free block
|
||||
|
|
@ -12443,6 +12444,8 @@ static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y,
|
|||
mobj->pitch = FixedAngle(mthing->pitch << FRACBITS);
|
||||
mobj->roll = FixedAngle(mthing->roll << FRACBITS);
|
||||
|
||||
P_SetThingTID(mobj, Tag_FGet(&mthing->tags));
|
||||
|
||||
mthing->mobj = mobj;
|
||||
|
||||
// Generic reverse gravity for individual objects flag.
|
||||
|
|
@ -13421,3 +13424,109 @@ fixed_t P_GetMobjZMovement(mobj_t *mo)
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -336,6 +336,10 @@ struct mobj_t
|
|||
UINT32 flags2; // MF2_ 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)
|
||||
// Player and mobj sprites in multiplayer modes are modified
|
||||
// using an internal color lookup table for re-indexing.
|
||||
|
|
|
|||
|
|
@ -2009,6 +2009,8 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
|
|||
diff2 |= MD2_SHADOWSCALE;
|
||||
if (mobj->renderflags)
|
||||
diff2 |= MD2_RENDERFLAGS;
|
||||
if (mobj->tid != 0)
|
||||
diff2 |= MD2_TID;
|
||||
if (mobj->spritexscale != FRACUNIT)
|
||||
diff2 |= MD2_SPRITEXSCALE;
|
||||
if (mobj->spriteyscale != FRACUNIT)
|
||||
|
|
@ -2210,6 +2212,8 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
|
|||
|
||||
WRITEUINT32(save->p, rf);
|
||||
}
|
||||
if (diff2 & MD2_TID)
|
||||
WRITEINT16(save->p, mobj->tid);
|
||||
if (diff2 & MD2_SPRITEXSCALE)
|
||||
WRITEFIXED(save->p, mobj->spritexscale);
|
||||
if (diff2 & MD2_SPRITEYSCALE)
|
||||
|
|
@ -3360,6 +3364,8 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker)
|
|||
}
|
||||
if (diff2 & MD2_RENDERFLAGS)
|
||||
mobj->renderflags = READUINT32(save->p);
|
||||
if (diff2 & MD2_TID)
|
||||
P_SetThingTID(mobj, READINT16(save->p));
|
||||
if (diff2 & MD2_SPRITEXSCALE)
|
||||
mobj->spritexscale = READFIXED(save->p);
|
||||
else
|
||||
|
|
|
|||
|
|
@ -8045,6 +8045,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
|
|||
R_InitializeLevelInterpolators();
|
||||
|
||||
P_InitThinkers();
|
||||
P_InitTIDHash();
|
||||
R_InitMobjInterpolators();
|
||||
P_InitCachedActions();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue