From d0888c4ac5e4b9d58f48f3b8c209bd561ab76e16 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Thu, 1 Jul 2021 18:48:18 +0200 Subject: [PATCH] Split wind/current and point push/pull thinkers --- src/p_saveg.c | 38 +++++++++++++++++++++ src/p_spec.c | 92 +++++++++++++++++++++++++++++++-------------------- src/p_spec.h | 13 +++++++- src/p_tick.c | 8 ++++- 4 files changed, 114 insertions(+), 37 deletions(-) diff --git a/src/p_saveg.c b/src/p_saveg.c index bf28b11a5..ea81e9853 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -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); } diff --git a/src/p_spec.c b/src/p_spec.c index 32b935959..e05f1f066 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -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<y_mag<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 diff --git a/src/p_spec.h b/src/p_spec.h index c2b6953cf..10e7c9368 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -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 diff --git a/src/p_tick.c b/src/p_tick.c index d7357eb82..1a8242db7 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -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;