Merge branch 'udmf-next' into 'next'

Merge udmf-next into next

See merge request STJr/SRB2!1075
This commit is contained in:
Nev3r 2020-07-28 14:03:59 -04:00
commit 6dfe236602
34 changed files with 7404 additions and 349 deletions

View File

@ -0,0 +1,77 @@
// Default lump name for new map
defaultlumpname = "MAP01";
//GZDB specific. Don't try to load lumps that don't exist.
basegame = "Doom";
//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

@ -0,0 +1,297 @@
common
{
// Simulate Doom brightness levels (turn this off for linear lighting)
doomlightlevels = true;
// 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;
// These directory names are ignored when loading PK3/PK7/Directory resources
ignoreddirectories = ".svn .git";
// Files with these extensions are ignored when loading PK3/PK7/Directory resources
ignoredextensions = "wad pk3 pk7 bak backup1 backup2 backup3 zip rar 7z";
// Default testing parameters
testparameters = "-file \"%AP\" \"%F\" -warp %L";
testshortpaths = true;
// Action special help
actionspecialhelp = "https://wiki.srb2.org/wiki/Linedef_type_%K";
// Generalized actions
generalizedlinedefs = false;
generalizedsectors = true;
// Maximum safe map size check (0 means skip check)
safeboundary = 1;
// Map boundaries. Map objects can only be placed within these boundaries
leftboundary = -32768;
rightboundary = 32767;
topboundary = 32767;
bottomboundary = -32768;
// Texture loading options
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
formatinterface = "DoomMapSetIO";
// Default nodebuilder configurations
defaultsavecompiler = "zennode_normal";
defaulttestcompiler = "zennode_fast";
/*
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
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";
// Default nodebuilder configurations
defaultsavecompiler = "zdbsp_udmf_normal";
defaulttestcompiler = "zdbsp_udmf_fast";
// Determines the textmap namespace
engine = "srb2";
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
defaultthingflags
{
}
// 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");
}
// GENERALISED SECTOR TYPES
gen_sectortypes
{
include("SRB222_sectors.cfg", "gen_sectortypes");
}
// LINEDEF FLAGS
linedefflags
{
include("SRB222_misc.cfg", "linedefflags_udmf");
}
linedefflagstranslation
{
include("SRB222_misc.cfg", "linedefflagstranslation");
}
// LINEDEF RENDERSTYLES
/*linedefrenderstyles
{
include("SRB222_misc.cfg", "linedefrenderstyles");
}*/
// 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");
}
// How to compare thing flags (for the stuck things error checker)
thingflagscompare
{
include("UDMF_misc.cfg", "thingflagscompare");
}
// LINEDEF TYPES
linedeftypes
{
include("SRB222_linedefs.cfg", "udmf");
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,625 @@
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 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";
nonet = "No Netgame";
effect6 = "Effect 6";
bouncy = "Bouncy Wall";
transfer = "Transfer Line";
}
/*linedefrenderstyles
{
translucent = "Translucent";
fog = "Fog";
}*/
sectorflags
{
colormapfog = "Fog Planes in Colormap";
colormapfadesprites = "Fade Fullbright in Colormap";
colormapprotected = "Protected Colormap";
}
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
{
lightalpha
{
type = 0;
default = 25;
}
fadealpha
{
type = 0;
default = 25;
}
fadestart
{
type = 0;
default = 0;
}
fadeend
{
type = 0;
default = 33;
}
foglighting
{
type = 3;
default = false;
}
}
linedef
{
arg5
{
type = 0;
default = 0;
}
stringarg0
{
type = 2;
default = "";
}
stringarg1
{
type = 2;
default = "";
}
executordelay
{
type = 0;
default = 0;
}
}
sidedef
{
repeatcnt
{
type = 0;
default = 0;
}
}
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";
}
frontback
{
0 = "None";
1 = "Front";
2 = "Back";
}
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;
}
}
}
// 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

@ -0,0 +1,109 @@
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/Spheres 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/Spheres 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

@ -0,0 +1,38 @@
/************************************************************************\
Ultimate Doom 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

@ -0,0 +1,47 @@
/************************************************************************\
Ultimate Doom 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 text 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

@ -8940,7 +8940,6 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_ANGLEMAN", "MT_ANGLEMAN",
"MT_POLYANCHOR", "MT_POLYANCHOR",
"MT_POLYSPAWN", "MT_POLYSPAWN",
"MT_POLYSPAWNCRUSH",
// Skybox objects // Skybox objects
"MT_SKYBOX", "MT_SKYBOX",

View File

@ -23,6 +23,8 @@
// Some global defines, that configure the game. // Some global defines, that configure the game.
#include "doomdef.h" #include "doomdef.h"
#include "m_fixed.h" // See the mapthing_t scale.
// //
// Map level types. // Map level types.
// The following data structures define the persistent format // The following data structures define the persistent format
@ -193,16 +195,24 @@ typedef struct
#pragma pack() #pragma pack()
#endif #endif
#define NUMMAPTHINGARGS 6
#define NUMMAPTHINGSTRINGARGS 2
// Thing definition, position, orientation and type, // Thing definition, position, orientation and type,
// plus visibility flags and attributes. // plus visibility flags and attributes.
typedef struct typedef struct
{ {
INT16 x, y; INT16 x, y;
INT16 angle; INT16 angle, pitch, roll;
UINT16 type; UINT16 type;
UINT16 options; UINT16 options;
INT16 z; INT16 z;
UINT8 extrainfo; UINT8 extrainfo;
fixed_t scale;
INT16 tag;
INT32 args[NUMMAPTHINGARGS];
char *stringargs[NUMMAPTHINGSTRINGARGS];
struct mobj_s *mobj; struct mobj_s *mobj;
} mapthing_t; } mapthing_t;

View File

@ -773,6 +773,7 @@ FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf)
{ {
switch (transtablenum) switch (transtablenum)
{ {
case 0 : pSurf->PolyColor.s.alpha = 0x00;return PF_Masked;
case tr_trans10 : pSurf->PolyColor.s.alpha = 0xe6;return PF_Translucent; case tr_trans10 : pSurf->PolyColor.s.alpha = 0xe6;return PF_Translucent;
case tr_trans20 : pSurf->PolyColor.s.alpha = 0xcc;return PF_Translucent; case tr_trans20 : pSurf->PolyColor.s.alpha = 0xcc;return PF_Translucent;
case tr_trans30 : pSurf->PolyColor.s.alpha = 0xb3;return PF_Translucent; case tr_trans30 : pSurf->PolyColor.s.alpha = 0xb3;return PF_Translucent;
@ -1441,37 +1442,10 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
wallVerts[1].y = FIXED_TO_FLOAT(l); wallVerts[1].y = FIXED_TO_FLOAT(l);
} }
// set alpha for transparent walls (new boom and legacy linedef types) // set alpha for transparent walls
// ooops ! this do not work at all because render order we should render it in backtofront order // ooops ! this do not work at all because render order we should render it in backtofront order
switch (gl_linedef->special) switch (gl_linedef->special)
{ {
case 900:
blendmode = HWR_TranstableToAlpha(tr_trans10, &Surf);
break;
case 901:
blendmode = HWR_TranstableToAlpha(tr_trans20, &Surf);
break;
case 902:
blendmode = HWR_TranstableToAlpha(tr_trans30, &Surf);
break;
case 903:
blendmode = HWR_TranstableToAlpha(tr_trans40, &Surf);
break;
case 904:
blendmode = HWR_TranstableToAlpha(tr_trans50, &Surf);
break;
case 905:
blendmode = HWR_TranstableToAlpha(tr_trans60, &Surf);
break;
case 906:
blendmode = HWR_TranstableToAlpha(tr_trans70, &Surf);
break;
case 907:
blendmode = HWR_TranstableToAlpha(tr_trans80, &Surf);
break;
case 908:
blendmode = HWR_TranstableToAlpha(tr_trans90, &Surf);
break;
// Translucent // Translucent
case 102: case 102:
case 121: case 121:
@ -1492,7 +1466,10 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
blendmode = PF_Translucent; blendmode = PF_Translucent;
break; break;
default: default:
blendmode = PF_Masked; if (gr_linedef->alpha >= 0 && gr_linedef->alpha < FRACUNIT)
blendmode = HWR_TranstableToAlpha(R_GetLinedefTransTable(gr_linedef->alpha), &Surf);
else
blendmode = PF_Masked;
break; break;
} }

View File

@ -20867,33 +20867,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate S_NULL // raisestate
}, },
{ // MT_POLYSPAWNCRUSH
762, // doomednum
S_INVISIBLE, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
3, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
1*FRACUNIT, // radius
1*FRACUNIT, // height
0, // display offset
1000, // mass
8, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_NOCLIP, // flags
S_NULL // raisestate
},
{ // MT_SKYBOX { // MT_SKYBOX
780, // doomednum 780, // doomednum
S_INVISIBLE, // spawnstate S_INVISIBLE, // spawnstate

View File

@ -4774,7 +4774,6 @@ typedef enum mobj_type
MT_ANGLEMAN, MT_ANGLEMAN,
MT_POLYANCHOR, MT_POLYANCHOR,
MT_POLYSPAWN, MT_POLYSPAWN,
MT_POLYSPAWNCRUSH,
// Skybox objects // Skybox objects
MT_SKYBOX, MT_SKYBOX,

View File

@ -176,6 +176,11 @@ static const struct {
{META_SECTORLINES, "sector_t.lines"}, {META_SECTORLINES, "sector_t.lines"},
{META_SIDENUM, "line_t.sidenum"}, {META_SIDENUM, "line_t.sidenum"},
{META_LINEARGS, "line_t.args"},
{META_LINESTRINGARGS, "line_t.stringargs"},
{META_THINGARGS, "mapthing.args"},
{META_THINGSTRINGARGS, "mapthing.stringargs"},
#ifdef HAVE_LUA_SEGS #ifdef HAVE_LUA_SEGS
{META_NODEBBOX, "node_t.bbox"}, {META_NODEBBOX, "node_t.bbox"},
{META_NODECHILDREN, "node_t.children"}, {META_NODECHILDREN, "node_t.children"},

View File

@ -1186,7 +1186,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.str, line->text)) if (strcmp(hookp->s.str, line->stringargs[0]))
continue; continue;
if (lua_gettop(gL) == 1) if (lua_gettop(gL) == 1)

View File

@ -54,6 +54,10 @@ extern lua_State *gL;
#define META_SECTORLINES "SECTOR_T*LINES" #define META_SECTORLINES "SECTOR_T*LINES"
#define META_SIDENUM "LINE_T*SIDENUM" #define META_SIDENUM "LINE_T*SIDENUM"
#define META_LINEARGS "LINE_T*ARGS"
#define META_LINESTRINGARGS "LINE_T*STRINGARGS"
#define META_THINGARGS "MAPTHING_T*ARGS"
#define META_THINGSTRINGARGS "MAPTHING_T*STRINGARGS"
#ifdef HAVE_LUA_SEGS #ifdef HAVE_LUA_SEGS
#define META_NODEBBOX "NODE_T*BBOX" #define META_NODEBBOX "NODE_T*BBOX"
#define META_NODECHILDREN "NODE_T*CHILDREN" #define META_NODECHILDREN "NODE_T*CHILDREN"

View File

@ -85,9 +85,13 @@ enum line_e {
line_flags, line_flags,
line_special, line_special,
line_tag, line_tag,
line_args,
line_stringargs,
line_sidenum, line_sidenum,
line_frontside, line_frontside,
line_backside, line_backside,
line_alpha,
line_executordelay,
line_slopetype, line_slopetype,
line_frontsector, line_frontsector,
line_backsector, line_backsector,
@ -106,9 +110,13 @@ static const char *const line_opt[] = {
"flags", "flags",
"special", "special",
"tag", "tag",
"args",
"stringargs",
"sidenum", "sidenum",
"frontside", "frontside",
"backside", "backside",
"alpha",
"executordelay",
"slopetype", "slopetype",
"frontsector", "frontsector",
"backsector", "backsector",
@ -691,6 +699,42 @@ static int subsector_num(lua_State *L)
// line_t // // line_t //
//////////// ////////////
// args, i -> args[i]
static int lineargs_get(lua_State *L)
{
INT32 *args = *((INT32**)luaL_checkudata(L, 1, META_LINEARGS));
int i = luaL_checkinteger(L, 2);
if (i < 0 || i >= NUMLINEARGS)
return luaL_error(L, LUA_QL("line_t.args") " index cannot be %d", i);
lua_pushinteger(L, args[i]);
return 1;
}
// #args -> NUMLINEARGS
static int lineargs_len(lua_State* L)
{
lua_pushinteger(L, NUMLINEARGS);
return 1;
}
// stringargs, i -> stringargs[i]
static int linestringargs_get(lua_State *L)
{
char **stringargs = *((char***)luaL_checkudata(L, 1, META_LINESTRINGARGS));
int i = luaL_checkinteger(L, 2);
if (i < 0 || i >= NUMLINESTRINGARGS)
return luaL_error(L, LUA_QL("line_t.stringargs") " index cannot be %d", i);
lua_pushstring(L, stringargs[i]);
return 1;
}
// #stringargs -> NUMLINESTRINGARGS
static int linestringargs_len(lua_State *L)
{
lua_pushinteger(L, NUMLINESTRINGARGS);
return 1;
}
static int line_get(lua_State *L) static int line_get(lua_State *L)
{ {
line_t *line = *((line_t **)luaL_checkudata(L, 1, META_LINE)); line_t *line = *((line_t **)luaL_checkudata(L, 1, META_LINE));
@ -731,6 +775,12 @@ static int line_get(lua_State *L)
case line_tag: case line_tag:
lua_pushinteger(L, line->tag); lua_pushinteger(L, line->tag);
return 1; return 1;
case line_args:
LUA_PushUserdata(L, line->args, META_LINEARGS);
return 1;
case line_stringargs:
LUA_PushUserdata(L, line->stringargs, META_LINESTRINGARGS);
return 1;
case line_sidenum: case line_sidenum:
LUA_PushUserdata(L, line->sidenum, META_SIDENUM); LUA_PushUserdata(L, line->sidenum, META_SIDENUM);
return 1; return 1;
@ -742,6 +792,12 @@ static int line_get(lua_State *L)
return 0; return 0;
LUA_PushUserdata(L, &sides[line->sidenum[1]], META_SIDE); LUA_PushUserdata(L, &sides[line->sidenum[1]], META_SIDE);
return 1; return 1;
case line_alpha:
lua_pushfixed(L, line->alpha);
return 1;
case line_executordelay:
lua_pushinteger(L, line->executordelay);
return 1;
case line_slopetype: case line_slopetype:
switch(line->slopetype) switch(line->slopetype)
{ {
@ -2143,6 +2199,22 @@ int LUA_MapLib(lua_State *L)
lua_setfield(L, -2, "__len"); lua_setfield(L, -2, "__len");
lua_pop(L, 1); lua_pop(L, 1);
luaL_newmetatable(L, META_LINEARGS);
lua_pushcfunction(L, lineargs_get);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, lineargs_len);
lua_setfield(L, -2, "__len");
lua_pop(L, 1);
luaL_newmetatable(L, META_LINESTRINGARGS);
lua_pushcfunction(L, linestringargs_get);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, linestringargs_len);
lua_setfield(L, -2, "__len");
lua_pop(L, 1);
luaL_newmetatable(L, META_SIDENUM); luaL_newmetatable(L, META_SIDENUM);
lua_pushcfunction(L, sidenum_get); lua_pushcfunction(L, sidenum_get);
lua_setfield(L, -2, "__index"); lua_setfield(L, -2, "__index");

View File

@ -31,6 +31,8 @@ enum mobj_e {
mobj_snext, mobj_snext,
mobj_sprev, mobj_sprev,
mobj_angle, mobj_angle,
mobj_pitch,
mobj_roll,
mobj_rollangle, mobj_rollangle,
mobj_sprite, mobj_sprite,
mobj_frame, mobj_frame,
@ -98,6 +100,8 @@ static const char *const mobj_opt[] = {
"snext", "snext",
"sprev", "sprev",
"angle", "angle",
"pitch",
"roll",
"rollangle", "rollangle",
"sprite", "sprite",
"frame", "frame",
@ -201,6 +205,12 @@ static int mobj_get(lua_State *L)
case mobj_angle: case mobj_angle:
lua_pushangle(L, mo->angle); lua_pushangle(L, mo->angle);
break; break;
case mobj_pitch:
lua_pushangle(L, mo->pitch);
break;
case mobj_roll:
lua_pushangle(L, mo->roll);
break;
case mobj_rollangle: case mobj_rollangle:
lua_pushangle(L, mo->rollangle); lua_pushangle(L, mo->rollangle);
break; break;
@ -458,6 +468,12 @@ static int mobj_set(lua_State *L)
if (mo->player) if (mo->player)
P_SetPlayerAngle(mo->player, mo->angle); P_SetPlayerAngle(mo->player, mo->angle);
break; break;
case mobj_pitch:
mo->pitch = luaL_checkangle(L, 3);
break;
case mobj_roll:
mo->roll = luaL_checkangle(L, 3);
break;
case mobj_rollangle: case mobj_rollangle:
mo->rollangle = luaL_checkangle(L, 3); mo->rollangle = luaL_checkangle(L, 3);
break; break;
@ -753,6 +769,42 @@ static int mobj_set(lua_State *L)
#undef NOSETPOS #undef NOSETPOS
#undef NOFIELD #undef NOFIELD
// args, i -> args[i]
static int thingargs_get(lua_State *L)
{
INT32 *args = *((INT32**)luaL_checkudata(L, 1, META_THINGARGS));
int i = luaL_checkinteger(L, 2);
if (i < 0 || i >= NUMMAPTHINGARGS)
return luaL_error(L, LUA_QL("mapthing_t.args") " index cannot be %d", i);
lua_pushinteger(L, args[i]);
return 1;
}
// #args -> NUMMAPTHINGARGS
static int thingargs_len(lua_State* L)
{
lua_pushinteger(L, NUMMAPTHINGARGS);
return 1;
}
// stringargs, i -> stringargs[i]
static int thingstringargs_get(lua_State *L)
{
char **stringargs = *((char***)luaL_checkudata(L, 1, META_THINGSTRINGARGS));
int i = luaL_checkinteger(L, 2);
if (i < 0 || i >= NUMMAPTHINGSTRINGARGS)
return luaL_error(L, LUA_QL("mapthing_t.stringargs") " index cannot be %d", i);
lua_pushstring(L, stringargs[i]);
return 1;
}
// #stringargs -> NUMMAPTHINGSTRINGARGS
static int thingstringargs_len(lua_State *L)
{
lua_pushinteger(L, NUMMAPTHINGSTRINGARGS);
return 1;
}
static int mapthing_get(lua_State *L) static int mapthing_get(lua_State *L)
{ {
mapthing_t *mt = *((mapthing_t **)luaL_checkudata(L, 1, META_MAPTHING)); mapthing_t *mt = *((mapthing_t **)luaL_checkudata(L, 1, META_MAPTHING));
@ -778,14 +830,32 @@ static int mapthing_get(lua_State *L)
number = mt->y; number = mt->y;
else if(fastcmp(field,"angle")) else if(fastcmp(field,"angle"))
number = mt->angle; number = mt->angle;
else if(fastcmp(field,"pitch"))
number = mt->pitch;
else if(fastcmp(field,"roll"))
number = mt->roll;
else if(fastcmp(field,"type")) else if(fastcmp(field,"type"))
number = mt->type; number = mt->type;
else if(fastcmp(field,"options")) else if(fastcmp(field,"options"))
number = mt->options; number = mt->options;
else if(fastcmp(field,"scale"))
number = mt->scale;
else if(fastcmp(field,"z")) else if(fastcmp(field,"z"))
number = mt->z; number = mt->z;
else if(fastcmp(field,"extrainfo")) else if(fastcmp(field,"extrainfo"))
number = mt->extrainfo; number = mt->extrainfo;
else if(fastcmp(field,"tag"))
number = mt->tag;
else if(fastcmp(field,"args"))
{
LUA_PushUserdata(L, mt->args, META_THINGARGS);
return 1;
}
else if(fastcmp(field,"stringargs"))
{
LUA_PushUserdata(L, mt->stringargs, META_THINGSTRINGARGS);
return 1;
}
else if(fastcmp(field,"mobj")) { else if(fastcmp(field,"mobj")) {
LUA_PushUserdata(L, mt->mobj, META_MOBJ); LUA_PushUserdata(L, mt->mobj, META_MOBJ);
return 1; return 1;
@ -815,10 +885,16 @@ static int mapthing_set(lua_State *L)
mt->y = (INT16)luaL_checkinteger(L, 3); mt->y = (INT16)luaL_checkinteger(L, 3);
else if(fastcmp(field,"angle")) else if(fastcmp(field,"angle"))
mt->angle = (INT16)luaL_checkinteger(L, 3); mt->angle = (INT16)luaL_checkinteger(L, 3);
else if(fastcmp(field,"pitch"))
mt->pitch = (INT16)luaL_checkinteger(L, 3);
else if(fastcmp(field,"roll"))
mt->roll = (INT16)luaL_checkinteger(L, 3);
else if(fastcmp(field,"type")) else if(fastcmp(field,"type"))
mt->type = (UINT16)luaL_checkinteger(L, 3); mt->type = (UINT16)luaL_checkinteger(L, 3);
else if(fastcmp(field,"options")) else if(fastcmp(field,"options"))
mt->options = (UINT16)luaL_checkinteger(L, 3); mt->options = (UINT16)luaL_checkinteger(L, 3);
else if(fastcmp(field,"scale"))
mt->scale = luaL_checkfixed(L, 3);
else if(fastcmp(field,"z")) else if(fastcmp(field,"z"))
mt->z = (INT16)luaL_checkinteger(L, 3); mt->z = (INT16)luaL_checkinteger(L, 3);
else if(fastcmp(field,"extrainfo")) else if(fastcmp(field,"extrainfo"))
@ -828,6 +904,8 @@ static int mapthing_set(lua_State *L)
return luaL_error(L, "mapthing_t extrainfo set %d out of range (%d - %d)", extrainfo, 0, 15); return luaL_error(L, "mapthing_t extrainfo set %d out of range (%d - %d)", extrainfo, 0, 15);
mt->extrainfo = (UINT8)extrainfo; mt->extrainfo = (UINT8)extrainfo;
} }
else if (fastcmp(field,"tag"))
mt->tag = (INT16)luaL_checkinteger(L, 3);
else if(fastcmp(field,"mobj")) else if(fastcmp(field,"mobj"))
mt->mobj = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); mt->mobj = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
else else
@ -903,6 +981,22 @@ int LUA_MobjLib(lua_State *L)
lua_setfield(L, -2, "__newindex"); lua_setfield(L, -2, "__newindex");
lua_pop(L,1); lua_pop(L,1);
luaL_newmetatable(L, META_THINGARGS);
lua_pushcfunction(L, thingargs_get);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, thingargs_len);
lua_setfield(L, -2, "__len");
lua_pop(L, 1);
luaL_newmetatable(L, META_THINGSTRINGARGS);
lua_pushcfunction(L, thingstringargs_get);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, thingstringargs_len);
lua_setfield(L, -2, "__len");
lua_pop(L, 1);
luaL_newmetatable(L, META_MAPTHING); luaL_newmetatable(L, META_MAPTHING);
lua_pushcfunction(L, mapthing_get); lua_pushcfunction(L, mapthing_get);
lua_setfield(L, -2, "__index"); lua_setfield(L, -2, "__index");

View File

@ -136,6 +136,9 @@ int LUA_PushGlobals(lua_State *L, const char *word)
if (fastcmp(word,"gamemap")) { if (fastcmp(word,"gamemap")) {
lua_pushinteger(L, gamemap); lua_pushinteger(L, gamemap);
return 1; return 1;
} else if (fastcmp(word,"udmf")) {
lua_pushboolean(L, udmf);
return 1;
} else if (fastcmp(word,"maptol")) { } else if (fastcmp(word,"maptol")) {
lua_pushinteger(L, maptol); lua_pushinteger(L, maptol);
return 1; return 1;

View File

@ -2882,8 +2882,7 @@ static boolean P_PlayerPolyObjectZMovement(mobj_t *mo)
continue; continue;
// We're landing on a PO, so check for a linedef executor. // We're landing on a PO, so check for a linedef executor.
// Trigger tags are 32000 + the PO's ID number. P_LinedefExecute(po->triggertag, mo, NULL);
P_LinedefExecute((INT16)(32000 + po->id), mo, NULL);
} }
} }
} }
@ -11615,7 +11614,7 @@ void P_MovePlayerToStarpost(INT32 playernum)
mapthing_t *huntemeralds[MAXHUNTEMERALDS]; mapthing_t *huntemeralds[MAXHUNTEMERALDS];
INT32 numhuntemeralds; INT32 numhuntemeralds;
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_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const fixed_t y, const fixed_t offset, const boolean flip, const fixed_t scale)
{ {
const subsector_t *ss = R_PointInSubsector(x, y); const subsector_t *ss = R_PointInSubsector(x, y);
@ -11625,9 +11624,9 @@ fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const f
// Establish height. // Establish height.
if (flip) if (flip)
return P_GetSectorCeilingZAt(ss->sector, x, y) - offset - mobjinfo[mobjtype].height; return P_GetSectorCeilingZAt(ss->sector, x, y) - FixedMul(scale, offset + mobjinfo[mobjtype].height);
else else
return P_GetSectorFloorZAt(ss->sector, x, y) + offset; return P_GetSectorFloorZAt(ss->sector, x, y) + FixedMul(scale, offset);
} }
fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y) fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y)
@ -11699,7 +11698,7 @@ fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mt
return ONFLOORZ; return ONFLOORZ;
} }
return P_GetMobjSpawnHeight(mobjtype, x, y, offset, flip); return P_GetMobjSpawnHeight(mobjtype, x, y, offset, flip, mthing->scale);
} }
static boolean P_SpawnNonMobjMapThing(mapthing_t *mthing) static boolean P_SpawnNonMobjMapThing(mapthing_t *mthing)
@ -12583,10 +12582,16 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
break; break;
} }
case MT_SKYBOX: case MT_SKYBOX:
if (mthing->tag < 0 || mthing->tag > 15)
{
CONS_Debug(DBG_GAMELOGIC, "P_SetupSpawnedMapThing: Skybox ID %d of mapthing %s is not between 0 and 15!\n", mthing->tag, sizeu1((size_t)(mthing - mapthings)));
break;
}
if (mthing->options & MTF_OBJECTSPECIAL) if (mthing->options & MTF_OBJECTSPECIAL)
skyboxcenterpnts[mthing->extrainfo] = mobj; skyboxcenterpnts[mthing->tag] = mobj;
else else
skyboxviewpnts[mthing->extrainfo] = mobj; skyboxviewpnts[mthing->tag] = mobj;
break; break;
case MT_EGGSTATUE: case MT_EGGSTATUE:
if (mthing->options & MTF_EXTRA) if (mthing->options & MTF_EXTRA)
@ -13074,12 +13079,18 @@ static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y,
mobj = P_SpawnMobj(x, y, z, i); mobj = P_SpawnMobj(x, y, z, i);
mobj->spawnpoint = mthing; mobj->spawnpoint = mthing;
P_SetScale(mobj, mthing->scale);
mobj->destscale = mthing->scale;
if (!P_SetupSpawnedMapThing(mthing, mobj, &doangle)) if (!P_SetupSpawnedMapThing(mthing, mobj, &doangle))
return mobj; return mobj;
if (doangle) if (doangle)
mobj->angle = FixedAngle(mthing->angle << FRACBITS); mobj->angle = FixedAngle(mthing->angle << FRACBITS);
mobj->pitch = FixedAngle(mthing->pitch << FRACBITS);
mobj->roll = FixedAngle(mthing->roll << FRACBITS);
mthing->mobj = mobj; mthing->mobj = mobj;
// ignore MTF_ flags and return early // ignore MTF_ flags and return early
@ -13176,7 +13187,7 @@ static void P_SpawnHoopInternal(mapthing_t *mthing, INT32 hoopsize, fixed_t size
TVector v, *res; TVector v, *res;
fixed_t x = mthing->x << FRACBITS; fixed_t x = mthing->x << FRACBITS;
fixed_t y = mthing->y << FRACBITS; fixed_t y = mthing->y << FRACBITS;
fixed_t z = P_GetMobjSpawnHeight(MT_HOOP, x, y, mthing->z << FRACBITS, false); fixed_t z = P_GetMobjSpawnHeight(MT_HOOP, x, y, mthing->z << FRACBITS, false, mthing->scale);
hoopcenter = P_SpawnMobj(x, y, z, MT_HOOPCENTER); hoopcenter = P_SpawnMobj(x, y, z, MT_HOOPCENTER);
hoopcenter->spawnpoint = mthing; hoopcenter->spawnpoint = mthing;
@ -13321,7 +13332,7 @@ static void P_SpawnItemRow(mapthing_t *mthing, mobjtype_t* itemtypes, UINT8 numi
itemtypes[r] = P_GetMobjtypeSubstitute(&dummything, itemtypes[r]); itemtypes[r] = P_GetMobjtypeSubstitute(&dummything, itemtypes[r]);
} }
} }
z = P_GetMobjSpawnHeight(itemtypes[0], x, y, z, mthing->options & MTF_OBJECTFLIP); z = P_GetMobjSpawnHeight(itemtypes[0], x, y, z, mthing->options & MTF_OBJECTFLIP, mthing->scale);
for (r = 0; r < numitems; r++) for (r = 0; r < numitems; r++)
{ {
@ -13379,7 +13390,7 @@ static void P_SpawnItemCircle(mapthing_t *mthing, mobjtype_t *itemtypes, UINT8 n
itemtypes[i] = P_GetMobjtypeSubstitute(&dummything, itemtypes[i]); itemtypes[i] = P_GetMobjtypeSubstitute(&dummything, itemtypes[i]);
} }
} }
z = P_GetMobjSpawnHeight(itemtypes[0], x, y, z, false); z = P_GetMobjSpawnHeight(itemtypes[0], x, y, z, false, mthing->scale);
for (i = 0; i < numitems; i++) for (i = 0; i < numitems; i++)
{ {

View File

@ -278,7 +278,7 @@ typedef struct mobj_s
struct mobj_s **sprev; // killough 8/11/98: change to ptr-to-ptr struct mobj_s **sprev; // killough 8/11/98: change to ptr-to-ptr
// More drawing info: to determine current sprite. // More drawing info: to determine current sprite.
angle_t angle; // orientation angle_t angle, pitch, roll; // orientation
angle_t rollangle; angle_t rollangle;
spritenum_t sprite; // used to find patch_t and flip value spritenum_t sprite; // used to find patch_t and flip value
UINT32 frame; // frame number, plus bits see p_pspr.h UINT32 frame; // frame number, plus bits see p_pspr.h
@ -399,7 +399,7 @@ typedef struct precipmobj_s
struct precipmobj_s **sprev; // killough 8/11/98: change to ptr-to-ptr struct precipmobj_s **sprev; // killough 8/11/98: change to ptr-to-ptr
// More drawing info: to determine current sprite. // More drawing info: to determine current sprite.
angle_t angle; // orientation angle_t angle, pitch, roll; // orientation
angle_t rollangle; angle_t rollangle;
spritenum_t sprite; // used to find patch_t and flip value spritenum_t sprite; // used to find patch_t and flip value
UINT32 frame; // frame number, plus bits see p_pspr.h UINT32 frame; // frame number, plus bits see p_pspr.h
@ -452,7 +452,7 @@ 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_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const fixed_t y, const fixed_t offset, const boolean flip, const fixed_t scale);
fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y); 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);

View File

@ -204,47 +204,44 @@ boolean P_BBoxInsidePolyobj(polyobj_t *po, fixed_t *bbox)
return true; return true;
} }
// Finds the 'polyobject settings' linedef for a polyobject // Gets the polyobject's settings from its first line
// the polyobject's id should be set as its tag // args[0] of the first line should be the polyobject's id
static void Polyobj_GetInfo(polyobj_t *po) static void Polyobj_GetInfo(polyobj_t *po, line_t *line)
{ {
INT32 i = P_FindSpecialLineFromTag(POLYINFO_SPECIALNUM, po->id, -1); po->parent = line->args[1];
po->flags = POF_SOLID|POF_TESTHEIGHT|POF_RENDERSIDES;
if (i == -1)
return; // no extra settings to apply, let's leave it
po->parent = lines[i].frontsector->special;
if (po->parent == po->id) // do not allow a self-reference if (po->parent == po->id) // do not allow a self-reference
po->parent = -1; po->parent = -1;
po->translucency = (lines[i].flags & ML_DONTPEGTOP) po->translucency = max(min(line->args[2], NUMTRANSMAPS), 0);
? (sides[lines[i].sidenum[0]].textureoffset>>FRACBITS)
: ((lines[i].frontsector->floorheight>>FRACBITS) / 100);
po->translucency = max(min(po->translucency, NUMTRANSMAPS), 0); po->flags = POF_SOLID|POF_TESTHEIGHT|POF_RENDERSIDES|POF_RENDERPLANES;
if (lines[i].flags & ML_EFFECT1) if (line->args[3] & TMPF_NOINSIDES)
po->flags |= POF_ONESIDE; po->flags |= POF_ONESIDE;
if (lines[i].flags & ML_EFFECT2) if (line->args[3] & TMPF_INTANGIBLE)
po->flags &= ~POF_SOLID; po->flags &= ~POF_SOLID;
if (lines[i].flags & ML_EFFECT3) if (line->args[3] & TMPF_PUSHABLESTOP)
po->flags |= POF_PUSHABLESTOP; po->flags |= POF_PUSHABLESTOP;
if (lines[i].flags & ML_EFFECT4) if (line->args[3] & TMPF_INVISIBLEPLANES)
po->flags |= POF_RENDERPLANES; po->flags &= ~POF_RENDERPLANES;
/*if (lines[i].flags & ML_EFFECT5) /*if (line->args[3] & TMPF_DONTCLIPPLANES)
po->flags &= ~POF_CLIPPLANES;*/ po->flags &= ~POF_CLIPPLANES;*/
if (lines[i].flags & ML_EFFECT6) if (line->args[3] & TMPF_SPLAT)
po->flags |= POF_SPLAT; po->flags |= POF_SPLAT;
if (lines[i].flags & ML_NOCLIMB) // Has a linedef executor if (line->args[3] & TMPF_EXECUTOR) // Has a linedef executor
po->flags |= POF_LDEXEC; po->flags |= POF_LDEXEC;
// TODO: support customized damage somehow?
if (line->args[3] & TMPF_CRUSH)
po->damage = 3;
po->triggertag = line->args[4];
} }
// Reallocating array maintenance // Reallocating array maintenance
@ -483,10 +480,6 @@ static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id)
po->id = id; po->id = id;
// TODO: support customized damage somehow?
if (spawnSpot->info->doomednum == POLYOBJ_SPAWNCRUSH_DOOMEDNUM)
po->damage = 3;
// set to default thrust; may be modified by attached thinkers // set to default thrust; may be modified by attached thinkers
// TODO: support customized thrust? // TODO: support customized thrust?
po->thrust = FRACUNIT; po->thrust = FRACUNIT;
@ -508,10 +501,10 @@ static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id)
if (seg->linedef->special != POLYOBJ_START_LINE) if (seg->linedef->special != POLYOBJ_START_LINE)
continue; continue;
if (seg->linedef->tag != po->id) if (seg->linedef->args[0] != po->id)
continue; continue;
Polyobj_GetInfo(po); // apply extra settings if they exist! Polyobj_GetInfo(po, seg->linedef); // apply extra settings if they exist!
// save original flags and translucency to reference later for netgames! // save original flags and translucency to reference later for netgames!
po->spawnflags = po->flags; po->spawnflags = po->flags;
@ -564,9 +557,9 @@ static void Polyobj_moveToSpawnSpot(mapthing_t *anchor)
vertex_t dist, sspot; vertex_t dist, sspot;
size_t i; size_t i;
if (!(po = Polyobj_GetForNum(anchor->angle))) if (!(po = Polyobj_GetForNum(anchor->tag)))
{ {
CONS_Debug(DBG_POLYOBJ, "Bad polyobject %d for anchor point\n", anchor->angle); CONS_Debug(DBG_POLYOBJ, "Bad polyobject %d for anchor point\n", anchor->tag);
return; return;
} }
@ -1314,8 +1307,7 @@ void Polyobj_InitLevel(void)
mo = (mobj_t *)th; mo = (mobj_t *)th;
if (mo->info->doomednum == POLYOBJ_SPAWN_DOOMEDNUM || if (mo->info->doomednum == POLYOBJ_SPAWN_DOOMEDNUM)
mo->info->doomednum == POLYOBJ_SPAWNCRUSH_DOOMEDNUM)
{ {
++numPolyObjects; ++numPolyObjects;
@ -1350,7 +1342,7 @@ void Polyobj_InitLevel(void)
{ {
qitem = (mobjqitem_t *)M_QueueIterator(&spawnqueue); qitem = (mobjqitem_t *)M_QueueIterator(&spawnqueue);
Polyobj_spawnPolyObj(i, qitem->mo, qitem->mo->spawnpoint->angle); Polyobj_spawnPolyObj(i, qitem->mo, qitem->mo->spawnpoint->tag);
} }
// move polyobjects to spawn points // move polyobjects to spawn points

View File

@ -26,10 +26,8 @@
#define POLYOBJ_ANCHOR_DOOMEDNUM 760 #define POLYOBJ_ANCHOR_DOOMEDNUM 760
#define POLYOBJ_SPAWN_DOOMEDNUM 761 #define POLYOBJ_SPAWN_DOOMEDNUM 761
#define POLYOBJ_SPAWNCRUSH_DOOMEDNUM 762 // todo: REMOVE
#define POLYOBJ_START_LINE 20 #define POLYOBJ_START_LINE 20
#define POLYINFO_SPECIALNUM 22
typedef enum typedef enum
{ {
@ -52,6 +50,18 @@ typedef enum
POF_SPLAT = 0x2000, ///< Use splat flat renderer (treat cyan pixels as invisible). POF_SPLAT = 0x2000, ///< Use splat flat renderer (treat cyan pixels as invisible).
} polyobjflags_e; } polyobjflags_e;
typedef enum
{
TMPF_NOINSIDES = 1,
TMPF_INTANGIBLE = 1<<1,
TMPF_PUSHABLESTOP = 1<<2,
TMPF_INVISIBLEPLANES = 1<<3,
TMPF_EXECUTOR = 1<<4,
TMPF_CRUSH = 1<<5,
TMPF_SPLAT = 1<<6,
//TMPF_DONTCLIPPLANES = 1<<7,
} textmappolyobjectflags_t;
// //
// Polyobject Structure // Polyobject Structure
// //
@ -97,6 +107,7 @@ typedef struct polyobj_s
UINT8 isBad; // a bad polyobject: should not be rendered/manipulated UINT8 isBad; // a bad polyobject: should not be rendered/manipulated
INT32 translucency; // index to translucency tables INT32 translucency; // index to translucency tables
INT16 triggertag; // Tag of linedef executor to trigger on touch
struct visplane_s *visplane; // polyobject's visplane, for ease of putting into the list later struct visplane_s *visplane; // polyobject's visplane, for ease of putting into the list later

View File

@ -787,10 +787,38 @@ static void P_NetUnArchiveWaypoints(void)
#define LD_DIFF2 0x80 #define LD_DIFF2 0x80
// diff2 flags // diff2 flags
#define LD_S2TEXOFF 0x01 #define LD_S2TEXOFF 0x01
#define LD_S2TOPTEX 0x02 #define LD_S2TOPTEX 0x02
#define LD_S2BOTTEX 0x04 #define LD_S2BOTTEX 0x04
#define LD_S2MIDTEX 0x08 #define LD_S2MIDTEX 0x08
#define LD_ARGS 0x10
#define LD_STRINGARGS 0x20
#define LD_EXECUTORDELAY 0x40
static boolean P_AreArgsEqual(const line_t *li, const line_t *spawnli)
{
UINT8 i;
for (i = 0; i < NUMLINEARGS; i++)
if (li->args[i] != spawnli->args[i])
return false;
return true;
}
static boolean P_AreStringArgsEqual(const line_t *li, const line_t *spawnli)
{
UINT8 i;
for (i = 0; i < NUMLINESTRINGARGS; i++)
{
if (!li->stringargs[i])
return !spawnli->stringargs[i];
if (strcmp(li->stringargs[i], spawnli->stringargs[i]))
return false;
}
return true;
}
#define FD_FLAGS 0x01 #define FD_FLAGS 0x01
#define FD_ALPHA 0x02 #define FD_ALPHA 0x02
@ -1085,6 +1113,15 @@ static void ArchiveLines(void)
if (spawnli->special == 321 || spawnli->special == 322) // only reason li->callcount would be non-zero is if either of these are involved if (spawnli->special == 321 || spawnli->special == 322) // only reason li->callcount would be non-zero is if either of these are involved
diff |= LD_CLLCOUNT; diff |= LD_CLLCOUNT;
if (!P_AreArgsEqual(li, spawnli))
diff2 |= LD_ARGS;
if (!P_AreStringArgsEqual(li, spawnli))
diff2 |= LD_STRINGARGS;
if (li->executordelay != spawnli->executordelay)
diff2 |= LD_EXECUTORDELAY;
if (li->sidenum[0] != 0xffff) if (li->sidenum[0] != 0xffff)
{ {
si = &sides[li->sidenum[0]]; si = &sides[li->sidenum[0]];
@ -1111,10 +1148,11 @@ static void ArchiveLines(void)
diff2 |= LD_S2BOTTEX; diff2 |= LD_S2BOTTEX;
if (si->midtexture != spawnsi->midtexture) if (si->midtexture != spawnsi->midtexture)
diff2 |= LD_S2MIDTEX; diff2 |= LD_S2MIDTEX;
if (diff2)
diff |= LD_DIFF2;
} }
if (diff2)
diff |= LD_DIFF2;
if (diff) if (diff)
{ {
WRITEINT16(save_p, i); WRITEINT16(save_p, i);
@ -1147,6 +1185,33 @@ static void ArchiveLines(void)
WRITEINT32(save_p, si->bottomtexture); WRITEINT32(save_p, si->bottomtexture);
if (diff2 & LD_S2MIDTEX) if (diff2 & LD_S2MIDTEX)
WRITEINT32(save_p, si->midtexture); WRITEINT32(save_p, si->midtexture);
if (diff2 & LD_ARGS)
{
UINT8 j;
for (j = 0; j < NUMLINEARGS; j++)
WRITEINT32(save_p, li->args[j]);
}
if (diff2 & LD_STRINGARGS)
{
UINT8 j;
for (j = 0; j < NUMLINESTRINGARGS; j++)
{
size_t len, k;
if (!li->stringargs[j])
{
WRITEINT32(save_p, 0);
continue;
}
len = strlen(li->stringargs[j]);
WRITEINT32(save_p, len);
for (k = 0; k < len; k++)
WRITECHAR(save_p, li->stringargs[j][k]);
}
}
if (diff2 & LD_EXECUTORDELAY)
WRITEINT32(save_p, li->executordelay);
} }
} }
WRITEUINT16(save_p, 0xffff); WRITEUINT16(save_p, 0xffff);
@ -1202,6 +1267,36 @@ static void UnArchiveLines(void)
si->bottomtexture = READINT32(save_p); si->bottomtexture = READINT32(save_p);
if (diff2 & LD_S2MIDTEX) if (diff2 & LD_S2MIDTEX)
si->midtexture = READINT32(save_p); si->midtexture = READINT32(save_p);
if (diff2 & LD_ARGS)
{
UINT8 j;
for (j = 0; j < NUMLINEARGS; j++)
li->args[j] = READINT32(save_p);
}
if (diff2 & LD_STRINGARGS)
{
UINT8 j;
for (j = 0; j < NUMLINESTRINGARGS; j++)
{
size_t len = READINT32(save_p);
size_t k;
if (!len)
{
Z_Free(li->stringargs[j]);
li->stringargs[j] = NULL;
continue;
}
li->stringargs[j] = Z_Realloc(li->stringargs[j], len + 1, PU_LEVEL, NULL);
for (k = 0; k < len; k++)
li->stringargs[j][k] = READCHAR(save_p);
li->stringargs[j][len] = '\0';
}
}
if (diff2 & LD_EXECUTORDELAY)
li->executordelay = READINT32(save_p);
} }
} }
@ -1400,7 +1495,9 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
if ((mobj->x != mobj->spawnpoint->x << FRACBITS) || if ((mobj->x != mobj->spawnpoint->x << FRACBITS) ||
(mobj->y != mobj->spawnpoint->y << FRACBITS) || (mobj->y != mobj->spawnpoint->y << FRACBITS) ||
(mobj->angle != FixedAngle(mobj->spawnpoint->angle*FRACUNIT))) (mobj->angle != FixedAngle(mobj->spawnpoint->angle*FRACUNIT)) ||
(mobj->pitch != FixedAngle(mobj->spawnpoint->pitch*FRACUNIT)) ||
(mobj->roll != FixedAngle(mobj->spawnpoint->roll*FRACUNIT)) )
diff |= MD_POS; diff |= MD_POS;
if (mobj->info->doomednum != mobj->spawnpoint->type) if (mobj->info->doomednum != mobj->spawnpoint->type)
@ -1556,6 +1653,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
WRITEFIXED(save_p, mobj->x); WRITEFIXED(save_p, mobj->x);
WRITEFIXED(save_p, mobj->y); WRITEFIXED(save_p, mobj->y);
WRITEANGLE(save_p, mobj->angle); WRITEANGLE(save_p, mobj->angle);
WRITEANGLE(save_p, mobj->pitch);
WRITEANGLE(save_p, mobj->roll);
} }
if (diff & MD_MOM) if (diff & MD_MOM)
{ {
@ -2513,12 +2612,16 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
mobj->x = READFIXED(save_p); mobj->x = READFIXED(save_p);
mobj->y = READFIXED(save_p); mobj->y = READFIXED(save_p);
mobj->angle = READANGLE(save_p); mobj->angle = READANGLE(save_p);
mobj->pitch = READANGLE(save_p);
mobj->roll = READANGLE(save_p);
} }
else else
{ {
mobj->x = mobj->spawnpoint->x << FRACBITS; mobj->x = mobj->spawnpoint->x << FRACBITS;
mobj->y = mobj->spawnpoint->y << FRACBITS; mobj->y = mobj->spawnpoint->y << FRACBITS;
mobj->angle = FixedAngle(mobj->spawnpoint->angle*FRACUNIT); mobj->angle = FixedAngle(mobj->spawnpoint->angle*FRACUNIT);
mobj->pitch = FixedAngle(mobj->spawnpoint->pitch*FRACUNIT);
mobj->roll = FixedAngle(mobj->spawnpoint->roll*FRACUNIT);
} }
if (diff & MD_MOM) if (diff & MD_MOM)
{ {

View File

@ -92,6 +92,7 @@ unsigned char mapmd5[16];
// Store VERTEXES, LINEDEFS, SIDEDEFS, etc. // Store VERTEXES, LINEDEFS, SIDEDEFS, etc.
// //
boolean udmf;
size_t numvertexes, numsegs, numsectors, numsubsectors, numnodes, numlines, numsides, nummapthings; size_t numvertexes, numsegs, numsectors, numsubsectors, numnodes, numlines, numsides, nummapthings;
vertex_t *vertexes; vertex_t *vertexes;
seg_t *segs; seg_t *segs;
@ -1039,6 +1040,8 @@ static void P_LoadSectors(UINT8 *data)
ss->floorpic_angle = ss->ceilingpic_angle = 0; ss->floorpic_angle = ss->ceilingpic_angle = 0;
ss->colormap_protected = false;
P_InitializeSector(ss); P_InitializeSector(ss);
} }
} }
@ -1145,6 +1148,10 @@ static void P_LoadLinedefs(UINT8 *data)
ld->flags = SHORT(mld->flags); ld->flags = SHORT(mld->flags);
ld->special = SHORT(mld->special); ld->special = SHORT(mld->special);
ld->tag = SHORT(mld->tag); ld->tag = SHORT(mld->tag);
memset(ld->args, 0, NUMLINEARGS*sizeof(*ld->args));
memset(ld->stringargs, 0x00, NUMLINESTRINGARGS*sizeof(*ld->stringargs));
ld->alpha = FRACUNIT;
ld->executordelay = 0;
P_SetLinedefV1(i, SHORT(mld->v1)); P_SetLinedefV1(i, SHORT(mld->v1));
P_SetLinedefV2(i, SHORT(mld->v2)); P_SetLinedefV2(i, SHORT(mld->v2));
@ -1218,9 +1225,11 @@ static void P_LoadSidedefs(UINT8 *data)
case 455: // Fade colormaps! mazmazz 9/12/2018 (:flag_us:) case 455: // Fade colormaps! mazmazz 9/12/2018 (:flag_us:)
// SoM: R_CreateColormap will only create a colormap in software mode... // SoM: R_CreateColormap will only create a colormap in software mode...
// Perhaps we should just call it instead of doing the calculations here. // Perhaps we should just call it instead of doing the calculations here.
sd->colormap_data = R_CreateColormap(msd->toptexture, msd->midtexture, if (!udmf)
msd->bottomtexture); {
sd->toptexture = sd->midtexture = sd->bottomtexture = 0; sd->colormap_data = R_CreateColormapFromLinedef(msd->toptexture, msd->midtexture, msd->bottomtexture);
sd->toptexture = sd->midtexture = sd->bottomtexture = 0;
}
break; break;
case 413: // Change music case 413: // Change music
@ -1371,6 +1380,11 @@ static void P_LoadThings(UINT8 *data)
mt->type = READUINT16(data); mt->type = READUINT16(data);
mt->options = READUINT16(data); mt->options = READUINT16(data);
mt->extrainfo = (UINT8)(mt->type >> 12); mt->extrainfo = (UINT8)(mt->type >> 12);
mt->scale = FRACUNIT;
mt->tag = 0;
memset(mt->args, 0, NUMMAPTHINGARGS*sizeof(*mt->args));
memset(mt->stringargs, 0x00, NUMMAPTHINGSTRINGARGS*sizeof(*mt->stringargs));
mt->pitch = mt->roll = 0;
mt->type &= 4095; mt->type &= 4095;
@ -1475,6 +1489,19 @@ static void ParseTextmapVertexParameter(UINT32 i, char *param, char *val)
} }
} }
typedef struct textmap_colormap_s {
boolean used;
INT32 lightcolor;
UINT8 lightalpha;
INT32 fadecolor;
UINT8 fadealpha;
UINT8 fadestart;
UINT8 fadeend;
UINT8 flags;
} textmap_colormap_t;
textmap_colormap_t textmap_colormap = { false, 0, 25, 0, 25, 0, 31, 0 };
static void ParseTextmapSectorParameter(UINT32 i, char *param, char *val) static void ParseTextmapSectorParameter(UINT32 i, char *param, char *val)
{ {
if (fastcmp(param, "heightfloor")) if (fastcmp(param, "heightfloor"))
@ -1503,6 +1530,48 @@ static void ParseTextmapSectorParameter(UINT32 i, char *param, char *val)
sectors[i].floorpic_angle = FixedAngle(FLOAT_TO_FIXED(atof(val))); sectors[i].floorpic_angle = FixedAngle(FLOAT_TO_FIXED(atof(val)));
else if (fastcmp(param, "rotationceiling")) else if (fastcmp(param, "rotationceiling"))
sectors[i].ceilingpic_angle = FixedAngle(FLOAT_TO_FIXED(atof(val))); sectors[i].ceilingpic_angle = FixedAngle(FLOAT_TO_FIXED(atof(val)));
else if (fastcmp(param, "lightcolor"))
{
textmap_colormap.used = true;
textmap_colormap.lightcolor = atol(val);
}
else if (fastcmp(param, "lightalpha"))
{
textmap_colormap.used = true;
textmap_colormap.lightalpha = atol(val);
}
else if (fastcmp(param, "fadecolor"))
{
textmap_colormap.used = true;
textmap_colormap.fadecolor = atol(val);
}
else if (fastcmp(param, "fadealpha"))
{
textmap_colormap.used = true;
textmap_colormap.fadealpha = atol(val);
}
else if (fastcmp(param, "fadestart"))
{
textmap_colormap.used = true;
textmap_colormap.fadestart = atol(val);
}
else if (fastcmp(param, "fadeend"))
{
textmap_colormap.used = true;
textmap_colormap.fadeend = atol(val);
}
else if (fastcmp(param, "colormapfog") && fastcmp("true", val))
{
textmap_colormap.used = true;
textmap_colormap.flags |= CMF_FOG;
}
else if (fastcmp(param, "colormapfadesprites") && fastcmp("true", val))
{
textmap_colormap.used = true;
textmap_colormap.flags |= CMF_FADEFULLBRIGHTSPRITES;
}
else if (fastcmp(param, "colormapprotected") && fastcmp("true", val))
sectors[i].colormap_protected = true;
} }
static void ParseTextmapSidedefParameter(UINT32 i, char *param, char *val) static void ParseTextmapSidedefParameter(UINT32 i, char *param, char *val)
@ -1533,10 +1602,29 @@ static void ParseTextmapLinedefParameter(UINT32 i, char *param, char *val)
P_SetLinedefV1(i, atol(val)); P_SetLinedefV1(i, atol(val));
else if (fastcmp(param, "v2")) else if (fastcmp(param, "v2"))
P_SetLinedefV2(i, atol(val)); P_SetLinedefV2(i, atol(val));
else if (fastncmp(param, "arg", 3) && strlen(param) > 3)
{
size_t argnum = atol(param + 3);
if (argnum >= NUMLINEARGS)
return;
lines[i].args[argnum] = atol(val);
}
else if (fastncmp(param, "stringarg", 9) && strlen(param) > 9)
{
size_t argnum = param[9] - '0';
if (argnum >= NUMLINESTRINGARGS)
return;
lines[i].stringargs[argnum] = Z_Malloc(strlen(val) + 1, PU_LEVEL, NULL);
M_Memcpy(lines[i].stringargs[argnum], val, strlen(val) + 1);
}
else if (fastcmp(param, "sidefront")) else if (fastcmp(param, "sidefront"))
lines[i].sidenum[0] = atol(val); lines[i].sidenum[0] = atol(val);
else if (fastcmp(param, "sideback")) else if (fastcmp(param, "sideback"))
lines[i].sidenum[1] = atol(val); lines[i].sidenum[1] = atol(val);
else if (fastcmp(param, "alpha"))
lines[i].alpha = FLOAT_TO_FIXED(atof(val));
else if (fastcmp(param, "executordelay"))
lines[i].executordelay = atol(val);
// Flags // Flags
else if (fastcmp(param, "blocking") && fastcmp("true", val)) else if (fastcmp(param, "blocking") && fastcmp("true", val))
@ -1575,6 +1663,8 @@ static void ParseTextmapLinedefParameter(UINT32 i, char *param, char *val)
static void ParseTextmapThingParameter(UINT32 i, char *param, char *val) static void ParseTextmapThingParameter(UINT32 i, char *param, char *val)
{ {
if (fastcmp(param, "id"))
mapthings[i].tag = atol(val);
if (fastcmp(param, "x")) if (fastcmp(param, "x"))
mapthings[i].x = atol(val); mapthings[i].x = atol(val);
else if (fastcmp(param, "y")) else if (fastcmp(param, "y"))
@ -1583,18 +1673,39 @@ static void ParseTextmapThingParameter(UINT32 i, char *param, char *val)
mapthings[i].z = atol(val); mapthings[i].z = atol(val);
else if (fastcmp(param, "angle")) else if (fastcmp(param, "angle"))
mapthings[i].angle = atol(val); mapthings[i].angle = atol(val);
else if (fastcmp(param, "pitch"))
mapthings[i].pitch = atol(val);
else if (fastcmp(param, "roll"))
mapthings[i].roll = atol(val);
else if (fastcmp(param, "type")) else if (fastcmp(param, "type"))
mapthings[i].type = atol(val); mapthings[i].type = atol(val);
else if (fastcmp(param, "scale") || fastcmp(param, "scalex") || fastcmp(param, "scaley"))
mapthings[i].scale = FLOAT_TO_FIXED(atof(val));
// Flags // Flags
else if (fastcmp(param, "extra") && fastcmp("true", val)) else if (fastcmp(param, "extra") && fastcmp("true", val))
mapthings[i].options |= MTF_EXTRA; mapthings[i].options |= MTF_EXTRA;
else if (fastcmp(param, "flip") && fastcmp("true", val)) else if (fastcmp(param, "flip") && fastcmp("true", val))
mapthings[i].options |= MTF_OBJECTFLIP; mapthings[i].options |= MTF_OBJECTFLIP;
else if (fastcmp(param, "special") && fastcmp("true", val)) else if (fastcmp(param, "objectspecial") && fastcmp("true", val))
mapthings[i].options |= MTF_OBJECTSPECIAL; mapthings[i].options |= MTF_OBJECTSPECIAL;
else if (fastcmp(param, "ambush") && fastcmp("true", val)) else if (fastcmp(param, "ambush") && fastcmp("true", val))
mapthings[i].options |= MTF_AMBUSH; mapthings[i].options |= MTF_AMBUSH;
else if (fastncmp(param, "arg", 3) && strlen(param) > 3)
{
size_t argnum = atol(param + 3);
if (argnum >= NUMMAPTHINGARGS)
return;
mapthings[i].args[argnum] = atol(val);
}
else if (fastncmp(param, "stringarg", 9) && strlen(param) > 9)
{
size_t argnum = param[9] - '0';
if (argnum >= NUMMAPTHINGSTRINGARGS)
return;
mapthings[i].stringargs[argnum] = Z_Malloc(strlen(val) + 1, PU_LEVEL, NULL);
M_Memcpy(mapthings[i].stringargs[argnum], val, strlen(val) + 1);
}
} }
/** From a given position table, run a specified parser function through a {}-encapsuled text. /** From a given position table, run a specified parser function through a {}-encapsuled text.
@ -1657,6 +1768,14 @@ static void TextmapFixFlatOffsets(sector_t *sec)
} }
} }
static INT32 P_ColorToRGBA(INT32 color, UINT8 alpha)
{
UINT8 r = (color >> 16) & 0xFF;
UINT8 g = (color >> 8) & 0xFF;
UINT8 b = color & 0xFF;
return R_PutRgbaRGBA(r, g, b, alpha);
}
/** Loads the textmap data, after obtaining the elements count and allocating their respective space. /** Loads the textmap data, after obtaining the elements count and allocating their respective space.
*/ */
static void P_LoadTextmap(void) static void P_LoadTextmap(void)
@ -1710,8 +1829,24 @@ static void P_LoadTextmap(void)
sc->floorpic_angle = sc->ceilingpic_angle = 0; sc->floorpic_angle = sc->ceilingpic_angle = 0;
sc->colormap_protected = false;
textmap_colormap.used = false;
textmap_colormap.lightcolor = 0;
textmap_colormap.lightalpha = 25;
textmap_colormap.fadecolor = 0;
textmap_colormap.fadealpha = 25;
textmap_colormap.fadestart = 0;
textmap_colormap.fadeend = 31;
textmap_colormap.flags = 0;
TextmapParse(sectorsPos[i], i, ParseTextmapSectorParameter); TextmapParse(sectorsPos[i], i, ParseTextmapSectorParameter);
P_InitializeSector(sc); P_InitializeSector(sc);
if (textmap_colormap.used)
{
INT32 rgba = P_ColorToRGBA(textmap_colormap.lightcolor, textmap_colormap.lightalpha);
INT32 fadergba = P_ColorToRGBA(textmap_colormap.fadecolor, textmap_colormap.fadealpha);
sc->extra_colormap = sc->spawn_extra_colormap = R_CreateColormap(rgba, fadergba, textmap_colormap.fadestart, textmap_colormap.fadeend, textmap_colormap.flags);
}
TextmapFixFlatOffsets(sc); TextmapFixFlatOffsets(sc);
} }
@ -1722,6 +1857,10 @@ static void P_LoadTextmap(void)
ld->flags = 0; ld->flags = 0;
ld->special = 0; ld->special = 0;
ld->tag = 0; ld->tag = 0;
memset(ld->args, 0, NUMLINEARGS*sizeof(*ld->args));
memset(ld->stringargs, 0x00, NUMLINESTRINGARGS*sizeof(*ld->stringargs));
ld->alpha = FRACUNIT;
ld->executordelay = 0;
ld->sidenum[0] = 0xffff; ld->sidenum[0] = 0xffff;
ld->sidenum[1] = 0xffff; ld->sidenum[1] = 0xffff;
@ -1760,11 +1899,15 @@ static void P_LoadTextmap(void)
{ {
// Defaults. // Defaults.
mt->x = mt->y = 0; mt->x = mt->y = 0;
mt->angle = 0; mt->angle = mt->pitch = mt->roll = 0;
mt->type = 0; mt->type = 0;
mt->options = 0; mt->options = 0;
mt->z = 0; mt->z = 0;
mt->extrainfo = 0; mt->extrainfo = 0;
mt->scale = FRACUNIT;
mt->tag = 0;
memset(mt->args, 0, NUMMAPTHINGARGS*sizeof(*mt->args));
memset(mt->stringargs, 0x00, NUMMAPTHINGSTRINGARGS*sizeof(*mt->stringargs));
mt->mobj = NULL; mt->mobj = NULL;
TextmapParse(mapthingsPos[i], i, ParseTextmapThingParameter); TextmapParse(mapthingsPos[i], i, ParseTextmapThingParameter);
@ -1780,9 +1923,9 @@ static void P_ProcessLinedefsAfterSidedefs(void)
ld->frontsector = sides[ld->sidenum[0]].sector; //e6y: Can't be -1 here ld->frontsector = sides[ld->sidenum[0]].sector; //e6y: Can't be -1 here
ld->backsector = ld->sidenum[1] != 0xffff ? sides[ld->sidenum[1]].sector : 0; ld->backsector = ld->sidenum[1] != 0xffff ? sides[ld->sidenum[1]].sector : 0;
// Compile linedef 'text' from both sidedefs 'text' for appropriate specials.
switch (ld->special) switch (ld->special)
{ {
// Compile linedef 'text' from both sidedefs 'text' for appropriate specials.
case 331: // Trigger linedef executor: Skin - Continuous case 331: // Trigger linedef executor: Skin - Continuous
case 332: // Trigger linedef executor: Skin - Each time case 332: // Trigger linedef executor: Skin - Each time
case 333: // Trigger linedef executor: Skin - Once case 333: // Trigger linedef executor: Skin - Once
@ -1798,6 +1941,41 @@ static void P_ProcessLinedefsAfterSidedefs(void)
M_Memcpy(ld->text + strlen(ld->text) + 1, sides[ld->sidenum[1]].text, strlen(sides[ld->sidenum[1]].text) + 1); M_Memcpy(ld->text + strlen(ld->text) + 1, sides[ld->sidenum[1]].text, strlen(sides[ld->sidenum[1]].text) + 1);
} }
break; break;
case 447: // Change colormap
case 455: // Fade colormap
if (udmf)
break;
if (ld->flags & ML_DONTPEGBOTTOM) // alternate alpha (by texture offsets)
{
extracolormap_t *exc = R_CopyColormap(sides[ld->sidenum[0]].colormap_data, false);
INT16 alpha = max(min(sides[ld->sidenum[0]].textureoffset >> FRACBITS, 25), -25);
INT16 fadealpha = max(min(sides[ld->sidenum[0]].rowoffset >> FRACBITS, 25), -25);
// If alpha is negative, set "subtract alpha" flag and store absolute value
if (alpha < 0)
{
alpha *= -1;
ld->args[2] |= TMCF_SUBLIGHTA;
}
if (fadealpha < 0)
{
fadealpha *= -1;
ld->args[2] |= TMCF_SUBFADEA;
}
exc->rgba = R_GetRgbaRGB(exc->rgba) + R_PutRgbaA(alpha);
exc->fadergba = R_GetRgbaRGB(exc->fadergba) + R_PutRgbaA(fadealpha);
if (!(sides[ld->sidenum[0]].colormap_data = R_GetColormapFromList(exc)))
{
exc->colormap = R_CreateLightTable(exc);
R_AddColormapToList(exc);
sides[ld->sidenum[0]].colormap_data = exc;
}
else
Z_Free(exc);
}
break;
} }
} }
} }
@ -1805,11 +1983,11 @@ static void P_ProcessLinedefsAfterSidedefs(void)
static boolean P_LoadMapData(const virtres_t *virt) static boolean P_LoadMapData(const virtres_t *virt)
{ {
virtlump_t *virtvertexes = NULL, *virtsectors = NULL, *virtsidedefs = NULL, *virtlinedefs = NULL, *virtthings = NULL; virtlump_t *virtvertexes = NULL, *virtsectors = NULL, *virtsidedefs = NULL, *virtlinedefs = NULL, *virtthings = NULL;
virtlump_t *textmap = vres_Find(virt, "TEXTMAP");
// Count map data. // Count map data.
if (textmap) // Count how many entries for each type we got in textmap. if (udmf) // Count how many entries for each type we got in textmap.
{ {
virtlump_t *textmap = vres_Find(virt, "TEXTMAP");
if (!TextmapCount(textmap->data, textmap->size)) if (!TextmapCount(textmap->data, textmap->size))
return false; return false;
} }
@ -1864,7 +2042,7 @@ static boolean P_LoadMapData(const virtres_t *virt)
numlevelflats = 0; numlevelflats = 0;
// Load map data. // Load map data.
if (textmap) if (udmf)
P_LoadTextmap(); P_LoadTextmap();
else else
{ {
@ -1972,7 +2150,12 @@ static void P_InitializeSeg(seg_t *seg)
{ {
if (seg->linedef) if (seg->linedef)
{ {
seg->sidedef = &sides[seg->linedef->sidenum[seg->side]]; UINT16 side = seg->linedef->sidenum[seg->side];
if (side == 0xffff)
I_Error("P_InitializeSeg: Seg %s refers to side %d of linedef %s, which doesn't exist!\n", sizeu1((size_t)(seg - segs)), seg->side, sizeu1((size_t)(seg->linedef - lines)));
seg->sidedef = &sides[side];
seg->frontsector = seg->sidedef->sector; seg->frontsector = seg->sidedef->sector;
seg->backsector = (seg->linedef->flags & ML_TWOSIDED) ? sides[seg->linedef->sidenum[seg->side ^ 1]].sector : NULL; seg->backsector = (seg->linedef->flags & ML_TWOSIDED) ? sides[seg->linedef->sidenum[seg->side ^ 1]].sector : NULL;
@ -2041,7 +2224,7 @@ static nodetype_t P_GetNodetype(const virtres_t *virt, UINT8 **nodedata)
nodetype_t nodetype = NT_UNSUPPORTED; nodetype_t nodetype = NT_UNSUPPORTED;
char signature[4 + 1]; char signature[4 + 1];
if (vres_Find(virt, "TEXTMAP")) if (udmf)
{ {
*nodedata = vres_Find(virt, "ZNODES")->data; *nodedata = vres_Find(virt, "ZNODES")->data;
supported[NT_XGLN] = supported[NT_XGL3] = true; supported[NT_XGLN] = supported[NT_XGL3] = true;
@ -2166,10 +2349,8 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype
segs[k - 1 + ((m == 0) ? subsectors[i].numlines : 0)].v2 = segs[k].v1 = &vertexes[vertexnum]; segs[k - 1 + ((m == 0) ? subsectors[i].numlines : 0)].v2 = segs[k].v1 = &vertexes[vertexnum];
READUINT32((*data)); // partner, can be ignored by software renderer READUINT32((*data)); // partner, can be ignored by software renderer
if (nodetype == NT_XGL3)
READUINT16((*data)); // Line number is 32-bit in XGL3, but we're limited to 16 bits.
linenum = READUINT16((*data)); linenum = (nodetype == NT_XGL3) ? READUINT32((*data)) : READUINT16((*data));
if (linenum != 0xFFFF && linenum >= numlines) if (linenum != 0xFFFF && linenum >= numlines)
I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %s in subsector %d has invalid linedef %d!\n", sizeu1(k), m, linenum); I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %s in subsector %d has invalid linedef %d!\n", sizeu1(k), m, linenum);
segs[k].glseg = (linenum == 0xFFFF); segs[k].glseg = (linenum == 0xFFFF);
@ -2737,6 +2918,259 @@ static void P_LinkMapData(void)
} }
} }
/** Hashes the sector tags across the sectors and linedefs.
*
* \sa P_FindSectorFromTag, P_ChangeSectorTag
* \author Lee Killough
*/
static inline void P_InitTagLists(void)
{
register size_t i;
for (i = numsectors - 1; i != (size_t)-1; i--)
{
size_t j = (unsigned)sectors[i].tag % numsectors;
sectors[i].nexttag = sectors[j].firsttag;
sectors[j].firsttag = (INT32)i;
}
for (i = numlines - 1; i != (size_t)-1; i--)
{
size_t j = (unsigned)lines[i].tag % numlines;
lines[i].nexttag = lines[j].firsttag;
lines[j].firsttag = (INT32)i;
}
}
//For maps in binary format, converts setup of specials to UDMF format.
static void P_ConvertBinaryMap(void)
{
size_t i;
for (i = 0; i < numlines; i++)
{
switch (lines[i].special)
{
case 20: //PolyObject first line
{
INT32 paramline = P_FindSpecialLineFromTag(22, lines[i].tag, -1);
//PolyObject ID
lines[i].args[0] = lines[i].tag;
//Default: Invisible planes
lines[i].args[3] |= TMPF_INVISIBLEPLANES;
//Linedef executor tag
lines[i].args[4] = 32000 + lines[i].args[0];
if (paramline == -1)
break; // no extra settings to apply, let's leave it
//Parent ID
lines[i].args[1] = lines[paramline].frontsector->special;
//Translucency
lines[i].args[2] = (lines[paramline].flags & ML_DONTPEGTOP)
? (sides[lines[paramline].sidenum[0]].textureoffset >> FRACBITS)
: ((lines[paramline].frontsector->floorheight >> FRACBITS) / 100);
//Flags
if (lines[paramline].flags & ML_EFFECT1)
lines[i].args[3] |= TMPF_NOINSIDES;
if (lines[paramline].flags & ML_EFFECT2)
lines[i].args[3] |= TMPF_INTANGIBLE;
if (lines[paramline].flags & ML_EFFECT3)
lines[i].args[3] |= TMPF_PUSHABLESTOP;
if (lines[paramline].flags & ML_EFFECT4)
lines[i].args[3] &= ~TMPF_INVISIBLEPLANES;
/*if (lines[paramline].flags & ML_EFFECT5)
lines[i].args[3] |= TMPF_DONTCLIPPLANES;*/
if (lines[paramline].flags & ML_EFFECT6)
lines[i].args[3] |= TMPF_SPLAT;
if (lines[paramline].flags & ML_NOCLIMB)
lines[i].args[3] |= TMPF_EXECUTOR;
break;
}
case 443: //Call Lua function
if (lines[i].text)
{
lines[i].stringargs[0] = Z_Malloc(strlen(lines[i].text) + 1, PU_LEVEL, NULL);
M_Memcpy(lines[i].stringargs[0], lines[i].text, strlen(lines[i].text) + 1);
}
else
CONS_Alert(CONS_WARNING, "Linedef %s is missing the hook name of the Lua function to call! (This should be given in the front texture fields)\n", sizeu1(i));
break;
case 447: //Change colormap
lines[i].args[0] = lines[i].tag;
if (lines[i].flags & ML_EFFECT3)
lines[i].args[2] |= TMCF_RELATIVE;
if (lines[i].flags & ML_EFFECT1)
lines[i].args[2] |= TMCF_SUBLIGHTR|TMCF_SUBFADER;
if (lines[i].flags & ML_NOCLIMB)
lines[i].args[2] |= TMCF_SUBLIGHTG|TMCF_SUBFADEG;
if (lines[i].flags & ML_EFFECT2)
lines[i].args[2] |= TMCF_SUBLIGHTB|TMCF_SUBFADEB;
break;
case 455: //Fade colormap
{
INT32 speed = (INT32)((((lines[i].flags & ML_DONTPEGBOTTOM) || !sides[lines[i].sidenum[0]].rowoffset) && lines[i].sidenum[1] != 0xFFFF) ?
abs(sides[lines[i].sidenum[1]].rowoffset >> FRACBITS)
: abs(sides[lines[i].sidenum[0]].rowoffset >> FRACBITS));
lines[i].args[0] = lines[i].tag;
if (lines[i].flags & ML_EFFECT4)
lines[i].args[2] = speed;
else
lines[i].args[2] = (256 + speed - 1)/speed;
if (lines[i].flags & ML_EFFECT3)
lines[i].args[3] |= TMCF_RELATIVE;
if (lines[i].flags & ML_EFFECT1)
lines[i].args[3] |= TMCF_SUBLIGHTR|TMCF_SUBFADER;
if (lines[i].flags & ML_NOCLIMB)
lines[i].args[3] |= TMCF_SUBLIGHTG|TMCF_SUBFADEG;
if (lines[i].flags & ML_EFFECT2)
lines[i].args[3] |= TMCF_SUBLIGHTB|TMCF_SUBFADEB;
if (lines[i].flags & ML_BOUNCY)
lines[i].args[3] |= TMCF_FROMBLACK;
if (lines[i].flags & ML_EFFECT5)
lines[i].args[3] |= TMCF_OVERRIDE;
break;
}
case 456: //Stop fading colormap
lines[i].args[0] = lines[i].tag;
break;
case 606: //Colormap
lines[i].args[0] = lines[i].tag;
break;
case 700: //Slope front sector floor
case 701: //Slope front sector ceiling
case 702: //Slope front sector floor and ceiling
case 703: //Slope front sector floor and back sector ceiling
case 710: //Slope back sector floor
case 711: //Slope back sector ceiling
case 712: //Slope back sector floor and ceiling
case 713: //Slope back sector floor and front sector ceiling
{
boolean frontfloor = (lines[i].special == 700 || lines[i].special == 702 || lines[i].special == 703);
boolean backfloor = (lines[i].special == 710 || lines[i].special == 712 || lines[i].special == 713);
boolean frontceil = (lines[i].special == 701 || lines[i].special == 702 || lines[i].special == 713);
boolean backceil = (lines[i].special == 711 || lines[i].special == 712 || lines[i].special == 703);
lines[i].args[0] = backfloor ? TMS_BACK : (frontfloor ? TMS_FRONT : TMS_NONE);
lines[i].args[1] = backceil ? TMS_BACK : (frontceil ? TMS_FRONT : TMS_NONE);
if (lines[i].flags & ML_NETONLY)
lines[i].args[2] |= TMSL_NOPHYSICS;
if (lines[i].flags & ML_NONET)
lines[i].args[2] |= TMSL_DYNAMIC;
lines[i].special = 700;
break;
}
case 704: //Slope front sector floor by 3 tagged vertices
case 705: //Slope front sector ceiling by 3 tagged vertices
case 714: //Slope back sector floor by 3 tagged vertices
case 715: //Slope back sector ceiling by 3 tagged vertices
{
if (lines[i].special == 704)
lines[i].args[0] = TMSP_FRONTFLOOR;
else if (lines[i].special == 705)
lines[i].args[0] = TMSP_FRONTCEILING;
else if (lines[i].special == 714)
lines[i].args[0] = TMSP_BACKFLOOR;
else if (lines[i].special == 715)
lines[i].args[0] = TMSP_BACKCEILING;
lines[i].args[1] = lines[i].tag;
if (lines[i].flags & ML_EFFECT6)
{
UINT8 side = lines[i].special >= 714;
if (side == 1 && lines[i].sidenum[1] == 0xffff)
CONS_Debug(DBG_GAMELOGIC, "P_ConvertBinaryMap: Line special %d (line #%s) missing 2nd side!\n", lines[i].special, sizeu1(i));
else
{
lines[i].args[2] = sides[lines[i].sidenum[side]].textureoffset >> FRACBITS;
lines[i].args[3] = sides[lines[i].sidenum[side]].rowoffset >> FRACBITS;
}
}
else
{
lines[i].args[2] = lines[i].args[1];
lines[i].args[3] = lines[i].args[1];
}
if (lines[i].flags & ML_NETONLY)
lines[i].args[4] |= TMSL_NOPHYSICS;
if (lines[i].flags & ML_NONET)
lines[i].args[4] |= TMSL_DYNAMIC;
lines[i].special = 704;
break;
}
case 720: //Copy front side floor slope
case 721: //Copy front side ceiling slope
case 722: //Copy front side floor and ceiling slope
if (lines[i].special != 721)
lines[i].args[0] = lines[i].tag;
if (lines[i].special != 720)
lines[i].args[1] = lines[i].tag;
lines[i].special = 720;
break;
case 900: //Translucent wall (10%)
case 901: //Translucent wall (20%)
case 902: //Translucent wall (30%)
case 903: //Translucent wall (40%)
case 904: //Translucent wall (50%)
case 905: //Translucent wall (60%)
case 906: //Translucent wall (70%)
case 907: //Translucent wall (80%)
case 908: //Translucent wall (90%)
lines[i].alpha = ((909 - lines[i].special) << FRACBITS)/10;
break;
default:
break;
}
//Linedef executor delay
if (lines[i].special >= 400 && lines[i].special < 500)
{
//Dummy value to indicate that this executor is delayed.
//The real value is taken from the back sector at runtime.
if (lines[i].flags & ML_DONTPEGTOP)
lines[i].executordelay = 1;
}
}
for (i = 0; i < nummapthings; i++)
{
switch (mapthings[i].type)
{
case 750:
case 760:
case 761:
mapthings[i].tag = mapthings[i].angle;
break;
case 762:
{
INT32 firstline = P_FindSpecialLineFromTag(20, mapthings[i].angle, -1);
if (firstline != -1)
lines[firstline].args[3] |= TMPF_CRUSH;
mapthings[i].tag = mapthings[i].angle;
mapthings[i].type = 761;
break;
}
case 780:
mapthings[i].tag = mapthings[i].extrainfo;
break;
default:
break;
}
}
}
/** Compute MD5 message digest for bytes read from memory source /** Compute MD5 message digest for bytes read from memory source
* *
* The resulting message digest number will be written into the 16 bytes * The resulting message digest number will be written into the 16 bytes
@ -2765,11 +3199,13 @@ static INT32 P_MakeBufferMD5(const char *buffer, size_t len, void *resblock)
static void P_MakeMapMD5(virtres_t *virt, void *dest) static void P_MakeMapMD5(virtres_t *virt, void *dest)
{ {
virtlump_t *textmap = vres_Find(virt, "TEXTMAP");
unsigned char resmd5[16]; unsigned char resmd5[16];
if (textmap) if (udmf)
{
virtlump_t *textmap = vres_Find(virt, "TEXTMAP");
P_MakeBufferMD5((char*)textmap->data, textmap->size, resmd5); P_MakeBufferMD5((char*)textmap->data, textmap->size, resmd5);
}
else else
{ {
unsigned char linemd5[16]; unsigned char linemd5[16];
@ -2800,6 +3236,8 @@ static void P_MakeMapMD5(virtres_t *virt, void *dest)
static boolean P_LoadMapFromFile(void) static boolean P_LoadMapFromFile(void)
{ {
virtres_t *virt = vres_GetMap(lastloadedmaplumpnum); virtres_t *virt = vres_GetMap(lastloadedmaplumpnum);
virtlump_t *textmap = vres_Find(virt, "TEXTMAP");
udmf = textmap != NULL;
if (!P_LoadMapData(virt)) if (!P_LoadMapData(virt))
return false; return false;
@ -2808,6 +3246,11 @@ static boolean P_LoadMapFromFile(void)
P_LinkMapData(); P_LinkMapData();
P_InitTagLists(); // Create xref tables for tags
if (!udmf)
P_ConvertBinaryMap();
// Copy relevant map data for NetArchive purposes. // Copy relevant map data for NetArchive purposes.
spawnsectors = Z_Calloc(numsectors * sizeof(*sectors), PU_LEVEL, NULL); spawnsectors = Z_Calloc(numsectors * sizeof(*sectors), PU_LEVEL, NULL);
spawnlines = Z_Calloc(numlines * sizeof(*lines), PU_LEVEL, NULL); spawnlines = Z_Calloc(numlines * sizeof(*lines), PU_LEVEL, NULL);
@ -3682,8 +4125,7 @@ boolean P_LoadLevel(boolean fromnetsave)
if (!P_LoadMapFromFile()) if (!P_LoadMapFromFile())
return false; return false;
// init gravity, tag lists, // init anything that P_SpawnSlopes/P_LoadThings needs to know
// anything that P_SpawnSlopes/P_LoadThings needs to know
P_InitSpecials(); P_InitSpecials();
P_SpawnSlopes(fromnetsave); P_SpawnSlopes(fromnetsave);

View File

@ -245,32 +245,30 @@ static void line_SpawnViaLine(const int linenum, const boolean spawnthinker)
// because checking to see if a slope had changed will waste more memory than // because checking to see if a slope had changed will waste more memory than
// if the slope was just updated when called // if the slope was just updated when called
line_t *line = lines + linenum; line_t *line = lines + linenum;
INT16 special = line->special;
pslope_t *fslope = NULL, *cslope = NULL; pslope_t *fslope = NULL, *cslope = NULL;
vector3_t origin, point; vector3_t origin, point;
vector2_t direction; vector2_t direction;
fixed_t nx, ny, dz, extent; fixed_t nx, ny, dz, extent;
boolean frontfloor = (special == 700 || special == 702 || special == 703); boolean frontfloor = line->args[0] == TMS_FRONT;
boolean backfloor = (special == 710 || special == 712 || special == 713); boolean backfloor = line->args[0] == TMS_BACK;
boolean frontceil = (special == 701 || special == 702 || special == 713); boolean frontceil = line->args[1] == TMS_FRONT;
boolean backceil = (special == 711 || special == 712 || special == 703); boolean backceil = line->args[1] == TMS_BACK;
UINT8 flags = 0; // Slope flags UINT8 flags = 0; // Slope flags
if (line->flags & ML_NETONLY) if (line->args[2] & TMSL_NOPHYSICS)
flags |= SL_NOPHYSICS; flags |= SL_NOPHYSICS;
if (line->flags & ML_NONET) if (line->args[2] & TMSL_DYNAMIC)
flags |= SL_DYNAMIC; flags |= SL_DYNAMIC;
if(!frontfloor && !backfloor && !frontceil && !backceil) if(!frontfloor && !backfloor && !frontceil && !backceil)
{ {
CONS_Printf("P_SpawnSlope_Line called with non-slope line special.\n"); CONS_Printf("line_SpawnViaLine: Slope special with nothing to do.\n");
return; return;
} }
if(!line->frontsector || !line->backsector) if(!line->frontsector || !line->backsector)
{ {
CONS_Debug(DBG_SETUP, "P_SpawnSlope_Line used on a line without two sides. (line number %i)\n", linenum); CONS_Debug(DBG_SETUP, "line_SpawnViaLine: Slope special used on a line without two sides. (line number %i)\n", linenum);
return; return;
} }
@ -297,7 +295,7 @@ static void line_SpawnViaLine(const int linenum, const boolean spawnthinker)
if(extent < 0) if(extent < 0)
{ {
CONS_Printf("P_SpawnSlope_Line failed to get frontsector extent on line number %i\n", linenum); CONS_Printf("line_SpawnViaLine failed to get frontsector extent on line number %i\n", linenum);
return; return;
} }
@ -363,7 +361,7 @@ static void line_SpawnViaLine(const int linenum, const boolean spawnthinker)
if(extent < 0) if(extent < 0)
{ {
CONS_Printf("P_SpawnSlope_Line failed to get backsector extent on line number %i\n", linenum); CONS_Printf("line_SpawnViaLine failed to get backsector extent on line number %i\n", linenum);
return; return;
} }
@ -428,11 +426,11 @@ static pslope_t *MakeViaMapthings(INT16 tag1, INT16 tag2, INT16 tag3, UINT8 flag
if (mt->type != 750) // Haha, I'm hijacking the old Chaos Spawn thingtype for something! if (mt->type != 750) // Haha, I'm hijacking the old Chaos Spawn thingtype for something!
continue; continue;
if (!vertices[0] && mt->angle == tag1) if (!vertices[0] && mt->tag == tag1)
vertices[0] = mt; vertices[0] = mt;
else if (!vertices[1] && mt->angle == tag2) else if (!vertices[1] && mt->tag == tag2)
vertices[1] = mt; vertices[1] = mt;
else if (!vertices[2] && mt->angle == tag3) else if (!vertices[2] && mt->tag == tag3)
vertices[2] = mt; vertices[2] = mt;
} }
@ -462,44 +460,36 @@ static void line_SpawnViaMapthingVertexes(const int linenum, const boolean spawn
line_t *line = lines + linenum; line_t *line = lines + linenum;
side_t *side; side_t *side;
pslope_t **slopetoset; pslope_t **slopetoset;
UINT16 tag1, tag2, tag3; UINT16 tag1 = line->args[1];
UINT16 tag2 = line->args[2];
UINT8 flags = 0; UINT16 tag3 = line->args[3];
if (line->flags & ML_NETONLY) UINT8 flags = 0; // Slope flags
if (line->args[4] & TMSL_NOPHYSICS)
flags |= SL_NOPHYSICS; flags |= SL_NOPHYSICS;
if (line->flags & ML_NONET) if (line->args[4] & TMSL_DYNAMIC)
flags |= SL_DYNAMIC; flags |= SL_DYNAMIC;
switch(line->special) switch(line->args[0])
{ {
case 704: case TMSP_FRONTFLOOR:
slopetoset = &line->frontsector->f_slope; slopetoset = &line->frontsector->f_slope;
side = &sides[line->sidenum[0]]; side = &sides[line->sidenum[0]];
break; break;
case 705: case TMSP_FRONTCEILING:
slopetoset = &line->frontsector->c_slope; slopetoset = &line->frontsector->c_slope;
side = &sides[line->sidenum[0]]; side = &sides[line->sidenum[0]];
break; break;
case 714: case TMSP_BACKFLOOR:
slopetoset = &line->backsector->f_slope; slopetoset = &line->backsector->f_slope;
side = &sides[line->sidenum[1]]; side = &sides[line->sidenum[1]];
break; break;
case 715: case TMSP_BACKCEILING:
slopetoset = &line->backsector->c_slope; slopetoset = &line->backsector->c_slope;
side = &sides[line->sidenum[1]]; side = &sides[line->sidenum[1]];
default: default:
return; return;
} }
if (line->flags & ML_EFFECT6)
{
tag1 = line->tag;
tag2 = side->textureoffset >> FRACBITS;
tag3 = side->rowoffset >> FRACBITS;
}
else
tag1 = tag2 = tag3 = line->tag;
*slopetoset = MakeViaMapthings(tag1, tag2, tag3, flags, spawnthinker); *slopetoset = MakeViaMapthings(tag1, tag2, tag3, flags, spawnthinker);
side->sector->hasslope = true; side->sector->hasslope = true;
@ -555,6 +545,47 @@ static void SpawnVertexSlopes(void)
} }
} }
static boolean P_SetSlopeFromTag(sector_t *sec, INT32 tag, boolean ceiling)
{
INT32 i;
pslope_t **secslope = ceiling ? &sec->c_slope : &sec->f_slope;
if (!tag || *secslope)
return false;
for (i = -1; (i = P_FindSectorFromTag(tag, i)) >= 0;)
{
pslope_t *srcslope = ceiling ? sectors[i].c_slope : sectors[i].f_slope;
if (srcslope)
{
*secslope = srcslope;
return true;
}
}
return false;
}
static boolean P_CopySlope(pslope_t **toslope, pslope_t *fromslope)
{
if (*toslope || !fromslope)
return true;
*toslope = fromslope;
return true;
}
static void P_UpdateHasSlope(sector_t *sec)
{
size_t i;
sec->hasslope = true;
// if this is an FOF control sector, make sure any target sectors also are marked as having slopes
if (sec->numattached)
for (i = 0; i < sec->numattached; i++)
sectors[sec->attached[i]].hasslope = true;
}
// //
// P_CopySectorSlope // P_CopySectorSlope
// //
@ -563,25 +594,31 @@ static void SpawnVertexSlopes(void)
void P_CopySectorSlope(line_t *line) void P_CopySectorSlope(line_t *line)
{ {
sector_t *fsec = line->frontsector; sector_t *fsec = line->frontsector;
int i, special = line->special; sector_t *bsec = line->backsector;
boolean setfront = false;
boolean setback = false;
// Check for copy linedefs setfront |= P_SetSlopeFromTag(fsec, line->args[0], false);
for (i = -1; (i = P_FindSectorFromTag(line->tag, i)) >= 0;) setfront |= P_SetSlopeFromTag(fsec, line->args[1], true);
if (bsec)
{ {
sector_t *srcsec = sectors + i; setback |= P_SetSlopeFromTag(bsec, line->args[2], false);
setback |= P_SetSlopeFromTag(bsec, line->args[3], true);
if ((special - 719) & 1 && !fsec->f_slope && srcsec->f_slope) if (line->args[4] & TMSC_FRONTTOBACKFLOOR)
fsec->f_slope = srcsec->f_slope; //P_CopySlope(srcsec->f_slope); setback |= P_CopySlope(&bsec->f_slope, fsec->f_slope);
if ((special - 719) & 2 && !fsec->c_slope && srcsec->c_slope) if (line->args[4] & TMSC_BACKTOFRONTFLOOR)
fsec->c_slope = srcsec->c_slope; //P_CopySlope(srcsec->c_slope); setfront |= P_CopySlope(&fsec->f_slope, bsec->f_slope);
if (line->args[4] & TMSC_FRONTTOBACKCEILING)
setback |= P_CopySlope(&bsec->c_slope, fsec->c_slope);
if (line->args[4] & TMSC_BACKTOFRONTCEILING)
setfront |= P_CopySlope(&fsec->c_slope, bsec->c_slope);
} }
fsec->hasslope = true; if (setfront)
P_UpdateHasSlope(fsec);
// if this is an FOF control sector, make sure any target sectors also are marked as having slopes if (setback)
if (fsec->numattached) P_UpdateHasSlope(bsec);
for (i = 0; i < (int)fsec->numattached; i++)
sectors[fsec->attached[i]].hasslope = true;
line->special = 0; // Linedef was use to set slopes, it finished its job, so now make it a normal linedef line->special = 0; // Linedef was use to set slopes, it finished its job, so now make it a normal linedef
} }
@ -614,20 +651,10 @@ void P_SpawnSlopes(const boolean fromsave) {
switch (lines[i].special) switch (lines[i].special)
{ {
case 700: case 700:
case 701:
case 702:
case 703:
case 710:
case 711:
case 712:
case 713:
line_SpawnViaLine(i, !fromsave); line_SpawnViaLine(i, !fromsave);
break; break;
case 704: case 704:
case 705:
case 714:
case 715:
line_SpawnViaMapthingVertexes(i, !fromsave); line_SpawnViaMapthingVertexes(i, !fromsave);
break; break;
@ -642,8 +669,6 @@ void P_SpawnSlopes(const boolean fromsave) {
switch (lines[i].special) switch (lines[i].special)
{ {
case 720: case 720:
case 721:
case 722:
P_CopySectorSlope(&lines[i]); P_CopySectorSlope(&lines[i]);
default: default:
break; break;

View File

@ -18,6 +18,35 @@
extern pslope_t *slopelist; extern pslope_t *slopelist;
extern UINT16 slopecount; extern UINT16 slopecount;
typedef enum
{
TMSP_FRONTFLOOR,
TMSP_FRONTCEILING,
TMSP_BACKFLOOR,
TMSP_BACKCEILING,
} textmapslopeplane_t;
typedef enum
{
TMSC_FRONTTOBACKFLOOR = 1,
TMSC_BACKTOFRONTFLOOR = 1<<1,
TMSC_FRONTTOBACKCEILING = 1<<2,
TMSC_BACKTOFRONTCEILING = 1<<3,
} textmapslopecopy_t;
typedef enum
{
TMS_NONE,
TMS_FRONT,
TMS_BACK,
} textmapside_t;
typedef enum
{
TMSL_NOPHYSICS = 1,
TMSL_DYNAMIC = 2,
} textmapslopeflags_t;
void P_LinkSlopeThinkers (void); void P_LinkSlopeThinkers (void);
void P_CalculateSlopeNormal(pslope_t *slope); void P_CalculateSlopeNormal(pslope_t *slope);

View File

@ -1496,30 +1496,6 @@ void P_RunNightsCapsuleTouchExecutors(mobj_t *actor, boolean entering, boolean e
} }
} }
/** Hashes the sector tags across the sectors and linedefs.
*
* \sa P_FindSectorFromTag, P_ChangeSectorTag
* \author Lee Killough
*/
static inline void P_InitTagLists(void)
{
register size_t i;
for (i = numsectors - 1; i != (size_t)-1; i--)
{
size_t j = (unsigned)sectors[i].tag % numsectors;
sectors[i].nexttag = sectors[j].firsttag;
sectors[j].firsttag = (INT32)i;
}
for (i = numlines - 1; i != (size_t)-1; i--)
{
size_t j = (unsigned)lines[i].tag % numlines;
lines[i].nexttag = lines[j].firsttag;
lines[j].firsttag = (INT32)i;
}
}
/** Finds minimum light from an adjacent sector. /** Finds minimum light from an adjacent sector.
* *
* \param sector Sector to start in. * \param sector Sector to start in.
@ -1563,16 +1539,24 @@ void T_ExecutorDelay(executor_t *e)
static void P_AddExecutorDelay(line_t *line, mobj_t *mobj, sector_t *sector) static void P_AddExecutorDelay(line_t *line, mobj_t *mobj, sector_t *sector)
{ {
executor_t *e; executor_t *e;
INT32 delay;
if (!line->backsector) if (udmf)
I_Error("P_AddExecutorDelay: Line has no backsector!\n"); delay = line->executordelay;
else
{
if (!line->backsector)
I_Error("P_AddExecutorDelay: Line has no backsector!\n");
delay = (line->backsector->ceilingheight >> FRACBITS) + (line->backsector->floorheight >> FRACBITS);
}
e = Z_Calloc(sizeof (*e), PU_LEVSPEC, NULL); e = Z_Calloc(sizeof (*e), PU_LEVSPEC, NULL);
e->thinker.function.acp1 = (actionf_p1)T_ExecutorDelay; e->thinker.function.acp1 = (actionf_p1)T_ExecutorDelay;
e->line = line; e->line = line;
e->sector = sector; e->sector = sector;
e->timer = (line->backsector->ceilingheight>>FRACBITS)+(line->backsector->floorheight>>FRACBITS); e->timer = delay;
P_SetTarget(&e->caller, mobj); // Use P_SetTarget to make sure the mobj doesn't get freed while we're delaying. P_SetTarget(&e->caller, mobj); // Use P_SetTarget to make sure the mobj doesn't get freed while we're delaying.
P_AddThinker(THINK_MAIN, &e->thinker); P_AddThinker(THINK_MAIN, &e->thinker);
} }
@ -1973,7 +1957,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
if (ctlsector->lines[i]->special >= 400 if (ctlsector->lines[i]->special >= 400
&& ctlsector->lines[i]->special < 500) && ctlsector->lines[i]->special < 500)
{ {
if (ctlsector->lines[i]->flags & ML_DONTPEGTOP) if (ctlsector->lines[i]->executordelay)
P_AddExecutorDelay(ctlsector->lines[i], actor, caller); P_AddExecutorDelay(ctlsector->lines[i], actor, caller);
else else
P_ProcessLineSpecial(ctlsector->lines[i], actor, caller); P_ProcessLineSpecial(ctlsector->lines[i], actor, caller);
@ -2061,7 +2045,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
if (ctlsector->lines[i]->special >= 400 if (ctlsector->lines[i]->special >= 400
&& ctlsector->lines[i]->special < 500) && ctlsector->lines[i]->special < 500)
{ {
if (ctlsector->lines[i]->flags & ML_DONTPEGTOP) if (ctlsector->lines[i]->executordelay)
P_AddExecutorDelay(ctlsector->lines[i], actor, caller); P_AddExecutorDelay(ctlsector->lines[i], actor, caller);
else else
P_ProcessLineSpecial(ctlsector->lines[i], actor, caller); P_ProcessLineSpecial(ctlsector->lines[i], actor, caller);
@ -3294,10 +3278,10 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
} }
case 443: // Calls a named Lua function case 443: // Calls a named Lua function
if (line->text) if (line->stringargs[0])
LUAh_LinedefExecute(line, mo, callsec); LUAh_LinedefExecute(line, mo, callsec);
else else
CONS_Alert(CONS_WARNING, "Linedef %s is missing the hook name of the Lua function to call! (This should be given in the front texture fields)\n", sizeu1(line-lines)); CONS_Alert(CONS_WARNING, "Linedef %s is missing the hook name of the Lua function to call! (This should be given in arg0str)\n", sizeu1(line-lines));
break; break;
case 444: // Earthquake camera case 444: // Earthquake camera
@ -3420,46 +3404,53 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
// Except it is activated by linedef executor, not level load // Except it is activated by linedef executor, not level load
// This could even override existing colormaps I believe // This could even override existing colormaps I believe
// -- Monster Iestyn 14/06/18 // -- Monster Iestyn 14/06/18
for (secnum = -1; (secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0 ;) {
extracolormap_t *source;
if (!udmf)
source = sides[line->sidenum[0]].colormap_data;
else
{ {
if (!line->args[1])
source = line->frontsector->extra_colormap;
else
{
INT32 sourcesec = P_FindSectorFromTag(line->args[1], -1);
if (sourcesec == -1)
{
CONS_Debug(DBG_GAMELOGIC, "Line type 447 Executor: Can't find sector with source colormap (tag %d)!\n", line->args[1]);
return;
}
source = sectors[sourcesec].extra_colormap;
}
}
for (secnum = -1; (secnum = P_FindSectorFromTag(line->args[0], secnum)) >= 0;)
{
if (sectors[secnum].colormap_protected)
continue;
P_ResetColormapFader(&sectors[secnum]); P_ResetColormapFader(&sectors[secnum]);
if (line->flags & ML_EFFECT3) // relative calc if (line->args[2] & TMCF_RELATIVE)
{ {
extracolormap_t *exc = R_AddColormaps( extracolormap_t *target = (!udmf && (line->flags & ML_TFERLINE) && line->sidenum[1] != 0xFFFF) ?
(line->flags & ML_TFERLINE) && line->sidenum[1] != 0xFFFF ? sides[line->sidenum[1]].colormap_data : sectors[secnum].extra_colormap; // use back colormap instead of target sector
sides[line->sidenum[1]].colormap_data : sectors[secnum].extra_colormap, // use back colormap instead of target sector
sides[line->sidenum[0]].colormap_data,
line->flags & ML_EFFECT1, // subtract R
line->flags & ML_NOCLIMB, // subtract G
line->flags & ML_EFFECT2, // subtract B
false, // subtract A (no flag for this, just pass negative alpha)
line->flags & ML_EFFECT1, // subtract FadeR
line->flags & ML_NOCLIMB, // subtract FadeG
line->flags & ML_EFFECT2, // subtract FadeB
false, // subtract FadeA (no flag for this, just pass negative alpha)
false, // subtract FadeStart (we ran out of flags)
false, // subtract FadeEnd (we ran out of flags)
false, // ignore Flags (we ran out of flags)
line->flags & ML_DONTPEGBOTTOM,
(line->flags & ML_DONTPEGBOTTOM) ? (sides[line->sidenum[0]].textureoffset >> FRACBITS) : 0,
(line->flags & ML_DONTPEGBOTTOM) ? (sides[line->sidenum[0]].rowoffset >> FRACBITS) : 0,
false);
if (!(sectors[secnum].extra_colormap = R_GetColormapFromList(exc))) extracolormap_t *exc = R_AddColormaps(
{ target,
exc->colormap = R_CreateLightTable(exc); source,
R_AddColormapToList(exc); line->args[2] & TMCF_SUBLIGHTR,
sectors[secnum].extra_colormap = exc; line->args[2] & TMCF_SUBLIGHTG,
} line->args[2] & TMCF_SUBLIGHTB,
else line->args[2] & TMCF_SUBLIGHTA,
Z_Free(exc); line->args[2] & TMCF_SUBFADER,
} line->args[2] & TMCF_SUBFADEG,
else if (line->flags & ML_DONTPEGBOTTOM) // alternate alpha (by texture offsets) line->args[2] & TMCF_SUBFADEB,
{ line->args[2] & TMCF_SUBFADEA,
extracolormap_t *exc = R_CopyColormap(sides[line->sidenum[0]].colormap_data, false); line->args[2] & TMCF_SUBFADESTART,
exc->rgba = R_GetRgbaRGB(exc->rgba) + R_PutRgbaA(max(min(sides[line->sidenum[0]].textureoffset >> FRACBITS, 25), 0)); line->args[2] & TMCF_SUBFADEEND,
exc->fadergba = R_GetRgbaRGB(exc->fadergba) + R_PutRgbaA(max(min(sides[line->sidenum[0]].rowoffset >> FRACBITS, 25), 0)); line->args[2] & TMCF_IGNOREFLAGS,
false);
if (!(sectors[secnum].extra_colormap = R_GetColormapFromList(exc))) if (!(sectors[secnum].extra_colormap = R_GetColormapFromList(exc)))
{ {
@ -3471,10 +3462,10 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
Z_Free(exc); Z_Free(exc);
} }
else else
sectors[secnum].extra_colormap = sides[line->sidenum[0]].colormap_data; sectors[secnum].extra_colormap = source;
} }
break; break;
}
case 448: // Change skybox viewpoint/centerpoint case 448: // Change skybox viewpoint/centerpoint
if ((mo && mo->player && P_IsLocalPlayer(mo->player)) || (line->flags & ML_NOCLIMB)) if ((mo && mo->player && P_IsLocalPlayer(mo->player)) || (line->flags & ML_NOCLIMB))
{ {
@ -3748,15 +3739,35 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
} }
case 455: // Fade colormap case 455: // Fade colormap
for (secnum = -1; (secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0 ;) {
extracolormap_t *dest;
if (!udmf)
dest = sides[line->sidenum[0]].colormap_data;
else
{
if (!line->args[1])
dest = line->frontsector->extra_colormap;
else
{
INT32 destsec = P_FindSectorFromTag(line->args[1], -1);
if (destsec == -1)
{
CONS_Debug(DBG_GAMELOGIC, "Line type 455 Executor: Can't find sector with destination colormap (tag %d)!\n", line->args[1]);
return;
}
dest = sectors[destsec].extra_colormap;
}
}
for (secnum = -1; (secnum = P_FindSectorFromTag(line->args[0], secnum)) >= 0;)
{ {
extracolormap_t *source_exc, *dest_exc, *exc; extracolormap_t *source_exc, *dest_exc, *exc;
INT32 speed = (INT32)((line->flags & ML_DONTPEGBOTTOM) || !sides[line->sidenum[0]].rowoffset) && line->sidenum[1] != 0xFFFF ?
abs(sides[line->sidenum[1]].rowoffset >> FRACBITS)
: abs(sides[line->sidenum[0]].rowoffset >> FRACBITS);
// Prevent continuous execs from interfering on an existing fade if (sectors[secnum].colormap_protected)
if (!(line->flags & ML_EFFECT5) continue;
// Don't interrupt ongoing fade
if (!(line->args[3] & TMCF_OVERRIDE)
&& sectors[secnum].fadecolormapdata) && sectors[secnum].fadecolormapdata)
//&& ((fadecolormap_t*)sectors[secnum].fadecolormapdata)->timer > (ticbased ? 2 : speed*2)) //&& ((fadecolormap_t*)sectors[secnum].fadecolormapdata)->timer > (ticbased ? 2 : speed*2))
{ {
@ -3764,19 +3775,19 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
continue; continue;
} }
if (line->flags & ML_TFERLINE) // use back colormap instead of target sector if (!udmf && (line->flags & ML_TFERLINE)) // use back colormap instead of target sector
sectors[secnum].extra_colormap = (line->sidenum[1] != 0xFFFF) ? sectors[secnum].extra_colormap = (line->sidenum[1] != 0xFFFF) ?
sides[line->sidenum[1]].colormap_data : NULL; sides[line->sidenum[1]].colormap_data : NULL;
exc = sectors[secnum].extra_colormap; exc = sectors[secnum].extra_colormap;
if (!(line->flags & ML_BOUNCY) // BOUNCY: Do not override fade from default rgba if (!(line->args[3] & TMCF_FROMBLACK) // Override fade from default rgba
&& !R_CheckDefaultColormap(sides[line->sidenum[0]].colormap_data, true, false, false) && !R_CheckDefaultColormap(dest, true, false, false)
&& R_CheckDefaultColormap(exc, true, false, false)) && R_CheckDefaultColormap(exc, true, false, false))
{ {
exc = R_CopyColormap(exc, false); exc = R_CopyColormap(exc, false);
exc->rgba = R_GetRgbaRGB(sides[line->sidenum[0]].colormap_data->rgba) + R_PutRgbaA(R_GetRgbaA(exc->rgba)); exc->rgba = R_GetRgbaRGB(dest->rgba) + R_PutRgbaA(R_GetRgbaA(exc->rgba));
//exc->fadergba = R_GetRgbaRGB(sides[line->sidenum[0]].colormap_data->rgba) + R_PutRgbaA(R_GetRgbaA(exc->fadergba)); //exc->fadergba = R_GetRgbaRGB(dest->rgba) + R_PutRgbaA(R_GetRgbaA(exc->fadergba));
if (!(source_exc = R_GetColormapFromList(exc))) if (!(source_exc = R_GetColormapFromList(exc)))
{ {
@ -3792,35 +3803,26 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
else else
source_exc = exc ? exc : R_GetDefaultColormap(); source_exc = exc ? exc : R_GetDefaultColormap();
if (line->flags & ML_EFFECT3) // relative calc if (line->args[3] & TMCF_RELATIVE)
{ {
exc = R_AddColormaps( exc = R_AddColormaps(
source_exc, source_exc,
sides[line->sidenum[0]].colormap_data, dest,
line->flags & ML_EFFECT1, // subtract R line->args[3] & TMCF_SUBLIGHTR,
line->flags & ML_NOCLIMB, // subtract G line->args[3] & TMCF_SUBLIGHTG,
line->flags & ML_EFFECT2, // subtract B line->args[3] & TMCF_SUBLIGHTB,
false, // subtract A (no flag for this, just pass negative alpha) line->args[3] & TMCF_SUBLIGHTA,
line->flags & ML_EFFECT1, // subtract FadeR line->args[3] & TMCF_SUBFADER,
line->flags & ML_NOCLIMB, // subtract FadeG line->args[3] & TMCF_SUBFADEG,
line->flags & ML_EFFECT2, // subtract FadeB line->args[3] & TMCF_SUBFADEB,
false, // subtract FadeA (no flag for this, just pass negative alpha) line->args[3] & TMCF_SUBFADEA,
false, // subtract FadeStart (we ran out of flags) line->args[3] & TMCF_SUBFADESTART,
false, // subtract FadeEnd (we ran out of flags) line->args[3] & TMCF_SUBFADEEND,
false, // ignore Flags (we ran out of flags) line->args[3] & TMCF_IGNOREFLAGS,
line->flags & ML_DONTPEGBOTTOM,
(line->flags & ML_DONTPEGBOTTOM) ? (sides[line->sidenum[0]].textureoffset >> FRACBITS) : 0,
(line->flags & ML_DONTPEGBOTTOM) ? (sides[line->sidenum[0]].rowoffset >> FRACBITS) : 0,
false); false);
} }
else if (line->flags & ML_DONTPEGBOTTOM) // alternate alpha (by texture offsets)
{
exc = R_CopyColormap(sides[line->sidenum[0]].colormap_data, false);
exc->rgba = R_GetRgbaRGB(exc->rgba) + R_PutRgbaA(max(min(sides[line->sidenum[0]].textureoffset >> FRACBITS, 25), 0));
exc->fadergba = R_GetRgbaRGB(exc->fadergba) + R_PutRgbaA(max(min(sides[line->sidenum[0]].rowoffset >> FRACBITS, 25), 0));
}
else else
exc = R_CopyColormap(sides[line->sidenum[0]].colormap_data, false); exc = R_CopyColormap(dest, false);
if (!(dest_exc = R_GetColormapFromList(exc))) if (!(dest_exc = R_GetColormapFromList(exc)))
{ {
@ -3831,13 +3833,13 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
else else
Z_Free(exc); Z_Free(exc);
Add_ColormapFader(&sectors[secnum], source_exc, dest_exc, (line->flags & ML_EFFECT4), // tic-based timing Add_ColormapFader(&sectors[secnum], source_exc, dest_exc, true, // tic-based timing
speed); line->args[2]);
} }
break; break;
}
case 456: // Stop fade colormap case 456: // Stop fade colormap
for (secnum = -1; (secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0 ;) for (secnum = -1; (secnum = P_FindSectorFromTag(line->args[0], secnum)) >= 0 ;)
P_ResetColormapFader(&sectors[secnum]); P_ResetColormapFader(&sectors[secnum]);
break; break;
@ -4027,6 +4029,23 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
} }
break; break;
case 465: // Set linedef executor delay
{
INT32 linenum;
if (!udmf)
break;
for (linenum = -1; (linenum = P_FindLineFromTag(line->args[0], linenum)) >= 0 ;)
{
if (line->args[2])
lines[linenum].executordelay += line->args[1];
else
lines[linenum].executordelay = line->args[1];
}
}
break;
case 480: // Polyobj_DoorSlide case 480: // Polyobj_DoorSlide
case 481: // Polyobj_DoorSwing case 481: // Polyobj_DoorSwing
PolyDoor(line); PolyDoor(line);
@ -5890,7 +5909,7 @@ static void P_AddRaiseThinker(sector_t *sec, INT16 tag, fixed_t speed, fixed_t c
raise->ceilingtop = ceilingtop; raise->ceilingtop = ceilingtop;
raise->ceilingbottom = ceilingbottom; raise->ceilingbottom = ceilingbottom;
raise->basespeed = speed; raise->basespeed = speed;
if (lower) if (lower)
raise->flags |= RF_REVERSE; raise->flags |= RF_REVERSE;
@ -6133,7 +6152,7 @@ static void P_RunLevelLoadExecutors(void)
* by P_SpawnSlopes or P_LoadThings. This was split off from * by P_SpawnSlopes or P_LoadThings. This was split off from
* P_SpawnSpecials, in case you couldn't tell. * P_SpawnSpecials, in case you couldn't tell.
* *
* \sa P_SpawnSpecials, P_InitTagLists * \sa P_SpawnSpecials
* \author Monster Iestyn * \author Monster Iestyn
*/ */
void P_InitSpecials(void) void P_InitSpecials(void)
@ -6164,8 +6183,6 @@ void P_InitSpecials(void)
// Set globalweather // Set globalweather
globalweather = mapheaderinfo[gamemap-1]->weather; globalweather = mapheaderinfo[gamemap-1]->weather;
P_InitTagLists(); // Create xref tables for tags
} }
static void P_ApplyFlatAlignment(line_t *master, sector_t *sector, angle_t flatangle, fixed_t xoffs, fixed_t yoffs) static void P_ApplyFlatAlignment(line_t *master, sector_t *sector, angle_t flatangle, fixed_t xoffs, fixed_t yoffs)
@ -7145,8 +7162,32 @@ void P_SpawnSpecials(boolean fromnetsave)
break; break;
case 606: // HACK! Copy colormaps. Just plain colormaps. case 606: // HACK! Copy colormaps. Just plain colormaps.
for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) for (s = -1; (s = P_FindSectorFromTag(lines[i].args[0], s)) >= 0;)
sectors[s].extra_colormap = sectors[s].spawn_extra_colormap = sides[lines[i].sidenum[0]].colormap_data; {
extracolormap_t *exc;
if (sectors[s].colormap_protected)
continue;
if (!udmf)
exc = sides[lines[i].sidenum[0]].colormap_data;
else
{
if (!lines[i].args[1])
exc = lines[i].frontsector->extra_colormap;
else
{
INT32 sourcesec = P_FindSectorFromTag(lines[i].args[1], -1);
if (sourcesec == -1)
{
CONS_Debug(DBG_GAMELOGIC, "Line type 606: Can't find sector with source colormap (tag %d)!\n", lines[i].args[1]);
return;
}
exc = sectors[sourcesec].extra_colormap;
}
}
sectors[s].extra_colormap = sectors[s].spawn_extra_colormap = exc;
}
break; break;
default: default:
@ -8109,7 +8150,7 @@ static void P_AddFakeFloorFader(ffloor_t *rover, size_t sectornum, size_t ffloor
d->destlightlevel = -1; d->destlightlevel = -1;
// Set a separate thinker for colormap fading // Set a separate thinker for colormap fading
if (docolormap && !(rover->flags & FF_NOSHADE) && sectors[rover->secnum].spawn_extra_colormap) if (docolormap && !(rover->flags & FF_NOSHADE) && sectors[rover->secnum].spawn_extra_colormap && !sectors[rover->secnum].colormap_protected)
{ {
extracolormap_t *dest_exc, extracolormap_t *dest_exc,
*source_exc = sectors[rover->secnum].extra_colormap ? sectors[rover->secnum].extra_colormap : R_GetDefaultColormap(); *source_exc = sectors[rover->secnum].extra_colormap ? sectors[rover->secnum].extra_colormap : R_GetDefaultColormap();

View File

@ -2080,7 +2080,7 @@ extracolormap_t *R_ColormapForName(char *name)
#endif #endif
// //
// R_CreateColormap // R_CreateColormapFromLinedef
// //
// This is a more GL friendly way of doing colormaps: Specify colormap // This is a more GL friendly way of doing colormaps: Specify colormap
// data in a special linedef's texture areas and use that to generate // data in a special linedef's texture areas and use that to generate
@ -2219,10 +2219,8 @@ lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap)
return lighttable; return lighttable;
} }
extracolormap_t *R_CreateColormap(char *p1, char *p2, char *p3) extracolormap_t *R_CreateColormapFromLinedef(char *p1, char *p2, char *p3)
{ {
extracolormap_t *extra_colormap, *exc;
// default values // default values
UINT8 cr = 0, cg = 0, cb = 0, ca = 0, cfr = 0, cfg = 0, cfb = 0, cfa = 25; UINT8 cr = 0, cg = 0, cb = 0, ca = 0, cfr = 0, cfg = 0, cfb = 0, cfa = 25;
UINT32 fadestart = 0, fadeend = 31; UINT32 fadestart = 0, fadeend = 31;
@ -2345,6 +2343,13 @@ extracolormap_t *R_CreateColormap(char *p1, char *p2, char *p3)
rgba = R_PutRgbaRGBA(cr, cg, cb, ca); rgba = R_PutRgbaRGBA(cr, cg, cb, ca);
fadergba = R_PutRgbaRGBA(cfr, cfg, cfb, cfa); fadergba = R_PutRgbaRGBA(cfr, cfg, cfb, cfa);
return R_CreateColormap(rgba, fadergba, fadestart, fadeend, flags);
}
extracolormap_t *R_CreateColormap(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 flags)
{
extracolormap_t *extra_colormap;
// Did we just make a default colormap? // Did we just make a default colormap?
#ifdef EXTRACOLORMAPLUMPS #ifdef EXTRACOLORMAPLUMPS
if (R_CheckDefaultColormapByValues(true, true, true, rgba, fadergba, fadestart, fadeend, flags, LUMPERROR)) if (R_CheckDefaultColormapByValues(true, true, true, rgba, fadergba, fadestart, fadeend, flags, LUMPERROR))
@ -2356,17 +2361,16 @@ extracolormap_t *R_CreateColormap(char *p1, char *p2, char *p3)
// Look for existing colormaps // Look for existing colormaps
#ifdef EXTRACOLORMAPLUMPS #ifdef EXTRACOLORMAPLUMPS
exc = R_GetColormapFromListByValues(rgba, fadergba, fadestart, fadeend, flags, LUMPERROR); extra_colormap = R_GetColormapFromListByValues(rgba, fadergba, fadestart, fadeend, flags, LUMPERROR);
#else #else
exc = R_GetColormapFromListByValues(rgba, fadergba, fadestart, fadeend, flags); extra_colormap = R_GetColormapFromListByValues(rgba, fadergba, fadestart, fadeend, flags);
#endif #endif
if (exc) if (extra_colormap)
return exc; return extra_colormap;
CONS_Debug(DBG_RENDER, "Creating Colormap: rgba(%d,%d,%d,%d) fadergba(%d,%d,%d,%d)\n", CONS_Debug(DBG_RENDER, "Creating Colormap: rgba(%x) fadergba(%x)\n", rgba, fadergba);
cr, cg, cb, ca, cfr, cfg, cfb, cfa);
extra_colormap = Z_Calloc(sizeof (*extra_colormap), PU_LEVEL, NULL); extra_colormap = Z_Calloc(sizeof(*extra_colormap), PU_LEVEL, NULL);
extra_colormap->fadestart = (UINT16)fadestart; extra_colormap->fadestart = (UINT16)fadestart;
extra_colormap->fadeend = (UINT16)fadeend; extra_colormap->fadeend = (UINT16)fadeend;
@ -2398,7 +2402,6 @@ extracolormap_t *R_AddColormaps(extracolormap_t *exc_augend, extracolormap_t *ex
boolean subR, boolean subG, boolean subB, boolean subA, boolean subR, boolean subG, boolean subB, boolean subA,
boolean subFadeR, boolean subFadeG, boolean subFadeB, boolean subFadeA, boolean subFadeR, boolean subFadeG, boolean subFadeB, boolean subFadeA,
boolean subFadeStart, boolean subFadeEnd, boolean ignoreFlags, boolean subFadeStart, boolean subFadeEnd, boolean ignoreFlags,
boolean useAltAlpha, INT16 altAlpha, INT16 altFadeAlpha,
boolean lighttable) boolean lighttable)
{ {
INT16 red, green, blue, alpha; INT16 red, green, blue, alpha;
@ -2434,7 +2437,7 @@ extracolormap_t *R_AddColormaps(extracolormap_t *exc_augend, extracolormap_t *ex
* R_GetRgbaB(exc_addend->rgba) * R_GetRgbaB(exc_addend->rgba)
, 255), 0); , 255), 0);
alpha = useAltAlpha ? altAlpha : R_GetRgbaA(exc_addend->rgba); alpha = R_GetRgbaA(exc_addend->rgba);
alpha = max(min(R_GetRgbaA(exc_augend->rgba) + (subA ? -1 : 1) * alpha, 25), 0); alpha = max(min(R_GetRgbaA(exc_augend->rgba) + (subA ? -1 : 1) * alpha, 25), 0);
exc_augend->rgba = R_PutRgbaRGBA(red, green, blue, alpha); exc_augend->rgba = R_PutRgbaRGBA(red, green, blue, alpha);
@ -2461,8 +2464,8 @@ extracolormap_t *R_AddColormaps(extracolormap_t *exc_augend, extracolormap_t *ex
* R_GetRgbaB(exc_addend->fadergba) * R_GetRgbaB(exc_addend->fadergba)
, 255), 0); , 255), 0);
alpha = useAltAlpha ? altFadeAlpha : R_GetRgbaA(exc_addend->fadergba); alpha = R_GetRgbaA(exc_addend->fadergba);
if (alpha == 25 && !useAltAlpha && !R_GetRgbaRGB(exc_addend->fadergba)) if (alpha == 25 && !R_GetRgbaRGB(exc_addend->fadergba))
alpha = 0; // HACK: fadergba A defaults at 25, so don't add anything in this case alpha = 0; // HACK: fadergba A defaults at 25, so don't add anything in this case
alpha = max(min(R_GetRgbaA(exc_augend->fadergba) + (subFadeA ? -1 : 1) * alpha, 25), 0); alpha = max(min(R_GetRgbaA(exc_augend->fadergba) + (subFadeA ? -1 : 1) * alpha, 25), 0);

View File

@ -149,13 +149,31 @@ boolean R_CheckDefaultColormap(extracolormap_t *extra_colormap, boolean checkrgb
boolean R_CheckEqualColormaps(extracolormap_t *exc_a, extracolormap_t *exc_b, boolean checkrgba, boolean checkfadergba, boolean checkparams); boolean R_CheckEqualColormaps(extracolormap_t *exc_a, extracolormap_t *exc_b, boolean checkrgba, boolean checkfadergba, boolean checkparams);
extracolormap_t *R_GetColormapFromList(extracolormap_t *extra_colormap); extracolormap_t *R_GetColormapFromList(extracolormap_t *extra_colormap);
typedef enum
{
TMCF_RELATIVE = 1,
TMCF_SUBLIGHTR = 1<<1,
TMCF_SUBLIGHTG = 1<<2,
TMCF_SUBLIGHTB = 1<<3,
TMCF_SUBLIGHTA = 1<<4,
TMCF_SUBFADER = 1<<5,
TMCF_SUBFADEG = 1<<6,
TMCF_SUBFADEB = 1<<7,
TMCF_SUBFADEA = 1<<8,
TMCF_SUBFADESTART = 1<<9,
TMCF_SUBFADEEND = 1<<10,
TMCF_IGNOREFLAGS = 1<<11,
TMCF_FROMBLACK = 1<<12,
TMCF_OVERRIDE = 1<<13,
} textmapcolormapflags_t;
lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap); lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap);
extracolormap_t *R_CreateColormap(char *p1, char *p2, char *p3); extracolormap_t * R_CreateColormapFromLinedef(char *p1, char *p2, char *p3);
extracolormap_t* R_CreateColormap(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 flags);
extracolormap_t *R_AddColormaps(extracolormap_t *exc_augend, extracolormap_t *exc_addend, extracolormap_t *R_AddColormaps(extracolormap_t *exc_augend, extracolormap_t *exc_addend,
boolean subR, boolean subG, boolean subB, boolean subA, boolean subR, boolean subG, boolean subB, boolean subA,
boolean subFadeR, boolean subFadeG, boolean subFadeB, boolean subFadeA, boolean subFadeR, boolean subFadeG, boolean subFadeB, boolean subFadeA,
boolean subFadeStart, boolean subFadeEnd, boolean ignoreFlags, boolean subFadeStart, boolean subFadeEnd, boolean ignoreFlags,
boolean useAltAlpha, INT16 altAlpha, INT16 altFadeAlpha,
boolean lighttable); boolean lighttable);
#ifdef EXTRACOLORMAPLUMPS #ifdef EXTRACOLORMAPLUMPS
extracolormap_t *R_ColormapForName(char *name); extracolormap_t *R_ColormapForName(char *name);

View File

@ -333,6 +333,7 @@ typedef struct sector_s
// per-sector colormaps! // per-sector colormaps!
extracolormap_t *extra_colormap; extracolormap_t *extra_colormap;
boolean colormap_protected;
// This points to the master's floorheight, so it can be changed in realtime! // This points to the master's floorheight, so it can be changed in realtime!
fixed_t *gravity; // per-sector gravity fixed_t *gravity; // per-sector gravity
@ -374,6 +375,9 @@ typedef enum
#define HORIZONSPECIAL 41 #define HORIZONSPECIAL 41
#define NUMLINEARGS 6
#define NUMLINESTRINGARGS 2
typedef struct line_s typedef struct line_s
{ {
// Vertices, from v1 to v2. // Vertices, from v1 to v2.
@ -386,9 +390,13 @@ typedef struct line_s
INT16 flags; INT16 flags;
INT16 special; INT16 special;
INT16 tag; INT16 tag;
INT32 args[NUMLINEARGS];
char *stringargs[NUMLINESTRINGARGS];
// Visual appearance: sidedefs. // Visual appearance: sidedefs.
UINT16 sidenum[2]; // sidenum[1] will be 0xffff if one-sided UINT16 sidenum[2]; // sidenum[1] will be 0xffff if one-sided
fixed_t alpha; // translucency
INT32 executordelay;
fixed_t bbox[4]; // bounding box for the extent of the linedef fixed_t bbox[4]; // bounding box for the extent of the linedef

View File

@ -274,6 +274,11 @@ static void R_Render2sidedMultiPatchColumn(column_t *column)
} }
} }
transnum_t R_GetLinedefTransTable(fixed_t alpha)
{
return (20*(FRACUNIT - alpha - 1) + FRACUNIT) >> (FRACBITS+1);
}
void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
{ {
size_t pindex; size_t pindex;
@ -300,31 +305,24 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
texnum = R_GetTextureNum(curline->sidedef->midtexture); texnum = R_GetTextureNum(curline->sidedef->midtexture);
windowbottom = windowtop = sprbotscreen = INT32_MAX; windowbottom = windowtop = sprbotscreen = INT32_MAX;
// hack translucent linedef types (900-909 for transtables 1-9)
ldef = curline->linedef; ldef = curline->linedef;
switch (ldef->special) if (!ldef->alpha)
return;
if (ldef->alpha > 0 && ldef->alpha < FRACUNIT)
{ {
case 900: dc_transmap = transtables + ((R_GetLinedefTransTable(ldef->alpha) - 1) << FF_TRANSSHIFT);
case 901: colfunc = colfuncs[COLDRAWFUNC_FUZZY];
case 902:
case 903:
case 904:
case 905:
case 906:
case 907:
case 908:
dc_transmap = transtables + ((ldef->special-900)<<FF_TRANSSHIFT);
colfunc = colfuncs[COLDRAWFUNC_FUZZY];
break;
case 909:
colfunc = colfuncs[COLDRAWFUNC_FOG];
windowtop = frontsector->ceilingheight;
windowbottom = frontsector->floorheight;
break;
default:
colfunc = colfuncs[BASEDRAWFUNC];
break;
} }
else if (ldef->special == 909)
{
colfunc = colfuncs[COLDRAWFUNC_FOG];
windowtop = frontsector->ceilingheight;
windowbottom = frontsector->floorheight;
}
else
colfunc = colfuncs[BASEDRAWFUNC];
if (curline->polyseg && curline->polyseg->translucency > 0) if (curline->polyseg && curline->polyseg->translucency > 0)
{ {

View File

@ -18,6 +18,7 @@
#pragma interface #pragma interface
#endif #endif
transnum_t R_GetLinedefTransTable(fixed_t alpha);
void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2); void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2);
void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pffloor); void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pffloor);
void R_StoreWallRange(INT32 start, INT32 stop); void R_StoreWallRange(INT32 start, INT32 stop);

View File

@ -52,6 +52,8 @@ extern size_t numspritelumps, max_spritelumps;
// //
// Lookup tables for map data. // Lookup tables for map data.
// //
extern boolean udmf;
extern size_t numsprites; extern size_t numsprites;
extern spritedef_t *sprites; extern spritedef_t *sprites;