- Update scripting branch to trunk.
SVN r3758 (scripting)
This commit is contained in:
commit
562cf04db2
614 changed files with 63691 additions and 31256 deletions
335
src/p_spec.cpp
335
src/p_spec.cpp
|
|
@ -44,7 +44,6 @@
|
|||
#include "m_bbox.h"
|
||||
#include "w_wad.h"
|
||||
|
||||
#include "r_local.h"
|
||||
#include "p_local.h"
|
||||
#include "p_lnspec.h"
|
||||
#include "p_terrain.h"
|
||||
|
|
@ -60,13 +59,15 @@
|
|||
#include "g_level.h"
|
||||
#include "v_font.h"
|
||||
#include "a_sharedglobal.h"
|
||||
#include "farchive.h"
|
||||
#include "a_keys.h"
|
||||
|
||||
// State.
|
||||
#include "r_state.h"
|
||||
|
||||
#include "c_console.h"
|
||||
|
||||
#include "r_interpolate.h"
|
||||
#include "r_data/r_interpolate.h"
|
||||
|
||||
static FRandom pr_playerinspecialsector ("PlayerInSpecialSector");
|
||||
void P_SetupPortals();
|
||||
|
|
@ -85,6 +86,14 @@ IMPLEMENT_POINTY_CLASS (DPusher)
|
|||
DECLARE_POINTER (m_Source)
|
||||
END_POINTERS
|
||||
|
||||
inline FArchive &operator<< (FArchive &arc, DScroller::EScrollType &type)
|
||||
{
|
||||
BYTE val = (BYTE)type;
|
||||
arc << val;
|
||||
type = (DScroller::EScrollType)val;
|
||||
return arc;
|
||||
}
|
||||
|
||||
DScroller::DScroller ()
|
||||
{
|
||||
}
|
||||
|
|
@ -109,6 +118,14 @@ 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);
|
||||
|
|
@ -219,11 +236,13 @@ bool P_ActivateLine (line_t *line, AActor *mo, int side, int activationType)
|
|||
{
|
||||
return false;
|
||||
}
|
||||
bool remote = (line->special != 7 && line->special != 8 && (line->special < 11 || line->special > 14));
|
||||
if (line->locknumber > 0 && !P_CheckKeys (mo, line->locknumber, remote)) return false;
|
||||
lineActivation = line->activation;
|
||||
repeat = line->flags & ML_REPEAT_SPECIAL;
|
||||
buttonSuccess = false;
|
||||
buttonSuccess = LineSpecials[line->special]
|
||||
(line, mo, side == 1, line->args[0],
|
||||
buttonSuccess = P_ExecuteSpecial(line->special,
|
||||
line, mo, side == 1, line->args[0],
|
||||
line->args[1], line->args[2],
|
||||
line->args[3], line->args[4]);
|
||||
|
||||
|
|
@ -256,7 +275,7 @@ bool P_ActivateLine (line_t *line, AActor *mo, int side, int activationType)
|
|||
// end of changed code
|
||||
if (developer && buttonSuccess)
|
||||
{
|
||||
Printf ("Line special %d activated\n", special);
|
||||
Printf ("Line special %d activated on line %i\n", special, int(line - lines));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -269,7 +288,7 @@ bool P_ActivateLine (line_t *line, AActor *mo, int side, int activationType)
|
|||
|
||||
bool P_TestActivateLine (line_t *line, AActor *mo, int side, int activationType)
|
||||
{
|
||||
int lineActivation = line->activation;
|
||||
int lineActivation = line->activation;
|
||||
|
||||
if (line->flags & ML_FIRSTSIDEONLY && side == 1)
|
||||
{
|
||||
|
|
@ -294,7 +313,7 @@ bool P_TestActivateLine (line_t *line, AActor *mo, int side, int activationType)
|
|||
{
|
||||
lineActivation |= SPAC_Cross|SPAC_MCross;
|
||||
}
|
||||
if (activationType ==SPAC_Use || activationType == SPAC_UseBack)
|
||||
if (activationType == SPAC_Use || activationType == SPAC_UseBack)
|
||||
{
|
||||
if (!P_CheckSwitchRange(mo, line, side))
|
||||
{
|
||||
|
|
@ -561,17 +580,106 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector)
|
|||
|
||||
if (sector->special & SECRET_MASK)
|
||||
{
|
||||
player->secretcount++;
|
||||
level.found_secrets++;
|
||||
sector->special &= ~SECRET_MASK;
|
||||
if (player->mo->CheckLocalView (consoleplayer))
|
||||
P_GiveSecret(player->mo, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// P_SectorDamage
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
static void DoSectorDamage(AActor *actor, sector_t *sec, int amount, FName type, PClassActor *protectClass, int flags)
|
||||
{
|
||||
if (!(actor->flags & MF_SHOOTABLE))
|
||||
return;
|
||||
|
||||
if (!(flags & DAMAGE_NONPLAYERS) && actor->player == NULL)
|
||||
return;
|
||||
|
||||
if (!(flags & DAMAGE_PLAYERS) && actor->player != NULL)
|
||||
return;
|
||||
|
||||
if (!(flags & DAMAGE_IN_AIR) && actor->z != sec->floorplane.ZatPoint(actor->x, actor->y) && !actor->waterlevel)
|
||||
return;
|
||||
|
||||
if (protectClass != NULL)
|
||||
{
|
||||
if (actor->FindInventory(protectClass, !!(flags & DAMAGE_SUBCLASSES_PROTECT)))
|
||||
return;
|
||||
}
|
||||
|
||||
P_DamageMobj (actor, NULL, NULL, amount, type);
|
||||
}
|
||||
|
||||
void P_SectorDamage(int tag, int amount, FName type, PClassActor *protectClass, int flags)
|
||||
{
|
||||
int secnum = -1;
|
||||
|
||||
while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0)
|
||||
{
|
||||
AActor *actor, *next;
|
||||
sector_t *sec = §ors[secnum];
|
||||
|
||||
// Do for actors in this sector.
|
||||
for (actor = sec->thinglist; actor != NULL; actor = next)
|
||||
{
|
||||
C_MidPrint (SmallFont, secretmessage);
|
||||
S_Sound (CHAN_AUTO, "misc/secret", 1, ATTN_NORM);
|
||||
next = actor->snext;
|
||||
DoSectorDamage(actor, sec, amount, type, protectClass, flags);
|
||||
}
|
||||
// If this is a 3D floor control sector, also do for anything in/on
|
||||
// those 3D floors.
|
||||
for (unsigned i = 0; i < sec->e->XFloor.attached.Size(); ++i)
|
||||
{
|
||||
sector_t *sec2 = sec->e->XFloor.attached[i];
|
||||
|
||||
for (actor = sec2->thinglist; actor != NULL; actor = next)
|
||||
{
|
||||
next = actor->snext;
|
||||
// Only affect actors touching the 3D floor
|
||||
if (actor->z + actor->height > sec->floorplane.ZatPoint(actor->x, actor->y))
|
||||
{
|
||||
// If DAMAGE_IN_AIR is used, anything not beneath the 3D floor will be
|
||||
// damaged (so, anything touching it or above it). Other 3D floors between
|
||||
// the actor and this one will not stop this effect.
|
||||
if ((flags & DAMAGE_IN_AIR) || actor->z <= sec->ceilingplane.ZatPoint(actor->x, actor->y))
|
||||
{
|
||||
// Here we pass the DAMAGE_IN_AIR flag to disable the floor check, since it
|
||||
// only works with the real sector's floor. We did the appropriate height checks
|
||||
// for 3D floors already.
|
||||
DoSectorDamage(actor, NULL, amount, type, protectClass, flags | DAMAGE_IN_AIR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// P_GiveSecret
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
void P_GiveSecret(AActor *actor, bool printmessage, bool playsound)
|
||||
{
|
||||
if (actor != NULL)
|
||||
{
|
||||
if (actor->player != NULL)
|
||||
{
|
||||
actor->player->secretcount++;
|
||||
}
|
||||
if (actor->CheckLocalView (consoleplayer))
|
||||
{
|
||||
if (printmessage) C_MidPrint (SmallFont, secretmessage);
|
||||
if (playsound) S_Sound (CHAN_AUTO | CHAN_UI, "misc/secret", 1, ATTN_NORM);
|
||||
}
|
||||
}
|
||||
level.found_secrets++;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// P_PlayerOnSpecialFlat
|
||||
|
|
@ -677,12 +785,12 @@ public:
|
|||
void Tick ();
|
||||
|
||||
protected:
|
||||
static void DoTransfer (BYTE level, int target, bool floor);
|
||||
static void DoTransfer (int level, int target, bool floor);
|
||||
|
||||
BYTE LastLight;
|
||||
sector_t *Source;
|
||||
int TargetTag;
|
||||
bool CopyFloor;
|
||||
short LastLight;
|
||||
};
|
||||
|
||||
IMPLEMENT_CLASS (DLightTransfer)
|
||||
|
|
@ -690,7 +798,17 @@ IMPLEMENT_CLASS (DLightTransfer)
|
|||
void DLightTransfer::Serialize (FArchive &arc)
|
||||
{
|
||||
Super::Serialize (arc);
|
||||
arc << LastLight << Source << TargetTag << CopyFloor;
|
||||
if (SaveVersion < 3223)
|
||||
{
|
||||
BYTE bytelight;
|
||||
arc << bytelight;
|
||||
LastLight = bytelight;
|
||||
}
|
||||
else
|
||||
{
|
||||
arc << LastLight;
|
||||
}
|
||||
arc << Source << TargetTag << CopyFloor;
|
||||
}
|
||||
|
||||
DLightTransfer::DLightTransfer (sector_t *srcSec, int target, bool copyFloor)
|
||||
|
|
@ -717,7 +835,7 @@ DLightTransfer::DLightTransfer (sector_t *srcSec, int target, bool copyFloor)
|
|||
|
||||
void DLightTransfer::Tick ()
|
||||
{
|
||||
BYTE light = Source->lightlevel;
|
||||
int light = Source->lightlevel;
|
||||
|
||||
if (light != LastLight)
|
||||
{
|
||||
|
|
@ -726,7 +844,7 @@ void DLightTransfer::Tick ()
|
|||
}
|
||||
}
|
||||
|
||||
void DLightTransfer::DoTransfer (BYTE level, int target, bool floor)
|
||||
void DLightTransfer::DoTransfer (int level, int target, bool floor)
|
||||
{
|
||||
int secnum;
|
||||
|
||||
|
|
@ -760,12 +878,12 @@ public:
|
|||
void Tick ();
|
||||
|
||||
protected:
|
||||
static void DoTransfer (BYTE level, int target, BYTE flags);
|
||||
static void DoTransfer (short level, int target, BYTE flags);
|
||||
|
||||
BYTE LastLight;
|
||||
BYTE Flags;
|
||||
sector_t *Source;
|
||||
int TargetID;
|
||||
short LastLight;
|
||||
BYTE Flags;
|
||||
};
|
||||
|
||||
IMPLEMENT_CLASS (DWallLightTransfer)
|
||||
|
|
@ -773,7 +891,17 @@ IMPLEMENT_CLASS (DWallLightTransfer)
|
|||
void DWallLightTransfer::Serialize (FArchive &arc)
|
||||
{
|
||||
Super::Serialize (arc);
|
||||
arc << LastLight << Source << TargetID << Flags;
|
||||
if (SaveVersion < 3223)
|
||||
{
|
||||
BYTE bytelight;
|
||||
arc << bytelight;
|
||||
LastLight = bytelight;
|
||||
}
|
||||
else
|
||||
{
|
||||
arc << LastLight;
|
||||
}
|
||||
arc << Source << TargetID << Flags;
|
||||
}
|
||||
|
||||
DWallLightTransfer::DWallLightTransfer (sector_t *srcSec, int target, BYTE flags)
|
||||
|
|
@ -784,10 +912,16 @@ DWallLightTransfer::DWallLightTransfer (sector_t *srcSec, int target, BYTE flags
|
|||
Source = srcSec;
|
||||
TargetID = target;
|
||||
Flags = flags;
|
||||
DoTransfer (LastLight = srcSec->lightlevel, target, Flags);
|
||||
DoTransfer (LastLight = srcSec->GetLightLevel(), target, Flags);
|
||||
|
||||
if (!(flags&WLF_NOFAKECONTRAST)) wallflags = WALLF_ABSLIGHTING;
|
||||
else wallflags = WALLF_NOFAKECONTRAST|WALLF_ABSLIGHTING;
|
||||
if (!(flags & WLF_NOFAKECONTRAST))
|
||||
{
|
||||
wallflags = WALLF_ABSLIGHTING;
|
||||
}
|
||||
else
|
||||
{
|
||||
wallflags = WALLF_ABSLIGHTING | WALLF_NOFAKECONTRAST;
|
||||
}
|
||||
|
||||
for (linenum = -1; (linenum = P_FindLineFromID (target, linenum)) >= 0; )
|
||||
{
|
||||
|
|
@ -806,7 +940,7 @@ DWallLightTransfer::DWallLightTransfer (sector_t *srcSec, int target, BYTE flags
|
|||
|
||||
void DWallLightTransfer::Tick ()
|
||||
{
|
||||
BYTE light = Source->lightlevel;
|
||||
short light = sector_t::ClampLight(Source->lightlevel);
|
||||
|
||||
if (light != LastLight)
|
||||
{
|
||||
|
|
@ -815,13 +949,13 @@ void DWallLightTransfer::Tick ()
|
|||
}
|
||||
}
|
||||
|
||||
void DWallLightTransfer::DoTransfer (BYTE lightlevel, int target, BYTE flags)
|
||||
void DWallLightTransfer::DoTransfer (short lightlevel, int target, BYTE flags)
|
||||
{
|
||||
int linenum;
|
||||
|
||||
for (linenum = -1; (linenum = P_FindLineFromID (target, linenum)) >= 0; )
|
||||
{
|
||||
line_t * line = &lines[linenum];
|
||||
line_t *line = &lines[linenum];
|
||||
|
||||
if (flags & WLF_SIDE1 && line->sidedef[0] != NULL)
|
||||
{
|
||||
|
|
@ -849,10 +983,11 @@ static void SetupFloorPortal (AStackPoint *point)
|
|||
NActorIterator it (NAME_LowerStackLookOnly, point->tid);
|
||||
sector_t *Sector = point->Sector;
|
||||
Sector->FloorSkyBox = static_cast<ASkyViewpoint*>(it.Next());
|
||||
if (Sector->FloorSkyBox != NULL)
|
||||
if (Sector->FloorSkyBox != NULL && Sector->FloorSkyBox->bAlways)
|
||||
{
|
||||
Sector->FloorSkyBox->Mate = point;
|
||||
Sector->FloorSkyBox->PlaneAlpha = Scale (point->args[0], OPAQUE, 255);
|
||||
if (Sector->GetAlpha(sector_t::floor) == OPAQUE)
|
||||
Sector->SetAlpha(sector_t::floor, Scale (point->args[0], OPAQUE, 255));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -861,13 +996,47 @@ static void SetupCeilingPortal (AStackPoint *point)
|
|||
NActorIterator it (NAME_UpperStackLookOnly, point->tid);
|
||||
sector_t *Sector = point->Sector;
|
||||
Sector->CeilingSkyBox = static_cast<ASkyViewpoint*>(it.Next());
|
||||
if (Sector->CeilingSkyBox != NULL)
|
||||
if (Sector->CeilingSkyBox != NULL && Sector->CeilingSkyBox->bAlways)
|
||||
{
|
||||
Sector->CeilingSkyBox->Mate = point;
|
||||
Sector->CeilingSkyBox->PlaneAlpha = Scale (point->args[0], OPAQUE, 255);
|
||||
if (Sector->GetAlpha(sector_t::ceiling) == OPAQUE)
|
||||
Sector->SetAlpha(sector_t::ceiling, Scale (point->args[0], OPAQUE, 255));
|
||||
}
|
||||
}
|
||||
|
||||
static bool SpreadCeilingPortal(AStackPoint *pt, fixed_t alpha, sector_t *sector)
|
||||
{
|
||||
bool fail = false;
|
||||
sector->validcount = validcount;
|
||||
for(int i=0; i<sector->linecount; i++)
|
||||
{
|
||||
line_t *line = sector->lines[i];
|
||||
sector_t *backsector = sector == line->frontsector? line->backsector : line->frontsector;
|
||||
if (line->backsector == line->frontsector) continue;
|
||||
if (backsector == NULL) { fail = true; continue; }
|
||||
if (backsector->validcount == validcount) continue;
|
||||
if (backsector->CeilingSkyBox == pt) continue;
|
||||
|
||||
// Check if the backside would map to the same visplane
|
||||
if (backsector->CeilingSkyBox != NULL) { fail = true; continue; }
|
||||
if (backsector->ceilingplane != sector->ceilingplane) { fail = true; continue; }
|
||||
if (backsector->lightlevel != sector->lightlevel) { fail = true; continue; }
|
||||
if (backsector->GetTexture(sector_t::ceiling) != sector->GetTexture(sector_t::ceiling)) { fail = true; continue; }
|
||||
if (backsector->GetXOffset(sector_t::ceiling) != sector->GetXOffset(sector_t::ceiling)) { fail = true; continue; }
|
||||
if (backsector->GetYOffset(sector_t::ceiling) != sector->GetYOffset(sector_t::ceiling)) { fail = true; continue; }
|
||||
if (backsector->GetXScale(sector_t::ceiling) != sector->GetXScale(sector_t::ceiling)) { fail = true; continue; }
|
||||
if (backsector->GetYScale(sector_t::ceiling) != sector->GetYScale(sector_t::ceiling)) { fail = true; continue; }
|
||||
if (backsector->GetAngle(sector_t::ceiling) != sector->GetAngle(sector_t::ceiling)) { fail = true; continue; }
|
||||
if (SpreadCeilingPortal(pt, alpha, backsector)) { fail = true; continue; }
|
||||
}
|
||||
if (!fail)
|
||||
{
|
||||
sector->CeilingSkyBox = pt;
|
||||
sector->SetAlpha(sector_t::ceiling, alpha);
|
||||
}
|
||||
return fail;
|
||||
}
|
||||
|
||||
void P_SetupPortals()
|
||||
{
|
||||
TThinkerIterator<AStackPoint> it;
|
||||
|
|
@ -888,45 +1057,28 @@ void P_SetupPortals()
|
|||
pt->special1 = 0;
|
||||
points.Push(pt);
|
||||
}
|
||||
|
||||
for(unsigned i=0;i<points.Size(); i++)
|
||||
{
|
||||
if (points[i]->special1 == 0 && points[i]->Mate != NULL)
|
||||
{
|
||||
for(unsigned j=1;j<points.Size(); j++)
|
||||
{
|
||||
if (points[j]->special1 == 0 && points[j]->Mate != NULL && points[i]->GetClass() == points[j]->GetClass())
|
||||
{
|
||||
fixed_t deltax1 = points[i]->Mate->x - points[i]->x;
|
||||
fixed_t deltay1 = points[i]->Mate->y - points[i]->y;
|
||||
fixed_t deltax2 = points[j]->Mate->x - points[j]->x;
|
||||
fixed_t deltay2 = points[j]->Mate->y - points[j]->y;
|
||||
if (deltax1 == deltax2 && deltay1 == deltay2)
|
||||
{
|
||||
if (points[j]->Sector->FloorSkyBox == points[j]->Mate)
|
||||
points[j]->Sector->FloorSkyBox = points[i]->Mate;
|
||||
|
||||
if (points[j]->Sector->CeilingSkyBox == points[j]->Mate)
|
||||
points[j]->Sector->CeilingSkyBox = points[i]->Mate;
|
||||
|
||||
points[j]->special1 = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void SetPortal(sector_t *sector, int plane, AStackPoint *portal)
|
||||
inline void SetPortal(sector_t *sector, int plane, AStackPoint *portal, fixed_t alpha)
|
||||
{
|
||||
// plane: 0=floor, 1=ceiling, 2=both
|
||||
if (plane > 0)
|
||||
{
|
||||
if (sector->CeilingSkyBox == NULL) sector->CeilingSkyBox = portal;
|
||||
if (sector->CeilingSkyBox == NULL || !sector->CeilingSkyBox->bAlways)
|
||||
{
|
||||
sector->CeilingSkyBox = portal;
|
||||
if (sector->GetAlpha(sector_t::ceiling) == OPAQUE)
|
||||
sector->SetAlpha(sector_t::ceiling, alpha);
|
||||
}
|
||||
}
|
||||
if (plane == 2 || plane == 0)
|
||||
{
|
||||
if (sector->FloorSkyBox == NULL) sector->FloorSkyBox = portal;
|
||||
if (sector->FloorSkyBox == NULL || !sector->FloorSkyBox->bAlways)
|
||||
{
|
||||
sector->FloorSkyBox = portal;
|
||||
}
|
||||
if (sector->GetAlpha(sector_t::floor) == OPAQUE)
|
||||
sector->SetAlpha(sector_t::floor, alpha);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -946,6 +1098,7 @@ void P_SpawnPortal(line_t *line, int sectortag, int plane, int alpha)
|
|||
fixed_t y1 = (line->v1->y + line->v2->y) >> 1;
|
||||
fixed_t x2 = (lines[i].v1->x + lines[i].v2->x) >> 1;
|
||||
fixed_t y2 = (lines[i].v1->y + lines[i].v2->y) >> 1;
|
||||
fixed_t alpha = Scale (lines[i].args[4], OPAQUE, 255);
|
||||
|
||||
AStackPoint *anchor = Spawn<AStackPoint>(x1, y1, 0, NO_REPLACE);
|
||||
AStackPoint *reference = Spawn<AStackPoint>(x2, y2, 0, NO_REPLACE);
|
||||
|
|
@ -960,27 +1113,27 @@ void P_SpawnPortal(line_t *line, int sectortag, int plane, int alpha)
|
|||
|
||||
for (int s=-1; (s = P_FindSectorFromTag(sectortag,s)) >= 0;)
|
||||
{
|
||||
SetPortal(§ors[s], plane, reference);
|
||||
SetPortal(§ors[s], plane, reference, alpha);
|
||||
}
|
||||
|
||||
for (int j=0;j<numlines;j++)
|
||||
{
|
||||
// Check if this portal needs to be copied to other sectors
|
||||
// This must be done here to ensure that it gets done only after the portal is set up
|
||||
if (lines[i].special == Sector_SetPortal &&
|
||||
lines[i].args[1] == 1 &&
|
||||
lines[i].args[2] == plane &&
|
||||
lines[i].args[3] == sectortag)
|
||||
if (lines[j].special == Sector_SetPortal &&
|
||||
lines[j].args[1] == 1 &&
|
||||
lines[j].args[2] == plane &&
|
||||
lines[j].args[3] == sectortag)
|
||||
{
|
||||
if (lines[i].args[0] == 0)
|
||||
if (lines[j].args[0] == 0)
|
||||
{
|
||||
SetPortal(lines[i].frontsector, plane, reference);
|
||||
SetPortal(lines[j].frontsector, plane, reference, alpha);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int s=-1; (s = P_FindSectorFromTag(lines[i].args[0],s)) >= 0;)
|
||||
for (int s=-1; (s = P_FindSectorFromTag(lines[j].args[0],s)) >= 0;)
|
||||
{
|
||||
SetPortal(§ors[s], plane, reference);
|
||||
SetPortal(§ors[s], plane, reference, alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1100,6 +1253,7 @@ void P_SpawnSpecials (void)
|
|||
break;
|
||||
|
||||
case dScroll_EastLavaDamage:
|
||||
new DStrobe (sector, STROBEBRIGHT, FASTDARK, false);
|
||||
new DScroller (DScroller::sc_floor, (-FRACUNIT/2)<<3,
|
||||
0, -1, int(sector-sectors), 0);
|
||||
break;
|
||||
|
|
@ -1307,9 +1461,29 @@ void P_SpawnSpecials (void)
|
|||
// This is the main scrolling code
|
||||
// killough 3/7/98
|
||||
|
||||
// [RH] Compensate for rotated sector textures by rotating the scrolling
|
||||
// in the opposite direction.
|
||||
static void RotationComp(const sector_t *sec, int which, fixed_t dx, fixed_t dy, fixed_t &tdx, fixed_t &tdy)
|
||||
{
|
||||
angle_t an = sec->GetAngle(which);
|
||||
if (an == 0)
|
||||
{
|
||||
tdx = dx;
|
||||
tdy = dy;
|
||||
}
|
||||
else
|
||||
{
|
||||
an = an >> ANGLETOFINESHIFT;
|
||||
fixed_t ca = -finecosine[an];
|
||||
fixed_t sa = -finesine[an];
|
||||
tdx = DMulScale16(dx, ca, -dy, sa);
|
||||
tdy = DMulScale16(dy, ca, dx, sa);
|
||||
}
|
||||
}
|
||||
|
||||
void DScroller::Tick ()
|
||||
{
|
||||
fixed_t dx = m_dx, dy = m_dy;
|
||||
fixed_t dx = m_dx, dy = m_dy, tdx, tdy;
|
||||
|
||||
if (m_Control != -1)
|
||||
{ // compute scroll amounts based on a sector's height changes
|
||||
|
|
@ -1353,13 +1527,15 @@ void DScroller::Tick ()
|
|||
break;
|
||||
|
||||
case sc_floor: // killough 3/7/98: Scroll floor texture
|
||||
sectors[m_Affectee].AddXOffset(sector_t::floor, dx);
|
||||
sectors[m_Affectee].AddYOffset(sector_t::floor, dy);
|
||||
RotationComp(§ors[m_Affectee], sector_t::floor, dx, dy, tdx, tdy);
|
||||
sectors[m_Affectee].AddXOffset(sector_t::floor, tdx);
|
||||
sectors[m_Affectee].AddYOffset(sector_t::floor, tdy);
|
||||
break;
|
||||
|
||||
case sc_ceiling: // killough 3/7/98: Scroll ceiling texture
|
||||
sectors[m_Affectee].AddXOffset(sector_t::ceiling, dx);
|
||||
sectors[m_Affectee].AddYOffset(sector_t::ceiling, dy);
|
||||
RotationComp(§ors[m_Affectee], sector_t::ceiling, dx, dy, tdx, tdy);
|
||||
sectors[m_Affectee].AddXOffset(sector_t::ceiling, tdx);
|
||||
sectors[m_Affectee].AddYOffset(sector_t::ceiling, tdy);
|
||||
break;
|
||||
|
||||
// [RH] Don't actually carry anything here. That happens later.
|
||||
|
|
@ -1923,6 +2099,15 @@ DPusher::DPusher (DPusher::EPusher type, line_t *l, int magnitude, int angle,
|
|||
m_Affectee = affectee;
|
||||
}
|
||||
|
||||
int DPusher::CheckForSectorMatch (EPusher type, int tag)
|
||||
{
|
||||
if (m_Type == type && sectors[m_Affectee].tag == tag)
|
||||
return m_Affectee;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
//
|
||||
// T_Pusher looks for all objects that are inside the radius of
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue