From 4b1a31c3ca861f712003db45799625657eb4e947 Mon Sep 17 00:00:00 2001 From: ZZYZX Date: Sat, 4 Mar 2017 02:13:39 +0200 Subject: [PATCH] Fixed: duration 0 frames should be skipped if there are nonzero frames after them (reported by Tormentor667, Ozymandias81). Fixed crash if some actor had a modeldef entry but doesn't anymore. --- Source/Core/Map/Thing.cs | 7 ++- Source/Core/Properties/AssemblyInfo.cs | 4 +- Source/Core/ZDoom/ActorStructure.cs | 44 ++++++++++++++----- Source/Core/ZDoom/DecorateStateStructure.cs | 13 ++++++ Source/Core/ZDoom/StateStructure.cs | 8 +++- Source/Core/ZDoom/ZScriptStateStructure.cs | 2 + .../BuilderModes/Properties/AssemblyInfo.cs | 2 +- 7 files changed, 64 insertions(+), 16 deletions(-) diff --git a/Source/Core/Map/Thing.cs b/Source/Core/Map/Thing.cs index 36266230..9e2a0b29 100755 --- a/Source/Core/Map/Thing.cs +++ b/Source/Core/Map/Thing.cs @@ -570,7 +570,12 @@ namespace CodeImp.DoomBuilder.Map ModelData md = General.Map.Data.ModeldefEntries[type]; if((md.LoadState == ModelLoadState.None && General.Map.Data.ProcessModel(type)) || md.LoadState != ModelLoadState.None) rendermode = (General.Map.Data.ModeldefEntries[type].IsVoxel ? ThingRenderMode.VOXEL : ThingRenderMode.MODEL); - } + } + else // reset rendermode if we SUDDENLY became a sprite out of a model. otherwise it crashes violently. + { + ThingTypeInfo ti = General.Map.Data.GetThingInfo(Type); + rendermode = (ti != null) ? ti.RenderMode : ThingRenderMode.NORMAL; + } // Update radian versions of pitch and roll switch(rendermode) diff --git a/Source/Core/Properties/AssemblyInfo.cs b/Source/Core/Properties/AssemblyInfo.cs index cdd7530c..90082204 100755 --- a/Source/Core/Properties/AssemblyInfo.cs +++ b/Source/Core/Properties/AssemblyInfo.cs @@ -30,6 +30,6 @@ using CodeImp.DoomBuilder; // Build Number // Revision // -[assembly: AssemblyVersion("2.3.0.2924")] +[assembly: AssemblyVersion("2.3.0.2927")] [assembly: NeutralResourcesLanguageAttribute("en")] -[assembly: AssemblyHash("6108502")] +[assembly: AssemblyHash("f97c15a")] diff --git a/Source/Core/ZDoom/ActorStructure.cs b/Source/Core/ZDoom/ActorStructure.cs index e63e86e4..d9d98d02 100755 --- a/Source/Core/ZDoom/ActorStructure.cs +++ b/Source/Core/ZDoom/ActorStructure.cs @@ -282,23 +282,45 @@ namespace CodeImp.DoomBuilder.ZDoom General.ErrorLogger.Add(ErrorType.Warning, "DECORATE warning in " + classname + ":" + doomednum + ". The sprite \"" + sprite + "\" assigned by the \"$sprite\" property does not exist."); } - //mxd. Try to get a suitable sprite from our hardcoded states list - foreach(string state in SPRITE_CHECK_STATES) + StateStructure.FrameInfo firstNonTntInfo = null; + StateStructure.FrameInfo firstInfo = null; + // Pick the first we can find (including and not including TNT1) + Dictionary list = GetAllStates(); + foreach (StateStructure s in list.Values) + { + StateStructure.FrameInfo info = s.GetSprite(0); + if (string.IsNullOrEmpty(info.Sprite)) continue; + + if (!info.IsEmpty()) firstNonTntInfo = info; + if (firstInfo == null) firstInfo = info; + + if (firstNonTntInfo != null) + break; + } + + //mxd. Try to get a suitable sprite from our hardcoded states list + StateStructure.FrameInfo lastNonTntInfo = null; + StateStructure.FrameInfo lastInfo = null; + foreach (string state in SPRITE_CHECK_STATES) { if(!HasState(state)) continue; StateStructure s = GetState(state); StateStructure.FrameInfo info = s.GetSprite(0); - if(!string.IsNullOrEmpty(info.Sprite)) return info; - } - - // Still no sprite found? then just pick the first we can find - Dictionary list = GetAllStates(); - foreach(StateStructure s in list.Values) - { - StateStructure.FrameInfo info = s.GetSprite(0); - if(!string.IsNullOrEmpty(info.Sprite)) return info; + //if(!string.IsNullOrEmpty(info.Sprite)) return info; + if (string.IsNullOrEmpty(info.Sprite)) continue; + + if (!info.IsEmpty()) lastNonTntInfo = info; + if (lastInfo == null) lastInfo = info; + + if (lastNonTntInfo != null) + break; } + + // [ZZ] return whatever is there by priority. try to pick non-TNT1 frames. + StateStructure.FrameInfo[] infos = new StateStructure.FrameInfo[] { lastNonTntInfo, firstNonTntInfo, lastInfo, firstInfo }; + foreach (StateStructure.FrameInfo info in infos) + if (info != null) return info; //mxd. No dice... return null; diff --git a/Source/Core/ZDoom/DecorateStateStructure.cs b/Source/Core/ZDoom/DecorateStateStructure.cs index 57dcd692..d2184abd 100755 --- a/Source/Core/ZDoom/DecorateStateStructure.cs +++ b/Source/Core/ZDoom/DecorateStateStructure.cs @@ -119,6 +119,19 @@ namespace CodeImp.DoomBuilder.ZDoom if (/*!realspritename.StartsWith("TNT1") && */!spritename.StartsWith("----") && !spritename.Contains("#")) // [ZZ] some actors have only TNT1 state and receive a random image because of this { info.Sprite = spritename; //mxd + int duration = -1; + parser.SkipWhitespace(false); + string durationstr = parser.ReadToken(); + if (durationstr == "-") + durationstr += parser.ReadToken(); + if (string.IsNullOrEmpty(durationstr) || durationstr == "\n") + { + parser.ReportError("Expected frame duration"); + return; + } + if (!int.TryParse(durationstr.Trim(), out duration)) + parser.DataStream.Seek(-(durationstr.Length), SeekOrigin.Current); + info.Duration = duration; sprites.Add(info); } } diff --git a/Source/Core/ZDoom/StateStructure.cs b/Source/Core/ZDoom/StateStructure.cs index dd4a3e79..f2e1bf20 100755 --- a/Source/Core/ZDoom/StateStructure.cs +++ b/Source/Core/ZDoom/StateStructure.cs @@ -33,6 +33,12 @@ namespace CodeImp.DoomBuilder.ZDoom public string Sprite; public string LightName; public bool Bright; + public int Duration; // this is used for TrimLeft + + public bool IsEmpty() + { + return (Sprite.StartsWith("TNT1") || Duration == 0); + } } #endregion @@ -78,7 +84,7 @@ namespace CodeImp.DoomBuilder.ZDoom int firstNonEmpty = -1; for (int i = 0; i < sprites.Count; i++) { - if (!sprites[i].Sprite.StartsWith("TNT1")) + if (!sprites[i].IsEmpty()) { firstNonEmpty = i; break; diff --git a/Source/Core/ZDoom/ZScriptStateStructure.cs b/Source/Core/ZDoom/ZScriptStateStructure.cs index 326ca5c0..a83859a5 100755 --- a/Source/Core/ZDoom/ZScriptStateStructure.cs +++ b/Source/Core/ZDoom/ZScriptStateStructure.cs @@ -148,6 +148,7 @@ namespace CodeImp.DoomBuilder.ZDoom token = tokenizer.ExpectToken(ZScriptTokenType.Identifier); if (token != null && token.IsValid) { + duration = -1; tokenizer.SkipWhitespace(); token = tokenizer.ExpectToken(ZScriptTokenType.OpenParen); if (token != null && token.IsValid) @@ -181,6 +182,7 @@ namespace CodeImp.DoomBuilder.ZDoom if (/*!realspritename.StartsWith("TNT1") && */!realspritename.StartsWith("----") && !realspritename.Contains("#")) // [ZZ] some actors have only TNT1 state and receive a random image because of this { info.Sprite = realspritename; //mxd + info.Duration = duration; sprites.Add(info); } diff --git a/Source/Plugins/BuilderModes/Properties/AssemblyInfo.cs b/Source/Plugins/BuilderModes/Properties/AssemblyInfo.cs index f0cff6af..bd22378e 100755 --- a/Source/Plugins/BuilderModes/Properties/AssemblyInfo.cs +++ b/Source/Plugins/BuilderModes/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Resources; // Build Number // Revision // -[assembly: AssemblyVersion("2.3.0.2924")] +[assembly: AssemblyVersion("2.3.0.2927")] [assembly: NeutralResourcesLanguageAttribute("en")]