Split wind/current and point push/pull thinkers

This commit is contained in:
MascaraSnake 2021-07-01 18:48:18 +02:00
parent 052bfe130c
commit d0888c4ac5
4 changed files with 114 additions and 37 deletions

View file

@ -1483,6 +1483,7 @@ typedef enum
tc_scroll,
tc_friction,
tc_pusher,
tc_pointpusher,
tc_laserflash,
tc_lightfade,
tc_executor,
@ -2141,6 +2142,19 @@ static inline void SavePusherThinker(const thinker_t *th, const UINT8 type)
WRITEINT32(save_p, ht->slider);
}
static inline void SavePointPusherThinker(const thinker_t* th, const UINT8 type)
{
const pointpusher_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEINT32(save_p, ht->magnitude);
WRITEINT32(save_p, ht->radius);
WRITEINT32(save_p, ht->x);
WRITEINT32(save_p, ht->y);
WRITEINT32(save_p, ht->z);
WRITEINT32(save_p, ht->affectee);
WRITEINT32(save_p, ht->exclusive);
}
static void SaveLaserThinker(const thinker_t *th, const UINT8 type)
{
const laserthink_t *ht = (const void *)th;
@ -2460,6 +2474,11 @@ static void P_NetArchiveThinkers(void)
SavePusherThinker(th, tc_pusher);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_PointPusher)
{
SavePointPusherThinker(th, tc_pointpusher);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_BounceCheese)
{
SaveBounceCheeseThinker(th, tc_bouncecheese);
@ -3282,6 +3301,21 @@ static thinker_t* LoadPusherThinker(actionf_p1 thinker)
return &ht->thinker;
}
static thinker_t* LoadPointPusherThinker(actionf_p1 thinker)
{
pointpusher_t *ht = Z_Malloc(sizeof(*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->magnitude = READINT32(save_p);
ht->radius = READINT32(save_p);
ht->x = READINT32(save_p);
ht->y = READINT32(save_p);
ht->z = READINT32(save_p);
ht->affectee = READINT32(save_p);
ht->exclusive = READINT32(save_p);
ht->source = P_GetPushThing(ht->affectee);
return &ht->thinker;
}
static inline thinker_t* LoadLaserThinker(actionf_p1 thinker)
{
laserthink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
@ -3744,6 +3778,10 @@ static void P_NetUnArchiveThinkers(void)
th = LoadPusherThinker((actionf_p1)T_Pusher);
break;
case tc_pointpusher:
th = LoadPointPusherThinker((actionf_p1)T_PointPusher);
break;
default:
I_Error("P_UnarchiveSpecials: Unknown tclass %d in savegame", tclass);
}

View file

@ -98,6 +98,7 @@ typedef struct
static void P_SpawnScrollers(void);
static void P_SpawnFriction(void);
static void P_SpawnPushers(void);
static void Add_PointPusher(INT32 magnitude, mobj_t *source, INT32 affectee, INT32 exclusive);
static void Add_Pusher(pushertype_e type, fixed_t x_mag, fixed_t y_mag, mobj_t *source, INT32 affectee, INT32 referrer, INT32 exclusive, INT32 slider); //SoM: 3/9/2000
static void Add_MasterDisappearer(tic_t appeartime, tic_t disappeartime, tic_t offset, INT32 line, INT32 sourceline);
static void P_ResetFakeFloorFader(ffloor_t *rover, fade_t *data, boolean finalize);
@ -5608,6 +5609,13 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, I
if (p->affectee == (INT32)sec2num)
Add_Pusher(p->type, p->x_mag<<FRACBITS, p->y_mag<<FRACBITS, p->source, (INT32)(sec-sectors), p->affectee, p->exclusive, p->slider);
}
else if (th->function.acp1 == (actionf_p1)T_PointPusher)
{
pointpusher_t *pp = (pointpusher_t *)th;
if (pp->affectee == (INT32)sec2num)
Add_PointPusher(pp->magnitude, pp->source, pp->affectee, pp->exclusive);
}
if(secthinkers) i++;
else th = th->next;
@ -6169,6 +6177,8 @@ void P_SpawnSpecials(boolean fromnetsave)
secthinkers[((friction_t *)th)->affectee].count++;
else if (th->function.acp1 == (actionf_p1)T_Pusher)
secthinkers[((pusher_t *)th)->affectee].count++;
else if (th->function.acp1 == (actionf_p1)T_PointPusher)
secthinkers[((pointpusher_t *)th)->affectee].count++;
}
// Allocate each list, and then zero the count so we can use it to track
@ -6189,6 +6199,8 @@ void P_SpawnSpecials(boolean fromnetsave)
secnum = ((friction_t *)th)->affectee;
else if (th->function.acp1 == (actionf_p1)T_Pusher)
secnum = ((pusher_t *)th)->affectee;
else if (th->function.acp1 == (actionf_p1)T_PointPusher)
secnum = ((pointpusher_t *)th)->affectee;
if (secnum != (size_t)-1)
secthinkers[secnum].thinkers[secthinkers[secnum].count++] = th;
@ -8497,6 +8509,26 @@ static void P_SpawnFriction(void)
#define PUSH_FACTOR 7
static void Add_PointPusher(INT32 magnitude, mobj_t *source, INT32 affectee, INT32 exclusive)
{
pointpusher_t *p = Z_Calloc(sizeof * p, PU_LEVSPEC, NULL);
p->thinker.function.acp1 = (actionf_p1)T_PointPusher;
p->source = source;
p->magnitude = magnitude;
p->exclusive = exclusive;
if (source) // point source exist?
{
p->radius = AngleFixed(source->angle);
p->x = p->source->x;
p->y = p->source->y;
p->z = p->source->z;
}
p->affectee = affectee;
P_AddThinker(THINK_MAIN, &p->thinker);
}
/** Adds a pusher.
*
* \param type Type of push/pull effect.
@ -8535,12 +8567,7 @@ static void Add_Pusher(pushertype_e type, fixed_t x_mag, fixed_t y_mag, mobj_t *
p->magnitude = P_AproxDistance(p->x_mag,p->y_mag);
if (source) // point source exist?
{
// where force goes to zero
if (type == p_push)
p->radius = AngleFixed(source->angle);
else
p->radius = (p->magnitude)<<(FRACBITS+1);
p->radius = (p->magnitude)<<(FRACBITS+1);
p->x = p->source->x;
p->y = p->source->y;
p->z = p->source->z;
@ -8549,10 +8576,9 @@ static void Add_Pusher(pushertype_e type, fixed_t x_mag, fixed_t y_mag, mobj_t *
P_AddThinker(THINK_MAIN, &p->thinker);
}
// PIT_PushThing determines the angle and magnitude of the effect.
// The object's x and y momentum values are changed.
static pusher_t *tmpusher; // pusher structure for blockmap searches
static pointpusher_t *tmpusher; // pointpusher structure for blockmap searches
/** Applies a point pusher/puller to a thing.
*
@ -8702,6 +8728,28 @@ static inline boolean PIT_PushThing(mobj_t *thing)
return true;
}
void T_PointPusher(pointpusher_t *p)
{
INT32 xl, xh, yl, yh, bx, by;
// Seek out all pushable things within the force radius of this
// point pusher. Crosses sectors, so use blockmap.
tmpusher = p; // MT_PUSH/MT_PULL point source
tmbbox[BOXTOP] = p->y + p->radius;
tmbbox[BOXBOTTOM] = p->y - p->radius;
tmbbox[BOXRIGHT] = p->x + p->radius;
tmbbox[BOXLEFT] = p->x - p->radius;
xl = (unsigned)(tmbbox[BOXLEFT] - bmaporgx - MAXRADIUS)>>MAPBLOCKSHIFT;
xh = (unsigned)(tmbbox[BOXRIGHT] - bmaporgx + MAXRADIUS)>>MAPBLOCKSHIFT;
yl = (unsigned)(tmbbox[BOXBOTTOM] - bmaporgy - MAXRADIUS)>>MAPBLOCKSHIFT;
yh = (unsigned)(tmbbox[BOXTOP] - bmaporgy + MAXRADIUS)>>MAPBLOCKSHIFT;
for (bx = xl; bx <= xh; bx++)
for (by = yl; by <= yh; by++)
P_BlockThingsIterator(bx, by, PIT_PushThing);
}
/** Applies a pusher to all affected objects.
*
* \param p Thinker for the pusher effect.
@ -8714,9 +8762,6 @@ void T_Pusher(pusher_t *p)
mobj_t *thing;
msecnode_t *node;
INT32 xspeed = 0,yspeed = 0;
INT32 xl, xh, yl, yh, bx, by;
INT32 radius;
//INT32 ht = 0;
boolean inFOF;
boolean touching;
boolean moved;
@ -8756,29 +8801,6 @@ void T_Pusher(pusher_t *p)
//
// In Phase II, you can apply these effects to Things other than players.
if (p->type == p_push)
{
// Seek out all pushable things within the force radius of this
// point pusher. Crosses sectors, so use blockmap.
tmpusher = p; // MT_PUSH/MT_PULL point source
radius = p->radius; // where force goes to zero
tmbbox[BOXTOP] = p->y + radius;
tmbbox[BOXBOTTOM] = p->y - radius;
tmbbox[BOXRIGHT] = p->x + radius;
tmbbox[BOXLEFT] = p->x - radius;
xl = (unsigned)(tmbbox[BOXLEFT] - bmaporgx - MAXRADIUS)>>MAPBLOCKSHIFT;
xh = (unsigned)(tmbbox[BOXRIGHT] - bmaporgx + MAXRADIUS)>>MAPBLOCKSHIFT;
yl = (unsigned)(tmbbox[BOXBOTTOM] - bmaporgy - MAXRADIUS)>>MAPBLOCKSHIFT;
yh = (unsigned)(tmbbox[BOXTOP] - bmaporgy + MAXRADIUS)>>MAPBLOCKSHIFT;
for (bx = xl; bx <= xh; bx++)
for (by = yl; by <= yh; by++)
P_BlockThingsIterator(bx,by, PIT_PushThing);
return;
}
// constant pushers p_wind and p_current
node = sec->touching_thinglist; // things touching this sector
for (; node; node = node->m_thinglist_next)
@ -9022,7 +9044,7 @@ static void P_SpawnPushers(void)
{
thing = P_GetPushThing(s);
if (thing) // No MT_P* means no effect
Add_Pusher(p_push, l->dx, l->dy, thing, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4);
Add_PointPusher(P_AproxDistance(l->dx >> FRACBITS, l->dy >> FRACBITS), thing, s, l->flags & ML_NOCLIMB);
}
break;
case 545: // current up

View file

@ -632,7 +632,6 @@ void T_Friction(friction_t *f);
typedef enum
{
p_push, ///< Point pusher or puller.
p_wind, ///< Wind.
p_current, ///< Current.
p_upcurrent, ///< Upwards current.
@ -661,6 +660,17 @@ typedef struct
INT32 slider; /// < Should the player go into an uncontrollable slide?
} pusher_t;
typedef struct
{
thinker_t thinker; ///< Thinker structure for push/pull effect.
mobj_t *source; ///< Point source.
INT32 magnitude; ///< Vector strength.
INT32 radius; ///< Effective radius.
INT32 x, y, z; ///< Point source.
INT32 affectee; ///< Number of affected sector.
INT32 exclusive; /// < Once this affect has been applied to a mobj, no other pushers may affect it.
} pointpusher_t;
// Model for disappearing/reappearing FOFs
typedef struct
{
@ -719,6 +729,7 @@ void T_FadeColormap(fadecolormap_t *d);
// Prototype functions for pushers
void T_Pusher(pusher_t *p);
void T_PointPusher(pointpusher_t *p);
mobj_t *P_GetPushThing(UINT32 s);
// Plane displacement

View file

@ -66,7 +66,8 @@ void Command_Numthinkers_f(void)
"\t2: P_NullPrecipThinker\n"
"\t3: T_Friction\n"
"\t4: T_Pusher\n"
"\t5: P_RemoveThinkerDelayed\n");
"\t5: T_PointPusher\n"
"\t6: P_RemoveThinkerDelayed\n");
return;
}
@ -103,6 +104,11 @@ void Command_Numthinkers_f(void)
CONS_Printf(M_GetText("Number of %s: "), "T_Pusher");
break;
case 5:
start = end = THINK_MAIN;
action = (actionf_p1)T_PointPusher;
CONS_Printf(M_GetText("Number of %s: "), "T_PointPusher");
break;
case 6:
action = (actionf_p1)P_RemoveThinkerDelayed;
CONS_Printf(M_GetText("Number of %s: "), "P_RemoveThinkerDelayed");
break;