Added GZDoom's glowing flats (http://www.zdoom.org/wiki/GLDEFS#Glowing_flats) support to Classic and Visual modes.

MAPINFO: added "DoomEdNum" and "SpawnNums" blocks support.
MAPINFO: added "#include" directive support.
MAPINFO: added "$gzdb_skip" special comment support.
DECORATE: "spawnthing" Game Configuration block is now updated using "SpawnID" actor property.
Game configurations: added "class" property to the most of ZDoom things.
Actions: removed "Reload MAPINFO" action.
Documentation: merged "GLDEFS and MODELDEF support", "(Z)MAPINFO support" and "TEXTURES support" topics into "(G)ZDoom text lumps support", added info about the other text lumps GZDB can use.
This commit is contained in:
MaxED 2015-04-14 11:33:57 +00:00
parent 56f9ad8469
commit 76559ae881
52 changed files with 1666 additions and 742 deletions

View file

@ -9,13 +9,17 @@ boom
sort = 1;
fixedsize = true;
5001 {
5001
{
title = "Pusher";
sprite = "internal:pointpusher";
class = "PointPusher";
}
5002 {
5002
{
title = "Puller";
sprite = "internal:pointpuller";
sprite = "internal:pointpuller";
class = "PointPuller";
}
}

View file

@ -15,27 +15,35 @@ players
{
title = "Player 1 start";
sprite = "PLAYA2A8";
class = "DoomPlayer";
class = "$Player1Start";
}
2
{
title = "Player 2 start";
sprite = "PLAYA2A8";
class = "$Player2Start";
}
3
{
title = "Player 3 start";
sprite = "PLAYA2A8";
class = "$Player3Start";
}
4
{
title = "Player 4 start";
sprite = "PLAYA2A8";
class = "$Player4Start";
}
11
{
title = "Player Deathmatch start";
sprite = "PLAYF1";
class = "$DeathmatchStart";
}
}
@ -56,6 +64,7 @@ teleports
{
title = "Teleport Destination";
sprite = "TFOGB0";
class = "TeleportDest";
}
}
@ -78,7 +87,6 @@ monsters
class = "ZombieMan";
}
9
{
title = "Former Sergeant";
@ -86,7 +94,6 @@ monsters
class = "ShotgunGuy";
}
3001
{
title = "Imp";
@ -94,7 +101,6 @@ monsters
class = "DoomImp";
}
3002
{
title = "Demon";
@ -103,7 +109,6 @@ monsters
class = "Demon";
}
58
{
title = "Spectre";
@ -112,7 +117,6 @@ monsters
class = "Spectre";
}
3006
{
title = "Lost Soul";
@ -121,7 +125,6 @@ monsters
class = "LostSoul";
}
3005
{
title = "Cacodemon";
@ -130,7 +133,6 @@ monsters
class = "Cacodemon";
}
3003
{
title = "Baron of Hell";
@ -140,7 +142,6 @@ monsters
class = "BaronOfHell";
}
16
{
title = "Cyberdemon";
@ -150,7 +151,6 @@ monsters
class = "Cyberdemon";
}
7
{
title = "Spider Mastermind";
@ -178,30 +178,35 @@ weapons
sprite = "CSAWA0";
class = "Chainsaw";
}
2001
{
title = "Shotgun";
sprite = "SHOTA0";
class = "Shotgun";
}
2002
{
title = "Chaingun";
sprite = "MGUNA0";
class = "Chaingun";
}
2003
{
title = "Rocket launcher";
sprite = "LAUNA0";
class = "RocketLauncher";
}
2004
{
title = "Plasma gun";
sprite = "PLASA0";
class = "PlasmaRifle";
}
2006
{
title = "BFG9000";
@ -228,12 +233,14 @@ ammunition
sprite = "CLIPA0";
class = "Clip";
}
2008
{
title = "Shotgun shells";
sprite = "SHELA0";
class = "Shell";
}
2010
{
title = "Rocket";
@ -241,24 +248,28 @@ ammunition
height = 25;
class = "RocketAmmo";
}
2047
{
title = "Cell charge";
sprite = "CELLA0";
class = "Cell";
}
2048
{
title = "Box of Ammo";
sprite = "AMMOA0";
class = "ClipBox";
}
2049
{
title = "Box of Shells";
sprite = "SBOXA0";
class = "ShellBox";
}
2046
{
title = "Box of Rockets";
@ -266,6 +277,7 @@ ammunition
height = 25;
class = "RocketBox";
}
17
{
title = "Cell charge pack";
@ -273,6 +285,7 @@ ammunition
height = 25;
class = "CellPack";
}
8
{
title = "Backpack";
@ -298,6 +311,7 @@ health
sprite = "STIMA0";
class = "Stimpack";
}
2012
{
title = "Medikit";
@ -305,24 +319,28 @@ health
height = 25;
class = "Medikit";
}
2014
{
title = "Health bonus";
sprite = "BON1A0";
class = "HealthBonus";
}
2015
{
title = "Armor bonus";
sprite = "BON2A0";
class = "ArmorBonus";
}
2018
{
title = "Green armor";
sprite = "ARM1A0";
class = "GreenArmor";
}
2019
{
title = "Blue armor";
@ -349,6 +367,7 @@ powerups
height = 45;
class = "Soulsphere";
}
2022
{
title = "Invulnerability";
@ -356,12 +375,14 @@ powerups
height = 30;
class = "InvulnerabilitySphere";
}
2023
{
title = "Berserk";
sprite = "PSTRA0";
class = "Berserk";
}
2024
{
title = "Invisibility";
@ -369,6 +390,7 @@ powerups
height = 45;
class = "BlurSphere";
}
2025
{
title = "Radiation suit";
@ -376,6 +398,7 @@ powerups
height = 60;
class = "RadSuit";
}
2026
{
title = "Computer map";
@ -383,6 +406,7 @@ powerups
height = 35;
class = "Allmap";
}
2045
{
title = "Lite Amplification goggles";
@ -408,30 +432,35 @@ keys
sprite = "BKEYA0";
class = "BlueCard";
}
40
{
title = "Blue skullkey";
sprite = "BSKUB0";
class = "BlueSkull";
}
13
{
title = "Red keycard";
sprite = "RKEYA0";
class = "RedCard";
}
38
{
title = "Red skullkey";
sprite = "RSKUB0";
class = "RedSkull";
}
6
{
title = "Yellow keycard";
sprite = "YKEYA0";
class = "YellowCard";
}
39
{
title = "Yellow skullkey";
@ -460,60 +489,70 @@ obstacles
height = 32;
class = "ExplosiveBarrel";
}
48
{
title = "Tall techno pillar";
sprite = "ELECA0";
class = "TechPillar";
}
30
{
title = "Tall green pillar";
sprite = "COL1A0";
class = "TallGreenColumn";
}
32
{
title = "Tall red pillar";
sprite = "COL3A0";
class = "TallRedColumn";
}
31
{
title = "Short green pillar";
sprite = "COL2A0";
class = "ShortGreenColumn";
}
36
{
title = "Short green pillar (beating heart)";
sprite = "COL5A0";
class = "HeartColumn";
}
33
{
title = "Short red pillar";
sprite = "COL4A0";
class = "ShortRedColumn";
}
37
{
title = "Short red pillar (skull)";
sprite = "COL6A0";
class = "SkullColumn";
}
47
{
title = "Stalagmite";
sprite = "SMITA0";
class = "Stalagmite";
}
43
{
title = "Gray tree";
sprite = "TRE1A0";
class = "TorchTree";
}
54
{
title = "Large brown tree";
@ -521,12 +560,14 @@ obstacles
sprite = "TRE2A0";
class = "BigTree";
}
41
{
title = "Evil Eye";
sprite = "CEYEA0";
class = "EvilEye";
}
42
{
title = "Floating skull rock";
@ -553,6 +594,7 @@ lights
sprite = "COLUA0";
class = "Column";
}
34
{
title = "Candle";
@ -562,42 +604,49 @@ lights
error = 1;
class = "Candlestick";
}
35
{
title = "Candelabra";
sprite = "CBRAA0";
class = "Candelabra";
}
44
{
title = "Tall blue firestick";
sprite = "TBLUA0";
class = "BlueTorch";
}
45
{
title = "Tall green firestick";
sprite = "TGRNA0";
class = "GreenTorch";
}
46
{
title = "Tall red firestick";
sprite = "TREDA0";
class = "RedTorch";
}
55
{
title = "Short blue firestick";
sprite = "SMBTA0";
class = "ShortBlueTorch";
}
56
{
title = "Short green firestick";
sprite = "SMGTA0";
class = "ShortGreenTorch";
}
57
{
title = "Short red firestick";
@ -629,7 +678,6 @@ decoration
class = "BloodyTwitch";
}
63
{
title = "Hanging victim, twitching";
@ -639,7 +687,6 @@ decoration
class = "NonsolidTwitch";
}
50
{
title = "Hanging victim, arms out (blocking)";
@ -651,7 +698,6 @@ decoration
class = "Meat2";
}
59
{
title = "Hanging victim, arms out";
@ -661,7 +707,6 @@ decoration
class = "NonsolidMeat2";
}
52
{
title = "Hanging pair of legs (blocking)";
@ -674,7 +719,6 @@ decoration
class = "Meat4";
}
60
{
title = "Hanging pair of legs";
@ -684,7 +728,6 @@ decoration
class = "NonsolidMeat4";
}
51
{
title = "Hanging victim, 1-legged (blocking)";
@ -697,7 +740,6 @@ decoration
class = "HangingCorpse";
}
61
{
title = "Hanging victim, 1-legged";
@ -707,7 +749,6 @@ decoration
class = "NonsolidMeat3";
}
53
{
title = "Hanging leg (blocking)";
@ -720,7 +761,6 @@ decoration
class = "Meat5";
}
62
{
title = "Hanging leg";
@ -730,7 +770,6 @@ decoration
class = "NonsolidMeat5";
}
25
{
title = "Impaled human";
@ -741,7 +780,6 @@ decoration
class = "DeadStick";
}
26
{
title = "Twitching impaled human";
@ -752,7 +790,6 @@ decoration
class = "LiveStick";
}
27
{
title = "Skull on a pole";
@ -763,7 +800,6 @@ decoration
class = "HeadOnAStick";
}
28
{
title = "5 skulls shish kebob";
@ -774,7 +810,6 @@ decoration
class = "HeadsOnAStick";
}
29
{
title = "Pile of skulls and candles";
@ -785,7 +820,6 @@ decoration
class = "HeadCandles";
}
10
{
title = "Bloody mess 1";
@ -793,7 +827,6 @@ decoration
class = "GibbedMarine";
}
12
{
title = "Bloody mess 2";
@ -801,7 +834,6 @@ decoration
class = "GibbedMarineExtra";
}
24
{
title = "Pool of blood and bones";
@ -809,7 +841,6 @@ decoration
class = "Gibs";
}
15
{
title = "Dead player";
@ -817,7 +848,6 @@ decoration
class = "DeadMarine";
}
18
{
title = "Dead former human";
@ -826,7 +856,6 @@ decoration
class = "DeadZombieMan";
}
19
{
title = "Dead former sergeant";
@ -835,7 +864,6 @@ decoration
class = "DeadShotgunGuy";
}
20
{
title = "Dead imp";
@ -844,7 +872,6 @@ decoration
class = "DeadDoomImp";
}
21
{
title = "Dead demon";
@ -853,7 +880,6 @@ decoration
class = "DeadDemon";
}
22
{
title = "Dead cacodemon";
@ -862,9 +888,9 @@ decoration
class = "DeadCacodemon";
}
23
{
title = "Dead lost soul";
class = "DeadLostSoul";
}
}

View file

@ -217,118 +217,6 @@ enums
spawnthing
{
0 = "None";
/*
T_NONE 0
T_CENTAUR 1
T_CENTAURLEADER 2
T_DEMON 3
T_ETTIN 4
T_FIREGARGOYLE 5
T_WATERLURKER 6
T_WATERLURKERLEADER 7
T_WRAITH 8
T_WRAITHBURIED 9
T_FIREBALL1 10
T_MANA1 11
T_MANA2 12
T_ITEMBOOTS 13
T_ITEMEGG 14
T_ITEMFLIGHT 15
T_ITEMSUMMON 16
T_ITEMTPORTOTHER 17
T_ITEMTELEPORT 18
T_BISHOP 19
T_ICEGOLEM 20
T_BRIDGE 21
T_DRAGONSKINBRACERS 22
T_ITEMHEALTHPOTION 23
T_ITEMHEALTHFLASK 24
T_ITEMHEALTHFULL 25
T_ITEMBOOSTMANA 26
T_FIGHTERAXE 27
T_FIGHTERHAMMER 28
T_FIGHTERSWORD1 29
T_FIGHTERSWORD2 30
T_FIGHTERSWORD3 31
T_CLERICSTAFF 32
T_CLERICHOLY1 33
T_CLERICHOLY2 34
T_CLERICHOLY3 35
T_MAGESHARDS 36
T_MAGESTAFF1 37
T_MAGESTAFF2 38
T_MAGESTAFF3 39
T_MORPHBLAST 40
T_ROCK1 41
T_ROCK2 42
T_ROCK3 43
T_DIRT1 44
T_DIRT2 45
T_DIRT3 46
T_DIRT4 47
T_DIRT5 48
T_DIRT6 49
T_ARROW 50
T_DART 51
T_POISONDART 52
T_RIPPERBALL 53
T_STAINEDGLASS1 54
T_STAINEDGLASS2 55
T_STAINEDGLASS3 56
T_STAINEDGLASS4 57
T_STAINEDGLASS5 58
T_STAINEDGLASS6 59
T_STAINEDGLASS7 60
T_STAINEDGLASS8 61
T_STAINEDGLASS9 62
T_STAINEDGLASS0 63
T_BLADE 64
T_ICESHARD 65
T_FLAME_SMALL 66
T_FLAME_LARGE 67
T_MESHARMOR 68
T_FALCONSHIELD 69
T_PLATINUMHELM 70
T_AMULETOFWARDING 71
T_ITEMFLECHETTE 72
T_ITEMTORCH 73
T_ITEMREPULSION 74
T_MANA3 75
T_PUZZSKULL 76
T_PUZZGEMBIG 77
T_PUZZGEMRED 78
T_PUZZGEMGREEN1 79
T_PUZZGEMGREEN2 80
T_PUZZGEMBLUE1 81
T_PUZZGEMBLUE2 82
T_PUZZBOOK1 83
T_PUZZBOOK2 84
T_METALKEY 85
T_SMALLMETALKEY 86
T_AXEKEY 87
T_FIREKEY 88
T_GREENKEY 89
T_MACEKEY 90
T_SILVERKEY 91
T_RUSTYKEY 92
T_HORNKEY 93
T_SERPENTKEY 94
T_WATERDRIP 95
T_TEMPSMALLFLAME 96
T_PERMSMALLFLAME 97
T_TEMPLARGEFLAME 98
T_PERMLARGEFLAME 99
T_DEMON_MASH 100
T_DEMON2_MASH 101
T_ETTIN_MASH 102
T_CENTAUR_MASH 103
T_THRUSTSPIKEUP 104
T_THRUSTSPIKEDOWN 105
T_FLESH_DRIP1 106
T_FLESH_DRIP2 107
T_SPARK_DRIP 108
*/
}
}

View file

@ -237,6 +237,7 @@ Field data types:
15 = linedef tag (integer) *
16 = enum option (string)
17 = angle in degrees (float)
22 = byte angle (integer)
*/
universalfields
{

View file

@ -21,11 +21,14 @@ zdoom
{
title = "Teleport (Z Height and Gravity)";
sprite = "internal:teleport";
class = "TeleportDest3";
}
9044
{
title = "Teleport (Z Height)";
sprite = "internal:teleport";
class = "TeleportDest2";
}
}
@ -41,13 +44,47 @@ zdoom
decoration
{
9027 = "Red Particle Fountain";
9028 = "Green Particle Fountain";
9029 = "Blue Particle Fountain";
9030 = "Yellow Particle Fountain";
9031 = "Purple Particle Fountain";
9032 = "Black Particle Fountain";
9033 = "White Particle Fountain";
9027
{
title = "Red Particle Fountain";
class = "RedParticleFountain";
}
9028
{
title = "Green Particle Fountain";
class = "GreenParticleFountain";
}
9029
{
title = "Blue Particle Fountain";
class = "BlueParticleFountain";
}
9030
{
title = "Yellow Particle Fountain";
class = "YellowParticleFountain";
}
9031
{
title = "Purple Particle Fountain";
class = "PurpleParticleFountain";
}
9032
{
title = "Black Particle Fountain";
class = "BlackParticleFountain";
}
9033
{
title = "White Particle Fountain";
class = "WhiteParticleFountain";
}
}
sounds
@ -73,9 +110,11 @@ zdoom
1407 = "Sound Sequence 7";
1408 = "Sound Sequence 8";
1409 = "Sound Sequence 9";
1411
{
title = "Sector Sound Sequence Override";
class = "$SSeqOverride";
arg0
{
title = "Sound Sequence Index";
@ -86,6 +125,7 @@ zdoom
}
}
}
14001 = "Ambient Sound 01";
14002 = "Ambient Sound 02";
14003 = "Ambient Sound 03";
@ -150,9 +190,11 @@ zdoom
14062 = "Ambient Sound 62";
14063 = "Ambient Sound 63";
14064 = "Ambient Sound 64";
14065
{
title = "Custom Ambient Sound";
class = "AmbientSound";
arg0
{
title = "Ambient Sound Index";
@ -176,9 +218,11 @@ zdoom
title = "Distance Multiplier";
}
}
14066
{
title = "Sound Sequence";
class = "SoundSequence";
arg0
{
title = "Sound Sequence Index";
@ -188,9 +232,11 @@ zdoom
title = "Choice";
}
}
14067
{
title = "Custom Ambient Sound (no gravity)";
class = "AmbientSoundNoGravity";
arg0
{
title = "Ambient Sound Index";
@ -214,6 +260,7 @@ zdoom
title = "Distance Multiplier";
}
}
14101 = "Music Changer 01";
14102 = "Music Changer 02";
14103 = "Music Changer 03";
@ -278,9 +325,11 @@ zdoom
14162 = "Music Changer 62";
14163 = "Music Changer 63";
14164 = "Music Changer 64";
14165
{
title = "Custom Music Changer";
class = "MusicChanger";
arg0
{
title = "MUSINFO Track Index";
@ -290,9 +339,11 @@ zdoom
title = "MOD Track Order";
}
}
9048
{
title = "Sound Environment (reverbs)";
class = "SoundEnvironment";
arg0
{
title = "ID (first part)";
@ -312,6 +363,7 @@ zdoom
width = 12;
height = 28;
sprite = "internal:dog";
class = "MBFHelperDog";
}
}
@ -331,21 +383,28 @@ zdoom
5064
{
title = "Invisible Bridge, radius 16";
class = "InvisibleBridge16";
width = 16;
}
5061
{
title = "Invisible Bridge, radius 32";
class = "InvisibleBridge32";
width = 32;
}
5065
{
title = "Invisible Bridge, radius 8";
class = "InvisibleBridge8";
width = 8;
}
9990
{
title = "Custom Invisible Bridge";
class = "InvisibleBridge";
arg0
{
title = "Radius";
@ -355,9 +414,11 @@ zdoom
title = "Thickness";
}
}
9991
{
title = "Bridge Custom";
class = "CustomBridge";
arg0
{
title = "Radius";
@ -399,6 +460,7 @@ zdoom
}
}
}
cameras
{
color = 7; // Light Grey
@ -416,6 +478,7 @@ zdoom
9025
{
title = "Security Camera";
class = "SecurityCamera";
arg0
{
title = "Pitch";
@ -431,9 +494,11 @@ zdoom
enum = "generic_door_delays";
}
}
9073
{
title = "Aiming Camera";
class = "AimingCamera";
arg0
{
title = "Pitch";
@ -452,19 +517,23 @@ zdoom
type = 14;
}
}
9080
{
title = "Skybox Viewpoint";
sprite = "internal:SkyboxViewpoint";
class = "SkyViewpoint";
arg0
{
title = "Visibility / 4";
}
}
9081
{
title = "Skybox Picker";
sprite = "internal:SkyboxPicker";
class = "SkyPicker";
arg0
{
title = "Skybox Viewpoint Tag";
@ -482,15 +551,19 @@ zdoom
}
}
}
9083
{
title = "Eternity Skybox Viewpoint";
sprite = "internal:SkyboxViewpoint";
class = "SkyCamCompat";
}
9074
{
title = "Actor Mover";
sprite = "internal:actormover";
class = "ActorMover";
arg0
{
title = "Interpolation Point Tag";
@ -519,10 +592,12 @@ zdoom
type = 14;
}
}
9070
{
title = "Interpolation Point";
sprite = "internal:InterpolationPoint";
class = "InterpolationPoint";
arg0
{
title = "Pitch";
@ -549,14 +624,18 @@ zdoom
title = "Next Point HiTag";
}
}
9075
{
title = "Interpolation Special";
sprite = "internal:InterpolationSpecial";
class = "InterpolationSpecial";
}
9072
{
title = "Moving Camera";
class = "MovingCamera";
arg0
{
title = "Interpolation Point Tag";
@ -585,10 +664,12 @@ zdoom
type = 14;
}
}
9071
{
title = "Path Follower";
sprite = "internal:PathFollower";
class = "PathFollower";
arg0
{
title = "Interpolation Point Tag";
@ -611,7 +692,12 @@ zdoom
}
}
}
9047 = "Patrol Special";
9047
{
title = "Patrol Special";
class = "PatrolSpecial";
}
}
sectors
@ -631,21 +717,79 @@ zdoom
{
title = "Silent Sector";
sprite = "internal:SilentSector";
class = "SectorSilencer";
}
9998 = "Actor enters sector";
9989 = "Actor hits fake floor";
9996 = "Actor hits ceiling";
9999 = "Actor hits floor";
9997 = "Actor leaves sector";
9982 = "Eyes above fake ceiling";
9992 = "Eyes above fake floor";
9983 = "Eyes below fake ceiling";
9993 = "Eyes below fake floor";
9995 = "Player uses sector";
9994 = "Player uses wall";
9998
{
title = "Actor enters sector";
class = "SecActEnter";
}
9989
{
title = "Actor hits fake floor";
class = "SecActHitFakeFloor";
}
9996
{
title = "Actor hits ceiling";
class = "SecActHitCeil";
}
9999
{
title = "Actor hits floor";
class = "SecActHitFloor";
}
9997
{
title = "Actor leaves sector";
class = "SecActExit";
}
9982
{
title = "Eyes above fake ceiling";
class = "SecActEyesAboveC";
}
9992
{
title = "Eyes above fake floor";
class = "SecActEyesSurface";
}
9983
{
title = "Eyes below fake ceiling";
class = "SecActEyesBelowC";
}
9993
{
title = "Eyes below fake floor";
class = "SecActEyesDive";
}
9995
{
title = "Player uses sector";
class = "SecActUse";
}
9994
{
title = "Player uses sector";
class = "SecActUseWall";
}
9038
{
title = "Color Setter";
title = "Color Setter";
class = "ColorSetter";
arg0
{
title = "Red";
@ -666,9 +810,11 @@ zdoom
title = "Desaturation";
}
}
9039
{
title = "Fade Setter";
class = "FadeSetter";
arg0
{
title = "Red";
@ -685,9 +831,11 @@ zdoom
default = 128;
}
}
9041
{
title = "Flag Setter";
title = "Sector Flag Setter";
class = "SectorFlagSetter";
arg0
{
title = "Set Flags";
@ -713,24 +861,29 @@ zdoom
9511
{
title = "Copy ceiling plane";
class = "$CopyCeilingPlane";
arg0
{
title = "Sector Tag";
type = 13;
}
}
9510
{
title = "Copy floor plane";
class = "$CopyFloorPlane";
arg0
{
title = "Sector Tag";
type = 13;
}
}
9503
{
title = "Set ceiling slope";
class = "$SetCeilingSlope";
arrow = 1;
arg0
{
@ -738,9 +891,11 @@ zdoom
default = 90;
}
}
9502
{
title = "Set floor slope";
class = "$SetFloorSlope";
arrow = 1;
arg0
{
@ -748,9 +903,11 @@ zdoom
default = 90;
}
}
9501
{
title = "Slope ceiling to here";
class = "$SlopeCeilingPointLine";
height = 8;
arg0
{
@ -758,9 +915,11 @@ zdoom
type = 15;
}
}
9500
{
title = "Slope floor to here";
class = "$SlopeFloorPointLine";
height = 4;
arg0
{
@ -772,18 +931,21 @@ zdoom
1500
{
title = "Line slope floor";
class = "$VavoomFloor";
height = 8;
}
1501
{
title = "Line slope ceiling";
class = "$VavoomCeiling";
height = 8;
}
1504
{
title = "Vertex slope floor";
class = "$VertexFloorZ";
height = 8;
absolutez = true;
}
@ -791,6 +953,7 @@ zdoom
1505
{
title = "Vertex slope ceiling";
class = "$VertexCeilingZ";
height = 8;
absolutez = true;
}
@ -813,15 +976,18 @@ zdoom
{
title = "Decal";
sprite = "internal:Decal";
class = "Decal";
arg0
{
title = "Decal ID";
}
}
9024
{
title = "Patrol Point";
sprite = "internal:PathFollower";
class = "PatrolPoint";
arg0
{
title = "Next Patrol Point Tag";
@ -834,18 +1000,22 @@ zdoom
enum = "delay_seconds";
}
}
9026
{
title = "Spark";
sprite = "internal:Sparkle";
class = "Spark";
arg0
{
title = "Particles Amount";
}
}
9040
{
title = "Map Marker";
class = "MapMarker";
arg0
{
title = "Follow Target Tag";
@ -858,15 +1028,19 @@ zdoom
enum = "noyes";
}
}
9045
{
title = "Water Zone";
sprite = "internal:DeepWater";
class = "Waterzone";
}
9046
{
title = "Secret";
sprite = "internal:Secret";
class = "SecretTrigger";
arg0
{
title = "Notification Type";
@ -880,48 +1054,64 @@ zdoom
}
}
}
9300
{
title = "Polyobject Anchor";
sprite = "internal:anchor";
class = "$PolyAnchor";
fixedrotation = true;
}
}
9301
{
title = "Polyobject Start Spot";
sprite = "internal:anchor";
class = "$PolySpawn";
fixedrotation = true;
}
9302
{
title = "Polyobject Start Spot (crush)";
sprite = "internal:anchor";
class = "$PolySpawnCrush";
fixedrotation = true;
}
}
9303
{
title = "Polyobject Start Spot (hurts to touch)";
sprite = "internal:anchor";
class = "$PolySpawnHurt";
fixedrotation = true;
}
9001
{
title = "Map Spot";
sprite = "internal:MapSpot";
class = "MapSpot";
}
9013
{
title = "Map Spot (gravity)";
sprite = "internal:MapSpotGravity";
class = "MapSpotGravity";
}
9076
{
title = "Hate target";
sprite = "internal:Target";
class = "HateTarget";
}
9988
{
title = "Custom Sprite";
class = "CustomSprite";
arg0
{
title = "BTILxxxx";
@ -972,6 +1162,7 @@ zdoom
{
title = "Upper Sector";
sprite = "internal:portal_upper";
class = "UpperStackLookOnly";
arg0
{
title = "Flat Opacity";
@ -983,6 +1174,7 @@ zdoom
{
title = "Lower Sector";
sprite = "internal:portal_lower";
class = "LowerStackLookOnly";
arg0
{
title = "Flat Opacity";
@ -998,25 +1190,33 @@ doom
players
{
blocking = 2;
4001
{
title = "Player 5 start";
sprite = "PLAYA2A8";
class = "$Player5Start";
}
4002
{
title = "Player 6 start";
sprite = "PLAYA2A8";
class = "$Player6Start";
}
4003
{
title = "Player 7 start";
sprite = "PLAYA2A8";
class = "$Player7Start";
}
4004
{
title = "Player 8 start";
sprite = "PLAYA2A8";
class = "$Player8Start";
}
}
@ -1030,6 +1230,7 @@ doom
width = "16";
height = "56";
sprite = "SKULA1";
class = "BetaSkull";
}
9050
@ -1038,70 +1239,93 @@ doom
width = 64;
height = 64;
sprite = "BSPIA2A8";
class = "StealthArachnotron";
}
9051
{
title = "Archvile (stealth)";
width = 20;
sprite = "VILEA2D8";
class = "StealthArchvile";
}
9052
{
title = "Baron of Hell (stealth)";
width = 24;
height = 64;
sprite = "BOSSA2A8";
class = "StealthBaron";
}
9053
{
title = "Cacodemon (stealth)";
width = 31;
sprite = "HEADA2A8";
class = "StealthCacodemon";
}
9054
{
title = "Chaingunner (stealth)";
sprite = "CPOSA2";
class = "StealthChaingunGuy";
}
9055
{
title = "Demon (stealth)";
width = 30;
sprite = "SARGA2A8";
class = "StealthDemon";
}
9056
{
title = "Hell Knight (stealth)";
width = 24;
height = 64;
sprite = "BOS2A2C8";
class = "StealthHellKnight";
}
9057
{
title = "Imp (stealth)";
sprite = "TROOA2A8";
class = "StealthDoomImp";
}
9058
{
title = "Mancubus (stealth)";
width = 48;
height = 64;
sprite = "FATTC2C8";
class = "StealthFatso";
}
9059
{
title = "Revenant (stealth)";
sprite = "SKELA2D8";
class = "StealthRevenant";
}
9060
{
title = "Former Sergeant (stealth)";
sprite = "SPOSA2A8";
class = "StealthShotgunGuy";
}
9061
{
title = "Former Human (stealth)";
sprite = "POSSA2A8";
class = "StealthZombieMan";
}
}
@ -1192,6 +1416,7 @@ doom
blocking = 2;
title = "Stalagmite";
sprite = "SMT2A0";
class = "Stalagmite";
width = 16;
height = 48;
}
@ -1203,13 +1428,23 @@ doom
{
title = "Pistol";
sprite = "PISGA0";
class = "Pistol";
}
}
powerups
{
2016 = "Evil Sceptre (BETA)";
2017 = "Unholy Bible (BETA)";
2016
{
title = "Evil Sceptre (BETA)";
class = "EvilSceptre";
}
2017
{
title = "Unholy Bible (BETA)";
class = "UnholyBible";
}
}
bridges
@ -1217,6 +1452,7 @@ doom
118
{
title = "Hack Bridge";
class = "ZBridge";
width = "36";
height = "4";
}
@ -1234,18 +1470,77 @@ doom
blocking = 0;
sprite = "PLAYA2A8";
9100 = "Scripted Marine";
9101 = "Marine Fist";
9102 = "Marine Berserk";
9103 = "Marine Chainsaw";
9104 = "Marine Pistol";
9105 = "Marine Shotgun";
9106 = "Marine SSG";
9107 = "Marine Chaingun";
9108 = "Marine Rocket Launcher";
9109 = "Marine Plasma Rifle";
9110 = "Marine Railgun";
9111 = "Marine BFG9000";
9100
{
title = "Scripted Marine";
class = "ScriptedMarine";
}
9101
{
title = "Marine (fist)";
class = "MarineFist";
}
9102
{
title = "Marine (berserk)";
class = "MarineBerserk";
}
9103
{
title = "Marine (chainsaw)";
class = "MarineChainsaw";
}
9104
{
title = "Marine (pistol)";
class = "MarinePistol";
}
9105
{
title = "Marine (shotgun)";
class = "MarineShotgun";
}
9106
{
title = "Marine (SSG)";
class = "MarineSSG";
}
9107
{
title = "Marine (chaingun)";
class = "MarineChaingun";
}
9108
{
title = "Marine (rocket launcher)";
class = "MarineRocket";
}
9109
{
title = "Marine (plasma rifle)";
class = "MarinePlasma";
}
9110
{
title = "Marine (Railgun)";
class = "MarineRailgun";
}
9111
{
title = "Marine (BFG9000)";
class = "MarineBFG";
}
}
}
@ -1254,25 +1549,33 @@ heretic
players
{
blocking = 2;
4001
{
title = "Player 5 start";
sprite = "PLAYA2A8";
class = "$Player5Start";
}
4002
{
title = "Player 6 start";
sprite = "PLAYA2A8";
class = "$Player6Start";
}
4003
{
title = "Player 7 start";
sprite = "PLAYA2A8";
class = "$Player7Start";
}
4004
{
title = "Player 8 start";
sprite = "PLAYA2A8";
class = "$Player8Start";
}
}
@ -1281,6 +1584,7 @@ heretic
118
{
title = "Glitter Bridge";
class = "Bridge";
width = "32";
height = "2";
}
@ -1326,26 +1630,33 @@ default
players
{
blocking = 2;
4001
{
title = "Player 5 start";
sprite = "PLAYA2A8";
class = "$Player5Start";
}
4002
{
title = "Player 6 start";
sprite = "PLAYA2A8";
class = "$Player6Start";
}
4003
{
title = "Player 7 start";
sprite = "PLAYA2A8";
class = "$Player7Start";
}
4004
{
title = "Player 8 start";
sprite = "PLAYA2A8";
class = "$Player8Start";
}
}
}

View file

@ -430,16 +430,8 @@
</OBJECT>
</UL>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="MAPINFO support">
<param name="Local" value="gzdb\mapinfo.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="MODELDEF and GLDEFS support">
<param name="Local" value="gzdb\gldefs.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="TEXTURES support">
<param name="Local" value="gzdb\textures.html">
<param name="Name" value="(G)ZDoom text lumps support">
<param name="Local" value="gzdb\text_lumps.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="List of deprecated plugins">

View file

@ -27,9 +27,7 @@
<h2>Table of contents</h2>
<ul>
<li><a href="gzdb/features/features.html">List of features</a>.</li>
<li><a href="gzdb/gldefs.html">MODELDEF and GLDEFS</a> support.</li>
<li><a href="gzdb/mapinfo.html">(Z)MAPINFO</a> support.</li>
<li><a href="gzdb/textures.html">TEXTURES</a> support.</li>
<li><a href="gzdb/text_lumps.html">(G)ZDoom text lumps support</a> support.</li>
<li><a href="gzdb/deprecated_plugins.html">List of deprecated plugins</a>.</li>
<li><a href="gzdb/faq.html">Frequently asked questions</a>.</li>
</ul>

View file

@ -37,6 +37,6 @@
<span class="style1">If you are using Zandronum:</span><br />
To get rid of these errors, add &quot;<strong>zandronum.pk3</strong>&quot; as a map resource. Don't forget to check &quot;<strong>Exclude from testing parameters</strong>&quot; chekbox while adding it, otherwise Zandronum won't load your map. &quot;<strong>zandronum.pk3</strong>&quot; can be found in Zandronum folder.</p><br />
<p><strong>Q:</strong> I don't like the &quot;fake contrast&quot; (<a href="http://zdoom.org/wiki/Fake_contrast">zdoom.org/wiki/Fake_contrast</a>) GZDB uses to render sector walls in Visual mode. How can I disable this?<br />
<strong>A:</strong> GZDB's Visual mode emulates (G)ZDoom's default rendering preferences (in (G)ZDoom, Options -&gt; Display options -&gt; Use fake contrast is &quot;on&quot; by default). You can change this behaviour by adding &quot;evenlighting&quot; or &quot;smoothlighting&quot; property to the &quot;map&quot; or &quot;defaultmap&quot; definition in the MAPINFO. More info about MAPINFO properties supported by GZDB can be found <a href="mapinfo.html">here</a>.</p>
<strong>A:</strong> GZDB's Visual mode emulates (G)ZDoom's default rendering preferences (in (G)ZDoom, Options -&gt; Display options -&gt; Use fake contrast is &quot;on&quot; by default). You can change this behaviour by adding &quot;evenlighting&quot; or &quot;smoothlighting&quot; property to the &quot;map&quot; or &quot;defaultmap&quot; definition in the MAPINFO. More info about MAPINFO properties supported by GZDB can be found <a href="text_lumps.html#mapinfo">here</a>.</p>
</div>
</body>

View file

@ -48,7 +48,6 @@
<li><strong><span class="style1">[new]</span></strong> New action: &quot;Export to Wavefront .obj&quot;, available as <strong>File -&gt; Export -&gt; Selection to Wavefront .obj</strong>. It will export selected sectors (or the whole map, if no sectors are selected) to Wavefront .obj model.</li>
<li>New action: &quot;<strong>Reload MODELDEF/VOXELDEF</strong>&quot; (<strong>Tools -&gt; Reload MODELDEF/VOXELDEF</strong>).</li>
<li>New action: &quot;<strong>Reload GLDEFS</strong>&quot; (<strong>Tools -&gt; Reload GLDEFS</strong>).</li>
<li>New action: &quot;<strong>Reload MAPINFO</strong>&quot; (<strong>Tools -&gt; Reload MAPINFO</strong>).</li>
<li><span class="red">[new]</span> Info about current selection is shown at the bottom of program's window.
<input class="spoilerbutton" type="button" onclick="ToggleSpoiler(this);" href="javascript:void(0);" value="Show image"/>
<div style="display: none; margin: 0px; padding: 6px; border: 1px inset;"><img src="general/selection_info.jpg" alt="" /></div>
@ -313,10 +312,11 @@
<li>
<h3><a name="formats" id="formats"></a>(G)ZDoom features support:</h3>
<ul>
<li><a href="../gldefs.html">MD2 and MD3 models</a> rendering in 2D and 3D modes.</li>
<li><span class="red">[new]</span> VOXLEDEF support.</li>
<li>More complete <a href="../textures.html">TEXTURES</a> support.</li>
<li>Partial<a href="../mapinfo.html"> MAPINFO</a> support.</li>
<li><a href="../text_lumps.html#modeldef">MD2 and MD3 models</a> rendering in 2D and 3D modes.</li>
<li><span class="red">[new]</span> <a href="../text_lumps.html#voxeldef">VOXLEDEF</a> support.</li>
<li><span class="red">[new]</span> <a href="../text_lumps.html#reverbs">REVERBS</a> support (used in <a href="classic_modes/mode_soundenvironment.html">Sound Environment Mode</a>).</li>
<li>More complete <a href="../text_lumps.html#textures">TEXTURES</a> support.</li>
<li>Partial <a href="../text_lumps.html#mapinfo">MAPINFO</a> support, including DoomEdNum and SpawnNums overrides.</li>
<li>ACS scripts with #include directives are compiled properly.</li>
<li>PNG and PCX image formats are supported.</li>
<li>PK7 archive format is supported.</li>

View file

@ -1,44 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>GZDoom Builder features</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<link rel="stylesheet" type="text/css" href="../default.css" media="screen" title="Default" />
<style type="text/css">
<!--
.style1 {color: #0000FF}
-->
</style>
</head>
<body>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="keyword" value="Template">
</object>
<div id="gz_title">
<h1>GLDEFS and MODELDEF support</h1>
</div>
<div id="contents">
<p>GZDoom Builder will automatically load data from GLDEFS and MODELDEF lumps if they are present in map resources.
<p><strong>MODELDEF support:</strong> all relevant MODELDEF properties and flags are supported. Sprite translations are not supported.<br /><br />
<strong>GLDEFS support:</strong>
only dynamic light definitions are currently supported. Brightmaps and glowing flats support may be added in the future. You can use &quot;<strong>//$GZDB_SKIP</strong>&quot; special comment to abort parsing of the current file.<br /><br />
You can reload GLDEFS and MODELDEF by using &quot;<strong>Reload GLDEFS</strong>&quot; and &quot;<strong>Reload MODELDEF</strong>&quot; actions.<br />
To enable GZDoom's built-in GLDEFS dynamic light definitions, you need to add "<strong>lights.pk3</strong>" as a map resource. "<strong>lights.pk3</strong>" can be found in GZDoom folder.
<p><b>If you are creating maps for Doom or Doom 2, you probably don't need to read this, since required information is already added for those games.</b><br />
<br />
<b>To load models or dynamic lights defined in GLDEFS for things defined in configuration files:</b><br />
To display a model instead of a thing sprite, or to attach a light defined in GLDEFS, GZDB needs to know a thing's class name (because that's how overrides are defined in MODELDEF and GLDEFS). Things defined in Doom Builder configuration files don't have this value. So, if you aren't using configs, which came with GZDoom Builder, or you are creating maps for games other than Doom and Doom 2, you'll need to add a new value named "class" to thing definition in game configuration:<br />
<pre>3001
{
title = "Imp";
sprite = "TROOA2A8";
<span class="blue">class = "DoomImp";</span> // <- you'll need to add this value
}</pre>
You can find all class names for things at <a href="http://www.zdoom.org/wiki/Classes">http://www.zdoom.org/wiki/Classes</a>.</p>
</div>
</body>

View file

@ -1,34 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>GZDoom Builder features</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<link rel="stylesheet" type="text/css" href="../default.css" media="screen" title="Default" />
</head>
<body>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="keyword" value="Template">
</object>
<div id="gz_title"><h1>(Z)MAPINFO support</h1></div>
<div id="contents">
<p>GZDoom Builder will automatically load data from (Z)MAPINFO lump if it's present in map resources. Both new and old MAPINFO definition styles are supported.<br />
Several values from (Z)MAPINFO are used in Visual mode. List of supported properties:
<ul>
<li>fade;</li>
<li>outsidefog;</li>
<li>fogdensity;</li>
<li>outsidefogdensity;</li>
<li>vertwallshade;</li>
<li>horizwallshade;</li>
<li>evenlighting;</li>
<li>smoothlighting.</li>
</ul>
You can reload (Z)MAPINFO by using "<strong>Reload (Z)MAPINFO</strong>" action.
</p>
</div>
</body>

82
Help/gzdb/text_lumps.html Normal file
View file

@ -0,0 +1,82 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>GZDoom Builder features</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<link rel="stylesheet" type="text/css" href="../default.css" media="screen" title="Default" />
</head>
<body>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="keyword" value="textures">
<param name="keyword" value="modeldef">
<param name="keyword" value="voxeldef">
<param name="keyword" value="reverbs">
<param name="keyword" value="gldefs">
</object>
<div id="gz_title">
<h1>(G)ZDoom text lumps support</h1>
</div>
<div id="contents">
<p>GZDoom Builder will automatically load data from the following lumps if they are present in the map's resources.</p>
<a name="textures" id="textures"></a><h2>TEXTURES:</h2>
You can use "<strong>//$GZDB_SKIP</strong>" special comment to abort parsing of the current file. Useful if you don't want textures from certain files or parts of files to show up in the <a href="w_imagesbrowser.html">Image Browser</a> or want to increase resource loading speed.<br /><br />
GZDoom Builder adds support for the following TEXTURES parameters:
<ul><li>FlipX, FlipY, Rotate and Blend (both styles) patch parameters.</li>
<li>&quot;Add&quot;, &quot;Modulate&quot;, &quot;Subtract&quot;, &quot;ReverseSubtract&quot; and &quot;Translucent&quot; patch Translucency Styles.</li>
</ul>
<a name="mapinfo" id="mapinfo"></a>
<h2>(Z)MAPINFO:</h2>
Both new and old MAPINFO definition styles are supported.<br />
You can use "<strong>//$GZDB_SKIP</strong>" special comment to abort parsing of the current file.<br />
<strong>DoomEdNum</strong> overrides are supported.<br />
<strong>SpawnNums</strong> overrides are supported. The values are used to update "spawnthing" Game Configuration enum.<br /><br />
In addition, following values from (Z)MAPINFO are supported by Visual mode:
<ul>
<li>fade;</li>
<li>outsidefog;</li>
<li>fogdensity;</li>
<li>outsidefogdensity;</li>
<li>vertwallshade;</li>
<li>horizwallshade;</li>
<li>evenlighting;</li>
<li>smoothlighting.</li>
</ul>
<a name="reverbs" id="reverbs"></a>
<h2>REVERBS:</h2>
Sound environment definitions are loaded and can be used in the <a href="features/classic_modes/mode_soundenvironment.html">Sound Environment Mode</a>.
<a name="modeldef" id="modeldef"></a>
<h2>MODELDEF:</h2>
All relevant MODELDEF properties and flags, except sprite translations are supported.
<a name="voxeldef" id="voxeldef"></a>
<h2>VOXELDEF:</h2>
All relevant VOXELDEF properties and flags are supported.
<a name="gldefs" id="gldefs"></a>
<h2>GLDEFS:</h2>
Only glowing flat and dynamic light definitions are currently supported. Brightmaps support may be added in the future.<br />You can use &quot;<strong>//$GZDB_SKIP</strong>&quot; special comment to abort parsing of the current file.<br />
<br />
You can reload GLDEFS and MODELDEF by using &quot;<strong>Reload GLDEFS</strong>&quot; and &quot;<strong>Reload MODELDEF</strong>&quot; actions.<br />
To enable GZDoom's built-in GLDEFS dynamic light definitions, you need to add "<strong>lights.pk3</strong>" as a map resource. "<strong>lights.pk3</strong>" can be found in GZDoom folder.
<h2>Additional info regarding MODELDEF and GLDEFS support:</h2>
<p>If you are creating maps for Doom or Doom 2, you probably don't need to read this, since required information is already added for those games.<br />
<br />
<b>To load models or dynamic lights defined in GLDEFS for things defined in configuration files:</b><br />
To display a model instead of a thing sprite, or to attach a light defined in GLDEFS, GZDB needs to know a thing's class name (because that's how overrides are defined in MODELDEF and GLDEFS). Things defined in Doom Builder configuration files don't have this value. So, if you aren't using configs, which came with GZDoom Builder, or you are creating maps for games other than Doom and Doom 2, you'll need to add a new value named "class" to thing definition in game configuration:<br />
<pre>3001
{
title = "Imp";
sprite = "TROOA2A8";
<span class="blue">class = "DoomImp";</span> // <- you'll need to add this value
}</pre>
<br>
You can find all thing class names at <a href="http://www.zdoom.org/wiki/Classes">http://www.zdoom.org/wiki/Classes</a>.</p>
</div>
</body>

View file

@ -1,28 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>GZDoom Builder features</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<link rel="stylesheet" type="text/css" href="../default.css" media="screen" title="Default" />
</head>
<body>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="keyword" value="textures">
</object>
<div id="gz_title"><h1>TEXTURES support</h1></div>
<div id="contents">
<p><strong>GZDoom Builder adds support for the following TEXTURES parameters:</strong></p>
<ul><li>FlipX, FlipY, Rotate and Blend (both styles) patch parameters.</li>
<li>&quot;Add&quot;, &quot;Modulate&quot;, &quot;Subtract&quot;, &quot;ReverseSubtract&quot; and &quot;Translucent&quot; patch Translucency Styles.</li>
</ul>
<p><strong>GZDoom Builder supports the following special comments:</strong></p>
<ul>
<li><strong>//$GZDB_SKIP</strong> - skip the rest of the current file. Useful if you don't want textures from certain files or parts of files to show up in the <a href="w_imagesbrowser.html">Image Browser</a> or want to increase resource loading speed.</li>
</ul>
</div>
</body>

View file

@ -822,6 +822,7 @@
<Compile Include="GZBuilder\Data\EngineInfo.cs" />
<Compile Include="GZBuilder\Data\GameType.cs" />
<Compile Include="GZBuilder\Data\DynamicLight.cs" />
<Compile Include="GZBuilder\Data\GlowingFlatData.cs" />
<Compile Include="GZBuilder\Data\LinedefColorPreset.cs" />
<Compile Include="GZBuilder\Data\LinksCollector.cs" />
<Compile Include="GZBuilder\Data\MapInfo.cs" />

View file

@ -36,7 +36,7 @@ namespace CodeImp.DoomBuilder.Config
private readonly string title;
private readonly bool used;
private readonly int type;
private readonly EnumList enumlist;
private EnumList enumlist;
private readonly object defaultvalue; //mxd
#endregion
@ -46,7 +46,7 @@ namespace CodeImp.DoomBuilder.Config
public string Title { get { return title; } }
public bool Used { get { return used; } }
public int Type { get { return type; } }
public EnumList Enum { get { return enumlist; } }
public EnumList Enum { get { return enumlist; } internal set { enumlist = value; } }
public object DefaultValue { get { return defaultvalue; } } //mxd
#endregion
@ -92,7 +92,7 @@ namespace CodeImp.DoomBuilder.Config
}
//mxd. Constructor for an argument info defined in DECORATE
internal ArgumentInfo(int argindex, string title)
internal ArgumentInfo(string title)
{
this.used = true;
this.title = title;

View file

@ -16,13 +16,14 @@
#region ================== Namespaces
using System;
using System.Globalization;
#endregion
namespace CodeImp.DoomBuilder.Config
{
public class EnumItem
public class EnumItem : IComparable<EnumItem>
{
#region ================== Constants
@ -62,6 +63,16 @@ namespace CodeImp.DoomBuilder.Config
return title;
}
//mxd. This compares against another activate info
public int CompareTo(EnumItem other)
{
int thisval = GetIntValue();
int otherval = other.GetIntValue();
if(thisval < otherval) return -1;
if(thisval > otherval) return 1;
return 0;
}
// This returns the value as int
public int GetIntValue()
{

View file

@ -32,10 +32,14 @@ namespace CodeImp.DoomBuilder.Config
#region ================== Variables
private readonly string name; //mxd
#endregion
#region ================== Properties
public string Name { get { return name; } } //mxd
#endregion
#region ================== Constructor
@ -48,6 +52,8 @@ namespace CodeImp.DoomBuilder.Config
// Constructor to load from dictionary
internal EnumList(IDictionary dic)
{
this.name = "<unnamed>"; //mxd
// Read the dictionary
foreach(DictionaryEntry de in dic)
{
@ -60,6 +66,8 @@ namespace CodeImp.DoomBuilder.Config
// Constructor to load from configuration
internal EnumList(string name, Configuration cfg)
{
this.name = name; //mxd
// Read the list from configuration
IDictionary dic = cfg.ReadSetting("enums." + name, new Hashtable());
foreach(DictionaryEntry de in dic)

View file

@ -38,23 +38,23 @@ namespace CodeImp.DoomBuilder.Config
private List<ThingTypeInfo> things;
// Category properties
private string name;
private string title;
private bool sorted;
private readonly string name;
private readonly string title;
private readonly bool sorted;
// Thing properties for inheritance
private string sprite;
private int color;
private int arrow;
private float radius;
private float height;
private int hangs;
private int blocking;
private int errorcheck;
private bool fixedsize;
private bool fixedrotation; //mxd
private bool absolutez;
private float spritescale;
private readonly string sprite;
private readonly int color;
private readonly int arrow;
private readonly float radius;
private readonly float height;
private readonly int hangs;
private readonly int blocking;
private readonly int errorcheck;
private readonly bool fixedsize;
private readonly bool fixedrotation; //mxd
private readonly bool absolutez;
private readonly float spritescale;
// Disposing
private bool isdisposed;
@ -198,6 +198,13 @@ namespace CodeImp.DoomBuilder.Config
things.Add(t);
}
//mxd. This removes a thing from the category
internal void RemoveThing(ThingTypeInfo t)
{
// Remove
if(things.Contains(t)) things.Remove(t);
}
// String representation
public override string ToString()
{

View file

@ -49,7 +49,7 @@ namespace CodeImp.DoomBuilder.Config
private string title;
private string sprite;
private ActorStructure actor;
private readonly string classname; //mxd
private string classname; //mxd
private long spritelongname;
private int color;
private readonly bool arrow;
@ -91,10 +91,8 @@ namespace CodeImp.DoomBuilder.Config
public bool IsNull { get { return (index == 0); } }
public bool AbsoluteZ { get { return absolutez; } }
public SizeF SpriteScale { get { return spritescale; } }
public string ClassName { get { return classname; } } //mxd. Need this to add model overrides for things defined in configs
//mxd. Need this to add model overrides for things defined in configs.
public string ClassName { get { return (actor != null ? actor.ClassName : classname); } }
#endregion
#region ================== Constructor / Disposer
@ -108,6 +106,7 @@ namespace CodeImp.DoomBuilder.Config
this.actor = null;
this.title = "<" + index.ToString(CultureInfo.InvariantCulture) + ">";
this.sprite = DataManager.INTERNAL_PREFIX + "unknownthing";
this.classname = string.Empty; //mxd
this.color = 0;
this.arrow = true;
this.radius = 10f;
@ -156,10 +155,7 @@ namespace CodeImp.DoomBuilder.Config
float sscale = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".spritescale", cat.SpriteScale);
this.spritescale = new SizeF(sscale, sscale);
this.locksprite = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".locksprite", false); //mxd
//mxd
string s_class = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".class", String.Empty);
if(s_class != String.Empty) this.classname = s_class; //I actually want to keep null value there if no such property exists...
this.classname = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".class", String.Empty); //mxd
// Read the args
for(int i = 0; i < Linedef.NUM_ARGS; i++)
@ -187,6 +183,7 @@ namespace CodeImp.DoomBuilder.Config
this.category = cat;
this.title = title;
this.actor = null;
this.classname = string.Empty; //mxd
this.isknown = true;
this.args = new ArgumentInfo[Linedef.NUM_ARGS];
for(int i = 0; i < Linedef.NUM_ARGS; i++) this.args[i] = new ArgumentInfo(i);
@ -228,6 +225,7 @@ namespace CodeImp.DoomBuilder.Config
this.category = cat;
this.title = "";
this.actor = actor;
this.classname = actor.ClassName; //mxd
this.isknown = true;
this.args = new ArgumentInfo[Linedef.NUM_ARGS];
for(int i = 0; i < Linedef.NUM_ARGS; i++) this.args[i] = new ArgumentInfo(i);
@ -257,6 +255,38 @@ namespace CodeImp.DoomBuilder.Config
GC.SuppressFinalize(this);
}
// Constructor
internal ThingTypeInfo(int index, ThingTypeInfo other)
{
// Initialize
this.index = index;
this.category = other.category;
this.title = other.title;
this.actor = other.actor;
this.classname = other.classname; //mxd
this.isknown = true;
this.args = new ArgumentInfo[Linedef.NUM_ARGS];
for(int i = 0; i < Linedef.NUM_ARGS; i++)
this.args[i] = other.args[i];
// Copy properties
this.sprite = other.sprite;
this.color = other.color;
this.arrow = other.arrow;
this.radius = other.radius;
this.height = other.height;
this.hangs = other.hangs;
this.blocking = other.blocking;
this.errorcheck = other.errorcheck;
this.fixedsize = other.fixedsize;
this.fixedrotation = other.fixedrotation; //mxd
this.absolutez = other.absolutez;
this.spritescale = new SizeF(other.spritescale.Width, other.spritescale.Height);
// We have no destructor
GC.SuppressFinalize(this);
}
#endregion
#region ================== Methods
@ -266,6 +296,7 @@ namespace CodeImp.DoomBuilder.Config
{
// Keep reference to actor
this.actor = actor;
this.classname = actor.ClassName; //mxd
// Set the title
if(actor.HasPropertyWithValue("$title"))
@ -290,7 +321,7 @@ namespace CodeImp.DoomBuilder.Config
{
if(!actor.HasPropertyWithValue("$arg" + i)) continue;
string argtitle = actor.GetPropertyAllValues("$arg" + i);
args[i] = new ArgumentInfo(i, ZDTextParser.StripQuotes(argtitle));
args[i] = new ArgumentInfo(ZDTextParser.StripQuotes(argtitle));
}
// Remove doublequotes from title
@ -343,7 +374,7 @@ namespace CodeImp.DoomBuilder.Config
// String representation
public override string ToString()
{
return this.title + " (" + index + ")";
return title + " (" + index + ")";
}
#endregion

View file

@ -330,8 +330,9 @@ namespace CodeImp.DoomBuilder.Controls
}
//mxd. Update help link
classname.Enabled = (thinginfo != null && !string.IsNullOrEmpty(thinginfo.ClassName) && !string.IsNullOrEmpty(General.Map.Config.ThingClassHelp));
classname.Text = (thinginfo != null && !string.IsNullOrEmpty(thinginfo.ClassName)) ? thinginfo.ClassName : "--";
bool displayclassname = (thinginfo != null && !string.IsNullOrEmpty(thinginfo.ClassName) && !thinginfo.ClassName.StartsWith("$"));
classname.Enabled = (displayclassname && !string.IsNullOrEmpty(General.Map.Config.ThingClassHelp));
classname.Text = (displayclassname ? thinginfo.ClassName : "--");
labelclassname.Enabled = classname.Enabled;
// Update icon (mxd)

View file

@ -65,10 +65,11 @@ namespace CodeImp.DoomBuilder.Data
private AllTextureSet alltextures;
//mxd
private Dictionary<int, ModelData> modeldefEntries; //Thing.Type, Model entry
private Dictionary<int, DynamicLightData> gldefsEntries; //Thing.Type, Light entry
private MapInfo mapInfo; //mapinfo
private Dictionary<int, ModelData> modeldefentries; //Thing.Type, Model entry
private readonly Dictionary<int, DynamicLightData> gldefsentries; //Thing.Type, Light entry
private MapInfo mapinfo;
private Dictionary<string, KeyValuePair<int, int>> reverbs; //<name, <arg1, arg2>
private Dictionary<long, GlowingFlatData> glowingflats; // Texture name hash, Glowing Flat Data
// Background loading
private Queue<ImageData> imageque;
@ -96,7 +97,6 @@ namespace CodeImp.DoomBuilder.Data
private DecorateParser decorate;
private List<ThingCategory> thingcategories;
private Dictionary<int, ThingTypeInfo> thingtypes;
private List<string> invalidDecorateActors;//mxd. List of actors without DoomEdNum
// Timing
private float loadstarttime;
@ -110,10 +110,11 @@ namespace CodeImp.DoomBuilder.Data
#region ================== Properties
//mxd
internal Dictionary<int, ModelData> ModeldefEntries { get { return modeldefEntries; } }
internal Dictionary<int, DynamicLightData> GldefsEntries { get { return gldefsEntries; } }
public MapInfo MapInfo { get { return mapInfo; } }
internal Dictionary<int, ModelData> ModeldefEntries { get { return modeldefentries; } }
internal Dictionary<int, DynamicLightData> GldefsEntries { get { return gldefsentries; } }
public MapInfo MapInfo { get { return mapinfo; } }
public Dictionary<string, KeyValuePair<int, int>> Reverbs { get { return reverbs; } }
public Dictionary<long, GlowingFlatData> GlowingFlats { get { return glowingflats; } }
public Playpal Palette { get { return palette; } }
public PreviewManager Previews { get { return previews; } }
@ -156,9 +157,10 @@ namespace CodeImp.DoomBuilder.Data
GC.SuppressFinalize(this);
//mxd.
modeldefEntries = new Dictionary<int, ModelData>();
gldefsEntries = new Dictionary<int, DynamicLightData>();
modeldefentries = new Dictionary<int, ModelData>();
gldefsentries = new Dictionary<int, DynamicLightData>();
reverbs = new Dictionary<string, KeyValuePair<int, int>>();
glowingflats = new Dictionary<long, GlowingFlatData>();
// Load special images
missingtexture3d = new ResourceImage("CodeImp.DoomBuilder.Resources.MissingTexture3D.png");
@ -200,8 +202,8 @@ namespace CodeImp.DoomBuilder.Data
whitetexture = null;
unknownimage.Dispose(); //mxd
unknownimage = null; //mxd
modeldefEntries = null;//mxd
mapInfo = null;
modeldefentries = null;//mxd
mapinfo = null;
// Done
isdisposed = true;
@ -317,18 +319,21 @@ namespace CodeImp.DoomBuilder.Data
flatcount = LoadFlats(flatsonly, flatnamesshorttofull);
colormapcount = LoadColormaps(colormapsonly);
LoadSprites();
thingcount = LoadDecorateThings();
//mxd. Load MAPINFO. Should happen before parisng DECORATE
Dictionary<int, string> spawnnums;
Dictionary<int, string> doomednums;
LoadMapInfo(out spawnnums, out doomednums);
thingcount = LoadDecorateThings(spawnnums, doomednums);
spritecount = LoadThingSprites();
LoadInternalSprites();
//mxd. Load more stuff
LoadMapInfo();
LoadReverbs();
ModelReader.Init();
LoadVoxels();
Dictionary<string, int> actorsByClass = CreateActorsByClassList();
LoadModeldefs(actorsByClass);
LoadGldefs(actorsByClass);
Dictionary<string, List<int>> actorsbyclass = CreateActorsByClassList();
LoadModeldefs(actorsbyclass);
foreach (Thing t in General.Map.Map.Things) t.UpdateCache();
General.MainWindow.DisplayReady();
@ -406,6 +411,9 @@ namespace CodeImp.DoomBuilder.Data
foreach (DataReader dr in containers)
dr.TextureSet.MixTexturesAndFlats();
}
//mxd. Should be done after loading textures...
LoadGldefs(actorsbyclass);
// Sort names
texturenames.Sort();
@ -443,7 +451,11 @@ namespace CodeImp.DoomBuilder.Data
StartBackgroundLoader();
// Output info
General.WriteLogLine("Loaded " + texcount + " textures, " + flatcount + " flats, " + colormapcount + " colormaps, " + spritecount + " sprites, " + thingcount + " decorate things, " + modeldefEntries.Count + " model deinitions, " + gldefsEntries.Count + " dynamic light definitions");
General.WriteLogLine("Loaded " + texcount + " textures, " + flatcount + " flats, " +
colormapcount + " colormaps, " + spritecount + " sprites, " +
thingcount + " decorate things, " + modeldefentries.Count + " model/voxel deinitions, " +
gldefsentries.Count + " dynamic light definitions, " +
glowingflats.Count + " glowing flat definitions, " + reverbs.Count + " sound environment definitions");
}
// This unloads all data
@ -466,9 +478,9 @@ namespace CodeImp.DoomBuilder.Data
palette = null;
//mxd
if (modeldefEntries != null)
if (modeldefentries != null)
{
foreach (KeyValuePair<int, ModelData> group in modeldefEntries)
foreach (KeyValuePair<int, ModelData> group in modeldefentries)
group.Value.Dispose();
}
@ -721,18 +733,18 @@ namespace CodeImp.DoomBuilder.Data
//mxd. This loads a model
internal bool ProcessModel(int type)
{
if(modeldefEntries[type].LoadState != ModelLoadState.None) return true;
if(modeldefentries[type].LoadState != ModelLoadState.None) return true;
//create models
ModelReader.Load(modeldefEntries[type], containers, General.Map.Graphics.Device);
ModelReader.Load(modeldefentries[type], containers, General.Map.Graphics.Device);
if(modeldefEntries[type].Model != null)
if(modeldefentries[type].Model != null)
{
modeldefEntries[type].LoadState = ModelLoadState.Ready;
modeldefentries[type].LoadState = ModelLoadState.Ready;
return true;
}
modeldefEntries.Remove(type);
modeldefentries.Remove(type);
return false;
}
@ -1322,15 +1334,13 @@ namespace CodeImp.DoomBuilder.Data
#region ================== Things
// This loads the things from Decorate
private int LoadDecorateThings()
private int LoadDecorateThings(Dictionary<int, string> spawnnumsoverride, Dictionary<int, string> doomednumsoverride)
{
int counter = 0;
// Create new parser
decorate = new DecorateParser();
decorate.OnInclude = LoadDecorateFromLocation;
invalidDecorateActors = new List<string>(); //mxd
// Only load these when the game configuration supports the use of decorate
if(!string.IsNullOrEmpty(General.Map.Config.DecorateGames))
@ -1362,7 +1372,7 @@ namespace CodeImp.DoomBuilder.Data
if(!decorate.HasError)
{
// Go for all actors in the decorate to make things or update things
// Step 1. Go for all actors in the decorate to make things or update things
foreach(ActorStructure actor in decorate.Actors)
{
// Check if we want to add this actor
@ -1380,28 +1390,7 @@ namespace CodeImp.DoomBuilder.Data
else
{
// Find the category to put the actor in
// First search by Title, then search by Name
ThingCategory cat = null;
foreach(ThingCategory c in thingcategories)
{
if(c.Title.ToLowerInvariant() == catname) cat = c;
}
if(cat == null)
{
foreach(ThingCategory c in thingcategories)
{
if(c.Name.ToLowerInvariant() == catname) cat = c;
}
}
// Make the category if needed
if(cat == null)
{
string catfullname = actor.GetPropertyAllValues("$category");
if(string.IsNullOrEmpty(catfullname.Trim())) catfullname = "Decorate";
cat = new ThingCategory(catname, catfullname);
thingcategories.Add(cat);
}
ThingCategory cat = GetThingCategory(actor, catname);
// Add new thing
ThingTypeInfo t = new ThingTypeInfo(cat, actor);
@ -1411,11 +1400,145 @@ namespace CodeImp.DoomBuilder.Data
// Count
counter++;
}
else //mxd
{
if(!invalidDecorateActors.Contains(actor.ClassName))
invalidDecorateActors.Add(actor.ClassName);
}
}
//mxd. Step 2. Apply DoomEdNum MAPINFO overrides, remove actors disabled in MAPINFO
if(doomednumsoverride.Count > 0)
{
List<int> toremove = new List<int>();
Dictionary<string, ThingTypeInfo> thingtypesbyclass = new Dictionary<string, ThingTypeInfo>();
foreach (KeyValuePair<int, ThingTypeInfo> group in thingtypes)
{
if(string.IsNullOrEmpty(group.Value.ClassName)) continue;
thingtypesbyclass[group.Value.ClassName.ToLowerInvariant()] = group.Value;
}
foreach(KeyValuePair<int, string> group in doomednumsoverride)
{
// Remove thing from the list?
if(group.Value == "none")
{
toremove.Add(group.Key);
continue;
}
// Skip if already added.
if(thingtypes.ContainsKey(group.Key) && thingtypes[group.Key].ClassName.ToLowerInvariant() == group.Value)
{
continue;
}
// Try to find the actor...
ActorStructure actor = null;
if(!decorate.HasError)
{
//... in ActorsByClass
if(decorate.ActorsByClass.ContainsKey(group.Value))
{
actor = decorate.ActorsByClass[group.Value];
}
// Try finding in ArchivedActors
else if(decorate.AllActorsByClass.ContainsKey(group.Value))
{
actor = decorate.AllActorsByClass[group.Value];
}
}
if(actor != null)
{
// Find the category to put the actor in
string catname = actor.GetPropertyAllValues("$category").ToLowerInvariant();
if(string.IsNullOrEmpty(catname.Trim())) catname = "decorate";
ThingCategory cat = GetThingCategory(actor, catname);
// Add a new ThingTypeInfo, replacing already existing one if necessary
ThingTypeInfo info = new ThingTypeInfo(cat, actor);
thingtypes[group.Key] = info;
}
// Check thingtypes...
else if(thingtypesbyclass.ContainsKey(group.Value))
{
ThingTypeInfo t = new ThingTypeInfo(group.Key, thingtypesbyclass[group.Value]);
// Add new thing, replacing already existing one if necessary
t.Category.AddThing(t);
thingtypes[group.Key] = t;
}
// Loudly give up...
else
{
General.ErrorLogger.Add(ErrorType.Warning, "Failed to apply MAPINFO DoomEdNum override '" + group.Key + " = " + group.Value + ": failed to find corresponding actor class...");
}
}
// Remove items
foreach(int id in toremove)
{
if(thingtypes.ContainsKey(id))
{
thingtypes[id].Category.RemoveThing(thingtypes[id]);
thingtypes.Remove(id);
}
}
}
//mxd. Step 3. Gather DECORATE SpawnIDs
Dictionary<int, EnumItem> configspawnnums = new Dictionary<int, EnumItem>();
// Update or create the main enums list
if(General.Map.Config.Enums.ContainsKey("spawnthing"))
{
foreach(EnumItem item in General.Map.Config.Enums["spawnthing"])
configspawnnums.Add(item.GetIntValue(), item);
}
bool spawnidschanged = false;
if(!decorate.HasError)
{
foreach(ActorStructure actor in decorate.Actors)
{
int spawnid = actor.GetPropertyValueInt("spawnid", 0);
if(spawnid != 0)
{
configspawnnums[spawnid] = new EnumItem(spawnid.ToString(), (actor.HasPropertyWithValue("$title") ? actor.GetPropertyAllValues("$title") : actor.ClassName));
spawnidschanged = true;
}
}
}
//mxd. Step 4. Update SpawnNums using MAPINFO overrides
if(spawnnumsoverride.Count > 0)
{
// Modify by MAPINFO data
foreach(KeyValuePair<int, string> group in spawnnumsoverride)
{
configspawnnums[group.Key] = new EnumItem(group.Key.ToString(), (thingtypes.ContainsKey(group.Key) ? thingtypes[group.Key].Title : group.Value));
}
spawnidschanged = true;
}
if(spawnidschanged)
{
// Update the main collection
EnumList newenums = new EnumList();
newenums.AddRange(configspawnnums.Values);
newenums.Sort();
General.Map.Config.Enums["spawnthing"] = newenums;
// Update all ArgumentInfos...
foreach (ThingTypeInfo info in thingtypes.Values)
{
foreach(ArgumentInfo ai in info.Args)
if(ai.Enum.Name == "spawnthing") ai.Enum = newenums;
}
foreach (LinedefActionInfo info in General.Map.Config.LinedefActions.Values)
{
foreach(ArgumentInfo ai in info.Args)
if(ai.Enum.Name == "spawnthing") ai.Enum = newenums;
}
}
}
@ -1424,6 +1547,37 @@ namespace CodeImp.DoomBuilder.Data
// Output info
return counter;
}
//mxd
private ThingCategory GetThingCategory(ActorStructure actor, string catname)
{
// Find the category to put the actor in
// First search by Title, then search by Name
ThingCategory cat = null;
foreach(ThingCategory c in thingcategories)
{
if(c.Title.ToLowerInvariant() == catname) cat = c;
}
if(cat == null)
{
foreach(ThingCategory c in thingcategories)
{
if(c.Name.ToLowerInvariant() == catname) cat = c;
}
}
// Make the category if needed
if(cat == null)
{
string catfullname = actor.GetPropertyAllValues("$category");
if(string.IsNullOrEmpty(catfullname.Trim())) catfullname = "Decorate";
cat = new ThingCategory(catname, catfullname);
thingcategories.Add(cat);
}
return cat;
}
// This loads Decorate data from a specific file or lump name
private void LoadDecorateFromLocation(DecorateParser parser, string location)
@ -1471,24 +1625,19 @@ namespace CodeImp.DoomBuilder.Data
#region ================== mxd. Modeldef, Voxeldef, Gldefs, Mapinfo
//mxd. This creates <Actor Class, Thing.Type> dictionary. Should be called after all DECORATE actors are parsed
private Dictionary<string, int> CreateActorsByClassList()
private Dictionary<string, List<int>> CreateActorsByClassList()
{
Dictionary<string, int> actors = new Dictionary<string, int>(StringComparer.Ordinal);
Dictionary<int, ThingTypeInfo> things = General.Map.Config.GetThingTypes();
Dictionary<string, List<int>> actors = new Dictionary<string, List<int>>(StringComparer.Ordinal);
//read our new shiny ClassNames for default game things
foreach (KeyValuePair<int, ThingTypeInfo> ti in things)
foreach (KeyValuePair<int, ThingTypeInfo> ti in thingtypes)
{
if (!string.IsNullOrEmpty(ti.Value.ClassName))
actors.Add(ti.Value.ClassName.ToLowerInvariant(), ti.Key);
}
//and for actors defined in DECORATE
ICollection<ActorStructure> ac = decorate.Actors;
foreach (ActorStructure actor in ac)
{
string classname = actor.ClassName.ToLowerInvariant();
if (!actors.ContainsKey(classname)) actors.Add(classname, actor.DoomEdNum);
if(!string.IsNullOrEmpty(ti.Value.ClassName))
{
string classname = ti.Value.ClassName.ToLowerInvariant();
if(!actors.ContainsKey(classname)) actors.Add(classname, new List<int>());
actors[classname].Add(ti.Key);
}
}
if (actors.Count == 0)
@ -1500,9 +1649,9 @@ namespace CodeImp.DoomBuilder.Data
//mxd
public void ReloadModeldef()
{
if (modeldefEntries != null)
if (modeldefentries != null)
{
foreach (KeyValuePair<int, ModelData> group in modeldefEntries)
foreach (KeyValuePair<int, ModelData> group in modeldefentries)
group.Value.Dispose();
}
@ -1548,36 +1697,11 @@ namespace CodeImp.DoomBuilder.Data
General.MainWindow.DisplayReady();
}
//mxd
public void ReloadMapInfo()
{
General.MainWindow.DisplayStatus(StatusType.Busy, "Reloading (Z)MAPINFO...");
try
{
LoadMapInfo();
}
catch (ArgumentNullException)
{
MessageBox.Show("(Z)MAPINFO reload failed. Try using 'Reload Resources' instead.\nCheck 'Errors and Warnings' window for more details.");
General.MainWindow.DisplayReady();
return;
}
//rebuild geometry if in Visual mode
if (General.Editing.Mode != null && General.Editing.Mode.GetType().Name == "BaseVisualMode")
{
General.Editing.Mode.OnReloadResources();
}
General.MainWindow.DisplayReady();
}
//mxd. This parses modeldefs. Should be called after all DECORATE actors are parsed and actorsByClass dictionary created
private void LoadModeldefs(Dictionary<string, int> actorsByClass)
private void LoadModeldefs(Dictionary<string, List<int>> actorsByClass)
{
//if no actors defined in DECORATE or game config...
if (actorsByClass == null || actorsByClass.Count == 0) return;
if (actorsByClass.Count == 0) return;
Dictionary<string, ModelData> modelDefEntriesByName = new Dictionary<string, ModelData>(StringComparer.Ordinal);
ModeldefParser parser = new ModeldefParser();
@ -1612,10 +1736,14 @@ namespace CodeImp.DoomBuilder.Data
foreach (KeyValuePair<string, ModelData> e in modelDefEntriesByName)
{
if (actorsByClass.ContainsKey(e.Key))
modeldefEntries[actorsByClass[e.Key]] = modelDefEntriesByName[e.Key];
else if(!invalidDecorateActors.Contains(e.Key))
if(actorsByClass.ContainsKey(e.Key))
{
foreach(int i in actorsByClass[e.Key]) modeldefentries[i] = modelDefEntriesByName[e.Key];
}
else if(!decorate.ActorsByClass.ContainsKey(e.Key))
{
General.ErrorLogger.Add(ErrorType.Warning, "Got MODELDEF override for class '" + e.Key + "', but haven't found such class in Decorate");
}
}
}
@ -1678,7 +1806,7 @@ namespace CodeImp.DoomBuilder.Data
{
if (sc.Key.Contains(entry.Key))
{
foreach(int id in sc.Value) modeldefEntries[id] = entry.Value;
foreach(int id in sc.Value) modeldefentries[id] = entry.Value;
processed.Add(entry.Key, false);
}
}
@ -1700,19 +1828,19 @@ namespace CodeImp.DoomBuilder.Data
ModelData data = new ModelData { IsVoxel = true };
data.ModelNames.Add(group.Key);
foreach(int id in sprites[sc.Key]) modeldefEntries[id] = data;
foreach(int id in sprites[sc.Key]) modeldefentries[id] = data;
}
}
}
}
//mxd. This parses gldefs. Should be called after all DECORATE actors are parsed and actorsByClass dictionary created
private void LoadGldefs(Dictionary<string, int> actorsByClass)
private void LoadGldefs(Dictionary<string, List<int>> actorsByClass)
{
//if no actors defined in DECORATE or game config...
if (actorsByClass == null || actorsByClass.Count == 0) return;
if (actorsByClass.Count == 0) return;
GldefsParser parser = new GldefsParser { OnInclude = LoadGldefsFromLocation };
GldefsParser parser = new GldefsParser { OnInclude = ParseFromLocation };
//load gldefs from resources
foreach (DataReader dr in containers)
@ -1728,27 +1856,31 @@ namespace CodeImp.DoomBuilder.Data
//create gldefsEntries dictionary
foreach (KeyValuePair<string, string> e in parser.Objects) //ClassName, Light name
{
//if we have decorate actor and light definition for given ClassName...
if (actorsByClass.ContainsKey(e.Key) && parser.LightsByName.ContainsKey(e.Value))
{
int thingType = actorsByClass[e.Key];
if (gldefsEntries.ContainsKey(thingType))
gldefsEntries[thingType] = parser.LightsByName[e.Value];
else
gldefsEntries.Add(thingType, parser.LightsByName[e.Value]);
foreach(int i in actorsByClass[e.Key])
{
if(gldefsentries.ContainsKey(i))
gldefsentries[i] = parser.LightsByName[e.Value];
else
gldefsentries.Add(i, parser.LightsByName[e.Value]);
}
}
else if(!invalidDecorateActors.Contains(e.Key))
else if(!decorate.AllActorsByClass.ContainsKey(e.Key))
{
General.ErrorLogger.Add(ErrorType.Warning, "Got GLDEFS light for class '" + e.Key + "', but haven't found such class in DECORATE");
}
}
// Grab them glowy flats!
glowingflats = parser.GlowingFlats;
}
//mxd. This loads (Z)MAPINFO
private void LoadMapInfo()
private void LoadMapInfo(out Dictionary<int, string> spawnnums, out Dictionary<int, string> doomednums)
{
MapinfoParser parser = new MapinfoParser();
MapinfoParser parser = new MapinfoParser { OnInclude = ParseFromLocation };
foreach (DataReader dr in containers)
{
@ -1761,16 +1893,21 @@ namespace CodeImp.DoomBuilder.Data
parser.Parse(group.Value, Path.Combine(currentreader.Location.location, group.Key), General.Map.Options.LevelName);
}
}
// Set the output values
spawnnums = parser.SpawnNums;
doomednums = parser.DoomEdNums;
// Store to our MapInfo property
currentreader = null;
mapInfo = parser.MapInfo ?? new MapInfo();
mapinfo = parser.MapInfo ?? new MapInfo();
}
private void LoadGldefsFromLocation(GldefsParser parser, string location)
private void ParseFromLocation(ZDTextParser parser, string location)
{
Dictionary<string, Stream> streams = currentreader.GetGldefsData(location);
foreach (KeyValuePair<string, Stream> group in streams)
parser.Parse(group.Value, group.Key);
if(currentreader.IsSuspended) throw new Exception("Data reader is suspended");
Stream s = currentreader.LoadFile(location);
if(s != null) parser.Parse(s, location);
}
//mxd. This loads REVERBS

View file

@ -163,7 +163,6 @@ namespace CodeImp.DoomBuilder.Data
//mxd. When implemented, this returns the Gldefs lump
public virtual Dictionary<string, Stream> GetGldefsData(GameType gameType) { return new Dictionary<string, Stream>(); }
public virtual Dictionary<string, Stream> GetGldefsData(string location) { return new Dictionary<string, Stream>(); }
//mxd. When implemented, this returns the Reverbs lump
public virtual Dictionary<string, Stream> GetReverbsData() { return new Dictionary<string, Stream>(); }

View file

@ -326,6 +326,65 @@ namespace CodeImp.DoomBuilder.Data
scale.y = 1.0f;
}
}
//mxd. Calculate average color?
if(General.Map != null && General.Map.Data != null && General.Map.Data.GlowingFlats != null &&
General.Map.Data.GlowingFlats.ContainsKey(longname) &&
General.Map.Data.GlowingFlats[longname].CalculateTextureColor)
{
BitmapData bmpdata = null;
try
{
bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Size.Width, bitmap.Size.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
}
catch(Exception e)
{
General.ErrorLogger.Add(ErrorType.Error, "Cannot lock image '" + this.fullname + "' for glow color calculationt. " + e.GetType().Name + ": " + e.Message);
}
if(bmpdata != null)
{
PixelColor* pixels = (PixelColor*) (bmpdata.Scan0.ToPointer());
int numpixels = bmpdata.Width * bmpdata.Height;
uint r = 0;
uint g = 0;
uint b = 0;
for(PixelColor* cp = pixels + numpixels - 1; cp >= pixels; cp--)
{
r += cp->r;
g += cp->g;
b += cp->b;
}
// Update glow data
int br = (int)(r / numpixels);
int bg = (int)(g / numpixels);
int bb = (int)(b / numpixels);
int max = Math.Max(br, Math.Max(bg, bb));
// Black can't glow...
if(max == 0)
{
General.Map.Data.GlowingFlats.Remove(longname);
}
else
{
// That's how it's done in GZDoom (and I may be totally wrong about this)
br = Math.Min(255, br * 153 / max);
bg = Math.Min(255, bg * 153 / max);
bb = Math.Min(255, bb * 153 / max);
General.Map.Data.GlowingFlats[longname].Color = new PixelColor(255, (byte)br, (byte)bg, (byte)bb);
General.Map.Data.GlowingFlats[longname].CalculateTextureColor = false;
}
// Release the data
bitmap.UnlockBits(bmpdata);
}
}
}
// Image is ready

View file

@ -475,7 +475,7 @@ namespace CodeImp.DoomBuilder.Data
foreach (string s in files)
{
if (s.ToLowerInvariant().IndexOf("modeldef") != -1)
if (Path.GetFileNameWithoutExtension(s).ToUpperInvariant().StartsWith("MODELDEF"))
streams.Add(s, LoadFile(s));
}
@ -567,10 +567,10 @@ namespace CodeImp.DoomBuilder.Data
//try to load game specific GLDEFS first
if (gametype != GameType.UNKNOWN)
{
string lumpname = Gldefs.GLDEFS_LUMPS_PER_GAME[(int)gametype].ToLowerInvariant();
string lumpname = Gldefs.GLDEFS_LUMPS_PER_GAME[(int)gametype];
foreach (string s in files)
{
if (s.ToLowerInvariant().IndexOf(lumpname) != -1)
if(Path.GetFileNameWithoutExtension(s).ToUpperInvariant() == lumpname)
streams.Add(s, LoadFile(s));
}
}
@ -578,25 +578,13 @@ namespace CodeImp.DoomBuilder.Data
// Can be several entries
foreach (string s in files)
{
if(s.ToLowerInvariant().IndexOf("gldefs") != -1)
if(Path.GetFileNameWithoutExtension(s).ToUpperInvariant().StartsWith("GLDEFS"))
streams.Add(s, LoadFile(s));
}
return streams;
}
//mxd
public override Dictionary<string, Stream> GetGldefsData(string location)
{
// Error when suspended
if (issuspended) throw new Exception("Data reader is suspended");
Dictionary<string, Stream> streams = new Dictionary<string, Stream>(StringComparer.Ordinal);
Stream s = LoadFile(location);
if (s != null) streams.Add(location, s);
return streams;
}
#endregion
#region ================== Reverbs

View file

@ -905,22 +905,16 @@ namespace CodeImp.DoomBuilder.Data
return streams;
}
//mxd
public override Dictionary<string, Stream> GetGldefsData(string location)
{
if (issuspended) throw new Exception("Data reader is suspended");
Dictionary<string, Stream> streams = new Dictionary<string, Stream>(StringComparer.Ordinal);
int lumpindex = file.FindLumpIndex(location);
if (lumpindex != -1) streams.Add(location, file.Lumps[lumpindex].Stream);
return streams;
}
//mxd
public override Dictionary<string, Stream> GetModeldefData()
{
return GetGldefsData("MODELDEF");
if(issuspended) throw new Exception("Data reader is suspended");
Dictionary<string, Stream> streams = new Dictionary<string, Stream>(StringComparer.Ordinal);
int lumpindex = file.FindLumpIndex("MODELDEF");
if(lumpindex != -1) streams.Add("MODELDEF", file.Lumps[lumpindex].Stream);
return streams;
}
//mxd

View file

@ -1,6 +1,8 @@

namespace CodeImp.DoomBuilder.GZBuilder.Data {
public enum GameType {
namespace CodeImp.DoomBuilder.GZBuilder.Data
{
public enum GameType
{
UNKNOWN = 0,
DOOM = 1,
HERETIC = 2,
@ -8,7 +10,8 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data {
STRIFE = 4,
}
public struct Gldefs {
public static string[] GLDEFS_LUMPS_PER_GAME = { "UNKNOWN_GAME", "DOOMDEFS", "HTICDEFS", "HEXNDEFS", "STRFDEFS" };
public struct Gldefs
{
public static readonly string[] GLDEFS_LUMPS_PER_GAME = { "UNKNOWN_GAME", "DOOMDEFS", "HTICDEFS", "HEXNDEFS", "STRFDEFS" };
}
}

View file

@ -0,0 +1,12 @@
using CodeImp.DoomBuilder.Rendering;
namespace CodeImp.DoomBuilder.GZBuilder.Data
{
public class GlowingFlatData
{
public PixelColor Color;
public int Height;
public bool Fullbright;
public bool CalculateTextureColor;
}
}

View file

@ -1,28 +1,24 @@
using System;
#region ================== Namespaces
using System;
using System.Drawing;
using System.IO;
using System.Collections.Generic;
using System.Globalization;
using CodeImp.DoomBuilder.ZDoom;
using CodeImp.DoomBuilder.GZBuilder.Data;
using CodeImp.DoomBuilder.Rendering;
using CodeImp.DoomBuilder.IO;
#endregion
namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
{
public sealed class GldefsParser : ZDTextParser
internal sealed class GldefsParser : ZDTextParser
{
#region ================== Structs
public delegate void IncludeDelegate(GldefsParser parser, string includefile);
public IncludeDelegate OnInclude;
private readonly Dictionary<string, DynamicLightData> lightsByName; //LightName, light definition
private readonly Dictionary<string, string> objects; //ClassName, LightName
public Dictionary<string, DynamicLightData> LightsByName { get { return lightsByName; } }
public Dictionary<string, string> Objects { get { return objects; } }
private readonly List<string> parsedLumps;
private struct GldefsLightType
private struct GldefsLightType
{
public const string POINT = "pointlight";
public const string PULSE = "pulselight";
@ -33,23 +29,60 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
public static readonly Dictionary<string, DynamicLightType> GLDEFS_TO_GZDOOM_LIGHT_TYPE = new Dictionary<string, DynamicLightType>(StringComparer.Ordinal) { { POINT, DynamicLightType.NORMAL }, { PULSE, DynamicLightType.PULSE }, { FLICKER, DynamicLightType.FLICKER }, { FLICKER2, DynamicLightType.RANDOM }, { SECTOR, DynamicLightType.SECTOR } };
}
#endregion
#region ================== Delegates
public delegate void IncludeDelegate(GldefsParser parser, string includefile);
public IncludeDelegate OnInclude;
#endregion
#region ================== Variables
private readonly Dictionary<string, DynamicLightData> lightsByName; //LightName, light definition
private readonly Dictionary<string, string> objects; //ClassName, LightName
private readonly Dictionary<long, GlowingFlatData> glowingflats;
private readonly List<string> parsedlumps;
#endregion
#region ================== Properties
public Dictionary<string, DynamicLightData> LightsByName { get { return lightsByName; } }
public Dictionary<string, string> Objects { get { return objects; } }
internal Dictionary<long, GlowingFlatData> GlowingFlats { get { return glowingflats; } }
#endregion
#region ================== Constructor
public GldefsParser()
{
parsedLumps = new List<string>();
// Syntax
whitespace = "\n \t\r\u00A0";
specialtokens = ",{}\n";
parsedlumps = new List<string>();
lightsByName = new Dictionary<string, DynamicLightData>(StringComparer.Ordinal); //LightName, Light params
objects = new Dictionary<string, string>(StringComparer.Ordinal); //ClassName, LightName
glowingflats = new Dictionary<long, GlowingFlatData>(); // Texture name hash, Glowing Flat Data
}
#endregion
#region ================== Parsing
public override bool Parse(Stream stream, string sourcefilename)
{
base.Parse(stream, sourcefilename);
if (parsedLumps.IndexOf(sourcefilename) != -1)
if (parsedlumps.IndexOf(sourcefilename) != -1)
{
General.ErrorLogger.Add(ErrorType.Error, "Error: already parsed '" + sourcefilename + "'. Check your #include directives!");
General.ErrorLogger.Add(ErrorType.Error, "already parsed '" + sourcefilename + "'. Check your #include directives!");
return false;
}
parsedLumps.Add(sourcefilename);
parsedlumps.Add(sourcefilename);
// Keep local data
Stream localstream = datastream;
@ -81,13 +114,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
if (!string.IsNullOrEmpty(lightName))
{
//now find opening brace
SkipWhitespace(true);
token = ReadToken();
if (token != "{")
{
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": expected '{', but got '" + token + "'");
continue; //something wrong with gldefs declaration, continue to next one
}
if(!NextTokenIs("{")) continue;
//read gldefs light structure
while (SkipWhitespace(true))
@ -105,7 +132,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
if (!float.TryParse(token, NumberStyles.Float, CultureInfo.InvariantCulture, out light.Color.Red))
{
// Not numeric!
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": expected Red Color value, but got '" + token + "'");
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": expected Red Color value, but got '" + token + "'.");
gotErrors = true;
break;
}
@ -116,7 +143,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
if (!float.TryParse(token, NumberStyles.Float, CultureInfo.InvariantCulture, out light.Color.Green))
{
// Not numeric!
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": expected Green Color value, but got '" + token + "'");
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": expected Green Color value, but got '" + token + "'.");
gotErrors = true;
break;
}
@ -127,7 +154,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
if (!float.TryParse(token, NumberStyles.Float, CultureInfo.InvariantCulture, out light.Color.Blue))
{
// Not numeric!
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": expected Blue Color value, but got '" + token + "'");
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": expected Blue Color value, but got '" + token + "'.");
gotErrors = true;
break;
}
@ -143,7 +170,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
if (!int.TryParse(token, NumberStyles.Integer, CultureInfo.InvariantCulture, out light.PrimaryRadius))
{
// Not numeric!
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": expected Size value, but got '" + token + "'");
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": expected Size value, but got '" + token + "'.");
gotErrors = true;
break;
}
@ -152,7 +179,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
}
else
{
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": '" + token + "' is not valid property for " + lightType);
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": '" + token + "' is not valid property for " + lightType + ".");
gotErrors = true;
break;
}
@ -166,7 +193,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
if (!ReadSignedFloat(token, ref light.Offset.X))
{
// Not numeric!
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": expected Offset X value, but got '" + token + "'");
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": expected Offset X value, but got '" + token + "'.");
gotErrors = true;
break;
}
@ -188,7 +215,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
if (!ReadSignedFloat(token, ref light.Offset.Y))
{
// Not numeric!
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": expected Offset Z value, but got '" + token + "'");
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": expected Offset Z value, but got '" + token + "'.");
gotErrors = true;
break;
}
@ -203,7 +230,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
if (!int.TryParse(token, NumberStyles.Integer, CultureInfo.InvariantCulture, out i))
{
// Not numeric!
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": expected Subtractive value, but got '" + token + "'");
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": expected Subtractive value, but got '" + token + "'.");
gotErrors = true;
break;
}
@ -220,7 +247,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
if (!int.TryParse(token, NumberStyles.Integer, CultureInfo.InvariantCulture, out i))
{
// Not numeric!
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": expected Dontlightself value, but got '" + token + "'");
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": expected Dontlightself value, but got '" + token + "'.");
gotErrors = true;
break;
}
@ -239,13 +266,13 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
if (!float.TryParse(token, NumberStyles.Float, CultureInfo.InvariantCulture, out interval))
{
// Not numeric!
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": expected Interval value, but got '" + token + "'");
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": expected Interval value, but got '" + token + "'.");
gotErrors = true;
break;
}
if(interval == 0)
General.ErrorLogger.Add(ErrorType.Warning, "Warning in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": Interval value should be greater than zero");
General.ErrorLogger.Add(ErrorType.Warning, "Warning in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": Interval value should be greater than zero.");
//I wrote logic for dynamic lights animation first, so here I modify gldefs settings to fit in existing logic
if (lightType == GldefsLightType.PULSE)
@ -259,7 +286,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
}
else
{
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": '"+token+"' is not valid property for " + lightType);
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": '" + token + "' is not valid property for " + lightType + ".");
gotErrors = true;
break;
}
@ -275,7 +302,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
if (!int.TryParse(token, NumberStyles.Integer, CultureInfo.InvariantCulture, out light.SecondaryRadius))
{
// Not numeric!
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": expected SecondarySize value, but got '" + token + "'");
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": expected SecondarySize value, but got '" + token + "'.");
gotErrors = true;
break;
}
@ -283,7 +310,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
}
else
{
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": '" + token + "' is not valid property for " + lightType);
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": '" + token + "' is not valid property for " + lightType + ".");
gotErrors = true;
break;
}
@ -300,7 +327,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
if (!float.TryParse(token, NumberStyles.Float, CultureInfo.InvariantCulture, out chance))
{
// Not numeric!
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": expected Chance value, but got '" + token + "'");
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": expected Chance value, but got '" + token + "'.");
gotErrors = true;
break;
}
@ -310,7 +337,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
}
else
{
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": '" + token + "' is not valid property for " + lightType);
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": '" + token + "' is not valid property for " + lightType + ".");
gotErrors = true;
break;
}
@ -327,14 +354,14 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
if (!float.TryParse(token, NumberStyles.Float, CultureInfo.InvariantCulture, out scale))
{
// Not numeric!
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": expected Scale value, but got '" + token + "'");
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": expected Scale value, but got '" + token + "'.");
gotErrors = true;
break;
}
if (scale > 1.0f)
{
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": scale must be in 0.0 - 1.0 range, but is " + scale);
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": scale must be in 0.0 - 1.0 range, but is " + scale + ".");
gotErrors = true;
break;
}
@ -345,7 +372,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
}
else
{
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": '" + token + "' is not valid property for " + lightType);
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": '" + token + "' is not valid property for " + lightType + ".");
gotErrors = true;
break;
}
@ -405,14 +432,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
if (!string.IsNullOrEmpty(objectClass))
{
//now find opening brace
SkipWhitespace(true);
token = ReadToken();
if (token != "{")
{
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": expected '{', but got '" + token + "'");
continue;
}
if(!NextTokenIs("{")) continue;
int bracesCount = 1;
bool foundLight = false;
@ -450,7 +470,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
}
else
{
General.ErrorLogger.Add(ErrorType.Warning, "Light declaration not found for light '" + token + "' ('" + sourcefilename + "', line " + GetCurrentLineNumber()+")");
General.ErrorLogger.Add(ErrorType.Warning, "Light declaration not found for light '" + token + "' ('" + sourcefilename + "', line " + GetCurrentLineNumber()+").");
}
}
}
@ -465,7 +485,128 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
}
}
}
}
}
//Glowing flats block start
else if(token == "glow")
{
// Next sould be opening brace
if(!NextTokenIs("{")) continue;
// Parse inner blocks
while(SkipWhitespace(true))
{
token = ReadToken().ToLowerInvariant();
if(token == "flats" || token == "walls")
{
// Next sould be opening brace
if(!NextTokenIs("{")) break;
// Read flat names
while(SkipWhitespace(true))
{
token = ReadToken();
if(token == "}") break;
// Add glow data
glowingflats[General.Map.Data.GetFullLongFlatName(Lump.MakeLongName(token, General.Map.Options.UseLongTextureNames))] = new GlowingFlatData {
Height = 128,
Fullbright = true,
Color = new PixelColor(255, 255, 255, 255),
CalculateTextureColor = true
};
}
}
else if(token == "texture")
{
string texturename = StripTokenQuotes(ReadToken());
if(string.IsNullOrEmpty(texturename))
{
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": expected a texture name.");
break;
}
// Now we should find a comma
if(!NextTokenIs(",")) break;
// Next is color
SkipWhitespace(true);
token = ReadToken();
int color;
if(!int.TryParse(token, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out color))
{
//probably it's a color name?
Color c = Color.FromName(token); //should be similar to C++ color name detection, I suppose
if(c.IsKnownColor)
{
color = PixelColor.FromColor(c).ToInt();
}
else
{
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": expected glow color value, but got '" + token + "'.");
break;
}
}
// The glow data is valid at thispoint. Let's get texture hash
long texturehash = General.Map.Data.GetFullLongFlatName(Lump.MakeLongName(texturename, General.Map.Options.UseLongTextureNames));
// Now we can find a comma
if(!NextTokenIs(",", false))
{
// Add glow data
glowingflats[texturehash] = new GlowingFlatData {
Height = 128,
Fullbright = false,
Color = PixelColor.FromInt(color).WithAlpha(255),
CalculateTextureColor = false
};
continue;
}
// Should be glow height
int height;
if(!int.TryParse(token, NumberStyles.Integer, CultureInfo.InvariantCulture, out height))
{
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": expected glow height value, but got '" + token + "'.");
break;
}
// Now we can find a comma
if(!NextTokenIs(",", false))
{
// Add glow data
glowingflats[texturehash] = new GlowingFlatData {
Height = height * 2,
Fullbright = false,
Color = PixelColor.FromInt(color).WithAlpha(255),
CalculateTextureColor = false
};
continue;
}
// Next is "fullbright" flag
SkipWhitespace(true);
bool fullbright = (ReadToken().ToLowerInvariant() == "fullbright");
// Add glow data
glowingflats[texturehash] = new GlowingFlatData {
Height = height,
Fullbright = fullbright,
Color = PixelColor.FromInt(color).WithAlpha(255),
CalculateTextureColor = false
};
}
}
// Now find closing brace
while(SkipWhitespace(true))
{
if(ReadToken() == "}") break;
}
}
else if (token == "#include")
{
SkipWhitespace(true);
@ -483,7 +624,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
}
else
{
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": got #include directive with missing or incorrect path: '" + includeLump + "'");
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": got #include directive with missing or incorrect path: '" + includeLump + "'.");
}
}
else if(token == "$gzdb_skip") //mxd
@ -518,9 +659,15 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
return objects.Count > 0;
}
#endregion
#region ================== Methods
internal void ClearIncludesList()
{
parsedLumps.Clear();
parsedlumps.Clear();
}
#endregion
}
}

View file

@ -1,21 +1,59 @@
using System.Drawing;
#region ================== Namespaces
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.IO;
using SlimDX;
using CodeImp.DoomBuilder.ZDoom;
using CodeImp.DoomBuilder.GZBuilder.Data;
namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
public sealed class MapinfoParser : ZDTextParser {
#endregion
private MapInfo mapInfo;
public MapInfo MapInfo { get { return mapInfo; } }
namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
{
internal sealed class MapinfoParser : ZDTextParser
{
#region ================== Delegates
public bool Parse(Stream stream, string sourcefilename, string mapName)
public delegate void IncludeDelegate(MapinfoParser parser, string includefile);
public IncludeDelegate OnInclude;
#endregion
#region ================== Variables
private MapInfo mapinfo;
private readonly Dictionary<int, string> spawnnums;
private readonly Dictionary<int, string> doomednums; // <DoomEdNum, <lowercase classname, List of default arguments>>
#endregion
#region ================== Properties
public MapInfo MapInfo { get { return mapinfo; } }
public Dictionary<int, string> SpawnNums { get { return spawnnums; } }
public Dictionary<int, string> DoomEdNums { get { return doomednums; } }
#endregion
#region ================== Constructor
public MapinfoParser()
{
mapinfo = new MapInfo();
spawnnums = new Dictionary<int, string>();
doomednums = new Dictionary<int, string>();
}
#endregion
#region ================== Parsing
public bool Parse(Stream stream, string sourcefilename, string mapname)
{
base.Parse(stream, sourcefilename);
mapName = mapName.ToLowerInvariant();
mapInfo = new MapInfo();
mapname = mapname.ToLowerInvariant();
while (SkipWhitespace(true))
{
@ -23,16 +61,16 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
if (token != null)
{
token = token.ToLowerInvariant();
if (ParseBlock(token, mapName)) break;
if (ParseBlock(token, mapname)) break;
}
}
//check values
if (mapInfo.FadeColor.Red > 0 || mapInfo.FadeColor.Green > 0 || mapInfo.FadeColor.Blue > 0)
mapInfo.HasFadeColor = true;
if (mapinfo.FadeColor.Red > 0 || mapinfo.FadeColor.Green > 0 || mapinfo.FadeColor.Blue > 0)
mapinfo.HasFadeColor = true;
if (mapInfo.OutsideFogColor.Red > 0 || mapInfo.OutsideFogColor.Green > 0 || mapInfo.OutsideFogColor.Blue > 0)
mapInfo.HasOutsideFogColor = true;
if (mapinfo.OutsideFogColor.Red > 0 || mapinfo.OutsideFogColor.Green > 0 || mapinfo.OutsideFogColor.Blue > 0)
mapinfo.HasOutsideFogColor = true;
//Cannot fail here
return true;
@ -41,6 +79,11 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
//returns true if parsing is finished
private bool ParseBlock(string token, string mapName)
{
// Keep local data
Stream localstream = datastream;
string localsourcename = sourcename;
BinaryReader localreader = datareader;
if (token == "map" || token == "defaultmap" || token == "adddefaultmap")
{
string curBlockName = token;
@ -55,7 +98,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
case "defaultmap":
//reset MapInfo
mapInfo = new MapInfo();
mapinfo = new MapInfo();
break;
}
@ -84,9 +127,9 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
if (!string.IsNullOrEmpty(skyTexture))
{
if (skyType == "sky1")
mapInfo.Sky1 = skyTexture;
mapinfo.Sky1 = skyTexture;
else
mapInfo.Sky2 = skyTexture;
mapinfo.Sky2 = skyTexture;
//check if we have scrollspeed
SkipWhitespace(true);
@ -111,9 +154,9 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
}
if (skyType == "sky1")
mapInfo.Sky1ScrollSpeed = scrollSpeed;
mapinfo.Sky1ScrollSpeed = scrollSpeed;
else
mapInfo.Sky2ScrollSpeed = scrollSpeed;
mapinfo.Sky2ScrollSpeed = scrollSpeed;
}
else
{
@ -133,9 +176,9 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
if (!string.IsNullOrEmpty(token))
{
if (skyType == "sky1")
mapInfo.Sky1 = token;
mapinfo.Sky1 = token;
else
mapInfo.Sky2 = token;
mapinfo.Sky2 = token;
//try to read scroll speed
SkipWhitespace(true);
@ -150,9 +193,9 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
}
if (skyType == "sky1")
mapInfo.Sky1ScrollSpeed = scrollSpeed;
mapinfo.Sky1ScrollSpeed = scrollSpeed;
else
mapInfo.Sky2ScrollSpeed = scrollSpeed;
mapinfo.Sky2ScrollSpeed = scrollSpeed;
}
else
@ -185,9 +228,9 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
if(GetColor(colorVal, ref color))
{
if(fadeType == "fade")
mapInfo.FadeColor = color;
mapinfo.FadeColor = color;
else
mapInfo.OutsideFogColor = color;
mapinfo.OutsideFogColor = color;
}
else //...or not
{
@ -225,9 +268,9 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
}
if(shadeType == "vertwallshade")
mapInfo.VertWallShade = General.Clamp(val, -255, 255);
mapinfo.VertWallShade = General.Clamp(val, -255, 255);
else
mapInfo.HorizWallShade = General.Clamp(val, -255, 255);
mapinfo.HorizWallShade = General.Clamp(val, -255, 255);
}
//fogdensity or outsidefogdensity
else if(token == "fogdensity" || token == "outsidefogdensity")
@ -253,25 +296,25 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
}
if (densityType == "fogdensity")
mapInfo.FogDensity = (int)(1024 * (256.0f / val));
mapinfo.FogDensity = (int)(1024 * (256.0f / val));
else
mapInfo.OutsideFogDensity = (int)(1024 * (256.0f / val));
mapinfo.OutsideFogDensity = (int)(1024 * (256.0f / val));
}
//doublesky
else if (token == "doublesky")
{
mapInfo.DoubleSky = true;
mapinfo.DoubleSky = true;
}
//evenlighting
else if (token == "evenlighting")
{
mapInfo.EvenLighting = true;
mapinfo.EvenLighting = true;
}
//smoothlighting
else if (token == "smoothlighting")
{
mapInfo.SmoothLighting = true;
mapinfo.SmoothLighting = true;
}
//block end
else if (token == "}")
@ -279,10 +322,134 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
return (curBlockName == "map" || ParseBlock(token, mapName));
}
}
}
else if(token == "#include")
{
SkipWhitespace(true);
string includeLump = StripTokenQuotes(ReadToken()).ToLowerInvariant();
if(!string.IsNullOrEmpty(includeLump))
{
// Callback to parse this file
if(OnInclude != null)
OnInclude(this, includeLump.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar));
// Set our buffers back to continue parsing
datastream = localstream;
datareader = localreader;
sourcename = localsourcename;
}
else
{
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcename + "' at line " + GetCurrentLineNumber() + ": got #include directive with missing or incorrect path: '" + includeLump + "'.");
}
}
else if(token == "doomednums")
{
if(!NextTokenIs("{")) return true; // Finished with this file
while(SkipWhitespace(true))
{
token = ReadToken();
if(string.IsNullOrEmpty(token))
{
General.ErrorLogger.Add(ErrorType.Error, "Error while parisng '" + sourcename + "' at line " + GetCurrentLineNumber() + ": failed to find the end of DoomEdNums block");
return true; // Finished with this file
}
if(token == "}") break;
// First must be a number
int id;
if(!int.TryParse(token, NumberStyles.Integer, CultureInfo.InvariantCulture, out id))
{
// Not numeric!
General.ErrorLogger.Add(ErrorType.Error, "Unexpected token found in '" + sourcename + "' at line " + GetCurrentLineNumber() + ": expected DoomEdNums entry number, but got '" + token + "'");
return true; // Finished with this file
}
// Then "="
if(!NextTokenIs("=")) return true; // Finished with this file
// Then actor class
SkipWhitespace(false);
string classname = StripTokenQuotes(ReadToken());
if(string.IsNullOrEmpty(classname))
{
General.ErrorLogger.Add(ErrorType.Error, "Error while parisng '" + sourcename + "' at line " + GetCurrentLineNumber() + ": unable to get DoomEdNums entry class definition");
return true; // Finished with this file
}
// Possible args
for (int i = 0; i < 5; i++)
{
if(!SkipWhitespace(false) || !NextTokenIs(",", false)) break;
// Read an arg
if(!SkipWhitespace(false)) break;
token = ReadToken();
int arg;
if(!int.TryParse(token, NumberStyles.Integer, CultureInfo.InvariantCulture, out arg))
{
// Not numeric!
General.ErrorLogger.Add(ErrorType.Error, "Unexpected token found in '" + sourcename + "' at line " + GetCurrentLineNumber() + ": expected SpawnNums actor argument " + (i + 1) + ", but got '" + token + "'");
break;
}
}
// Add to collection?
if(id != 0) doomednums[id] = classname.ToLowerInvariant();
}
}
else if(token == "spawnnums")
{
if(!NextTokenIs("{")) return true; // Finished with this file
while (SkipWhitespace(true))
{
token = ReadToken();
if(string.IsNullOrEmpty(token))
{
General.ErrorLogger.Add(ErrorType.Error, "Error while parisng '" + sourcename + "' at line " + GetCurrentLineNumber() + ": failed to find the end of SpawnNums block");
return true; // Finished with this file
}
if(token == "}") break;
// First must be a number
int id;
if(!int.TryParse(token, NumberStyles.Integer, CultureInfo.InvariantCulture, out id))
{
// Not numeric!
General.ErrorLogger.Add(ErrorType.Error, "Unexpected token found in '" + sourcename + "' at line " + GetCurrentLineNumber() + ": expected SpawnNums number, but got '" + token + "'");
return true; // Finished with this file
}
// Then "="
if(!NextTokenIs("=")) return true; // Finished with this file
// Then actor class
SkipWhitespace(false);
token = StripTokenQuotes(ReadToken());
if(string.IsNullOrEmpty(token))
{
General.ErrorLogger.Add(ErrorType.Error, "Error while parisng '" + sourcename + "' at line " + GetCurrentLineNumber() + ": unable to get SpawnNums entry class definition");
return true;
}
// Add to collection
spawnnums[id] = token.ToLowerInvariant();
}
}
else if(token == "$gzdb_skip")
{
return true; // Finished with this file
}
return false;
return false; // Not done yet
}
#endregion
#region ================== Methods
private static bool GetColor(string name, ref Color4 color)
{
if (name == "black") return true;
@ -304,5 +471,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
}
return false;
}
#endregion
}
}

View file

@ -150,12 +150,6 @@ namespace CodeImp.DoomBuilder.GZBuilder
if (General.Map != null) General.Map.Data.ReloadGldefs();
}
[BeginAction("gzreloadmapinfo")]
private static void ReloadMapInfo()
{
if (General.Map != null) General.Map.Data.ReloadMapInfo();
}
#endregion
}
}

View file

@ -36,26 +36,14 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
}
}
private static VertexElement[] vertexElements;
#endregion
#region ================== Init
internal static void Init()
private static readonly VertexElement[] vertexElements = new[]
{
if(vertexElements == null)
{
vertexElements = new[]
{
new VertexElement(0, 0, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Position, 0),
new VertexElement(0, 12, DeclarationType.Color, DeclarationMethod.Default, DeclarationUsage.Color, 0),
new VertexElement(0, 16, DeclarationType.Float2, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 0),
new VertexElement(0, 24, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Normal, 0),
VertexElement.VertexDeclarationEnd
};
}
}
new VertexElement(0, 0, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Position, 0),
new VertexElement(0, 12, DeclarationType.Color, DeclarationMethod.Default, DeclarationUsage.Color, 0),
new VertexElement(0, 16, DeclarationType.Float2, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 0),
new VertexElement(0, 24, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Normal, 0),
VertexElement.VertexDeclarationEnd
};
#endregion

View file

@ -1,4 +1,5 @@
using System;
using CodeImp.DoomBuilder.Rendering;
namespace CodeImp.DoomBuilder.Geometry
{
@ -57,5 +58,15 @@ namespace CodeImp.DoomBuilder.Geometry
{
return (int)Math.Round(-(val2 - val1) / 2 * (float)(Math.Cos(Math.PI * delta) - 1) + val1);
}
//mxd
public static int InterpolateColor(PixelColor c1, PixelColor c2, float delta)
{
float invdelta = 1.0f - delta;
byte r = (byte)(c1.r * delta + c2.r * invdelta);
byte g = (byte)(c1.g * delta + c2.g * invdelta);
byte b = (byte)(c1.b * delta + c2.b * invdelta);
return new PixelColor(255, r, g, b).ToInt();
}
}
}

View file

@ -24,7 +24,7 @@ namespace CodeImp.DoomBuilder.Rendering
public struct FlatVertex
{
// Vertex format
public static readonly int Stride = 6 * 4;
public const int Stride = 6 * 4;
// Members
public float x;

View file

@ -16,6 +16,7 @@
#region ================== Namespaces
using System;
using System.Drawing;
using SlimDX;
@ -153,6 +154,18 @@ namespace CodeImp.DoomBuilder.Rendering
return c;
}
//mxd. This adds two colors
public static PixelColor Add(PixelColor a, PixelColor b)
{
return new PixelColor
{
a = (byte)(Math.Min(a.a + b.a, 255)),
r = (byte)(Math.Min(a.r + b.r, 255)),
g = (byte)(Math.Min(a.g + b.g, 255)),
b = (byte)(Math.Min(a.b + b.b, 255))
};
}
// This modulates two colors
public static PixelColor Modulate(PixelColor a, PixelColor b)
@ -165,12 +178,14 @@ namespace CodeImp.DoomBuilder.Rendering
float br = b.r * BYTE_TO_FLOAT;
float bg = b.g * BYTE_TO_FLOAT;
float bb = b.b * BYTE_TO_FLOAT;
PixelColor c = new PixelColor();
c.a = (byte)((aa * ba) * 255.0f);
c.r = (byte)((ar * br) * 255.0f);
c.g = (byte)((ag * bg) * 255.0f);
c.b = (byte)((ab * bb) * 255.0f);
return c;
return new PixelColor
{
a = (byte)((aa * ba) * 255.0f),
r = (byte)((ar * br) * 255.0f),
g = (byte)((ag * bg) * 255.0f),
b = (byte)((ab * bb) * 255.0f)
};
}
#endregion

View file

@ -24,7 +24,7 @@ namespace CodeImp.DoomBuilder.Rendering
// of sector vertices, the surface manager will take care of splitting it up in several SurfaceEntries.
internal class SurfaceUpdate
{
public int numvertices;
public readonly int numvertices;
// Sector geometry (local copy used to quickly refill buffers)
// The sector must set these!
@ -43,15 +43,8 @@ namespace CodeImp.DoomBuilder.Rendering
this.floortexture = 0;
this.ceiltexture = 0;
if(updatefloor)
this.floorvertices = new FlatVertex[numvertices];
else
this.floorvertices = null;
if(updateceiling)
this.ceilvertices = new FlatVertex[numvertices];
else
this.ceilvertices = null;
this.floorvertices = (updatefloor ? new FlatVertex[numvertices] : null);
this.ceilvertices = (updateceiling ? new FlatVertex[numvertices] : null);
}
}
}

View file

@ -26,7 +26,7 @@ namespace CodeImp.DoomBuilder.Rendering
public struct WorldVertex
{
// Vertex format
public static readonly int Stride = 9 * 4; //mxd: was 6 * 4
public const int Stride = 9 * 4; //mxd: was 6 * 4
// Members
public float x;
@ -58,7 +58,7 @@ namespace CodeImp.DoomBuilder.Rendering
}
// Constructor
public WorldVertex(float x, float y, float z, int c, Vector2D t)
/*public WorldVertex(float x, float y, float z, int c, Vector2D t)
{
this.x = x;
this.y = y;
@ -71,10 +71,10 @@ namespace CodeImp.DoomBuilder.Rendering
this.nx = 0.0f;
this.ny = 0.0f;
this.nz = 0.0f;
}
}*/
// Constructor
public WorldVertex(Vector3D p, int c, float u, float v)
/*public WorldVertex(Vector3D p, int c, float u, float v)
{
this.x = p.x;
this.y = p.y;
@ -87,7 +87,7 @@ namespace CodeImp.DoomBuilder.Rendering
this.nx = 0.0f;
this.ny = 0.0f;
this.nz = 0.0f;
}
}*/
// Constructor
public WorldVertex(Vector3D p, int c, Vector2D t)
@ -106,7 +106,7 @@ namespace CodeImp.DoomBuilder.Rendering
}
// Constructor
public WorldVertex(float x, float y, float z, float u, float v)
/*public WorldVertex(float x, float y, float z, float u, float v)
{
this.x = x;
this.y = y;
@ -119,10 +119,10 @@ namespace CodeImp.DoomBuilder.Rendering
this.nx = 0.0f;
this.ny = 0.0f;
this.nz = 0.0f;
}
}*/
// Constructor
public WorldVertex(float x, float y, float z, Vector2D t)
/*public WorldVertex(float x, float y, float z, Vector2D t)
{
this.x = x;
this.y = y;
@ -135,10 +135,10 @@ namespace CodeImp.DoomBuilder.Rendering
this.nx = 0.0f;
this.ny = 0.0f;
this.nz = 0.0f;
}
}*/
// Constructor
public WorldVertex(Vector3D p, float u, float v)
/*public WorldVertex(Vector3D p, float u, float v)
{
this.x = p.x;
this.y = p.y;
@ -151,10 +151,10 @@ namespace CodeImp.DoomBuilder.Rendering
this.nx = 0.0f;
this.ny = 0.0f;
this.nz = 0.0f;
}
}*/
// Constructor
public WorldVertex(Vector3D p, Vector2D t)
/*public WorldVertex(Vector3D p, Vector2D t)
{
this.x = p.x;
this.y = p.y;
@ -167,10 +167,10 @@ namespace CodeImp.DoomBuilder.Rendering
this.nx = 0.0f;
this.ny = 0.0f;
this.nz = 0.0f;
}
}*/
// Constructor
public WorldVertex(float x, float y, float z, int c)
/*public WorldVertex(float x, float y, float z, int c)
{
this.x = x;
this.y = y;
@ -183,10 +183,10 @@ namespace CodeImp.DoomBuilder.Rendering
this.nx = 0.0f;
this.ny = 0.0f;
this.nz = 0.0f;
}
}*/
// Constructor
public WorldVertex(Vector3D p, int c)
/*public WorldVertex(Vector3D p, int c)
{
this.x = p.x;
this.y = p.y;
@ -199,7 +199,7 @@ namespace CodeImp.DoomBuilder.Rendering
this.nx = 0.0f;
this.ny = 0.0f;
this.nz = 0.0f;
}
}*/
// Constructor
public WorldVertex(float x, float y, float z)

View file

@ -1158,7 +1158,7 @@ gzreloadmodeldef
gzreloadgldefs
{
title = "Reload GLDEFS";
title = "Reload GLDEFS";
category = "tools";
description = "Reloads GLDEFS. Useful when resource files have been changed outside of Doom Builder.";
allowkeys = true;
@ -1167,17 +1167,6 @@ gzreloadgldefs
default = 131189;
}
gzreloadmapinfo
{
title = "Reload (Z)MAPINFO";
category = "tools";
description = "Reloads (Z)MAPINFO. Useful when resource files have been changed outside of Doom Builder.";
allowkeys = true;
allowmouse = false;
allowscroll = false;
default = 131190;
}
/////////////////////////////////////////
//GZDOOMBUILDER EXTENDED THING MOVEMENT//
/////////////////////////////////////////

View file

@ -48,7 +48,7 @@ namespace CodeImp.DoomBuilder.Types
// When set up for an argument
public override void SetupArgument(TypeHandlerAttribute attr, ArgumentInfo arginfo)
{
defaultvalue = new EnumItem("0", "0: No Tag");
defaultvalue = new EnumItem("0", "0");
base.SetupArgument(attr, arginfo);
// Create enum list reference
@ -106,7 +106,7 @@ namespace CodeImp.DoomBuilder.Types
// Input null?
if(value == null)
{
this.value = new EnumItem("0", "0: No Tag");
this.value = new EnumItem("0", "0");
}
else
{

View file

@ -121,7 +121,6 @@ namespace CodeImp.DoomBuilder.Windows
this.itemreloadresources = new System.Windows.Forms.ToolStripMenuItem();
this.itemReloadModedef = new System.Windows.Forms.ToolStripMenuItem();
this.itemReloadGldefs = new System.Windows.Forms.ToolStripMenuItem();
this.itemReloadMapinfo = new System.Windows.Forms.ToolStripMenuItem();
this.itemshowerrors = new System.Windows.Forms.ToolStripMenuItem();
this.seperatortoolsresources = new System.Windows.Forms.ToolStripSeparator();
this.configurationToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@ -962,7 +961,6 @@ namespace CodeImp.DoomBuilder.Windows
this.itemreloadresources,
this.itemReloadModedef,
this.itemReloadGldefs,
this.itemReloadMapinfo,
this.itemshowerrors,
this.seperatortoolsresources,
this.configurationToolStripMenuItem,
@ -1000,14 +998,6 @@ namespace CodeImp.DoomBuilder.Windows
this.itemReloadGldefs.Text = "Reload GLDEFS";
this.itemReloadGldefs.Click += new System.EventHandler(this.InvokeTaggedAction);
//
// itemReloadMapinfo
//
this.itemReloadMapinfo.Name = "itemReloadMapinfo";
this.itemReloadMapinfo.Size = new System.Drawing.Size(246, 22);
this.itemReloadMapinfo.Tag = "builder_gzreloadmapinfo";
this.itemReloadMapinfo.Text = "Reload (Z)MAPINFO";
this.itemReloadMapinfo.Click += new System.EventHandler(this.InvokeTaggedAction);
//
// itemshowerrors
//
this.itemshowerrors.Image = global::CodeImp.DoomBuilder.Properties.Resources.Warning;
@ -2422,7 +2412,6 @@ namespace CodeImp.DoomBuilder.Windows
private System.Windows.Forms.ToolStripStatusLabel warnsLabel;
private System.Windows.Forms.ToolStripMenuItem itemReloadModedef;
private System.Windows.Forms.ToolStripMenuItem itemReloadGldefs;
private System.Windows.Forms.ToolStripMenuItem itemReloadMapinfo;
private System.Windows.Forms.ToolStripSeparator separatorDrawModes;
private System.Windows.Forms.ToolStripButton buttontoggleeventlines;
private System.Windows.Forms.ToolStripButton buttontogglevisualvertices;

View file

@ -2916,7 +2916,6 @@ namespace CodeImp.DoomBuilder.Windows
//mxd
itemReloadGldefs.Enabled = enabled;
itemReloadMapinfo.Enabled = enabled;
itemReloadModedef.Enabled = enabled;
}

View file

@ -40,7 +40,7 @@ namespace CodeImp.DoomBuilder.ZDoom
private readonly string classname;
private readonly string inheritclass;
private readonly string replaceclass;
private readonly int doomednum = -1;
private int doomednum = -1;
// Inheriting
private ActorStructure baseclass;
@ -66,7 +66,7 @@ namespace CodeImp.DoomBuilder.ZDoom
public string InheritsClass { get { return inheritclass; } }
public string ReplacesClass { get { return replaceclass; } }
public ActorStructure BaseClass { get { return baseclass; } }
public int DoomEdNum { get { return doomednum; } }
internal int DoomEdNum { get { return doomednum; } set { doomednum = value; } }
public List<string> UserVars { get { return userVars; } } //mxd
#endregion

View file

@ -59,7 +59,17 @@ namespace CodeImp.DoomBuilder.ZDoom
/// All actors defined in the loaded DECORATE structures. This includes actors not supported in the current game.
/// </summary>
public ICollection<ActorStructure> AllActors { get { return archivedactors.Values; } }
/// <summary>
/// mxd. All actors that are supported by the current game.
/// </summary>
internal Dictionary<string, ActorStructure> ActorsByClass { get { return actors; } }
/// <summary>
/// mxd. All actors defined in the loaded DECORATE structures. This includes actors not supported in the current game.
/// </summary>
internal Dictionary<string, ActorStructure> AllActorsByClass { get { return archivedactors; } }
#endregion
#region ================== Constructor / Disposer

View file

@ -369,6 +369,7 @@
<Compile Include="VisualModes\Effect3DFloor.cs" />
<Compile Include="VisualModes\EffectBrightnessLevel.cs" />
<Compile Include="VisualModes\EffectCopySlope.cs" />
<Compile Include="VisualModes\EffectGlowingFlat.cs" />
<Compile Include="VisualModes\EffectLineSlope.cs" />
<Compile Include="VisualModes\EffectPlaneCopySlope.cs" />
<Compile Include="VisualModes\EffectThingLineSlope.cs" />

View file

@ -288,9 +288,22 @@ namespace CodeImp.DoomBuilder.BuilderModes
Vector2D scale = new Vector2D(s.Fields.GetValue("xscalefloor", 1.0f),
s.Fields.GetValue("yscalefloor", 1.0f));
float rotate = s.Fields.GetValue("rotationfloor", 0.0f);
int color = s.Fields.GetValue("lightcolor", -1);
int light = s.Fields.GetValue("lightfloor", 0);
bool absolute = s.Fields.GetValue("lightfloorabsolute", false);
int color, light;
bool absolute;
//mxd. Apply GLDEFS override?
if(General.Map.Data.GlowingFlats.ContainsKey(s.LongFloorTexture) && General.Map.Data.GlowingFlats[s.LongFloorTexture].Fullbright)
{
color = -1;
light = 255;
absolute = true;
}
else
{
color = s.Fields.GetValue("lightcolor", -1);
light = s.Fields.GetValue("lightfloor", 0);
absolute = s.Fields.GetValue("lightfloorabsolute", false);
}
// Setup the vertices with the given settings
SetupSurfaceVertices(vertices, s, img, offset, scale, rotate, color, light, absolute);
@ -326,9 +339,22 @@ namespace CodeImp.DoomBuilder.BuilderModes
Vector2D scale = new Vector2D(s.Fields.GetValue("xscaleceiling", 1.0f),
s.Fields.GetValue("yscaleceiling", 1.0f));
float rotate = s.Fields.GetValue("rotationceiling", 0.0f);
int color = s.Fields.GetValue("lightcolor", -1);
int light = s.Fields.GetValue("lightceiling", 0);
bool absolute = s.Fields.GetValue("lightceilingabsolute", false);
int color, light;
bool absolute;
//mxd. Apply GLDEFS override?
if(General.Map.Data.GlowingFlats.ContainsKey(s.LongCeilTexture) && General.Map.Data.GlowingFlats[s.LongCeilTexture].Fullbright)
{
color = -1;
light = 255;
absolute = true;
}
else
{
color = s.Fields.GetValue("lightcolor", -1);
light = s.Fields.GetValue("lightceiling", 0);
absolute = s.Fields.GetValue("lightceilingabsolute", false);
}
// Setup the vertices with the given settings
SetupSurfaceVertices(vertices, s, img, offset, scale, rotate, color, light, absolute);

View file

@ -219,11 +219,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
//mxd
protected void OnTextureChanged()
{
//mxd. Effects may need updating...
mode.RebuildElementData();
if(level.sector == this.Sector.Sector)
{
this.Setup();
//check for 3d floors
//mxd. 3D floors may need updating...
foreach(Sidedef s in level.sector.Sidedefs)
{
if(s.Line.Action == 160 && s.Line.Front != null)
@ -239,7 +242,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
}
}
}
}
//mxd. As well as this sector's geometry
else if(mode.VisualSectorExists(level.sector))
{
BaseVisualSector vs = (BaseVisualSector)mode.GetVisualSector(level.sector);
@ -761,12 +765,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
General.Interface.OnEditFormValuesChanged += Interface_OnEditFormValuesChanged; //mxd
mode.StartRealtimeInterfaceUpdate(SelectionType.Sectors); //mxd
General.Interface.ShowEditSectors(sectors);
DialogResult result = General.Interface.ShowEditSectors(sectors);
mode.StopRealtimeInterfaceUpdate(SelectionType.Sectors); //mxd
General.Interface.OnEditFormValuesChanged -= Interface_OnEditFormValuesChanged; //mxd
updateList.Clear(); //mxd
updateList = null; //mxd
if(result == DialogResult.OK) mode.RebuildElementData(); //mxd
}
}

View file

@ -181,8 +181,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
&& (prevlight.lighttype == LightLevelType.TYPE1 && l.lighttype != LightLevelType.TYPE1_BOTTOM))
continue;
if(l.type == SectorLevelType.Light) prevlight = l;
if((l != sd.Floor) && (l != sd.Ceiling) && (l.type != SectorLevelType.Floor || l.alpha < 255))
{
// Go for all polygons
@ -213,8 +211,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
PixelColor wallbrightness = PixelColor.FromInt(mode.CalculateBrightness(lightlevel, Sidedef)); //mxd
PixelColor wallcolor = PixelColor.Modulate(l.colorbelow, wallbrightness);
np.color = wallcolor.WithAlpha(255).ToInt();
np.color = PixelColor.Modulate(l.colorbelow, wallbrightness).WithAlpha(255).ToInt();
if(p.Count == 0)
{
@ -232,6 +229,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
}
}
//mxd
if(l.type == SectorLevelType.Light) prevlight = l;
}
// Go for all polygons to make geometry
@ -239,12 +239,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
// Find texture coordinates for each vertex in the polygon
List<Vector2D> texc = new List<Vector2D>(p.Count);
foreach(Vector3D v in p)
texc.Add(tp.GetTextureCoordsAt(v));
foreach(Vector3D v in p) texc.Add(tp.GetTextureCoordsAt(v));
// Now we create triangles from the polygon.
// The polygon is convex and clockwise, so this is a piece of cake.
if(p.Count >= 3)
if(p.Count > 2)
{
for(int k = 1; k < (p.Count - 1); k++)
{
@ -254,9 +253,54 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
}
}
//mxd. Interpolate vertex colors?
if(sd.CeilingGlow != null || sd.FloorGlow != null)
{
for(int i = 0; i < verts.Count; i++)
verts[i] = InterpolateVertexColor(verts[i], sd);
}
return verts;
}
//mxd
private static WorldVertex InterpolateVertexColor(WorldVertex v, SectorData data)
{
// Apply ceiling glow?
if(data.CeilingGlow != null)
{
float cgz = data.CeilingGlowPlane.GetZ(v.x, v.y);
// Vertex is above ceiling glow plane?
if(v.z > cgz)
{
float cz = data.Ceiling.plane.GetZ(v.x, v.y);
float delta = ((v.z - cgz) / (cz - cgz)) * 0.9f;
PixelColor vc = PixelColor.FromInt(v.c);
v.c = InterpolationTools.InterpolateColor(PixelColor.Add(vc, data.CeilingGlow.Color), vc, delta);
}
}
// Apply floor glow?
if(data.FloorGlow != null)
{
float fgz = data.FloorGlowPlane.GetZ(v.x, v.y);
// Vertex is below floor glow plane?
if(v.z < fgz)
{
float fz = data.Floor.plane.GetZ(v.x, v.y);
float delta = ((v.z - fz) / (fgz - fz)) * 0.9f;
PixelColor vc = PixelColor.FromInt(v.c);
v.c = InterpolationTools.InterpolateColor(vc, PixelColor.Add(vc, data.FloorGlow.Color), delta);
}
}
return v;
}
// This splits a polygon with a plane and returns the other part as a new polygon
// The polygon is expected to be convex and clockwise
@ -1255,25 +1299,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
updateList.Clear();
updateList = null;
if(result == DialogResult.OK)
{
foreach(Linedef l in linedefs)
{
if(l.Front != null && mode.VisualSectorExists(l.Front.Sector))
{
BaseVisualSector vs = (BaseVisualSector)mode.GetVisualSector(l.Front.Sector);
vs.UpdateSectorGeometry(false);
}
if(l.Back != null && mode.VisualSectorExists(l.Back.Sector))
{
BaseVisualSector vs = (BaseVisualSector)mode.GetVisualSector(l.Back.Sector);
vs.UpdateSectorGeometry(false);
}
}
mode.RebuildElementData();
}
//mxd. Effects may need updating...
if(result == DialogResult.OK) mode.RebuildElementData();
}
}

View file

@ -859,6 +859,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
sd.AddEffectThingVertexSlope(slopeceilingthings, false);
}
}
else if(General.Map.Data.GlowingFlats.ContainsKey(s.LongFloorTexture) || General.Map.Data.GlowingFlats.ContainsKey(s.LongCeilTexture))
{
SectorData sd = GetSectorData(s);
sd.AddEffectGlowingFlat(s);
}
}
// Find interesting linedefs (such as line slopes)

View file

@ -0,0 +1,93 @@
using CodeImp.DoomBuilder.Map;
using CodeImp.DoomBuilder.Rendering;
namespace CodeImp.DoomBuilder.BuilderModes
{
internal class EffectGlowingFlat : SectorEffect
{
private readonly Sector sector;
// Level planes
private SectorLevel ceillevel;
private SectorLevel floorlevel;
// Constructor
public EffectGlowingFlat(SectorData data, Sector sourcesector) : base(data)
{
sector = sourcesector;
// New effect added: This sector needs an update!
if(data.Mode.VisualSectorExists(data.Sector))
{
BaseVisualSector vs = (BaseVisualSector)data.Mode.GetVisualSector(data.Sector);
vs.UpdateSectorGeometry(false);
}
}
public override void Update()
{
// Create ceiling glow effect?
if(General.Map.Data.GlowingFlats.ContainsKey(sector.LongCeilTexture))
{
// Create ceiling level?
if(ceillevel == null)
{
ceillevel = new SectorLevel(data.Ceiling);
ceillevel.type = SectorLevelType.Glow;
ceillevel.disablelighting = true;
data.AddSectorLevel(ceillevel);
}
// Update ceiling level
data.CeilingGlow = General.Map.Data.GlowingFlats[sector.LongCeilTexture];
ceillevel.brightnessbelow = -1; // We need this plane for clipping only,
ceillevel.color = 0; // so we need to reset all shading and coloring
ceillevel.plane = data.Ceiling.plane;
ceillevel.plane.Offset -= data.CeilingGlow.Height;
data.CeilingGlowPlane = ceillevel.plane;
}
else
{
data.CeilingGlow = null;
}
// Create floor glow effect?
if(General.Map.Data.GlowingFlats.ContainsKey(sector.LongFloorTexture))
{
// Create floor level?
if(floorlevel == null)
{
floorlevel = new SectorLevel(data.Floor);
floorlevel.type = SectorLevelType.Glow;
floorlevel.disablelighting = true;
data.AddSectorLevel(floorlevel);
}
// Update floor level
data.FloorGlow = General.Map.Data.GlowingFlats[sector.LongFloorTexture];
floorlevel.plane = data.Floor.plane.GetInverted();
floorlevel.plane.Offset += data.FloorGlow.Height;
if(floorlevel.plane.Offset < data.Ceiling.plane.Offset)
{
floorlevel.brightnessbelow = -1; // We need this plane for clipping only,
floorlevel.color = 0; // so we need to reset all shading and coloring
floorlevel.colorbelow = new PixelColor(0, 0, 0, 0);
}
else
{
// If glow plane is above real ceiling, apply ceiling colouring
floorlevel.brightnessbelow = data.Ceiling.brightnessbelow;
floorlevel.color = data.Ceiling.color;
floorlevel.colorbelow = data.Ceiling.colorbelow;
}
data.FloorGlowPlane = floorlevel.plane;
}
else
{
data.FloorGlow = null;
}
}
}
}

View file

@ -1,6 +1,7 @@
#region === Copyright (c) 2010 Pascal van der Heiden ===
using System.Collections.Generic;
using CodeImp.DoomBuilder.GZBuilder.Data;
using CodeImp.DoomBuilder.Geometry;
using CodeImp.DoomBuilder.Map;
using CodeImp.DoomBuilder.Rendering;
@ -31,6 +32,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Effects
private readonly List<SectorEffect> alleffects;
private readonly List<Effect3DFloor> extrafloors;
internal GlowingFlatData CeilingGlow; //mxd
internal GlowingFlatData FloorGlow; //mxd
internal Plane FloorGlowPlane; //mxd
internal Plane CeilingGlowPlane; //mxd
// Sectors that must be updated when this sector is changed
// The boolean value is the 'includeneighbours' of the UpdateSectorGeometry function which
@ -169,6 +175,13 @@ namespace CodeImp.DoomBuilder.BuilderModes
EffectUDMFVertexOffset e = new EffectUDMFVertexOffset(this);
alleffects.Add(e);
}
//mxd.
public void AddEffectGlowingFlat(Sector sourcesector)
{
EffectGlowingFlat e = new EffectGlowingFlat(this, sourcesector);
alleffects.Add(e);
}
// This adds a sector for updating
public void AddUpdateSector(Sector s, bool includeneighbours)
@ -187,9 +200,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
// This resets this sector data and all sectors that require updating after me
public void Reset()
{
if(isupdating)
return;
if(isupdating) return;
isupdating = true;
// This is set to false so that this sector is rebuilt the next time it is needed!
@ -280,8 +291,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
BasicSetup();
// Update all effects
foreach(SectorEffect e in alleffects)
e.Update();
foreach(SectorEffect e in alleffects) e.Update();
// Sort the levels (only if there are more than 2 sector levels - mxd)
if (lightlevels.Count > 2)
@ -352,6 +362,24 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(l.brightnessbelow == -1) l.brightnessbelow = pl.brightnessbelow;
}
//mxd. Apply glow effects?
if(CeilingGlow != null && CeilingGlow.Fullbright)
{
ceiling.color = -1;
}
if(FloorGlow != null)
{
if(FloorGlow.Fullbright) floor.color = -1;
floor.brightnessbelow = ((FloorGlow.Fullbright ? 255 : (FloorGlow.Color.r + FloorGlow.Color.g + FloorGlow.Color.b) / 3) + sector.Brightness) / 2;
if(floor.colorbelow.ToInt() == 0)
{
byte bb = (byte)floor.brightnessbelow;
floor.colorbelow = PixelColor.Add(floor.colorbelow, new PixelColor(255, bb, bb, bb));
}
}
floorchanged = false;
ceilingchanged = false;
updated = true;
@ -458,7 +486,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
return found;
}
#endregion
}

View file

@ -20,26 +20,24 @@ namespace CodeImp.DoomBuilder.BuilderModes
this.center = new Vector2D(s.BBox.Left + s.BBox.Width / 2, s.BBox.Top + s.BBox.Height / 2);
}
// Comparer
// Comparer. -1 = x is less than y.
public int Compare(SectorLevel x, SectorLevel y)
{
if(x == y) return 0; //mxd
float diff = (float)Math.Round(x.plane.GetZ(center) - y.plane.GetZ(center), 3);
if(diff == 0)
{
bool xislight = (x.type == SectorLevelType.Light || x.type == SectorLevelType.Glow);
bool yislight = (y.type == SectorLevelType.Light || y.type == SectorLevelType.Glow);
//mxd. Push light levels above floor and ceiling levels when height is the same
if(x.type != SectorLevelType.Light) return (y.type == SectorLevelType.Light ? -1 : 0);
if(y.type != SectorLevelType.Light) return (x.type == SectorLevelType.Light ? 1 : 0);
if(!xislight) return (yislight ? -1 : 0);
if(!yislight) return 1;
//mxd. Push light levels without lighttype (those should be lower levels of type 1 Transfer Brightness effect) above other ones
if(x.type == SectorLevelType.Light && y.type == SectorLevelType.Light)
{
if(x.lighttype == y.lighttype) return 0; //TODO: how this should be handled?
if(x.lighttype == LightLevelType.TYPE1_BOTTOM) return 1;
return -1;
}
return 0;
if(x.lighttype == y.lighttype) return 0; //TODO: how this should be handled?
if(x.lighttype == LightLevelType.TYPE1_BOTTOM) return 1;
return -1;
}
return Math.Sign(diff);

View file

@ -8,7 +8,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
Light,
Floor,
Ceiling
Ceiling,
Glow
}
//mxd

View file

@ -12,20 +12,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
// The color that the wall should have
public int color;
// Constructor
public WallPolygon()
{
}
// Constructor
public WallPolygon(int capacity) : base(capacity)
{
}
// Constructor
public WallPolygon(IEnumerable<Vector3D> collection) : base(collection)
{
}
// Constructors
public WallPolygon() { }
public WallPolygon(int capacity) : base(capacity) { }
// This copies all the wall properties
public void CopyProperties(WallPolygon target)