- Update scripting branch to trunk.

SVN r3758 (scripting)
This commit is contained in:
Randy Heit 2012-07-14 03:04:41 +00:00
commit 562cf04db2
614 changed files with 63691 additions and 31256 deletions

View file

@ -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 = &sectors[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(&sectors[s], plane, reference);
SetPortal(&sectors[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(&sectors[s], plane, reference);
SetPortal(&sectors[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(&sectors[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(&sectors[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