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
parent 2d249748fb
commit f9b5597951
12 changed files with 184 additions and 101 deletions

View file

@ -1588,7 +1588,7 @@ namespace CodeImp.DoomBuilder.Geometry
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);
if(texture != null)
if(texture != null && texture.IsImageLoaded)
l.Front.OffsetX = (int)Math.Round((reversed ? totalLength - curLength - l.Length : curLength)) % texture.Width;
}
@ -1603,7 +1603,7 @@ namespace CodeImp.DoomBuilder.Geometry
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);
if(texture != null)
if(texture != null && texture.IsImageLoaded)
l.Back.OffsetX = (int)Math.Round((reversed ? totalLength - curLength - l.Length : curLength)) % texture.Width;
}
@ -1623,24 +1623,24 @@ namespace CodeImp.DoomBuilder.Geometry
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);
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(l.Front.HighRequired() && l.Front.LongHighTexture != MapSet.EmptyLongName && General.Map.Data.GetTextureExists(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(l.Front.LowRequired() && l.Front.LongLowTexture != MapSet.EmptyLongName && General.Map.Data.GetTextureExists(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);
}
}
@ -1650,24 +1650,24 @@ namespace CodeImp.DoomBuilder.Geometry
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);
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(l.Back.HighRequired() && l.Back.LongHighTexture != MapSet.EmptyLongName && General.Map.Data.GetTextureExists(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(l.Back.LowRequired() && l.Back.LongLowTexture != MapSet.EmptyLongName && General.Map.Data.GetTextureExists(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);
}
}

View file

@ -1378,7 +1378,8 @@ namespace CodeImp.DoomBuilder.Map
texture = General.Map.Data.GetTextureImage(newline.front.LowTexture);
//clamp offsetX
if(texture != null) newline.front.OffsetX %= texture.Width;
if(texture != null && texture.IsImageLoaded)
newline.front.OffsetX %= texture.Width;
}
if((oldline.back != null) && (newline.back != null))
@ -1394,7 +1395,8 @@ namespace CodeImp.DoomBuilder.Map
texture = General.Map.Data.GetTextureImage(newline.back.LowTexture);
//clamp offsetX
if(texture != null) newline.back.OffsetX %= texture.Width;
if(texture != null && texture.IsImageLoaded)
newline.back.OffsetX %= texture.Width;
}
break;

View file

@ -751,7 +751,8 @@ namespace CodeImp.DoomBuilder.Map
float scaleTop = Fields.GetValue("scalex_top", 1.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);
}
@ -762,7 +763,8 @@ namespace CodeImp.DoomBuilder.Map
float scaleMid = Fields.GetValue("scalex_mid", 1.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);
}
@ -773,7 +775,8 @@ namespace CodeImp.DoomBuilder.Map
float scaleLow = Fields.GetValue("scalex_bottom", 1.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);
}
}

View file

@ -300,13 +300,13 @@ namespace CodeImp.DoomBuilder.BuilderModes
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);
}
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);
}
@ -390,13 +390,13 @@ namespace CodeImp.DoomBuilder.BuilderModes
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);
}
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);
}

View file

@ -640,7 +640,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(options.FitAcrossSurfaces)
{
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
{
@ -682,17 +683,24 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
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
{
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);
}
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);
@ -710,9 +718,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
//mxd. Oh so special cases...
private float GetLowerOffsetY(float scaley)
{
float offsety;
if(Sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag))
return ((-Sidedef.OffsetY - Sidedef.GetMiddleHeight() - Sidedef.GetHighHeight()) * scaley) % Texture.Height;
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
@ -1468,10 +1481,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
else
{
//mxd. Apply classic offsets
bool textureloaded = (Texture != null && Texture.IsImageLoaded);
Sidedef.OffsetX = (Sidedef.OffsetX - horizontal);
if(Texture != null) Sidedef.OffsetX %= Texture.Width;
if(textureloaded) Sidedef.OffsetX %= Texture.Width;
Sidedef.OffsetY = (Sidedef.OffsetY - vertical);
if(geometrytype != VisualGeometryType.WALL_MIDDLE && Texture != null) Sidedef.OffsetY %= Texture.Height;
if(geometrytype != VisualGeometryType.WALL_MIDDLE && textureloaded) Sidedef.OffsetY %= Texture.Height;
mode.SetActionResult("Changed texture offsets to " + Sidedef.OffsetX + ", " + Sidedef.OffsetY + ".");
@ -1488,7 +1502,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
//mxd
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))
undoticket = mode.CreateUndo("Change wall scale");

View file

@ -3996,9 +3996,17 @@ namespace CodeImp.DoomBuilder.BuilderModes
offset -= j.sidedef.OffsetX;
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)
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(j.sidedef.Index != j.controlSide.Index) //mxd. if it's a part of 3d-floor
@ -4007,7 +4015,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
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));
}
}
@ -4017,9 +4027,19 @@ namespace CodeImp.DoomBuilder.BuilderModes
offset -= j.sidedef.OffsetY; //mxd
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)
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)
{
//mxd. Side is part of a 3D floor?
@ -4027,43 +4047,51 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
offset -= j.controlSide.OffsetY;
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
{
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);
bool startisnonwrappedmidtex = (start.Sidedef.Other != null && start.GeometryType == VisualGeometryType.WALL_MIDDLE && !start.Sidedef.IsFlagSet("wrapmidtex") && !start.Sidedef.Line.IsFlagSet("wrapmidtex"));
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)
if(tex != null && tex.IsImageLoaded)
{
//mxd. This should be doublesided non-wrapped line. Find the nearset aligned position
float curoffset = UniFields.GetFloat(j.sidedef.Fields, "offsety_mid") + j.sidedef.OffsetY;
offset += midtex.Height * (float)Math.Round(curoffset / midtex.Height - 0.5f * Math.Sign(j.scaleY));
bool startisnonwrappedmidtex = (start.Sidedef.Other != null && start.GeometryType == VisualGeometryType.WALL_MIDDLE && !start.Sidedef.IsFlagSet("wrapmidtex") && !start.Sidedef.Line.IsFlagSet("wrapmidtex"));
bool cursideisnonwrappedmidtex = (j.sidedef.Other != null && !j.sidedef.IsFlagSet("wrapmidtex") && !j.sidedef.Line.IsFlagSet("wrapmidtex"));
// Make sure the surface stays between floor and ceiling
if(j.sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag) || Math.Sign(j.scaleY) == -1)
//mxd. Only clamp when the texture is wrapped
if(!cursideisnonwrappedmidtex) offset %= tex.Height;
if(!startisnonwrappedmidtex && cursideisnonwrappedmidtex)
{
if(offset < -midtex.Height)
offset += midtex.Height;
else if(offset > j.sidedef.GetMiddleHeight())
offset -= midtex.Height;
}
else
{
if(offset < -(j.sidedef.GetMiddleHeight() + midtex.Height))
offset += midtex.Height;
else if(offset > midtex.Height)
offset -= midtex.Height;
//mxd. This should be doublesided non-wrapped line. Find the nearset aligned position
float curoffset = UniFields.GetFloat(j.sidedef.Fields, "offsety_mid") + j.sidedef.OffsetY;
offset += tex.Height * (float)Math.Round(curoffset / tex.Height - 0.5f * Math.Sign(j.scaleY));
// Make sure the surface stays between floor and ceiling
if(j.sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag) || Math.Sign(j.scaleY) == -1)
{
if(offset < -tex.Height)
offset += tex.Height;
else if(offset > j.sidedef.GetMiddleHeight())
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
}
}
}
@ -4092,9 +4120,19 @@ namespace CodeImp.DoomBuilder.BuilderModes
offset -= j.sidedef.OffsetX;
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)
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(j.sidedef.Index != j.controlSide.Index) //mxd
@ -4103,7 +4141,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
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));
}
}
@ -4113,9 +4154,19 @@ namespace CodeImp.DoomBuilder.BuilderModes
offset -= j.sidedef.OffsetY; //mxd
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)
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)
{
//mxd. Side is part of a 3D floor?
@ -4123,43 +4174,51 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
offset -= j.controlSide.OffsetY;
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
{
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);
bool startisnonwrappedmidtex = (start.Sidedef.Other != null && start.GeometryType == VisualGeometryType.WALL_MIDDLE && !start.Sidedef.IsFlagSet("wrapmidtex") && !start.Sidedef.Line.IsFlagSet("wrapmidtex"));
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)
if(tex != null && tex.IsImageLoaded)
{
//mxd. This should be doublesided non-wrapped line. Find the nearset aligned position
float curoffset = UniFields.GetFloat(j.sidedef.Fields, "offsety_mid") + j.sidedef.OffsetY;
offset += midtex.Height * (float)Math.Round(curoffset / midtex.Height - 0.5f * Math.Sign(j.scaleY));
bool startisnonwrappedmidtex = (start.Sidedef.Other != null && start.GeometryType == VisualGeometryType.WALL_MIDDLE && !start.Sidedef.IsFlagSet("wrapmidtex") && !start.Sidedef.Line.IsFlagSet("wrapmidtex"));
bool cursideisnonwrappedmidtex = (j.sidedef.Other != null && !j.sidedef.IsFlagSet("wrapmidtex") && !j.sidedef.Line.IsFlagSet("wrapmidtex"));
// Make sure the surface stays between floor and ceiling
if(j.sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag) || Math.Sign(j.scaleY) == -1)
//mxd. Only clamp when the texture is wrapped
if(!cursideisnonwrappedmidtex) offset %= tex.Height;
if(!startisnonwrappedmidtex && cursideisnonwrappedmidtex)
{
if(offset < -midtex.Height)
offset += midtex.Height;
else if(offset > j.sidedef.GetMiddleHeight())
offset -= midtex.Height;
}
else
{
if(offset < -(j.sidedef.GetMiddleHeight() + midtex.Height))
offset += midtex.Height;
else if(offset > midtex.Height)
offset -= midtex.Height;
//mxd. This should be doublesided non-wrapped line. Find the nearset aligned position
float curoffset = UniFields.GetFloat(j.sidedef.Fields, "offsety_mid") + j.sidedef.OffsetY;
offset += tex.Height * (float)Math.Round(curoffset / tex.Height - 0.5f * Math.Sign(j.scaleY));
// Make sure the surface stays between floor and ceiling
if(j.sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag) || Math.Sign(j.scaleY) == -1)
{
if(offset < -tex.Height)
offset += tex.Height;
else if(offset > j.sidedef.GetMiddleHeight())
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

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

View file

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

View file

@ -249,8 +249,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
float oldy = Sidedef.Fields.GetValue("offsety_bottom", 0.0f);
float scalex = Sidedef.Fields.GetValue("scalex_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
Sidedef.Fields["offsety_bottom"] = new UniValue(UniversalType.Float, GetRoundedTextureOffset(oldy, xy.Y, scaley, Texture != null ? Texture.Height : -1)); //mxd
bool textureloaded = (Texture != null && Texture.IsImageLoaded); //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()

View file

@ -434,7 +434,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
//mxd. Only control sidedef scale is used by GZDoom
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))
undoticket = mode.CreateUndo("Change wall scale");

View file

@ -348,10 +348,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
float oldy = Sidedef.Fields.GetValue("offsety_mid", 0.0f);
float scalex = Sidedef.Fields.GetValue("scalex_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
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));
}

View file

@ -251,8 +251,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
float oldy = Sidedef.Fields.GetValue("offsety_top", 0.0f);
float scalex = Sidedef.Fields.GetValue("scalex_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
Sidedef.Fields["offsety_top"] = new UniValue(UniversalType.Float, GetRoundedTextureOffset(oldy, xy.Y, scaley, Texture != null ? Texture.Height : -1)); //mxd
bool textureloaded = (Texture != null && Texture.IsImageLoaded); //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()