Update to 2.2.4

This commit is contained in:
SwitchKaze 2020-05-22 16:47:51 -05:00
commit 46191cade7
149 changed files with 10296 additions and 19268 deletions

View file

@ -51,8 +51,8 @@ jobs:
- /var/cache/apt/archives - /var/cache/apt/archives
- checkout - checkout
- run: - run:
name: Compile without network support and BLUA name: Compile without network support
command: make -C src LINUX=1 ERRORMODE=1 -k NONET=1 NO_LUA=1 command: make -C src LINUX=1 ERRORMODE=1 -k NONET=1
- run: - run:
name: wipe build name: wipe build
command: make -C src LINUX=1 cleandep command: make -C src LINUX=1 cleandep

View file

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0)
# DO NOT CHANGE THIS SRB2 STRING! Some variable names depend on this string. # DO NOT CHANGE THIS SRB2 STRING! Some variable names depend on this string.
# Version change is fine. # Version change is fine.
project(SRB2 project(SRB2
VERSION 2.2.2 VERSION 2.2.4
LANGUAGES C) LANGUAGES C)
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR}) if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})

View file

@ -1,4 +1,4 @@
version: 2.2.2.{branch}-{build} version: 2.2.4.{branch}-{build}
os: MinGW os: MinGW
environment: environment:

View file

@ -1,77 +0,0 @@
// Default lump name for new map
defaultlumpname = "MAP01";
//GZDB specific. Don't try to load lumps that don't exist.
basegame = 0;
//Sky textures for vanilla maps
defaultskytextures
{
SKY1 = "MAP01,MAP02,MAP03,MAP33,MAP50,MAP60,MAPF0,MAPM0";
SKY2 = "MAPM7,MAPMB";
SKY4 = "MAP04,MAP06,MAP61,MAPF6,MAPM1";
SKY6 = "MAP05,MAP51,MAPMA";
SKY7 = "MAPM2,MAPM5";
SKY8 = "MAP07,MAP08,MAP09,MAP52,MAP62,MAPF1";
SKY10 = "MAP10,MAP12,MAP53,MAP63,MAPM3";
SKY11 = "MAP11,MAPF7";
SKY13 = "MAP13,MAP64";
SKY14 = "MAP14";
SKY15 = "MAP15,MAP54";
SKY17 = "MAP70";
SKY20 = "MAP32,MAP55,MAP65,MAPF2,MAPF5";
SKY21 = "MAPM4";
SKY22 = "MAP22,MAP23,MAP25,MAP26,MAP27,MAP56,MAP66,MAPF4,MAPM6";
SKY30 = "MAP30";
SKY31 = "MAP31";
SKY35 = "MAP42";
SKY40 = "MAP41,MAP71,MAPM9";
SKY55 = "MAPF3,MAPM8";
SKY68 = "MAPF8";
SKY99 = "MAP57,MAPZ0";
SKY159 = "MAP16";
SKY172 = "MAP40";
SKY300 = "MAP72";
SKY301 = "MAP73";
}
// Skill levels
skills
{
1 = "Normal";
}
// Skins
skins
{
Sonic;
Tails;
Knuckles;
Amy;
Fang;
Metalsonic;
}
// Gametypes
gametypes
{
-1 = "Single Player";
0 = "Co-op";
1 = "Competition";
2 = "Race";
3 = "Match";
4 = "Team Match";
5 = "Tag";
6 = "Hide and Seek";
7 = "CTF";
}
// Texture loading options
defaultwalltexture = "GFZROCK";
defaultfloortexture = "GFZFLR01";
defaultceilingtexture = "F_SKY1";
// Default texture sets
// (these are not required, but useful for new users)
texturesets
{
}

View file

@ -1,309 +0,0 @@
common
{
// Some common settings
// Default testing parameters
testparameters = "-file \"%AP\" \"%F\" -warp %L";
testshortpaths = true;
// Action special help (mxd)
actionspecialhelp = "https://wiki.srb2.org/wiki/Linedef_type_%K";
// Default nodebuilder configurations
defaultsavecompiler = "zennode_normal";
defaulttestcompiler = "zennode_fast";
// Generalized actions
generalizedlinedefs = false;
generalizedsectors = true;
mixtexturesflats = true;
defaulttexturescale = 1.0f;
defaultflatscale = 1.0f;
scaledtextureoffsets = true;
// Thing number for start position in 3D Mode
start3dmode = 3328;
// Texture sources
textures
{
include("SRB222_misc.cfg", "textures");
}
// Patch sources
patches
{
include("SRB222_misc.cfg", "patches");
}
// Sprite sources
sprites
{
include("SRB222_misc.cfg", "sprites");
}
// Flat sources
flats
{
include("SRB222_misc.cfg", "flats");
}
}
mapformat_doom
{
// The format interface handles the map data format - DoomMapSetIO for SRB2DB2, SRB2MapSetIO for Zone Builder
formatinterface = "SRB2MapSetIO";
/*
GAME DETECT PATTERN
Used to guess the game for which a WAD file is made.
1 = One of these lumps must exist
2 = None of these lumps must exist
3 = All of these lumps must exist
*/
gamedetect
{
EXTENDED = 2;
BEHAVIOR = 2;
E#M# = 2;
MAP?? = 1;
}
/*
MAP LUMP NAMES
Map lumps are loaded with the map as long as they are right after each other. When the editor
meets a lump which is not defined in this list it will ignore the map if not satisfied.
The order of items defines the order in which lumps will be written to WAD file on save.
To indicate the map header lump, use ~MAP
Legenda:
required = Lump is required to exist.
blindcopy = Lump will be copied along with the map blindly. (usefull for lumps Doom Builder doesn't use)
nodebuild = The nodebuilder generates this lump.
allowempty = The nodebuilder is allowed to leave this lump empty.
script = This lump is a text-based script. Specify the filename of the script configuration to use.
*/
maplumpnames
{
include("SRB222_misc.cfg", "doommaplumpnames");
}
// When this is set to true, sectors with the same tag will light up when a line is highlighted
linetagindicatesectors = true;
// Special linedefs
include("SRB222_misc.cfg", "speciallinedefs");
// Default flags for first new thing (As far as 2.2 goes, they're empty just like in 2.1)
defaultthingflags
{
}
// DEFAULT SECTOR BRIGHTNESS LEVELS
sectorbrightness
{
include("SRB222_misc.cfg", "sectorbrightness");
}
// SECTOR TYPES-----------------------------------------------------------------
sectortypes
{
include("SRB222_sectors.cfg", "sectortypes");
}
// GENERALISED SECTOR TYPES-----------------------------------------------------------------
gen_sectortypes
{
include("SRB222_sectors.cfg", "gen_sectortypes");
}
// LINEDEF FLAGS
linedefflags
{
include("SRB222_misc.cfg", "linedefflags");
}
// Linedef flags UDMF translation table
// This is needed for copy/paste and prefabs to work properly
// When the UDMF field name is prefixed with ! it is inverted
linedefflagstranslation
{
include("SRB222_misc.cfg", "linedefflagstranslation");
}
// LINEDEF ACTIVATIONS
linedefactivations
{
}
// LINEDEF TYPES
linedeftypes
{
include("SRB222_linedefs.cfg", "doom");
}
// THING FLAGS
thingflags
{
include("SRB222_misc.cfg", "thingflags");
}
// Thing flags UDMF translation table
// This is needed for copy/paste and prefabs to work properly
// When the UDMF field name is prefixed with ! it is inverted
thingflagstranslation
{
include("SRB222_misc.cfg", "thingflagstranslation");
}
// THING FLAGS ERROR MASK
// Mask for the thing flags which indicates the options
// that make the same thing appear in the same modes
thingflagsmask1 = 7; // 1 + 2 + 4
thingflagsmask2 = 0;
}
mapformat_udmf
{
// The format interface handles the map data format
formatinterface = "UniversalMapSetIO";
// Enables support for long (> 8 chars) texture names
// WARNING: this should only be enabled for UDMF game configurations!
// WARNING: enabling this will make maps incompatible with Doom Builder 2 and can lead to problems in Slade 3!
longtexturenames = false;
// Default nodebuilder configurations
defaultsavecompiler = "zdbsp_udmf_normal";
defaulttestcompiler = "zdbsp_udmf_fast";
engine = "srb2"; // override that so that DB2 uses the correct namespace
maplumpnames
{
include("UDMF_misc.cfg", "udmfmaplumpnames_begin");
include("SRB222_misc.cfg", "udmfmaplumpnames");
include("UDMF_misc.cfg", "udmfmaplumpnames_end");
}
universalfields
{
// include("SRB222_misc.cfg", "universalfields");
}
// When this is set to true, sectors with the same tag will light up when a line is highlighted
linetagindicatesectors = false;
// Special linedefs
include("SRB222_misc.cfg", "speciallinedefs_udmf");
// Default flags for first new thing (As far as 2.2 goes, they're empty just like in 2.1)
defaultthingflags
{
}
// Generalized actions
generalizedlinedefs = false;
// SECTOR FLAGS
sectorflags
{
// include("SRB222_misc.cfg", "sectorflags");
}
// DEFAULT SECTOR BRIGHTNESS LEVELS
sectorbrightness
{
include("SRB222_misc.cfg", "sectorbrightness");
}
// SECTOR TYPES
sectortypes
{
include("SRB222_sectors.cfg", "sectortypes");
}
// SECTOR RENSERSTYLES
/* sectorrenderstyles
{
include("SRB222_misc.cfg", "sectorrenderstyles");
}*/
// LINEDEF FLAGS
linedefflags
{
include("SRB222_misc.cfg", "linedefflags_udmf");
}
// LINEDEF ACTIVATIONS
linedefactivations
{
include("SRB222_misc.cfg", "linedefactivations_udmf");
}
linedefflagstranslation
{
}
// LINEDEF RENSERSTYLES
linedefrenderstyles
{
include("SRB222_misc.cfg", "linedefrenderstyles");
}
//SIDEDEF FLAGS
/* sidedefflags
{
include("UDMF_misc.cfg", "sidedefflags");
}*/
// THING FLAGS
thingflags
{
include("SRB222_misc.cfg", "thingflags_udmf");
}
// Thing flags UDMF translation table
// This is needed for copy/paste and prefabs to work properly
// When the UDMF field name is prefixed with ! it is inverted
thingflagstranslation
{
include("SRB222_misc.cfg", "thingflagstranslation");
}
// THING RENSERSTYLES
/* thingrenderstyles
{
include("SRB222_misc.cfg", "thingrenderstyles");
}*/
// How to compare thing flags (for the stuck things error checker)
/* thingflagscompare
{
include("UDMF_misc.cfg", "thingflagscompare");
}*/
//mxd. Thing flags UDMF translation table
// This is needed for copy/paste and prefabs to work properly
// When the UDMF field name is prefixed with ! it is inverted
thingflagstranslation
{
}
// LINEDEF TYPES
linedeftypes
{
include("SRB222_linedefs.cfg", "udmf");
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,726 +0,0 @@
linedefflags
{
1 = "[0] Impassable";
2 = "[1] Block Enemies";
4 = "[2] Double-Sided";
8 = "[3] Upper Unpegged";
16 = "[4] Lower Unpegged";
32 = "[5] Slope Skew (E1)";
64 = "[6] Not Climbable";
128 = "[7] No Midtexture Skew (E2)";
256 = "[8] Peg Midtexture (E3)";
512 = "[9] Solid Midtexture (E4)";
1024 = "[10] Repeat Midtexture (E5)";
2048 = "[11] Netgame Only";
4096 = "[12] No Netgame";
8192 = "[13] Effect 6";
16384 = "[14] Bouncy Wall";
32768 = "[15] Transfer Line";
}
// LINEDEF ACTIVATIONS
// Make sure these are in order from lowest value to highest value
linedefactivations
{
}
// Linedef flags UDMF translation table
// This is needed for copy/paste and prefabs to work properly
// When the UDMF field name is prefixed with ! it is inverted
linedefflagstranslation
{
1 = "blocking";
2 = "blockmonsters";
4 = "twosided";
8 = "dontpegtop";
16 = "dontpegbottom";
32 = "skewtd";
64 = "noclimb";
128 = "noskew";
256 = "midpeg";
512 = "midsolid";
1024 = "wrapmidtex";
2048 = "netonly";
4096 = "nonet";
8192 = "effect6";
16384 = "bouncy";
32768 = "transfer";
}
linedefflags_udmf
{
blocking = "Impassable";
blockmonsters = "Block Enemies";
twosided = "Double-Sided";
dontpegtop = "Upper Unpegged";
dontpegbottom = "Lower Unpegged";
skewtd = "Slope Skew";
noclimb = "Not Climbable";
noskew = "No Midtexture Skew";
midpeg = "Peg Midtexture";
midsolid = "Solid Midtexture";
wrapmidtex = "Repeat Midtexture";
// netonly = "Netgame-Only special";
// nonet = "No netgame special";
// effect6 = "Effect 6";
bouncy = "Bouncy Wall";
// transfer = "Transfer Line";
}
linedefactivations_udmf
{
notriggerorder = "Out of Order";
netonly = "Netgame-Only";
nonet = "No netgame";
}
sidedefflags
{
clipmidtex = "Clip middle texture";
wrapmidtex = "Wrap middle texture";
smoothlighting = "Smooth lighting";
nofakecontrast = "Even lighting";
nodecals = "No decals";
lightfog = "Use sidedef brightness on fogged walls";
}
//RENDER STYLES
thingrenderstyles
{
}
linedefrenderstyles
{
translucent = "Translucent";
fog = "Fog";
}
sectorrenderstyles
{
}
thingflags
{
1 = "[1] Extra";
2 = "[2] Flip";
4 = "[4] Special";
8 = "[8] Ambush";
}
// THING FLAGS
thingflags_udmf
{
extra = "Extra";
flip = "Flip";
special = "Special";
ambush = "Ambush";
}
// Thing flags UDMF translation table
// This is needed for copy/paste and prefabs to work properly
// When the UDMF field name is prefixed with ! it is inverted
thingflagstranslation
{
1 = "extra";
2 = "flip";
4 = "special";
8 = "ambush";
}
// DEFAULT SECTOR BRIGHTNESS LEVELS
sectorbrightness
{
255;
248;
240;
232;
224;
216;
208;
200;
192;
184;
176;
168;
160;
152;
144;
136;
128;
120;
112;
104;
96;
88;
80;
72;
64;
56;
48;
40;
32;
24;
16;
8;
0;
}
/*
TEXTURES AND FLAT SOURCES
This tells Doom Builder where to find the information for textures
and flats in the IWAD file, Addition WAD file and Map WAD file.
Start and end lumps must be given in a structure (of which the
key name doesnt matter) and any textures or flats in between them
are loaded in either the textures category or flats category.
For textures: PNAMES, TEXTURE1 and TEXTURE2 are loaded by default.
*/
textures
{
zdoom1
{
start = "TX_START";
end = "TX_END";
}
}
/*
ADDITIONAL UNIVERSAL DOOM MAP FORMAT FIELD DEFINITIONS
Only add fields here that Doom Builder does not edit with its own user-interface!
The "default" field must match the UDMF specifications!
Field data types:
0 = integer *
1 = float
2 = string
3 = bool
4 = linedef action (integer) *
5 = sector effect (integer) *
6 = texture (string)
7 = flat (string)
8 = angle in degrees (integer)
9 = angle in radians (float)
10 = XXRRGGBB color (integer)
11 = enum option (integer) *
12 = enum bits (integer) *
13 = sector tag (integer) *
14 = thing tag (integer) *
15 = linedef tag (integer) *
16 = enum option (string)
17 = angle in degrees (float)
22 = byte angle (integer)
*/
universalfields
{
sector
{
friction
{
name = "Friction";
type = 1;
default = 1;
}
specialeffectplanes
{
type = 11;
enum = "floorceiling";
default = 0;
}
colormapbegin
{
type = 0;
default = 0;
}
colormapend
{
type = 0;
default = 33;
}
foglighting
{
type = 3;
default = false;
}
teambase
{
type = 11;
enum = "ctfteam";
default = 0;
}
triggersector
{
type = 3;
default = false;
}
triggerobject
{
type = 11;
enum = "triggerobjects";
default = 0;
}
triggersurface
{
type = 11;
enum = "triggersurfaces";
default = 0;
}
ringdrain
{
type = 1;
default = 0;
}
}
linedef
{
executordelay
{
type = 0;
default = 0;
}
midtexrepetitions
{
type = 0;
default = 0;
}
arg5
{
type = 0;
default = 0;
}
arg1str
{
type = 2;
default = "";
}
}
thing
{
}
}
/*
MAP LUMP NAMES
Map lumps are loaded with the map as long as they are right after each other. When the editor
meets a lump which is not defined in this list it will ignore the map if not satisfied.
The order of items defines the order in which lumps will be written to WAD file on save.
To indicate the map header lump, use ~MAP
Legenda:
required = Lump is required to exist.
blindcopy = Lump will be copied along with the map blindly. (useful for lumps Doom Builder doesn't use)
nodebuild = The nodebuilder generates this lump.
allowempty = The nodebuilder is allowed to leave this lump empty.
scriptbuild = This lump is a text-based script, which should be compiled using current script compiler;
script = This lump is a text-based script. Specify the filename of the script configuration to use.
*/
doommaplumpnames
{
~MAP
{
required = true;
blindcopy = true;
nodebuild = false;
}
THINGS
{
required = true;
nodebuild = true;
allowempty = true;
}
LINEDEFS
{
required = true;
nodebuild = true;
allowempty = false;
}
SIDEDEFS
{
required = true;
nodebuild = true;
allowempty = false;
}
VERTEXES
{
required = true;
nodebuild = true;
allowempty = false;
}
SEGS
{
required = false;
nodebuild = true;
allowempty = false;
}
SSECTORS
{
required = false;
nodebuild = true;
allowempty = false;
}
NODES
{
required = false;
nodebuild = true;
allowempty = false;
}
SECTORS
{
required = true;
nodebuild = true;
allowempty = false;
}
REJECT
{
required = false;
nodebuild = true;
allowempty = false;
}
BLOCKMAP
{
required = false;
nodebuild = true;
allowempty = true;
}
}
udmfmaplumpnames
{
ZNODES
{
required = false;
nodebuild = true;
allowempty = false;
}
REJECT
{
required = false;
nodebuild = true;
allowempty = false;
}
BLOCKMAP
{
required = false;
nodebuild = true;
allowempty = true;
}
}
// ENUMERATIONS
// These are enumerated lists for linedef types and UDMF fields.
// Reserved names are: angledeg, anglerad, color, texture, flat
enums
{
falsetrue
{
0 = "False";
1 = "True";
}
yesno
{
0 = "Yes";
1 = "No";
}
noyes
{
0 = "No";
1 = "Yes";
}
onoff
{
0 = "On";
1 = "Off";
}
offon
{
0 = "Off";
1 = "On";
}
updown
{
0 = "Up";
1 = "Down";
}
downup
{
0 = "Down";
1 = "Up";
}
addset
{
0 = "Add";
1 = "Set";
}
floorceiling
{
0 = "Floor";
1 = "Ceiling";
2 = "Floor and ceiling";
}
triggertype
{
0 = "Continuous";
1 = "Each Time (Enter)";
2 = "Each Time (Enter and leave)";
3 = "Once";
}
frontback
{
0 = "None";
1 = "Front";
2 = "Back";
}
ctfteam
{
0 = "None";
1 = "Red";
2 = "Blue";
}
triggerobjects
{
0 = "Any player";
1 = "All players";
2 = "Pushable object";
3 = "Any object with thinker";
}
triggersurfaces
{
0 = "Floor touch";
1 = "Ceiling touch";
2 = "Floor or ceiling touch";
3 = "Anywhere in sector";
}
tangibility
{
1 = "Intangible from top";
2 = "Intangible from bottom";
4 = "Don't block players";
8 = "Don't block non-players";
}
}
//Default things filters
thingsfilters
{
filter0
{
name = "Player starts";
category = "starts";
type = -1;
}
filter1
{
name = "Enemies";
category = "enemies";
type = -1;
}
filter2
{
name = "NiGHTS Track";
category = "nightstrk";
type = -1;
}
filter3
{
name = "Normal Gravity";
category = "";
type = -1;
fields
{
2 = false;
}
}
filter4
{
name = "Reverse Gravity";
category = "";
type = -1;
fields
{
2 = true;
}
}
}
thingsfilters_udmf
{
}
// Special linedefs
speciallinedefs
{
soundlinedefflag = 64; // See linedefflags
singlesidedflag = 1; // See linedefflags
doublesidedflag = 4; // See linedefflags
impassableflag = 1;
upperunpeggedflag = 8;
lowerunpeggedflag = 16;
repeatmidtextureflag = 1024;
pegmidtextureflag = 256;
}
speciallinedefs_udmf
{
soundlinedefflag = "noclimb";
singlesidedflag = "blocking";
doublesidedflag = "twosided";
impassableflag = "blocking";
upperunpeggedflag = "dontpegtop";
lowerunpeggedflag = "dontpegbottom";
repeatmidtextureflag = "wrapmidtex";
pegmidtextureflag = "midpeg";
}
scriptlumpnames
{
MAINCFG
{
script = "SOC.cfg";
}
OBJCTCFG
{
script = "SOC.cfg";
}
SOC_
{
script = "SOC.cfg";
isprefix = true;
}
LUA_
{
script = "Lua.cfg";
isprefix = true;
}
}
// Texture sources
textures
{
zdoom1
{
start = "TX_START";
end = "TX_END";
}
}
// Patch sources
patches
{
standard1
{
start = "P_START";
end = "P_END";
}
standard2
{
start = "PP_START";
end = "PP_END";
}
}
// Sprite sources
sprites
{
standard1
{
start = "S_START";
end = "S_END";
}
standard2
{
start = "SS_START";
end = "SS_END";
}
}
// Flat sources
flats
{
standard1
{
start = "F_START";
end = "F_END";
}
standard2
{
start = "FF_START";
end = "FF_END";
}
standard3
{
start = "FF_START";
end = "F_END";
}
standard4
{
start = "F_START";
end = "FF_END";
}
}

View file

@ -1,109 +0,0 @@
sectortypes
{
0 = "Normal";
1 = "Damage";
2 = "Damage (Water)";
3 = "Damage (Fire)";
4 = "Damage (Electrical)";
5 = "Spikes";
6 = "Death Pit (Camera Tilt)";
7 = "Death Pit (No Camera Tilt)";
8 = "Instant Kill";
9 = "Ring Drainer (Floor Touch)";
10 = "Ring Drainer (Anywhere in Sector)";
11 = "Special Stage Damage";
12 = "Space Countdown";
13 = "Ramp Sector (double step-up/down)";
14 = "Non-Ramp Sector (no step-down)";
15 = "Bouncy FOF";
16 = "Trigger Line Ex. (Pushable Objects)";
32 = "Trigger Line Ex. (Anywhere, All Players)";
48 = "Trigger Line Ex. (Floor Touch, All Players)";
64 = "Trigger Line Ex. (Anywhere in Sector)";
80 = "Trigger Line Ex. (Floor Touch)";
96 = "Trigger Line Ex. (Emerald Check)";
112 = "Trigger Line Ex. (NiGHTS Mare)";
128 = "Check for Linedef Executor on FOFs";
144 = "Egg Capsule";
160 = "Special Stage Time/Rings Parameters";
176 = "Custom Global Gravity";
512 = "Wind/Current";
1024 = "Conveyor Belt";
1280 = "Speed Pad";
4096 = "Star Post Activator";
8192 = "Exit/Special Stage Pit/Return Flag";
12288 = "CTF Red Team Base";
16384 = "CTF Blue Team Base";
20480 = "Fan Sector";
24576 = "Super Sonic Transform";
28672 = "Force Spin";
32768 = "Zoom Tube Start";
36864 = "Zoom Tube End";
40960 = "Circuit Finish Line";
45056 = "Rope Hang";
49152 = "Intangible to the Camera";
}
gen_sectortypes
{
first
{
0 = "Normal";
1 = "Damage";
2 = "Damage (Water)";
3 = "Damage (Fire)";
4 = "Damage (Electrical)";
5 = "Spikes";
6 = "Death Pit (Camera Tilt)";
7 = "Death Pit (No Camera Tilt)";
8 = "Instant Kill";
9 = "Ring Drainer (Floor Touch)";
10 = "Ring Drainer (Anywhere in Sector)";
11 = "Special Stage Damage";
12 = "Space Countdown";
13 = "Ramp Sector (double step-up/down)";
14 = "Non-Ramp Sector (no step-down)";
15 = "Bouncy FOF";
}
second
{
0 = "Normal";
16 = "Trigger Line Ex. (Pushable Objects)";
32 = "Trigger Line Ex. (Anywhere, All Players)";
48 = "Trigger Line Ex. (Floor Touch, All Players)";
64 = "Trigger Line Ex. (Anywhere in Sector)";
80 = "Trigger Line Ex. (Floor Touch)";
96 = "Trigger Line Ex. (Emerald Check)";
112 = "Trigger Line Ex. (NiGHTS Mare)";
128 = "Check for Linedef Executor on FOFs";
144 = "Egg Capsule";
160 = "Special Stage Time/Rings Parameters";
176 = "Custom Global Gravity";
}
third
{
0 = "Normal";
512 = "Wind/Current";
1024 = "Conveyor Belt";
1280 = "Speed Pad";
}
fourth
{
0 = "Normal";
4096 = "Star Post Activator";
8192 = "Exit/Special Stage Pit/Return Flag";
12288 = "CTF Red Team Base";
16384 = "CTF Blue Team Base";
20480 = "Fan Sector";
24576 = "Super Sonic Transform";
28672 = "Force Spin";
32768 = "Zoom Tube Start";
36864 = "Zoom Tube End";
40960 = "Circuit Finish Line";
45056 = "Rope Hang";
49152 = "Intangible to the Camera";
}
}

File diff suppressed because it is too large Load diff

View file

@ -15,7 +15,7 @@
* Oogaland * Oogaland
* Rob * Rob
* Shadow Hog * Shadow Hog
* Spherallic * sphere
* SRB2-Playah * SRB2-Playah
* SSNTails * SSNTails
* SteelT * SteelT
@ -435,7 +435,7 @@ sectortypes
112 = "Trigger Line Ex. (NiGHTS Mare)"; 112 = "Trigger Line Ex. (NiGHTS Mare)";
128 = "Check for Linedef Executor on FOFs"; 128 = "Check for Linedef Executor on FOFs";
144 = "Egg Capsule"; 144 = "Egg Capsule";
160 = "Special Stage Time/Rings Parameters"; 160 = "Special Stage Time/Spheres Parameters";
176 = "Custom Global Gravity"; 176 = "Custom Global Gravity";
512 = "Wind/Current"; 512 = "Wind/Current";
1024 = "Conveyor Belt"; 1024 = "Conveyor Belt";
@ -490,7 +490,7 @@ gen_sectortypes
112 = "Trigger Line Ex. (NiGHTS Mare)"; 112 = "Trigger Line Ex. (NiGHTS Mare)";
128 = "Check for Linedef Executor on FOFs"; 128 = "Check for Linedef Executor on FOFs";
144 = "Egg Capsule"; 144 = "Egg Capsule";
160 = "Special Stage Time/Rings Parameters"; 160 = "Special Stage Time/Spheres Parameters";
176 = "Custom Global Gravity"; 176 = "Custom Global Gravity";
} }
@ -738,12 +738,6 @@ linedeftypes
flags2text = "[1] Use control sector tag"; flags2text = "[1] Use control sector tag";
flags64text = "[6] No sound effect"; flags64text = "[6] No sound effect";
} }
65
{
title = "Bridge Thinker <disabled>";
prefix = "(65)";
}
} }
polyobject polyobject
@ -756,16 +750,12 @@ linedeftypes
prefix = "(20)"; prefix = "(20)";
} }
21
{
title = "Explicitly Include Line <disabled>";
prefix = "(21)";
}
22 22
{ {
title = "Parameters"; title = "Parameters";
prefix = "(22)"; prefix = "(22)";
flags8text = "[3] Set translucency by X offset";
flags32text = "[5] Render outer sides only";
flags64text = "[6] Trigger linedef executor"; flags64text = "[6] Trigger linedef executor";
flags128text = "[7] Intangible"; flags128text = "[7] Intangible";
flags256text = "[8] Stopped by pushables"; flags256text = "[8] Stopped by pushables";
@ -788,7 +778,6 @@ linedeftypes
{ {
title = "Angular Displacement by Front Sector"; title = "Angular Displacement by Front Sector";
prefix = "(32)"; prefix = "(32)";
flags8text = "[3] Set delay by backside sector";
flags64text = "[6] Don't turn players"; flags64text = "[6] Don't turn players";
flags512text = "[9] Turn all objects"; flags512text = "[9] Turn all objects";
} }
@ -1136,7 +1125,6 @@ linedeftypes
{ {
title = "Goo Water, Translucent, No Sides"; title = "Goo Water, Translucent, No Sides";
prefix = "(125)"; prefix = "(125)";
flags8text = "[3] Slope skew sides";
flags64text = "[6] Use two light levels"; flags64text = "[6] Use two light levels";
flags512text = "[9] Use target light level"; flags512text = "[9] Use target light level";
flags1024text = "[10] Ripple effect"; flags1024text = "[10] Ripple effect";
@ -1227,6 +1215,18 @@ linedeftypes
3dfloorflags = "19F"; 3dfloorflags = "19F";
} }
153
{
title = "Dynamically Sinking Platform";
prefix = "(153)";
flags8text = "[3] Slope skew sides";
flags32text = "[5] Only block player";
flags64text = "[6] Spindash to move";
flags128text = "[7] Only block non-players";
3dfloor = true;
3dfloorflags = "19F";
}
160 160
{ {
title = "Floating, Bobbing"; title = "Floating, Bobbing";
@ -1282,7 +1282,6 @@ linedeftypes
title = "Rising Platform, Solid, Invisible"; title = "Rising Platform, Solid, Invisible";
prefix = "(193)"; prefix = "(193)";
flags2text = "[1] Sink when stepped on"; flags2text = "[1] Sink when stepped on";
flags8text = "[3] Slope skew sides";
flags32text = "[5] Only block player"; flags32text = "[5] Only block player";
flags64text = "[6] Spindash to move"; flags64text = "[6] Spindash to move";
flags128text = "[7] Only block non-players"; flags128text = "[7] Only block non-players";
@ -1488,16 +1487,22 @@ linedeftypes
{ {
title = "Mario Block"; title = "Mario Block";
prefix = "(250)"; prefix = "(250)";
flags8text = "[3] Slope skew sides";
flags32text = "[5] Invisible block"; flags32text = "[5] Invisible block";
flags64text = "[6] Brick block"; flags64text = "[6] Brick block";
3dfloor = true; 3dfloor = true;
3dfloorflags = "40019F"; 3dfloorflags = "40019F";
flags323dfloorflagsremove = "19E";
flags643dfloorflagsadd = "200000";
} }
251 251
{ {
title = "Thwomp Block"; title = "Thwomp Block";
prefix = "(251)"; prefix = "(251)";
flags8text = "[3] Slope skew sides";
flags32text = "[5] Only block player";
flags128text = "[7] Only block non-players";
flags512text = "[9] Custom crushing sound"; flags512text = "[9] Custom crushing sound";
flags1024text = "[10] Custom speed"; flags1024text = "[10] Custom speed";
3dfloor = true; 3dfloor = true;
@ -1513,8 +1518,8 @@ linedeftypes
flags512text = "[9] Shattered by pushables"; flags512text = "[9] Shattered by pushables";
flags1024text = "[10] Trigger linedef executor"; flags1024text = "[10] Trigger linedef executor";
3dfloor = true; 3dfloor = true;
3dfloorflags = "8800019"; 3dfloorflags = "880001D";
flags643dfloorflagsadd = "200006"; flags643dfloorflagsadd = "200002";
} }
253 253
@ -1525,7 +1530,7 @@ linedeftypes
flags512text = "[9] Shattered by pushables"; flags512text = "[9] Shattered by pushables";
flags1024text = "[10] Trigger linedef executor"; flags1024text = "[10] Trigger linedef executor";
3dfloor = true; 3dfloor = true;
3dfloorflags = "8801019"; 3dfloorflags = "880101D";
} }
254 254
@ -1533,6 +1538,7 @@ linedeftypes
title = "Bustable Block"; title = "Bustable Block";
prefix = "(254)"; prefix = "(254)";
flags8text = "[3] Slope skew sides"; flags8text = "[3] Slope skew sides";
flags32text = "[5] Only block player";
flags64text = "[6] Strong characters only"; flags64text = "[6] Strong characters only";
flags128text = "[7] Only block non-players"; flags128text = "[7] Only block non-players";
flags512text = "[9] Shattered by pushables"; flags512text = "[9] Shattered by pushables";
@ -1593,6 +1599,7 @@ linedeftypes
{ {
title = "Custom FOF"; title = "Custom FOF";
prefix = "(259)"; prefix = "(259)";
flags8text = "[3] Slope skew sides";
flags32text = "[5] Only block player"; flags32text = "[5] Only block player";
flags128text = "[7] Only block non-players"; flags128text = "[7] Only block non-players";
flags512text = "[9] Shattered by pushables"; flags512text = "[9] Shattered by pushables";
@ -1896,6 +1903,27 @@ linedeftypes
prefix = "(333)"; prefix = "(333)";
} }
334
{
title = "Object Dye - Continuous";
flags64text = "[6] Disable for this color";
prefix = "(334)";
}
335
{
title = "Object Dye - Each Time";
flags64text = "[6] Disable for this color";
prefix = "(335)";
}
336
{
title = "Object Dye - Once";
flags64text = "[6] Disable for this color";
prefix = "(336)";
}
399 399
{ {
title = "Level Load"; title = "Level Load";
@ -2161,6 +2189,14 @@ linedeftypes
flags8text = "[3] Set delay by backside sector"; flags8text = "[3] Set delay by backside sector";
} }
449
{
title = "Enable Bosses with Parameter";
prefix = "(449)";
flags8text = "[3] Set delay by backside sector";
flags64text = "[6] Disable bosses";
}
457 457
{ {
title = "Track Object's Angle"; title = "Track Object's Angle";
@ -2180,12 +2216,15 @@ linedeftypes
{ {
title = "Award Rings"; title = "Award Rings";
prefix = "(460)"; prefix = "(460)";
flags8text = "[3] Set delay by backside sector";
} }
461 461
{ {
title = "Spawn Object"; title = "Spawn Object";
prefix = "(461)"; prefix = "(461)";
flags8text = "[3] Set delay by backside sector";
flags32text = "[5] Use line angle for object";
flags64text = "[6] Spawn inside a range"; flags64text = "[6] Spawn inside a range";
} }
@ -2193,6 +2232,20 @@ linedeftypes
{ {
title = "Stop Timer/Exit Stage in Record Attack"; title = "Stop Timer/Exit Stage in Record Attack";
prefix = "(462)"; prefix = "(462)";
flags8text = "[3] Set delay by backside sector";
}
463
{
title = "Dye Object";
prefix = "(463)";
}
464
{
title = "Trigger Egg Capsule";
prefix = "(464)";
flags64text = "[6] Don't end level";
} }
} }
@ -2206,7 +2259,7 @@ linedeftypes
prefix = "(413)"; prefix = "(413)";
flags2text = "[1] Keep after death"; flags2text = "[1] Keep after death";
flags8text = "[3] Set delay by backside sector"; flags8text = "[3] Set delay by backside sector";
flags32text = "[5] Seek to current song position"; flags32text = "[5] Seek from current position";
flags64text = "[6] For everyone"; flags64text = "[6] For everyone";
flags128text = "[7] Fade to custom volume"; flags128text = "[7] Fade to custom volume";
flags512text = "[9] Don't loop"; flags512text = "[9] Don't loop";
@ -2220,7 +2273,7 @@ linedeftypes
flags2text = "[1] From calling sector"; flags2text = "[1] From calling sector";
flags8text = "[3] Set delay by backside sector"; flags8text = "[3] Set delay by backside sector";
flags64text = "[6] From nowhere for triggerer"; flags64text = "[6] From nowhere for triggerer";
flags512text = "[9] For everyone"; flags512text = "[9] From nowhere for everyone";
flags1024text = "[10] From tagged sectors"; flags1024text = "[10] From tagged sectors";
} }
@ -2298,7 +2351,6 @@ linedeftypes
flags8text = "[3] Set delay by backside sector"; flags8text = "[3] Set delay by backside sector";
} }
445 445
{ {
title = "Make FOF Disappear/Reappear"; title = "Make FOF Disappear/Reappear";
@ -2325,8 +2377,8 @@ linedeftypes
flags32text = "[5] Subtract Red value"; flags32text = "[5] Subtract Red value";
flags64text = "[6] Subtract Green value"; flags64text = "[6] Subtract Green value";
flags128text = "[7] Subtract Blue value"; flags128text = "[7] Subtract Blue value";
flags256text = "[8] Calc relative values"; flags256text = "[8] Set relative to current";
flags32768text = "[15] Use back side colormap"; flags32768text = "[15] Use backside colormap";
} }
448 448
@ -2359,7 +2411,7 @@ linedeftypes
prefix = "(452)"; prefix = "(452)";
flags8text = "[3] Set delay by backside sector"; flags8text = "[3] Set delay by backside sector";
flags64text = "[6] Do not handle FF_TRANS"; flags64text = "[6] Do not handle FF_TRANS";
flags256text = "[8] Set relative to current val"; flags256text = "[8] Set relative to current";
} }
453 453
@ -2371,7 +2423,7 @@ linedeftypes
flags32text = "[5] No collision during fade"; flags32text = "[5] No collision during fade";
flags64text = "[6] Do not handle FF_TRANS"; flags64text = "[6] Do not handle FF_TRANS";
flags128text = "[7] Do not handle lighting"; flags128text = "[7] Do not handle lighting";
flags256text = "[8] Set relative to current val"; flags256text = "[8] Set relative to current";
flags512text = "[9] Speed = Tic Duration"; flags512text = "[9] Speed = Tic Duration";
flags1024text = "[10] Override existing fade"; flags1024text = "[10] Override existing fade";
flags16384text = "[14] Do not handle collision"; flags16384text = "[14] Do not handle collision";
@ -2395,11 +2447,11 @@ linedeftypes
flags32text = "[5] Subtract Red value"; flags32text = "[5] Subtract Red value";
flags64text = "[6] Subtract Green value"; flags64text = "[6] Subtract Green value";
flags128text = "[7] Subtract Blue value"; flags128text = "[7] Subtract Blue value";
flags256text = "[8] Calc relative values"; flags256text = "[8] Set relative to current";
flags512text = "[9] Speed = Tic Duration"; flags512text = "[9] Speed = Tic Duration";
flags1024text = "[10] Override existing fade"; flags1024text = "[10] Override existing fade";
flags16384text = "[14] Fade from invisible black"; flags16384text = "[14] Fade from invisible black";
flags32768text = "[15] Use back side colormap"; flags32768text = "[15] Use backside colormap";
} }
456 456
@ -2416,9 +2468,7 @@ linedeftypes
flags2text = "[1] Close text prompt"; flags2text = "[1] Close text prompt";
flags8text = "[3] Set delay by backside sector"; flags8text = "[3] Set delay by backside sector";
flags32text = "[5] Run executor tag on close"; flags32text = "[5] Run executor tag on close";
flags64text = "[6] For everyone"; flags128text = "[7] Don't disable controls";
flags128text = "[7] Do not block controls";
flags256text = "[8] Do not freeze time";
flags32768text = "[15] Find prompt by name"; flags32768text = "[15] Find prompt by name";
} }
} }
@ -2524,7 +2574,7 @@ linedeftypes
prefix = "(491)"; prefix = "(491)";
flags8text = "[3] Set delay by backside sector"; flags8text = "[3] Set delay by backside sector";
flags16text = "[4] Set raw alpha by Front X"; flags16text = "[4] Set raw alpha by Front X";
flags256text = "[8] Calc relative values"; flags256text = "[8] Set relative to current";
} }
492 492
@ -2534,7 +2584,7 @@ linedeftypes
flags8text = "[3] Set delay by backside sector"; flags8text = "[3] Set delay by backside sector";
flags16text = "[4] Set raw alpha by Front X"; flags16text = "[4] Set raw alpha by Front X";
flags32text = "[5] No collision during fade"; flags32text = "[5] No collision during fade";
flags256text = "[8] Calc relative values"; flags256text = "[8] Set relative to current";
flags512text = "[9] Speed = Tic Duration"; flags512text = "[9] Speed = Tic Duration";
flags1024text = "[10] Override existing fade"; flags1024text = "[10] Override existing fade";
flags16384text = "[14] Do not handle collision"; flags16384text = "[14] Do not handle collision";
@ -2632,76 +2682,84 @@ linedeftypes
{ {
title = "Carry Objects on Floor"; title = "Carry Objects on Floor";
prefix = "(520)"; prefix = "(520)";
flags64text = "[6] Exclusive";
} }
521 521
{ {
title = "Carry Objects on Floor (Accelerative)"; title = "Carry Objects on Floor (Accelerative)";
prefix = "(521)"; prefix = "(521)";
flags64text = "[6] Even across edges"; flags64text = "[6] Exclusive";
} }
522 522
{ {
title = "Carry Objects on Floor (Displacement)"; title = "Carry Objects on Floor (Displacement)";
prefix = "(522)"; prefix = "(522)";
flags64text = "[6] Exclusive";
} }
523 523
{ {
title = "Carry Objects on Ceiling"; title = "Carry Objects on Ceiling";
prefix = "(523)"; prefix = "(523)";
flags64text = "[6] Even across edges"; flags64text = "[6] Exclusive";
} }
524 524
{ {
title = "Carry Objects on Ceiling (Accelerative)"; title = "Carry Objects on Ceiling (Accelerative)";
prefix = "(524)"; prefix = "(524)";
flags64text = "[6] Exclusive";
} }
525 525
{ {
title = "Carry Objects on Ceiling (Displacement)"; title = "Carry Objects on Ceiling (Displacement)";
prefix = "(525)"; prefix = "(525)";
flags64text = "[6] Exclusive";
} }
530 530
{ {
title = "Scroll Floor Texture and Carry Objects"; title = "Scroll Floor Texture and Carry Objects";
prefix = "(530)"; prefix = "(530)";
flags64text = "[6] Even across edges"; flags64text = "[6] Exclusive";
} }
531 531
{ {
title = "Scroll Floor Texture and Carry Objects (Accelerative)"; title = "Scroll Floor Texture and Carry Objects (Accelerative)";
prefix = "(531)"; prefix = "(531)";
flags64text = "[6] Exclusive";
} }
532 532
{ {
title = "Scroll Floor Texture and Carry Objects (Displacement)"; title = "Scroll Floor Texture and Carry Objects (Displacement)";
prefix = "(532)"; prefix = "(532)";
flags64text = "[6] Exclusive";
} }
533 533
{ {
title = "Scroll Ceiling Texture and Carry Objects"; title = "Scroll Ceiling Texture and Carry Objects";
prefix = "(533)"; prefix = "(533)";
flags64text = "[6] Even across edges"; flags64text = "[6] Exclusive";
} }
534 534
{ {
title = "Scroll Ceiling Texture and Carry Objects (Accelerative)"; title = "Scroll Ceiling Texture and Carry Objects (Accelerative)";
prefix = "(534)"; prefix = "(534)";
flags64text = "[6] Exclusive";
} }
535 535
{ {
title = "Scroll Ceiling Texture and Carry Objects (Displacement)"; title = "Scroll Ceiling Texture and Carry Objects (Displacement)";
prefix = "(535)"; prefix = "(535)";
flags64text = "[6] Exclusive";
} }
} }
@ -2714,7 +2772,7 @@ linedeftypes
title = "Wind"; title = "Wind";
prefix = "(541)"; prefix = "(541)";
flags512text = "[9] Player slides"; flags512text = "[9] Player slides";
flags64text = "[6] Even across edges"; flags64text = "[6] Exclusive";
} }
542 542
@ -2722,7 +2780,7 @@ linedeftypes
title = "Upwards Wind"; title = "Upwards Wind";
prefix = "(542)"; prefix = "(542)";
flags512text = "[9] Player slides"; flags512text = "[9] Player slides";
flags64text = "[6] Even across edges"; flags64text = "[6] Exclusive";
} }
543 543
@ -2730,7 +2788,7 @@ linedeftypes
title = "Downwards Wind"; title = "Downwards Wind";
prefix = "(543)"; prefix = "(543)";
flags512text = "[9] Player slides"; flags512text = "[9] Player slides";
flags64text = "[6] Even across edges"; flags64text = "[6] Exclusive";
} }
544 544
@ -2738,7 +2796,7 @@ linedeftypes
title = "Current"; title = "Current";
prefix = "(544)"; prefix = "(544)";
flags512text = "[9] Player slides"; flags512text = "[9] Player slides";
flags64text = "[6] Even across edges"; flags64text = "[6] Exclusive";
} }
545 545
@ -2746,7 +2804,7 @@ linedeftypes
title = "Upwards Current"; title = "Upwards Current";
prefix = "(545)"; prefix = "(545)";
flags512text = "[9] Player slides"; flags512text = "[9] Player slides";
flags64text = "[6] Even across edges"; flags64text = "[6] Exclusive";
} }
546 546
@ -2754,13 +2812,14 @@ linedeftypes
title = "Downwards Current"; title = "Downwards Current";
prefix = "(546)"; prefix = "(546)";
flags512text = "[9] Player slides"; flags512text = "[9] Player slides";
flags64text = "[6] Even across edges"; flags64text = "[6] Exclusive";
} }
547 547
{ {
title = "Push/Pull"; title = "Push/Pull";
prefix = "(547)"; prefix = "(547)";
flags64text = "[6] Exclusive";
} }
} }
@ -3407,8 +3466,8 @@ thingtypes
sprite = "ESHIA1"; sprite = "ESHIA1";
width = 16; width = 16;
height = 48; height = 48;
flags1text = "[1] 90 degrees counter-clockwise"; flags1text = "[1] 90 degrees clockwise";
flags4text = "[4] 90 degrees clockwise"; flags4text = "[4] 90 degrees counter-clockwise";
flags8text = "[8] Double speed"; flags8text = "[8] Double speed";
} }
115 115
@ -3674,6 +3733,7 @@ thingtypes
width = 8; width = 8;
height = 16; height = 16;
sprite = "internal:capsule"; sprite = "internal:capsule";
angletext = "Tag";
} }
292 292
{ {
@ -3870,6 +3930,8 @@ thingtypes
{ {
title = "Emerald Hunt Location"; title = "Emerald Hunt Location";
sprite = "SHRDA0"; sprite = "SHRDA0";
flags8height = 24;
flags8text = "[8] Float";
} }
321 321
{ {
@ -3897,9 +3959,10 @@ thingtypes
title = "Monitors"; title = "Monitors";
width = 18; width = 18;
height = 40; height = 40;
flags1text = "[1] Run Linedef Executor on pop"; flags1text = "[1] Run linedef executor on pop";
flags4text = "[4] Random (Strong)"; flags4text = "[4] Random (Strong)";
flags8text = "[8] Random (Weak)"; flags8text = "[8] Random (Weak)";
angletext = "Tag";
400 400
{ {
@ -4029,7 +4092,8 @@ thingtypes
title = "Monitors (Respawning)"; title = "Monitors (Respawning)";
width = 20; width = 20;
height = 44; height = 44;
flags1text = "[1] Run Linedef Executor on pop"; flags1text = "[1] Run linedef executor on pop";
angletext = "Tag";
431 431
{ {
@ -4125,7 +4189,9 @@ thingtypes
sprite = "STPTA0M0"; sprite = "STPTA0M0";
width = 64; width = 64;
height = 128; height = 128;
flags4text = "[4] Respawn at center";
angletext = "Angle/Order"; angletext = "Angle/Order";
parametertext = "Order";
} }
520 520
{ {
@ -4152,6 +4218,7 @@ thingtypes
sprite = "WSPKALAR"; sprite = "WSPKALAR";
width = 16; width = 16;
height = 14; height = 14;
arrow = 1;
flags1text = "[1] Start retracted"; flags1text = "[1] Start retracted";
flags4text = "[4] Retractable"; flags4text = "[4] Retractable";
flags8text = "[8] Intangible"; flags8text = "[8] Intangible";
@ -4558,6 +4625,7 @@ thingtypes
sprite = "TOADA0"; sprite = "TOADA0";
width = 32; width = 32;
height = 16; height = 16;
angletext = "Tag";
} }
757 757
{ {
@ -5832,7 +5900,7 @@ thingtypes
sprite = "CAPSA0"; sprite = "CAPSA0";
width = 72; width = 72;
height = 144; height = 144;
angletext = "Rings"; angletext = "Spheres";
parametertext = "Mare"; parametertext = "Mare";
} }
} }
@ -6273,7 +6341,7 @@ thingtypes
sprite = "PUMKA0"; sprite = "PUMKA0";
width = 16; width = 16;
height = 40; height = 40;
flags1text = "Don't flicker"; flags1text = "[1] Don't flicker";
} }
2007 2007
{ {
@ -6281,7 +6349,7 @@ thingtypes
sprite = "PUMKB0"; sprite = "PUMKB0";
width = 16; width = 16;
height = 40; height = 40;
flags1text = "Don't flicker"; flags1text = "[1] Don't flicker";
} }
2008 2008
{ {
@ -6289,7 +6357,7 @@ thingtypes
sprite = "PUMKC0"; sprite = "PUMKC0";
width = 16; width = 16;
height = 40; height = 40;
flags1text = "Don't flicker"; flags1text = "[1] Don't flicker";
} }
2009 2009
{ {

View file

@ -1,38 +0,0 @@
/************************************************************************\
Zone Builder Game Configuration for Sonic Robo Blast 2 Version 2.2
\************************************************************************/
// This is required to prevent accidental use of a different configuration
type = "Doom Builder 2 Game Configuration";
// This is the title to show for this game
game = "Sonic Robo Blast 2 - 2.2 (Doom format)";
// This is the simplified game engine/sourceport name
engine = "zdoom";
// Settings common to all games and all map formats
include("Includes\\SRB222_common.cfg", "common");
// Settings common to Doom map format
include("Includes\\SRB222_common.cfg", "mapformat_doom");
include("Includes\\Game_SRB222.cfg");
// Script lumps detection
scriptlumpnames
{
include("Includes\\SRB222_misc.cfg", "scriptlumpnames");
}
// THING TYPES
thingtypes
{
include("Includes\\SRB222_things.cfg");
}
//Default things filters
thingsfilters
{
include("Includes\\SRB222_misc.cfg", "thingsfilters");
}

View file

@ -1,47 +0,0 @@
/************************************************************************\
Zone Builder Game Configuration for Sonic Robo Blast 2 Version 2.2
\************************************************************************/
// This is required to prevent accidental use of a different configuration
type = "Doom Builder 2 Game Configuration";
// This is the title to show for this game
game = "Sonic Robo Blast 2 - 2.2 (UDMF)";
// This is the simplified game engine/sourceport name
engine = "zdoom";
// Settings common to all games and all map formats
include("Includes\\SRB222_common.cfg", "common");
// Settings common to Doom map format
include("Includes\\SRB222_common.cfg", "mapformat_udmf");
include("Includes\\Game_SRB222.cfg");
// Script lumps detection
scriptlumpnames
{
include("Includes\\SRB222_misc.cfg", "scriptlumpnames");
}
// THING TYPES
thingtypes
{
include("Includes\\SRB222_things.cfg");
}
//Default things filters
thingsfilters
{
include("Includes\\SRB222_misc.cfg", "thingsfilters");
}
// ENUMERATIONS
// Each engine has its own additional thing types
// These are enumerated lists for linedef types and UDMF fields.
enums
{
// Basic game enums
include("Includes\\SRB222_misc.cfg", "enums");
}

View file

@ -16,6 +16,7 @@ set(SRB2_CORE_SOURCES
f_finale.c f_finale.c
f_wipe.c f_wipe.c
filesrch.c filesrch.c
g_demo.c
g_game.c g_game.c
g_input.c g_input.c
hu_stuff.c hu_stuff.c
@ -71,6 +72,7 @@ set(SRB2_CORE_HEADERS
f_finale.h f_finale.h
fastcmp.h fastcmp.h
filesrch.h filesrch.h
g_demo.h
g_game.h g_game.h
g_input.h g_input.h
g_state.h g_state.h
@ -120,6 +122,7 @@ set(SRB2_CORE_RENDER_SOURCES
r_main.c r_main.c
r_plane.c r_plane.c
r_segs.c r_segs.c
r_skins.c
r_sky.c r_sky.c
r_splats.c r_splats.c
r_things.c r_things.c
@ -134,6 +137,7 @@ set(SRB2_CORE_RENDER_SOURCES
r_main.h r_main.h
r_plane.h r_plane.h
r_segs.h r_segs.h
r_skins.h
r_sky.h r_sky.h
r_splats.h r_splats.h
r_state.h r_state.h
@ -214,8 +218,6 @@ source_group("Assembly" FILES ${SRB2_ASM_SOURCES} ${SRB2_NASM_SOURCES})
### Configuration ### Configuration
set(SRB2_CONFIG_HAVE_BLUA ON CACHE BOOL
"Enable Lua interpreter support")
set(SRB2_CONFIG_HAVE_PNG ON CACHE BOOL set(SRB2_CONFIG_HAVE_PNG ON CACHE BOOL
"Enable PNG support. Depends on zlib, so will be disabled if you don't enable that too.") "Enable PNG support. Depends on zlib, so will be disabled if you don't enable that too.")
set(SRB2_CONFIG_HAVE_ZLIB ON CACHE BOOL set(SRB2_CONFIG_HAVE_ZLIB ON CACHE BOOL
@ -239,92 +241,90 @@ if(${CMAKE_SYSTEM} MATCHES "Windows") ###set on Windows only
"Use SRB2's internal copies of required dependencies (SDL2, PNG, zlib, GME, OpenMPT).") "Use SRB2's internal copies of required dependencies (SDL2, PNG, zlib, GME, OpenMPT).")
endif() endif()
if(${SRB2_CONFIG_HAVE_BLUA}) set(SRB2_LUA_SOURCES
add_definitions(-DHAVE_BLUA) lua_baselib.c
set(SRB2_LUA_SOURCES lua_blockmaplib.c
lua_baselib.c lua_consolelib.c
lua_blockmaplib.c lua_hooklib.c
lua_consolelib.c lua_hudlib.c
lua_hooklib.c lua_infolib.c
lua_hudlib.c lua_maplib.c
lua_infolib.c lua_mathlib.c
lua_maplib.c lua_mobjlib.c
lua_mathlib.c lua_playerlib.c
lua_mobjlib.c lua_script.c
lua_playerlib.c lua_skinlib.c
lua_script.c lua_thinkerlib.c
lua_skinlib.c )
lua_thinkerlib.c set(SRB2_LUA_HEADERS
) lua_hook.h
set(SRB2_LUA_HEADERS lua_hud.h
lua_hook.h lua_libs.h
lua_hud.h lua_script.h
lua_libs.h )
lua_script.h
)
prepend_sources(SRB2_LUA_SOURCES) prepend_sources(SRB2_LUA_SOURCES)
prepend_sources(SRB2_LUA_HEADERS) prepend_sources(SRB2_LUA_HEADERS)
source_group("LUA" FILES ${SRB2_LUA_SOURCES} ${SRB2_LUA_HEADERS}) source_group("LUA" FILES ${SRB2_LUA_SOURCES} ${SRB2_LUA_HEADERS})
set(SRB2_BLUA_SOURCES set(SRB2_BLUA_SOURCES
blua/lapi.c blua/lapi.c
blua/lauxlib.c blua/lauxlib.c
blua/lbaselib.c blua/lbaselib.c
blua/lcode.c blua/lcode.c
blua/ldebug.c blua/ldebug.c
blua/ldo.c blua/ldo.c
blua/ldump.c blua/ldump.c
blua/lfunc.c blua/lfunc.c
blua/lgc.c blua/lgc.c
blua/linit.c blua/linit.c
blua/llex.c blua/liolib.c
blua/lmem.c blua/llex.c
blua/lobject.c blua/lmem.c
blua/lopcodes.c blua/lobject.c
blua/lparser.c blua/lopcodes.c
blua/lstate.c blua/lparser.c
blua/lstring.c blua/lstate.c
blua/lstrlib.c blua/lstring.c
blua/ltable.c blua/lstrlib.c
blua/ltablib.c blua/ltable.c
blua/ltm.c blua/ltablib.c
blua/lundump.c blua/ltm.c
blua/lvm.c blua/lundump.c
blua/lzio.c blua/lvm.c
) blua/lzio.c
set(SRB2_BLUA_HEADERS )
blua/lapi.h set(SRB2_BLUA_HEADERS
blua/lauxlib.h blua/lapi.h
blua/lcode.h blua/lauxlib.h
blua/ldebug.h blua/lcode.h
blua/ldo.h blua/ldebug.h
blua/lfunc.h blua/ldo.h
blua/lgc.h blua/lfunc.h
blua/llex.h blua/lgc.h
blua/llimits.h blua/llex.h
blua/lmem.h blua/llimits.h
blua/lobject.h blua/lmem.h
blua/lopcodes.h blua/lobject.h
blua/lparser.h blua/lopcodes.h
blua/lstate.h blua/lparser.h
blua/lstring.h blua/lstate.h
blua/ltable.h blua/lstring.h
blua/ltm.h blua/ltable.h
blua/lua.h blua/ltm.h
blua/luaconf.h blua/lua.h
blua/lualib.h blua/luaconf.h
blua/lundump.h blua/lualib.h
blua/lvm.h blua/lundump.h
blua/lzio.h blua/lvm.h
) blua/lzio.h
)
prepend_sources(SRB2_BLUA_SOURCES) prepend_sources(SRB2_BLUA_SOURCES)
prepend_sources(SRB2_BLUA_HEADERS) prepend_sources(SRB2_BLUA_HEADERS)
source_group("LUA\\Interpreter" FILES ${SRB2_BLUA_SOURCES} ${SRB2_BLUA_HEADERS}) source_group("LUA\\Interpreter" FILES ${SRB2_BLUA_SOURCES} ${SRB2_BLUA_HEADERS})
endif()
if(${SRB2_CONFIG_HAVE_GME}) if(${SRB2_CONFIG_HAVE_GME})
if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES}) if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES})

View file

@ -340,9 +340,7 @@ CFLAGS+=-DHAVE_MINIUPNPC
endif endif
endif endif
ifndef NO_LUA include blua/Makefile.cfg
include blua/Makefile.cfg
endif
ifdef NOMD5 ifdef NOMD5
OPTS+=-DNOMD5 OPTS+=-DNOMD5
@ -424,6 +422,7 @@ OBJS:=$(i_main_o) \
$(OBJDIR)/z_zone.o \ $(OBJDIR)/z_zone.o \
$(OBJDIR)/f_finale.o \ $(OBJDIR)/f_finale.o \
$(OBJDIR)/f_wipe.o \ $(OBJDIR)/f_wipe.o \
$(OBJDIR)/g_demo.o \
$(OBJDIR)/g_game.o \ $(OBJDIR)/g_game.o \
$(OBJDIR)/g_input.o \ $(OBJDIR)/g_input.o \
$(OBJDIR)/am_map.o \ $(OBJDIR)/am_map.o \
@ -468,6 +467,7 @@ OBJS:=$(i_main_o) \
$(OBJDIR)/r_main.o \ $(OBJDIR)/r_main.o \
$(OBJDIR)/r_plane.o \ $(OBJDIR)/r_plane.o \
$(OBJDIR)/r_segs.o \ $(OBJDIR)/r_segs.o \
$(OBJDIR)/r_skins.o \
$(OBJDIR)/r_sky.o \ $(OBJDIR)/r_sky.o \
$(OBJDIR)/r_splats.o \ $(OBJDIR)/r_splats.o \
$(OBJDIR)/r_things.o \ $(OBJDIR)/r_things.o \
@ -682,9 +682,7 @@ $(OBJDIR)/depend.dep:
ifndef NOHW ifndef NOHW
$(CC) $(CFLAGS) -MM hardware/*.c >> $(OBJDIR)/depend.ped $(CC) $(CFLAGS) -MM hardware/*.c >> $(OBJDIR)/depend.ped
endif endif
ifndef NO_LUA
$(CC) $(CFLAGS) -MM blua/*.c >> $(OBJDIR)/depend.ped $(CC) $(CFLAGS) -MM blua/*.c >> $(OBJDIR)/depend.ped
endif
@sed -e 's,\(.*\)\.o: ,$(subst /,\/,$(OBJDIR))\/&,g' < $(OBJDIR)/depend.ped > $(OBJDIR)/depend.dep @sed -e 's,\(.*\)\.o: ,$(subst /,\/,$(OBJDIR))\/&,g' < $(OBJDIR)/depend.ped > $(OBJDIR)/depend.dep
$(REMOVE) $(OBJDIR)/depend.ped $(REMOVE) $(OBJDIR)/depend.ped
@echo "Created dependency file, depend.dep" @echo "Created dependency file, depend.dep"

View file

@ -920,10 +920,8 @@ static inline void AM_drawWalls(void)
{ {
size_t i; size_t i;
static mline_t l; static mline_t l;
#ifdef ESLOPE
fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends
fixed_t backf1 = 0, backf2 = 0, backc1 = 0, backc2 = 0; // back floor ceiling ends fixed_t backf1 = 0, backf2 = 0, backc1 = 0, backc2 = 0; // back floor ceiling ends
#endif
for (i = 0; i < numlines; i++) for (i = 0; i < numlines; i++)
{ {
@ -931,13 +929,10 @@ static inline void AM_drawWalls(void)
l.a.y = lines[i].v1->y >> FRACTOMAPBITS; l.a.y = lines[i].v1->y >> FRACTOMAPBITS;
l.b.x = lines[i].v2->x >> FRACTOMAPBITS; l.b.x = lines[i].v2->x >> FRACTOMAPBITS;
l.b.y = lines[i].v2->y >> FRACTOMAPBITS; l.b.y = lines[i].v2->y >> FRACTOMAPBITS;
#ifdef ESLOPE
#define SLOPEPARAMS(slope, end1, end2, normalheight) \ #define SLOPEPARAMS(slope, end1, end2, normalheight) \
if (slope) { \ end1 = P_GetZAt(slope, lines[i].v1->x, lines[i].v1->y, normalheight); \
end1 = P_GetZAt(slope, lines[i].v1->x, lines[i].v1->y); \ end2 = P_GetZAt(slope, lines[i].v2->x, lines[i].v2->y, normalheight);
end2 = P_GetZAt(slope, lines[i].v2->x, lines[i].v2->y); \
} else \
end1 = end2 = normalheight;
SLOPEPARAMS(lines[i].frontsector->f_slope, frontf1, frontf2, lines[i].frontsector->floorheight) SLOPEPARAMS(lines[i].frontsector->f_slope, frontf1, frontf2, lines[i].frontsector->floorheight)
SLOPEPARAMS(lines[i].frontsector->c_slope, frontc1, frontc2, lines[i].frontsector->ceilingheight) SLOPEPARAMS(lines[i].frontsector->c_slope, frontc1, frontc2, lines[i].frontsector->ceilingheight)
@ -946,7 +941,6 @@ static inline void AM_drawWalls(void)
SLOPEPARAMS(lines[i].backsector->c_slope, backc1, backc2, lines[i].backsector->ceilingheight) SLOPEPARAMS(lines[i].backsector->c_slope, backc1, backc2, lines[i].backsector->ceilingheight)
} }
#undef SLOPEPARAMS #undef SLOPEPARAMS
#endif
if (!lines[i].backsector) // 1-sided if (!lines[i].backsector) // 1-sided
{ {
@ -955,19 +949,11 @@ static inline void AM_drawWalls(void)
else else
AM_drawMline(&l, WALLCOLORS); AM_drawMline(&l, WALLCOLORS);
} }
#ifdef ESLOPE
else if ((backf1 == backc1 && backf2 == backc2) // Back is thok barrier else if ((backf1 == backc1 && backf2 == backc2) // Back is thok barrier
|| (frontf1 == frontc1 && frontf2 == frontc2)) // Front is thok barrier || (frontf1 == frontc1 && frontf2 == frontc2)) // Front is thok barrier
{ {
if (backf1 == backc1 && backf2 == backc2 if (backf1 == backc1 && backf2 == backc2
&& frontf1 == frontc1 && frontf2 == frontc2) // BOTH are thok barriers && frontf1 == frontc1 && frontf2 == frontc2) // BOTH are thok barriers
#else
else if (lines[i].backsector->floorheight == lines[i].backsector->ceilingheight // Back is thok barrier
|| lines[i].frontsector->floorheight == lines[i].frontsector->ceilingheight) // Front is thok barrier
{
if (lines[i].backsector->floorheight == lines[i].backsector->ceilingheight
&& lines[i].frontsector->floorheight == lines[i].frontsector->ceilingheight) // BOTH are thok barriers
#endif
{ {
if (lines[i].flags & ML_NOCLIMB) if (lines[i].flags & ML_NOCLIMB)
AM_drawMline(&l, NOCLIMBTSWALLCOLORS); AM_drawMline(&l, NOCLIMBTSWALLCOLORS);
@ -985,20 +971,10 @@ static inline void AM_drawWalls(void)
else else
{ {
if (lines[i].flags & ML_NOCLIMB) { if (lines[i].flags & ML_NOCLIMB) {
#ifdef ESLOPE
if (backf1 != frontf1 || backf2 != frontf2) { if (backf1 != frontf1 || backf2 != frontf2) {
#else
if (lines[i].backsector->floorheight
!= lines[i].frontsector->floorheight) {
#endif
AM_drawMline(&l, NOCLIMBFDWALLCOLORS); // floor level change AM_drawMline(&l, NOCLIMBFDWALLCOLORS); // floor level change
} }
#ifdef ESLOPE
else if (backc1 != frontc1 || backc2 != frontc2) { else if (backc1 != frontc1 || backc2 != frontc2) {
#else
else if (lines[i].backsector->ceilingheight
!= lines[i].frontsector->ceilingheight) {
#endif
AM_drawMline(&l, NOCLIMBCDWALLCOLORS); // ceiling level change AM_drawMline(&l, NOCLIMBCDWALLCOLORS); // ceiling level change
} }
else else
@ -1006,20 +982,10 @@ static inline void AM_drawWalls(void)
} }
else else
{ {
#ifdef ESLOPE
if (backf1 != frontf1 || backf2 != frontf2) { if (backf1 != frontf1 || backf2 != frontf2) {
#else
if (lines[i].backsector->floorheight
!= lines[i].frontsector->floorheight) {
#endif
AM_drawMline(&l, FDWALLCOLORS); // floor level change AM_drawMline(&l, FDWALLCOLORS); // floor level change
} }
#ifdef ESLOPE
else if (backc1 != frontc1 || backc2 != frontc2) { else if (backc1 != frontc1 || backc2 != frontc2) {
#else
else if (lines[i].backsector->ceilingheight
!= lines[i].frontsector->ceilingheight) {
#endif
AM_drawMline(&l, CDWALLCOLORS); // ceiling level change AM_drawMline(&l, CDWALLCOLORS); // ceiling level change
} }
else else

View file

@ -19,10 +19,10 @@ boolean allow_fullscreen = false;
consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
void I_StartupGraphics(void){} void I_StartupGraphics(void){}
void I_StartupHardwareGraphics(void){}
void I_ShutdownGraphics(void){} void I_ShutdownGraphics(void){}
void VID_StartupOpenGL(void){}
void I_SetPalette(RGBA_t *palette) void I_SetPalette(RGBA_t *palette)
{ {
(void)palette; (void)palette;
@ -52,10 +52,8 @@ INT32 VID_SetMode(INT32 modenum)
return 0; return 0;
} }
void VID_CheckRenderer(void) void VID_CheckRenderer(void) {}
{ void VID_CheckGLLoaded(rendermode_t oldrender) {}
// ..............
}
const char *VID_GetModeName(INT32 modenum) const char *VID_GetModeName(INT32 modenum)
{ {

View file

@ -74,11 +74,9 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd)
if (!sonic || sonic->health <= 0) if (!sonic || sonic->health <= 0)
return; return;
#ifdef HAVE_BLUA
// Lua can handle it! // Lua can handle it!
if (LUAh_BotAI(sonic, tails, cmd)) if (LUAh_BotAI(sonic, tails, cmd))
return; return;
#endif
if (tails->player->powers[pw_carry] == CR_MACESPIN || tails->player->powers[pw_carry] == CR_GENERIC) if (tails->player->powers[pw_carry] == CR_MACESPIN || tails->player->powers[pw_carry] == CR_GENERIC)
{ {
@ -364,11 +362,9 @@ void B_BuildTiccmd(player_t *player, ticcmd_t *cmd)
// Bot AI isn't programmed in analog. // Bot AI isn't programmed in analog.
CV_SetValue(&cv_analog[1], false); CV_SetValue(&cv_analog[1], false);
#ifdef HAVE_BLUA
// Let Lua scripts build ticcmds // Let Lua scripts build ticcmds
if (LUAh_BotTiccmd(player, cmd)) if (LUAh_BotTiccmd(player, cmd))
return; return;
#endif
// We don't have any main character AI, sorry. D: // We don't have any main character AI, sorry. D:
if (player-players == consoleplayer) if (player-players == consoleplayer)
@ -463,6 +459,19 @@ boolean B_CheckRespawn(player_t *player)
if (!sonic || sonic->health <= 0) if (!sonic || sonic->health <= 0)
return false; return false;
// B_RespawnBot doesn't do anything if the condition above this isn't met
{
UINT8 shouldForce = LUAh_BotRespawn(sonic, tails);
if (P_MobjWasRemoved(sonic) || P_MobjWasRemoved(tails))
return (shouldForce == 1); // mobj was removed
if (shouldForce == 1)
return true;
else if (shouldForce == 2)
return false;
}
// Check if Sonic is busy first. // Check if Sonic is busy first.
// If he's doing any of these things, he probably doesn't want to see us. // If he's doing any of these things, he probably doesn't want to see us.
if (sonic->player->pflags & (PF_GLIDING|PF_SLIDING|PF_BOUNCING) if (sonic->player->pflags & (PF_GLIDING|PF_SLIDING|PF_BOUNCING)

View file

@ -10,14 +10,13 @@ WFLAGS+=-Wno-logical-op
endif endif
endif endif
OPTS+=-DHAVE_BLUA
OBJS:=$(OBJS) \ OBJS:=$(OBJS) \
$(OBJDIR)/lapi.o \ $(OBJDIR)/lapi.o \
$(OBJDIR)/lbaselib.o \ $(OBJDIR)/lbaselib.o \
$(OBJDIR)/ldo.o \ $(OBJDIR)/ldo.o \
$(OBJDIR)/lfunc.o \ $(OBJDIR)/lfunc.o \
$(OBJDIR)/linit.o \ $(OBJDIR)/linit.o \
$(OBJDIR)/liolib.o \
$(OBJDIR)/llex.o \ $(OBJDIR)/llex.o \
$(OBJDIR)/lmem.o \ $(OBJDIR)/lmem.o \
$(OBJDIR)/lobject.o \ $(OBJDIR)/lobject.o \

View file

@ -17,6 +17,7 @@
static const luaL_Reg lualibs[] = { static const luaL_Reg lualibs[] = {
{"", luaopen_base}, {"", luaopen_base},
{LUA_TABLIBNAME, luaopen_table}, {LUA_TABLIBNAME, luaopen_table},
{LUA_IOLIBNAME, luaopen_io},
{LUA_STRLIBNAME, luaopen_string}, {LUA_STRLIBNAME, luaopen_string},
{NULL, NULL} {NULL, NULL}
}; };

635
src/blua/liolib.c Normal file
View file

@ -0,0 +1,635 @@
/*
** $Id: liolib.c,v 2.73.1.3 2008/01/18 17:47:43 roberto Exp $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define liolib_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "../i_system.h"
#include "../g_game.h"
#include "../d_netfil.h"
#include "../lua_libs.h"
#include "../byteptr.h"
#include "../lua_script.h"
#include "../m_misc.h"
#define IO_INPUT 1
#define IO_OUTPUT 2
#define FILELIMIT (1024 * 1024) // Size limit for reading/writing files
#define FMT_FILECALLBACKID "file_callback_%d"
// Allow scripters to write files of these types to SRB2's folder
static const char *whitelist[] = {
".bmp",
".cfg",
".csv",
".dat",
".png",
".sav2",
".txt",
};
static int pushresult (lua_State *L, int i, const char *filename) {
int en = errno; /* calls to Lua API may change this value */
if (i) {
lua_pushboolean(L, 1);
return 1;
}
else {
lua_pushnil(L);
if (filename)
lua_pushfstring(L, "%s: %s", filename, strerror(en));
else
lua_pushfstring(L, "%s", strerror(en));
lua_pushinteger(L, en);
return 3;
}
}
#define tofilep(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE))
static int io_type (lua_State *L) {
void *ud;
luaL_checkany(L, 1);
ud = lua_touserdata(L, 1);
lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE);
if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1))
lua_pushnil(L); /* not a file */
else if (*((FILE **)ud) == NULL)
lua_pushliteral(L, "closed file");
else
lua_pushliteral(L, "file");
return 1;
}
static FILE *tofile (lua_State *L) {
FILE **f = tofilep(L);
if (*f == NULL)
luaL_error(L, "attempt to use a closed file");
return *f;
}
/*
** When creating file handles, always creates a `closed' file handle
** before opening the actual file; so, if there is a memory error, the
** file is not left opened.
*/
static FILE **newfile (lua_State *L) {
FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *));
*pf = NULL; /* file handle is currently `closed' */
luaL_getmetatable(L, LUA_FILEHANDLE);
lua_setmetatable(L, -2);
return pf;
}
/*
** function to (not) close the standard files stdin, stdout, and stderr
*/
static int io_noclose (lua_State *L) {
lua_pushnil(L);
lua_pushliteral(L, "cannot close standard file");
return 2;
}
/*
** function to close regular files
*/
static int io_fclose (lua_State *L) {
FILE **p = tofilep(L);
int ok = (fclose(*p) == 0);
*p = NULL;
return pushresult(L, ok, NULL);
}
static int aux_close (lua_State *L) {
lua_getfenv(L, 1);
lua_getfield(L, -1, "__close");
return (lua_tocfunction(L, -1))(L);
}
static int io_close (lua_State *L) {
if (lua_isnone(L, 1))
lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT);
tofile(L); /* make sure argument is a file */
return aux_close(L);
}
static int io_gc (lua_State *L) {
FILE *f = *tofilep(L);
/* ignore closed files */
if (f != NULL)
aux_close(L);
return 0;
}
static int io_tostring (lua_State *L) {
FILE *f = *tofilep(L);
if (f == NULL)
lua_pushliteral(L, "file (closed)");
else
lua_pushfstring(L, "file (%p)", f);
return 1;
}
// Create directories in the path
void MakePathDirs(char *path)
{
char *c;
for (c = path; *c; c++)
if (*c == '/' || *c == '\\')
{
char sep = *c;
*c = '\0';
I_mkdir(path, 0755);
*c = sep;
}
}
static int CheckFileName(lua_State *L, const char *filename)
{
int length = strlen(filename);
boolean pass = false;
size_t i;
if (strchr(filename, '\\'))
{
luaL_error(L, "access denied to %s: \\ is not allowed, use / instead", filename);
return pushresult(L,0,filename);
}
for (i = 0; i < (sizeof (whitelist) / sizeof(const char *)); i++)
if (!stricmp(&filename[length - strlen(whitelist[i])], whitelist[i]))
{
pass = true;
break;
}
if (strstr(filename, "./")
|| strstr(filename, "..") || strchr(filename, ':')
|| filename[0] == '/'
|| !pass)
{
luaL_error(L, "access denied to %s", filename);
return pushresult(L,0,filename);
}
return 0;
}
static int io_open (lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
const char *mode = luaL_optstring(L, 2, "r");
int checkresult;
checkresult = CheckFileName(L, filename);
if (checkresult)
return checkresult;
luaL_checktype(L, 3, LUA_TFUNCTION);
if (!(strchr(mode, 'r') || strchr(mode, '+')))
luaL_error(L, "open() is only for reading, use openlocal() for writing");
AddLuaFileTransfer(filename, mode);
return 0;
}
static int io_openlocal (lua_State *L) {
FILE **pf;
const char *filename = luaL_checkstring(L, 1);
const char *mode = luaL_optstring(L, 2, "r");
char *realfilename;
luafiletransfer_t *filetransfer;
int checkresult;
checkresult = CheckFileName(L, filename);
if (checkresult)
return checkresult;
realfilename = va("%s" PATHSEP "%s", luafiledir, filename);
if (client && strnicmp(filename, "client/", strlen("client/")))
I_Error("Access denied to %s\n"
"Clients can only access files stored in luafiles/client/\n",
filename);
// Prevent access if the file is being downloaded
for (filetransfer = luafiletransfers; filetransfer; filetransfer = filetransfer->next)
if (!stricmp(filetransfer->filename, filename))
I_Error("Access denied to %s\n"
"Files can't be opened while being downloaded\n",
filename);
MakePathDirs(realfilename);
// Open and return the file
pf = newfile(L);
*pf = fopen(realfilename, mode);
return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
}
void Got_LuaFile(UINT8 **cp, INT32 playernum)
{
FILE **pf = NULL;
UINT8 success = READUINT8(*cp); // The first (and only) byte indicates whether the file could be opened
if (playernum != serverplayer)
{
CONS_Alert(CONS_WARNING, M_GetText("Illegal luafile command received from %s\n"), player_names[playernum]);
if (server)
SendKick(playernum, KICK_MSG_CON_FAIL);
return;
}
if (!luafiletransfers)
I_Error("No Lua file transfer\n");
// Retrieve the callback and push it on the stack
lua_pushfstring(gL, FMT_FILECALLBACKID, luafiletransfers->id);
lua_gettable(gL, LUA_REGISTRYINDEX);
// Push the first argument (file handle or nil) on the stack
if (success)
{
pf = newfile(gL); // Create and push the file handle
*pf = fopen(luafiletransfers->realfilename, luafiletransfers->mode); // Open the file
if (!*pf)
I_Error("Can't open file \"%s\"\n", luafiletransfers->realfilename); // The file SHOULD exist
}
else
lua_pushnil(gL);
// Push the second argument (file name) on the stack
lua_pushstring(gL, luafiletransfers->filename);
// Call the callback
LUA_Call(gL, 2);
if (success)
{
// Close the file
if (*pf)
{
fclose(*pf);
*pf = NULL;
}
if (client)
remove(luafiletransfers->realfilename);
}
RemoveLuaFileTransfer();
if (server && luafiletransfers)
{
if (FIL_FileOK(luafiletransfers->realfilename))
SV_PrepareSendLuaFileToNextNode();
else
{
// Send a net command with 0 as its first byte to indicate the file couldn't be opened
success = 0;
SendNetXCmd(XD_LUAFILE, &success, 1);
}
}
}
void StoreLuaFileCallback(INT32 id)
{
lua_pushfstring(gL, FMT_FILECALLBACKID, id);
lua_pushvalue(gL, 3); // Parameter 3 is the callback
lua_settable(gL, LUA_REGISTRYINDEX); // registry[callbackid] = callback
}
void RemoveLuaFileCallback(INT32 id)
{
lua_pushfstring(gL, FMT_FILECALLBACKID, id);
lua_pushnil(gL);
lua_settable(gL, LUA_REGISTRYINDEX); // registry[callbackid] = nil
}
static int io_tmpfile (lua_State *L) {
FILE **pf = newfile(L);
*pf = tmpfile();
return (*pf == NULL) ? pushresult(L, 0, NULL) : 1;
}
static int io_readline (lua_State *L);
static void aux_lines (lua_State *L, int idx, int toclose) {
lua_pushvalue(L, idx);
lua_pushboolean(L, toclose); /* close/not close file when finished */
lua_pushcclosure(L, io_readline, 2);
}
static int f_lines (lua_State *L) {
tofile(L); /* check that it's a valid file handle */
aux_lines(L, 1, 0);
return 1;
}
/*
** {======================================================
** READ
** =======================================================
*/
static int read_number (lua_State *L, FILE *f) {
lua_Number d;
if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) {
lua_pushnumber(L, d);
return 1;
}
else return 0; /* read fails */
}
static int test_eof (lua_State *L, FILE *f) {
int c = getc(f);
ungetc(c, f);
lua_pushlstring(L, NULL, 0);
return (c != EOF);
}
static int read_line (lua_State *L, FILE *f) {
luaL_Buffer b;
luaL_buffinit(L, &b);
for (;;) {
size_t l;
char *p = luaL_prepbuffer(&b);
if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */
luaL_pushresult(&b); /* close buffer */
return (lua_objlen(L, -1) > 0); /* check whether read something */
}
l = strlen(p);
if (l == 0 || p[l-1] != '\n')
luaL_addsize(&b, l);
else {
luaL_addsize(&b, l - 1); /* do not include `eol' */
luaL_pushresult(&b); /* close buffer */
return 1; /* read at least an `eol' */
}
}
}
static int read_chars (lua_State *L, FILE *f, size_t n) {
size_t rlen; /* how much to read */
size_t nr; /* number of chars actually read */
luaL_Buffer b;
luaL_buffinit(L, &b);
rlen = LUAL_BUFFERSIZE; /* try to read that much each time */
do {
char *p = luaL_prepbuffer(&b);
if (rlen > n) rlen = n; /* cannot read more than asked */
nr = fread(p, sizeof(char), rlen, f);
luaL_addsize(&b, nr);
n -= nr; /* still have to read `n' chars */
} while (n > 0 && nr == rlen); /* until end of count or eof */
luaL_pushresult(&b); /* close buffer */
return (n == 0 || lua_objlen(L, -1) > 0);
}
static int g_read (lua_State *L, FILE *f, int first) {
int nargs = lua_gettop(L) - 1;
int success;
int n;
clearerr(f);
if (nargs == 0) { /* no arguments? */
success = read_line(L, f);
n = first+1; /* to return 1 result */
}
else { /* ensure stack space for all results and for auxlib's buffer */
luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments");
success = 1;
for (n = first; nargs-- && success; n++) {
if (lua_type(L, n) == LUA_TNUMBER) {
size_t l = (size_t)lua_tointeger(L, n);
success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l);
}
else {
const char *p = lua_tostring(L, n);
luaL_argcheck(L, p && p[0] == '*', n, "invalid option");
switch (p[1]) {
case 'n': /* number */
success = read_number(L, f);
break;
case 'l': /* line */
success = read_line(L, f);
break;
case 'a': /* file */
read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */
success = 1; /* always success */
break;
default:
return luaL_argerror(L, n, "invalid format");
}
}
}
}
if (ferror(f))
return pushresult(L, 0, NULL);
if (!success) {
lua_pop(L, 1); /* remove last result */
lua_pushnil(L); /* push nil instead */
}
return n - first;
}
static int f_read (lua_State *L) {
return g_read(L, tofile(L), 2);
}
static int io_readline (lua_State *L) {
FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1));
int sucess;
if (f == NULL) /* file is already closed? */
luaL_error(L, "file is already closed");
sucess = read_line(L, f);
if (ferror(f))
return luaL_error(L, "%s", strerror(errno));
if (sucess) return 1;
else { /* EOF */
if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */
lua_settop(L, 0);
lua_pushvalue(L, lua_upvalueindex(1));
aux_close(L); /* close it */
}
return 0;
}
}
/* }====================================================== */
static int g_write (lua_State *L, FILE *f, int arg) {
int nargs = lua_gettop(L) - 1;
int status = 1;
for (; nargs--; arg++) {
if (lua_type(L, arg) == LUA_TNUMBER) {
/* optimization: could be done exactly as for strings */
status = status &&
fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
}
else {
size_t l;
const char *s = luaL_checklstring(L, arg, &l);
if (ftell(f) + l > FILELIMIT) {
luaL_error(L,"write limit bypassed in file. Changes have been discarded.");
break;
}
status = status && (fwrite(s, sizeof(char), l, f) == l);
}
}
return pushresult(L, status, NULL);
}
static int f_write (lua_State *L) {
return g_write(L, tofile(L), 2);
}
static int f_seek (lua_State *L) {
static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
static const char *const modenames[] = {"set", "cur", "end", NULL};
FILE *f = tofile(L);
int op = luaL_checkoption(L, 2, "cur", modenames);
long offset = luaL_optlong(L, 3, 0);
op = fseek(f, offset, mode[op]);
if (op)
return pushresult(L, 0, NULL); /* error */
else {
lua_pushinteger(L, ftell(f));
return 1;
}
}
static int f_setvbuf (lua_State *L) {
static const int mode[] = {_IONBF, _IOFBF, _IOLBF};
static const char *const modenames[] = {"no", "full", "line", NULL};
FILE *f = tofile(L);
int op = luaL_checkoption(L, 2, NULL, modenames);
lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
int res = setvbuf(f, NULL, mode[op], sz);
return pushresult(L, res == 0, NULL);
}
static int f_flush (lua_State *L) {
return pushresult(L, fflush(tofile(L)) == 0, NULL);
}
static const luaL_Reg iolib[] = {
{"close", io_close},
{"open", io_open},
{"openlocal", io_openlocal},
{"tmpfile", io_tmpfile},
{"type", io_type},
{NULL, NULL}
};
static const luaL_Reg flib[] = {
{"close", io_close},
{"flush", f_flush},
{"lines", f_lines},
{"read", f_read},
{"seek", f_seek},
{"setvbuf", f_setvbuf},
{"write", f_write},
{"__gc", io_gc},
{"__tostring", io_tostring},
{NULL, NULL}
};
static void createmeta (lua_State *L) {
luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */
lua_pushvalue(L, -1); /* push metatable */
lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
luaL_register(L, NULL, flib); /* file methods */
}
static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) {
*newfile(L) = f;
if (k > 0) {
lua_pushvalue(L, -1);
lua_rawseti(L, LUA_ENVIRONINDEX, k);
}
lua_pushvalue(L, -2); /* copy environment */
lua_setfenv(L, -2); /* set it */
lua_setfield(L, -3, fname);
}
static void newfenv (lua_State *L, lua_CFunction cls) {
lua_createtable(L, 0, 1);
lua_pushcfunction(L, cls);
lua_setfield(L, -2, "__close");
}
LUALIB_API int luaopen_io (lua_State *L) {
createmeta(L);
/* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */
newfenv(L, io_fclose);
lua_replace(L, LUA_ENVIRONINDEX);
/* open library */
luaL_register(L, LUA_IOLIBNAME, iolib);
/* create (and set) default files */
newfenv(L, io_noclose); /* close function for default files */
createstdfile(L, stdin, IO_INPUT, "stdin");
createstdfile(L, stdout, IO_OUTPUT, "stdout");
createstdfile(L, stderr, 0, "stderr");
lua_pop(L, 1); /* pop environment for default files */
return 1;
}

View file

@ -21,6 +21,9 @@ LUALIB_API int (luaopen_base) (lua_State *L);
#define LUA_TABLIBNAME "table" #define LUA_TABLIBNAME "table"
LUALIB_API int (luaopen_table) (lua_State *L); LUALIB_API int (luaopen_table) (lua_State *L);
#define LUA_IOLIBNAME "io"
LUALIB_API int (luaopen_io) (lua_State *L);
#define LUA_STRLIBNAME "string" #define LUA_STRLIBNAME "string"
LUALIB_API int (luaopen_string) (lua_State *L); LUALIB_API int (luaopen_string) (lua_State *L);

View file

@ -80,7 +80,7 @@ static boolean joyaxis2_default = false;
static INT32 joyaxis_count = 0; static INT32 joyaxis_count = 0;
static INT32 joyaxis2_count = 0; static INT32 joyaxis2_count = 0;
#define COM_BUF_SIZE 8192 // command buffer size #define COM_BUF_SIZE (32<<10) // command buffer size
#define MAX_ALIAS_RECURSION 100 // max recursion allowed for aliases #define MAX_ALIAS_RECURSION 100 // max recursion allowed for aliases
static INT32 com_wait; // one command per frame (for cmd sequences) static INT32 com_wait; // one command per frame (for cmd sequences)
@ -481,13 +481,11 @@ void COM_AddCommand(const char *name, com_func_t func)
{ {
if (!stricmp(name, cmd->name)) //case insensitive now that we have lower and uppercase! if (!stricmp(name, cmd->name)) //case insensitive now that we have lower and uppercase!
{ {
#ifdef HAVE_BLUA
// don't I_Error for Lua commands // don't I_Error for Lua commands
// Lua commands can replace game commands, and they have priority. // Lua commands can replace game commands, and they have priority.
// BUT, if for some reason we screwed up and made two console commands with the same name, // BUT, if for some reason we screwed up and made two console commands with the same name,
// it's good to have this here so we find out. // it's good to have this here so we find out.
if (cmd->function != COM_Lua_f) if (cmd->function != COM_Lua_f)
#endif
I_Error("Command %s already exists\n", name); I_Error("Command %s already exists\n", name);
return; return;
@ -501,7 +499,6 @@ void COM_AddCommand(const char *name, com_func_t func)
com_commands = cmd; com_commands = cmd;
} }
#ifdef HAVE_BLUA
/** Adds a console command for Lua. /** Adds a console command for Lua.
* No I_Errors allowed; return a negative code instead. * No I_Errors allowed; return a negative code instead.
* *
@ -534,7 +531,6 @@ int COM_AddLuaCommand(const char *name)
com_commands = cmd; com_commands = cmd;
return 0; return 0;
} }
#endif
/** Tests if a command exists. /** Tests if a command exists.
* *
@ -1427,9 +1423,7 @@ finish:
} }
var->flags |= CV_MODIFIED; var->flags |= CV_MODIFIED;
// raise 'on change' code // raise 'on change' code
#ifdef HAVE_BLUA
LUA_CVarChanged(var->name); // let consolelib know what cvar this is. LUA_CVarChanged(var->name); // let consolelib know what cvar this is.
#endif
if (var->flags & CV_CALL && !stealth) if (var->flags & CV_CALL && !stealth)
var->func(); var->func();

View file

@ -28,12 +28,14 @@
/* Manually defined asset hashes for non-CMake builds /* Manually defined asset hashes for non-CMake builds
* Last updated 2020 / 02 / 15 - v2.2.1 - main assets * Last updated 2020 / 02 / 15 - v2.2.1 - main assets
* Last updated 2020 / 02 / 22 - v2.2.2 - patch.pk3 * Last updated 2020 / 02 / 22 - v2.2.2 - patch.pk3
* Last updated 2020 / 05 / 10 - v2.2.3 - player.dta & patch.pk3
* Last updated 2020 / 05 / 11 - v2.2.4 - patch.pk3
*/ */
#define ASSET_HASH_SRB2_PK3 "0277c9416756627004e83cbb5b2e3e28" #define ASSET_HASH_SRB2_PK3 "0277c9416756627004e83cbb5b2e3e28"
#define ASSET_HASH_ZONES_PK3 "f7e88afb6af7996a834c7d663144bead" #define ASSET_HASH_ZONES_PK3 "f7e88afb6af7996a834c7d663144bead"
#define ASSET_HASH_PLAYER_DTA "ad49e07b17cc662f1ad70c454910b4ae" #define ASSET_HASH_PLAYER_DTA "8a4507ddf9bc0682c09174400f26ad65"
#ifdef USE_PATCH_DTA #ifdef USE_PATCH_DTA
#define ASSET_HASH_PATCH_PK3 "ee54330ecb743314c5f962af4db731ff" #define ASSET_HASH_PATCH_PK3 "bbbf6af3b20349612ee06e0b55979a76"
#endif #endif
#endif #endif

View file

@ -97,6 +97,7 @@ static void CON_InputInit(void);
static void CON_RecalcSize(void); static void CON_RecalcSize(void);
static void CON_ChangeHeight(void); static void CON_ChangeHeight(void);
static void CON_DrawBackpic(void);
static void CONS_hudlines_Change(void); static void CONS_hudlines_Change(void);
static void CONS_backcolor_Change(void); static void CONS_backcolor_Change(void);
@ -1530,6 +1531,51 @@ static void CON_DrawHudlines(void)
con_clearlines = y; // this is handled by HU_Erase(); con_clearlines = y; // this is handled by HU_Erase();
} }
// Lactozilla: Draws the console's background picture.
static void CON_DrawBackpic(void)
{
patch_t *con_backpic;
lumpnum_t piclump;
int x, w, h;
// Get the lumpnum for CONSBACK, or fallback into MISSING.
piclump = W_CheckNumForName("CONSBACK");
if (piclump == LUMPERROR)
piclump = W_GetNumForName("MISSING");
// Cache the Software patch.
con_backpic = W_CacheSoftwarePatchNum(piclump, PU_PATCH);
// Center the backpic, and draw a vertically cropped patch.
w = (con_backpic->width * vid.dupx);
x = (vid.width / 2) - (w / 2);
h = con_curlines/vid.dupy;
// If the patch doesn't fill the entire screen,
// then fill the sides with a solid color.
if (x > 0)
{
column_t *column = (column_t *)((UINT8 *)(con_backpic) + LONG(con_backpic->columnofs[0]));
if (!column->topdelta)
{
UINT8 *source = (UINT8 *)(column) + 3;
INT32 color = (source[0] | V_NOSCALESTART);
// left side
V_DrawFill(0, 0, x, con_curlines, color);
// right side
V_DrawFill((x + w), 0, (vid.width - w), con_curlines, color);
}
}
// Cache the patch normally.
con_backpic = W_CachePatchNum(piclump, PU_PATCH);
V_DrawCroppedPatch(x << FRACBITS, 0, FRACUNIT, V_NOSCALESTART, con_backpic,
0, ( BASEVIDHEIGHT - h ), BASEVIDWIDTH, h);
// Unlock the cached patch.
W_UnlockCachedPatch(con_backpic);
}
// draw the console background, text, and prompt if enough place // draw the console background, text, and prompt if enough place
// //
static void CON_DrawConsole(void) static void CON_DrawConsole(void)
@ -1551,19 +1597,7 @@ static void CON_DrawConsole(void)
// draw console background // draw console background
if (cons_backpic.value || con_forcepic) if (cons_backpic.value || con_forcepic)
{ CON_DrawBackpic();
patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_PATCH);
int h;
h = con_curlines/vid.dupy;
// Jimita: CON_DrawBackpic just called V_DrawScaledPatch
//V_DrawScaledPatch(0, 0, 0, con_backpic);
V_DrawCroppedPatch(0, 0, FRACUNIT, 0, con_backpic,
0, ( BASEVIDHEIGHT - h ), BASEVIDWIDTH, h);
W_UnlockCachedPatch(con_backpic);
}
else else
{ {
// inu: no more width (was always 0 and vid.width) // inu: no more width (was always 0 and vid.width)

View file

@ -85,6 +85,10 @@ tic_t jointimeout = (10*TICRATE);
static boolean sendingsavegame[MAXNETNODES]; // Are we sending the savegame? static boolean sendingsavegame[MAXNETNODES]; // Are we sending the savegame?
static tic_t freezetimeout[MAXNETNODES]; // Until when can this node freeze the server before getting a timeout? static tic_t freezetimeout[MAXNETNODES]; // Until when can this node freeze the server before getting a timeout?
// Incremented by cv_joindelay when a client joins, decremented each tic.
// If higher than cv_joindelay * 2 (3 joins in a short timespan), joins are temporarily disabled.
static tic_t joindelay = 0;
UINT16 pingmeasurecount = 1; UINT16 pingmeasurecount = 1;
UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will be sent to everyone. UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will be sent to everyone.
UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values. UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values.
@ -1289,6 +1293,37 @@ static boolean CL_SendJoin(void)
return HSendPacket(servernode, true, 0, sizeof (clientconfig_pak)); return HSendPacket(servernode, true, 0, sizeof (clientconfig_pak));
} }
static INT32 FindRejoinerNum(SINT8 node)
{
char strippednodeaddress[64];
const char *nodeaddress;
char *port;
INT32 i;
// Make sure there is no dead dress before proceeding to the stripping
if (!I_GetNodeAddress)
return -1;
nodeaddress = I_GetNodeAddress(node);
if (!nodeaddress)
return -1;
// Strip the address of its port
strcpy(strippednodeaddress, nodeaddress);
port = strchr(strippednodeaddress, ':');
if (port)
*port = '\0';
// Check if any player matches the stripped address
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] && playeraddress[i][0] && playernode[i] == UINT8_MAX
&& !strcmp(playeraddress[i], strippednodeaddress))
return i;
}
return -1;
}
static void SV_SendServerInfo(INT32 node, tic_t servertime) static void SV_SendServerInfo(INT32 node, tic_t servertime)
{ {
UINT8 *p; UINT8 *p;
@ -1306,6 +1341,16 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
netbuffer->u.serverinfo.numberofplayer = (UINT8)D_NumPlayers(); netbuffer->u.serverinfo.numberofplayer = (UINT8)D_NumPlayers();
netbuffer->u.serverinfo.maxplayer = (UINT8)cv_maxplayers.value; netbuffer->u.serverinfo.maxplayer = (UINT8)cv_maxplayers.value;
if (!node || FindRejoinerNum(node) != -1)
netbuffer->u.serverinfo.refusereason = 0;
else if (!cv_allownewplayer.value)
netbuffer->u.serverinfo.refusereason = 1;
else if (D_NumPlayers() >= cv_maxplayers.value)
netbuffer->u.serverinfo.refusereason = 2;
else
netbuffer->u.serverinfo.refusereason = 0;
strncpy(netbuffer->u.serverinfo.gametypename, Gametype_Names[gametype], strncpy(netbuffer->u.serverinfo.gametypename, Gametype_Names[gametype],
sizeof netbuffer->u.serverinfo.gametypename); sizeof netbuffer->u.serverinfo.gametypename);
netbuffer->u.serverinfo.modifiedgame = (UINT8)modifiedgame; netbuffer->u.serverinfo.modifiedgame = (UINT8)modifiedgame;
@ -1645,7 +1690,7 @@ static void CL_LoadReceivedSavegame(void)
// load a base level // load a base level
if (P_LoadNetGame()) if (P_LoadNetGame())
{ {
const INT32 actnum = mapheaderinfo[gamemap-1]->actnum; const UINT8 actnum = mapheaderinfo[gamemap-1]->actnum;
CONS_Printf(M_GetText("Map is now \"%s"), G_BuildMapName(gamemap)); CONS_Printf(M_GetText("Map is now \"%s"), G_BuildMapName(gamemap));
if (strcmp(mapheaderinfo[gamemap-1]->lvlttl, "")) if (strcmp(mapheaderinfo[gamemap-1]->lvlttl, ""))
{ {
@ -1863,12 +1908,17 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent)
} }
// Quit here rather than downloading files and being refused later. // Quit here rather than downloading files and being refused later.
if (serverlist[i].info.numberofplayer >= serverlist[i].info.maxplayer) if (serverlist[i].info.refusereason)
{ {
D_QuitNetGame(); D_QuitNetGame();
CL_Reset(); CL_Reset();
D_StartTitle(); D_StartTitle();
M_StartMessage(va(M_GetText("Maximum players reached: %d\n\nPress ESC\n"), serverlist[i].info.maxplayer), NULL, MM_NOTHING); if (serverlist[i].info.refusereason == 1)
M_StartMessage(M_GetText("The server is not accepting\njoins for the moment.\n\nPress ESC\n"), NULL, MM_NOTHING);
else if (serverlist[i].info.refusereason == 2)
M_StartMessage(va(M_GetText("Maximum players reached: %d\n\nPress ESC\n"), serverlist[i].info.maxplayer), NULL, MM_NOTHING);
else
M_StartMessage(M_GetText("You can't join.\nI don't know why,\nbut you can't join.\n\nPress ESC\n"), NULL, MM_NOTHING);
return false; return false;
} }
@ -2439,14 +2489,14 @@ static void CL_RemovePlayer(INT32 playernum, kickreason_t reason)
if (!playeringame[playernum]) if (!playeringame[playernum])
return; return;
if (server && !demoplayback) if (server && !demoplayback && playernode[playernum] != UINT8_MAX)
{ {
INT32 node = playernode[playernum]; INT32 node = playernode[playernum];
playerpernode[node]--; playerpernode[node]--;
if (playerpernode[node] <= 0) if (playerpernode[node] <= 0)
{ {
nodeingame[playernode[playernum]] = false; nodeingame[node] = false;
Net_CloseConnection(playernode[playernum]); Net_CloseConnection(node);
ResetNode(node); ResetNode(node);
} }
} }
@ -2501,20 +2551,14 @@ static void CL_RemovePlayer(INT32 playernum, kickreason_t reason)
} }
} }
#ifdef HAVE_BLUA
LUAh_PlayerQuit(&players[playernum], reason); // Lua hook for player quitting LUAh_PlayerQuit(&players[playernum], reason); // Lua hook for player quitting
#else
(void)reason;
#endif
// don't look through someone's view who isn't there // don't look through someone's view who isn't there
if (playernum == displayplayer) if (playernum == displayplayer)
{ {
#ifdef HAVE_BLUA
// Call ViewpointSwitch hooks here. // Call ViewpointSwitch hooks here.
// The viewpoint was forcibly changed. // The viewpoint was forcibly changed.
LUAh_ViewpointSwitch(&players[consoleplayer], &players[displayplayer], true); LUAh_ViewpointSwitch(&players[consoleplayer], &players[consoleplayer], true);
#endif
displayplayer = consoleplayer; displayplayer = consoleplayer;
} }
@ -2535,9 +2579,7 @@ static void CL_RemovePlayer(INT32 playernum, kickreason_t reason)
RemoveAdminPlayer(playernum); // don't stay admin after you're gone RemoveAdminPlayer(playernum); // don't stay admin after you're gone
} }
#ifdef HAVE_BLUA
LUA_InvalidatePlayer(&players[playernum]); LUA_InvalidatePlayer(&players[playernum]);
#endif
if (G_TagGametype()) //Check if you still have a game. Location flexible. =P if (G_TagGametype()) //Check if you still have a game. Location flexible. =P
P_CheckSurvivors(); P_CheckSurvivors();
@ -2792,16 +2834,13 @@ static void Command_Kick(void)
if (pn == -1 || pn == 0) if (pn == -1 || pn == 0)
return; return;
if (server) // Special case if we are trying to kick a player who is downloading the game state:
// trigger a timeout instead of kicking them, because a kick would only
// take effect after they have finished downloading
if (server && playernode[pn] != UINT8_MAX && sendingsavegame[playernode[pn]])
{ {
// Special case if we are trying to kick a player who is downloading the game state: Net_ConnectionTimeout(playernode[pn]);
// trigger a timeout instead of kicking them, because a kick would only return;
// take effect after they have finished downloading
if (sendingsavegame[playernode[pn]])
{
Net_ConnectionTimeout(playernode[pn]);
return;
}
} }
WRITESINT8(p, pn); WRITESINT8(p, pn);
@ -2859,7 +2898,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
// Is playernum authorized to make this kick? // Is playernum authorized to make this kick?
if (playernum != serverplayer && !IsPlayerAdmin(playernum) if (playernum != serverplayer && !IsPlayerAdmin(playernum)
&& !(playerpernode[playernode[playernum]] == 2 && !(playernode[playernum] != UINT8_MAX && playerpernode[playernode[playernum]] == 2
&& nodetoplayer2[playernode[playernum]] == pnum)) && nodetoplayer2[playernode[playernum]] == pnum))
{ {
// We received a kick command from someone who isn't the // We received a kick command from someone who isn't the
@ -3018,7 +3057,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
} }
else if (keepbody) else if (keepbody)
{ {
if (server && !demoplayback) if (server && !demoplayback && playernode[pnum] != UINT8_MAX)
{ {
INT32 node = playernode[pnum]; INT32 node = playernode[pnum];
playerpernode[node]--; playerpernode[node]--;
@ -3042,6 +3081,8 @@ consvar_t cv_allownewplayer = {"allowjoin", "On", CV_NETVAR, CV_OnOff, NULL, 0,
consvar_t cv_joinnextround = {"joinnextround", "Off", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; /// \todo not done consvar_t cv_joinnextround = {"joinnextround", "Off", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; /// \todo not done
static CV_PossibleValue_t maxplayers_cons_t[] = {{2, "MIN"}, {32, "MAX"}, {0, NULL}}; static CV_PossibleValue_t maxplayers_cons_t[] = {{2, "MIN"}, {32, "MAX"}, {0, NULL}};
consvar_t cv_maxplayers = {"maxplayers", "8", CV_SAVE, maxplayers_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_maxplayers = {"maxplayers", "8", CV_SAVE, maxplayers_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t joindelay_cons_t[] = {{1, "MIN"}, {3600, "MAX"}, {0, "Off"}, {0, NULL}};
consvar_t cv_joindelay = {"joindelay", "10", CV_SAVE, joindelay_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t rejointimeout_cons_t[] = {{1, "MIN"}, {60 * FRACUNIT, "MAX"}, {0, "Off"}, {0, NULL}}; static CV_PossibleValue_t rejointimeout_cons_t[] = {{1, "MIN"}, {60 * FRACUNIT, "MAX"}, {0, "Off"}, {0, NULL}};
consvar_t cv_rejointimeout = {"rejointimeout", "Off", CV_SAVE|CV_FLOAT, rejointimeout_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_rejointimeout = {"rejointimeout", "Off", CV_SAVE|CV_FLOAT, rejointimeout_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -3129,14 +3170,14 @@ void SV_ResetServer(void)
neededtic = maketic; neededtic = maketic;
tictoclear = maketic; tictoclear = maketic;
joindelay = 0;
for (i = 0; i < MAXNETNODES; i++) for (i = 0; i < MAXNETNODES; i++)
ResetNode(i); ResetNode(i);
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
{ {
#ifdef HAVE_BLUA
LUA_InvalidatePlayer(&players[i]); LUA_InvalidatePlayer(&players[i]);
#endif
playeringame[i] = false; playeringame[i] = false;
playernode[i] = UINT8_MAX; playernode[i] = UINT8_MAX;
memset(playeraddress[i], 0, sizeof(*playeraddress)); memset(playeraddress[i], 0, sizeof(*playeraddress));
@ -3197,6 +3238,8 @@ void D_QuitNetGame(void)
// abort send/receive of files // abort send/receive of files
CloseNetFile(); CloseNetFile();
RemoveAllLuaFileTransfers();
waitingforluafiletransfer = false;
if (server) if (server)
{ {
@ -3230,37 +3273,6 @@ void D_QuitNetGame(void)
#endif #endif
} }
static INT32 FindRejoinerNum(SINT8 node)
{
char strippednodeaddress[64];
const char *nodeaddress;
char *port;
INT32 i;
// Make sure there is no dead dress before proceeding to the stripping
if (!I_GetNodeAddress)
return -1;
nodeaddress = I_GetNodeAddress(node);
if (!nodeaddress)
return -1;
// Strip the address of its port
strcpy(strippednodeaddress, nodeaddress);
port = strchr(strippednodeaddress, ':');
if (port)
*port = '\0';
// Check if any player matches the stripped address
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] && playeraddress[i][0] && playernode[i] == UINT8_MAX
&& !strcmp(playeraddress[i], strippednodeaddress))
return i;
}
return -1;
}
// Adds a node to the game (player will follow at map change or at savegame....) // Adds a node to the game (player will follow at map change or at savegame....)
static inline void SV_AddNode(INT32 node) static inline void SV_AddNode(INT32 node)
{ {
@ -3398,10 +3410,8 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
if (server && multiplayer && motd[0] != '\0') if (server && multiplayer && motd[0] != '\0')
COM_BufAddText(va("sayto %d %s\n", newplayernum, motd)); COM_BufAddText(va("sayto %d %s\n", newplayernum, motd));
#ifdef HAVE_BLUA
if (!rejoined) if (!rejoined)
LUAh_PlayerJoin(newplayernum); LUAh_PlayerJoin(newplayernum);
#endif
} }
static boolean SV_AddWaitingPlayers(const char *name, const char *name2) static boolean SV_AddWaitingPlayers(const char *name, const char *name2)
@ -3591,7 +3601,7 @@ static void HandleConnect(SINT8 node)
rejoinernum = FindRejoinerNum(node); rejoinernum = FindRejoinerNum(node);
if (bannednode && bannednode[node]) if (bannednode && bannednode[node])
SV_SendRefuse(node, M_GetText("You have been banned\nfrom the server")); SV_SendRefuse(node, M_GetText("You have been banned\nfrom the server."));
else if (netbuffer->u.clientcfg._255 != 255 || else if (netbuffer->u.clientcfg._255 != 255 ||
netbuffer->u.clientcfg.packetversion != PACKETVERSION) netbuffer->u.clientcfg.packetversion != PACKETVERSION)
SV_SendRefuse(node, "Incompatible packet formats."); SV_SendRefuse(node, "Incompatible packet formats.");
@ -3602,13 +3612,18 @@ static void HandleConnect(SINT8 node)
|| netbuffer->u.clientcfg.subversion != SUBVERSION) || netbuffer->u.clientcfg.subversion != SUBVERSION)
SV_SendRefuse(node, va(M_GetText("Different SRB2 versions cannot\nplay a netgame!\n(server version %d.%d.%d)"), VERSION/100, VERSION%100, SUBVERSION)); SV_SendRefuse(node, va(M_GetText("Different SRB2 versions cannot\nplay a netgame!\n(server version %d.%d.%d)"), VERSION/100, VERSION%100, SUBVERSION));
else if (!cv_allownewplayer.value && node && rejoinernum == -1) else if (!cv_allownewplayer.value && node && rejoinernum == -1)
SV_SendRefuse(node, M_GetText("The server is not accepting\njoins for the moment")); SV_SendRefuse(node, M_GetText("The server is not accepting\njoins for the moment."));
else if (D_NumPlayers() >= cv_maxplayers.value && rejoinernum == -1) else if (D_NumPlayers() >= cv_maxplayers.value && rejoinernum == -1)
SV_SendRefuse(node, va(M_GetText("Maximum players reached: %d"), cv_maxplayers.value)); SV_SendRefuse(node, va(M_GetText("Maximum players reached: %d"), cv_maxplayers.value));
else if (netgame && netbuffer->u.clientcfg.localplayers > 1) // Hacked client? else if (netgame && netbuffer->u.clientcfg.localplayers > 1) // Hacked client?
SV_SendRefuse(node, M_GetText("Too many players from\nthis node.")); SV_SendRefuse(node, M_GetText("Too many players from\nthis node."));
else if (netgame && !netbuffer->u.clientcfg.localplayers) // Stealth join? else if (netgame && !netbuffer->u.clientcfg.localplayers) // Stealth join?
SV_SendRefuse(node, M_GetText("No players from\nthis node.")); SV_SendRefuse(node, M_GetText("No players from\nthis node."));
else if (luafiletransfers)
SV_SendRefuse(node, M_GetText("The server is broadcasting a file\nrequested by a Lua script.\nPlease wait a bit and then\ntry rejoining."));
else if (netgame && joindelay > 2 * (tic_t)cv_joindelay.value * TICRATE)
SV_SendRefuse(node, va(M_GetText("Too many people are connecting.\nPlease wait %d seconds and then\ntry rejoining."),
(joindelay - 2 * cv_joindelay.value * TICRATE) / TICRATE));
else else
{ {
#ifndef NONET #ifndef NONET
@ -3666,6 +3681,7 @@ static void HandleConnect(SINT8 node)
DEBFILE("send savegame\n"); DEBFILE("send savegame\n");
} }
SV_AddWaitingPlayers(names[0], names[1]); SV_AddWaitingPlayers(names[0], names[1]);
joindelay += cv_joindelay.value * TICRATE;
player_joining = true; player_joining = true;
} }
#else #else
@ -3966,7 +3982,7 @@ static void HandlePacketFromPlayer(SINT8 node)
case PT_RESYNCHGET: case PT_RESYNCHGET:
if (client) if (client)
break; break;
SV_AcknowledgeResynchAck(netconsole, netbuffer->u.resynchgot); SV_AcknowledgeResynchAck(node, netbuffer->u.resynchgot);
break; break;
case PT_CLIENTCMD: case PT_CLIENTCMD:
case PT_CLIENT2CMD: case PT_CLIENT2CMD:
@ -4195,6 +4211,18 @@ static void HandlePacketFromPlayer(SINT8 node)
Net_CloseConnection(node); Net_CloseConnection(node);
nodeingame[node] = false; nodeingame[node] = false;
break; break;
case PT_ASKLUAFILE:
if (server && luafiletransfers && luafiletransfers->nodestatus[node] == LFTNS_ASKED)
{
char *name = va("%s" PATHSEP "%s", luafiledir, luafiletransfers->filename);
boolean textmode = !strchr(luafiletransfers->mode, 'b');
SV_SendLuaFile(node, name, textmode);
}
break;
case PT_HASLUAFILE:
if (server && luafiletransfers && luafiletransfers->nodestatus[node] == LFTNS_SENDING)
SV_HandleLuaFileSent(node);
break;
// -------------------------------------------- CLIENT RECEIVE ---------- // -------------------------------------------- CLIENT RECEIVE ----------
case PT_RESYNCHEND: case PT_RESYNCHEND:
// Only accept PT_RESYNCHEND from the server. // Only accept PT_RESYNCHEND from the server.
@ -4322,6 +4350,10 @@ static void HandlePacketFromPlayer(SINT8 node)
if (client) if (client)
Got_Filetxpak(); Got_Filetxpak();
break; break;
case PT_SENDINGLUAFILE:
if (client)
CL_PrepareDownloadLuaFile();
break;
default: default:
DEBFILE(va("UNKNOWN PACKET TYPE RECEIVED %d from host %d\n", DEBFILE(va("UNKNOWN PACKET TYPE RECEIVED %d from host %d\n",
netbuffer->packettype, node)); netbuffer->packettype, node));
@ -4855,7 +4887,8 @@ static inline void PingUpdate(void)
{ {
for (i = 1; i < MAXPLAYERS; i++) for (i = 1; i < MAXPLAYERS; i++)
{ {
if (playeringame[i] && (realpingtable[i] / pingmeasurecount > (unsigned)cv_maxping.value)) if (playeringame[i] && !players[i].quittime
&& (realpingtable[i] / pingmeasurecount > (unsigned)cv_maxping.value))
{ {
if (players[i].jointime > 30 * TICRATE) if (players[i].jointime > 30 * TICRATE)
laggers[i] = true; laggers[i] = true;
@ -4874,8 +4907,8 @@ static inline void PingUpdate(void)
if (playeringame[i] && laggers[i]) if (playeringame[i] && laggers[i])
{ {
pingtimeout[i]++; pingtimeout[i]++;
// ok your net has been bad for too long, you deserve to die.
if (pingtimeout[i] > cv_pingtimeout.value) if (pingtimeout[i] > cv_pingtimeout.value)
// ok your net has been bad for too long, you deserve to die.
{ {
pingtimeout[i] = 0; pingtimeout[i] = 0;
SendKick(i, KICK_MSG_PING_HIGH | KICK_MSG_KEEP_BODY); SendKick(i, KICK_MSG_PING_HIGH | KICK_MSG_KEEP_BODY);
@ -4943,7 +4976,7 @@ void NetUpdate(void)
PingUpdate(); PingUpdate();
// update node latency values so we can take an average later. // update node latency values so we can take an average later.
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i]) if (playeringame[i] && playernode[i] != UINT8_MAX)
realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i])); realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i]));
pingmeasurecount++; pingmeasurecount++;
} }
@ -5017,12 +5050,21 @@ void NetUpdate(void)
hu_resynching = true; hu_resynching = true;
} }
} }
Net_AckTicker(); Net_AckTicker();
// Handle timeouts to prevent definitive freezes from happenning // Handle timeouts to prevent definitive freezes from happenning
if (server) if (server)
{
for (i = 1; i < MAXNETNODES; i++) for (i = 1; i < MAXNETNODES; i++)
if (nodeingame[i] && freezetimeout[i] < I_GetTime()) if (nodeingame[i] && freezetimeout[i] < I_GetTime())
Net_ConnectionTimeout(i); Net_ConnectionTimeout(i);
// In case the cvar value was lowered
if (joindelay)
joindelay = min(joindelay - 1, 3 * (tic_t)cv_joindelay.value * TICRATE);
}
nowtime /= NEWTICRATERATIO; nowtime /= NEWTICRATERATIO;
if (nowtime > resptime) if (nowtime > resptime)
{ {
@ -5030,6 +5072,7 @@ void NetUpdate(void)
M_Ticker(); M_Ticker();
CON_Ticker(); CON_Ticker();
} }
SV_FileSendTicker(); SV_FileSendTicker();
} }

View file

@ -20,14 +20,11 @@
#include "d_player.h" #include "d_player.h"
/* /*
The 'packet version' may be used with packets whose The 'packet version' is used to distinguish packet formats.
format is expected to change between versions. This version is independent of VERSION and SUBVERSION. Different
applications may follow different packet versions.
This version is independent of the mod name, and standard
version and subversion. It should only account for the
basic fields of the packet, and change infrequently.
*/ */
#define PACKETVERSION 2 #define PACKETVERSION 3
// Network play related stuff. // Network play related stuff.
// There is a data struct that stores network // There is a data struct that stores network
@ -36,7 +33,7 @@ basic fields of the packet, and change infrequently.
// be transmitted. // be transmitted.
// Networking and tick handling related. // Networking and tick handling related.
#define BACKUPTICS 32 #define BACKUPTICS 96
#define MAXTEXTCMD 256 #define MAXTEXTCMD 256
// //
// Packet structure // Packet structure
@ -67,6 +64,10 @@ typedef enum
PT_RESYNCHEND, // Player is now resynched and is being requested to remake the gametic PT_RESYNCHEND, // Player is now resynched and is being requested to remake the gametic
PT_RESYNCHGET, // Player got resynch packet PT_RESYNCHGET, // Player got resynch packet
PT_SENDINGLUAFILE, // Server telling a client Lua needs to open a file
PT_ASKLUAFILE, // Client telling the server they don't have the file
PT_HASLUAFILE, // Client telling the server they have the file
// Add non-PT_CANFAIL packet types here to avoid breaking MS compatibility. // Add non-PT_CANFAIL packet types here to avoid breaking MS compatibility.
PT_CANFAIL, // This is kind of a priority. Anything bigger than CANFAIL PT_CANFAIL, // This is kind of a priority. Anything bigger than CANFAIL
@ -361,6 +362,7 @@ typedef struct
UINT8 subversion; UINT8 subversion;
UINT8 numberofplayer; UINT8 numberofplayer;
UINT8 maxplayer; UINT8 maxplayer;
UINT8 refusereason; // 0: joinable, 1: joins disabled, 2: full
char gametypename[24]; char gametypename[24];
UINT8 modifiedgame; UINT8 modifiedgame;
UINT8 cheatsenabled; UINT8 cheatsenabled;
@ -513,7 +515,7 @@ extern UINT32 realpingtable[MAXPLAYERS];
extern UINT32 playerpingtable[MAXPLAYERS]; extern UINT32 playerpingtable[MAXPLAYERS];
extern tic_t servermaxping; extern tic_t servermaxping;
extern consvar_t cv_allownewplayer, cv_joinnextround, cv_maxplayers, cv_rejointimeout; extern consvar_t cv_allownewplayer, cv_joinnextround, cv_maxplayers, cv_joindelay, cv_rejointimeout;
extern consvar_t cv_resynchattempts, cv_blamecfail; extern consvar_t cv_resynchattempts, cv_blamecfail;
extern consvar_t cv_maxsend, cv_noticedownload, cv_downloadspeed; extern consvar_t cv_maxsend, cv_noticedownload, cv_downloadspeed;

View file

@ -91,9 +91,7 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
#include "hardware/hw3sound.h" #include "hardware/hw3sound.h"
#endif #endif
#ifdef HAVE_BLUA
#include "lua_script.h" #include "lua_script.h"
#endif
// platform independant focus loss // platform independant focus loss
UINT8 window_notinfocus = false; UINT8 window_notinfocus = false;
@ -127,6 +125,8 @@ boolean advancedemo;
INT32 debugload = 0; INT32 debugload = 0;
#endif #endif
char savegamename[256];
char srb2home[256] = "."; char srb2home[256] = ".";
char srb2path[256] = "."; char srb2path[256] = ".";
boolean usehome = true; boolean usehome = true;
@ -312,7 +312,9 @@ static void D_Display(void)
F_WipeStartScreen(); F_WipeStartScreen();
// Check for Mega Genesis fade // Check for Mega Genesis fade
wipestyleflags = WSF_FADEOUT; wipestyleflags = WSF_FADEOUT;
if (F_TryColormapFade(31)) if (wipegamestate == (gamestate_t)FORCEWIPE)
F_WipeColorFill(31);
else if (F_TryColormapFade(31))
wipetypepost = -1; // Don't run the fade below this one wipetypepost = -1; // Don't run the fade below this one
F_WipeEndScreen(); F_WipeEndScreen();
F_RunWipe(wipetypepre, gamestate != GS_TIMEATTACK && gamestate != GS_TITLESCREEN); F_RunWipe(wipetypepre, gamestate != GS_TIMEATTACK && gamestate != GS_TITLESCREEN);
@ -746,9 +748,7 @@ void D_SRB2Loop(void)
HW3S_EndFrameUpdate(); HW3S_EndFrameUpdate();
#endif #endif
#ifdef HAVE_BLUA
LUA_Step(); LUA_Step();
#endif
} }
} }
@ -880,6 +880,40 @@ static inline void D_CleanFile(void)
} }
} }
///\brief Checks if a netgame URL is being handled, and changes working directory to the EXE's if so.
/// Done because browsers (at least, Firefox on Windows) launch the game from the browser's directory, which causes problems.
static void ChangeDirForUrlHandler(void)
{
// URL handlers are opened by web browsers (at least Firefox) from the browser's working directory, not the game's stored directory,
// so chdir to that directory unless overridden.
if (M_GetUrlProtocolArg() != NULL && !M_CheckParm("-nochdir"))
{
size_t i;
CONS_Printf("%s connect links load game files from the SRB2 application's stored directory. Switching to ", SERVER_URL_PROTOCOL);
strlcpy(srb2path, myargv[0], sizeof(srb2path));
// Get just the directory, minus the EXE name
for (i = strlen(srb2path)-1; i > 0; i--)
{
if (srb2path[i] == '/' || srb2path[i] == '\\')
{
srb2path[i] = '\0';
break;
}
}
CONS_Printf("%s\n", srb2path);
#if defined (_WIN32)
SetCurrentDirectoryA(srb2path);
#else
if (chdir(srb2path) == -1)
I_OutputMsg("Couldn't change working directory\n");
#endif
}
}
// ========================================================================== // ==========================================================================
// Identify the SRB2 version, and IWAD file to use. // Identify the SRB2 version, and IWAD file to use.
// ========================================================================== // ==========================================================================
@ -961,6 +995,7 @@ static void IdentifyVersion(void)
} }
MUSICTEST("music.dta") MUSICTEST("music.dta")
MUSICTEST("patch_music.pk3")
#ifdef DEVELOP // remove when music_new.dta is merged into music.dta #ifdef DEVELOP // remove when music_new.dta is merged into music.dta
MUSICTEST("music_new.dta") MUSICTEST("music_new.dta")
#endif #endif
@ -1068,6 +1103,9 @@ void D_SRB2Main(void)
// Test Dehacked lists // Test Dehacked lists
DEH_Check(); DEH_Check();
// Netgame URL special case: change working dir to EXE folder.
ChangeDirForUrlHandler();
// identify the main IWAD file to use // identify the main IWAD file to use
IdentifyVersion(); IdentifyVersion();
@ -1124,7 +1162,8 @@ void D_SRB2Main(void)
// can't use sprintf since there is %u in savegamename // can't use sprintf since there is %u in savegamename
strcatbf(savegamename, srb2home, PATHSEP); strcatbf(savegamename, srb2home, PATHSEP);
#else snprintf(luafiledir, sizeof luafiledir, "%s" PATHSEP "luafiles", srb2home);
#else // DEFAULTDIR
snprintf(srb2home, sizeof srb2home, "%s", userhome); snprintf(srb2home, sizeof srb2home, "%s", userhome);
snprintf(downloaddir, sizeof downloaddir, "%s", userhome); snprintf(downloaddir, sizeof downloaddir, "%s", userhome);
if (dedicated) if (dedicated)
@ -1134,7 +1173,9 @@ void D_SRB2Main(void)
// can't use sprintf since there is %u in savegamename // can't use sprintf since there is %u in savegamename
strcatbf(savegamename, userhome, PATHSEP); strcatbf(savegamename, userhome, PATHSEP);
#endif
snprintf(luafiledir, sizeof luafiledir, "%s" PATHSEP "luafiles", userhome);
#endif // DEFAULTDIR
} }
configfile[sizeof configfile - 1] = '\0'; configfile[sizeof configfile - 1] = '\0';
@ -1154,9 +1195,15 @@ void D_SRB2Main(void)
// any wad file is added, as they may contain colors themselves // any wad file is added, as they may contain colors themselves
M_InitPlayerSetupColors(); M_InitPlayerSetupColors();
CONS_Printf("Z_Init(): Init zone memory allocation daemon. \n");
Z_Init();
// Do this up here so that WADs loaded through the command line can use ExecCfg
COM_Init();
// add any files specified on the command line with -file wadfile // add any files specified on the command line with -file wadfile
// to the wad list // to the wad list
if (!(M_CheckParm("-connect") && !M_CheckParm("-server"))) if (!((M_GetUrlProtocolArg() || M_CheckParm("-connect")) && !M_CheckParm("-server")))
{ {
if (M_CheckParm("-file")) if (M_CheckParm("-file"))
{ {
@ -1181,9 +1228,6 @@ void D_SRB2Main(void)
if (M_CheckParm("-server") || dedicated) if (M_CheckParm("-server") || dedicated)
netgame = server = true; netgame = server = true;
CONS_Printf("Z_Init(): Init zone memory allocation daemon. \n");
Z_Init();
// adapt tables to SRB2's needs, including extra slots for dehacked file support // adapt tables to SRB2's needs, including extra slots for dehacked file support
P_PatchInfoTables(); P_PatchInfoTables();
@ -1191,7 +1235,7 @@ void D_SRB2Main(void)
M_InitMenuPresTables(); M_InitMenuPresTables();
// init title screen display params // init title screen display params
if (M_CheckParm("-connect")) if (M_GetUrlProtocolArg() || M_CheckParm("-connect"))
F_InitMenuPresValues(); F_InitMenuPresValues();
//---------------------------------------------------- READY TIME //---------------------------------------------------- READY TIME
@ -1255,7 +1299,6 @@ void D_SRB2Main(void)
CONS_Printf("HU_Init(): Setting up heads up display.\n"); CONS_Printf("HU_Init(): Setting up heads up display.\n");
HU_Init(); HU_Init();
COM_Init();
CON_Init(); CON_Init();
D_RegisterServerCommands(); D_RegisterServerCommands();
@ -1280,13 +1323,19 @@ void D_SRB2Main(void)
// Lactozilla: Does the render mode need to change? // Lactozilla: Does the render mode need to change?
if ((setrenderneeded != 0) && (setrenderneeded != rendermode)) if ((setrenderneeded != 0) && (setrenderneeded != rendermode))
{ {
CONS_Printf("Switching the renderer...\n"); CONS_Printf(M_GetText("Switching the renderer...\n"));
Z_PreparePatchFlush();
// set needpatchflush / needpatchrecache true for D_CheckRendererState
needpatchflush = true; needpatchflush = true;
needpatchrecache = true; needpatchrecache = true;
// Set cv_renderer to the new render mode
VID_CheckRenderer(); VID_CheckRenderer();
SCR_ChangeRendererCVars(setrenderneeded); SCR_ChangeRendererCVars(rendermode);
// check the renderer's state
D_CheckRendererState(); D_CheckRendererState();
setrenderneeded = 0;
} }
wipegamestate = gamestate; wipegamestate = gamestate;

View file

@ -715,6 +715,8 @@ void Net_CloseConnection(INT32 node)
InitNode(&nodes[node]); InitNode(&nodes[node]);
SV_AbortSendFiles(node); SV_AbortSendFiles(node);
if (server)
SV_AbortLuaFileTransfer(node);
I_NetFreeNodenum(node); I_NetFreeNodenum(node);
#endif #endif
} }
@ -799,12 +801,17 @@ static const char *packettypename[NUMPACKETTYPE] =
"RESYNCHEND", "RESYNCHEND",
"RESYNCHGET", "RESYNCHGET",
"SENDINGLUAFILE",
"ASKLUAFILE",
"HASLUAFILE",
"FILEFRAGMENT", "FILEFRAGMENT",
"TEXTCMD", "TEXTCMD",
"TEXTCMD2", "TEXTCMD2",
"CLIENTJOIN", "CLIENTJOIN",
"NODETIMEOUT", "NODETIMEOUT",
"RESYNCHING", "RESYNCHING",
"LOGIN",
"PING" "PING"
}; };

View file

@ -22,7 +22,7 @@
#include "g_input.h" #include "g_input.h"
#include "m_menu.h" #include "m_menu.h"
#include "r_local.h" #include "r_local.h"
#include "r_things.h" #include "r_skins.h"
#include "p_local.h" #include "p_local.h"
#include "p_setup.h" #include "p_setup.h"
#include "s_sound.h" #include "s_sound.h"
@ -157,10 +157,8 @@ static void Command_Isgamemodified_f(void);
static void Command_Cheats_f(void); static void Command_Cheats_f(void);
#ifdef _DEBUG #ifdef _DEBUG
static void Command_Togglemodified_f(void); static void Command_Togglemodified_f(void);
#ifdef HAVE_BLUA
static void Command_Archivetest_f(void); static void Command_Archivetest_f(void);
#endif #endif
#endif
// ========================================================================= // =========================================================================
// CLIENT VARIABLES // CLIENT VARIABLES
@ -416,10 +414,9 @@ const char *netxcmdnames[MAXNETXCMD - 1] =
"DELFILE", // replace next time we add an XD "DELFILE", // replace next time we add an XD
"SETMOTD", "SETMOTD",
"SUICIDE", "SUICIDE",
#ifdef HAVE_BLUA
"LUACMD", "LUACMD",
"LUAVAR" "LUAVAR",
#endif "LUAFILE"
}; };
// ========================================================================= // =========================================================================
@ -452,9 +449,8 @@ void D_RegisterServerCommands(void)
RegisterNetXCmd(XD_PAUSE, Got_Pause); RegisterNetXCmd(XD_PAUSE, Got_Pause);
RegisterNetXCmd(XD_SUICIDE, Got_Suicide); RegisterNetXCmd(XD_SUICIDE, Got_Suicide);
RegisterNetXCmd(XD_RUNSOC, Got_RunSOCcmd); RegisterNetXCmd(XD_RUNSOC, Got_RunSOCcmd);
#ifdef HAVE_BLUA
RegisterNetXCmd(XD_LUACMD, Got_Luacmd); RegisterNetXCmd(XD_LUACMD, Got_Luacmd);
#endif RegisterNetXCmd(XD_LUAFILE, Got_LuaFile);
// Remote Administration // Remote Administration
COM_AddCommand("password", Command_Changepassword_f); COM_AddCommand("password", Command_Changepassword_f);
@ -503,9 +499,7 @@ void D_RegisterServerCommands(void)
COM_AddCommand("cheats", Command_Cheats_f); // test COM_AddCommand("cheats", Command_Cheats_f); // test
#ifdef _DEBUG #ifdef _DEBUG
COM_AddCommand("togglemodified", Command_Togglemodified_f); COM_AddCommand("togglemodified", Command_Togglemodified_f);
#ifdef HAVE_BLUA
COM_AddCommand("archivetest", Command_Archivetest_f); COM_AddCommand("archivetest", Command_Archivetest_f);
#endif
#endif #endif
// for master server connection // for master server connection
@ -580,6 +574,7 @@ void D_RegisterServerCommands(void)
// d_clisrv // d_clisrv
CV_RegisterVar(&cv_maxplayers); CV_RegisterVar(&cv_maxplayers);
CV_RegisterVar(&cv_joindelay);
CV_RegisterVar(&cv_rejointimeout); CV_RegisterVar(&cv_rejointimeout);
CV_RegisterVar(&cv_resynchattempts); CV_RegisterVar(&cv_resynchattempts);
CV_RegisterVar(&cv_maxsend); CV_RegisterVar(&cv_maxsend);
@ -914,7 +909,7 @@ void D_RegisterClientCommands(void)
#ifdef _DEBUG #ifdef _DEBUG
COM_AddCommand("causecfail", Command_CauseCfail_f); COM_AddCommand("causecfail", Command_CauseCfail_f);
#endif #endif
#if defined(HAVE_BLUA) && defined(LUA_ALLOW_BYTECODE) #ifdef LUA_ALLOW_BYTECODE
COM_AddCommand("dumplua", Command_Dumplua_f); COM_AddCommand("dumplua", Command_Dumplua_f);
#endif #endif
} }
@ -1264,7 +1259,7 @@ static void SendNameAndColor(void)
players[consoleplayer].skincolor = cv_playercolor.value; players[consoleplayer].skincolor = cv_playercolor.value;
if (players[consoleplayer].mo) if (players[consoleplayer].mo && !players[consoleplayer].powers[pw_dye])
players[consoleplayer].mo->color = players[consoleplayer].skincolor; players[consoleplayer].mo->color = players[consoleplayer].skincolor;
if (metalrecording) if (metalrecording)
@ -1381,8 +1376,9 @@ static void SendNameAndColor2(void)
if (botingame) if (botingame)
{ {
players[secondplaya].skincolor = botcolor; players[secondplaya].skincolor = botcolor;
if (players[secondplaya].mo) if (players[secondplaya].mo && !players[secondplaya].powers[pw_dye])
players[secondplaya].mo->color = players[secondplaya].skincolor; players[secondplaya].mo->color = players[secondplaya].skincolor;
SetPlayerSkinByNum(secondplaya, botskin-1); SetPlayerSkinByNum(secondplaya, botskin-1);
return; return;
} }
@ -1395,7 +1391,7 @@ static void SendNameAndColor2(void)
// don't use secondarydisplayplayer: the second player must be 1 // don't use secondarydisplayplayer: the second player must be 1
players[secondplaya].skincolor = cv_playercolor2.value; players[secondplaya].skincolor = cv_playercolor2.value;
if (players[secondplaya].mo) if (players[secondplaya].mo && !players[secondplaya].powers[pw_dye])
players[secondplaya].mo->color = players[secondplaya].skincolor; players[secondplaya].mo->color = players[secondplaya].skincolor;
if (cv_forceskin.value >= 0 && (netgame || multiplayer)) // Server wants everyone to use the same player if (cv_forceskin.value >= 0 && (netgame || multiplayer)) // Server wants everyone to use the same player
@ -2038,9 +2034,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
UINT8 flags; UINT8 flags;
INT32 resetplayer = 1, lastgametype; INT32 resetplayer = 1, lastgametype;
UINT8 skipprecutscene, FLS; UINT8 skipprecutscene, FLS;
#ifdef HAVE_BLUA
INT16 mapnumber; INT16 mapnumber;
#endif
if (playernum != serverplayer && !IsPlayerAdmin(playernum)) if (playernum != serverplayer && !IsPlayerAdmin(playernum))
{ {
@ -2102,10 +2096,8 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
CV_StealthSetValue(&cv_playercolor, players[0].skincolor); CV_StealthSetValue(&cv_playercolor, players[0].skincolor);
} }
#ifdef HAVE_BLUA
mapnumber = M_MapNumber(mapname[3], mapname[4]); mapnumber = M_MapNumber(mapname[3], mapname[4]);
LUAh_MapChange(mapnumber); LUAh_MapChange(mapnumber);
#endif
G_InitNew(ultimatemode, mapname, resetplayer, skipprecutscene, FLS); G_InitNew(ultimatemode, mapname, resetplayer, skipprecutscene, FLS);
if (demoplayback && !timingdemo) if (demoplayback && !timingdemo)
@ -2689,11 +2681,9 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
return; return;
} }
#ifdef HAVE_BLUA
// Don't switch team, just go away, please, go awaayyyy, aaauuauugghhhghgh // Don't switch team, just go away, please, go awaayyyy, aaauuauugghhhghgh
if (!LUAh_TeamSwitch(&players[playernum], NetPacket.packet.newteam, players[playernum].spectator, NetPacket.packet.autobalance, NetPacket.packet.scrambled)) if (!LUAh_TeamSwitch(&players[playernum], NetPacket.packet.newteam, players[playernum].spectator, NetPacket.packet.autobalance, NetPacket.packet.scrambled))
return; return;
#endif
//no status changes after hidetime //no status changes after hidetime
if ((gametyperules & GTR_HIDEFROZEN) && (leveltime >= (hidetime * TICRATE))) if ((gametyperules & GTR_HIDEFROZEN) && (leveltime >= (hidetime * TICRATE)))
@ -2850,12 +2840,10 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
//reset view if you are changed, or viewing someone who was changed. //reset view if you are changed, or viewing someone who was changed.
if (playernum == consoleplayer || displayplayer == playernum) if (playernum == consoleplayer || displayplayer == playernum)
{ {
#ifdef HAVE_BLUA
// Call ViewpointSwitch hooks here. // Call ViewpointSwitch hooks here.
// The viewpoint was forcibly changed. // The viewpoint was forcibly changed.
if (displayplayer != consoleplayer) // You're already viewing yourself. No big deal. if (displayplayer != consoleplayer) // You're already viewing yourself. No big deal.
LUAh_ViewpointSwitch(&players[playernum], &players[displayplayer], true); LUAh_ViewpointSwitch(&players[consoleplayer], &players[consoleplayer], true);
#endif
displayplayer = consoleplayer; displayplayer = consoleplayer;
} }
@ -3353,10 +3341,6 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
boolean kick = false; boolean kick = false;
boolean toomany = false; boolean toomany = false;
INT32 i,j; INT32 i,j;
serverinfo_pak *dummycheck = NULL;
// Shut the compiler up.
(void)dummycheck;
READSTRINGN(*cp, filename, 240); READSTRINGN(*cp, filename, 240);
READMEM(*cp, md5sum, 16); READMEM(*cp, md5sum, 16);
@ -3764,11 +3748,11 @@ static void ExitMove_OnChange(void)
{ {
if (players[i].mo->target && players[i].mo->target->type == MT_SIGN) if (players[i].mo->target && players[i].mo->target->type == MT_SIGN)
P_SetTarget(&players[i].mo->target, NULL); P_SetTarget(&players[i].mo->target, NULL);
if (players[i].pflags & PF_FINISHED) if (players[i].pflags & PF_FINISHED)
P_GiveFinishFlags(&players[i]); P_GiveFinishFlags(&players[i]);
} }
CONS_Printf(M_GetText("Players can now move after completing the level.\n")); CONS_Printf(M_GetText("Players can now move after completing the level.\n"));
} }
else else
@ -4345,7 +4329,6 @@ static void Command_Togglemodified_f(void)
modifiedgame = !modifiedgame; modifiedgame = !modifiedgame;
} }
#ifdef HAVE_BLUA
extern UINT8 *save_p; extern UINT8 *save_p;
static void Command_Archivetest_f(void) static void Command_Archivetest_f(void)
{ {
@ -4390,7 +4373,6 @@ static void Command_Archivetest_f(void)
CONS_Printf("Done. No crash.\n"); CONS_Printf("Done. No crash.\n");
} }
#endif #endif
#endif
/** Makes a change to ::cv_forceskin take effect immediately. /** Makes a change to ::cv_forceskin take effect immediately.
* *

View file

@ -142,10 +142,9 @@ typedef enum
XD_SETMOTD, // 19 XD_SETMOTD, // 19
XD_SUICIDE, // 20 XD_SUICIDE, // 20
XD_DEMOTED, // 21 XD_DEMOTED, // 21
#ifdef HAVE_BLUA
XD_LUACMD, // 22 XD_LUACMD, // 22
XD_LUAVAR, // 23 XD_LUAVAR, // 23
#endif XD_LUAFILE, // 24
MAXNETXCMD MAXNETXCMD
} netxcmd_t; } netxcmd_t;

View file

@ -69,6 +69,7 @@ typedef struct filetx_s
UINT32 size; // Size of the file UINT32 size; // Size of the file
UINT8 fileid; UINT8 fileid;
INT32 node; // Destination INT32 node; // Destination
boolean textmode; // For files requested by Lua without the "b" option
struct filetx_s *next; // Next file in the list struct filetx_s *next; // Next file in the list
} filetx_t; } filetx_t;
@ -94,6 +95,11 @@ char downloaddir[512] = "DOWNLOAD";
INT32 lastfilenum = -1; INT32 lastfilenum = -1;
#endif #endif
luafiletransfer_t *luafiletransfers = NULL;
boolean waitingforluafiletransfer = false;
char luafiledir[256 + 16] = "luafiles";
/** Fills a serverinfo packet with information about wad files loaded. /** Fills a serverinfo packet with information about wad files loaded.
* *
* \todo Give this function a better name since it is in global scope. * \todo Give this function a better name since it is in global scope.
@ -159,6 +165,7 @@ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr)
fileneeded[i].file = NULL; // The file isn't open yet fileneeded[i].file = NULL; // The file isn't open yet
READSTRINGN(p, fileneeded[i].filename, MAX_WADPATH); // The next bytes are the file name READSTRINGN(p, fileneeded[i].filename, MAX_WADPATH); // The next bytes are the file name
READMEM(p, fileneeded[i].md5sum, 16); // The last 16 bytes are the file checksum READMEM(p, fileneeded[i].md5sum, 16); // The last 16 bytes are the file checksum
fileneeded[i].textmode = false;
} }
} }
@ -170,6 +177,7 @@ void CL_PrepareDownloadSaveGame(const char *tmpsave)
fileneeded[0].file = NULL; fileneeded[0].file = NULL;
memset(fileneeded[0].md5sum, 0, 16); memset(fileneeded[0].md5sum, 0, 16);
strcpy(fileneeded[0].filename, tmpsave); strcpy(fileneeded[0].filename, tmpsave);
fileneeded[0].textmode = false;
} }
/** Checks the server to see if we CAN download all the files, /** Checks the server to see if we CAN download all the files,
@ -448,6 +456,162 @@ void CL_LoadServerFiles(void)
} }
} }
void AddLuaFileTransfer(const char *filename, const char *mode)
{
luafiletransfer_t **prevnext; // A pointer to the "next" field of the last transfer in the list
luafiletransfer_t *filetransfer;
static INT32 id;
//CONS_Printf("AddLuaFileTransfer \"%s\"\n", filename);
// Find the last transfer in the list and set a pointer to its "next" field
prevnext = &luafiletransfers;
while (*prevnext)
prevnext = &((*prevnext)->next);
// Allocate file transfer information and append it to the transfer list
filetransfer = malloc(sizeof(luafiletransfer_t));
if (!filetransfer)
I_Error("AddLuaFileTransfer: Out of memory\n");
*prevnext = filetransfer;
filetransfer->next = NULL;
// Allocate the file name
filetransfer->filename = strdup(filename);
if (!filetransfer->filename)
I_Error("AddLuaFileTransfer: Out of memory\n");
// Create and allocate the real file name
if (server)
filetransfer->realfilename = strdup(va("%s" PATHSEP "%s",
luafiledir, filename));
else
filetransfer->realfilename = strdup(va("%s" PATHSEP "client" PATHSEP "$$$%d%d.tmp",
luafiledir, rand(), rand()));
if (!filetransfer->realfilename)
I_Error("AddLuaFileTransfer: Out of memory\n");
strlcpy(filetransfer->mode, mode, sizeof(filetransfer->mode));
if (server)
{
INT32 i;
// Set status to "waiting" for everyone
for (i = 0; i < MAXNETNODES; i++)
filetransfer->nodestatus[i] = LFTNS_WAITING;
if (!luafiletransfers->next) // Only if there is no transfer already going on
{
if (FIL_ReadFileOK(filetransfer->realfilename))
SV_PrepareSendLuaFileToNextNode();
else
{
// Send a net command with 0 as its first byte to indicate the file couldn't be opened
UINT8 success = 0;
SendNetXCmd(XD_LUAFILE, &success, 1);
}
}
}
// Store the callback so it can be called once everyone has the file
filetransfer->id = id;
StoreLuaFileCallback(id);
id++;
if (waitingforluafiletransfer)
{
waitingforluafiletransfer = false;
CL_PrepareDownloadLuaFile();
}
}
void SV_PrepareSendLuaFileToNextNode(void)
{
INT32 i;
UINT8 success = 1;
// Find a client to send the file to
for (i = 1; i < MAXNETNODES; i++)
if (nodeingame[i] && luafiletransfers->nodestatus[i] == LFTNS_WAITING) // Node waiting
{
// Tell the client we're about to send them the file
netbuffer->packettype = PT_SENDINGLUAFILE;
if (!HSendPacket(i, true, 0, 0))
I_Error("Failed to send a PT_SENDINGLUAFILE packet\n"); // !!! Todo: Handle failure a bit better lol
luafiletransfers->nodestatus[i] = LFTNS_ASKED;
return;
}
// No client found, everyone has the file
// Send a net command with 1 as its first byte to indicate the file could be opened
SendNetXCmd(XD_LUAFILE, &success, 1);
}
void SV_HandleLuaFileSent(UINT8 node)
{
luafiletransfers->nodestatus[node] = LFTNS_SENT;
SV_PrepareSendLuaFileToNextNode();
}
void RemoveLuaFileTransfer(void)
{
luafiletransfer_t *filetransfer = luafiletransfers;
RemoveLuaFileCallback(filetransfer->id);
luafiletransfers = filetransfer->next;
free(filetransfer->filename);
free(filetransfer->realfilename);
free(filetransfer);
}
void RemoveAllLuaFileTransfers(void)
{
while (luafiletransfers)
RemoveLuaFileTransfer();
}
void SV_AbortLuaFileTransfer(INT32 node)
{
if (luafiletransfers
&& (luafiletransfers->nodestatus[node] == LFTNS_ASKED
|| luafiletransfers->nodestatus[node] == LFTNS_SENDING))
{
luafiletransfers->nodestatus[node] = LFTNS_WAITING;
SV_PrepareSendLuaFileToNextNode();
}
}
void CL_PrepareDownloadLuaFile(void)
{
// If there is no transfer in the list, this normally means the server
// called io.open before us, so we have to wait until we call it too
if (!luafiletransfers)
{
waitingforluafiletransfer = true;
return;
}
// Tell the server we are ready to receive the file
netbuffer->packettype = PT_ASKLUAFILE;
HSendPacket(servernode, true, 0, 0);
fileneedednum = 1;
fileneeded[0].status = FS_REQUESTED;
fileneeded[0].totalsize = UINT32_MAX;
fileneeded[0].file = NULL;
memset(fileneeded[0].md5sum, 0, 16);
strcpy(fileneeded[0].filename, luafiletransfers->realfilename);
fileneeded[0].textmode = !strchr(luafiletransfers->mode, 'b');
// Make sure all directories in the file path exist
MakePathDirs(fileneeded[0].filename);
}
// Number of files to send // Number of files to send
// Little optimization to quickly test if there is a file in the queue // Little optimization to quickly test if there is a file in the queue
static INT32 filestosend = 0; static INT32 filestosend = 0;
@ -458,6 +622,7 @@ static INT32 filestosend = 0;
* \param filename The file to send * \param filename The file to send
* \param fileid ??? * \param fileid ???
* \sa SV_SendRam * \sa SV_SendRam
* \sa SV_SendLuaFile
* *
*/ */
static boolean SV_SendFile(INT32 node, const char *filename, UINT8 fileid) static boolean SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
@ -548,6 +713,7 @@ static boolean SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
* \param freemethod How to free the block after it has been sent * \param freemethod How to free the block after it has been sent
* \param fileid ??? * \param fileid ???
* \sa SV_SendFile * \sa SV_SendFile
* \sa SV_SendLuaFile
* *
*/ */
void SV_SendRam(INT32 node, void *data, size_t size, freemethod_t freemethod, UINT8 fileid) void SV_SendRam(INT32 node, void *data, size_t size, freemethod_t freemethod, UINT8 fileid)
@ -579,6 +745,55 @@ void SV_SendRam(INT32 node, void *data, size_t size, freemethod_t freemethod, UI
filestosend++; filestosend++;
} }
/** Adds a file requested by Lua to the file list for a node
*
* \param node The node to send the file to
* \param filename The file to send
* \sa SV_SendFile
* \sa SV_SendRam
*
*/
boolean SV_SendLuaFile(INT32 node, const char *filename, boolean textmode)
{
filetx_t **q; // A pointer to the "next" field of the last file in the list
filetx_t *p; // The new file request
//INT32 i;
//char wadfilename[MAX_WADPATH];
luafiletransfers->nodestatus[node] = LFTNS_SENDING;
// Find the last file in the list and set a pointer to its "next" field
q = &transfer[node].txlist;
while (*q)
q = &((*q)->next);
// Allocate a file request and append it to the file list
p = *q = (filetx_t *)malloc(sizeof (filetx_t));
if (!p)
I_Error("SV_SendLuaFile: No more memory\n");
// Initialise with zeros
memset(p, 0, sizeof (filetx_t));
// Allocate the file name
p->id.filename = (char *)malloc(MAX_WADPATH); // !!!
if (!p->id.filename)
I_Error("SV_SendLuaFile: No more memory\n");
// Set the file name and get rid of the path
strlcpy(p->id.filename, filename, MAX_WADPATH); // !!!
//nameonly(p->id.filename);
// Open in text mode if required by the Lua script
p->textmode = textmode;
DEBFILE(va("Sending Lua file %s to %d\n", filename, node));
p->ram = SF_FILE; // It's a file, we need to close it and free its name once we're done sending it
p->next = NULL; // End of list
filestosend++;
return true;
}
/** Stops sending a file for a node, and removes the file request from the list, /** Stops sending a file for a node, and removes the file request from the list,
* either because the file has been fully sent or because the node was disconnected * either because the file has been fully sent or because the node was disconnected
* *
@ -684,7 +899,7 @@ void SV_FileSendTicker(void)
long filesize; long filesize;
transfer[i].currentfile = transfer[i].currentfile =
fopen(f->id.filename, "rb"); fopen(f->id.filename, f->textmode ? "r" : "rb");
if (!transfer[i].currentfile) if (!transfer[i].currentfile)
I_Error("File %s does not exist", I_Error("File %s does not exist",
@ -715,11 +930,20 @@ void SV_FileSendTicker(void)
size = f->size-transfer[i].position; size = f->size-transfer[i].position;
if (ram) if (ram)
M_Memcpy(p->data, &f->id.ram[transfer[i].position], size); M_Memcpy(p->data, &f->id.ram[transfer[i].position], size);
else if (fread(p->data, 1, size, transfer[i].currentfile) != size) else
I_Error("SV_FileSendTicker: can't read %s byte on %s at %d because %s", sizeu1(size), f->id.filename, transfer[i].position, M_FileError(transfer[i].currentfile)); {
size_t n = fread(p->data, 1, size, transfer[i].currentfile);
if (n != size) // Either an error or Windows turning CR-LF into LF
{
if (f->textmode && feof(transfer[i].currentfile))
size = n;
else if (fread(p->data, 1, size, transfer[i].currentfile) != size)
I_Error("SV_FileSendTicker: can't read %s byte on %s at %d because %s", sizeu1(size), f->id.filename, transfer[i].position, M_FileError(transfer[i].currentfile));
}
}
p->position = LONG(transfer[i].position); p->position = LONG(transfer[i].position);
// Put flag so receiver knows the total size // Put flag so receiver knows the total size
if (transfer[i].position + size == f->size) if (transfer[i].position + size == f->size || (f->textmode && feof(transfer[i].currentfile)))
p->position |= LONG(0x80000000); p->position |= LONG(0x80000000);
p->fileid = f->fileid; p->fileid = f->fileid;
p->size = SHORT((UINT16)size); p->size = SHORT((UINT16)size);
@ -728,7 +952,7 @@ void SV_FileSendTicker(void)
if (HSendPacket(i, true, 0, FILETXHEADER + size)) // Reliable SEND if (HSendPacket(i, true, 0, FILETXHEADER + size)) // Reliable SEND
{ // Success { // Success
transfer[i].position = (UINT32)(transfer[i].position + size); transfer[i].position = (UINT32)(transfer[i].position + size);
if (transfer[i].position == f->size) // Finish? if (transfer[i].position == f->size || (f->textmode && feof(transfer[i].currentfile))) // Finish?
SV_EndFileSend(i); SV_EndFileSend(i);
} }
else else
@ -772,7 +996,7 @@ void Got_Filetxpak(void)
{ {
if (file->file) if (file->file)
I_Error("Got_Filetxpak: already open file\n"); I_Error("Got_Filetxpak: already open file\n");
file->file = fopen(filename, "wb"); file->file = fopen(filename, file->textmode ? "w" : "wb");
if (!file->file) if (!file->file)
I_Error("Can't create file %s: %s", filename, strerror(errno)); I_Error("Can't create file %s: %s", filename, strerror(errno));
CONS_Printf("\r%s...\n",filename); CONS_Printf("\r%s...\n",filename);
@ -793,7 +1017,7 @@ void Got_Filetxpak(void)
} }
// We can receive packet in the wrong order, anyway all os support gaped file // We can receive packet in the wrong order, anyway all os support gaped file
fseek(file->file, pos, SEEK_SET); fseek(file->file, pos, SEEK_SET);
if (fwrite(netbuffer->u.filetxpak.data,size,1,file->file) != 1) if (size && fwrite(netbuffer->u.filetxpak.data,size,1,file->file) != 1)
I_Error("Can't write to %s: %s\n",filename, M_FileError(file->file)); I_Error("Can't write to %s: %s\n",filename, M_FileError(file->file));
file->currentsize += size; file->currentsize += size;
@ -805,6 +1029,12 @@ void Got_Filetxpak(void)
file->status = FS_FOUND; file->status = FS_FOUND;
CONS_Printf(M_GetText("Downloading %s...(done)\n"), CONS_Printf(M_GetText("Downloading %s...(done)\n"),
filename); filename);
if (luafiletransfers)
{
// Tell the server we have received the file
netbuffer->packettype = PT_HASLUAFILE;
HSendPacket(servernode, true, 0, 0);
}
} }
} }
else else

View file

@ -13,6 +13,7 @@
#ifndef __D_NETFIL__ #ifndef __D_NETFIL__
#define __D_NETFIL__ #define __D_NETFIL__
#include "d_net.h"
#include "w_wad.h" #include "w_wad.h"
typedef enum typedef enum
@ -43,6 +44,7 @@ typedef struct
UINT32 currentsize; UINT32 currentsize;
UINT32 totalsize; UINT32 totalsize;
filestatus_t status; // The value returned by recsearch filestatus_t status; // The value returned by recsearch
boolean textmode; // For files requested by Lua without the "b" option
} fileneeded_t; } fileneeded_t;
extern INT32 fileneedednum; extern INT32 fileneedednum;
@ -70,6 +72,42 @@ boolean CL_CheckDownloadable(void);
boolean CL_SendRequestFile(void); boolean CL_SendRequestFile(void);
boolean Got_RequestFilePak(INT32 node); boolean Got_RequestFilePak(INT32 node);
typedef enum
{
LFTNS_WAITING, // This node is waiting for the server to send the file
LFTNS_ASKED, // The server has told the node they're ready to send the file
LFTNS_SENDING, // The server is sending the file to this node
LFTNS_SENT // The node already has the file
} luafiletransfernodestatus_t;
typedef struct luafiletransfer_s
{
char *filename;
char *realfilename;
char mode[4]; // rb+/wb+/ab+ + null character
INT32 id; // Callback ID
luafiletransfernodestatus_t nodestatus[MAXNETNODES];
struct luafiletransfer_s *next;
} luafiletransfer_t;
extern luafiletransfer_t *luafiletransfers;
extern boolean waitingforluafiletransfer;
extern char luafiledir[256 + 16];
void AddLuaFileTransfer(const char *filename, const char *mode);
void SV_PrepareSendLuaFileToNextNode(void);
boolean SV_SendLuaFile(INT32 node, const char *filename, boolean textmode);
void SV_PrepareSendLuaFile(const char *filename);
void SV_HandleLuaFileSent(UINT8 node);
void RemoveLuaFileTransfer(void);
void RemoveAllLuaFileTransfers(void);
void SV_AbortLuaFileTransfer(INT32 node);
void CL_PrepareDownloadLuaFile(void);
void Got_LuaFile(UINT8 **cp, INT32 playernum);
void StoreLuaFileCallback(INT32 id);
void RemoveLuaFileCallback(INT32 id);
void MakePathDirs(char *path);
void SV_AbortSendFiles(INT32 node); void SV_AbortSendFiles(INT32 node);
void CloseNetFile(void); void CloseNetFile(void);

View file

@ -48,6 +48,7 @@ typedef enum
SF_FASTEDGE = 1<<12, // Faster edge teeter? SF_FASTEDGE = 1<<12, // Faster edge teeter?
SF_MULTIABILITY = 1<<13, // Revenge of Final Demo. SF_MULTIABILITY = 1<<13, // Revenge of Final Demo.
SF_NONIGHTSROTATION = 1<<14, // Disable sprite rotation for NiGHTS SF_NONIGHTSROTATION = 1<<14, // Disable sprite rotation for NiGHTS
SF_NONIGHTSSUPER = 1<<15, // Disable super colors for NiGHTS (if you have SF_SUPER)
// free up to and including 1<<31 // free up to and including 1<<31
} skinflags_t; } skinflags_t;
@ -238,7 +239,8 @@ typedef enum
CR_MACESPIN, CR_MACESPIN,
CR_MINECART, CR_MINECART,
CR_ROLLOUT, CR_ROLLOUT,
CR_PTERABYTE CR_PTERABYTE,
CR_DUSTDEVIL
} carrytype_t; // pw_carry } carrytype_t; // pw_carry
// Player powers. (don't edit this comment) // Player powers. (don't edit this comment)
@ -278,6 +280,9 @@ typedef enum
pw_nights_linkfreeze, pw_nights_linkfreeze,
pw_nocontrol, //for linedef exec 427 pw_nocontrol, //for linedef exec 427
pw_dye, // for dyes
pw_justlaunched, // Launched off a slope this tic (0=none, 1=standard launch, 2=half-pipe launch) pw_justlaunched, // Launched off a slope this tic (0=none, 1=standard launch, 2=half-pipe launch)
NUMPOWERS NUMPOWERS

View file

@ -31,6 +31,7 @@
#include "r_data.h" #include "r_data.h"
#include "r_draw.h" #include "r_draw.h"
#include "r_patch.h" #include "r_patch.h"
#include "r_things.h" // R_Char2Frame
#include "r_sky.h" #include "r_sky.h"
#include "fastcmp.h" #include "fastcmp.h"
#include "lua_script.h" #include "lua_script.h"
@ -39,9 +40,7 @@
#include "m_cond.h" #include "m_cond.h"
#ifdef HAVE_BLUA
#include "v_video.h" // video flags (for lua) #include "v_video.h" // video flags (for lua)
#endif
#ifdef HWRENDER #ifdef HWRENDER
#include "hardware/hw_light.h" #include "hardware/hw_light.h"
@ -78,10 +77,8 @@ static UINT16 get_mus(const char *word, UINT8 dehacked_mode);
#endif #endif
static hudnum_t get_huditem(const char *word); static hudnum_t get_huditem(const char *word);
static menutype_t get_menutype(const char *word); static menutype_t get_menutype(const char *word);
#ifndef HAVE_BLUA //static INT16 get_gametype(const char *word);
static INT16 get_gametype(const char *word); //static powertype_t get_power(const char *word);
static powertype_t get_power(const char *word);
#endif
skincolornum_t get_skincolor(const char *word); skincolornum_t get_skincolor(const char *word);
boolean deh_loaded = false; boolean deh_loaded = false;
@ -1340,7 +1337,7 @@ static void readgametype(MYFILE *f, char *gtname)
newgttol = (UINT32)i; newgttol = (UINT32)i;
else else
{ {
UINT16 tol = 0; UINT32 tol = 0;
tmp = strtok(word2,","); tmp = strtok(word2,",");
do { do {
for (i = 0; TYPEOFLEVEL[i].name; i++) for (i = 0; TYPEOFLEVEL[i].name; i++)
@ -1506,7 +1503,6 @@ static void readlevelheader(MYFILE *f, INT32 num)
// Lua custom options also go above, contents may be case sensitive. // Lua custom options also go above, contents may be case sensitive.
if (fastncmp(word, "LUA.", 4)) if (fastncmp(word, "LUA.", 4))
{ {
#ifdef HAVE_BLUA
UINT8 j; UINT8 j;
customoption_t *modoption; customoption_t *modoption;
@ -1540,9 +1536,6 @@ static void readlevelheader(MYFILE *f, INT32 num)
modoption->option[31] = '\0'; modoption->option[31] = '\0';
strncpy(modoption->value, word2, 255); strncpy(modoption->value, word2, 255);
modoption->value[255] = '\0'; modoption->value[255] = '\0';
#else
// Silently ignore.
#endif
continue; continue;
} }
@ -1655,7 +1648,7 @@ static void readlevelheader(MYFILE *f, INT32 num)
} }
else if (fastcmp(word, "ACT")) else if (fastcmp(word, "ACT"))
{ {
if (i >= 0 && i < 20) // 0 for no act number, TTL1 through TTL19 if (i >= 0 && i <= 99) // 0 for no act number
mapheaderinfo[num-1]->actnum = (UINT8)i; mapheaderinfo[num-1]->actnum = (UINT8)i;
else else
deh_warning("Level header %d: invalid act number %d", num, i); deh_warning("Level header %d: invalid act number %d", num, i);
@ -1682,7 +1675,7 @@ static void readlevelheader(MYFILE *f, INT32 num)
mapheaderinfo[num-1]->typeoflevel = (UINT32)i; mapheaderinfo[num-1]->typeoflevel = (UINT32)i;
else else
{ {
UINT16 tol = 0; UINT32 tol = 0;
tmp = strtok(word2,","); tmp = strtok(word2,",");
do { do {
for (i = 0; TYPEOFLEVEL[i].name; i++) for (i = 0; TYPEOFLEVEL[i].name; i++)
@ -1961,6 +1954,12 @@ static void readlevelheader(MYFILE *f, INT32 num)
} }
else if (fastcmp(word, "STARTRINGS")) else if (fastcmp(word, "STARTRINGS"))
mapheaderinfo[num-1]->startrings = (UINT16)i; mapheaderinfo[num-1]->startrings = (UINT16)i;
else if (fastcmp(word, "SPECIALSTAGETIME"))
mapheaderinfo[num-1]->sstimer = i;
else if (fastcmp(word, "SPECIALSTAGESPHERES"))
mapheaderinfo[num-1]->ssspheres = i;
else if (fastcmp(word, "GRAVITY"))
mapheaderinfo[num-1]->gravity = FLOAT_TO_FIXED(atof(word2));
else else
deh_warning("Level header %d: unknown word '%s'", num, word); deh_warning("Level header %d: unknown word '%s'", num, word);
} }
@ -2905,7 +2904,7 @@ static actionpointer_t actionpointers[] =
{{A_ThrownRing}, "A_THROWNRING"}, {{A_ThrownRing}, "A_THROWNRING"},
{{A_SetSolidSteam}, "A_SETSOLIDSTEAM"}, {{A_SetSolidSteam}, "A_SETSOLIDSTEAM"},
{{A_UnsetSolidSteam}, "A_UNSETSOLIDSTEAM"}, {{A_UnsetSolidSteam}, "A_UNSETSOLIDSTEAM"},
{{A_SignSpin}, "S_SIGNSPIN"}, {{A_SignSpin}, "A_SIGNSPIN"},
{{A_SignPlayer}, "A_SIGNPLAYER"}, {{A_SignPlayer}, "A_SIGNPLAYER"},
{{A_OverlayThink}, "A_OVERLAYTHINK"}, {{A_OverlayThink}, "A_OVERLAYTHINK"},
{{A_JetChase}, "A_JETCHASE"}, {{A_JetChase}, "A_JETCHASE"},
@ -3007,6 +3006,7 @@ static actionpointer_t actionpointers[] =
{{A_SetRandomTics}, "A_SETRANDOMTICS"}, {{A_SetRandomTics}, "A_SETRANDOMTICS"},
{{A_ChangeColorRelative}, "A_CHANGECOLORRELATIVE"}, {{A_ChangeColorRelative}, "A_CHANGECOLORRELATIVE"},
{{A_ChangeColorAbsolute}, "A_CHANGECOLORABSOLUTE"}, {{A_ChangeColorAbsolute}, "A_CHANGECOLORABSOLUTE"},
{{A_Dye}, "A_DYE"},
{{A_MoveRelative}, "A_MOVERELATIVE"}, {{A_MoveRelative}, "A_MOVERELATIVE"},
{{A_MoveAbsolute}, "A_MOVEABSOLUTE"}, {{A_MoveAbsolute}, "A_MOVEABSOLUTE"},
{{A_Thrust}, "A_THRUST"}, {{A_Thrust}, "A_THRUST"},
@ -3124,6 +3124,7 @@ static actionpointer_t actionpointers[] =
{{A_DragonbomberSpawn}, "A_DRAGONBOMERSPAWN"}, {{A_DragonbomberSpawn}, "A_DRAGONBOMERSPAWN"},
{{A_DragonWing}, "A_DRAGONWING"}, {{A_DragonWing}, "A_DRAGONWING"},
{{A_DragonSegment}, "A_DRAGONSEGMENT"}, {{A_DragonSegment}, "A_DRAGONSEGMENT"},
{{A_ChangeHeight}, "A_CHANGEHEIGHT"},
{{NULL}, "NONE"}, {{NULL}, "NONE"},
// This NULL entry must be the last in the list // This NULL entry must be the last in the list
@ -3214,22 +3215,20 @@ static void readframe(MYFILE *f, INT32 num)
} }
z = 0; z = 0;
#ifdef HAVE_BLUA
found = LUA_SetLuaAction(&states[num], actiontocompare); found = LUA_SetLuaAction(&states[num], actiontocompare);
if (!found) if (!found)
#endif while (actionpointers[z].name)
while (actionpointers[z].name)
{
if (fastcmp(actiontocompare, actionpointers[z].name))
{ {
states[num].action = actionpointers[z].action; if (fastcmp(actiontocompare, actionpointers[z].name))
states[num].action.acv = actionpointers[z].action.acv; // assign {
states[num].action.acp1 = actionpointers[z].action.acp1; states[num].action = actionpointers[z].action;
found = true; states[num].action.acv = actionpointers[z].action.acv; // assign
break; states[num].action.acp1 = actionpointers[z].action.acp1;
found = true;
break;
}
z++;
} }
z++;
}
if (!found) if (!found)
deh_warning("Unknown action %s", actiontocompare); deh_warning("Unknown action %s", actiontocompare);
@ -3980,7 +3979,26 @@ static void readmaincfg(MYFILE *f)
value = atoi(word2); // used for numerical settings value = atoi(word2); // used for numerical settings
if (fastcmp(word, "EXECCFG")) if (fastcmp(word, "EXECCFG"))
COM_BufAddText(va("exec %s\n", word2)); {
if (strchr(word2, '.'))
COM_BufAddText(va("exec %s\n", word2));
else
{
lumpnum_t lumpnum;
char newname[9];
strncpy(newname, word2, 8);
newname[8] = '\0';
lumpnum = W_CheckNumForName(newname);
if (lumpnum == LUMPERROR || W_LumpLength(lumpnum) == 0)
CONS_Debug(DBG_SETUP, "SOC Error: script lump %s not found/not valid.\n", newname);
else
COM_BufInsertText(W_CacheLumpNum(lumpnum, PU_CACHE));
}
}
else if (fastcmp(word, "SPSTAGE_START")) else if (fastcmp(word, "SPSTAGE_START"))
{ {
@ -4222,6 +4240,10 @@ static void readmaincfg(MYFILE *f)
{ {
maxXtraLife = (UINT8)get_number(word2); maxXtraLife = (UINT8)get_number(word2);
} }
else if (fastcmp(word, "USECONTINUES"))
{
useContinues = (UINT8)(value || word2[0] == 'T' || word2[0] == 'Y');
}
else if (fastcmp(word, "GAMEDATA")) else if (fastcmp(word, "GAMEDATA"))
{ {
@ -6313,6 +6335,14 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_ROCKET", "S_ROCKET",
"S_LASER", "S_LASER",
"S_LASER2",
"S_LASERFLASH",
"S_LASERFLAME1",
"S_LASERFLAME2",
"S_LASERFLAME3",
"S_LASERFLAME4",
"S_LASERFLAME5",
"S_TORPEDO", "S_TORPEDO",
@ -7580,7 +7610,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
// Got Flag Sign // Got Flag Sign
"S_GOTFLAG", "S_GOTFLAG",
// Finish flag // Finish flag
"S_FINISHFLAG", "S_FINISHFLAG",
@ -8951,14 +8981,12 @@ static const char *const MOBJEFLAG_LIST[] = {
NULL NULL
}; };
#ifdef HAVE_BLUA
static const char *const MAPTHINGFLAG_LIST[4] = { static const char *const MAPTHINGFLAG_LIST[4] = {
"EXTRA", // Extra flag for objects. "EXTRA", // Extra flag for objects.
"OBJECTFLIP", // Reverse gravity flag for objects. "OBJECTFLIP", // Reverse gravity flag for objects.
"OBJECTSPECIAL", // Special flag used with certain objects. "OBJECTSPECIAL", // Special flag used with certain objects.
"AMBUSH" // Deaf monsters/do not react to sound. "AMBUSH" // Deaf monsters/do not react to sound.
}; };
#endif
static const char *const PLAYERFLAG_LIST[] = { static const char *const PLAYERFLAG_LIST[] = {
@ -9055,7 +9083,6 @@ static const char *const GAMETYPERULE_LIST[] = {
NULL NULL
}; };
#ifdef HAVE_BLUA
// Linedef flags // Linedef flags
static const char *const ML_LIST[16] = { static const char *const ML_LIST[16] = {
"IMPASSIBLE", "IMPASSIBLE",
@ -9075,7 +9102,6 @@ static const char *const ML_LIST[16] = {
"BOUNCY", "BOUNCY",
"TFERLINE" "TFERLINE"
}; };
#endif
static const char *COLOR_ENUMS[] = { static const char *COLOR_ENUMS[] = {
"NONE", // SKINCOLOR_NONE, "NONE", // SKINCOLOR_NONE,
@ -9246,7 +9272,11 @@ static const char *const POWERS_LIST[] = {
//for linedef exec 427 //for linedef exec 427
"NOCONTROL", "NOCONTROL",
"JUSTLAUNCHED",
//for dyes
"DYE",
"JUSTLAUNCHED"
}; };
static const char *const HUDITEMS_LIST[] = { static const char *const HUDITEMS_LIST[] = {
@ -9310,6 +9340,7 @@ static const char *const MENUTYPES_LIST[] = {
"MP_CONNECT", "MP_CONNECT",
"MP_ROOM", "MP_ROOM",
"MP_PLAYERSETUP", // MP_PlayerSetupDef shared with SPLITSCREEN if #defined NONET "MP_PLAYERSETUP", // MP_PlayerSetupDef shared with SPLITSCREEN if #defined NONET
"MP_SERVER_OPTIONS",
// Options // Options
"OP_MAIN", "OP_MAIN",
@ -9319,10 +9350,14 @@ static const char *const MENUTYPES_LIST[] = {
"OP_P1MOUSE", "OP_P1MOUSE",
"OP_P1JOYSTICK", "OP_P1JOYSTICK",
"OP_JOYSTICKSET", // OP_JoystickSetDef shared with P2 "OP_JOYSTICKSET", // OP_JoystickSetDef shared with P2
"OP_P1CAMERA",
"OP_P2CONTROLS", "OP_P2CONTROLS",
"OP_P2MOUSE", "OP_P2MOUSE",
"OP_P2JOYSTICK", "OP_P2JOYSTICK",
"OP_P2CAMERA",
"OP_PLAYSTYLE",
"OP_VIDEO", "OP_VIDEO",
"OP_VIDEOMODE", "OP_VIDEOMODE",
@ -9372,11 +9407,7 @@ static const char *const MENUTYPES_LIST[] = {
struct { struct {
const char *n; const char *n;
// has to be able to hold both fixed_t and angle_t, so drastic measure!! // has to be able to hold both fixed_t and angle_t, so drastic measure!!
#ifdef HAVE_BLUA
lua_Integer v; lua_Integer v;
#else
INT64 v;
#endif
} const INT_CONST[] = { } const INT_CONST[] = {
// If a mod removes some variables here, // If a mod removes some variables here,
// please leave the names in-tact and just set // please leave the names in-tact and just set
@ -9559,6 +9590,7 @@ struct {
{"CR_MINECART",CR_MINECART}, {"CR_MINECART",CR_MINECART},
{"CR_ROLLOUT",CR_ROLLOUT}, {"CR_ROLLOUT",CR_ROLLOUT},
{"CR_PTERABYTE",CR_PTERABYTE}, {"CR_PTERABYTE",CR_PTERABYTE},
{"CR_DUSTDEVIL",CR_DUSTDEVIL},
// Ring weapons (ringweapons_t) // Ring weapons (ringweapons_t)
// Useful for A_GiveWeapon // Useful for A_GiveWeapon
@ -9586,6 +9618,7 @@ struct {
{"SF_FASTEDGE",SF_FASTEDGE}, {"SF_FASTEDGE",SF_FASTEDGE},
{"SF_MULTIABILITY",SF_MULTIABILITY}, {"SF_MULTIABILITY",SF_MULTIABILITY},
{"SF_NONIGHTSROTATION",SF_NONIGHTSROTATION}, {"SF_NONIGHTSROTATION",SF_NONIGHTSROTATION},
{"SF_NONIGHTSSUPER",SF_NONIGHTSSUPER},
// Dashmode constants // Dashmode constants
{"DASHMODE_THRESHOLD",DASHMODE_THRESHOLD}, {"DASHMODE_THRESHOLD",DASHMODE_THRESHOLD},
@ -9633,7 +9666,6 @@ struct {
{"ME_ULTIMATE",ME_ULTIMATE}, {"ME_ULTIMATE",ME_ULTIMATE},
{"ME_PERFECT",ME_PERFECT}, {"ME_PERFECT",ME_PERFECT},
#ifdef HAVE_BLUA
// p_local.h constants // p_local.h constants
{"FLOATSPEED",FLOATSPEED}, {"FLOATSPEED",FLOATSPEED},
{"MAXSTEPMOVE",MAXSTEPMOVE}, {"MAXSTEPMOVE",MAXSTEPMOVE},
@ -9768,11 +9800,11 @@ struct {
{"FF_CUTEXTRA",FF_CUTEXTRA}, ///< Cuts out hidden translucent pixels. {"FF_CUTEXTRA",FF_CUTEXTRA}, ///< Cuts out hidden translucent pixels.
{"FF_CUTLEVEL",FF_CUTLEVEL}, ///< Cuts out all hidden pixels. {"FF_CUTLEVEL",FF_CUTLEVEL}, ///< Cuts out all hidden pixels.
{"FF_CUTSPRITES",FF_CUTSPRITES}, ///< Final step in making 3D water. {"FF_CUTSPRITES",FF_CUTSPRITES}, ///< Final step in making 3D water.
{"FF_BOTHPLANES",FF_BOTHPLANES}, ///< Renders both planes all the time. {"FF_BOTHPLANES",FF_BOTHPLANES}, ///< Render inside and outside planes.
{"FF_EXTRA",FF_EXTRA}, ///< Gets cut by ::FF_CUTEXTRA. {"FF_EXTRA",FF_EXTRA}, ///< Gets cut by ::FF_CUTEXTRA.
{"FF_TRANSLUCENT",FF_TRANSLUCENT}, ///< See through! {"FF_TRANSLUCENT",FF_TRANSLUCENT}, ///< See through!
{"FF_FOG",FF_FOG}, ///< Fog "brush." {"FF_FOG",FF_FOG}, ///< Fog "brush."
{"FF_INVERTPLANES",FF_INVERTPLANES}, ///< Reverse the plane visibility rules. {"FF_INVERTPLANES",FF_INVERTPLANES}, ///< Only render inside planes.
{"FF_ALLSIDES",FF_ALLSIDES}, ///< Render inside and outside sides. {"FF_ALLSIDES",FF_ALLSIDES}, ///< Render inside and outside sides.
{"FF_INVERTSIDES",FF_INVERTSIDES}, ///< Only render inside sides. {"FF_INVERTSIDES",FF_INVERTSIDES}, ///< Only render inside sides.
{"FF_DOUBLESHADOW",FF_DOUBLESHADOW}, ///< Make two lightlist entries to reset light? {"FF_DOUBLESHADOW",FF_DOUBLESHADOW}, ///< Make two lightlist entries to reset light?
@ -9798,11 +9830,10 @@ struct {
// Node flags // Node flags
{"NF_SUBSECTOR",NF_SUBSECTOR}, // Indicate a leaf. {"NF_SUBSECTOR",NF_SUBSECTOR}, // Indicate a leaf.
#endif #endif
#ifdef ESLOPE
// Slope flags // Slope flags
{"SL_NOPHYSICS",SL_NOPHYSICS}, {"SL_NOPHYSICS",SL_NOPHYSICS},
{"SL_DYNAMIC",SL_DYNAMIC}, {"SL_DYNAMIC",SL_DYNAMIC},
#endif
// Angles // Angles
{"ANG1",ANG1}, {"ANG1",ANG1},
@ -9966,7 +9997,6 @@ struct {
{"TC_RAINBOW",TC_RAINBOW}, {"TC_RAINBOW",TC_RAINBOW},
{"TC_BLINK",TC_BLINK}, {"TC_BLINK",TC_BLINK},
{"TC_DASHMODE",TC_DASHMODE}, {"TC_DASHMODE",TC_DASHMODE},
#endif
{NULL,0} {NULL,0}
}; };
@ -10143,8 +10173,7 @@ static menutype_t get_menutype(const char *word)
return MN_NONE; return MN_NONE;
} }
#ifndef HAVE_BLUA /*static INT16 get_gametype(const char *word)
static INT16 get_gametype(const char *word)
{ // Returns the value of GT_ enumerations { // Returns the value of GT_ enumerations
INT16 i; INT16 i;
if (*word >= '0' && *word <= '9') if (*word >= '0' && *word <= '9')
@ -10170,7 +10199,7 @@ static powertype_t get_power(const char *word)
return i; return i;
deh_warning("Couldn't find power named 'pw_%s'",word); deh_warning("Couldn't find power named 'pw_%s'",word);
return pw_invulnerability; return pw_invulnerability;
} }*/
/// \todo Make ANY of this completely over-the-top math craziness obey the order of operations. /// \todo Make ANY of this completely over-the-top math craziness obey the order of operations.
static fixed_t op_mul(fixed_t a, fixed_t b) { return a*b; } static fixed_t op_mul(fixed_t a, fixed_t b) { return a*b; }
@ -10198,7 +10227,7 @@ struct {
}; };
// Returns the full word, cut at the first symbol or whitespace // Returns the full word, cut at the first symbol or whitespace
static char *read_word(const char *line) /*static char *read_word(const char *line)
{ {
// Part 1: You got the start of the word, now find the end. // Part 1: You got the start of the word, now find the end.
const char *p; const char *p;
@ -10363,7 +10392,7 @@ static fixed_t find_const(const char **rword)
free(word); free(word);
return r; return r;
} }
else if (fastncmp("GT_",word,4)) { else if (fastncmp("GT_",word,3)) {
r = get_gametype(word); r = get_gametype(word);
free(word); free(word);
return r; return r;
@ -10422,16 +10451,14 @@ static fixed_t find_const(const char **rword)
const_warning("constant",word); const_warning("constant",word);
free(word); free(word);
return 0; return 0;
} }*/
#endif
// Loops through every constant and operation in word and performs its calculations, returning the final value. // Loops through every constant and operation in word and performs its calculations, returning the final value.
fixed_t get_number(const char *word) fixed_t get_number(const char *word)
{ {
#ifdef HAVE_BLUA
return LUA_EvalMath(word); return LUA_EvalMath(word);
#else
// DESPERATELY NEEDED: Order of operations support! :x /*// DESPERATELY NEEDED: Order of operations support! :x
fixed_t i = find_const(&word); fixed_t i = find_const(&word);
INT32 o; INT32 o;
while(*word) { while(*word) {
@ -10441,8 +10468,7 @@ fixed_t get_number(const char *word)
else else
break; break;
} }
return i; return i;*/
#endif
} }
void DEH_Check(void) void DEH_Check(void)
@ -10467,7 +10493,6 @@ void DEH_Check(void)
#endif #endif
} }
#ifdef HAVE_BLUA
#include "lua_script.h" #include "lua_script.h"
#include "lua_libs.h" #include "lua_libs.h"
@ -11116,5 +11141,3 @@ void LUA_SetActionByName(void *state, const char *actiontocompare)
} }
} }
} }
#endif // HAVE_BLUA

View file

@ -34,11 +34,9 @@ void DEH_Check(void);
fixed_t get_number(const char *word); fixed_t get_number(const char *word);
#ifdef HAVE_BLUA
boolean LUA_SetLuaAction(void *state, const char *actiontocompare); boolean LUA_SetLuaAction(void *state, const char *actiontocompare);
const char *LUA_GetActionName(void *action); const char *LUA_GetActionName(void *action);
void LUA_SetActionByName(void *state, const char *actiontocompare); void LUA_SetActionByName(void *state, const char *actiontocompare);
#endif
extern boolean deh_loaded; extern boolean deh_loaded;

View file

@ -339,7 +339,4 @@ void I_StartupGraphics(void)
} }
void I_StartupHardwareGraphics(void) void VID_StartupOpenGL(void) {}
{
// oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo y
}

View file

@ -378,10 +378,8 @@ INT32 VID_SetMode (INT32 modenum) //, UINT8 *palette)
return 1; return 1;
} }
void VID_CheckRenderer(void) void VID_CheckRenderer(void) {}
{ void VID_CheckGLLoaded(rendermode_t oldrender) {}
// ..............
}

View file

@ -143,13 +143,16 @@ extern char logfilename[1024];
// we use comprevision and compbranch instead. // we use comprevision and compbranch instead.
#else #else
#define VERSION 202 // Game version #define VERSION 202 // Game version
#define SUBVERSION 2 // more precise version number #define SUBVERSION 4 // more precise version number
#define VERSIONSTRING "v2.2.2" #define VERSIONSTRING "v2.2.4"
#define VERSIONSTRINGW L"v2.2.2" #define VERSIONSTRINGW L"v2.2.4"
// Hey! If you change this, add 1 to the MODVERSION below! // Hey! If you change this, add 1 to the MODVERSION below!
// Otherwise we can't force updates! // Otherwise we can't force updates!
#endif #endif
/* A custom URL protocol for server links. */
#define SERVER_URL_PROTOCOL "srb2://"
// Does this version require an added patch file? // Does this version require an added patch file?
// Comment or uncomment this as necessary. // Comment or uncomment this as necessary.
#define USE_PATCH_DTA #define USE_PATCH_DTA
@ -210,7 +213,7 @@ extern char logfilename[1024];
// it's only for detection of the version the player is using so the MS can alert them of an update. // it's only for detection of the version the player is using so the MS can alert them of an update.
// Only set it higher, not lower, obviously. // Only set it higher, not lower, obviously.
// Note that we use this to help keep internal testing in check; this is why v2.2.0 is not version "1". // Note that we use this to help keep internal testing in check; this is why v2.2.0 is not version "1".
#define MODVERSION 42 #define MODVERSION 44
// To version config.cfg, MAJOREXECVERSION is set equal to MODVERSION automatically. // To version config.cfg, MAJOREXECVERSION is set equal to MODVERSION automatically.
// Increment MINOREXECVERSION whenever a config change is needed that does not correspond // Increment MINOREXECVERSION whenever a config change is needed that does not correspond
@ -475,7 +478,7 @@ void CONS_Debug(INT32 debugflags, const char *fmt, ...) FUNCDEBUG;
// Things that used to be in dstrings.h // Things that used to be in dstrings.h
#define SAVEGAMENAME "srb2sav" #define SAVEGAMENAME "srb2sav"
char savegamename[256]; extern char savegamename[256];
// m_misc.h // m_misc.h
#ifdef GETTEXT #ifdef GETTEXT
@ -582,15 +585,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
// None of these that are disabled in the normal build are guaranteed to work perfectly // None of these that are disabled in the normal build are guaranteed to work perfectly
// Compile them at your own risk! // Compile them at your own risk!
/// Kalaron/Eternity Engine slope code (SRB2CB ported)
#define ESLOPE
#ifdef ESLOPE
/// Backwards compatibility with SRB2CB's slope linedef types.
/// \note A simple shim that prints a warning.
#define ESLOPE_TYPESHIM
#endif
/// Allows the use of devmode in multiplayer. AKA "fishcake" /// Allows the use of devmode in multiplayer. AKA "fishcake"
//#define NETGAME_DEVMODE //#define NETGAME_DEVMODE
@ -600,9 +594,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// Dumps the contents of a network save game upon consistency failure for debugging. /// Dumps the contents of a network save game upon consistency failure for debugging.
//#define DUMPCONSISTENCY //#define DUMPCONSISTENCY
/// Polyobject fake flat code
#define POLYOBJECTS_PLANES
/// See name of player in your crosshair /// See name of player in your crosshair
#define SEENAMES #define SEENAMES

View file

@ -319,6 +319,9 @@ typedef struct
char selectheading[22]; ///< Level select heading. Allows for controllable grouping. char selectheading[22]; ///< Level select heading. Allows for controllable grouping.
UINT16 startrings; ///< Number of rings players start with. UINT16 startrings; ///< Number of rings players start with.
INT32 sstimer; ///< Timer for special stages.
UINT32 ssspheres; ///< Sphere requirement in special stages.
fixed_t gravity; ///< Map-wide gravity.
// Title card. // Title card.
char ltzzpatch[8]; ///< Zig zag patch. char ltzzpatch[8]; ///< Zig zag patch.
@ -493,7 +496,6 @@ extern UINT16 emeralds;
#define EMERALD7 64 #define EMERALD7 64
#define ALL7EMERALDS(v) ((v & (EMERALD1|EMERALD2|EMERALD3|EMERALD4|EMERALD5|EMERALD6|EMERALD7)) == (EMERALD1|EMERALD2|EMERALD3|EMERALD4|EMERALD5|EMERALD6|EMERALD7)) #define ALL7EMERALDS(v) ((v & (EMERALD1|EMERALD2|EMERALD3|EMERALD4|EMERALD5|EMERALD6|EMERALD7)) == (EMERALD1|EMERALD2|EMERALD3|EMERALD4|EMERALD5|EMERALD6|EMERALD7))
// yes, even in non HAVE_BLUA
#define NUM_LUABANKS 16 // please only make this number go up between versions, never down. you'll break saves otherwise. also, must fit in UINT8 #define NUM_LUABANKS 16 // please only make this number go up between versions, never down. you'll break saves otherwise. also, must fit in UINT8
extern INT32 luabanks[NUM_LUABANKS]; extern INT32 luabanks[NUM_LUABANKS];
@ -543,7 +545,7 @@ extern recorddata_t *mainrecords[NUMMAPS];
extern UINT8 mapvisited[NUMMAPS]; extern UINT8 mapvisited[NUMMAPS];
// Temporary holding place for nights data for the current map // Temporary holding place for nights data for the current map
nightsdata_t ntemprecords; extern nightsdata_t ntemprecords;
extern UINT32 token; ///< Number of tokens collected in a level extern UINT32 token; ///< Number of tokens collected in a level
extern UINT32 tokenlist; ///< List of tokens collected extern UINT32 tokenlist; ///< List of tokens collected
@ -576,6 +578,8 @@ extern UINT8 creditscutscene;
extern UINT8 use1upSound; extern UINT8 use1upSound;
extern UINT8 maxXtraLife; // Max extra lives from rings extern UINT8 maxXtraLife; // Max extra lives from rings
extern UINT8 useContinues;
#define continuesInSession (!multiplayer && (useContinues || ultimatemode || !(cursaveslot > 0)))
extern mobj_t *hunt1, *hunt2, *hunt3; // Emerald hunt locations extern mobj_t *hunt1, *hunt2, *hunt3; // Emerald hunt locations
@ -616,6 +620,19 @@ extern mapthing_t *playerstarts[MAXPLAYERS]; // Cooperative
extern mapthing_t *bluectfstarts[MAXPLAYERS]; // CTF extern mapthing_t *bluectfstarts[MAXPLAYERS]; // CTF
extern mapthing_t *redctfstarts[MAXPLAYERS]; // CTF extern mapthing_t *redctfstarts[MAXPLAYERS]; // CTF
#define WAYPOINTSEQUENCESIZE 256
#define NUMWAYPOINTSEQUENCES 256
extern mobj_t *waypoints[NUMWAYPOINTSEQUENCES][WAYPOINTSEQUENCESIZE];
extern UINT16 numwaypoints[NUMWAYPOINTSEQUENCES];
void P_AddWaypoint(UINT8 sequence, UINT8 id, mobj_t *waypoint);
mobj_t *P_GetFirstWaypoint(UINT8 sequence);
mobj_t *P_GetLastWaypoint(UINT8 sequence);
mobj_t *P_GetPreviousWaypoint(mobj_t *current, boolean wrap);
mobj_t *P_GetNextWaypoint(mobj_t *current, boolean wrap);
mobj_t *P_GetClosestWaypoint(UINT8 sequence, mobj_t *mo);
boolean P_IsDegeneratedWaypointSequence(UINT8 sequence);
// ===================================== // =====================================
// Internal parameters, used for engine. // Internal parameters, used for engine.
// ===================================== // =====================================

View file

@ -11,10 +11,10 @@ boolean allow_fullscreen = false;
consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
void I_StartupGraphics(void){} void I_StartupGraphics(void){}
void I_StartupHardwareGraphics(void){}
void I_ShutdownGraphics(void){} void I_ShutdownGraphics(void){}
void VID_StartupOpenGL(void){}
void I_SetPalette(RGBA_t *palette) void I_SetPalette(RGBA_t *palette)
{ {
(void)palette; (void)palette;
@ -40,10 +40,8 @@ INT32 VID_SetMode(INT32 modenum)
return 0; return 0;
} }
void VID_CheckRenderer(void) void VID_CheckRenderer(void) {}
{ void VID_CheckGLLoaded(rendermode_t oldrender) {}
// ..............
}
const char *VID_GetModeName(INT32 modenum) const char *VID_GetModeName(INT32 modenum)
{ {

View file

@ -39,9 +39,7 @@
#include "fastcmp.h" #include "fastcmp.h"
#include "console.h" #include "console.h"
#ifdef HAVE_BLUA
#include "lua_hud.h" #include "lua_hud.h"
#endif
// Stage of animation: // Stage of animation:
// 0 = text, 1 = art screen // 0 = text, 1 = art screen
@ -2762,11 +2760,7 @@ void F_TitleScreenDrawer(void)
// rei|miru: use title pics? // rei|miru: use title pics?
hidepics = curhidepics; hidepics = curhidepics;
if (hidepics) if (hidepics)
#ifdef HAVE_BLUA
goto luahook; goto luahook;
#else
return;
#endif
switch(curttmode) switch(curttmode)
{ {
@ -3488,10 +3482,8 @@ void F_TitleScreenDrawer(void)
break; break;
} }
#ifdef HAVE_BLUA
luahook: luahook:
LUAh_TitleHUD(); LUAh_TitleHUD();
#endif
} }
// separate animation timer for backgrounds, since we also count // separate animation timer for backgrounds, since we also count
@ -3626,7 +3618,7 @@ void F_StartContinue(void)
{ {
I_Assert(!netgame && !multiplayer); I_Assert(!netgame && !multiplayer);
if (players[consoleplayer].continues <= 0) if (continuesInSession && players[consoleplayer].continues <= 0)
{ {
Command_ExitGame_f(); Command_ExitGame_f();
return; return;
@ -3733,7 +3725,9 @@ void F_ContinueDrawer(void)
} }
// Draw the continue markers! Show continues. // Draw the continue markers! Show continues.
if (ncontinues > 10) if (!continuesInSession)
;
else if (ncontinues > 10)
{ {
if (!(continuetime & 1) || continuetime > 17) if (!(continuetime & 1) || continuetime > 17)
V_DrawContinueIcon(x, 68, 0, players[consoleplayer].skin, players[consoleplayer].skincolor); V_DrawContinueIcon(x, 68, 0, players[consoleplayer].skin, players[consoleplayer].skincolor);

View file

@ -16,6 +16,7 @@
#include "i_video.h" #include "i_video.h"
#include "v_video.h" #include "v_video.h"
#include "r_state.h" // fadecolormap
#include "r_draw.h" // transtable #include "r_draw.h" // transtable
#include "p_pspr.h" // tr_transxxx #include "p_pspr.h" // tr_transxxx
#include "p_local.h" #include "p_local.h"
@ -32,9 +33,7 @@
#include "doomstat.h" #include "doomstat.h"
#ifdef HAVE_BLUA
#include "lua_hud.h" // level title #include "lua_hud.h" // level title
#endif
#ifdef HWRENDER #ifdef HWRENDER
#include "hardware/hw_main.h" #include "hardware/hw_main.h"

View file

@ -60,7 +60,7 @@ typedef enum
#endif #endif
EXT_PK3, EXT_PK3,
EXT_SOC, EXT_SOC,
EXT_LUA, // allowed even if not HAVE_BLUA so that we can yell on load attempt EXT_LUA,
NUM_EXT, NUM_EXT,
NUM_EXT_TABLE = NUM_EXT-EXT_START, NUM_EXT_TABLE = NUM_EXT-EXT_START,
EXT_LOADED = 0x80 EXT_LOADED = 0x80

2505
src/g_demo.c Normal file

File diff suppressed because it is too large Load diff

86
src/g_demo.h Normal file
View file

@ -0,0 +1,86 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2020 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file g_demo.h
/// \brief Demo recording and playback
#ifndef __G_DEMO__
#define __G_DEMO__
#include "doomdef.h"
#include "doomstat.h"
#include "d_event.h"
// ======================================
// DEMO playback/recording related stuff.
// ======================================
// demoplaying back and demo recording
extern boolean demoplayback, titledemo, demorecording, timingdemo;
extern tic_t demostarttime;
// Quit after playing a demo from cmdline.
extern boolean singledemo;
extern boolean demo_start;
extern boolean demosynced;
extern mobj_t *metalplayback;
// Only called by startup code.
void G_RecordDemo(const char *name);
void G_RecordMetal(void);
void G_BeginRecording(void);
void G_BeginMetal(void);
// Only called by shutdown code.
void G_SetDemoTime(UINT32 ptime, UINT32 pscore, UINT16 prings);
UINT8 G_CmpDemoTime(char *oldname, char *newname);
typedef enum
{
GHC_NORMAL = 0,
GHC_SUPER,
GHC_FIREFLOWER,
GHC_INVINCIBLE,
GHC_NIGHTSSKIN, // not actually a colour
GHC_RETURNSKIN // ditto
} ghostcolor_t;
// Record/playback tics
void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum);
void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum);
void G_GhostAddThok(void);
void G_GhostAddSpin(void);
void G_GhostAddRev(void);
void G_GhostAddColor(ghostcolor_t color);
void G_GhostAddFlip(void);
void G_GhostAddScale(fixed_t scale);
void G_GhostAddHit(mobj_t *victim);
void G_WriteGhostTic(mobj_t *ghost);
void G_ConsGhostTic(void);
void G_GhostTicker(void);
void G_ReadMetalTic(mobj_t *metal);
void G_WriteMetalTic(mobj_t *metal);
void G_SaveMetal(UINT8 **buffer);
void G_LoadMetal(UINT8 **buffer);
void G_DeferedPlayDemo(const char *demo);
void G_DoPlayDemo(char *defdemoname);
void G_TimeDemo(const char *name);
void G_AddGhost(char *defdemoname);
void G_FreeGhosts(void);
void G_DoPlayMetal(void);
void G_DoneLevelLoad(void);
void G_StopMetalDemo(void);
ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill);
void G_StopDemo(void);
boolean G_CheckDemoStatus(void);
#endif // __G_DEMO__

File diff suppressed because it is too large Load diff

View file

@ -17,6 +17,7 @@
#include "doomdef.h" #include "doomdef.h"
#include "doomstat.h" #include "doomstat.h"
#include "d_event.h" #include "d_event.h"
#include "g_demo.h"
extern char gamedatafilename[64]; extern char gamedatafilename[64];
extern char timeattackfolder[64]; extern char timeattackfolder[64];
@ -31,21 +32,6 @@ extern char player_names[MAXPLAYERS][MAXPLAYERNAME+1];
extern player_t players[MAXPLAYERS]; extern player_t players[MAXPLAYERS];
extern boolean playeringame[MAXPLAYERS]; extern boolean playeringame[MAXPLAYERS];
// ======================================
// DEMO playback/recording related stuff.
// ======================================
// demoplaying back and demo recording
extern boolean demoplayback, titledemo, demorecording, timingdemo;
extern tic_t demostarttime;
// Quit after playing a demo from cmdline.
extern boolean singledemo;
extern boolean demo_start;
extern boolean demosynced;
extern mobj_t *metalplayback;
// gametic at level start // gametic at level start
extern tic_t levelstarttic; extern tic_t levelstarttic;
@ -173,7 +159,6 @@ void G_DoLoadLevel(boolean resetplayer);
void G_StartTitleCard(void); void G_StartTitleCard(void);
void G_PreLevelTitleCard(void); void G_PreLevelTitleCard(void);
boolean G_IsTitleCardAvailable(void); boolean G_IsTitleCardAvailable(void);
void G_DeferedPlayDemo(const char *demo);
// Can be called by the startup code or M_Responder, calls P_SetupLevel. // Can be called by the startup code or M_Responder, calls P_SetupLevel.
void G_LoadGame(UINT32 slot, INT16 mapoverride); void G_LoadGame(UINT32 slot, INT16 mapoverride);
@ -184,54 +169,6 @@ void G_SaveGame(UINT32 slot);
void G_SaveGameOver(UINT32 slot, boolean modifylives); void G_SaveGameOver(UINT32 slot, boolean modifylives);
// Only called by startup code.
void G_RecordDemo(const char *name);
void G_RecordMetal(void);
void G_BeginRecording(void);
void G_BeginMetal(void);
// Only called by shutdown code.
void G_SetDemoTime(UINT32 ptime, UINT32 pscore, UINT16 prings);
UINT8 G_CmpDemoTime(char *oldname, char *newname);
typedef enum
{
GHC_NORMAL = 0,
GHC_SUPER,
GHC_FIREFLOWER,
GHC_INVINCIBLE,
GHC_NIGHTSSKIN, // not actually a colour
GHC_RETURNSKIN // ditto
} ghostcolor_t;
// Record/playback tics
void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum);
void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum);
void G_GhostAddThok(void);
void G_GhostAddSpin(void);
void G_GhostAddRev(void);
void G_GhostAddColor(ghostcolor_t color);
void G_GhostAddFlip(void);
void G_GhostAddScale(fixed_t scale);
void G_GhostAddHit(mobj_t *victim);
void G_WriteGhostTic(mobj_t *ghost);
void G_ConsGhostTic(void);
void G_GhostTicker(void);
void G_ReadMetalTic(mobj_t *metal);
void G_WriteMetalTic(mobj_t *metal);
void G_SaveMetal(UINT8 **buffer);
void G_LoadMetal(UINT8 **buffer);
void G_DoPlayDemo(char *defdemoname);
void G_TimeDemo(const char *name);
void G_AddGhost(char *defdemoname);
void G_DoPlayMetal(void);
void G_DoneLevelLoad(void);
void G_StopMetalDemo(void);
ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill);
void G_StopDemo(void);
boolean G_CheckDemoStatus(void);
extern UINT32 gametypedefaultrules[NUMGAMETYPES]; extern UINT32 gametypedefaultrules[NUMGAMETYPES];
extern UINT32 gametypetol[NUMGAMETYPES]; extern UINT32 gametypetol[NUMGAMETYPES];
extern INT16 gametyperankings[NUMGAMETYPES]; extern INT16 gametyperankings[NUMGAMETYPES];
@ -309,6 +246,6 @@ FUNCMATH INT32 G_TicsToCentiseconds(tic_t tics);
FUNCMATH INT32 G_TicsToMilliseconds(tic_t tics); FUNCMATH INT32 G_TicsToMilliseconds(tic_t tics);
// Don't split up TOL handling // Don't split up TOL handling
INT16 G_TOLFlag(INT32 pgametype); UINT32 G_TOLFlag(INT32 pgametype);
#endif #endif

View file

@ -28,7 +28,7 @@
#include "../tables.h" #include "../tables.h"
#include "../sounds.h" #include "../sounds.h"
#include "../r_main.h" #include "../r_main.h"
#include "../r_things.h" #include "../r_skins.h"
#include "../m_random.h" #include "../m_random.h"
#include "../p_local.h" #include "../p_local.h"
#include "hw3dsdrv.h" #include "hw3dsdrv.h"

View file

@ -887,12 +887,10 @@ static void AdjustSegs(void)
float distv1,distv2,tmp; float distv1,distv2,tmp;
nearv1 = nearv2 = MYMAX; nearv1 = nearv2 = MYMAX;
#ifdef POLYOBJECTS
// Don't touch polyobject segs. We'll compensate // Don't touch polyobject segs. We'll compensate
// for this when we go about drawing them. // for this when we go about drawing them.
if (lseg->polyseg) if (lseg->polyseg)
continue; continue;
#endif
if (p) { if (p) {
for (j = 0; j < p->numpts; j++) for (j = 0; j < p->numpts; j++)

View file

@ -234,11 +234,11 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
if (mipmap->colormap) if (mipmap->colormap)
texel = mipmap->colormap[texel]; texel = mipmap->colormap[texel];
// transparent pixel // If the mipmap is chromakeyed, check if the texel's color
if (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX) // is equivalent to the chroma key's color index.
alpha = 0xff;
if ((mipmap->flags & TF_CHROMAKEYED) && (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX))
alpha = 0x00; alpha = 0x00;
else
alpha = 0xff;
// hope compiler will get this switch out of the loops (dreams...) // hope compiler will get this switch out of the loops (dreams...)
// gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?) // gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?)

View file

@ -291,7 +291,7 @@ void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t
if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT) if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT)
{ {
// Need to temporarily cache the real patch to get the colour of the top left pixel // Need to temporarily cache the real patch to get the colour of the top left pixel
patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC); patch_t *realpatch = W_CacheSoftwarePatchNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
const column_t *column = (const column_t *)((const UINT8 *)(realpatch) + LONG((realpatch)->columnofs[0])); const column_t *column = (const column_t *)((const UINT8 *)(realpatch) + LONG((realpatch)->columnofs[0]));
if (!column->topdelta) if (!column->topdelta)
{ {
@ -450,7 +450,7 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT) if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT)
{ {
// Need to temporarily cache the real patch to get the colour of the top left pixel // Need to temporarily cache the real patch to get the colour of the top left pixel
patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC); patch_t *realpatch = W_CacheSoftwarePatchNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
const column_t *column = (const column_t *)((const UINT8 *)(realpatch) + LONG((realpatch)->columnofs[0])); const column_t *column = (const column_t *)((const UINT8 *)(realpatch) + LONG((realpatch)->columnofs[0]));
if (!column->topdelta) if (!column->topdelta)
{ {

View file

@ -298,6 +298,8 @@ light_t *t_lspr[NUMSPRITES] =
// Projectiles // Projectiles
&lspr[NOLIGHT], // SPR_MISL &lspr[NOLIGHT], // SPR_MISL
&lspr[SMALLREDBALL_L], // SPR_LASR
&lspr[REDSHINE_L], // SPR_LASF
&lspr[NOLIGHT], // SPR_TORP &lspr[NOLIGHT], // SPR_TORP
&lspr[NOLIGHT], // SPR_ENRG &lspr[NOLIGHT], // SPR_ENRG
&lspr[NOLIGHT], // SPR_MINE &lspr[NOLIGHT], // SPR_MINE

File diff suppressed because it is too large Load diff

View file

@ -1221,7 +1221,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr)
light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); // Always use the light at the top instead of whatever I was doing before light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); // Always use the light at the top instead of whatever I was doing before
if (!(spr->mobj->frame & FF_FULLBRIGHT)) if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = *sector->lightlist[light].lightlevel; lightlevel = *sector->lightlist[light].lightlevel > 255 ? 255 : *sector->lightlist[light].lightlevel;
if (*sector->lightlist[light].extra_colormap) if (*sector->lightlist[light].extra_colormap)
colormap = *sector->lightlist[light].extra_colormap; colormap = *sector->lightlist[light].extra_colormap;
@ -1229,7 +1229,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr)
else else
{ {
if (!(spr->mobj->frame & FF_FULLBRIGHT)) if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = sector->lightlevel; lightlevel = sector->lightlevel > 255 ? 255 : sector->lightlevel;
if (sector->extra_colormap) if (sector->extra_colormap)
colormap = sector->extra_colormap; colormap = sector->extra_colormap;
@ -1478,7 +1478,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr)
// rotation pivot // rotation pivot
p.centerx = FIXED_TO_FLOAT(spr->mobj->radius/2); p.centerx = FIXED_TO_FLOAT(spr->mobj->radius/2);
p.centery = FIXED_TO_FLOAT(spr->mobj->height/2); p.centery = FIXED_TO_FLOAT(spr->mobj->height/(flip ? -2 : 2));
// rotation axis // rotation axis
if (sprinfo->available) if (sprinfo->available)
@ -1490,6 +1490,9 @@ boolean HWR_DrawModel(gr_vissprite_t *spr)
p.rollflip = 1; p.rollflip = 1;
else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left
p.rollflip = -1; p.rollflip = -1;
if (flip)
p.rollflip *= -1;
} }
p.anglex = 0.0f; p.anglex = 0.0f;

View file

@ -610,10 +610,8 @@ static boolean isCeilingFloating(sector_t *thisSector)
if (!adjSector) // assume floating sectors have surrounding sectors if (!adjSector) // assume floating sectors have surrounding sectors
return false; return false;
#ifdef ESLOPE
if (adjSector->c_slope) // Don't bother with slopes if (adjSector->c_slope) // Don't bother with slopes
return false; return false;
#endif
if (!refSector) if (!refSector)
{ {
@ -663,10 +661,8 @@ static boolean isFloorFloating(sector_t *thisSector)
if (!adjSector) // assume floating sectors have surrounding sectors if (!adjSector) // assume floating sectors have surrounding sectors
return false; return false;
#ifdef ESLOPE
if (adjSector->f_slope) // Don't bother with slopes if (adjSector->f_slope) // Don't bother with slopes
return false; return false;
#endif
if (!refSector) if (!refSector)
{ {

View file

@ -49,8 +49,7 @@ static const GLubyte white[4] = { 255, 255, 255, 255 };
// ========================================================================== // ==========================================================================
// With OpenGL 1.1+, the first texture should be 1 // With OpenGL 1.1+, the first texture should be 1
#define NOTEXTURE_NUM 1 // small white texture static GLuint NOTEXTURE_NUM = 0;
#define FIRST_TEX_AVAIL (NOTEXTURE_NUM + 1)
#define N_PI_DEMI (M_PIl/2.0f) //(1.5707963268f) #define N_PI_DEMI (M_PIl/2.0f) //(1.5707963268f)
@ -63,7 +62,6 @@ static float NEAR_CLIPPING_PLANE = NZCLIP_PLANE;
// ************************************************************************** // **************************************************************************
static GLuint NextTexAvail = FIRST_TEX_AVAIL;
static GLuint tex_downloaded = 0; static GLuint tex_downloaded = 0;
static GLfloat fov = 90.0f; static GLfloat fov = 90.0f;
#if 0 #if 0
@ -72,8 +70,8 @@ static FRGBAFloat const_pal_col;
#endif #endif
static FBITFIELD CurrentPolyFlags; static FBITFIELD CurrentPolyFlags;
static FTextureInfo* gr_cachetail = NULL; static FTextureInfo *gr_cachetail = NULL;
static FTextureInfo* gr_cachehead = NULL; static FTextureInfo *gr_cachehead = NULL;
RGBA_t myPaletteData[256]; RGBA_t myPaletteData[256];
GLint screen_width = 0; // used by Draw2DLine() GLint screen_width = 0; // used by Draw2DLine()
@ -94,16 +92,10 @@ static GLfloat modelMatrix[16];
static GLfloat projMatrix[16]; static GLfloat projMatrix[16];
static GLint viewport[4]; static GLint viewport[4];
// Yay for arbitrary numbers! NextTexAvail is buggy for some reason.
// Sryder: NextTexAvail is broken for these because palette changes or changes to the texture filter or antialiasing // Sryder: NextTexAvail is broken for these because palette changes or changes to the texture filter or antialiasing
// flush all of the stored textures, leaving them unavailable at times such as between levels // flush all of the stored textures, leaving them unavailable at times such as between levels
// These need to start at 0 and be set to their number, and be reset to 0 when deleted so that intel GPUs // These need to start at 0 and be set to their number, and be reset to 0 when deleted so that intel GPUs
// can know when the textures aren't there, as textures are always considered resident in their virtual memory // can know when the textures aren't there, as textures are always considered resident in their virtual memory
// TODO: Store them in a more normal way
#define SCRTEX_SCREENTEXTURE 4294967295U
#define SCRTEX_STARTSCREENWIPE 4294967294U
#define SCRTEX_ENDSCREENWIPE 4294967293U
#define SCRTEX_FINALSCREENTEXTURE 4294967292U
static GLuint screentexture = 0; static GLuint screentexture = 0;
static GLuint startScreenWipe = 0; static GLuint startScreenWipe = 0;
static GLuint endScreenWipe = 0; static GLuint endScreenWipe = 0;
@ -243,6 +235,7 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...)
/* 1.1 functions */ /* 1.1 functions */
/* texture objects */ //GL_EXT_texture_object /* texture objects */ //GL_EXT_texture_object
#define pglGenTextures glGenTextures
#define pglDeleteTextures glDeleteTextures #define pglDeleteTextures glDeleteTextures
#define pglBindTexture glBindTexture #define pglBindTexture glBindTexture
/* texture mapping */ //GL_EXT_copy_texture /* texture mapping */ //GL_EXT_copy_texture
@ -359,6 +352,8 @@ static PFNglFogfv pglFogfv;
/* 1.1 functions */ /* 1.1 functions */
/* texture objects */ //GL_EXT_texture_object /* texture objects */ //GL_EXT_texture_object
typedef void (APIENTRY * PFNglGenTextures) (GLsizei n, const GLuint *textures);
static PFNglGenTextures pglGenTextures;
typedef void (APIENTRY * PFNglDeleteTextures) (GLsizei n, const GLuint *textures); typedef void (APIENTRY * PFNglDeleteTextures) (GLsizei n, const GLuint *textures);
static PFNglDeleteTextures pglDeleteTextures; static PFNglDeleteTextures pglDeleteTextures;
typedef void (APIENTRY * PFNglBindTexture) (GLenum target, GLuint texture); typedef void (APIENTRY * PFNglBindTexture) (GLenum target, GLuint texture);
@ -487,6 +482,7 @@ boolean SetupGLfunc(void)
GETOPENGLFUNC(pglFogf , glFogf) GETOPENGLFUNC(pglFogf , glFogf)
GETOPENGLFUNC(pglFogfv , glFogfv) GETOPENGLFUNC(pglFogfv , glFogfv)
GETOPENGLFUNC(pglGenTextures , glGenTextures)
GETOPENGLFUNC(pglDeleteTextures , glDeleteTextures) GETOPENGLFUNC(pglDeleteTextures , glDeleteTextures)
GETOPENGLFUNC(pglBindTexture , glBindTexture) GETOPENGLFUNC(pglBindTexture , glBindTexture)
@ -527,6 +523,8 @@ static void SetNoTexture(void)
// Set small white texture. // Set small white texture.
if (tex_downloaded != NOTEXTURE_NUM) if (tex_downloaded != NOTEXTURE_NUM)
{ {
if (NOTEXTURE_NUM == 0)
pglGenTextures(1, &NOTEXTURE_NUM);
pglBindTexture(GL_TEXTURE_2D, NOTEXTURE_NUM); pglBindTexture(GL_TEXTURE_2D, NOTEXTURE_NUM);
tex_downloaded = NOTEXTURE_NUM; tex_downloaded = NOTEXTURE_NUM;
} }
@ -641,11 +639,6 @@ void SetModelView(GLint w, GLint h)
// -----------------+ // -----------------+
void SetStates(void) void SetStates(void)
{ {
// Bind little white RGBA texture to ID NOTEXTURE_NUM.
/*
FUINT Data[8*8];
INT32 i;
*/
#ifdef GL_LIGHT_MODEL_AMBIENT #ifdef GL_LIGHT_MODEL_AMBIENT
GLfloat LightDiffuse[] = {1.0f, 1.0f, 1.0f, 1.0f}; GLfloat LightDiffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};
#endif #endif
@ -679,16 +672,8 @@ void SetStates(void)
CurrentPolyFlags = 0xffffffff; CurrentPolyFlags = 0xffffffff;
SetBlend(0); SetBlend(0);
/* tex_downloaded = 0;
for (i = 0; i < 64; i++)
Data[i] = 0xffFFffFF; // white pixel
*/
tex_downloaded = (GLuint)-1;
SetNoTexture(); SetNoTexture();
//pglBindTexture(GL_TEXTURE_2D, NOTEXTURE_NUM);
//tex_downloaded = NOTEXTURE_NUM;
//pglTexImage2D(GL_TEXTURE_2D, 0, 4, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, Data);
pglPolygonOffset(-1.0f, -1.0f); pglPolygonOffset(-1.0f, -1.0f);
@ -723,33 +708,12 @@ void Flush(void)
while (gr_cachehead) while (gr_cachehead)
{ {
// this is not necessary at all, because you have loaded them normally, if (gr_cachehead->downloaded)
// and so they already are in your list! pglDeleteTextures(1, (GLuint *)&gr_cachehead->downloaded);
#if 0
//Hurdler: 25/04/2000: now support colormap in hardware mode
FTextureInfo *tmp = gr_cachehead->nextskin;
// The memory should be freed in the main code
while (tmp)
{
pglDeleteTextures(1, &tmp->downloaded);
tmp->downloaded = 0;
tmp = tmp->nextcolormap;
}
#endif
pglDeleteTextures(1, (GLuint *)&gr_cachehead->downloaded);
gr_cachehead->downloaded = 0; gr_cachehead->downloaded = 0;
gr_cachehead = gr_cachehead->nextmipmap; gr_cachehead = gr_cachehead->nextmipmap;
} }
gr_cachetail = gr_cachehead = NULL; //Hurdler: well, gr_cachehead is already NULL gr_cachetail = gr_cachehead = NULL; //Hurdler: well, gr_cachehead is already NULL
NextTexAvail = FIRST_TEX_AVAIL;
#if 0
if (screentexture != FIRST_TEX_AVAIL)
{
pglDeleteTextures(1, &screentexture);
screentexture = FIRST_TEX_AVAIL;
}
#endif
tex_downloaded = 0; tex_downloaded = 0;
} }
@ -1128,8 +1092,10 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo)
static RGBA_t tex[2048*2048]; static RGBA_t tex[2048*2048];
const GLvoid *ptex = tex; const GLvoid *ptex = tex;
INT32 w, h; INT32 w, h;
GLuint texnum = 0;
//DBG_Printf ("DownloadMipmap %d %x\n",NextTexAvail,pTexInfo->grInfo.data); pglGenTextures(1, &texnum);
//DBG_Printf ("DownloadMipmap %d %x\n",(INT32)texnum,pTexInfo->grInfo.data);
w = pTexInfo->width; w = pTexInfo->width;
h = pTexInfo->height; h = pTexInfo->height;
@ -1217,9 +1183,10 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo)
else else
DBG_Printf ("SetTexture(bad format) %ld\n", pTexInfo->grInfo.format); DBG_Printf ("SetTexture(bad format) %ld\n", pTexInfo->grInfo.format);
pTexInfo->downloaded = NextTexAvail++; // the texture number was already generated by pglGenTextures
tex_downloaded = pTexInfo->downloaded; pglBindTexture(GL_TEXTURE_2D, texnum);
pglBindTexture(GL_TEXTURE_2D, pTexInfo->downloaded); pTexInfo->downloaded = texnum;
tex_downloaded = texnum;
// disable texture filtering on any texture that has holes so there's no dumb borders or blending issues // disable texture filtering on any texture that has holes so there's no dumb borders or blending issues
if (pTexInfo->flags & TF_TRANSPARENT) if (pTexInfo->flags & TF_TRANSPARENT)
@ -2419,7 +2386,7 @@ EXPORT void HWRAPI(StartScreenWipe) (void)
// Create screen texture // Create screen texture
if (firstTime) if (firstTime)
startScreenWipe = SCRTEX_STARTSCREENWIPE; pglGenTextures(1, &startScreenWipe);
pglBindTexture(GL_TEXTURE_2D, startScreenWipe); pglBindTexture(GL_TEXTURE_2D, startScreenWipe);
if (firstTime) if (firstTime)
@ -2450,7 +2417,7 @@ EXPORT void HWRAPI(EndScreenWipe)(void)
// Create screen texture // Create screen texture
if (firstTime) if (firstTime)
endScreenWipe = SCRTEX_ENDSCREENWIPE; pglGenTextures(1, &endScreenWipe);
pglBindTexture(GL_TEXTURE_2D, endScreenWipe); pglBindTexture(GL_TEXTURE_2D, endScreenWipe);
if (firstTime) if (firstTime)
@ -2621,7 +2588,7 @@ EXPORT void HWRAPI(MakeScreenTexture) (void)
// Create screen texture // Create screen texture
if (firstTime) if (firstTime)
screentexture = SCRTEX_SCREENTEXTURE; pglGenTextures(1, &screentexture);
pglBindTexture(GL_TEXTURE_2D, screentexture); pglBindTexture(GL_TEXTURE_2D, screentexture);
if (firstTime) if (firstTime)
@ -2651,7 +2618,7 @@ EXPORT void HWRAPI(MakeScreenFinalTexture) (void)
// Create screen texture // Create screen texture
if (firstTime) if (firstTime)
finalScreenTexture = SCRTEX_FINALSCREENTEXTURE; pglGenTextures(1, &finalScreenTexture);
pglBindTexture(GL_TEXTURE_2D, finalScreenTexture); pglBindTexture(GL_TEXTURE_2D, finalScreenTexture);
if (firstTime) if (firstTime)

View file

@ -47,10 +47,8 @@
#include "hardware/hw_main.h" #include "hardware/hw_main.h"
#endif #endif
#ifdef HAVE_BLUA
#include "lua_hud.h" #include "lua_hud.h"
#include "lua_hook.h" #include "lua_hook.h"
#endif
// coords are scaled // coords are scaled
#define HU_INPUTX 0 #define HU_INPUTX 0
@ -70,7 +68,7 @@ patch_t *nightsnum[10]; // 0-9
// Level title and credits fonts // Level title and credits fonts
patch_t *lt_font[LT_FONTSIZE]; patch_t *lt_font[LT_FONTSIZE];
patch_t *cred_font[CRED_FONTSIZE]; patch_t *cred_font[CRED_FONTSIZE];
patch_t *ttlnum[20]; // act numbers (0-19) patch_t *ttlnum[10]; // act numbers (0-9)
// Name tag fonts // Name tag fonts
patch_t *ntb_font[NT_FONTSIZE]; patch_t *ntb_font[NT_FONTSIZE];
@ -245,7 +243,7 @@ void HU_LoadGraphics(void)
tallinfin = (patch_t *)W_CachePatchName("STTINFIN", PU_HUDGFX); tallinfin = (patch_t *)W_CachePatchName("STTINFIN", PU_HUDGFX);
// cache act numbers for level titles // cache act numbers for level titles
for (i = 0; i < 20; i++) for (i = 0; i < 10; i++)
{ {
sprintf(buffer, "TTL%.2d", i); sprintf(buffer, "TTL%.2d", i);
ttlnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); ttlnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
@ -688,10 +686,8 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
// run the lua hook even if we were supposed to eat the msg, netgame consistency goes first. // run the lua hook even if we were supposed to eat the msg, netgame consistency goes first.
#ifdef HAVE_BLUA
if (LUAh_PlayerMsg(playernum, target, flags, msg)) if (LUAh_PlayerMsg(playernum, target, flags, msg))
return; return;
#endif
if (spam_eatmsg) if (spam_eatmsg)
return; // don't proceed if we were supposed to eat the message. return; // don't proceed if we were supposed to eat the message.
@ -2104,18 +2100,14 @@ void HU_Drawer(void)
{ {
if (netgame || multiplayer) if (netgame || multiplayer)
{ {
#ifdef HAVE_BLUA
if (LUA_HudEnabled(hud_rankings)) if (LUA_HudEnabled(hud_rankings))
#endif HU_DrawRankings();
HU_DrawRankings();
if (gametype == GT_COOP) if (gametype == GT_COOP)
HU_DrawNetplayCoopOverlay(); HU_DrawNetplayCoopOverlay();
} }
else else
HU_DrawCoopOverlay(); HU_DrawCoopOverlay();
#ifdef HAVE_BLUA
LUAh_ScoresHUD(); LUAh_ScoresHUD();
#endif
} }
if (gamestate != GS_LEVEL) if (gamestate != GS_LEVEL)
@ -3098,29 +3090,20 @@ static void HU_DrawRankings(void)
static void HU_DrawCoopOverlay(void) static void HU_DrawCoopOverlay(void)
{ {
if (token if (token && LUA_HudEnabled(hud_tokens))
#ifdef HAVE_BLUA
&& LUA_HudEnabled(hud_tokens)
#endif
)
{ {
V_DrawString(168, 176, 0, va("- %d", token)); V_DrawString(168, 176, 0, va("- %d", token));
V_DrawSmallScaledPatch(148, 172, 0, tokenicon); V_DrawSmallScaledPatch(148, 172, 0, tokenicon);
} }
#ifdef HAVE_BLUA if (LUA_HudEnabled(hud_tabemblems) && (!modifiedgame || savemoddata))
if (LUA_HudEnabled(hud_tabemblems))
#endif
if (!modifiedgame || savemoddata)
{ {
V_DrawString(160, 144, 0, va("- %d/%d", M_CountEmblems(), numemblems+numextraemblems)); V_DrawString(160, 144, 0, va("- %d/%d", M_CountEmblems(), numemblems+numextraemblems));
V_DrawScaledPatch(128, 144 - SHORT(emblemicon->height)/4, 0, emblemicon); V_DrawScaledPatch(128, 144 - SHORT(emblemicon->height)/4, 0, emblemicon);
} }
#ifdef HAVE_BLUA
if (!LUA_HudEnabled(hud_coopemeralds)) if (!LUA_HudEnabled(hud_coopemeralds))
return; return;
#endif
if (emeralds & EMERALD1) if (emeralds & EMERALD1)
V_DrawScaledPatch((BASEVIDWIDTH/2)-8 , (BASEVIDHEIGHT/3)-32, 0, emeraldpics[0][0]); V_DrawScaledPatch((BASEVIDWIDTH/2)-8 , (BASEVIDHEIGHT/3)-32, 0, emeraldpics[0][0]);
@ -3142,20 +3125,14 @@ static void HU_DrawNetplayCoopOverlay(void)
{ {
int i; int i;
if (token if (token && LUA_HudEnabled(hud_tokens))
#ifdef HAVE_BLUA
&& LUA_HudEnabled(hud_tokens)
#endif
)
{ {
V_DrawString(168, 10, 0, va("- %d", token)); V_DrawString(168, 10, 0, va("- %d", token));
V_DrawSmallScaledPatch(148, 6, 0, tokenicon); V_DrawSmallScaledPatch(148, 6, 0, tokenicon);
} }
#ifdef HAVE_BLUA
if (!LUA_HudEnabled(hud_coopemeralds)) if (!LUA_HudEnabled(hud_coopemeralds))
return; return;
#endif
for (i = 0; i < 7; ++i) for (i = 0; i < 7; ++i)
{ {

View file

@ -85,7 +85,7 @@ extern patch_t *lt_font[LT_FONTSIZE];
extern patch_t *cred_font[CRED_FONTSIZE]; extern patch_t *cred_font[CRED_FONTSIZE];
extern patch_t *ntb_font[NT_FONTSIZE]; extern patch_t *ntb_font[NT_FONTSIZE];
extern patch_t *nto_font[NT_FONTSIZE]; extern patch_t *nto_font[NT_FONTSIZE];
extern patch_t *ttlnum[20]; extern patch_t *ttlnum[10];
extern patch_t *emeraldpics[3][8]; extern patch_t *emeraldpics[3][8];
extern patch_t *rflagico; extern patch_t *rflagico;
extern patch_t *bflagico; extern patch_t *bflagico;

View file

@ -1423,6 +1423,7 @@ static void SOCK_ClearBans(void)
boolean I_InitTcpNetwork(void) boolean I_InitTcpNetwork(void)
{ {
char serverhostname[255]; char serverhostname[255];
const char *urlparam = NULL;
boolean ret = false; boolean ret = false;
// initilize the OS's TCP/IP stack // initilize the OS's TCP/IP stack
if (!I_InitTcpDriver()) if (!I_InitTcpDriver())
@ -1476,10 +1477,12 @@ boolean I_InitTcpNetwork(void)
ret = true; ret = true;
} }
else if (M_CheckParm("-connect")) else if ((urlparam = M_GetUrlProtocolArg()) != NULL || M_CheckParm("-connect"))
{ {
if (M_IsNextParm()) if (urlparam != NULL)
strcpy(serverhostname, M_GetNextParm()); strlcpy(serverhostname, urlparam, sizeof(serverhostname));
else if (M_IsNextParm())
strlcpy(serverhostname, M_GetNextParm(), sizeof(serverhostname));
else else
serverhostname[0] = 0; // assuming server in the LAN, use broadcast to detect it serverhostname[0] = 0; // assuming server in the LAN, use broadcast to detect it

View file

@ -32,10 +32,14 @@ typedef enum
render_none = 3 // for dedicated server render_none = 3 // for dedicated server
} rendermode_t; } rendermode_t;
/** \brief currect render mode /** \brief current render mode
*/ */
extern rendermode_t rendermode; extern rendermode_t rendermode;
/** \brief OpenGL state
0 = never loaded, 1 = loaded successfully, -1 = failed loading
*/
extern INT32 vid_opengl_state;
/** \brief use highcolor modes if true /** \brief use highcolor modes if true
*/ */
@ -44,9 +48,8 @@ extern boolean highcolor;
/** \brief setup video mode /** \brief setup video mode
*/ */
void I_StartupGraphics(void); void I_StartupGraphics(void);
void I_StartupHardwareGraphics(void);
/** \brief restore old video mode /** \brief shutdown video mode
*/ */
void I_ShutdownGraphics(void); void I_ShutdownGraphics(void);
@ -82,11 +85,22 @@ INT32 VID_GetModeForSize(INT32 w, INT32 h);
\param modenum video mode to set to \param modenum video mode to set to
\return currect video mode \return current video mode
*/ */
INT32 VID_SetMode(INT32 modenum); INT32 VID_SetMode(INT32 modenum);
/** \brief Checks the render state
*/
void VID_CheckRenderer(void); void VID_CheckRenderer(void);
/** \brief Load OpenGL mode
*/
void VID_StartupOpenGL(void);
/** \brief Checks if OpenGL loaded
*/
void VID_CheckGLLoaded(rendermode_t oldrender);
/** \brief The VID_GetModeName function /** \brief The VID_GetModeName function
\param modenum video mode number \param modenum video mode number

View file

@ -188,6 +188,8 @@ char sprnames[NUMSPRITES + 1][5] =
// Projectiles // Projectiles
"MISL", "MISL",
"LASR", // GFZ3 laser
"LASF", // GFZ3 laser flames
"TORP", // Torpedo "TORP", // Torpedo
"ENRG", // Energy ball "ENRG", // Energy ball
"MINE", // Skim mine "MINE", // Skim mine
@ -2059,7 +2061,15 @@ state_t states[NUMSTATES] =
{SPR_MISL, FF_FULLBRIGHT, 1, {A_SmokeTrailer}, MT_SMOKE, 0, S_ROCKET}, // S_ROCKET {SPR_MISL, FF_FULLBRIGHT, 1, {A_SmokeTrailer}, MT_SMOKE, 0, S_ROCKET}, // S_ROCKET
{SPR_MISL, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_LASER {SPR_LASR, FF_FULLBRIGHT|0, 2, {NULL}, 0, 0, S_NULL}, // S_LASER
{SPR_LASR, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_NULL}, // S_LASER2
{SPR_LASR, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_NULL}, // S_LASERFLASH
{SPR_LASF, FF_FULLBRIGHT|0, 2, {NULL}, 0, 0, S_LASERFLAME2}, // S_LASERFLAME1
{SPR_LASF, FF_FULLBRIGHT|1, 1, {A_ChangeHeight}, 156*FRACUNIT, 3, S_LASERFLAME3}, // S_LASERFLAME2
{SPR_LASF, FF_FULLBRIGHT|2, 0, {A_ChangeHeight}, 32*FRACUNIT, 3, S_LASERFLAME4}, // S_LASERFLAME3
{SPR_LASF, FF_ANIMATE|FF_PAPERSPRITE|FF_FULLBRIGHT|2, 4, {NULL}, 1, 2, S_LASERFLAME5}, // S_LASERFLAME4
{SPR_LASF, FF_ANIMATE|FF_PAPERSPRITE|FF_FULLBRIGHT|4, 28, {NULL}, 2, 2, S_NULL}, // S_LASERFLAME5
{SPR_TORP, 0, 1, {A_SmokeTrailer}, MT_SMOKE, 0, S_TORPEDO}, // S_TORPEDO {SPR_TORP, 0, 1, {A_SmokeTrailer}, MT_SMOKE, 0, S_TORPEDO}, // S_TORPEDO
@ -5666,28 +5676,28 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_EGGMOBILE_FIRE { // MT_EGGMOBILE_FIRE
-1, // doomednum -1, // doomednum
S_SPINFIRE1, // spawnstate S_LASERFLAME1, // spawnstate
1, // spawnhealth 1, // spawnhealth
S_NULL, // seestate S_NULL, // seestate
sfx_None, // seesound sfx_s3kc2s, // seesound
8, // reactiontime 8, // reactiontime
sfx_None, // attacksound sfx_None, // attacksound
S_NULL, // painstate S_NULL, // painstate
0, // painchance 0, // painchance
sfx_None, // painsound sfx_s3k8d, // painsound
S_NULL, // meleestate S_NULL, // meleestate
S_NULL, // missilestate S_NULL, // missilestate
S_NULL, // deathstate S_NULL, // deathstate
S_NULL, // xdeathstate S_NULL, // xdeathstate
sfx_None, // deathsound sfx_None, // deathsound
0, // speed 0, // speed
8*FRACUNIT, // radius 24*FRACUNIT, // radius
14*FRACUNIT, // height 84*FRACUNIT, // height
0, // display offset 0, // display offset
DMG_FIRE, // mass DMG_FIRE, // mass
1, // damage 1, // damage
sfx_None, // activesound sfx_None, // activesound
MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY|MF_FIRE, // flags MF_NOGRAVITY|MF_FIRE|MF_PAIN, // flags
S_NULL // raisestate S_NULL // raisestate
}, },
@ -9638,8 +9648,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // painstate S_NULL, // painstate
0, // painchance 0, // painchance
sfx_None, // painsound sfx_None, // painsound
S_NULL, // meleestate S_LASERFLASH, // meleestate
S_NULL, // missilestate S_LASER2, // missilestate
S_NULL, // deathstate S_NULL, // deathstate
S_NULL, // xdeathstate S_NULL, // xdeathstate
sfx_None, // deathsound sfx_None, // deathsound
@ -9650,7 +9660,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
0, // mass 0, // mass
20, // damage 20, // damage
sfx_None, // activesound sfx_None, // activesound
MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags MF_MISSILE|MF_NOGRAVITY, // flags
S_NULL // raisestate S_NULL // raisestate
}, },

View file

@ -165,6 +165,7 @@ void A_SetTics();
void A_SetRandomTics(); void A_SetRandomTics();
void A_ChangeColorRelative(); void A_ChangeColorRelative();
void A_ChangeColorAbsolute(); void A_ChangeColorAbsolute();
void A_Dye();
void A_MoveRelative(); void A_MoveRelative();
void A_MoveAbsolute(); void A_MoveAbsolute();
void A_Thrust(); void A_Thrust();
@ -283,6 +284,7 @@ void A_RolloutRock();
void A_DragonbomberSpawn(); void A_DragonbomberSpawn();
void A_DragonWing(); void A_DragonWing();
void A_DragonSegment(); void A_DragonSegment();
void A_ChangeHeight();
// ratio of states to sprites to mobj types is roughly 6 : 1 : 1 // ratio of states to sprites to mobj types is roughly 6 : 1 : 1
#define NUMMOBJFREESLOTS 512 #define NUMMOBJFREESLOTS 512
@ -450,6 +452,8 @@ typedef enum sprite
// Projectiles // Projectiles
SPR_MISL, SPR_MISL,
SPR_LASR, // GFZ3 laser
SPR_LASF, // GFZ3 laser flames
SPR_TORP, // Torpedo SPR_TORP, // Torpedo
SPR_ENRG, // Energy ball SPR_ENRG, // Energy ball
SPR_MINE, // Skim mine SPR_MINE, // Skim mine
@ -2219,6 +2223,14 @@ typedef enum state
S_ROCKET, S_ROCKET,
S_LASER, S_LASER,
S_LASER2,
S_LASERFLASH,
S_LASERFLAME1,
S_LASERFLAME2,
S_LASERFLAME3,
S_LASERFLAME4,
S_LASERFLAME5,
S_TORPEDO, S_TORPEDO,

View file

@ -11,17 +11,14 @@
/// \brief basic functions for Lua scripting /// \brief basic functions for Lua scripting
#include "doomdef.h" #include "doomdef.h"
#ifdef HAVE_BLUA
#include "fastcmp.h" #include "fastcmp.h"
#include "p_local.h" #include "p_local.h"
#include "p_setup.h" // So we can have P_SetupLevelSky #include "p_setup.h" // So we can have P_SetupLevelSky
#ifdef ESLOPE #include "p_slopes.h" // P_GetSlopeZAt
#include "p_slopes.h" // P_GetZAt
#endif
#include "z_zone.h" #include "z_zone.h"
#include "r_main.h" #include "r_main.h"
#include "r_draw.h" #include "r_draw.h"
#include "r_things.h" #include "r_things.h" // R_Frame2Char etc
#include "m_random.h" #include "m_random.h"
#include "s_sound.h" #include "s_sound.h"
#include "g_game.h" #include "g_game.h"
@ -224,10 +221,16 @@ static const char *GetUserdataUType(lua_State *L)
// or players[0].powers -> "player_t.powers" // or players[0].powers -> "player_t.powers"
static int lib_userdataType(lua_State *L) static int lib_userdataType(lua_State *L)
{ {
int type;
lua_settop(L, 1); // pop everything except arg 1 (in case somebody decided to add more) lua_settop(L, 1); // pop everything except arg 1 (in case somebody decided to add more)
luaL_checktype(L, 1, LUA_TUSERDATA); type = lua_type(L, 1);
lua_pushstring(L, GetUserdataUType(L)); if (type == LUA_TLIGHTUSERDATA || type == LUA_TUSERDATA)
return 1; {
lua_pushstring(L, GetUserdataUType(L));
return 1;
}
else
return luaL_typerror(L, 1, "userdata");
} }
static int lib_isPlayerAdmin(lua_State *L) static int lib_isPlayerAdmin(lua_State *L)
@ -1080,11 +1083,60 @@ static int lib_pSetObjectMomZ(lua_State *L)
return 0; return 0;
} }
static int lib_pPlayJingle(lua_State *L)
{
player_t *player = NULL;
jingletype_t jingletype = luaL_checkinteger(L, 2);
//NOHUD
//INLEVEL
if (!lua_isnone(L, 1) && lua_isuserdata(L, 1))
{
player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
if (!player)
return LUA_ErrInvalid(L, "player_t");
}
if (jingletype >= NUMJINGLES)
return luaL_error(L, "jingletype %d out of range (0 - %d)", jingletype, NUMJINGLES-1);
P_PlayJingle(player, jingletype);
return 0;
}
static int lib_pPlayJingleMusic(lua_State *L)
{
player_t *player = NULL;
const char *musnamearg = luaL_checkstring(L, 2);
char musname[7], *p = musname;
UINT16 musflags = luaL_optinteger(L, 3, 0);
boolean looping = lua_opttrueboolean(L, 4);
jingletype_t jingletype = luaL_optinteger(L, 5, JT_OTHER);
//NOHUD
//INLEVEL
if (!lua_isnone(L, 1) && lua_isuserdata(L, 1))
{
player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
if (!player)
return LUA_ErrInvalid(L, "player_t");
}
if (jingletype >= NUMJINGLES)
return luaL_error(L, "jingletype %d out of range (0 - %d)", jingletype, NUMJINGLES-1);
musname[6] = '\0';
strncpy(musname, musnamearg, 6);
while (*p) {
*p = tolower(*p);
++p;
}
P_PlayJingleMusic(player, musname, musflags, looping, jingletype);
return 0;
}
static int lib_pRestoreMusic(lua_State *L) static int lib_pRestoreMusic(lua_State *L)
{ {
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
NOHUD //NOHUD
INLEVEL //INLEVEL
if (!player) if (!player)
return LUA_ErrInvalid(L, "player_t"); return LUA_ErrInvalid(L, "player_t");
if (P_IsLocalPlayer(player)) if (P_IsLocalPlayer(player))
@ -1714,11 +1766,15 @@ static int lib_pPlayVictorySound(lua_State *L)
static int lib_pPlayLivesJingle(lua_State *L) static int lib_pPlayLivesJingle(lua_State *L)
{ {
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); player_t *player = NULL;
NOHUD //NOHUD
INLEVEL //INLEVEL
if (!player) if (!lua_isnone(L, 1) && lua_isuserdata(L, 1))
return LUA_ErrInvalid(L, "player_t"); {
player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
if (!player)
return LUA_ErrInvalid(L, "player_t");
}
P_PlayLivesJingle(player); P_PlayLivesJingle(player);
return 0; return 0;
} }
@ -2163,23 +2219,27 @@ static int lib_evStartCrumble(lua_State *L)
return 0; return 0;
} }
#ifdef ESLOPE
// P_SLOPES // P_SLOPES
//////////// ////////////
static int lib_pGetZAt(lua_State *L) static int lib_pGetZAt(lua_State *L)
{ {
pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE));
fixed_t x = luaL_checkfixed(L, 2); fixed_t x = luaL_checkfixed(L, 2);
fixed_t y = luaL_checkfixed(L, 3); fixed_t y = luaL_checkfixed(L, 3);
//HUDSAFE //HUDSAFE
if (!slope) if (lua_isnil(L, 1))
return LUA_ErrInvalid(L, "pslope_t"); {
fixed_t z = luaL_checkfixed(L, 4);
lua_pushfixed(L, P_GetZAt(NULL, x, y, z));
}
else
{
pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE));
lua_pushfixed(L, P_GetSlopeZAt(slope, x, y));
}
lua_pushfixed(L, P_GetZAt(slope, x, y));
return 1; return 1;
} }
#endif
// R_DEFS // R_DEFS
//////////// ////////////
@ -2371,7 +2431,7 @@ static int lib_sStartSound(lua_State *L)
const void *origin = NULL; const void *origin = NULL;
sfxenum_t sound_id = luaL_checkinteger(L, 2); sfxenum_t sound_id = luaL_checkinteger(L, 2);
player_t *player = NULL; player_t *player = NULL;
//NOHUD // kys @whoever did this. //NOHUD
if (sound_id >= NUMSFX) if (sound_id >= NUMSFX)
return luaL_error(L, "sfx %d out of range (0 - %d)", sound_id, NUMSFX-1); return luaL_error(L, "sfx %d out of range (0 - %d)", sound_id, NUMSFX-1);
if (!lua_isnil(L, 1)) if (!lua_isnil(L, 1))
@ -2402,7 +2462,7 @@ static int lib_sStartSoundAtVolume(lua_State *L)
sfxenum_t sound_id = luaL_checkinteger(L, 2); sfxenum_t sound_id = luaL_checkinteger(L, 2);
INT32 volume = (INT32)luaL_checkinteger(L, 3); INT32 volume = (INT32)luaL_checkinteger(L, 3);
player_t *player = NULL; player_t *player = NULL;
NOHUD //NOHUD
if (!lua_isnil(L, 1)) if (!lua_isnil(L, 1))
{ {
@ -2426,13 +2486,27 @@ static int lib_sStartSoundAtVolume(lua_State *L)
static int lib_sStopSound(lua_State *L) static int lib_sStopSound(lua_State *L)
{ {
void *origin = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); void *origin = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
NOHUD //NOHUD
if (!origin) if (!origin)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
S_StopSound(origin); S_StopSound(origin);
return 0; return 0;
} }
static int lib_sStopSoundByID(lua_State *L)
{
void *origin = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
sfxenum_t sound_id = luaL_checkinteger(L, 2);
//NOHUD
if (!origin)
return LUA_ErrInvalid(L, "mobj_t");
if (sound_id >= NUMSFX)
return luaL_error(L, "sfx %d out of range (0 - %d)", sound_id, NUMSFX-1);
S_StopSoundByID(origin, sound_id);
return 0;
}
static int lib_sChangeMusic(lua_State *L) static int lib_sChangeMusic(lua_State *L)
{ {
#ifdef MUSICSLOT_COMPATIBILITY #ifdef MUSICSLOT_COMPATIBILITY
@ -2443,7 +2517,7 @@ static int lib_sChangeMusic(lua_State *L)
boolean looping; boolean looping;
player_t *player = NULL; player_t *player = NULL;
UINT16 music_flags = 0; UINT16 music_flags = 0;
NOHUD //NOHUD
if (lua_isnumber(L, 1)) if (lua_isnumber(L, 1))
{ {
@ -2472,7 +2546,7 @@ static int lib_sChangeMusic(lua_State *L)
boolean looping = (boolean)lua_opttrueboolean(L, 2); boolean looping = (boolean)lua_opttrueboolean(L, 2);
player_t *player = NULL; player_t *player = NULL;
UINT16 music_flags = 0; UINT16 music_flags = 0;
NOHUD //NOHUD
#endif #endif
if (!lua_isnone(L, 3) && lua_isuserdata(L, 3)) if (!lua_isnone(L, 3) && lua_isuserdata(L, 3))
@ -2503,7 +2577,7 @@ static int lib_sSpeedMusic(lua_State *L)
fixed_t fixedspeed = luaL_checkfixed(L, 1); fixed_t fixedspeed = luaL_checkfixed(L, 1);
float speed = FIXED_TO_FLOAT(fixedspeed); float speed = FIXED_TO_FLOAT(fixedspeed);
player_t *player = NULL; player_t *player = NULL;
NOHUD //NOHUD
if (!lua_isnone(L, 2) && lua_isuserdata(L, 2)) if (!lua_isnone(L, 2) && lua_isuserdata(L, 2))
{ {
player = *((player_t **)luaL_checkudata(L, 2, META_PLAYER)); player = *((player_t **)luaL_checkudata(L, 2, META_PLAYER));
@ -2518,7 +2592,7 @@ static int lib_sSpeedMusic(lua_State *L)
static int lib_sStopMusic(lua_State *L) static int lib_sStopMusic(lua_State *L)
{ {
player_t *player = NULL; player_t *player = NULL;
NOHUD //NOHUD
if (!lua_isnone(L, 1) && lua_isuserdata(L, 1)) if (!lua_isnone(L, 1) && lua_isuserdata(L, 1))
{ {
player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
@ -2534,7 +2608,7 @@ static int lib_sSetInternalMusicVolume(lua_State *L)
{ {
UINT32 volume = (UINT32)luaL_checkinteger(L, 1); UINT32 volume = (UINT32)luaL_checkinteger(L, 1);
player_t *player = NULL; player_t *player = NULL;
NOHUD //NOHUD
if (!lua_isnone(L, 2) && lua_isuserdata(L, 2)) if (!lua_isnone(L, 2) && lua_isuserdata(L, 2))
{ {
player = *((player_t **)luaL_checkudata(L, 2, META_PLAYER)); player = *((player_t **)luaL_checkudata(L, 2, META_PLAYER));
@ -2554,7 +2628,7 @@ static int lib_sSetInternalMusicVolume(lua_State *L)
static int lib_sStopFadingMusic(lua_State *L) static int lib_sStopFadingMusic(lua_State *L)
{ {
player_t *player = NULL; player_t *player = NULL;
NOHUD //NOHUD
if (!lua_isnone(L, 1) && lua_isuserdata(L, 1)) if (!lua_isnone(L, 1) && lua_isuserdata(L, 1))
{ {
player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
@ -2577,7 +2651,7 @@ static int lib_sFadeMusic(lua_State *L)
UINT32 ms; UINT32 ms;
INT32 source_volume; INT32 source_volume;
player_t *player = NULL; player_t *player = NULL;
NOHUD //NOHUD
if (!lua_isnone(L, 3) && lua_isuserdata(L, 3)) if (!lua_isnone(L, 3) && lua_isuserdata(L, 3))
{ {
player = *((player_t **)luaL_checkudata(L, 3, META_PLAYER)); player = *((player_t **)luaL_checkudata(L, 3, META_PLAYER));
@ -2605,8 +2679,6 @@ static int lib_sFadeMusic(lua_State *L)
ms = (UINT32)luaL_checkinteger(L, 3); ms = (UINT32)luaL_checkinteger(L, 3);
} }
NOHUD
if (!player || P_IsLocalPlayer(player)) if (!player || P_IsLocalPlayer(player))
lua_pushboolean(L, S_FadeMusicFromVolume(target_volume, source_volume, ms)); lua_pushboolean(L, S_FadeMusicFromVolume(target_volume, source_volume, ms));
else else
@ -2618,7 +2690,7 @@ static int lib_sFadeOutStopMusic(lua_State *L)
{ {
UINT32 ms = (UINT32)luaL_checkinteger(L, 1); UINT32 ms = (UINT32)luaL_checkinteger(L, 1);
player_t *player = NULL; player_t *player = NULL;
NOHUD //NOHUD
if (!lua_isnone(L, 2) && lua_isuserdata(L, 2)) if (!lua_isnone(L, 2) && lua_isuserdata(L, 2))
{ {
player = *((player_t **)luaL_checkudata(L, 2, META_PLAYER)); player = *((player_t **)luaL_checkudata(L, 2, META_PLAYER));
@ -2634,10 +2706,29 @@ static int lib_sFadeOutStopMusic(lua_State *L)
return 1; return 1;
} }
static int lib_sGetMusicLength(lua_State *L)
{
lua_pushinteger(L, S_GetMusicLength());
return 1;
}
static int lib_sGetMusicPosition(lua_State *L)
{
lua_pushinteger(L, S_GetMusicPosition());
return 1;
}
static int lib_sSetMusicPosition(lua_State *L)
{
UINT32 pos = (UINT32)luaL_checkinteger(L, 1);
lua_pushboolean(L, S_SetMusicPosition(pos));
return 1;
}
static int lib_sOriginPlaying(lua_State *L) static int lib_sOriginPlaying(lua_State *L)
{ {
void *origin = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); void *origin = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
NOHUD //NOHUD
INLEVEL INLEVEL
if (!origin) if (!origin)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
@ -2648,7 +2739,7 @@ static int lib_sOriginPlaying(lua_State *L)
static int lib_sIdPlaying(lua_State *L) static int lib_sIdPlaying(lua_State *L)
{ {
sfxenum_t id = luaL_checkinteger(L, 1); sfxenum_t id = luaL_checkinteger(L, 1);
NOHUD //NOHUD
if (id >= NUMSFX) if (id >= NUMSFX)
return luaL_error(L, "sfx %d out of range (0 - %d)", id, NUMSFX-1); return luaL_error(L, "sfx %d out of range (0 - %d)", id, NUMSFX-1);
lua_pushboolean(L, S_IdPlaying(id)); lua_pushboolean(L, S_IdPlaying(id));
@ -2659,7 +2750,7 @@ static int lib_sSoundPlaying(lua_State *L)
{ {
void *origin = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); void *origin = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
sfxenum_t id = luaL_checkinteger(L, 2); sfxenum_t id = luaL_checkinteger(L, 2);
NOHUD //NOHUD
INLEVEL INLEVEL
if (!origin) if (!origin)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
@ -2677,7 +2768,7 @@ static int lib_sStartMusicCaption(lua_State *L)
const char *caption = luaL_checkstring(L, 1); const char *caption = luaL_checkstring(L, 1);
UINT16 lifespan = (UINT16)luaL_checkinteger(L, 2); UINT16 lifespan = (UINT16)luaL_checkinteger(L, 2);
//HUDSAFE //HUDSAFE
INLEVEL //INLEVEL
if (!lua_isnone(L, 3) && lua_isuserdata(L, 3)) if (!lua_isnone(L, 3) && lua_isuserdata(L, 3))
{ {
@ -2836,15 +2927,50 @@ static int lib_gAddGametype(lua_State *L)
return 0; return 0;
} }
static int Lcheckmapnumber (lua_State *L, int idx, const char *fun)
{
if (ISINLEVEL)
return luaL_optinteger(L, idx, gamemap);
else
{
if (lua_isnoneornil(L, idx))
{
return luaL_error(L,
"%s can only be used without a parameter while in a level.",
fun
);
}
else
return luaL_checkinteger(L, idx);
}
}
static int lib_gBuildMapName(lua_State *L) static int lib_gBuildMapName(lua_State *L)
{ {
INT32 map = luaL_optinteger(L, 1, gamemap); INT32 map = Lcheckmapnumber(L, 1, "G_BuildMapName");
//HUDSAFE //HUDSAFE
INLEVEL
lua_pushstring(L, G_BuildMapName(map)); lua_pushstring(L, G_BuildMapName(map));
return 1; return 1;
} }
static int lib_gBuildMapTitle(lua_State *L)
{
INT32 map = Lcheckmapnumber(L, 1, "G_BuildMapTitle");
char *name;
if (map < 1 || map > NUMMAPS)
{
return luaL_error(L,
"map number %d out of range (1 - %d)",
map,
NUMMAPS
);
}
name = G_BuildMapTitle(map);
lua_pushstring(L, name);
Z_Free(name);
return 1;
}
static int lib_gDoReborn(lua_State *L) static int lib_gDoReborn(lua_State *L)
{ {
INT32 playernum = luaL_checkinteger(L, 1); INT32 playernum = luaL_checkinteger(L, 1);
@ -3104,6 +3230,8 @@ static luaL_Reg lib[] = {
{"P_InSpaceSector",lib_pInSpaceSector}, {"P_InSpaceSector",lib_pInSpaceSector},
{"P_InQuicksand",lib_pInQuicksand}, {"P_InQuicksand",lib_pInQuicksand},
{"P_SetObjectMomZ",lib_pSetObjectMomZ}, {"P_SetObjectMomZ",lib_pSetObjectMomZ},
{"P_PlayJingle",lib_pPlayJingle},
{"P_PlayJingleMusic",lib_pPlayJingleMusic},
{"P_RestoreMusic",lib_pRestoreMusic}, {"P_RestoreMusic",lib_pRestoreMusic},
{"P_SpawnShieldOrb",lib_pSpawnShieldOrb}, {"P_SpawnShieldOrb",lib_pSpawnShieldOrb},
{"P_SpawnGhostMobj",lib_pSpawnGhostMobj}, {"P_SpawnGhostMobj",lib_pSpawnGhostMobj},
@ -3186,10 +3314,8 @@ static luaL_Reg lib[] = {
{"EV_CrumbleChain",lib_evCrumbleChain}, {"EV_CrumbleChain",lib_evCrumbleChain},
{"EV_StartCrumble",lib_evStartCrumble}, {"EV_StartCrumble",lib_evStartCrumble},
#ifdef ESLOPE
// p_slopes // p_slopes
{"P_GetZAt",lib_pGetZAt}, {"P_GetZAt",lib_pGetZAt},
#endif
// r_defs // r_defs
{"R_PointToAngle",lib_rPointToAngle}, {"R_PointToAngle",lib_rPointToAngle},
@ -3216,6 +3342,7 @@ static luaL_Reg lib[] = {
{"S_StartSound",lib_sStartSound}, {"S_StartSound",lib_sStartSound},
{"S_StartSoundAtVolume",lib_sStartSoundAtVolume}, {"S_StartSoundAtVolume",lib_sStartSoundAtVolume},
{"S_StopSound",lib_sStopSound}, {"S_StopSound",lib_sStopSound},
{"S_StopSoundByID",lib_sStopSoundByID},
{"S_ChangeMusic",lib_sChangeMusic}, {"S_ChangeMusic",lib_sChangeMusic},
{"S_SpeedMusic",lib_sSpeedMusic}, {"S_SpeedMusic",lib_sSpeedMusic},
{"S_StopMusic",lib_sStopMusic}, {"S_StopMusic",lib_sStopMusic},
@ -3223,6 +3350,9 @@ static luaL_Reg lib[] = {
{"S_StopFadingMusic",lib_sStopFadingMusic}, {"S_StopFadingMusic",lib_sStopFadingMusic},
{"S_FadeMusic",lib_sFadeMusic}, {"S_FadeMusic",lib_sFadeMusic},
{"S_FadeOutStopMusic",lib_sFadeOutStopMusic}, {"S_FadeOutStopMusic",lib_sFadeOutStopMusic},
{"S_GetMusicLength",lib_sGetMusicLength},
{"S_GetMusicPosition",lib_sGetMusicPosition},
{"S_SetMusicPosition",lib_sSetMusicPosition},
{"S_OriginPlaying",lib_sOriginPlaying}, {"S_OriginPlaying",lib_sOriginPlaying},
{"S_IdPlaying",lib_sIdPlaying}, {"S_IdPlaying",lib_sIdPlaying},
{"S_SoundPlaying",lib_sSoundPlaying}, {"S_SoundPlaying",lib_sSoundPlaying},
@ -3231,6 +3361,7 @@ static luaL_Reg lib[] = {
// g_game // g_game
{"G_AddGametype", lib_gAddGametype}, {"G_AddGametype", lib_gAddGametype},
{"G_BuildMapName",lib_gBuildMapName}, {"G_BuildMapName",lib_gBuildMapName},
{"G_BuildMapTitle",lib_gBuildMapTitle},
{"G_DoReborn",lib_gDoReborn}, {"G_DoReborn",lib_gDoReborn},
{"G_SetCustomExitVars",lib_gSetCustomExitVars}, {"G_SetCustomExitVars",lib_gSetCustomExitVars},
{"G_EnoughPlayersFinished",lib_gEnoughPlayersFinished}, {"G_EnoughPlayersFinished",lib_gEnoughPlayersFinished},
@ -3271,5 +3402,3 @@ int LUA_BaseLib(lua_State *L)
luaL_register(L, NULL, lib); luaL_register(L, NULL, lib);
return 0; return 0;
} }
#endif

View file

@ -11,7 +11,6 @@
/// \brief blockmap library for Lua scripting /// \brief blockmap library for Lua scripting
#include "doomdef.h" #include "doomdef.h"
#ifdef HAVE_BLUA
#include "p_local.h" #include "p_local.h"
#include "r_main.h" // validcount #include "r_main.h" // validcount
#include "lua_script.h" #include "lua_script.h"
@ -81,9 +80,7 @@ static UINT8 lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *th
{ {
INT32 offset; INT32 offset;
const INT32 *list; // Big blockmap const INT32 *list; // Big blockmap
#ifdef POLYOBJECTS
polymaplink_t *plink; // haleyjd 02/22/06 polymaplink_t *plink; // haleyjd 02/22/06
#endif
line_t *ld; line_t *ld;
if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight) if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight)
@ -91,7 +88,6 @@ static UINT8 lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *th
offset = y*bmapwidth + x; offset = y*bmapwidth + x;
#ifdef POLYOBJECTS
// haleyjd 02/22/06: consider polyobject lines // haleyjd 02/22/06: consider polyobject lines
plink = polyblocklinks[offset]; plink = polyblocklinks[offset];
@ -134,7 +130,6 @@ static UINT8 lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *th
} }
plink = (polymaplink_t *)(plink->link.next); plink = (polymaplink_t *)(plink->link.next);
} }
#endif
offset = *(blockmap + offset); // offset = blockmap[y*bmapwidth+x]; offset = *(blockmap + offset); // offset = blockmap[y*bmapwidth+x];
@ -264,5 +259,3 @@ int LUA_BlockmapLib(lua_State *L)
lua_register(L, "searchBlockmap", lib_searchBlockmap); lua_register(L, "searchBlockmap", lib_searchBlockmap);
return 0; return 0;
} }
#endif

View file

@ -11,7 +11,6 @@
/// \brief console modifying/etc library for Lua scripting /// \brief console modifying/etc library for Lua scripting
#include "doomdef.h" #include "doomdef.h"
#ifdef HAVE_BLUA
#include "fastcmp.h" #include "fastcmp.h"
#include "p_local.h" #include "p_local.h"
#include "g_game.h" #include "g_game.h"
@ -431,22 +430,8 @@ static int lib_cvRegisterVar(lua_State *L)
static int lib_cvFindVar(lua_State *L) static int lib_cvFindVar(lua_State *L)
{ {
consvar_t *cv; LUA_PushLightUserdata(L, CV_FindVar(luaL_checkstring(L,1)), META_CVAR);
if (( cv = CV_FindVar(luaL_checkstring(L,1)) )) return 1;
{
lua_settop(L,1);/* We only want one argument in the stack. */
lua_pushlightuserdata(L, cv);/* Now the second value on stack. */
luaL_getmetatable(L, META_CVAR);
/*
The metatable is the last value on the stack, so this
applies it to the second value, which is the cvar.
*/
lua_setmetatable(L,2);
lua_pushvalue(L,2);
return 1;
}
else
return 0;
} }
// CONS_Printf for a single player // CONS_Printf for a single player
@ -551,5 +536,3 @@ int LUA_ConsoleLib(lua_State *L)
luaL_register(L, NULL, lib); luaL_register(L, NULL, lib);
return 0; return 0;
} }
#endif

View file

@ -10,8 +10,6 @@
/// \file lua_hook.h /// \file lua_hook.h
/// \brief hooks for Lua scripting /// \brief hooks for Lua scripting
#ifdef HAVE_BLUA
#include "r_defs.h" #include "r_defs.h"
#include "d_player.h" #include "d_player.h"
@ -42,6 +40,7 @@ enum hook {
hook_JumpSpinSpecial, hook_JumpSpinSpecial,
hook_BotTiccmd, hook_BotTiccmd,
hook_BotAI, hook_BotAI,
hook_BotRespawn,
hook_LinedefExecute, hook_LinedefExecute,
hook_PlayerMsg, hook_PlayerMsg,
hook_HurtMsg, hook_HurtMsg,
@ -58,6 +57,7 @@ enum hook {
hook_ViewpointSwitch, hook_ViewpointSwitch,
hook_SeenPlayer, hook_SeenPlayer,
hook_PlayerThink, hook_PlayerThink,
hook_ShouldJingleContinue,
hook_MAX // last hook hook_MAX // last hook
}; };
@ -92,6 +92,7 @@ boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8
#define LUAh_JumpSpinSpecial(player) LUAh_PlayerHook(player, hook_JumpSpinSpecial) // Hook for P_DoJumpStuff (Spin button effect (mid-air)) #define LUAh_JumpSpinSpecial(player) LUAh_PlayerHook(player, hook_JumpSpinSpecial) // Hook for P_DoJumpStuff (Spin button effect (mid-air))
boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd); // Hook for B_BuildTiccmd boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd); // Hook for B_BuildTiccmd
boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd); // Hook for B_BuildTailsTiccmd by skin name boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd); // Hook for B_BuildTailsTiccmd by skin name
boolean LUAh_BotRespawn(mobj_t *sonic, mobj_t *tails); // Hook for B_CheckRespawn
boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector); // Hook for linedef executors boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector); // Hook for linedef executors
boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg); // Hook for chat messages boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg); // Hook for chat messages
boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 damagetype); // Hook for hurt messages boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 damagetype); // Hook for hurt messages
@ -110,5 +111,4 @@ UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean
boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend); // Hook for MT_NAMECHECK boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend); // Hook for MT_NAMECHECK
#endif #endif
#define LUAh_PlayerThink(player) LUAh_PlayerHook(player, hook_PlayerThink) // Hook for P_PlayerThink #define LUAh_PlayerThink(player) LUAh_PlayerHook(player, hook_PlayerThink) // Hook for P_PlayerThink
boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname); // Hook for whether a jingle of the given music should continue playing
#endif

View file

@ -11,11 +11,10 @@
/// \brief hooks for Lua scripting /// \brief hooks for Lua scripting
#include "doomdef.h" #include "doomdef.h"
#ifdef HAVE_BLUA
#include "doomstat.h" #include "doomstat.h"
#include "p_mobj.h" #include "p_mobj.h"
#include "g_game.h" #include "g_game.h"
#include "r_things.h" #include "r_skins.h"
#include "b_bot.h" #include "b_bot.h"
#include "z_zone.h" #include "z_zone.h"
@ -53,6 +52,7 @@ const char *const hookNames[hook_MAX+1] = {
"JumpSpinSpecial", "JumpSpinSpecial",
"BotTiccmd", "BotTiccmd",
"BotAI", "BotAI",
"BotRespawn",
"LinedefExecute", "LinedefExecute",
"PlayerMsg", "PlayerMsg",
"HurtMsg", "HurtMsg",
@ -69,6 +69,7 @@ const char *const hookNames[hook_MAX+1] = {
"ViewpointSwitch", "ViewpointSwitch",
"SeenPlayer", "SeenPlayer",
"PlayerThink", "PlayerThink",
"ShouldJingleContinue",
NULL NULL
}; };
@ -80,8 +81,7 @@ struct hook_s
UINT16 id; UINT16 id;
union { union {
mobjtype_t mt; mobjtype_t mt;
char *skinname; char *str;
char *funcname;
} s; } s;
boolean error; boolean error;
}; };
@ -149,28 +149,17 @@ static int lib_addHook(lua_State *L)
luaL_argcheck(L, hook.s.mt < NUMMOBJTYPES, 2, "invalid mobjtype_t"); luaL_argcheck(L, hook.s.mt < NUMMOBJTYPES, 2, "invalid mobjtype_t");
break; break;
case hook_BotAI: case hook_BotAI:
hook.s.skinname = NULL; case hook_ShouldJingleContinue:
hook.s.str = NULL;
if (lua_isstring(L, 2)) if (lua_isstring(L, 2))
{ // lowercase copy { // lowercase copy
const char *s = lua_tostring(L, 2); hook.s.str = Z_StrDup(lua_tostring(L, 2));
char *p = hook.s.skinname = ZZ_Alloc(strlen(s)+1); strlwr(hook.s.str);
do {
*p = tolower(*s);
++p;
} while(*(++s));
*p = 0;
} }
break; break;
case hook_LinedefExecute: // Linedef executor functions case hook_LinedefExecute: // Linedef executor functions
{ // uppercase copy hook.s.str = Z_StrDup(luaL_checkstring(L, 2));
const char *s = luaL_checkstring(L, 2); strupr(hook.s.str);
char *p = hook.s.funcname = ZZ_Alloc(strlen(s)+1);
do {
*p = toupper(*s);
++p;
} while(*(++s));
*p = 0;
}
break; break;
default: default:
break; break;
@ -1073,7 +1062,7 @@ boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd)
for (hookp = roothook; hookp; hookp = hookp->next) for (hookp = roothook; hookp; hookp = hookp->next)
{ {
if (hookp->type != hook_BotAI if (hookp->type != hook_BotAI
|| (hookp->s.skinname && strcmp(hookp->s.skinname, ((skin_t*)tails->skin)->name))) || (hookp->s.str && strcmp(hookp->s.str, ((skin_t*)tails->skin)->name)))
continue; continue;
if (lua_gettop(gL) == 0) if (lua_gettop(gL) == 0)
@ -1123,6 +1112,51 @@ boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd)
return hooked; return hooked;
} }
// Hook for B_CheckRespawn
boolean LUAh_BotRespawn(mobj_t *sonic, mobj_t *tails)
{
hook_p hookp;
UINT8 shouldRespawn = 0; // 0 = default, 1 = force yes, 2 = force no.
if (!gL || !(hooksAvailable[hook_BotRespawn/8] & (1<<(hook_BotRespawn%8))))
return false;
lua_settop(gL, 0);
for (hookp = roothook; hookp; hookp = hookp->next)
{
if (hookp->type != hook_BotRespawn)
continue;
if (lua_gettop(gL) == 0)
{
LUA_PushUserdata(gL, sonic, META_MOBJ);
LUA_PushUserdata(gL, tails, META_MOBJ);
}
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
lua_gettable(gL, LUA_REGISTRYINDEX);
lua_pushvalue(gL, -3);
lua_pushvalue(gL, -3);
if (lua_pcall(gL, 2, 1, 0)) {
if (!hookp->error || cv_debug & DBG_LUA)
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
lua_pop(gL, 1);
hookp->error = true;
continue;
}
if (!lua_isnil(gL, -1))
{
if (lua_toboolean(gL, -1))
shouldRespawn = 1; // Force yes
else
shouldRespawn = 2; // Force no
}
lua_pop(gL, 1);
}
lua_settop(gL, 0);
return shouldRespawn;
}
// Hook for linedef executors // Hook for linedef executors
boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector) boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector)
{ {
@ -1135,7 +1169,7 @@ boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector)
for (hookp = linedefexecutorhooks; hookp; hookp = hookp->next) for (hookp = linedefexecutorhooks; hookp; hookp = hookp->next)
{ {
if (strcmp(hookp->s.funcname, line->text)) if (strcmp(hookp->s.str, line->text))
continue; continue;
if (lua_gettop(gL) == 0) if (lua_gettop(gL) == 0)
@ -1660,4 +1694,45 @@ boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend)
} }
#endif // SEENAMES #endif // SEENAMES
#endif boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname)
{
hook_p hookp;
boolean keepplaying = false;
if (!gL || !(hooksAvailable[hook_ShouldJingleContinue/8] & (1<<(hook_ShouldJingleContinue%8))))
return true;
lua_settop(gL, 0);
hud_running = true; // local hook
for (hookp = roothook; hookp; hookp = hookp->next)
{
if (hookp->type != hook_ShouldJingleContinue
|| (hookp->s.str && strcmp(hookp->s.str, musname)))
continue;
if (lua_gettop(gL) == 0)
{
LUA_PushUserdata(gL, player, META_PLAYER);
lua_pushstring(gL, musname);
}
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
lua_gettable(gL, LUA_REGISTRYINDEX);
lua_pushvalue(gL, -3);
lua_pushvalue(gL, -3);
if (lua_pcall(gL, 2, 1, 0)) {
if (!hookp->error || cv_debug & DBG_LUA)
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
lua_pop(gL, 1);
hookp->error = true;
continue;
}
if (!lua_isnil(gL, -1) && lua_toboolean(gL, -1))
keepplaying = true; // Keep playing this boolean
lua_pop(gL, 1);
}
lua_settop(gL, 0);
hud_running = false;
return keepplaying;
}

View file

@ -11,7 +11,6 @@
/// \brief custom HUD rendering library for Lua scripting /// \brief custom HUD rendering library for Lua scripting
#include "doomdef.h" #include "doomdef.h"
#ifdef HAVE_BLUA
#include "fastcmp.h" #include "fastcmp.h"
#include "r_defs.h" #include "r_defs.h"
#include "r_local.h" #include "r_local.h"
@ -413,9 +412,9 @@ static int libd_cachePatch(lua_State *L)
HUDONLY HUDONLY
luapat = patchinfohead; luapat = patchinfohead;
lumpnum = W_CheckNumForName(luaL_checkstring(L, 1)); lumpnum = W_CheckNumForLongName(luaL_checkstring(L, 1));
if (lumpnum == LUMPERROR) if (lumpnum == LUMPERROR)
lumpnum = W_GetNumForName("MISSING"); lumpnum = W_GetNumForLongName("MISSING");
for (i = 0; i < numluapatches; i++) for (i = 0; i < numluapatches; i++)
{ {
@ -455,7 +454,7 @@ static int libd_cachePatch(lua_State *L)
numluapatches++; numluapatches++;
#else #else
HUDONLY HUDONLY
LUA_PushUserdata(L, W_CachePatchName(luaL_checkstring(L, 1), PU_PATCH), META_PATCH); LUA_PushUserdata(L, W_CachePatchLongName(luaL_checkstring(L, 1), PU_PATCH), META_PATCH);
#endif #endif
return 1; return 1;
} }
@ -1466,5 +1465,3 @@ void LUAh_IntermissionHUD(void)
lua_pop(gL, -1); lua_pop(gL, -1);
hud_running = false; hud_running = false;
} }
#endif

View file

@ -11,7 +11,6 @@
/// \brief infotable editing library for Lua scripting /// \brief infotable editing library for Lua scripting
#include "doomdef.h" #include "doomdef.h"
#ifdef HAVE_BLUA
#include "fastcmp.h" #include "fastcmp.h"
#include "info.h" #include "info.h"
#include "dehacked.h" #include "dehacked.h"
@ -392,10 +391,7 @@ static int lib_setSpriteInfo(lua_State *L)
lua_Integer i = 0; lua_Integer i = 0;
const char *str = NULL; const char *str = NULL;
if (lua_isnumber(L, 2)) if (lua_isnumber(L, 2))
{
i = lua_tointeger(L, 2); i = lua_tointeger(L, 2);
i++; // shift index in case of missing rotsprite support
}
else else
str = luaL_checkstring(L, 2); str = luaL_checkstring(L, 2);
@ -1896,7 +1892,6 @@ int LUA_InfoLib(lua_State *L)
lua_pushcfunction(L, lib_spriteinfolen); lua_pushcfunction(L, lib_spriteinfolen);
lua_setfield(L, -2, "__len"); lua_setfield(L, -2, "__len");
lua_setmetatable(L, -2); lua_setmetatable(L, -2);
lua_pushvalue(L, -1);
lua_setglobal(L, "spriteinfo"); lua_setglobal(L, "spriteinfo");
luaL_newmetatable(L, META_LUABANKS); luaL_newmetatable(L, META_LUABANKS);
@ -1912,5 +1907,3 @@ int LUA_InfoLib(lua_State *L)
return 0; return 0;
} }
#endif

View file

@ -10,8 +10,6 @@
/// \file lua_libs.h /// \file lua_libs.h
/// \brief libraries for Lua scripting /// \brief libraries for Lua scripting
#ifdef HAVE_BLUA
extern lua_State *gL; extern lua_State *gL;
#define LREG_VALID "VALID_USERDATA" #define LREG_VALID "VALID_USERDATA"
@ -47,11 +45,9 @@ extern lua_State *gL;
#define META_SEG "SEG_T*" #define META_SEG "SEG_T*"
#define META_NODE "NODE_T*" #define META_NODE "NODE_T*"
#endif #endif
#ifdef ESLOPE
#define META_SLOPE "PSLOPE_T*" #define META_SLOPE "PSLOPE_T*"
#define META_VECTOR2 "VECTOR2_T" #define META_VECTOR2 "VECTOR2_T"
#define META_VECTOR3 "VECTOR3_T" #define META_VECTOR3 "VECTOR3_T"
#endif
#define META_MAPHEADER "MAPHEADER_T*" #define META_MAPHEADER "MAPHEADER_T*"
#define META_CVAR "CONSVAR_T*" #define META_CVAR "CONSVAR_T*"
@ -90,5 +86,3 @@ int LUA_ThinkerLib(lua_State *L);
int LUA_MapLib(lua_State *L); int LUA_MapLib(lua_State *L);
int LUA_BlockmapLib(lua_State *L); int LUA_BlockmapLib(lua_State *L);
int LUA_HudLib(lua_State *L); int LUA_HudLib(lua_State *L);
#endif

View file

@ -11,14 +11,11 @@
/// \brief game map library for Lua scripting /// \brief game map library for Lua scripting
#include "doomdef.h" #include "doomdef.h"
#ifdef HAVE_BLUA
#include "r_state.h" #include "r_state.h"
#include "p_local.h" #include "p_local.h"
#include "p_setup.h" #include "p_setup.h"
#include "z_zone.h" #include "z_zone.h"
#ifdef ESLOPE
#include "p_slopes.h" #include "p_slopes.h"
#endif
#include "r_main.h" #include "r_main.h"
#include "lua_script.h" #include "lua_script.h"
@ -42,13 +39,9 @@ enum sector_e {
sector_heightsec, sector_heightsec,
sector_camsec, sector_camsec,
sector_lines, sector_lines,
#ifdef ESLOPE
sector_ffloors, sector_ffloors,
sector_fslope, sector_fslope,
sector_cslope sector_cslope
#else
sector_ffloors
#endif
}; };
static const char *const sector_opt[] = { static const char *const sector_opt[] = {
@ -65,10 +58,8 @@ static const char *const sector_opt[] = {
"camsec", "camsec",
"lines", "lines",
"ffloors", "ffloors",
#ifdef ESLOPE
"f_slope", "f_slope",
"c_slope", "c_slope",
#endif
NULL}; NULL};
enum subsector_e { enum subsector_e {
@ -181,10 +172,8 @@ enum ffloor_e {
ffloor_toplightlevel, ffloor_toplightlevel,
ffloor_bottomheight, ffloor_bottomheight,
ffloor_bottompic, ffloor_bottompic,
#ifdef ESLOPE
ffloor_tslope, ffloor_tslope,
ffloor_bslope, ffloor_bslope,
#endif
ffloor_sector, ffloor_sector,
ffloor_flags, ffloor_flags,
ffloor_master, ffloor_master,
@ -201,10 +190,8 @@ static const char *const ffloor_opt[] = {
"toplightlevel", "toplightlevel",
"bottomheight", "bottomheight",
"bottompic", "bottompic",
#ifdef ESLOPE
"t_slope", "t_slope",
"b_slope", "b_slope",
#endif
"sector", // secnum pushed as control sector userdata "sector", // secnum pushed as control sector userdata
"flags", "flags",
"master", // control linedef "master", // control linedef
@ -290,7 +277,6 @@ static const char *const bbox_opt[] = {
"right", "right",
NULL}; NULL};
#ifdef ESLOPE
enum slope_e { enum slope_e {
slope_valid = 0, slope_valid = 0,
slope_o, slope_o,
@ -325,7 +311,6 @@ static const char *const vector_opt[] = {
"y", "y",
"z", "z",
NULL}; NULL};
#endif
static const char *const array_opt[] ={"iterate",NULL}; static const char *const array_opt[] ={"iterate",NULL};
static const char *const valid_opt[] ={"valid",NULL}; static const char *const valid_opt[] ={"valid",NULL};
@ -571,14 +556,12 @@ static int sector_get(lua_State *L)
LUA_PushUserdata(L, sector->ffloors, META_FFLOOR); LUA_PushUserdata(L, sector->ffloors, META_FFLOOR);
lua_pushcclosure(L, sector_iterate, 2); // push lib_iterateFFloors and sector->ffloors as upvalues for the function lua_pushcclosure(L, sector_iterate, 2); // push lib_iterateFFloors and sector->ffloors as upvalues for the function
return 1; return 1;
#ifdef ESLOPE
case sector_fslope: // f_slope case sector_fslope: // f_slope
LUA_PushUserdata(L, sector->f_slope, META_SLOPE); LUA_PushUserdata(L, sector->f_slope, META_SLOPE);
return 1; return 1;
case sector_cslope: // c_slope case sector_cslope: // c_slope
LUA_PushUserdata(L, sector->c_slope, META_SLOPE); LUA_PushUserdata(L, sector->c_slope, META_SLOPE);
return 1; return 1;
#endif
} }
return 0; return 0;
} }
@ -602,10 +585,8 @@ static int sector_set(lua_State *L)
case sector_camsec: // camsec case sector_camsec: // camsec
case sector_lines: // lines case sector_lines: // lines
case sector_ffloors: // ffloors case sector_ffloors: // ffloors
#ifdef ESLOPE
case sector_fslope: // f_slope case sector_fslope: // f_slope
case sector_cslope: // c_slope case sector_cslope: // c_slope
#endif
default: default:
return luaL_error(L, "sector_t field " LUA_QS " cannot be set.", sector_opt[field]); return luaL_error(L, "sector_t field " LUA_QS " cannot be set.", sector_opt[field]);
case sector_floorheight: { // floorheight case sector_floorheight: { // floorheight
@ -1693,14 +1674,12 @@ static int ffloor_get(lua_State *L)
lua_pushlstring(L, levelflat->name, i); lua_pushlstring(L, levelflat->name, i);
return 1; return 1;
} }
#ifdef ESLOPE
case ffloor_tslope: case ffloor_tslope:
LUA_PushUserdata(L, *ffloor->t_slope, META_SLOPE); LUA_PushUserdata(L, *ffloor->t_slope, META_SLOPE);
return 1; return 1;
case ffloor_bslope: case ffloor_bslope:
LUA_PushUserdata(L, *ffloor->b_slope, META_SLOPE); LUA_PushUserdata(L, *ffloor->b_slope, META_SLOPE);
return 1; return 1;
#endif
case ffloor_sector: case ffloor_sector:
LUA_PushUserdata(L, &sectors[ffloor->secnum], META_SECTOR); LUA_PushUserdata(L, &sectors[ffloor->secnum], META_SECTOR);
return 1; return 1;
@ -1740,10 +1719,8 @@ static int ffloor_set(lua_State *L)
switch(field) switch(field)
{ {
case ffloor_valid: // valid case ffloor_valid: // valid
#ifdef ESLOPE
case ffloor_tslope: // t_slope case ffloor_tslope: // t_slope
case ffloor_bslope: // b_slope case ffloor_bslope: // b_slope
#endif
case ffloor_sector: // sector case ffloor_sector: // sector
case ffloor_master: // master case ffloor_master: // master
case ffloor_target: // target case ffloor_target: // target
@ -1804,7 +1781,6 @@ static int ffloor_set(lua_State *L)
return 0; return 0;
} }
#ifdef ESLOPE
////////////// //////////////
// pslope_t // // pslope_t //
////////////// //////////////
@ -1977,7 +1953,6 @@ static int vector3_get(lua_State *L)
return 0; return 0;
} }
#endif
///////////////////// /////////////////////
// mapheaderinfo[] // // mapheaderinfo[] //
@ -2107,6 +2082,12 @@ static int mapheaderinfo_get(lua_State *L)
lua_pushinteger(L, header->menuflags); lua_pushinteger(L, header->menuflags);
else if (fastcmp(field,"startrings")) else if (fastcmp(field,"startrings"))
lua_pushinteger(L, header->startrings); lua_pushinteger(L, header->startrings);
else if (fastcmp(field, "sstimer"))
lua_pushinteger(L, header->sstimer);
else if (fastcmp(field, "ssspheres"))
lua_pushinteger(L, header->ssspheres);
else if (fastcmp(field, "gravity"))
lua_pushfixed(L, header->gravity);
// TODO add support for reading numGradedMares and grades // TODO add support for reading numGradedMares and grades
else { else {
// Read custom vars now // Read custom vars now
@ -2226,7 +2207,6 @@ int LUA_MapLib(lua_State *L)
lua_setfield(L, -2, "__index"); lua_setfield(L, -2, "__index");
lua_pop(L, 1); lua_pop(L, 1);
#ifdef ESLOPE
luaL_newmetatable(L, META_SLOPE); luaL_newmetatable(L, META_SLOPE);
lua_pushcfunction(L, slope_get); lua_pushcfunction(L, slope_get);
lua_setfield(L, -2, "__index"); lua_setfield(L, -2, "__index");
@ -2244,7 +2224,6 @@ int LUA_MapLib(lua_State *L)
lua_pushcfunction(L, vector3_get); lua_pushcfunction(L, vector3_get);
lua_setfield(L, -2, "__index"); lua_setfield(L, -2, "__index");
lua_pop(L, 1); lua_pop(L, 1);
#endif
luaL_newmetatable(L, META_MAPHEADER); luaL_newmetatable(L, META_MAPHEADER);
lua_pushcfunction(L, mapheaderinfo_get); lua_pushcfunction(L, mapheaderinfo_get);
@ -2337,5 +2316,3 @@ int LUA_MapLib(lua_State *L)
lua_setglobal(L, "mapheaderinfo"); lua_setglobal(L, "mapheaderinfo");
return 0; return 0;
} }
#endif

View file

@ -11,7 +11,6 @@
/// \brief basic math library for Lua scripting /// \brief basic math library for Lua scripting
#include "doomdef.h" #include "doomdef.h"
#ifdef HAVE_BLUA
//#include "fastcmp.h" //#include "fastcmp.h"
#include "tables.h" #include "tables.h"
#include "p_local.h" #include "p_local.h"
@ -216,5 +215,3 @@ int LUA_MathLib(lua_State *L)
luaL_register(L, NULL, lib); luaL_register(L, NULL, lib);
return 0; return 0;
} }
#endif

View file

@ -11,9 +11,8 @@
/// \brief mobj/thing library for Lua scripting /// \brief mobj/thing library for Lua scripting
#include "doomdef.h" #include "doomdef.h"
#ifdef HAVE_BLUA
#include "fastcmp.h" #include "fastcmp.h"
#include "r_things.h" #include "r_skins.h"
#include "p_local.h" #include "p_local.h"
#include "g_game.h" #include "g_game.h"
#include "p_setup.h" #include "p_setup.h"
@ -85,9 +84,7 @@ enum mobj_e {
mobj_extravalue2, mobj_extravalue2,
mobj_cusval, mobj_cusval,
mobj_cvmem, mobj_cvmem,
#ifdef ESLOPE
mobj_standingslope, mobj_standingslope,
#endif
mobj_colorized, mobj_colorized,
mobj_shadowscale mobj_shadowscale
}; };
@ -153,9 +150,7 @@ static const char *const mobj_opt[] = {
"extravalue2", "extravalue2",
"cusval", "cusval",
"cvmem", "cvmem",
#ifdef ESLOPE
"standingslope", "standingslope",
#endif
"colorized", "colorized",
"shadowscale", "shadowscale",
NULL}; NULL};
@ -384,11 +379,9 @@ static int mobj_get(lua_State *L)
case mobj_cvmem: case mobj_cvmem:
lua_pushinteger(L, mo->cvmem); lua_pushinteger(L, mo->cvmem);
break; break;
#ifdef ESLOPE
case mobj_standingslope: case mobj_standingslope:
LUA_PushUserdata(L, mo->standingslope, META_SLOPE); LUA_PushUserdata(L, mo->standingslope, META_SLOPE);
break; break;
#endif
case mobj_colorized: case mobj_colorized:
lua_pushboolean(L, mo->colorized); lua_pushboolean(L, mo->colorized);
break; break;
@ -717,10 +710,8 @@ static int mobj_set(lua_State *L)
case mobj_cvmem: case mobj_cvmem:
mo->cvmem = luaL_checkinteger(L, 3); mo->cvmem = luaL_checkinteger(L, 3);
break; break;
#ifdef ESLOPE
case mobj_standingslope: case mobj_standingslope:
return NOSET; return NOSET;
#endif
case mobj_colorized: case mobj_colorized:
mo->colorized = luaL_checkboolean(L, 3); mo->colorized = luaL_checkboolean(L, 3);
break; break;
@ -915,5 +906,3 @@ int LUA_MobjLib(lua_State *L)
lua_setglobal(L, "mapthings"); lua_setglobal(L, "mapthings");
return 0; return 0;
} }
#endif

View file

@ -11,7 +11,6 @@
/// \brief player object library for Lua scripting /// \brief player object library for Lua scripting
#include "doomdef.h" #include "doomdef.h"
#ifdef HAVE_BLUA
#include "fastcmp.h" #include "fastcmp.h"
#include "p_mobj.h" #include "p_mobj.h"
#include "d_player.h" #include "d_player.h"
@ -878,5 +877,3 @@ int LUA_PlayerLib(lua_State *L)
lua_setglobal(L, "players"); lua_setglobal(L, "players");
return 0; return 0;
} }
#endif

View file

@ -11,7 +11,6 @@
/// \brief Lua scripting basics /// \brief Lua scripting basics
#include "doomdef.h" #include "doomdef.h"
#ifdef HAVE_BLUA
#include "fastcmp.h" #include "fastcmp.h"
#include "dehacked.h" #include "dehacked.h"
#include "z_zone.h" #include "z_zone.h"
@ -24,9 +23,7 @@
#include "byteptr.h" #include "byteptr.h"
#include "p_saveg.h" #include "p_saveg.h"
#include "p_local.h" #include "p_local.h"
#ifdef ESLOPE
#include "p_slopes.h" // for P_SlopeById #include "p_slopes.h" // for P_SlopeById
#endif
#ifdef LUA_ALLOW_BYTECODE #ifdef LUA_ALLOW_BYTECODE
#include "d_netfil.h" // for LUA_DumpFile #include "d_netfil.h" // for LUA_DumpFile
#endif #endif
@ -444,9 +441,9 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump)
else // If it's not a .lua file, copy the lump name in too. else // If it's not a .lua file, copy the lump name in too.
{ {
lumpinfo_t *lump_p = &wadfiles[wad]->lumpinfo[lump]; lumpinfo_t *lump_p = &wadfiles[wad]->lumpinfo[lump];
len += 1 + strlen(lump_p->name2); // length of file name, '|', and lump name len += 1 + strlen(lump_p->fullname); // length of file name, '|', and lump name
name = malloc(len+1); name = malloc(len+1);
sprintf(name, "%s|%s", wadfiles[wad]->filename, lump_p->name2); sprintf(name, "%s|%s", wadfiles[wad]->filename, lump_p->fullname);
name[len] = '\0'; name[len] = '\0';
} }
@ -571,6 +568,27 @@ fixed_t LUA_EvalMath(const char *word)
return res; return res;
} }
/*
LUA_PushUserdata but no userdata is created.
You can't invalidate it therefore.
*/
void LUA_PushLightUserdata (lua_State *L, void *data, const char *meta)
{
if (data)
{
lua_pushlightuserdata(L, data);
luaL_getmetatable(L, meta);
/*
The metatable is the last value on the stack, so this
applies it to the second value, which is the userdata.
*/
lua_setmetatable(L, -2);
}
else
lua_pushnil(L);
}
// Takes a pointer, any pointer, and a metatable name // Takes a pointer, any pointer, and a metatable name
// Creates a userdata for that pointer with the given metatable // Creates a userdata for that pointer with the given metatable
// Pushes it to the stack and stores it in the registry. // Pushes it to the stack and stores it in the registry.
@ -712,9 +730,13 @@ void LUA_InvalidatePlayer(player_t *player)
enum enum
{ {
ARCH_NULL=0, ARCH_NULL=0,
ARCH_BOOLEAN, ARCH_TRUE,
ARCH_SIGNED, ARCH_FALSE,
ARCH_STRING, ARCH_INT8,
ARCH_INT16,
ARCH_INT32,
ARCH_SMALLSTRING,
ARCH_LARGESTRING,
ARCH_TABLE, ARCH_TABLE,
ARCH_MOBJINFO, ARCH_MOBJINFO,
@ -732,9 +754,7 @@ enum
ARCH_NODE, ARCH_NODE,
#endif #endif
ARCH_FFLOOR, ARCH_FFLOOR,
#ifdef ESLOPE
ARCH_SLOPE, ARCH_SLOPE,
#endif
ARCH_MAPHEADER, ARCH_MAPHEADER,
ARCH_SKINCOLOR, ARCH_SKINCOLOR,
@ -760,9 +780,7 @@ static const struct {
{META_NODE, ARCH_NODE}, {META_NODE, ARCH_NODE},
#endif #endif
{META_FFLOOR, ARCH_FFLOOR}, {META_FFLOOR, ARCH_FFLOOR},
#ifdef ESLOPE
{META_SLOPE, ARCH_SLOPE}, {META_SLOPE, ARCH_SLOPE},
#endif
{META_MAPHEADER, ARCH_MAPHEADER}, {META_MAPHEADER, ARCH_MAPHEADER},
{META_SKINCOLOR, ARCH_SKINCOLOR}, {META_SKINCOLOR, ARCH_SKINCOLOR},
{NULL, ARCH_NULL} {NULL, ARCH_NULL}
@ -805,22 +823,33 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
WRITEUINT8(save_p, ARCH_NULL); WRITEUINT8(save_p, ARCH_NULL);
return 2; return 2;
case LUA_TBOOLEAN: case LUA_TBOOLEAN:
WRITEUINT8(save_p, ARCH_BOOLEAN); WRITEUINT8(save_p, lua_toboolean(gL, myindex) ? ARCH_TRUE : ARCH_FALSE);
WRITEUINT8(save_p, lua_toboolean(gL, myindex));
break; break;
case LUA_TNUMBER: case LUA_TNUMBER:
{ {
lua_Integer number = lua_tointeger(gL, myindex); lua_Integer number = lua_tointeger(gL, myindex);
WRITEUINT8(save_p, ARCH_SIGNED); if (number >= INT8_MIN && number <= INT8_MAX)
WRITEFIXED(save_p, number); {
WRITEUINT8(save_p, ARCH_INT8);
WRITESINT8(save_p, number);
}
else if (number >= INT16_MIN && number <= INT16_MAX)
{
WRITEUINT8(save_p, ARCH_INT16);
WRITEINT16(save_p, number);
}
else
{
WRITEUINT8(save_p, ARCH_INT32);
WRITEFIXED(save_p, number);
}
break; break;
} }
case LUA_TSTRING: case LUA_TSTRING:
{ {
UINT16 len = (UINT16)lua_objlen(gL, myindex); // get length of string, including embedded zeros UINT32 len = (UINT32)lua_objlen(gL, myindex); // get length of string, including embedded zeros
const char *s = lua_tostring(gL, myindex); const char *s = lua_tostring(gL, myindex);
UINT16 i = 0; UINT32 i = 0;
WRITEUINT8(save_p, ARCH_STRING);
// if you're wondering why we're writing a string to save_p this way, // if you're wondering why we're writing a string to save_p this way,
// it turns out that Lua can have embedded zeros ('\0') in the strings, // it turns out that Lua can have embedded zeros ('\0') in the strings,
// so we can't use WRITESTRING as that cuts off when it finds a '\0'. // so we can't use WRITESTRING as that cuts off when it finds a '\0'.
@ -828,7 +857,16 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
// fixing the awful crashes previously encountered for reading strings longer than 1024 // fixing the awful crashes previously encountered for reading strings longer than 1024
// (yes I know that's kind of a stupid thing to care about, but it'd be evil to trim or ignore them?) // (yes I know that's kind of a stupid thing to care about, but it'd be evil to trim or ignore them?)
// -- Monster Iestyn 05/08/18 // -- Monster Iestyn 05/08/18
WRITEUINT16(save_p, len); // save size of string if (len < 255)
{
WRITEUINT8(save_p, ARCH_SMALLSTRING);
WRITEUINT8(save_p, len); // save size of string
}
else
{
WRITEUINT8(save_p, ARCH_LARGESTRING);
WRITEUINT32(save_p, len); // save size of string
}
while (i < len) while (i < len)
WRITECHAR(save_p, s[i++]); // write chars individually, including the embedded zeros WRITECHAR(save_p, s[i++]); // write chars individually, including the embedded zeros
break; break;
@ -998,16 +1036,8 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
if (!rover) if (!rover)
WRITEUINT8(save_p, ARCH_NULL); WRITEUINT8(save_p, ARCH_NULL);
else { else {
ffloor_t *r2; UINT16 i = P_GetFFloorID(rover);
UINT16 i = 0; if (i == UINT16_MAX) // invalid ID
// search for id
for (r2 = rover->target->ffloors; r2; r2 = r2->next)
{
if (r2 == rover)
break;
i++;
}
if (!r2)
WRITEUINT8(save_p, ARCH_NULL); WRITEUINT8(save_p, ARCH_NULL);
else else
{ {
@ -1018,7 +1048,6 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
} }
break; break;
} }
#ifdef ESLOPE
case ARCH_SLOPE: case ARCH_SLOPE:
{ {
pslope_t *slope = *((pslope_t **)lua_touserdata(gL, myindex)); pslope_t *slope = *((pslope_t **)lua_touserdata(gL, myindex));
@ -1030,7 +1059,6 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
} }
break; break;
} }
#endif
case ARCH_MAPHEADER: case ARCH_MAPHEADER:
{ {
mapheader_t *header = *((mapheader_t **)lua_touserdata(gL, myindex)); mapheader_t *header = *((mapheader_t **)lua_touserdata(gL, myindex));
@ -1176,21 +1204,36 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
case ARCH_NULL: case ARCH_NULL:
lua_pushnil(gL); lua_pushnil(gL);
break; break;
case ARCH_BOOLEAN: case ARCH_TRUE:
lua_pushboolean(gL, READUINT8(save_p)); lua_pushboolean(gL, true);
break; break;
case ARCH_SIGNED: case ARCH_FALSE:
lua_pushboolean(gL, false);
break;
case ARCH_INT8:
lua_pushinteger(gL, READSINT8(save_p));
break;
case ARCH_INT16:
lua_pushinteger(gL, READINT16(save_p));
break;
case ARCH_INT32:
lua_pushinteger(gL, READFIXED(save_p)); lua_pushinteger(gL, READFIXED(save_p));
break; break;
case ARCH_STRING: case ARCH_SMALLSTRING:
case ARCH_LARGESTRING:
{ {
UINT16 len = READUINT16(save_p); // length of string, including embedded zeros UINT32 len;
char *value; char *value;
UINT16 i = 0; UINT32 i = 0;
// See my comments in the ArchiveValue function; // See my comments in the ArchiveValue function;
// it's much the same for reading strings as writing them! // it's much the same for reading strings as writing them!
// (i.e. we can't use READSTRING either) // (i.e. we can't use READSTRING either)
// -- Monster Iestyn 05/08/18 // -- Monster Iestyn 05/08/18
if (type == ARCH_SMALLSTRING)
len = READUINT8(save_p); // length of string, including embedded zeros
else
len = READUINT32(save_p); // length of string, including embedded zeros
value = malloc(len); // make temp buffer of size len value = malloc(len); // make temp buffer of size len
// now read the actual string // now read the actual string
while (i < len) while (i < len)
@ -1260,11 +1303,9 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
LUA_PushUserdata(gL, rover, META_FFLOOR); LUA_PushUserdata(gL, rover, META_FFLOOR);
break; break;
} }
#ifdef ESLOPE
case ARCH_SLOPE: case ARCH_SLOPE:
LUA_PushUserdata(gL, P_SlopeById(READUINT16(save_p)), META_SLOPE); LUA_PushUserdata(gL, P_SlopeById(READUINT16(save_p)), META_SLOPE);
break; break;
#endif
case ARCH_MAPHEADER: case ARCH_MAPHEADER:
LUA_PushUserdata(gL, mapheaderinfo[READUINT16(save_p)], META_MAPHEADER); LUA_PushUserdata(gL, mapheaderinfo[READUINT16(save_p)], META_MAPHEADER);
break; break;
@ -1436,5 +1477,3 @@ int Lua_optoption(lua_State *L, int narg,
return i; return i;
return -1; return -1;
} }
#endif // HAVE_BLUA

View file

@ -10,8 +10,6 @@
/// \file lua_script.h /// \file lua_script.h
/// \brief Lua scripting basics /// \brief Lua scripting basics
#ifdef HAVE_BLUA
#include "m_fixed.h" #include "m_fixed.h"
#include "doomtype.h" #include "doomtype.h"
#include "d_player.h" #include "d_player.h"
@ -46,6 +44,7 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump);
void LUA_DumpFile(const char *filename); void LUA_DumpFile(const char *filename);
#endif #endif
fixed_t LUA_EvalMath(const char *word); fixed_t LUA_EvalMath(const char *word);
void LUA_PushLightUserdata(lua_State *L, void *data, const char *meta);
void LUA_PushUserdata(lua_State *L, void *data, const char *meta); void LUA_PushUserdata(lua_State *L, void *data, const char *meta);
void LUA_InvalidateUserdata(void *data); void LUA_InvalidateUserdata(void *data);
void LUA_InvalidateLevel(void); void LUA_InvalidateLevel(void);
@ -100,7 +99,8 @@ void COM_Lua_f(void);
// uncomment if you want seg_t/node_t in Lua // uncomment if you want seg_t/node_t in Lua
// #define HAVE_LUA_SEGS // #define HAVE_LUA_SEGS
#define INLEVEL if (gamestate != GS_LEVEL && !titlemapinaction)\ #define ISINLEVEL \
return luaL_error(L, "This can only be used in a level!"); (gamestate == GS_LEVEL || titlemapinaction)
#endif #define INLEVEL if (! ISINLEVEL)\
return luaL_error(L, "This can only be used in a level!");

View file

@ -11,9 +11,8 @@
/// \brief player skin structure library for Lua scripting /// \brief player skin structure library for Lua scripting
#include "doomdef.h" #include "doomdef.h"
#ifdef HAVE_BLUA
#include "fastcmp.h" #include "fastcmp.h"
#include "r_things.h" #include "r_skins.h"
#include "sounds.h" #include "sounds.h"
#include "lua_script.h" #include "lua_script.h"
@ -358,5 +357,3 @@ int LUA_SkinLib(lua_State *L)
return 0; return 0;
} }
#endif

View file

@ -11,7 +11,6 @@
/// \brief thinker library for Lua scripting /// \brief thinker library for Lua scripting
#include "doomdef.h" #include "doomdef.h"
#ifdef HAVE_BLUA
#include "p_local.h" #include "p_local.h"
#include "lua_script.h" #include "lua_script.h"
#include "lua_libs.h" #include "lua_libs.h"
@ -139,5 +138,3 @@ int LUA_ThinkerLib(lua_State *L)
lua_setglobal(L, "mobjs"); lua_setglobal(L, "mobjs");
return 0; return 0;
} }
#endif

View file

@ -490,29 +490,28 @@ const UINT8 gifframe_gchead[4] = {0x21,0xF9,0x04,0x04}; // GCE, bytes, packed by
static UINT8 *gifframe_data = NULL; static UINT8 *gifframe_data = NULL;
static size_t gifframe_size = 8192; static size_t gifframe_size = 8192;
//
// GIF_rgbconvert
// converts an RGB frame to a frame with a palette.
//
#ifdef HWRENDER #ifdef HWRENDER
static void hwrconvert(void) static void GIF_rgbconvert(UINT8 *linear, UINT8 *scr)
{ {
UINT8 *linear = HWR_GetScreenshot();
UINT8 *dest = screens[2];
UINT8 r, g, b; UINT8 r, g, b;
INT32 x, y; size_t src = 0, dest = 0;
size_t i = 0; size_t size = (vid.width * vid.height * 3);
InitColorLUT(gif_framepalette); InitColorLUT(gif_framepalette);
for (y = 0; y < vid.height; y++) while (src < size)
{ {
for (x = 0; x < vid.width; x++, i += 3) r = (UINT8)linear[src];
{ g = (UINT8)linear[src + 1];
r = (UINT8)linear[i]; b = (UINT8)linear[src + 2];
g = (UINT8)linear[i + 1]; scr[dest] = colorlookup[r >> SHIFTCOLORBITS][g >> SHIFTCOLORBITS][b >> SHIFTCOLORBITS];
b = (UINT8)linear[i + 2]; src += (3 * scrbuf_downscaleamt);
dest[(y * vid.width) + x] = colorlookup[r >> SHIFTCOLORBITS][g >> SHIFTCOLORBITS][b >> SHIFTCOLORBITS]; dest += scrbuf_downscaleamt;
}
} }
free(linear);
} }
#endif #endif
@ -556,7 +555,11 @@ static void GIF_framewrite(void)
I_ReadScreen(movie_screen); I_ReadScreen(movie_screen);
#ifdef HWRENDER #ifdef HWRENDER
else if (rendermode == render_opengl) else if (rendermode == render_opengl)
hwrconvert(); {
UINT8 *linear = HWR_GetScreenshot();
GIF_rgbconvert(linear, movie_screen);
free(linear);
}
#endif #endif
} }
else else
@ -565,18 +568,20 @@ static void GIF_framewrite(void)
blitw = vid.width; blitw = vid.width;
blith = vid.height; blith = vid.height;
if (gif_frames == 0)
{
if (rendermode == render_soft)
I_ReadScreen(movie_screen);
#ifdef HWRENDER #ifdef HWRENDER
else if (rendermode == render_opengl) // Copy the current OpenGL frame into the base screen
{ if (rendermode == render_opengl)
hwrconvert(); {
VID_BlitLinearScreen(screens[2], screens[0], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes); UINT8 *linear = HWR_GetScreenshot();
} GIF_rgbconvert(linear, screens[0]);
#endif free(linear);
} }
#endif
// Copy the first frame into the movie screen
// OpenGL already does the same above.
if (gif_frames == 0 && rendermode == render_soft)
I_ReadScreen(movie_screen);
movie_screen = screens[0]; movie_screen = screens[0];
} }

View file

@ -34,6 +34,25 @@ boolean myargmalloc = false;
*/ */
static INT32 found; static INT32 found;
/** \brief Parses a server URL (such as srb2://127.0.0.1) as may be passed to the game via a web browser, etc.
\return the contents of the URL after the protocol (a server to join), or NULL if not found
*/
const char *M_GetUrlProtocolArg(void)
{
INT32 i;
const size_t len = strlen(SERVER_URL_PROTOCOL);
for (i = 1; i < myargc; i++)
{
if (strlen(myargv[i]) > len && !strnicmp(myargv[i], SERVER_URL_PROTOCOL, len))
{
return &myargv[i][len];
}
}
return NULL;
}
/** \brief The M_CheckParm function /** \brief The M_CheckParm function

View file

@ -21,6 +21,9 @@ extern INT32 myargc;
extern char **myargv; extern char **myargv;
extern boolean myargmalloc; extern boolean myargmalloc;
// Looks for an srb2:// (or similar) URL passed in as an argument and returns the IP to connect to if found.
const char *M_GetUrlProtocolArg(void);
// Returns the position of the given parameter in the arg list (0 if not found). // Returns the position of the given parameter in the arg list (0 if not found).
INT32 M_CheckParm(const char *check); INT32 M_CheckParm(const char *check);

View file

@ -788,7 +788,7 @@ void Command_CauseCfail_f(void)
} }
#endif #endif
#if defined(HAVE_BLUA) && defined(LUA_ALLOW_BYTECODE) #ifdef LUA_ALLOW_BYTECODE
void Command_Dumplua_f(void) void Command_Dumplua_f(void)
{ {
if (modifiedgame) if (modifiedgame)
@ -934,6 +934,12 @@ void Command_Setcontinues_f(void)
REQUIRE_NOULTIMATE; REQUIRE_NOULTIMATE;
REQUIRE_PANDORA; REQUIRE_PANDORA;
if (!continuesInSession)
{
CONS_Printf(M_GetText("This session does not use continues.\n"));
return;
}
if (COM_Argc() > 1) if (COM_Argc() > 1)
{ {
INT32 numcontinues = atoi(COM_Argv(1)); INT32 numcontinues = atoi(COM_Argv(1));
@ -1025,13 +1031,9 @@ static boolean OP_HeightOkay(player_t *player, UINT8 ceiling)
if (ceiling) if (ceiling)
{ {
#ifdef ESLOPE
// Truncate position to match where mapthing would be when spawned // Truncate position to match where mapthing would be when spawned
// (this applies to every further P_GetZAt call as well) // (this applies to every further P_GetSlopeZAt call as well)
fixed_t cheight = sec->c_slope ? P_GetZAt(sec->c_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->ceilingheight; fixed_t cheight = P_GetSectorCeilingZAt(sec, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000);
#else
fixed_t cheight = sec->ceilingheight;
#endif
if (((cheight - player->mo->z - player->mo->height)>>FRACBITS) >= (1 << (16-ZSHIFT))) if (((cheight - player->mo->z - player->mo->height)>>FRACBITS) >= (1 << (16-ZSHIFT)))
{ {
@ -1042,11 +1044,7 @@ static boolean OP_HeightOkay(player_t *player, UINT8 ceiling)
} }
else else
{ {
#ifdef ESLOPE fixed_t fheight = P_GetSectorFloorZAt(sec, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000);
fixed_t fheight = sec->f_slope ? P_GetZAt(sec->f_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->floorheight;
#else
fixed_t fheight = sec->floorheight;
#endif
if (((player->mo->z - fheight)>>FRACBITS) >= (1 << (16-ZSHIFT))) if (((player->mo->z - fheight)>>FRACBITS) >= (1 << (16-ZSHIFT)))
{ {
CONS_Printf(M_GetText("Sorry, you're too %s to place this object (max: %d %s).\n"), M_GetText("high"), CONS_Printf(M_GetText("Sorry, you're too %s to place this object (max: %d %s).\n"), M_GetText("high"),
@ -1062,9 +1060,7 @@ static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean c
mapthing_t *mt = mapthings; mapthing_t *mt = mapthings;
sector_t *sec = player->mo->subsector->sector; sector_t *sec = player->mo->subsector->sector;
#ifdef HAVE_BLUA
LUA_InvalidateMapthings(); LUA_InvalidateMapthings();
#endif
mapthings = Z_Realloc(mapthings, ++nummapthings * sizeof (*mapthings), PU_LEVEL, NULL); mapthings = Z_Realloc(mapthings, ++nummapthings * sizeof (*mapthings), PU_LEVEL, NULL);
@ -1095,20 +1091,12 @@ static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean c
mt->y = (INT16)(player->mo->y>>FRACBITS); mt->y = (INT16)(player->mo->y>>FRACBITS);
if (ceiling) if (ceiling)
{ {
#ifdef ESLOPE fixed_t cheight = P_GetSectorCeilingZAt(sec, mt->x << FRACBITS, mt->y << FRACBITS);
fixed_t cheight = sec->c_slope ? P_GetZAt(sec->c_slope, mt->x << FRACBITS, mt->y << FRACBITS) : sec->ceilingheight;
#else
fixed_t cheight = sec->ceilingheight;
#endif
mt->z = (UINT16)((cheight - player->mo->z - player->mo->height)>>FRACBITS); mt->z = (UINT16)((cheight - player->mo->z - player->mo->height)>>FRACBITS);
} }
else else
{ {
#ifdef ESLOPE fixed_t fheight = P_GetSectorFloorZAt(sec, mt->x << FRACBITS, mt->y << FRACBITS);
fixed_t fheight = sec->f_slope ? P_GetZAt(sec->f_slope, mt->x << FRACBITS, mt->y << FRACBITS) : sec->floorheight;
#else
fixed_t fheight = sec->floorheight;
#endif
mt->z = (UINT16)((player->mo->z - fheight)>>FRACBITS); mt->z = (UINT16)((player->mo->z - fheight)>>FRACBITS);
} }
mt->angle = (INT16)(FixedInt(AngleFixed(player->mo->angle))); mt->angle = (INT16)(FixedInt(AngleFixed(player->mo->angle)));
@ -1354,20 +1342,12 @@ void OP_ObjectplaceMovement(player_t *player)
if (!!(mobjinfo[op_currentthing].flags & MF_SPAWNCEILING) ^ !!(cv_opflags.value & MTF_OBJECTFLIP)) if (!!(mobjinfo[op_currentthing].flags & MF_SPAWNCEILING) ^ !!(cv_opflags.value & MTF_OBJECTFLIP))
{ {
#ifdef ESLOPE fixed_t cheight = P_GetSectorCeilingZAt(sec, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000);
fixed_t cheight = sec->c_slope ? P_GetZAt(sec->c_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->ceilingheight;
#else
fixed_t cheight = sec->ceilingheight;
#endif
op_displayflags = (UINT16)((cheight - player->mo->z - mobjinfo[op_currentthing].height)>>FRACBITS); op_displayflags = (UINT16)((cheight - player->mo->z - mobjinfo[op_currentthing].height)>>FRACBITS);
} }
else else
{ {
#ifdef ESLOPE fixed_t fheight = P_GetSectorFloorZAt(sec, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000);
fixed_t fheight = sec->f_slope ? P_GetZAt(sec->f_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->floorheight;
#else
fixed_t fheight = sec->floorheight;
#endif
op_displayflags = (UINT16)((player->mo->z - fheight)>>FRACBITS); op_displayflags = (UINT16)((player->mo->z - fheight)>>FRACBITS);
} }
op_displayflags <<= ZSHIFT; op_displayflags <<= ZSHIFT;

View file

@ -68,7 +68,7 @@ void Command_Toggletwod_f(void);
#ifdef _DEBUG #ifdef _DEBUG
void Command_CauseCfail_f(void); void Command_CauseCfail_f(void);
#endif #endif
#if defined(HAVE_BLUA) && defined(LUA_ALLOW_BYTECODE) #ifdef LUA_ALLOW_BYTECODE
void Command_Dumplua_f(void); void Command_Dumplua_f(void);
#endif #endif

View file

@ -18,7 +18,7 @@
#include "v_video.h" // video flags #include "v_video.h" // video flags
#include "g_game.h" // record info #include "g_game.h" // record info
#include "r_things.h" // numskins #include "r_skins.h" // numskins
#include "r_draw.h" // R_GetColorByName #include "r_draw.h" // R_GetColorByName
// Map triggers for linedef executors // Map triggers for linedef executors

View file

@ -38,8 +38,20 @@ typedef INT32 fixed_t;
/*! /*!
\brief convert fixed_t into floating number \brief convert fixed_t into floating number
*/ */
#define FIXED_TO_FLOAT(x) (((float)(x)) / ((float)FRACUNIT))
#define FLOAT_TO_FIXED(f) (fixed_t)((f) * ((float)FRACUNIT)) FUNCMATH FUNCINLINE static ATTRINLINE float FixedToFloat(fixed_t x)
{
return x / (float)FRACUNIT;
}
FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FloatToFixed(float f)
{
return (fixed_t)(f * FRACUNIT);
}
// for backwards compat
#define FIXED_TO_FLOAT(x) FixedToFloat(x) // (((float)(x)) / ((float)FRACUNIT))
#define FLOAT_TO_FIXED(f) FloatToFixed(f) // (fixed_t)((f) * ((float)FRACUNIT))
#if defined (__WATCOMC__) && FRACBITS == 16 #if defined (__WATCOMC__) && FRACBITS == 16

View file

@ -312,6 +312,7 @@ static void M_AssignJoystick(INT32 choice);
static void M_ChangeControl(INT32 choice); static void M_ChangeControl(INT32 choice);
// Video & Sound // Video & Sound
static void M_VideoOptions(INT32 choice);
menu_t OP_VideoOptionsDef, OP_VideoModeDef, OP_ColorOptionsDef; menu_t OP_VideoOptionsDef, OP_VideoModeDef, OP_ColorOptionsDef;
#ifdef HWRENDER #ifdef HWRENDER
static void M_OpenGLOptionsMenu(void); static void M_OpenGLOptionsMenu(void);
@ -521,6 +522,8 @@ static menuitem_t MISC_AddonsMenu[] =
// --------------------------------- // ---------------------------------
static menuitem_t MAPauseMenu[] = static menuitem_t MAPauseMenu[] =
{ {
{IT_CALL | IT_STRING, NULL, "Emblem Hints...", M_EmblemHints, 32},
{IT_CALL | IT_STRING, NULL, "Continue", M_SelectableClearMenus,48}, {IT_CALL | IT_STRING, NULL, "Continue", M_SelectableClearMenus,48},
{IT_CALL | IT_STRING, NULL, "Retry", M_ModeAttackRetry, 56}, {IT_CALL | IT_STRING, NULL, "Retry", M_ModeAttackRetry, 56},
{IT_CALL | IT_STRING, NULL, "Abort", M_ModeAttackEndGame, 64}, {IT_CALL | IT_STRING, NULL, "Abort", M_ModeAttackEndGame, 64},
@ -528,6 +531,7 @@ static menuitem_t MAPauseMenu[] =
typedef enum typedef enum
{ {
mapause_hints,
mapause_continue, mapause_continue,
mapause_retry, mapause_retry,
mapause_abort mapause_abort
@ -729,9 +733,9 @@ static menuitem_t SR_SoundTestMenu[] =
static menuitem_t SR_EmblemHintMenu[] = static menuitem_t SR_EmblemHintMenu[] =
{ {
{IT_STRING | IT_ARROWS, NULL, "Page", M_HandleEmblemHints, 10}, {IT_STRING | IT_ARROWS, NULL, "Page", M_HandleEmblemHints, 10},
{IT_STRING|IT_CVAR, NULL, "Emblem Radar", &cv_itemfinder, 20}, {IT_STRING|IT_CVAR, NULL, "Emblem Radar", &cv_itemfinder, 20},
{IT_WHITESTRING|IT_SUBMENU, NULL, "Back", &SPauseDef, 30} {IT_WHITESTRING|IT_CALL, NULL, "Back", M_GoBack, 30}
}; };
// -------------------------------- // --------------------------------
@ -878,7 +882,8 @@ static menuitem_t SP_NightsAttackLevelSelectMenu[] =
static menuitem_t SP_NightsAttackMenu[] = static menuitem_t SP_NightsAttackMenu[] =
{ {
{IT_STRING|IT_KEYHANDLER, NULL, "Level Select...", &M_HandleTimeAttackLevelSelect, 52}, {IT_STRING|IT_KEYHANDLER, NULL, "Level Select...", &M_HandleTimeAttackLevelSelect, 52},
{IT_STRING|IT_CVAR, NULL, "Show Records For", &cv_dummymares, 62}, {IT_STRING|IT_CVAR, NULL, "Character", &cv_chooseskin, 62},
{IT_STRING|IT_CVAR, NULL, "Show Records For", &cv_dummymares, 72},
{IT_DISABLED, NULL, "Guest Option...", &SP_NightsGuestReplayDef, 100}, {IT_DISABLED, NULL, "Guest Option...", &SP_NightsGuestReplayDef, 100},
{IT_DISABLED, NULL, "Replay...", &SP_NightsReplayDef, 110}, {IT_DISABLED, NULL, "Replay...", &SP_NightsReplayDef, 110},
@ -889,6 +894,7 @@ static menuitem_t SP_NightsAttackMenu[] =
enum enum
{ {
nalevel, nalevel,
nachar,
narecords, narecords,
naguest, naguest,
@ -1034,7 +1040,7 @@ static menuitem_t OP_MainMenu[] =
{IT_SUBMENU | IT_STRING, NULL, "Player 2 Controls...", &OP_P2ControlsDef, 20}, {IT_SUBMENU | IT_STRING, NULL, "Player 2 Controls...", &OP_P2ControlsDef, 20},
{IT_CVAR | IT_STRING, NULL, "Controls per key", &cv_controlperkey, 30}, {IT_CVAR | IT_STRING, NULL, "Controls per key", &cv_controlperkey, 30},
{IT_SUBMENU | IT_STRING, NULL, "Video Options...", &OP_VideoOptionsDef, 50}, {IT_CALL | IT_STRING, NULL, "Video Options...", M_VideoOptions, 50},
{IT_SUBMENU | IT_STRING, NULL, "Sound Options...", &OP_SoundOptionsDef, 60}, {IT_SUBMENU | IT_STRING, NULL, "Sound Options...", &OP_SoundOptionsDef, 60},
{IT_CALL | IT_STRING, NULL, "Server Options...", M_ServerOptions, 80}, {IT_CALL | IT_STRING, NULL, "Server Options...", M_ServerOptions, 80},
@ -1285,6 +1291,16 @@ static menuitem_t OP_Camera2ExtendedOptionsMenu[] =
{IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 126}, {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 126},
}; };
enum
{
op_video_resolution = 1,
#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)
op_video_fullscreen,
#endif
op_video_vsync,
op_video_renderer,
};
static menuitem_t OP_VideoOptionsMenu[] = static menuitem_t OP_VideoOptionsMenu[] =
{ {
{IT_HEADER, NULL, "Screen", NULL, 0}, {IT_HEADER, NULL, "Screen", NULL, 0},
@ -1569,7 +1585,7 @@ static menuitem_t OP_ServerOptionsMenu[] =
{IT_HEADER, NULL, "General", NULL, 0}, {IT_HEADER, NULL, "General", NULL, 0},
#ifndef NONET #ifndef NONET
{IT_STRING | IT_CVAR | IT_CV_STRING, {IT_STRING | IT_CVAR | IT_CV_STRING,
NULL, "Server name", &cv_servername, 7}, NULL, "Server name", &cv_servername, 7},
{IT_STRING | IT_CVAR, NULL, "Max Players", &cv_maxplayers, 21}, {IT_STRING | IT_CVAR, NULL, "Max Players", &cv_maxplayers, 21},
{IT_STRING | IT_CVAR, NULL, "Allow Add-on Downloading", &cv_downloading, 26}, {IT_STRING | IT_CVAR, NULL, "Allow Add-on Downloading", &cv_downloading, 26},
{IT_STRING | IT_CVAR, NULL, "Allow players to join", &cv_allownewplayer, 31}, {IT_STRING | IT_CVAR, NULL, "Allow players to join", &cv_allownewplayer, 31},
@ -1614,8 +1630,9 @@ static menuitem_t OP_ServerOptionsMenu[] =
#ifndef NONET #ifndef NONET
{IT_HEADER, NULL, "Advanced", NULL, 225}, {IT_HEADER, NULL, "Advanced", NULL, 225},
{IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 231}, {IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 231},
{IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 245}, {IT_STRING | IT_CVAR, NULL, "Join delay", &cv_joindelay, 246},
{IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 251},
#endif #endif
}; };
@ -1687,7 +1704,7 @@ static INT32 highlightflags, recommendedflags, warningflags;
// Sky Room // Sky Room
menu_t SR_PandoraDef = menu_t SR_PandoraDef =
{ {
MN_SR_MAIN + (MN_SR_PANDORA << 6), MTREE2(MN_SR_MAIN, MN_SR_PANDORA),
"M_PANDRA", "M_PANDRA",
sizeof (SR_PandorasBox)/sizeof (menuitem_t), sizeof (SR_PandorasBox)/sizeof (menuitem_t),
&SPauseDef, &SPauseDef,
@ -1701,12 +1718,12 @@ menu_t SR_PandoraDef =
menu_t SR_MainDef = DEFAULTMENUSTYLE(MN_SR_MAIN, "M_SECRET", SR_MainMenu, &MainDef, 60, 40); menu_t SR_MainDef = DEFAULTMENUSTYLE(MN_SR_MAIN, "M_SECRET", SR_MainMenu, &MainDef, 60, 40);
menu_t SR_LevelSelectDef = MAPPLATTERMENUSTYLE( menu_t SR_LevelSelectDef = MAPPLATTERMENUSTYLE(
MN_SR_MAIN + (MN_SR_LEVELSELECT << 6), MTREE2(MN_SR_MAIN, MN_SR_LEVELSELECT),
NULL, SR_LevelSelectMenu); NULL, SR_LevelSelectMenu);
menu_t SR_UnlockChecklistDef = menu_t SR_UnlockChecklistDef =
{ {
MN_SR_MAIN + (MN_SR_UNLOCKCHECKLIST << 6), MTREE2(MN_SR_MAIN, MN_SR_UNLOCKCHECKLIST),
"M_SECRET", "M_SECRET",
1, 1,
&SR_MainDef, &SR_MainDef,
@ -1719,7 +1736,7 @@ menu_t SR_UnlockChecklistDef =
menu_t SR_SoundTestDef = menu_t SR_SoundTestDef =
{ {
MN_SR_MAIN + (MN_SR_SOUNDTEST << 6), MTREE2(MN_SR_MAIN, MN_SR_SOUNDTEST),
NULL, NULL,
sizeof (SR_SoundTestMenu)/sizeof (menuitem_t), sizeof (SR_SoundTestMenu)/sizeof (menuitem_t),
&SR_MainDef, &SR_MainDef,
@ -1732,7 +1749,7 @@ menu_t SR_SoundTestDef =
menu_t SR_EmblemHintDef = menu_t SR_EmblemHintDef =
{ {
MN_SR_MAIN + (MN_SR_EMBLEMHINT << 6), MTREE2(MN_SR_MAIN, MN_SR_EMBLEMHINT),
NULL, NULL,
sizeof (SR_EmblemHintMenu)/sizeof (menuitem_t), sizeof (SR_EmblemHintMenu)/sizeof (menuitem_t),
&SPauseDef, &SPauseDef,
@ -1759,7 +1776,7 @@ menu_t SP_MainDef = //CENTERMENUSTYLE(NULL, SP_MainMenu, &MainDef, 72);
menu_t SP_LoadDef = menu_t SP_LoadDef =
{ {
MN_SP_MAIN + (MN_SP_LOAD << 6), MTREE2(MN_SP_MAIN, MN_SP_LOAD),
"M_PICKG", "M_PICKG",
1, 1,
&SP_MainDef, &SP_MainDef,
@ -1771,12 +1788,12 @@ menu_t SP_LoadDef =
}; };
menu_t SP_LevelSelectDef = MAPPLATTERMENUSTYLE( menu_t SP_LevelSelectDef = MAPPLATTERMENUSTYLE(
MN_SP_MAIN + (MN_SP_LOAD << 6) + (MN_SP_PLAYER << 12) + (MN_SP_LEVELSELECT << 18), MTREE4(MN_SP_MAIN, MN_SP_LOAD, MN_SP_PLAYER, MN_SP_LEVELSELECT),
NULL, SP_LevelSelectMenu); NULL, SP_LevelSelectMenu);
menu_t SP_LevelStatsDef = menu_t SP_LevelStatsDef =
{ {
MN_SP_MAIN + (MN_SP_LEVELSTATS << 6), MTREE2(MN_SP_MAIN, MN_SP_LEVELSTATS),
"M_STATS", "M_STATS",
1, 1,
&SP_MainDef, &SP_MainDef,
@ -1788,12 +1805,12 @@ menu_t SP_LevelStatsDef =
}; };
menu_t SP_TimeAttackLevelSelectDef = MAPPLATTERMENUSTYLE( menu_t SP_TimeAttackLevelSelectDef = MAPPLATTERMENUSTYLE(
MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_TIMEATTACK_LEVELSELECT << 12), MTREE3(MN_SP_MAIN, MN_SP_TIMEATTACK, MN_SP_TIMEATTACK_LEVELSELECT),
"M_ATTACK", SP_TimeAttackLevelSelectMenu); "M_ATTACK", SP_TimeAttackLevelSelectMenu);
static menu_t SP_TimeAttackDef = static menu_t SP_TimeAttackDef =
{ {
MN_SP_MAIN + (MN_SP_TIMEATTACK << 6), MTREE2(MN_SP_MAIN, MN_SP_TIMEATTACK),
"M_ATTACK", "M_ATTACK",
sizeof (SP_TimeAttackMenu)/sizeof (menuitem_t), sizeof (SP_TimeAttackMenu)/sizeof (menuitem_t),
&MainDef, // Doesn't matter. &MainDef, // Doesn't matter.
@ -1805,7 +1822,7 @@ static menu_t SP_TimeAttackDef =
}; };
static menu_t SP_ReplayDef = static menu_t SP_ReplayDef =
{ {
MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_REPLAY << 12), MTREE3(MN_SP_MAIN, MN_SP_TIMEATTACK, MN_SP_REPLAY),
"M_ATTACK", "M_ATTACK",
sizeof(SP_ReplayMenu)/sizeof(menuitem_t), sizeof(SP_ReplayMenu)/sizeof(menuitem_t),
&SP_TimeAttackDef, &SP_TimeAttackDef,
@ -1817,7 +1834,7 @@ static menu_t SP_ReplayDef =
}; };
static menu_t SP_GuestReplayDef = static menu_t SP_GuestReplayDef =
{ {
MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_GUESTREPLAY << 12), MTREE3(MN_SP_MAIN, MN_SP_TIMEATTACK, MN_SP_GUESTREPLAY),
"M_ATTACK", "M_ATTACK",
sizeof(SP_GuestReplayMenu)/sizeof(menuitem_t), sizeof(SP_GuestReplayMenu)/sizeof(menuitem_t),
&SP_TimeAttackDef, &SP_TimeAttackDef,
@ -1829,7 +1846,7 @@ static menu_t SP_GuestReplayDef =
}; };
static menu_t SP_GhostDef = static menu_t SP_GhostDef =
{ {
MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_GHOST << 12), MTREE3(MN_SP_MAIN, MN_SP_TIMEATTACK, MN_SP_GHOST),
"M_ATTACK", "M_ATTACK",
sizeof(SP_GhostMenu)/sizeof(menuitem_t), sizeof(SP_GhostMenu)/sizeof(menuitem_t),
&SP_TimeAttackDef, &SP_TimeAttackDef,
@ -1841,12 +1858,12 @@ static menu_t SP_GhostDef =
}; };
menu_t SP_NightsAttackLevelSelectDef = MAPPLATTERMENUSTYLE( menu_t SP_NightsAttackLevelSelectDef = MAPPLATTERMENUSTYLE(
MN_SP_MAIN + (MN_SP_NIGHTSATTACK << 6) + (MN_SP_NIGHTS_LEVELSELECT << 12), MTREE3(MN_SP_MAIN, MN_SP_NIGHTSATTACK, MN_SP_NIGHTS_LEVELSELECT),
"M_NIGHTS", SP_NightsAttackLevelSelectMenu); "M_NIGHTS", SP_NightsAttackLevelSelectMenu);
static menu_t SP_NightsAttackDef = static menu_t SP_NightsAttackDef =
{ {
MN_SP_MAIN + (MN_SP_NIGHTSATTACK << 6), MTREE2(MN_SP_MAIN, MN_SP_NIGHTSATTACK),
"M_NIGHTS", "M_NIGHTS",
sizeof (SP_NightsAttackMenu)/sizeof (menuitem_t), sizeof (SP_NightsAttackMenu)/sizeof (menuitem_t),
&MainDef, // Doesn't matter. &MainDef, // Doesn't matter.
@ -1858,7 +1875,7 @@ static menu_t SP_NightsAttackDef =
}; };
static menu_t SP_NightsReplayDef = static menu_t SP_NightsReplayDef =
{ {
MN_SP_MAIN + (MN_SP_NIGHTSATTACK << 6) + (MN_SP_NIGHTS_REPLAY << 12), MTREE3(MN_SP_MAIN, MN_SP_NIGHTSATTACK, MN_SP_NIGHTS_REPLAY),
"M_NIGHTS", "M_NIGHTS",
sizeof(SP_NightsReplayMenu)/sizeof(menuitem_t), sizeof(SP_NightsReplayMenu)/sizeof(menuitem_t),
&SP_NightsAttackDef, &SP_NightsAttackDef,
@ -1870,7 +1887,7 @@ static menu_t SP_NightsReplayDef =
}; };
static menu_t SP_NightsGuestReplayDef = static menu_t SP_NightsGuestReplayDef =
{ {
MN_SP_MAIN + (MN_SP_NIGHTSATTACK << 6) + (MN_SP_NIGHTS_GUESTREPLAY << 12), MTREE3(MN_SP_MAIN, MN_SP_NIGHTSATTACK, MN_SP_NIGHTS_GUESTREPLAY),
"M_NIGHTS", "M_NIGHTS",
sizeof(SP_NightsGuestReplayMenu)/sizeof(menuitem_t), sizeof(SP_NightsGuestReplayMenu)/sizeof(menuitem_t),
&SP_NightsAttackDef, &SP_NightsAttackDef,
@ -1882,7 +1899,7 @@ static menu_t SP_NightsGuestReplayDef =
}; };
static menu_t SP_NightsGhostDef = static menu_t SP_NightsGhostDef =
{ {
MN_SP_MAIN + (MN_SP_NIGHTSATTACK << 6) + (MN_SP_NIGHTS_GHOST << 12), MTREE3(MN_SP_MAIN, MN_SP_NIGHTSATTACK, MN_SP_NIGHTS_GHOST),
"M_NIGHTS", "M_NIGHTS",
sizeof(SP_NightsGhostMenu)/sizeof(menuitem_t), sizeof(SP_NightsGhostMenu)/sizeof(menuitem_t),
&SP_NightsAttackDef, &SP_NightsAttackDef,
@ -1896,7 +1913,7 @@ static menu_t SP_NightsGhostDef =
menu_t SP_PlayerDef = menu_t SP_PlayerDef =
{ {
MN_SP_MAIN + (MN_SP_LOAD << 6) + (MN_SP_PLAYER << 12), MTREE3(MN_SP_MAIN, MN_SP_LOAD, MN_SP_PLAYER),
"M_PICKP", "M_PICKP",
sizeof (SP_PlayerMenu)/sizeof (menuitem_t), sizeof (SP_PlayerMenu)/sizeof (menuitem_t),
&SP_MainDef, &SP_MainDef,
@ -1911,7 +1928,7 @@ menu_t SP_PlayerDef =
menu_t MP_SplitServerDef = menu_t MP_SplitServerDef =
{ {
MN_MP_MAIN + (MN_MP_SPLITSCREEN << 6), MTREE2(MN_MP_MAIN, MN_MP_SPLITSCREEN),
"M_MULTI", "M_MULTI",
sizeof (MP_SplitServerMenu)/sizeof (menuitem_t), sizeof (MP_SplitServerMenu)/sizeof (menuitem_t),
#ifndef NONET #ifndef NONET
@ -1943,7 +1960,7 @@ menu_t MP_MainDef =
menu_t MP_ServerDef = menu_t MP_ServerDef =
{ {
MN_MP_MAIN + (MN_MP_SERVER << 6), MTREE2(MN_MP_MAIN, MN_MP_SERVER),
"M_MULTI", "M_MULTI",
sizeof (MP_ServerMenu)/sizeof (menuitem_t), sizeof (MP_ServerMenu)/sizeof (menuitem_t),
&MP_MainDef, &MP_MainDef,
@ -1956,7 +1973,7 @@ menu_t MP_ServerDef =
menu_t MP_ConnectDef = menu_t MP_ConnectDef =
{ {
MN_MP_MAIN + (MN_MP_CONNECT << 6), MTREE2(MN_MP_MAIN, MN_MP_CONNECT),
"M_MULTI", "M_MULTI",
sizeof (MP_ConnectMenu)/sizeof (menuitem_t), sizeof (MP_ConnectMenu)/sizeof (menuitem_t),
&MP_MainDef, &MP_MainDef,
@ -1969,7 +1986,7 @@ menu_t MP_ConnectDef =
menu_t MP_RoomDef = menu_t MP_RoomDef =
{ {
MN_MP_MAIN + (MN_MP_ROOM << 6), MTREE2(MN_MP_MAIN, MN_MP_ROOM),
"M_MULTI", "M_MULTI",
sizeof (MP_RoomMenu)/sizeof (menuitem_t), sizeof (MP_RoomMenu)/sizeof (menuitem_t),
&MP_ConnectDef, &MP_ConnectDef,
@ -1984,9 +2001,9 @@ menu_t MP_RoomDef =
menu_t MP_PlayerSetupDef = menu_t MP_PlayerSetupDef =
{ {
#ifdef NONET #ifdef NONET
MN_MP_MAIN + (MN_MP_PLAYERSETUP << 6), MTREE2(MN_MP_MAIN, MN_MP_PLAYERSETUP),
#else #else
MN_MP_MAIN + (MN_MP_SPLITSCREEN << 6) + (MN_MP_PLAYERSETUP << 12), MTREE3(MN_MP_MAIN, MN_MP_SPLITSCREEN, MN_MP_PLAYERSETUP),
#endif #endif
"M_SPLAYR", "M_SPLAYR",
sizeof (MP_PlayerSetupMenu)/sizeof (menuitem_t), sizeof (MP_PlayerSetupMenu)/sizeof (menuitem_t),
@ -2002,12 +2019,13 @@ menu_t MP_PlayerSetupDef =
menu_t OP_MainDef = DEFAULTMENUSTYLE( menu_t OP_MainDef = DEFAULTMENUSTYLE(
MN_OP_MAIN, MN_OP_MAIN,
"M_OPTTTL", OP_MainMenu, &MainDef, 50, 30); "M_OPTTTL", OP_MainMenu, &MainDef, 50, 30);
menu_t OP_ChangeControlsDef = CONTROLMENUSTYLE( menu_t OP_ChangeControlsDef = CONTROLMENUSTYLE(
MN_OP_MAIN + (MN_OP_CHANGECONTROLS << 12), // second level (<<6) set on runtime MTREE3(MN_OP_MAIN, 0, MN_OP_CHANGECONTROLS), // second level set on runtime
OP_ChangeControlsMenu, &OP_MainDef); OP_ChangeControlsMenu, &OP_MainDef);
menu_t OP_P1ControlsDef = { menu_t OP_P1ControlsDef = {
MN_OP_MAIN + (MN_OP_P1CONTROLS << 6), MTREE2(MN_OP_MAIN, MN_OP_P1CONTROLS),
"M_CONTRO", "M_CONTRO",
sizeof(OP_P1ControlsMenu)/sizeof(menuitem_t), sizeof(OP_P1ControlsMenu)/sizeof(menuitem_t),
&OP_MainDef, &OP_MainDef,
@ -2015,7 +2033,7 @@ menu_t OP_P1ControlsDef = {
M_DrawControlsDefMenu, M_DrawControlsDefMenu,
50, 30, 0, NULL}; 50, 30, 0, NULL};
menu_t OP_P2ControlsDef = { menu_t OP_P2ControlsDef = {
MN_OP_MAIN + (MN_OP_P2CONTROLS << 6), MTREE2(MN_OP_MAIN, MN_OP_P2CONTROLS),
"M_CONTRO", "M_CONTRO",
sizeof(OP_P2ControlsMenu)/sizeof(menuitem_t), sizeof(OP_P2ControlsMenu)/sizeof(menuitem_t),
&OP_MainDef, &OP_MainDef,
@ -2024,20 +2042,22 @@ menu_t OP_P2ControlsDef = {
50, 30, 0, NULL}; 50, 30, 0, NULL};
menu_t OP_MouseOptionsDef = DEFAULTMENUSTYLE( menu_t OP_MouseOptionsDef = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_P1CONTROLS << 6) + (MN_OP_P1MOUSE << 12), MTREE3(MN_OP_MAIN, MN_OP_P1CONTROLS, MN_OP_P1MOUSE),
"M_CONTRO", OP_MouseOptionsMenu, &OP_P1ControlsDef, 35, 30); "M_CONTRO", OP_MouseOptionsMenu, &OP_P1ControlsDef, 35, 30);
menu_t OP_Mouse2OptionsDef = DEFAULTMENUSTYLE( menu_t OP_Mouse2OptionsDef = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_P2CONTROLS << 6) + (MN_OP_P2MOUSE << 12), MTREE3(MN_OP_MAIN, MN_OP_P2CONTROLS, MN_OP_P2MOUSE),
"M_CONTRO", OP_Mouse2OptionsMenu, &OP_P2ControlsDef, 35, 30); "M_CONTRO", OP_Mouse2OptionsMenu, &OP_P2ControlsDef, 35, 30);
menu_t OP_Joystick1Def = DEFAULTMENUSTYLE( menu_t OP_Joystick1Def = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_P1CONTROLS << 6) + (MN_OP_P1JOYSTICK << 12), MTREE3(MN_OP_MAIN, MN_OP_P1CONTROLS, MN_OP_P1JOYSTICK),
"M_CONTRO", OP_Joystick1Menu, &OP_P1ControlsDef, 50, 30); "M_CONTRO", OP_Joystick1Menu, &OP_P1ControlsDef, 50, 30);
menu_t OP_Joystick2Def = DEFAULTMENUSTYLE( menu_t OP_Joystick2Def = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_P2CONTROLS << 6) + (MN_OP_P2JOYSTICK << 12), MTREE3(MN_OP_MAIN, MN_OP_P2CONTROLS, MN_OP_P2JOYSTICK),
"M_CONTRO", OP_Joystick2Menu, &OP_P2ControlsDef, 50, 30); "M_CONTRO", OP_Joystick2Menu, &OP_P2ControlsDef, 50, 30);
menu_t OP_JoystickSetDef = menu_t OP_JoystickSetDef =
{ {
MN_OP_MAIN + (MN_OP_JOYSTICKSET << MENUBITS*3), // second (<<6) and third level (<<12) set on runtime MTREE4(MN_OP_MAIN, 0, 0, MN_OP_JOYSTICKSET), // second and third level set on runtime
"M_CONTRO", "M_CONTRO",
sizeof (OP_JoystickSetMenu)/sizeof (menuitem_t), sizeof (OP_JoystickSetMenu)/sizeof (menuitem_t),
&OP_Joystick1Def, &OP_Joystick1Def,
@ -2049,7 +2069,7 @@ menu_t OP_JoystickSetDef =
}; };
menu_t OP_CameraOptionsDef = { menu_t OP_CameraOptionsDef = {
MN_OP_MAIN + (MN_OP_P1CONTROLS << 6) + (MN_OP_P1CAMERA << 12), MTREE3(MN_OP_MAIN, MN_OP_P1CONTROLS, MN_OP_P1CAMERA),
"M_CONTRO", "M_CONTRO",
sizeof (OP_CameraOptionsMenu)/sizeof (menuitem_t), sizeof (OP_CameraOptionsMenu)/sizeof (menuitem_t),
&OP_P1ControlsDef, &OP_P1ControlsDef,
@ -2060,7 +2080,7 @@ menu_t OP_CameraOptionsDef = {
NULL NULL
}; };
menu_t OP_Camera2OptionsDef = { menu_t OP_Camera2OptionsDef = {
MN_OP_MAIN + (MN_OP_P2CONTROLS << 6) + (MN_OP_P2CAMERA << 12), MTREE3(MN_OP_MAIN, MN_OP_P2CONTROLS, MN_OP_P2CAMERA),
"M_CONTRO", "M_CONTRO",
sizeof (OP_Camera2OptionsMenu)/sizeof (menuitem_t), sizeof (OP_Camera2OptionsMenu)/sizeof (menuitem_t),
&OP_P2ControlsDef, &OP_P2ControlsDef,
@ -2074,7 +2094,7 @@ menu_t OP_Camera2OptionsDef = {
static menuitem_t OP_PlaystyleMenu[] = {{IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandlePlaystyleMenu, 0}}; static menuitem_t OP_PlaystyleMenu[] = {{IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandlePlaystyleMenu, 0}};
menu_t OP_PlaystyleDef = { menu_t OP_PlaystyleDef = {
MN_OP_MAIN + (MN_OP_P1CONTROLS << 6) + (MN_OP_PLAYSTYLE << 12), MTREE3(MN_OP_MAIN, MN_OP_P1CONTROLS, MN_OP_PLAYSTYLE), ///@TODO the second level should be set in runtime
NULL, NULL,
1, 1,
&OP_P1ControlsDef, &OP_P1ControlsDef,
@ -2083,10 +2103,24 @@ menu_t OP_PlaystyleDef = {
0, 0, 0, NULL 0, 0, 0, NULL
}; };
static void M_VideoOptions(INT32 choice)
{
(void)choice;
#ifdef HWRENDER
if (vid_opengl_state == -1)
{
OP_VideoOptionsMenu[op_video_renderer].status = (IT_TRANSTEXT | IT_PAIR);
OP_VideoOptionsMenu[op_video_renderer].patch = "Renderer";
OP_VideoOptionsMenu[op_video_renderer].text = "Software";
}
#endif
M_SetupNextMenu(&OP_VideoOptionsDef);
}
menu_t OP_VideoOptionsDef = menu_t OP_VideoOptionsDef =
{ {
MN_OP_MAIN + (MN_OP_VIDEO << 6), MTREE2(MN_OP_MAIN, MN_OP_VIDEO),
"M_VIDEO", "M_VIDEO",
sizeof (OP_VideoOptionsMenu)/sizeof (menuitem_t), sizeof (OP_VideoOptionsMenu)/sizeof (menuitem_t),
&OP_MainDef, &OP_MainDef,
@ -2098,7 +2132,7 @@ menu_t OP_VideoOptionsDef =
}; };
menu_t OP_VideoModeDef = menu_t OP_VideoModeDef =
{ {
MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_VIDEOMODE << 12), MTREE3(MN_OP_MAIN, MN_OP_VIDEO, MN_OP_VIDEOMODE),
"M_VIDEO", "M_VIDEO",
1, 1,
&OP_VideoOptionsDef, &OP_VideoOptionsDef,
@ -2110,7 +2144,7 @@ menu_t OP_VideoModeDef =
}; };
menu_t OP_ColorOptionsDef = menu_t OP_ColorOptionsDef =
{ {
MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_COLOR << 12), MTREE3(MN_OP_MAIN, MN_OP_VIDEO, MN_OP_COLOR),
"M_VIDEO", "M_VIDEO",
sizeof (OP_ColorOptionsMenu)/sizeof (menuitem_t), sizeof (OP_ColorOptionsMenu)/sizeof (menuitem_t),
&OP_VideoOptionsDef, &OP_VideoOptionsDef,
@ -2121,17 +2155,19 @@ menu_t OP_ColorOptionsDef =
NULL NULL
}; };
menu_t OP_SoundOptionsDef = DEFAULTMENUSTYLE( menu_t OP_SoundOptionsDef = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_SOUND << 6), MTREE2(MN_OP_MAIN, MN_OP_SOUND),
"M_SOUND", OP_SoundOptionsMenu, &OP_MainDef, 30, 30); "M_SOUND", OP_SoundOptionsMenu, &OP_MainDef, 30, 30);
menu_t OP_SoundAdvancedDef = DEFAULTMENUSTYLE(MN_OP_MAIN + (MN_OP_SOUND << 6), "M_SOUND", OP_SoundAdvancedMenu, &OP_SoundOptionsDef, 30, 30); menu_t OP_SoundAdvancedDef = DEFAULTMENUSTYLE(
MTREE2(MN_OP_MAIN, MN_OP_SOUND),
"M_SOUND", OP_SoundAdvancedMenu, &OP_SoundOptionsDef, 30, 30);
menu_t OP_ServerOptionsDef = DEFAULTSCROLLMENUSTYLE( menu_t OP_ServerOptionsDef = DEFAULTSCROLLMENUSTYLE(
MN_OP_MAIN + (MN_OP_SERVER << 6), MTREE2(MN_OP_MAIN, MN_OP_SERVER),
"M_SERVER", OP_ServerOptionsMenu, &OP_MainDef, 30, 30); "M_SERVER", OP_ServerOptionsMenu, &OP_MainDef, 30, 30);
menu_t OP_MonitorToggleDef = menu_t OP_MonitorToggleDef =
{ {
MN_OP_MAIN + (MN_OP_SERVER << 6) + (MN_OP_MONITORTOGGLE << 12), MTREE3(MN_OP_MAIN, MN_OP_SOUND, MN_OP_MONITORTOGGLE),
"M_SERVER", "M_SERVER",
sizeof (OP_MonitorToggleMenu)/sizeof (menuitem_t), sizeof (OP_MonitorToggleMenu)/sizeof (menuitem_t),
&OP_ServerOptionsDef, &OP_ServerOptionsDef,
@ -2152,16 +2188,16 @@ static void M_OpenGLOptionsMenu(void)
} }
menu_t OP_OpenGLOptionsDef = DEFAULTMENUSTYLE( menu_t OP_OpenGLOptionsDef = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_OPENGL << 12), MTREE3(MN_OP_MAIN, MN_OP_VIDEO, MN_OP_OPENGL),
"M_VIDEO", OP_OpenGLOptionsMenu, &OP_VideoOptionsDef, 30, 30); "M_VIDEO", OP_OpenGLOptionsMenu, &OP_VideoOptionsDef, 30, 30);
#ifdef ALAM_LIGHTING #ifdef ALAM_LIGHTING
menu_t OP_OpenGLLightingDef = DEFAULTMENUSTYLE( menu_t OP_OpenGLLightingDef = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_OPENGL << 12) + (MN_OP_OPENGL_LIGHTING << 18), MTREE4(MN_OP_MAIN, MN_OP_VIDEO, MN_OP_OPENGL, MN_OP_OPENGL_LIGHTING),
"M_VIDEO", OP_OpenGLLightingMenu, &OP_OpenGLOptionsDef, 60, 40); "M_VIDEO", OP_OpenGLLightingMenu, &OP_OpenGLOptionsDef, 60, 40);
#endif #endif
menu_t OP_OpenGLFogDef = menu_t OP_OpenGLFogDef =
{ {
MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_OPENGL << 12) + (MN_OP_OPENGL_FOG << 18), MTREE4(MN_OP_MAIN, MN_OP_VIDEO, MN_OP_OPENGL, MN_OP_OPENGL_FOG),
"M_VIDEO", "M_VIDEO",
sizeof (OP_OpenGLFogMenu)/sizeof (menuitem_t), sizeof (OP_OpenGLFogMenu)/sizeof (menuitem_t),
&OP_OpenGLOptionsDef, &OP_OpenGLOptionsDef,
@ -2173,13 +2209,13 @@ menu_t OP_OpenGLFogDef =
}; };
#endif #endif
menu_t OP_DataOptionsDef = DEFAULTMENUSTYLE( menu_t OP_DataOptionsDef = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_DATA << 6), MTREE2(MN_OP_MAIN, MN_OP_DATA),
"M_DATA", OP_DataOptionsMenu, &OP_MainDef, 60, 30); "M_DATA", OP_DataOptionsMenu, &OP_MainDef, 60, 30);
menu_t OP_ScreenshotOptionsDef = menu_t OP_ScreenshotOptionsDef =
{ {
MN_OP_MAIN + (MN_OP_DATA << 6) + (MN_OP_SCREENSHOTS << 12), MTREE3(MN_OP_MAIN, MN_OP_DATA, MN_OP_SCREENSHOTS),
"M_DATA", "M_SCREEN",
sizeof (OP_ScreenshotOptionsMenu)/sizeof (menuitem_t), sizeof (OP_ScreenshotOptionsMenu)/sizeof (menuitem_t),
&OP_DataOptionsDef, &OP_DataOptionsDef,
OP_ScreenshotOptionsMenu, OP_ScreenshotOptionsMenu,
@ -2190,11 +2226,11 @@ menu_t OP_ScreenshotOptionsDef =
}; };
menu_t OP_AddonsOptionsDef = DEFAULTMENUSTYLE( menu_t OP_AddonsOptionsDef = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_DATA << 6) + (MN_OP_ADDONS << 12), MTREE3(MN_OP_MAIN, MN_OP_DATA, MN_OP_ADDONS),
"M_ADDONS", OP_AddonsOptionsMenu, &OP_DataOptionsDef, 30, 30); "M_ADDONS", OP_AddonsOptionsMenu, &OP_DataOptionsDef, 30, 30);
menu_t OP_EraseDataDef = DEFAULTMENUSTYLE( menu_t OP_EraseDataDef = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_DATA << 6) + (MN_OP_ERASEDATA << 12), MTREE3(MN_OP_MAIN, MN_OP_DATA, MN_OP_ERASEDATA),
"M_DATA", OP_EraseDataMenu, &OP_DataOptionsDef, 60, 30); "M_DATA", OP_EraseDataMenu, &OP_DataOptionsDef, 60, 30);
// ========================================================================== // ==========================================================================
@ -3609,6 +3645,7 @@ void M_StartControlPanel(void)
else if (modeattacking) else if (modeattacking)
{ {
currentMenu = &MAPauseDef; currentMenu = &MAPauseDef;
MAPauseMenu[mapause_hints].status = (M_SecretUnlocked(SECRET_EMBLEMHINTS)) ? (IT_STRING | IT_CALL) : (IT_DISABLED);
itemOn = mapause_continue; itemOn = mapause_continue;
} }
else if (!(netgame || multiplayer)) // Single Player else if (!(netgame || multiplayer)) // Single Player
@ -5049,6 +5086,17 @@ static boolean M_SetNextMapOnPlatter(void)
} }
#endif #endif
static boolean M_GametypeHasLevels(INT32 gt)
{
INT32 mapnum;
for (mapnum = 0; mapnum < NUMMAPS; mapnum++)
if (M_CanShowLevelOnPlatter(mapnum, gt))
return true;
return false;
}
static INT32 M_CountRowsToShowOnPlatter(INT32 gt) static INT32 M_CountRowsToShowOnPlatter(INT32 gt)
{ {
INT32 mapnum = 0, prevmapnum = 0, col = 0, rows = 0; INT32 mapnum = 0, prevmapnum = 0, col = 0, rows = 0;
@ -5140,7 +5188,7 @@ static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick)
{ {
if (M_CanShowLevelOnPlatter(mapnum, gt)) if (M_CanShowLevelOnPlatter(mapnum, gt))
{ {
const INT32 actnum = mapheaderinfo[mapnum]->actnum; const UINT8 actnum = mapheaderinfo[mapnum]->actnum;
const boolean headingisname = (fastcmp(mapheaderinfo[mapnum]->selectheading, mapheaderinfo[mapnum]->lvlttl)); const boolean headingisname = (fastcmp(mapheaderinfo[mapnum]->selectheading, mapheaderinfo[mapnum]->lvlttl));
const boolean wide = (mapheaderinfo[mapnum]->menuflags & LF2_WIDEICON); const boolean wide = (mapheaderinfo[mapnum]->menuflags & LF2_WIDEICON);
@ -5366,7 +5414,10 @@ static void M_HandleLevelPlatter(INT32 choice)
case KEY_RIGHTARROW: case KEY_RIGHTARROW:
if (levellistmode == LLM_CREATESERVER && !lsrow) if (levellistmode == LLM_CREATESERVER && !lsrow)
{ {
CV_AddValue(&cv_newgametype, 1); INT32 startinggametype = cv_newgametype.value;
do
CV_AddValue(&cv_newgametype, 1);
while (cv_newgametype.value != startinggametype && !M_GametypeHasLevels(cv_newgametype.value));
S_StartSound(NULL,sfx_menu1); S_StartSound(NULL,sfx_menu1);
lscol = 0; lscol = 0;
@ -5395,7 +5446,10 @@ static void M_HandleLevelPlatter(INT32 choice)
case KEY_LEFTARROW: case KEY_LEFTARROW:
if (levellistmode == LLM_CREATESERVER && !lsrow) if (levellistmode == LLM_CREATESERVER && !lsrow)
{ {
CV_AddValue(&cv_newgametype, -1); INT32 startinggametype = cv_newgametype.value;
do
CV_AddValue(&cv_newgametype, -1);
while (cv_newgametype.value != startinggametype && !M_GametypeHasLevels(cv_newgametype.value));
S_StartSound(NULL,sfx_menu1); S_StartSound(NULL,sfx_menu1);
lscol = 0; lscol = 0;
@ -5715,6 +5769,8 @@ static void M_DrawNightsAttackSuperSonic(void)
const UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_YELLOW, GTC_CACHE); const UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_YELLOW, GTC_CACHE);
INT32 timer = (ntsatkdrawtimer/4) % 2; INT32 timer = (ntsatkdrawtimer/4) % 2;
angle_t fa = (FixedAngle(((ntsatkdrawtimer * 4) % 360)<<FRACBITS)>>ANGLETOFINESHIFT) & FINEMASK; angle_t fa = (FixedAngle(((ntsatkdrawtimer * 4) % 360)<<FRACBITS)>>ANGLETOFINESHIFT) & FINEMASK;
ntssupersonic[0] = W_CachePatchName("NTSSONC1", PU_PATCH);
ntssupersonic[1] = W_CachePatchName("NTSSONC2", PU_PATCH);
V_DrawFixedPatch(235<<FRACBITS, (120<<FRACBITS) - (8*FINESINE(fa)), FRACUNIT, 0, ntssupersonic[timer], colormap); V_DrawFixedPatch(235<<FRACBITS, (120<<FRACBITS) - (8*FINESINE(fa)), FRACUNIT, 0, ntssupersonic[timer], colormap);
} }
@ -6630,12 +6686,6 @@ static void M_HandleAddons(INT32 choice)
M_AddonExec(KEY_ENTER); M_AddonExec(KEY_ENTER);
break; break;
case EXT_LUA: case EXT_LUA:
#ifndef HAVE_BLUA
S_StartSound(NULL, sfx_lose);
M_StartMessage(va("%c%s\x80\nThis copy of SRB2 was compiled\nwithout support for .lua files.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), dirmenu[dir_on[menudepthleft]]+DIR_STRING),NULL,MM_NOTHING);
break;
#endif
/* FALLTHRU */
case EXT_SOC: case EXT_SOC:
case EXT_WAD: case EXT_WAD:
#ifdef USE_KART #ifdef USE_KART
@ -6686,6 +6736,7 @@ static void M_PandorasBox(INT32 choice)
else else
CV_StealthSetValue(&cv_dummylives, max(players[consoleplayer].lives, 1)); CV_StealthSetValue(&cv_dummylives, max(players[consoleplayer].lives, 1));
CV_StealthSetValue(&cv_dummycontinues, players[consoleplayer].continues); CV_StealthSetValue(&cv_dummycontinues, players[consoleplayer].continues);
SR_PandorasBox[3].status = (continuesInSession) ? (IT_STRING | IT_CVAR) : (IT_GRAYEDOUT);
SR_PandorasBox[6].status = (players[consoleplayer].charflags & SF_SUPER) ? (IT_GRAYEDOUT) : (IT_STRING | IT_CALL); SR_PandorasBox[6].status = (players[consoleplayer].charflags & SF_SUPER) ? (IT_GRAYEDOUT) : (IT_STRING | IT_CALL);
SR_PandorasBox[7].status = (emeralds == ((EMERALD7)*2)-1) ? (IT_GRAYEDOUT) : (IT_STRING | IT_CALL); SR_PandorasBox[7].status = (emeralds == ((EMERALD7)*2)-1) ? (IT_GRAYEDOUT) : (IT_STRING | IT_CALL);
M_SetupNextMenu(&SR_PandoraDef); M_SetupNextMenu(&SR_PandoraDef);
@ -6702,7 +6753,7 @@ static boolean M_ExitPandorasBox(void)
} }
if (cv_dummylives.value != players[consoleplayer].lives) if (cv_dummylives.value != players[consoleplayer].lives)
COM_ImmedExecute(va("setlives %d", cv_dummylives.value)); COM_ImmedExecute(va("setlives %d", cv_dummylives.value));
if (cv_dummycontinues.value != players[consoleplayer].continues) if (continuesInSession && cv_dummycontinues.value != players[consoleplayer].continues)
COM_ImmedExecute(va("setcontinues %d", cv_dummycontinues.value)); COM_ImmedExecute(va("setcontinues %d", cv_dummycontinues.value));
return true; return true;
} }
@ -7266,6 +7317,7 @@ static void M_EmblemHints(INT32 choice)
SR_EmblemHintMenu[0].status = (local > NUMHINTS*2) ? (IT_STRING | IT_ARROWS) : (IT_DISABLED); SR_EmblemHintMenu[0].status = (local > NUMHINTS*2) ? (IT_STRING | IT_ARROWS) : (IT_DISABLED);
SR_EmblemHintMenu[1].status = (M_SecretUnlocked(SECRET_ITEMFINDER)) ? (IT_CVAR|IT_STRING) : (IT_SECRET); SR_EmblemHintMenu[1].status = (M_SecretUnlocked(SECRET_ITEMFINDER)) ? (IT_CVAR|IT_STRING) : (IT_SECRET);
hintpage = 1; hintpage = 1;
SR_EmblemHintDef.prevMenu = currentMenu;
M_SetupNextMenu(&SR_EmblemHintDef); M_SetupNextMenu(&SR_EmblemHintDef);
itemOn = 2; // always start on back. itemOn = 2; // always start on back.
} }
@ -7946,12 +7998,20 @@ static void M_CustomLevelSelect(INT32 choice)
static void M_SinglePlayerMenu(INT32 choice) static void M_SinglePlayerMenu(INT32 choice)
{ {
(void)choice; (void)choice;
SP_MainMenu[sptutorial].status =
tutorialmap ? IT_CALL|IT_STRING : IT_NOTHING|IT_DISABLED; levellistmode = LLM_RECORDATTACK;
SP_MainMenu[sprecordattack].status = if (M_GametypeHasLevels(-1))
(M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING : IT_SECRET; SP_MainMenu[sprecordattack].status = (M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING : IT_SECRET;
SP_MainMenu[spnightsmode].status = else
(M_SecretUnlocked(SECRET_NIGHTSMODE)) ? IT_CALL|IT_STRING : IT_SECRET; SP_MainMenu[sprecordattack].status = IT_NOTHING|IT_DISABLED;
levellistmode = LLM_NIGHTSATTACK;
if (M_GametypeHasLevels(-1))
SP_MainMenu[spnightsmode].status = (M_SecretUnlocked(SECRET_NIGHTSMODE)) ? IT_CALL|IT_STRING : IT_SECRET;
else
SP_MainMenu[spnightsmode].status = IT_NOTHING|IT_DISABLED;
SP_MainMenu[sptutorial].status = tutorialmap ? IT_CALL|IT_STRING : IT_NOTHING|IT_DISABLED;
M_SetupNextMenu(&SP_MainDef); M_SetupNextMenu(&SP_MainDef);
} }
@ -8213,9 +8273,19 @@ static void M_DrawLoadGameData(void)
V_DrawRightAlignedThinString(x + 79, y, V_YELLOWMAP, savegameinfo[savetodraw].levelname); V_DrawRightAlignedThinString(x + 79, y, V_YELLOWMAP, savegameinfo[savetodraw].levelname);
} }
if ((savegameinfo[savetodraw].lives == -42) if (savegameinfo[savetodraw].lives == -42)
|| (savegameinfo[savetodraw].lives == -666)) {
if (!useContinues)
V_DrawRightAlignedThinString(x + 80, y+1+60+16, V_GRAYMAP, "00000000");
continue; continue;
}
if (savegameinfo[savetodraw].lives == -666)
{
if (!useContinues)
V_DrawRightAlignedThinString(x + 80, y+1+60+16, V_REDMAP, "????????");
continue;
}
y += 64; y += 64;
@ -8232,7 +8302,7 @@ static void M_DrawLoadGameData(void)
y -= 4; y -= 4;
// character heads, lives, and continues // character heads, lives, and continues/score
{ {
spritedef_t *sprdef; spritedef_t *sprdef;
spriteframe_t *sprframe; spriteframe_t *sprframe;
@ -8283,10 +8353,14 @@ skipbot:
skipsign: skipsign:
y += 16; y += 16;
tempx = x + 10; tempx = x;
if (savegameinfo[savetodraw].lives != INFLIVES if (useContinues)
&& savegameinfo[savetodraw].lives > 9) {
tempx -= 4; tempx += 10;
if (savegameinfo[savetodraw].lives != INFLIVES
&& savegameinfo[savetodraw].lives > 9)
tempx -= 4;
}
if (!charskin) // shut up compiler if (!charskin) // shut up compiler
goto skiplife; goto skiplife;
@ -8316,22 +8390,45 @@ skiplife:
else else
V_DrawString(tempx, y, 0, va("%d", savegameinfo[savetodraw].lives)); V_DrawString(tempx, y, 0, va("%d", savegameinfo[savetodraw].lives));
tempx = x + 47; if (!useContinues)
if (savegameinfo[savetodraw].continues > 9)
tempx -= 4;
// continues
if (savegameinfo[savetodraw].continues > 0)
{ {
V_DrawSmallScaledPatch(tempx, y, 0, W_CachePatchName("CONTSAVE", PU_PATCH)); INT32 workingscorenum = savegameinfo[savetodraw].continuescore;
V_DrawScaledPatch(tempx + 9, y + 2, 0, patch); char workingscorestr[11] = " 000000000\0";
V_DrawString(tempx + 16, y, 0, va("%d", savegameinfo[savetodraw].continues)); SINT8 j = 9;
// Change the above two lines if MAXSCORE ever changes from 8 digits long.
workingscorestr[0] = '\x86'; // done here instead of in initialiser 'cuz compiler complains
if (!workingscorenum)
j--; // just so ONE digit is not greyed out
else
{
while (workingscorenum)
{
workingscorestr[j--] = '0' + (workingscorenum % 10);
workingscorenum /= 10;
}
}
workingscorestr[j] = (savegameinfo[savetodraw].continuescore == MAXSCORE) ? '\x83' : '\x80';
V_DrawRightAlignedThinString(x + 80, y+1, 0, workingscorestr);
} }
else else
{ {
V_DrawSmallScaledPatch(tempx, y, 0, W_CachePatchName("CONTNONE", PU_PATCH)); tempx = x + 47;
V_DrawScaledPatch(tempx + 9, y + 2, 0, W_CachePatchName("STNONEX", PU_PATCH)); if (savegameinfo[savetodraw].continuescore > 9)
V_DrawString(tempx + 16, y, V_GRAYMAP, "0"); tempx -= 4;
// continues
if (savegameinfo[savetodraw].continuescore > 0)
{
V_DrawSmallScaledPatch(tempx, y, 0, W_CachePatchName("CONTSAVE", PU_PATCH));
V_DrawScaledPatch(tempx + 9, y + 2, 0, patch);
V_DrawString(tempx + 16, y, 0, va("%d", savegameinfo[savetodraw].continuescore));
}
else
{
V_DrawSmallScaledPatch(tempx, y, 0, W_CachePatchName("CONTNONE", PU_PATCH));
V_DrawScaledPatch(tempx + 9, y + 2, 0, W_CachePatchName("STNONEX", PU_PATCH));
V_DrawString(tempx + 16, y, V_GRAYMAP, "0");
}
} }
} }
} }
@ -8464,9 +8561,11 @@ static void M_ReadSavegameInfo(UINT32 slot)
CHECKPOS CHECKPOS
savegameinfo[slot].lives = READSINT8(save_p); // lives savegameinfo[slot].lives = READSINT8(save_p); // lives
CHECKPOS CHECKPOS
(void)READINT32(save_p); // Score savegameinfo[slot].continuescore = READINT32(save_p); // score
CHECKPOS CHECKPOS
savegameinfo[slot].continues = READINT32(save_p); // continues fake = READINT32(save_p); // continues
if (useContinues)
savegameinfo[slot].continuescore = fake;
// File end marker check // File end marker check
CHECKPOS CHECKPOS
@ -8848,16 +8947,11 @@ static void M_SetupChoosePlayer(INT32 choice)
/* the menus suck -James */ /* the menus suck -James */
if (currentMenu == &SP_LoadDef)/* from save states */ if (currentMenu == &SP_LoadDef)/* from save states */
{ {
SP_PlayerDef.menuid = SP_PlayerDef.menuid = MTREE3(MN_SP_MAIN, MN_SP_LOAD, MN_SP_PLAYER);
MN_SP_MAIN +
( MN_SP_LOAD << 6 ) +
( MN_SP_PLAYER << 12 );
} }
else/* from Secret level select */ else/* from Secret level select */
{ {
SP_PlayerDef.menuid = SP_PlayerDef.menuid = MTREE2(MN_SR_MAIN, MN_SR_PLAYER);
MN_SR_MAIN +
( MN_SR_PLAYER << 6 );
} }
SP_PlayerDef.prevMenu = currentMenu; SP_PlayerDef.prevMenu = currentMenu;
@ -9003,7 +9097,7 @@ static void M_DrawSetupChoosePlayerMenu(void)
col = skincolors[charskin->prefcolor].invcolor; col = skincolors[charskin->prefcolor].invcolor;
// Make the translation colormap // Make the translation colormap
colormap = R_GetTranslationColormap(TC_DEFAULT, col, 0); colormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_CACHE);
// Don't render the title map // Don't render the title map
hidetitlemap = true; hidetitlemap = true;
@ -9079,8 +9173,8 @@ static void M_DrawSetupChoosePlayerMenu(void)
{ {
V_DrawNameTag( V_DrawNameTag(
x, y, V_CENTERNAMETAG, FRACUNIT, x, y, V_CENTERNAMETAG, FRACUNIT,
R_GetTranslationColormap(TC_DEFAULT, curtextcolor, 0), R_GetTranslationColormap(TC_DEFAULT, curtextcolor, GTC_CACHE),
R_GetTranslationColormap(TC_DEFAULT, curoutlinecolor, 0), R_GetTranslationColormap(TC_DEFAULT, curoutlinecolor, GTC_CACHE),
curtext curtext
); );
} }
@ -9112,8 +9206,8 @@ static void M_DrawSetupChoosePlayerMenu(void)
{ {
V_DrawNameTag( V_DrawNameTag(
x, y, V_CENTERNAMETAG, FRACUNIT, x, y, V_CENTERNAMETAG, FRACUNIT,
R_GetTranslationColormap(TC_DEFAULT, prevtextcolor, 0), R_GetTranslationColormap(TC_DEFAULT, prevtextcolor, GTC_CACHE),
R_GetTranslationColormap(TC_DEFAULT, prevoutlinecolor, 0), R_GetTranslationColormap(TC_DEFAULT, prevoutlinecolor, GTC_CACHE),
prevtext prevtext
); );
} }
@ -9142,8 +9236,8 @@ static void M_DrawSetupChoosePlayerMenu(void)
{ {
V_DrawNameTag( V_DrawNameTag(
x, y, V_CENTERNAMETAG, FRACUNIT, x, y, V_CENTERNAMETAG, FRACUNIT,
R_GetTranslationColormap(TC_DEFAULT, nexttextcolor, 0), R_GetTranslationColormap(TC_DEFAULT, nexttextcolor, GTC_CACHE),
R_GetTranslationColormap(TC_DEFAULT, nextoutlinecolor, 0), R_GetTranslationColormap(TC_DEFAULT, nextoutlinecolor, GTC_CACHE),
nexttext nexttext
); );
} }
@ -9953,9 +10047,6 @@ static void M_NightsAttack(INT32 choice)
// This is really just to make sure Sonic is the played character, just in case // This is really just to make sure Sonic is the played character, just in case
M_PatchSkinNameTable(); M_PatchSkinNameTable();
ntssupersonic[0] = W_CachePatchName("NTSSONC1", PU_PATCH);
ntssupersonic[1] = W_CachePatchName("NTSSONC2", PU_PATCH);
G_SetGamestate(GS_TIMEATTACK); // do this before M_SetupNextMenu so that menu meta state knows that we're switching G_SetGamestate(GS_TIMEATTACK); // do this before M_SetupNextMenu so that menu meta state knows that we're switching
titlemapinaction = TITLEMAP_OFF; // Nope don't give us HOMs please titlemapinaction = TITLEMAP_OFF; // Nope don't give us HOMs please
M_SetupNextMenu(&SP_NightsAttackDef); M_SetupNextMenu(&SP_NightsAttackDef);
@ -10075,13 +10166,13 @@ static void M_ReplayTimeAttack(INT32 choice)
static void M_EraseGuest(INT32 choice) static void M_EraseGuest(INT32 choice)
{ {
const char *rguest = va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)); const char *rguest = va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value));
(void)choice;
if (FIL_FileExists(rguest)) if (choice == 'y' || choice == KEY_ENTER)
remove(rguest); {
if (currentMenu == &SP_NightsGuestReplayDef) if (FIL_FileExists(rguest))
M_SetupNextMenu(&SP_NightsAttackDef); remove(rguest);
else }
M_SetupNextMenu(&SP_TimeAttackDef); M_SetupNextMenu(currentMenu->prevMenu->prevMenu);
Nextmap_OnChange(); Nextmap_OnChange();
M_StartMessage(M_GetText("Guest replay data erased.\n"),NULL,MM_NOTHING); M_StartMessage(M_GetText("Guest replay data erased.\n"),NULL,MM_NOTHING);
} }
@ -10370,7 +10461,7 @@ static void M_DrawConnectMenu(void)
for (i = 0; i < min(serverlistcount - serverlistpage * SERVERS_PER_PAGE, SERVERS_PER_PAGE); i++) for (i = 0; i < min(serverlistcount - serverlistpage * SERVERS_PER_PAGE, SERVERS_PER_PAGE); i++)
{ {
INT32 slindex = i + serverlistpage * SERVERS_PER_PAGE; INT32 slindex = i + serverlistpage * SERVERS_PER_PAGE;
UINT32 globalflags = ((serverlist[slindex].info.numberofplayer >= serverlist[slindex].info.maxplayer) ? V_TRANSLUCENT : 0) UINT32 globalflags = (serverlist[slindex].info.refusereason ? V_TRANSLUCENT : 0)
|((itemOn == FIRSTSERVERLINE+i) ? V_YELLOWMAP : 0)|V_ALLOWLOWERCASE; |((itemOn == FIRSTSERVERLINE+i) ? V_YELLOWMAP : 0)|V_ALLOWLOWERCASE;
V_DrawString(currentMenu->x, S_LINEY(i), globalflags, serverlist[slindex].info.servername); V_DrawString(currentMenu->x, S_LINEY(i), globalflags, serverlist[slindex].info.servername);
@ -10734,7 +10825,8 @@ static void M_ServerOptions(INT32 choice)
OP_ServerOptionsMenu[ 3].status = IT_GRAYEDOUT; // Allow add-on downloading OP_ServerOptionsMenu[ 3].status = IT_GRAYEDOUT; // Allow add-on downloading
OP_ServerOptionsMenu[ 4].status = IT_GRAYEDOUT; // Allow players to join OP_ServerOptionsMenu[ 4].status = IT_GRAYEDOUT; // Allow players to join
OP_ServerOptionsMenu[35].status = IT_GRAYEDOUT; // Master server OP_ServerOptionsMenu[35].status = IT_GRAYEDOUT; // Master server
OP_ServerOptionsMenu[36].status = IT_GRAYEDOUT; // Attempts to resynchronise OP_ServerOptionsMenu[36].status = IT_GRAYEDOUT; // Minimum delay between joins
OP_ServerOptionsMenu[37].status = IT_GRAYEDOUT; // Attempts to resynchronise
} }
else else
{ {
@ -10746,14 +10838,15 @@ static void M_ServerOptions(INT32 choice)
? IT_GRAYEDOUT ? IT_GRAYEDOUT
: (IT_STRING | IT_CVAR | IT_CV_STRING)); : (IT_STRING | IT_CVAR | IT_CV_STRING));
OP_ServerOptionsMenu[36].status = IT_STRING | IT_CVAR; OP_ServerOptionsMenu[36].status = IT_STRING | IT_CVAR;
OP_ServerOptionsMenu[37].status = IT_STRING | IT_CVAR;
} }
#endif #endif
/* Disable fading because of different menu head. */ /* Disable fading because of different menu head. */
if (currentMenu == &OP_MainDef)/* from Options menu */ if (currentMenu == &OP_MainDef)/* from Options menu */
OP_ServerOptionsDef.menuid = MN_OP_MAIN + ( MN_OP_SERVER << 6 ); OP_ServerOptionsDef.menuid = MTREE2(MN_OP_MAIN, MN_OP_SERVER);
else/* from Multiplayer menu */ else/* from Multiplayer menu */
OP_ServerOptionsDef.menuid = MN_MP_MAIN + ( MN_MP_SERVER_OPTIONS << 6 ); OP_ServerOptionsDef.menuid = MTREE2(MN_MP_MAIN, MN_MP_SERVER_OPTIONS);
OP_ServerOptionsDef.prevMenu = currentMenu; OP_ServerOptionsDef.prevMenu = currentMenu;
M_SetupNextMenu(&OP_ServerOptionsDef); M_SetupNextMenu(&OP_ServerOptionsDef);
@ -11865,8 +11958,8 @@ static void M_Setup1PControlsMenu(INT32 choice)
OP_ChangeControlsMenu[27+3].status = IT_CALL|IT_STRING2; OP_ChangeControlsMenu[27+3].status = IT_CALL|IT_STRING2;
OP_ChangeControlsDef.prevMenu = &OP_P1ControlsDef; OP_ChangeControlsDef.prevMenu = &OP_P1ControlsDef;
OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove first level (<< 6) OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove second level
OP_ChangeControlsDef.menuid |= MN_OP_P1CONTROLS << MENUBITS; // combine first level (<< 6) OP_ChangeControlsDef.menuid |= MN_OP_P1CONTROLS << MENUBITS; // combine second level
M_SetupNextMenu(&OP_ChangeControlsDef); M_SetupNextMenu(&OP_ChangeControlsDef);
} }
@ -11896,8 +11989,8 @@ static void M_Setup2PControlsMenu(INT32 choice)
OP_ChangeControlsMenu[27+3].status = IT_GRAYEDOUT2; OP_ChangeControlsMenu[27+3].status = IT_GRAYEDOUT2;
OP_ChangeControlsDef.prevMenu = &OP_P2ControlsDef; OP_ChangeControlsDef.prevMenu = &OP_P2ControlsDef;
OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove first level (<< 6) OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove second level
OP_ChangeControlsDef.menuid |= MN_OP_P2CONTROLS << MENUBITS; // combine first level (<< 6) OP_ChangeControlsDef.menuid |= MN_OP_P2CONTROLS << MENUBITS; // combine second level
M_SetupNextMenu(&OP_ChangeControlsDef); M_SetupNextMenu(&OP_ChangeControlsDef);
} }
@ -12309,7 +12402,6 @@ static void M_VideoModeMenu(INT32 choice)
static void M_DrawMainVideoMenu(void) static void M_DrawMainVideoMenu(void)
{ {
M_DrawGenericScrollMenu(); M_DrawGenericScrollMenu();
if (itemOn < 8) // where it starts to go offscreen; change this number if you change the layout of the video menu if (itemOn < 8) // where it starts to go offscreen; change this number if you change the layout of the video menu
{ {

View file

@ -15,9 +15,10 @@
#ifndef __X_MENU__ #ifndef __X_MENU__
#define __X_MENU__ #define __X_MENU__
#include "doomstat.h" // for NUMGAMETYPES
#include "d_event.h" #include "d_event.h"
#include "command.h" #include "command.h"
#include "r_things.h" // for SKINNAMESIZE #include "r_skins.h" // for SKINNAMESIZE
#include "f_finale.h" // for ttmode_enum #include "f_finale.h" // for ttmode_enum
// //
@ -30,6 +31,9 @@
#define MENUBITS 6 #define MENUBITS 6
// Menu IDs sectioned by numeric places to signify hierarchy // Menu IDs sectioned by numeric places to signify hierarchy
/**
* IF YOU MODIFY THIS, MODIFY MENUTYPES_LIST[] IN dehacked.c TO MATCH.
*/
typedef enum typedef enum
{ {
MN_NONE, MN_NONE,
@ -128,6 +132,9 @@ typedef enum
MN_SPECIAL, MN_SPECIAL,
NUMMENUTYPES, NUMMENUTYPES,
} menutype_t; // up to 63; MN_SPECIAL = 53 } menutype_t; // up to 63; MN_SPECIAL = 53
#define MTREE2(a,b) (a | (b<<MENUBITS))
#define MTREE3(a,b,c) MTREE2(a, MTREE2(b,c))
#define MTREE4(a,b,c,d) MTREE2(a, MTREE3(b,c,d))
typedef struct typedef struct
{ {
@ -396,7 +403,7 @@ typedef struct
UINT8 numemeralds; UINT8 numemeralds;
UINT8 numgameovers; UINT8 numgameovers;
INT32 lives; INT32 lives;
INT32 continues; INT32 continuescore;
INT32 gamemap; INT32 gamemap;
} saveinfo_t; } saveinfo_t;

View file

@ -68,7 +68,7 @@ extern consvar_t cv_masterserver, cv_servername;
// < 0 to not connect (usually -1) (offline mode) // < 0 to not connect (usually -1) (offline mode)
// == 0 to show all rooms, not a valid hosting room // == 0 to show all rooms, not a valid hosting room
// anything else is whatever room the MS assigns to that number (online mode) // anything else is whatever room the MS assigns to that number (online mode)
INT16 ms_RoomId; extern INT16 ms_RoomId;
const char *GetMasterServerPort(void); const char *GetMasterServerPort(void);
const char *GetMasterServerIP(void); const char *GetMasterServerIP(void);

View file

@ -47,8 +47,7 @@ void T_MoveCeiling(ceiling_t *ceiling)
case 0: // IN STASIS case 0: // IN STASIS
break; break;
case 1: // UP case 1: // UP
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->topheight, false, res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->topheight, false, true, ceiling->direction);
1, ceiling->direction);
if (ceiling->type == bounceCeiling) if (ceiling->type == bounceCeiling)
{ {
@ -159,8 +158,7 @@ void T_MoveCeiling(ceiling_t *ceiling)
break; break;
case -1: // DOWN case -1: // DOWN
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, ceiling->crush, true, ceiling->direction);
ceiling->crush, 1, ceiling->direction);
if (ceiling->type == bounceCeiling) if (ceiling->type == bounceCeiling)
{ {
@ -314,11 +312,10 @@ void T_CrushCeiling(ceiling_t *ceiling)
if (ceiling->type == crushBothOnce) if (ceiling->type == crushBothOnce)
{ {
// Move the floor // Move the floor
T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight-(ceiling->topheight-ceiling->bottomheight), false, 0, -ceiling->direction); T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight-(ceiling->topheight-ceiling->bottomheight), false, false, -ceiling->direction);
} }
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->topheight, res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->topheight, false, true, ceiling->direction);
false, 1, ceiling->direction);
if (res == pastdest) if (res == pastdest)
{ {
@ -357,11 +354,10 @@ void T_CrushCeiling(ceiling_t *ceiling)
if (ceiling->type == crushBothOnce) if (ceiling->type == crushBothOnce)
{ {
// Move the floor // Move the floor
T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, ceiling->crush, 0, -ceiling->direction); T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, ceiling->crush, false, -ceiling->direction);
} }
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, ceiling->crush, true, ceiling->direction);
ceiling->crush, 1, ceiling->direction);
if (res == pastdest) if (res == pastdest)
{ {
@ -399,7 +395,7 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type)
sector_t *sec; sector_t *sec;
ceiling_t *ceiling; ceiling_t *ceiling;
while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) while ((secnum = P_FindSectorFromTag(line->tag,secnum)) >= 0)
{ {
sec = &sectors[secnum]; sec = &sectors[secnum];
@ -619,7 +615,7 @@ INT32 EV_DoCrush(line_t *line, ceiling_e type)
sector_t *sec; sector_t *sec;
ceiling_t *ceiling; ceiling_t *ceiling;
while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) while ((secnum = P_FindSectorFromTag(line->tag,secnum)) >= 0)
{ {
sec = &sectors[secnum]; sec = &sectors[secnum];

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -365,10 +365,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (special->flags & (MF_ENEMY|MF_BOSS) && special->flags2 & MF2_FRET) if (special->flags & (MF_ENEMY|MF_BOSS) && special->flags2 & MF2_FRET)
return; return;
#ifdef HAVE_BLUA
if (LUAh_TouchSpecial(special, toucher) || P_MobjWasRemoved(special)) if (LUAh_TouchSpecial(special, toucher) || P_MobjWasRemoved(special))
return; return;
#endif
// 0 = none, 1 = elemental pierce, 2 = bubble bounce // 0 = none, 1 = elemental pierce, 2 = bubble bounce
elementalpierce = (((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL || (player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) && (player->pflags & PF_SHIELDABILITY) elementalpierce = (((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL || (player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) && (player->pflags & PF_SHIELDABILITY)
@ -635,7 +633,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (ALL7EMERALDS(emeralds)) // Got all 7 if (ALL7EMERALDS(emeralds)) // Got all 7
{ {
if (!(netgame || multiplayer)) if (continuesInSession)
{ {
player->continues += 1; player->continues += 1;
player->gotcontinue = true; player->gotcontinue = true;
@ -645,7 +643,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
S_StartSound(toucher, sfx_chchng); S_StartSound(toucher, sfx_chchng);
} }
else else
{
P_GiveCoopLives(player, 1, true); // if continues are disabled, a life is a reasonable substitute
S_StartSound(toucher, sfx_chchng); S_StartSound(toucher, sfx_chchng);
}
} }
else else
{ {
@ -1919,10 +1920,8 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour
if (!netgame) if (!netgame)
return; // Presumably it's obvious what's happening in splitscreen. return; // Presumably it's obvious what's happening in splitscreen.
#ifdef HAVE_BLUA
if (LUAh_HurtMsg(player, inflictor, source, damagetype)) if (LUAh_HurtMsg(player, inflictor, source, damagetype))
return; return;
#endif
deadtarget = (player->mo->health <= 0); deadtarget = (player->mo->health <= 0);
@ -2395,10 +2394,8 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
target->flags2 &= ~(MF2_SKULLFLY|MF2_NIGHTSPULL); target->flags2 &= ~(MF2_SKULLFLY|MF2_NIGHTSPULL);
target->health = 0; // This makes it easy to check if something's dead elsewhere. target->health = 0; // This makes it easy to check if something's dead elsewhere.
#ifdef HAVE_BLUA
if (LUAh_MobjDeath(target, inflictor, source, damagetype) || P_MobjWasRemoved(target)) if (LUAh_MobjDeath(target, inflictor, source, damagetype) || P_MobjWasRemoved(target))
return; return;
#endif
// Let EVERYONE know what happened to a player! 01-29-2002 Tails // Let EVERYONE know what happened to a player! 01-29-2002 Tails
if (target->player && !target->player->spectator) if (target->player && !target->player->spectator)
@ -3156,7 +3153,7 @@ static boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj_t *sou
return false; return false;
// In COOP/RACE, you can't hurt other players unless cv_friendlyfire is on // In COOP/RACE, you can't hurt other players unless cv_friendlyfire is on
if (!(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE)) && (G_PlatformGametype())) if (!(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE)) && (gametyperules & GTR_FRIENDLY))
{ {
if (gametype == GT_COOP && inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK)) // co-op only if (gametype == GT_COOP && inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK)) // co-op only
{ {
@ -3441,7 +3438,7 @@ void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source)
if (player->powers[pw_invulnerability] || player->powers[pw_flashing] || player->powers[pw_super]) if (player->powers[pw_invulnerability] || player->powers[pw_flashing] || player->powers[pw_super])
return; return;
if (!cv_friendlyfire.value) if (!cv_friendlyfire.value && source && source->player)
{ {
if (inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK)) if (inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK))
{ {
@ -3456,7 +3453,7 @@ void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source)
return; return;
} }
if (inflictor->type == MT_LHRT) if (inflictor && inflictor->type == MT_LHRT)
return; return;
if (player->powers[pw_shield] || player->bot) //If One-Hit Shield if (player->powers[pw_shield] || player->bot) //If One-Hit Shield
@ -3511,11 +3508,7 @@ void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source)
boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype)
{ {
player_t *player; player_t *player;
#ifdef HAVE_BLUA
boolean force = false; boolean force = false;
#else
static const boolean force = false;
#endif
if (objectplacing) if (objectplacing)
return false; return false;
@ -3533,7 +3526,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
return false; return false;
} }
#ifdef HAVE_BLUA
// Everything above here can't be forced. // Everything above here can't be forced.
if (!metalrecording) if (!metalrecording)
{ {
@ -3545,7 +3537,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
else if (shouldForce == 2) else if (shouldForce == 2)
return false; return false;
} }
#endif
if (!force) if (!force)
{ {
@ -3579,10 +3570,8 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (!force && target->flags2 & MF2_FRET) // Currently flashing from being hit if (!force && target->flags2 & MF2_FRET) // Currently flashing from being hit
return false; return false;
#ifdef HAVE_BLUA
if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype) || P_MobjWasRemoved(target)) if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype) || P_MobjWasRemoved(target))
return true; return true;
#endif
if (target->health > 1) if (target->health > 1)
target->flags2 |= MF2_FRET; target->flags2 |= MF2_FRET;
@ -3631,10 +3620,8 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|| (G_GametypeHasTeams() && player->ctfteam == source->player->ctfteam))) || (G_GametypeHasTeams() && player->ctfteam == source->player->ctfteam)))
return false; // Don't run eachother over in special stages and team games and such return false; // Don't run eachother over in special stages and team games and such
} }
#ifdef HAVE_BLUA
if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype)) if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype))
return true; return true;
#endif
P_NiGHTSDamage(target, source); // -5s :( P_NiGHTSDamage(target, source); // -5s :(
return true; return true;
} }
@ -3687,18 +3674,14 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (force if (force
|| (inflictor && inflictor->flags & MF_MISSILE && inflictor->flags2 & MF2_SUPERFIRE)) // Super Sonic is stunned! || (inflictor && inflictor->flags & MF_MISSILE && inflictor->flags2 & MF2_SUPERFIRE)) // Super Sonic is stunned!
{ {
#ifdef HAVE_BLUA
if (!LUAh_MobjDamage(target, inflictor, source, damage, damagetype)) if (!LUAh_MobjDamage(target, inflictor, source, damage, damagetype))
#endif
P_SuperDamage(player, inflictor, source, damage); P_SuperDamage(player, inflictor, source, damage);
return true; return true;
} }
return false; return false;
} }
#ifdef HAVE_BLUA
else if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype)) else if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype))
return true; return true;
#endif
else if (player->powers[pw_shield] || (player->bot && !ultimatemode)) //If One-Hit Shield else if (player->powers[pw_shield] || (player->bot && !ultimatemode)) //If One-Hit Shield
{ {
P_ShieldDamage(player, inflictor, source, damage, damagetype); P_ShieldDamage(player, inflictor, source, damage, damagetype);

View file

@ -66,9 +66,7 @@ typedef enum
THINK_POLYOBJ, THINK_POLYOBJ,
THINK_MAIN, THINK_MAIN,
THINK_MOBJ, THINK_MOBJ,
#ifdef ESLOPE
THINK_DYNSLOPE, THINK_DYNSLOPE,
#endif
THINK_PRECIP, THINK_PRECIP,
NUM_THINKERLISTS NUM_THINKERLISTS
} thinklistnum_t; /**< Thinker lists. */ } thinklistnum_t; /**< Thinker lists. */
@ -250,7 +248,7 @@ extern jingle_t jingleinfo[NUMJINGLES];
#define JINGLEPOSTFADE 1000 #define JINGLEPOSTFADE 1000
void P_PlayJingle(player_t *player, jingletype_t jingletype); void P_PlayJingle(player_t *player, jingletype_t jingletype);
boolean P_EvaluateMusicStatus(UINT16 status); boolean P_EvaluateMusicStatus(UINT16 status, const char *musname);
void P_PlayJingleMusic(player_t *player, const char *musname, UINT16 musflags, boolean looping, UINT16 status); void P_PlayJingleMusic(player_t *player, const char *musname, UINT16 musflags, boolean looping, UINT16 status);
// //
@ -383,9 +381,7 @@ extern mobj_t *tmfloorthing, *tmhitthing, *tmthing;
extern camera_t *mapcampointer; extern camera_t *mapcampointer;
extern fixed_t tmx; extern fixed_t tmx;
extern fixed_t tmy; extern fixed_t tmy;
#ifdef ESLOPE
extern pslope_t *tmfloorslope, *tmceilingslope; extern pslope_t *tmfloorslope, *tmceilingslope;
#endif
/* cphipps 2004/08/30 */ /* cphipps 2004/08/30 */
extern void P_MapStart(void); extern void P_MapStart(void);

View file

@ -27,9 +27,7 @@
#include "r_splats.h" #include "r_splats.h"
#ifdef ESLOPE
#include "p_slopes.h" #include "p_slopes.h"
#endif
#include "z_zone.h" #include "z_zone.h"
@ -53,9 +51,7 @@ static fixed_t tmdropoffz, tmdrpoffceilz; // drop-off floor/ceiling heights
mobj_t *tmfloorthing; // the thing corresponding to tmfloorz or NULL if tmfloorz is from a sector mobj_t *tmfloorthing; // the thing corresponding to tmfloorz or NULL if tmfloorz is from a sector
mobj_t *tmhitthing; // the solid thing you bumped into (for collisions) mobj_t *tmhitthing; // the solid thing you bumped into (for collisions)
ffloor_t *tmfloorrover, *tmceilingrover; ffloor_t *tmfloorrover, *tmceilingrover;
#ifdef ESLOPE
pslope_t *tmfloorslope, *tmceilingslope; pslope_t *tmfloorslope, *tmceilingslope;
#endif
// keep track of the line that lowers the ceiling, // keep track of the line that lowers the ceiling,
// so missiles don't explode against sky hack walls // so missiles don't explode against sky hack walls
@ -262,9 +258,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
if (!vertispeed && !horizspeed) if (!vertispeed && !horizspeed)
return false; return false;
#ifdef ESLOPE
object->standingslope = NULL; // Okay, now we know it's not going to be relevant - no launching off at silly angles for you. object->standingslope = NULL; // Okay, now we know it's not going to be relevant - no launching off at silly angles for you.
#endif
if (spring->eflags & MFE_VERTICALFLIP) if (spring->eflags & MFE_VERTICALFLIP)
vertispeed *= -1; vertispeed *= -1;
@ -439,9 +433,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
P_SetPlayerMobjState(object, S_PLAY_FALL); P_SetPlayerMobjState(object, S_PLAY_FALL);
} }
#ifdef ESLOPE
object->standingslope = NULL; // And again. object->standingslope = NULL; // And again.
#endif
final = true; final = true;
@ -491,9 +483,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object)
zdist = object->z - spring->z; zdist = object->z - spring->z;
} }
#ifdef ESLOPE
object->standingslope = NULL; // No launching off at silly angles for you. object->standingslope = NULL; // No launching off at silly angles for you.
#endif
switch (spring->type) switch (spring->type)
{ {
@ -756,11 +746,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (tmthing->z + tmthing->height < thing->z) if (tmthing->z + tmthing->height < thing->z)
return true; // underneath return true; // underneath
#ifdef HAVE_BLUA
// REX HAS SEEN YOU // REX HAS SEEN YOU
if (!LUAh_SeenPlayer(tmthing->target->player, thing->player)) if (!LUAh_SeenPlayer(tmthing->target->player, thing->player))
return false; return false;
#endif
seenplayer = thing->player; seenplayer = thing->player;
return false; return false;
@ -948,7 +936,6 @@ static boolean PIT_CheckThing(mobj_t *thing)
return true; // the line doesn't cross between either pair of opposite corners return true; // the line doesn't cross between either pair of opposite corners
} }
#ifdef HAVE_BLUA
{ {
UINT8 shouldCollide = LUAh_MobjCollide(thing, tmthing); // checks hook for thing's type UINT8 shouldCollide = LUAh_MobjCollide(thing, tmthing); // checks hook for thing's type
if (P_MobjWasRemoved(tmthing) || P_MobjWasRemoved(thing)) if (P_MobjWasRemoved(tmthing) || P_MobjWasRemoved(thing))
@ -957,9 +944,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
return false; // force collide return false; // force collide
else if (shouldCollide == 2) else if (shouldCollide == 2)
return true; // force no collide return true; // force no collide
}
{ shouldCollide = LUAh_MobjMoveCollide(tmthing, thing); // checks hook for tmthing's type
UINT8 shouldCollide = LUAh_MobjMoveCollide(tmthing, thing); // checks hook for tmthing's type
if (P_MobjWasRemoved(tmthing) || P_MobjWasRemoved(thing)) if (P_MobjWasRemoved(tmthing) || P_MobjWasRemoved(thing))
return true; // one of them was removed??? return true; // one of them was removed???
if (shouldCollide == 1) if (shouldCollide == 1)
@ -967,7 +953,6 @@ static boolean PIT_CheckThing(mobj_t *thing)
else if (shouldCollide == 2) else if (shouldCollide == 2)
return true; // force no collide return true; // force no collide
} }
#endif
if (tmthing->type == MT_LAVAFALL_LAVA && (thing->type == MT_RING || thing->type == MT_REDTEAMRING || thing->type == MT_BLUETEAMRING || thing->type == MT_FLINGRING)) if (tmthing->type == MT_LAVAFALL_LAVA && (thing->type == MT_RING || thing->type == MT_REDTEAMRING || thing->type == MT_BLUETEAMRING || thing->type == MT_FLINGRING))
{ {
@ -1741,9 +1726,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
{ {
tmfloorz = thing->z + thing->height; tmfloorz = thing->z + thing->height;
tmfloorrover = NULL; tmfloorrover = NULL;
#ifdef ESLOPE
tmfloorslope = NULL; tmfloorslope = NULL;
#endif
} }
return true; return true;
} }
@ -1762,18 +1745,14 @@ static boolean PIT_CheckThing(mobj_t *thing)
tmfloorz = tmceilingz = topz; // block while in air tmfloorz = tmceilingz = topz; // block while in air
tmceilingrover = NULL; tmceilingrover = NULL;
#ifdef ESLOPE
tmceilingslope = NULL; tmceilingslope = NULL;
#endif
tmfloorthing = thing; // needed for side collision tmfloorthing = thing; // needed for side collision
} }
else if (topz < tmceilingz && tmthing->z <= thing->z+thing->height) else if (topz < tmceilingz && tmthing->z <= thing->z+thing->height)
{ {
tmceilingz = topz; tmceilingz = topz;
tmceilingrover = NULL; tmceilingrover = NULL;
#ifdef ESLOPE
tmceilingslope = NULL; tmceilingslope = NULL;
#endif
tmfloorthing = thing; // thing we may stand on tmfloorthing = thing; // thing we may stand on
} }
} }
@ -1788,9 +1767,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
{ {
tmceilingz = thing->z; tmceilingz = thing->z;
tmceilingrover = NULL; tmceilingrover = NULL;
#ifdef ESLOPE
tmceilingslope = NULL; tmceilingslope = NULL;
#endif
} }
return true; return true;
} }
@ -1809,18 +1786,14 @@ static boolean PIT_CheckThing(mobj_t *thing)
tmfloorz = tmceilingz = topz; // block while in air tmfloorz = tmceilingz = topz; // block while in air
tmfloorrover = NULL; tmfloorrover = NULL;
#ifdef ESLOPE
tmfloorslope = NULL; tmfloorslope = NULL;
#endif
tmfloorthing = thing; // needed for side collision tmfloorthing = thing; // needed for side collision
} }
else if (topz > tmfloorz && tmthing->z+tmthing->height >= thing->z) else if (topz > tmfloorz && tmthing->z+tmthing->height >= thing->z)
{ {
tmfloorz = topz; tmfloorz = topz;
tmfloorrover = NULL; tmfloorrover = NULL;
#ifdef ESLOPE
tmfloorslope = NULL; tmfloorslope = NULL;
#endif
tmfloorthing = thing; // thing we may stand on tmfloorthing = thing; // thing we may stand on
} }
} }
@ -1946,7 +1919,6 @@ static boolean PIT_CheckLine(line_t *ld)
// this line is out of the if so upper and lower textures can be hit by a splat // this line is out of the if so upper and lower textures can be hit by a splat
blockingline = ld; blockingline = ld;
#ifdef HAVE_BLUA
{ {
UINT8 shouldCollide = LUAh_MobjLineCollide(tmthing, blockingline); // checks hook for thing's type UINT8 shouldCollide = LUAh_MobjLineCollide(tmthing, blockingline); // checks hook for thing's type
if (P_MobjWasRemoved(tmthing)) if (P_MobjWasRemoved(tmthing))
@ -1956,7 +1928,6 @@ static boolean PIT_CheckLine(line_t *ld)
else if (shouldCollide == 2) else if (shouldCollide == 2)
return true; // force no collide return true; // force no collide
} }
#endif
if (!ld->backsector) // one sided line if (!ld->backsector) // one sided line
{ {
@ -1983,18 +1954,14 @@ static boolean PIT_CheckLine(line_t *ld)
tmceilingz = opentop; tmceilingz = opentop;
ceilingline = ld; ceilingline = ld;
tmceilingrover = openceilingrover; tmceilingrover = openceilingrover;
#ifdef ESLOPE
tmceilingslope = opentopslope; tmceilingslope = opentopslope;
#endif
} }
if (openbottom > tmfloorz) if (openbottom > tmfloorz)
{ {
tmfloorz = openbottom; tmfloorz = openbottom;
tmfloorrover = openfloorrover; tmfloorrover = openfloorrover;
#ifdef ESLOPE
tmfloorslope = openbottomslope; tmfloorslope = openbottomslope;
#endif
} }
if (highceiling > tmdrpoffceilz) if (highceiling > tmdrpoffceilz)
@ -2075,10 +2042,8 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
tmceilingz = P_GetCeilingZ(thing, newsubsec->sector, x, y, NULL); //newsubsec->sector->ceilingheight; tmceilingz = P_GetCeilingZ(thing, newsubsec->sector, x, y, NULL); //newsubsec->sector->ceilingheight;
tmfloorrover = NULL; tmfloorrover = NULL;
tmceilingrover = NULL; tmceilingrover = NULL;
#ifdef ESLOPE
tmfloorslope = newsubsec->sector->f_slope; tmfloorslope = newsubsec->sector->f_slope;
tmceilingslope = newsubsec->sector->c_slope; tmceilingslope = newsubsec->sector->c_slope;
#endif
// Check list of fake floors and see if tmfloorz/tmceilingz need to be altered. // Check list of fake floors and see if tmfloorz/tmceilingz need to be altered.
if (newsubsec->sector->ffloors) if (newsubsec->sector->ffloors)
@ -2119,9 +2084,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
if (tmfloorz < topheight - sinklevel) { if (tmfloorz < topheight - sinklevel) {
tmfloorz = topheight - sinklevel; tmfloorz = topheight - sinklevel;
tmfloorrover = rover; tmfloorrover = rover;
#ifdef ESLOPE
tmfloorslope = *rover->t_slope; tmfloorslope = *rover->t_slope;
#endif
} }
} }
else if (thing->eflags & MFE_VERTICALFLIP && thingtop <= bottomheight + sinklevel && thing->momz >= 0) else if (thing->eflags & MFE_VERTICALFLIP && thingtop <= bottomheight + sinklevel && thing->momz >= 0)
@ -2129,9 +2092,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
if (tmceilingz > bottomheight + sinklevel) { if (tmceilingz > bottomheight + sinklevel) {
tmceilingz = bottomheight + sinklevel; tmceilingz = bottomheight + sinklevel;
tmceilingrover = rover; tmceilingrover = rover;
#ifdef ESLOPE
tmceilingslope = *rover->b_slope; tmceilingslope = *rover->b_slope;
#endif
} }
} }
} }
@ -2154,9 +2115,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
if (tmfloorz < thing->z) { if (tmfloorz < thing->z) {
tmfloorz = thing->z; tmfloorz = thing->z;
tmfloorrover = rover; tmfloorrover = rover;
#ifdef ESLOPE
tmfloorslope = NULL; tmfloorslope = NULL;
#endif
} }
} }
// Quicksand blocks never change heights otherwise. // Quicksand blocks never change heights otherwise.
@ -2173,9 +2132,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
{ {
tmfloorz = tmdropoffz = topheight; tmfloorz = tmdropoffz = topheight;
tmfloorrover = rover; tmfloorrover = rover;
#ifdef ESLOPE
tmfloorslope = *rover->t_slope; tmfloorslope = *rover->t_slope;
#endif
} }
if (bottomheight < tmceilingz && abs(delta1) >= abs(delta2) if (bottomheight < tmceilingz && abs(delta1) >= abs(delta2)
&& !(rover->flags & FF_PLATFORM) && !(rover->flags & FF_PLATFORM)
@ -2183,9 +2140,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
{ {
tmceilingz = tmdrpoffceilz = bottomheight; tmceilingz = tmdrpoffceilz = bottomheight;
tmceilingrover = rover; tmceilingrover = rover;
#ifdef ESLOPE
tmceilingslope = *rover->b_slope; tmceilingslope = *rover->b_slope;
#endif
} }
} }
} }
@ -2202,7 +2157,6 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
BMBOUNDFIX(xl, xh, yl, yh); BMBOUNDFIX(xl, xh, yl, yh);
#ifdef POLYOBJECTS
// Check polyobjects and see if tmfloorz/tmceilingz need to be altered // Check polyobjects and see if tmfloorz/tmceilingz need to be altered
{ {
validcount++; validcount++;
@ -2260,17 +2214,13 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
if (polytop > tmfloorz && abs(delta1) < abs(delta2)) { if (polytop > tmfloorz && abs(delta1) < abs(delta2)) {
tmfloorz = tmdropoffz = polytop; tmfloorz = tmdropoffz = polytop;
#ifdef ESLOPE
tmfloorslope = NULL; tmfloorslope = NULL;
#endif
tmfloorrover = NULL; tmfloorrover = NULL;
} }
if (polybottom < tmceilingz && abs(delta1) >= abs(delta2)) { if (polybottom < tmceilingz && abs(delta1) >= abs(delta2)) {
tmceilingz = tmdrpoffceilz = polybottom; tmceilingz = tmdrpoffceilz = polybottom;
#ifdef ESLOPE
tmceilingslope = NULL; tmceilingslope = NULL;
#endif
tmceilingrover = NULL; tmceilingrover = NULL;
} }
} }
@ -2278,7 +2228,6 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
} }
} }
} }
#endif
// tmfloorthing is set when tmfloorz comes from a thing's top // tmfloorthing is set when tmfloorz comes from a thing's top
tmfloorthing = NULL; tmfloorthing = NULL;
@ -2436,7 +2385,6 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
BMBOUNDFIX(xl, xh, yl, yh); BMBOUNDFIX(xl, xh, yl, yh);
#ifdef POLYOBJECTS
// Check polyobjects and see if tmfloorz/tmceilingz need to be altered // Check polyobjects and see if tmfloorz/tmceilingz need to be altered
{ {
validcount++; validcount++;
@ -2507,7 +2455,6 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
} }
} }
} }
#endif
// check lines // check lines
for (bx = xl; bx <= xh; bx++) for (bx = xl; bx <= xh; bx++)
@ -2671,10 +2618,8 @@ boolean PIT_PushableMoved(mobj_t *thing)
line_t *oldblockline = blockingline; line_t *oldblockline = blockingline;
ffloor_t *oldflrrover = tmfloorrover; ffloor_t *oldflrrover = tmfloorrover;
ffloor_t *oldceilrover = tmceilingrover; ffloor_t *oldceilrover = tmceilingrover;
#ifdef ESLOPE
pslope_t *oldfslope = tmfloorslope; pslope_t *oldfslope = tmfloorslope;
pslope_t *oldcslope = tmceilingslope; pslope_t *oldcslope = tmceilingslope;
#endif
// Move the player // Move the player
P_TryMove(thing, thing->x+stand->momx, thing->y+stand->momy, true); P_TryMove(thing, thing->x+stand->momx, thing->y+stand->momy, true);
@ -2689,10 +2634,8 @@ boolean PIT_PushableMoved(mobj_t *thing)
blockingline = oldblockline; blockingline = oldblockline;
tmfloorrover = oldflrrover; tmfloorrover = oldflrrover;
tmceilingrover = oldceilrover; tmceilingrover = oldceilrover;
#ifdef ESLOPE
tmfloorslope = oldfslope; tmfloorslope = oldfslope;
tmceilingslope = oldcslope; tmceilingslope = oldcslope;
#endif
thing->momz = stand->momz; thing->momz = stand->momz;
} }
else else
@ -2714,9 +2657,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
fixed_t tryy = thing->y; fixed_t tryy = thing->y;
fixed_t radius = thing->radius; fixed_t radius = thing->radius;
fixed_t thingtop = thing->z + thing->height; fixed_t thingtop = thing->z + thing->height;
#ifdef ESLOPE
fixed_t startingonground = P_IsObjectOnGround(thing); fixed_t startingonground = P_IsObjectOnGround(thing);
#endif
floatok = false; floatok = false;
if (radius < MAXRADIUS/2) if (radius < MAXRADIUS/2)
@ -2802,14 +2743,12 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
thing->ceilingrover = tmceilingrover; thing->ceilingrover = tmceilingrover;
thing->eflags |= MFE_JUSTSTEPPEDDOWN; thing->eflags |= MFE_JUSTSTEPPEDDOWN;
} }
#ifdef ESLOPE
else if (tmceilingz < thingtop && thingtop - tmceilingz <= maxstep) else if (tmceilingz < thingtop && thingtop - tmceilingz <= maxstep)
{ {
thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height; thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height;
thing->ceilingrover = tmceilingrover; thing->ceilingrover = tmceilingrover;
thing->eflags |= MFE_JUSTSTEPPEDDOWN; thing->eflags |= MFE_JUSTSTEPPEDDOWN;
} }
#endif
} }
else if (thing->z == thing->floorz && tmfloorz < thing->z && thing->z - tmfloorz <= maxstep) else if (thing->z == thing->floorz && tmfloorz < thing->z && thing->z - tmfloorz <= maxstep)
{ {
@ -2817,14 +2756,12 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
thing->floorrover = tmfloorrover; thing->floorrover = tmfloorrover;
thing->eflags |= MFE_JUSTSTEPPEDDOWN; thing->eflags |= MFE_JUSTSTEPPEDDOWN;
} }
#ifdef ESLOPE
else if (tmfloorz > thing->z && tmfloorz - thing->z <= maxstep) else if (tmfloorz > thing->z && tmfloorz - thing->z <= maxstep)
{ {
thing->z = thing->floorz = tmfloorz; thing->z = thing->floorz = tmfloorz;
thing->floorrover = tmfloorrover; thing->floorrover = tmfloorrover;
thing->eflags |= MFE_JUSTSTEPPEDDOWN; thing->eflags |= MFE_JUSTSTEPPEDDOWN;
} }
#endif
} }
if (thing->eflags & MFE_VERTICALFLIP) if (thing->eflags & MFE_VERTICALFLIP)
@ -2888,7 +2825,6 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
thing->floorrover = tmfloorrover; thing->floorrover = tmfloorrover;
thing->ceilingrover = tmceilingrover; thing->ceilingrover = tmceilingrover;
#ifdef ESLOPE
if (!(thing->flags & MF_NOCLIPHEIGHT)) if (!(thing->flags & MF_NOCLIPHEIGHT))
{ {
// Assign thing's standingslope if needed // Assign thing's standingslope if needed
@ -2909,7 +2845,6 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
} }
else // don't set standingslope if you're not going to clip against it else // don't set standingslope if you're not going to clip against it
thing->standingslope = NULL; thing->standingslope = NULL;
#endif
thing->x = x; thing->x = x;
thing->y = y; thing->y = y;
@ -3267,109 +3202,83 @@ isblocking:
static boolean P_IsClimbingValid(player_t *player, angle_t angle) static boolean P_IsClimbingValid(player_t *player, angle_t angle)
{ {
fixed_t platx, platy; fixed_t platx, platy;
subsector_t *glidesector; sector_t *glidesector;
fixed_t floorz, ceilingz; fixed_t floorz, ceilingz;
mobj_t *mo = player->mo;
ffloor_t *rover;
platx = P_ReturnThrustX(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); platx = P_ReturnThrustX(mo, angle, mo->radius + FixedMul(8*FRACUNIT, mo->scale));
platy = P_ReturnThrustY(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); platy = P_ReturnThrustY(mo, angle, mo->radius + FixedMul(8*FRACUNIT, mo->scale));
glidesector = R_PointInSubsector(player->mo->x + platx, player->mo->y + platy); glidesector = R_PointInSubsector(mo->x + platx, mo->y + platy)->sector;
#ifdef ESLOPE floorz = P_GetSectorFloorZAt (glidesector, mo->x, mo->y);
floorz = glidesector->sector->f_slope ? P_GetZAt(glidesector->sector->f_slope, player->mo->x, player->mo->y) : glidesector->sector->floorheight; ceilingz = P_GetSectorCeilingZAt(glidesector, mo->x, mo->y);
ceilingz = glidesector->sector->c_slope ? P_GetZAt(glidesector->sector->c_slope, player->mo->x, player->mo->y) : glidesector->sector->ceilingheight;
#else
floorz = glidesector->sector->floorheight;
ceilingz = glidesector->sector->ceilingheight;
#endif
if (glidesector->sector != player->mo->subsector->sector) if (glidesector != mo->subsector->sector)
{ {
boolean floorclimb = false; boolean floorclimb = false;
fixed_t topheight, bottomheight; fixed_t topheight, bottomheight;
if (glidesector->sector->ffloors) for (rover = glidesector->ffloors; rover; rover = rover->next)
{ {
ffloor_t *rover; if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER))
for (rover = glidesector->sector->ffloors; rover; rover = rover->next) continue;
topheight = P_GetFFloorTopZAt (rover, mo->x, mo->y);
bottomheight = P_GetFFloorBottomZAt(rover, mo->x, mo->y);
floorclimb = true;
if (mo->eflags & MFE_VERTICALFLIP)
{ {
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER)) if ((topheight < mo->z + mo->height) && ((mo->z + mo->height + mo->momz) < topheight))
continue; floorclimb = true;
if (topheight < mo->z) // Waaaay below the ledge.
topheight = *rover->topheight; floorclimb = false;
bottomheight = *rover->bottomheight; if (bottomheight > mo->z + mo->height - FixedMul(16*FRACUNIT,mo->scale))
floorclimb = false;
#ifdef ESLOPE
if (*rover->t_slope)
topheight = P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y);
if (*rover->b_slope)
bottomheight = P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y);
#endif
floorclimb = true;
if (player->mo->eflags & MFE_VERTICALFLIP)
{
if ((topheight < player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) < topheight))
{
floorclimb = true;
}
if (topheight < player->mo->z) // Waaaay below the ledge.
{
floorclimb = false;
}
if (bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale))
{
floorclimb = false;
}
}
else
{
if ((bottomheight > player->mo->z) && ((player->mo->z - player->mo->momz) > bottomheight))
{
floorclimb = true;
}
if (bottomheight > player->mo->z + player->mo->height) // Waaaay below the ledge.
{
floorclimb = false;
}
if (topheight < player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale))
{
floorclimb = false;
}
}
if (floorclimb)
break;
} }
else
{
if ((bottomheight > mo->z) && ((mo->z - mo->momz) > bottomheight))
floorclimb = true;
if (bottomheight > mo->z + mo->height) // Waaaay below the ledge.
floorclimb = false;
if (topheight < mo->z + FixedMul(16*FRACUNIT,mo->scale))
floorclimb = false;
}
if (floorclimb)
break;
} }
if (player->mo->eflags & MFE_VERTICALFLIP) if (mo->eflags & MFE_VERTICALFLIP)
{ {
if ((floorz <= player->mo->z + player->mo->height) if ((floorz <= mo->z + mo->height)
&& ((player->mo->z + player->mo->height - player->mo->momz) <= floorz)) && ((mo->z + mo->height - mo->momz) <= floorz))
floorclimb = true; floorclimb = true;
if ((floorz > player->mo->z) if ((floorz > mo->z)
&& glidesector->sector->floorpic == skyflatnum) && glidesector->floorpic == skyflatnum)
return false; return false;
if ((player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale) > ceilingz) if ((mo->z + mo->height - FixedMul(16*FRACUNIT,mo->scale) > ceilingz)
|| (player->mo->z + player->mo->height <= floorz)) || (mo->z + mo->height <= floorz))
floorclimb = true; floorclimb = true;
} }
else else
{ {
if ((ceilingz >= player->mo->z) if ((ceilingz >= mo->z)
&& ((player->mo->z - player->mo->momz) >= ceilingz)) && ((mo->z - mo->momz) >= ceilingz))
floorclimb = true; floorclimb = true;
if ((ceilingz < player->mo->z+player->mo->height) if ((ceilingz < mo->z+mo->height)
&& glidesector->sector->ceilingpic == skyflatnum) && glidesector->ceilingpic == skyflatnum)
return false; return false;
if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < floorz) if ((mo->z + FixedMul(16*FRACUNIT,mo->scale) < floorz)
|| (player->mo->z >= ceilingz)) || (mo->z >= ceilingz))
floorclimb = true; floorclimb = true;
} }
@ -3457,15 +3366,8 @@ isblocking:
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
continue; continue;
topheight = *rover->topheight; topheight = P_GetFFloorTopZAt (rover, slidemo->x, slidemo->y);
bottomheight = *rover->bottomheight; bottomheight = P_GetFFloorBottomZAt(rover, slidemo->x, slidemo->y);
#ifdef ESLOPE
if (*rover->t_slope)
topheight = P_GetZAt(*rover->t_slope, slidemo->x, slidemo->y);
if (*rover->b_slope)
bottomheight = P_GetZAt(*rover->b_slope, slidemo->x, slidemo->y);
#endif
if (topheight < slidemo->z) if (topheight < slidemo->z)
continue; continue;
@ -3670,11 +3572,7 @@ static void P_CheckLavaWall(mobj_t *mo, sector_t *sec)
if (rover->master->flags & ML_BLOCKMONSTERS) if (rover->master->flags & ML_BLOCKMONSTERS)
continue; continue;
topheight = topheight = P_GetFFloorTopZAt(rover, mo->x, mo->y);
#ifdef ESLOPE
*rover->t_slope ? P_GetZAt(*rover->t_slope, mo->x, mo->y) :
#endif
*rover->topheight;
if (mo->eflags & MFE_VERTICALFLIP) if (mo->eflags & MFE_VERTICALFLIP)
{ {
@ -3687,11 +3585,7 @@ static void P_CheckLavaWall(mobj_t *mo, sector_t *sec)
continue; continue;
} }
bottomheight = bottomheight = P_GetFFloorBottomZAt(rover, mo->x, mo->y);
#ifdef ESLOPE
*rover->b_slope ? P_GetZAt(*rover->b_slope, mo->x, mo->y) :
#endif
*rover->bottomheight;
if (mo->eflags & MFE_VERTICALFLIP) if (mo->eflags & MFE_VERTICALFLIP)
{ {
@ -4277,13 +4171,8 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush)
topheight = *rover->topheight; topheight = *rover->topheight;
bottomheight = *rover->bottomheight; bottomheight = *rover->bottomheight;
//topheight = P_GetFFloorTopZAt (rover, thing->x, thing->y);
/*#ifdef ESLOPE //bottomheight = P_GetFFloorBottomZAt(rover, thing->x, thing->y);
if (rover->t_slope)
topheight = P_GetZAt(rover->t_slope, thing->x, thing->y);
if (rover->b_slope)
bottomheight = P_GetZAt(rover->b_slope, thing->x, thing->y);
#endif*/
delta1 = thing->z - (bottomheight + topheight)/2; delta1 = thing->z - (bottomheight + topheight)/2;
delta2 = thingtop - (bottomheight + topheight)/2; delta2 = thingtop - (bottomheight + topheight)/2;
@ -4299,21 +4188,19 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush)
{ {
//If the thing was crushed by a crumbling FOF, reward the player who made it crumble! //If the thing was crushed by a crumbling FOF, reward the player who made it crumble!
thinker_t *think; thinker_t *think;
elevator_t *crumbler; crumble_t *crumbler;
for (think = thlist[THINK_MAIN].next; think != &thlist[THINK_MAIN]; think = think->next) for (think = thlist[THINK_MAIN].next; think != &thlist[THINK_MAIN]; think = think->next)
{ {
if (think->function.acp1 != (actionf_p1)T_StartCrumble) if (think->function.acp1 != (actionf_p1)T_StartCrumble)
continue; continue;
crumbler = (elevator_t *)think; crumbler = (crumble_t *)think;
if (crumbler->player && crumbler->player->mo if (crumbler->player && crumbler->player->mo
&& crumbler->player->mo != thing && crumbler->player->mo != thing
&& crumbler->actionsector == thing->subsector->sector && crumbler->actionsector == thing->subsector->sector
&& crumbler->sector == rover->master->frontsector && crumbler->sector == rover->master->frontsector)
&& (crumbler->type == elevateBounce
|| crumbler->type == elevateContinuous))
{ {
killer = crumbler->player->mo; killer = crumbler->player->mo;
} }
@ -5062,12 +4949,7 @@ void P_MapEnd(void)
fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
{ {
sector_t *sec = R_PointInSubsector(x, y)->sector; sector_t *sec = R_PointInSubsector(x, y)->sector;
fixed_t floorz = sec->floorheight; fixed_t floorz = P_GetSectorFloorZAt(sec, x, y);
#ifdef ESLOPE
if (sec->f_slope)
floorz = P_GetZAt(sec->f_slope, x, y);
#endif
// Intercept the stupid 'fall through 3dfloors' bug Tails 03-17-2002 // Intercept the stupid 'fall through 3dfloors' bug Tails 03-17-2002
if (sec->ffloors) if (sec->ffloors)
@ -5084,15 +4966,8 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
if ((!(rover->flags & FF_SOLID || rover->flags & FF_QUICKSAND) || (rover->flags & FF_SWIMMABLE))) if ((!(rover->flags & FF_SOLID || rover->flags & FF_QUICKSAND) || (rover->flags & FF_SWIMMABLE)))
continue; continue;
topheight = *rover->topheight; topheight = P_GetFFloorTopZAt (rover, x, y);
bottomheight = *rover->bottomheight; bottomheight = P_GetFFloorBottomZAt(rover, x, y);
#ifdef ESLOPE
if (*rover->t_slope)
topheight = P_GetZAt(*rover->t_slope, x, y);
if (*rover->b_slope)
bottomheight = P_GetZAt(*rover->b_slope, x, y);
#endif
if (rover->flags & FF_QUICKSAND) if (rover->flags & FF_QUICKSAND)
{ {

View file

@ -277,9 +277,7 @@ fixed_t P_InterceptVector(divline_t *v2, divline_t *v1)
// OPTIMIZE: keep this precalculated // OPTIMIZE: keep this precalculated
// //
fixed_t opentop, openbottom, openrange, lowfloor, highceiling; fixed_t opentop, openbottom, openrange, lowfloor, highceiling;
#ifdef ESLOPE
pslope_t *opentopslope, *openbottomslope; pslope_t *opentopslope, *openbottomslope;
#endif
ffloor_t *openfloorrover, *openceilingrover; ffloor_t *openfloorrover, *openceilingrover;
// P_CameraLineOpening // P_CameraLineOpening
@ -305,53 +303,33 @@ void P_CameraLineOpening(line_t *linedef)
// If you can see through it, why not move the camera through it too? // If you can see through it, why not move the camera through it too?
if (front->camsec >= 0) if (front->camsec >= 0)
{ {
frontfloor = sectors[front->camsec].floorheight; // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope)
frontceiling = sectors[front->camsec].ceilingheight; frontfloor = P_GetSectorFloorZAt (&sectors[front->camsec], camera.x, camera.y);
#ifdef ESLOPE frontceiling = P_GetSectorCeilingZAt(&sectors[front->camsec], camera.x, camera.y);
if (sectors[front->camsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope)
frontfloor = P_GetZAt(sectors[front->camsec].f_slope, camera.x, camera.y);
if (sectors[front->camsec].c_slope)
frontceiling = P_GetZAt(sectors[front->camsec].c_slope, camera.x, camera.y);
#endif
} }
else if (front->heightsec >= 0) else if (front->heightsec >= 0)
{ {
frontfloor = sectors[front->heightsec].floorheight; // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope)
frontceiling = sectors[front->heightsec].ceilingheight; frontfloor = P_GetSectorFloorZAt (&sectors[front->heightsec], camera.x, camera.y);
#ifdef ESLOPE frontceiling = P_GetSectorCeilingZAt(&sectors[front->heightsec], camera.x, camera.y);
if (sectors[front->heightsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope)
frontfloor = P_GetZAt(sectors[front->heightsec].f_slope, camera.x, camera.y);
if (sectors[front->heightsec].c_slope)
frontceiling = P_GetZAt(sectors[front->heightsec].c_slope, camera.x, camera.y);
#endif
} }
else else
{ {
frontfloor = P_CameraGetFloorZ(mapcampointer, front, tmx, tmy, linedef); frontfloor = P_CameraGetFloorZ (mapcampointer, front, tmx, tmy, linedef);
frontceiling = P_CameraGetCeilingZ(mapcampointer, front, tmx, tmy, linedef); frontceiling = P_CameraGetCeilingZ(mapcampointer, front, tmx, tmy, linedef);
} }
if (back->camsec >= 0) if (back->camsec >= 0)
{ {
backfloor = sectors[back->camsec].floorheight; // SRB2CBTODO: ESLOPE (sectors[back->heightsec].f_slope)
backceiling = sectors[back->camsec].ceilingheight; backfloor = P_GetSectorFloorZAt (&sectors[back->camsec], camera.x, camera.y);
#ifdef ESLOPE backceiling = P_GetSectorCeilingZAt(&sectors[back->camsec], camera.x, camera.y);
if (sectors[back->camsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope)
frontfloor = P_GetZAt(sectors[back->camsec].f_slope, camera.x, camera.y);
if (sectors[back->camsec].c_slope)
frontceiling = P_GetZAt(sectors[back->camsec].c_slope, camera.x, camera.y);
#endif
} }
else if (back->heightsec >= 0) else if (back->heightsec >= 0)
{ {
backfloor = sectors[back->heightsec].floorheight; // SRB2CBTODO: ESLOPE (sectors[back->heightsec].f_slope)
backceiling = sectors[back->heightsec].ceilingheight; backfloor = P_GetSectorFloorZAt (&sectors[back->heightsec], camera.x, camera.y);
#ifdef ESLOPE backceiling = P_GetSectorCeilingZAt(&sectors[back->heightsec], camera.x, camera.y);
if (sectors[back->heightsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope)
frontfloor = P_GetZAt(sectors[back->heightsec].f_slope, camera.x, camera.y);
if (sectors[back->heightsec].c_slope)
frontceiling = P_GetZAt(sectors[back->heightsec].c_slope, camera.x, camera.y);
#endif
} }
else else
{ {
@ -461,7 +439,6 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
I_Assert(back != NULL); I_Assert(back != NULL);
openfloorrover = openceilingrover = NULL; openfloorrover = openceilingrover = NULL;
#ifdef POLYOBJECTS
if (linedef->polyobj) if (linedef->polyobj)
{ {
// set these defaults so that polyobjects don't interfere with collision above or below them // set these defaults so that polyobjects don't interfere with collision above or below them
@ -469,12 +446,9 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
openbottom = INT32_MIN; openbottom = INT32_MIN;
highceiling = INT32_MIN; highceiling = INT32_MIN;
lowfloor = INT32_MAX; lowfloor = INT32_MAX;
#ifdef ESLOPE
opentopslope = openbottomslope = NULL; opentopslope = openbottomslope = NULL;
#endif
} }
else else
#endif
{ // Set open and high/low values here { // Set open and high/low values here
fixed_t frontheight, backheight; fixed_t frontheight, backheight;
@ -485,17 +459,13 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
{ {
opentop = frontheight; opentop = frontheight;
highceiling = backheight; highceiling = backheight;
#ifdef ESLOPE
opentopslope = front->c_slope; opentopslope = front->c_slope;
#endif
} }
else else
{ {
opentop = backheight; opentop = backheight;
highceiling = frontheight; highceiling = frontheight;
#ifdef ESLOPE
opentopslope = back->c_slope; opentopslope = back->c_slope;
#endif
} }
frontheight = P_GetFloorZ(mobj, front, tmx, tmy, linedef); frontheight = P_GetFloorZ(mobj, front, tmx, tmy, linedef);
@ -505,17 +475,13 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
{ {
openbottom = frontheight; openbottom = frontheight;
lowfloor = backheight; lowfloor = backheight;
#ifdef ESLOPE
openbottomslope = front->f_slope; openbottomslope = front->f_slope;
#endif
} }
else else
{ {
openbottom = backheight; openbottom = backheight;
lowfloor = frontheight; lowfloor = frontheight;
#ifdef ESLOPE
openbottomslope = back->f_slope; openbottomslope = back->f_slope;
#endif
} }
} }
@ -537,7 +503,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
texheight = textures[texnum]->height << FRACBITS; texheight = textures[texnum]->height << FRACBITS;
// Set texbottom and textop to the Z coordinates of the texture's boundaries // Set texbottom and textop to the Z coordinates of the texture's boundaries
#if 0 // #ifdef POLYOBJECTS #if 0
// don't remove this code unless solid midtextures // don't remove this code unless solid midtextures
// on non-solid polyobjects should NEVER happen in the future // on non-solid polyobjects should NEVER happen in the future
if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT)) { if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT)) {
@ -580,7 +546,6 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
} }
} }
} }
#ifdef POLYOBJECTS
if (linedef->polyobj) if (linedef->polyobj)
{ {
// Treat polyobj's backsector like a 3D Floor // Treat polyobj's backsector like a 3D Floor
@ -617,102 +582,95 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
// otherwise don't do anything special, pretend there's nothing else there // otherwise don't do anything special, pretend there's nothing else there
} }
else else
#endif
// Check for fake floors in the sector.
if (front->ffloors || back->ffloors)
{ {
ffloor_t *rover; // Check for fake floors in the sector.
fixed_t delta1, delta2; if (front->ffloors || back->ffloors)
// Check for frontsector's fake floors
for (rover = front->ffloors; rover; rover = rover->next)
{ {
fixed_t topheight, bottomheight; ffloor_t *rover;
if (!(rover->flags & FF_EXISTS)) fixed_t delta1, delta2;
continue;
if (mobj->player && (P_CheckSolidLava(rover) || P_CanRunOnWater(mobj->player, rover))) // Check for frontsector's fake floors
; for (rover = front->ffloors; rover; rover = rover->next)
else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
|| (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
continue;
topheight = P_GetFOFTopZ(mobj, front, rover, tmx, tmy, linedef);
bottomheight = P_GetFOFBottomZ(mobj, front, rover, tmx, tmy, linedef);
delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF
{ {
if (bottomheight < opentop) { fixed_t topheight, bottomheight;
opentop = bottomheight; if (!(rover->flags & FF_EXISTS))
#ifdef ESLOPE continue;
opentopslope = *rover->b_slope;
#endif if (mobj->player && (P_CheckSolidLava(rover) || P_CanRunOnWater(mobj->player, rover)))
openceilingrover = rover; ;
else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
|| (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
continue;
topheight = P_GetFOFTopZ(mobj, front, rover, tmx, tmy, linedef);
bottomheight = P_GetFOFBottomZ(mobj, front, rover, tmx, tmy, linedef);
delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF
{
if (bottomheight < opentop) {
opentop = bottomheight;
opentopslope = *rover->b_slope;
openceilingrover = rover;
}
else if (bottomheight < highceiling)
highceiling = bottomheight;
}
if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF
{
if (topheight > openbottom) {
openbottom = topheight;
openbottomslope = *rover->t_slope;
openfloorrover = rover;
}
else if (topheight > lowfloor)
lowfloor = topheight;
} }
else if (bottomheight < highceiling)
highceiling = bottomheight;
} }
if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF // Check for backsectors fake floors
for (rover = back->ffloors; rover; rover = rover->next)
{ {
if (topheight > openbottom) { fixed_t topheight, bottomheight;
openbottom = topheight; if (!(rover->flags & FF_EXISTS))
#ifdef ESLOPE continue;
openbottomslope = *rover->t_slope;
#endif if (mobj->player && (P_CheckSolidLava(rover) || P_CanRunOnWater(mobj->player, rover)))
openfloorrover = rover; ;
else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
|| (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
continue;
topheight = P_GetFOFTopZ(mobj, back, rover, tmx, tmy, linedef);
bottomheight = P_GetFOFBottomZ(mobj, back, rover, tmx, tmy, linedef);
delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF
{
if (bottomheight < opentop) {
opentop = bottomheight;
opentopslope = *rover->b_slope;
openceilingrover = rover;
}
else if (bottomheight < highceiling)
highceiling = bottomheight;
} }
else if (topheight > lowfloor)
lowfloor = topheight;
}
}
// Check for backsectors fake floors if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF
for (rover = back->ffloors; rover; rover = rover->next) {
{ if (topheight > openbottom) {
fixed_t topheight, bottomheight; openbottom = topheight;
if (!(rover->flags & FF_EXISTS)) openbottomslope = *rover->t_slope;
continue; openfloorrover = rover;
}
if (mobj->player && (P_CheckSolidLava(rover) || P_CanRunOnWater(mobj->player, rover))) else if (topheight > lowfloor)
; lowfloor = topheight;
else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
|| (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
continue;
topheight = P_GetFOFTopZ(mobj, back, rover, tmx, tmy, linedef);
bottomheight = P_GetFOFBottomZ(mobj, back, rover, tmx, tmy, linedef);
delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF
{
if (bottomheight < opentop) {
opentop = bottomheight;
#ifdef ESLOPE
opentopslope = *rover->b_slope;
#endif
openceilingrover = rover;
} }
else if (bottomheight < highceiling)
highceiling = bottomheight;
}
if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF
{
if (topheight > openbottom) {
openbottom = topheight;
#ifdef ESLOPE
openbottomslope = *rover->t_slope;
#endif
openfloorrover = rover;
}
else if (topheight > lowfloor)
lowfloor = topheight;
} }
} }
} }
@ -962,9 +920,7 @@ boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean (*func)(line_t *))
{ {
INT32 offset; INT32 offset;
const INT32 *list; // Big blockmap const INT32 *list; // Big blockmap
#ifdef POLYOBJECTS
polymaplink_t *plink; // haleyjd 02/22/06 polymaplink_t *plink; // haleyjd 02/22/06
#endif
line_t *ld; line_t *ld;
if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight) if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight)
@ -972,7 +928,6 @@ boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean (*func)(line_t *))
offset = y*bmapwidth + x; offset = y*bmapwidth + x;
#ifdef POLYOBJECTS
// haleyjd 02/22/06: consider polyobject lines // haleyjd 02/22/06: consider polyobject lines
plink = polyblocklinks[offset]; plink = polyblocklinks[offset];
@ -996,7 +951,6 @@ boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean (*func)(line_t *))
} }
plink = (polymaplink_t *)(plink->link.next); plink = (polymaplink_t *)(plink->link.next);
} }
#endif
offset = *(blockmap + offset); // offset = blockmap[y*bmapwidth+x]; offset = *(blockmap + offset); // offset = blockmap[y*bmapwidth+x];

View file

@ -55,9 +55,7 @@ void P_CreatePrecipSecNodeList(precipmobj_t *thing, fixed_t x,fixed_t y);
boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y); boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y);
extern fixed_t opentop, openbottom, openrange, lowfloor, highceiling; extern fixed_t opentop, openbottom, openrange, lowfloor, highceiling;
#ifdef ESLOPE
extern pslope_t *opentopslope, *openbottomslope; extern pslope_t *opentopslope, *openbottomslope;
#endif
extern ffloor_t *openfloorrover, *openceilingrover; extern ffloor_t *openfloorrover, *openceilingrover;
void P_LineOpening(line_t *plinedef, mobj_t *mobj); void P_LineOpening(line_t *plinedef, mobj_t *mobj);

File diff suppressed because it is too large Load diff

View file

@ -370,9 +370,7 @@ typedef struct mobj_s
INT32 cusval; INT32 cusval;
INT32 cvmem; INT32 cvmem;
#ifdef ESLOPE
struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?) struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?)
#endif
boolean colorized; // Whether the mobj uses the rainbow colormap boolean colorized; // Whether the mobj uses the rainbow colormap
fixed_t shadowscale; // If this object casts a shadow, and the size relative to radius fixed_t shadowscale; // If this object casts a shadow, and the size relative to radius
@ -453,6 +451,9 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing);
void P_MovePlayerToStarpost(INT32 playernum); void P_MovePlayerToStarpost(INT32 playernum);
void P_AfterPlayerSpawn(INT32 playernum); void P_AfterPlayerSpawn(INT32 playernum);
fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const fixed_t y, const fixed_t offset, const boolean flip);
fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y);
mobj_t *P_SpawnMapThing(mapthing_t *mthing); mobj_t *P_SpawnMapThing(mapthing_t *mthing);
void P_SpawnHoop(mapthing_t *mthing); void P_SpawnHoop(mapthing_t *mthing);
void P_SetBonusTime(mobj_t *mobj); void P_SetBonusTime(mobj_t *mobj);

File diff suppressed because it is too large Load diff

View file

@ -18,8 +18,6 @@
#include "p_mobj.h" #include "p_mobj.h"
#include "r_defs.h" #include "r_defs.h"
// haleyjd: temporary define
#ifdef POLYOBJECTS
// //
// Defines // Defines
// //
@ -31,7 +29,6 @@
#define POLYOBJ_SPAWNCRUSH_DOOMEDNUM 762 // todo: REMOVE #define POLYOBJ_SPAWNCRUSH_DOOMEDNUM 762 // todo: REMOVE
#define POLYOBJ_START_LINE 20 #define POLYOBJ_START_LINE 20
#define POLYOBJ_EXPLICIT_LINE 21
#define POLYINFO_SPECIALNUM 22 #define POLYINFO_SPECIALNUM 22
typedef enum typedef enum
@ -143,26 +140,26 @@ typedef struct polymove_s
UINT32 angle; // angle along which to move UINT32 angle; // angle along which to move
} polymove_t; } polymove_t;
// PolyObject waypoint movement return behavior
typedef enum
{
PWR_STOP, // Stop after reaching last waypoint
PWR_WRAP, // Wrap back to first waypoint
PWR_COMEBACK, // Repeat sequence in reverse
} polywaypointreturn_e;
typedef struct polywaypoint_s typedef struct polywaypoint_s
{ {
thinker_t thinker; // must be first thinker_t thinker; // must be first
INT32 polyObjNum; // numeric id of polyobject INT32 polyObjNum; // numeric id of polyobject
INT32 speed; // resultant velocity INT32 speed; // resultant velocity
INT32 sequence; // waypoint sequence # INT32 sequence; // waypoint sequence #
INT32 pointnum; // waypoint # INT32 pointnum; // waypoint #
INT32 direction; // 1 for normal, -1 for backwards INT32 direction; // 1 for normal, -1 for backwards
UINT8 comeback; // reverses and comes back when the end is reached UINT8 returnbehavior; // behavior after reaching the last waypoint
UINT8 wrap; // Wrap around waypoints UINT8 continuous; // continuously move - used with PWR_WRAP or PWR_COMEBACK
UINT8 continuous; // continuously move - used with COMEBACK or WRAP UINT8 stophere; // Will stop after it reaches the next waypoint
UINT8 stophere; // Will stop after it reaches the next waypoint
// Difference between location of PO and location of waypoint (offset)
fixed_t diffx;
fixed_t diffy;
fixed_t diffz;
mobj_t *target; // next waypoint mobj
} polywaypoint_t; } polywaypoint_t;
typedef struct polyslidedoor_s typedef struct polyslidedoor_s
@ -257,15 +254,19 @@ typedef struct polymovedata_s
UINT8 overRide; // if true, will override any action on the object UINT8 overRide; // if true, will override any action on the object
} polymovedata_t; } polymovedata_t;
typedef enum
{
PWF_REVERSE = 1, // Move through waypoints in reverse order
PWF_LOOP = 1<<1, // Loop movement (used with PWR_WRAP or PWR_COMEBACK)
} polywaypointflags_e;
typedef struct polywaypointdata_s typedef struct polywaypointdata_s
{ {
INT32 polyObjNum; // numeric id of polyobject to affect INT32 polyObjNum; // numeric id of polyobject to affect
INT32 sequence; // waypoint sequence # INT32 sequence; // waypoint sequence #
fixed_t speed; // linear speed fixed_t speed; // linear speed
UINT8 reverse; // if true, will go in reverse waypoint order UINT8 returnbehavior; // behavior after reaching the last waypoint
UINT8 comeback; // reverses and comes back when the end is reached UINT8 flags; // PWF_ flags
UINT8 wrap; // Wrap around waypoints
UINT8 continuous; // continuously move - used with COMEBACK or WRAP
} polywaypointdata_t; } polywaypointdata_t;
// polyobject door types // polyobject door types
@ -301,6 +302,14 @@ typedef struct polyrotdisplacedata_s
UINT8 turnobjs; UINT8 turnobjs;
} polyrotdisplacedata_t; } polyrotdisplacedata_t;
typedef struct polyflagdata_s
{
INT32 polyObjNum;
INT32 speed;
UINT32 angle;
fixed_t momx;
} polyflagdata_t;
typedef struct polyfadedata_s typedef struct polyfadedata_s
{ {
INT32 polyObjNum; INT32 polyObjNum;
@ -322,7 +331,6 @@ boolean P_PointInsidePolyobj(polyobj_t *po, fixed_t x, fixed_t y);
boolean P_MobjTouchingPolyobj(polyobj_t *po, mobj_t *mo); boolean P_MobjTouchingPolyobj(polyobj_t *po, mobj_t *mo);
boolean P_MobjInsidePolyobj(polyobj_t *po, mobj_t *mo); boolean P_MobjInsidePolyobj(polyobj_t *po, mobj_t *mo);
boolean P_BBoxInsidePolyobj(polyobj_t *po, fixed_t *bbox); boolean P_BBoxInsidePolyobj(polyobj_t *po, fixed_t *bbox);
void Polyobj_GetInfo(INT16 poid, INT32 *poflags, INT32 *parentID, INT32 *potrans);
// thinkers (needed in p_saveg.c) // thinkers (needed in p_saveg.c)
void T_PolyObjRotate(polyrotate_t *); void T_PolyObjRotate(polyrotate_t *);
@ -335,14 +343,14 @@ void T_PolyObjRotDisplace (polyrotdisplace_t *);
void T_PolyObjFlag (polymove_t *); void T_PolyObjFlag (polymove_t *);
void T_PolyObjFade (polyfade_t *); void T_PolyObjFade (polyfade_t *);
INT32 EV_DoPolyDoor(polydoordata_t *); boolean EV_DoPolyDoor(polydoordata_t *);
INT32 EV_DoPolyObjMove(polymovedata_t *); boolean EV_DoPolyObjMove(polymovedata_t *);
INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *); boolean EV_DoPolyObjWaypoint(polywaypointdata_t *);
INT32 EV_DoPolyObjRotate(polyrotdata_t *); boolean EV_DoPolyObjRotate(polyrotdata_t *);
INT32 EV_DoPolyObjDisplace(polydisplacedata_t *); boolean EV_DoPolyObjDisplace(polydisplacedata_t *);
INT32 EV_DoPolyObjRotDisplace(polyrotdisplacedata_t *); boolean EV_DoPolyObjRotDisplace(polyrotdisplacedata_t *);
INT32 EV_DoPolyObjFlag(struct line_s *); boolean EV_DoPolyObjFlag(polyflagdata_t *);
INT32 EV_DoPolyObjFade(polyfadedata_t *); boolean EV_DoPolyObjFade(polyfadedata_t *);
// //
@ -353,8 +361,6 @@ extern polyobj_t *PolyObjects;
extern INT32 numPolyObjects; extern INT32 numPolyObjects;
extern polymaplink_t **polyblocklinks; // polyobject blockmap extern polymaplink_t **polyblocklinks; // polyobject blockmap
#endif // ifdef POLYOBJECTS
#endif #endif
// EOF // EOF

Some files were not shown because too many files have changed in this diff Show more