//mxd. This changes slope angle. Amount is in radians!
 protected override void ChangeAngle(float amount)
 {
     mode.CreateUndo("Change ceiling slope angle", UndoGroup.AngleChange, Sector.Sector.Index);
     Sector.Sector.SetFlag(General.Map.FormatInterface.SectorFlags.Sloped, true, false);
     Sector.Sector.CeilingSlope = General.Clamp(Sector.Sector.CeilingSlope - amount, General.Map.FormatInterface.MinSlope, General.Map.FormatInterface.MaxSlope);
     mode.SetActionResult("Changed ceiling slope angle to " + Math.Round(Angle2D.RadToDeg(Sector.Sector.CeilingSlope) - 90, 1) + ".");
 }
Exemplo n.º 2
0
        //mxd. This calculates wall brightness level with doom-style shading
        public int CalculateBrightness(int level, Sidedef sd)
        {
            if (level < 253 && sd != null)
            {
                bool evenlighting   = General.Map.Data.MapInfo.EvenLighting;
                bool smoothlighting = General.Map.Data.MapInfo.SmoothLighting;

                //check for possiburu UDMF overrides
                if (General.Map.UDMF)
                {
                    if (sd.IsFlagSet("lightabsolute") && sd.Fields.ContainsKey("light"))
                    {
                        evenlighting = true;
                    }
                    else
                    {
                        if (sd.IsFlagSet("nofakecontrast"))
                        {
                            evenlighting = true;
                        }
                        if (sd.IsFlagSet("smoothlighting"))
                        {
                            smoothlighting = true;
                        }
                    }
                }

                if (!evenlighting)
                {
                    //all walls are shaded by their angle
                    if (smoothlighting)
                    {
                        float ammount  = Math.Abs((float)Math.Sin(sd.Angle));
                        int   hAmmount = (int)((1.0f - ammount) * General.Map.Data.MapInfo.HorizWallShade);
                        int   vAmmount = (int)(ammount * General.Map.Data.MapInfo.VertWallShade);

                        level = General.Clamp(level - hAmmount - vAmmount, 0, 255);
                    }
                    else                     //only horizontal/verticel walls are shaded
                    {
                        switch ((int)Angle2D.RadToDeg(sd.Angle))
                        {
                        // Horizontal wall
                        case 90:
                        case 270:
                            level = General.Clamp(level + General.Map.Data.MapInfo.HorizWallShade, 0, 255);
                            break;

                        // Vertical wall
                        case 180:
                        case 0:
                            level = General.Clamp(level + General.Map.Data.MapInfo.VertWallShade, 0, 255);
                            break;
                        }
                    }
                }
            }

            return(CalculateBrightness(level));
        }
Exemplo n.º 3
0
 //mxd. This updates the sprite frame to be rendered
 internal void UpdateSpriteFrame()
 {
     if (textures.Length != 8)
     {
         spriteframe = 0;
     }
     else
     {
         spriteframe = (General.ClampAngle((int)Angle2D.RadToDeg((General.Map.VisualCamera.Position - thing.Position).GetAngleXY()) - thing.AngleDoom + 292)) / 45;                 // Convert to [0..7] range; 292 == 270 + 45/2
     }
 }
Exemplo n.º 4
0
        internal SlopeArchForm(SlopeArcher slopearcher)
        {
            InitializeComponent();
            this.slopearcher = slopearcher;

            oldtheta             = originaltheta = Math.Round(Angle2D.RadToDeg(this.slopearcher.Theta), 2);
            oldoffset            = originaloffset = Math.Round(Angle2D.RadToDeg(this.slopearcher.OffsetAngle), 2);
            oldscale             = originalscale = this.slopearcher.Scale;
            originalheightoffset = this.slopearcher.HeightOffset;

            theta.Text        = originaltheta.ToString();
            offset.Text       = originaloffset.ToString();
            scale.Text        = (originalscale * 100.0).ToString();
            heightoffset.Text = originalheightoffset.ToString();
        }
        // This updates the text
        protected virtual void UpdateText()
        {
            Vector2D delta = end - start;

            // Update label text
            float length = delta.GetLength();

            if (showangle)
            {
                int displayangle = General.ClampAngle((int)Math.Round(Angle2D.RadToDeg(delta.GetAngle())));
                label.Text = "L:" + length.ToString(VALUE_FORMAT) + "; A:" + displayangle;
            }
            else
            {
                label.Text = length.ToString(VALUE_FORMAT);
            }
        }
Exemplo n.º 6
0
        // This sets the dynamic values
        public void ShowCurrentValues(Vector2D pos, Vector2D relpos, Vector2D size, Vector2D relsize, float rotation)
        {
            // Set values
            this.abspos = pos;
            this.relpos = relpos;
            this.abssize = size;
            this.relsize = relsize;
            this.absrotate = Angle2D.RadToDeg(rotation);

            // Set controls
            absposx.Text = pos.x.ToString("0.#");
            absposy.Text = pos.y.ToString("0.#");
            relposx.Text = relpos.x.ToString("0.#");
            relposy.Text = relpos.y.ToString("0.#");
            abssizex.Text = size.x.ToString("0.#");
            abssizey.Text = size.y.ToString("0.#");
            relsizex.Text = relsize.x.ToString("0.#");
            relsizey.Text = relsize.y.ToString("0.#");
            absrot.Text = this.absrotate.ToString("0.#");

            userinput = false;
        }
Exemplo n.º 7
0
        // Texture offset change
        public virtual void OnChangeTextureOffset(int horizontal, int vertical, bool doSurfaceAngleCorrection)
        {
            if (horizontal == 0 && vertical == 0)
            {
                return;                                              //mxd
            }
            //mxd
            if (!General.Map.UDMF)
            {
                General.Interface.DisplayStatus(StatusType.Warning, "Floor/ceiling texture offsets cannot be changed in this map format!");
                return;
            }

            if ((General.Map.UndoRedo.NextUndo == null) || (General.Map.UndoRedo.NextUndo.TicketID != undoticket))
            {
                undoticket = mode.CreateUndo("Change texture offsets");
            }

            //mxd
            changed = true;

            //mxd
            if (doSurfaceAngleCorrection)
            {
                Point p     = new Point(horizontal, vertical);
                float angle = Angle2D.RadToDeg(General.Map.VisualCamera.AngleXY);
                if (GeometryType == VisualGeometryType.CEILING)
                {
                    angle += level.sector.Fields.GetValue("rotationceiling", 0f);
                }
                else
                {
                    angle += level.sector.Fields.GetValue("rotationfloor", 0f);
                }

                angle = General.ClampAngle(angle);

                if (angle > 315 || angle < 46)
                {
                    //already correct
                }
                else if (angle > 225)
                {
                    vertical   = p.X;
                    horizontal = -p.Y;
                }
                else if (angle > 135)
                {
                    horizontal = -p.X;
                    vertical   = -p.Y;
                }
                else
                {
                    vertical   = -p.X;
                    horizontal = p.Y;
                }
            }

            // Apply offsets
            MoveTextureOffset(-horizontal, -vertical);

            // Rebuild sector
            BaseVisualSector vs;

            if (mode.VisualSectorExists(level.sector))
            {
                vs = (BaseVisualSector)mode.GetVisualSector(level.sector);
            }
            else
            {
                //mxd. Need this to apply changes to 3d-floor even if control sector doesn't exist as BaseVisualSector
                vs = mode.CreateBaseVisualSector(level.sector);
            }

            if (vs != null)
            {
                vs.UpdateSectorGeometry(false);
            }
        }
Exemplo n.º 8
0
        // 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(angle.GetResult(t.AngleDoom));
                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;
            Cleanup();
            this.DialogResult = DialogResult.OK;
            this.Close();
        }
Exemplo n.º 9
0
        // 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);
                }
            }
        }
Exemplo n.º 10
0
        // Apply clicked
        private void apply_Click(object sender, EventArgs e)
        {
            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
                if (cbRandomAngle.Checked)                //mxd
                {
                    int newangle = General.Random(0, 359);
                    if (General.Map.Config.DoomThingRotationAngles)
                    {
                        newangle = newangle / 45 * 45;
                    }
                    t.Rotate(newangle);
                }

                //mxd. Check position
                float px = General.Clamp(t.Position.x, General.Map.Config.LeftBoundary, General.Map.Config.RightBoundary);
                float 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));
                }

                // Apply all flags
                foreach (CheckBox c in flags.Checkboxes)
                {
                    switch (c.CheckState)
                    {
                    case CheckState.Checked: t.SetFlag(c.Tag.ToString(), true); break;

                    case CheckState.Unchecked: t.SetFlag(c.Tag.ToString(), false); break;
                    }
                }

                // 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);

                // 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();
        }
Exemplo n.º 11
0
        // 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();
        }
Exemplo n.º 12
0
        // OK clicked
        private void apply_Click(object sender, EventArgs e)
        {
            // Verify properties
            if (!VerifyValue(hitag.GetResult(0), General.Map.FormatInterface.MinTag, General.Map.FormatInterface.MaxTag, "Sector hitag"))
            {
                return;
            }
            if (!VerifyValue(lotag.GetResult(0), General.Map.FormatInterface.MinTag, General.Map.FormatInterface.MaxTag, "Sector lotag"))
            {
                return;
            }
            if (!VerifyValue(extra.GetResult(0), General.Map.FormatInterface.MinExtra, General.Map.FormatInterface.MaxExtra, "Sector extra"))
            {
                return;
            }
            if (!VerifyValue(ceilpalette.GetResult(0), 0, 255, "Ceiling palette"))
            {
                return;
            }
            if (!VerifyValue(floorpalette.GetResult(0), 0, 255, "Floor palette"))
            {
                return;
            }

            // Make undo
            General.Map.UndoRedo.CreateUndo("Edit " + (sectors.Count > 1 ? sectors.Count + " sectors" : "sector"));

            // Collect flags...
            Dictionary <string, CheckState> floorflagsstate = new Dictionary <string, CheckState>();

            foreach (CheckBox c in floorflags.Checkboxes)
            {
                floorflagsstate[c.Tag.ToString()] = c.CheckState;
            }

            Dictionary <string, CheckState> ceilflagsstate = new Dictionary <string, CheckState>();

            foreach (CheckBox c in ceilflags.Checkboxes)
            {
                ceilflagsstate[c.Tag.ToString()] = c.CheckState;
            }

            // Update slope flags?
            float ceilslopedeg = ceilslope.GetResultFloat(VALUE_MISMATCH);

            if (ceilslopedeg != VALUE_MISMATCH)
            {
                ceilflagsstate[General.Map.FormatInterface.SectorFlags.Sloped] = (ceilslopedeg != 0 ? CheckState.Checked : CheckState.Unchecked);
            }

            float floorslopedeg = floorslope.GetResultFloat(VALUE_MISMATCH);

            if (floorslopedeg != VALUE_MISMATCH)
            {
                floorflagsstate[General.Map.FormatInterface.SectorFlags.Sloped] = (floorslopedeg != 0 ? CheckState.Checked : CheckState.Unchecked);
            }

            // Go for all sectors
            foreach (Sector s in sectors)
            {
                // Floor/ceiling
                s.FloorHeight   = floorheight.GetResult(s.FloorHeight);
                s.CeilingHeight = ceilheight.GetResult(s.CeilingHeight);
                s.Visibility    = visibility.GetResult(s.Visibility);

                // Ceiling
                foreach (KeyValuePair <string, CheckState> group in ceilflagsstate)
                {
                    switch (group.Value)
                    {
                    case CheckState.Checked: s.SetFlag(group.Key, true, false); break;

                    case CheckState.Unchecked: s.SetFlag(group.Key, false, false); break;
                    }
                }

                s.CeilingTileIndex    = General.Clamp(ceiltex.GetResult(s.CeilingTileIndex), General.Map.FormatInterface.MinTileIndex, General.Map.FormatInterface.MaxTileIndex);
                s.CeilingOffsetX      = General.Wrap(ceiloffsetx.GetResult(s.CeilingOffsetX), General.Map.FormatInterface.MinImageOffset, General.Map.FormatInterface.MaxImageOffset);
                s.CeilingOffsetY      = General.Wrap(ceiloffsety.GetResult(s.CeilingOffsetY), General.Map.FormatInterface.MinImageOffset, General.Map.FormatInterface.MaxImageOffset);
                s.CeilingShade        = General.Clamp(ceilshade.GetResult(s.CeilingShade), General.Map.FormatInterface.MinShade, General.Map.FormatInterface.MaxShade);
                s.CeilingPaletteIndex = ceilpalette.GetResult(s.CeilingPaletteIndex);
                s.CeilingSlope        = General.Clamp(Angle2D.DegToRad(ceilslope.GetResultFloat(Angle2D.RadToDeg(s.CeilingSlope) - 90) + 90), General.Map.FormatInterface.MinSlope, General.Map.FormatInterface.MaxSlope);

                // Floor
                foreach (KeyValuePair <string, CheckState> group in floorflagsstate)
                {
                    switch (group.Value)
                    {
                    case CheckState.Checked: s.SetFlag(group.Key, true, true); break;

                    case CheckState.Unchecked: s.SetFlag(group.Key, false, true); break;
                    }
                }

                s.FloorTileIndex    = General.Clamp(floortex.GetResult(s.FloorTileIndex), General.Map.FormatInterface.MinTileIndex, General.Map.FormatInterface.MaxTileIndex);
                s.FloorOffsetX      = General.Wrap(flooroffsetx.GetResult(s.FloorOffsetX), General.Map.FormatInterface.MinImageOffset, General.Map.FormatInterface.MaxImageOffset);
                s.FloorOffsetY      = General.Wrap(flooroffsety.GetResult(s.FloorOffsetY), General.Map.FormatInterface.MinImageOffset, General.Map.FormatInterface.MaxImageOffset);
                s.FloorShade        = General.Clamp(floorshade.GetResult(s.FloorShade), General.Map.FormatInterface.MinShade, General.Map.FormatInterface.MaxShade);
                s.FloorPaletteIndex = floorpalette.GetResult(s.FloorPaletteIndex);
                s.FloorSlope        = General.Clamp(Angle2D.DegToRad(floorslope.GetResultFloat(Angle2D.RadToDeg(s.FloorSlope) - 90) + 90), General.Map.FormatInterface.MinSlope, General.Map.FormatInterface.MaxSlope);

                // Identification
                s.HiTag = hitag.GetResult(s.HiTag);
                s.LoTag = lotag.GetResult(s.LoTag);
                s.Extra = extra.GetResult(s.Extra);
            }

            // Update the used textures
            General.Map.Data.UpdateUsedImages();

            // Done
            General.Map.IsChanged = true;
            this.DialogResult     = DialogResult.OK;
            this.Close();
        }
Exemplo n.º 13
0
        //mxd
        protected void AlignTextureToClosestLine(bool alignx, bool aligny)
        {
            if (!(mode.HighlightedObject is BaseVisualSector))
            {
                return;
            }

            // Do we need to align this? (and also grab texture scale while we are at it)
            float scaleX, scaleY;
            bool  isFloor = (geometrytype == VisualGeometryType.FLOOR);

            if (mode.HighlightedTarget is VisualFloor)
            {
                VisualFloor target = (VisualFloor)mode.HighlightedTarget;

                // Check texture
                if (target.Sector.Sector.FloorTexture != (isFloor ? Sector.Sector.FloorTexture : Sector.Sector.CeilTexture))
                {
                    return;
                }

                scaleX = target.Sector.Sector.Fields.GetValue("xscalefloor", 1.0f);
                scaleY = target.Sector.Sector.Fields.GetValue("yscalefloor", 1.0f);
            }
            else
            {
                VisualCeiling target = (VisualCeiling)mode.HighlightedTarget;

                // Check texture
                if (target.Sector.Sector.CeilTexture != (isFloor ? Sector.Sector.FloorTexture : Sector.Sector.CeilTexture))
                {
                    return;
                }

                scaleX = target.Sector.Sector.Fields.GetValue("xscaleceiling", 1.0f);
                scaleY = target.Sector.Sector.Fields.GetValue("yscaleceiling", 1.0f);
            }

            //find a linedef to align to
            Vector2D hitpos = mode.GetHitPosition();

            if (!hitpos.IsFinite())
            {
                return;
            }

            //align to line of highlighted sector, which is closest to hitpos
            Sector         highlightedSector = ((BaseVisualSector)mode.HighlightedObject).Sector;
            List <Linedef> lines             = new List <Linedef>();

            foreach (Sidedef side in highlightedSector.Sidedefs)
            {
                lines.Add(side.Line);
            }

            Linedef targetLine = MapSet.NearestLinedef(lines, hitpos);

            if (targetLine == null)
            {
                return;
            }

            bool isFront = targetLine.SideOfLine(hitpos) > 0;

            Sector.Sector.Fields.BeforeFieldsChange();

            //find an angle to rotate texture
            float sourceAngle = (float)Math.Round(General.ClampAngle(isFront ? -Angle2D.RadToDeg(targetLine.Angle) + 90 : -Angle2D.RadToDeg(targetLine.Angle) - 90), 1);

            if (!isFront)
            {
                sourceAngle = General.ClampAngle(sourceAngle + 180);
            }

            //update angle
            UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "rotationfloor" : "rotationceiling"), sourceAngle, 0f);

            //set scale
            UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "xscalefloor" : "xscaleceiling"), scaleX, 1.0f);
            UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "yscalefloor" : "yscaleceiling"), scaleY, 1.0f);

            //update offset
            float    distToStart = Vector2D.Distance(hitpos, targetLine.Start.Position);
            float    distToEnd   = Vector2D.Distance(hitpos, targetLine.End.Position);
            Vector2D offset      = (distToStart < distToEnd ? targetLine.Start.Position : targetLine.End.Position).GetRotated(Angle2D.DegToRad(sourceAngle));

            if (alignx)
            {
                if (Texture != null && Texture.IsImageLoaded)
                {
                    offset.x %= Texture.Width / scaleX;
                }
                UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "xpanningfloor" : "xpanningceiling"), (float)Math.Round(-offset.x), 0f);
            }

            if (aligny)
            {
                if (Texture != null && Texture.IsImageLoaded)
                {
                    offset.y %= Texture.Height / scaleY;
                }
                UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "ypanningfloor" : "ypanningceiling"), (float)Math.Round(offset.y), 0f);
            }

            //update geometry
            Sector.UpdateSectorGeometry(false);
        }
        // Texture offset change
        public virtual void OnChangeTextureOffset(int horizontal, int vertical, bool doSurfaceAngleCorrection)
        {
            if (horizontal == 0 && vertical == 0)
            {
                return;                                              //mxd
            }
            //mxd
            if (!General.Map.UDMF)
            {
                General.Interface.DisplayStatus(StatusType.Warning, "Floor/ceiling texture offsets cannot be changed in this map format!");
                return;
            }

            if ((General.Map.UndoRedo.NextUndo == null) || (General.Map.UndoRedo.NextUndo.TicketID != undoticket))
            {
                undoticket = mode.CreateUndo("Change texture offsets");
            }

            //mxd
            if (doSurfaceAngleCorrection)
            {
                Point p     = new Point(horizontal, vertical);
                float angle = Angle2D.RadToDeg(General.Map.VisualCamera.AngleXY);
                if (GeometryType == VisualGeometryType.CEILING)
                {
                    angle += level.sector.Fields.GetValue("rotationceiling", 0f);
                }
                else
                {
                    angle += level.sector.Fields.GetValue("rotationfloor", 0f);
                }

                angle = General.ClampAngle(angle);

                if (angle > 315 || angle < 46)
                {
                    //already correct
                }
                else if (angle > 225)
                {
                    vertical   = p.X;
                    horizontal = -p.Y;
                }
                else if (angle > 135)
                {
                    horizontal = -p.X;
                    vertical   = -p.Y;
                }
                else
                {
                    vertical   = -p.X;
                    horizontal = p.Y;
                }
            }

            // Apply offsets
            MoveTextureOffset(new Point(-horizontal, -vertical));

            // Update sector geometry
            Sector s = GetControlSector();

            if (s.Index != Sector.Sector.Index)
            {
                s.UpdateNeeded = true;
                s.UpdateCache();
                mode.GetSectorData(s).Update();
                BaseVisualSector vs = (BaseVisualSector)mode.GetVisualSector(s);
                vs.UpdateSectorGeometry(false);
                vs.Rebuild();
            }

            Sector.Sector.UpdateNeeded = true;
            Sector.Sector.UpdateCache();
            Sector.UpdateSectorGeometry(false);
            Sector.Rebuild();
        }
Exemplo n.º 15
0
        // This moves the selected things relatively
        // Returns true when things has actually moved
        private bool MoveThingsRelative(Vector2D offset, bool snapgrid, bool snapgridincrement, bool snapnearest, bool snapcardinal)
        {
            //mxd. If snap to cardinal directions is enabled, modify the offset
            if (snapcardinal)
            {
                float angle = Angle2D.DegToRad((General.ClampAngle((int)Angle2D.RadToDeg(offset.GetAngle()) + 44)) / 90 * 90);
                offset            = new Vector2D(0, -offset.GetLength()).GetRotated(angle);
                snapgridincrement = true;                 // We don't want to move Things away from the cardinal directions
            }

            Vector2D oldpos = dragitem.Position;
            Vector2D tl, br;

            // don't move if the offset contains invalid data
            if (!offset.IsFinite())
            {
                return(false);
            }

            // Find the outmost things
            tl = br = oldpositions[0];
            for (int i = 0; i < oldpositions.Count; i++)
            {
                if (oldpositions[i].x < tl.x)
                {
                    tl.x = (int)oldpositions[i].x;
                }
                if (oldpositions[i].x > br.x)
                {
                    br.x = (int)oldpositions[i].x;
                }
                if (oldpositions[i].y > tl.y)
                {
                    tl.y = (int)oldpositions[i].y;
                }
                if (oldpositions[i].y < br.y)
                {
                    br.y = (int)oldpositions[i].y;
                }
            }

            // Snap to nearest?
            if (snapnearest)
            {
                // Find nearest unselected item within selection range
                Thing nearest = MapSet.NearestThingSquareRange(unselectedthings, mousemappos, BuilderPlug.Me.StitchRange / renderer.Scale);
                if (nearest != null)
                {
                    // Move the dragged item
                    dragitem.Move((Vector2D)nearest.Position);

                    // Adjust the offset
                    offset = (Vector2D)nearest.Position - dragitemposition;

                    // Do not snap to grid!
                    snapgrid          = false;
                    snapgridincrement = false;                     //mxd
                }
            }

            // Snap to grid?
            if (snapgrid || snapgridincrement)
            {
                // Move the dragged item
                dragitem.Move(dragitemposition + offset);

                // Snap item to grid increment (mxd)
                if (snapgridincrement)
                {
                    dragitem.Move(General.Map.Grid.SnappedToGrid(dragitemposition + offset) - dragstartoffset);
                }
                else                 // Or to the grid itself
                {
                    dragitem.SnapToGrid();
                }

                // Adjust the offset
                offset += (Vector2D)dragitem.Position - (dragitemposition + offset);
            }

            // Make sure the offset is inside the map boundaries
            if (offset.x + tl.x < General.Map.Config.LeftBoundary)
            {
                offset.x = General.Map.Config.LeftBoundary - tl.x;
            }
            if (offset.x + br.x > General.Map.Config.RightBoundary)
            {
                offset.x = General.Map.Config.RightBoundary - br.x;
            }
            if (offset.y + tl.y > General.Map.Config.TopBoundary)
            {
                offset.y = General.Map.Config.TopBoundary - tl.y;
            }
            if (offset.y + br.y < General.Map.Config.BottomBoundary)
            {
                offset.y = General.Map.Config.BottomBoundary - br.y;
            }

            // Drag item moved?
            if ((!snapgrid && !snapgridincrement) || ((Vector2D)dragitem.Position != oldpos))
            {
                int i = 0;

                // Move selected geometry
                foreach (Thing t in selectedthings)
                {
                    // Move vertex from old position relative to the
                    // mouse position change since drag start
                    t.Move(oldpositions[i] + offset);

                    // Next
                    i++;
                }

                // Moved
                return(true);
            }
            else
            {
                // No changes
                return(false);
            }
        }
        //mxd
        protected void AlignTextureToClosestLine(bool alignx, bool aligny)
        {
            if (!(mode.HighlightedObject is BaseVisualSector))
            {
                return;
            }

            // Do we need to align this? (and also grab texture scale while we are at it)
            float scaleX, scaleY;
            bool  isFloor = (geometrytype == VisualGeometryType.FLOOR);

            if (mode.HighlightedTarget is VisualFloor)
            {
                Sector      target;
                VisualFloor vf = (VisualFloor)mode.HighlightedTarget;

                // Use the control sector if the floor belongs to a 3D floor
                if (vf.ExtraFloor == null)
                {
                    target = vf.Sector.Sector;
                }
                else
                {
                    target = vf.GetControlSector();
                }

                // Check texture
                if (target.FloorTexture != (isFloor ? Sector.Sector.FloorTexture : Sector.Sector.CeilTexture))
                {
                    return;
                }

                scaleX = target.Fields.GetValue("xscalefloor", 1.0f);
                scaleY = target.Fields.GetValue("yscalefloor", 1.0f);
            }
            else
            {
                Sector        target;
                VisualCeiling vc = (VisualCeiling)mode.HighlightedTarget;

                // Use the control sector if the ceiling belongs to a 3D floor
                if (vc.ExtraFloor == null)
                {
                    target = vc.Sector.Sector;
                }
                else
                {
                    target = vc.GetControlSector();
                }

                // Check texture
                if (target.CeilTexture != (isFloor ? Sector.Sector.FloorTexture : Sector.Sector.CeilTexture))
                {
                    return;
                }

                scaleX = target.Fields.GetValue("xscaleceiling", 1.0f);
                scaleY = target.Fields.GetValue("yscaleceiling", 1.0f);
            }

            //find a linedef to align to
            Vector2D hitpos = mode.GetHitPosition();

            if (!hitpos.IsFinite())
            {
                return;
            }

            //align to line of highlighted sector, which is closest to hitpos
            Sector         highlightedSector = ((BaseVisualSector)mode.HighlightedObject).Sector;
            List <Linedef> lines             = new List <Linedef>();

            foreach (Sidedef side in highlightedSector.Sidedefs)
            {
                lines.Add(side.Line);
            }

            Linedef targetLine = MapSet.NearestLinedef(lines, hitpos);

            if (targetLine == null)
            {
                return;
            }

            bool isFront = targetLine.SideOfLine(hitpos) > 0;

            Sector.Sector.Fields.BeforeFieldsChange();

            //find an angle to rotate texture
            float sourceAngle = (float)Math.Round(General.ClampAngle(isFront ? -Angle2D.RadToDeg(targetLine.Angle) + 90 : -Angle2D.RadToDeg(targetLine.Angle) - 90), 1);

            if (!isFront)
            {
                sourceAngle = General.ClampAngle(sourceAngle + 180);
            }

            //update angle
            UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "rotationfloor" : "rotationceiling"), sourceAngle, 0f);

            // Scale texture if it's a slope and the appropriate option is set
            if (level.plane.Normal.z != 1.0f && BuilderPlug.Me.ScaleTexturesOnSlopes != 2)
            {
                Vector2D basescale = new Vector2D(1.0f, 1.0f);

                // User wants to use the current scale as a base?
                if (BuilderPlug.Me.ScaleTexturesOnSlopes == 1)
                {
                    basescale.x = scaleX;
                    basescale.y = scaleY;
                }

                // Create a unit vector of the direction of the target line in 3D space
                Vector3D targetlinevector = new Line3D(new Vector3D(targetLine.Start.Position, level.plane.GetZ(targetLine.Start.Position)), new Vector3D(targetLine.End.Position, level.plane.GetZ(targetLine.End.Position))).GetDelta().GetNormal();

                // Get a perpendicular vector of the target line in 3D space. This is used to get the slope angle relative to the target line
                Vector3D targetlineperpendicular = Vector3D.CrossProduct(targetlinevector, level.plane.Normal);

                if (alignx)
                {
                    scaleX = Math.Abs(basescale.x * (1.0f / (float)Math.Cos(targetlinevector.GetAngleZ())));
                }

                if (aligny)
                {
                    scaleY = Math.Abs(basescale.y * (1.0f / (float)Math.Cos(targetlineperpendicular.GetAngleZ())));
                }
            }

            //set scale
            UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "xscalefloor" : "xscaleceiling"), scaleX, 1.0f);
            UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "yscalefloor" : "yscaleceiling"), scaleY, 1.0f);

            //update offset
            float    distToStart = Vector2D.Distance(hitpos, targetLine.Start.Position);
            float    distToEnd   = Vector2D.Distance(hitpos, targetLine.End.Position);
            Vector2D offset      = (distToStart < distToEnd ? targetLine.Start.Position : targetLine.End.Position).GetRotated(Angle2D.DegToRad(sourceAngle));

            if (alignx)
            {
                if (Texture != null && Texture.IsImageLoaded)
                {
                    offset.x %= Texture.Width / scaleX;
                }
                UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "xpanningfloor" : "xpanningceiling"), (float)Math.Round(-offset.x), 0f);
            }

            if (aligny)
            {
                if (Texture != null && Texture.IsImageLoaded)
                {
                    offset.y %= Texture.Height / scaleY;
                }
                UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "ypanningfloor" : "ypanningceiling"), (float)Math.Round(offset.y), 0f);
            }

            //update geometry
            Sector.UpdateSectorGeometry(false);
        }
Exemplo n.º 17
0
        // This moves the selected geometry relatively
        // Returns true when geometry has actually moved
        private bool MoveGeometryRelative(Vector2D offset, bool snapgrid, bool snapgridincrement, bool snapnearest, bool snapcardinal)
        {
            //mxd. If snap to cardinal directions is enabled, modify the offset
            if (snapcardinal)
            {
                double angle = Angle2D.DegToRad((General.ClampAngle((int)Angle2D.RadToDeg(offset.GetAngle()) + 44)) / 90 * 90);
                offset            = new Vector2D(0, -offset.GetLength()).GetRotated(angle);
                snapgridincrement = true;                 // We don't want to move the geometry away from the cardinal directions
            }

            Vector2D oldpos = dragitem.Position;
            Vector2D anchorpos = dragitemposition + offset;
            Vector2D tl, br;

            // don't move if the offset contains invalid data
            if (!offset.IsFinite())
            {
                return(false);
            }

            // Find the outmost vertices
            tl = br = oldpositions[0];
            for (int i = 0; i < oldpositions.Count; i++)
            {
                if (oldpositions[i].x < tl.x)
                {
                    tl.x = (int)oldpositions[i].x;
                }
                if (oldpositions[i].x > br.x)
                {
                    br.x = (int)oldpositions[i].x;
                }
                if (oldpositions[i].y > tl.y)
                {
                    tl.y = (int)oldpositions[i].y;
                }
                if (oldpositions[i].y < br.y)
                {
                    br.y = (int)oldpositions[i].y;
                }
            }

            // Snap to nearest?
            if (snapnearest)
            {
                // Find nearest unselected vertex within range
                Vertex nv = MapSet.NearestVertexSquareRange(unselectedverts, anchorpos, BuilderPlug.Me.StitchRange / renderer.Scale);
                if (nv != null)
                {
                    // Move the dragged item
                    dragitem.Move(nv.Position);

                    // Adjust the offset
                    offset = nv.Position - dragitemposition;

                    // Do not snap to grid!
                    snapgrid            = false;
                    snaptogridincrement = false;                     //mxd
                }
                else
                {
                    // Find the nearest unselected line within range
                    Linedef nl = MapSet.NearestLinedefRange(snaptolines, anchorpos, BuilderPlug.Me.StitchRange / renderer.Scale);
                    if (nl != null)
                    {
                        // Snap to grid?
                        if (snapgrid || snapgridincrement)
                        {
                            // Get grid intersection coordinates
                            List <Vector2D> coords = nl.GetGridIntersections(snapgridincrement ? dragstartoffset : new Vector2D(),
                                                                             General.Map.Grid.GridRotate, General.Map.Grid.GridOriginX, General.Map.Grid.GridOriginY);

                            // mxd. Do the rest only if we actually have some coordinates
                            if (coords.Count > 0)
                            {
                                // Find nearest grid intersection
                                double   found_distance = double.MaxValue;
                                Vector2D found_coord    = new Vector2D();

                                foreach (Vector2D v in coords)
                                {
                                    Vector2D delta = anchorpos - v;
                                    if (delta.GetLengthSq() < found_distance)
                                    {
                                        found_distance = delta.GetLengthSq();
                                        found_coord    = v;
                                    }
                                }

                                // Move the dragged item
                                dragitem.Move(found_coord);

                                // Align to line here
                                offset = found_coord - dragitemposition;

                                // Do not snap to grid anymore
                                snapgrid          = false;
                                snapgridincrement = false;                                 //mxd
                            }
                        }
                        else
                        {
                            // Move the dragged item
                            dragitem.Move(nl.NearestOnLine(anchorpos));

                            // Align to line here
                            offset = nl.NearestOnLine(anchorpos) - dragitemposition;
                        }
                    }
                }
            }

            // Snap to grid or grid increment?
            if (snapgrid || snapgridincrement)
            {
                // Move the dragged item
                dragitem.Move(anchorpos);

                // Snap item to grid increment
                if (snapgridincrement)                //mxd
                {
                    dragitem.Move(General.Map.Grid.SnappedToGrid(dragitem.Position) - dragstartoffset);
                }
                else                 // Or to the grid itself
                {
                    dragitem.SnapToGrid();
                }

                // Adjust the offset
                offset += dragitem.Position - anchorpos;
            }

            // Make sure the offset is inside the map boundaries
            if (offset.x + tl.x < General.Map.Config.LeftBoundary)
            {
                offset.x = General.Map.Config.LeftBoundary - tl.x;
            }
            if (offset.x + br.x > General.Map.Config.RightBoundary)
            {
                offset.x = General.Map.Config.RightBoundary - br.x;
            }
            if (offset.y + tl.y > General.Map.Config.TopBoundary)
            {
                offset.y = General.Map.Config.TopBoundary - tl.y;
            }
            if (offset.y + br.y < General.Map.Config.BottomBoundary)
            {
                offset.y = General.Map.Config.BottomBoundary - br.y;
            }

            // Drag item moved?
            if ((!snapgrid && !snapgridincrement) || (dragitem.Position != oldpos))
            {
                int i = 0;

                // Move selected geometry
                foreach (Vertex v in selectedverts)
                {
                    // Move vertex from old position relative to the mouse position change since drag start
                    v.Move(oldpositions[i++] + offset);
                }

                //mxd. Move selected things
                i = 0;
                foreach (Thing t in thingstodrag)
                {
                    t.Move(oldthingpositions[i++] + offset);
                }

                // Update labels
                int index = 0;
                foreach (Linedef l in unstablelines)
                {
                    labels[index++].Move(l.Start.Position, l.End.Position);
                }

                // Moved
                return(true);
            }

            // No changes
            return(false);
        }
Exemplo n.º 18
0
        // This makes sure we are updated with the source linedef information
        public override void Update()
        {
            SectorData sd = data.Mode.GetSectorData(linedef.Front.Sector);

            if (!sd.Updated)
            {
                sd.Update();
            }
            sd.AddUpdateSector(data.Sector, true);

            if (floor == null)
            {
                floor = new SectorLevel(sd.Floor);
                data.AddSectorLevel(floor);
            }

            if (ceiling == null)
            {
                ceiling = new SectorLevel(sd.Ceiling);
                data.AddSectorLevel(ceiling);
            }

            // For non-vavoom types, we must switch the level types
            if (linedef.Args[1] != (int)FloorTypes.VavoomStyle)
            {
                //mxd. check for Swimmable/RenderInside/RenderAdditive flags
                renderadditive = (linedef.Args[2] & (int)Flags.RenderAdditive) == (int)Flags.RenderAdditive;
                renderinside   = ((((linedef.Args[1] & (int)FloorTypes.Swimmable) == (int)FloorTypes.Swimmable) && (linedef.Args[1] & (int)FloorTypes.NonSolid) != (int)FloorTypes.NonSolid)) ||
                                 ((linedef.Args[1] & (int)FloorTypes.RenderInside) == (int)FloorTypes.RenderInside);
                ignorebottomheight = ((linedef.Args[2] & (int)Flags.IgnoreBottomHeight) == (int)Flags.IgnoreBottomHeight);

                vavoomtype = false;
                alpha      = General.Clamp(linedef.Args[3], 0, 255);
                sd.Ceiling.CopyProperties(floor);
                sd.Floor.CopyProperties(ceiling);
                floor.type    = SectorLevelType.Floor;
                floor.plane   = sd.Ceiling.plane.GetInverted();
                ceiling.type  = SectorLevelType.Ceiling;
                ceiling.plane = (ignorebottomheight ? sd.Ceiling.plane : sd.Floor.plane.GetInverted());                 //mxd. Use upper plane when "ignorebottomheight" flag is set

                //mxd
                clipsides = (!renderinside && !renderadditive && alpha > 254 && !ignorebottomheight);

                // A 3D floor's color is always that of the sector it is placed in
                // (unless it's affected by glow) - mxd
                if (sd.CeilingGlow == null || !sd.CeilingGlow.Fullbright)
                {
                    floor.color = 0;
                }
            }
            else
            {
                vavoomtype     = true;
                renderadditive = false;           //mxd
                clipsides      = true;            //mxd
                floor.type     = SectorLevelType.Ceiling;
                floor.plane    = sd.Ceiling.plane;
                ceiling.type   = SectorLevelType.Floor;
                ceiling.plane  = sd.Floor.plane;
                alpha          = 255;

                // A 3D floor's color is always that of the sector it is placed in
                // (unless it's affected by glow) - mxd
                if (sd.FloorGlow == null || !sd.FloorGlow.Fullbright)
                {
                    ceiling.color = 0;
                }
            }

            // Apply alpha
            floor.alpha   = alpha;
            ceiling.alpha = alpha;

            //mxd
            floor.extrafloor   = true;
            ceiling.extrafloor = true;
            floor.splitsides   = !clipsides;
            ceiling.splitsides = (!clipsides && !ignorebottomheight);             // if "ignorebottomheight" flag is set, both ceiling and floor will be at the same level and sidedef clipping with floor level will fail resulting in incorrect light props transfer in some cases

            //mxd. Check slopes, cause GZDoom can't handle sloped translucent 3d floors...
            sloped3dfloor = ((alpha < 255 || renderadditive) &&
                             (Angle2D.RadToDeg(ceiling.plane.Normal.GetAngleZ()) != 270 ||
                              Angle2D.RadToDeg(floor.plane.Normal.GetAngleZ()) != 90));

            // Do not adjust light? (works only for non-vavoom types)
            if (!vavoomtype)
            {
                bool disablelighting  = ((linedef.Args[2] & (int)Flags.DisableLighting) == (int)Flags.DisableLighting);             //mxd
                bool restrictlighting = ((linedef.Args[2] & (int)Flags.RestrictLighting) == (int)Flags.RestrictLighting);           //mxd
                floor.resetlighting = ((linedef.Args[2] & (int)Flags.ResetLighting) == (int)Flags.ResetLighting);                   //mxd

                if (disablelighting || restrictlighting)
                {
                    floor.restrictlighting = restrictlighting; //mxd
                    floor.disablelighting  = disablelighting;  //mxd

                    if (disablelighting)                       //mxd
                    {
                        floor.color           = 0;
                        floor.brightnessbelow = -1;
                        floor.colorbelow      = PixelColor.FromInt(0);
                    }

                    ceiling.disablelighting  = disablelighting;                    //mxd
                    ceiling.restrictlighting = restrictlighting;                   //mxd

                    ceiling.color           = 0;
                    ceiling.brightnessbelow = -1;
                    ceiling.colorbelow      = PixelColor.FromInt(0);
                }
            }
        }
Exemplo n.º 19
0
        // Apply clicked
        private void apply_Click(object sender, EventArgs e)
        {
            // Verify properties
            if (!VerifyValue(hitag.GetResult(0), General.Map.FormatInterface.MinTag, General.Map.FormatInterface.MaxTag, "Sprite hitag"))
            {
                return;
            }
            if (!VerifyValue(lotag.GetResult(0), General.Map.FormatInterface.MinTag, General.Map.FormatInterface.MaxTag, "Sprite lotag"))
            {
                return;
            }
            if (!VerifyValue(extra.GetResult(0), General.Map.FormatInterface.MinExtra, General.Map.FormatInterface.MaxExtra, "Sprite extra"))
            {
                return;
            }
            if (!VerifyValue(palette.GetResult(0), 0, 255, "Sprite palette"))
            {
                return;
            }

            // Verify the coordinates
            int px = posx.GetResult(0);
            int py = -posy.GetResult(0);

            if ((px < General.Map.FormatInterface.MinCoordinate) || (px > General.Map.FormatInterface.MaxCoordinate) ||
                (py < General.Map.FormatInterface.MinCoordinate) || (py > General.Map.FormatInterface.MaxCoordinate))
            {
                General.ShowWarningMessage("Sprite coordinates must be between " + General.Map.FormatInterface.MinCoordinate + " and " + General.Map.FormatInterface.MaxCoordinate + ".", MessageBoxButtons.OK);
                return;
            }

            // Make undo
            General.Map.UndoRedo.CreateUndo("Edit " + (sprites.Count > 1 ? sprites.Count + " sprites" : "sprite"));

            // Collect flags...
            Dictionary <string, CheckState> flagsstate = new Dictionary <string, CheckState>();

            foreach (CheckBox c in flags.Checkboxes)
            {
                flagsstate[c.Tag.ToString()] = c.CheckState;
            }

            bool applyposition = (posx.ApplyMode != NumericTextboxApplyMode.NO_VALUE ||
                                  posy.ApplyMode != NumericTextboxApplyMode.NO_VALUE ||
                                  posz.ApplyMode != NumericTextboxApplyMode.NO_VALUE);

            bool applyvelocity = (velx.ApplyMode != NumericTextboxApplyMode.NO_VALUE ||
                                  vely.ApplyMode != NumericTextboxApplyMode.NO_VALUE ||
                                  velz.ApplyMode != NumericTextboxApplyMode.NO_VALUE);

            // Apply to all sprites...
            foreach (Thing s in sprites)
            {
                // Type
                s.TileIndex = General.Clamp(tex.GetResult(s.TileIndex), General.Map.FormatInterface.MinTileIndex, General.Map.FormatInterface.MaxTileIndex);

                // Properties
                s.OffsetX      = General.Wrap(offsetx.GetResult(s.OffsetX), General.Map.FormatInterface.MinSpriteOffset, General.Map.FormatInterface.MaxSpriteOffset);
                s.OffsetY      = General.Wrap(offsety.GetResult(s.OffsetY), General.Map.FormatInterface.MinSpriteOffset, General.Map.FormatInterface.MaxSpriteOffset);
                s.RepeatX      = General.Clamp(repeatx.GetResult(s.RepeatX), General.Map.FormatInterface.MinSpriteRepeat, General.Map.FormatInterface.MaxSpriteRepeat);
                s.RepeatY      = General.Clamp(repeaty.GetResult(s.RepeatY), General.Map.FormatInterface.MinSpriteRepeat, General.Map.FormatInterface.MaxSpriteRepeat);
                s.Shade        = General.Clamp(shade.GetResult(s.Shade), General.Map.FormatInterface.MinShade, General.Map.FormatInterface.MaxShade);
                s.PaletteIndex = palette.GetResult(s.PaletteIndex);
                s.Owner        = owner.GetResult(s.Owner);

                // Position and velocity
                if (applyposition)
                {
                    s.Move(new Vector3D(posx.GetResultFloat(s.Position.x), -posy.GetResultFloat(-s.Position.y), posz.GetResultFloat(s.Position.z)));
                }
                if (applyvelocity)
                {
                    s.Velocity = new Vector3D(velx.GetResultFloat(s.Velocity.x), vely.GetResultFloat(s.Velocity.y), velz.GetResultFloat(s.Velocity.z));
                }

                // Angle
                s.Angle = Angle2D.DegToRad(General.Wrap(angle.GetResultFloat(Angle2D.RadToDeg(s.Angle)), 0f, 359f));

                // Identification
                s.HiTag = hitag.GetResult(s.HiTag);
                s.LoTag = lotag.GetResult(s.LoTag);
                s.Extra = extra.GetResult(s.Extra);

                // Flags
                foreach (KeyValuePair <string, CheckState> group in flagsstate)
                {
                    switch (group.Value)
                    {
                    case CheckState.Checked: s.SetFlag(group.Key, true); break;

                    case CheckState.Unchecked: s.SetFlag(group.Key, false); break;
                    }
                }

                // Update settings
                s.UpdateConfiguration();
            }

            // Update defaults
            var defaultflags = new List <string>();

            foreach (CheckBox c in flags.Checkboxes)
            {
                if (c.CheckState == CheckState.Checked)
                {
                    defaultflags.Add(c.Tag.ToString());
                }
            }
            General.Map.Config.DefaultSpriteTile  = spritetype.GetResult(General.Map.Config.DefaultSpriteTile);
            General.Map.Config.DefaultSpriteAngle = Angle2D.DegToRad((float)angle.GetResult((int)Angle2D.RadToDeg(General.Map.Config.DefaultSpriteAngle) - 90) + 90);
            General.Map.Config.DefaultSpriteFlags = defaultflags;

            // Done
            General.Map.IsChanged = true;
            this.DialogResult     = DialogResult.OK;
            this.Close();
        }
Exemplo n.º 20
0
        //mxd
        public virtual void OnChangeScale(int incrementX, int incrementY)
        {
            if (!General.Map.UDMF || !Texture.IsImageLoaded)
            {
                return;
            }

            changed = true;

            if ((General.Map.UndoRedo.NextUndo == null) || (General.Map.UndoRedo.NextUndo.TicketID != undoticket))
            {
                undoticket = mode.CreateUndo("Change texture scale");
            }

            // Adjust to camera view
            float angle = Angle2D.RadToDeg(General.Map.VisualCamera.AngleXY);

            if (GeometryType == VisualGeometryType.CEILING)
            {
                angle += level.sector.Fields.GetValue("rotationceiling", 0f);
            }
            else
            {
                angle += level.sector.Fields.GetValue("rotationfloor", 0f);
            }
            angle = General.ClampAngle(angle);

            if (angle > 315 || angle < 46)
            {
                ChangeTextureScale(incrementX, incrementY);
            }
            else if (angle > 225)
            {
                ChangeTextureScale(incrementY, incrementX);
            }
            else if (angle > 135)
            {
                ChangeTextureScale(incrementX, incrementY);
            }
            else
            {
                ChangeTextureScale(incrementY, incrementX);
            }

            // Rebuild sector
            BaseVisualSector vs;

            if (mode.VisualSectorExists(level.sector))
            {
                vs = (BaseVisualSector)mode.GetVisualSector(level.sector);
            }
            else
            {
                //mxd. Need this to apply changes to 3d-floor even if control sector doesn't exist as BaseVisualSector
                vs = mode.CreateBaseVisualSector(level.sector);
            }

            if (vs != null)
            {
                vs.UpdateSectorGeometry(false);
            }
        }
        // This shows the info
        public void ShowInfo(Thing s)
        {
            infopanel.Text = " Sprite " + s.Index + (s.Sector != null ? " (sector " + s.Sector.Index + ") " : " ");
            General.DisplayZoomedImage(spritetex, General.Map.Data.GetImageData(s.TileIndex).GetPreview());
            spritename.Text = s.TileIndex.ToString();

            var  info            = General.Map.Data.GetSpriteInfoEx(s.TileIndex);
            bool havedefinedtype = (info != null);

            type.Text         = (havedefinedtype ? info.Title : "--");
            type.Enabled      = havedefinedtype;
            typelabel.Enabled = havedefinedtype;

            // Determine z info to show
            s.DetermineSector();
            string zinfo = (s.Sector != null ? s.Position.z + s.Sector.FloorPlane.GetZ(s.Position) : s.Position.z).ToString();

            position.Text     = s.Position.x + ", " + (-s.Position.y) + ", " + zinfo;
            angle.Text        = (int)Math.Round(Angle2D.RadToDeg(s.Angle)) + "\u00B0";
            clipdistance.Text = s.ClipDistance.ToString();
            owner.Text        = s.Owner.ToString();

            offsetx.Text = s.OffsetX.ToString();
            offsety.Text = s.OffsetY.ToString();
            repeatx.Text = s.RepeatX.ToString();
            repeaty.Text = s.RepeatY.ToString();

            hitag.Text   = s.HiTag.ToString();
            lotag.Text   = s.LoTag.ToString();
            extra.Text   = s.Extra.ToString();
            shade.Text   = s.Shade.ToString();
            palette.Text = s.PaletteIndex.ToString();

            // Disable identification labels when showing default values
            hitag.Enabled      = s.HiTag > 0;
            hitaglabel.Enabled = s.HiTag > 0;
            lotag.Enabled      = s.LoTag > 0;
            lotaglabel.Enabled = s.LoTag > 0;
            extra.Enabled      = s.Extra != -1;
            extralabel.Enabled = s.Extra != -1;
            owner.Enabled      = s.Owner != -1;
            ownerlabel.Enabled = s.Owner != -1;

            offsetx.Enabled      = s.OffsetX != 0;
            offsetxlabel.Enabled = s.OffsetX != 0;
            offsety.Enabled      = s.OffsetY != 0;
            offsetylabel.Enabled = s.OffsetY != 0;

            repeatx.Enabled      = s.RepeatX != 0;
            repeatxlabel.Enabled = s.RepeatX != 0;
            repeaty.Enabled      = s.RepeatY != 0;
            repeatylabel.Enabled = s.RepeatY != 0;

            palette.Enabled      = s.PaletteIndex > 0;
            palettelabel.Enabled = s.PaletteIndex > 0;

            // Flags
            List <string> flagnames = new List <string>();

            foreach (KeyValuePair <string, string> group in General.Map.Config.SpriteFlags)
            {
                if (s.IsFlagSet(group.Key))
                {
                    flagnames.Add(group.Value);
                }
            }
            flags.Setup(flagnames);

            // Show the whole thing
            this.Show();
            this.Update();
        }
Exemplo n.º 22
0
        // This is called to update UV dragging
        protected virtual void UpdateDragUV()
        {
            float u_ray = 1.0f;

            // Calculate intersection position
            this.Level.plane.GetIntersection(General.Map.VisualCamera.Position, General.Map.VisualCamera.Target, ref u_ray);
            Vector3D intersect = General.Map.VisualCamera.Position + (General.Map.VisualCamera.Target - General.Map.VisualCamera.Position) * u_ray;

            // Calculate offsets
            Vector3D dragdelta = intersect - dragorigin;
            float    offsetx   = dragdelta.x;
            float    offsety   = dragdelta.y;

            bool lockX = General.Interface.CtrlState && !General.Interface.ShiftState;
            bool lockY = !General.Interface.CtrlState && General.Interface.ShiftState;

            if (lockX || lockY)
            {
                float camAngle = Angle2D.RadToDeg(General.Map.VisualCamera.AngleXY);

                if (camAngle > 315 || camAngle < 46)
                {
                    if (lockX)
                    {
                        offsetx = 0;
                    }
                    if (lockY)
                    {
                        offsety = 0;
                    }
                }
                else if (camAngle > 225)
                {
                    if (lockX)
                    {
                        offsety = 0;
                    }
                    if (lockY)
                    {
                        offsetx = 0;
                    }
                }
                else if (camAngle > 135)
                {
                    if (lockX)
                    {
                        offsetx = 0;
                    }
                    if (lockY)
                    {
                        offsety = 0;
                    }
                }
                else
                {
                    if (lockX)
                    {
                        offsety = 0;
                    }
                    if (lockY)
                    {
                        offsetx = 0;
                    }
                }
            }

            //mxd. Modify offsets based on surface and camera angles
            float angle;

            if (GeometryType == VisualGeometryType.CEILING)
            {
                angle = Angle2D.DegToRad(level.sector.Fields.GetValue("rotationceiling", 0f));
            }
            else
            {
                angle = Angle2D.DegToRad(level.sector.Fields.GetValue("rotationfloor", 0f));
            }

            Vector2D v = new Vector2D(offsetx, offsety).GetRotated(angle);

            offsetx = (int)Math.Round(v.x);
            offsety = (int)Math.Round(v.y);

            // Calculate deltas
            int deltax, deltay;

            if (General.Interface.CtrlState && General.Interface.ShiftState)
            {
                //mxd. Clamp to grid size?
                int newoffsetx = startoffsetx - (int)Math.Round(offsetx);
                int newoffsety = startoffsety + (int)Math.Round(offsety);
                deltax = prevoffsetx - newoffsetx;
                deltay = prevoffsety - newoffsety;

                if (Math.Abs(deltax) >= General.Map.Grid.GridSize)
                {
                    deltax      = General.Map.Grid.GridSize * Math.Sign(deltax);
                    prevoffsetx = newoffsetx;
                }
                else
                {
                    deltax = 0;
                }

                if (Math.Abs(deltay) >= General.Map.Grid.GridSize)
                {
                    deltay      = General.Map.Grid.GridSize * Math.Sign(deltay);
                    prevoffsety = newoffsety;
                }
                else
                {
                    deltay = 0;
                }
            }
            else
            {
                int newoffsetx = startoffsetx - (int)Math.Round(offsetx);
                int newoffsety = startoffsety + (int)Math.Round(offsety);

                deltax = prevoffsetx - newoffsetx;
                deltay = prevoffsety - newoffsety;

                prevoffsetx = newoffsetx;
                prevoffsety = newoffsety;
            }

            //mxd. Apply offset?
            if (deltax != 0 || deltay != 0)
            {
                mode.ApplyFlatOffsetChange(deltax, deltay);
            }
            mode.ShowTargetInfo();
        }
Exemplo n.º 23
0
        // This returns the aligned and snapped draw position
        public static DrawnVertex GetCurrentPosition(Vector2D mousemappos, bool snaptonearest, bool snaptogrid, bool snaptocardinal, bool usefourcardinaldirections, IRenderer2D renderer, List <DrawnVertex> points)
        {
            DrawnVertex p = new DrawnVertex();

            p.stitch       = true;                                 //mxd. Setting these to false seems to be a good way to create invalid geometry...
            p.stitchline   = true;                                 //mxd
            snaptocardinal = (snaptocardinal && points.Count > 0); //mxd. Don't snap to cardinal when there are no points

            //mxd. If snap to cardinal directions is enabled and we have points, modify mouse position
            Vector2D vm, gridoffset;

            if (snaptocardinal)
            {
                Vector2D offset = mousemappos - points[points.Count - 1].pos;

                float angle;
                if (usefourcardinaldirections)
                {
                    angle = Angle2D.DegToRad((General.ClampAngle((int)Angle2D.RadToDeg(offset.GetAngle()))) / 90 * 90 + 45);
                }
                else
                {
                    angle = Angle2D.DegToRad((General.ClampAngle((int)Angle2D.RadToDeg(offset.GetAngle()) + 22)) / 45 * 45);
                }

                offset = new Vector2D(0, -offset.GetLength()).GetRotated(angle);
                vm     = points[points.Count - 1].pos + offset;

                //mxd. We need to be snapped relative to initial position
                Vector2D prev = points[points.Count - 1].pos;
                gridoffset = prev - General.Map.Grid.SnappedToGrid(prev);
            }
            else
            {
                vm         = mousemappos;
                gridoffset = new Vector2D();
            }

            float vrange = BuilderPlug.Me.StitchRange / renderer.Scale;

            // Snap to nearest?
            if (snaptonearest)
            {
                // Go for all drawn points
                foreach (DrawnVertex v in points)
                {
                    if (Vector2D.DistanceSq(vm, v.pos) < (vrange * vrange))
                    {
                        p.pos = v.pos;
                        return(p);
                    }
                }

                // Try the nearest vertex
                Vertex nv = General.Map.Map.NearestVertexSquareRange(vm, vrange);
                if (nv != null)
                {
                    //mxd. Line angle must stay the same
                    if (snaptocardinal)
                    {
                        Line2D ourline = new Line2D(points[points.Count - 1].pos, vm);
                        if (Math.Round(ourline.GetSideOfLine(nv.Position), 1) == 0)
                        {
                            p.pos = nv.Position;
                            return(p);
                        }
                    }
                    else
                    {
                        p.pos = nv.Position;
                        return(p);
                    }
                }

                // Try the nearest linedef. mxd. We'll need much bigger stitch distance when snapping to cardinal directions
                Linedef nl = General.Map.Map.NearestLinedefRange(vm, BuilderPlug.Me.StitchRange / renderer.Scale);
                if (nl != null)
                {
                    //mxd. Line angle must stay the same
                    if (snaptocardinal)
                    {
                        Line2D   ourline      = new Line2D(points[points.Count - 1].pos, vm);
                        Line2D   nearestline  = new Line2D(nl.Start.Position, nl.End.Position);
                        Vector2D intersection = Line2D.GetIntersectionPoint(nearestline, ourline, false);
                        if (!float.IsNaN(intersection.x))
                        {
                            // Intersection is on nearestline?
                            float u = Line2D.GetNearestOnLine(nearestline.v1, nearestline.v2, intersection);

                            if (u < 0f || u > 1f)
                            {
                            }
                            else
                            {
                                p.pos = new Vector2D((float)Math.Round(intersection.x, General.Map.FormatInterface.VertexDecimals),
                                                     (float)Math.Round(intersection.y, General.Map.FormatInterface.VertexDecimals));
                                return(p);
                            }
                        }
                    }
                    // Snap to grid?
                    else if (snaptogrid)
                    {
                        // Get grid intersection coordinates
                        List <Vector2D> coords = nl.GetGridIntersections(General.Map.Grid.GridRotate,
                                                                         General.Map.Grid.GridOriginX, General.Map.Grid.GridOriginY);

                        // Find nearest grid intersection
                        bool     found          = false;
                        float    found_distance = float.MaxValue;
                        Vector2D found_coord    = new Vector2D();
                        foreach (Vector2D v in coords)
                        {
                            Vector2D delta = vm - v;
                            if (delta.GetLengthSq() < found_distance)
                            {
                                found_distance = delta.GetLengthSq();
                                found_coord    = v;
                                found          = true;
                            }
                        }

                        if (found)
                        {
                            // Align to the closest grid intersection
                            p.pos = found_coord;
                            return(p);
                        }
                    }
                    else
                    {
                        // Aligned to line
                        p.pos = nl.NearestOnLine(vm);
                        return(p);
                    }
                }
            }
            else
            {
                // Always snap to the first drawn vertex so that the user can finish a complete sector without stitching
                if (points.Count > 0)
                {
                    if (Vector2D.DistanceSq(vm, points[0].pos) < (vrange * vrange))
                    {
                        p.pos = points[0].pos;
                        return(p);
                    }
                }
            }

            // if the mouse cursor is outside the map bondaries check if the line between the last set point and the
            // mouse cursor intersect any of the boundary lines. If it does, set the position to this intersection
            if (points.Count > 0 &&
                (mousemappos.x < General.Map.Config.LeftBoundary || mousemappos.x > General.Map.Config.RightBoundary ||
                 mousemappos.y > General.Map.Config.TopBoundary || mousemappos.y < General.Map.Config.BottomBoundary))
            {
                Line2D        dline             = new Line2D(mousemappos, points[points.Count - 1].pos);
                bool          foundintersection = false;
                float         u      = 0.0f;
                List <Line2D> blines = new List <Line2D>();

                // lines for left, top, right and bottom boundaries
                blines.Add(new Line2D(General.Map.Config.LeftBoundary, General.Map.Config.BottomBoundary, General.Map.Config.LeftBoundary, General.Map.Config.TopBoundary));
                blines.Add(new Line2D(General.Map.Config.LeftBoundary, General.Map.Config.TopBoundary, General.Map.Config.RightBoundary, General.Map.Config.TopBoundary));
                blines.Add(new Line2D(General.Map.Config.RightBoundary, General.Map.Config.TopBoundary, General.Map.Config.RightBoundary, General.Map.Config.BottomBoundary));
                blines.Add(new Line2D(General.Map.Config.RightBoundary, General.Map.Config.BottomBoundary, General.Map.Config.LeftBoundary, General.Map.Config.BottomBoundary));

                // check for intersections with boundaries
                for (int i = 0; i < blines.Count; i++)
                {
                    if (!foundintersection)
                    {
                        // only check for intersection if the last set point is not on the
                        // line we are checking against
                        if (blines[i].GetSideOfLine(points[points.Count - 1].pos) != 0.0f)
                        {
                            foundintersection = blines[i].GetIntersection(dline, out u);
                        }
                    }
                }

                // if there was no intersection set the position to the last set point
                if (!foundintersection)
                {
                    vm = points[points.Count - 1].pos;
                }
                else
                {
                    vm = dline.GetCoordinatesAt(u);
                }
            }

            // Snap to grid?
            if (snaptogrid)
            {
                // Aligned to grid
                p.pos = General.Map.Grid.SnappedToGrid(vm - gridoffset) + gridoffset;

                // special handling
                if (p.pos.x > General.Map.Config.RightBoundary)
                {
                    p.pos.x = General.Map.Config.RightBoundary;
                }
                if (p.pos.y < General.Map.Config.BottomBoundary)
                {
                    p.pos.y = General.Map.Config.BottomBoundary;
                }

                return(p);
            }
            else
            {
                // Normal position
                p.pos.x = (float)Math.Round(vm.x);                 //mxd
                p.pos.y = (float)Math.Round(vm.y);                 //mxd

                return(p);
            }
        }
Exemplo n.º 24
0
        //mxd
        protected void AlignTextureToSlopeLine(Linedef slopeSource, float slopeAngle, bool isFront, bool alignx, bool aligny)
        {
            bool isFloor = (geometrytype == VisualGeometryType.FLOOR);

            Sector.Sector.Fields.BeforeFieldsChange();
            float sourceAngle = (float)Math.Round(General.ClampAngle(isFront ? -Angle2D.RadToDeg(slopeSource.Angle) + 90 : -Angle2D.RadToDeg(slopeSource.Angle) - 90), 1);

            if (isFloor)
            {
                if ((isFront && slopeSource.Front.Sector.FloorHeight > slopeSource.Back.Sector.FloorHeight) ||
                    (!isFront && slopeSource.Front.Sector.FloorHeight < slopeSource.Back.Sector.FloorHeight))
                {
                    sourceAngle = General.ClampAngle(sourceAngle + 180);
                }
            }
            else
            {
                if ((isFront && slopeSource.Front.Sector.CeilHeight < slopeSource.Back.Sector.CeilHeight) ||
                    (!isFront && slopeSource.Front.Sector.CeilHeight > slopeSource.Back.Sector.CeilHeight))
                {
                    sourceAngle = General.ClampAngle(sourceAngle + 180);
                }
            }

            //update angle
            UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "rotationfloor" : "rotationceiling"), sourceAngle, 0f);

            //update scaleY
            string xScaleKey = (isFloor ? "xscalefloor" : "xscaleceiling");
            string yScaleKey = (isFloor ? "yscalefloor" : "yscaleceiling");

            float scaleX = Sector.Sector.Fields.GetValue(xScaleKey, 1.0f);
            float scaleY;

            //set scale
            if (aligny)
            {
                scaleY = (float)Math.Round(scaleX * (1 / (float)Math.Cos(slopeAngle)), 2);
                UniFields.SetFloat(Sector.Sector.Fields, yScaleKey, scaleY, 1.0f);
            }
            else
            {
                scaleY = Sector.Sector.Fields.GetValue(yScaleKey, 1.0f);
            }

            //update texture offsets
            Vector2D offset;

            if (isFloor)
            {
                if ((isFront && slopeSource.Front.Sector.FloorHeight < slopeSource.Back.Sector.FloorHeight) ||
                    (!isFront && slopeSource.Front.Sector.FloorHeight > slopeSource.Back.Sector.FloorHeight))
                {
                    offset = slopeSource.End.Position;
                }
                else
                {
                    offset = slopeSource.Start.Position;
                }
            }
            else
            {
                if ((isFront && slopeSource.Front.Sector.CeilHeight > slopeSource.Back.Sector.CeilHeight) ||
                    (!isFront && slopeSource.Front.Sector.CeilHeight < slopeSource.Back.Sector.CeilHeight))
                {
                    offset = slopeSource.End.Position;
                }
                else
                {
                    offset = slopeSource.Start.Position;
                }
            }

            offset = offset.GetRotated(Angle2D.DegToRad(sourceAngle));

            if (alignx)
            {
                if (Texture != null && Texture.IsImageLoaded)
                {
                    offset.x %= Texture.Width / scaleX;
                }
                UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "xpanningfloor" : "xpanningceiling"), (float)Math.Round(-offset.x), 0f);
            }

            if (aligny)
            {
                if (Texture != null && Texture.IsImageLoaded)
                {
                    offset.y %= Texture.Height / scaleY;
                }
                UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "ypanningfloor" : "ypanningceiling"), (float)Math.Round(offset.y), 0f);
            }

            //update geometry
            Sector.UpdateSectorGeometry(false);
        }
Exemplo n.º 25
0
        // This sets up the form to edit the given sectors
        public void Setup(ICollection <Sector> sectors)
        {
            // Keep this list
            this.sectors = sectors;
            if (sectors.Count > 1)
            {
                this.Text = "Edit sectors (" + sectors.Count + ")";
            }

            // Use the first sector as a reference
            BuildSector first = new BuildSector(General.GetFirst(sectors));
            Dictionary <string, int> intflagsceiling = new Dictionary <string, int>();
            Dictionary <string, int> intflagsfloor   = new Dictionary <string, int>();

            foreach (var group in General.Map.Config.SectorFlags)
            {
                intflagsceiling[group.Key] = (first.CeilingFlags.ContainsKey(group.Key) && first.CeilingFlags[group.Key] ? 1 : 0);
                intflagsfloor[group.Key]   = (first.FloorFlags.ContainsKey(group.Key) && first.FloorFlags[group.Key] ? 1 : 0);
            }

            // Go for all sectors to compare properties
            foreach (Sector s in sectors)
            {
                // Floor/ceiling
                if (first.FloorHeight != s.FloorHeight)
                {
                    first.FloorHeight = VALUE_MISMATCH;
                }
                if (first.CeilingHeight != s.CeilingHeight)
                {
                    first.CeilingHeight = VALUE_MISMATCH;
                }
                if (first.Visibility != s.Visibility)
                {
                    first.Visibility = VALUE_MISMATCH;
                }

                // Identification
                if (first.HiTag != s.HiTag)
                {
                    first.HiTag = VALUE_MISMATCH;
                }
                if (first.LoTag != s.LoTag)
                {
                    first.LoTag = VALUE_MISMATCH;
                }
                if (first.Extra != s.Extra)
                {
                    first.Extra = VALUE_MISMATCH;
                }

                // Ceiling
                foreach (string flagname in General.Map.Config.SectorFlags.Keys)
                {
                    int flag = (s.IsFlagSet(flagname, false) ? 1 : 0);
                    if (flag != intflagsceiling[flagname])
                    {
                        intflagsceiling[flagname] = VALUE_MISMATCH;
                    }
                }

                if (first.CeilingTileIndex != s.CeilingTileIndex)
                {
                    first.CeilingTileIndex = VALUE_MISMATCH;
                }
                if (first.CeilingOffsetX != s.CeilingOffsetX)
                {
                    first.CeilingOffsetX = VALUE_MISMATCH;
                }
                if (first.CeilingOffsetY != s.CeilingOffsetY)
                {
                    first.CeilingOffsetY = VALUE_MISMATCH;
                }
                if (first.CeilingShade != s.CeilingShade)
                {
                    first.CeilingShade = VALUE_MISMATCH;
                }
                if (first.CeilingPaletteIndex != s.CeilingPaletteIndex)
                {
                    first.CeilingPaletteIndex = VALUE_MISMATCH;
                }
                if (first.CeilingSlope != s.CeilingSlope)
                {
                    first.CeilingSlope = VALUE_MISMATCH;
                }

                // Floor
                foreach (string flagname in General.Map.Config.SectorFlags.Keys)
                {
                    int flag = (s.IsFlagSet(flagname, true) ? 1 : 0);
                    if (flag != intflagsfloor[flagname])
                    {
                        intflagsfloor[flagname] = VALUE_MISMATCH;
                    }
                }

                if (first.FloorTileIndex != s.FloorTileIndex)
                {
                    first.FloorTileIndex = VALUE_MISMATCH;
                }
                if (first.FloorOffsetX != s.FloorOffsetX)
                {
                    first.FloorOffsetX = VALUE_MISMATCH;
                }
                if (first.FloorOffsetY != s.FloorOffsetY)
                {
                    first.FloorOffsetY = VALUE_MISMATCH;
                }
                if (first.FloorShade != s.FloorShade)
                {
                    first.FloorShade = VALUE_MISMATCH;
                }
                if (first.FloorPaletteIndex != s.FloorPaletteIndex)
                {
                    first.FloorPaletteIndex = VALUE_MISMATCH;
                }
                if (first.FloorSlope != s.FloorSlope)
                {
                    first.FloorSlope = VALUE_MISMATCH;
                }
            }

            // Update interface
            this.SuspendLayout();

            // Floor/ceiling
            if (first.FloorHeight != VALUE_MISMATCH)
            {
                floorheight.Text = first.FloorHeight.ToString();
            }
            if (first.CeilingHeight != VALUE_MISMATCH)
            {
                ceilheight.Text = first.CeilingHeight.ToString();
            }
            if (first.Visibility != VALUE_MISMATCH)
            {
                visibility.Text = first.Visibility.ToString();
            }

            // Identification
            //TODO: handlers
            if (first.HiTag != VALUE_MISMATCH)
            {
                hitag.Text = first.HiTag.ToString();
            }
            if (first.LoTag != VALUE_MISMATCH)
            {
                lotag.Text = first.LoTag.ToString();
            }
            if (first.Extra != VALUE_MISMATCH)
            {
                extra.Text = first.Extra.ToString();
            }

            // Ceiling
            foreach (CheckBox c in ceilflags.Checkboxes)
            {
                switch (intflagsceiling[c.Tag.ToString()])
                {
                case 1:
                    c.Checked = true;
                    break;

                case VALUE_MISMATCH:
                    c.ThreeState = true;
                    c.CheckState = CheckState.Indeterminate;
                    break;
                }
            }

            ceiltex.TextureName = (first.CeilingTileIndex != VALUE_MISMATCH ? first.CeilingTileIndex.ToString() : "");
            if (first.CeilingOffsetX != VALUE_MISMATCH)
            {
                ceiloffsetx.Text = first.CeilingOffsetX.ToString();
            }
            if (first.CeilingOffsetY != VALUE_MISMATCH)
            {
                ceiloffsety.Text = first.CeilingOffsetY.ToString();
            }
            if (first.CeilingShade != VALUE_MISMATCH)
            {
                ceilshade.Text = first.CeilingShade.ToString();
            }
            if (first.CeilingPaletteIndex != VALUE_MISMATCH)
            {
                ceilpalette.Text = first.CeilingPaletteIndex.ToString();
            }
            if (first.CeilingSlope != VALUE_MISMATCH)
            {
                ceilslope.Text = ((float)Math.Round(General.Wrap(Angle2D.RadToDeg(first.CeilingSlope) - 90, -90, 90), 1)).ToString();
            }

            // Floor
            foreach (CheckBox c in floorflags.Checkboxes)
            {
                switch (intflagsfloor[c.Tag.ToString()])
                {
                case 1:
                    c.Checked = true;
                    break;

                case VALUE_MISMATCH:
                    c.ThreeState = true;
                    c.CheckState = CheckState.Indeterminate;
                    break;
                }
            }

            floortex.TextureName = (first.FloorTileIndex != VALUE_MISMATCH ? first.FloorTileIndex.ToString() : "");
            if (first.FloorOffsetX != VALUE_MISMATCH)
            {
                flooroffsetx.Text = first.FloorOffsetX.ToString();
            }
            if (first.FloorOffsetY != VALUE_MISMATCH)
            {
                flooroffsety.Text = first.FloorOffsetY.ToString();
            }
            if (first.FloorShade != VALUE_MISMATCH)
            {
                floorshade.Text = first.FloorShade.ToString();
            }
            if (first.FloorPaletteIndex != VALUE_MISMATCH)
            {
                floorpalette.Text = first.FloorPaletteIndex.ToString();
            }
            if (first.FloorSlope != VALUE_MISMATCH)
            {
                floorslope.Text = ((float)Math.Round(General.Wrap(Angle2D.RadToDeg(first.FloorSlope) - 90, -90, 90), 1)).ToString();
            }

            this.ResumeLayout();

            // Show sector height
            UpdateSectorHeight();
        }
Exemplo n.º 26
0
        // This restores all sectors to original values
        private void RestoreSectors()
        {
            int index = 0;

            foreach (Sector s in selection)
            {
                SectorInfo si = sectorinfo[index];
                s.Fields.BeforeFieldsChange();
                s.Fields[RotationName] = new UniValue(UniversalType.AngleDegreesFloat, Angle2D.RadToDeg(si.rotation));
                s.Fields[XScaleName]   = new UniValue(UniversalType.Float, si.scale.x);
                s.Fields[YScaleName]   = new UniValue(UniversalType.Float, si.scale.y);
                s.Fields[XOffsetName]  = new UniValue(UniversalType.Float, si.offset.x);
                s.Fields[YOffsetName]  = new UniValue(UniversalType.Float, -si.offset.y);
                s.UpdateNeeded         = true;
                s.UpdateCache();
                index++;
            }
        }
        // This shows the info
        public void ShowInfo(Sector s)
        {
            // Lookup effect description in config
            if (s.LoTag != 0 && General.Map.Config.SectorEffects.ContainsKey(s.LoTag))
            {
                lotag.Text      = General.Map.Config.SectorEffects[s.LoTag].ToString();
                lotaglabel.Text = "Effect:";
            }
            else
            {
                lotag.Text      = s.LoTag.ToString();
                lotaglabel.Text = "LoTag:";
            }

            // Sector info
            sectorinfo.Text = " Sector " + s.Index + " (" + (s.Sidedefs != null ? s.Sidedefs.Count.ToString() : "no") + " walls)";
            firstwall.Text  = (s.FirstWall != null ? s.FirstWall.Index.ToString() : "--");
            hitag.Text      = s.HiTag.ToString();
            extra.Text      = s.Extra.ToString();
            ceiling.Text    = s.CeilingHeight.ToString();
            floor.Text      = s.FloorHeight.ToString();
            height.Text     = (s.CeilingHeight - s.FloorHeight).ToString();
            visibility.Text = s.Visibility.ToString();

            // Floor info
            General.DisplayZoomedImage(floortex, General.Map.Data.GetImageData(s.FloorTileIndex).GetPreview());
            floorname.Text    = s.FloorTileIndex.ToString();
            flooroffsetx.Text = s.FloorOffsetX.ToString();
            flooroffsety.Text = s.FloorOffsetY.ToString();
            floorshade.Text   = s.FloorShade.ToString();
            floorpalette.Text = s.FloorPaletteIndex.ToString();
            floorslope.Text   = Math.Round(General.Wrap(Angle2D.RadToDeg(s.FloorSlope) - 90, -90, 90), 1) + "\u00B0";

            // Ceiling info
            General.DisplayZoomedImage(ceiltex, General.Map.Data.GetImageData(s.CeilingTileIndex).GetPreview());
            ceilname.Text    = s.CeilingTileIndex.ToString();
            ceiloffsetx.Text = s.CeilingOffsetX.ToString();
            ceiloffsety.Text = s.CeilingOffsetY.ToString();
            ceilshade.Text   = s.CeilingShade.ToString();
            ceilpalette.Text = s.CeilingPaletteIndex.ToString();
            ceilslope.Text   = Math.Round(General.Wrap(Angle2D.RadToDeg(s.CeilingSlope) - 90, -90, 90), 1) + "\u00B0";

            // Disable identification labels when showing default values
            hitag.Enabled      = s.HiTag > 0;
            hitaglabel.Enabled = s.HiTag > 0;
            lotag.Enabled      = s.LoTag > 0;
            lotaglabel.Enabled = s.LoTag > 0;
            extra.Enabled      = s.Extra != -1;
            extralabel.Enabled = s.Extra != -1;

            flooroffsetx.Enabled      = s.FloorOffsetX != 0;
            flooroffsetxlabel.Enabled = s.FloorOffsetX != 0;
            flooroffsety.Enabled      = s.FloorOffsetY != 0;
            flooroffsetylabel.Enabled = s.FloorOffsetY != 0;

            ceiloffsetx.Enabled      = s.CeilingOffsetX != 0;
            ceiloffsetxlabel.Enabled = s.CeilingOffsetX != 0;
            ceiloffsety.Enabled      = s.CeilingOffsetY != 0;
            ceiloffsetylabel.Enabled = s.CeilingOffsetY != 0;

            floorpalette.Enabled      = s.FloorPaletteIndex > 0;
            floorpalettelabel.Enabled = s.FloorPaletteIndex > 0;

            bool floorsloped = (s.FloorSloped && s.FloorSlope != 0);

            floorslope.Enabled      = floorsloped;
            floorslopelabel.Enabled = floorsloped;

            ceilpalette.Enabled      = s.CeilingPaletteIndex > 0;
            ceilpalettelabel.Enabled = s.CeilingPaletteIndex > 0;

            bool ceilsloped = (s.CeilingSloped && s.CeilingSlope != 0);

            ceilslope.Enabled      = ceilsloped;
            ceilslopelabel.Enabled = ceilsloped;

            // Floor flags
            List <string> floorflagnames = new List <string>();

            foreach (KeyValuePair <string, string> group in General.Map.Config.SectorFlags)
            {
                if (s.IsFlagSet(group.Key, true))
                {
                    floorflagnames.Add(group.Value);
                }
            }
            floorflags.Setup(floorflagnames);

            // Ceiling flags
            List <string> ceilingflagnames = new List <string>();

            foreach (KeyValuePair <string, string> group in General.Map.Config.SectorFlags)
            {
                if (s.IsFlagSet(group.Key, false))
                {
                    ceilingflagnames.Add(group.Value);
                }
            }
            ceilingflags.Setup(ceilingflagnames);

            // Resize and reposition
            if (floorflagnames.Count > 0)
            {
                ceilinggroup.Left = floorflags.Right + floorflags.Margin.Right + ceilinggroup.Margin.Left;
            }
            else
            {
                ceilinggroup.Left = floorgroup.Right + floorgroup.Margin.Right + ceilinggroup.Margin.Left;
            }

            if (ceilingflagnames.Count > 0)
            {
                ceilingflags.Left = ceilinggroup.Right + ceilinggroup.Margin.Right + ceilingflags.Margin.Left;
                this.Width        = ceilingflags.Right + ceilingflags.Margin.Right;
            }
            else
            {
                this.Width = ceilinggroup.Right + ceilinggroup.Margin.Right;
            }

            // Show the whole thing
            this.Show();
            this.Update();
        }