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
{
alpha = <float>; // Translucency of this line, default is 1.0
renderstyle = <string>; // Render style, can be "translucent" or "add",
// default is "translucent".
playeruseback = <bool>; // New SPAC flag, true = player can use from back side.
anycross = <bool>; // New SPAC flag, true = any non-projectile
// crossing will trigger this line
monsteractivate = <bool>; // Monsters can trigger this line.
// For compatibility only because this flag's
// semantics can not be fully reproduced with
// explicit trigger flags.
blockplayers = <bool>; // Line blocks players' movement.
blockeverything = <bool>; // Line blocks everything.
firstsideonly = <bool>; // Line can only be triggered from the front side.
zoneboundary = <bool>; // Line is a boundary for sound reverb zones.
clipmidtex = <bool>; // Line's mid textures are clipped to floor and ceiling.
wrapmidtex = <bool>; // Line's mid textures are wrapped.
midtex3d = <bool>; // Actors can walk on mid texture.
checkswitchrange = <bool>;// Switches can only be activated when vertically reachable.
blockprojectiles = <bool>;// Line blocks all projectiles
blockuse = <bool>; // Line blocks all use actions
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
alpha = <float>; // Translucency of this line, default is 1.0
renderstyle = <string>; // Render style, can be "translucent" or "add",
// default is "translucent".
playeruseback = <bool> ; // New SPAC flag, true = player can use from back side.
anycross = <bool>; // New SPAC flag, true = any non-projectile
// crossing will trigger this line
monsteractivate = <bool>; // Monsters can trigger this line.
// For compatibility only because this flag's
// semantics can not be fully reproduced with
// explicit trigger flags.
blockplayers = <bool>; // Line blocks players' movement.
blockeverything = <bool>; // Line blocks everything.
firstsideonly = <bool>; // Line can only be triggered from the front side.
zoneboundary = <bool>; // Line is a boundary for sound reverb zones.
clipmidtex = <bool>; // Line's mid textures are clipped to floor and ceiling.
wrapmidtex = <bool>; // Line's mid textures are wrapped.
midtex3d = <bool>; // Actors can walk on mid texture.
midtex3dimpassible = <bool>;// Used in conjuction with midtex3d - causes the mid
// texture to behave like an impassible line (projectiles
// pass through it).
checkswitchrange = <bool>; // Switches can only be activated when vertically reachable.
blockprojectiles = <bool>; // Line blocks all projectiles
blockuse = <bool>; // Line blocks all use actions
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)

View file

@ -56,6 +56,13 @@ AActor *COPY_AAPTR(AActor *origin, int selector)
case AAPTR_TRACER: return origin->tracer;
case AAPTR_FRIENDPLAYER:
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_FRIENDPLAYER = 0x4000,
AAPTR_GET_LINETARGET = 0x8000,
AAPTR_PLAYER_SELECTORS =
AAPTR_PLAYER_GETTARGET|AAPTR_PLAYER_GETCONVERSATION,
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_PLAYER1|AAPTR_PLAYER2|AAPTR_PLAYER3|AAPTR_PLAYER4|

View file

@ -281,7 +281,8 @@ void CT_Drawer (void)
if (players[consoleplayer].camera != NULL &&
(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.
gamestate != GS_INTERMISSION)
{

View file

@ -756,9 +756,9 @@ void D_Display ()
}
screen->SetBlendingRect(viewwindowx, viewwindowy,
viewwindowx + viewwidth, viewwindowy + viewheight);
P_PredictPlayer(&players[consoleplayer]);
Renderer->RenderView(&players[consoleplayer]);
P_UnPredictPlayer();
if ((hw2d = screen->Begin2D(viewactive)))
{
// 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 lastglobalrecvtime; // Identify the last time a packet was recieved.
bool hadlate;
int netdelay[MAXNETNODES][BACKUPTICS]; // Used for storing network delay times.
int lastaverage;
int nodeforplayer[MAXPLAYERS];
int playerfornode[MAXNETNODES];
int maketic;
int skiptics;
int ticdup;
int ticdup;
void D_ProcessEvents (void);
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
static struct TicSpecial
{
@ -347,6 +375,9 @@ int NetbufferSize ()
k += netbuffer[k] + 1;
}
// Network delay byte
k++;
if (netbuffer[0] & NCMD_MULTI)
{
count = netbuffer[k];
@ -487,7 +518,30 @@ void HSendPacket (int node, int len)
doomcom.remotenode = node;
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)
return false;
doomcom.command = CMD_GET;
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)
{
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;
}
#endif
if (debugfile)
{
@ -570,6 +654,9 @@ bool HGetPacket (void)
if (doomcom.datalength != NetbufferSize ())
{
Printf("Bad packet length %i (calculated %i)\n",
doomcom.datalength, NetbufferSize());
if (debugfile)
fprintf (debugfile,"---bad packet length %i (calculated %i)\n",
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;
if (netbuffer[0] & NCMD_MULTI)
{
@ -1150,11 +1240,18 @@ void NetUpdate (void)
netbuffer[k++] = lowtic;
}
numtics = lowtic - realstart;
numtics = MAX(0, lowtic - realstart);
if (numtics > BACKUPTICS)
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])
{
@ -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)
{
int l;
@ -1299,9 +1400,37 @@ void NetUpdate (void)
// that it won't adapt. Fortunately, player prediction helps
// 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)
{
@ -1346,9 +1475,8 @@ void NetUpdate (void)
//
// 0 One byte set to NCMD_SETUP+2
// 1 One byte for ticdup setting
// 2 One byte for extratics setting
// 3 One byte for NetMode setting
// 4 String with starting map's name
// 2 One byte for NetMode setting
// 3 String with starting map's name
// . Four bytes for the RNG seed
// . Stream containing remaining game info
//
@ -1429,10 +1557,9 @@ bool DoArbitrate (void *userdata)
data->gotsetup[0] = 0x80;
ticdup = doomcom.ticdup = netbuffer[1];
doomcom.extratics = netbuffer[2];
NetMode = netbuffer[3];
NetMode = netbuffer[2];
stream = &netbuffer[4];
stream = &netbuffer[3];
s = ReadString (&stream);
startmap = s;
delete[] s;
@ -1497,9 +1624,8 @@ bool DoArbitrate (void *userdata)
{
netbuffer[0] = NCMD_SETUP+2;
netbuffer[1] = (BYTE)doomcom.ticdup;
netbuffer[2] = (BYTE)doomcom.extratics;
netbuffer[3] = NetMode;
stream = &netbuffer[4];
netbuffer[2] = NetMode;
stream = &netbuffer[3];
WriteString (startmap, &stream);
WriteLong (rngseed, &stream);
C_WriteCVars (&stream, CVAR_SERVERINFO, true);
@ -1647,15 +1773,23 @@ void D_CheckNetGame (void)
consoleplayer = doomcom.consoleplayer;
v = Args->CheckValue ("-netmode");
if (v != NULL)
if (consoleplayer == Net_Arbitrator)
{
NetMode = atoi (v) != 0 ? NET_PacketServer : NET_PeerToPeer;
}
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");
v = Args->CheckValue("-netmode");
if (v != NULL)
{
NetMode = atoi(v) != 0 ? NET_PacketServer : NET_PeerToPeer;
}
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
@ -1683,6 +1817,11 @@ void D_CheckNetGame (void)
for (i = 0; i < doomcom.numnodes; i++)
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",
consoleplayer+1, doomcom.numplayers, doomcom.numnodes);
}
@ -1809,6 +1948,9 @@ void TryRunTics (void)
{
C_Ticker();
M_Ticker();
// Repredict the player for new buffered movement
P_UnPredictPlayer();
P_PredictPlayer(&players[consoleplayer]);
}
return;
}
@ -1844,6 +1986,9 @@ void TryRunTics (void)
{
C_Ticker ();
M_Ticker ();
// Repredict the player for new buffered movement
P_UnPredictPlayer();
P_PredictPlayer(&players[consoleplayer]);
return;
}
}
@ -1857,6 +2002,7 @@ void TryRunTics (void)
// run the count tics
if (counts > 0)
{
P_UnPredictPlayer();
while (counts--)
{
if (gametic > lowtic)
@ -1876,6 +2022,7 @@ void TryRunTics (void)
NetUpdate (); // check for new console commands
}
P_PredictPlayer(&players[consoleplayer]);
S_UpdateSounds (players[consoleplayer].camera); // move positional sounds
}
}
@ -2713,7 +2860,6 @@ void Net_SkipCommand (int type, BYTE **stream)
CCMD (pings)
{
int i;
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i])
Printf ("% 4d %s\n", currrecvtime[i] - lastrecvtime[i],

View file

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

View file

@ -162,6 +162,7 @@ enum ELineFlags
ML_BLOCKUSE = 0x02000000, // blocks all use actions through this line
ML_BLOCKSIGHT = 0x04000000, // blocks monster line of sight
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));
}
//
// A_BFGSpray
// Spawn a BFG explosion on every monster in view
@ -559,14 +560,21 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray)
AActor *thingToHit;
AActor *linetarget;
ACTION_PARAM_START(3);
ACTION_PARAM_START(7);
ACTION_PARAM_CLASS(spraytype, 0);
ACTION_PARAM_INT(numrays, 1);
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 (numrays <= 0) numrays = 40;
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
if (!self->target)
@ -575,10 +583,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray)
// offset angles from its attack angle
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
P_AimLineAttack (self->target, an, 16*64*FRACUNIT, &linetarget, ANGLE_1*32);
P_AimLineAttack (self->target, an, distance, &linetarget, vrange);
if (!linetarget)
continue;
@ -589,10 +597,17 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray)
if (spray && (spray->flags5 & MF5_PUFFGETSOWNER))
spray->target = self->target;
damage = 0;
for (j = 0; j < damagecnt; ++j)
damage += (pr_bfgspray() & 7) + 1;
if (defdamage == 0)
{
damage = 0;
for (j = 0; j < damagecnt; ++j)
damage += (pr_bfgspray() & 7) + 1;
}
else
{
// if this is used, damagecnt will be ignored
damage = defdamage;
}
thingToHit = linetarget;
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.
#include "doomtype.h"
#include "doomdef.h"
#include "v_video.h"
#include "gi.h"
#include "c_cvars.h"
@ -48,6 +49,7 @@
#include "p_local.h"
#include "doomstat.h"
#include "g_level.h"
#include "d_net.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 (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_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_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);
}
//---------------------------------------------------------------------------
//
// 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);
DrawTime();
DrawLatency();
}
else
{

View file

@ -48,6 +48,8 @@
#include "d_player.h"
#include "hu_stuff.h"
#include "gstrings.h"
#include "d_net.h"
#include "c_dispatch.h"
// MACROS ------------------------------------------------------------------
@ -61,7 +63,7 @@
static void HU_DoDrawScores (player_t *, player_t *[MAXPLAYERS]);
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 ----------------------------------------------
@ -116,6 +118,8 @@ int STACK_ARGS compareteams (const void *arg1, const void *arg2)
return diff;
}
bool SB_ForceActive = false;
// PRIVATE DATA DEFINITIONS ------------------------------------------------
// CODE --------------------------------------------------------------------
@ -228,7 +232,7 @@ static void HU_DoDrawScores (player_t *player, player_t *sortedplayers[MAXPLAYER
int maxnamewidth, maxscorewidth, maxiconheight;
int numTeams = 0;
int x, y, ypadding, bottom;
int col2, col3, col4;
int col2, col3, col4, col5;
if (deathmatch)
{
@ -309,12 +313,14 @@ static void HU_DoDrawScores (player_t *player, player_t *sortedplayers[MAXPLAYER
const char *text_color = GStrings("SCORE_COLOR"),
*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;
col3 = col2 + (SmallFont->StringWidth(text_frags) + 8) * 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,
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,
DTA_CleanNoMove, true, TAG_DONE);
screen->DrawText(SmallFont, color, x + col5, y, text_delay,
DTA_CleanNoMove, true, TAG_DONE);
y += height + 6 * CleanYfac;
bottom -= height;
@ -332,7 +341,7 @@ static void HU_DoDrawScores (player_t *player, player_t *sortedplayers[MAXPLAYER
{
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;
}
}
@ -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;
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
// other way to do highlighting. And it may as well be used for
// 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;
col3 += col1;
col4 += col1;
col5 += col1;
color = HU_GetRowColor(player, highlight);
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(),
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 ())
{
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);
int HU_GetRowColor(player_t *player, bool hightlight);
extern bool SB_ForceActive;
// Sorting routines
int STACK_ARGS comparepoints(const void *arg1, const void *arg2);

View file

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

View file

@ -298,6 +298,8 @@ xx(Abs)
xx(ACS_NamedExecuteWithResult)
xx(CallACS)
xx(Sqrt)
xx(CheckClass)
xx(IsPointerEqual)
// Various actor names which are used internally
xx(MapSpot)
@ -418,6 +420,7 @@ xx(Passuse)
xx(Repeatspecial)
xx(Conversation)
xx(Locknumber)
xx(Midtex3dimpassible)
xx(Playercross)
xx(Playeruse)
@ -596,4 +599,4 @@ xx(NeverSwitchOnPickup)
xx(MoveBob)
xx(StillBob)
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)
{
// [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;
open.abovemidtex = false;

View file

@ -3843,6 +3843,10 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value)
actor->reactiontime = value;
break;
case APROP_MeleeRange:
actor->meleerange = value;
break;
case APROP_ViewHeight:
if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn)))
static_cast<APlayerPawn *>(actor)->ViewHeight = value;
@ -4368,6 +4372,9 @@ enum EACSFunctions
ACSF_ChangeActorPitch, // 80
ACSF_GetArmorInfo,
ACSF_DropInventory,
ACSF_PickActor,
ACSF_IsPointerEqual,
ACSF_CanRaiseActor,
/* Zandronum's - these must be skipped when we reach 99!
-100:ResetMap(0),
@ -5593,6 +5600,74 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
}
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:
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_RemoveThing(AActor * actor);
bool P_Thing_Raise(AActor *thing);
bool P_Thing_CanRaise(AActor *thing);
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, 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, AActor *target, angle_t angle, int pitch);
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.
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;
}
return false;
@ -1981,13 +1983,6 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y,
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 (!(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);
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);
}
@ -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
newsec = thing->Sector;
if (newsec->heightsec && oldsec->heightsec && newsec->SecActTarget)
@ -3783,6 +3789,52 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance,
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");
void P_SetupPortals();
EXTERN_CVAR(Bool, cl_predict_specials)
IMPLEMENT_POINTY_CLASS (DScroller)
DECLARE_POINTER (m_Interpolations[0])
@ -408,6 +409,48 @@ bool P_TestActivateLine (line_t *line, AActor *mo, int side, int activationType)
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
// Called every tic frame

View file

@ -166,6 +166,7 @@ void P_UpdateSpecials (void);
// when needed
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_PredictLine (line_t *ld, AActor *mo, int side, int activationType);
void P_PlayerInSpecialSector (player_t *player, sector_t * sector=NULL);
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 useFog, bool sourceFog, bool keepOrientation, bool bHaltVelocity, bool keepHeight)
{
bool predicting = (thing->player && (thing->player->cheats & CF_PREDICTING));
fixed_t oldx;
fixed_t oldy;
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;
}
// Spawn teleport fog at source and destination
if (sourceFog)
if (sourceFog && !predicting)
{
fixed_t fogDelta = thing->flags & MF_MISSILE ? 0 : TELEFOGHEIGHT;
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)
{
fixed_t fogDelta = thing->flags & MF_MISSILE ? 0 : TELEFOGHEIGHT;
an = angle >> ANGLETOFINESHIFT;
AActor *fog = Spawn<ATeleportFog> (x + 20*finecosine[an],
y + 20*finesine[an], thing->z + fogDelta, ALLOW_REPLACE);
fog->target = thing;
if (!predicting)
{
fixed_t fogDelta = thing->flags & MF_MISSILE ? 0 : TELEFOGHEIGHT;
an = angle >> ANGLETOFINESHIFT;
AActor *fog = Spawn<ATeleportFog>(x + 20 * finecosine[an],
y + 20 * finesine[an], thing->z + fogDelta, ALLOW_REPLACE);
fog->target = thing;
}
if (thing->player)
{
// [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;
}
static AActor *SelectTeleDest (int tid, int tag)
static AActor *SelectTeleDest (int tid, int tag, bool norandom)
{
AActor *searcher;
@ -276,7 +281,7 @@ static AActor *SelectTeleDest (int tid, int tag)
}
else
{
if (count != 1)
if (count != 1 && !norandom)
{
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 sourceFog, bool keepOrientation, bool haltVelocity, bool keepHeight)
{
AActor *searcher;
fixed_t z;
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
return false;
}
bool predicting = (thing->player && (thing->player->cheats & CF_PREDICTING));
if (thing->flags2 & MF2_NOTELEPORT)
{
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.
return 0;
}
searcher = SelectTeleDest (tid, tag);
searcher = SelectTeleDest(tid, tag, predicting);
if (searcher == NULL)
{
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->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 ();
}

View file

@ -445,6 +445,40 @@ bool P_Thing_Raise(AActor *thing)
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)
{
if (actor != NULL)

View file

@ -1030,11 +1030,16 @@ public:
Flag(ld->flags, ML_BLOCKHITSCAN, key);
continue;
// [Dusk] lock number
// [TP] Locks the special with a key
case NAME_Locknumber:
ld->locknumber = CheckInt(key);
continue;
// [TP] Causes a 3d midtex to behave like an impassible line
case NAME_Midtex3dimpassible:
Flag(ld->flags, ML_3DMIDTEX_IMPASS, key);
continue;
default:
break;
}
@ -1081,6 +1086,10 @@ public:
{
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
CVAR (Bool, cl_noprediction, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR(Bool, cl_predict_specials, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
static player_t PredictionPlayerBackup;
static BYTE PredictionActorBackup[sizeof(AActor)];
static TArray<sector_t *> PredictionTouchingSectorsBackup;
@ -2722,8 +2723,12 @@ void P_PredictPlayer (player_t *player)
}
act->BlockNode = NULL;
bool NoInterpolateOld = R_GetViewInterpolationStatus();
for (int i = gametic; i < maxtic; ++i)
{
if (!NoInterpolateOld)
R_RebuildViewInterpolation(player);
player->cmd = localcmds[i % LOCALCMDTICS];
P_PlayerThink (player);
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

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);
fixed_t R_PointToDist2 (fixed_t dx, fixed_t dy);
void R_ResetViewInterpolation ();
void R_RebuildViewInterpolation(player_t *player);
bool R_GetViewInterpolationStatus();
void R_SetViewSize (int blocks);
void R_SetFOV (float fov);
float R_GetFOV ();

View file

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

View file

@ -43,6 +43,8 @@
#include "tarray.h"
#include "thingdef.h"
#include "thingdef_exp.h"
#include "actor.h"
#include "actorptrselect.h"
static TMap<FName, FxGlobalFunctionCall::Creator> CreatorMap;
@ -185,3 +187,110 @@ public:
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++;
}
FName symname = sc.String;
if (sc.CheckToken('['))
{
@ -391,6 +393,15 @@ static void ParseUserVariable (FScanner &sc, PSymbolTable *symt, PClass *cls)
}
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);
sym->offset = cls->Extend(sizeof(int) * (valuetype.Type == VAL_Array ? valuetype.size : 1));
sym->ValueType = valuetype;

View file

@ -51,7 +51,7 @@ const char *GetVersionString();
// Version identifier for network games.
// Bump it every time you do a release unless you're certain you
// didn't change anything that will affect sync.
#define NETGAMEVERSION 230
#define NETGAMEVERSION 231
// Version stored in the ini's [LastRun] section.
// 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 int reactiontime;
native fixed_t meleerange;
native fixed_t speed;
// Meh, MBF redundant functions. Only for DeHackEd support.
action native A_Turn(float angle = 0);
@ -69,7 +70,7 @@ ACTOR Actor native //: Thinker
// End of MBF redundant functions.
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_NoBlocking();
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_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_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_JumpIfTracerCloser(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_CheckFlag(string flagname, state label, int check_pointer = AAPTR_DEFAULT);
action native A_JumpIf(bool expression, state label);
action native A_RemoveMaster();
action native A_RemoveChildren(bool removeall = false);
action native A_RemoveSiblings(bool removeall = false);
action native A_KillMaster(name damagetype = "none");
action native A_KillChildren(name damagetype = "none");
action native A_KillSiblings(name damagetype = "none");
action native A_RemoveMaster(int flags = 0);
action native A_RemoveChildren(bool removeall = false, int flags = 0);
action native A_RemoveSiblings(bool removeall = false, int flags = 0);
action native A_KillMaster(name damagetype = "none", int flags = 0);
action native A_KillChildren(name damagetype = "none", int flags = 0);
action native A_KillSiblings(name damagetype = "none", int flags = 0);
action native A_RaiseMaster();
action native A_RaiseChildren();
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_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_DamageMaster(int amount, name damagetype = "none");
action native A_DamageChildren(int amount, name damagetype = "none");
action native A_DamageSiblings(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", int flags = 0);
action native A_DamageSiblings(int amount, name damagetype = "none", int flags = 0);
action native A_SelectWeapon(class<Weapon> whichweapon);
action native A_Punch();
action native A_Feathers();
@ -302,6 +303,15 @@ ACTOR Actor native //: Thinker
action native A_SetTics(int tics);
action native A_SetDamageType(name damagetype);
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_CheckRange(float distance, state label);

View file

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

View file

@ -341,6 +341,7 @@ OptionMenu "OptionsMenu"
Submenu "Automap Options", "AutomapOptions"
Submenu "HUD Options", "HUDOptions"
Submenu "Miscellaneous Options", "MiscOptions"
Submenu "Network Options", "NetworkOptions"
Submenu "Sound Options", "SoundOptions"
Submenu "Display Options", "VideoOptions"
Submenu "Set video mode", "VideoModeMenu"
@ -457,6 +458,7 @@ OptionMenu "CustomizeControls"
Control "Run", "+speed"
Control "Strafe", "+strafe"
Control "Show Scoreboard", "+showscores"
Control "Toggle Scoreboard", "togglescoreboard"
StaticText ""
StaticText "Chat", 1
Control "Say", "messagemode"
@ -805,6 +807,13 @@ OptionValue "AltHUDTime"
9, "System"
}
OptionValue "AltHUDLag"
{
0, "Off"
1, "Netgames only"
2, "Always"
}
OptionMenu "AltHUDOptions"
{
Title "Alternative HUD"
@ -819,6 +828,7 @@ OptionMenu "AltHUDOptions"
Option "Show weapons", "hud_showweapons", "OnOff"
Option "Show time", "hud_showtime", "AltHUDTime"
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 "Yellow ammo display below %", "hud_ammo_yellow", 0, 100, 1, 0
Slider "Red health display below", "hud_health_red", 0, 100, 1, 0
@ -1591,3 +1601,28 @@ OptionMenu 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"
}