diff --git a/Source/Core/Config/ThingTypeInfo.cs b/Source/Core/Config/ThingTypeInfo.cs index aa579bf..1e110f1 100644 --- a/Source/Core/Config/ThingTypeInfo.cs +++ b/Source/Core/Config/ThingTypeInfo.cs @@ -420,8 +420,8 @@ namespace CodeImp.DoomBuilder.Config this.arrow = (cat.Arrow != 0); this.radius = o.radius; this.height = o.height; - this.hangs = (cat.Hangs != 0); - this.blocking = cat.Blocking; + this.hangs = o.Hangs(); + this.blocking = o.Blocking() ? 2 : 0; this.errorcheck = cat.ErrorCheck; this.fixedsize = cat.FixedSize; this.fixedrotation = cat.FixedRotation; //mxd diff --git a/Source/Core/SRB2/LuaObjectParser.cs b/Source/Core/SRB2/LuaObjectParser.cs index 3cb140e..7535e23 100644 --- a/Source/Core/SRB2/LuaObjectParser.cs +++ b/Source/Core/SRB2/LuaObjectParser.cs @@ -30,6 +30,39 @@ namespace CodeImp.DoomBuilder.SRB2 private List objectfreeslots; private List statefreeslots; private List spritefreeslots;*/ + private IDictionary flagValues = new Dictionary + { + { "MF_SPECIAL", 0x1 }, + { "MF_SOLID", 0x2 }, + { "MF_SHOOTABLE", 0x4 }, + { "MF_NOSECTOR", 0x8 }, + { "MF_NOBLOCKMAP", 0x10 }, + { "MF_AMBUSH", 0x20 }, + { "MF_PUSHABLE", 0x40 }, + { "MF_BOSS", 0x80 }, + { "MF_SPAWNCEILING", 0x100 }, + { "MF_NOGRAVITY", 0x200 }, + { "MF_AMBIENT", 0x400 }, + { "MF_SLIDEME", 0x800 }, + { "MF_NOCLIP", 0x1000 }, + { "MF_FLOAT", 0x2000 }, + { "MF_BOXICON", 0x4000 }, + { "MF_MISSILE", 0x8000 }, + { "MF_SPRING", 0x10000 }, + { "MF_BOUNCE", 0x20000 }, + { "MF_MONITOR", 0x40000 }, + { "MF_NOTHINK", 0x80000 }, + { "MF_FIRE", 0x100000 }, + { "MF_NOCLIPHEIGHT", 0x200000 }, + { "MF_ENEMY", 0x400000 }, + { "MF_SCENERY", 0x800000 }, + { "MF_PAIN", 0x1000000 }, + { "MF_STICKY", 0x2000000 }, + { "MF_NIGHTSITEM", 0x4000000 }, + { "MF_NOCLIPTHING", 0x8000000 }, + { "MF_GRENADEBOUNCE", 0x10000000 }, + { "MF_RUNSPAWNFUNC", 0x10000000 } + }; #endregion @@ -93,6 +126,7 @@ namespace CodeImp.DoomBuilder.SRB2 int mapThingNum = -1; int radius = 0; int height = 0; + int flags = 0; SkipWhitespace(true); token = ReadToken(); @@ -190,6 +224,11 @@ namespace CodeImp.DoomBuilder.SRB2 if (!ReadParameter(out token, out finished)) return false; states[7] = token; break; + case "flags": + if (!ReadParameter(out token, out finished)) return false; + if (!ParseFlags(token, out flags)) + LogWarning("Could not parse flags"); + break; case "spawnhealth": case "seesound": case "reactiontime": @@ -202,7 +241,6 @@ namespace CodeImp.DoomBuilder.SRB2 case "mass": case "damage": case "activesound": - case "flags": if (!ReadParameter(out token, out finished)) return false; break; case "}": @@ -228,7 +266,7 @@ namespace CodeImp.DoomBuilder.SRB2 if (mapThingNum > 0) { - SRB2Object o = new SRB2Object(name, sprite, category, states, mapThingNum, radius, height); + SRB2Object o = new SRB2Object(name, sprite, category, states, mapThingNum, radius, height, flags); if (objects.ContainsKey(objname)) objects[objname] = o; else @@ -630,6 +668,27 @@ namespace CodeImp.DoomBuilder.SRB2 return true; } + private bool ParseFlags(string input, out int output) + { + output = 0; + string[] tokens = input.Split(new char[] { '|' }); + foreach (string token in tokens) + { + if (flagValues.ContainsKey(token)) + { + output |= flagValues[token]; + } + else + { + int val = 0; + if (!int.TryParse(token, NumberStyles.Integer, CultureInfo.InvariantCulture, out val)) + return false; + output |= val; + } + } + return true; + } + protected override string GetLanguageType() { return "Lua"; diff --git a/Source/Core/SRB2/SOCObjectParser.cs b/Source/Core/SRB2/SOCObjectParser.cs index 29a0ba9..837bab8 100644 --- a/Source/Core/SRB2/SOCObjectParser.cs +++ b/Source/Core/SRB2/SOCObjectParser.cs @@ -30,6 +30,39 @@ namespace CodeImp.DoomBuilder.SRB2 private List objectfreeslots; private List statefreeslots; private List spritefreeslots;*/ + private IDictionary flagValues = new Dictionary + { + { "MF_SPECIAL", 0x1 }, + { "MF_SOLID", 0x2 }, + { "MF_SHOOTABLE", 0x4 }, + { "MF_NOSECTOR", 0x8 }, + { "MF_NOBLOCKMAP", 0x10 }, + { "MF_AMBUSH", 0x20 }, + { "MF_PUSHABLE", 0x40 }, + { "MF_BOSS", 0x80 }, + { "MF_SPAWNCEILING", 0x100 }, + { "MF_NOGRAVITY", 0x200 }, + { "MF_AMBIENT", 0x400 }, + { "MF_SLIDEME", 0x800 }, + { "MF_NOCLIP", 0x1000 }, + { "MF_FLOAT", 0x2000 }, + { "MF_BOXICON", 0x4000 }, + { "MF_MISSILE", 0x8000 }, + { "MF_SPRING", 0x10000 }, + { "MF_BOUNCE", 0x20000 }, + { "MF_MONITOR", 0x40000 }, + { "MF_NOTHINK", 0x80000 }, + { "MF_FIRE", 0x100000 }, + { "MF_NOCLIPHEIGHT", 0x200000 }, + { "MF_ENEMY", 0x400000 }, + { "MF_SCENERY", 0x800000 }, + { "MF_PAIN", 0x1000000 }, + { "MF_STICKY", 0x2000000 }, + { "MF_NIGHTSITEM", 0x4000000 }, + { "MF_NOCLIPTHING", 0x8000000 }, + { "MF_GRENADEBOUNCE", 0x10000000 }, + { "MF_RUNSPAWNFUNC", 0x10000000 } + }; private StreamReader streamreader; private int linenumber; @@ -145,6 +178,7 @@ namespace CodeImp.DoomBuilder.SRB2 int mapThingNum = -1; int radius = 0; int height = 0; + int flags = 0; while (!streamreader.EndOfStream) { string line = streamreader.ReadLine(); @@ -224,11 +258,15 @@ namespace CodeImp.DoomBuilder.SRB2 case "RAISESTATE": states[7] = tokens[1]; break; + case "FLAGS": + if (!ParseFlags(tokens[1], out flags)) + LogWarning("Could not parse flags"); + break; } } if (mapThingNum > 0) { - SRB2Object o = new SRB2Object(name, sprite, category, states, mapThingNum, radius, height); + SRB2Object o = new SRB2Object(name, sprite, category, states, mapThingNum, radius, height, flags); if (objects.ContainsKey(objname)) objects[objname] = o; else @@ -314,6 +352,27 @@ namespace CodeImp.DoomBuilder.SRB2 return true; } + private bool ParseFlags(string input, out int output) + { + output = 0; + string[] tokens = input.Split(new char[] { '|' }); + foreach (string token in tokens) + { + if (flagValues.ContainsKey(token)) + { + output |= flagValues[token]; + } + else + { + int val = 0; + if (!int.TryParse(token, NumberStyles.Integer, CultureInfo.InvariantCulture, out val)) + return false; + output |= val; + } + } + return true; + } + // This reports an error protected internal override void ReportError(string message) { diff --git a/Source/Core/SRB2/SRB2Object.cs b/Source/Core/SRB2/SRB2Object.cs index e53e1f8..6010c3c 100644 --- a/Source/Core/SRB2/SRB2Object.cs +++ b/Source/Core/SRB2/SRB2Object.cs @@ -26,7 +26,10 @@ namespace CodeImp.DoomBuilder.SRB2 { public struct SRB2Object { - #region ================== Constants + #region ================== Constants + + public const int MF_SOLID = 0x2; + public const int MF_SPAWNCEILING = 0x100; #endregion @@ -39,13 +42,14 @@ namespace CodeImp.DoomBuilder.SRB2 public readonly int mapThingNum; public readonly int radius; public readonly int height; - - #endregion - - #region ================== Constructor / Disposer - - // Constructor - internal SRB2Object(string name, string sprite, string category, string[] states, int mapThingNum, int radius, int height) + public readonly int flags; + + #endregion + + #region ================== Constructor / Disposer + + // Constructor + internal SRB2Object(string name, string sprite, string category, string[] states, int mapThingNum, int radius, int height, int flags) { this.name = name; this.sprite = sprite; @@ -54,8 +58,21 @@ namespace CodeImp.DoomBuilder.SRB2 this.mapThingNum = mapThingNum; this.radius = radius; this.height = height; + this.flags = flags; } - - #endregion - } + + #endregion + + #region ================== Methods + internal bool Blocking() + { + return (flags & MF_SOLID) == MF_SOLID; + } + + internal bool Hangs() + { + return (flags & MF_SPAWNCEILING) == MF_SPAWNCEILING; + } + #endregion + } }