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; }
//measurement units are second and pixel public void ProcessPhysics() { double timeDiff = (Environment.TickCount - lastProcessTimeStamp) / 1000d; if (timeDiff == 0) return; if (mode == CharacterMode.Prone) goto end; int x_threshold = (int)(timeDiff * Velocity.X + (Acceleration.X / 2) * timeDiff * timeDiff);//x = vt + 0.5at^2 int y_threshold = (int)(timeDiff * Velocity.Y + (Acceleration.Y / 2) * timeDiff * timeDiff); Velocity.X += (int)(Acceleration.X * timeDiff); //v = at Velocity.Y += (int)(Acceleration.Y * timeDiff); if (Velocity.Y > fallSpeed) Velocity.Y = (int)fallSpeed; if (mode != CharacterMode.Fly) { if (direction == 1 && x + x_threshold > foothold.x2) { if (foothold.next != 0) { Foothold = foothold.next; x = foothold.x1; y = foothold.y1; SetVelocity((int)Velocity.X); } } else if (direction == -1 && x - x_threshold < foothold.x1) { if (foothold.prev != 0) { Foothold = foothold.prev; x = foothold.x2; y = foothold.y2; SetVelocity((int)Velocity.X); } } else { y += y_threshold; x += x_threshold; } if (foothold.num == 0) DoProne(); } else { if (Velocity.Y > 0) foreach (DictionaryEntry fhEntry in MapSimulator.footholds) { Foothold fh = (Foothold)fhEntry.Value; if (fh.x1 < x + x_threshold && fh.x2 > x + x_threshold) { int slope = (fh.y2 - fh.y1) / (fh.x2 - fh.x1); int yPos = fh.y1 + slope * ((x + x_threshold) - fh.x1); if (y < yPos && y + y_threshold >= yPos) { y = yPos; x += x_threshold; foothold = fh; footholdNum = fh.num; mode = CharacterMode.Prone; goto end; } } } y += y_threshold; if (y_threshold < 0) { } x += x_threshold; } end: lastProcessTimeStamp = Environment.TickCount; }