diff --git a/dumb/include/dumb.h b/dumb/include/dumb.h index bcd2022987..cafcfea3b8 100644 --- a/dumb/include/dumb.h +++ b/dumb/include/dumb.h @@ -44,7 +44,7 @@ #define DUMB_VERSION_STR "0.9.3" -#define DUMB_NAME "DUMB v"DUMB_VERSION_STR +#define DUMB_NAME "DUMB v" DUMB_VERSION_STR #define DUMB_YEAR 2005 #define DUMB_MONTH 8 @@ -56,13 +56,13 @@ #define DUMB_DAY_STR1 "7" #if DUMB_MONTH < 10 -#define DUMB_MONTH_STR2 "0"DUMB_MONTH_STR1 +#define DUMB_MONTH_STR2 "0" DUMB_MONTH_STR1 #else #define DUMB_MONTH_STR2 DUMB_MONTH_STR1 #endif #if DUMB_DAY < 10 -#define DUMB_DAY_STR2 "0"DUMB_DAY_STR1 +#define DUMB_DAY_STR2 "0" DUMB_DAY_STR1 #else #define DUMB_DAY_STR2 DUMB_DAY_STR1 #endif @@ -74,7 +74,7 @@ */ #define DUMB_DATE (DUMB_YEAR*10000 + DUMB_MONTH*100 + DUMB_DAY) -#define DUMB_DATE_STR DUMB_DAY_STR1"."DUMB_MONTH_STR1"."DUMB_YEAR_STR4 +#define DUMB_DATE_STR DUMB_DAY_STR1 "." DUMB_MONTH_STR1 "." DUMB_YEAR_STR4 #undef MIN diff --git a/dumb/src/it/readmod.c b/dumb/src/it/readmod.c index 9d105f126d..801b1ce766 100644 --- a/dumb/src/it/readmod.c +++ b/dumb/src/it/readmod.c @@ -650,8 +650,8 @@ static DUMB_IT_SIGDATA *it_mod_load_sigdata(DUMBFILE *f, int rstrict) if ( ( rstrict & 2 ) ) { - long total_sample_size; - long remain; + int32 total_sample_size; + int32 remain; rem = f; f = dumbfile_buffer_mod_2(rem, sigdata->n_samples, sigdata->sample, &total_sample_size, &remain); if (!f) { diff --git a/dumb/src/it/readxm.c b/dumb/src/it/readxm.c index 25ca07108e..7b92cb9548 100644 --- a/dumb/src/it/readxm.c +++ b/dumb/src/it/readxm.c @@ -436,7 +436,7 @@ static int limit_xm_getc(void *f) -static long limit_xm_getnc(char *ptr, int32 n, void *f) +static int32 limit_xm_getnc(char *ptr, int32 n, void *f) { LIMITED_XM *lx = f; int left; diff --git a/specs/udmf_zdoom.txt b/specs/udmf_zdoom.txt index bdd70322eb..3241bf4c84 100644 --- a/specs/udmf_zdoom.txt +++ b/specs/udmf_zdoom.txt @@ -113,6 +113,7 @@ Note: All fields default to false unless mentioned otherwise. blockprojectiles = ;// Line blocks all projectiles blockuse = ; // Line blocks all use actions blocksight = ; // Line blocks monster line of sight + blockhitscan = ; // Line blocks hitscan attacks locknumber = ; // Line special is locked arg0str = ; // Alternate string-based version of arg0 @@ -186,6 +187,7 @@ Note: All fields default to false unless mentioned otherwise. soundsequence = ; // The sound sequence to play when this sector moves. Placing a // sound sequence thing in the sector will override this property. hidden = ; // if true this sector will not be drawn on the textured automap. + waterzone = ; // Sector is under water and swimmable * Note about dropactors @@ -203,6 +205,8 @@ Note: All fields default to false unless mentioned otherwise. // Parameter is the conversation ID, 0 meaning none. countsecret = ; // Picking up this actor counts as a secret. arg0str = ; // Alternate string-based version of arg0 + gravity = ; // Set per-actor gravity. Positive values are multiplied with the class's property, + // negative values are used as their absolute. Default = 1.0. * Note about arg0str @@ -328,6 +332,9 @@ Added back locknumber property. 1.20 25.02.2012 Added arg0str thing property. +1.21 09.08.2013 +Added waterzone sector property. + =============================================================================== EOF =============================================================================== diff --git a/src/actor.h b/src/actor.h index 7ec6534473..c60b6a516a 100644 --- a/src/actor.h +++ b/src/actor.h @@ -236,7 +236,7 @@ enum MF4_RANDOMIZE = 0x00000010, // Missile has random initial tic count MF4_NOSKIN = 0x00000020, // Player cannot use skins MF4_FIXMAPTHINGPOS = 0x00000040, // Fix this actor's position when spawned as a map thing - MF4_ACTLIKEBRIDGE = 0x00000080, // Pickups can "stand" on this actor + MF4_ACTLIKEBRIDGE = 0x00000080, // Pickups can "stand" on this actor / cannot be moved by any sector action. MF4_STRIFEDAMAGE = 0x00000100, // Strife projectiles only do up to 4x damage, not 8x MF4_CANUSEWALLS = 0x00000200, // Can activate 'use' specials @@ -266,9 +266,9 @@ enum // --- mobj.flags5 --- MF5_DONTDRAIN = 0x00000001, // cannot be drained health from. - /* = 0x00000002, */ + /* = 0x00000002, reserved for use by scripting branch */ MF5_NODROPOFF = 0x00000004, // cannot drop off under any circumstances. - /* = 0x00000008, */ + MF5_NOFORWARDFALL = 0x00000008, // Does not make any actor fall forward by being damaged by this MF5_COUNTSECRET = 0x00000010, // From Doom 64: actor acts like a secret MF5_AVOIDINGDROPOFF = 0x00000020, // Used to move monsters away from dropoffs MF5_NODAMAGE = 0x00000040, // Actor can be shot and reacts to being shot but takes no damage @@ -284,7 +284,7 @@ enum MF5_NEVERFAST = 0x00010000, // never uses 'fast' attacking logic MF5_ALWAYSRESPAWN = 0x00020000, // always respawns, regardless of skill setting MF5_NEVERRESPAWN = 0x00040000, // never respawns, regardless of skill setting - MF5_DONTRIP = 0x00080000, // Ripping projectiles explode when hittin this actor + MF5_DONTRIP = 0x00080000, // Ripping projectiles explode when hitting this actor MF5_NOINFIGHTING = 0x00100000, // This actor doesn't switch target when it's hurt MF5_NOINTERACTION = 0x00200000, // Thing is completely excluded from any gameplay related checks MF5_NOTIMEFREEZE = 0x00400000, // Actor is not affected by time freezer @@ -331,6 +331,14 @@ enum MF6_DOHARMSPECIES = 0x08000000, // Do hurt one's own species with projectiles. MF6_INTRYMOVE = 0x10000000, // Executing P_TryMove MF6_NOTAUTOAIMED = 0x20000000, // Do not subject actor to player autoaim. + MF6_NOTONAUTOMAP = 0x40000000, // will not be shown on automap with the 'scanner' powerup. + MF6_RELATIVETOFLOOR = 0x80000000, // [RC] Make flying actors be affected by lifts. + +// --- mobj.flags6 --- + + MF7_NEVERTARGET = 0x00000001, // can not be targetted at all, even if monster friendliness is considered. + MF7_NOTELESTOMP = 0x00000002, // cannot telefrag under any circumstances (even when set by MAPINFO) + MF7_ALWAYSTELEFRAG = 0x00000004, // will unconditionally be telefragged when in the way. Overrides all other settings. // --- mobj.renderflags --- @@ -836,6 +844,7 @@ public: DWORD flags4; // [RH] Even more flags! DWORD flags5; // OMG! We need another one. DWORD flags6; // Shit! Where did all the flags go? + DWORD flags7; // // [BB] If 0, everybody can see the actor, if > 0, only members of team (VisibleToTeam-1) can see it. DWORD VisibleToTeam; diff --git a/src/am_map.cpp b/src/am_map.cpp index 0c8293ebe5..c227143168 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -68,12 +68,83 @@ #include "a_keys.h" #include "r_data/colormaps.h" + +//============================================================================= +// +// CVARs +// +//============================================================================= + +CVAR (Int, am_rotate, 0, CVAR_ARCHIVE); +CVAR (Int, am_overlay, 0, CVAR_ARCHIVE); +CVAR (Bool, am_showsecrets, true, CVAR_ARCHIVE); +CVAR (Bool, am_showmonsters, true, CVAR_ARCHIVE); +CVAR (Bool, am_showitems, false, CVAR_ARCHIVE); +CVAR (Bool, am_showtime, true, CVAR_ARCHIVE); +CVAR (Bool, am_showtotaltime, false, CVAR_ARCHIVE); +CVAR (Int, am_colorset, 0, CVAR_ARCHIVE); +CVAR (Bool, am_customcolors, true, CVAR_ARCHIVE); +CVAR (Int, am_map_secrets, 1, CVAR_ARCHIVE); +CVAR (Int, am_drawmapback, 1, CVAR_ARCHIVE); +CVAR (Bool, am_showkeys, true, CVAR_ARCHIVE); +CVAR (Bool, am_showtriggerlines, false, CVAR_ARCHIVE); +CVAR (Int, am_showthingsprites, 0, CVAR_ARCHIVE); + //============================================================================= // // Automap colors // //============================================================================= +CVAR (Color, am_backcolor, 0x6c5440, CVAR_ARCHIVE); +CVAR (Color, am_yourcolor, 0xfce8d8, CVAR_ARCHIVE); +CVAR (Color, am_wallcolor, 0x2c1808, CVAR_ARCHIVE); +CVAR (Color, am_secretwallcolor, 0x000000, CVAR_ARCHIVE); +CVAR (Color, am_specialwallcolor, 0xffffff, CVAR_ARCHIVE); +CVAR (Color, am_tswallcolor, 0x888888, CVAR_ARCHIVE); +CVAR (Color, am_fdwallcolor, 0x887058, CVAR_ARCHIVE); +CVAR (Color, am_cdwallcolor, 0x4c3820, CVAR_ARCHIVE); +CVAR (Color, am_efwallcolor, 0x665555, CVAR_ARCHIVE); +CVAR (Color, am_thingcolor, 0xfcfcfc, CVAR_ARCHIVE); +CVAR (Color, am_gridcolor, 0x8b5a2b, CVAR_ARCHIVE); +CVAR (Color, am_xhaircolor, 0x808080, CVAR_ARCHIVE); +CVAR (Color, am_notseencolor, 0x6c6c6c, CVAR_ARCHIVE); +CVAR (Color, am_lockedcolor, 0x007800, CVAR_ARCHIVE); +CVAR (Color, am_intralevelcolor, 0x0000ff, CVAR_ARCHIVE); +CVAR (Color, am_interlevelcolor, 0xff0000, CVAR_ARCHIVE); +CVAR (Color, am_secretsectorcolor, 0xff00ff, CVAR_ARCHIVE); +CVAR (Color, am_thingcolor_friend, 0xfcfcfc, CVAR_ARCHIVE); +CVAR (Color, am_thingcolor_monster, 0xfcfcfc, CVAR_ARCHIVE); +CVAR (Color, am_thingcolor_ncmonster, 0xfcfcfc, CVAR_ARCHIVE); +CVAR (Color, am_thingcolor_item, 0xfcfcfc, CVAR_ARCHIVE); +CVAR (Color, am_thingcolor_citem, 0xfcfcfc, CVAR_ARCHIVE); + +CVAR (Color, am_ovyourcolor, 0xfce8d8, CVAR_ARCHIVE); +CVAR (Color, am_ovwallcolor, 0x00ff00, CVAR_ARCHIVE); +CVAR (Color, am_ovsecretwallcolor, 0x008844, CVAR_ARCHIVE); +CVAR (Color, am_ovspecialwallcolor, 0xffffff, CVAR_ARCHIVE); +CVAR (Color, am_ovotherwallscolor, 0x008844, CVAR_ARCHIVE); +CVAR (Color, am_ovlockedcolor, 0x008844, CVAR_ARCHIVE); +CVAR (Color, am_ovefwallcolor, 0x008844, CVAR_ARCHIVE); +CVAR (Color, am_ovfdwallcolor, 0x008844, CVAR_ARCHIVE); +CVAR (Color, am_ovcdwallcolor, 0x008844, CVAR_ARCHIVE); +CVAR (Color, am_ovunseencolor, 0x00226e, CVAR_ARCHIVE); +CVAR (Color, am_ovtelecolor, 0xffff00, CVAR_ARCHIVE); +CVAR (Color, am_ovinterlevelcolor, 0xffff00, CVAR_ARCHIVE); +CVAR (Color, am_ovsecretsectorcolor,0x00ffff, CVAR_ARCHIVE); +CVAR (Color, am_ovthingcolor, 0xe88800, CVAR_ARCHIVE); +CVAR (Color, am_ovthingcolor_friend, 0xe88800, CVAR_ARCHIVE); +CVAR (Color, am_ovthingcolor_monster, 0xe88800, CVAR_ARCHIVE); +CVAR (Color, am_ovthingcolor_ncmonster, 0xe88800, CVAR_ARCHIVE); +CVAR (Color, am_ovthingcolor_item, 0xe88800, CVAR_ARCHIVE); +CVAR (Color, am_ovthingcolor_citem, 0xe88800, CVAR_ARCHIVE); + +//============================================================================= +// +// internal representation of a single color +// +//============================================================================= + struct AMColor { int Index; @@ -90,48 +161,374 @@ struct AMColor RGB = MAKEARGB(255, r, g, b); Index = ColorMatcher.Pick(r, g, b); } -}; -static AMColor Background, YourColor, WallColor, TSWallColor, - FDWallColor, CDWallColor, EFWallColor, ThingColor, - ThingColor_Item, ThingColor_CountItem, ThingColor_Monster, ThingColor_Friend, - SpecialWallColor, SecretWallColor, GridColor, XHairColor, - NotSeenColor, - LockedColor, - AlmostBackground, - IntraTeleportColor, InterTeleportColor, - SecretSectorColor; + void setInvalid() + { + Index = -1; + RGB = -1; + } -static AMColor DoomColors[11]; -static BYTE DoomPaletteVals[11*3] = -{ - 0x00,0x00,0x00, 0xff,0xff,0xff, 0x10,0x10,0x10, - 0xfc,0x00,0x00, 0x80,0x80,0x80, 0xbc,0x78,0x48, - 0xfc,0xfc,0x00, 0x74,0xfc,0x6c, 0x4c,0x4c,0x4c, - 0x80,0x80,0x80, 0x6c,0x6c,0x6c -}; - -static AMColor StrifeColors[11]; -static BYTE StrifePaletteVals[11*3] = -{ - 0x00,0x00,0x00, 239, 239, 0, 0x10,0x10,0x10, - 199, 195, 195, 119, 115, 115, 55, 59, 91, - 119, 115, 115, 0xfc,0x00,0x00, 0x4c,0x4c,0x4c, - 187, 59, 0, 219, 171, 0 -}; - -static AMColor RavenColors[11]; -static BYTE RavenPaletteVals[11*3] = -{ - 0x6c,0x54,0x40, 255, 255, 255, 0x74,0x5c,0x48, - 75, 50, 16, 88, 93, 86, 208, 176, 133, - 103, 59, 31, 236, 236, 236, 0, 0, 0, - 0, 0, 0, 0, 0, 0, + bool isValid() const + { + return Index > -1; + } }; //============================================================================= // -// globals +// a complete color set +// +//============================================================================= + +static const char *ColorNames[] = { + "Background", + "YourColor", + "WallColor", + "TwoSidedWallColor", + "FloorDiffWallColor", + "CeilingDiffWallColor", + "ExtraFloorWallColor", + "ThingColor", + "ThingColor_Item", + "ThingColor_CountItem", + "ThingColor_Monster", + "ThingColor_NocountMonster", + "ThingColor_Friend", + "SpecialWallColor", + "SecretWallColor", + "GridColor", + "XHairColor", + "NotSeenColor", + "LockedColor", + "IntraTeleportColor", + "InterTeleportColor", + "SecretSectorColor", + "AlmostBackgroundColor", + NULL +}; + +struct AMColorset +{ + enum + { + Background, + YourColor, + WallColor, + TSWallColor, + FDWallColor, + CDWallColor, + EFWallColor, + ThingColor, + ThingColor_Item, + ThingColor_CountItem, + ThingColor_Monster, + ThingColor_NocountMonster, + ThingColor_Friend, + SpecialWallColor, + SecretWallColor, + GridColor, + XHairColor, + NotSeenColor, + LockedColor, + IntraTeleportColor, + InterTeleportColor, + SecretSectorColor, + AlmostBackgroundColor, + AM_NUM_COLORS + }; + + AMColor c[AM_NUM_COLORS]; + bool displayLocks; + bool forcebackground; + bool defined; // only for mod specific colorsets: must be true to be usable + + void initFromCVars(FColorCVar **values) + { + for(int i=0;i MapArrow; static TArray CheatMapArrow; static TArray CheatKey; @@ -342,15 +707,11 @@ static mline_t square_guy[] = { -EXTERN_CVAR (Bool, sv_cheats) -CUSTOM_CVAR (Int, am_cheat, 0, 0) -{ - // No automap cheat in net games when cheats are disabled! - if (netgame && !sv_cheats && self != 0) - { - self = 0; - } -} +//============================================================================= +// +// +// +//============================================================================= static int grid = 0; @@ -560,21 +921,6 @@ void AM_StaticInit() } markpointnum = 0; mapback.SetInvalid(); - - static DWORD *lastpal = NULL; - //static int lastback = -1; - DWORD *palette; - - palette = (DWORD *)GPalette.BaseColors; - - int i, j; - - for (i = j = 0; i < 11; i++, j += 3) - { - DoomColors[i].FromRGB(DoomPaletteVals[j], DoomPaletteVals[j+1], DoomPaletteVals[j+2]); - StrifeColors[i].FromRGB(StrifePaletteVals[j], StrifePaletteVals[j+1], StrifePaletteVals[j+2]); - RavenColors[i].FromRGB(RavenPaletteVals[j], RavenPaletteVals[j+1], RavenPaletteVals[j+2]); - } } //============================================================================= @@ -910,131 +1256,39 @@ static void AM_initColors (bool overlayed) { if (overlayed) { - YourColor.FromCVar (am_ovyourcolor); - WallColor.FromCVar (am_ovwallcolor); - SpecialWallColor.FromCVar(am_ovspecialwallcolor); - SecretWallColor = WallColor; - SecretSectorColor.FromCVar (am_ovsecretsectorcolor); - ThingColor_Item.FromCVar (am_ovthingcolor_item); - ThingColor_CountItem.FromCVar (am_ovthingcolor_citem); - ThingColor_Friend.FromCVar (am_ovthingcolor_friend); - ThingColor_Monster.FromCVar (am_ovthingcolor_monster); - ThingColor.FromCVar (am_ovthingcolor); - LockedColor.FromCVar (am_ovotherwallscolor); - EFWallColor = FDWallColor = CDWallColor = LockedColor; - TSWallColor.FromCVar (am_ovunseencolor); - NotSeenColor = TSWallColor; - InterTeleportColor.FromCVar (am_ovtelecolor); - IntraTeleportColor = InterTeleportColor; + if (am_customcolors && AMModOverlay.defined) + { + AMColors = AMModOverlay; + } + else + { + AMColors.initFromCVars(cv_overlay); + } + } + else if (am_customcolors && AMMod.defined) + { + AMColors = AMMod; } else switch(am_colorset) { default: - { /* Use the custom colors in the am_* cvars */ - Background.FromCVar (am_backcolor); - YourColor.FromCVar (am_yourcolor); - SecretWallColor.FromCVar (am_secretwallcolor); - SpecialWallColor.FromCVar (am_specialwallcolor); - WallColor.FromCVar (am_wallcolor); - TSWallColor.FromCVar (am_tswallcolor); - FDWallColor.FromCVar (am_fdwallcolor); - CDWallColor.FromCVar (am_cdwallcolor); - EFWallColor.FromCVar (am_efwallcolor); - ThingColor_Item.FromCVar (am_thingcolor_item); - ThingColor_CountItem.FromCVar (am_thingcolor_citem); - ThingColor_Friend.FromCVar (am_thingcolor_friend); - ThingColor_Monster.FromCVar (am_thingcolor_monster); - ThingColor.FromCVar (am_thingcolor); - GridColor.FromCVar (am_gridcolor); - XHairColor.FromCVar (am_xhaircolor); - NotSeenColor.FromCVar (am_notseencolor); - LockedColor.FromCVar (am_lockedcolor); - InterTeleportColor.FromCVar (am_interlevelcolor); - IntraTeleportColor.FromCVar (am_intralevelcolor); - SecretSectorColor.FromCVar (am_secretsectorcolor); - - DWORD ba = am_backcolor; - - int r = RPART(ba) - 16; - int g = GPART(ba) - 16; - int b = BPART(ba) - 16; - - if (r < 0) - r += 32; - if (g < 0) - g += 32; - if (b < 0) - b += 32; - - AlmostBackground.FromRGB(r, g, b); + AMColors.initFromCVars(cv_standard); break; - } case 1: // Doom // Use colors corresponding to the original Doom's - Background = DoomColors[0]; - YourColor = DoomColors[1]; - AlmostBackground = DoomColors[2]; - SecretSectorColor = - SecretWallColor = - SpecialWallColor = - WallColor = DoomColors[3]; - TSWallColor = DoomColors[4]; - EFWallColor = FDWallColor = DoomColors[5]; - LockedColor = - CDWallColor = DoomColors[6]; - ThingColor_Item = - ThingColor_Friend = - ThingColor_Monster = - ThingColor = DoomColors[7]; - GridColor = DoomColors[8]; - XHairColor = DoomColors[9]; - NotSeenColor = DoomColors[10]; + AMColors.initFromColors(DoomColors, false); break; case 2: // Strife // Use colors corresponding to the original Strife's - Background = StrifeColors[0]; - YourColor = StrifeColors[1]; - AlmostBackground = DoomColors[2]; - SecretSectorColor = - SecretWallColor = - SpecialWallColor = - WallColor = StrifeColors[3]; - TSWallColor = StrifeColors[4]; - EFWallColor = FDWallColor = StrifeColors[5]; - LockedColor = - CDWallColor = StrifeColors[6]; - ThingColor_Item = StrifeColors[10]; - ThingColor_Friend = - ThingColor_Monster = StrifeColors[7]; - ThingColor = StrifeColors[9]; - GridColor = StrifeColors[8]; - XHairColor = DoomColors[9]; - NotSeenColor = DoomColors[10]; + AMColors.initFromColors(StrifeColors, false); break; case 3: // Raven // Use colors corresponding to the original Raven's - Background = RavenColors[0]; - YourColor = RavenColors[1]; - AlmostBackground = DoomColors[2]; - SecretSectorColor = - SecretWallColor = - SpecialWallColor = - WallColor = RavenColors[3]; - TSWallColor = RavenColors[4]; - EFWallColor = FDWallColor = RavenColors[5]; - LockedColor = - CDWallColor = RavenColors[6]; - ThingColor = - ThingColor_Item = - ThingColor_Friend = - ThingColor_Monster = RavenColors[7]; - GridColor = RavenColors[4]; - XHairColor = RavenColors[9]; - NotSeenColor = RavenColors[10]; + AMColors.initFromColors(RavenColors, true); break; } @@ -1363,7 +1617,17 @@ void AM_Ticker () void AM_clearFB (const AMColor &color) { - if (!mapback.isValid() || !am_drawmapback) + bool drawback = mapback.isValid() && am_drawmapback != 0; + if (am_drawmapback == 2) + { + // only draw background when using a mod defined custom color set or Raven colors, if am_drawmapback is 2. + if (!am_customcolors || !AMMod.defined) + { + drawback &= (am_colorset == 3); + } + } + + if (!drawback) { screen->Clear (0, 0, f_w, f_h, color.Index, color.RGB); } @@ -1536,13 +1800,18 @@ void AM_drawMline (mline_t *ml, const AMColor &color) } } +inline void AM_drawMline (mline_t *ml, int colorindex) +{ + AM_drawMline(ml, AMColors[colorindex]); +} + //============================================================================= // // Draws flat (floor/ceiling tile) aligned grid lines. // //============================================================================= -void AM_drawGrid (const AMColor &color) +void AM_drawGrid (int color) { fixed_t x, y; fixed_t start, end; @@ -1781,20 +2050,23 @@ void AM_drawSubsectors() static bool AM_CheckSecret(line_t *line) { - if (line->frontsector != NULL) + if (AMColors.isValid(AMColors.SecretSectorColor)) { - if (line->frontsector->secretsector) + if (line->frontsector != NULL) { - if (am_map_secrets!=0 && !(line->frontsector->special&SECRET_MASK)) return true; - if (am_map_secrets==2 && !(line->flags & ML_SECRET)) return true; + if (line->frontsector->secretsector) + { + if (am_map_secrets!=0 && !(line->frontsector->special&SECRET_MASK)) return true; + if (am_map_secrets==2 && !(line->flags & ML_SECRET)) return true; + } } - } - if (line->backsector != NULL) - { - if (line->backsector->secretsector) + if (line->backsector != NULL) { - if (am_map_secrets!=0 && !(line->backsector->special&SECRET_MASK)) return true; - if (am_map_secrets==2 && !(line->flags & ML_SECRET)) return true; + if (line->backsector->secretsector) + { + if (am_map_secrets!=0 && !(line->backsector->special&SECRET_MASK)) return true; + if (am_map_secrets==2 && !(line->flags & ML_SECRET)) return true; + } } } return false; @@ -1966,7 +2238,7 @@ void AM_drawWalls (bool allmap) if (am_cheat != 0 || (lines[i].flags & ML_MAPPED)) { - if ((lines[i].flags & ML_DONTDRAW) && am_cheat == 0) + if ((lines[i].flags & ML_DONTDRAW) && (am_cheat == 0 || am_cheat >= 4)) { if (!am_showallenabled || CheckCheatmode(false)) { @@ -1977,39 +2249,42 @@ void AM_drawWalls (bool allmap) if (AM_CheckSecret(&lines[i])) { // map secret sectors like Boom - AM_drawMline(&l, SecretSectorColor); + AM_drawMline(&l, AMColors.SecretSectorColor); } else if (lines[i].flags & ML_SECRET) { // secret door if (am_cheat != 0 && lines[i].backsector != NULL) - AM_drawMline(&l, SecretWallColor); + AM_drawMline(&l, AMColors.SecretWallColor); else - AM_drawMline(&l, WallColor); - } else if (lines[i].locknumber > 0) { // [Dusk] specials w/ locknumbers + AM_drawMline(&l, AMColors.WallColor); + } + else if (lines[i].locknumber > 0 && AMColors.displayLocks) + { // [Dusk] specials w/ locknumbers lock = lines[i].locknumber; color = P_GetMapColorForLock(lock); AMColor c; if (color >= 0) c.FromRGB(RPART(color), GPART(color), BPART(color)); - else c = LockedColor; + else c = AMColors[AMColors.LockedColor]; AM_drawMline (&l, c); - } else if ((lines[i].special == Teleport || + } + else if ((lines[i].special == Teleport || lines[i].special == Teleport_NoFog || lines[i].special == Teleport_ZombieChanger || lines[i].special == Teleport_Line) && (lines[i].activation & SPAC_PlayerActivate) && - am_colorset == 0) + AMColors.isValid(AMColors.IntraTeleportColor)) { // intra-level teleporters - AM_drawMline(&l, IntraTeleportColor); + AM_drawMline(&l, AMColors.IntraTeleportColor); } else if ((lines[i].special == Teleport_NewMap || lines[i].special == Teleport_EndGame || lines[i].special == Exit_Normal || lines[i].special == Exit_Secret) && - am_colorset == 0) + AMColors.isValid(AMColors.InterTeleportColor)) { // inter-level/game-ending teleporters - AM_drawMline(&l, InterTeleportColor); + AM_drawMline(&l, AMColors.InterTeleportColor); } else if (lines[i].special == Door_LockedRaise || lines[i].special == ACS_LockedExecute || @@ -2017,7 +2292,7 @@ void AM_drawWalls (bool allmap) (lines[i].special == Door_Animated && lines[i].args[3] != 0) || (lines[i].special == Generic_Door && lines[i].args[4] != 0)) { - if (am_colorset == 0 || am_colorset == 3) // Raven games show door colors + if (AMColors.displayLocks) { int P_GetMapColorForLock(int lock); @@ -2030,16 +2305,16 @@ void AM_drawWalls (bool allmap) AMColor c; if (color >= 0) c.FromRGB(RPART(color), GPART(color), BPART(color)); - else c = LockedColor; + else c = AMColors[AMColors.LockedColor]; AM_drawMline (&l, c); } else { - AM_drawMline (&l, LockedColor); // locked special + AM_drawMline (&l, AMColors.LockedColor); // locked special } } - else if (am_showtriggerlines && am_colorset == 0 && lines[i].special != 0 + else if (am_showtriggerlines && AMColors.isValid(AMColors.SpecialWallColor) && lines[i].special != 0 && lines[i].special != Door_Open && lines[i].special != Door_Close && lines[i].special != Door_CloseWaitOpen @@ -2048,43 +2323,43 @@ void AM_drawWalls (bool allmap) && lines[i].special != Generic_Door && (lines[i].activation & SPAC_PlayerActivate)) { - AM_drawMline(&l, SpecialWallColor); // wall with special non-door action the player can do + AM_drawMline(&l, AMColors.SpecialWallColor); // wall with special non-door action the player can do } else if (lines[i].backsector == NULL) { - AM_drawMline(&l, WallColor); // one-sided wall + AM_drawMline(&l, AMColors.WallColor); // one-sided wall } else if (lines[i].backsector->floorplane != lines[i].frontsector->floorplane) { - AM_drawMline(&l, FDWallColor); // floor level change + AM_drawMline(&l, AMColors.FDWallColor); // floor level change } else if (lines[i].backsector->ceilingplane != lines[i].frontsector->ceilingplane) { - AM_drawMline(&l, CDWallColor); // ceiling level change + AM_drawMline(&l, AMColors.CDWallColor); // ceiling level change } #ifdef _3DFLOORS else if (AM_Check3DFloors(&lines[i])) { - AM_drawMline(&l, EFWallColor); // Extra floor border + AM_drawMline(&l, AMColors.EFWallColor); // Extra floor border } #endif - else if (am_cheat != 0) + else if (am_cheat > 0 && am_cheat < 4) { - AM_drawMline(&l, TSWallColor); + AM_drawMline(&l, AMColors.TSWallColor); } } else if (allmap) { - if ((lines[i].flags & ML_DONTDRAW) && am_cheat == 0) + if ((lines[i].flags & ML_DONTDRAW) && (am_cheat == 0 || am_cheat >= 4)) { if (!am_showallenabled || CheckCheatmode(false)) { continue; } } - AM_drawMline(&l, NotSeenColor); + AM_drawMline(&l, AMColors.NotSeenColor); } } } @@ -2197,7 +2472,7 @@ AM_drawLineCharacter void AM_drawPlayers () { - if (am_cheat >= 2 && am_showthingsprites > 0) + if (am_cheat >= 2 && am_cheat != 4 && am_showthingsprites > 0) { // Player sprites are drawn with the others return; @@ -2234,7 +2509,7 @@ void AM_drawPlayers () arrow = &MapArrow[0]; numarrowlines = MapArrow.Size(); } - AM_drawLineCharacter(arrow, numarrowlines, 0, angle, YourColor, pt.x, pt.y); + AM_drawLineCharacter(arrow, numarrowlines, 0, angle, AMColors[AMColors.YourColor], pt.x, pt.y); return; } @@ -2261,7 +2536,7 @@ void AM_drawPlayers () if (p->mo->alpha < OPAQUE) { - color = AlmostBackground; + color = AMColors[AMColors.AlmostBackgroundColor]; } else { @@ -2317,7 +2592,6 @@ void AM_drawKeys () angle += ANG90 - players[consoleplayer].camera->angle; } - color = ThingColor; if (key->flags & MF_SPECIAL) { // Find the key's own color. @@ -2327,7 +2601,7 @@ void AM_drawKeys () int c = P_GetMapColorForKey(key); if (c >= 0) color.FromRGB(RPART(c), GPART(c), BPART(c)); - else color = ThingColor_CountItem; + else color = AMColors[AMColors.ThingColor_CountItem]; AM_drawLineCharacter(&EasyKey[0], EasyKey.Size(), 0, 0, color, p.x, p.y); } } @@ -2351,114 +2625,117 @@ void AM_drawThings () t = sectors[i].thinglist; while (t) { - p.x = t->x >> FRACTOMAPBITS; - p.y = t->y >> FRACTOMAPBITS; - - if (am_showthingsprites > 0 && t->sprite > 0) + if (am_cheat > 0 || !(t->flags6 & MF6_NOTONAUTOMAP)) { - FTexture *texture = NULL; - spriteframe_t *frame; - angle_t rotation = 0; + p.x = t->x >> FRACTOMAPBITS; + p.y = t->y >> FRACTOMAPBITS; - // try all modes backwards until a valid texture has been found. - for(int show = am_showthingsprites; show > 0 && texture == NULL; show--) + if (am_showthingsprites > 0 && t->sprite > 0) { - const spritedef_t& sprite = sprites[t->sprite]; - const size_t spriteIndex = sprite.spriteframes + (show > 1 ? t->frame : 0); + FTexture *texture = NULL; + spriteframe_t *frame; + angle_t rotation = 0; + + // try all modes backwards until a valid texture has been found. + for(int show = am_showthingsprites; show > 0 && texture == NULL; show--) + { + const spritedef_t& sprite = sprites[t->sprite]; + const size_t spriteIndex = sprite.spriteframes + (show > 1 ? t->frame : 0); + + frame = &SpriteFrames[spriteIndex]; + angle_t angle = ANGLE_270 - t->angle; + if (frame->Texture[0] != frame->Texture[1]) angle += (ANGLE_180 / 16); + if (am_rotate == 1 || (am_rotate == 2 && viewactive)) + { + angle += players[consoleplayer].camera->angle - ANGLE_90; + } + rotation = angle >> 28; + + const FTextureID textureID = frame->Texture[show > 2 ? rotation : 0]; + texture = TexMan(textureID); + } + + if (texture == NULL) goto drawTriangle; // fall back to standard display if no sprite can be found. + + const fixed_t spriteScale = 10 * scale_mtof; + + DrawMarker (texture, p.x, p.y, 0, !!(frame->Flip & (1 << rotation)), + spriteScale, spriteScale, 0, FRACUNIT, 0, LegacyRenderStyles[STYLE_Normal]); + } + else + { + drawTriangle: + angle = t->angle; - frame = &SpriteFrames[spriteIndex]; - angle_t angle = ANGLE_270 - t->angle; - if (frame->Texture[0] != frame->Texture[1]) angle += (ANGLE_180 / 16); if (am_rotate == 1 || (am_rotate == 2 && viewactive)) { - angle += players[consoleplayer].camera->angle - ANGLE_90; + AM_rotatePoint (&p.x, &p.y); + angle += ANG90 - players[consoleplayer].camera->angle; } - rotation = angle >> 28; - const FTextureID textureID = frame->Texture[show > 2 ? rotation : 0]; - texture = TexMan(textureID); - } + color = AMColors[AMColors.ThingColor]; - if (texture == NULL) goto drawTriangle; // fall back to standard display if no sprite can be found. - - const fixed_t spriteScale = 10 * scale_mtof; - - DrawMarker (texture, p.x, p.y, 0, !!(frame->Flip & (1 << rotation)), - spriteScale, spriteScale, 0, FRACUNIT, 0, LegacyRenderStyles[STYLE_Normal]); - } - else - { - drawTriangle: - angle = t->angle; - - if (am_rotate == 1 || (am_rotate == 2 && viewactive)) - { - AM_rotatePoint (&p.x, &p.y); - angle += ANG90 - players[consoleplayer].camera->angle; - } - - color = ThingColor; - - // use separate colors for special thing types - if (t->flags3&MF3_ISMONSTER && !(t->flags&MF_CORPSE)) - { - if (t->flags & MF_FRIENDLY || !(t->flags & MF_COUNTKILL)) color = ThingColor_Friend; - else color = ThingColor_Monster; - } - else if (t->flags&MF_SPECIAL) - { - // Find the key's own color. - // Only works correctly if single-key locks have lower numbers than any-key locks. - // That is the case for all default keys, however. - if (t->IsKindOf(RUNTIME_CLASS(AKey))) + // use separate colors for special thing types + if (t->flags3&MF3_ISMONSTER && !(t->flags&MF_CORPSE)) { - if (G_SkillProperty(SKILLP_EasyKey)) + if (t->flags & MF_FRIENDLY) color = AMColors[AMColors.ThingColor_Friend]; + else if (!(t->flags & MF_COUNTKILL)) color = AMColors[AMColors.ThingColor_NocountMonster]; + else color = AMColors[AMColors.ThingColor_Monster]; + } + else if (t->flags&MF_SPECIAL) + { + // Find the key's own color. + // Only works correctly if single-key locks have lower numbers than any-key locks. + // That is the case for all default keys, however. + if (t->IsKindOf(RUNTIME_CLASS(AKey))) { - // Already drawn by AM_drawKeys(), so don't draw again - color.Index = -1; - } - else if (am_showkeys) - { - int P_GetMapColorForKey (AInventory * key); - int c = P_GetMapColorForKey(static_cast(t)); + if (G_SkillProperty(SKILLP_EasyKey)) + { + // Already drawn by AM_drawKeys(), so don't draw again + color.Index = -1; + } + else if (am_showkeys) + { + int P_GetMapColorForKey (AInventory * key); + int c = P_GetMapColorForKey(static_cast(t)); - if (c >= 0) color.FromRGB(RPART(c), GPART(c), BPART(c)); - else color = ThingColor_CountItem; - AM_drawLineCharacter(&CheatKey[0], CheatKey.Size(), 0, 0, color, p.x, p.y); - color.Index = -1; + if (c >= 0) color.FromRGB(RPART(c), GPART(c), BPART(c)); + else color = AMColors[AMColors.ThingColor_CountItem]; + AM_drawLineCharacter(&CheatKey[0], CheatKey.Size(), 0, 0, color, p.x, p.y); + color.Index = -1; + } + else + { + color = AMColors[AMColors.ThingColor_Item]; + } } + else if (t->flags&MF_COUNTITEM) + color = AMColors[AMColors.ThingColor_CountItem]; else - { - color = ThingColor_Item; - } + color = AMColors[AMColors.ThingColor_Item]; } - else if (t->flags&MF_COUNTITEM) - color = ThingColor_CountItem; - else - color = ThingColor_Item; - } - if (color.Index != -1) - { - AM_drawLineCharacter - (thintriangle_guy, NUMTHINTRIANGLEGUYLINES, - 16<= 3) - { - static const mline_t box[4] = + if (color.Index != -1) { - { { -MAPUNIT, -MAPUNIT }, { MAPUNIT, -MAPUNIT } }, - { { MAPUNIT, -MAPUNIT }, { MAPUNIT, MAPUNIT } }, - { { MAPUNIT, MAPUNIT }, { -MAPUNIT, MAPUNIT } }, - { { -MAPUNIT, MAPUNIT }, { -MAPUNIT, -MAPUNIT } }, - }; + AM_drawLineCharacter + (thintriangle_guy, NUMTHINTRIANGLEGUYLINES, + 16<radius >> FRACTOMAPBITS, angle - t->angle, color, p.x, p.y); + if (am_cheat == 3 || am_cheat == 6) + { + static const mline_t box[4] = + { + { { -MAPUNIT, -MAPUNIT }, { MAPUNIT, -MAPUNIT } }, + { { MAPUNIT, -MAPUNIT }, { MAPUNIT, MAPUNIT } }, + { { MAPUNIT, MAPUNIT }, { -MAPUNIT, MAPUNIT } }, + { { -MAPUNIT, MAPUNIT }, { -MAPUNIT, -MAPUNIT } }, + }; + + AM_drawLineCharacter (box, 4, t->radius >> FRACTOMAPBITS, angle - t->angle, color, p.x, p.y); + } } } - t = t->snext; } } @@ -2621,7 +2898,7 @@ void AM_Drawer () f_h = ST_Y; f_p = screen->GetPitch (); - AM_clearFB(Background); + AM_clearFB(AMColors[AMColors.Background]); } else { @@ -2637,19 +2914,19 @@ void AM_Drawer () AM_drawSubsectors(); if (grid) - AM_drawGrid(GridColor); + AM_drawGrid(AMColors.GridColor); AM_drawWalls(allmap); AM_drawPlayers(); if (G_SkillProperty(SKILLP_EasyKey)) AM_drawKeys(); - if (am_cheat >= 2 || allthings) + if ((am_cheat >= 2 && am_cheat != 4) || allthings) AM_drawThings(); AM_drawAuthorMarkers(); if (!viewactive) - AM_drawCrosshair(XHairColor); + AM_drawCrosshair(AMColors[AMColors.XHairColor]); AM_drawMarks(); diff --git a/src/b_game.cpp b/src/b_game.cpp index a4c0a18428..ed3a5c8487 100644 --- a/src/b_game.cpp +++ b/src/b_game.cpp @@ -505,7 +505,7 @@ bool FCajunMaster::LoadBots () bool gotteam = false; bglobal.ForgetBots (); -#ifndef unix +#ifndef __unix__ tmp = progdir; tmp += "zcajun/" BOTFILENAME; if (!FileExists (tmp)) diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index 5bde4c5060..cdf615ef49 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -51,6 +51,7 @@ #include "i_system.h" +#include "doomerrors.h" #include "doomstat.h" #include "gstrings.h" #include "s_sound.h" @@ -343,22 +344,30 @@ CCMD (changemap) if (argv.argc() > 1) { - if (!P_CheckMapData(argv[1])) + try { - Printf ("No map %s\n", argv[1]); - } - else - { - if (argv.argc() > 2) + if (!P_CheckMapData(argv[1])) { - Net_WriteByte (DEM_CHANGEMAP2); - Net_WriteByte (atoi(argv[2])); + Printf ("No map %s\n", argv[1]); } else { - Net_WriteByte (DEM_CHANGEMAP); + if (argv.argc() > 2) + { + Net_WriteByte (DEM_CHANGEMAP2); + Net_WriteByte (atoi(argv[2])); + } + else + { + Net_WriteByte (DEM_CHANGEMAP); + } + Net_WriteString (argv[1]); } - Net_WriteString (argv[1]); + } + catch(CRecoverableError &error) + { + if (error.GetMessage()) + Printf("%s", error.GetMessage()); } } else diff --git a/src/c_console.cpp b/src/c_console.cpp index e5d3d97ab1..0c02d0489b 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -1742,7 +1742,7 @@ static bool C_HandleKey (event_t *ev, BYTE *buffer, int len) } break; -#ifdef unix +#ifdef __unix__ case EV_GUI_MButtonDown: C_PasteText(I_GetFromClipboard(true), buffer, len); break; diff --git a/src/c_dispatch.cpp b/src/c_dispatch.cpp index 76b6e395df..88dbc5d649 100644 --- a/src/c_dispatch.cpp +++ b/src/c_dispatch.cpp @@ -1506,7 +1506,7 @@ CCMD (pullin) { const char *lastSlash; -#ifdef unix +#ifdef __unix__ lastSlash = strrchr (PullinFile, '/'); #else const char *lastSlash1, *lastSlash2; diff --git a/src/ct_chat.cpp b/src/ct_chat.cpp index d99acda42d..c0c1f13f0a 100644 --- a/src/ct_chat.cpp +++ b/src/ct_chat.cpp @@ -169,7 +169,7 @@ bool CT_Responder (event_t *ev) } return true; } -#ifdef unix +#ifdef __unix__ else if (ev->subtype == EV_GUI_MButtonDown) { CT_PasteChat(I_GetFromClipboard(true)); diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index dd00000438..e6376a589e 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -1755,21 +1755,21 @@ static int PatchCheats (int dummy) static int PatchMisc (int dummy) { static const struct Key keys[] = { - { "Initial Health", myoffsetof(struct DehInfo,StartHealth) }, - { "Initial Bullets", myoffsetof(struct DehInfo,StartBullets) }, - { "Max Health", myoffsetof(struct DehInfo,MaxHealth) }, - { "Max Armor", myoffsetof(struct DehInfo,MaxArmor) }, - { "Green Armor Class", myoffsetof(struct DehInfo,GreenAC) }, - { "Blue Armor Class", myoffsetof(struct DehInfo,BlueAC) }, - { "Max Soulsphere", myoffsetof(struct DehInfo,MaxSoulsphere) }, - { "Soulsphere Health", myoffsetof(struct DehInfo,SoulsphereHealth) }, - { "Megasphere Health", myoffsetof(struct DehInfo,MegasphereHealth) }, - { "God Mode Health", myoffsetof(struct DehInfo,GodHealth) }, - { "IDFA Armor", myoffsetof(struct DehInfo,FAArmor) }, - { "IDFA Armor Class", myoffsetof(struct DehInfo,FAAC) }, - { "IDKFA Armor", myoffsetof(struct DehInfo,KFAArmor) }, - { "IDKFA Armor Class", myoffsetof(struct DehInfo,KFAAC) }, - { "No Autofreeze", myoffsetof(struct DehInfo,NoAutofreeze) }, + { "Initial Health", static_cast(myoffsetof(struct DehInfo,StartHealth)) }, + { "Initial Bullets", static_cast(myoffsetof(struct DehInfo,StartBullets)) }, + { "Max Health", static_cast(myoffsetof(struct DehInfo,MaxHealth)) }, + { "Max Armor", static_cast(myoffsetof(struct DehInfo,MaxArmor)) }, + { "Green Armor Class", static_cast(myoffsetof(struct DehInfo,GreenAC)) }, + { "Blue Armor Class", static_cast(myoffsetof(struct DehInfo,BlueAC)) }, + { "Max Soulsphere", static_cast(myoffsetof(struct DehInfo,MaxSoulsphere)) }, + { "Soulsphere Health", static_cast(myoffsetof(struct DehInfo,SoulsphereHealth)) }, + { "Megasphere Health", static_cast(myoffsetof(struct DehInfo,MegasphereHealth)) }, + { "God Mode Health", static_cast(myoffsetof(struct DehInfo,GodHealth)) }, + { "IDFA Armor", static_cast(myoffsetof(struct DehInfo,FAArmor)) }, + { "IDFA Armor Class", static_cast(myoffsetof(struct DehInfo,FAAC)) }, + { "IDKFA Armor", static_cast(myoffsetof(struct DehInfo,KFAArmor)) }, + { "IDKFA Armor Class", static_cast(myoffsetof(struct DehInfo,KFAAC)) }, + { "No Autofreeze", static_cast(myoffsetof(struct DehInfo,NoAutofreeze)) }, { NULL, 0 } }; int result; @@ -2329,6 +2329,18 @@ static int DoInclude (int dummy) return GetLine(); } +CVAR(Int, dehload, 0, CVAR_ARCHIVE) // Autoloading of .DEH lumps is disabled by default. + +// checks if lump is a .deh or .bex file. Only lumps in the root directory are considered valid. +static bool isDehFile(int lumpnum) +{ + const char* const fullName = Wads.GetLumpFullName(lumpnum); + const char* const extension = strrchr(fullName, '.'); + + return NULL != extension && strchr(fullName, '/') == NULL + && (0 == stricmp(extension, ".deh") || 0 == stricmp(extension, ".bex")); +} + int D_LoadDehLumps() { int lastlump = 0, lumpnum, count = 0; @@ -2338,23 +2350,29 @@ int D_LoadDehLumps() count += D_LoadDehLump(lumpnum); } - if (0 == PatchSize) + if (0 == PatchSize && dehload > 0) { // No DEH/BEX patch is loaded yet, try to find lump(s) with specific extensions - for (lumpnum = 0, lastlump = Wads.GetNumLumps(); - lumpnum < lastlump; - ++lumpnum) + if (dehload == 1) // load all .DEH lumps that are found. { - const char* const fullName = Wads.GetLumpFullName(lumpnum); - const char* const extension = strrchr(fullName, '.'); - - const bool isDehOrBex = NULL != extension - && (0 == stricmp(extension, ".deh") || 0 == stricmp(extension, ".bex")); - - if (isDehOrBex) + for (lumpnum = 0, lastlump = Wads.GetNumLumps(); lumpnum < lastlump; ++lumpnum) { - count += D_LoadDehLump(lumpnum); + if (isDehFile(lumpnum)) + { + count += D_LoadDehLump(lumpnum); + } + } + } + else // only load the last .DEH lump that is found. + { + for (lumpnum = Wads.GetNumLumps()-1; lumpnum >=0; --lumpnum) + { + if (isDehFile(lumpnum)) + { + count += D_LoadDehLump(lumpnum); + break; + } } } } @@ -2927,7 +2945,7 @@ void FinishDehPatch () PClass *subclass = RUNTIME_CLASS(ADehackedPickup)->CreateDerivedClass (typeNameBuilder, sizeof(ADehackedPickup)); AActor *defaults2 = GetDefaultByType (subclass); - memcpy (defaults2, defaults1, sizeof(AActor)); + memcpy ((void *)defaults2, (void *)defaults1, sizeof(AActor)); // Make a copy of the replaced class's state labels FStateDefinitions statedef; diff --git a/src/d_main.cpp b/src/d_main.cpp index 6c92babe4a..b70e5d779c 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -38,7 +38,7 @@ #endif #include -#if defined(unix) || defined(__APPLE__) +#if defined(__unix__) || defined(__APPLE__) #include #endif @@ -855,7 +855,7 @@ void D_Display () FTexture *tex; int x; - tex = TexMan[gameinfo.PauseSign]; + tex = TexMan(gameinfo.PauseSign); x = (SCREENWIDTH - tex->GetScaledWidth() * CleanXfac)/2 + tex->GetScaledLeftOffset() * CleanXfac; screen->DrawTexture (tex, x, 4, DTA_CleanNoMove, true, TAG_DONE); @@ -1300,7 +1300,7 @@ void D_DoAdvanceDemo (void) gamestate = GS_DEMOSCREEN; pagename = gameinfo.titlePage; pagetic = (int)(gameinfo.titleTime * TICRATE); - S_StartMusic (gameinfo.titleMusic); + S_ChangeMusic (gameinfo.titleMusic, gameinfo.titleOrder, false); demosequence = 3; pagecount = 0; C_HideConsole (); @@ -2009,7 +2009,7 @@ static void AddAutoloadFiles(const char *gamesection) D_AddFile (allwads, wad); // [RH] Add any .wad files in the skins directory -#ifdef unix +#ifdef __unix__ file = SHARE_DIR; #else file = progdir; @@ -2017,7 +2017,7 @@ static void AddAutoloadFiles(const char *gamesection) file += "skins"; D_AddDirectory (allwads, file); -#ifdef unix +#ifdef __unix__ file = NicePath("~/" GAME_DIR "/skins"); D_AddDirectory (allwads, file); #endif @@ -2137,7 +2137,7 @@ static void CheckCmdLine() Printf ("%s", GStrings("D_DEVSTR")); } -#if !defined(unix) && !defined(__APPLE__) +#if !defined(__unix__) && !defined(__APPLE__) // We do not need to support -cdrom under Unix, because all the files // that would go to c:\\zdoomdat are already stored in .zdoom inside // the user's home directory. diff --git a/src/d_player.h b/src/d_player.h index 892adeebf1..75ed533d90 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -141,6 +141,7 @@ public: FNameNoInit MorphWeapon; fixed_t AttackZOffset; // attack height, relative to player center fixed_t UseRange; // [NS] Distance at which player can +use + fixed_t AirCapacity; // Multiplier for air supply underwater. const PClass *FlechetteType; // [CW] Fades for when you are being damaged. diff --git a/src/decallib.cpp b/src/decallib.cpp index c8fe6c593b..91827409b8 100644 --- a/src/decallib.cpp +++ b/src/decallib.cpp @@ -452,7 +452,7 @@ void FDecalLib::ParseDecal (FScanner &sc) decalNum = GetDecalID (sc); sc.MustGetStringName ("{"); - memset (&newdecal, 0, sizeof(newdecal)); + memset ((void *)&newdecal, 0, sizeof(newdecal)); newdecal.PicNum.SetInvalid(); newdecal.ScaleX = newdecal.ScaleY = FRACUNIT; newdecal.RenderFlags = RF_WALLSPRITE; diff --git a/src/doomdata.h b/src/doomdata.h index eeff13e2e5..55903170a7 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -153,6 +153,7 @@ enum ELineFlags ML_BLOCKPROJECTILE = 0x01000000, ML_BLOCKUSE = 0x02000000, // blocks all use actions through this line ML_BLOCKSIGHT = 0x04000000, // blocks monster line of sight + ML_BLOCKHITSCAN = 0x08000000, // blocks hitscan attacks }; @@ -342,6 +343,7 @@ struct FMapThing int special; int args[5]; int Conversation; + fixed_t gravity; void Serialize (FArchive &); }; diff --git a/src/g_doom/a_archvile.cpp b/src/g_doom/a_archvile.cpp index e2fb689c2a..8fce33324f 100644 --- a/src/g_doom/a_archvile.cpp +++ b/src/g_doom/a_archvile.cpp @@ -101,15 +101,20 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileTarget) // // A_VileAttack // + +// A_VileAttack flags +#define VAF_DMGTYPEAPPLYTODIRECT 1 + DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileAttack) { - ACTION_PARAM_START(6); + ACTION_PARAM_START(7); ACTION_PARAM_SOUND(snd,0); ACTION_PARAM_INT(dmg,1); ACTION_PARAM_INT(blastdmg,2); ACTION_PARAM_INT(blastrad,3); ACTION_PARAM_FIXED(thrust,4); ACTION_PARAM_NAME(dmgtype,5); + ACTION_PARAM_INT(flags,6); AActor *fire, *target; angle_t an; @@ -123,7 +128,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileAttack) return; S_Sound (self, CHAN_WEAPON, snd, 1, ATTN_NORM); - int newdam = P_DamageMobj (target, self, self, dmg, NAME_None); + + int newdam; + + if (flags & VAF_DMGTYPEAPPLYTODIRECT) + newdam = P_DamageMobj (target, self, self, dmg, dmgtype); + + else + newdam = P_DamageMobj (target, self, self, dmg, NAME_None); + P_TraceBleed (newdam > 0 ? newdam : dmg, target); an = self->angle >> ANGLETOFINESHIFT; diff --git a/src/g_game.cpp b/src/g_game.cpp index 0db149b0b0..79cd4b2333 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -862,7 +862,10 @@ static void ChangeSpy (int changespy) int pnum = consoleplayer; if (changespy != SPY_CANCEL) { - pnum = int(players[consoleplayer].camera->player - players); + player_t *player = players[consoleplayer].camera->player; + // only use the camera as starting index if it's a valid player. + if (player != NULL) pnum = int(players[consoleplayer].camera->player - players); + int step = (changespy == SPY_NEXT) ? 1 : -1; do @@ -1916,7 +1919,7 @@ FString G_BuildSaveName (const char *prefix, int slot) leader = Args->CheckValue ("-savedir"); if (leader.IsEmpty()) { -#if !defined(unix) && !defined(__APPLE__) +#if !defined(__unix__) && !defined(__APPLE__) if (Args->CheckParm ("-cdrom")) { leader = CDROM_DIR "/"; @@ -1928,7 +1931,7 @@ FString G_BuildSaveName (const char *prefix, int slot) } if (leader.IsEmpty()) { -#ifdef unix +#ifdef __unix__ leader = "~/" GAME_DIR; #elif defined(__APPLE__) char cpath[PATH_MAX]; diff --git a/src/g_level.cpp b/src/g_level.cpp index a452d55767..7e56d8843d 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -40,6 +40,7 @@ #include "s_sound.h" #include "d_event.h" #include "m_random.h" +#include "doomerrors.h" #include "doomstat.h" #include "wi_stuff.h" #include "w_wad.h" @@ -170,13 +171,21 @@ CCMD (map) } if (argv.argc() > 1) { - if (!P_CheckMapData(argv[1])) + try { - Printf ("No map %s\n", argv[1]); + if (!P_CheckMapData(argv[1])) + { + Printf ("No map %s\n", argv[1]); + } + else + { + G_DeferedInitNew (argv[1]); + } } - else + catch(CRecoverableError &error) { - G_DeferedInitNew (argv[1]); + if (error.GetMessage()) + Printf("%s", error.GetMessage()); } } else diff --git a/src/g_level.h b/src/g_level.h index e7d1cbbd2b..c431b96956 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -103,6 +103,7 @@ struct FMapInfoParser void ParseIntermissionAction(FIntermissionDescriptor *Desc); void ParseIntermission(); + void ParseAMColors(bool); FName CheckEndSequence(); FName ParseEndGame(); }; diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index 7a80751742..04617a0689 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -1842,6 +1842,18 @@ void FMapInfoParser::ParseMapInfo (int lump, level_info_t &gamedefaults, level_i sc.ScriptError("intermission definitions not supported with old MAPINFO syntax"); } } + else if (sc.Compare("automap") || sc.Compare("automap_overlay")) + { + if (format_type != FMT_Old) + { + format_type = FMT_New; + ParseAMColors(sc.Compare("automap_overlay")); + } + else + { + sc.ScriptError("automap colorset definitions not supported with old MAPINFO syntax"); + } + } else { sc.ScriptError("%s: Unknown top level keyword", sc.String); diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 0de822f626..2ef2b03c54 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -589,7 +589,7 @@ void APowerInvisibility::DoEffect () Super::DoEffect(); // Due to potential interference with other PowerInvisibility items // the effect has to be refreshed each tic. - fixed_t ts = Strength * (special1 + 1); if (ts > FRACUNIT) ts = FRACUNIT; + fixed_t ts = (Strength/100) * (special1 + 1); if (ts > FRACUNIT) ts = FRACUNIT; Owner->alpha = clamp((OPAQUE - ts), 0, OPAQUE); switch (Mode) { @@ -669,7 +669,7 @@ int APowerInvisibility::AlterWeaponSprite (visstyle_t *vis) else if (changed == 1) { // something else set the weapon sprite back to opaque but this item is still active. - fixed_t ts = Strength * (special1 + 1); if (ts > FRACUNIT) ts = FRACUNIT; + fixed_t ts = (Strength/100) * (special1 + 1); if (ts > FRACUNIT) ts = FRACUNIT; vis->alpha = clamp((OPAQUE - ts), 0, OPAQUE); switch (Mode) { @@ -696,7 +696,7 @@ int APowerInvisibility::AlterWeaponSprite (visstyle_t *vis) // Handling of Strife-like cumulative invisibility powerups, the weapon itself shouldn't become invisible if ((vis->alpha < TRANSLUC25 && special1 > 0) || (vis->alpha == 0)) { - vis->alpha = clamp((OPAQUE - Strength), 0, OPAQUE); + vis->alpha = clamp((OPAQUE - (Strength/100)), 0, OPAQUE); vis->colormap = SpecialColormaps[INVERSECOLORMAP].Colormap; } return -1; // This item is valid so another one shouldn't reset the translucency @@ -1697,7 +1697,7 @@ void APowerRegeneration::DoEffect() { if (Owner != NULL && Owner->health > 0 && (level.time & 31) == 0) { - if (P_GiveBody(Owner, 5)) + if (P_GiveBody(Owner, Strength/FRACUNIT)) { S_Sound(Owner, CHAN_ITEM, "*regenerate", 1, ATTN_NORM ); } diff --git a/src/g_shared/a_pickups.h b/src/g_shared/a_pickups.h index 6c68990d14..22d1e009fb 100644 --- a/src/g_shared/a_pickups.h +++ b/src/g_shared/a_pickups.h @@ -134,6 +134,8 @@ enum IF_RESTRICTABSOLUTELY = 1<<19, // RestrictedTo and ForbiddenTo do not allow pickup in any form by other classes IF_NEVERRESPAWN = 1<<20, // Never, ever respawns IF_NOSCREENFLASH = 1<<21, // No pickup flash on the player's screen + IF_TOSSED = 1<<22, // Was spawned by P_DropItem (i.e. as a monster drop) + }; diff --git a/src/g_shared/a_randomspawner.cpp b/src/g_shared/a_randomspawner.cpp index 293b17d3b6..adfc09b6e6 100644 --- a/src/g_shared/a_randomspawner.cpp +++ b/src/g_shared/a_randomspawner.cpp @@ -121,7 +121,11 @@ class ARandomSpawner : public AActor AActor * newmobj = NULL; bool boss = false; Super::PostBeginPlay(); - if (Species == NAME_None) { Destroy(); return; } + if (Species == NAME_None) + { + Destroy(); + return; + } const PClass * cls = PClass::FindClass(Species); if (this->flags & MF_MISSILE && target && target->target) // Attempting to spawn a missile. { @@ -142,8 +146,9 @@ class ARandomSpawner : public AActor newmobj->args[4] = args[4]; newmobj->special1 = special1; newmobj->special2 = special2; - newmobj->SpawnFlags = SpawnFlags; + newmobj->SpawnFlags = SpawnFlags & ~MTF_SECRET; // MTF_SECRET needs special treatment to avoid incrementing the secret counter twice. It had already been processed for the spawner itself. newmobj->HandleSpawnFlags(); + newmobj->SpawnFlags = SpawnFlags; newmobj->tid = tid; newmobj->AddToHash(); newmobj->velx = velx; diff --git a/src/g_strife/a_strifeweapons.cpp b/src/g_strife/a_strifeweapons.cpp index 82560e6f79..a410584925 100644 --- a/src/g_strife/a_strifeweapons.cpp +++ b/src/g_strife/a_strifeweapons.cpp @@ -137,18 +137,40 @@ DEFINE_ACTION_FUNCTION(AActor, A_JabDagger) // //============================================================================ +enum +{ + AMF_TARGETEMITTER = 1, + AMF_TARGETNONPLAYER = 2, + AMF_EMITFROMTARGET = 4, +}; + DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_AlertMonsters) { ACTION_PARAM_START(1); ACTION_PARAM_FIXED(maxdist, 0); + ACTION_PARAM_INT(Flags, 1); - if (self->player != NULL) + AActor * target = NULL; + AActor * emitter = self; + + if (self->player != NULL || (Flags & AMF_TARGETEMITTER)) { - P_NoiseAlert(self, self, false, maxdist); + target = self; + } + else if (self->target != NULL && (Flags & AMF_TARGETNONPLAYER)) + { + target = self->target; } else if (self->target != NULL && self->target->player != NULL) { - P_NoiseAlert (self->target, self, false, maxdist); + target = self->target; + } + + if (Flags & AMF_EMITFROMTARGET) emitter = target; + + if (target != NULL && emitter != NULL) + { + P_NoiseAlert(target, emitter, false, maxdist); } } diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index 5c6fb0ce2e..211ef96c65 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -135,7 +135,7 @@ FGameConfigFile::FGameConfigFile () local_app_support << cpath << "/" GAME_DIR; SetValueForKey("Path", local_app_support, true); } -#elif !defined(unix) +#elif !defined(__unix__) SetValueForKey ("Path", "$HOME", true); SetValueForKey ("Path", "$PROGDIR", true); #else @@ -153,7 +153,7 @@ FGameConfigFile::FGameConfigFile () SetValueForKey ("Path", user_app_support, true); SetValueForKey ("Path", "$PROGDIR", true); SetValueForKey ("Path", local_app_support, true); -#elif !defined(unix) +#elif !defined(__unix__) SetValueForKey ("Path", "$PROGDIR", true); #else SetValueForKey ("Path", "~/" GAME_DIR, true); @@ -683,7 +683,7 @@ void FGameConfigFile::CreateStandardAutoExec(const char *section, bool start) { path << cpath << "/" GAME_DIR "/autoexec.cfg"; } -#elif !defined(unix) +#elif !defined(__unix__) path = "$PROGDIR/autoexec.cfg"; #else path = GetUserFile ("autoexec.cfg"); diff --git a/src/gi.cpp b/src/gi.cpp index 75476c8005..d9d58dc9e6 100644 --- a/src/gi.cpp +++ b/src/gi.cpp @@ -184,6 +184,20 @@ const char* GameInfoBorders[] = gameinfo.key.color = NAME_Null; \ } +#define GAMEINFOKEY_MUSIC(key, order, variable) \ + else if(nextKey.CompareNoCase(variable) == 0) \ + { \ + sc.MustGetToken(TK_StringConst); \ + gameinfo.order = 0; \ + char *colon = strchr (sc.String, ':'); \ + if (colon) \ + { \ + gameinfo.order = atoi(colon+1); \ + *colon = 0; \ + } \ + gameinfo.key = sc.String; \ + } + void FMapInfoParser::ParseGameInfo() { @@ -286,12 +300,12 @@ void FMapInfoParser::ParseGameInfo() GAMEINFOKEY_STRINGARRAY(creditPages, "CreditPage", 8, true) GAMEINFOKEY_STRINGARRAY(PlayerClasses, "addplayerclasses", 0, false) GAMEINFOKEY_STRINGARRAY(PlayerClasses, "playerclasses", 0, true) - GAMEINFOKEY_STRING(titleMusic, "titleMusic") + GAMEINFOKEY_MUSIC(titleMusic, titleOrder, "titleMusic") GAMEINFOKEY_FLOAT(titleTime, "titleTime") GAMEINFOKEY_FLOAT(advisoryTime, "advisoryTime") GAMEINFOKEY_FLOAT(pageTime, "pageTime") GAMEINFOKEY_STRING(chatSound, "chatSound") - GAMEINFOKEY_STRING(finaleMusic, "finaleMusic") + GAMEINFOKEY_MUSIC(finaleMusic, finaleOrder, "finaleMusic") GAMEINFOKEY_CSTRING(finaleFlat, "finaleFlat", 8) GAMEINFOKEY_STRINGARRAY(finalePages, "finalePage", 8, true) GAMEINFOKEY_STRINGARRAY(infoPages, "addinfoPage", 8, false) @@ -309,7 +323,7 @@ void FMapInfoParser::ParseGameInfo() GAMEINFOKEY_COLOR(defaultbloodparticlecolor, "defaultbloodparticlecolor") GAMEINFOKEY_STRING(backpacktype, "backpacktype") GAMEINFOKEY_STRING(statusbar, "statusbar") - GAMEINFOKEY_STRING(intermissionMusic, "intermissionMusic") + GAMEINFOKEY_MUSIC(intermissionMusic, intermissionOrder, "intermissionMusic") GAMEINFOKEY_STRING(CursorPic, "CursorPic") GAMEINFOKEY_BOOL(noloopfinalemusic, "noloopfinalemusic") GAMEINFOKEY_BOOL(drawreadthis, "drawreadthis") diff --git a/src/gi.h b/src/gi.h index ff678df074..6b887e1dd0 100644 --- a/src/gi.h +++ b/src/gi.h @@ -91,11 +91,13 @@ struct gameinfo_t TArray PlayerClasses; FString titleMusic; + int titleOrder; float titleTime; float advisoryTime; float pageTime; FString chatSound; FString finaleMusic; + int finaleOrder; char finaleFlat[9]; char borderFlat[9]; char SkyFlatName[9]; @@ -114,6 +116,7 @@ struct gameinfo_t FString backpacktype; FString statusbar; FString intermissionMusic; + int intermissionOrder; FString CursorPic; DWORD dimcolor; float dimamount; diff --git a/src/gstrings.h b/src/gstrings.h index 41e37dbc50..770510cfdd 100644 --- a/src/gstrings.h +++ b/src/gstrings.h @@ -42,11 +42,6 @@ extern FStringTable GStrings; -// QuitGame messages -#define NUM_QUITDOOMMESSAGES 14 -#define NUM_QUITSTRIFEMESSAGES 8 -#define NUM_QUITCHEXMESSAGES 7 - extern const char *endmsg[]; diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index 6ee67006e4..91090e4328 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -80,7 +80,7 @@ void DIntermissionScreen::Init(FIntermissionAction *desc, bool first) if (desc->mMusic.IsEmpty()) { // only start the default music if this is the first action in an intermission - if (first) S_ChangeMusic (gameinfo.finaleMusic, 0, desc->mMusicLooping); + if (first) S_ChangeMusic (gameinfo.finaleMusic, gameinfo.finaleOrder, desc->mMusicLooping); } else { diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index 07c467bac6..5d9d48bea6 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -311,6 +311,7 @@ void cht_DoCheat (player_t *player, int cheat) player->mo->flags4 = player->mo->GetDefault()->flags4; player->mo->flags5 = player->mo->GetDefault()->flags5; player->mo->flags6 = player->mo->GetDefault()->flags6; + player->mo->flags7 = player->mo->GetDefault()->flags7; player->mo->renderflags &= ~RF_INVISIBLE; player->mo->height = player->mo->GetDefault()->height; player->mo->radius = player->mo->GetDefault()->radius; diff --git a/src/m_fixed.h b/src/m_fixed.h index 61080d73d2..71b3981241 100644 --- a/src/m_fixed.h +++ b/src/m_fixed.h @@ -12,7 +12,7 @@ #include #include "doomtype.h" -#if defined(__GNUC__) && defined(__i386__) +#if defined(__GNUC__) && defined(__i386__) && !defined(__clang__) #include "gccinlines.h" #elif defined(_MSC_VER) && defined(_M_IX86) #include "mscinlines.h" diff --git a/src/m_misc.cpp b/src/m_misc.cpp index a8c6b73802..e218cadc44 100644 --- a/src/m_misc.cpp +++ b/src/m_misc.cpp @@ -333,7 +333,7 @@ static long ParseCommandLine (const char *args, int *argc, char **argv) } -#if defined(unix) +#if defined(__unix__) FString GetUserFile (const char *file) { FString path; @@ -698,7 +698,7 @@ void M_ScreenShot (const char *filename) // find a file name to save it to if (filename == NULL || filename[0] == '\0') { -#if !defined(unix) && !defined(__APPLE__) +#if !defined(__unix__) && !defined(__APPLE__) if (Args->CheckParm ("-cdrom")) { autoname = CDROM_DIR "\\"; @@ -715,7 +715,7 @@ void M_ScreenShot (const char *filename) dirlen = autoname.Len(); if (dirlen == 0) { -#ifdef unix +#ifdef __unix__ autoname = "~/" GAME_DIR "/screenshots/"; #elif defined(__APPLE__) char cpath[PATH_MAX]; diff --git a/src/menu/loadsavemenu.cpp b/src/menu/loadsavemenu.cpp index 9a87bb806b..f16e1cbc22 100644 --- a/src/menu/loadsavemenu.cpp +++ b/src/menu/loadsavemenu.cpp @@ -345,7 +345,7 @@ void DLoadSaveMenu::NotifyNewSave (const char *file, const char *title, bool okF for (unsigned i=0; iFilename.Compare (file) == 0) #else if (node->Filename.CompareNoCase (file) == 0) diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index dc1b8ccd8b..d01f0807f3 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -207,7 +207,7 @@ bool DMenu::MouseEventBack(int type, int x, int y) { if (m_show_backbutton >= 0) { - FTexture *tex = TexMan[gameinfo.mBackButton]; + FTexture *tex = TexMan(gameinfo.mBackButton); if (tex != NULL) { if (m_show_backbutton&1) x -= screen->GetWidth() - tex->GetScaledWidth() * CleanXfac; @@ -263,7 +263,7 @@ void DMenu::Drawer () { if (this == DMenu::CurrentMenu && BackbuttonAlpha > 0 && m_show_backbutton >= 0 && m_use_mouse) { - FTexture *tex = TexMan[gameinfo.mBackButton]; + FTexture *tex = TexMan(gameinfo.mBackButton); int w = tex->GetScaledWidth() * CleanXfac; int h = tex->GetScaledHeight() * CleanYfac; int x = (!(m_show_backbutton&1))? 0:screen->GetWidth() - w; @@ -909,6 +909,11 @@ CCMD (openmenu) M_SetMenu(argv[1], -1); } +CCMD (closemenu) +{ + M_ClearMenus(); +} + // // Toggle messages on/off // diff --git a/src/menu/menudef.cpp b/src/menu/menudef.cpp index 00af179a5c..616bdf2ca3 100644 --- a/src/menu/menudef.cpp +++ b/src/menu/menudef.cpp @@ -158,7 +158,7 @@ static bool CheckSkipOptionBlock(FScanner &sc) } else if (sc.Compare("unix")) { - #ifdef unix + #ifdef __unix__ filter = true; #endif } diff --git a/src/menu/optionmenuitems.h b/src/menu/optionmenuitems.h index d57e13d05c..ff3eb016aa 100644 --- a/src/menu/optionmenuitems.h +++ b/src/menu/optionmenuitems.h @@ -763,7 +763,7 @@ public: : FOptionMenuItem(label, menu) { FBaseCVar *cv = FindCVar(menu, NULL); - if (cv->GetRealType() == CVAR_Color) + if (cv != NULL && cv->GetRealType() == CVAR_Color) { mCVar = (FColorCVar*)cv; } diff --git a/src/namedef.h b/src/namedef.h index 44fe35e79a..f7607400e2 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -442,6 +442,7 @@ xx(Alphafloor) xx(Alphaceiling) xx(Renderstylefloor) xx(Renderstyleceiling) +xx(Waterzone) xx(offsetx_top) xx(offsety_top) @@ -464,6 +465,7 @@ xx(blockprojectiles) xx(blockuse) xx(hidden) xx(blocksight) +xx(blockhitscan) xx(Renderstyle) diff --git a/src/p_3dfloors.cpp b/src/p_3dfloors.cpp index 56b34ca0fa..51ac24229d 100644 --- a/src/p_3dfloors.cpp +++ b/src/p_3dfloors.cpp @@ -60,7 +60,7 @@ FDynamicColormap *F3DFloor::GetColormap() { // If there's no fog in either model or target sector this is easy and fast. - if ((target->ColorMap->Fade == 0 && model->ColorMap->Fade == 0) || (flags & FF_FADEWALLS)) + if ((target->ColorMap->Fade == 0 && model->ColorMap->Fade == 0) || (flags & (FF_FADEWALLS|FF_FOG))) { return model->ColorMap; } diff --git a/src/p_acs.cpp b/src/p_acs.cpp index d061d451ae..aa6a8ca874 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -46,6 +46,7 @@ #include "p_acs.h" #include "p_saveg.h" #include "p_lnspec.h" +#include "p_enemy.h" #include "m_random.h" #include "doomstat.h" #include "c_console.h" @@ -3512,6 +3513,8 @@ enum APROP_Radius = 36, APROP_ReactionTime = 37, APROP_MeleeRange = 38, + APROP_ViewHeight = 39, + APROP_AttackZOffset = 40 }; // These are needed for ACS's APROP_RenderStyle @@ -3727,6 +3730,16 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value) actor->reactiontime = value; break; + case APROP_ViewHeight: + if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn))) + static_cast(actor)->ViewHeight = value; + break; + + case APROP_AttackZOffset: + if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn))) + static_cast(actor)->AttackZOffset = value; + break; + default: // do nothing. break; @@ -3799,6 +3812,23 @@ int DLevelScript::GetActorProperty (int tid, int property, const SDWORD *stack, case APROP_Radius: return actor->radius; case APROP_ReactionTime:return actor->reactiontime; case APROP_MeleeRange: return actor->meleerange; + case APROP_ViewHeight: if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn))) + { + return static_cast(actor)->ViewHeight; + } + else + { + return 0; + } + case APROP_AttackZOffset: + if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn))) + { + return static_cast(actor)->AttackZOffset; + } + else + { + return 0; + } case APROP_SeeSound: return GlobalACSStrings.AddString(actor->SeeSound, stack, stackdepth); case APROP_AttackSound: return GlobalACSStrings.AddString(actor->AttackSound, stack, stackdepth); @@ -3851,6 +3881,8 @@ int DLevelScript::CheckActorProperty (int tid, int property, int value) case APROP_Radius: case APROP_ReactionTime: case APROP_MeleeRange: + case APROP_ViewHeight: + case APROP_AttackZOffset: return (GetActorProperty(tid, property, NULL, 0) == value); // Boolean values need to compare to a binary version of value @@ -4202,6 +4234,8 @@ enum EACSFunctions ACSF_PlayActorSound, ACSF_SpawnDecal, ACSF_CheckFont, + ACSF_DropItem, + ACSF_CheckFlag, // ZDaemon ACSF_GetTeamScore = 19620, // (int team) @@ -5204,6 +5238,49 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) // bool CheckFont(str fontname) return V_GetFont(FBehavior::StaticLookupString(args[0])) != NULL; + case ACSF_DropItem: + { + const char *type = FBehavior::StaticLookupString(args[1]); + int amount = argCount >= 3? args[2] : -1; + int chance = argCount >= 4? args[3] : 256; + const PClass *cls = PClass::FindClass(type); + int cnt = 0; + if (cls != NULL) + { + if (args[0] == 0) + { + if (activator != NULL) + { + P_DropItem(activator, cls, amount, chance); + cnt++; + } + } + else + { + FActorIterator it(args[0]); + AActor *actor; + + while ((actor = it.Next()) != NULL) + { + P_DropItem(actor, cls, amount, chance); + cnt++; + } + } + return cnt; + } + break; + } + + case ACSF_CheckFlag: + { + AActor *actor = SingleActorFromTID(args[0], activator); + if (actor != NULL) + { + return !!CheckActorFlag(actor, FBehavior::StaticLookupString(args[1])); + } + break; + } + default: break; } diff --git a/src/p_buildmap.cpp b/src/p_buildmap.cpp index 417343f211..f2fd7b0bf8 100644 --- a/src/p_buildmap.cpp +++ b/src/p_buildmap.cpp @@ -698,6 +698,7 @@ static int LoadSprites (spritetype *sprites, Xsprite *xsprites, int numsprites, mapthings[count].SkillFilter = 0xffff; mapthings[count].flags = MTF_SINGLE|MTF_COOPERATIVE|MTF_DEATHMATCH; mapthings[count].special = 0; + mapthings[count].gravity = FRACUNIT; if (xsprites != NULL && sprites[i].lotag == 710) { // Blood ambient sound diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index d567f98666..350c464789 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -1152,7 +1152,7 @@ void P_StartConversation (AActor *npc, AActor *pc, bool facetalker, bool saveang break; } } - if (jump) + if (jump && CurNode->ItemCheckNode > 0) { int root = pc->player->ConversationNPC->ConversationRoot; CurNode = StrifeDialogues[root + CurNode->ItemCheckNode - 1]; diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 81a58ac158..fa39297e67 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -1425,6 +1425,9 @@ AActor *LookForEnemiesInBlock (AActor *lookee, int index, void *extparam) if (!(link->flags3 & MF3_ISMONSTER)) continue; // don't target it if it isn't a monster (could be a barrel) + if (link->flags7 & MF7_NEVERTARGET) + continue; + other = NULL; if (link->flags & MF_FRIENDLY) { @@ -2644,6 +2647,7 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates) corpsehit->flags4 = info->flags4; corpsehit->flags5 = info->flags5; corpsehit->flags6 = info->flags6; + corpsehit->flags7 = info->flags7; corpsehit->health = info->health; corpsehit->target = NULL; corpsehit->lastenemy = NULL; @@ -3087,6 +3091,7 @@ AInventory *P_DropItem (AActor *source, const PClass *type, int dropamount, int { AInventory * inv = static_cast(mo); ModifyDropAmount(inv, dropamount); + inv->ItemFlags |= IF_TOSSED; if (inv->SpecialDropAction (source)) { // The special action indicates that the item should not spawn diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 919bd86545..47ed87888c 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -744,9 +744,12 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags) { SetState (diestate); - tics -= pr_killmobj() & 3; - if (tics < 1) - tics = 1; + if (tics > 1) + { + tics -= pr_killmobj() & 3; + if (tics < 1) + tics = 1; + } } else { @@ -1140,7 +1143,9 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, && (pr_damagemobj()&1) // [RH] But only if not too fast and not flying && thrust < 10*FRACUNIT - && !(target->flags & MF_NOGRAVITY)) + && !(target->flags & MF_NOGRAVITY) + && (inflictor == NULL || !(inflictor->flags5 & MF5_NOFORWARDFALL)) + ) { ang += ANG180; thrust *= 4; @@ -1503,6 +1508,9 @@ bool AActor::OkayToSwitchTarget (AActor *other) if (other == this) return false; // [RH] Don't hate self (can happen when shooting barrels) + if (other->flags7 & MF7_NEVERTARGET) + return false; // never EVER target me! + if (!(other->flags & MF_SHOOTABLE)) return false; // Don't attack things that can't be hurt diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index a0164ab824..869fd51690 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -2545,6 +2545,7 @@ FUNC(LS_Line_SetBlocking) ML_RAILING, ML_BLOCKUSE, ML_BLOCKSIGHT, + ML_BLOCKHITSCAN, -1 }; diff --git a/src/p_map.cpp b/src/p_map.cpp index 211e030565..a3379910de 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -53,11 +53,6 @@ #include "r_data/r_translate.h" #include "g_level.h" -#define WATER_SINK_FACTOR 3 -#define WATER_SINK_SMALL_FACTOR 4 -#define WATER_SINK_SPEED (FRACUNIT/2) -#define WATER_JUMP_SPEED (FRACUNIT*7/2) - CVAR (Bool, cl_bloodsplats, true, CVAR_ARCHIVE) CVAR (Int, sv_smartaim, 0, CVAR_ARCHIVE|CVAR_SERVERINFO) CVAR (Bool, cl_doautoaim, false, CVAR_ARCHIVE) @@ -334,8 +329,7 @@ bool P_TeleportMove (AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefr spechit.Clear (); - bool StompAlwaysFrags = (thing->flags2 & MF2_TELESTOMP) || - (level.flags & LEVEL_MONSTERSTELEFRAG) || telefrag; + bool StompAlwaysFrags = ((thing->flags2 & MF2_TELESTOMP) || (level.flags & LEVEL_MONSTERSTELEFRAG) || telefrag) && !(thing->flags7 & MF7_NOTELESTOMP); FBoundingBox box(x, y, thing->radius); FBlockLinesIterator it(box); @@ -383,7 +377,8 @@ bool P_TeleportMove (AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefr // monsters don't stomp things except on boss level // [RH] Some Heretic/Hexen monsters can telestomp - if (StompAlwaysFrags && !(th->flags6 & MF6_NOTELEFRAG)) + // ... and some items can never be telefragged while others will be telefragged by everything that teleports upon them. + if ((StompAlwaysFrags && !(th->flags6 & MF6_NOTELEFRAG)) || (th->flags7 & MF7_ALWAYSTELEFRAG)) { P_DamageMobj (th, thing, thing, TELEFRAG_DAMAGE, NAME_Telefrag, DMG_THRUSTLESS); continue; @@ -3563,7 +3558,7 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, else tflags = TRACE_NoSky|TRACE_Impact; if (!Trace (t1->x, t1->y, shootz, t1->Sector, vx, vy, vz, distance, - MF_SHOOTABLE, ML_BLOCKEVERYTHING, t1, trace, + MF_SHOOTABLE, ML_BLOCKEVERYTHING|ML_BLOCKHITSCAN, t1, trace, tflags, hitGhosts ? CheckForGhost : CheckForSpectral)) { // hit nothing if (puffDefaults == NULL) @@ -5047,6 +5042,15 @@ void PIT_FloorDrop (AActor *thing, FChangePosition *cpos) P_CheckFakeFloorTriggers (thing, oldz); } } + else if ((thing->z != oldfloorz && !(thing->flags & MF_NOLIFTDROP))) + { + fixed_t oldz = thing->z; + if ((thing->flags & MF_NOGRAVITY) && (thing->flags6 & MF6_RELATIVETOFLOOR)) + { + thing->z = thing->z - oldfloorz + thing->floorz; + P_CheckFakeFloorTriggers (thing, oldz); + } + } } //============================================================================= @@ -5058,6 +5062,7 @@ void PIT_FloorDrop (AActor *thing, FChangePosition *cpos) void PIT_FloorRaise (AActor *thing, FChangePosition *cpos) { fixed_t oldfloorz = thing->floorz; + fixed_t oldz = thing->z; P_AdjustFloorCeil (thing, cpos); @@ -5072,22 +5077,30 @@ void PIT_FloorRaise (AActor *thing, FChangePosition *cpos) return; // do not move bridge things } intersectors.Clear (); - fixed_t oldz = thing->z; thing->z = thing->floorz; - switch (P_PushUp (thing, cpos)) + } + else + { + if((thing->flags & MF_NOGRAVITY) && (thing->flags6 & MF6_RELATIVETOFLOOR)) { - default: - P_CheckFakeFloorTriggers (thing, oldz); - break; - case 1: - P_DoCrunch (thing, cpos); - P_CheckFakeFloorTriggers (thing, oldz); - break; - case 2: - P_DoCrunch (thing, cpos); - thing->z = oldz; - break; + intersectors.Clear (); + thing->z = thing->z - oldfloorz + thing->floorz; } + else return; + } + switch (P_PushUp (thing, cpos)) + { + default: + P_CheckFakeFloorTriggers (thing, oldz); + break; + case 1: + P_DoCrunch (thing, cpos); + P_CheckFakeFloorTriggers (thing, oldz); + break; + case 2: + P_DoCrunch (thing, cpos); + thing->z = oldz; + break; } } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 3b11ec415d..13f9de0af3 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -200,8 +200,12 @@ void AActor::Serialize (FArchive &arc) << flags3 << flags4 << flags5 - << flags6 - << special1 + << flags6; + if (SaveVersion >= 4504) + { + arc << flags7; + } + arc << special1 << special2 << health << movedir @@ -826,7 +830,7 @@ void AActor::CopyFriendliness (AActor *other, bool changeTarget, bool resetHealt flags4 = (flags4 & ~(MF4_NOHATEPLAYERS | MF4_BOSSSPAWNED)) | (other->flags4 & (MF4_NOHATEPLAYERS | MF4_BOSSSPAWNED)); FriendPlayer = other->FriendPlayer; DesignatedTeam = other->DesignatedTeam; - if (changeTarget && other->target != NULL && !(other->target->flags3 & MF3_NOTARGET)) + if (changeTarget && other->target != NULL && !(other->target->flags3 & MF3_NOTARGET) && !(other->target->flags7 & MF7_NEVERTARGET)) { // LastHeard must be set as well so that A_Look can react to the new target if called LastHeard = target = other->target; @@ -3993,8 +3997,12 @@ void AActor::HandleSpawnFlags () } if (SpawnFlags & MTF_SECRET) { - //Printf("Secret %s in sector %i!\n", GetTag(), Sector->sectornum); - flags5 |= MF5_COUNTSECRET; + if (!(flags5 & MF5_COUNTSECRET)) + { + //Printf("Secret %s in sector %i!\n", GetTag(), Sector->sectornum); + flags5 |= MF5_COUNTSECRET; + level.total_secrets++; + } } } @@ -4712,6 +4720,10 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) mobj->SpawnPoint[2] = mthing->z; mobj->SpawnAngle = mthing->angle; mobj->SpawnFlags = mthing->flags; + if (mthing->gravity < 0) mobj->gravity = -mthing->gravity; + else if (mthing->gravity > 0) mobj->gravity = FixedMul(mobj->gravity, mthing->gravity); + else mobj->flags &= ~MF_NOGRAVITY; + P_FindFloorCeiling(mobj, FFCF_SAMESECTOR | FFCF_ONLY3DFLOORS | FFCF_3DRESTRICT); if (!(mobj->flags2 & MF2_ARGSDEFINED)) @@ -6129,6 +6141,9 @@ void PrintMiscActorInfo(AActor *query) Printf("\n\tflags6: %x", query->flags6); for (flagi = 0; flagi <= 31; flagi++) if (query->flags6 & 1<flags7); + for (flagi = 0; flagi <= 31; flagi++) + if (query->flags7 & 1<BounceFlags, FIXED2FLOAT(query->bouncefactor), FIXED2FLOAT(query->wallbouncefactor)); diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 0f6917f8df..784e6946fd 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -329,7 +329,15 @@ MapData *P_OpenMapData(const char * mapname) // Since levels must be stored in WADs they can't really have full // names and for any valid level lump this always returns the short name. const char * lumpname = Wads.GetLumpFullName(lump_name + i); - index = GetMapIndex(mapname, index, lumpname, i != 1 || Wads.LumpLength(lump_name + i) == 0); + try + { + index = GetMapIndex(mapname, index, lumpname, true); + } + catch(...) + { + delete map; + throw; + } if (index == ML_BEHAVIOR) map->HasBehavior = true; // The next lump is not part of this map anymore @@ -461,7 +469,15 @@ MapData *P_OpenMapData(const char * mapname) if (i>0) { - index = GetMapIndex(maplabel, index, lumpname, true); + try + { + index = GetMapIndex(maplabel, index, lumpname, true); + } + catch(...) + { + delete map; + throw; + } if (index == ML_BEHAVIOR) map->HasBehavior = true; // The next lump is not part of this map anymore @@ -1734,6 +1750,7 @@ void P_LoadThings (MapData * map) memset (&mti[i], 0, sizeof(mti[i])); + mti[i].gravity = FRACUNIT; mti[i].Conversation = 0; mti[i].SkillFilter = MakeSkill(flags); mti[i].ClassFilter = 0xffff; // Doom map format doesn't have class flags so spawn for all player classes @@ -1809,6 +1826,7 @@ void P_LoadThings2 (MapData * map) mti[i].ClassFilter = (mti[i].flags & MTF_CLASS_MASK) >> MTF_CLASS_SHIFT; mti[i].flags &= ~(MTF_SKILLMASK|MTF_CLASS_MASK); mti[i].Conversation = 0; + mti[i].gravity = FRACUNIT; } delete[] mtp; } diff --git a/src/p_things.cpp b/src/p_things.cpp index a0f905a7fc..4828e8cbc6 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -452,6 +452,7 @@ bool P_Thing_Raise(AActor *thing) thing->flags4 = info->flags4; thing->flags5 = info->flags5; thing->flags6 = info->flags6; + thing->flags7 = info->flags7; thing->health = info->health; thing->target = NULL; thing->lastenemy = NULL; diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index c1d18fd4c7..fc5964737d 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -475,6 +475,7 @@ public: FString arg0str, arg1str; memset(th, 0, sizeof(*th)); + th->gravity = FRACUNIT; sc.MustGetToken('{'); while (!sc.CheckToken('}')) { @@ -515,6 +516,11 @@ public: th->special = CheckInt(key); break; + case NAME_Gravity: + CHECK_N(Zd | Zdt) + th->gravity = CheckFixed(key); + break; + case NAME_Arg0: case NAME_Arg1: case NAME_Arg2: @@ -921,6 +927,10 @@ public: Flag(ld->flags, ML_BLOCKSIGHT, key); continue; + case NAME_blockhitscan: + Flag(ld->flags, ML_BLOCKHITSCAN, key); + continue; + // [Dusk] lock number case NAME_Locknumber: ld->locknumber = CheckInt(key); @@ -1326,7 +1336,11 @@ public: continue; case NAME_hidden: - sec->MoreFlags |= SECF_HIDDEN; + Flag(sec->MoreFlags, SECF_HIDDEN, key); + break; + + case NAME_Waterzone: + Flag(sec->MoreFlags, SECF_UNDERWATER, key); break; default: diff --git a/src/p_usdf.cpp b/src/p_usdf.cpp index dc287384d1..95c8f5dc04 100644 --- a/src/p_usdf.cpp +++ b/src/p_usdf.cpp @@ -288,6 +288,7 @@ class USDFParser : public UDMFParserBase //node->ItemCheckCount[0] = node->ItemCheckCount[1] = node->ItemCheckCount[2] = -1; node->ThisNodeNum = StrifeDialogues.Push(node); + node->ItemCheckNode = -1; FString SpeakerName; FString Dialogue; diff --git a/src/p_user.cpp b/src/p_user.cpp index c427353a5b..e2c8b80c96 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -477,6 +477,10 @@ void APlayerPawn::Serialize (FArchive &arc) { arc << UseRange; } + if (SaveVersion >= 4503) + { + arc << AirCapacity; + } } //=========================================================================== @@ -1066,7 +1070,7 @@ bool APlayerPawn::ResetAirSupply (bool playgasp) { S_Sound (this, CHAN_VOICE, "*gasp", 1, ATTN_NORM); } - if (level.airsupply> 0) player->air_finished = level.time + level.airsupply; + if (level.airsupply> 0 && player->mo->AirCapacity > 0) player->air_finished = level.time + FixedMul(level.airsupply, player->mo->AirCapacity); else player->air_finished = INT_MAX; return wasdrowning; } diff --git a/src/r_segs.cpp b/src/r_segs.cpp index d050d8c3ba..4fec863ff0 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -828,7 +828,7 @@ void R_RenderFakeWallRange (drawseg_t *ds, int x1, int x2) { if (sclipTop <= backsector->e->XFloor.lightlist[j].plane.Zat0()) { - lightlist_t *lit = &backsector->e->XFloor.lightlist[i]; + lightlist_t *lit = &backsector->e->XFloor.lightlist[j]; basecolormap = lit->extra_colormap; wallshade = LIGHT2SHADE(curline->sidedef->GetLightLevel(foggy, *lit->p_lightlevel, lit->lightsource == NULL) + r_actualextralight); break; diff --git a/src/resourcefiles/file_zip.cpp b/src/resourcefiles/file_zip.cpp index 7e59bd35ad..101b519823 100644 --- a/src/resourcefiles/file_zip.cpp +++ b/src/resourcefiles/file_zip.cpp @@ -259,6 +259,13 @@ bool FZipFile::Open(bool quiet) lump_p->CompressedSize = LittleLong(zip_fh->CompressedSize); lump_p->Position = LittleLong(zip_fh->LocalHeaderOffset); lump_p->CheckEmbedded(); + + // Ignore some very specific names + if (0 == stricmp("dehacked.exe", name)) + { + memset(lump_p->Name, 0, sizeof(lump_p->Name)); + } + lump_p++; } // Resize the lump record array to its actual size diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp index c21ba40549..f832183c0d 100644 --- a/src/sound/fmodsound.cpp +++ b/src/sound/fmodsound.cpp @@ -816,7 +816,7 @@ bool FMODSoundRenderer::Init() } result = Sys->getNumDrivers(&driver); -#ifdef unix +#ifdef __unix__ if (result == FMOD_OK) { // On Linux, FMOD defaults to OSS. If OSS is not present, it doesn't diff --git a/src/sound/music_fluidsynth_mididevice.cpp b/src/sound/music_fluidsynth_mididevice.cpp index 53a93fe099..af8fe6667f 100644 --- a/src/sound/music_fluidsynth_mididevice.cpp +++ b/src/sound/music_fluidsynth_mididevice.cpp @@ -295,7 +295,7 @@ FluidSynthMIDIDevice::FluidSynthMIDIDevice() fluid_chorus_speed, fluid_chorus_depth, fluid_chorus_type); if (0 == LoadPatchSets(fluid_patchset)) { -#ifdef unix +#ifdef __unix__ // This is the standard location on Ubuntu. if (0 == LoadPatchSets("/usr/share/sounds/sf2/FluidR3_GS.sf2:/usr/share/sounds/sf2/FluidR3_GM.sf2")) { @@ -322,7 +322,7 @@ FluidSynthMIDIDevice::FluidSynthMIDIDevice() } } #endif -#ifdef unix +#ifdef __unix__ } #endif } diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index 0302ca5435..f28026f193 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -127,7 +127,7 @@ void FTextureManager::DeleteAll() { if (mAnimatedDoors[i].TextureFrames != NULL) { - delete mAnimatedDoors[i].TextureFrames; + delete[] mAnimatedDoors[i].TextureFrames; mAnimatedDoors[i].TextureFrames = NULL; } } diff --git a/src/thingdef/thingdef.h b/src/thingdef/thingdef.h index 08264e0a8c..c388a8544f 100644 --- a/src/thingdef/thingdef.h +++ b/src/thingdef/thingdef.h @@ -31,6 +31,7 @@ bool CheckDeprecatedFlags(const AActor *actor, FActorInfo *info, int index); const char *GetFlagName(unsigned int flagnum, int flagoffset); void ModActorFlag(AActor *actor, FFlagDef *fd, bool set); INTBOOL CheckActorFlag(const AActor *actor, FFlagDef *fd); +INTBOOL CheckActorFlag(const AActor *owner, const char *flagname, bool printerror = true); #define FLAG_NAME(flagnum, flagvar) GetFlagName(flagnum, myoffsetof(AActor, flagvar)) @@ -354,11 +355,11 @@ int MatchString (const char *in, const char **strings); MSVC_MSEG FVariableInfo *infoptr_GlobalDef__##name GCC_MSEG = &GlobalDef__##name; #define DEFINE_MEMBER_VARIABLE(name, cls) \ - static FVariableInfo GlobalDef__##name = { #name, myoffsetof(cls, name), RUNTIME_CLASS(cls) }; \ + static FVariableInfo GlobalDef__##name = { #name, static_cast(myoffsetof(cls, name)), RUNTIME_CLASS(cls) }; \ MSVC_MSEG FVariableInfo *infoptr_GlobalDef__##name GCC_MSEG = &GlobalDef__##name; #define DEFINE_MEMBER_VARIABLE_ALIAS(name, alias, cls) \ - static FVariableInfo GlobalDef__##name = { #name, myoffsetof(cls, alias), RUNTIME_CLASS(cls) }; \ + static FVariableInfo GlobalDef__##name = { #name, static_cast(myoffsetof(cls, alias)), RUNTIME_CLASS(cls) }; \ MSVC_MSEG FVariableInfo *infoptr_GlobalDef__##name GCC_MSEG = &GlobalDef__##name; diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 476c29eafe..7964c422b6 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -3777,32 +3777,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckFlag) COPY_AAPTR_NOT_NULL(self, owner, checkpointer); - const char *dot = strchr (flagname, '.'); - FFlagDef *fd; - const PClass *cls = owner->GetClass(); - - if (dot != NULL) + if (CheckActorFlag(owner, flagname)) { - FString part1(flagname, dot-flagname); - fd = FindFlag (cls, part1, dot+1); + ACTION_JUMP(jumpto); } - else - { - fd = FindFlag (cls, flagname, NULL); - } - - if (fd != NULL) - { - if (CheckActorFlag(owner, fd)) - { - ACTION_JUMP(jumpto); - } - } - else - { - Printf("Unknown flag '%s' in '%s'\n", flagname, cls->TypeName.GetChars()); - } - } @@ -4951,3 +4929,19 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetDamageType) self->DamageType = damagetype; } + +//========================================================================== +// +// A_DropItem +// +//========================================================================== + +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DropItem) +{ + ACTION_PARAM_START(3); + ACTION_PARAM_CLASS(spawntype, 0); + ACTION_PARAM_INT(amount, 1); + ACTION_PARAM_INT(chance, 2); + + P_DropItem(self, spawntype, amount, chance); +} diff --git a/src/thingdef/thingdef_data.cpp b/src/thingdef/thingdef_data.cpp index 795bcb5cc7..bf0bf2e13b 100644 --- a/src/thingdef/thingdef_data.cpp +++ b/src/thingdef/thingdef_data.cpp @@ -184,6 +184,7 @@ static FFlagDef ActorFlags[]= DEFINE_FLAG(MF5, DONTDRAIN, AActor, flags5), DEFINE_FLAG(MF5, NODROPOFF, AActor, flags5), + DEFINE_FLAG(MF5, NOFORWARDFALL, AActor, flags5), DEFINE_FLAG(MF5, COUNTSECRET, AActor, flags5), DEFINE_FLAG(MF5, NODAMAGE, AActor, flags5), DEFINE_FLAG(MF5, BLOODSPLATTER, AActor, flags5), @@ -233,6 +234,12 @@ static FFlagDef ActorFlags[]= DEFINE_FLAG(MF6, DOHARMSPECIES, AActor, flags6), DEFINE_FLAG(MF6, POISONALWAYS, AActor, flags6), DEFINE_FLAG(MF6, NOTAUTOAIMED, AActor, flags6), + DEFINE_FLAG(MF6, NOTONAUTOMAP, AActor, flags6), + DEFINE_FLAG(MF6, RELATIVETOFLOOR, AActor, flags6), + + DEFINE_FLAG(MF7, NEVERTARGET, AActor, flags7), + DEFINE_FLAG(MF7, NOTELESTOMP, AActor, flags7), + DEFINE_FLAG(MF7, ALWAYSTELEFRAG, AActor, flags7), // Effect flags DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects), @@ -302,6 +309,7 @@ static FFlagDef InventoryFlags[] = DEFINE_FLAG(IF, RESTRICTABSOLUTELY, AInventory, ItemFlags), DEFINE_FLAG(IF, NEVERRESPAWN, AInventory, ItemFlags), DEFINE_FLAG(IF, NOSCREENFLASH, AInventory, ItemFlags), + DEFINE_FLAG(IF, TOSSED, AInventory, ItemFlags), DEFINE_DEPRECATED_FLAG(PICKUPFLASH), DEFINE_DEPRECATED_FLAG(INTERHUBSTRIP),}; diff --git a/src/thingdef/thingdef_parse.cpp b/src/thingdef/thingdef_parse.cpp index c065dfbe03..498003b4ee 100644 --- a/src/thingdef/thingdef_parse.cpp +++ b/src/thingdef/thingdef_parse.cpp @@ -867,7 +867,7 @@ static void ParseActionDef (FScanner &sc, PClass *cls) OPTIONAL = 1 }; - bool error = false; + unsigned int error = 0; const AFuncDesc *afd; FName funcname; FString args; @@ -876,8 +876,8 @@ static void ParseActionDef (FScanner &sc, PClass *cls) if (sc.LumpNum == -1 || Wads.GetLumpFile(sc.LumpNum) > 0) { - sc.ScriptMessage ("action functions can only be imported by internal class and actor definitions!"); - error++; + sc.ScriptMessage ("Action functions can only be imported by internal class and actor definitions!"); + ++error; } sc.MustGetToken(TK_Native); @@ -887,7 +887,7 @@ static void ParseActionDef (FScanner &sc, PClass *cls) if (afd == NULL) { sc.ScriptMessage ("The function '%s' has not been exported from the executable.", sc.String); - error++; + ++error; } sc.MustGetToken('('); if (!sc.CheckToken(')')) @@ -998,7 +998,7 @@ static void ParseActionDef (FScanner &sc, PClass *cls) } if (error) { - FScriptPosition::ErrorCounter++; + FScriptPosition::ErrorCounter += error; } else if (cls->Symbols.AddSymbol (sym) == NULL) { diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index 61a18b370d..d6731aafaa 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -180,6 +180,33 @@ INTBOOL CheckActorFlag(const AActor *owner, FFlagDef *fd) #endif } +INTBOOL CheckActorFlag(const AActor *owner, const char *flagname, bool printerror) +{ + const char *dot = strchr (flagname, '.'); + FFlagDef *fd; + const PClass *cls = owner->GetClass(); + + if (dot != NULL) + { + FString part1(flagname, dot-flagname); + fd = FindFlag (cls, part1, dot+1); + } + else + { + fd = FindFlag (cls, flagname, NULL); + } + + if (fd != NULL) + { + return CheckActorFlag(owner, fd); + } + else + { + if (printerror) Printf("Unknown flag '%s' in '%s'\n", flagname, cls->TypeName.GetChars()); + return false; + } +} + //=========================================================================== // // HandleDeprecatedFlags @@ -433,7 +460,7 @@ DEFINE_PROPERTY(skip_super, 0, Actor) return; } - memcpy (defaults, GetDefault(), sizeof(AActor)); + memcpy ((void *)defaults, (void *)GetDefault(), sizeof(AActor)); if (bag.DropItemList != NULL) { FreeDropItemChain (bag.DropItemList); @@ -1286,7 +1313,8 @@ DEFINE_PROPERTY(clearflags, 0, Actor) defaults->flags3 = defaults->flags4 = defaults->flags5 = - defaults->flags6 = 0; + defaults->flags6 = + defaults->flags7 = 0; defaults->flags2 &= MF2_ARGSDEFINED; // this flag must not be cleared } @@ -2113,9 +2141,8 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, strength, F, Inventory) I_Error("\"powerup.strength\" requires an actor of type \"Powerup\"\n"); return; } - // Puts a percent value in the 0.0..1.0 range PROP_FIXED_PARM(f, 0); - *pStrength = f / 100; + *pStrength = f; } //========================================================================== @@ -2419,6 +2446,15 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, userange, F, PlayerPawn) defaults->UseRange = z; } +//========================================================================== +// +//========================================================================== +DEFINE_CLASS_PROPERTY_PREFIX(player, aircapacity, F, PlayerPawn) +{ + PROP_FIXED_PARM(z, 0); + defaults->AirCapacity = z; +} + //========================================================================== // //========================================================================== diff --git a/src/timidity/instrum.cpp b/src/timidity/instrum.cpp index 55683cb4e1..5ab55201e0 100644 --- a/src/timidity/instrum.cpp +++ b/src/timidity/instrum.cpp @@ -166,7 +166,7 @@ static Instrument *load_instrument(Renderer *song, const char *name, int percuss tmp += ".pat"; if ((fp = open_filereader(tmp, openmode, NULL)) == NULL) { -#ifdef unix // Windows isn't case-sensitive. +#ifdef __unix__ // Windows isn't case-sensitive. tmp.ToUpper(); if ((fp = open_filereader(tmp, openmode, NULL)) == NULL) #endif diff --git a/src/version.h b/src/version.h index 8bdd8ca818..d7acf1e6aa 100644 --- a/src/version.h +++ b/src/version.h @@ -76,7 +76,7 @@ const char *GetVersionString(); // Use 4500 as the base git save version, since it's higher than the // SVN revision ever got. -#define SAVEVER 4502 +#define SAVEVER 4504 #define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x) @@ -91,7 +91,7 @@ const char *GetVersionString(); #define FORUM_URL "http://forum.zdoom.org" #define BUGS_FORUM_URL "http://forum.zdoom.org/index.php?c=3" -#ifdef unix +#ifdef __unix__ #define GAME_DIR ".config/zdoom" #elif defined(__APPLE__) #define GAME_DIR GAMENAME diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index 37b418ce99..6ae9148aff 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -1947,7 +1947,7 @@ void WI_Ticker(void) if (level.info->InterMusic.IsNotEmpty()) S_ChangeMusic(level.info->InterMusic, level.info->intermusicorder); else - S_ChangeMusic (gameinfo.intermissionMusic.GetChars()); + S_ChangeMusic (gameinfo.intermissionMusic.GetChars(), gameinfo.intermissionOrder); } diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index c2fa8a0c72..73119c9413 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -84,7 +84,7 @@ ACTOR Actor native //: Thinker action native A_VileChase(); action native A_VileStart(); action native A_VileTarget(class fire = "ArchvileFire"); - action native A_VileAttack(sound snd = "vile/stop", int initialdmg = 20, int blastdmg = 70, int blastradius = 70, float thrustfac = 1.0, name damagetype = "Fire"); + action native A_VileAttack(sound snd = "vile/stop", int initialdmg = 20, int blastdmg = 70, int blastradius = 70, float thrustfac = 1.0, name damagetype = "Fire", int flags = 0); action native A_StartFire(); action native A_Fire(float spawnheight = 0); action native A_FireCrackle(); @@ -180,7 +180,7 @@ ACTOR Actor native //: Thinker action native A_TurretLook(); action native A_KlaxonBlare(); action native A_Countdown(); - action native A_AlertMonsters(float maxdist = 0); + action native A_AlertMonsters(float maxdist = 0, int flags = 0); action native A_ClearSoundTarget(); action native A_FireAssaultGun(); action native A_CheckTerrain(); @@ -300,6 +300,7 @@ ACTOR Actor native //: Thinker action native A_Quake(int intensity, int duration, int damrad, int tremrad, sound sfx = "world/quake"); action native A_SetTics(int tics); action native A_SetDamageType(name damagetype); + action native A_DropItem(class item, int dropamount = -1, int chance = 256); action native A_CheckSightOrRange(float distance, state label); action native A_CheckRange(float distance, state label); diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index 18f991e435..dee498b6a0 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -4,6 +4,9 @@ const int PAF_NOSKULLATTACK = 1; const int PAF_AIMFACING = 2; const int PAF_NOTARGET = 4; +// Flags for A_VileAttack +const int VAF_DMGTYPEAPPLYTODIRECT = 1; + // Flags for A_Saw const int SF_NORANDOM = 1; const int SF_RANDOMLIGHTMISS = 2; @@ -345,5 +348,12 @@ enum CLOFF_NOAIM = CLOFF_NOAIM_VERT|CLOFF_NOAIM_HORZ }; + +// Flags for A_AlertMonsters +const int AMF_TARGETEMITTER = 1; +const int AMF_TARGETNONPLAYER = 2; +const int AMF_EMITFROMTARGET = 4; + + // This is only here to provide one global variable for testing. native int testglobalvar; diff --git a/wadsrc/static/actors/shared/inventory.txt b/wadsrc/static/actors/shared/inventory.txt index 5f5e20b502..ed113c4dfb 100644 --- a/wadsrc/static/actors/shared/inventory.txt +++ b/wadsrc/static/actors/shared/inventory.txt @@ -300,6 +300,7 @@ ACTOR PowerDrain : Powerup native ACTOR PowerRegeneration : Powerup native { Powerup.Duration -120 + Powerup.Strength 5 } ACTOR PowerHighJump : Powerup native {} diff --git a/wadsrc/static/actors/shared/player.txt b/wadsrc/static/actors/shared/player.txt index 5457880a76..159d4cca94 100644 --- a/wadsrc/static/actors/shared/player.txt +++ b/wadsrc/static/actors/shared/player.txt @@ -32,6 +32,7 @@ Actor PlayerPawn : Actor native Player.DamageScreenColor "ff 00 00" Player.MugShotMaxHealth 0 Player.FlechetteType "ArtiPoisonBag3" + Player.AirCapacity 1 Obituary "$OB_MPDEFAULT" } diff --git a/wadsrc/static/actors/strife/alienspectres.txt b/wadsrc/static/actors/strife/alienspectres.txt index bdd30d8e49..6e56f680d0 100644 --- a/wadsrc/static/actors/strife/alienspectres.txt +++ b/wadsrc/static/actors/strife/alienspectres.txt @@ -20,6 +20,7 @@ ACTOR AlienSpectre1 : SpectralMonster 129 PainSound "alienspectre/pain" DeathSound "alienspectre/death" ActiveSound "alienspectre/active" + Obituary "$OB_ALIENSPECTRE" +NOGRAVITY +FLOAT +SHADOW diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index 8a0a5f4ee6..5695ad502c 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -736,7 +736,7 @@ OB_MACIL = "%o should have never rebelled against Macil."; OB_REBEL = "%o was gunned down by a Rebel."; OB_BEGGAR = "%o was beaten to death by the poor."; OB_PEASANT = "%o should have never picked a fight with a civilian."; -OB_ALIENSPECTE = "%o was struck down by the Spectre."; +OB_ALIENSPECTRE = "%o was struck down by the Spectre."; OB_ENTITY = "%o felt the wrath of The One God."; OB_LOREMASTER = "%o couldn't escape from the Lore Master's grasp."; OB_PROGRAMMER = "%o was deleted by the Programmer."; diff --git a/wadsrc/static/language.fr b/wadsrc/static/language.fr index 354ba2bee2..1533a15065 100644 --- a/wadsrc/static/language.fr +++ b/wadsrc/static/language.fr @@ -779,7 +779,7 @@ OB_MACIL = "%o n'aurait jamais du se rebelle contre Macil."; OB_REBEL = "%o a ete abbatu par un Rebel."; OB_BEGGAR = "%o a ete battu a mort par un pauvre."; OB_PEASANT = "%o n'aurait jamais du chercher la bagarre a un civil."; -OB_ALIENSPECTE = "%o a ete terrasse par le Spectre."; +OB_ALIENSPECTRE = "%o a ete terrasse par le Spectre."; OB_ENTITY = "%o a senti le courroux du dieu unique."; OB_LOREMASTER = "%o n'a pu echapper a l'emprise du Maitre des Traditions."; OB_PROGRAMMER = "%o a ete efface par le Programmer."; diff --git a/wadsrc/static/language.ptb b/wadsrc/static/language.ptb index 1dc0e36c02..9f7cc4e113 100644 --- a/wadsrc/static/language.ptb +++ b/wadsrc/static/language.ptb @@ -712,7 +712,7 @@ OB_MACIL = "%o should have never rebelled against Macil."; OB_REBEL = "%o was gunned down by a Rebel."; OB_BEGGAR = "%o was beaten to death by the poor."; OB_PEASANT = "%o should have never picked a fight with a civilian."; -OB_ALIENSPECTE = "%o was struck down by the Spectre."; +OB_ALIENSPECTRE = "%o was struck down by the Spectre."; OB_ENTITY = "%o felt the wrath of The One God."; OB_LOREMASTER = "%o couldn't escape from the Lore Master's grasp."; OB_PROGRAMMER = "%o was deleted by the Programmer."; diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 21f19c1068..6457051bf8 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -850,6 +850,13 @@ OptionValue Autosave 2, "Never" } +OptionValue dehopt +{ + 0, "Never" + 1, "All" + 2, "Only last one" +} + OptionMenu "MiscOptions" { Title "Miscellaneous Options" @@ -864,6 +871,7 @@ OptionMenu "MiscOptions" Option "Enable cheats from all games", "allcheats", "OnOff" Option "Enable autosaves", "disableautosave", "Autosave" Slider "Number of autosaves", "autosavecount", 1, 20, 1, 0 + Option "Load *.deh/*.bex lumps", "dehload", "dehopt" StaticText " " Option "Cache nodes", "gl_cachenodes", "OnOff" Slider "Time threshold for node caching", "gl_cachetime", 0.0, 2.0, 0.1 @@ -920,10 +928,18 @@ OptionValue STSTypes 3, "Rotated" } +OptionValue MapBackTypes +{ + 0, "Off" + 1, "On" + 2, "Map defined colors only" +} + OptionMenu AutomapOptions { Title "AUTOMAP OPTIONS" Option "Map color set", "am_colorset", "MapColorTypes" + Option "Allow map defined colors", "am_customcolors", "YesNo" Submenu "Set custom colors", "MapColorMenu" Submenu "Customize map controls", "MapControlsMenu" StaticText " " @@ -939,7 +955,7 @@ OptionMenu AutomapOptions Option "Show total time elapsed", "am_showtotaltime", "OnOff" Option "Show secrets on map", "am_map_secrets", "SecretTypes" Option "Show map label", "am_showmaplabel", "MaplabelTypes" - Option "Draw map background", "am_drawmapback", "OnOff" + Option "Draw map background", "am_drawmapback", "MapBackTypes" Option "Show keys (cheat)", "am_showkeys", "OnOff" Option "Show trigger lines", "am_showtriggerlines", "OnOff" Option "Show things as sprites", "am_showthingsprites", "STSTypes" @@ -1003,6 +1019,7 @@ OptionMenu MapColorMenu ColorPicker "Secret walls", "am_secretwallcolor" ColorPicker "Actors", "am_thingcolor" ColorPicker "Monsters", "am_thingcolor_monster" + ColorPicker "non-counting Monsters", "am_thingcolor_ncmonster" ColorPicker "Friends", "am_thingcolor_friend" ColorPicker "Items", "am_thingcolor_item" ColorPicker "Count Items", "am_thingcolor_citem" @@ -1010,15 +1027,22 @@ OptionMenu MapColorMenu StaticText "Overlay Mode", 1 ColorPicker "You", "am_ovyourcolor" ColorPicker "1-sided walls", "am_ovwallcolor" - ColorPicker "2-sided walls", "am_ovotherwallscolor" + ColorPicker "2-sided walls with different floors", "am_ovfdwallcolor" + ColorPicker "2-sided walls with different ceilings", "am_ovcdwallcolor" + ColorPicker "2-sided walls with 3D floors", "am_ovefwallcolor" ColorPicker "Not-yet-seen walls", "am_ovunseencolor" - ColorPicker "Teleporter", "am_ovtelecolor" + ColorPicker "Locked doors", "am_ovlockedcolor" + ColorPicker "Teleporter to the same map", "am_ovtelecolor" + ColorPicker "Teleporter to a different map", "am_ovinterlevelcolor" ColorPicker "Secret sector", "am_ovsecretsectorcolor" ColorPicker "Special trigger lines", "am_ovspecialwallcolor" StaticText " " StaticText "Overlay Cheat Mode", 1 + ColorPicker "Invisible 2-sided walls", "am_ovotherwallscolor" + ColorPicker "Secret walls", "am_ovsecretwallcolor" ColorPicker "Actors", "am_ovthingcolor" ColorPicker "Monsters", "am_ovthingcolor_monster" + ColorPicker "non-counting Monsters", "am_ovthingcolor_ncmonster" ColorPicker "Friends", "am_ovthingcolor_friend" ColorPicker "Items", "am_ovthingcolor_item" ColorPicker "Count Items", "am_ovthingcolor_citem"