Merge pull request #42 from Xabis/master

Direct tag-to-tag associations
This commit is contained in:
jewalky 2017-02-14 22:37:44 +02:00 committed by GitHub
commit 3540f55a25
6 changed files with 122 additions and 7 deletions

View file

@ -853,6 +853,7 @@ zdoom
title = "Interpolation Point"; title = "Interpolation Point";
sprite = "internal:InterpolationPoint"; sprite = "internal:InterpolationPoint";
class = "InterpolationPoint"; class = "InterpolationPoint";
thinglink = 9075;
arg0 arg0
{ {
title = "Pitch"; title = "Pitch";
@ -885,6 +886,7 @@ zdoom
title = "Interpolation Special"; title = "Interpolation Special";
sprite = "internal:InterpolationSpecial"; sprite = "internal:InterpolationSpecial";
class = "InterpolationSpecial"; class = "InterpolationSpecial";
thinglink = -9070;
} }
9072 9072
@ -952,6 +954,7 @@ zdoom
{ {
title = "Patrol Special"; title = "Patrol Special";
class = "PatrolSpecial"; class = "PatrolSpecial";
thinglink = -9024;
} }
} }
@ -1248,6 +1251,7 @@ zdoom
title = "Patrol Point"; title = "Patrol Point";
sprite = "internal:PathFollower"; sprite = "internal:PathFollower";
class = "PatrolPoint"; class = "PatrolPoint";
thinglink = 9047;
arg0 arg0
{ {
title = "Next Patrol Point Tag"; title = "Next Patrol Point Tag";

View file

@ -87,6 +87,7 @@ namespace CodeImp.DoomBuilder.Config
private bool obsolete; //mxd private bool obsolete; //mxd
private string obsoletemessage; //mxd private string obsoletemessage; //mxd
private Dictionary<string, Dictionary<string, string>> flagsrename; //mxd. <MapSetIOName, <flag, title>> private Dictionary<string, Dictionary<string, string>> flagsrename; //mxd. <MapSetIOName, <flag, title>>
private int thinglink;
//mxd. GZDoom rendering properties //mxd. GZDoom rendering properties
private ThingRenderMode rendermode; private ThingRenderMode rendermode;
@ -137,6 +138,8 @@ namespace CodeImp.DoomBuilder.Config
public bool RollSprite { get { return rollsprite; } } public bool RollSprite { get { return rollsprite; } }
public bool RollCenter { get { return rollcenter; } } public bool RollCenter { get { return rollcenter; } }
public int ThingLink { get { return thinglink; } }
//mxd. Ambinent sound info //mxd. Ambinent sound info
public AmbientSoundInfo AmbientSound { get { return ambientsound; } internal set { ambientsound = value; } } public AmbientSoundInfo AmbientSound { get { return ambientsound; } internal set { ambientsound = value; } }
@ -176,6 +179,7 @@ namespace CodeImp.DoomBuilder.Config
this.xybillboard = false; this.xybillboard = false;
this.locksprite = false; //mxd this.locksprite = false; //mxd
this.flagsrename = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase); //mxd this.flagsrename = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase); //mxd
this.thinglink = 0;
// We have no destructor // We have no destructor
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
@ -215,6 +219,7 @@ namespace CodeImp.DoomBuilder.Config
this.spritescale = new SizeF(sscale, sscale); this.spritescale = new SizeF(sscale, sscale);
this.locksprite = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".locksprite", false); //mxd this.locksprite = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".locksprite", false); //mxd
this.classname = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".class", String.Empty); //mxd this.classname = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".class", String.Empty); //mxd
this.thinglink = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".thinglink", 0);
//mxd. Read flagsrename //mxd. Read flagsrename
this.flagsrename = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase); this.flagsrename = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);

View file

@ -19,7 +19,9 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
private class SpecialThings private class SpecialThings
{ {
public readonly Dictionary<int, List<Thing>> PatrolPoints; // PatrolPoint tag, list of PatrolPoints 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 Dictionary<int, List<PathNode>> InterpolationPoints; // InterpolationPoint tag, list of InterpolationPoints
public readonly List<Thing> InterpolationSpecials;
public readonly List<Thing> ThingsWithGoal; public readonly List<Thing> ThingsWithGoal;
public readonly List<Thing> Cameras; public readonly List<Thing> Cameras;
public readonly Dictionary<int, List<Thing>> ActorMovers; // ActorMover target tag, list of ActorMovers public readonly Dictionary<int, List<Thing>> ActorMovers; // ActorMover target tag, list of ActorMovers
@ -30,7 +32,9 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
public SpecialThings() public SpecialThings()
{ {
PatrolPoints = new Dictionary<int, List<Thing>>(); PatrolPoints = new Dictionary<int, List<Thing>>();
PatrolSpecials = new List<Thing>();
InterpolationPoints = new Dictionary<int, List<PathNode>>(); InterpolationPoints = new Dictionary<int, List<PathNode>>();
InterpolationSpecials = new List<Thing>();
ThingsWithGoal = new List<Thing>(); ThingsWithGoal = new List<Thing>();
Cameras = new List<Thing>(); Cameras = new List<Thing>();
ActorMovers = new Dictionary<int, List<Thing>>(); ActorMovers = new Dictionary<int, List<Thing>>();
@ -158,6 +162,10 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
} }
break; break;
case "patrolspecial":
result.PatrolSpecials.Add(t);
break;
case "$polyanchor": case "$polyanchor":
if(!result.PolyobjectAnchors.ContainsKey(t.AngleDoom)) result.PolyobjectAnchors[t.AngleDoom] = new List<Thing>(); if(!result.PolyobjectAnchors.ContainsKey(t.AngleDoom)) result.PolyobjectAnchors[t.AngleDoom] = new List<Thing>();
result.PolyobjectAnchors[t.AngleDoom].Add(t); result.PolyobjectAnchors[t.AngleDoom].Add(t);
@ -194,6 +202,10 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
result.InterpolationPoints[t.Tag].Add(new PathNode(t, blockmap)); result.InterpolationPoints[t.Tag].Add(new PathNode(t, blockmap));
break; break;
case "interpolationspecial":
result.InterpolationSpecials.Add(t);
break;
case "movingcamera": case "movingcamera":
if(t.Args[0] != 0 || t.Args[1] != 0) result.Cameras.Add(t); if(t.Args[0] != 0 || t.Args[1] != 0) result.Cameras.Add(t);
break; break;
@ -269,6 +281,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] // Process cameras [CAN USE INTERPOLATION]
foreach(Thing t in result.Cameras) foreach(Thing t in result.Cameras)
{ {
@ -382,6 +411,24 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
foreach(PathNode node in group.Value) node.PropagateCurvedFlag(); 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 // 3. Make lines
HashSet<int> processedindices = new HashSet<int>(); HashSet<int> processedindices = new HashSet<int>();
foreach(KeyValuePair<int, List<PathNode>> group in result.InterpolationPoints) foreach(KeyValuePair<int, List<PathNode>> group in result.InterpolationPoints)

View file

@ -56,6 +56,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Highlighted item // Highlighted item
private Thing highlighted; private Thing highlighted;
private readonly Association[] association = new Association[Thing.NUM_ARGS]; private readonly Association[] association = new Association[Thing.NUM_ARGS];
private readonly Association directasso = new Association();
private readonly Association highlightasso = new Association(); private readonly Association highlightasso = new Association();
// Interface // Interface
@ -88,6 +89,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
{ {
//mxd. Associations now requre initializing... //mxd. Associations now requre initializing...
for(int i = 0; i < association.Length; i++) association[i] = new Association(); for(int i = 0; i < association.Length; i++) association[i] = new Association();
directasso = new Association();
} }
//mxd //mxd
@ -244,6 +246,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
renderer.RenderThingSet(General.Map.ThingsFilter.HiddenThings, General.Settings.HiddenThingsAlpha); renderer.RenderThingSet(General.Map.ThingsFilter.HiddenThings, General.Settings.HiddenThingsAlpha);
renderer.RenderThingSet(General.Map.ThingsFilter.VisibleThings, alpha); renderer.RenderThingSet(General.Map.ThingsFilter.VisibleThings, alpha);
for(int i = 0; i < Thing.NUM_ARGS; i++) BuilderPlug.RenderAssociations(renderer, association[i], eventlines); 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) if(highlighted != null && !highlighted.IsDisposed)
{ {
@ -353,8 +356,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
//mxd. Update label color? //mxd. Update label color?
if(labels.ContainsKey(t)) labels[t].Color = General.Colors.Selection; 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? // 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 else
{ {
@ -382,6 +391,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
LinedefActionInfo action = General.Map.Config.LinedefActions[t.Action]; LinedefActionInfo action = General.Map.Config.LinedefActions[t.Action];
for(int i = 0; i < Thing.NUM_ARGS; i++) for(int i = 0; i < Thing.NUM_ARGS; i++)
association[i].Set(t.Position, t.Args[i], action.Args[i].Type); 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 //mxd. Check if we can use thing arguments
else if(t.Action == 0) else if(t.Action == 0)
@ -398,7 +412,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
// mxd. Clear associations? // mxd. Clear associations?
if(clearassociations) 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 // Set new highlight and redraw display
highlighted = t; highlighted = t;

View file

@ -29,10 +29,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
private HashSet<int> tags; private HashSet<int> tags;
private Vector2D center; private Vector2D center;
private UniversalType type; private UniversalType type;
private int directlinktype;
public HashSet<int> Tags { get { return tags; } } public HashSet<int> Tags { get { return tags; } }
public Vector2D Center { get { return center; } } public Vector2D Center { get { return center; } }
public UniversalType Type { get { return type; } } public UniversalType Type { get { return type; } }
public int DirectLinkType { get { return directlinktype; } }
//mxd. This sets up the association //mxd. This sets up the association
public Association() public Association()
@ -74,34 +76,51 @@ namespace CodeImp.DoomBuilder.BuilderModes
// This sets up the association // This sets up the association
public void Set(Vector2D center, int tag, int type) 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.tags = new HashSet<int> { tag }; //mxd
this.type = (UniversalType)type; this.type = (UniversalType)type;
this.center = center; this.center = center;
this.directlinktype = directlinktype;
} }
// This sets up the association // This sets up the association
public void Set(Vector2D center, int tag, UniversalType type) 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.tags = new HashSet<int> { tag }; //mxd
this.type = type; this.type = type;
this.center = center; this.center = center;
this.directlinktype = directlinktype;
} }
//mxd. This also sets up the association //mxd. This also sets up the association
public void Set(Vector2D center, IEnumerable<int> tags, int type) public void Set(Vector2D center, IEnumerable<int> tags, int type)
{ {
this.tags = new HashSet<int>(tags); //mxd this.Set(center, tags, (UniversalType)type, 0);
this.type = (UniversalType)type;
this.center = center;
} }
//mxd. This also sets up the association //mxd. This also sets up the association
public void Set(Vector2D center, IEnumerable<int> tags, UniversalType type) 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.tags = new HashSet<int>(tags); //mxd
this.type = type; this.type = type;
this.center = center; this.center = center;
this.directlinktype = directlinktype;
} }
// This compares an association // This compares an association

View file

@ -632,6 +632,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
foreach(Thing t in General.Map.Map.Things) foreach(Thing t in General.Map.Map.Things)
{ {
if(!asso.Tags.Contains(t.Tag)) continue; 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); renderer.RenderThing(t, General.Colors.Indication, General.Settings.ActiveThingsAlpha);
if(General.Settings.GZShowEventLines) eventlines.Add(new Line3D(asso.Center, t.Position)); //mxd if(General.Settings.GZShowEventLines) eventlines.Add(new Line3D(asso.Center, t.Position)); //mxd
} }
@ -699,9 +705,17 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Things // Things
foreach(Thing t in General.Map.Map.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? // Known action on this thing?
if((t.Action > 0) && General.Map.Config.LinedefActions.ContainsKey(t.Action)) 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]; LinedefActionInfo action = General.Map.Config.LinedefActions[t.Action];
if( ((action.Args[0].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[0]))) || 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]))) || ((action.Args[1].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[1]))) ||
@ -712,12 +726,20 @@ namespace CodeImp.DoomBuilder.BuilderModes
renderer.RenderThing(t, General.Colors.Indication, General.Settings.ActiveThingsAlpha); renderer.RenderThing(t, General.Colors.Indication, General.Settings.ActiveThingsAlpha);
if(General.Settings.GZShowEventLines) eventlines.Add(new Line3D(t.Position, asso.Center)); //mxd 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? //mxd. Thing action on this thing?
else if(t.Action == 0) else if(t.Action == 0)
{ {
ThingTypeInfo ti = General.Map.Data.GetThingInfoEx(t.Type); //Draw the association, unless it is a child link.
if(ti != null) // 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]))) || 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]))) || ((ti.Args[1].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[1]))) ||