added gravity, upper/lower unpegged toggle, and texture auto-alignment (both X and Y) in visual mode. also some small changes.

This commit is contained in:
codeimp 2008-12-31 00:44:04 +00:00
parent 79676b312e
commit 28bb966a12
17 changed files with 414 additions and 24 deletions

View file

@ -59,6 +59,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Settings
private int showvisualthings; // 0 = none, 1 = sprite only, 2 = sprite caged
private bool usegravity;
#endregion
@ -72,6 +73,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
public FindReplaceForm FindReplaceForm { get { return findreplaceform; } }
public ErrorCheckForm ErrorCheckForm { get { return errorcheckform; } }
public int ShowVisualThings { get { return showvisualthings; } set { showvisualthings = value; } }
public bool UseGravity { get { return usegravity; } set { usegravity = value; } }
#endregion
@ -85,6 +87,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Settings
this.showvisualthings = 2;
this.usegravity = false;
// Load menus form and register it
menusform = new MenusForm();

View file

@ -416,3 +416,63 @@ texturepaste
allowmouse = true;
allowscroll = true;
}
visualautoalignx
{
title = "Auto-align Textures X";
category = "visual";
description = "Automatically aligns the neighbouring textures X offsets until another texture is encountered.";
allowkeys = true;
allowmouse = true;
allowscroll = true;
}
visualautoaligny
{
title = "Auto-align Textures Y";
category = "visual";
description = "Automatically aligns the neighbouring textures Y offsets until another texture is encountered. The Y alignment only takes the ceiling height for each sidedef into account.";
allowkeys = true;
allowmouse = true;
allowscroll = true;
}
toggleupperunpegged
{
title = "Toggle Upper Unpegged";
category = "visual";
description = "Toggles the Upper Unpegged setting on the selected or targeted linedef.";
allowkeys = true;
allowmouse = true;
allowscroll = true;
}
togglelowerunpegged
{
title = "Toggle Lower Unpegged";
category = "visual";
description = "Toggles the Lower Unpegged setting on the selected or targeted linedef.";
allowkeys = true;
allowmouse = true;
allowscroll = true;
}
togglemiddletexture
{
title = "Toggle Middle Texture";
category = "visual";
description = "Toggles the middle texture on the selected or targeted double-sided linedef.";
allowkeys = true;
allowmouse = true;
allowscroll = true;
}
togglegravity
{
title = "Toggle Gravity";
category = "visual";
description = "Toggles the use of gravity while moving around in visual mode. Turn gravity off to fly around, turn gravity on to walk on the sector floors.";
allowkeys = true;
allowmouse = true;
allowscroll = true;
}

View file

@ -79,6 +79,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
public virtual void OnEditBegin() { }
public virtual void OnMouseMove(MouseEventArgs e) { }
public virtual void OnChangeTextureOffset(int horizontal, int vertical) { }
public virtual void OnTextureAlign(bool alignx, bool aligny) { }
public virtual void OnToggleUpperUnpegged() { }
public virtual void OnToggleLowerUnpegged() { }
protected virtual void SetTexture(string texturename) { }
// Select texture

View file

@ -113,6 +113,85 @@ namespace CodeImp.DoomBuilder.BuilderModes
public virtual void OnChangeTargetHeight(int amount) { }
protected virtual void SetTexture(string texturename) { }
// Toggle upper-unpegged
public virtual void OnToggleUpperUnpegged()
{
if(this.Sidedef.Line.Flags.ContainsKey(General.Map.Config.UpperUnpeggedFlag) &&
this.Sidedef.Line.Flags[General.Map.Config.UpperUnpeggedFlag])
{
// Remove flag
General.Map.UndoRedo.CreateUndo("Remove upper-unpegged setting");
this.Sidedef.Line.Flags[General.Map.Config.UpperUnpeggedFlag] = false;
}
else
{
// Add flag
General.Map.UndoRedo.CreateUndo("Set upper-unpegged setting");
this.Sidedef.Line.Flags[General.Map.Config.UpperUnpeggedFlag] = true;
}
// Update sidedef geometry
VisualSidedefParts parts = Sector.GetSidedefParts(Sidedef);
if(parts.lower != null) parts.lower.Setup();
if(parts.middledouble != null) parts.middledouble.Setup();
if(parts.middlesingle != null) parts.middlesingle.Setup();
if(parts.upper != null) parts.upper.Setup();
}
// Toggle lower-unpegged
public virtual void OnToggleLowerUnpegged()
{
if(this.Sidedef.Line.Flags.ContainsKey(General.Map.Config.LowerUnpeggedFlag) &&
this.Sidedef.Line.Flags[General.Map.Config.LowerUnpeggedFlag])
{
// Remove flag
General.Map.UndoRedo.CreateUndo("Remove lower-unpegged setting");
this.Sidedef.Line.Flags[General.Map.Config.LowerUnpeggedFlag] = false;
}
else
{
// Add flag
General.Map.UndoRedo.CreateUndo("Set lower-unpegged setting");
this.Sidedef.Line.Flags[General.Map.Config.LowerUnpeggedFlag] = true;
}
// Update sidedef geometry
VisualSidedefParts parts = Sector.GetSidedefParts(Sidedef);
if(parts.lower != null) parts.lower.Setup();
if(parts.middledouble != null) parts.middledouble.Setup();
if(parts.middlesingle != null) parts.middlesingle.Setup();
if(parts.upper != null) parts.upper.Setup();
}
// Auto-align texture X offsets
public virtual void OnTextureAlign(bool alignx, bool aligny)
{
General.Map.UndoRedo.CreateUndo("Auto-align textures");
// Get the texture long name
string texname = GetTextureName();
long longtexname = General.Map.Data.GetLongImageName(texname);
// Do the alignment
Tools.AutoAlignTextures(this.Sidedef, longtexname, alignx, aligny, true);
// Get the changed sidedefs
List<Sidedef> changes = General.Map.Map.GetMarkedSidedefs(true);
foreach(Sidedef sd in changes)
{
// Update the parts for this sidedef!
if(mode.VisualSectorExists(sd.Sector))
{
BaseVisualSector vs = (mode.GetVisualSector(sd.Sector) as BaseVisualSector);
VisualSidedefParts parts = vs.GetSidedefParts(sd);
if(parts.lower != null) parts.lower.Setup();
if(parts.middledouble != null) parts.middledouble.Setup();
if(parts.middlesingle != null) parts.middlesingle.Setup();
if(parts.upper != null) parts.upper.Setup();
}
}
}
// Select texture
public virtual void OnSelectTexture()
{
@ -128,8 +207,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Paste texture
public virtual void OnPasteTexture()
{
General.Map.UndoRedo.CreateUndo("Paste texture " + mode.CopiedTexture);
SetTexture(mode.CopiedTexture);
if(mode.CopiedTexture != null)
{
General.Map.UndoRedo.CreateUndo("Paste texture " + mode.CopiedTexture);
SetTexture(mode.CopiedTexture);
}
}
// Copy texture

View file

@ -47,9 +47,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
#region ================== Constants
// Object picking interval
// Object picking
private const double PICK_INTERVAL = 100.0d;
private const float PICK_RANGE = 0.98f;
// Gravity
private const float GRAVITY = -0.06f;
private const float CAMERA_FLOOR_OFFSET = 41f; // same as in doom
private const float CAMERA_CEILING_OFFSET = 10f;
#endregion
@ -64,6 +69,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
private string copiedtexture;
private string copiedflat;
// Gravity vector
private Vector3D gravity;
#endregion
#region ================== Properties
@ -79,6 +87,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
public BaseVisualMode()
{
// Initialize
this.gravity = new Vector3D(0.0f, 0.0f, 0.0f);
// We have no destructor
GC.SuppressFinalize(this);
@ -204,6 +213,42 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Process things?
base.ProcessThings = (BuilderPlug.Me.ShowVisualThings != 0);
// Setup the move multiplier depending on gravity
Vector3D movemultiplier = new Vector3D(1.0f, 1.0f, 1.0f);
if(BuilderPlug.Me.UseGravity) movemultiplier.z = 0.0f;
base.MoveMultiplier = movemultiplier;
// Apply gravity?
if(BuilderPlug.Me.UseGravity && (CameraSector != null))
{
// Camera below floor level?
if(base.CameraPosition.z <= (CameraSector.FloorHeight + CAMERA_FLOOR_OFFSET + 0.1f))
{
// Stay above floor
gravity = new Vector3D(0.0f, 0.0f, 0.0f);
base.CameraPosition = new Vector3D(base.CameraPosition.x, base.CameraPosition.y,
CameraSector.FloorHeight + CAMERA_FLOOR_OFFSET);
}
else
{
// Fall down
gravity += new Vector3D(0.0f, 0.0f, (float)(GRAVITY * deltatime));
base.CameraPosition = base.CameraPosition + gravity;
}
// Camera above ceiling level?
if(base.CameraPosition.z >= (CameraSector.CeilHeight - CAMERA_CEILING_OFFSET - 0.1f))
{
// Stay below ceiling
base.CameraPosition = new Vector3D(base.CameraPosition.x, base.CameraPosition.y,
CameraSector.CeilHeight - CAMERA_CEILING_OFFSET);
}
}
else
{
gravity = new Vector3D(0.0f, 0.0f, 0.0f);
}
// Do processing
base.OnProcess(deltatime);
@ -402,6 +447,46 @@ namespace CodeImp.DoomBuilder.BuilderModes
PickTargetUnlocked();
if(target.picked != null) (target.picked as IVisualEventReceiver).OnPasteTexture();
}
[BeginAction("visualautoalignx")]
public void TextureAutoAlignX()
{
PickTargetUnlocked();
renderer.SetCrosshairBusy(true);
General.Interface.RedrawDisplay();
if(target.picked != null) (target.picked as IVisualEventReceiver).OnTextureAlign(true, false);
renderer.SetCrosshairBusy(false);
}
[BeginAction("visualautoaligny")]
public void TextureAutoAlignY()
{
PickTargetUnlocked();
renderer.SetCrosshairBusy(true);
General.Interface.RedrawDisplay();
if(target.picked != null) (target.picked as IVisualEventReceiver).OnTextureAlign(false, true);
renderer.SetCrosshairBusy(false);
}
[BeginAction("toggleupperunpegged")]
public void ToggleUpperUnpegged()
{
PickTargetUnlocked();
if(target.picked != null) (target.picked as IVisualEventReceiver).OnToggleUpperUnpegged();
}
[BeginAction("togglelowerunpegged")]
public void ToggleLowerUnpegged()
{
PickTargetUnlocked();
if(target.picked != null) (target.picked as IVisualEventReceiver).OnToggleLowerUnpegged();
}
[BeginAction("togglegravity")]
public void ToggleGravity()
{
BuilderPlug.Me.UseGravity = !BuilderPlug.Me.UseGravity;
}
#endregion
}

View file

@ -341,7 +341,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
public virtual void OnSelectTexture() { }
public virtual void OnCopyTexture() { }
public virtual void OnPasteTexture() { }
public virtual void OnTextureAlign(bool alignx, bool aligny) { }
public virtual void OnToggleUpperUnpegged() { }
public virtual void OnToggleLowerUnpegged() { }
// Return texture name
public virtual string GetTextureName() { return ""; }

View file

@ -50,7 +50,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
void OnSelectTexture();
void OnCopyTexture();
void OnPasteTexture();
void OnTextureAlign(bool alignx, bool aligny);
void OnToggleUpperUnpegged();
void OnToggleLowerUnpegged();
// Other methods
string GetTextureName();
}

View file

@ -126,9 +126,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Paste texture
public override void OnPasteTexture()
{
General.Map.UndoRedo.CreateUndo("Paste ceiling " + mode.CopiedFlat);
SetTexture(mode.CopiedFlat);
this.Setup();
if(mode.CopiedFlat != null)
{
General.Map.UndoRedo.CreateUndo("Paste ceiling " + mode.CopiedFlat);
SetTexture(mode.CopiedFlat);
this.Setup();
}
}
// This changes the height

View file

@ -113,9 +113,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Paste texture
public override void OnPasteTexture()
{
General.Map.UndoRedo.CreateUndo("Paste floor " + mode.CopiedFlat);
SetTexture(mode.CopiedFlat);
this.Setup();
if(mode.CopiedFlat != null)
{
General.Map.UndoRedo.CreateUndo("Paste floor " + mode.CopiedFlat);
SetTexture(mode.CopiedFlat);
this.Setup();
}
}
// This changes the height

View file

@ -1053,6 +1053,12 @@ namespace CodeImp.DoomBuilder.Data
updatedusedtextures = true;
}
}
// This returns the long name for a string
public long GetLongImageName(string name)
{
return Lump.MakeLongName(name);
}
#endregion
}

View file

@ -573,6 +573,12 @@ namespace CodeImp.DoomBuilder.Editing
#region ================== Actions
[BeginAction("gridsetup", BaseAction = true)]
protected void ShowGridSetup()
{
General.Map.Grid.ShowGridSetup();
}
[BeginAction("pan_view", BaseAction = true)]
protected virtual void BeginViewPan()
{

View file

@ -24,6 +24,7 @@ using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using CodeImp.DoomBuilder.VisualModes;
using CodeImp.DoomBuilder.Windows;
using CodeImp.DoomBuilder.IO;
using CodeImp.DoomBuilder.Map;
@ -214,7 +215,6 @@ namespace CodeImp.DoomBuilder.Editing
#region ================== Actions
// This shows the grid setup dialog
[BeginAction("gridsetup")]
internal void ShowGridSetup()
{
// Show preferences dialog
@ -228,7 +228,7 @@ namespace CodeImp.DoomBuilder.Editing
// Done
gridform.Dispose();
}
// This changes grid size
[BeginAction("gridinc")]
internal void IncreaseGrid()

View file

@ -150,16 +150,18 @@ namespace CodeImp.DoomBuilder.Editing
}
// This makes an undo and returns the unique ticket id
// Also automatically indicates that the map is changed
public int CreateUndo(string description)
{
return CreateUndo(description, UndoGroup.None, 0);
}
// This makes an undo and returns the unique ticket id
// Also automatically indicates that the map is changed
public int CreateUndo(string description, UndoGroup group, int grouptag)
{
UndoSnapshot u;
// Not the same as previous group?
if((group == UndoGroup.None) ||
(group != lastgroup) ||
@ -183,6 +185,9 @@ namespace CodeImp.DoomBuilder.Editing
// Keep grouping info
lastgroup = group;
lastgrouptag = grouptag;
// Map changes!
General.Map.IsChanged = true;
// Update
General.MainWindow.UpdateInterface();

View file

@ -553,11 +553,6 @@ namespace CodeImp.DoomBuilder
General.WriteLogLine("Application path: " + apppath);
General.WriteLogLine("Temporary path: " + temppath);
General.WriteLogLine("Local settings path: " + settingspath);
General.WriteLogLine("Configurations path: " + configspath);
General.WriteLogLine("Compilers path: " + compilerspath);
General.WriteLogLine("Plugins path: " + pluginspath);
General.WriteLogLine("Scripts path: " + scriptspath);
General.WriteLogLine("Sprites path: " + spritespath);
General.WriteLogLine("Command-line arguments: " + args.Length);
for(int i = 0; i < args.Length; i++)
General.WriteLogLine("Argument " + i + ": \"" + args[i] + "\"");

View file

@ -46,6 +46,23 @@ namespace CodeImp.DoomBuilder.Geometry
public string newtexlow;
}
private struct SidedefAlignJob
{
public Sidedef sidedef;
public int offsetx;
// This is an absolute height in world space. Subtract the
// ceiling height to get the correct Y offset.
public int offsety;
// When this is true, the previous sidedef was on the left of
// this one and the texture X offset of this sidedef can be set
// directly. When this is false, the length of this sidedef
// must be subtracted from the X offset first.
public bool forward;
}
#endregion
#region ================== Constants
@ -1176,5 +1193,118 @@ namespace CodeImp.DoomBuilder.Geometry
}
#endregion
#region ================== Texture Alignment
// This performs texture alignment along all walls that match with the same texture
// NOTE: This method uses the sidedefs marking to indicate which sides have been aligned
// When resetsidemarks is set to true, all sidedefs will first be marked false (not aligned).
// Setting resetsidemarks to false is usefull to align only within a specific selection
// (set the marked property to true for the sidedefs outside the selection)
public static void AutoAlignTextures(Sidedef start, long texturelongname, bool alignx, bool aligny, bool resetsidemarks)
{
Stack<SidedefAlignJob> todo = new Stack<SidedefAlignJob>(50);
// Mark all sidedefs false (they will be marked true when the texture is aligned)
if(resetsidemarks) General.Map.Map.ClearMarkedSidedefs(false);
// Begin with first sidedef
SidedefAlignJob first = new SidedefAlignJob();
first.sidedef = start;
first.offsetx = start.OffsetX;
first.offsety = start.OffsetY + start.Sector.CeilHeight;
first.forward = true;
todo.Push(first);
// Continue until nothing more to align
while(todo.Count > 0)
{
// Get the align job to do
SidedefAlignJob j = todo.Pop();
if(j.forward)
{
Vertex v;
// Apply alignment
if(alignx) j.sidedef.OffsetX = j.offsetx;
if(aligny) j.sidedef.OffsetY = j.offsety - j.sidedef.Sector.CeilHeight;
int forwardoffset = j.offsetx + (int)Math.Round(j.sidedef.Line.Length);
int backwardoffset = j.offsetx;
j.sidedef.Marked = true;
// Add sidedefs forward (connected to the right vertex)
v = j.sidedef.IsFront ? j.sidedef.Line.End : j.sidedef.Line.Start;
AddSidedefsForAlignment(todo, v, true, forwardoffset, j.offsety, texturelongname);
// Add sidedefs backward (connected to the left vertex)
v = j.sidedef.IsFront ? j.sidedef.Line.Start : j.sidedef.Line.End;
AddSidedefsForAlignment(todo, v, false, backwardoffset, j.offsety, texturelongname);
}
else
{
Vertex v;
// Apply alignment
if(alignx) j.sidedef.OffsetX = j.offsetx - (int)Math.Round(j.sidedef.Line.Length);
if(aligny) j.sidedef.OffsetY = j.offsety - j.sidedef.Sector.CeilHeight;
int forwardoffset = j.offsetx;
int backwardoffset = j.offsetx - (int)Math.Round(j.sidedef.Line.Length);
j.sidedef.Marked = true;
// Add sidedefs backward (connected to the left vertex)
v = j.sidedef.IsFront ? j.sidedef.Line.Start : j.sidedef.Line.End;
AddSidedefsForAlignment(todo, v, false, backwardoffset, j.offsety, texturelongname);
// Add sidedefs forward (connected to the right vertex)
v = j.sidedef.IsFront ? j.sidedef.Line.End : j.sidedef.Line.Start;
AddSidedefsForAlignment(todo, v, true, forwardoffset, j.offsety, texturelongname);
}
}
}
// This adds the matching, unmarked sidedefs from a vertex for texture alignment
private static void AddSidedefsForAlignment(Stack<SidedefAlignJob> stack, Vertex v, bool forward, int offsetx, int offsety, long texturelongname)
{
foreach(Linedef ld in v.Linedefs)
{
Sidedef side1 = forward ? ld.Front : ld.Back;
Sidedef side2 = forward ? ld.Back : ld.Front;
if((ld.Start == v) && (side1 != null) && !side1.Marked)
{
if(SidedefTextureMatch(side1, texturelongname))
{
SidedefAlignJob nj = new SidedefAlignJob();
nj.forward = forward;
nj.offsetx = offsetx;
nj.offsety = offsety;
nj.sidedef = side1;
stack.Push(nj);
}
}
else if((ld.End == v) && (side2 != null) && !side2.Marked)
{
if(SidedefTextureMatch(side2, texturelongname))
{
SidedefAlignJob nj = new SidedefAlignJob();
nj.forward = forward;
nj.offsetx = offsetx;
nj.offsety = offsety;
nj.sidedef = side2;
stack.Push(nj);
}
}
}
}
// This checks if any of the sidedef texture match the given texture
private static bool SidedefTextureMatch(Sidedef sd, long texturelongname)
{
return (sd.LongHighTexture == texturelongname) ||
(sd.LongLowTexture == texturelongname) ||
(sd.LongMiddleTexture == texturelongname);
}
#endregion
}
}

View file

@ -294,7 +294,7 @@ deleteitem
gridsetup
{
title = "Grid Setup";
category = "edit";
category = "classic";
description = "Shows the Custom Grid Setup dialog which allows you to set custom grid sizes and a background image.";
allowkeys = true;
allowmouse = true;

View file

@ -64,6 +64,7 @@ namespace CodeImp.DoomBuilder.VisualModes
// Camera
private Vector3D campos;
private Vector3D camtarget;
private Vector3D movemultiplier;
private float camanglexy, camanglez;
private Sector camsector;
@ -98,6 +99,7 @@ namespace CodeImp.DoomBuilder.VisualModes
public Sector CameraSector { get { return camsector; } }
public bool ProcessGeometry { get { return processgeometry; } set { processgeometry = value; } }
public bool ProcessThings { get { return processthings; } set { processthings = value; } }
public Vector3D MoveMultiplier { get { return movemultiplier; } set { movemultiplier = value; } }
#endregion
@ -112,6 +114,7 @@ namespace CodeImp.DoomBuilder.VisualModes
this.renderer = General.Map.Renderer3D;
this.renderer3d = (Renderer3D)General.Map.Renderer3D;
this.campos = new Vector3D(0.0f, 0.0f, 96.0f);
this.movemultiplier = new Vector3D(1.0f, 1.0f, 1.0f);
this.camanglez = Angle2D.PI;
this.blockmap = new VisualBlockMap();
this.allsectors = new Dictionary<Sector, VisualSector>(General.Map.Map.Sectors.Count);
@ -742,10 +745,10 @@ namespace CodeImp.DoomBuilder.VisualModes
// Move the camera
if(doublespeed) multiplier = MOVE_SPEED_MULTIPLIER * 2.0f; else multiplier = MOVE_SPEED_MULTIPLIER;
if(keyforward) campos += camvec * (float)((double)General.Settings.MoveSpeed * multiplier * deltatime);
if(keybackward) campos -= camvec * (float)((double)General.Settings.MoveSpeed * multiplier * deltatime);
if(keyleft) campos -= camvecstrafe * (float)((double)General.Settings.MoveSpeed * multiplier * deltatime);
if(keyright) campos += camvecstrafe * (float)((double)General.Settings.MoveSpeed * multiplier * deltatime);
if(keyforward) campos += camvec * movemultiplier * (float)((double)General.Settings.MoveSpeed * multiplier * deltatime);
if(keybackward) campos -= camvec * movemultiplier * (float)((double)General.Settings.MoveSpeed * multiplier * deltatime);
if(keyleft) campos -= camvecstrafe * movemultiplier * (float)((double)General.Settings.MoveSpeed * multiplier * deltatime);
if(keyright) campos += camvecstrafe * movemultiplier * (float)((double)General.Settings.MoveSpeed * multiplier * deltatime);
// Target the camera
camtarget = campos + camvec;