Handle the Object Flip flag in Visual Mode.

This commit is contained in:
MascaraSnake 2016-01-03 13:07:14 +01:00
parent 5e5da324d5
commit 0489386e7a
8 changed files with 69 additions and 40 deletions

View file

@ -91,8 +91,8 @@ namespace CodeImp.DoomBuilder.Controls
}
else
{
// Hangs from ceiling?
if(ti.Hangs)
// Hangs from ceiling? (MascaraSnake: Or flipped?)
if(t.IsFlipped)
zinfo = t.Position.z + " (" + ((float)Math.Round(Sector.GetCeilingPlane(t.Sector).GetZ(t.Position) - t.Position.z - ti.Height, General.Map.FormatInterface.VertexDecimals)).ToString(CultureInfo.InvariantCulture) + ")"; //mxd
else
zinfo = t.Position.z + " (" + ((float)Math.Round(Sector.GetFloorPlane(t.Sector).GetZ(t.Position) + t.Position.z, General.Map.FormatInterface.VertexDecimals)).ToString(CultureInfo.InvariantCulture) + ")"; //mxd

View file

@ -1363,6 +1363,12 @@ namespace CodeImp.DoomBuilder.Data
else
{
Stream spritedata = null;
bool flip = false;
if (name.EndsWith("_flipped"))
{
name = name.Substring(0, name.Length - 8);
flip = true;
}
// Go for all opened containers
for(int i = containers.Count - 1; i >= 0; i--)
@ -1370,13 +1376,13 @@ namespace CodeImp.DoomBuilder.Data
// This container provides this sprite?
spritedata = containers[i].GetSpriteData(name);
if(spritedata != null) break;
}
}
// Found anything?
if(spritedata != null)
{
// Make new sprite image
SpriteImage image = new SpriteImage(name);
SpriteImage image = new SpriteImage(name, flip);
// Add to collection
sprites.Add(longname, image);

View file

@ -32,6 +32,7 @@ namespace CodeImp.DoomBuilder.Data
protected int offsetx;
protected int offsety;
protected bool flipped;
#endregion
@ -45,8 +46,9 @@ namespace CodeImp.DoomBuilder.Data
#region ================== Constructor / Disposer
// Constructor
internal SpriteImage(string name)
internal SpriteImage(string name, bool flip = false)
{
flipped = flip;
// Initialize
SetName(name);
@ -121,7 +123,8 @@ namespace CodeImp.DoomBuilder.Data
offsetx = (int)((width * scale.x) * 0.5f);
offsety = (int)(height * scale.y);
}
}
if (flipped) bitmap.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);
}
else
{
loadfailed = true;

View file

@ -2047,7 +2047,7 @@ namespace CodeImp.DoomBuilder.Geometry
ThingTypeInfo ti = General.Map.Data.GetThingInfo(t.Type);
int absz = GetThingAbsoluteZ(t, ti);
int height = ti.Height == 0 ? 1 : (int)ti.Height;
Rectangle thing = new Rectangle(0, ti.Hangs ? absz - height : absz, 1, height);
Rectangle thing = new Rectangle(0, t.IsFlipped ? absz - height : absz, 1, height);
if(front.FloorHeight < back.FloorHeight)
{
@ -2098,7 +2098,7 @@ namespace CodeImp.DoomBuilder.Geometry
ThingTypeInfo ti = General.Map.Data.GetThingInfo(t.Type);
if(ti.AbsoluteZ) return;
if(ti.Hangs && initialSector.CeilHeight != t.Sector.CeilHeight)
if(t.IsFlipped && initialSector.CeilHeight != t.Sector.CeilHeight)
{
t.Move(t.Position.x, t.Position.y, t.Position.z - (initialSector.CeilHeight - t.Sector.CeilHeight));
return;
@ -2117,7 +2117,7 @@ namespace CodeImp.DoomBuilder.Geometry
if(t.Sector != null)
{
// Hangs from ceiling?
if(ti.Hangs) return (int)(t.Sector.CeilHeight - t.Position.z - ti.Height);
if(t.IsFlipped) return (int)(t.Sector.CeilHeight - t.Position.z - ti.Height);
return (int)(t.Sector.FloorHeight + t.Position.z);
}

View file

@ -120,6 +120,15 @@ namespace CodeImp.DoomBuilder.Map
public bool IsDirectional { get { return directional; } } //mxd
public bool Highlighted { get { return highlighted; } set { highlighted = value; } } //mxd
public bool IsSlopeVertex { get { return General.Map.FormatInterface.SlopeVertexType == this.Type; } }
public bool IsFlipped
{
get
{
ThingTypeInfo ti = General.Map.Data.GetThingInfo(Type);
return (ti.Hangs && !IsReverse) || (!ti.Hangs && IsReverse);
}
}
public bool IsReverse { get { return General.Map.SRB2 && IsFlagSet("2"); } }
#endregion

View file

@ -310,7 +310,7 @@ namespace CodeImp.DoomBuilder.VisualModes
if(!float.IsNaN(floorz) && !float.IsNaN(ceilz))
{
float voffset;
if(info.Hangs)
if(thing.IsFlipped)
{
float thingz = ceilz - Thing.Position.z + Thing.Height;
voffset = 0.01f - floorz - General.Clamp(thingz, 0, ceilz - floorz);
@ -353,7 +353,7 @@ namespace CodeImp.DoomBuilder.VisualModes
if(!float.IsNaN(floorz) && !float.IsNaN(ceilz))
{
float voffset;
if(info.Hangs)
if(thing.IsFlipped)
{
float thingz = ceilz - Math.Max(0, Thing.Position.z) - Thing.Height;
voffset = -0.01f - General.Clamp(thingz, 0, ceilz - floorz);

View file

@ -372,7 +372,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
Vector3D pos = thing.Thing.Position;
float thingheight = thing.Thing.Height;
bool absolute = thing.Info.AbsoluteZ;
bool hangs = thing.Info.Hangs;
bool hangs = thing.Thing.IsFlipped;
if(absolute && hangs)
{
@ -468,7 +468,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
Vector3D pos = thing.Thing.Position;
float thingheight = thing.Thing.Height;
bool absolute = thing.Info.AbsoluteZ;
bool hangs = thing.Info.Hangs;
bool hangs = thing.Thing.IsFlipped;
if(absolute && hangs)
{
@ -593,7 +593,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
ThingTypeInfo info = General.Map.Data.GetThingInfoEx(t.Type);
if(info != null)
{
if(info.AbsoluteZ && info.Hangs) return t.Position.z; // Not sure what to do here...
if(info.AbsoluteZ && t.IsFlipped) return t.Position.z; // Not sure what to do here...
if(info.AbsoluteZ)
{
// Transform to floor-aligned position
@ -601,7 +601,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
return t.Position.z - nsd.Floor.plane.GetZ(t.Position) + t.Height;
}
if(info.Hangs)
if(t.IsFlipped)
{
// Transform to floor-aligned position. Align top of target thing to the bottom of the hanging thing
SectorData nsd = mode.GetSectorData(t.Sector);

View file

@ -43,12 +43,13 @@ namespace CodeImp.DoomBuilder.BuilderModes
private bool isloaded;
private bool nointeraction; //mxd
private ImageData sprite;
private ImageData flippedsprite;
private float cageradius2;
private Vector2D pos2d;
private Vector3D boxp1;
private Vector3D boxp2;
private static List<BaseVisualThing> updateList; //mxd
// Undo/redo
private int undoticket;
@ -60,6 +61,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Properties
public bool Changed { get { return changed; } set { changed |= value; } }
private ImageData Sprite { get { return Thing.IsReverse ? flippedsprite : sprite; } set { if (Thing.IsReverse) flippedsprite = value; else sprite = value; } }
#endregion
@ -81,7 +83,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
sprite = General.Map.Data.GetSpriteImage(info.Sprite);
if(sprite != null) sprite.AddReference();
}
flippedsprite = General.Map.Data.GetSpriteImage(info.Sprite + "_flipped");
if (flippedsprite != null) flippedsprite.AddReference();
}
//mxd
if(mode.UseSelectionFromClassicMode && t.Selected)
@ -191,7 +195,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
sizeless = false;
}
if(sprite != null)
if(Sprite != null)
{
Plane floor = new Plane(); //mxd
Plane ceiling = new Plane(); //mxd
@ -313,22 +317,22 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
// Check if the texture is loaded
sprite.LoadImage();
isloaded = sprite.IsImageLoaded;
Sprite.LoadImage();
isloaded = Sprite.IsImageLoaded;
if(isloaded)
{
float offsetx = 0.0f;
float offsety = 0.0f;
base.Texture = sprite;
base.Texture = Sprite;
// Determine sprite size and offset
float radius = sprite.ScaledWidth * 0.5f;
float height = sprite.ScaledHeight;
if(sprite is SpriteImage)
float radius = Sprite.ScaledWidth * 0.5f;
float height = Sprite.ScaledHeight;
if(Sprite is SpriteImage)
{
offsetx = radius - (sprite as SpriteImage).OffsetX;
offsety = (sprite as SpriteImage).OffsetY - height;
offsetx = radius - (Sprite as SpriteImage).OffsetX;
offsety = (Sprite as SpriteImage).OffsetY - height;
}
// Scale by thing type/actor scale
@ -417,7 +421,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Absolute Z position
pos.z = Thing.Position.z;
}
else if(info.Hangs)
else if(Thing.IsFlipped)
{
// Hang from ceiling
if(Thing.Sector != null)
@ -491,8 +495,13 @@ namespace CodeImp.DoomBuilder.BuilderModes
sprite.RemoveReference();
sprite = null;
}
if (flippedsprite != null)
{
flippedsprite.RemoveReference();
flippedsprite = null;
}
base.Dispose();
base.Dispose();
}
}
@ -514,10 +523,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
sprite = General.Map.Data.GetSpriteImage(info.Sprite);
if(sprite != null) sprite.AddReference();
}
// Setup visual thing
Setup();
flippedsprite = General.Map.Data.GetSpriteImage(info.Sprite + "_flipped");
if (flippedsprite != null) flippedsprite.AddReference();
}
// Setup visual thing
Setup();
}
// This updates the thing when needed
@ -526,7 +537,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(!isloaded)
{
// Rebuild sprite geometry when sprite is loaded
if(sprite.IsImageLoaded)
if(Sprite.IsImageLoaded)
{
Setup();
}
@ -782,7 +793,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
if((General.Map.UndoRedo.NextUndo == null) || (General.Map.UndoRedo.NextUndo.TicketID != undoticket))
undoticket = mode.CreateUndo("Change thing height");
Vector3D newPosition = Thing.Position + new Vector3D(0.0f, 0.0f, (info.Hangs ? -amount : amount));
Vector3D newPosition = Thing.Position + new Vector3D(0.0f, 0.0f, (Thing.IsFlipped ? -amount : amount));
newPosition.z = General.Clamp(newPosition.z, General.Map.FormatInterface.MinThingHeight, General.Map.FormatInterface.MaxThingHeight);
Thing.Move(newPosition);
@ -807,7 +818,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
//mxd
public void OnChangeScale(int incrementX, int incrementY)
{
if(!General.Map.UDMF || !sprite.IsImageLoaded) return;
if(!General.Map.UDMF || !Sprite.IsImageLoaded) return;
if((General.Map.UndoRedo.NextUndo == null) || (General.Map.UndoRedo.NextUndo.TicketID != undoticket))
undoticket = mode.CreateUndo("Change thing scale");
@ -817,20 +828,20 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(incrementX != 0)
{
float pix = (int)Math.Round(sprite.Width * scaleX) + incrementX;
float newscaleX = (float)Math.Round(pix / sprite.Width, 3);
float pix = (int)Math.Round(Sprite.Width * scaleX) + incrementX;
float newscaleX = (float)Math.Round(pix / Sprite.Width, 3);
scaleX = (newscaleX == 0 ? scaleX * -1 : newscaleX);
}
if(incrementY != 0)
{
float pix = (int)Math.Round(sprite.Height * scaleY) + incrementY;
float newscaleY = (float)Math.Round(pix / sprite.Height, 3);
float pix = (int)Math.Round(Sprite.Height * scaleY) + incrementY;
float newscaleY = (float)Math.Round(pix / Sprite.Height, 3);
scaleY = (newscaleY == 0 ? scaleY * -1 : newscaleY);
}
Thing.SetScale(scaleX, scaleY);
mode.SetActionResult("Changed thing scale to " + scaleX.ToString("F03", CultureInfo.InvariantCulture) + ", " + scaleY.ToString("F03", CultureInfo.InvariantCulture) + " (" + (int)Math.Round(sprite.Width * scaleX) + " x " + (int)Math.Round(sprite.Height * scaleY) + ").");
mode.SetActionResult("Changed thing scale to " + scaleX.ToString("F03", CultureInfo.InvariantCulture) + ", " + scaleY.ToString("F03", CultureInfo.InvariantCulture) + " (" + (int)Math.Round(Sprite.Width * scaleX) + " x " + (int)Math.Round(Sprite.Height * scaleY) + ").");
// Update what must be updated
this.Changed = true;