diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4a8101d79..e53749904 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1070,6 +1070,7 @@ add_executable( zdoom WIN32 MACOSX_BUNDLE p_pillar.cpp p_plats.cpp p_pspr.cpp + p_pusher.cpp p_saveg.cpp p_scroll.cpp p_sectors.cpp diff --git a/src/doomstat.cpp b/src/doomstat.cpp index 8f314ad50..d693aae1b 100644 --- a/src/doomstat.cpp +++ b/src/doomstat.cpp @@ -43,7 +43,6 @@ CVAR (Bool, developer, false, 0) // [RH] Feature control cvars CVAR (Bool, var_friction, true, CVAR_SERVERINFO); -CVAR (Bool, var_pushers, true, CVAR_SERVERINFO); CVAR (Bool, alwaysapplydmflags, false, CVAR_SERVERINFO); diff --git a/src/doomstat.h b/src/doomstat.h index 43d81e866..e762b07dc 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -212,7 +212,6 @@ extern bool ToggleFullscreen; extern int Net_Arbitrator; EXTERN_CVAR (Bool, var_friction) -EXTERN_CVAR (Bool, var_pushers) // [RH] Miscellaneous info for DeHackEd support diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index ca17a4f20..849295c2c 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -2146,43 +2146,8 @@ FUNC(LS_Sector_ChangeFlags) } -void AdjustPusher (int tag, int magnitude, int angle, DPusher::EPusher type) -{ - // Find pushers already attached to the sector, and change their parameters. - TArray Collection; - { - TThinkerIterator iterator; - FThinkerCollection collect; - while ( (collect.Obj = iterator.Next ()) ) - { - if ((collect.RefNum = ((DPusher *)collect.Obj)->CheckForSectorMatch (type, tag)) >= 0) - { - ((DPusher *)collect.Obj)->ChangeValues (magnitude, angle); - Collection.Push (collect); - } - } - } - - size_t numcollected = Collection.Size (); - int secnum; - - // Now create pushers for any sectors that don't already have them. - FSectorTagIterator itr(tag); - while ((secnum = itr.Next()) >= 0) - { - unsigned int i; - for (i = 0; i < numcollected; i++) - { - if (Collection[i].RefNum == sectors[secnum].sectornum) - break; - } - if (i == numcollected) - { - new DPusher (type, NULL, magnitude, angle, NULL, secnum); - } - } -} +void AdjustPusher(int tag, int magnitude, int angle, bool wind); FUNC(LS_Sector_SetWind) // Sector_SetWind (tag, amount, angle) @@ -2190,7 +2155,7 @@ FUNC(LS_Sector_SetWind) if (arg3) return false; - AdjustPusher (arg0, arg1, arg2, DPusher::p_wind); + AdjustPusher (arg0, arg1, arg2, true); return true; } @@ -2200,7 +2165,7 @@ FUNC(LS_Sector_SetCurrent) if (arg3) return false; - AdjustPusher (arg0, arg1, arg2, DPusher::p_current); + AdjustPusher (arg0, arg1, arg2, false); return true; } diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 700cf2c1e..834df5956 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -84,40 +84,11 @@ static FRandom pr_playerinspecialsector ("PlayerInSpecialSector"); EXTERN_CVAR(Bool, cl_predict_specials) -IMPLEMENT_POINTY_CLASS (DPusher) - DECLARE_POINTER (m_Source) -END_POINTERS - -DPusher::DPusher () -{ -} - -inline FArchive &operator<< (FArchive &arc, DPusher::EPusher &type) -{ - BYTE val = (BYTE)type; - arc << val; - type = (DPusher::EPusher)val; - return arc; -} - -void DPusher::Serialize (FArchive &arc) -{ - Super::Serialize (arc); - arc << m_Type - << m_Source - << m_Xmag - << m_Ymag - << m_Magnitude - << m_Radius - << m_X - << m_Y - << m_Affectee; -} // killough 3/7/98: Initialize generalized scrolling void P_SpawnScrollers(); static void P_SpawnFriction (); // phares 3/16/98 -static void P_SpawnPushers (); // phares 3/20/98 +void P_SpawnPushers (); // phares 3/20/98 // [RH] Check dmflags for noexit and respond accordingly @@ -1631,345 +1602,6 @@ void P_SetSectorFriction (int tag, int amount, bool alterFlag) // //////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -// -// PUSH/PULL EFFECT -// -// phares 3/20/98: Start of push/pull effects -// -// This is where push/pull effects are applied to objects in the sectors. -// -// There are four kinds of push effects -// -// 1) Pushing Away -// -// Pushes you away from a point source defined by the location of an -// MT_PUSH Thing. The force decreases linearly with distance from the -// source. This force crosses sector boundaries and is felt w/in a circle -// whose center is at the MT_PUSH. The force is felt only if the point -// MT_PUSH can see the target object. -// -// 2) Pulling toward -// -// Same as Pushing Away except you're pulled toward an MT_PULL point -// source. This force crosses sector boundaries and is felt w/in a circle -// whose center is at the MT_PULL. The force is felt only if the point -// MT_PULL can see the target object. -// -// 3) Wind -// -// Pushes you in a constant direction. Full force above ground, half -// force on the ground, nothing if you're below it (water). -// -// 4) Current -// -// Pushes you in a constant direction. No force above ground, full -// force if on the ground or below it (water). -// -// The magnitude of the force is controlled by the length of a controlling -// linedef. The force vector for types 3 & 4 is determined by the angle -// of the linedef, and is constant. -// -// For each sector where these effects occur, the sector special type has -// to have the PUSH_MASK bit set. If this bit is turned off by a switch -// at run-time, the effect will not occur. The controlling sector for -// types 1 & 2 is the sector containing the MT_PUSH/MT_PULL Thing. - - -#define PUSH_FACTOR 7 - -///////////////////////////// -// -// Add a push thinker to the thinker list - -DPusher::DPusher (DPusher::EPusher type, line_t *l, int magnitude, int angle, - AActor *source, int affectee) -{ - m_Source = source; - m_Type = type; - if (l) - { - m_Xmag = l->dx>>FRACBITS; - m_Ymag = l->dy>>FRACBITS; - m_Magnitude = P_AproxDistance (m_Xmag, m_Ymag); - } - else - { // [RH] Allow setting magnitude and angle with parameters - ChangeValues (magnitude, angle); - } - if (source) // point source exist? - { - m_Radius = (m_Magnitude) << (FRACBITS+1); // where force goes to zero - m_X = m_Source->X(); - m_Y = m_Source->Y(); - } - m_Affectee = affectee; -} - -int DPusher::CheckForSectorMatch (EPusher type, int tag) -{ - if (m_Type == type && tagManager.SectorHasTag(m_Affectee, tag)) - return m_Affectee; - else - return -1; -} - - -///////////////////////////// -// -// T_Pusher looks for all objects that are inside the radius of -// the effect. -// -void DPusher::Tick () -{ - sector_t *sec; - AActor *thing; - msecnode_t *node; - int xspeed,yspeed; - int ht; - - if (!var_pushers) - return; - - sec = sectors + m_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 (!(sec->Flags & SECF_PUSH)) - return; - - // For constant pushers (wind/current) there are 3 situations: - // - // 1) Affected Thing is above the floor. - // - // Apply the full force if wind, no force if current. - // - // 2) Affected Thing is on the ground. - // - // Apply half force if wind, full force if current. - // - // 3) Affected Thing is below the ground (underwater effect). - // - // Apply no force if wind, full force if current. - // - // Apply the effect to clipped players only for now. - // - // In Phase II, you can apply these effects to Things other than players. - // [RH] No Phase II, but it works with anything having MF2_WINDTHRUST now. - - if (m_Type == p_push) - { - // Seek out all pushable things within the force radius of this - // point pusher. Crosses sectors, so use blockmap. - - FPortalGroupArray check(FPortalGroupArray::PGA_NoSectorPortals); // no sector portals because this thing is utterly z-unaware. - FMultiBlockThingsIterator it(check, m_X, m_Y, 0, 0, m_Radius, false, m_Source->Sector); - FMultiBlockThingsIterator::CheckResult cres; - - - while (it.Next(&cres)) - { - AActor *thing = cres.thing; - // Normal ZDoom is based only on the WINDTHRUST flag, with the noclip cheat as an exemption. - bool pusharound = ((thing->flags2 & MF2_WINDTHRUST) && !(thing->flags & MF_NOCLIP)); - - // MBF allows any sentient or shootable thing to be affected, but players with a fly cheat aren't. - if (compatflags & COMPATF_MBFMONSTERMOVE) - { - pusharound = ((pusharound || (thing->IsSentient()) || (thing->flags & MF_SHOOTABLE)) // Add categories here - && (!(thing->player && (thing->flags & (MF_NOGRAVITY))))); // Exclude flying players here - } - - if ((pusharound) ) - { - int sx = m_X; - int sy = m_Y; - int dist = thing->AproxDistance (sx, sy); - int speed = (m_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. - - if ((speed > 0) && (P_CheckSight (thing, m_Source, SF_IGNOREVISIBILITY))) - { - angle_t pushangle = thing->AngleTo(sx, sy); - if (m_Source->GetClass()->TypeName == NAME_PointPusher) - pushangle += ANG180; // away - pushangle >>= ANGLETOFINESHIFT; - thing->vel.x += FixedMul (speed, finecosine[pushangle]); - thing->vel.y += FixedMul (speed, finesine[pushangle]); - } - } - } - return; - } - - // constant pushers p_wind and p_current - - node = sec->touching_thinglist; // things touching this sector - for ( ; node ; node = node->m_snext) - { - thing = node->m_thing; - if (!(thing->flags2 & MF2_WINDTHRUST) || (thing->flags & MF_NOCLIP)) - continue; - - sector_t *hsec = sec->GetHeightSec(); - fixedvec3 pos = thing->PosRelative(sec); - if (m_Type == p_wind) - { - if (hsec == NULL) - { // NOT special water sector - if (thing->Z() > thing->floorz) // above ground - { - xspeed = m_Xmag; // full force - yspeed = m_Ymag; - } - else // on ground - { - xspeed = (m_Xmag)>>1; // half force - yspeed = (m_Ymag)>>1; - } - } - else // special water sector - { - ht = hsec->floorplane.ZatPoint(pos); - if (thing->Z() > ht) // above ground - { - xspeed = m_Xmag; // full force - yspeed = m_Ymag; - } - else if (thing->player->viewz < ht) // underwater - { - xspeed = yspeed = 0; // no force - } - else // wading in water - { - xspeed = (m_Xmag)>>1; // half force - yspeed = (m_Ymag)>>1; - } - } - } - else // p_current - { - const secplane_t *floor; - - if (hsec == NULL) - { // NOT special water sector - floor = &sec->floorplane; - } - else - { // special water sector - floor = &hsec->floorplane; - } - if (thing->Z() > floor->ZatPoint(pos)) - { // above ground - xspeed = yspeed = 0; // no force - } - else - { // on ground/underwater - xspeed = m_Xmag; // full force - yspeed = m_Ymag; - } - } - thing->vel.x += xspeed<<(FRACBITS-PUSH_FACTOR); - thing->vel.y += yspeed<<(FRACBITS-PUSH_FACTOR); - } -} - -///////////////////////////// -// -// P_GetPushThing() returns a pointer to an MT_PUSH or MT_PULL thing, -// NULL otherwise. - -AActor *P_GetPushThing (int s) -{ - AActor* thing; - sector_t* sec; - - sec = sectors + s; - thing = sec->thinglist; - - while (thing && - thing->GetClass()->TypeName != NAME_PointPusher && - thing->GetClass()->TypeName != NAME_PointPuller) - { - thing = thing->snext; - } - return thing; -} - -///////////////////////////// -// -// Initialize the sectors where pushers are present -// - -static void P_SpawnPushers () -{ - int i; - line_t *l = lines; - int s; - - for (i = 0; i < numlines; i++, l++) - { - switch (l->special) - { - case Sector_SetWind: // wind - { - FSectorTagIterator itr(l->args[0]); - while ((s = itr.Next()) >= 0) - new DPusher(DPusher::p_wind, l->args[3] ? l : NULL, l->args[1], l->args[2], NULL, s); - l->special = 0; - break; - } - - case Sector_SetCurrent: // current - { - FSectorTagIterator itr(l->args[0]); - while ((s = itr.Next()) >= 0) - new DPusher(DPusher::p_current, l->args[3] ? l : NULL, l->args[1], l->args[2], NULL, s); - l->special = 0; - break; - } - - case PointPush_SetForce: // push/pull - if (l->args[0]) { // [RH] Find thing by sector - FSectorTagIterator itr(l->args[0]); - while ((s = itr.Next()) >= 0) - { - AActor *thing = P_GetPushThing (s); - if (thing) { // No MT_P* means no effect - // [RH] Allow narrowing it down by tid - if (!l->args[1] || l->args[1] == thing->tid) - new DPusher (DPusher::p_push, l->args[3] ? l : NULL, l->args[2], - 0, thing, s); - } - } - } else { // [RH] Find thing by tid - AActor *thing; - FActorIterator iterator (l->args[1]); - - while ( (thing = iterator.Next ()) ) - { - if (thing->GetClass()->TypeName == NAME_PointPusher || - thing->GetClass()->TypeName == NAME_PointPuller) - { - new DPusher (DPusher::p_push, l->args[3] ? l : NULL, l->args[2], - 0, thing, int(thing->Sector - sectors)); - } - } - } - l->special = 0; - break; - } - } -} - -// -// phares 3/20/98: End of Pusher effects -// -//////////////////////////////////////////////////////////////////////////// - void sector_t::AdjustFloorClip () const { msecnode_t *node; diff --git a/src/p_spec.h b/src/p_spec.h index 129e7f03b..73f913a00 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -71,51 +71,6 @@ typedef enum // (This is so scrolling floors and objects on them can move at same speed.) enum { CARRYFACTOR = (3*FRACUNIT >> 5) }; -// phares 3/20/98: added new model of Pushers for push/pull effects - -class DPusher : public DThinker -{ - DECLARE_CLASS (DPusher, DThinker) - HAS_OBJECT_POINTERS -public: - enum EPusher - { - p_push, - p_pull, - p_wind, - p_current - }; - - DPusher (); - DPusher (EPusher type, line_t *l, int magnitude, int angle, AActor *source, int affectee); - void Serialize (FArchive &arc); - int CheckForSectorMatch (EPusher type, int tag); - void ChangeValues (int magnitude, int angle) - { - angle_t ang = ((angle_t)(angle<<24)) >> ANGLETOFINESHIFT; - m_Xmag = (magnitude * finecosine[ang]) >> FRACBITS; - m_Ymag = (magnitude * finesine[ang]) >> FRACBITS; - m_Magnitude = magnitude; - } - - void Tick (); - -protected: - EPusher m_Type; - TObjPtr m_Source;// Point source if point pusher - int m_Xmag; // X Strength - int m_Ymag; // Y Strength - int m_Magnitude; // Vector strength for point pusher - int m_Radius; // Effective radius for point pusher - int m_X; // X of point source if point pusher - int m_Y; // Y of point source if point pusher - int m_Affectee; // Number of affected sector - - friend bool PIT_PushThing (AActor *thing); -}; - -bool PIT_PushThing (AActor *thing); - // Define values for map objects #define MO_TELEPORTMAN 14