From ebf692f1432307fd9e79897914fc2d0669586cb0 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Thu, 16 Dec 2021 07:00:30 +0100 Subject: [PATCH] Adapt push/pull point to UDMF --- extras/conf/udb/Includes/SRB222_things.cfg | 26 +- src/info.c | 28 -- src/info.h | 1 - src/p_mobj.c | 127 ++++++++- src/p_saveg.c | 38 --- src/p_setup.c | 57 ++++ src/p_spec.c | 287 +-------------------- src/p_spec.h | 23 +- src/p_tick.c | 8 +- 9 files changed, 216 insertions(+), 379 deletions(-) diff --git a/extras/conf/udb/Includes/SRB222_things.cfg b/extras/conf/udb/Includes/SRB222_things.cfg index 007196959..dd8e353eb 100644 --- a/extras/conf/udb/Includes/SRB222_things.cfg +++ b/extras/conf/udb/Includes/SRB222_things.cfg @@ -4504,13 +4504,27 @@ udmf 754 { - title = "Push Point"; + title = "Push/Pull Point"; sprite = "GWLGA0"; - } - 755 - { - title = "Pull Point"; - sprite = "GWLRA0"; + arg0 + { + title = "Radius"; + } + arg1 + { + title = "Strength"; + } + arg2 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Fade using XY"; + 2 = "Push using XYZ"; + 4 = "Non-exclusive"; + } + } } 756 { diff --git a/src/info.c b/src/info.c index f56e5d78e..f44659bda 100644 --- a/src/info.c +++ b/src/info.c @@ -20713,34 +20713,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - // for use with wind and current effects - { // MT_PULL - 755, // doomednum - S_INVISIBLE, // spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 8, // radius - 8, // height - 0, // display offset - 10, // mass - 0, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOGRAVITY, // flags - S_NULL // raisestate - }, - { // MT_GHOST -1, // doomednum S_THOK, // spawnstate diff --git a/src/info.h b/src/info.h index 031a08b43..28965f4b3 100644 --- a/src/info.h +++ b/src/info.h @@ -5046,7 +5046,6 @@ typedef enum mobj_type MT_CRUMBLEOBJ, // Sound generator for crumbling platform MT_TUBEWAYPOINT, MT_PUSH, - MT_PULL, MT_GHOST, MT_OVERLAY, MT_ANGLEMAN, diff --git a/src/p_mobj.c b/src/p_mobj.c index 5b4feb3ca..cf4e2ad6e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9234,6 +9234,118 @@ static void P_DragonbomberThink(mobj_t *mobj) #undef DRAGONTURNSPEED } +static mobj_t *pushmobj; + +#define PUSH_FACTOR 7 + +static inline boolean PIT_PushThing(mobj_t *thing) +{ + if (thing->eflags & MFE_PUSHED) + return false; + + if (thing->player && thing->player->powers[pw_carry] == CR_ROPEHANG) + return false; + + if (!pushmobj) + return false; + + if (!pushmobj->spawnpoint) + return false; + + // Allow this to affect pushable objects at some point? + if (thing->player && !(thing->flags & (MF_NOGRAVITY|MF_NOCLIP))) + { + INT32 dist; + INT32 speed; + INT32 sx = pushmobj->x; + INT32 sy = pushmobj->y; + INT32 sz = pushmobj->z; + fixed_t radius = pushmobj->spawnpoint->args[0] << FRACBITS; + + if (pushmobj->spawnpoint->args[2] & TMPP_NOZFADE) + dist = P_AproxDistance(thing->x - sx, thing->y - sy); + else + { + // Make sure the Z is in range + if (thing->z < sz - radius || thing->z > sz + radius) + return false; + + dist = P_AproxDistance(P_AproxDistance(thing->x - sx, thing->y - sy), thing->z - sz); + } + + speed = (abs(pushmobj->spawnpoint->args[1]) - ((dist>>FRACBITS)>>1))<<(FRACBITS - PUSH_FACTOR - 1); + + // If speed <= 0, you're outside the effective radius. You also have + // to be able to see the push/pull source point. + + // Written with bits and pieces of P_HomingAttack + if ((speed > 0) && (P_CheckSight(thing, pushmobj))) + { + fixed_t tmpmomx, tmpmomy, tmpmomz; + + if (pushmobj->spawnpoint->args[2] & TMPP_PUSHZ) + { + tmpmomx = FixedMul(FixedDiv(sx - thing->x, dist), speed); + tmpmomy = FixedMul(FixedDiv(sy - thing->y, dist), speed); + tmpmomz = FixedMul(FixedDiv(sz - thing->z, dist), speed); + } + else + { + angle_t pushangle = R_PointToAngle2(thing->x, thing->y, sx, sy) >> ANGLETOFINESHIFT; + tmpmomx = FixedMul(speed, FINECOSINE(pushangle)); + tmpmomy = FixedMul(speed, FINESINE(pushangle)); + tmpmomz = 0; + } + + if (pushmobj->spawnpoint->args[1] > 0) // away! + { + tmpmomx *= -1; + tmpmomy *= -1; + tmpmomz *= -1; + } + + thing->momx += tmpmomx; + thing->momy += tmpmomy; + thing->momz += tmpmomz; + + if (thing->player) + { + thing->player->cmomx += tmpmomx; + thing->player->cmomy += tmpmomy; + thing->player->cmomx = FixedMul(thing->player->cmomx, 0xe800); + thing->player->cmomy = FixedMul(thing->player->cmomy, 0xe800); + } + } + } + + if (!(pushmobj->spawnpoint->args[2] & TMPP_NONEXCLUSIVE)) + thing->eflags |= MFE_PUSHED; + + return true; +} + +static void P_PointPushThink(mobj_t *mobj) +{ + INT32 xl, xh, yl, yh, bx, by; + fixed_t radius; + + if (!mobj->spawnpoint) + return; + + // Seek out all pushable things within the force radius of this + // point pusher. Crosses sectors, so use blockmap. + radius = mobj->spawnpoint->args[0] << FRACBITS; + + pushmobj = mobj; + xl = (unsigned)(mobj->x - radius - bmaporgx - MAXRADIUS)>>MAPBLOCKSHIFT; + xh = (unsigned)(mobj->x + radius - bmaporgx + MAXRADIUS)>>MAPBLOCKSHIFT; + yl = (unsigned)(mobj->y - radius - bmaporgy - MAXRADIUS)>>MAPBLOCKSHIFT; + yh = (unsigned)(mobj->y + radius - bmaporgy + MAXRADIUS)>>MAPBLOCKSHIFT; + for (bx = xl; bx <= xh; bx++) + for (by = yl; by <= yh; by++) + P_BlockThingsIterator(bx, by, PIT_PushThing); +} + static boolean P_MobjRegularThink(mobj_t *mobj) { if ((mobj->flags & MF_ENEMY) && (mobj->state->nextstate == mobj->info->spawnstate && mobj->tics == 1)) @@ -9721,6 +9833,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj) else mobj->rollangle = R_PointToAngle2(0, 0, mobj->momz, (mobj->scale << 1) - min(abs(mobj->momz), mobj->scale << 1)); break; + case MT_PUSH: + P_PointPushThink(mobj); + break; case MT_SPINFIRE: if (mobj->flags & MF_NOGRAVITY) { @@ -12956,18 +13071,6 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean blueflag = mobj; bflagpoint = mobj->spawnpoint; break; - case MT_PUSH: - case MT_PULL: - mobj->health = 0; // Default behaviour: pushing uses XY, fading uses XYZ - - if (mthing->options & MTF_AMBUSH) - mobj->health |= 1; // If ambush is set, push using XYZ - if (mthing->options & MTF_OBJECTSPECIAL) - mobj->health |= 2; // If object special is set, fade using XY - - if (G_IsSpecialStage(gamemap)) - P_SetMobjState(mobj, (mobj->type == MT_PUSH) ? S_GRAVWELLGREEN : S_GRAVWELLRED); - break; case MT_NIGHTSSTAR: if (maptol & TOL_XMAS) P_SetMobjState(mobj, mobj->info->seestate); diff --git a/src/p_saveg.c b/src/p_saveg.c index bc9c31d64..689fa4d95 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1537,7 +1537,6 @@ typedef enum tc_scroll, tc_friction, tc_pusher, - tc_pointpusher, tc_laserflash, tc_lightfade, tc_executor, @@ -2191,19 +2190,6 @@ 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; @@ -2523,11 +2509,6 @@ 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); @@ -3344,21 +3325,6 @@ 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); @@ -3821,10 +3787,6 @@ 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_setup.c b/src/p_setup.c index aecb4fe4d..ce4c764e4 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3146,6 +3146,28 @@ static void P_WriteConstant(INT32 constant, char **target) M_Memcpy(*target, buffer, strlen(buffer) + 1); } +static line_t *P_FindPointPushLine(taglist_t *list) +{ + INT32 i, l; + + for (i = 0; i < list->count; i++) + { + mtag_t tag = list->tags[i]; + TAG_ITER_LINES(tag, l) + { + if (Tag_FGet(&lines[l].tags) != tag) + continue; + + if (lines[l].special != 547) + continue; + + return &lines[l]; + } + } + + return NULL; +} + //For maps in binary format, converts setup of specials to UDMF format. static void P_ConvertBinaryMap(void) { @@ -4851,6 +4873,41 @@ static void P_ConvertBinaryMap(void) { switch (mapthings[i].type) { + case 754: //Push point + case 755: //Pull point + { + subsector_t *ss = R_PointInSubsector(mapthings[i].x << FRACBITS, mapthings[i].y << FRACBITS); + sector_t *s; + line_t *line; + + if (!ss) + { + CONS_Debug(DBG_GAMELOGIC, "Push/pull point: Placed outside of map bounds!\n"); + break; + } + + s = ss->sector; + line = P_FindPointPushLine(&s->tags); + + if (!line) + { + CONS_Debug(DBG_GAMELOGIC, "Push/pull point: Unable to find line of type 547 tagged to sector %s!\n", sizeu1((size_t)(s - sectors))); + break; + } + + mapthings[i].args[0] = mapthings[i].angle; + mapthings[i].args[1] = P_AproxDistance(line->dx >> FRACBITS, line->dy >> FRACBITS); + if (mapthings[i].type == 755) + mapthings[i].args[1] *= -1; + if (mapthings[i].options & MTF_OBJECTSPECIAL) + mapthings[i].args[2] |= TMPP_NOZFADE; + if (mapthings[i].options & MTF_AMBUSH) + mapthings[i].args[2] |= TMPP_PUSHZ; + if (!(line->flags & ML_NOCLIMB)) + mapthings[i].args[2] |= TMPP_NONEXCLUSIVE; + mapthings[i].type = 754; + break; + } case 762: //PolyObject spawn point (crush) { INT32 check = -1; diff --git a/src/p_spec.c b/src/p_spec.c index a1eb4183c..deb915eeb 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -98,7 +98,6 @@ 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, fixed_t z_mag, 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); @@ -5331,7 +5330,6 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, I thinker_t *th; friction_t *f; pusher_t *p; - pointpusher_t *pp; size_t sec2num; size_t i; @@ -5442,13 +5440,6 @@ 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, p->y_mag, p->z_mag, (INT32)(sec-sectors), p->affectee, p->exclusive, p->slider); } - else if (th->function.acp1 == (actionf_p1)T_PointPusher) - { - 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; @@ -6024,8 +6015,6 @@ 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 @@ -6046,8 +6035,6 @@ 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; @@ -8328,26 +8315,6 @@ 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. @@ -8382,187 +8349,6 @@ static void Add_Pusher(pushertype_e type, fixed_t x_mag, fixed_t y_mag, fixed_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 pointpusher_t *tmpusher; // pointpusher structure for blockmap searches - -/** Applies a point pusher/puller to a thing. - * - * \param thing Thing to be pushed. - * \return True if the thing was pushed. - * \todo Make a more robust P_BlockThingsIterator() so the hidden parameter - * ::tmpusher won't need to be used. - * \sa T_Pusher - */ -static inline boolean PIT_PushThing(mobj_t *thing) -{ - if (thing->eflags & MFE_PUSHED) - return false; - - if (thing->player && thing->player->powers[pw_carry] == CR_ROPEHANG) - return false; - - if (!tmpusher->source) - return false; - - // Allow this to affect pushable objects at some point? - if (thing->player && (!(thing->flags & (MF_NOGRAVITY | MF_NOCLIP)) || thing->player->powers[pw_carry] == CR_NIGHTSMODE)) - { - INT32 dist; - INT32 speed; - INT32 sx, sy, sz; - - sx = tmpusher->x; - sy = tmpusher->y; - sz = tmpusher->z; - - // don't fade wrt Z if health & 2 (mapthing has multi flag) - if (tmpusher->source->health & 2) - dist = P_AproxDistance(thing->x - sx,thing->y - sy); - else - { - // Make sure the Z is in range - if (thing->z < sz - tmpusher->radius || thing->z > sz + tmpusher->radius) - return false; - - dist = P_AproxDistance(P_AproxDistance(thing->x - sx, thing->y - sy), - thing->z - sz); - } - - speed = (tmpusher->magnitude - ((dist>>FRACBITS)>>1))<<(FRACBITS - PUSH_FACTOR - 1); - - // If speed <= 0, you're outside the effective radius. You also have - // to be able to see the push/pull source point. - - // Written with bits and pieces of P_HomingAttack - if ((speed > 0) && (P_CheckSight(thing, tmpusher->source))) - { - if (thing->player->powers[pw_carry] != CR_NIGHTSMODE) - { - // only push wrt Z if health & 1 (mapthing has ambush flag) - if (tmpusher->source->health & 1) - { - fixed_t tmpmomx, tmpmomy, tmpmomz; - - tmpmomx = FixedMul(FixedDiv(sx - thing->x, dist), speed); - tmpmomy = FixedMul(FixedDiv(sy - thing->y, dist), speed); - tmpmomz = FixedMul(FixedDiv(sz - thing->z, dist), speed); - if (tmpusher->source->type == MT_PUSH) // away! - { - tmpmomx *= -1; - tmpmomy *= -1; - tmpmomz *= -1; - } - - thing->momx += tmpmomx; - thing->momy += tmpmomy; - thing->momz += tmpmomz; - - if (thing->player) - { - thing->player->cmomx += tmpmomx; - thing->player->cmomy += tmpmomy; - thing->player->cmomx = FixedMul(thing->player->cmomx, 0xe800); - thing->player->cmomy = FixedMul(thing->player->cmomy, 0xe800); - } - } - else - { - angle_t pushangle; - - pushangle = R_PointToAngle2(thing->x, thing->y, sx, sy); - if (tmpusher->source->type == MT_PUSH) - pushangle += ANGLE_180; // away - pushangle >>= ANGLETOFINESHIFT; - thing->momx += FixedMul(speed, FINECOSINE(pushangle)); - thing->momy += FixedMul(speed, FINESINE(pushangle)); - - if (thing->player) - { - thing->player->cmomx += FixedMul(speed, FINECOSINE(pushangle)); - thing->player->cmomy += FixedMul(speed, FINESINE(pushangle)); - thing->player->cmomx = FixedMul(thing->player->cmomx, 0xe800); - thing->player->cmomy = FixedMul(thing->player->cmomy, 0xe800); - } - } - } - else - { - //NiGHTS-specific handling. - //By default, pushes and pulls only affect the Z-axis. - //By having the ambush flag, it affects the X-axis. - //By having the object special flag, it affects the Y-axis. - fixed_t tmpmomx, tmpmomy, tmpmomz; - - if (tmpusher->source->health & 1) - tmpmomx = FixedMul(FixedDiv(sx - thing->x, dist), speed); - else - tmpmomx = 0; - - if (tmpusher->source->health & 2) - tmpmomy = FixedMul(FixedDiv(sy - thing->y, dist), speed); - else - tmpmomy = 0; - - tmpmomz = FixedMul(FixedDiv(sz - thing->z, dist), speed); - - if (tmpusher->source->type == MT_PUSH) // away! - { - tmpmomx *= -1; - tmpmomy *= -1; - tmpmomz *= -1; - } - - thing->momx += tmpmomx; - thing->momy += tmpmomy; - thing->momz += tmpmomz; - - if (thing->player) - { - thing->player->cmomx += tmpmomx; - thing->player->cmomy += tmpmomy; - thing->player->cmomx = FixedMul(thing->player->cmomx, 0xe800); - thing->player->cmomy = FixedMul(thing->player->cmomy, 0xe800); - } - } - } - } - - if (tmpusher->exclusive) - thing->eflags |= MFE_PUSHED; - - return true; -} - -void T_PointPusher(pointpusher_t *p) -{ - INT32 xl, xh, yl, yh, bx, by; - sector_t *sec = sectors + p->affectee; - - // Be sure the special sector type is still turned on. If so, proceed. - // Else, bail out; the sector type has been changed on us. - - if (GETSECSPECIAL(sec->special, 3) != 2) - return; - - // 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. @@ -8751,78 +8537,33 @@ void T_Pusher(pusher_t *p) } } - -/** Gets a push/pull object. - * - * \param s Sector number to look in. - * \return Pointer to the first ::MT_PUSH or ::MT_PULL object found in the - * sector. - * \sa P_GetTeleportDestThing, P_GetStarpostThing, P_GetAltViewThing - */ -mobj_t *P_GetPushThing(UINT32 s) -{ - mobj_t *thing; - sector_t *sec; - - sec = sectors + s; - thing = sec->thinglist; - while (thing) - { - switch (thing->type) - { - case MT_PUSH: - case MT_PULL: - return thing; - default: - break; - } - thing = thing->snext; - } - return NULL; -} - /** Spawns pushers. * - * \todo Remove magic numbers. * \sa P_SpawnSpecials, Add_Pusher */ static void P_SpawnPushers(void) { size_t i; line_t *l = lines; - mtag_t tag; register INT32 s; - mobj_t *thing; + fixed_t length, hspeed, dx, dy; for (i = 0; i < numlines; i++, l++) { - tag = Tag_FGet(&l->tags); - switch (l->special) - { - case 541: // wind/current - { - fixed_t length = R_PointToDist2(l->v2->x, l->v2->y, l->v1->x, l->v1->y); - fixed_t hspeed = l->args[1] << FRACBITS; - fixed_t dx = FixedMul(FixedDiv(l->dx, length), hspeed); - fixed_t dy = FixedMul(FixedDiv(l->dy, length), hspeed); + if (l->special != 541) + continue; - if (l->args[0] == 0) - Add_Pusher(l->args[3], dx, dy, l->args[2] << FRACBITS, (INT32)(l->frontsector - sectors), -1, !(l->args[4] & TMPF_NONEXCLUSIVE), !!(l->args[4] & TMPF_SLIDE)); - else - { - TAG_ITER_SECTORS(l->args[0], s) - Add_Pusher(l->args[3], dx, dy, l->args[2] << FRACBITS, s, -1, !(l->args[4] & TMPF_NONEXCLUSIVE), !!(l->args[4] & TMPF_SLIDE)); - } - break; - } - case 547: // push/pull - TAG_ITER_SECTORS(tag, s) - { - thing = P_GetPushThing(s); - if (thing) // No MT_P* means no effect - Add_PointPusher(P_AproxDistance(l->dx >> FRACBITS, l->dy >> FRACBITS), thing, s, l->flags & ML_NOCLIMB); - } - break; + length = R_PointToDist2(l->v2->x, l->v2->y, l->v1->x, l->v1->y); + hspeed = l->args[1] << FRACBITS; + dx = FixedMul(FixedDiv(l->dx, length), hspeed); + dy = FixedMul(FixedDiv(l->dy, length), hspeed); + + if (l->args[0] == 0) + Add_Pusher(l->args[3], dx, dy, l->args[2] << FRACBITS, (INT32)(l->frontsector - sectors), -1, !(l->args[4] & TMPF_NONEXCLUSIVE), !!(l->args[4] & TMPF_SLIDE)); + else + { + TAG_ITER_SECTORS(l->args[0], s) + Add_Pusher(l->args[3], dx, dy, l->args[2] << FRACBITS, s, -1, !(l->args[4] & TMPF_NONEXCLUSIVE), !!(l->args[4] & TMPF_SLIDE)); } } } diff --git a/src/p_spec.h b/src/p_spec.h index 94bd079b6..8e210b543 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -343,6 +343,14 @@ typedef enum TMPF_NONEXCLUSIVE = 1<<1, } textmappusherflags_t; + +typedef enum +{ + TMPP_NOZFADE = 1, + TMPP_PUSHZ = 1<<1, + TMPP_NONEXCLUSIVE = 1<<2, +} textmappointpushflags_t; + // GETSECSPECIAL (specialval, section) // // Pulls out the special # from a particular section. @@ -874,17 +882,6 @@ 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 { @@ -941,10 +938,8 @@ typedef struct void T_FadeColormap(fadecolormap_t *d); -// Prototype functions for pushers +// Prototype function for pushers void T_Pusher(pusher_t *p); -void T_PointPusher(pointpusher_t *p); -mobj_t *P_GetPushThing(UINT32 s); // Plane displacement typedef struct diff --git a/src/p_tick.c b/src/p_tick.c index d34272045..55a16fd81 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -66,8 +66,7 @@ void Command_Numthinkers_f(void) "\t2: P_NullPrecipThinker\n" "\t3: T_Friction\n" "\t4: T_Pusher\n" - "\t5: T_PointPusher\n" - "\t6: P_RemoveThinkerDelayed\n"); + "\t5: P_RemoveThinkerDelayed\n"); return; } @@ -104,11 +103,6 @@ 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;