Beispiel #1
0
        private static FootholdLine GetOtherFh(FootholdAnchor anchor, FootholdLine source, Hashtable fhListByPoint)
        {
            List <FootholdLine> connectedLines = (List <FootholdLine>)fhListByPoint[new Point(anchor.X, anchor.Y)];

            if (connectedLines.Count < 2)
            {
                return(null);
            }
            else if (connectedLines.Count == 2)
            {
                return(connectedLines[1].FhEquals(source) ? connectedLines[0] : connectedLines[1]);
            }
            else //reaching this part means whoever made the map is a f*****g idiot
            {
                FootholdLine longestFh      = null;
                int          longestFhLenth = 0;
                foreach (FootholdLine fh in connectedLines)
                {
                    int length = (int)Math.Sqrt(Math.Pow((fh.SecondDot.X - fh.FirstDot.X), 2) + Math.Pow((fh.SecondDot.Y - fh.FirstDot.Y), 2));
                    if (!fh.FhEquals(source) && length > longestFhLenth)
                    {
                        longestFh      = fh;
                        longestFhLenth = length;
                    }
                }
                return(longestFh);
            }
        }
Beispiel #2
0
        public FootholdEditor(FootholdLine[] footholds)
        {
            this.footholds = footholds;
            InitializeComponent();

            int? force = footholds[0].Force;
            int? piece = footholds[0].Piece;
            bool cantThrough = footholds[0].CantThrough;
            bool forbidFallDown = footholds[0].ForbidFallDown;
            bool indeterminate = false;
            for (int i = 1; i < footholds.Length; i++)
                if (footholds[i].Force != force) { indeterminate = true; break; }
            if (indeterminate) forceEnable.CheckState = CheckState.Indeterminate;
            else if (forceEnable.Checked = force != null) forceInt.Value = (int)force;

            indeterminate = false;
            for (int i = 1; i < footholds.Length; i++)
                if (footholds[i].Piece != piece) { indeterminate = true; break; }
            if (indeterminate) pieceEnable.CheckState = CheckState.Indeterminate;
            else if (pieceEnable.Checked = force != null) pieceInt.Value = (int)piece;

            indeterminate = false;
            for (int i = 1; i < footholds.Length; i++)
                if (footholds[i].CantThrough != cantThrough) { indeterminate = true; break; }
            if (indeterminate) cantThroughBox.CheckState = CheckState.Indeterminate;
            else cantThroughBox.Checked = cantThrough;

            indeterminate = false;
            for (int i = 1; i < footholds.Length; i++)
                if (footholds[i].ForbidFallDown != forbidFallDown) { indeterminate = true; break; }
            if (indeterminate) forbidFallDownBox.CheckState = CheckState.Indeterminate;
            else forbidFallDownBox.Checked = forbidFallDown;
        }
 private void CreateFootholdsFromAnchorList(Board board, List <FootholdAnchor> anchors)
 {
     for (int i = 0; i < anchors.Count - 1; i++)
     {
         FootholdLine fh = new FootholdLine(board, anchors[i], anchors[i + 1]);
         board.BoardItems.FootholdLines.Add(fh);
     }
 }
        public void ParseOffsets(TileInstance instance, Board board, int x, int y)
        {
            List <FootholdAnchor> anchors = new List <FootholdAnchor>();

            foreach (XNA.Point foothold in footholdOffsets)
            {
                FootholdAnchor anchor = new FootholdAnchor(board, x + foothold.X, y + foothold.Y, instance.LayerNumber, instance.PlatformNumber, true);
                anchors.Add(anchor);
                board.BoardItems.FHAnchors.Add(anchor);
                instance.BindItem(anchor, foothold);
            }
            for (int i = 0; i < anchors.Count - 1; i++)
            {
                FootholdLine fh = new FootholdLine(board, anchors[i], anchors[i + 1]);
                board.BoardItems.FootholdLines.Add(fh);
            }
        }
        private bool IsAnchorPrevOfFoothold(FootholdAnchor a, FootholdLine x)
        {
            int prevnum = x.prev;
            int nextnum = x.next;

            foreach (FootholdLine l in a.connectedLines)
            {
                if (l.num == prevnum)
                {
                    return(true);
                }
                else if (l.num == nextnum)
                {
                    return(false);
                }
            }

            throw new Exception("Could not match anchor to foothold");
        }
Beispiel #6
0
 public void Clear()
 {
     lock (Board.ParentControl)
     {
         if (currAddedObj != null)
         {
             currAddedObj.RemoveItem(null);
             currAddedObj = null;
         }
         if (state == MouseState.Ropes || state == MouseState.Tooltip)
         {
             if (state == MouseState.Ropes)
             {
                 ((RopeAnchor)BoundItems.Keys.ElementAt(0)).RemoveItem(null);
             }
             else
             {
                 ((ToolTipDot)BoundItems.Keys.ElementAt(0)).ParentTooltip.RemoveItem(null);
             }
         }
         else if (state == MouseState.Footholds && connectedLines.Count > 0)
         {
             FootholdLine fh = (FootholdLine)connectedLines[0];
             fh.Remove(false, null);
             Board.BoardItems.FootholdLines.Remove(fh);
         }
         else if (state == MouseState.Clock)
         {
             List <BoardItem> items = BoundItems.Keys.ToList();
             foreach (BoardItem item in items)
             {
                 item.RemoveItem(null);
             }
         }
         InputHandler.ClearBoundItems(Board);
         InputHandler.ClearSelectedItems(Board);
         IsDown = false;
     }
 }
Beispiel #7
0
 private static void CheckAnchorPairMerge(FootholdAnchor a, FootholdAnchor b)
 {
     if (a.X == b.X && a.Y == b.Y && a.LayerNumber == b.LayerNumber)
     {
         FootholdLine lineA = (FootholdLine)a.connectedLines[0];
         FootholdLine lineB = (FootholdLine)b.connectedLines[0];
         if ((lineA.next == lineB.num && lineB.prev == lineA.num) ||
             (lineA.prev == lineB.num && lineB.next == lineA.num))
         {
             b.removed = true;
             if (lineB.FirstDot == b) //b is firstdot
             {
                 lineB.FirstDot = a;
             }
             else
             {
                 lineB.SecondDot = a;
             }
             a.connectedLines.Add(lineB);
         }
     }
 }
Beispiel #8
0
 public void TryConnectFoothold()
 {
     lock (Board.ParentControl)
     {
         Xna.Point     pos = new Xna.Point(X, Y);
         SelectionInfo sel = board.GetUserSelectionInfo();
         foreach (FootholdAnchor anchor in Board.BoardItems.FHAnchors)
         {
             if (MultiBoard.IsPointInsideRectangle(pos, anchor.Left, anchor.Top, anchor.Right, anchor.Bottom) && anchor.CheckIfLayerSelected(sel))
             {
                 if (anchor.connectedLines.Count > 1)
                 {
                     continue;
                 }
                 if (connectedLines.Count > 0) // Are we already holding a foothold?
                 {
                     // We are, so connect the two ends
                     // Check that we are not connecting a foothold to itself, or creating duplicate footholds
                     if (connectedLines[0].FirstDot != anchor && !FootholdLine.Exists(anchor.X, anchor.Y, connectedLines[0].FirstDot.X, connectedLines[0].FirstDot.Y, Board))
                     {
                         Board.UndoRedoMan.AddUndoBatch(new List <UndoRedoAction> {
                             UndoRedoManager.LineAdded(connectedLines[0], connectedLines[0].FirstDot, anchor)
                         });
                         connectedLines[0].ConnectSecondDot(anchor);
                         // Now that we finished the previous foothold, create a new one between the anchor and the mouse
                         FootholdLine fh = new FootholdLine(Board, anchor);
                         Board.BoardItems.FootholdLines.Add(fh);
                     }
                 }
                 else // Construct a footholdline between the anchor and the mouse
                 {
                     Board.BoardItems.FootholdLines.Add(new FootholdLine(Board, anchor));
                 }
             }
         }
     }
 }
Beispiel #9
0
        //false = prev is in second point, true = prev is in first point
        private static bool GetVerticalFootholdDirection(FootholdLine fh, Hashtable fhListByPoint)
        {
            FootholdLine oldFh  = null;
            FootholdLine currFh = fh;

            while (currFh.FirstDot.X == currFh.SecondDot.X)
            {
                oldFh  = currFh;
                currFh = GetOtherFh(GetTopAnchor(currFh), currFh, fhListByPoint);
                if (currFh == null)
                {
                    goto try_other_side;                 //no more connections, try from other side
                }
            }

            FootholdAnchor oldFhConnectAnchor = GetTopAnchor(oldFh);
            FootholdAnchor otherAnchor        = oldFhConnectAnchor == currFh.FirstDot ? (FootholdAnchor)currFh.SecondDot : (FootholdAnchor)currFh.FirstDot;

            return(!((otherAnchor.X > oldFhConnectAnchor.X) ^ (fh.FirstDot.Y > fh.SecondDot.Y)));

try_other_side:
            oldFh  = null;
            currFh = fh;
            while (currFh.FirstDot.X == currFh.SecondDot.X)
            {
                oldFh  = currFh;
                currFh = GetOtherFh(GetBottomAnchor(currFh), currFh, fhListByPoint);
                if (currFh == null)
                {
                    return(false);                //no more connections, return false (could be true too) because this foothold is 100% wall
                }
            }

            oldFhConnectAnchor = GetBottomAnchor(oldFh);
            otherAnchor        = oldFhConnectAnchor == currFh.FirstDot ? (FootholdAnchor)currFh.SecondDot : (FootholdAnchor)currFh.FirstDot;
            return(!((otherAnchor.X > oldFhConnectAnchor.X) ^ (fh.FirstDot.Y < fh.SecondDot.Y)));
        }
Beispiel #10
0
 private static FootholdAnchor GetBottomAnchor(FootholdLine fh)
 {
     return(fh.FirstDot.Y < fh.SecondDot.Y ? (FootholdAnchor)fh.SecondDot : (FootholdAnchor)fh.FirstDot);
 }
Beispiel #11
0
        public static void ConvertToMapleFootholds2(ref MapleList <FootholdLine> oldFootholds, ref MapleList <FootholdAnchor> oldAnchors)
        {
            //Part 1 - copying and filtering out unused anchors
            List <FootholdLine>   footholds = new List <FootholdLine>(oldFootholds.Count);
            List <FootholdAnchor> anchors   = new List <FootholdAnchor>(oldAnchors.Count);

            foreach (FootholdAnchor oldAnchor in oldAnchors)
            {
                if (oldAnchor.connectedLines.Count == 0)
                {
                    continue;
                }
                //if (oldAnchor.IsMoveHandled) throw new Exception();
                FootholdAnchor anchor = new FootholdAnchor(oldAnchor.Board, oldAnchor.X, oldAnchor.Y, oldAnchor.LayerNumber, oldAnchor.BeforeAdding);
                anchor.connectedLines = new List <MapleLine>(oldAnchor.connectedLines.Count);
                foreach (FootholdLine oldLine in oldAnchor.connectedLines)
                {
                    if (oldLine.cloneLine == null)
                    {
                        FootholdAnchor firstDot  = null;
                        FootholdAnchor secondDot = null;
                        if (oldLine.FirstDot.X > oldLine.SecondDot.X)
                        {
                            firstDot  = (FootholdAnchor)oldLine.SecondDot;
                            secondDot = (FootholdAnchor)oldLine.FirstDot;
                        }
                        else if (oldLine.FirstDot.X < oldLine.SecondDot.X)
                        {
                            firstDot  = (FootholdAnchor)oldLine.FirstDot;
                            secondDot = (FootholdAnchor)oldLine.SecondDot;
                        }
                        else
                        {
                            if (oldLine.FirstDot.Y > oldLine.SecondDot.Y)
                            {
                                firstDot  = (FootholdAnchor)oldLine.SecondDot;
                                secondDot = (FootholdAnchor)oldLine.FirstDot;
                            }
                            else
                            {
                                firstDot  = (FootholdAnchor)oldLine.FirstDot;
                                secondDot = (FootholdAnchor)oldLine.SecondDot;
                            }
                        }
                        if (anchor.X == firstDot.X && anchor.Y == firstDot.Y) //we are firstdot
                        {
                            firstDot  = anchor;
                            secondDot = null;
                        }
                        else //we are seconddot
                        {
                            firstDot  = null;
                            secondDot = anchor;
                        }
                        oldLine.cloneLine = FootholdLine.CreateCustomFootholdLine(oldLine.Board, firstDot, secondDot);
                        footholds.Add(oldLine.cloneLine);
                    }
                    else
                    {
                        if (oldLine.cloneLine.FirstDot == null)
                        {
                            oldLine.cloneLine.FirstDot = anchor;
                        }
                        else
                        {
                            oldLine.cloneLine.SecondDot = anchor;
                        }
                    }
                    anchor.connectedLines.Add(oldLine.cloneLine);
                }
                anchors.Add(anchor);
            }
            foreach (FootholdLine fhLine in oldFootholds)
            {
                fhLine.cloneLine = null;
            }

            //Part 2 - combining anchors that are on the exact same position
            anchors.Sort(new Comparison <FootholdAnchor>(FootholdAnchor.FHAnchorSorter));
            int            groupStart = 0; //inclusive
            int            groupEnd   = 0; //inclusive
            FootholdAnchor a;
            FootholdAnchor b;
            FootholdAnchor c;
            FootholdAnchor d;
            FootholdLine   line;

            for (int i = 0; i < anchors.Count - 1; i++)
            {
                a = anchors[i];
                b = anchors[i + 1];
                if (a.Y != b.Y && a.X != b.X && a.LayerNumber == b.LayerNumber)
                {
                    groupEnd = i;
                    if (groupEnd - groupStart == 1) //there are 2 objects in the group, since groupEnd and groupStart are inclusive
                    {
                        c = anchors[groupStart];
                        d = anchors[groupEnd];
                        if (c.connectedLines.Count == 1 && d.connectedLines.Count == 1)
                        {
                            d.removed = true;
                            line      = (FootholdLine)d.connectedLines[0];
                            if (line.FirstDot == d)
                            {
                                line.FirstDot = c;
                            }
                            else
                            {
                                line.SecondDot = c;
                            }
                            c.connectedLines.Add(line);
                        }
                    }
                    groupStart = groupEnd + 1;
                }
            }

            groupEnd = anchors.Count - 1;
            if (groupEnd - groupStart == 1) //there are 2 objects in the group, since groupEnd and groupStart are inclusive
            {
                c = anchors[groupStart];
                d = anchors[groupEnd];
                if (c.connectedLines.Count == 1 && d.connectedLines.Count == 1)
                {
                    d.removed = true;
                    line      = (FootholdLine)d.connectedLines[0];
                    if (line.FirstDot == d)
                    {
                        line.FirstDot = c;
                    }
                    else
                    {
                        line.SecondDot = c;
                    }
                    c.connectedLines.Add(line);
                }
            }

            //Part 3 - connecting footholds to anchors they pass through, selectively
            //this part is made purely to fix problems in the foothold structure caused
            //by the auto foothold connection feature for tiles
            for (int i = 0; i < footholds.Count; i++)
            {
                line = footholds[i];
                if (line.FirstDot.Y != line.SecondDot.Y)
                {
                    continue;
                }
                foreach (FootholdAnchor anchor in anchors)
                {
                    if (anchor.X == line.FirstDot.Y && ((IContainsLayerInfo)line.FirstDot).LayerNumber == anchor.LayerNumber)
                    {
                        if (anchor.connectedLines.Count == 1)
                        {
                            line = (FootholdLine)anchor.connectedLines[0];
                        }
                        else
                        {
                            line = (FootholdLine)(anchor.connectedLines[0].FirstDot.Y == anchor.connectedLines[0].SecondDot.Y ? anchor.connectedLines[0] : anchor.connectedLines[1]);
                        }
                        if (line.FirstDot.Y == line.SecondDot.Y) //blueCave2 tiles, first anchor of sloped tiles
                        {
                            //footholds.RemoveAt(i);
                            line.remove = true;
                            footholds.Add(new FootholdLine(line.Board, line.FirstDot, anchor));
                            footholds.Add(new FootholdLine(line.Board, anchor, line.SecondDot));
                            //i--;
                            break;
                            //anchor.keyAnchor = line.FirstDot.Y == line.SecondDot.Y && IsValidKeyAnchor(anchor);
                        }
                        else //junction anchor for sloped tiles
                        {
                            bool direction = line.FirstDot == anchor; //true = anchor is the left dot, so we need to delete the line going to the right
                            //footholds.RemoveAt(i);
                            line.remove = true;
                            if (direction)
                            {
                                footholds.Add(new FootholdLine(line.Board, line.FirstDot, anchor));
                            }
                            else
                            {
                                footholds.Add(new FootholdLine(line.Board, anchor, line.SecondDot));
                            }
                            break;
                        }
                    }
                }

                /*                     if (((line.FirstDot.X == line.SecondDot.X) && (anchor.X == line.FirstDot.X && anchor.Y > line.FirstDot.Y && anchor.Y < line.SecondDot.Y)
                || ((line.FirstDot.Y == line.SecondDot.Y) && (anchor.Y == line.FirstDot.Y && anchor.X > line.FirstDot.X && anchor.X < line.SecondDot.X)))
                || && ((IContainsLayerInfo)line.FirstDot).LayerNumber == anchor.LayerNumber)*/
            }

            FootholdLine lineA;
            FootholdLine lineB;

            //Part 4 - removing duplicate footholds (caused by step 3, case 1)
            footholds.Sort(new Comparison <FootholdLine>(FHSorter));
            for (int i = 0; i < footholds.Count - 1; i++)
            {
                lineA = footholds[i];
                lineB = footholds[i + 1];
                if (lineA.FirstDot.X == lineB.FirstDot.X && lineA.FirstDot.Y == lineB.FirstDot.Y &&
                    lineA.SecondDot.X == lineB.SecondDot.X && lineA.SecondDot.Y == lineB.SecondDot.Y)
                {
                    //footholds.RemoveAt(i);
                    lineA.remove = true;
                    i--;
                }
            }

            //Part 5 - executing foothold changes and updating anchors
            foreach (FootholdAnchor anchor in anchors)
            {
                for (int i = 0; i < anchor.connectedLines.Count; i++)
                {
                    if (((FootholdLine)anchor.connectedLines[i]).remove)
                    {
                        anchor.connectedLines.RemoveAt(i);
                    }
                }
            }
            List <FootholdLine> newFootholds = new List <FootholdLine>(footholds.Count);

            foreach (FootholdLine fh in footholds)
            {
                if (!fh.remove)
                {
                    newFootholds.Add(fh);
                }
            }
            footholds = newFootholds;


            //Part 6 - dealing with 3 way (or more) foothold junctions

            /*foreach (FootholdAnchor anchor in anchors)
             * {
             *  if (anchor.connectedLines.Count > 2)
             *  {
             *      if (anchor.keyAnchor)
             *      {
             *          int leftLineIndex = -1;
             *          int rightLineIndex = -1;
             *          int slopedLineIndex = -1;
             *          for(int i=0; i<anchor.connectedLines.Count; i++)
             *          {
             *              FootholdLine line = (FootholdLine)anchor.connectedLines[i];
             *              if (line.FirstDot.Y == line.SecondDot.Y)
             *              {
             *                  if (anchor == line.FirstDot) rightLineIndex = i;
             *                  else if (anchor == line.SecondDot) leftLineIndex = i;
             *                  else
             *                  {
             *                      MessageBox.Show("Error at foothold parsing"); //TODO
             *                  }
             *              }
             *              else if (line.FirstDot.X != line.SecondDot.X) slopedLineIndex = i;
             *          }
             *          if (leftLineIndex == -1 || rightLineIndex == -1 || slopedLineIndex == -1)
             *          {
             *              MessageBox.Show("Error at foothold parsing"); //TODO
             *          }
             *          FootholdLine slopedLine = (FootholdLine)anchor.connectedLines[slopedLineIndex];
             *          if (slopedLine.FirstDot.Y < slopedLine.SecondDot.Y)
             *          { //eliminate left
             *              EliminateFootholdTree(anchor, leftLineIndex, ref footholds);
             *          }
             *          else
             *          {
             *              //eliminate right
             *              EliminateFootholdTree(anchor, rightLineIndex, ref footholds);
             *          }
             *      }
             *      else
             *      {
             *          double lowestLength = double.MaxValue;
             *          int shortestLineIndex = -1;
             *          for (int i = 0; i < anchor.connectedLines.Count; i++)
             *          {
             *              double length = CalculateFootholdTreeLength(anchor, i);
             *              if (length < lowestLength)
             *              {
             *                  lowestLength = length;
             *                  shortestLineIndex = i;
             *              }
             *          }
             *          EliminateFootholdTree(anchor, shortestLineIndex, ref footholds);
             *      }
             *  }
             * }
             *
             * //Part 7 - executing foothold changes and updating anchors (again)
             * foreach (FootholdAnchor anchor in anchors)
             *  for (int i = 0; i < anchor.connectedLines.Count; i++)
             *      if (((FootholdLine)anchor.connectedLines[i]).remove)
             *          anchor.connectedLines.RemoveAt(i);*/

            oldAnchors.Clear();
            foreach (FootholdAnchor anchor in anchors) /*anchor.keyAnchor = false; */ oldAnchors {
        public void LoadFootholds(WzImage mapImage, Board mapBoard)
        {
            List <FootholdAnchor> anchors        = new List <FootholdAnchor>();
            WzSubProperty         footholdParent = (WzSubProperty)mapImage["foothold"];
            int            layer;
            FootholdAnchor a;
            FootholdAnchor b;
            Dictionary <int, FootholdLine> fhs = new Dictionary <int, FootholdLine>();

            foreach (WzSubProperty layerProp in footholdParent.WzProperties)
            {
                layer = int.Parse(layerProp.Name);
                Layer l = mapBoard.Layers[layer];
                foreach (WzSubProperty platProp in layerProp.WzProperties)
                {
                    int zM = int.Parse(platProp.Name);
                    l.zMList.Add(zM);
                    foreach (WzSubProperty fhProp in platProp.WzProperties)
                    {
                        a = new FootholdAnchor(mapBoard, InfoTool.GetInt(fhProp["x1"]), InfoTool.GetInt(fhProp["y1"]), layer, zM, false);
                        b = new FootholdAnchor(mapBoard, InfoTool.GetInt(fhProp["x2"]), InfoTool.GetInt(fhProp["y2"]), layer, zM, false);
                        int       num            = int.Parse(fhProp.Name);
                        int       next           = InfoTool.GetInt(fhProp["next"]);
                        int       prev           = InfoTool.GetInt(fhProp["prev"]);
                        MapleBool cantThrough    = InfoTool.GetOptionalBool(fhProp["cantThrough"]);
                        MapleBool forbidFallDown = InfoTool.GetOptionalBool(fhProp["forbidFallDown"]);
                        int?      piece          = InfoTool.GetOptionalInt(fhProp["piece"]);
                        int?      force          = InfoTool.GetOptionalInt(fhProp["force"]);
                        if (a.X != b.X || a.Y != b.Y)
                        {
                            FootholdLine fh = new FootholdLine(mapBoard, a, b, forbidFallDown, cantThrough, piece, force);
                            fh.num  = num;
                            fh.prev = prev;
                            fh.next = next;
                            mapBoard.BoardItems.FootholdLines.Add(fh);
                            fhs[num] = fh;
                            anchors.Add(a);
                            anchors.Add(b);
                        }
                    }
                }

                anchors.Sort(new Comparison <FootholdAnchor>(FootholdAnchor.FHAnchorSorter));
                for (int i = 0; i < anchors.Count - 1; i++)
                {
                    a = anchors[i];
                    b = anchors[i + 1];
                    if (a.X == b.X && a.Y == b.Y)
                    {
                        FootholdAnchor.MergeAnchors(a, b); // Transfer lines from b to a
                        anchors.RemoveAt(i + 1);           // Remove b
                        i--;                               // Fix index after we removed b
                    }
                }
                foreach (FootholdAnchor anchor in anchors)
                {
                    if (anchor.connectedLines.Count > 2)
                    {
                        foreach (FootholdLine line in anchor.connectedLines)
                        {
                            if (IsAnchorPrevOfFoothold(anchor, line))
                            {
                                if (fhs.ContainsKey(line.prev))
                                {
                                    line.prevOverride = fhs[line.prev];
                                }
                            }
                            else
                            {
                                if (fhs.ContainsKey(line.next))
                                {
                                    line.nextOverride = fhs[line.next];
                                }
                            }
                        }
                    }
                    mapBoard.BoardItems.FHAnchors.Add(anchor);
                }
                anchors.Clear();
            }
        }
Beispiel #13
0
 private bool TryGetSimpleFootholdOrientation(FootholdLine line, out FootholdOrientation result)
 {
     if (line.prevOverride != null && line.FirstDot.connectedLines.Contains(line.prevOverride))
     {
         result = FootholdOrientation.PrevFirstNextSecond;
         return true;
     }
     else if (line.prevOverride != null && line.SecondDot.connectedLines.Contains(line.prevOverride))
     {
         result = FootholdOrientation.NextFirstPrevSecond;
         return true;
     }
     else if (line.nextOverride != null && line.FirstDot.connectedLines.Contains(line.nextOverride))
     {
         result = FootholdOrientation.NextFirstPrevSecond;
         return true;
     }
     else if (line.nextOverride != null && line.SecondDot.connectedLines.Contains(line.nextOverride))
     {
         result = FootholdOrientation.PrevFirstNextSecond;
         return true;
     }
     else if (!line.IsWall)
     {
         result = GetNonverticalFootholdOrientation(line);
         return true;
     }
     else
     {
         // Result doesn't really matter here since we're returning false
         result = FootholdOrientation.PrevFirstNextSecond;
         return false;
     }
 }
Beispiel #14
0
        private bool IsAnchorPrevOfFoothold(FootholdAnchor a, FootholdLine x)
        {
            int prevnum = x.prev;
            int nextnum = x.next;

            foreach (FootholdLine l in a.connectedLines)
            {
                if (l.num == prevnum)
                {
                    return true;
                }
                else if (l.num == nextnum)
                {
                    return false;
                }
            }

            throw new Exception("Could not match anchor to foothold");
        }
Beispiel #15
0
        public void LoadFootholds(WzImage mapImage, Board mapBoard)
        {
            List<FootholdAnchor> anchors = new List<FootholdAnchor>();
            WzSubProperty footholdParent = (WzSubProperty)mapImage["foothold"];
            int layer;
            FootholdAnchor a;
            FootholdAnchor b;
            Dictionary<int, FootholdLine> fhs = new Dictionary<int, FootholdLine>();
            foreach (WzSubProperty layerProp in footholdParent.WzProperties)
            {
                layer = int.Parse(layerProp.Name);
                Layer l = mapBoard.Layers[layer];
                foreach (WzSubProperty platProp in layerProp.WzProperties)
                {
                    int zM = int.Parse(platProp.Name);
                    l.zMList.Add(zM);
                    foreach (WzSubProperty fhProp in platProp.WzProperties)
                    {
                        a = new FootholdAnchor(mapBoard, InfoTool.GetInt(fhProp["x1"]), InfoTool.GetInt(fhProp["y1"]), layer, zM, false);
                        b = new FootholdAnchor(mapBoard, InfoTool.GetInt(fhProp["x2"]), InfoTool.GetInt(fhProp["y2"]), layer, zM, false);
                        int num = int.Parse(fhProp.Name);
                        int next = InfoTool.GetInt(fhProp["next"]);
                        int prev = InfoTool.GetInt(fhProp["prev"]);
                        MapleBool cantThrough = InfoTool.GetOptionalBool(fhProp["cantThrough"]);
                        MapleBool forbidFallDown = InfoTool.GetOptionalBool(fhProp["forbidFallDown"]);
                        int? piece = InfoTool.GetOptionalInt(fhProp["piece"]);
                        int? force = InfoTool.GetOptionalInt(fhProp["force"]);
                        if (a.X != b.X || a.Y != b.Y)
                        {
                            FootholdLine fh = new FootholdLine(mapBoard, a, b, forbidFallDown, cantThrough, piece, force);
                            fh.num = num;
                            fh.prev = prev;
                            fh.next = next;
                            mapBoard.BoardItems.FootholdLines.Add(fh);
                            fhs[num] = fh;
                            anchors.Add(a);
                            anchors.Add(b);
                        }
                    }
                }

                anchors.Sort(new Comparison<FootholdAnchor>(FootholdAnchor.FHAnchorSorter));
                for (int i = 0; i < anchors.Count - 1; i++)
                {
                    a = anchors[i];
                    b = anchors[i + 1];
                    if (a.X == b.X && a.Y == b.Y)
                    {
                        FootholdAnchor.MergeAnchors(a, b); // Transfer lines from b to a
                        anchors.RemoveAt(i + 1); // Remove b
                        i--; // Fix index after we removed b
                    }
                }
                foreach (FootholdAnchor anchor in anchors)
                {
                    if (anchor.connectedLines.Count > 2)
                    {
                        foreach (FootholdLine line in anchor.connectedLines)
                        {
                            if (IsAnchorPrevOfFoothold(anchor, line))
                            {
                                if (fhs.ContainsKey(line.prev))
                                {
                                    line.prevOverride = fhs[line.prev];
                                }
                            }
                            else
                            {
                                if (fhs.ContainsKey(line.next))
                                {
                                    line.nextOverride = fhs[line.next];
                                }
                            }
                        }
                    }
                    mapBoard.BoardItems.FHAnchors.Add(anchor);
                }
                anchors.Clear();
            }
        }
Beispiel #16
0
        private void multiBoard_OnEditInstanceClicked(BoardItem item)
        {
            InputHandler.ClearBoundItems(multiBoard.SelectedBoard);
            switch (item.GetType().Name)
            {
            case "ObjectInstance":
                new InstanceEditor.ObjectInstanceEditor((ObjectInstance)item).ShowDialog();
                multiBoard.RenderFrame();
                break;

            case "TileInstance":
            case "Chair":
                new InstanceEditor.GeneralInstanceEditor(item).ShowDialog();
                multiBoard.RenderFrame();
                break;

            case "FootholdAnchor":
                FootholdLine[] selectedFootholds = FootholdLine.GetSelectedFootholds(item.Board);
                if (selectedFootholds.Length > 0)
                {
                    new InstanceEditor.FootholdEditor(selectedFootholds).ShowDialog();
                }
                else
                {
                    new InstanceEditor.GeneralInstanceEditor(item).ShowDialog();
                }
                multiBoard.RenderFrame();
                break;

            case "RopeAnchor":
                new InstanceEditor.RopeInstanceEditor((RopeAnchor)item).ShowDialog();
                multiBoard.RenderFrame();
                break;

            case "LifeInstance":
                new InstanceEditor.LifeInstanceEditor((LifeInstance)item).ShowDialog();
                multiBoard.RenderFrame();
                break;

            case "ReactorInstance":
                new InstanceEditor.ReactorInstanceEditor((ReactorInstance)item).ShowDialog();
                multiBoard.RenderFrame();
                break;

            case "BackgroundInstance":
                multiBoard.RenderFrame();
                break;

            case "PortalInstance":
                new InstanceEditor.PortalInstanceEditor((PortalInstance)item).ShowDialog();
                multiBoard.RenderFrame();
                break;

            case "ToolTip":

                break;

            default:
                break;
            }
        }
Beispiel #17
0
        private FootholdOrientation GetFootholdOrientation(FootholdLine line)
        {
            FootholdOrientation result;
            if (TryGetSimpleFootholdOrientation(line, out result))
            {
                return result;
            }
            else
            {
                // Vertical foothold, search for near nonvertical foothold as orientation reference

                // Obtain vertical orientation of the foothold
                FootholdAnchor top, bottom;
                if (line.FirstDot.Y < line.SecondDot.Y)
                {
                    top = (FootholdAnchor)line.FirstDot;
                    bottom = (FootholdAnchor)line.SecondDot;
                }
                else if (line.FirstDot.Y > line.SecondDot.Y)
                {
                    bottom = (FootholdAnchor)line.FirstDot;
                    top = (FootholdAnchor)line.SecondDot;
                }
                else
                {
                    throw new Exception("Zero length foothold in saving");
                }

                // For starters, we search the footholds linking downards from us.
                // This is because we are looking for the conventional foothold U scheme:
                //
                // |     |
                // |     |
                // |_ _ _|
                //
                // or the Z/S schemes:
                //_ _ _                _ _ _
                //     |              |
                //     |              |
                //     |_ _ _ or _ _ _|
                FootholdEnumerator referenceEnumerator = new FootholdEnumerator(line, top);
                foreach (FootholdLine reference in referenceEnumerator)
                {
                    if (!reference.IsWall)
                    {
                        // We found a suiting foothold reference, find what is our orientation
                        return GetVerticalFootholdOrientationByReference(line, top, reference, referenceEnumerator.CurrentAnchor);
                    }
                }

                // If downard-search failed, search upwards, to resolve the n scheme:
                //  _ _ _
                // |     |
                // |     |
                // |     |
                //
                // Note that the order of searches is important; we MUST search downwards before upwards, to resolve schemes such as the tower scheme:
                //
                // |           |
                // |           |
                // |_ _     _ _|
                // |           |
                // |           |
                // |_ _ _ _ _ _|
                //
                // If we searched upwards-first, the footholds between the two tower "floors" would be treated as n scheme footholds, while they should be U schemed.

                referenceEnumerator = new FootholdEnumerator(line, bottom);
                foreach (FootholdLine reference in referenceEnumerator)
                {
                    if (!reference.IsWall)
                    {
                        // We found a suiting foothold reference, find what is our orientation
                        return GetVerticalFootholdOrientationByReference(line, bottom, reference, referenceEnumerator.CurrentAnchor);
                    }
                }

                // If all else failed, we are dealing with a pure-wall foothold platform (i.e. a foothold graph consisting only of vertical footholds)
                // In this case, we arbitrarily select the Normal orientation, since there's no more actual logic we can perform to know what is the correct orientation.
                return FootholdOrientation.PrevFirstNextSecond;
            }
        }
Beispiel #18
0
        public static Hashtable ConvertToMapleFootholds2(List <FootholdLine> footholds, List <FootholdAnchor> anchors)
        {
            Hashtable fhListByPoint = new Hashtable();

            foreach (FootholdAnchor anchor in anchors)
            {
                Point anchorPos            = new Point(anchor.X, anchor.Y);
                List <FootholdLine> fhList = (List <FootholdLine>)fhListByPoint[anchorPos];
                if (fhList == null)
                {
                    fhList = new List <FootholdLine>(2);
                    fhListByPoint.Add(anchorPos, fhList);
                }
                fhList.AddRange(anchor.connectedLines.Cast <FootholdLine>());
            }
            Hashtable fhByNum = new Hashtable();

            for (int i = 1; i <= footholds.Count; i++)
            {
                FootholdLine fhClass = footholds[i - 1];
                if (fhClass.FirstDot.X == fhClass.SecondDot.X && fhClass.FirstDot.Y == fhClass.SecondDot.Y)
                {
                    continue;
                }
                fhClass.num = i;
                Foothold mapleFh = new Foothold();
                mapleFh.num   = i;
                mapleFh.layer = ((FootholdAnchor)fhClass.FirstDot).LayerNumber;
                fhByNum[i]    = mapleFh;
            }
            for (int i = 1; i <= footholds.Count; i++)
            {
                FootholdLine fhClass       = footholds[i - 1];
                Foothold     mapleFh       = (Foothold)fhByNum[i];
                FootholdLine firstOtherFh  = GetOtherFh((FootholdAnchor)fhClass.FirstDot, fhClass, fhListByPoint);
                FootholdLine secondOtherFh = GetOtherFh((FootholdAnchor)fhClass.SecondDot, fhClass, fhListByPoint);
                if (fhClass.FirstDot.X < fhClass.SecondDot.X)
                {
                    mapleFh.x1   = fhClass.FirstDot.X;
                    mapleFh.x2   = fhClass.SecondDot.X;
                    mapleFh.y1   = fhClass.FirstDot.Y;
                    mapleFh.y2   = fhClass.SecondDot.Y;
                    mapleFh.prev = firstOtherFh == null ? 0 : firstOtherFh.num;
                    mapleFh.next = secondOtherFh == null ? 0 : secondOtherFh.num;
                }
                else if (fhClass.FirstDot.X > fhClass.SecondDot.X)
                {
                    mapleFh.x1   = fhClass.SecondDot.X;
                    mapleFh.x2   = fhClass.FirstDot.X;
                    mapleFh.y1   = fhClass.SecondDot.Y;
                    mapleFh.y2   = fhClass.FirstDot.Y;
                    mapleFh.prev = secondOtherFh == null ? 0 : secondOtherFh.num;
                    mapleFh.next = firstOtherFh == null ? 0 : firstOtherFh.num;
                }
                else
                {
                    bool fhDir = GetVerticalFootholdDirection(fhClass, fhListByPoint);
                    if (fhDir) //prev = firstdot
                    {
                        mapleFh.x1   = fhClass.FirstDot.X;
                        mapleFh.x2   = fhClass.SecondDot.X;
                        mapleFh.y1   = fhClass.FirstDot.Y;
                        mapleFh.y2   = fhClass.SecondDot.Y;
                        mapleFh.prev = firstOtherFh == null ? 0 : firstOtherFh.num;
                        mapleFh.next = secondOtherFh == null ? 0 : secondOtherFh.num;
                    }
                    else //prev = seconddot
                    {
                        mapleFh.x1   = fhClass.SecondDot.X;
                        mapleFh.x2   = fhClass.FirstDot.X;
                        mapleFh.y1   = fhClass.SecondDot.Y;
                        mapleFh.y2   = fhClass.FirstDot.Y;
                        mapleFh.prev = secondOtherFh == null ? 0 : secondOtherFh.num;
                        mapleFh.next = firstOtherFh == null ? 0 : firstOtherFh.num;
                    }
                }
                fhByNum[i] = mapleFh;
            }
            return(fhByNum);
        }
Beispiel #19
0
        private static void LoadFootholds(WzImage mapImage, Board mapBoard)
        {
            List <FootholdAnchor> anchors        = new List <FootholdAnchor>();
            WzSubProperty         footholdParent = (WzSubProperty)mapImage["foothold"];
            int            layer;
            FootholdAnchor a;
            FootholdAnchor b;
            FootholdAnchor c;
            FootholdAnchor d;

            foreach (WzSubProperty layerProp in footholdParent.WzProperties)
            {
                layer = int.Parse(layerProp.Name);
                foreach (WzSubProperty platProp in layerProp.WzProperties)
                {
                    foreach (WzSubProperty fhProp in platProp.WzProperties)
                    {
                        a = new FootholdAnchor(mapBoard, InfoTool.GetInt(fhProp["x1"]), InfoTool.GetInt(fhProp["y1"]), layer, false);
                        b = new FootholdAnchor(mapBoard, InfoTool.GetInt(fhProp["x2"]), InfoTool.GetInt(fhProp["y2"]), layer, false);
                        int num  = int.Parse(fhProp.Name);
                        int next = InfoTool.GetInt(fhProp["next"]);
                        int prev = InfoTool.GetInt(fhProp["prev"]);
                        if (a.X != b.X || a.Y != b.Y)
                        {
                            FootholdLine fh = new FootholdLine(mapBoard, a, b);
                            fh.num  = num;
                            fh.prev = prev;
                            fh.next = next;
                            mapBoard.BoardItems.FootholdLines.Add(fh);
                            anchors.Add(a);
                            anchors.Add(b);
                        }
                    }
                }

                anchors.Sort(new Comparison <FootholdAnchor>(FootholdAnchor.FHAnchorSorter));
                int groupStart = 0; //inclusive
                int groupEnd   = 0; //inclusive
                for (int i = 0; i < anchors.Count - 1; i++)
                {
                    a = anchors[i];
                    b = anchors[i + 1];
                    if (a.Y != b.Y && a.X != b.X && a.LayerNumber == b.LayerNumber)
                    {
                        groupEnd = i;
                        if (groupEnd - groupStart == 1) //there are 2 objects in the group, since groupEnd and groupStart are inclusive
                        {
                            c = anchors[groupStart];
                            d = anchors[groupEnd];
                            CheckAnchorPairMerge(c, d);
                        }
                        else if (groupEnd - groupStart != 0)
                        {
                            for (int j = groupStart; j <= groupEnd; j++)
                            {
                                c = anchors[j];
                                for (int k = groupStart; k <= groupEnd; k++)
                                {
                                    if (c.removed)
                                    {
                                        break;
                                    }
                                    d = anchors[k];
                                    if (d.removed)
                                    {
                                        continue;
                                    }
                                    CheckAnchorPairMerge(c, d);
                                }
                            }
                        }
                        groupStart = groupEnd + 1;
                    }
                }

                groupEnd = anchors.Count - 1;
                if (groupEnd - groupStart == 1) //there are 2 objects in the group, since groupEnd and groupStart are inclusive
                {
                    c = anchors[groupStart];
                    d = anchors[groupEnd];
                    CheckAnchorPairMerge(c, d);
                }
                else if (groupEnd - groupStart != 0)
                {
                    for (int j = groupStart; j <= groupEnd; j++)
                    {
                        c = anchors[j];
                        for (int k = groupStart; k <= groupEnd; k++)
                        {
                            if (c.removed)
                            {
                                break;
                            }
                            d = anchors[k];
                            if (d.removed)
                            {
                                continue;
                            }
                            CheckAnchorPairMerge(c, d);
                        }
                    }
                }

                //FootholdAnchor.MergeAnchors(ref anchors);

                /*if (mapBoard.BoardItems.FHAnchors.Count + anchors.Count > mapBoard.BoardItems.FHAnchors.Capacity)
                 *  mapBoard.BoardItems.FHAnchors.Capacity = mapBoard.BoardItems.FHAnchors.Count + anchors.Count;
                 * anchors.ForEach(X => if  mapBoard.BoardItems.FHAnchors.Add(X));
                 * anchors.Clear();*/
                mapBoard.BoardItems.FHAnchors.Capacity = mapBoard.BoardItems.FHAnchors.Count + anchors.Count * 2;
                foreach (FootholdAnchor anchor in anchors)
                {
                    if (!anchor.removed)
                    {
                        mapBoard.BoardItems.FHAnchors.Add(anchor);
                    }
                }
                anchors.Clear();
            }
        }
Beispiel #20
0
        private FootholdOrientation GetVerticalFootholdOrientationByReference(FootholdLine line, FootholdAnchor anchor, FootholdLine reference, FootholdAnchor referenceAnchor)
        {
            FootholdOrientation referenceOrientation = GetNonverticalFootholdOrientation(reference);
            bool leadingAnchorIsFirst = referenceAnchor == reference.FirstDot;
            bool firstIsPrev = referenceOrientation == FootholdOrientation.PrevFirstNextSecond;
            bool startAnchorIsFirst = anchor == line.FirstDot;

            // LAIF | FIP | RESULT (leadingAnchorIsPrev "LAIP")
            //  1   |  1  |   1
            //  1   |  0  |   0
            //  0   |  1  |   0
            //  0   |  0  |   1

            // LAIP | SAIF | RESULT (Orientation: 0 normal, 1 inverted)
            //  1   |  1   |   0
            //  1   |  0   |   1
            //  0   |  1   |   1
            //  0   |  0   |   0

            return !(leadingAnchorIsFirst ^ firstIsPrev) ^ startAnchorIsFirst ? FootholdOrientation.NextFirstPrevSecond : FootholdOrientation.PrevFirstNextSecond;
        }
Beispiel #21
0
 private FootholdOrientation GetNonverticalFootholdOrientation(FootholdLine line)
 {
     if (line.FirstDot.X < line.SecondDot.X)
     {
         // Normal foothold orientation
         return FootholdOrientation.PrevFirstNextSecond;
     }
     else // (line.FirstDot.X > line.SecondDot.X)
     {
         // Inverted foothold orientation
         return FootholdOrientation.NextFirstPrevSecond;
     }
 }
Beispiel #22
0
 private int GetFootholdPrevNext(FootholdLine line, FootholdOrientation orientation, FootholdDirection dir)
 {
     FootholdLine overrideLine = dir == FootholdDirection.Prev ? line.prevOverride : line.nextOverride;
     if (overrideLine != null && (line.FirstDot.connectedLines.Contains(overrideLine) || line.SecondDot.connectedLines.Contains(overrideLine)))
     {
         return overrideLine.num;
     }
     else
     {
         FootholdAnchor anchor = (FootholdAnchor)((orientation == FootholdOrientation.PrevFirstNextSecond) ^ (dir == FootholdDirection.Next) ? line.FirstDot : line.SecondDot);
         if (anchor.connectedLines.Count < 2)
         {
             return 0;
         }
         else
         {
             return anchor.GetOtherLine(line).num;
         }
     }
 }