Fixed several cases when certain texture manipulation-related actions caused a crash when performed on not-yet-loaded textures.

This commit is contained in:
MaxED 2016-09-02 19:18:37 +00:00 committed by spherallic
parent 9af958312b
commit d1d0e93cef
12 changed files with 185 additions and 104 deletions

View file

@ -1590,7 +1590,7 @@ namespace CodeImp.DoomBuilder.Geometry
else if(l.Front.LowRequired() && l.Front.LongLowTexture != MapSet.EmptyLongName && General.Map.Data.GetTextureExists(l.Front.LongLowTexture)) else if(l.Front.LowRequired() && l.Front.LongLowTexture != MapSet.EmptyLongName && General.Map.Data.GetTextureExists(l.Front.LongLowTexture))
texture = General.Map.Data.GetTextureImage(l.Front.LongLowTexture); texture = General.Map.Data.GetTextureImage(l.Front.LongLowTexture);
if(texture != null) if(texture != null && texture.IsImageLoaded)
{ {
int repeatmidtexoffset = General.Map.SRB2 && l.IsFlagSet(General.Map.Config.RepeatMidtextureFlag) ? (l.Front.OffsetX / 4096) * 4096 : 0; int repeatmidtexoffset = General.Map.SRB2 && l.IsFlagSet(General.Map.Config.RepeatMidtextureFlag) ? (l.Front.OffsetX / 4096) * 4096 : 0;
l.Front.OffsetX = (int)Math.Round((reversed ? totalLength - curLength - l.Length : curLength)) % texture.Width + repeatmidtexoffset; l.Front.OffsetX = (int)Math.Round((reversed ? totalLength - curLength - l.Length : curLength)) % texture.Width + repeatmidtexoffset;
@ -1609,7 +1609,7 @@ namespace CodeImp.DoomBuilder.Geometry
else if(l.Back.LowRequired() && l.Back.LongLowTexture != MapSet.EmptyLongName && General.Map.Data.GetTextureExists(l.Back.LongLowTexture)) else if(l.Back.LowRequired() && l.Back.LongLowTexture != MapSet.EmptyLongName && General.Map.Data.GetTextureExists(l.Back.LongLowTexture))
texture = General.Map.Data.GetTextureImage(l.Back.LongLowTexture); texture = General.Map.Data.GetTextureImage(l.Back.LongLowTexture);
if(texture != null) if(texture != null && texture.IsImageLoaded)
{ {
int repeatmidtexoffset = General.Map.SRB2 && l.IsFlagSet(General.Map.Config.RepeatMidtextureFlag) ? (l.Back.OffsetX / 4096) * 4096 : 0; int repeatmidtexoffset = General.Map.SRB2 && l.IsFlagSet(General.Map.Config.RepeatMidtextureFlag) ? (l.Back.OffsetX / 4096) * 4096 : 0;
l.Back.OffsetX = (int)Math.Round((reversed ? totalLength - curLength - l.Length : curLength)) % texture.Width + repeatmidtexoffset; l.Back.OffsetX = (int)Math.Round((reversed ? totalLength - curLength - l.Length : curLength)) % texture.Width + repeatmidtexoffset;
@ -1632,24 +1632,24 @@ namespace CodeImp.DoomBuilder.Geometry
if(l.Front.MiddleRequired() && l.Front.LongMiddleTexture != MapSet.EmptyLongName && General.Map.Data.GetTextureExists(l.Front.LongMiddleTexture)) if(l.Front.MiddleRequired() && l.Front.LongMiddleTexture != MapSet.EmptyLongName && General.Map.Data.GetTextureExists(l.Front.LongMiddleTexture))
{ {
ImageData texture = General.Map.Data.GetTextureImage(l.Front.LongMiddleTexture); ImageData texture = General.Map.Data.GetTextureImage(l.Front.LongMiddleTexture);
float offset = (int)Math.Round((reversed ? totalLength - curLength - l.Length : curLength)) % texture.Width; float offset = (int)Math.Round((reversed ? totalLength - curLength - l.Length : curLength));
if(texture.IsImageLoaded) offset %= texture.Width;
if(offset > 0) UniFields.SetFloat(l.Front.Fields, "offsetx_mid", offset); if(offset > 0) UniFields.SetFloat(l.Front.Fields, "offsetx_mid", offset);
} }
if(l.Front.HighRequired() && l.Front.LongHighTexture != MapSet.EmptyLongName && General.Map.Data.GetTextureExists(l.Front.LongHighTexture)) if(l.Front.HighRequired() && l.Front.LongHighTexture != MapSet.EmptyLongName && General.Map.Data.GetTextureExists(l.Front.LongHighTexture))
{ {
ImageData texture = General.Map.Data.GetTextureImage(l.Front.LongHighTexture); ImageData texture = General.Map.Data.GetTextureImage(l.Front.LongHighTexture);
float offset = (int)Math.Round((reversed ? totalLength - curLength - l.Length : curLength)) % texture.Width; float offset = (int)Math.Round((reversed ? totalLength - curLength - l.Length : curLength));
if(texture.IsImageLoaded) offset %= texture.Width;
if(offset > 0) UniFields.SetFloat(l.Front.Fields, "offsetx_top", offset); if(offset > 0) UniFields.SetFloat(l.Front.Fields, "offsetx_top", offset);
} }
if(l.Front.LowRequired() && l.Front.LongLowTexture != MapSet.EmptyLongName && General.Map.Data.GetTextureExists(l.Front.LongLowTexture)) if(l.Front.LowRequired() && l.Front.LongLowTexture != MapSet.EmptyLongName && General.Map.Data.GetTextureExists(l.Front.LongLowTexture))
{ {
ImageData texture = General.Map.Data.GetTextureImage(l.Front.LongLowTexture); ImageData texture = General.Map.Data.GetTextureImage(l.Front.LongLowTexture);
float offset = (int)Math.Round((reversed ? totalLength - curLength - l.Length : curLength)) % texture.Width; float offset = (int)Math.Round((reversed ? totalLength - curLength - l.Length : curLength));
if(texture.IsImageLoaded) offset %= texture.Width;
if(offset > 0) UniFields.SetFloat(l.Front.Fields, "offsetx_bottom", offset); if(offset > 0) UniFields.SetFloat(l.Front.Fields, "offsetx_bottom", offset);
} }
} }
@ -1659,24 +1659,24 @@ namespace CodeImp.DoomBuilder.Geometry
if(l.Back.MiddleRequired() && l.Back.LongMiddleTexture != MapSet.EmptyLongName && General.Map.Data.GetTextureExists(l.Back.LongMiddleTexture)) if(l.Back.MiddleRequired() && l.Back.LongMiddleTexture != MapSet.EmptyLongName && General.Map.Data.GetTextureExists(l.Back.LongMiddleTexture))
{ {
ImageData texture = General.Map.Data.GetTextureImage(l.Back.LongMiddleTexture); ImageData texture = General.Map.Data.GetTextureImage(l.Back.LongMiddleTexture);
float offset = (int)Math.Round((reversed ? totalLength - curLength - l.Length : curLength)) % texture.Width; float offset = (int)Math.Round((reversed ? totalLength - curLength - l.Length : curLength));
if(texture.IsImageLoaded) offset %= texture.Width;
if(offset > 0) UniFields.SetFloat(l.Back.Fields, "offsetx_mid", offset); if(offset > 0) UniFields.SetFloat(l.Back.Fields, "offsetx_mid", offset);
} }
if(l.Back.HighRequired() && l.Back.LongHighTexture != MapSet.EmptyLongName && General.Map.Data.GetTextureExists(l.Back.LongHighTexture)) if(l.Back.HighRequired() && l.Back.LongHighTexture != MapSet.EmptyLongName && General.Map.Data.GetTextureExists(l.Back.LongHighTexture))
{ {
ImageData texture = General.Map.Data.GetTextureImage(l.Back.LongHighTexture); ImageData texture = General.Map.Data.GetTextureImage(l.Back.LongHighTexture);
float offset = (int)Math.Round((reversed ? totalLength - curLength - l.Length : curLength)) % texture.Width; float offset = (int)Math.Round((reversed ? totalLength - curLength - l.Length : curLength));
if(texture.IsImageLoaded) offset %= texture.Width;
if(offset > 0) UniFields.SetFloat(l.Back.Fields, "offsetx_top", offset); if(offset > 0) UniFields.SetFloat(l.Back.Fields, "offsetx_top", offset);
} }
if(l.Back.LowRequired() && l.Back.LongLowTexture != MapSet.EmptyLongName && General.Map.Data.GetTextureExists(l.Back.LongLowTexture)) if(l.Back.LowRequired() && l.Back.LongLowTexture != MapSet.EmptyLongName && General.Map.Data.GetTextureExists(l.Back.LongLowTexture))
{ {
ImageData texture = General.Map.Data.GetTextureImage(l.Back.LongLowTexture); ImageData texture = General.Map.Data.GetTextureImage(l.Back.LongLowTexture);
float offset = (int)Math.Round((reversed ? totalLength - curLength - l.Length : curLength)) % texture.Width; float offset = (int)Math.Round((reversed ? totalLength - curLength - l.Length : curLength));
if(texture.IsImageLoaded) offset %= texture.Width;
if(offset > 0) UniFields.SetFloat(l.Back.Fields, "offsetx_bottom", offset); if(offset > 0) UniFields.SetFloat(l.Back.Fields, "offsetx_bottom", offset);
} }
} }

View file

@ -1559,7 +1559,7 @@ namespace CodeImp.DoomBuilder.Map
texture = General.Map.Data.GetTextureImage(newline.front.LowTexture); texture = General.Map.Data.GetTextureImage(newline.front.LowTexture);
//clamp offsetX //clamp offsetX
if (texture != null) if (texture != null && texture.IsImageLoaded)
{ {
int repeatmidtexoffset = General.Map.SRB2 && newline.IsFlagSet(General.Map.Config.RepeatMidtextureFlag) ? (newline.front.OffsetX / 4096) * 4096 : 0; int repeatmidtexoffset = General.Map.SRB2 && newline.IsFlagSet(General.Map.Config.RepeatMidtextureFlag) ? (newline.front.OffsetX / 4096) * 4096 : 0;
newline.front.OffsetX %= texture.Width; newline.front.OffsetX %= texture.Width;
@ -1580,7 +1580,7 @@ namespace CodeImp.DoomBuilder.Map
texture = General.Map.Data.GetTextureImage(newline.back.LowTexture); texture = General.Map.Data.GetTextureImage(newline.back.LowTexture);
//clamp offsetX //clamp offsetX
if (texture != null) if (texture != null && texture.IsImageLoaded)
{ {
int repeatmidtexoffset = General.Map.SRB2 && newline.IsFlagSet(General.Map.Config.RepeatMidtextureFlag) ? (newline.back.OffsetX / 4096) * 4096 : 0; int repeatmidtexoffset = General.Map.SRB2 && newline.IsFlagSet(General.Map.Config.RepeatMidtextureFlag) ? (newline.back.OffsetX / 4096) * 4096 : 0;
newline.back.OffsetX %= texture.Width; newline.back.OffsetX %= texture.Width;

View file

@ -791,7 +791,8 @@ namespace CodeImp.DoomBuilder.Map
float scaleTop = Fields.GetValue("scalex_top", 1.0f); float scaleTop = Fields.GetValue("scalex_top", 1.0f);
float value = Fields.GetValue("offsetx_top", 0f); float value = Fields.GetValue("offsetx_top", 0f);
float result = (float)(Math.Round(value + offset * scaleTop) % texture.Width); float result = (float)(Math.Round(value + offset * scaleTop));
if(texture.IsImageLoaded) result %= texture.Width;
UniFields.SetFloat(Fields, "offsetx_top", result); UniFields.SetFloat(Fields, "offsetx_top", result);
} }
@ -802,7 +803,8 @@ namespace CodeImp.DoomBuilder.Map
float scaleMid = Fields.GetValue("scalex_mid", 1.0f); float scaleMid = Fields.GetValue("scalex_mid", 1.0f);
float value = Fields.GetValue("offsetx_mid", 0f); float value = Fields.GetValue("offsetx_mid", 0f);
float result = (float)(Math.Round(value + offset * scaleMid) % texture.Width); float result = (float)(Math.Round(value + offset * scaleMid));
if(texture.IsImageLoaded) result %= texture.Width;
UniFields.SetFloat(Fields, "offsetx_mid", result); UniFields.SetFloat(Fields, "offsetx_mid", result);
} }
@ -813,7 +815,8 @@ namespace CodeImp.DoomBuilder.Map
float scaleLow = Fields.GetValue("scalex_bottom", 1.0f); float scaleLow = Fields.GetValue("scalex_bottom", 1.0f);
float value = Fields.GetValue("offsetx_bottom", 0f); float value = Fields.GetValue("offsetx_bottom", 0f);
float result = (float)(Math.Round(value + offset * scaleLow) % texture.Width); float result = (float)(Math.Round(value + offset * scaleLow));
if(texture.IsImageLoaded) result %= texture.Width;
UniFields.SetFloat(Fields, "offsetx_bottom", result); UniFields.SetFloat(Fields, "offsetx_bottom", result);
} }
} }

View file

@ -299,13 +299,13 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(alignx) if(alignx)
{ {
if(Texture != null) offset.x %= Texture.Width / scaleX; if(Texture != null && Texture.IsImageLoaded) offset.x %= Texture.Width / scaleX;
UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "xpanningfloor" : "xpanningceiling"), (float)Math.Round(-offset.x), 0f); UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "xpanningfloor" : "xpanningceiling"), (float)Math.Round(-offset.x), 0f);
} }
if(aligny) if(aligny)
{ {
if(Texture != null) offset.y %= Texture.Height / scaleY; if(Texture != null && Texture.IsImageLoaded) offset.y %= Texture.Height / scaleY;
UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "ypanningfloor" : "ypanningceiling"), (float)Math.Round(offset.y), 0f); UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "ypanningfloor" : "ypanningceiling"), (float)Math.Round(offset.y), 0f);
} }
@ -389,13 +389,13 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(alignx) if(alignx)
{ {
if(Texture != null) offset.x %= Texture.Width / scaleX; if(Texture != null && Texture.IsImageLoaded) offset.x %= Texture.Width / scaleX;
UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "xpanningfloor" : "xpanningceiling"), (float)Math.Round(-offset.x), 0f); UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "xpanningfloor" : "xpanningceiling"), (float)Math.Round(-offset.x), 0f);
} }
if(aligny) if(aligny)
{ {
if(Texture != null) offset.y %= Texture.Height / scaleY; if(Texture != null && Texture.IsImageLoaded) offset.y %= Texture.Height / scaleY;
UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "ypanningfloor" : "ypanningceiling"), (float)Math.Round(offset.y), 0f); UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "ypanningfloor" : "ypanningceiling"), (float)Math.Round(offset.y), 0f);
} }

View file

@ -682,11 +682,13 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(options.FitWidth) if(options.FitWidth)
{ {
float scalex, offsetx; float scalex, offsetx;
float linelength = (float)Math.Round(Sidedef.Line.Length); // Let's use ZDoom-compatible line length here
if(options.FitAcrossSurfaces) if(options.FitAcrossSurfaces)
{ {
scalex = Texture.ScaledWidth / (Sidedef.Line.Length * (options.GlobalBounds.Width / Sidedef.Line.Length)) * options.HorizontalRepeat; scalex = Texture.ScaledWidth / (linelength * (options.GlobalBounds.Width / linelength)) * options.HorizontalRepeat;
offsetx = (float)Math.Round((options.Bounds.X * scalex - Sidedef.OffsetX - options.ControlSideOffsetX) % Texture.Width, General.Map.FormatInterface.VertexDecimals); offsetx = (float)Math.Round((options.Bounds.X * scalex - Sidedef.OffsetX - options.ControlSideOffsetX), General.Map.FormatInterface.VertexDecimals);
if(Texture.IsImageLoaded) offsetx %= Texture.Width;
} }
else else
{ {
@ -728,17 +730,24 @@ namespace CodeImp.DoomBuilder.BuilderModes
} }
else else
{ {
offsety = Tools.GetSidedefOffsetY(Sidedef, geometrytype, options.Bounds.Y * scaley - Sidedef.OffsetY - options.ControlSideOffsetY, scaley, true) % Texture.Height; offsety = Tools.GetSidedefOffsetY(Sidedef, geometrytype, options.Bounds.Y * scaley - Sidedef.OffsetY - options.ControlSideOffsetY, scaley, true);
if(Texture.IsImageLoaded) offsety %= Texture.Height;
} }
} }
else else
{ {
scaley = Texture.ScaledHeight / options.Bounds.Height * options.VerticalRepeat; scaley = Texture.ScaledHeight / options.Bounds.Height * options.VerticalRepeat;
if(this is VisualLower) // Special cases, special cases... // Special cases, special cases...
if(this is VisualLower)
{
offsety = GetLowerOffsetY(scaley); offsety = GetLowerOffsetY(scaley);
}
else else
offsety = Tools.GetSidedefOffsetY(Sidedef, geometrytype, -Sidedef.OffsetY - options.ControlSideOffsetY, scaley, true) % Texture.Height; {
offsety = Tools.GetSidedefOffsetY(Sidedef, geometrytype, -Sidedef.OffsetY - options.ControlSideOffsetY, scaley, true);
if(Texture.IsImageLoaded) offsety %= Texture.Height;
}
} }
UniFields.SetFloat(controlside.Fields, "scaley_" + partname, (float)Math.Round(scaley, General.Map.FormatInterface.VertexDecimals), 1.0f); UniFields.SetFloat(controlside.Fields, "scaley_" + partname, (float)Math.Round(scaley, General.Map.FormatInterface.VertexDecimals), 1.0f);
@ -756,9 +765,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
//mxd. Oh so special cases... //mxd. Oh so special cases...
private float GetLowerOffsetY(float scaley) private float GetLowerOffsetY(float scaley)
{ {
if(IsLowerUnpegged()) float offsety;
return ((-Sidedef.OffsetY - Sidedef.GetMiddleHeight() - Sidedef.GetHighHeight()) * scaley) % Texture.Height; if(Sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag))
return (-Sidedef.OffsetY * scaley) % Texture.Height; offsety = (-Sidedef.OffsetY - Sidedef.GetMiddleHeight() - Sidedef.GetHighHeight()) * scaley;
else
offsety = -Sidedef.OffsetY * scaley;
if(Texture.IsImageLoaded) offsety %= Texture.Height;
return offsety;
} }
#endregion #endregion
@ -1579,8 +1593,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
protected virtual int ChangeOffsetX(int amount) protected virtual int ChangeOffsetX(int amount)
{ {
Sidedef.OffsetX -= amount; Sidedef.OffsetX -= amount;
if (Texture != null) if (Texture != null && Texture.IsImageLoaded)
{ {
int repeatmidtexoffset = General.Map.SRB2 && Sidedef.Line.IsFlagSet(General.Map.Config.RepeatMidtextureFlag) ? (Sidedef.OffsetX / 4096) * 4096 : 0; int repeatmidtexoffset = General.Map.SRB2 && Sidedef.Line.IsFlagSet(General.Map.Config.RepeatMidtextureFlag) ? (Sidedef.OffsetX / 4096) * 4096 : 0;
Sidedef.OffsetX %= Texture.Width; Sidedef.OffsetX %= Texture.Width;
Sidedef.OffsetX += repeatmidtexoffset; Sidedef.OffsetX += repeatmidtexoffset;
@ -1591,7 +1605,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
protected virtual int ChangeOffsetY(int amount) protected virtual int ChangeOffsetY(int amount)
{ {
Sidedef.OffsetY -= amount; Sidedef.OffsetY -= amount;
if (geometrytype != VisualGeometryType.WALL_MIDDLE && Texture != null) Sidedef.OffsetY %= Texture.Height; if (geometrytype != VisualGeometryType.WALL_MIDDLE && Texture != null && Texture.IsImageLoaded) Sidedef.OffsetY %= Texture.Height;
return Sidedef.OffsetY; return Sidedef.OffsetY;
} }
@ -1604,7 +1618,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
//mxd //mxd
public virtual void OnChangeScale(int incrementX, int incrementY) public virtual void OnChangeScale(int incrementX, int incrementY)
{ {
if(!General.Map.UDMF || !Texture.IsImageLoaded) return; if(!General.Map.UDMF || Texture == null || !Texture.IsImageLoaded) return;
if((General.Map.UndoRedo.NextUndo == null) || (General.Map.UndoRedo.NextUndo.TicketID != undoticket)) if((General.Map.UndoRedo.NextUndo == null) || (General.Map.UndoRedo.NextUndo.TicketID != undoticket))
undoticket = mode.CreateUndo("Change wall scale"); undoticket = mode.CreateUndo("Change wall scale");

View file

@ -4764,9 +4764,17 @@ namespace CodeImp.DoomBuilder.BuilderModes
offset -= j.sidedef.OffsetX; offset -= j.sidedef.OffsetX;
if(matchtop) if(matchtop)
j.sidedef.Fields["offsetx_top"] = new UniValue(UniversalType.Float, (float)Math.Round(offset % General.Map.Data.GetTextureImage(j.sidedef.LongHighTexture).Width, General.Map.FormatInterface.VertexDecimals)); {
ImageData tex = General.Map.Data.GetTextureImage(j.sidedef.LongHighTexture);
int texwidth = (tex != null && tex.IsImageLoaded) ? tex.Width : 1;
j.sidedef.Fields["offsetx_top"] = new UniValue(UniversalType.Float, (float)Math.Round(offset % texwidth, General.Map.FormatInterface.VertexDecimals));
}
if(matchbottom) if(matchbottom)
j.sidedef.Fields["offsetx_bottom"] = new UniValue(UniversalType.Float, (float)Math.Round(offset % General.Map.Data.GetTextureImage(j.sidedef.LongLowTexture).Width, General.Map.FormatInterface.VertexDecimals)); {
ImageData tex = General.Map.Data.GetTextureImage(j.sidedef.LongLowTexture);
int texwidth = (tex != null && tex.IsImageLoaded) ? tex.Width : 1;
j.sidedef.Fields["offsetx_bottom"] = new UniValue(UniversalType.Float, (float)Math.Round(offset % texwidth, General.Map.FormatInterface.VertexDecimals));
}
if(matchmid) if(matchmid)
{ {
if(j.sidedef.Index != j.controlSide.Index) //mxd. if it's a part of 3d-floor if(j.sidedef.Index != j.controlSide.Index) //mxd. if it's a part of 3d-floor
@ -4775,7 +4783,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
offset -= j.controlSide.Fields.GetValue("offsetx_mid", 0.0f); offset -= j.controlSide.Fields.GetValue("offsetx_mid", 0.0f);
} }
j.sidedef.Fields["offsetx_mid"] = new UniValue(UniversalType.Float, (float)Math.Round(offset % General.Map.Data.GetTextureImage(j.controlSide.LongMiddleTexture).Width, General.Map.FormatInterface.VertexDecimals)); ImageData tex = General.Map.Data.GetTextureImage(j.controlSide.LongMiddleTexture);
int texwidth = (tex != null && tex.IsImageLoaded) ? tex.Width : 1;
j.sidedef.Fields["offsetx_mid"] = new UniValue(UniversalType.Float, (float)Math.Round(offset % texwidth, General.Map.FormatInterface.VertexDecimals));
} }
} }
@ -4785,9 +4795,19 @@ namespace CodeImp.DoomBuilder.BuilderModes
offset -= j.sidedef.OffsetY; //mxd offset -= j.sidedef.OffsetY; //mxd
if(matchtop) if(matchtop)
j.sidedef.Fields["offsety_top"] = new UniValue(UniversalType.Float, (float)Math.Round(Tools.GetSidedefTopOffsetY(j.sidedef, offset, j.scaleY / scaley, true) % General.Map.Data.GetTextureImage(j.sidedef.LongHighTexture).Height, General.Map.FormatInterface.VertexDecimals)); //mxd {
ImageData tex = General.Map.Data.GetTextureImage(j.sidedef.LongHighTexture);
int texheight = (tex != null && tex.IsImageLoaded) ? tex.Height : 1;
j.sidedef.Fields["offsety_top"] = new UniValue(UniversalType.Float,
(float)Math.Round(Tools.GetSidedefTopOffsetY(j.sidedef, offset, j.scaleY / scaley, true) % texheight, General.Map.FormatInterface.VertexDecimals)); //mxd
}
if(matchbottom) if(matchbottom)
j.sidedef.Fields["offsety_bottom"] = new UniValue(UniversalType.Float, (float)Math.Round(Tools.GetSidedefBottomOffsetY(j.sidedef, offset, j.scaleY / scaley, true) % General.Map.Data.GetTextureImage(j.sidedef.LongLowTexture).Height, General.Map.FormatInterface.VertexDecimals)); //mxd {
ImageData tex = General.Map.Data.GetTextureImage(j.sidedef.LongLowTexture);
int texheight = (tex != null && tex.IsImageLoaded) ? tex.Height : 1;
j.sidedef.Fields["offsety_bottom"] = new UniValue(UniversalType.Float,
(float)Math.Round(Tools.GetSidedefBottomOffsetY(j.sidedef, offset, j.scaleY / scaley, true) % texheight, General.Map.FormatInterface.VertexDecimals)); //mxd
}
if(matchmid) if(matchmid)
{ {
//mxd. Side is part of a 3D floor? //mxd. Side is part of a 3D floor?
@ -4795,43 +4815,51 @@ namespace CodeImp.DoomBuilder.BuilderModes
{ {
offset -= j.controlSide.OffsetY; offset -= j.controlSide.OffsetY;
offset -= j.controlSide.Fields.GetValue("offsety_mid", 0.0f); offset -= j.controlSide.Fields.GetValue("offsety_mid", 0.0f);
j.sidedef.Fields["offsety_mid"] = new UniValue(UniversalType.Float, (float)Math.Round(offset % General.Map.Data.GetTextureImage(j.controlSide.LongMiddleTexture).Height, General.Map.FormatInterface.VertexDecimals));
ImageData tex = General.Map.Data.GetTextureImage(j.controlSide.LongMiddleTexture);
int texheight = (tex != null && tex.IsImageLoaded) ? tex.Height : 1;
j.sidedef.Fields["offsety_mid"] = new UniValue(UniversalType.Float,
(float)Math.Round(offset % texheight, General.Map.FormatInterface.VertexDecimals));
} }
else else
{ {
ImageData midtex = General.Map.Data.GetTextureImage(j.sidedef.LongMiddleTexture); ImageData tex = General.Map.Data.GetTextureImage(j.sidedef.LongMiddleTexture);
offset = Tools.GetSidedefMiddleOffsetY(j.sidedef, offset, j.scaleY / scaley, true); offset = Tools.GetSidedefMiddleOffsetY(j.sidedef, offset, j.scaleY / scaley, true);
bool startisnonwrappedmidtex = (start.Sidedef.Other != null && start.GeometryType == VisualGeometryType.WALL_MIDDLE && !start.Sidedef.IsFlagSet("wrapmidtex") && !start.Sidedef.Line.IsFlagSet("wrapmidtex")); if(tex != null && tex.IsImageLoaded)
bool cursideisnonwrappedmidtex = (j.sidedef.Other != null && !j.sidedef.IsFlagSet("wrapmidtex") && !j.sidedef.Line.IsFlagSet("wrapmidtex"));
//mxd. Only clamp when the texture is wrapped
if(!cursideisnonwrappedmidtex) offset %= midtex.Height;
if(!startisnonwrappedmidtex && cursideisnonwrappedmidtex)
{ {
//mxd. This should be doublesided non-wrapped line. Find the nearset aligned position bool startisnonwrappedmidtex = (start.Sidedef.Other != null && start.GeometryType == VisualGeometryType.WALL_MIDDLE && !start.Sidedef.IsFlagSet("wrapmidtex") && !start.Sidedef.Line.IsFlagSet("wrapmidtex"));
float curoffset = UniFields.GetFloat(j.sidedef.Fields, "offsety_mid") + j.sidedef.OffsetY; bool cursideisnonwrappedmidtex = (j.sidedef.Other != null && !j.sidedef.IsFlagSet("wrapmidtex") && !j.sidedef.Line.IsFlagSet("wrapmidtex"));
offset += midtex.Height * (float)Math.Round(curoffset / midtex.Height - 0.5f * Math.Sign(j.scaleY));
// Make sure the surface stays between floor and ceiling //mxd. Only clamp when the texture is wrapped
if(j.sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag) || Math.Sign(j.scaleY) == -1) if(!cursideisnonwrappedmidtex) offset %= tex.Height;
if(!startisnonwrappedmidtex && cursideisnonwrappedmidtex)
{ {
if(offset < -midtex.Height) //mxd. This should be doublesided non-wrapped line. Find the nearset aligned position
offset += midtex.Height; float curoffset = UniFields.GetFloat(j.sidedef.Fields, "offsety_mid") + j.sidedef.OffsetY;
else if(offset > j.sidedef.GetMiddleHeight()) offset += tex.Height * (float)Math.Round(curoffset / tex.Height - 0.5f * Math.Sign(j.scaleY));
offset -= midtex.Height;
} // Make sure the surface stays between floor and ceiling
else if(j.sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag) || Math.Sign(j.scaleY) == -1)
{ {
if(offset < -(j.sidedef.GetMiddleHeight() + midtex.Height)) if(offset < -tex.Height)
offset += midtex.Height; offset += tex.Height;
else if(offset > midtex.Height) else if(offset > j.sidedef.GetMiddleHeight())
offset -= midtex.Height; offset -= tex.Height;
}
else
{
if(offset < -(j.sidedef.GetMiddleHeight() + tex.Height))
offset += tex.Height;
else if(offset > tex.Height)
offset -= tex.Height;
}
} }
} }
j.sidedef.Fields["offsety_mid"] = new UniValue(UniversalType.Float, (float)Math.Round(offset, General.Map.FormatInterface.VertexDecimals)); //mxd j.sidedef.Fields["offsety_mid"] = new UniValue(UniversalType.Float,
(float)Math.Round(offset, General.Map.FormatInterface.VertexDecimals)); //mxd
} }
} }
} }
@ -4860,9 +4888,19 @@ namespace CodeImp.DoomBuilder.BuilderModes
offset -= j.sidedef.OffsetX; offset -= j.sidedef.OffsetX;
if(matchtop) if(matchtop)
j.sidedef.Fields["offsetx_top"] = new UniValue(UniversalType.Float, (float)Math.Round(offset % General.Map.Data.GetTextureImage(j.sidedef.LongHighTexture).Width, General.Map.FormatInterface.VertexDecimals)); {
ImageData tex = General.Map.Data.GetTextureImage(j.sidedef.LongHighTexture);
int texwidth = (tex != null && tex.IsImageLoaded) ? tex.Width : 1;
j.sidedef.Fields["offsetx_top"] = new UniValue(UniversalType.Float,
(float)Math.Round(offset % texwidth, General.Map.FormatInterface.VertexDecimals));
}
if(matchbottom) if(matchbottom)
j.sidedef.Fields["offsetx_bottom"] = new UniValue(UniversalType.Float, (float)Math.Round(offset % General.Map.Data.GetTextureImage(j.sidedef.LongLowTexture).Width, General.Map.FormatInterface.VertexDecimals)); {
ImageData tex = General.Map.Data.GetTextureImage(j.sidedef.LongLowTexture);
int texwidth = (tex != null && tex.IsImageLoaded) ? tex.Width : 1;
j.sidedef.Fields["offsetx_bottom"] = new UniValue(UniversalType.Float,
(float)Math.Round(offset % texwidth, General.Map.FormatInterface.VertexDecimals));
}
if(matchmid) if(matchmid)
{ {
if(j.sidedef.Index != j.controlSide.Index) //mxd if(j.sidedef.Index != j.controlSide.Index) //mxd
@ -4871,7 +4909,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
offset -= j.controlSide.Fields.GetValue("offsetx_mid", 0.0f); offset -= j.controlSide.Fields.GetValue("offsetx_mid", 0.0f);
} }
j.sidedef.Fields["offsetx_mid"] = new UniValue(UniversalType.Float, (float)Math.Round(offset % General.Map.Data.GetTextureImage(j.controlSide.LongMiddleTexture).Width, General.Map.FormatInterface.VertexDecimals)); ImageData tex = General.Map.Data.GetTextureImage(j.controlSide.LongMiddleTexture);
int texwidth = (tex != null && tex.IsImageLoaded) ? tex.Width : 1;
j.sidedef.Fields["offsetx_mid"] = new UniValue(UniversalType.Float,
(float)Math.Round(offset % texwidth, General.Map.FormatInterface.VertexDecimals));
} }
} }
@ -4881,9 +4922,19 @@ namespace CodeImp.DoomBuilder.BuilderModes
offset -= j.sidedef.OffsetY; //mxd offset -= j.sidedef.OffsetY; //mxd
if(matchtop) if(matchtop)
j.sidedef.Fields["offsety_top"] = new UniValue(UniversalType.Float, (float)Math.Round(Tools.GetSidedefTopOffsetY(j.sidedef, offset, j.scaleY / scaley, true) % General.Map.Data.GetTextureImage(j.sidedef.LongHighTexture).Height, General.Map.FormatInterface.VertexDecimals)); //mxd {
ImageData tex = General.Map.Data.GetTextureImage(j.sidedef.LongHighTexture);
int texheight = (tex != null && tex.IsImageLoaded) ? tex.Height : 1;
j.sidedef.Fields["offsety_top"] = new UniValue(UniversalType.Float,
(float)Math.Round(Tools.GetSidedefTopOffsetY(j.sidedef, offset, j.scaleY / scaley, true) % texheight, General.Map.FormatInterface.VertexDecimals)); //mxd
}
if(matchbottom) if(matchbottom)
j.sidedef.Fields["offsety_bottom"] = new UniValue(UniversalType.Float, (float)Math.Round(Tools.GetSidedefBottomOffsetY(j.sidedef, offset, j.scaleY / scaley, true) % General.Map.Data.GetTextureImage(j.sidedef.LongLowTexture).Height, General.Map.FormatInterface.VertexDecimals)); //mxd {
ImageData tex = General.Map.Data.GetTextureImage(j.sidedef.LongLowTexture);
int texheight = (tex != null && tex.IsImageLoaded) ? tex.Height : 1;
j.sidedef.Fields["offsety_bottom"] = new UniValue(UniversalType.Float,
(float)Math.Round(Tools.GetSidedefBottomOffsetY(j.sidedef, offset, j.scaleY / scaley, true) % texheight, General.Map.FormatInterface.VertexDecimals)); //mxd
}
if(matchmid) if(matchmid)
{ {
//mxd. Side is part of a 3D floor? //mxd. Side is part of a 3D floor?
@ -4891,43 +4942,51 @@ namespace CodeImp.DoomBuilder.BuilderModes
{ {
offset -= j.controlSide.OffsetY; offset -= j.controlSide.OffsetY;
offset -= j.controlSide.Fields.GetValue("offsety_mid", 0.0f); offset -= j.controlSide.Fields.GetValue("offsety_mid", 0.0f);
j.sidedef.Fields["offsety_mid"] = new UniValue(UniversalType.Float, (float)Math.Round(offset % General.Map.Data.GetTextureImage(j.controlSide.LongMiddleTexture).Height, General.Map.FormatInterface.VertexDecimals)); //mxd
ImageData tex = General.Map.Data.GetTextureImage(j.controlSide.LongMiddleTexture);
int texheight = (tex != null && tex.IsImageLoaded) ? tex.Height : 1;
j.sidedef.Fields["offsety_mid"] = new UniValue(UniversalType.Float,
(float)Math.Round(offset % texheight, General.Map.FormatInterface.VertexDecimals)); //mxd
} }
else else
{ {
ImageData midtex = General.Map.Data.GetTextureImage(j.sidedef.LongMiddleTexture); ImageData tex = General.Map.Data.GetTextureImage(j.sidedef.LongMiddleTexture);
offset = Tools.GetSidedefMiddleOffsetY(j.sidedef, offset, j.scaleY / scaley, true); offset = Tools.GetSidedefMiddleOffsetY(j.sidedef, offset, j.scaleY / scaley, true);
bool startisnonwrappedmidtex = (start.Sidedef.Other != null && start.GeometryType == VisualGeometryType.WALL_MIDDLE && !start.Sidedef.IsFlagSet("wrapmidtex") && !start.Sidedef.Line.IsFlagSet("wrapmidtex")); if(tex != null && tex.IsImageLoaded)
bool cursideisnonwrappedmidtex = (j.sidedef.Other != null && !j.sidedef.IsFlagSet("wrapmidtex") && !j.sidedef.Line.IsFlagSet("wrapmidtex"));
//mxd. Only clamp when the texture is wrapped
if(!cursideisnonwrappedmidtex) offset %= midtex.Height;
if(!startisnonwrappedmidtex && cursideisnonwrappedmidtex)
{ {
//mxd. This should be doublesided non-wrapped line. Find the nearset aligned position bool startisnonwrappedmidtex = (start.Sidedef.Other != null && start.GeometryType == VisualGeometryType.WALL_MIDDLE && !start.Sidedef.IsFlagSet("wrapmidtex") && !start.Sidedef.Line.IsFlagSet("wrapmidtex"));
float curoffset = UniFields.GetFloat(j.sidedef.Fields, "offsety_mid") + j.sidedef.OffsetY; bool cursideisnonwrappedmidtex = (j.sidedef.Other != null && !j.sidedef.IsFlagSet("wrapmidtex") && !j.sidedef.Line.IsFlagSet("wrapmidtex"));
offset += midtex.Height * (float)Math.Round(curoffset / midtex.Height - 0.5f * Math.Sign(j.scaleY));
// Make sure the surface stays between floor and ceiling //mxd. Only clamp when the texture is wrapped
if(j.sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag) || Math.Sign(j.scaleY) == -1) if(!cursideisnonwrappedmidtex) offset %= tex.Height;
if(!startisnonwrappedmidtex && cursideisnonwrappedmidtex)
{ {
if(offset < -midtex.Height) //mxd. This should be doublesided non-wrapped line. Find the nearset aligned position
offset += midtex.Height; float curoffset = UniFields.GetFloat(j.sidedef.Fields, "offsety_mid") + j.sidedef.OffsetY;
else if(offset > j.sidedef.GetMiddleHeight()) offset += tex.Height * (float)Math.Round(curoffset / tex.Height - 0.5f * Math.Sign(j.scaleY));
offset -= midtex.Height;
} // Make sure the surface stays between floor and ceiling
else if(j.sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag) || Math.Sign(j.scaleY) == -1)
{ {
if(offset < -(j.sidedef.GetMiddleHeight() + midtex.Height)) if(offset < -tex.Height)
offset += midtex.Height; offset += tex.Height;
else if(offset > midtex.Height) else if(offset > j.sidedef.GetMiddleHeight())
offset -= midtex.Height; offset -= tex.Height;
}
else
{
if(offset < -(j.sidedef.GetMiddleHeight() + tex.Height))
offset += tex.Height;
else if(offset > tex.Height)
offset -= tex.Height;
}
} }
} }
j.sidedef.Fields["offsety_mid"] = new UniValue(UniversalType.Float, (float)Math.Round(offset, General.Map.FormatInterface.VertexDecimals)); //mxd j.sidedef.Fields["offsety_mid"] = new UniValue(UniversalType.Float,
(float)Math.Round(offset, General.Map.FormatInterface.VertexDecimals)); //mxd
} }
} }
} }

View file

@ -310,6 +310,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
//mxd. Texture scale change //mxd. Texture scale change
protected override void ChangeTextureScale(int incrementX, int incrementY) protected override void ChangeTextureScale(int incrementX, int incrementY)
{ {
if(Texture == null || !Texture.IsImageLoaded) return;
Sector s = GetControlSector(); Sector s = GetControlSector();
float scaleX = s.Fields.GetValue("xscaleceiling", 1.0f); float scaleX = s.Fields.GetValue("xscaleceiling", 1.0f);
float scaleY = s.Fields.GetValue("yscaleceiling", 1.0f); float scaleY = s.Fields.GetValue("yscaleceiling", 1.0f);

View file

@ -292,6 +292,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
//mxd. Texture scale change //mxd. Texture scale change
protected override void ChangeTextureScale(int incrementX, int incrementY) protected override void ChangeTextureScale(int incrementX, int incrementY)
{ {
if(Texture == null || !Texture.IsImageLoaded) return;
Sector s = GetControlSector(); Sector s = GetControlSector();
float scaleX = s.Fields.GetValue("xscalefloor", 1.0f); float scaleX = s.Fields.GetValue("xscalefloor", 1.0f);
float scaleY = s.Fields.GetValue("yscalefloor", 1.0f); float scaleY = s.Fields.GetValue("yscalefloor", 1.0f);

View file

@ -306,8 +306,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
float oldy = Sidedef.Fields.GetValue("offsety_bottom", 0.0f); float oldy = Sidedef.Fields.GetValue("offsety_bottom", 0.0f);
float scalex = Sidedef.Fields.GetValue("scalex_bottom", 1.0f); float scalex = Sidedef.Fields.GetValue("scalex_bottom", 1.0f);
float scaley = Sidedef.Fields.GetValue("scaley_bottom", 1.0f); float scaley = Sidedef.Fields.GetValue("scaley_bottom", 1.0f);
Sidedef.Fields["offsetx_bottom"] = new UniValue(UniversalType.Float, GetRoundedTextureOffset(oldx, xy.X, scalex, Texture != null ? Texture.Width : -1)); //mxd bool textureloaded = (Texture != null && Texture.IsImageLoaded); //mxd
Sidedef.Fields["offsety_bottom"] = new UniValue(UniversalType.Float, GetRoundedTextureOffset(oldy, xy.Y, scaley, Texture != null ? Texture.Height : -1)); //mxd Sidedef.Fields["offsetx_bottom"] = new UniValue(UniversalType.Float, GetRoundedTextureOffset(oldx, xy.X, scalex, textureloaded ? Texture.Width : -1)); //mxd
Sidedef.Fields["offsety_bottom"] = new UniValue(UniversalType.Float, GetRoundedTextureOffset(oldy, xy.Y, scaley, textureloaded ? Texture.Height : -1)); //mxd
} }
protected override Point GetTextureOffset() protected override Point GetTextureOffset()

View file

@ -490,7 +490,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
//mxd. Only control sidedef scale is used by GZDoom //mxd. Only control sidedef scale is used by GZDoom
public override void OnChangeScale(int incrementX, int incrementY) public override void OnChangeScale(int incrementX, int incrementY)
{ {
if(!General.Map.UDMF || !Texture.IsImageLoaded) return; if(!General.Map.UDMF || Texture == null || !Texture.IsImageLoaded) return;
if((General.Map.UndoRedo.NextUndo == null) || (General.Map.UndoRedo.NextUndo.TicketID != undoticket)) if((General.Map.UndoRedo.NextUndo == null) || (General.Map.UndoRedo.NextUndo.TicketID != undoticket))
undoticket = mode.CreateUndo("Change wall scale"); undoticket = mode.CreateUndo("Change wall scale");

View file

@ -471,10 +471,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
float oldy = Sidedef.Fields.GetValue("offsety_mid", 0.0f); float oldy = Sidedef.Fields.GetValue("offsety_mid", 0.0f);
float scalex = Sidedef.Fields.GetValue("scalex_mid", 1.0f); float scalex = Sidedef.Fields.GetValue("scalex_mid", 1.0f);
float scaley = Sidedef.Fields.GetValue("scaley_mid", 1.0f); float scaley = Sidedef.Fields.GetValue("scaley_mid", 1.0f);
Sidedef.Fields["offsetx_mid"] = new UniValue(UniversalType.Float, GetRoundedTextureOffset(oldx, xy.X, scalex, Texture != null ? Texture.Width : -1)); //mxd bool textureloaded = (Texture != null && Texture.IsImageLoaded); //mxd
Sidedef.Fields["offsetx_mid"] = new UniValue(UniversalType.Float, GetRoundedTextureOffset(oldx, xy.X, scalex, textureloaded ? Texture.Width : -1)); //mxd
//mxd. Don't clamp offsetY of clipped mid textures //mxd. Don't clamp offsetY of clipped mid textures
bool dontClamp = (Texture == null || (!Sidedef.IsFlagSet("wrapmidtex") && !Sidedef.Line.IsFlagSet("wrapmidtex"))); bool dontClamp = (!textureloaded || (!Sidedef.IsFlagSet("wrapmidtex") && !Sidedef.Line.IsFlagSet("wrapmidtex")));
Sidedef.Fields["offsety_mid"] = new UniValue(UniversalType.Float, GetRoundedTextureOffset(oldy, xy.Y, scaley, dontClamp ? -1 : Texture.Height)); Sidedef.Fields["offsety_mid"] = new UniValue(UniversalType.Float, GetRoundedTextureOffset(oldy, xy.Y, scaley, dontClamp ? -1 : Texture.Height));
} }

View file

@ -301,8 +301,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
float oldy = Sidedef.Fields.GetValue("offsety_top", 0.0f); float oldy = Sidedef.Fields.GetValue("offsety_top", 0.0f);
float scalex = Sidedef.Fields.GetValue("scalex_top", 1.0f); float scalex = Sidedef.Fields.GetValue("scalex_top", 1.0f);
float scaley = Sidedef.Fields.GetValue("scaley_top", 1.0f); float scaley = Sidedef.Fields.GetValue("scaley_top", 1.0f);
Sidedef.Fields["offsetx_top"] = new UniValue(UniversalType.Float, GetRoundedTextureOffset(oldx, xy.X, scalex, Texture != null ? Texture.Width : -1)); //mxd bool textureloaded = (Texture != null && Texture.IsImageLoaded); //mxd
Sidedef.Fields["offsety_top"] = new UniValue(UniversalType.Float, GetRoundedTextureOffset(oldy, xy.Y, scaley, Texture != null ? Texture.Height : -1)); //mxd Sidedef.Fields["offsetx_top"] = new UniValue(UniversalType.Float, GetRoundedTextureOffset(oldx, xy.X, scalex, textureloaded ? Texture.Width : -1)); //mxd
Sidedef.Fields["offsety_top"] = new UniValue(UniversalType.Float, GetRoundedTextureOffset(oldy, xy.Y, scaley, textureloaded ? Texture.Height : -1)); //mxd
} }
protected override Point GetTextureOffset() protected override Point GetTextureOffset()