Implement thing special

Executes when an object is killed.
This commit is contained in:
Sally Coolatta 2023-01-05 23:58:48 -05:00
parent 1caf255f5c
commit 75658fd469
7 changed files with 79 additions and 4 deletions

View file

@ -248,6 +248,7 @@ struct mapthing_t
UINT8 extrainfo;
taglist_t tags;
fixed_t scale;
INT16 special;
INT32 args[NUMMAPTHINGARGS];
char *stringargs[NUMMAPTHINGSTRINGARGS];
mobj_t *mobj;

View file

@ -956,6 +956,8 @@ static int mapthing_get(lua_State *L)
LUA_PushUserdata(L, &mt->tags, META_TAGLIST);
return 1;
}
else if(fastcmp(field,"special"))
number = mt->special;
else if(fastcmp(field,"args"))
{
LUA_PushUserdata(L, mt->args, META_THINGARGS);
@ -1020,6 +1022,12 @@ static int mapthing_set(lua_State *L)
Tag_FSet(&mt->tags, (INT16)luaL_checkinteger(L, 3));
else if (fastcmp(field,"taglist"))
return LUA_ErrSetDirectly(L, "mapthing_t", "taglist");
else if (fastcmp(field,"special"))
{
// Can't change mapthing args (yet?), so let's not allow changing special either.
//mt->special = (INT16)luaL_checkinteger(L, 3);
return LUA_ErrSetDirectly(L, "mapthing_t", "special");
}
else if(fastcmp(field,"mobj"))
mt->mobj = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
else

View file

@ -1036,6 +1036,8 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
if (LUA_HookMobjDeath(target, inflictor, source, damagetype) || P_MobjWasRemoved(target))
return;
P_ActivateThingSpecial(target, source);
//K_SetHitLagForObjects(target, inflictor, MAXHITLAGTICS, true);
// SRB2kart

View file

@ -1693,6 +1693,8 @@ static void ParseTextmapThingParameter(UINT32 i, const char *param, const char *
else if (fastcmp(param, "flip") && fastcmp("true", val))
mapthings[i].options |= MTF_OBJECTFLIP;
else if (fastcmp(param, "special"))
mapthings[i].special = atol(val);
else if (fastncmp(param, "stringarg", 9) && strlen(param) > 9)
{
size_t argnum = atol(param + 9);
@ -2100,6 +2102,8 @@ static void P_WriteTextmap(void)
fprintf(f, "scale = %f;\n", FIXED_TO_FLOAT(wmapthings[i].scale));
if (wmapthings[i].options & MTF_OBJECTFLIP)
fprintf(f, "flip = true;\n");
if (wmapthings[i].special != 0)
fprintf(f, "special = %d;\n", wmapthings[i].special);
for (j = 0; j < NUMMAPTHINGARGS; j++)
if (wmapthings[i].args[j] != 0)
fprintf(f, "arg%s = %d;\n", sizeu1(j), wmapthings[i].args[j]);

View file

@ -2185,7 +2185,6 @@ void P_CrossSpecialLine(line_t *line, INT32 side, mobj_t *thing)
activator->line = line;
activator->side = side;
activator->sector = (side != 0) ? line->backsector : line->frontsector;
activator->fromLineSpecial = true;
result = P_ProcessSpecial(activator, line->special, line->args, line->stringargs);
Z_Free(activator);
@ -2268,7 +2267,6 @@ void P_PushSpecialLine(line_t *line, mobj_t *thing)
activator->line = line;
activator->side = P_PointOnLineSide(thing->x, thing->y, line);
activator->sector = (activator->side != 0) ? line->backsector : line->frontsector;
activator->fromLineSpecial = true;
result = P_ProcessSpecial(activator, line->special, line->args, line->stringargs);
Z_Free(activator);
@ -2279,6 +2277,68 @@ void P_PushSpecialLine(line_t *line, mobj_t *thing)
}
}
//
// P_ActivateThingSpecial - TRIGGER
// Called when a thing is killed, or upon
// any other type-specific conditions
//
void P_ActivateThingSpecial(mobj_t *mo, mobj_t *source)
{
mapthing_t *mt = NULL;
player_t *player = NULL;
activator_t *activator = NULL;
if (mo == NULL || P_MobjWasRemoved(mo) == true)
{
// Invalid mobj.
return;
}
mt = mo->spawnpoint;
if (mt == NULL)
{
// No mapthing to activate the special of.
return;
}
// Is this necessary? Probably not, but I hate
// spectators so I will manually ensure they
// can't impact the gamestate anyway.
player = mo->player;
if (player != NULL)
{
if (player->spectator == true)
{
// Ignore spectators.
return;
}
if (player->pflags & PF_NOCONTEST)
{
// Ignore NO CONTEST.
return;
}
}
if (P_CanActivateSpecial(mt->special) == false)
{
// No special to even activate.
return;
}
activator = Z_Calloc(sizeof(activator_t), PU_LEVEL, NULL);
I_Assert(activator != NULL);
if (source != NULL)
{
P_SetTarget(&activator->mo, source);
activator->sector = source->subsector->sector;
}
P_ProcessSpecial(activator, mt->special, mt->args, mt->stringargs);
Z_Free(activator);
}
/** Gets an object.
*
* \param type Object type to look for.
@ -2379,7 +2439,6 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
P_SetTarget(&activator->mo, mo);
activator->line = line;
activator->sector = callsec;
activator->fromLineSpecial = true;
P_ProcessSpecial(activator, line->special, line->args, line->stringargs);
Z_Free(activator);

View file

@ -565,6 +565,7 @@ INT32 P_FindMinSurroundingLight(sector_t *sector, INT32 max);
void P_CrossSpecialLine(line_t *line, INT32 side, mobj_t *thing);
void P_PushSpecialLine(line_t *line, mobj_t *thing);
void P_ActivateThingSpecial(mobj_t *mo, mobj_t *source);
//
// Special activation info

View file

@ -339,7 +339,7 @@ if ((*mop = targ) != NULL) // Set new target and if non-NULL, increase its count
// Rewritten to delete nodes implicitly, by making currentthinker
// external and using P_RemoveThinkerDelayed() implicitly.
//
static inline void P_RunThinkers(void)
static void P_RunThinkers(void)
{
size_t i;