// Serialize / deserialize new internal void ReadWrite(IReadWriteStream s) { if (!s.IsWriting) { BeforePropsChange(); } base.ReadWrite(s); if (s.IsWriting) { s.wInt(flags.Count); foreach (KeyValuePair <string, bool> f in flags) { s.wString(f.Key); s.wBool(f.Value); } } else { int c; s.rInt(out c); flags = new Dictionary <string, bool>(c, StringComparer.Ordinal); for (int i = 0; i < c; i++) { string t; s.rString(out t); bool b; s.rBool(out b); flags.Add(t, b); } } s.rwInt(ref type); s.rwVector3D(ref pos); s.rwInt(ref angledoom); s.rwInt(ref pitch); //mxd s.rwInt(ref roll); //mxd s.rwDouble(ref scaleX); //mxd s.rwDouble(ref scaleY); //mxd s.rwInt(ref tag); s.rwInt(ref action); for (int i = 0; i < NUM_ARGS; i++) { s.rwInt(ref args[i]); } if (!s.IsWriting) { anglerad = Angle2D.DoomToReal(angledoom); UpdateCache(); //mxd } }
// This reads the THINGS from WAD file private void ReadThings(MapSet map, int firstindex) { MemoryStream mem; BinaryReader reader; int num, i, x, y, type, flags; Dictionary <string, bool> stringflags; float angle; Thing t; // Get the lump from wad file Lump lump = wad.FindLump("THINGS", firstindex); if (lump == null) { throw new Exception("Could not find required lump THINGS!"); } // Prepare to read the items mem = new MemoryStream(lump.Stream.ReadAllBytes()); num = (int)lump.Stream.Length / 10; reader = new BinaryReader(mem); // Read items from the lump map.SetCapacity(0, 0, 0, 0, map.Things.Count + num); for (i = 0; i < num; i++) { // Read properties from stream x = reader.ReadInt16(); y = reader.ReadInt16(); angle = Angle2D.DoomToReal(reader.ReadInt16()); type = reader.ReadUInt16(); flags = reader.ReadUInt16(); // Make string flags stringflags = new Dictionary <string, bool>(); foreach (KeyValuePair <string, string> f in manager.Config.ThingFlags) { int fnum; if (int.TryParse(f.Key, out fnum)) { stringflags[f.Key] = ((flags & fnum) == fnum); } } // Create new item t = map.CreateThing(); t.Update(type, x, y, 0, angle, stringflags, 0, 0, new int[Thing.NUM_ARGS]); } // Done mem.Dispose(); }
// This rotates the thing public void Rotate(int newangle) { BeforePropsChange(); // Change angle anglerad = Angle2D.DoomToReal(newangle); angledoom = newangle; if (type != General.Map.Config.Start3DModeThingType) { General.Map.IsChanged = true; } }
// This reads the things private void ReadThings(MapSet map, UniversalParser textmap) { // Get list of entries List <UniversalCollection> collections = GetNamedCollections(textmap.Root, "thing"); // Go for all collections map.SetCapacity(0, 0, 0, 0, map.Things.Count + collections.Count); for (int i = 0; i < collections.Count; i++) { // Read fields UniversalCollection c = collections[i]; int[] args = new int[Linedef.NUM_ARGS]; string where = "thing " + i; float x = GetCollectionEntry <float>(c, "x", true, 0.0f, where); float y = GetCollectionEntry <float>(c, "y", true, 0.0f, where); float height = GetCollectionEntry <float>(c, "height", false, 0.0f, where); int tag = GetCollectionEntry <int>(c, "id", false, 0, where); int angledeg = GetCollectionEntry <int>(c, "angle", false, 0, where); int type = GetCollectionEntry <int>(c, "type", true, 0, where); int special = GetCollectionEntry <int>(c, "special", false, 0, where); args[0] = GetCollectionEntry <int>(c, "arg0", false, 0, where); args[1] = GetCollectionEntry <int>(c, "arg1", false, 0, where); args[2] = GetCollectionEntry <int>(c, "arg2", false, 0, where); args[3] = GetCollectionEntry <int>(c, "arg3", false, 0, where); args[4] = GetCollectionEntry <int>(c, "arg4", false, 0, where); // Flags Dictionary <string, bool> stringflags = new Dictionary <string, bool>(); foreach (KeyValuePair <string, string> flag in General.Map.Config.ThingFlags) { stringflags[flag.Key] = GetCollectionEntry <bool>(c, flag.Key, false, false, where); } foreach (FlagTranslation ft in General.Map.Config.ThingFlagsTranslation) { foreach (string field in ft.Fields) { stringflags[field] = GetCollectionEntry <bool>(c, field, false, false, where); } } // Create new item Thing t = map.CreateThing(); if (t != null) { t.Update(type, x, y, height, Angle2D.DoomToReal(angledeg), stringflags, tag, special, args); // Custom fields ReadCustomFields(c, t, "thing"); } } }
// This updates all properties // NOTE: This does not update sector! (call DetermineSector) public void Update(int type, float x, float y, float zoffset, int angle, Dictionary <string, bool> flags, int tag, int action, int[] args) { // Apply changes this.type = type; this.anglerad = Angle2D.DoomToReal(angle); this.angledoom = angle; this.flags = new Dictionary <string, bool>(flags); this.tag = tag; this.action = action; this.args = new int[NUM_ARGS]; args.CopyTo(this.args, 0); this.Move(x, y, zoffset); }
// 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 replacement int replaceangle = 0; if (replace) { // If it cannot be interpreted, set replacewith to null (not replacing at all) if (!int.TryParse(replacewith, out replaceangle)) { 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 angle; if (int.TryParse(value, out angle)) { // 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 (Angle2D.RealToDoom(t.Angle) == angle) { // Replace if (replace) { t.Rotate(Angle2D.DoomToReal(replaceangle)); } // 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 updates all properties // NOTE: This does not update sector! (call DetermineSector) public void Update(int type, double x, double y, double zoffset, int angle, int pitch, int roll, double scaleX, double scaleY, Dictionary <string, bool> flags, int tag, int action, int[] args) { // Apply changes this.type = type; this.anglerad = Angle2D.DoomToReal(angle); this.angledoom = angle; this.pitch = pitch; //mxd this.roll = roll; //mxd this.scaleX = (scaleX == 0 ? 1.0f : scaleX); //mxd this.scaleY = (scaleY == 0 ? 1.0f : scaleY); //mxd this.flags = new Dictionary <string, bool>(flags); this.tag = tag; this.action = action; this.args = new int[NUM_ARGS]; args.CopyTo(this.args, 0); this.Move(x, y, zoffset); UpdateCache(); //mxd }
public void ThingRotateRight() { // Make list of selected things List <Thing> selected = new List <Thing>(General.Map.Map.GetSelectedThings(true)); if ((selected.Count == 0) && (highlighted != null) && !highlighted.IsDisposed) { selected.Add(highlighted); } // Anything to do? if (selected.Count > 0) { // Make undo if (selected.Count > 1) { General.Map.UndoRedo.CreateUndo("Rotate " + selected.Count + " things"); General.Interface.DisplayStatus(StatusType.Action, "Rotated " + selected.Count + " things."); } else { General.Map.UndoRedo.CreateUndo("Rotate thing"); General.Interface.DisplayStatus(StatusType.Action, "Rotated a thing."); } foreach (Thing t in selected) { int angle; angle = Angle2D.RealToDoom(t.Angle); angle -= 45; t.Rotate(Angle2D.DoomToReal(angle)); } General.Map.IsChanged = true; General.Map.ThingsFilter.Update(); General.Interface.RefreshInfo(); General.Interface.RedrawDisplay(); } }
// This makes sure we are updated with the source linedef information public override void Update() { ThingData td = data.Mode.GetThingData(thing); Thing t = thing; // Floor slope thing if (t.Type == 9502) { t.DetermineSector(data.Mode.BlockMap); if (t.Sector != null) { //mxd. Vertex zheight overrides this effect if (General.Map.UDMF && t.Sector.Sidedefs.Count == 3) { foreach (Sidedef side in t.Sector.Sidedefs) { if (!double.IsNaN(side.Line.Start.ZFloor) || !double.IsNaN(side.Line.End.ZFloor)) { return; } } } double angle = Angle2D.DoomToReal((int)Angle2D.RadToDeg(t.Angle)); double vangle = Angle2D.DegToRad(General.Clamp(t.Args[0], 0, 180)); //mxd. Don't underestimate user stupidity (or curiosity)! Vector2D point = new Vector2D(t.Position.x + Math.Cos(angle) * Math.Sin(vangle), t.Position.y + Math.Sin(angle) * Math.Sin(vangle)); Vector2D perpendicular = new Line2D(t.Position, point).GetPerpendicular(); Vector3D v1 = new Vector3D(t.Position.x, t.Position.y, t.Position.z + t.Sector.FloorHeight); Vector3D v2 = new Vector3D( point.x + perpendicular.x, point.y + perpendicular.y, t.Position.z + t.Sector.FloorHeight + Math.Cos(vangle) ); Vector3D v3 = new Vector3D( point.x - perpendicular.x, point.y - perpendicular.y, t.Position.z + t.Sector.FloorHeight + Math.Cos(vangle) ); SectorData sd = data.Mode.GetSectorData(t.Sector); sd.AddUpdateSector(data.Sector, true); if (!sd.Updated) { sd.Update(); } td.AddUpdateSector(t.Sector, true); sd.Floor.plane = new Plane(v1, v2, v3, true); } } // Ceiling slope thing else if (t.Type == 9503) { t.DetermineSector(data.Mode.BlockMap); if (t.Sector != null) { //mxd. Vertex zheight overrides this effect if (General.Map.UDMF && t.Sector.Sidedefs.Count == 3) { foreach (Sidedef side in t.Sector.Sidedefs) { if (!double.IsNaN(side.Line.Start.ZCeiling) || !double.IsNaN(side.Line.End.ZCeiling)) { return; } } } double angle = Angle2D.DoomToReal((int)Angle2D.RadToDeg(t.Angle)); double vangle = Angle2D.DegToRad(General.Clamp(t.Args[0], 0, 180)); //mxd. Don't underestimate user stupidity (or curiosity)! Vector2D point = new Vector2D(t.Position.x + Math.Cos(angle) * Math.Sin(vangle), t.Position.y + Math.Sin(angle) * Math.Sin(vangle)); Vector2D perpendicular = new Line2D(t.Position, point).GetPerpendicular(); Vector3D v1 = new Vector3D(t.Position.x, t.Position.y, t.Position.z + t.Sector.CeilHeight); Vector3D v2 = new Vector3D( point.x + perpendicular.x, point.y + perpendicular.y, t.Position.z + t.Sector.CeilHeight + Math.Cos(vangle) ); Vector3D v3 = new Vector3D( point.x - perpendicular.x, point.y - perpendicular.y, t.Position.z + t.Sector.CeilHeight + Math.Cos(vangle) ); SectorData sd = data.Mode.GetSectorData(t.Sector); sd.AddUpdateSector(data.Sector, true); if (!sd.Updated) { sd.Update(); } td.AddUpdateSector(t.Sector, true); sd.Ceiling.plane = new Plane(v1, v2, v3, false); } } }
public override void Browse(IWin32Window parent) { value = Angle2D.DoomToReal(AngleForm.ShowDialog(parent, Angle2D.RealToDoom(value))); }
/// <summary> /// This loads all nodes structures data from the lumps /// </summary> private void LoadStructures() { // Load the nodes structure MemoryStream nodesstream = General.Map.GetLumpData("NODES"); BinaryReader nodesreader = new BinaryReader(nodesstream); int numnodes = (int)nodesstream.Length / 28; nodes = new Node[numnodes]; for (int i = 0; i < nodes.Length; i++) { nodes[i].linestart.x = nodesreader.ReadInt16(); nodes[i].linestart.y = nodesreader.ReadInt16(); nodes[i].linedelta.x = nodesreader.ReadInt16(); nodes[i].linedelta.y = nodesreader.ReadInt16(); float top = nodesreader.ReadInt16(); float bot = nodesreader.ReadInt16(); float left = nodesreader.ReadInt16(); float right = nodesreader.ReadInt16(); nodes[i].rightbox = new RectangleF(left, top, (right - left), (bot - top)); top = nodesreader.ReadInt16(); bot = nodesreader.ReadInt16(); left = nodesreader.ReadInt16(); right = nodesreader.ReadInt16(); nodes[i].leftbox = new RectangleF(left, top, (right - left), (bot - top)); int rightindex = nodesreader.ReadInt16(); int leftindex = nodesreader.ReadInt16(); nodes[i].rightchild = rightindex & 0x7FFF; nodes[i].leftchild = leftindex & 0x7FFF; nodes[i].rightsubsector = (rightindex & 0x8000) != 0; nodes[i].leftsubsector = (leftindex & 0x8000) != 0; } nodesreader.Close(); nodesstream.Close(); nodesstream.Dispose(); // Add additional properties to nodes nodes[nodes.Length - 1].parent = -1; RecursiveSetupNodes(nodes.Length - 1); // Load the segs structure MemoryStream segsstream = General.Map.GetLumpData("SEGS"); BinaryReader segsreader = new BinaryReader(segsstream); int numsegs = (int)segsstream.Length / 12; segs = new Seg[numsegs]; for (int i = 0; i < segs.Length; i++) { segs[i].startvertex = segsreader.ReadInt16(); segs[i].endvertex = segsreader.ReadInt16(); segs[i].angle = Angle2D.DoomToReal(segsreader.ReadInt16()); segs[i].lineindex = segsreader.ReadInt16(); segs[i].leftside = segsreader.ReadInt16() != 0; segs[i].offset = segsreader.ReadInt16(); } segsreader.Close(); segsstream.Close(); segsstream.Dispose(); // Load the vertexes structure MemoryStream vertsstream = General.Map.GetLumpData("VERTEXES"); BinaryReader vertsreader = new BinaryReader(vertsstream); int numverts = (int)vertsstream.Length / 4; verts = new Vector2D[numverts]; for (int i = 0; i < verts.Length; i++) { verts[i].x = vertsreader.ReadInt16(); verts[i].y = vertsreader.ReadInt16(); } vertsreader.Close(); vertsstream.Close(); vertsstream.Dispose(); // Load the subsectors structure MemoryStream ssecstream = General.Map.GetLumpData("SSECTORS"); BinaryReader ssecreader = new BinaryReader(ssecstream); int numssec = (int)ssecstream.Length / 4; ssectors = new Subsector[numssec]; for (int i = 0; i < ssectors.Length; i++) { ssectors[i].numsegs = ssecreader.ReadInt16(); ssectors[i].firstseg = ssecreader.ReadInt16(); } ssecreader.Close(); ssecstream.Close(); ssecstream.Dispose(); // Link all segs to their subsectors for (int i = 0; i < ssectors.Length; i++) { int lastseg = ssectors[i].firstseg + ssectors[i].numsegs - 1; for (int sg = ssectors[i].firstseg; sg <= lastseg; sg++) { segs[sg].ssector = i; } } }
// Apply clicked private void apply_Click(object sender, EventArgs e) { List <string> defaultflags = new List <string>(); string undodesc = "thing"; // Verify the tag if (General.Map.FormatInterface.HasThingTag && ((tag.GetResult(0) < General.Map.FormatInterface.MinTag) || (tag.GetResult(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 (((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; } // Make undo if (things.Count > 1) { undodesc = things.Count + " things"; } General.Map.UndoRedo.CreateUndo("Edit " + undodesc); // Go for all the things foreach (Thing t in things) { // Thing type index t.Type = General.Clamp(thingtype.GetResult(t.Type), General.Map.FormatInterface.MinThingType, General.Map.FormatInterface.MaxThingType); // Coordination t.Rotate(Angle2D.DoomToReal(angle.GetResult(Angle2D.RealToDoom(t.Angle)))); t.Move(t.Position.x, t.Position.y, (float)height.GetResult((int)t.Position.z)); // Apply all flags foreach (CheckBox c in flags.Checkboxes) { if (c.CheckState == CheckState.Checked) { t.SetFlag(c.Tag.ToString(), true); } else if (c.CheckState == CheckState.Unchecked) { t.SetFlag(c.Tag.ToString(), false); } } // Action/tags t.Tag = tag.GetResult(t.Tag); if (!action.Empty) { t.Action = action.Value; } t.Args[0] = arg0.GetResult(t.Args[0]); t.Args[1] = arg1.GetResult(t.Args[1]); t.Args[2] = arg2.GetResult(t.Args[2]); t.Args[3] = arg3.GetResult(t.Args[3]); t.Args[4] = arg4.GetResult(t.Args[4]); // Custom fields fieldslist.Apply(t.Fields); // Update settings t.UpdateConfiguration(); } // 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; this.DialogResult = DialogResult.OK; this.Close(); }