mirror of
https://git.do.srb2.org/STJr/ZoneBuilder.git
synced 2024-11-10 06:41:49 +00:00
* A direct tag-to-tag relationship can now be established between two things, which allows event lines to be properly setup between them. This is intended for interpolation and patrol specials which are linked via a shared tag, instead of an argument. A POSITIVE value represents the parent thing, where a NEGATIVE value represents the child thing.
* Added interpolation and patrol point specials to the persistent event line processing
This commit is contained in:
parent
21e2d93784
commit
f8e048b1c1
5 changed files with 121 additions and 11 deletions
|
@ -85,6 +85,7 @@ namespace CodeImp.DoomBuilder.Config
|
|||
private string angletext;
|
||||
private string flagsvaluetext;
|
||||
private string parametertext;
|
||||
private int thinglink;
|
||||
|
||||
//mxd. GLOOME rendering settings
|
||||
private Thing.SpriteRenderMode rendermode;
|
||||
|
@ -137,7 +138,8 @@ namespace CodeImp.DoomBuilder.Config
|
|||
public string AngleText { get { return angletext; } }
|
||||
public string FlagsValueText { get { return flagsvaluetext; } }
|
||||
public string ParameterText { get { return parametertext; } }
|
||||
#endregion
|
||||
public int ThingLink { get { return thinglink; } }
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor / Disposer
|
||||
|
||||
|
@ -180,9 +182,10 @@ namespace CodeImp.DoomBuilder.Config
|
|||
this.angletext = "Angle";
|
||||
this.flagsvaluetext = "Flags value";
|
||||
this.parametertext = "Parameter";
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
this.thinglink = 0;
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
// Constructor
|
||||
|
@ -227,6 +230,7 @@ namespace CodeImp.DoomBuilder.Config
|
|||
this.angletext = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".angletext", cat.AngleText);
|
||||
this.flagsvaluetext = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".flagsvaluetext", cat.FlagsValueText);
|
||||
this.parametertext = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".parametertext", cat.ParameterText);
|
||||
this.thinglink = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".thinglink", 0);
|
||||
|
||||
// Read the args
|
||||
for (int i = 0; i < Linedef.NUM_ARGS; i++)
|
||||
|
|
|
@ -12,7 +12,9 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
|
|||
private class SpecialThings
|
||||
{
|
||||
public readonly Dictionary<int, List<Thing>> PatrolPoints; // PatrolPoint tag, list of PatrolPoints
|
||||
public readonly List<Thing> PatrolSpecials;
|
||||
public readonly Dictionary<int, List<PathNode>> InterpolationPoints; // InterpolationPoint tag, list of InterpolationPoints
|
||||
public readonly List<Thing> InterpolationSpecials;
|
||||
public readonly List<Thing> ThingsWithGoal;
|
||||
public readonly List<Thing> Cameras;
|
||||
public readonly Dictionary<int, List<Thing>> ActorMovers; // ActorMover target tag, list of ActorMovers
|
||||
|
@ -23,7 +25,9 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
|
|||
public SpecialThings()
|
||||
{
|
||||
PatrolPoints = new Dictionary<int, List<Thing>>();
|
||||
PatrolSpecials = new List<Thing>();
|
||||
InterpolationPoints = new Dictionary<int, List<PathNode>>();
|
||||
InterpolationSpecials = new List<Thing>();
|
||||
ThingsWithGoal = new List<Thing>();
|
||||
Cameras = new List<Thing>();
|
||||
ActorMovers = new Dictionary<int, List<Thing>>();
|
||||
|
@ -97,6 +101,10 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
|
|||
}
|
||||
break;
|
||||
|
||||
case "patrolspecial":
|
||||
result.PatrolSpecials.Add(t);
|
||||
break;
|
||||
|
||||
case "$polyanchor":
|
||||
if(!result.PolyobjectAnchors.ContainsKey(t.AngleDoom)) result.PolyobjectAnchors[t.AngleDoom] = new List<Thing>();
|
||||
result.PolyobjectAnchors[t.AngleDoom].Add(t);
|
||||
|
@ -133,6 +141,10 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
|
|||
result.InterpolationPoints[t.Tag].Add(new PathNode(t, blockmap, bsp, useblockmap));
|
||||
break;
|
||||
|
||||
case "interpolationspecial":
|
||||
result.InterpolationSpecials.Add(t);
|
||||
break;
|
||||
|
||||
case "movingcamera":
|
||||
if(t.Args[0] != 0 || t.Args[1] != 0) result.Cameras.Add(t);
|
||||
break;
|
||||
|
@ -208,6 +220,23 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
|
|||
}
|
||||
}
|
||||
|
||||
// Process patrol specials
|
||||
foreach (Thing t in result.PatrolSpecials)
|
||||
{
|
||||
if (!result.PatrolPoints.ContainsKey(t.Tag)) continue;
|
||||
|
||||
start = t.Position;
|
||||
start.z += GetCorrectHeight(t, blockmap, true);
|
||||
|
||||
foreach (Thing tt in result.PatrolPoints[t.Tag])
|
||||
{
|
||||
end = tt.Position;
|
||||
end.z += GetCorrectHeight(tt, blockmap, true);
|
||||
|
||||
lines.Add(new Line3D(start, end, General.Colors.Selection));
|
||||
}
|
||||
}
|
||||
|
||||
// Process cameras [CAN USE INTERPOLATION]
|
||||
foreach(Thing t in result.Cameras)
|
||||
{
|
||||
|
@ -321,6 +350,24 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
|
|||
foreach(PathNode node in group.Value) node.PropagateCurvedFlag();
|
||||
}
|
||||
|
||||
// Process interpolation specials
|
||||
foreach (Thing t in result.InterpolationSpecials)
|
||||
{
|
||||
int targettag = t.Tag;
|
||||
if (targettag == 0 || !result.InterpolationPoints.ContainsKey(targettag)) continue; //no target / target doesn't exist
|
||||
|
||||
start = t.Position;
|
||||
start.z += GetCorrectHeight(t, blockmap, true);
|
||||
|
||||
foreach (PathNode node in result.InterpolationPoints[targettag])
|
||||
{
|
||||
//Do not connect specials to the first or last node of a curved path, since those are used as spline control points only
|
||||
if (node.IsCurved && (node.PreviousNodes.Count == 0 || node.NextNodes.Count == 0))
|
||||
continue;
|
||||
lines.Add(new Line3D(start, node.Position, General.Colors.Selection));
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Make lines
|
||||
HashSet<int> processedindices = new HashSet<int>();
|
||||
foreach(KeyValuePair<int, List<PathNode>> group in result.InterpolationPoints)
|
||||
|
|
|
@ -57,6 +57,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
// Highlighted item
|
||||
private Thing highlighted;
|
||||
private readonly Association[] association = new Association[Thing.NUM_ARGS];
|
||||
private readonly Association directasso = new Association();
|
||||
private readonly Association highlightasso = new Association();
|
||||
|
||||
// Interface
|
||||
|
@ -90,6 +91,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
{
|
||||
//mxd. Associations now requre initializing...
|
||||
for(int i = 0; i < association.Length; i++) association[i] = new Association();
|
||||
directasso = new Association();
|
||||
}
|
||||
|
||||
//mxd
|
||||
|
@ -253,6 +255,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
renderer.RenderThingSet(General.Map.ThingsFilter.VisibleThings, alpha);
|
||||
renderer.RenderNiGHTSPath();
|
||||
for (int i = 0; i < Thing.NUM_ARGS; i++) BuilderPlug.RenderAssociations(renderer, association[i], eventlines);
|
||||
BuilderPlug.RenderAssociations(renderer, directasso, eventlines);
|
||||
|
||||
if((highlighted != null) && !highlighted.IsDisposed)
|
||||
{
|
||||
|
@ -353,8 +356,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
//mxd. Update label color?
|
||||
if(labels.ContainsKey(t)) labels[t].Color = General.Colors.Selection;
|
||||
|
||||
//check if this thing directly links to another type of thing
|
||||
ThingTypeInfo ti = General.Map.Data.GetThingInfoEx(t.Type);
|
||||
int linktype = 0;
|
||||
if (ti != null)
|
||||
linktype = ti.ThingLink;
|
||||
|
||||
// New association highlights something?
|
||||
if(t.Tag != 0) highlightasso.Set(t.Position, t.Tag, UniversalType.ThingTag);
|
||||
if(t.Tag != 0) highlightasso.Set(t.Position, t.Tag, UniversalType.ThingTag, linktype);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -382,6 +391,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
LinedefActionInfo action = General.Map.Config.LinedefActions[t.Action];
|
||||
for(int i = 0; i < Thing.NUM_ARGS; i++)
|
||||
association[i].Set(t.Position, t.Args[i], action.Args[i].Type);
|
||||
|
||||
//Some things, such as Patrol and Interpolation specials, are associated via a shared tag rather than an argument
|
||||
ThingTypeInfo ti = General.Map.Data.GetThingInfoEx(t.Type);
|
||||
if (ti != null && ti.ThingLink < 0)
|
||||
directasso.Set(t.Position, t.Tag, (int)UniversalType.ThingTag);
|
||||
}
|
||||
//mxd. Check if we can use thing arguments
|
||||
else if(t.Action == 0)
|
||||
|
@ -398,7 +412,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
|
||||
// mxd. Clear associations?
|
||||
if(clearassociations)
|
||||
for(int i = 0; i < Thing.NUM_ARGS; i++) association[i].Set(new Vector2D(), 0, 0);
|
||||
{
|
||||
for (int i = 0; i < Thing.NUM_ARGS; i++)
|
||||
association[i].Set(new Vector2D(), 0, 0);
|
||||
directasso.Set(new Vector2D(), 0, 0);
|
||||
}
|
||||
|
||||
// Set new highlight and redraw display
|
||||
highlighted = t;
|
||||
|
|
|
@ -29,10 +29,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
private HashSet<int> tags;
|
||||
private Vector2D center;
|
||||
private UniversalType type;
|
||||
private int directlinktype;
|
||||
|
||||
public HashSet<int> Tags { get { return tags; } }
|
||||
public Vector2D Center { get { return center; } }
|
||||
public UniversalType Type { get { return type; } }
|
||||
public int DirectLinkType { get { return directlinktype; } }
|
||||
|
||||
//mxd. This sets up the association
|
||||
public Association()
|
||||
|
@ -74,34 +76,51 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
|
||||
// This sets up the association
|
||||
public void Set(Vector2D center, int tag, int type)
|
||||
{
|
||||
this.Set(center, tag, type, 0);
|
||||
}
|
||||
|
||||
public void Set(Vector2D center, int tag, int type, int directlinktype)
|
||||
{
|
||||
this.tags = new HashSet<int> { tag }; //mxd
|
||||
this.type = (UniversalType)type;
|
||||
this.center = center;
|
||||
this.directlinktype = directlinktype;
|
||||
}
|
||||
|
||||
// This sets up the association
|
||||
public void Set(Vector2D center, int tag, UniversalType type)
|
||||
{
|
||||
this.Set(center, tag, type, 0);
|
||||
}
|
||||
|
||||
public void Set(Vector2D center, int tag, UniversalType type, int directlinktype)
|
||||
{
|
||||
this.tags = new HashSet<int> { tag }; //mxd
|
||||
this.type = type;
|
||||
this.center = center;
|
||||
this.directlinktype = directlinktype;
|
||||
}
|
||||
|
||||
//mxd. This also sets up the association
|
||||
public void Set(Vector2D center, IEnumerable<int> tags, int type)
|
||||
{
|
||||
this.tags = new HashSet<int>(tags); //mxd
|
||||
this.type = (UniversalType)type;
|
||||
this.center = center;
|
||||
this.Set(center, tags, (UniversalType)type, 0);
|
||||
}
|
||||
|
||||
//mxd. This also sets up the association
|
||||
public void Set(Vector2D center, IEnumerable<int> tags, UniversalType type)
|
||||
{
|
||||
this.Set(center, tags, type, 0);
|
||||
}
|
||||
|
||||
//mxd. This also sets up the association
|
||||
public void Set(Vector2D center, IEnumerable<int> tags, UniversalType type, int directlinktype)
|
||||
{
|
||||
this.tags = new HashSet<int>(tags); //mxd
|
||||
this.type = type;
|
||||
this.center = center;
|
||||
this.directlinktype = directlinktype;
|
||||
}
|
||||
|
||||
// This compares an association
|
||||
|
|
|
@ -746,6 +746,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
foreach(Thing t in General.Map.Map.Things)
|
||||
{
|
||||
if(!asso.Tags.Contains(t.Tag)) continue;
|
||||
|
||||
//Do not draw the association if the user is hovering over a child link
|
||||
ThingTypeInfo ti = General.Map.Data.GetThingInfoEx(t.Type);
|
||||
if (ti != null && ti.ThingLink < 0)
|
||||
continue;
|
||||
|
||||
renderer.RenderThing(t, General.Colors.Indication, General.Settings.ActiveThingsAlpha);
|
||||
if(General.Settings.GZShowEventLines) eventlines.Add(new Line3D(asso.Center, t.Position)); //mxd
|
||||
}
|
||||
|
@ -813,9 +819,17 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
// Things
|
||||
foreach(Thing t in General.Map.Map.Things)
|
||||
{
|
||||
// Get the thing type info
|
||||
ThingTypeInfo ti = General.Map.Data.GetThingInfoEx(t.Type);
|
||||
|
||||
// Known action on this thing?
|
||||
if((t.Action > 0) && General.Map.Config.LinedefActions.ContainsKey(t.Action))
|
||||
{
|
||||
//Do not draw the association if this is a child link.
|
||||
// This prevents a reverse link to a thing via an argument, when it should be a direct tag-to-tag link instead.
|
||||
if(ti != null && asso.DirectLinkType < 0 && asso.DirectLinkType != -t.Type)
|
||||
continue;
|
||||
|
||||
LinedefActionInfo action = General.Map.Config.LinedefActions[t.Action];
|
||||
if( ((action.Args[0].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[0]))) ||
|
||||
((action.Args[1].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[1]))) ||
|
||||
|
@ -826,12 +840,20 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
renderer.RenderThing(t, General.Colors.Indication, General.Settings.ActiveThingsAlpha);
|
||||
if(General.Settings.GZShowEventLines) eventlines.Add(new Line3D(t.Position, asso.Center)); //mxd
|
||||
}
|
||||
|
||||
//If there is a link setup on this thing, and it matches the association, then draw a direct link to any matching tag
|
||||
if(ti != null && asso.DirectLinkType == t.Type && asso.Tags.Contains(t.Tag))
|
||||
{
|
||||
renderer.RenderThing(t, General.Colors.Indication, General.Settings.ActiveThingsAlpha);
|
||||
if (General.Settings.GZShowEventLines) eventlines.Add(new Line3D(t.Position, asso.Center));
|
||||
}
|
||||
}
|
||||
//mxd. Thing action on this thing?
|
||||
else if(t.Action == 0)
|
||||
{
|
||||
ThingTypeInfo ti = General.Map.Data.GetThingInfoEx(t.Type);
|
||||
if(ti != null)
|
||||
//Draw the association, unless it is a child link.
|
||||
// This prevents a reverse link to a thing via an argument, when it should be a direct tag-to-tag link instead.
|
||||
if(ti != null && asso.DirectLinkType >= 0 && Math.Abs(asso.DirectLinkType) != t.Type)
|
||||
{
|
||||
if( ((ti.Args[0].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[0]))) ||
|
||||
((ti.Args[1].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[1]))) ||
|
||||
|
|
Loading…
Reference in a new issue