// Selected type changes private void thingtype_OnTypeChanged(ThingTypeInfo value) { thinginfo = value; // Update arguments action_ValueChanges(this, EventArgs.Empty); //mxd. Update things if (preventchanges || (!string.IsNullOrEmpty(thingtype.TypeStringValue) && thingtype.GetResult(0) < General.Map.FormatInterface.MinThingType || thingtype.GetResult(0) > General.Map.FormatInterface.MaxThingType)) { return; } MakeUndo(); //mxd foreach (Thing t in things) { //Set type t.Type = thingtype.GetResult(t.Type); // Update settings t.UpdateConfiguration(); } UpdateFlagNames(); //mxd General.Map.IsChanged = true; if (OnValuesChanged != null) { OnValuesChanged(this, EventArgs.Empty); } }
// This runs the check public override void Run() { int progress = 0; int stepprogress = 0; // Go for all things foreach(Thing t in General.Map.Map.Things) { ThingTypeInfo info = General.Map.Data.GetThingInfoEx(t.Type); if(info != null && info.IsObsolete) { SubmitResult(new ResultObsoleteThing(t, info.ObsoleteMessage)); } // Handle thread interruption try { Thread.Sleep(0); } catch(ThreadInterruptedException) { return; } // We are making progress! if((++progress / PROGRESS_STEP) > stepprogress) { stepprogress = (progress / PROGRESS_STEP); AddProgress(1); } } }
// Checks if two things overlap private static bool ThingsOverlap(Thing t1, Thing t2) { Vector3D p1 = t1.Position; Vector3D p2 = t2.Position; ThingTypeInfo t1info = General.Map.Data.GetThingInfo(t1.Type); ThingTypeInfo t2info = General.Map.Data.GetThingInfo(t2.Type); // simple bounding box collision detection if (p1.x + t1.Size - ALLOWED_STUCK_DISTANCE < p2.x - t2.Size + ALLOWED_STUCK_DISTANCE || p1.x - t1.Size + ALLOWED_STUCK_DISTANCE > p2.x + t2.Size - ALLOWED_STUCK_DISTANCE || p1.y - t1.Size + ALLOWED_STUCK_DISTANCE > p2.y + t2.Size - ALLOWED_STUCK_DISTANCE || p1.y + t1.Size - ALLOWED_STUCK_DISTANCE < p2.y - t2.Size + ALLOWED_STUCK_DISTANCE) { return(false); } // if either thing blocks full height there's no need to check the z-axis if (t1info.Blocking == ThingTypeInfo.THING_BLOCKING_FULL || t2info.Blocking == ThingTypeInfo.THING_BLOCKING_FULL) { return(true); } // check z-axis if (p1.z > p2.z + t2info.Height || p1.z + t1info.Height < p2.z) { return(false); } return(true); }
public override void Browse(IWin32Window parent) { int tid = 0; // Find the thing with this class name foreach (ThingTypeInfo t in General.Map.Data.ThingTypes) { if ((t.Actor != null) && (string.Compare(t.Actor.ClassName, value, true) == 0)) { tid = t.Index; break; } } //tid = ThingBrowserForm.BrowseThing(parent, tid); ThingBrowserForm f = new ThingBrowserForm(tid); if (f.ShowDialog(Form.ActiveForm) == DialogResult.OK) { // Find the class name for this thing ThingTypeInfo t = General.Map.Data.GetThingInfo(f.SelectedType); if (t.Actor != null) { this.value = t.Actor.ClassName; } else { this.value = ""; } } f.Dispose(); }
protected override EnumList CreateEnumList() { // Collect polyobjects HashSet <int> ponums = new HashSet <int>(); EnumList polist = new EnumList(); foreach (Thing t in General.Map.Map.Things) { ThingTypeInfo info = General.Map.Data.GetThingInfoEx(t.Type); if (info == null || info.ClassName.ToLowerInvariant() != "$polyanchor") { continue; } ponums.Add(t.AngleDoom); } // Now sort them in descending order List <int> ponumslist = new List <int>(ponums); ponumslist.Sort((a, b) => - 1 * a.CompareTo(b)); // Create enum items foreach (int ponum in ponums) { polist.Add(new EnumItem(ponum.ToString(), ponum.ToString())); } return(polist); }
private static float GetAlignedThingZ(BaseVisualMode mode, Thing t, float targtthingheight) { 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) { // Transform to floor-aligned position SectorData nsd = mode.GetSectorData(t.Sector); return(t.Position.z - nsd.Floor.plane.GetZ(t.Position) + t.Height); } if (info.Hangs) { // Transform to floor-aligned position. Align top of target thing to the bottom of the hanging thing SectorData nsd = mode.GetSectorData(t.Sector); return((nsd.Ceiling.plane.GetZ(t.Position) - nsd.Floor.plane.GetZ(t.Position)) - t.Position.z - t.Height - targtthingheight); } } return(t.Position.z + t.Height); }
public override void Browse(IWin32Window parent) { int tid = 0; // Find the thing with this class name foreach (ThingTypeInfo t in General.Map.Data.ThingTypes) { if ((string.Compare(t.ClassName, value, true) == 0)) //mxd { tid = t.Index; break; } } ThingBrowserForm f = new ThingBrowserForm(tid); if (f.ShowDialog(Form.ActiveForm) == DialogResult.OK) { // Find the class name for this thing ThingTypeInfo t = General.Map.Data.GetThingInfo(f.SelectedType); this.value = !string.IsNullOrEmpty(t.ClassName) ? t.ClassName : ""; //mxd } f.Dispose(); }
// Selected type changes private void thingtype_OnTypeChanged(ThingTypeInfo value) { thinginfo = value; // Update preview image if (thinginfo != null) { if (thinginfo.Sprite.ToLowerInvariant().StartsWith(DataManager.INTERNAL_PREFIX) && (thinginfo.Sprite.Length > DataManager.INTERNAL_PREFIX.Length)) { General.DisplayZoomedImage(spritetex, General.Map.Data.GetSpriteImage(thinginfo.Sprite).GetBitmap()); } else if (thinginfo.Sprite.Length > 0) { General.DisplayZoomedImage(spritetex, General.Map.Data.GetSpriteImage(thinginfo.Sprite).GetPreview()); } else { spritetex.BackgroundImage = null; } } else { spritetex.BackgroundImage = null; } // Update arguments action_ValueChanges(this, EventArgs.Empty); }
// This is called to perform a search (and replace) // Returns a list of items to show in the results list // replacewith is null when not replacing public override FindReplaceObject[] Find(string value, bool withinselection, string replacewith, bool keepselection) { List <FindReplaceObject> objs = new List <FindReplaceObject>(); // Interpret the replacement int replacetype = 0; if (replacewith != null) { // If it cannot be interpreted, set replacewith to null (not replacing at all) if (!int.TryParse(replacewith, out replacetype)) { replacewith = null; } if (replacetype < 0) { replacewith = null; } if (replacetype > Int16.MaxValue) { replacewith = null; } if (replacewith == null) { MessageBox.Show("Invalid replace value for this search type!", "Find and Replace", MessageBoxButtons.OK, MessageBoxIcon.Error); return(objs.ToArray()); } } // Interpret the number given int findtype = 0; if (int.TryParse(value, out findtype)) { // Where to search? ICollection <Thing> list = withinselection ? General.Map.Map.GetSelectedThings(true) : General.Map.Map.Things; // Go for all things foreach (Thing t in list) { // Match? if (t.Type == findtype) { // Replace if (replacewith != null) { t.Type = replacetype; t.UpdateConfiguration(); } // Add to list ThingTypeInfo ti = General.Map.Data.GetThingInfo(t.Type); objs.Add(new FindReplaceObject(t, "Thing " + t.Index + " (" + ti.Title + ")")); } } } return(objs.ToArray()); }
//mxd. This checks if the thing has model override and whether pitch/roll values should be used internal void UpdateCache() { if (General.Map.Data == null) { return; } // Check if the thing has model override if (General.Map.Data.ModeldefEntries.ContainsKey(type)) { ModelData md = General.Map.Data.ModeldefEntries[type]; if ((md.LoadState == ModelLoadState.None && General.Map.Data.ProcessModel(type)) || md.LoadState != ModelLoadState.None) { rendermode = (General.Map.Data.ModeldefEntries[type].IsVoxel ? ThingRenderMode.VOXEL : ThingRenderMode.MODEL); } } else // reset rendermode if we SUDDENLY became a sprite out of a model. otherwise it crashes violently. { ThingTypeInfo ti = General.Map.Data.GetThingInfo(Type); rendermode = (ti != null) ? ti.RenderMode : ThingRenderMode.NORMAL; } // Update radian versions of pitch and roll switch (rendermode) { case ThingRenderMode.MODEL: float pmult = General.Map.Config.BuggyModelDefPitch ? 1 : -1; ModelData md = General.Map.Data.ModeldefEntries[type]; rollrad = (md.UseActorRoll ? Angle2D.DegToRad(roll) : 0); pitchrad = ((md.InheritActorPitch || md.UseActorPitch) ? Angle2D.DegToRad(pmult * (md.InheritActorPitch ? -pitch : pitch)) : 0); break; case ThingRenderMode.FLATSPRITE: rollrad = Angle2D.DegToRad(roll); pitchrad = Angle2D.DegToRad(pitch); break; case ThingRenderMode.WALLSPRITE: rollrad = Angle2D.DegToRad(roll); pitchrad = 0; break; case ThingRenderMode.NORMAL: rollrad = (rollsprite ? Angle2D.DegToRad(roll) : 0); pitchrad = 0; break; case ThingRenderMode.VOXEL: rollrad = 0; pitchrad = 0; break; default: throw new NotImplementedException("Unknown ThingRenderMode"); } }
//constructor public NodeInfo(Thing t) { type = NodeInfoType.THING; index = t.Index; action = t.Action; tag = t.Tag; polyobjnumber = ((t.Type > 9299 && t.Type < 9304) ? t.AngleDoom : int.MinValue); ThingTypeInfo tti = General.Map.Data.GetThingInfoEx(t.Type); defaultname = (tti != null ? tti.Title : "Thing"); }
// This renders the associated things with the indication color public static void RenderAssociations(IRenderer2D renderer, Association asso, List <Line3D> eventlines) { // Tag must be above zero if (General.GetByIndex(asso.Tags, 0) < 1) { return; } // Things? switch (asso.Type) { case UniversalType.ThingTag: 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 } } break; case UniversalType.SectorTag: foreach (Sector s in General.Map.Map.Sectors) { if (!asso.Tags.Overlaps(s.Tags)) { continue; } int highlightedColor = General.Colors.Highlight.WithAlpha(128).ToInt(); FlatVertex[] verts = new FlatVertex[s.FlatVertices.Length]; s.FlatVertices.CopyTo(verts, 0); for (int i = 0; i < verts.Length; i++) { verts[i].c = highlightedColor; } renderer.RenderGeometry(verts, null, true); } break; } }
// This updates the settings from configuration public void UpdateConfiguration() { // Lookup settings ThingTypeInfo ti = General.Map.Data.GetThingInfo(type); // Apply size dynamiclighttype = GZGeneral.GetGZLightTypeByClass(ti.Actor); if (dynamiclighttype == null) { dynamiclighttype = ti.DynamicLightType; } //General.ErrorLogger.Add(ErrorType.Warning, string.Format("thing dynamiclighttype is {0}; class is {1}", dynamiclighttype, ti.Actor.ClassName)); size = ti.Radius; rendersize = ti.RenderRadius; height = ti.Height; //mxd fixedsize = ti.FixedSize; spritescale = ti.SpriteScale; //mxd //mxd. Apply radius and height overrides? for (int i = 0; i < ti.Args.Length; i++) { if (ti.Args[i] == null) { continue; } if (ti.Args[i].Type == (int)UniversalType.ThingRadius && args[i] > 0) { size = args[i]; } else if (ti.Args[i].Type == (int)UniversalType.ThingHeight && args[i] > 0) { height = args[i]; } } // Color valid? if ((ti.Color >= 0) && (ti.Color < ColorCollection.NUM_THING_COLORS)) { // Apply color color = General.Colors.Colors[ti.Color + ColorCollection.THING_COLORS_OFFSET]; } else { // Unknown thing color color = General.Colors.Colors[ColorCollection.THING_COLORS_OFFSET]; } directional = ti.Arrow; //mxd rendermode = ti.RenderMode; //mxd rollsprite = ti.RollSprite; //mxd UpdateCache(); //mxd }
/// <summary> /// Checks if there's an association between the element and a Thing /// </summary> /// <param name="thing">Thing to check the association against</param> /// <returns>true if the Thing and the element are associated, false if not</returns> private bool IsAssociatedToThing(Thing thing) { // Get the thing type info ThingTypeInfo ti = General.Map.Data.GetThingInfoEx(thing.Type); // Known action on this thing? if ((thing.Action > 0) && General.Map.Config.LinedefActions.ContainsKey(thing.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 && directlinktype < 0 && directlinktype != -thing.Type) { return(false); } LinedefActionInfo action = General.Map.Config.LinedefActions[thing.Action]; if (((action.Args[0].Type == (int)type) && (tags.Contains(thing.Args[0]))) || ((action.Args[1].Type == (int)type) && (tags.Contains(thing.Args[1]))) || ((action.Args[2].Type == (int)type) && (tags.Contains(thing.Args[2]))) || ((action.Args[3].Type == (int)type) && (tags.Contains(thing.Args[3]))) || ((action.Args[4].Type == (int)type) && (tags.Contains(thing.Args[4])))) { return(true); } //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 && directlinktype == thing.Type && tags.Contains(thing.Tag)) { return(true); } } //mxd. Thing action on this thing? else if (thing.Action == 0) { // Gets 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 && directlinktype >= 0 && Math.Abs(directlinktype) != thing.Type) { if (((ti.Args[0].Type == (int)type) && (tags.Contains(thing.Args[0]))) || ((ti.Args[1].Type == (int)type) && (tags.Contains(thing.Args[1]))) || ((ti.Args[2].Type == (int)type) && (tags.Contains(thing.Args[2]))) || ((ti.Args[3].Type == (int)type) && (tags.Contains(thing.Args[3]))) || ((ti.Args[4].Type == (int)type) && (tags.Contains(thing.Args[4])))) { return(true); } } } return(false); }
// This renders the associated things with the indication color public static void RenderReverseAssociations(IRenderer2D renderer, Association asso, List <Line3D> eventlines) { // Tag must be above zero if (General.GetByIndex(asso.Tags, 0) < 1) { return; } // Things foreach (Thing t in General.Map.Map.Things) { // Known action on this thing? if ((t.Action > 0) && General.Map.Config.LinedefActions.ContainsKey(t.Action)) { 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]))) || ((action.Args[2].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[2]))) || ((action.Args[3].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[3]))) || ((action.Args[4].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[4])))) { renderer.RenderThing(t, General.Colors.Indication, General.Settings.ActiveThingsAlpha); if (General.Settings.GZShowEventLines) { eventlines.Add(new Line3D(t.Position, asso.Center)); //mxd } } } //mxd. Thing action on this thing? else if (t.Action == 0) { ThingTypeInfo ti = General.Map.Data.GetThingInfoEx(t.Type); if (ti != null) { 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[2].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[2]))) || ((ti.Args[3].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[3]))) || ((ti.Args[4].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[4])))) { renderer.RenderThing(t, General.Colors.Indication, General.Settings.ActiveThingsAlpha); if (General.Settings.GZShowEventLines) { eventlines.Add(new Line3D(t.Position, asso.Center)); } } } } } }
protected override EnumList CreateEnumList() { // Collect tags List <int> tags = new List <int>(); EnumList taglist = new EnumList(); if (General.Map.Map != null) { foreach (Thing t in General.Map.Map.Things) { if (t.Tag == 0 || tags.Contains(t.Tag)) { continue; } // Check target class? if (arginfo.TargetClasses.Count > 0) { ThingTypeInfo info = General.Map.Data.GetThingInfoEx(t.Type); if (info != null && !arginfo.TargetClasses.Contains(info.ClassName)) { continue; } } tags.Add(t.Tag); } // Now sort them in descending order tags.Sort((a, b) => - 1 * a.CompareTo(b)); // Create enum items foreach (int tag in tags) { if (General.Map.Options.TagLabels.ContainsKey(tag)) // Tag labels { taglist.Add(new EnumItem(tag.ToString(), General.Map.Options.TagLabels[tag])); } else { taglist.Add(new EnumItem(tag.ToString(), tag.ToString())); } } } return(taglist); }
// This updates the settings from configuration public void UpdateConfiguration() { // Lookup settings ThingTypeInfo ti = General.Map.Data.GetThingInfo(type); // Apply size dynamiclighttype = (Array.IndexOf(GZBuilder.GZGeneral.GZ_LIGHTS, type) != -1) ? type : ti.DynamicLightType; size = ti.Radius; height = ti.Height; //mxd fixedsize = ti.FixedSize; spritescale = ti.SpriteScale; //mxd //mxd. Apply radius and height overrides? for (int i = 0; i < ti.Args.Length; i++) { if (ti.Args[i] == null) { continue; } if (ti.Args[i].Type == (int)UniversalType.ThingRadius && args[i] > 0) { size = args[i]; } else if (ti.Args[i].Type == (int)UniversalType.ThingHeight && args[i] > 0) { height = args[i]; } } // Color valid? if ((ti.Color >= 0) && (ti.Color < ColorCollection.NUM_THING_COLORS)) { // Apply color color = General.Colors.Colors[ti.Color + ColorCollection.THING_COLORS_OFFSET]; } else { // Unknown thing color color = General.Colors.Colors[ColorCollection.THING_COLORS_OFFSET]; } directional = ti.Arrow; //mxd rendermode = ti.RenderMode; //mxd rollsprite = ti.RollSprite; //mxd UpdateCache(); //mxd }
//set sliders count and labels based on given thing, set lightProps start values //this is called only once private void SetupSliders(Thing referenceThing) { ThingTypeInfo typeInfo = General.Map.Data.GetThingInfoEx(referenceThing.DynamicLightType.LightNum); int firstArg = 3; if (referenceThing.DynamicLightType.LightVavoom) { firstArg = 0; } //first slider is always used colorPickerSlider1.Label = typeInfo.Args[firstArg].Title + ":"; colorPickerSlider1.OnValueChanged += OnSliderValueChanged; //either both of them or none are used if (Array.IndexOf(LIGHT_USES_ANGLE_VALUE, referenceThing.DynamicLightType.LightNum) != -1) { showAllControls = true; colorPickerSlider2.Label = typeInfo.Args[4].Title + ":"; colorPickerSlider2.OnValueChanged += OnSliderValueChanged; colorPickerSlider3.Label = "Interval:"; colorPickerSlider3.OnValueChanged += OnSliderValueChanged; colorPickerSlider3.UseSlider(true); } else { colorPickerSlider2.Visible = false; colorPickerSlider3.Visible = false; } //set window height int newHeight; if (showAllControls) { newHeight = colorPickerSlider3.Location.Y + colorPickerSlider3.Height + 8; } else { newHeight = colorPickerSlider1.Location.Y + colorPickerSlider1.Height + 8; } this.ClientSize = new Size(this.ClientSize.Width, newHeight); }
// This forces to rebuild the whole thing public void Rebuild() { // Find thing information info = General.Map.Data.GetThingInfo(Thing.Type); // Find sprite texture if (info.Sprite.Length > 0) { sprite = General.Map.Data.GetSpriteImage(info.Sprite); if (sprite != null) { sprite.AddReference(); } } // Setup visual thing Setup(); }
// This is called to perform a search (and replace) // Returns a list of items to show in the results list // replacewith is null when not replacing public override FindReplaceObject[] Find(string value, bool withinselection, bool replace, string replacewith, bool keepselection) { List <FindReplaceObject> objs = new List <FindReplaceObject>(); // Interpret the number given int index; if (int.TryParse(value, out index)) { Thing t = General.Map.Map.GetThingByIndex(index); if (t != null) { ThingTypeInfo ti = General.Map.Data.GetThingInfo(t.Type); objs.Add(new FindReplaceObject(t, "Thing " + index + " (" + ti.Title + ")")); } } return(objs.ToArray()); }
private void Setup(ICollection <Thing> selection) { this.selection = selection; //get thing types Dictionary <int, int> thingcounts = new Dictionary <int, int>(); Dictionary <int, string> thingtitles = new Dictionary <int, string>(); foreach (Thing t in selection) { if (!thingcounts.ContainsKey(t.Type)) { thingcounts.Add(t.Type, 1); ThingTypeInfo ti = General.Map.Data.GetThingInfo(t.Type); thingtitles.Add(t.Type, ti.Title); } else { thingcounts[t.Type]++; } } //add data foreach (KeyValuePair <int, int> group in thingcounts) { DataGridViewRow row = new DataGridViewRow(); row.Cells.Add(new DataGridViewTextBoxCell { Value = group.Key }); //type row.Cells.Add(new DataGridViewTextBoxCell { Value = thingtitles[group.Key] }); //title row.Cells.Add(new DataGridViewTextBoxCell { Value = group.Value }); //count dataGridView.Rows.Add(row); } dataGridView.Sort(ThingType, ListSortDirection.Ascending); }
// Thing type selection changed private void typelist_AfterSelect(object sender, TreeViewEventArgs e) { if (doupdatetextbox) { // Anything selected? if (typelist.SelectedNode != null) { TreeNode n = typelist.SelectedNode; // Node is a child node? if ((n.Nodes.Count == 0) && (n.Tag != null) && (n.Tag is ThingTypeInfo)) { ThingTypeInfo ti = (n.Tag as ThingTypeInfo); // Show info typeid.Text = ti.Index.ToString(); } } } }
// Constructor public BaseVisualThing(BaseVisualMode mode, Thing t) : base(t) { this.mode = mode; // Find thing information info = General.Map.Data.GetThingInfo(Thing.Type); // Find sprite texture if (info.Sprite.Length > 0) { sprite = General.Map.Data.GetSpriteImage(info.Sprite); if (sprite != null) { sprite.AddReference(); } } // We have no destructor GC.SuppressFinalize(this); }
// This is called to perform a search (and replace) // Returns a list of items to show in the results list // replacewith is null when not replacing public override FindReplaceObject[] Find(string value, bool withinselection, string replacewith, bool keepselection) { List <FindReplaceObject> objs = new List <FindReplaceObject>(); // Where to search? ICollection <Thing> list = withinselection ? General.Map.Map.GetSelectedThings(true) : General.Map.Map.Things; // Go for all things foreach (Thing t in list) { bool match = true; // Parse the value string... foreach (string s in value.Split(',')) { string str = s.Trim(); // ... and check if the flags don't match if (General.Map.Config.ThingFlags.ContainsKey(str) && !t.IsFlagSet(str)) { match = false; break; } } // Match? if (match) { // Add to list ThingTypeInfo ti = General.Map.Data.GetThingInfo(t.Type); objs.Add(new FindReplaceObject(t, "Thing " + t.Index + " (" + ti.Title + ")")); } } return(objs.ToArray()); }
// This renders the associated things with the indication color public static void RenderReverseAssociations(IRenderer2D renderer, Association asso, List <Line3D> eventlines) { // Tag must be above zero if (General.GetByIndex(asso.Tags, 0) < 1) { return; } // 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]))) || ((action.Args[2].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[2]))) || ((action.Args[3].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[3]))) || ((action.Args[4].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[4])))) { 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) { //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]))) || ((ti.Args[2].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[2]))) || ((ti.Args[3].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[3]))) || ((ti.Args[4].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[4])))) { renderer.RenderThing(t, General.Colors.Indication, General.Settings.ActiveThingsAlpha); if (General.Settings.GZShowEventLines) { eventlines.Add(new Line3D(t.Position, asso.Center)); } } } } } }
// Apply clicked private void apply_Click(object sender, EventArgs e) { //mxd. Make Undo MakeUndo(); List <string> defaultflags = new List <string>(); // Verify the tag if (General.Map.FormatInterface.HasThingTag) //mxd { tagSelector.ValidateTag(); //mxd if (((tagSelector.GetTag(0) < General.Map.FormatInterface.MinTag) || (tagSelector.GetTag(0) > General.Map.FormatInterface.MaxTag))) { General.ShowWarningMessage("Thing tag must be between " + General.Map.FormatInterface.MinTag + " and " + General.Map.FormatInterface.MaxTag + ".", MessageBoxButtons.OK); return; } } // Verify the type if (!string.IsNullOrEmpty(thingtype.TypeStringValue) && ((thingtype.GetResult(0) < General.Map.FormatInterface.MinThingType) || (thingtype.GetResult(0) > General.Map.FormatInterface.MaxThingType))) { General.ShowWarningMessage("Thing type must be between " + General.Map.FormatInterface.MinThingType + " and " + General.Map.FormatInterface.MaxThingType + ".", MessageBoxButtons.OK); return; } // Verify the action if (General.Map.FormatInterface.HasThingAction && ((action.Value < General.Map.FormatInterface.MinAction) || (action.Value > General.Map.FormatInterface.MaxAction))) { General.ShowWarningMessage("Thing action must be between " + General.Map.FormatInterface.MinAction + " and " + General.Map.FormatInterface.MaxAction + ".", MessageBoxButtons.OK); return; } // Go for all the things int offset = 0; //mxd foreach (Thing t in things) { // Coordination //mxd. Randomize rotations? if (cbrandomangle.Checked) { int newangle = General.Random(0, 359); if (General.Map.Config.DoomThingRotationAngles) { newangle = newangle / 45 * 45; } t.Rotate(newangle); } if (cbrandompitch.Checked) { t.SetPitch(General.Random(0, 359)); } if (cbrandomroll.Checked) { t.SetRoll(General.Random(0, 359)); } //mxd. Check position double px = General.Clamp(t.Position.x, General.Map.Config.LeftBoundary, General.Map.Config.RightBoundary); double py = General.Clamp(t.Position.y, General.Map.Config.BottomBoundary, General.Map.Config.TopBoundary); if (t.Position.x != px || t.Position.y != py) { t.Move(new Vector2D(px, py)); } // Action/tags t.Tag = General.Clamp(tagSelector.GetSmartTag(t.Tag, offset), General.Map.FormatInterface.MinTag, General.Map.FormatInterface.MaxTag); //mxd if (!action.Empty) { t.Action = action.Value; } //mxd. Apply args argscontrol.Apply(t, offset); //mxd. Custom fields fieldslist.Apply(t.Fields); if (!string.IsNullOrEmpty(conversationID.Text)) { UniFields.SetInteger(t.Fields, "conversation", conversationID.GetResult(t.Fields.GetValue("conversation", 0)), 0); } if (!string.IsNullOrEmpty(floatbobphase.Text)) { UniFields.SetInteger(t.Fields, "floatbobphase", General.Clamp(floatbobphase.GetResult(t.Fields.GetValue("floatbobphase", -1)), -1, 63), -1); } if (!string.IsNullOrEmpty(gravity.Text)) { UniFields.SetFloat(t.Fields, "gravity", gravity.GetResultFloat(t.Fields.GetValue("gravity", 1.0)), 1.0); } if (!string.IsNullOrEmpty(health.Text)) { UniFields.SetInteger(t.Fields, "health", health.GetResult(t.Fields.GetValue("health", 1)), 1); } if (!string.IsNullOrEmpty(score.Text)) { UniFields.SetInteger(t.Fields, "score", score.GetResult(t.Fields.GetValue("score", 0)), 0); } //mxd. User vars. Should be called after fieldslist.Apply() ThingTypeInfo ti = General.Map.Data.GetThingInfoEx(t.Type); if (ti != null && ti.Actor != null && ti.Actor.UserVars.Count > 0) { fieldslist.ApplyUserVars(ti.Actor.UserVars, t.Fields); } color.ApplyTo(t.Fields, t.Fields.GetValue("fillcolor", 0)); //mxd. Comments commenteditor.Apply(t.Fields); // Update settings t.UpdateConfiguration(); //mxd. Increase offset... offset++; } // Set as defaults foreach (CheckBox c in flags.Checkboxes) { if (c.CheckState == CheckState.Checked) { defaultflags.Add(c.Tag.ToString()); } } General.Settings.DefaultThingType = thingtype.GetResult(General.Settings.DefaultThingType); General.Settings.DefaultThingAngle = Angle2D.DegToRad((float)angle.GetResult((int)Angle2D.RadToDeg(General.Settings.DefaultThingAngle) - 90) + 90); General.Settings.SetDefaultThingFlags(defaultflags); // Done General.Map.IsChanged = true; if (OnValuesChanged != null) { OnValuesChanged(this, EventArgs.Empty); //mxd } this.DialogResult = DialogResult.OK; this.Close(); }
// This sets up the form to edit the given things public void Setup(ICollection <Thing> things) { preventchanges = true; undocreated = false; argscontrol.Reset(); // Keep this list this.things = things; if (things.Count > 1) { this.Text = "Edit Things (" + things.Count + ")"; } hint.Visible = things.Count > 1; //mxd hintlabel.Visible = things.Count > 1; //mxd thingtype.UseMultiSelection = things.Count > 1; //mxd //////////////////////////////////////////////////////////////////////// // Set all options to the first thing properties //////////////////////////////////////////////////////////////////////// Thing ft = General.GetByIndex(things, 0); // Set type thingtype.SelectType(ft.Type); // Flags foreach (CheckBox c in flags.Checkboxes) { if (ft.Flags.ContainsKey(c.Tag.ToString())) { c.Checked = ft.Flags[c.Tag.ToString()]; } } // Coordination angle.Text = ft.AngleDoom.ToString(); zlabel.Text = useabsoluteheight ? "Z:" : "Height:"; //mxd cbAbsoluteHeight.Checked = useabsoluteheight; //mxd //mxd ft.DetermineSector(); float floorheight = (ft.Sector != null ? Sector.GetFloorPlane(ft.Sector).GetZ(ft.Position) : 0); posX.Text = ((int)ft.Position.x).ToString(); posY.Text = ((int)ft.Position.y).ToString(); posZ.Text = (useabsoluteheight ? ((int)Math.Round(ft.Position.z + floorheight)).ToString() : ((int)ft.Position.z).ToString()); posX.ButtonStep = General.Map.Grid.GridSize; posY.ButtonStep = General.Map.Grid.GridSize; posZ.ButtonStep = General.Map.Grid.GridSize; //mxd thinginfo = General.Map.Data.GetThingInfoEx(ft.Type); // Action/tags action.Value = ft.Action; if (General.Map.FormatInterface.HasThingTag) //mxd { tagSelector.Setup(UniversalType.ThingTag); tagSelector.SetTag(ft.Tag); } //mxd. Args argscontrol.SetValue(ft, true); //////////////////////////////////////////////////////////////////////// // Now go for all lines and change the options when a setting is different //////////////////////////////////////////////////////////////////////// thingprops = new List <ThingProperties>(); // Go for all things foreach (Thing t in things) { //mxd. Update sector info t.DetermineSector(); // Type does not match? ThingTypeInfo info = thingtype.GetSelectedInfo(); //mxd if (info != null && info.Index != t.Type) { thingtype.ClearSelectedType(); thinginfo = null; //mxd } // Flags foreach (CheckBox c in flags.Checkboxes) { if (c.CheckState == CheckState.Indeterminate) { continue; //mxd } if (t.IsFlagSet(c.Tag.ToString()) != c.Checked) { c.ThreeState = true; c.CheckState = CheckState.Indeterminate; } } // Coordination if (t.AngleDoom.ToString() != angle.Text) { angle.Text = ""; } //mxd. Position if (((int)t.Position.x).ToString() != posX.Text) { posX.Text = ""; } if (((int)t.Position.y).ToString() != posY.Text) { posY.Text = ""; } if (useabsoluteheight && t.Sector != null) { if (((int)Math.Round(Sector.GetFloorPlane(t.Sector).GetZ(t.Position) + t.Position.z)).ToString() != posZ.Text) { posZ.Text = ""; } } else if (((int)t.Position.z).ToString() != posZ.Text) { posZ.Text = ""; } // Action/tags if (t.Action != action.Value) { action.Empty = true; } if (General.Map.FormatInterface.HasThingTag && t.Tag != ft.Tag) { tagSelector.ClearTag(); //mxd } //mxd. Arguments argscontrol.SetValue(t, false); //mxd. Store initial properties thingprops.Add(new ThingProperties(t)); } preventchanges = false; //mxd. Trigger updates manually... preventmapchange = true; angle_WhenTextChanged(angle, EventArgs.Empty); flags_OnValueChanged(flags, EventArgs.Empty); preventmapchange = false; argscontrol.UpdateScriptControls(); //mxd actionhelp.UpdateAction(action.GetValue()); //mxd UpdateFlagNames(); //mxd }
//mxd protected static void DeleteThings(ICollection <Thing> things) { if (things.Count == 0) { return; } General.Map.Map.BeginAddRemove(); //mxd // Dispose selected things foreach (Thing t in things) { //mxd. Do some path reconnecting shenanigans... ThingTypeInfo info = General.Map.Data.GetThingInfo(t.Type); string targetclass = string.Empty; int targetarg = -1; // Thing type can be changed in MAPINFO DoomEdNums block... switch (info.ClassName.ToLowerInvariant()) { case "interpolationpoint": if (t.Tag != 0 && t.Args[3] != 0) { targetclass = "interpolationpoint"; targetarg = 3; } break; case "patrolpoint": if (t.Tag != 0 && t.Args[0] != 0) { targetclass = "patrolpoint"; targetarg = 0; } break; } // Try to reconnect path... if (!string.IsNullOrEmpty(targetclass) && targetarg > -1) { General.Map.Map.EndAddRemove(); // We'll need to unlock the things array... foreach (Thing other in General.Map.Map.Things) { if (other.Index == t.Index) { continue; } info = General.Map.Data.GetThingInfo(other.Type); if (info.ClassName.ToLowerInvariant() == targetclass && other.Args[targetarg] == t.Tag) { other.Move(other.Position); //hacky way to call BeforePropsChange()... other.Args[targetarg] = t.Args[targetarg]; break; } } General.Map.Map.BeginAddRemove(); // We'll need to lock it again... } // Get rid of the thing t.Dispose(); } General.Map.Map.EndAddRemove(); //mxd }
/// <summary> /// Gets a dictionary of sector tags, linedef tags, and thing tags, grouped by their type, that the map element is referencing /// </summary> /// <returns>Dictionary of sector tags, linedef tags, and thing tags that the map element is referencing</returns> private Dictionary <int, HashSet <int> > GetTagsByType() { LinedefActionInfo action = null; int[] actionargs = new int[5]; Dictionary <int, HashSet <int> > actiontags = new Dictionary <int, HashSet <int> >(); // Get the action and its arguments from a linedef or a thing, if they have them if (element is Linedef) { Linedef ld = element as Linedef; if (ld.Action > 0 && General.Map.Config.LinedefActions.ContainsKey(ld.Action)) { action = General.Map.Config.LinedefActions[ld.Action]; } actionargs = ld.Args; } else if (element is Thing) { Thing t = element as Thing; if (t.Action > 0 && General.Map.Config.LinedefActions.ContainsKey(t.Action)) { action = General.Map.Config.LinedefActions[t.Action]; } actionargs = t.Args; } else // element is a Sector { return(actiontags); } if (action != null) { // Collect what map element the action arguments are referencing. Ignore the argument if it's 0, so that they // are not associated to everything untagged for (int i = 0; i < Linedef.NUM_ARGS; i++) { if ((action.Args[i].Type == (int)UniversalType.SectorTag || action.Args[i].Type == (int)UniversalType.LinedefTag || action.Args[i].Type == (int)UniversalType.ThingTag) && actionargs[i] > 0) { if (!actiontags.ContainsKey(action.Args[i].Type)) { actiontags[action.Args[i].Type] = new HashSet <int>(); } actiontags[action.Args[i].Type].Add(actionargs[i]); } } } else if (element is Thing && directlinktype >= 0 && Math.Abs(directlinktype) != ((Thing)element).Type) { // The direct link shenanigans if the thing doesn't have an action, but still reference something through // the action parameters Thing t = element as Thing; ThingTypeInfo ti = General.Map.Data.GetThingInfoEx(t.Type); if (ti != null && directlinktype >= 0 && Math.Abs(directlinktype) != t.Type) { for (int i = 0; i < Linedef.NUM_ARGS; i++) { if ((ti.Args[i].Type == (int)UniversalType.SectorTag || ti.Args[i].Type == (int)UniversalType.LinedefTag || ti.Args[i].Type == (int)UniversalType.ThingTag)) { if (!actiontags.ContainsKey(ti.Args[i].Type)) { actiontags[ti.Args[i].Type] = new HashSet <int>(); } actiontags[ti.Args[i].Type].Add(actionargs[i]); } } } } return(actiontags); }
/// <summary> /// Sets the association to a map element. Only works with an instance of Thing, Sector, or Linedef. /// Also gets the forward and reverse associations /// </summary> /// <param name="element">An instance of Thing, Sector, or Linedef</param> public void Set(SelectableElement element) { this.element = element; things = new List <Thing>(); sectors = new List <Sector>(); linedefs = new List <Linedef>(); eventlines = new Dictionary <string, List <Line3D> >(); if (element is Sector) { Sector s = element as Sector; center = (s.Labels.Count > 0 ? s.Labels[0].position : new Vector2D(s.BBox.X + s.BBox.Width / 2, s.BBox.Y + s.BBox.Height / 2)); type = UniversalType.SectorTag; tags = new HashSet <int>(s.Tags); } else if (element is Linedef) { Linedef ld = element as Linedef; center = ld.GetCenterPoint(); type = UniversalType.LinedefTag; tags = new HashSet <int>(ld.Tags); } else if (element is Thing) { Thing t = element as Thing; center = t.Position; ThingTypeInfo ti = General.Map.Data.GetThingInfoEx(t.Type); if (ti != null) { directlinktype = ti.ThingLink; } else { directlinktype = 0; } type = UniversalType.ThingTag; tags = new HashSet <int>(new int[] { t.Tag }); } // Remove the tag 0, because nothing sensible will come from it tags.Remove(0); // Get forward and reverse associations GetAssociations(); // Cache width of label text and generate the labels textwidths = new Dictionary <string, Vector2D>(eventlines.Count); textlabels = new Dictionary <string, List <TextLabel> >(eventlines.Count); foreach (KeyValuePair <string, List <Line3D> > kvp in eventlines) { SizeF size = General.Interface.MeasureString(kvp.Key, font); textwidths[kvp.Key] = new Vector2D(size.Width, size.Height); // Create one label for each line. We might not need them all, but better // to have them all at the beginning than to generate them later textlabels[kvp.Key] = new List <TextLabel>(kvp.Value.Count); for (int i = 0; i < kvp.Value.Count; i++) { // We don't need to set the position here, since it'll be done on the fly later TextLabel l = new TextLabel(); l.AlignX = TextAlignmentX.Center; l.AlignY = TextAlignmentY.Middle; l.TransformCoords = true; l.Text = kvp.Key; textlabels[kvp.Key].Add(l); } textwidths[kvp.Key] = new Vector2D(textlabels[kvp.Key][0].TextSize.Width, textlabels[kvp.Key][0].TextSize.Height); } SetEventLineColors(); }