This commit is contained in:
alexey.lysiuk 2014-10-12 15:19:11 +03:00
commit 25b808cd82
36 changed files with 6457 additions and 5463 deletions

View file

@ -92,30 +92,33 @@ Note: All <bool> fields default to false unless mentioned otherwise.
linedef linedef
{ {
alpha = <float>; // Translucency of this line, default is 1.0 alpha = <float>; // Translucency of this line, default is 1.0
renderstyle = <string>; // Render style, can be "translucent" or "add", renderstyle = <string>; // Render style, can be "translucent" or "add",
// default is "translucent". // default is "translucent".
playeruseback = <bool>; // New SPAC flag, true = player can use from back side. playeruseback = <bool> ; // New SPAC flag, true = player can use from back side.
anycross = <bool>; // New SPAC flag, true = any non-projectile anycross = <bool>; // New SPAC flag, true = any non-projectile
// crossing will trigger this line // crossing will trigger this line
monsteractivate = <bool>; // Monsters can trigger this line. monsteractivate = <bool>; // Monsters can trigger this line.
// For compatibility only because this flag's // For compatibility only because this flag's
// semantics can not be fully reproduced with // semantics can not be fully reproduced with
// explicit trigger flags. // explicit trigger flags.
blockplayers = <bool>; // Line blocks players' movement. blockplayers = <bool>; // Line blocks players' movement.
blockeverything = <bool>; // Line blocks everything. blockeverything = <bool>; // Line blocks everything.
firstsideonly = <bool>; // Line can only be triggered from the front side. firstsideonly = <bool>; // Line can only be triggered from the front side.
zoneboundary = <bool>; // Line is a boundary for sound reverb zones. zoneboundary = <bool>; // Line is a boundary for sound reverb zones.
clipmidtex = <bool>; // Line's mid textures are clipped to floor and ceiling. clipmidtex = <bool>; // Line's mid textures are clipped to floor and ceiling.
wrapmidtex = <bool>; // Line's mid textures are wrapped. wrapmidtex = <bool>; // Line's mid textures are wrapped.
midtex3d = <bool>; // Actors can walk on mid texture. midtex3d = <bool>; // Actors can walk on mid texture.
checkswitchrange = <bool>;// Switches can only be activated when vertically reachable. midtex3dimpassible = <bool>;// Used in conjuction with midtex3d - causes the mid
blockprojectiles = <bool>;// Line blocks all projectiles // texture to behave like an impassible line (projectiles
blockuse = <bool>; // Line blocks all use actions // pass through it).
blocksight = <bool>; // Line blocks monster line of sight checkswitchrange = <bool>; // Switches can only be activated when vertically reachable.
blockhitscan = <bool>; // Line blocks hitscan attacks blockprojectiles = <bool>; // Line blocks all projectiles
locknumber = <int>; // Line special is locked blockuse = <bool>; // Line blocks all use actions
arg0str = <string>; // Alternate string-based version of arg0 blocksight = <bool>; // Line blocks monster line of sight
blockhitscan = <bool>; // Line blocks hitscan attacks
locknumber = <int>; // Line special is locked
arg0str = <string>; // Alternate string-based version of arg0
transparent = <bool>; // true = line is a Strife transparent line (alpha 0.25) transparent = <bool>; // true = line is a Strife transparent line (alpha 0.25)

View file

@ -56,6 +56,13 @@ AActor *COPY_AAPTR(AActor *origin, int selector)
case AAPTR_TRACER: return origin->tracer; case AAPTR_TRACER: return origin->tracer;
case AAPTR_FRIENDPLAYER: case AAPTR_FRIENDPLAYER:
return origin->FriendPlayer ? AAPTR_RESOLVE_PLAYERNUM(origin->FriendPlayer - 1) : NULL; return origin->FriendPlayer ? AAPTR_RESOLVE_PLAYERNUM(origin->FriendPlayer - 1) : NULL;
case AAPTR_GET_LINETARGET:
{
AActor *gettarget = NULL;
P_BulletSlope(origin, &gettarget);
return gettarget;
}
} }
} }

View file

@ -36,12 +36,13 @@ enum AAPTR
AAPTR_PLAYER8 = 0x2000, AAPTR_PLAYER8 = 0x2000,
AAPTR_FRIENDPLAYER = 0x4000, AAPTR_FRIENDPLAYER = 0x4000,
AAPTR_GET_LINETARGET = 0x8000,
AAPTR_PLAYER_SELECTORS = AAPTR_PLAYER_SELECTORS =
AAPTR_PLAYER_GETTARGET|AAPTR_PLAYER_GETCONVERSATION, AAPTR_PLAYER_GETTARGET|AAPTR_PLAYER_GETCONVERSATION,
AAPTR_GENERAL_SELECTORS = AAPTR_GENERAL_SELECTORS =
AAPTR_TARGET|AAPTR_MASTER|AAPTR_TRACER|AAPTR_FRIENDPLAYER, AAPTR_TARGET|AAPTR_MASTER|AAPTR_TRACER|AAPTR_FRIENDPLAYER|AAPTR_GET_LINETARGET,
AAPTR_STATIC_SELECTORS = AAPTR_STATIC_SELECTORS =
AAPTR_PLAYER1|AAPTR_PLAYER2|AAPTR_PLAYER3|AAPTR_PLAYER4| AAPTR_PLAYER1|AAPTR_PLAYER2|AAPTR_PLAYER3|AAPTR_PLAYER4|

View file

@ -281,7 +281,8 @@ void CT_Drawer (void)
if (players[consoleplayer].camera != NULL && if (players[consoleplayer].camera != NULL &&
(Button_ShowScores.bDown || (Button_ShowScores.bDown ||
players[consoleplayer].camera->health <= 0) && players[consoleplayer].camera->health <= 0 ||
SB_ForceActive) &&
// Don't draw during intermission, since it has its own scoreboard in wi_stuff.cpp. // Don't draw during intermission, since it has its own scoreboard in wi_stuff.cpp.
gamestate != GS_INTERMISSION) gamestate != GS_INTERMISSION)
{ {

View file

@ -756,9 +756,9 @@ void D_Display ()
} }
screen->SetBlendingRect(viewwindowx, viewwindowy, screen->SetBlendingRect(viewwindowx, viewwindowy,
viewwindowx + viewwidth, viewwindowy + viewheight); viewwindowx + viewwidth, viewwindowy + viewheight);
P_PredictPlayer(&players[consoleplayer]);
Renderer->RenderView(&players[consoleplayer]); Renderer->RenderView(&players[consoleplayer]);
P_UnPredictPlayer();
if ((hw2d = screen->Begin2D(viewactive))) if ((hw2d = screen->Begin2D(viewactive)))
{ {
// Redraw everything every frame when using 2D accel // Redraw everything every frame when using 2D accel

View file

@ -110,13 +110,15 @@ unsigned int lastrecvtime[MAXPLAYERS]; // [RH] Used for pings
unsigned int currrecvtime[MAXPLAYERS]; unsigned int currrecvtime[MAXPLAYERS];
unsigned int lastglobalrecvtime; // Identify the last time a packet was recieved. unsigned int lastglobalrecvtime; // Identify the last time a packet was recieved.
bool hadlate; bool hadlate;
int netdelay[MAXNETNODES][BACKUPTICS]; // Used for storing network delay times.
int lastaverage;
int nodeforplayer[MAXPLAYERS]; int nodeforplayer[MAXPLAYERS];
int playerfornode[MAXNETNODES]; int playerfornode[MAXNETNODES];
int maketic; int maketic;
int skiptics; int skiptics;
int ticdup; int ticdup;
void D_ProcessEvents (void); void D_ProcessEvents (void);
void G_BuildTiccmd (ticcmd_t *cmd); void G_BuildTiccmd (ticcmd_t *cmd);
@ -151,6 +153,32 @@ CUSTOM_CVAR (Bool, cl_capfps, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
} }
} }
CVAR(Bool, net_ticbalance, false, CVAR_SERVERINFO | CVAR_NOSAVE)
CUSTOM_CVAR(Int, net_extratic, 0, CVAR_SERVERINFO | CVAR_NOSAVE)
{
if (self < 0)
{
self = 0;
}
else if (self > 2)
{
self = 2;
}
}
#ifdef _DEBUG
CVAR(Int, net_fakelatency, 0, 0);
struct PacketStore
{
int timer;
doomcom_t message;
};
static TArray<PacketStore> InBuffer;
static TArray<PacketStore> OutBuffer;
#endif
// [RH] Special "ticcmds" get stored in here // [RH] Special "ticcmds" get stored in here
static struct TicSpecial static struct TicSpecial
{ {
@ -347,6 +375,9 @@ int NetbufferSize ()
k += netbuffer[k] + 1; k += netbuffer[k] + 1;
} }
// Network delay byte
k++;
if (netbuffer[0] & NCMD_MULTI) if (netbuffer[0] & NCMD_MULTI)
{ {
count = netbuffer[k]; count = netbuffer[k];
@ -487,7 +518,30 @@ void HSendPacket (int node, int len)
doomcom.remotenode = node; doomcom.remotenode = node;
doomcom.datalength = len; doomcom.datalength = len;
I_NetCmd (); #ifdef _DEBUG
if (net_fakelatency / 2 > 0)
{
PacketStore store;
store.message = doomcom;
store.timer = I_GetTime(false) + ((net_fakelatency / 2) / (1000 / TICRATE));
OutBuffer.Push(store);
}
else
I_NetCmd();
for (unsigned int i = 0; i < OutBuffer.Size(); i++)
{
if (OutBuffer[i].timer <= I_GetTime(false))
{
doomcom = OutBuffer[i].message;
I_NetCmd();
OutBuffer.Delete(i);
i = -1;
}
}
#else
I_NetCmd();
#endif
} }
// //
@ -509,12 +563,42 @@ bool HGetPacket (void)
if (demoplayback) if (demoplayback)
return false; return false;
doomcom.command = CMD_GET; doomcom.command = CMD_GET;
I_NetCmd (); I_NetCmd ();
#ifdef _DEBUG
if (net_fakelatency / 2 > 0 && doomcom.remotenode != -1)
{
PacketStore store;
store.message = doomcom;
store.timer = I_GetTime(false) + ((net_fakelatency / 2) / (1000 / TICRATE));
InBuffer.Push(store);
doomcom.remotenode = -1;
}
if (doomcom.remotenode == -1) if (doomcom.remotenode == -1)
{
bool gotmessage = false;
for (unsigned int i = 0; i < InBuffer.Size(); i++)
{
if (InBuffer[i].timer <= I_GetTime(false))
{
doomcom = InBuffer[i].message;
InBuffer.Delete(i);
gotmessage = true;
break;
}
}
if (!gotmessage)
return false;
}
#else
if (doomcom.remotenode == -1)
{
return false; return false;
}
#endif
if (debugfile) if (debugfile)
{ {
@ -570,6 +654,9 @@ bool HGetPacket (void)
if (doomcom.datalength != NetbufferSize ()) if (doomcom.datalength != NetbufferSize ())
{ {
Printf("Bad packet length %i (calculated %i)\n",
doomcom.datalength, NetbufferSize());
if (debugfile) if (debugfile)
fprintf (debugfile,"---bad packet length %i (calculated %i)\n", fprintf (debugfile,"---bad packet length %i (calculated %i)\n",
doomcom.datalength, NetbufferSize()); doomcom.datalength, NetbufferSize());
@ -782,6 +869,9 @@ void GetPackets (void)
} }
} }
// Pull current network delay from node
netdelay[netnode][(nettics[netnode]+1) % BACKUPTICS] = netbuffer[k++];
playerbytes[0] = netconsole; playerbytes[0] = netconsole;
if (netbuffer[0] & NCMD_MULTI) if (netbuffer[0] & NCMD_MULTI)
{ {
@ -1150,11 +1240,18 @@ void NetUpdate (void)
netbuffer[k++] = lowtic; netbuffer[k++] = lowtic;
} }
numtics = lowtic - realstart; numtics = MAX(0, lowtic - realstart);
if (numtics > BACKUPTICS) if (numtics > BACKUPTICS)
I_Error ("NetUpdate: Node %d missed too many tics", i); I_Error ("NetUpdate: Node %d missed too many tics", i);
resendto[i] = MAX (0, lowtic - doomcom.extratics); switch (net_extratic)
{
case 0:
default:
resendto[i] = lowtic; break;
case 1: resendto[i] = MAX(0, lowtic - 1); break;
case 2: resendto[i] = nettics[i]; break;
}
if (numtics == 0 && resendOnly && !remoteresend[i] && nettics[i]) if (numtics == 0 && resendOnly && !remoteresend[i] && nettics[i])
{ {
@ -1190,6 +1287,10 @@ void NetUpdate (void)
} }
} }
// Send current network delay
// The number of tics we just made should be removed from the count.
netbuffer[k++] = ((maketic - newtics - gametic) / ticdup);
if (numtics > 0) if (numtics > 0)
{ {
int l; int l;
@ -1299,9 +1400,37 @@ void NetUpdate (void)
// that it won't adapt. Fortunately, player prediction helps // that it won't adapt. Fortunately, player prediction helps
// alleviate the lag somewhat. // alleviate the lag somewhat.
if (NetMode != NET_PacketServer) if (NetMode == NET_PeerToPeer)
{ {
mastertics = nettics[nodeforplayer[Net_Arbitrator]]; int totalavg = 0;
if (net_ticbalance)
{
// Try to guess ahead the time it takes to send responses to the slowest node
int nodeavg = 0, arbavg = 0;
for (j = 0; j < BACKUPTICS; j++)
{
arbavg += netdelay[nodeforplayer[Net_Arbitrator]][j];
nodeavg += netdelay[0][j];
}
arbavg /= BACKUPTICS;
nodeavg /= BACKUPTICS;
// We shouldn't adapt if we are already the arbitrator isn't what we are waiting for, otherwise it just adds more latency
if (arbavg > nodeavg)
{
lastaverage = totalavg = ((arbavg + nodeavg) / 2);
}
else
{
// Allow room to guess two tics ahead
if (nodeavg > (arbavg + 2) && lastaverage > 0)
lastaverage--;
totalavg = lastaverage;
}
}
mastertics = nettics[nodeforplayer[Net_Arbitrator]] + totalavg;
} }
if (nettics[0] <= mastertics) if (nettics[0] <= mastertics)
{ {
@ -1346,9 +1475,8 @@ void NetUpdate (void)
// //
// 0 One byte set to NCMD_SETUP+2 // 0 One byte set to NCMD_SETUP+2
// 1 One byte for ticdup setting // 1 One byte for ticdup setting
// 2 One byte for extratics setting // 2 One byte for NetMode setting
// 3 One byte for NetMode setting // 3 String with starting map's name
// 4 String with starting map's name
// . Four bytes for the RNG seed // . Four bytes for the RNG seed
// . Stream containing remaining game info // . Stream containing remaining game info
// //
@ -1429,10 +1557,9 @@ bool DoArbitrate (void *userdata)
data->gotsetup[0] = 0x80; data->gotsetup[0] = 0x80;
ticdup = doomcom.ticdup = netbuffer[1]; ticdup = doomcom.ticdup = netbuffer[1];
doomcom.extratics = netbuffer[2]; NetMode = netbuffer[2];
NetMode = netbuffer[3];
stream = &netbuffer[4]; stream = &netbuffer[3];
s = ReadString (&stream); s = ReadString (&stream);
startmap = s; startmap = s;
delete[] s; delete[] s;
@ -1497,9 +1624,8 @@ bool DoArbitrate (void *userdata)
{ {
netbuffer[0] = NCMD_SETUP+2; netbuffer[0] = NCMD_SETUP+2;
netbuffer[1] = (BYTE)doomcom.ticdup; netbuffer[1] = (BYTE)doomcom.ticdup;
netbuffer[2] = (BYTE)doomcom.extratics; netbuffer[2] = NetMode;
netbuffer[3] = NetMode; stream = &netbuffer[3];
stream = &netbuffer[4];
WriteString (startmap, &stream); WriteString (startmap, &stream);
WriteLong (rngseed, &stream); WriteLong (rngseed, &stream);
C_WriteCVars (&stream, CVAR_SERVERINFO, true); C_WriteCVars (&stream, CVAR_SERVERINFO, true);
@ -1647,15 +1773,23 @@ void D_CheckNetGame (void)
consoleplayer = doomcom.consoleplayer; consoleplayer = doomcom.consoleplayer;
v = Args->CheckValue ("-netmode"); if (consoleplayer == Net_Arbitrator)
if (v != NULL)
{ {
NetMode = atoi (v) != 0 ? NET_PacketServer : NET_PeerToPeer; v = Args->CheckValue("-netmode");
} if (v != NULL)
if (doomcom.numnodes > 1) {
{ NetMode = atoi(v) != 0 ? NET_PacketServer : NET_PeerToPeer;
Printf ("Selected " TEXTCOLOR_BLUE "%s" TEXTCOLOR_NORMAL " networking mode. (%s)\n", NetMode == NET_PeerToPeer ? "peer to peer" : "packet server", }
v != NULL ? "forced" : "auto"); if (doomcom.numnodes > 1)
{
Printf("Selected " TEXTCOLOR_BLUE "%s" TEXTCOLOR_NORMAL " networking mode. (%s)\n", NetMode == NET_PeerToPeer ? "peer to peer" : "packet server",
v != NULL ? "forced" : "auto");
}
if (Args->CheckParm("-extratic"))
{
net_extratic = 1;
}
} }
// [RH] Setup user info // [RH] Setup user info
@ -1683,6 +1817,11 @@ void D_CheckNetGame (void)
for (i = 0; i < doomcom.numnodes; i++) for (i = 0; i < doomcom.numnodes; i++)
nodeingame[i] = true; nodeingame[i] = true;
if (consoleplayer != Net_Arbitrator && doomcom.numnodes > 1)
{
Printf("Arbitrator selected " TEXTCOLOR_BLUE "%s" TEXTCOLOR_NORMAL " networking mode.\n", NetMode == NET_PeerToPeer ? "peer to peer" : "packet server");
}
Printf ("player %i of %i (%i nodes)\n", Printf ("player %i of %i (%i nodes)\n",
consoleplayer+1, doomcom.numplayers, doomcom.numnodes); consoleplayer+1, doomcom.numplayers, doomcom.numnodes);
} }
@ -1809,6 +1948,9 @@ void TryRunTics (void)
{ {
C_Ticker(); C_Ticker();
M_Ticker(); M_Ticker();
// Repredict the player for new buffered movement
P_UnPredictPlayer();
P_PredictPlayer(&players[consoleplayer]);
} }
return; return;
} }
@ -1844,6 +1986,9 @@ void TryRunTics (void)
{ {
C_Ticker (); C_Ticker ();
M_Ticker (); M_Ticker ();
// Repredict the player for new buffered movement
P_UnPredictPlayer();
P_PredictPlayer(&players[consoleplayer]);
return; return;
} }
} }
@ -1857,6 +2002,7 @@ void TryRunTics (void)
// run the count tics // run the count tics
if (counts > 0) if (counts > 0)
{ {
P_UnPredictPlayer();
while (counts--) while (counts--)
{ {
if (gametic > lowtic) if (gametic > lowtic)
@ -1876,6 +2022,7 @@ void TryRunTics (void)
NetUpdate (); // check for new console commands NetUpdate (); // check for new console commands
} }
P_PredictPlayer(&players[consoleplayer]);
S_UpdateSounds (players[consoleplayer].camera); // move positional sounds S_UpdateSounds (players[consoleplayer].camera); // move positional sounds
} }
} }
@ -2713,7 +2860,6 @@ void Net_SkipCommand (int type, BYTE **stream)
CCMD (pings) CCMD (pings)
{ {
int i; int i;
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i]) if (playeringame[i])
Printf ("% 4d %s\n", currrecvtime[i] - lastrecvtime[i], Printf ("% 4d %s\n", currrecvtime[i] - lastrecvtime[i],

View file

@ -70,7 +70,6 @@ struct doomcom_t
// info common to all nodes // info common to all nodes
SWORD numnodes; // console is always node 0. SWORD numnodes; // console is always node 0.
SWORD ticdup; // 1 = no duplication, 2-5 = dup for slow nets SWORD ticdup; // 1 = no duplication, 2-5 = dup for slow nets
SWORD extratics; // 1 = send a backup tic in every packet
#ifdef DJGPP #ifdef DJGPP
SWORD pad[5]; // keep things aligned for DOS drivers SWORD pad[5]; // keep things aligned for DOS drivers
#endif #endif
@ -143,6 +142,8 @@ extern struct ticcmd_t localcmds[LOCALCMDTICS];
extern int maketic; extern int maketic;
extern int nettics[MAXNETNODES]; extern int nettics[MAXNETNODES];
extern int netdelay[MAXNETNODES][BACKUPTICS];
extern int nodeforplayer[MAXPLAYERS];
extern ticcmd_t netcmds[MAXPLAYERS][BACKUPTICS]; extern ticcmd_t netcmds[MAXPLAYERS][BACKUPTICS];
extern int ticdup; extern int ticdup;

View file

@ -162,6 +162,7 @@ enum ELineFlags
ML_BLOCKUSE = 0x02000000, // blocks all use actions through this line ML_BLOCKUSE = 0x02000000, // blocks all use actions through this line
ML_BLOCKSIGHT = 0x04000000, // blocks monster line of sight ML_BLOCKSIGHT = 0x04000000, // blocks monster line of sight
ML_BLOCKHITSCAN = 0x08000000, // blocks hitscan attacks ML_BLOCKHITSCAN = 0x08000000, // blocks hitscan attacks
ML_3DMIDTEX_IMPASS = 0x10000000, // [TP] if 3D midtex, behaves like a height-restricted ML_BLOCKING
}; };

View file

@ -546,6 +546,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireBFG)
P_SpawnPlayerMissile (self, 0, 0, 0, PClass::FindClass("BFGBall"), self->angle, NULL, NULL, !!(dmflags2 & DF2_NO_FREEAIMBFG)); P_SpawnPlayerMissile (self, 0, 0, 0, PClass::FindClass("BFGBall"), self->angle, NULL, NULL, !!(dmflags2 & DF2_NO_FREEAIMBFG));
} }
// //
// A_BFGSpray // A_BFGSpray
// Spawn a BFG explosion on every monster in view // Spawn a BFG explosion on every monster in view
@ -559,14 +560,21 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray)
AActor *thingToHit; AActor *thingToHit;
AActor *linetarget; AActor *linetarget;
ACTION_PARAM_START(3); ACTION_PARAM_START(7);
ACTION_PARAM_CLASS(spraytype, 0); ACTION_PARAM_CLASS(spraytype, 0);
ACTION_PARAM_INT(numrays, 1); ACTION_PARAM_INT(numrays, 1);
ACTION_PARAM_INT(damagecnt, 2); ACTION_PARAM_INT(damagecnt, 2);
ACTION_PARAM_ANGLE(angle, 3);
ACTION_PARAM_FIXED(distance, 4);
ACTION_PARAM_ANGLE(vrange, 5);
ACTION_PARAM_INT(defdamage, 6);
if (spraytype == NULL) spraytype = PClass::FindClass("BFGExtra"); if (spraytype == NULL) spraytype = PClass::FindClass("BFGExtra");
if (numrays <= 0) numrays = 40; if (numrays <= 0) numrays = 40;
if (damagecnt <= 0) damagecnt = 15; if (damagecnt <= 0) damagecnt = 15;
if (angle == 0) angle = ANG90;
if (distance <= 0) distance = 16 * 64 * FRACUNIT;
if (vrange == 0) vrange = ANGLE_1 * 32;
// [RH] Don't crash if no target // [RH] Don't crash if no target
if (!self->target) if (!self->target)
@ -575,10 +583,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray)
// offset angles from its attack angle // offset angles from its attack angle
for (i = 0; i < numrays; i++) for (i = 0; i < numrays; i++)
{ {
an = self->angle - ANG90/2 + ANG90/numrays*i; an = self->angle - angle/2 + angle/numrays*i;
// self->target is the originator (player) of the missile // self->target is the originator (player) of the missile
P_AimLineAttack (self->target, an, 16*64*FRACUNIT, &linetarget, ANGLE_1*32); P_AimLineAttack (self->target, an, distance, &linetarget, vrange);
if (!linetarget) if (!linetarget)
continue; continue;
@ -589,10 +597,17 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray)
if (spray && (spray->flags5 & MF5_PUFFGETSOWNER)) if (spray && (spray->flags5 & MF5_PUFFGETSOWNER))
spray->target = self->target; spray->target = self->target;
if (defdamage == 0)
damage = 0; {
for (j = 0; j < damagecnt; ++j) damage = 0;
damage += (pr_bfgspray() & 7) + 1; for (j = 0; j < damagecnt; ++j)
damage += (pr_bfgspray() & 7) + 1;
}
else
{
// if this is used, damagecnt will be ignored
damage = defdamage;
}
thingToHit = linetarget; thingToHit = linetarget;
int newdam = P_DamageMobj (thingToHit, self->target, self->target, damage, spray != NULL? FName(spray->DamageType) : FName(NAME_BFGSplash), int newdam = P_DamageMobj (thingToHit, self->target, self->target, damage, spray != NULL? FName(spray->DamageType) : FName(NAME_BFGSplash),

View file

@ -37,6 +37,7 @@
// copy would be. // copy would be.
#include "doomtype.h" #include "doomtype.h"
#include "doomdef.h"
#include "v_video.h" #include "v_video.h"
#include "gi.h" #include "gi.h"
#include "c_cvars.h" #include "c_cvars.h"
@ -48,6 +49,7 @@
#include "p_local.h" #include "p_local.h"
#include "doomstat.h" #include "doomstat.h"
#include "g_level.h" #include "g_level.h"
#include "d_net.h"
#include <time.h> #include <time.h>
@ -73,6 +75,7 @@ CVAR (Bool, hud_showscore, false, CVAR_ARCHIVE); // for user maintained score
CVAR (Bool, hud_showweapons, true, CVAR_ARCHIVE); // Show weapons collected CVAR (Bool, hud_showweapons, true, CVAR_ARCHIVE); // Show weapons collected
CVAR (Int , hud_showtime, 0, CVAR_ARCHIVE); // Show time on HUD CVAR (Int , hud_showtime, 0, CVAR_ARCHIVE); // Show time on HUD
CVAR (Int , hud_timecolor, CR_GOLD,CVAR_ARCHIVE); // Color of in-game time on HUD CVAR (Int , hud_timecolor, CR_GOLD,CVAR_ARCHIVE); // Color of in-game time on HUD
CVAR (Int , hud_showlag, 0, CVAR_ARCHIVE); // Show input latency (maketic - gametic difference)
CVAR (Int, hud_ammo_red, 25, CVAR_ARCHIVE) // ammo percent less than which status is red CVAR (Int, hud_ammo_red, 25, CVAR_ARCHIVE) // ammo percent less than which status is red
CVAR (Int, hud_ammo_yellow, 50, CVAR_ARCHIVE) // ammo percent less is yellow more green CVAR (Int, hud_ammo_yellow, 50, CVAR_ARCHIVE) // ammo percent less is yellow more green
@ -917,6 +920,51 @@ static void DrawTime()
DrawHudText(SmallFont, hud_timecolor, timeString, hudwidth - width, height, FRACUNIT); DrawHudText(SmallFont, hud_timecolor, timeString, hudwidth - width, height, FRACUNIT);
} }
//---------------------------------------------------------------------------
//
// Draw in-game latency
//
//---------------------------------------------------------------------------
static void DrawLatency()
{
if (hud_showlag <= 0 ||
(hud_showlag == 1 && !netgame) ||
hud_showlag > 2)
{
return;
}
int i, localdelay = 0, arbitratordelay = 0;
for (i = 0; i < BACKUPTICS; i++) localdelay += netdelay[0][i];
for (i = 0; i < BACKUPTICS; i++) arbitratordelay += netdelay[nodeforplayer[Net_Arbitrator]][i];
localdelay = ((localdelay / BACKUPTICS) * ticdup) * (1000 / TICRATE);
arbitratordelay = ((arbitratordelay / BACKUPTICS) * ticdup) * (1000 / TICRATE);
int color = CR_GREEN;
if (MAX(localdelay, arbitratordelay) > 200)
{
color = CR_YELLOW;
}
if (MAX(localdelay, arbitratordelay) > 400)
{
color = CR_ORANGE;
}
if (MAX(localdelay, arbitratordelay) >= ((BACKUPTICS / 2 - 1) * ticdup) * (1000 / TICRATE))
{
color = CR_RED;
}
char tempstr[32];
const int millis = (level.time % TICRATE) * (1000 / TICRATE);
mysnprintf(tempstr, sizeof(tempstr), "a:%dms - l:%dms", arbitratordelay, localdelay);
const int characterCount = strlen(tempstr);
const int width = SmallFont->GetCharWidth('0') * characterCount + 2; // small offset from screen's border
const int height = SmallFont->GetHeight() * 2;
DrawHudText(SmallFont, color, tempstr, hudwidth - width, height, FRACUNIT);
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //
@ -982,6 +1030,7 @@ void DrawHUD()
if (idmypos) DrawCoordinates(CPlayer); if (idmypos) DrawCoordinates(CPlayer);
DrawTime(); DrawTime();
DrawLatency();
} }
else else
{ {

View file

@ -48,6 +48,8 @@
#include "d_player.h" #include "d_player.h"
#include "hu_stuff.h" #include "hu_stuff.h"
#include "gstrings.h" #include "gstrings.h"
#include "d_net.h"
#include "c_dispatch.h"
// MACROS ------------------------------------------------------------------ // MACROS ------------------------------------------------------------------
@ -61,7 +63,7 @@
static void HU_DoDrawScores (player_t *, player_t *[MAXPLAYERS]); static void HU_DoDrawScores (player_t *, player_t *[MAXPLAYERS]);
static void HU_DrawTimeRemaining (int y); static void HU_DrawTimeRemaining (int y);
static void HU_DrawPlayer (player_t *, bool, int, int, int, int, int, int, int, int); static void HU_DrawPlayer(player_t *, bool, int, int, int, int, int, int, int, int, int);
// EXTERNAL DATA DECLARATIONS ---------------------------------------------- // EXTERNAL DATA DECLARATIONS ----------------------------------------------
@ -116,6 +118,8 @@ int STACK_ARGS compareteams (const void *arg1, const void *arg2)
return diff; return diff;
} }
bool SB_ForceActive = false;
// PRIVATE DATA DEFINITIONS ------------------------------------------------ // PRIVATE DATA DEFINITIONS ------------------------------------------------
// CODE -------------------------------------------------------------------- // CODE --------------------------------------------------------------------
@ -228,7 +232,7 @@ static void HU_DoDrawScores (player_t *player, player_t *sortedplayers[MAXPLAYER
int maxnamewidth, maxscorewidth, maxiconheight; int maxnamewidth, maxscorewidth, maxiconheight;
int numTeams = 0; int numTeams = 0;
int x, y, ypadding, bottom; int x, y, ypadding, bottom;
int col2, col3, col4; int col2, col3, col4, col5;
if (deathmatch) if (deathmatch)
{ {
@ -309,12 +313,14 @@ static void HU_DoDrawScores (player_t *player, player_t *sortedplayers[MAXPLAYER
const char *text_color = GStrings("SCORE_COLOR"), const char *text_color = GStrings("SCORE_COLOR"),
*text_frags = GStrings(deathmatch ? "SCORE_FRAGS" : "SCORE_KILLS"), *text_frags = GStrings(deathmatch ? "SCORE_FRAGS" : "SCORE_KILLS"),
*text_name = GStrings("SCORE_NAME"); *text_name = GStrings("SCORE_NAME"),
*text_delay = GStrings("SCORE_DELAY");
col2 = (SmallFont->StringWidth(text_color) + 8) * CleanXfac; col2 = (SmallFont->StringWidth(text_color) + 8) * CleanXfac;
col3 = col2 + (SmallFont->StringWidth(text_frags) + 8) * CleanXfac; col3 = col2 + (SmallFont->StringWidth(text_frags) + 8) * CleanXfac;
col4 = col3 + maxscorewidth * CleanXfac; col4 = col3 + maxscorewidth * CleanXfac;
x = (SCREENWIDTH >> 1) - ((maxnamewidth * CleanXfac + col4) >> 1); col5 = col4 + (maxnamewidth + 8) * CleanXfac;
x = (SCREENWIDTH >> 1) - (((SmallFont->StringWidth(text_delay) * CleanXfac) + col5) >> 1);
screen->DrawText (SmallFont, color, x, y, text_color, screen->DrawText (SmallFont, color, x, y, text_color,
DTA_CleanNoMove, true, TAG_DONE); DTA_CleanNoMove, true, TAG_DONE);
@ -325,6 +331,9 @@ static void HU_DoDrawScores (player_t *player, player_t *sortedplayers[MAXPLAYER
screen->DrawText (SmallFont, color, x + col4, y, text_name, screen->DrawText (SmallFont, color, x + col4, y, text_name,
DTA_CleanNoMove, true, TAG_DONE); DTA_CleanNoMove, true, TAG_DONE);
screen->DrawText(SmallFont, color, x + col5, y, text_delay,
DTA_CleanNoMove, true, TAG_DONE);
y += height + 6 * CleanYfac; y += height + 6 * CleanYfac;
bottom -= height; bottom -= height;
@ -332,7 +341,7 @@ static void HU_DoDrawScores (player_t *player, player_t *sortedplayers[MAXPLAYER
{ {
if (playeringame[sortedplayers[i] - players]) if (playeringame[sortedplayers[i] - players])
{ {
HU_DrawPlayer (sortedplayers[i], player==sortedplayers[i], x, col2, col3, col4, maxnamewidth, y, ypadding, lineheight); HU_DrawPlayer(sortedplayers[i], player == sortedplayers[i], x, col2, col3, col4, col5, maxnamewidth, y, ypadding, lineheight);
y += lineheight + CleanYfac; y += lineheight + CleanYfac;
} }
} }
@ -377,7 +386,7 @@ static void HU_DrawTimeRemaining (int y)
// //
//========================================================================== //==========================================================================
static void HU_DrawPlayer (player_t *player, bool highlight, int col1, int col2, int col3, int col4, int maxnamewidth, int y, int ypadding, int height) static void HU_DrawPlayer (player_t *player, bool highlight, int col1, int col2, int col3, int col4, int col5, int maxnamewidth, int y, int ypadding, int height)
{ {
int color; int color;
char str[80]; char str[80];
@ -387,12 +396,13 @@ static void HU_DrawPlayer (player_t *player, bool highlight, int col1, int col2,
// The teamplay mode uses colors to show teams, so we need some // The teamplay mode uses colors to show teams, so we need some
// other way to do highlighting. And it may as well be used for // other way to do highlighting. And it may as well be used for
// all modes for the sake of consistancy. // all modes for the sake of consistancy.
screen->Dim(MAKERGB(200,245,255), 0.125f, col1 - 12*CleanXfac, y - 1, col4 + (maxnamewidth + 24)*CleanXfac, height + 2); screen->Dim(MAKERGB(200,245,255), 0.125f, col1 - 12*CleanXfac, y - 1, col5 + (maxnamewidth + 24)*CleanXfac, height + 2);
} }
col2 += col1; col2 += col1;
col3 += col1; col3 += col1;
col4 += col1; col4 += col1;
col5 += col1;
color = HU_GetRowColor(player, highlight); color = HU_GetRowColor(player, highlight);
HU_DrawColorBar(col1, y, height, (int)(player - players)); HU_DrawColorBar(col1, y, height, (int)(player - players));
@ -412,6 +422,18 @@ static void HU_DrawPlayer (player_t *player, bool highlight, int col1, int col2,
screen->DrawText (SmallFont, color, col4, y + ypadding, player->userinfo.GetName(), screen->DrawText (SmallFont, color, col4, y + ypadding, player->userinfo.GetName(),
DTA_CleanNoMove, true, TAG_DONE); DTA_CleanNoMove, true, TAG_DONE);
int avgdelay = 0;
for (int i = 0; i < BACKUPTICS; i++)
{
avgdelay += netdelay[nodeforplayer[(int)(player - players)]][i];
}
avgdelay /= BACKUPTICS;
mysnprintf(str, countof(str), "%d", (avgdelay * ticdup) * (1000 / TICRATE));
screen->DrawText(SmallFont, color, col5, y + ypadding, str,
DTA_CleanNoMove, true, TAG_DONE);
if (teamplay && Teams[player->userinfo.GetTeam()].GetLogo().IsNotEmpty ()) if (teamplay && Teams[player->userinfo.GetTeam()].GetLogo().IsNotEmpty ())
{ {
FTexture *pic = TexMan[Teams[player->userinfo.GetTeam()].GetLogo().GetChars ()]; FTexture *pic = TexMan[Teams[player->userinfo.GetTeam()].GetLogo().GetChars ()];
@ -473,3 +495,8 @@ int HU_GetRowColor(player_t *player, bool highlight)
} }
} }
} }
CCMD (togglescoreboard)
{
SB_ForceActive = !SB_ForceActive;
}

View file

@ -52,6 +52,8 @@ void HU_GetPlayerWidths(int &maxnamewidth, int &maxscorewidth, int &maxiconheigh
void HU_DrawColorBar(int x, int y, int height, int playernum); void HU_DrawColorBar(int x, int y, int height, int playernum);
int HU_GetRowColor(player_t *player, bool hightlight); int HU_GetRowColor(player_t *player, bool hightlight);
extern bool SB_ForceActive;
// Sorting routines // Sorting routines
int STACK_ARGS comparepoints(const void *arg1, const void *arg2); int STACK_ARGS comparepoints(const void *arg1, const void *arg2);

View file

@ -208,11 +208,11 @@ void PacketSend (void)
{ {
I_FatalError("Netbuffer overflow!"); I_FatalError("Netbuffer overflow!");
} }
assert(!(doomcom.data[0] & NCMD_COMPRESSED));
uLong size = TRANSMIT_SIZE - 1; uLong size = TRANSMIT_SIZE - 1;
if (doomcom.datalength >= 10) if (doomcom.datalength >= 10)
{ {
assert(!(doomcom.data[0] & NCMD_COMPRESSED));
TransmitBuffer[0] = doomcom.data[0] | NCMD_COMPRESSED; TransmitBuffer[0] = doomcom.data[0] | NCMD_COMPRESSED;
c = compress2(TransmitBuffer + 1, &size, doomcom.data + 1, doomcom.datalength - 1, 9); c = compress2(TransmitBuffer + 1, &size, doomcom.data + 1, doomcom.datalength - 1, 9);
size += 1; size += 1;
@ -938,11 +938,6 @@ bool I_InitNetwork (void)
doomcom.ticdup = 1; doomcom.ticdup = 1;
} }
if (Args->CheckParm ("-extratic"))
doomcom.extratics = 1;
else
doomcom.extratics = 0;
v = Args->CheckValue ("-port"); v = Args->CheckValue ("-port");
if (v) if (v)
{ {

View file

@ -298,6 +298,8 @@ xx(Abs)
xx(ACS_NamedExecuteWithResult) xx(ACS_NamedExecuteWithResult)
xx(CallACS) xx(CallACS)
xx(Sqrt) xx(Sqrt)
xx(CheckClass)
xx(IsPointerEqual)
// Various actor names which are used internally // Various actor names which are used internally
xx(MapSpot) xx(MapSpot)
@ -418,6 +420,7 @@ xx(Passuse)
xx(Repeatspecial) xx(Repeatspecial)
xx(Conversation) xx(Conversation)
xx(Locknumber) xx(Locknumber)
xx(Midtex3dimpassible)
xx(Playercross) xx(Playercross)
xx(Playeruse) xx(Playeruse)
@ -596,4 +599,4 @@ xx(NeverSwitchOnPickup)
xx(MoveBob) xx(MoveBob)
xx(StillBob) xx(StillBob)
xx(PlayerClass) xx(PlayerClass)
xx(Wi_NoAutostartMap) xx(Wi_NoAutostartMap)

View file

@ -258,6 +258,13 @@ bool P_GetMidTexturePosition(const line_t *line, int sideno, fixed_t *ptextop, f
bool P_LineOpening_3dMidtex(AActor *thing, const line_t *linedef, FLineOpening &open, bool restrict) bool P_LineOpening_3dMidtex(AActor *thing, const line_t *linedef, FLineOpening &open, bool restrict)
{ {
// [TP] Impassible-like 3dmidtextures do not block missiles
if ((linedef->flags & ML_3DMIDTEX_IMPASS)
&& (thing->flags & MF_MISSILE || thing->BounceFlags & BOUNCE_MBF))
{
return false;
}
fixed_t tt, tb; fixed_t tt, tb;
open.abovemidtex = false; open.abovemidtex = false;

View file

@ -3843,6 +3843,10 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value)
actor->reactiontime = value; actor->reactiontime = value;
break; break;
case APROP_MeleeRange:
actor->meleerange = value;
break;
case APROP_ViewHeight: case APROP_ViewHeight:
if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn))) if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn)))
static_cast<APlayerPawn *>(actor)->ViewHeight = value; static_cast<APlayerPawn *>(actor)->ViewHeight = value;
@ -4368,6 +4372,9 @@ enum EACSFunctions
ACSF_ChangeActorPitch, // 80 ACSF_ChangeActorPitch, // 80
ACSF_GetArmorInfo, ACSF_GetArmorInfo,
ACSF_DropInventory, ACSF_DropInventory,
ACSF_PickActor,
ACSF_IsPointerEqual,
ACSF_CanRaiseActor,
/* Zandronum's - these must be skipped when we reach 99! /* Zandronum's - these must be skipped when we reach 99!
-100:ResetMap(0), -100:ResetMap(0),
@ -5593,6 +5600,74 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
} }
break; break;
case ACSF_PickActor:
if (argCount >= 5)
{
actor = SingleActorFromTID(args[0], activator);
if (actor == NULL)
{
return 0;
}
DWORD actorMask = MF_SHOOTABLE;
if (argCount >= 6) {
actorMask = args[5];
}
DWORD wallMask = ML_BLOCKEVERYTHING | ML_BLOCKHITSCAN;
if (argCount >= 7) {
wallMask = args[6];
}
AActor* pickedActor = P_LinePickActor(actor, args[1] << 16, args[3], args[2] << 16, actorMask, wallMask);
if (pickedActor == NULL) {
return 0;
}
pickedActor->RemoveFromHash();
pickedActor->tid = args[4];
pickedActor->AddToHash();
return 1;
}
break;
case ACSF_IsPointerEqual:
{
int tid1 = 0, tid2 = 0;
switch (argCount)
{
case 4: tid2 = args[3];
case 3: tid1 = args[2];
}
actor = SingleActorFromTID(tid1, activator);
AActor * actor2 = tid2 == tid1 ? actor : SingleActorFromTID(tid2, activator);
return COPY_AAPTR(actor, args[0]) == COPY_AAPTR(actor2, args[1]);
}
break;
case ACSF_CanRaiseActor:
if (argCount >= 1) {
if (args[0] == 0) {
actor = SingleActorFromTID(args[0], activator);
if (actor != NULL) {
return P_Thing_CanRaise(actor);
}
}
FActorIterator iterator(args[0]);
bool canraiseall = false;
while ((actor = iterator.Next()))
{
canraiseall = !P_Thing_CanRaise(actor) | canraiseall;
}
return !canraiseall;
}
break;
default: default:
break; break;
} }

View file

@ -171,6 +171,7 @@ int P_Thing_Damage (int tid, AActor *whofor0, int amount, FName type);
void P_Thing_SetVelocity(AActor *actor, fixed_t vx, fixed_t vy, fixed_t vz, bool add, bool setbob); void P_Thing_SetVelocity(AActor *actor, fixed_t vx, fixed_t vy, fixed_t vz, bool add, bool setbob);
void P_RemoveThing(AActor * actor); void P_RemoveThing(AActor * actor);
bool P_Thing_Raise(AActor *thing); bool P_Thing_Raise(AActor *thing);
bool P_Thing_CanRaise(AActor *thing);
const PClass *P_GetSpawnableType(int spawnnum); const PClass *P_GetSpawnableType(int spawnnum);
// //
@ -462,6 +463,7 @@ enum // P_LineAttack flags
AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, const PClass *pufftype, int flags = 0, AActor **victim = NULL, int *actualdamage = NULL); AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, const PClass *pufftype, int flags = 0, AActor **victim = NULL, int *actualdamage = NULL);
AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, FName pufftype, int flags = 0, AActor **victim = NULL, int *actualdamage = NULL); AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, FName pufftype, int flags = 0, AActor **victim = NULL, int *actualdamage = NULL);
AActor *P_LinePickActor (AActor *t1, angle_t angle, fixed_t distance, int pitch, DWORD actorMask, DWORD wallMask);
void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *target, angle_t angle, int pitch); void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *target, angle_t angle, int pitch);
void P_TraceBleed (int damage, AActor *target, angle_t angle, int pitch); void P_TraceBleed (int damage, AActor *target, angle_t angle, int pitch);
void P_TraceBleed (int damage, AActor *target, AActor *missile); // missile version void P_TraceBleed (int damage, AActor *target, AActor *missile); // missile version

View file

@ -380,7 +380,9 @@ bool P_TeleportMove(AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefra
// ... and some items can never be telefragged while others will be telefragged by everything that teleports upon them. // ... and some items can never be telefragged while others will be telefragged by everything that teleports upon them.
if ((StompAlwaysFrags && !(th->flags6 & MF6_NOTELEFRAG)) || (th->flags7 & MF7_ALWAYSTELEFRAG)) if ((StompAlwaysFrags && !(th->flags6 & MF6_NOTELEFRAG)) || (th->flags7 & MF7_ALWAYSTELEFRAG))
{ {
P_DamageMobj(th, thing, thing, TELEFRAG_DAMAGE, NAME_Telefrag, DMG_THRUSTLESS); // Don't actually damage if predicting a teleport
if (thing->player == NULL || !(thing->player->cheats & CF_PREDICTING))
P_DamageMobj(th, thing, thing, TELEFRAG_DAMAGE, NAME_Telefrag, DMG_THRUSTLESS);
continue; continue;
} }
return false; return false;
@ -1981,13 +1983,6 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y,
thing->AdjustFloorClip(); thing->AdjustFloorClip();
} }
// [RH] Don't activate anything if just predicting
if (thing->player && (thing->player->cheats & CF_PREDICTING))
{
thing->flags6 &= ~MF6_INTRYMOVE;
return true;
}
// if any special lines were hit, do the effect // if any special lines were hit, do the effect
if (!(thing->flags & (MF_TELEPORT | MF_NOCLIP))) if (!(thing->flags & (MF_TELEPORT | MF_NOCLIP)))
{ {
@ -1998,7 +1993,11 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y,
oldside = P_PointOnLineSide(oldx, oldy, ld); oldside = P_PointOnLineSide(oldx, oldy, ld);
if (side != oldside && ld->special && !(thing->flags6 & MF6_NOTRIGGER)) if (side != oldside && ld->special && !(thing->flags6 & MF6_NOTRIGGER))
{ {
if (thing->player) if (thing->player && (thing->player->cheats & CF_PREDICTING))
{
P_PredictLine(ld, thing, oldside, SPAC_Cross);
}
else if (thing->player)
{ {
P_ActivateLine(ld, thing, oldside, SPAC_Cross); P_ActivateLine(ld, thing, oldside, SPAC_Cross);
} }
@ -2024,6 +2023,13 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y,
} }
} }
// [RH] Don't activate anything if just predicting
if (thing->player && (thing->player->cheats & CF_PREDICTING))
{
thing->flags6 &= ~MF6_INTRYMOVE;
return true;
}
// [RH] Check for crossing fake floor/ceiling // [RH] Check for crossing fake floor/ceiling
newsec = thing->Sector; newsec = thing->Sector;
if (newsec->heightsec && oldsec->heightsec && newsec->SecActTarget) if (newsec->heightsec && oldsec->heightsec && newsec->SecActTarget)
@ -3783,6 +3789,52 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance,
return NULL; return NULL;
} }
//==========================================================================
//
// P_LinePickActor
//
//==========================================================================
AActor *P_LinePickActor(AActor *t1, angle_t angle, fixed_t distance, int pitch,
DWORD actorMask, DWORD wallMask)
{
fixed_t vx, vy, vz, shootz;
angle >>= ANGLETOFINESHIFT;
pitch = (angle_t)(pitch) >> ANGLETOFINESHIFT;
vx = FixedMul(finecosine[pitch], finecosine[angle]);
vy = FixedMul(finecosine[pitch], finesine[angle]);
vz = -finesine[pitch];
shootz = t1->z - t1->floorclip + (t1->height >> 1);
if (t1->player != NULL)
{
shootz += FixedMul(t1->player->mo->AttackZOffset, t1->player->crouchfactor);
}
else
{
shootz += 8 * FRACUNIT;
}
FTraceResults trace;
Origin TData;
TData.Caller = t1;
TData.hitGhosts = true;
if (Trace(t1->x, t1->y, shootz, t1->Sector, vx, vy, vz, distance,
actorMask, wallMask, t1, trace, TRACE_NoSky, CheckForActor, &TData))
{
if (trace.HitType == TRACE_HitActor)
{
return trace.Actor;
}
}
return NULL;
}
//========================================================================== //==========================================================================
// //
// //

View file

@ -73,6 +73,7 @@
static FRandom pr_playerinspecialsector ("PlayerInSpecialSector"); static FRandom pr_playerinspecialsector ("PlayerInSpecialSector");
void P_SetupPortals(); void P_SetupPortals();
EXTERN_CVAR(Bool, cl_predict_specials)
IMPLEMENT_POINTY_CLASS (DScroller) IMPLEMENT_POINTY_CLASS (DScroller)
DECLARE_POINTER (m_Interpolations[0]) DECLARE_POINTER (m_Interpolations[0])
@ -408,6 +409,48 @@ bool P_TestActivateLine (line_t *line, AActor *mo, int side, int activationType)
return true; return true;
} }
//============================================================================
//
// P_PredictLine
//
//============================================================================
bool P_PredictLine(line_t *line, AActor *mo, int side, int activationType)
{
int lineActivation;
INTBOOL buttonSuccess;
BYTE special;
// Only predict a very specifc section of specials
if (line->special != Teleport_Line &&
line->special != Teleport)
{
return false;
}
if (!P_TestActivateLine(line, mo, side, activationType) || !cl_predict_specials)
{
return false;
}
if (line->locknumber > 0) return false;
lineActivation = line->activation;
buttonSuccess = false;
buttonSuccess = P_ExecuteSpecial(line->special,
line, mo, side == 1, line->args[0],
line->args[1], line->args[2],
line->args[3], line->args[4]);
special = line->special;
// end of changed code
if (developer && buttonSuccess)
{
Printf("Line special %d predicted on line %i\n", special, int(line - lines));
}
return true;
}
// //
// P_PlayerInSpecialSector // P_PlayerInSpecialSector
// Called every tic frame // Called every tic frame

View file

@ -166,6 +166,7 @@ void P_UpdateSpecials (void);
// when needed // when needed
bool P_ActivateLine (line_t *ld, AActor *mo, int side, int activationType); bool P_ActivateLine (line_t *ld, AActor *mo, int side, int activationType);
bool P_TestActivateLine (line_t *ld, AActor *mo, int side, int activationType); bool P_TestActivateLine (line_t *ld, AActor *mo, int side, int activationType);
bool P_PredictLine (line_t *ld, AActor *mo, int side, int activationType);
void P_PlayerInSpecialSector (player_t *player, sector_t * sector=NULL); void P_PlayerInSpecialSector (player_t *player, sector_t * sector=NULL);
void P_PlayerOnSpecialFlat (player_t *player, int floorType); void P_PlayerOnSpecialFlat (player_t *player, int floorType);

View file

@ -96,6 +96,8 @@ void P_SpawnTeleportFog(fixed_t x, fixed_t y, fixed_t z, int spawnid)
bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
bool useFog, bool sourceFog, bool keepOrientation, bool bHaltVelocity, bool keepHeight) bool useFog, bool sourceFog, bool keepOrientation, bool bHaltVelocity, bool keepHeight)
{ {
bool predicting = (thing->player && (thing->player->cheats & CF_PREDICTING));
fixed_t oldx; fixed_t oldx;
fixed_t oldy; fixed_t oldy;
fixed_t oldz; fixed_t oldz;
@ -181,7 +183,7 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
angle = thing->angle; angle = thing->angle;
} }
// Spawn teleport fog at source and destination // Spawn teleport fog at source and destination
if (sourceFog) if (sourceFog && !predicting)
{ {
fixed_t fogDelta = thing->flags & MF_MISSILE ? 0 : TELEFOGHEIGHT; fixed_t fogDelta = thing->flags & MF_MISSILE ? 0 : TELEFOGHEIGHT;
AActor *fog = Spawn<ATeleportFog> (oldx, oldy, oldz + fogDelta, ALLOW_REPLACE); AActor *fog = Spawn<ATeleportFog> (oldx, oldy, oldz + fogDelta, ALLOW_REPLACE);
@ -189,11 +191,14 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
} }
if (useFog) if (useFog)
{ {
fixed_t fogDelta = thing->flags & MF_MISSILE ? 0 : TELEFOGHEIGHT; if (!predicting)
an = angle >> ANGLETOFINESHIFT; {
AActor *fog = Spawn<ATeleportFog> (x + 20*finecosine[an], fixed_t fogDelta = thing->flags & MF_MISSILE ? 0 : TELEFOGHEIGHT;
y + 20*finesine[an], thing->z + fogDelta, ALLOW_REPLACE); an = angle >> ANGLETOFINESHIFT;
fog->target = thing; AActor *fog = Spawn<ATeleportFog>(x + 20 * finecosine[an],
y + 20 * finesine[an], thing->z + fogDelta, ALLOW_REPLACE);
fog->target = thing;
}
if (thing->player) if (thing->player)
{ {
// [RH] Zoom player's field of vision // [RH] Zoom player's field of vision
@ -226,7 +231,7 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
return true; return true;
} }
static AActor *SelectTeleDest (int tid, int tag) static AActor *SelectTeleDest (int tid, int tag, bool norandom)
{ {
AActor *searcher; AActor *searcher;
@ -276,7 +281,7 @@ static AActor *SelectTeleDest (int tid, int tag)
} }
else else
{ {
if (count != 1) if (count != 1 && !norandom)
{ {
count = 1 + (pr_teleport() % count); count = 1 + (pr_teleport() % count);
} }
@ -323,6 +328,7 @@ static AActor *SelectTeleDest (int tid, int tag)
bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, bool fog, bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, bool fog,
bool sourceFog, bool keepOrientation, bool haltVelocity, bool keepHeight) bool sourceFog, bool keepOrientation, bool haltVelocity, bool keepHeight)
{ {
AActor *searcher; AActor *searcher;
fixed_t z; fixed_t z;
angle_t angle = 0; angle_t angle = 0;
@ -334,6 +340,7 @@ bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, bool
{ // Teleport function called with an invalid actor { // Teleport function called with an invalid actor
return false; return false;
} }
bool predicting = (thing->player && (thing->player->cheats & CF_PREDICTING));
if (thing->flags2 & MF2_NOTELEPORT) if (thing->flags2 & MF2_NOTELEPORT)
{ {
return false; return false;
@ -342,7 +349,7 @@ bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, bool
{ // Don't teleport if hit back of line, so you can get out of teleporter. { // Don't teleport if hit back of line, so you can get out of teleporter.
return 0; return 0;
} }
searcher = SelectTeleDest (tid, tag); searcher = SelectTeleDest(tid, tag, predicting);
if (searcher == NULL) if (searcher == NULL)
{ {
return false; return false;
@ -390,7 +397,7 @@ bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, bool
thing->velx = FixedMul(velx, c) - FixedMul(vely, s); thing->velx = FixedMul(velx, c) - FixedMul(vely, s);
thing->vely = FixedMul(vely, c) + FixedMul(velx, s); thing->vely = FixedMul(vely, c) + FixedMul(velx, s);
} }
if ((velx | vely) == 0 && thing->player != NULL && thing->player->mo == thing) if ((velx | vely) == 0 && thing->player != NULL && thing->player->mo == thing && !predicting)
{ {
thing->player->mo->PlayIdle (); thing->player->mo->PlayIdle ();
} }

View file

@ -445,6 +445,40 @@ bool P_Thing_Raise(AActor *thing)
return true; return true;
} }
bool P_Thing_CanRaise(AActor *thing)
{
FState * RaiseState = thing->GetRaiseState();
if (RaiseState == NULL)
{
return false;
}
AActor *info = thing->GetDefault();
// Check against real height and radius
int oldflags = thing->flags;
fixed_t oldheight = thing->height;
fixed_t oldradius = thing->radius;
thing->flags |= MF_SOLID;
thing->height = info->height;
thing->radius = info->radius;
bool check = P_CheckPosition (thing, thing->x, thing->y);
// Restore checked properties
thing->flags = oldflags;
thing->radius = oldradius;
thing->height = oldheight;
if (!check)
{
return false;
}
return true;
}
void P_Thing_SetVelocity(AActor *actor, fixed_t vx, fixed_t vy, fixed_t vz, bool add, bool setbob) void P_Thing_SetVelocity(AActor *actor, fixed_t vx, fixed_t vy, fixed_t vz, bool add, bool setbob)
{ {
if (actor != NULL) if (actor != NULL)

View file

@ -1030,11 +1030,16 @@ public:
Flag(ld->flags, ML_BLOCKHITSCAN, key); Flag(ld->flags, ML_BLOCKHITSCAN, key);
continue; continue;
// [Dusk] lock number // [TP] Locks the special with a key
case NAME_Locknumber: case NAME_Locknumber:
ld->locknumber = CheckInt(key); ld->locknumber = CheckInt(key);
continue; continue;
// [TP] Causes a 3d midtex to behave like an impassible line
case NAME_Midtex3dimpassible:
Flag(ld->flags, ML_3DMIDTEX_IMPASS, key);
continue;
default: default:
break; break;
} }
@ -1081,6 +1086,10 @@ public:
{ {
ld->args[1] = -FName(arg1str); ld->args[1] = -FName(arg1str);
} }
if ((ld->flags & ML_3DMIDTEX_IMPASS) && !(ld->flags & ML_3DMIDTEX)) // [TP]
{
Printf ("Line %d has midtex3dimpassible without midtex3d.\n", index);
}
} }
//=========================================================================== //===========================================================================

View file

@ -62,6 +62,7 @@ static FRandom pr_skullpop ("SkullPop");
// Variables for prediction // Variables for prediction
CVAR (Bool, cl_noprediction, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Bool, cl_noprediction, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR(Bool, cl_predict_specials, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
static player_t PredictionPlayerBackup; static player_t PredictionPlayerBackup;
static BYTE PredictionActorBackup[sizeof(AActor)]; static BYTE PredictionActorBackup[sizeof(AActor)];
static TArray<sector_t *> PredictionTouchingSectorsBackup; static TArray<sector_t *> PredictionTouchingSectorsBackup;
@ -2722,8 +2723,12 @@ void P_PredictPlayer (player_t *player)
} }
act->BlockNode = NULL; act->BlockNode = NULL;
bool NoInterpolateOld = R_GetViewInterpolationStatus();
for (int i = gametic; i < maxtic; ++i) for (int i = gametic; i < maxtic; ++i)
{ {
if (!NoInterpolateOld)
R_RebuildViewInterpolation(player);
player->cmd = localcmds[i % LOCALCMDTICS]; player->cmd = localcmds[i % LOCALCMDTICS];
P_PlayerThink (player); P_PlayerThink (player);
player->mo->Tick (); player->mo->Tick ();

View file

@ -729,6 +729,42 @@ void R_ClearPastViewer (AActor *actor)
} }
} }
//==========================================================================
//
// R_RebuildViewInterpolation
//
//==========================================================================
void R_RebuildViewInterpolation(player_t *player)
{
if (player == NULL || player->camera == NULL)
return;
if (!NoInterpolateView)
return;
NoInterpolateView = false;
InterpolationViewer *iview = FindPastViewer(player->camera);
iview->oviewx = iview->nviewx;
iview->oviewy = iview->nviewy;
iview->oviewz = iview->nviewz;
iview->oviewpitch = iview->nviewpitch;
iview->oviewangle = iview->nviewangle;
}
//==========================================================================
//
// R_GetViewInterpolationStatus
//
//==========================================================================
bool R_GetViewInterpolationStatus()
{
return NoInterpolateView;
}
//========================================================================== //==========================================================================
// //
// R_SetupFrame // R_SetupFrame

View file

@ -61,6 +61,8 @@ inline angle_t R_PointToAngle (fixed_t x, fixed_t y) { return R_PointToAngle2 (v
subsector_t *R_PointInSubsector (fixed_t x, fixed_t y); subsector_t *R_PointInSubsector (fixed_t x, fixed_t y);
fixed_t R_PointToDist2 (fixed_t dx, fixed_t dy); fixed_t R_PointToDist2 (fixed_t dx, fixed_t dy);
void R_ResetViewInterpolation (); void R_ResetViewInterpolation ();
void R_RebuildViewInterpolation(player_t *player);
bool R_GetViewInterpolationStatus();
void R_SetViewSize (int blocks); void R_SetViewSize (int blocks);
void R_SetFOV (float fov); void R_SetFOV (float fov);
float R_GetFOV (); float R_GetFOV ();

View file

@ -2347,14 +2347,14 @@ class AMusicChanger : public ASectorAction
{ {
DECLARE_CLASS (AMusicChanger, ASectorAction) DECLARE_CLASS (AMusicChanger, ASectorAction)
public: public:
virtual bool TriggerAction (AActor *triggerer, int activationType); virtual bool DoTriggerAction (AActor *triggerer, int activationType);
virtual void Tick(); virtual void Tick();
virtual void PostBeginPlay(); virtual void PostBeginPlay();
}; };
IMPLEMENT_CLASS(AMusicChanger) IMPLEMENT_CLASS(AMusicChanger)
bool AMusicChanger::TriggerAction (AActor *triggerer, int activationType) bool AMusicChanger::DoTriggerAction (AActor *triggerer, int activationType)
{ {
if (activationType & SECSPAC_Enter) if (activationType & SECSPAC_Enter)
{ {
@ -2364,7 +2364,7 @@ bool AMusicChanger::TriggerAction (AActor *triggerer, int activationType)
reactiontime = 30; reactiontime = 30;
} }
} }
return Super::TriggerAction (triggerer, activationType); return Super::DoTriggerAction (triggerer, activationType);
} }
void AMusicChanger::Tick() void AMusicChanger::Tick()

File diff suppressed because it is too large Load diff

View file

@ -88,6 +88,7 @@ DEFINE_MEMBER_VARIABLE(height, AActor)
DEFINE_MEMBER_VARIABLE(radius, AActor) DEFINE_MEMBER_VARIABLE(radius, AActor)
DEFINE_MEMBER_VARIABLE(reactiontime, AActor) DEFINE_MEMBER_VARIABLE(reactiontime, AActor)
DEFINE_MEMBER_VARIABLE(meleerange, AActor) DEFINE_MEMBER_VARIABLE(meleerange, AActor)
DEFINE_MEMBER_VARIABLE(Speed, AActor)
//========================================================================== //==========================================================================

View file

@ -43,6 +43,8 @@
#include "tarray.h" #include "tarray.h"
#include "thingdef.h" #include "thingdef.h"
#include "thingdef_exp.h" #include "thingdef_exp.h"
#include "actor.h"
#include "actorptrselect.h"
static TMap<FName, FxGlobalFunctionCall::Creator> CreatorMap; static TMap<FName, FxGlobalFunctionCall::Creator> CreatorMap;
@ -185,3 +187,110 @@ public:
GLOBALFUNCTION_ADDER(Sqrt); GLOBALFUNCTION_ADDER(Sqrt);
//==========================================================================
//
// Function: checkclass
//
//==========================================================================
class FxGlobalFunctionCall_CheckClass : public FxGlobalFunctionCall
{
public:
GLOBALFUNCTION_DEFINE(CheckClass);
FxExpression *Resolve(FCompileContext& ctx)
{
CHECKRESOLVED();
if (!ResolveArgs(ctx, 1, 3, false))
return NULL;
for (int i = ArgList->Size(); i > 1;)
{
if (!(*ArgList)[--i]->ValueType.isNumeric())
{
ScriptPosition.Message(MSG_ERROR, "numeric value expected for parameter");
delete this;
return NULL;
}
}
switch ((*ArgList)[0]->ValueType.Type)
{
case VAL_Class: case VAL_Name:break;
default:
ScriptPosition.Message(MSG_ERROR, "actor class expected for parameter");
delete this;
return NULL;
}
ValueType = VAL_Float;
return this;
}
ExpVal EvalExpression(AActor *self)
{
ExpVal ret;
ret.Type = VAL_Int;
const PClass * checkclass;
{
ExpVal v = (*ArgList)[0]->EvalExpression(self);
checkclass = v.GetClass();
if (!checkclass)
{
checkclass = PClass::FindClass(v.GetName());
if (!checkclass) { ret.Int = 0; return ret; }
}
}
bool match_superclass = false;
int pick_pointer = AAPTR_DEFAULT;
switch (ArgList->Size())
{
case 3: match_superclass = (*ArgList)[2]->EvalExpression(self).GetBool();
case 2: pick_pointer = (*ArgList)[1]->EvalExpression(self).GetInt();
}
self = COPY_AAPTR(self, pick_pointer);
if (!self){ ret.Int = 0; return ret; }
ret.Int = match_superclass ? checkclass->IsAncestorOf(self->GetClass()) : checkclass == self->GetClass();
return ret;
}
};
GLOBALFUNCTION_ADDER(CheckClass);
//==========================================================================
//
// Function: ispointerequal
//
//==========================================================================
class FxGlobalFunctionCall_IsPointerEqual : public FxGlobalFunctionCall
{
public:
GLOBALFUNCTION_DEFINE(IsPointerEqual);
FxExpression *Resolve(FCompileContext& ctx)
{
CHECKRESOLVED();
if (!ResolveArgs(ctx, 2, 2, true))
return NULL;
ValueType = VAL_Int;
return this;
}
ExpVal EvalExpression(AActor *self)
{
ExpVal ret;
ret.Type = VAL_Int;
ret.Int = COPY_AAPTR(self, (*ArgList)[0]->EvalExpression(self).GetInt()) == COPY_AAPTR(self, (*ArgList)[1]->EvalExpression(self).GetInt());
return ret;
}
};
GLOBALFUNCTION_ADDER(IsPointerEqual);

View file

@ -374,6 +374,8 @@ static void ParseUserVariable (FScanner &sc, PSymbolTable *symt, PClass *cls)
FScriptPosition::ErrorCounter++; FScriptPosition::ErrorCounter++;
} }
FName symname = sc.String; FName symname = sc.String;
if (sc.CheckToken('[')) if (sc.CheckToken('['))
{ {
@ -391,6 +393,15 @@ static void ParseUserVariable (FScanner &sc, PSymbolTable *symt, PClass *cls)
} }
sc.MustGetToken(';'); sc.MustGetToken(';');
// We must ensure that we do not define duplicates, even when they come from a parent table.
if (symt->FindSymbol(symname, true) != NULL)
{
sc.ScriptMessage ("'%s' is already defined in '%s' or one of its ancestors.",
symname.GetChars(), cls ? cls->TypeName.GetChars() : "Global");
FScriptPosition::ErrorCounter++;
return;
}
PSymbolVariable *sym = new PSymbolVariable(symname); PSymbolVariable *sym = new PSymbolVariable(symname);
sym->offset = cls->Extend(sizeof(int) * (valuetype.Type == VAL_Array ? valuetype.size : 1)); sym->offset = cls->Extend(sizeof(int) * (valuetype.Type == VAL_Array ? valuetype.size : 1));
sym->ValueType = valuetype; sym->ValueType = valuetype;

View file

@ -51,7 +51,7 @@ const char *GetVersionString();
// Version identifier for network games. // Version identifier for network games.
// Bump it every time you do a release unless you're certain you // Bump it every time you do a release unless you're certain you
// didn't change anything that will affect sync. // didn't change anything that will affect sync.
#define NETGAMEVERSION 230 #define NETGAMEVERSION 231
// Version stored in the ini's [LastRun] section. // Version stored in the ini's [LastRun] section.
// Bump it if you made some configuration change that you want to // Bump it if you made some configuration change that you want to

View file

@ -62,6 +62,7 @@ ACTOR Actor native //: Thinker
native fixed_t radius; native fixed_t radius;
native int reactiontime; native int reactiontime;
native fixed_t meleerange; native fixed_t meleerange;
native fixed_t speed;
// Meh, MBF redundant functions. Only for DeHackEd support. // Meh, MBF redundant functions. Only for DeHackEd support.
action native A_Turn(float angle = 0); action native A_Turn(float angle = 0);
@ -69,7 +70,7 @@ ACTOR Actor native //: Thinker
// End of MBF redundant functions. // End of MBF redundant functions.
action native A_MonsterRail(); action native A_MonsterRail();
action native A_BFGSpray(class<Actor> spraytype = "BFGExtra", int numrays = 40, int damagecount = 15); action native A_BFGSpray(class<Actor> spraytype = "BFGExtra", int numrays = 40, int damagecount = 15, float angle = 90, float distance = 16*64, float vrange = 32, int damage = 0);
action native A_Pain(); action native A_Pain();
action native A_NoBlocking(); action native A_NoBlocking();
action native A_XScream(); action native A_XScream();
@ -203,7 +204,7 @@ ACTOR Actor native //: Thinker
action native A_CustomMissile(class<Actor> missiletype, float spawnheight = 32, int spawnofs_xy = 0, float angle = 0, int flags = 0, float pitch = 0); action native A_CustomMissile(class<Actor> missiletype, float spawnheight = 32, int spawnofs_xy = 0, float angle = 0, int flags = 0, float pitch = 0);
action native A_CustomBulletAttack(float spread_xy, float spread_z, int numbullets, int damageperbullet, class<Actor> pufftype = "BulletPuff", float range = 0, int flags = 0); action native A_CustomBulletAttack(float spread_xy, float spread_z, int numbullets, int damageperbullet, class<Actor> pufftype = "BulletPuff", float range = 0, int flags = 0);
action native A_CustomRailgun(int damage, int spawnofs_xy = 0, color color1 = "", color color2 = "", int flags = 0, bool aim = false, float maxdiff = 0, class<Actor> pufftype = "BulletPuff", float spread_xy = 0, float spread_z = 0, float range = 0, int duration = 0, float sparsity = 1.0, float driftspeed = 1.0, class<Actor> spawnclass = "none", float spawnofs_z = 0); action native A_CustomRailgun(int damage, int spawnofs_xy = 0, color color1 = "", color color2 = "", int flags = 0, bool aim = false, float maxdiff = 0, class<Actor> pufftype = "BulletPuff", float spread_xy = 0, float spread_z = 0, float range = 0, int duration = 0, float sparsity = 1.0, float driftspeed = 1.0, class<Actor> spawnclass = "none", float spawnofs_z = 0);
action native A_JumpIfHealthLower(int health, state label); action native A_JumpIfHealthLower(int health, state label, int ptr_selector = AAPTR_DEFAULT);
action native A_JumpIfCloser(float distance, state label); action native A_JumpIfCloser(float distance, state label);
action native A_JumpIfTracerCloser(float distance, state label); action native A_JumpIfTracerCloser(float distance, state label);
action native A_JumpIfMasterCloser(float distance, state label); action native A_JumpIfMasterCloser(float distance, state label);
@ -233,12 +234,12 @@ ACTOR Actor native //: Thinker
action native A_ChangeFlag(string flagname, bool value); action native A_ChangeFlag(string flagname, bool value);
action native A_CheckFlag(string flagname, state label, int check_pointer = AAPTR_DEFAULT); action native A_CheckFlag(string flagname, state label, int check_pointer = AAPTR_DEFAULT);
action native A_JumpIf(bool expression, state label); action native A_JumpIf(bool expression, state label);
action native A_RemoveMaster(); action native A_RemoveMaster(int flags = 0);
action native A_RemoveChildren(bool removeall = false); action native A_RemoveChildren(bool removeall = false, int flags = 0);
action native A_RemoveSiblings(bool removeall = false); action native A_RemoveSiblings(bool removeall = false, int flags = 0);
action native A_KillMaster(name damagetype = "none"); action native A_KillMaster(name damagetype = "none", int flags = 0);
action native A_KillChildren(name damagetype = "none"); action native A_KillChildren(name damagetype = "none", int flags = 0);
action native A_KillSiblings(name damagetype = "none"); action native A_KillSiblings(name damagetype = "none", int flags = 0);
action native A_RaiseMaster(); action native A_RaiseMaster();
action native A_RaiseChildren(); action native A_RaiseChildren();
action native A_RaiseSiblings(); action native A_RaiseSiblings();
@ -274,9 +275,9 @@ ACTOR Actor native //: Thinker
action native A_CheckLOF(state jump, int flags = 0, float range = 0, float minrange = 0, float angle = 0, float pitch = 0, float offsetheight = 0, float offsetwidth = 0, int ptr_target = AAPTR_DEFAULT); action native A_CheckLOF(state jump, int flags = 0, float range = 0, float minrange = 0, float angle = 0, float pitch = 0, float offsetheight = 0, float offsetwidth = 0, int ptr_target = AAPTR_DEFAULT);
action native A_JumpIfTargetInLOS (state label, float fov = 0, int flags = 0, float dist_max = 0, float dist_close = 0); action native A_JumpIfTargetInLOS (state label, float fov = 0, int flags = 0, float dist_max = 0, float dist_close = 0);
action native A_JumpIfInTargetLOS (state label, float fov = 0, int flags = 0, float dist_max = 0, float dist_close = 0); action native A_JumpIfInTargetLOS (state label, float fov = 0, int flags = 0, float dist_max = 0, float dist_close = 0);
action native A_DamageMaster(int amount, name damagetype = "none"); action native A_DamageMaster(int amount, name damagetype = "none", int flags = 0);
action native A_DamageChildren(int amount, name damagetype = "none"); action native A_DamageChildren(int amount, name damagetype = "none", int flags = 0);
action native A_DamageSiblings(int amount, name damagetype = "none"); action native A_DamageSiblings(int amount, name damagetype = "none", int flags = 0);
action native A_SelectWeapon(class<Weapon> whichweapon); action native A_SelectWeapon(class<Weapon> whichweapon);
action native A_Punch(); action native A_Punch();
action native A_Feathers(); action native A_Feathers();
@ -302,6 +303,15 @@ ACTOR Actor native //: Thinker
action native A_SetTics(int tics); action native A_SetTics(int tics);
action native A_SetDamageType(name damagetype); action native A_SetDamageType(name damagetype);
action native A_DropItem(class<Actor> item, int dropamount = -1, int chance = 256); action native A_DropItem(class<Actor> item, int dropamount = -1, int chance = 256);
action native A_SetSpeed(float speed);
action native A_DamageSelf(int amount, name damagetype = "none", int flags = 0);
action native A_DamageTarget(int amount, name damagetype = "none", int flags = 0);
action native A_DamageTracer(int amount, name damagetype = "none", int flags = 0);
action native A_KillTarget(name damagetype = "none", int flags = 0);
action native A_KillTracer(name damagetype = "none", int flags = 0);
action native A_RemoveTarget(int flags = 0);
action native A_RemoveTracer(int flags = 0);
action native A_Remove(int removee, int flags = 0);
action native A_CheckSightOrRange(float distance, state label); action native A_CheckSightOrRange(float distance, state label);
action native A_CheckRange(float distance, state label); action native A_CheckRange(float distance, state label);

View file

@ -1,371 +1,401 @@
// Flags for A_PainAttack // Flags for A_PainAttack
const int PAF_NOSKULLATTACK = 1; const int PAF_NOSKULLATTACK = 1;
const int PAF_AIMFACING = 2; const int PAF_AIMFACING = 2;
const int PAF_NOTARGET = 4; const int PAF_NOTARGET = 4;
// Flags for A_VileAttack // Flags for A_VileAttack
const int VAF_DMGTYPEAPPLYTODIRECT = 1; const int VAF_DMGTYPEAPPLYTODIRECT = 1;
// Flags for A_Saw // Flags for A_Saw
const int SF_NORANDOM = 1; const int SF_NORANDOM = 1;
const int SF_RANDOMLIGHTMISS = 2; const int SF_RANDOMLIGHTMISS = 2;
const int SF_RANDOMLIGHTHIT = 4; const int SF_RANDOMLIGHTHIT = 4;
const int SF_RANDOMLIGHTBOTH = 6; const int SF_RANDOMLIGHTBOTH = 6;
const int SF_NOUSEAMMOMISS = 8; const int SF_NOUSEAMMOMISS = 8;
const int SF_NOUSEAMMO = 16; const int SF_NOUSEAMMO = 16;
const int SF_NOPULLIN = 32; const int SF_NOPULLIN = 32;
const int SF_NOTURN = 64; const int SF_NOTURN = 64;
// Flags for A_CustomMissile // Flags for A_CustomMissile
const int CMF_AIMOFFSET = 1; const int CMF_AIMOFFSET = 1;
const int CMF_AIMDIRECTION = 2; const int CMF_AIMDIRECTION = 2;
const int CMF_TRACKOWNER = 4; const int CMF_TRACKOWNER = 4;
const int CMF_CHECKTARGETDEAD = 8; const int CMF_CHECKTARGETDEAD = 8;
const int CMF_ABSOLUTEPITCH = 16; const int CMF_ABSOLUTEPITCH = 16;
const int CMF_OFFSETPITCH = 32; const int CMF_OFFSETPITCH = 32;
const int CMF_SAVEPITCH = 64; const int CMF_SAVEPITCH = 64;
const int CMF_ABSOLUTEANGLE = 128; const int CMF_ABSOLUTEANGLE = 128;
// Flags for A_CustomBulletAttack // Flags for A_CustomBulletAttack
const int CBAF_AIMFACING = 1; const int CBAF_AIMFACING = 1;
const int CBAF_NORANDOM = 2; const int CBAF_NORANDOM = 2;
const int CBAF_EXPLICITANGLE = 4; const int CBAF_EXPLICITANGLE = 4;
const int CBAF_NOPITCH = 8; const int CBAF_NOPITCH = 8;
const int CBAF_NORANDOMPUFFZ = 16; const int CBAF_NORANDOMPUFFZ = 16;
// Flags for A_GunFlash // Flags for A_GunFlash
const int GFF_NOEXTCHANGE = 1; const int GFF_NOEXTCHANGE = 1;
// Flags for A_FireBullets // Flags for A_FireBullets
const int FBF_USEAMMO = 1; const int FBF_USEAMMO = 1;
const int FBF_NORANDOM = 2; const int FBF_NORANDOM = 2;
const int FBF_EXPLICITANGLE = 4; const int FBF_EXPLICITANGLE = 4;
const int FBF_NOPITCH = 8; const int FBF_NOPITCH = 8;
const int FBF_NOFLASH = 16; const int FBF_NOFLASH = 16;
const int FBF_NORANDOMPUFFZ = 32; const int FBF_NORANDOMPUFFZ = 32;
// Flags for A_SpawnItemEx // Flags for A_SpawnItemEx
const int SXF_TRANSFERTRANSLATION = 1; const int SXF_TRANSFERTRANSLATION = 1 << 0;
const int SXF_ABSOLUTEPOSITION = 2; const int SXF_ABSOLUTEPOSITION = 1 << 1;
const int SXF_ABSOLUTEANGLE = 4; const int SXF_ABSOLUTEANGLE = 1 << 2;
const int SXF_ABSOLUTEMOMENTUM = 8; const int SXF_ABSOLUTEMOMENTUM = 1 << 3; //Since "momentum" is declared to be deprecated in the expressions, for compatibility
const int SXF_ABSOLUTEVELOCITY = 8; const int SXF_ABSOLUTEVELOCITY = 1 << 3; //purposes, this was made. It does the same thing though. Do not change the value.
const int SXF_SETMASTER = 16; const int SXF_SETMASTER = 1 << 4;
const int SXF_NOCHECKPOSITION = 32; const int SXF_NOCHECKPOSITION = 1 << 5;
const int SXF_TELEFRAG = 64; const int SXF_TELEFRAG = 1 << 6;
const int SXF_CLIENTSIDE = 128; // only used by Skulltag const int SXF_CLIENTSIDE = 1 << 7; // only used by Skulltag
const int SXF_TRANSFERAMBUSHFLAG = 256; const int SXF_TRANSFERAMBUSHFLAG = 1 << 8;
const int SXF_TRANSFERPITCH = 512; const int SXF_TRANSFERPITCH = 1 << 9;
const int SXF_TRANSFERPOINTERS = 1024; const int SXF_TRANSFERPOINTERS = 1 << 10;
const int SXF_USEBLOODCOLOR = 2048; const int SXF_USEBLOODCOLOR = 1 << 11;
const int SXF_CLEARCALLERTID = 4096; const int SXF_CLEARCALLERTID = 1 << 12;
const int SXF_MULTIPLYSPEED = 8192; const int SXF_MULTIPLYSPEED = 1 << 13;
const int SXF_TRANSFERSCALE = 16384; const int SXF_TRANSFERSCALE = 1 << 14;
const int SXF_TRANSFERSPECIAL = 32768; const int SXF_TRANSFERSPECIAL = 1 << 15;
const int SXF_CLEARCALLERSPECIAL = 65536; const int SXF_CLEARCALLERSPECIAL = 1 << 16;
const int SXF_TRANSFERSTENCILCOL = 131072; const int SXF_TRANSFERSTENCILCOL = 1 << 17;
const int SXF_TRANSFERALPHA = 262144; const int SXF_TRANSFERALPHA = 1 << 18;
const int SXF_TRANSFERRENDERSTYLE = 524288; const int SXF_TRANSFERRENDERSTYLE = 1 << 19;
const int SXF_SETTARGET = 1 << 20;
// Flags for A_Chase const int SXF_SETTRACER = 1 << 21;
const int CHF_FASTCHASE = 1; const int SXF_NOPOINTERS = 1 << 22;
const int CHF_NOPLAYACTIVE = 2; const int SXF_ORIGINATOR = 1 << 23;
const int CHF_NIGHTMAREFAST = 4;
const int CHF_RESURRECT = 8; // Flags for A_Chase
const int CHF_DONTMOVE = 16; const int CHF_FASTCHASE = 1;
const int CHF_NOPLAYACTIVE = 2;
// Flags for A_LookEx const int CHF_NIGHTMAREFAST = 4;
const int LOF_NOSIGHTCHECK = 1; const int CHF_RESURRECT = 8;
const int LOF_NOSOUNDCHECK = 2; const int CHF_DONTMOVE = 16;
const int LOF_DONTCHASEGOAL = 4;
const int LOF_NOSEESOUND = 8; // Flags for A_LookEx
const int LOF_FULLVOLSEESOUND = 16; const int LOF_NOSIGHTCHECK = 1;
const int LOF_NOJUMP = 32; const int LOF_NOSOUNDCHECK = 2;
const int LOF_DONTCHASEGOAL = 4;
// Flags for A_Respawn const int LOF_NOSEESOUND = 8;
const int RSF_FOG = 1; const int LOF_FULLVOLSEESOUND = 16;
const int RSF_KEEPTARGET = 2; const int LOF_NOJUMP = 32;
const int RSF_TELEFRAG = 4;
// Flags for A_Respawn
// Flags for A_JumpIfTargetInLOS and A_JumpIfInTargetLOS const int RSF_FOG = 1;
const int JLOSF_PROJECTILE = 1; const int RSF_KEEPTARGET = 2;
const int JLOSF_NOSIGHT = 2; const int RSF_TELEFRAG = 4;
const int JLOSF_CLOSENOFOV = 4;
const int JLOSF_CLOSENOSIGHT = 8; // Flags for A_JumpIfTargetInLOS and A_JumpIfInTargetLOS
const int JLOSF_CLOSENOJUMP = 16; enum
const int JLOSF_DEADNOJUMP = 32; {
const int JLOSF_CHECKMASTER = 64; JLOSF_PROJECTILE = 1,
const int JLOSF_TARGETLOS = 128; JLOSF_NOSIGHT = 1 << 1,
const int JLOSF_FLIPFOV = 256; JLOSF_CLOSENOFOV = 1 << 2,
const int JLOSF_ALLYNOJUMP = 512; JLOSF_CLOSENOSIGHT = 1 << 3,
const int JLOSF_COMBATANTONLY = 1024; JLOSF_CLOSENOJUMP = 1 << 4,
const int JLOSF_NOAUTOAIM = 2048; JLOSF_DEADNOJUMP = 1 << 5,
JLOSF_CHECKMASTER = 1 << 6,
// Flags for A_ChangeVelocity JLOSF_TARGETLOS = 1 << 7,
const int CVF_RELATIVE = 1; JLOSF_FLIPFOV = 1 << 8,
const int CVF_REPLACE = 2; JLOSF_ALLYNOJUMP = 1 << 9,
JLOSF_COMBATANTONLY = 1 << 10,
// Flags for A_WeaponReady JLOSF_NOAUTOAIM = 1 << 11,
const int WRF_NOBOB = 1; JLOSF_CHECKTRACER = 1 << 12,
const int WRF_NOSWITCH = 2; };
const int WRF_NOPRIMARY = 4;
const int WRF_NOSECONDARY = 8; // Flags for A_ChangeVelocity
const int WRF_NOFIRE = WRF_NOPRIMARY | WRF_NOSECONDARY; const int CVF_RELATIVE = 1;
const int WRF_ALLOWRELOAD = 16; const int CVF_REPLACE = 2;
const int WRF_ALLOWZOOM = 32;
const int WRF_DISABLESWITCH = 64; // Flags for A_WeaponReady
const int WRF_NOBOB = 1;
// Morph constants const int WRF_NOSWITCH = 2;
const int MRF_ADDSTAMINA = 1; const int WRF_NOPRIMARY = 4;
const int MRF_FULLHEALTH = 2; const int WRF_NOSECONDARY = 8;
const int MRF_UNDOBYTOMEOFPOWER = 4; const int WRF_NOFIRE = WRF_NOPRIMARY | WRF_NOSECONDARY;
const int MRF_UNDOBYCHAOSDEVICE = 8; const int WRF_ALLOWRELOAD = 16;
const int MRF_FAILNOTELEFRAG = 16; const int WRF_ALLOWZOOM = 32;
const int MRF_FAILNOLAUGH = 32; const int WRF_DISABLESWITCH = 64;
const int MRF_WHENINVULNERABLE = 64;
const int MRF_LOSEACTUALWEAPON = 128; // Morph constants
const int MRF_NEWTIDBEHAVIOUR = 256; const int MRF_ADDSTAMINA = 1;
const int MRF_UNDOBYDEATH = 512; const int MRF_FULLHEALTH = 2;
const int MRF_UNDOBYDEATHFORCED = 1024; const int MRF_UNDOBYTOMEOFPOWER = 4;
const int MRF_UNDOBYDEATHSAVES = 2048; const int MRF_UNDOBYCHAOSDEVICE = 8;
const int MRF_FAILNOTELEFRAG = 16;
// Flags for A_RailAttack and A_CustomRailgun const int MRF_FAILNOLAUGH = 32;
const int RGF_SILENT = 1; const int MRF_WHENINVULNERABLE = 64;
const int RGF_NOPIERCING = 2; const int MRF_LOSEACTUALWEAPON = 128;
const int RGF_EXPLICITANGLE = 4; const int MRF_NEWTIDBEHAVIOUR = 256;
const int RGF_FULLBRIGHT = 8; const int MRF_UNDOBYDEATH = 512;
const int RGF_CENTERZ = 16; const int MRF_UNDOBYDEATHFORCED = 1024;
const int MRF_UNDOBYDEATHSAVES = 2048;
// Flags for A_Mushroom
const int MSF_Standard = 0; // Flags for A_RailAttack and A_CustomRailgun
const int MSF_Classic = 1; const int RGF_SILENT = 1;
const int MSF_DontHurt = 2; const int RGF_NOPIERCING = 2;
const int RGF_EXPLICITANGLE = 4;
// Flags for A_Explode const int RGF_FULLBRIGHT = 8;
const int XF_HURTSOURCE = 1; const int RGF_CENTERZ = 16;
const int XF_NOTMISSILE = 4;
// Flags for A_Mushroom
// Flags for A_RadiusThrust const int MSF_Standard = 0;
const int RTF_AFFECTSOURCE = 1; const int MSF_Classic = 1;
const int RTF_NOIMPACTDAMAGE = 2; const int MSF_DontHurt = 2;
const int RTF_NOTMISSILE = 4;
// Flags for A_Explode
// Flags for A_Blast const int XF_HURTSOURCE = 1;
const int BF_USEAMMO = 1; const int XF_NOTMISSILE = 4;
const int BF_DONTWARN = 2;
const int BF_AFFECTBOSSES = 4; // Flags for A_RadiusThrust
const int BF_NOIMPACTDAMAGE = 8; const int RTF_AFFECTSOURCE = 1;
const int RTF_NOIMPACTDAMAGE = 2;
// Flags for A_SeekerMissile const int RTF_NOTMISSILE = 4;
const int SMF_LOOK = 1;
const int SMF_PRECISE = 2; // Flags for A_Blast
const int SMF_CURSPEED = 4; const int BF_USEAMMO = 1;
const int BF_DONTWARN = 2;
// Flags for A_CustomPunch const int BF_AFFECTBOSSES = 4;
const int CPF_USEAMMO = 1; const int BF_NOIMPACTDAMAGE = 8;
const int CPF_DAGGER = 2;
const int CPF_PULLIN = 4; // Flags for A_SeekerMissile
const int CPF_NORANDOMPUFFZ = 8; const int SMF_LOOK = 1;
const int SMF_PRECISE = 2;
// Flags for A_CustomMissile const int SMF_CURSPEED = 4;
const int FPF_AIMATANGLE = 1;
const int FPF_TRANSFERTRANSLATION = 2; // Flags for A_CustomPunch
const int CPF_USEAMMO = 1;
// Flags for A_Teleport const int CPF_DAGGER = 2;
const int TF_TELEFRAG = 1;const int TF_RANDOMDECIDE = 2; const int CPF_PULLIN = 4;
const int CPF_NORANDOMPUFFZ = 8;
// Flags for A_WolfAttack
const int WAF_NORANDOM = 1; // Flags for A_CustomMissile
const int WAF_USEPUFF = 2; const int FPF_AIMATANGLE = 1;
const int FPF_TRANSFERTRANSLATION = 2;
// Flags for A_RadiusGive
enum // Flags for A_Teleport
{ const int TF_TELEFRAG = 1;const int TF_RANDOMDECIDE = 2;
RGF_GIVESELF = 1,
RGF_PLAYERS = 2, // Flags for A_WolfAttack
RGF_MONSTERS = 4, const int WAF_NORANDOM = 1;
RGF_OBJECTS = 8, const int WAF_USEPUFF = 2;
RGF_VOODOO = 16,
RGF_CORPSES = 32, // Flags for A_RadiusGive
RGF_NOTARGET = 64, enum
RGF_NOTRACER = 128, {
RGF_NOMASTER = 256, RGF_GIVESELF = 1,
RGF_CUBE = 512, RGF_PLAYERS = 2,
}; RGF_MONSTERS = 4,
RGF_OBJECTS = 8,
// Activation flags RGF_VOODOO = 16,
enum RGF_CORPSES = 32,
{ RGF_NOTARGET = 64,
THINGSPEC_Default = 0, RGF_NOTRACER = 128,
THINGSPEC_ThingActs = 1, RGF_NOMASTER = 256,
THINGSPEC_ThingTargets = 2, RGF_CUBE = 512,
THINGSPEC_TriggerTargets = 4, };
THINGSPEC_MonsterTrigger = 8,
THINGSPEC_MissileTrigger = 16, // Activation flags
THINGSPEC_ClearSpecial = 32, enum
THINGSPEC_NoDeathSpecial = 64, {
THINGSPEC_TriggerActs = 128, THINGSPEC_Default = 0,
}; THINGSPEC_ThingActs = 1,
// Shorter aliases for same THINGSPEC_ThingTargets = 2,
const int AF_Default = 0; THINGSPEC_TriggerTargets = 4,
const int AF_ThingActs = 1; THINGSPEC_MonsterTrigger = 8,
const int AF_ThingTargets = 2; THINGSPEC_MissileTrigger = 16,
const int AF_TriggerTargets = 4; THINGSPEC_ClearSpecial = 32,
const int AF_MonsterTrigger = 8; THINGSPEC_NoDeathSpecial = 64,
const int AF_MissileTrigger = 16; THINGSPEC_TriggerActs = 128,
const int AF_ClearSpecial = 32; };
const int AF_NoDeathSpecial = 64; // Shorter aliases for same
const int AF_TriggerActs = 128; const int AF_Default = 0;
const int AF_ThingActs = 1;
// Flags for A_TakeInventory and A_TakeFromTarget const int AF_ThingTargets = 2;
const int TIF_NOTAKEINFINITE = 1; const int AF_TriggerTargets = 4;
const int AF_MonsterTrigger = 8;
// constants for A_PlaySound const int AF_MissileTrigger = 16;
enum const int AF_ClearSpecial = 32;
{ const int AF_NoDeathSpecial = 64;
CHAN_AUTO = 0, const int AF_TriggerActs = 128;
CHAN_WEAPON = 1,
CHAN_VOICE = 2, // Flags for A_TakeInventory and A_TakeFromTarget
CHAN_ITEM = 3, const int TIF_NOTAKEINFINITE = 1;
CHAN_BODY = 4,
CHAN_5 = 5, // constants for A_PlaySound
CHAN_6 = 6, enum
CHAN_7 = 7, {
CHAN_AUTO = 0,
// modifier flags CHAN_WEAPON = 1,
CHAN_LISTENERZ = 8, CHAN_VOICE = 2,
CHAN_MAYBE_LOCAL = 16, CHAN_ITEM = 3,
CHAN_UI = 32, CHAN_BODY = 4,
CHAN_NOPAUSE = 64 CHAN_5 = 5,
}; CHAN_6 = 6,
CHAN_7 = 7,
// sound attenuation values
const float ATTN_NONE = 0; // modifier flags
const float ATTN_NORM = 1; CHAN_LISTENERZ = 8,
const float ATTN_IDLE = 1.001; CHAN_MAYBE_LOCAL = 16,
const float ATTN_STATIC = 3; CHAN_UI = 32,
CHAN_NOPAUSE = 64
// For SetPlayerProprty action special };
Const Int PROP_FROZEN = 0;
Const Int PROP_NOTARGET = 1; // sound attenuation values
Const Int PROP_INSTANTWEAPONSWITCH = 2; const float ATTN_NONE = 0;
Const Int PROP_FLY = 3; const float ATTN_NORM = 1;
Const Int PROP_TOTALLYFROZEN = 4; const float ATTN_IDLE = 1.001;
Const Int PROP_INVULNERABILITY = 5; // (Deprecated) const float ATTN_STATIC = 3;
Const Int PROP_STRENGTH = 6; // (Deprecated)
Const Int PROP_INVISIBILITY = 7; // (Deprecated) // For SetPlayerProprty action special
Const Int PROP_RADIATIONSUIT = 8; // (Deprecated) Const Int PROP_FROZEN = 0;
Const Int PROP_ALLMAP = 9; // (Deprecated) Const Int PROP_NOTARGET = 1;
Const Int PROP_INFRARED = 10; // (Deprecated) Const Int PROP_INSTANTWEAPONSWITCH = 2;
Const Int PROP_WEAPONLEVEL2 = 11; // (Deprecated) Const Int PROP_FLY = 3;
Const Int PROP_FLIGHT = 12; // (Deprecated) Const Int PROP_TOTALLYFROZEN = 4;
Const Int PROP_SPEED = 15; // (Deprecated) Const Int PROP_INVULNERABILITY = 5; // (Deprecated)
Const Int PROP_BUDDHA = 16; Const Int PROP_STRENGTH = 6; // (Deprecated)
Const Int PROP_INVISIBILITY = 7; // (Deprecated)
// Line_SetBlocking Const Int PROP_RADIATIONSUIT = 8; // (Deprecated)
Const Int BLOCKF_CREATURES = 1; Const Int PROP_ALLMAP = 9; // (Deprecated)
Const Int BLOCKF_MONSTERS = 2; Const Int PROP_INFRARED = 10; // (Deprecated)
Const Int BLOCKF_PLAYERS = 4; Const Int PROP_WEAPONLEVEL2 = 11; // (Deprecated)
Const Int BLOCKF_FLOATERS = 8; Const Int PROP_FLIGHT = 12; // (Deprecated)
Const Int BLOCKF_PROJECTILES = 16; Const Int PROP_SPEED = 15; // (Deprecated)
Const Int BLOCKF_EVERYTHING = 32; Const Int PROP_BUDDHA = 16;
Const Int BLOCKF_RAILING = 64;
Const Int BLOCKF_USE = 128; // Line_SetBlocking
Const Int BLOCKF_CREATURES = 1;
// Pointer constants, bitfield-enabled Const Int BLOCKF_MONSTERS = 2;
Const Int BLOCKF_PLAYERS = 4;
Const Int AAPTR_DEFAULT = 0; Const Int BLOCKF_FLOATERS = 8;
Const Int AAPTR_NULL = 1; Const Int BLOCKF_PROJECTILES = 16;
Const Int AAPTR_TARGET = 2; Const Int BLOCKF_EVERYTHING = 32;
Const Int AAPTR_MASTER = 4; Const Int BLOCKF_RAILING = 64;
Const Int AAPTR_TRACER = 8; Const Int BLOCKF_USE = 128;
Const Int AAPTR_PLAYER_GETTARGET = 16; // Pointer constants, bitfield-enabled
Const Int AAPTR_PLAYER_GETCONVERSATION = 32;
Const Int AAPTR_DEFAULT = 0;
Const Int AAPTR_PLAYER1 = 64; Const Int AAPTR_NULL = 0x1;
Const Int AAPTR_PLAYER2 = 128; Const Int AAPTR_TARGET = 0x2;
Const Int AAPTR_PLAYER3 = 256; Const Int AAPTR_MASTER = 0x4;
Const Int AAPTR_PLAYER4 = 512; Const Int AAPTR_TRACER = 0x8;
Const Int AAPTR_PLAYER5 = 1024;
Const Int AAPTR_PLAYER6 = 2048; Const Int AAPTR_PLAYER_GETTARGET = 0x10;
Const Int AAPTR_PLAYER7 = 4096; Const Int AAPTR_PLAYER_GETCONVERSATION = 0x20;
Const Int AAPTR_PLAYER8 = 8192;
Const Int AAPTR_PLAYER1 = 0x40;
Const Int AAPTR_FRIENDPLAYER = 16384; Const Int AAPTR_PLAYER2 = 0x80;
Const Int AAPTR_PLAYER3 = 0x100;
// Pointer operation flags Const Int AAPTR_PLAYER4 = 0x200;
Const Int AAPTR_PLAYER5 = 0x400;
Const Int PTROP_UNSAFETARGET = 1; Const Int AAPTR_PLAYER6 = 0x800;
Const Int PTROP_UNSAFEMASTER = 2; Const Int AAPTR_PLAYER7 = 0x1000;
Const Int PTROP_NOSAFEGUARDS = PTROP_UNSAFETARGET|PTROP_UNSAFEMASTER; Const Int AAPTR_PLAYER8 = 0x2000;
Const Int AAPTR_FRIENDPLAYER = 0x4000;
// Flags for A_Warp Const Int AAPTR_LINETARGET = 0x8000;
Const Int WARPF_ABSOLUTEOFFSET = 0x1; // Pointer operation flags
Const Int WARPF_ABSOLUTEANGLE = 0x2;
Const Int WARPF_USECALLERANGLE = 0x4; Const Int PTROP_UNSAFETARGET = 1;
Const Int WARPF_NOCHECKPOSITION = 0x8; Const Int PTROP_UNSAFEMASTER = 2;
Const Int WARPF_INTERPOLATE = 0x10; Const Int PTROP_NOSAFEGUARDS = PTROP_UNSAFETARGET|PTROP_UNSAFEMASTER;
Const Int WARPF_WARPINTERPOLATION = 0x20;
Const Int WARPF_COPYINTERPOLATION = 0x40;
Const Int WARPF_STOP = 0x80; // Flags for A_Warp
Const Int WARPF_TOFLOOR = 0x100;
Const Int WARPF_TESTONLY = 0x200; Const Int WARPF_ABSOLUTEOFFSET = 0x1;
Const Int WARPF_ABSOLUTEANGLE = 0x2;
// flags for A_SetPitch/SetAngle Const Int WARPF_USECALLERANGLE = 0x4;
const int SPF_FORCECLAMP = 1; Const Int WARPF_NOCHECKPOSITION = 0x8;
const int SPF_INTERPOLATE = 2; Const Int WARPF_INTERPOLATE = 0x10;
Const Int WARPF_WARPINTERPOLATION = 0x20;
Const Int WARPF_COPYINTERPOLATION = 0x40;
// flags for A_CheckLOF Const Int WARPF_STOP = 0x80;
Const Int WARPF_TOFLOOR = 0x100;
enum Const Int WARPF_TESTONLY = 0x200;
{ Const Int WAPRF_ABSOLUTEPOSITION = 0x400;
CLOFF_NOAIM_VERT = 0x1,
CLOFF_NOAIM_HORZ = 0x2, // flags for A_SetPitch/SetAngle
const int SPF_FORCECLAMP = 1;
CLOFF_JUMPENEMY = 0x4, const int SPF_INTERPOLATE = 2;
CLOFF_JUMPFRIEND = 0x8,
CLOFF_JUMPOBJECT = 0x10,
CLOFF_JUMPNONHOSTILE = 0x20, // flags for A_CheckLOF
CLOFF_SKIPENEMY = 0x40, enum
CLOFF_SKIPFRIEND = 0x80, {
CLOFF_SKIPOBJECT = 0x100, CLOFF_NOAIM_VERT = 0x1,
CLOFF_SKIPNONHOSTILE = 0x200, CLOFF_NOAIM_HORZ = 0x2,
CLOFF_MUSTBESHOOTABLE = 0x400, CLOFF_JUMPENEMY = 0x4,
CLOFF_JUMPFRIEND = 0x8,
CLOFF_SKIPTARGET = 0x800, CLOFF_JUMPOBJECT = 0x10,
CLOFF_ALLOWNULL = 0x1000, CLOFF_JUMPNONHOSTILE = 0x20,
CLOFF_CHECKPARTIAL = 0x2000,
CLOFF_SKIPENEMY = 0x40,
CLOFF_MUSTBEGHOST = 0x4000, CLOFF_SKIPFRIEND = 0x80,
CLOFF_IGNOREGHOST = 0x8000, CLOFF_SKIPOBJECT = 0x100,
CLOFF_SKIPNONHOSTILE = 0x200,
CLOFF_MUSTBESOLID = 0x10000,
CLOFF_BEYONDTARGET = 0x20000, CLOFF_MUSTBESHOOTABLE = 0x400,
CLOFF_FROMBASE = 0x40000, CLOFF_SKIPTARGET = 0x800,
CLOFF_MUL_HEIGHT = 0x80000, CLOFF_ALLOWNULL = 0x1000,
CLOFF_MUL_WIDTH = 0x100000, CLOFF_CHECKPARTIAL = 0x2000,
CLOFF_JUMP_ON_MISS = 0x200000, CLOFF_MUSTBEGHOST = 0x4000,
CLOFF_AIM_VERT_NOOFFSET = 0x400000, CLOFF_IGNOREGHOST = 0x8000,
CLOFF_SKIPOBSTACLES = CLOFF_SKIPENEMY|CLOFF_SKIPFRIEND|CLOFF_SKIPOBJECT|CLOFF_SKIPNONHOSTILE, CLOFF_MUSTBESOLID = 0x10000,
CLOFF_NOAIM = CLOFF_NOAIM_VERT|CLOFF_NOAIM_HORZ CLOFF_BEYONDTARGET = 0x20000,
};
CLOFF_FROMBASE = 0x40000,
CLOFF_MUL_HEIGHT = 0x80000,
// Flags for A_AlertMonsters CLOFF_MUL_WIDTH = 0x100000,
const int AMF_TARGETEMITTER = 1;
const int AMF_TARGETNONPLAYER = 2; CLOFF_JUMP_ON_MISS = 0x200000,
const int AMF_EMITFROMTARGET = 4; CLOFF_AIM_VERT_NOOFFSET = 0x400000,
CLOFF_SKIPOBSTACLES = CLOFF_SKIPENEMY|CLOFF_SKIPFRIEND|CLOFF_SKIPOBJECT|CLOFF_SKIPNONHOSTILE,
// This is only here to provide one global variable for testing. CLOFF_NOAIM = CLOFF_NOAIM_VERT|CLOFF_NOAIM_HORZ
native int testglobalvar; };
// Flags for A_Kill (Master/Target/Tracer/Children/Siblings) series
const int KILS_FOILINVUL = 1;
const int KILS_KILLMISSILES = 2;
const int KILS_NOMONSTERS = 4;
// Flags for A_Damage (Master/Target/Tracer/Children/Siblings/Self) series
const int DMSS_FOILINVUL = 1;
const int DMSS_AFFECTARMOR = 2;
const int DMSS_KILL = 4;
const int DMSS_NOFACTOR = 8;
// Flags for A_AlertMonsters
const int AMF_TARGETEMITTER = 1;
const int AMF_TARGETNONPLAYER = 2;
const int AMF_EMITFROMTARGET = 4;
// Flags for A_Remove*
enum
{
RMVF_MISSILES = 1 << 0,
RMVF_NOMONSTERS = 1 << 1,
RMVF_MISC = 1 << 2,
RMVF_EVERYTHING = 1 << 3,
};
// This is only here to provide one global variable for testing.
native int testglobalvar;

View file

@ -836,6 +836,7 @@ SCORE_BONUS = "BONUS";
SCORE_COLOR = "COLOR"; SCORE_COLOR = "COLOR";
SCORE_SECRET = "SECRET"; SCORE_SECRET = "SECRET";
SCORE_NAME = "NAME"; SCORE_NAME = "NAME";
SCORE_DELAY = "DELAY(ms)";
SCORE_KILLS = "KILLS"; SCORE_KILLS = "KILLS";
SCORE_FRAGS = "FRAGS"; SCORE_FRAGS = "FRAGS";
SCORE_DEATHS = "DEATHS"; SCORE_DEATHS = "DEATHS";

View file

@ -341,6 +341,7 @@ OptionMenu "OptionsMenu"
Submenu "Automap Options", "AutomapOptions" Submenu "Automap Options", "AutomapOptions"
Submenu "HUD Options", "HUDOptions" Submenu "HUD Options", "HUDOptions"
Submenu "Miscellaneous Options", "MiscOptions" Submenu "Miscellaneous Options", "MiscOptions"
Submenu "Network Options", "NetworkOptions"
Submenu "Sound Options", "SoundOptions" Submenu "Sound Options", "SoundOptions"
Submenu "Display Options", "VideoOptions" Submenu "Display Options", "VideoOptions"
Submenu "Set video mode", "VideoModeMenu" Submenu "Set video mode", "VideoModeMenu"
@ -457,6 +458,7 @@ OptionMenu "CustomizeControls"
Control "Run", "+speed" Control "Run", "+speed"
Control "Strafe", "+strafe" Control "Strafe", "+strafe"
Control "Show Scoreboard", "+showscores" Control "Show Scoreboard", "+showscores"
Control "Toggle Scoreboard", "togglescoreboard"
StaticText "" StaticText ""
StaticText "Chat", 1 StaticText "Chat", 1
Control "Say", "messagemode" Control "Say", "messagemode"
@ -805,6 +807,13 @@ OptionValue "AltHUDTime"
9, "System" 9, "System"
} }
OptionValue "AltHUDLag"
{
0, "Off"
1, "Netgames only"
2, "Always"
}
OptionMenu "AltHUDOptions" OptionMenu "AltHUDOptions"
{ {
Title "Alternative HUD" Title "Alternative HUD"
@ -819,6 +828,7 @@ OptionMenu "AltHUDOptions"
Option "Show weapons", "hud_showweapons", "OnOff" Option "Show weapons", "hud_showweapons", "OnOff"
Option "Show time", "hud_showtime", "AltHUDTime" Option "Show time", "hud_showtime", "AltHUDTime"
Option "Time color", "hud_timecolor", "TextColors" Option "Time color", "hud_timecolor", "TextColors"
Option "Show network latency", "hud_showlag", "AltHUDLag"
Slider "Red ammo display below %", "hud_ammo_red", 0, 100, 1, 0 Slider "Red ammo display below %", "hud_ammo_red", 0, 100, 1, 0
Slider "Yellow ammo display below %", "hud_ammo_yellow", 0, 100, 1, 0 Slider "Yellow ammo display below %", "hud_ammo_yellow", 0, 100, 1, 0
Slider "Red health display below", "hud_health_red", 0, 100, 1, 0 Slider "Red health display below", "hud_health_red", 0, 100, 1, 0
@ -1591,3 +1601,28 @@ OptionMenu VideoModeMenu
class VideoModeMenu class VideoModeMenu
} }
/*=======================================
*
* Network options menu
*
*=======================================*/
OptionMenu NetworkOptions
{
Title "NETWORK OPTIONS"
StaticText "Local options", 1
Option "Movement prediction", "cl_noprediction", "OffOn"
Option "Predict line actions", "cl_predict_specials", "OnOff"
StaticText " "
StaticText "Host options", 1
Option "Extra Tics", "net_extratic", "ExtraTicMode"
Option "Latency balancing", "net_ticbalance", "OnOff"
}
OptionValue ExtraTicMode
{
0, "None"
1, "1"
2, "All unacknowledged"
}