Skip to content
This repository has been archived by the owner on Sep 3, 2022. It is now read-only.

Commit

Permalink
Progress #1366 -- Various TeleportID-related fixes (#1367)
Browse files Browse the repository at this point in the history
I wrote "progress" because I still have to use teleportation for collisions. Otherwise, collision avoidance comes into play and the minions go in different directions. They are already trying to do this, but in the *indev* branch they are teleported away every tick of the server. This also looks ugly, but I decided to keep this behavior.
At least now, instead of recalculating the entire path, a collision only changes the zero point of the path. And this is usually enough, because the collision only throws the unit back a little.
  • Loading branch information
Killfrra committed Mar 25, 2022
1 parent 412736d commit 22dc5e4
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 103 deletions.
5 changes: 2 additions & 3 deletions GameServerCore/Packets/Interfaces/IPacketNotifier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -195,11 +195,10 @@ public interface IPacketNotifier
/// <param name="o">GameObject entering vision.</param>
/// <param name="userId">User to send the packet to.</param>
/// <param name="isChampion">Whether or not the GameObject entering vision is a Champion.</param>
/// <param name="useTeleportID">Whether or not to teleport the object to its current position.</param>
/// <param name="ignoreVision">Optionally ignore vision checks when sending this packet.</param>
/// <param name="packets">Takes in a list of packets to send alongside this vision packet.</param>
/// TODO: Incomplete implementation.
void NotifyEnterVisibilityClient(IGameObject o, int userId = 0, bool isChampion = false, bool useTeleportID = false, bool ignoreVision = false, List<GamePacket> packets = null);
void NotifyEnterVisibilityClient(IGameObject o, int userId = 0, bool isChampion = false, bool ignoreVision = false, List<GamePacket> packets = null);
/// <summary>
/// Sends a packet to all players with vision of the specified unit detailing that the unit has begun facing the specified direction.
/// </summary>
Expand Down Expand Up @@ -938,7 +937,7 @@ public interface IPacketNotifier
/// <param name="u">AttackableUnit that is moving.</param>
/// <param name="userId">UserId to send the packet to. If not specified or zero, the packet is broadcasted to all players that have vision of the specified unit.</param>
/// <param name="useTeleportID">Whether or not to teleport the unit to its current position in its path.</param>
void NotifyWaypointGroup(IAttackableUnit u, int userId = 0, bool useTeleportID = true);
void NotifyWaypointGroup(IAttackableUnit u, int userId = 0, bool useTeleportID = false);
/// <summary>
/// Sends a packet to all players that have vision of the specified unit.
/// The packet details a group of waypoints with speed parameters which determine what kind of movement will be done to reach the waypoints, or optionally a GameObject.
Expand Down
2 changes: 1 addition & 1 deletion GameServerLib/Chatbox/Commands/SpawnCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ public void SpawnChampForTeam(TeamId team, int userId, string model)
c.Stats.SetSummonerSpellEnabled(0, true);
c.Stats.SetSummonerSpellEnabled(1, true);

Game.PacketNotifier.NotifyEnterVisibilityClient(c, 0, true, false, true);
Game.PacketNotifier.NotifyEnterVisibilityClient(c, 0, true, true);

ChatCommandManager.SendDebugMsgFormatted(DebugMsgType.INFO, "Spawned Bot" + clientInfoTemp.Name + " as " + c.Model + " with NetID: " + c.NetId + ".");
}
Expand Down
61 changes: 43 additions & 18 deletions GameServerLib/GameObjects/AttackableUnits/AttackableUnit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,21 +176,29 @@ public uint GetObjHash()
public void SetPosition(Vector2 vec, bool repath = true)
{
Position = vec;
_movementUpdated = true;

// Reevaluate our current path to account for the starting position being changed.
if (repath && !IsPathEnded())
if(!IsPathEnded())
{
List<Vector2> safePath = _game.Map.PathingHandler.GetPath(Position, _game.Map.NavigationGrid.GetClosestTerrainExit(Waypoints.Last(), PathfindingRadius));
// Reevaluate our current path to account for the starting position being changed.
if(repath)
{
List<Vector2> safePath = _game.Map.PathingHandler.GetPath(Position, _game.Map.NavigationGrid.GetClosestTerrainExit(Waypoints.Last(), PathfindingRadius));

// TODO: When using this safePath, sometimes we collide with the terrain again, so we use an unsafe path the next collision, however,
// sometimes we collide again before we can finish the unsafe path, so we end up looping collisions between safe and unsafe paths, never actually escaping (ex: sharp corners).
// This is a more fundamental issue where the pathfinding should be taking into account collision radius, rather than simply pathing from center of an object.
if (safePath != null)
// TODO: When using this safePath, sometimes we collide with the terrain again, so we use an unsafe path the next collision, however,
// sometimes we collide again before we can finish the unsafe path, so we end up looping collisions between safe and unsafe paths, never actually escaping (ex: sharp corners).
// This is a more fundamental issue where the pathfinding should be taking into account collision radius, rather than simply pathing from center of an object.
if (safePath != null)
{
SetWaypoints(safePath);
}
}
else
{
SetWaypoints(safePath);
Waypoints[0] = Position;
}
}
else if (!repath && !IsPathEnded())
else
{
ResetWaypoints();
}
Expand Down Expand Up @@ -264,7 +272,7 @@ public override void OnCollision(IGameObject collider, bool isTerrain = false)

// only time we would collide with terrain is if we are inside of it, so we should teleport out of it.
Vector2 exit = _game.Map.NavigationGrid.GetClosestTerrainExit(Position, PathfindingRadius + 1.0f);
TeleportTo(exit.X, exit.Y, true);
SetPosition(exit, false);
}
else
{
Expand All @@ -280,7 +288,11 @@ public override void OnCollision(IGameObject collider, bool isTerrain = false)
// We should not teleport here because Pathfinding should handle it.
// TODO: Implement a PathfindingHandler, and remove currently implemented manual pathfinding.
Vector2 exit = Extensions.GetCircleEscapePoint(Position, PathfindingRadius + 1, collider.Position, collider.PathfindingRadius);
TeleportTo(exit.X, exit.Y, true);
if (!_game.Map.PathingHandler.IsWalkable(exit, PathfindingRadius))
{
exit = _game.Map.NavigationGrid.GetClosestTerrainExit(exit, PathfindingRadius + 1.0f);
}
SetPosition(exit, false);
}
}

Expand Down Expand Up @@ -962,16 +974,29 @@ public void UpdateStatus()
/// <param name="repath">Whether or not to repath from the new position.</param>
public void TeleportTo(float x, float y, bool repath = false)
{
var position = new Vector2(x, y);
TeleportTo(new Vector2(x, y), repath);
}

if (!_game.Map.PathingHandler.IsWalkable(new Vector2(x, y), PathfindingRadius))
/// <summary>
/// Teleports this unit to the given position, and optionally repaths from the new position.
/// </summary>
public void TeleportTo(Vector2 position, bool repath = false)
{
position = _game.Map.NavigationGrid.GetClosestTerrainExit(position, PathfindingRadius + 1.0f);

if(repath)
{
SetPosition(position, true);
}
else
{
position = _game.Map.NavigationGrid.GetClosestTerrainExit(new Vector2(x, y), PathfindingRadius + 1.0f);
Position = position;
ResetWaypoints();
}

SetPosition(position, repath);
TeleportID++;
_game.PacketNotifier.NotifyTeleport(this, position);
_game.PacketNotifier.NotifyWaypointGroup(this, useTeleportID: true);
_movementUpdated = false;
}

/// <summary>
Expand Down Expand Up @@ -1680,11 +1705,11 @@ public void DashToLocation(Vector2 endPos, float dashSpeed, string animation = "
SetAnimStates(animPairs);
}

_game.PacketNotifier.NotifyWaypointGroupWithSpeed(this);

// Movement is networked this way instead.
// TODO: Verify if we want to use NotifyWaypointListWithSpeed instead as it does not require conversions.
//_game.PacketNotifier.NotifyWaypointListWithSpeed(this, dashSpeed, leapGravity, keepFacingLastDirection, null, 0, 0, 20000.0f);
_game.PacketNotifier.NotifyWaypointGroupWithSpeed(this);
_movementUpdated = false;
}

/// <summary>
Expand Down
10 changes: 5 additions & 5 deletions GameServerLib/GameObjects/GameObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ public virtual void OnCollision(IGameObject collider, bool isTerrain = false)
// Escape functionality should be moved to GameObject.OnCollision.
// only time we would collide with terrain is if we are inside of it, so we should teleport out of it.
Vector2 exit = _game.Map.NavigationGrid.GetClosestTerrainExit(Position, PathfindingRadius + 1.0f);
TeleportTo(exit.X, exit.Y);
SetPosition(exit);
}
}

Expand Down Expand Up @@ -320,12 +320,12 @@ public void SetSpawnedForPlayer(int userId)
public virtual void TeleportTo(float x, float y)
{
var position = _game.Map.NavigationGrid.GetClosestTerrainExit(new Vector2(x, y), PathfindingRadius + 1.0f);

SetPosition(position);

// TODO: Verify which one we want to use. WaypointList does not require conversions, however WaypointGroup does (and it has TeleportID functionality).
//_game.PacketNotifier.NotifyWaypointList(this, new List<Vector2> { Position });
_game.PacketNotifier.NotifyEnterVisibilityClient(this, useTeleportID: true);
// TODO: Find a suitable function for this. Maybe modify NotifyWaypointGroup to accept simple objects.
_game.PacketNotifier.NotifyEnterVisibilityClient(this);
_movementUpdated = false;
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion GameServerLib/ObjectManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ void Sync(IGameObject obj, int userId = 0)
// TODO: Verify which one we want to use. WaypointList does not require conversions, however WaypointGroup does (and it has TeleportID functionality).
//_game.PacketNotifier.NotifyWaypointList(u);
// TODO: Verify if we want to use TeleportID.
_game.PacketNotifier.NotifyWaypointGroup(u, userId, true);
_game.PacketNotifier.NotifyWaypointGroup(u, userId, false);
}
}
}
Expand Down
83 changes: 21 additions & 62 deletions PacketDefinitions420/PacketExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,88 +132,47 @@ public static MovementData CreateMovementData(IGameObject o, INavigationGrid gri
return md;
}

var currentWaypoints = new List<Vector2>(unit.Waypoints);
currentWaypoints[0] = unit.Position;

int count = 2 + ((currentWaypoints.Count - 1) - unit.CurrentWaypoint.Key);
if (count >= 2)
{
currentWaypoints.RemoveRange(1, currentWaypoints.Count - count);
}

var waypoints = currentWaypoints.ConvertAll(v => Vector2ToWaypoint(TranslateToCenteredCoordinates(v, grid)));

switch (type)
{
case MovementDataType.WithSpeed:
{
if (speeds == null)
{
break;
}

var waypoints = unit.Waypoints.ConvertAll(v => Vector2ToWaypoint(TranslateToCenteredCoordinates(v, grid)));

if (useTeleportID)
if (speeds != null)
{
var currentWaypoints = new List<Vector2>();
currentWaypoints.AddRange(unit.Waypoints);
currentWaypoints.RemoveAt(0);
currentWaypoints.Insert(0, unit.Position);

var count = 2 + ((currentWaypoints.Count - 1) - unit.CurrentWaypoint.Key);
if (count >= 2)
md = new MovementDataWithSpeed
{
currentWaypoints.RemoveRange(1, currentWaypoints.Count - count);
}

waypoints = currentWaypoints.ConvertAll(v => Vector2ToWaypoint(TranslateToCenteredCoordinates(v, grid)));
}

md = new MovementDataWithSpeed
{
SyncID = unit.SyncId,
TeleportNetID = unit.NetId,
// TODO: Implement teleportID (likely to be the index (starting at 1) of a waypoint we want to TP to).
// Crucial in syncing client positions with server positions, especially when entering vision
HasTeleportID = useTeleportID,
TeleportID = unit.TeleportID,
Waypoints = waypoints,
SpeedParams = speeds
};

if (useTeleportID)
{
unit.TeleportID++;
SyncID = unit.SyncId,
TeleportNetID = unit.NetId,
HasTeleportID = useTeleportID,
TeleportID = useTeleportID ? unit.TeleportID : (byte)0,
Waypoints = waypoints,
SpeedParams = speeds
};
}

break;
}
case MovementDataType.Normal:
{
var waypoints = unit.Waypoints.ConvertAll(v => Vector2ToWaypoint(TranslateToCenteredCoordinates(v, grid)));

if (useTeleportID)
{
var currentWaypoints = new List<Vector2>();
currentWaypoints.AddRange(unit.Waypoints);
currentWaypoints.RemoveAt(0);
currentWaypoints.Insert(0, unit.Position);

var count = 2 + ((currentWaypoints.Count - 1) - unit.CurrentWaypoint.Key);
if (count >= 2)
{
currentWaypoints.RemoveRange(1, currentWaypoints.Count - count);
}

waypoints = currentWaypoints.ConvertAll(v => Vector2ToWaypoint(TranslateToCenteredCoordinates(v, grid)));
}

md = new MovementDataNormal
{
SyncID = unit.SyncId,
TeleportNetID = unit.NetId,
// TODO: Implement teleportID (likely to be the index (starting at 1) of a waypoint we want to TP to).
// Crucial in syncing client positions with server positions, especially when entering vision
HasTeleportID = useTeleportID,
TeleportID = unit.TeleportID,
TeleportID = useTeleportID ? unit.TeleportID : (byte)0,
Waypoints = waypoints
};

if (useTeleportID)
{
unit.TeleportID++;
}

break;
}
}
Expand Down
20 changes: 7 additions & 13 deletions PacketDefinitions420/PacketNotifier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,7 @@ public void NotifyEnterLocalVisibilityClient(IGameObject o, int userId = 0, bool
}
}

OnEnterVisibilityClient ConstructEnterVisibilityClientPacket(IGameObject o, bool isChampion = false, bool useTeleportID = false, List<GamePacket> packets = null)
OnEnterVisibilityClient ConstructEnterVisibilityClientPacket(IGameObject o, bool isChampion = false, List<GamePacket> packets = null)
{
var itemData = new List<ItemData>(); //TODO: Fix item system so this can be finished
var shields = new ShieldValues(); //TODO: Implement shields so this can be finished
Expand Down Expand Up @@ -793,7 +793,7 @@ OnEnterVisibilityClient ConstructEnterVisibilityClientPacket(IGameObject o, bool
}
}

var md = PacketExtensions.CreateMovementData(o, _navGrid, type, speeds, useTeleportID: useTeleportID);
var md = PacketExtensions.CreateMovementData(o, _navGrid, type, speeds, useTeleportID: true);

var enterVis = new OnEnterVisibilityClient // TYPO >:(
{
Expand Down Expand Up @@ -822,14 +822,13 @@ OnEnterVisibilityClient ConstructEnterVisibilityClientPacket(IGameObject o, bool
/// <param name="o">GameObject entering vision.</param>
/// <param name="userId">User to send the packet to.</param>
/// <param name="isChampion">Whether or not the GameObject entering vision is a Champion.</param>
/// <param name="useTeleportID">Whether or not to teleport the object to its current position.</param>
/// <param name="ignoreVision">Optionally ignore vision checks when sending this packet.</param>
/// <param name="packets">Takes in a list of packets to send alongside this vision packet.</param>
/// TODO: Incomplete implementation.
public void NotifyEnterVisibilityClient(IGameObject o, int userId = 0, bool isChampion = false, bool useTeleportID = false, bool ignoreVision = false, List<GamePacket> packets = null)
public void NotifyEnterVisibilityClient(IGameObject o, int userId = 0, bool isChampion = false, bool ignoreVision = false, List<GamePacket> packets = null)
{

var enterVis = ConstructEnterVisibilityClientPacket(o, isChampion, useTeleportID, packets);
var enterVis = ConstructEnterVisibilityClientPacket(o, isChampion, packets);

if (userId != 0)
{
Expand Down Expand Up @@ -3312,7 +3311,7 @@ GamePacket ConstructSpawnPacket(IGameObject o, float gameTime = 0)
return ConstructFXCreateGroupPacket(particle);
}
// Generic object
return ConstructEnterVisibilityClientPacket(o, useTeleportID: true);
return ConstructEnterVisibilityClientPacket(o);
}

/// <summary>
Expand Down Expand Up @@ -3802,12 +3801,7 @@ void NotifyEnterTeamVision(IGameObject obj, TeamId team, int userId = 0, GamePac
{
packets = new List<GamePacket>(1){ spawnPacket };
}
visibilityPacket = ConstructEnterVisibilityClientPacket(
obj,
isChampion: obj is IChampion,
useTeleportID: true,
packets: packets
);
visibilityPacket = ConstructEnterVisibilityClientPacket(obj, obj is IChampion, packets);
}
var healthbarPacket = ConstructEnterLocalVisibilityClientPacket(obj);
//TODO: try to include it to packets too?
Expand Down Expand Up @@ -3873,7 +3867,7 @@ void NotifyLeaveTeamVision(IGameObject obj, TeamId team, int userId = 0)
/// <param name="u">AttackableUnit that is moving.</param>
/// <param name="userId">UserId to send the packet to. If not specified or zero, the packet is broadcasted to all players that have vision of the specified unit.</param>
/// <param name="useTeleportID">Whether or not to teleport the unit to its current position in its path.</param>
public void NotifyWaypointGroup(IAttackableUnit u, int userId = 0, bool useTeleportID = true)
public void NotifyWaypointGroup(IAttackableUnit u, int userId = 0, bool useTeleportID = false)
{
// TODO: Verify if casts correctly
var move = (MovementDataNormal)PacketExtensions.CreateMovementData(u, _navGrid, MovementDataType.Normal, useTeleportID: useTeleportID);
Expand Down

0 comments on commit 22dc5e4

Please sign in to comment.