private void ReCalculatePath() { if (map == null || map.HeightMapBuilder == null || target == null) { return; } map.HeightMapBuilder.NormalizeCoordinates(target.X, target.Y, target.Z, out int tmpX, out int tmpY, out int tmpZ); bool found = false; List <Vec3i> points = new List <Vec3i>(); for (int i = tmpX - 1; i <= tmpX + 1 && !found; i++) { for (int j = tmpY - 1; j <= tmpY + 1 && !found; j++) { if (map.HeightMapBuilder.IsWalkable(i, j, tmpZ, i, j, tmpZ)) { map.HeightMapBuilder.RealCoordinatesFromNormalized(i, j, tmpZ, out int tmpX2, out int tmpY2, out int tmpZ2); points.Add(new Vec3i(tmpX2, tmpY2, tmpZ2)); } } } points = points.OrderBy((point) => { return(self.DistanceToPoint(point.X, point.Y, point.Z)); }).ToList(); if (points.Count > 0) { found = true; x = (short)points[0].X; y = (short)points[0].Y; z = (short)points[0].Z; } if (found) { currentPath = map.PathFinding.FindPath(self.X, self.Y, self.Z, x, y, z); x = (short)target.X; y = (short)target.Y; z = (short)target.Z; } else { currentPath = map.PathFinding.FindPath(self.X, self.Y, self.Z, target.X, target.Y, target.Z); } curPathIdx = 0; }
public void Update() { if (currentPath == null) { ReCalculatePath(); } if (self.DistanceToPoint(x, y, z) > 30) { if (currentPath.Count > curPathIdx) { PathNode node = currentPath[curPathIdx++]; MoveArgument arg = new MoveArgument() { X = node.X, Y = node.Y, Z = map.HeightMapBuilder.GetZ((short)node.X, (short)node.Y, (short)node.Z) }; if (arg.Z == 0) { status = CommandStatus.Finished; return; } arg.Dir = self.DirectionFromTarget(node.X, node.Y); arg.Speed = (ushort)((500 * ((float)500 / self.Speed)) * 2); arg.DashID = 0; arg.DashUnknown = 0; arg.BNSMoveType = MoveType.Walk; map.MoveActor(self, arg); } else { status = CommandStatus.Finished; } } else { status = CommandStatus.Finished; } }
private void DoNormal() { currentTarget = GetCurrentTarget(); if (currentTarget != null && (npc.DistanceToActor(currentTarget) > 500 || (currentTarget.Status.Dead && !currentTarget.Status.Recovering))) { hateTable.TryRemove(currentTarget.ActorID, out int removed); currentTarget = null; } if (currentCommand == null) { if (currentTarget == null) { period = 1000; if (!HasVisiblePlayer()) { sleepCounter++; if (sleepCounter > 100) { Deactivate(); sleepCounter = 0; } } else { sleepCounter = 0; } CheckAggro(); if (npc.MoveRange > 0 || (npc.DistanceToPoint(npc.X_Ori, npc.Y_Ori, npc.Z_Ori) > npc.MoveRange && npc.MoveRange > 0)) { if (Global.Random.Next(0, 99) < 30) { Vec3 vec = Vec3.Zero; int shouldDistance = 75; int dis = npc.DistanceToPoint(npc.X_Ori, npc.Y_Ori, npc.Z_Ori); if (dis > npc.MoveRange) { int deltaX = npc.X_Ori - npc.X; int deltaY = npc.Y_Ori - npc.Y; float distance = (float)(Math.Sqrt(deltaX * deltaX + deltaY * deltaY)); vec.X = deltaX / distance; vec.Y = deltaY / distance; if (dis < shouldDistance) { shouldDistance = dis; } } else { ushort dir = (ushort)Global.Random.Next(0, 359); vec = dir.DirectionToVector(); } if (shouldDistance > 15) { vec *= shouldDistance; vec.X += npc.X; vec.Y += npc.Y; var points = from p in map.HeightMapBuilder.GetZ((short)vec.X, (short)vec.Y) orderby Math.Abs(npc.Z - p.Key) select p; currentCommand = new Move(this, npc, (short)vec.X, (short)vec.Y, points.FirstOrDefault().Key); } } } } else { period = 400; if (npc.DistanceToActor(currentTarget) <= GetCurrentCastRange(currentTarget)) { currentCommand = new Attack(this, npc, currentTarget); } else { currentCommand = new Chase(this, npc, currentTarget); } } } else { if (currentTarget == null) { CheckAggro(); } currentCommand.Target = currentTarget; if (currentCommand.Status == CommandStatus.Running) { currentCommand.Update(); } else { currentCommand = null; } } }