public bool RayTrace(Vec3 from, Vec3 to, MovementFlag flags, out Vec3 intersection) { using (new ReadLock(DataLock)) { intersection = Vec3.Empty; Vec3 ray_dir = to - from; ray_dir.Normalize(); foreach (Cell c in m_AllCells) { if (!c.HasFlags(flags)) { continue; } Vec3 new_intersection = null; if (c.AABB.RayTest(from, ray_dir, ref new_intersection) && from.DistanceSqr(new_intersection) < from.DistanceSqr(intersection)) { intersection = new_intersection; } } return(!intersection.IsEmpty); } }
public CellsPatch(HashSet <Cell> cells, Dictionary <AABB, List <Cell> > cellsGrid, MovementFlag movement_flags) { Flags = movement_flags; Cells = cells; CellsGrid = cellsGrid; GlobalId = Interlocked.Increment(ref LastCellsPatchGlobalId); }
public void Move(MovementFlag direction) { positionOnLine(); if (direction == MovementFlag.Left) { Rotation = (Rotation + TMath.HALF_PI) % TMath.TWO_PI; if (Math.Round(Rotation) == 6) // Above two pi { Rotation = 0; } } else if (direction == MovementFlag.Right) { Rotation -= TMath.HALF_PI; if (Rotation < 0) { if (Math.Round(Rotation) == 0) { Rotation = 0; } else { Rotation += TMath.TWO_PI; } } } Velocity = _velocities[Math.Round(Rotation)]; }
public bool IsPositionReachable(Vec3 from, Vec3 to, MovementFlag flags, float tolerance) { List <Vec3> tmp_path = new List <Vec3>(); FindPath(from, to, flags, ref tmp_path, -1, true, true, 0, false, 0, false); return(tmp_path.Count > 0 ? tmp_path.Last().Distance(to) <= tolerance : false); }
public static void Visit <T>(T cell, ref HashSet <T> visited, MovementFlag flags, bool visit_disabled, int depth = 1, int max_depth = -1, HashSet <T> allowed_cells = null, IVisitor <T> visitor = null) where T : Cell { visited.Add(cell); if (max_depth > 0 && depth >= max_depth) { return; } foreach (Cell.Neighbour neighbour in cell.Neighbours) { T neighbour_cell = (T)neighbour.cell; if ((!visit_disabled && neighbour_cell.Disabled) || (neighbour.connection_flags & flags) != flags) { continue; } if (visitor != null) { visitor.Visit(neighbour_cell); } if ((allowed_cells == null || allowed_cells.Contains(neighbour_cell)) && !visited.Contains(neighbour_cell)) { Visit(neighbour_cell, ref visited, flags, visit_disabled, depth + 1, max_depth, allowed_cells, visitor); } } }
public bool FindPath(Vec3 from, Vec3 to, MovementFlag flags, ref List <Vec3> path, float merge_distance = -1, bool as_close_as_possible = false, bool include_from = false, float random_coeff = 0, bool bounce = false, float shift_nodes_distance = 0, bool smoothen = true) { using (m_Navmesh.AcquireReadDataLock()) { List <path_pos> tmp_path = new List <path_pos>(); if (from.IsEmpty || to.IsEmpty) { return(false); } Cell start = null; Cell end = null; bool start_on_nav_mesh = m_Navmesh.GetCellContaining(from, out start, flags, false, as_close_as_possible, -1, false, 2, null); bool end_on_nav_mesh = m_Navmesh.GetCellContaining(to, out end, flags, false, as_close_as_possible, -1, false, 2, null); if (bounce) { Vec3 bounce_dir = start.AABB.GetBounceDir2D(from); Vec3 new_from = from + bounce_dir * 10; m_Navmesh.GetCellContaining(new_from, out start, flags, false, as_close_as_possible, -1, false, 2, null); if (!Algorihms.FindPath <Cell>(start, ref end, new_from, to, flags, ref tmp_path, random_coeff, true)) { return(false); } tmp_path.Insert(0, new path_pos(start.AABB.Align(from), start)); } else { if (!Algorihms.FindPath <Cell>(start, ref end, from, to, flags, ref tmp_path, random_coeff, true)) { return(false); } } if (smoothen && random_coeff == 0) { SmoothenPath(ref tmp_path, flags, bounce ? 1 : 0); } if (DistToKeepFromEdge > 0 && random_coeff == 0) { KeepAwayFromEdges(ref tmp_path, flags); } path = tmp_path.Select(x => x.pos).ToList(); PostProcessPath(ref path, merge_distance, shift_nodes_distance); if (!include_from && start_on_nav_mesh) { path.RemoveAt(0); } return(true); } }
// This function will return list of cells pairs that should be connected public List <(Cell, Cell, Vec3)> CheckNeighbour(GridCell grid_cell, out MovementFlag connection_flags) { var result = new List <(Cell, Cell, Vec3)>(); connection_flags = MovementFlag.None; if (GlobalId == grid_cell.GlobalId || !AABB.Overlaps2D(grid_cell.AABB, true)) { return(result); } foreach (Cell our_cell in Cells) { foreach (Cell other_cell in grid_cell.Cells) { Vec3 border_point = default(Vec3); bool should_be_connected = our_cell.ShouldBecomeNeighbours(other_cell, ref border_point); if (should_be_connected) { result.Add((our_cell, other_cell, border_point)); MovementFlag flags = our_cell.Flags & other_cell.Flags; if (flags > connection_flags) { connection_flags = flags; } } } } return(result); }
public bool AreConnected(Vec3 pos1, Vec3 pos2, MovementFlag flags) { using (new ReadLock(DataLock)) { GridCell pos1_gc = m_GridCells.Find(g => g.Contains2D(pos1)); GridCell pos2_gc = m_GridCells.Find(g => g.Contains2D(pos2)); return(Algorihms.AreConnected(pos1_gc, ref pos2_gc, flags)); } }
private void InitCell(int id, AABB aabb, MovementFlag flags, float movement_cost_mult) { Id = id; Flags = flags; MovementCostMult = movement_cost_mult; Replacement = false; Disabled = false; AABB = aabb; Neighbours = new List <Neighbour>(); GlobalId = LastCellGlobalId++; }
// Try to connect grid_cell with this cell. Connection can be established only when any two cells of both grid cells are connected. This function should behave // properly when called multiple times for the same pair of grid cells! public void AddNeighbour(GridCell grid_cell) { if (GlobalId == grid_cell.GlobalId || !AABB.Overlaps2D(grid_cell.AABB, true)) { return; } // this is removed to properly handle merging //if (Neighbours.Exists(x => x.cell.Equals(grid_cell))) // return; bool any_cells_connected = false; MovementFlag connection_flags = MovementFlag.None; foreach (Cell our_cell in Cells) { foreach (Cell other_cell in grid_cell.Cells) { Vec3 border_point = default(Vec3); bool cells_connected = our_cell.AddNeighbour(other_cell, ref border_point); if (cells_connected) { any_cells_connected = true; MovementFlag flags = our_cell.Flags & other_cell.Flags; if (flags > connection_flags) { connection_flags = flags; } } } } if (any_cells_connected) { Neighbour n1 = Neighbours.FirstOrDefault(x => x.cell.GlobalId == grid_cell.GlobalId); // if they were not connected before, simply connect them if (n1 == null) { Neighbours.Add(new Neighbour(grid_cell, Vec3.ZERO, connection_flags)); grid_cell.Neighbours.Add(new Neighbour(this, Vec3.ZERO, connection_flags)); } // otherwise verify connection flags else if (n1.connection_flags < connection_flags) { Neighbour n2 = grid_cell.Neighbours.FirstOrDefault(x => x.cell.GlobalId == GlobalId); n1.connection_flags = connection_flags; n2.connection_flags = connection_flags; } } }
public static object[] BuildMovementPayload(Cycle cycle, MovementFlag direction) { var payload = new MovementPayload { ID = cycle.ID, Direction = direction, Position = cycle.MovementController.Position }; return(_compressor.Compress(payload)); }
private void TurnRandomly(GameTime gameTime) { List <MovementFlag> possibleMoves = MovementController.GetValidMovements(); if (possibleMoves.Count != 0) { MovementFlag movement = possibleMoves[_gen.Next(possibleMoves.Count - 1)]; base.RegisterMove(movement); _lastRandTurn = gameTime.Now; } }
public static object[] BuildMovementPayload(Cycle cycle, MovementFlag direction) { var payload = new MovementPayload { ID = cycle.ID, Direction = direction, Position = cycle.MovementController.Position }; return _compressor.Compress(payload); }
private void SmoothenPath(ref List <path_pos> path, MovementFlag flags, int skip_first_count = 0) { int ray_start_index = skip_first_count; Vec3 intersection = null; while (ray_start_index + 2 < path.Count) { path_pos ray_start_data = path[ray_start_index]; path_pos intermediate_data = path[ray_start_index + 1]; path_pos ray_end_data = path[ray_start_index + 2]; // try remove middle point completely if (m_Navmesh.RayCast2D(ray_start_data.pos, ray_end_data.pos, flags, ref intersection, false)) { path.RemoveAt(ray_start_index + 1); } else { ++ray_start_index; } } // perform second smoothing pass after getting rid of all unnecessary points to get better performance and results // this pass is basically "moving" from point to point and checking at which step (in-between points) I can already see the next point if (PathSmoothingPrecision > 0) { ray_start_index = skip_first_count; while (ray_start_index + 2 < path.Count) { path_pos ray_start_data = path[ray_start_index]; path_pos intermediate_data = path[ray_start_index + 1]; path_pos ray_end_data = path[ray_start_index + 2]; Vec3 dir = intermediate_data.pos - ray_start_data.pos; float length = dir.Normalize(); int steps = (int)(length / PathSmoothingPrecision); for (int i = 1; i < steps; ++i) // checking 0 is unnecessary since this is the current path { if (m_Navmesh.RayCast2D(ray_start_data.pos + dir * (float)i * PathSmoothingPrecision, ray_end_data.pos, flags, ref intersection, false)) { path[ray_start_index + 1] = new path_pos(ray_start_data.pos + dir * (float)i * PathSmoothingPrecision, intermediate_data.cell); break; } } ++ray_start_index; } } }
//TODO: Parameter validation /// <inheritdoc /> public MovementInfo(MovementFlag movementFlags, MovementFlagExtra extraFlags, uint timeStamp, Vector3 <float> position, float orientation, TransportationInfo transportationInformation, int transportationTime, float movePitch, int fallTime, Vector4 <float> fallData, float splineElevation) { MovementFlags = movementFlags; ExtraFlags = extraFlags; TimeStamp = timeStamp; Position = position; Orientation = orientation; TransportationInformation = transportationInformation; TransportationTime = transportationTime; MovePitch = movePitch; FallTime = fallTime; FallData = fallData; SplineElevation = splineElevation; }
public MovementInfo Convert(MovementInfo_Vanilla fromObject) { if (fromObject == null) { return(null); } MovementFlag moveFlags = MoveFlagsConverter.Convert(fromObject.MoveFlags); MovementInfo info = new MovementInfo(moveFlags, MovementFlagExtra.None, fromObject.TimeStamp, fromObject.Position, fromObject.Orientation, TransportInfoConverter.Convert(fromObject.TransportationInformation), fromObject.TransportTime, fromObject.MovePitch, fromObject.FallTime, fromObject.FallData, fromObject.SplineElevation); return(info); }
public static void VisitBreadth <T>(T cell, MovementFlag flags, int max_depth = -1, HashSet <T> allowed_cells = null, IDistanceVisitor <T> visitor = null) where T : Cell { HashSet <T> visited = new HashSet <T>(); List <visit_node <T> > to_visit = new List <visit_node <T> >(); to_visit.Add(new visit_node <T>(cell, 0, 0)); while (to_visit.Count > 0) { visit_node <T> cell_data = to_visit.First(); to_visit.RemoveAt(0); visited.Add(cell_data.cell); if (visitor != null && (allowed_cells == null || allowed_cells.Contains(cell_data.cell))) { visitor.Visit(cell_data.cell, cell_data.distance); } if (max_depth < 0 || cell_data.depth < max_depth) { foreach (Cell.Neighbour neighbour in cell_data.cell.Neighbours) { T neighbour_cell = (T)neighbour.cell; float distance = cell_data.distance + cell_data.cell.Distance(neighbour_cell); visit_node <T> neighbour_cell_data = to_visit.FirstOrDefault(x => x.cell.Equals(neighbour_cell)); if (neighbour_cell_data != null) { neighbour_cell_data.distance = Math.Min(neighbour_cell_data.distance, distance); continue; } if ((neighbour.connection_flags & flags) != flags || visited.Contains(neighbour_cell)) { continue; } to_visit.Add(new visit_node <T>(neighbour_cell, distance, cell_data.depth + 1)); } } } }
public static List <CellsPatch> GenerateCellsPatches(List <Cell> cells, MovementFlag movement_flags) { List <CellsPatch> patches = new List <CellsPatch>(); //create cells patch for each interconnected group of cells HashSet <Cell> cells_copy = new HashSet <Cell>(cells); while (cells_copy.Count > 0) { HashSet <Cell> visited = new HashSet <Cell>(); Algorihms.Visit(cells_copy.First(), ref visited, movement_flags, true, 1, -1, cells_copy); patches.Add(new CellsPatch(visited, movement_flags)); cells_copy.RemoveWhere(x => visited.Contains(x)); } return(patches); }
public void Move(MovementFlag direction) { MovementController.Move(direction); // This must be before the Move takes place so that the same logic can occur on the client if (OnMove != null) { OnMove(this, new MoveEventArgs(direction)); } if (!MovementController.Velocity.IsZero()) { Colliding = false; } if (OnForcedPositionChange != null) { OnForcedPositionChange(this, null); } }
private void StraightenPath(ref List <path_pos> path, MovementFlag flags, int skip_first_count = 0) { int ray_start_index = skip_first_count; while (ray_start_index + 2 < path.Count) { path_pos ray_start_data = path[ray_start_index]; path_pos intermediate_data = path[ray_start_index + 1]; path_pos ray_end_data = path[ray_start_index + 2]; if (m_Navmesh.RayCast2D(ray_start_data.pos, ray_end_data.pos, flags, false)) { path.RemoveAt(ray_start_index + 1); } else { ++ray_start_index; } } }
public SceneSnoNavData(Enigma.D3.Assets.Scene sno_scene) { scene_sno_id = (int)sno_scene.x000_Header.x00_SnoId; Enigma.D3.Assets.Scene.NavCell[] nav_cells = sno_scene.x180_NavZoneDefinition.x08_NavCells; if (nav_cells == null) { return; } foreach (Enigma.D3.Assets.Scene.NavCell nav_cell in nav_cells) { MovementFlag flags = MovementFlag.None; if ((nav_cell.x18 & (short)NavCellFlags.AllowWalk) != 0) { flags |= MovementFlag.Walk; } if ((nav_cell.x18 & (short)NavCellFlags.AllowFlier) != 0) { flags |= MovementFlag.Fly; } // skip not walkable/flyable if (flags == MovementFlag.None) { continue; } float min_x = nav_cell.x00.X; float min_y = nav_cell.x00.Y; float min_z = nav_cell.x00.Z; float max_x = nav_cell.x0C.X; float max_y = nav_cell.x0C.Y; float max_z = nav_cell.x0C.Z; cells.Add(new Nav.Cell(min_x, min_y, min_z, max_x, max_y, max_z, flags)); } }
internal List <Cell> GetCellsWithin(Vec3 p, float radius, MovementFlag flags) { var result_cells = new List <Cell>(); if (p.IsZero()) { return(result_cells); } foreach (var cellsG in CellsGrid) { if (cellsG.Key.Distance2D(p) > radius) { continue; } result_cells.AddRange(Algorihms.GetCellsWithin(cellsG.Value, p, radius, flags, allow_disabled: true)); } return(result_cells); }
public void Move(string where) { if (_users.UserExists(Context.ConnectionId)) { try { User user = Users.Instance.GetUser(Context.ConnectionId); if (user.InMatch()) { MovementFlag direction = (MovementFlag)Enum.Parse(typeof(MovementFlag), where); user.CurrentMatch.Game.CommandHandler.MovementCommand(user, direction); } } catch (Exception ex) { ErrorLog.Instance.Log(ex); } } }
IEnumerator ChangeMoveMent() { // 몬스터마다 다른 패턴을 가지므로 enum()이 몬스터마다 다를 때를 대비해서 int num = System.Enum.GetValues(typeof(MovementFlag)).Length; Debug.Log("MovementFlag Length : " + num); while (true) { if (isTracing) { movementFlag = MovementFlag.Trace; } else { movementFlag = (MovementFlag)Random.Range(0, num); } yield return(new WaitForSeconds(3.0f)); } }
UnitMoveType SelectSpeedType(MovementFlag moveFlags) { /*! Not sure about MOVEMENTFLAG_CAN_FLY here - do creatures that can fly * but are on ground right now also have it? If yes, this needs a more * dynamic check, such as is flying now */ if (Convert.ToBoolean(moveFlags & (MovementFlag.Fly | MovementFlag.CanFly | MovementFlag.DisableGravity))) { if (Convert.ToBoolean(moveFlags & MovementFlag.Backward /*&& speed_obj.flight >= speed_obj.flight_back*/)) { return(UnitMoveType.FlightBack); } else { return(UnitMoveType.Flight); } } else if (Convert.ToBoolean(moveFlags & MovementFlag.Swim)) { if (Convert.ToBoolean(moveFlags & MovementFlag.Backward /*&& speed_obj.swim >= speed_obj.swim_back*/)) { return(UnitMoveType.SwimBack); } else { return(UnitMoveType.Swim); } } else if (Convert.ToBoolean(moveFlags & MovementFlag.Walk)) { //if (speed_obj.run > speed_obj.walk) return(UnitMoveType.Walk); } else if (Convert.ToBoolean(moveFlags & MovementFlag.Backward /*&& speed_obj.run >= speed_obj.run_back*/)) { return(UnitMoveType.RunBack); } return(UnitMoveType.Run); }
// Only grid cells connected vis cells with Walk movement flags will be treated as neighbours public void AddNeighbour(GridCell grid_cell) { if (AABB.Intersect(grid_cell.AABB, true) == null) { return; } if (Neighbours.Exists(x => x.cell.Equals(grid_cell))) { return; } bool any_cells_connected = false; MovementFlag connection_flags = MovementFlag.None; foreach (Cell our_cell in Cells) { foreach (Cell other_cell in grid_cell.Cells) { bool cells_connected = our_cell.AddNeighbour(other_cell); if (cells_connected) { any_cells_connected = true; MovementFlag flags = our_cell.Flags & other_cell.Flags; if (flags > connection_flags) { connection_flags = flags; } } } } if (any_cells_connected) { Neighbours.Add(new Neighbour(grid_cell, null, connection_flags)); grid_cell.Neighbours.Add(new Neighbour(this, null, connection_flags)); } }
public static Cell GetCellAt(IEnumerable <Cell> cells, Vec3 p, MovementFlag flags, bool allow_disabled = false, bool test_2d = true, float z_tolerance = 0) { if (p.IsZero()) { return(null); } foreach (Cell cell in cells) { if ((!allow_disabled && cell.Disabled) || (cell.Flags & flags) != flags) { continue; } if (test_2d ? cell.Contains2D(p) : cell.Contains(p, z_tolerance)) { return(cell); } } return(null); }
public double this[PlanetId id, MovementFlag flag] { get { if (id > PlanetId.SE_PLUTO && id != PlanetId.SE_EARTH) { return(0); } else if (Time1 == Time2) { return(0); } switch (flag) { case MovementFlag.GeoLongitudeMovement: return(LongitudeChanges[Ephemeris.GeocentricLuminaries.IndexOf(id)]); case MovementFlag.GeoLatitudeMovement: return(LatitudeChanges[Ephemeris.GeocentricLuminaries.IndexOf(id)]); case MovementFlag.GeoDistanceMovement: return(DistanceChanges[Ephemeris.GeocentricLuminaries.IndexOf(id)]); case MovementFlag.HelioLongitudeMovement: return(LongitudeChanges[HelioIndex + Ephemeris.HeliocentricLuminaries.IndexOf(id)]); case MovementFlag.HelioLatitudeMovement: return(LatitudeChanges[HelioIndex + Ephemeris.HeliocentricLuminaries.IndexOf(id)]); case MovementFlag.HelioDistanceMovement: return(DistanceChanges[HelioIndex + Ephemeris.HeliocentricLuminaries.IndexOf(id)]); default: return(0); } } }
UnitMoveType SelectSpeedType(MovementFlag moveFlags) { if (moveFlags.HasAnyFlag(MovementFlag.Flying)) { if (moveFlags.HasAnyFlag(MovementFlag.Backward)) { return(UnitMoveType.FlightBack); } else { return(UnitMoveType.Flight); } } else if (moveFlags.HasAnyFlag(MovementFlag.Swimming)) { if (moveFlags.HasAnyFlag(MovementFlag.Backward)) { return(UnitMoveType.SwimBack); } else { return(UnitMoveType.Swim); } } else if (moveFlags.HasAnyFlag(MovementFlag.Walking)) { return(UnitMoveType.Walk); } else if (moveFlags.HasAnyFlag(MovementFlag.Backward)) { return(UnitMoveType.RunBack); } // Flying creatures use MOVEMENTFLAG_CAN_FLY or MOVEMENTFLAG_DISABLE_GRAVITY // Run speed is their default flight speed. return(UnitMoveType.Run); }
UnitMoveType SelectSpeedType(MovementFlag moveFlags) { if (Convert.ToBoolean(moveFlags & (MovementFlag.Flying | MovementFlag.CanFly | MovementFlag.DisableGravity))) { if (Convert.ToBoolean(moveFlags & MovementFlag.Backward)) { return(UnitMoveType.FlightBack); } else { return(UnitMoveType.Flight); } } else if (Convert.ToBoolean(moveFlags & MovementFlag.Swimming)) { if (Convert.ToBoolean(moveFlags & MovementFlag.Backward)) { return(UnitMoveType.SwimBack); } else { return(UnitMoveType.Swim); } } else if (Convert.ToBoolean(moveFlags & MovementFlag.Walking)) { return(UnitMoveType.Walk); } else if (Convert.ToBoolean(moveFlags & MovementFlag.Backward)) { return(UnitMoveType.RunBack); } // Flying creatures use MOVEMENTFLAG_CAN_FLY or MOVEMENTFLAG_DISABLE_GRAVITY // Run speed is their default flight speed. return(UnitMoveType.Run); }
public bool AreConnected(Vec3 pos1, Vec3 pos2, MovementFlag flags, float nearest_tolerance) { using (new ReadLock(DataLock)) { Cell pos1_cell = null; Cell pos2_cell = null; // do not ignore disabled as cells patches to not include replacement cells! GetCellContaining(pos1, out pos1_cell, flags, true, true, nearest_tolerance, false, 2); if (pos1_cell == null) { return(false); } // do not ignore disabled as cells patches to not include replacement cells! GetCellContaining(pos2, out pos2_cell, flags, true, true, nearest_tolerance, false, 2); if (pos2_cell == null) { return(false); } IEnumerable <CellsPatch> pos1_patches = m_CellsPatches.Where(x => x.Cells.Contains(pos1_cell)); foreach (var p in pos1_patches) { if (p.Cells.Contains(pos2_cell)) { return(true); } } return(false); } }
private void StraightenPath(ref List<path_pos> path, MovementFlag flags, int skip_first_count = 0) { int ray_start_index = skip_first_count; while (ray_start_index + 2 < path.Count) { path_pos ray_start_data = path[ray_start_index]; path_pos intermediate_data = path[ray_start_index + 1]; path_pos ray_end_data = path[ray_start_index + 2]; if (m_Navmesh.RayCast2D(ray_start_data.pos, ray_end_data.pos, flags, false)) path.RemoveAt(ray_start_index + 1); else ++ray_start_index; } }
public bool IsPositionReachable(Vec3 from, Vec3 to, MovementFlag flags, float tolerance) { List<Vec3> tmp_path = new List<Vec3>(); FindPath(from, to, flags, ref tmp_path, -1, true, true, 0, false, 0, false); return tmp_path.Count > 0 ? tmp_path.Last().Distance(to) <= tolerance : false; }
public void MovementCommand(User by, MovementFlag direction) { _cycles[by.ID].RegisterMove(direction); }
public void Move(MovementFlag direction) { positionOnLine(); if (direction == MovementFlag.Left) { Rotation = (Rotation + TMath.HALF_PI) % TMath.TWO_PI; if(Math.Round(Rotation) == 6) // Above two pi { Rotation = 0; } } else if (direction == MovementFlag.Right) { Rotation -= TMath.HALF_PI; if (Rotation < 0) { if (Math.Round(Rotation) == 0) { Rotation = 0; } else { Rotation += TMath.TWO_PI; } } } Velocity = _velocities[Math.Round(Rotation)]; }
public bool CanMove(MovementFlag direction) { return GetValidMovements().Contains(direction); }
public PendingMovement(MapLocation currentMapLocation, Vector3 startLocation, MovementFlag direction) { CurrentMapLocation = currentMapLocation; StartLocation = startLocation; Direction = direction; }
public MoveEventArgs(MovementFlag direction) { Direction = direction; }
public bool FindPath(Vec3 from, Vec3 to, MovementFlag flags, ref List<Vec3> path, float merge_distance = -1, bool as_close_as_possible = false, bool include_from = false, float random_coeff = 0, bool bounce = false, float shift_nodes_distance = 0, bool straighten = true) { using (m_Navmesh.AquireReadDataLock()) { List<path_pos> tmp_path = new List<path_pos>(); if (from.IsEmpty || to.IsEmpty) return false; Cell start = null; Cell end = null; bool start_on_nav_mesh = m_Navmesh.GetCellContaining(from, out start, null, as_close_as_possible, flags, false, 2); bool end_on_nav_mesh = m_Navmesh.GetCellContaining(to, out end, null, as_close_as_possible, flags, false, 2); if (bounce) { Vec3 bounce_dir = start.AABB.GetBounceDir2D(from); Vec3 new_from = from + bounce_dir * 10; m_Navmesh.GetCellContaining(new_from, out start, null, as_close_as_possible, flags, false, 2); if (!Algorihms.FindPath<Cell>(start, ref end, new_from, to, flags, ref tmp_path, random_coeff, true)) return false; tmp_path.Insert(0, new path_pos(start.AABB.Align(from), start)); } else { if (!Algorihms.FindPath<Cell>(start, ref end, from, to, flags, ref tmp_path, random_coeff, true)) return false; } if (straighten && random_coeff == 0) StraightenPath(ref tmp_path, flags, bounce ? 1 : 0); path = tmp_path.Select(x => x.pos).ToList(); PostProcessPath(ref path, merge_distance, shift_nodes_distance); if (!include_from && start_on_nav_mesh) path.RemoveAt(0); return true; } }