Skip to content

Commit

Permalink
Fix fleeing npcs from running past their reset radius and instantly r…
Browse files Browse the repository at this point in the history
…estoring health. (#789)
  • Loading branch information
jcsnider authored and lodicolo committed Jul 15, 2021
1 parent 40eb62c commit 06d8869
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 16 deletions.
18 changes: 11 additions & 7 deletions Intersect.Server/Entities/Entity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2320,19 +2320,23 @@ public int GetDistanceTo(Entity target)

public int GetDistanceTo(MapInstance targetMap, int targetX, int targetY)
{
var myMap = MapInstance.Get(MapId);
if (myMap != null && targetMap != null && myMap.MapGrid == targetMap.MapGrid
return GetDistanceBetween(Map, targetMap, X, targetX, Y, targetY);
}

public int GetDistanceBetween(MapInstance mapA, MapInstance mapB, int xTileA, int xTileB, int yTileA, int yTileB)
{
if (mapA != null && mapB != null && mapA.MapGrid == mapB.MapGrid
) //Make sure both maps exist and that they are in the same dimension
{
//Calculate World Tile of Me
var x1 = X + myMap.MapGridX * Options.MapWidth;
var y1 = Y + myMap.MapGridY * Options.MapHeight;
var x1 = xTileA + mapA.MapGridX * Options.MapWidth;
var y1 = yTileA + mapA.MapGridY * Options.MapHeight;

//Calculate world tile of target
var x2 = targetX + targetMap.MapGridX * Options.MapWidth;
var y2 = targetY + targetMap.MapGridY * Options.MapHeight;
var x2 = xTileB + mapB.MapGridX * Options.MapWidth;
var y2 = yTileB + mapB.MapGridY * Options.MapHeight;

return (int) Math.Sqrt(Math.Pow(x1 - x2, 2) + Math.Pow(y1 - y2, 2));
return (int)Math.Sqrt(Math.Pow(x1 - x2, 2) + Math.Pow(y1 - y2, 2));
}

//Something is null.. return a value that is out of range :)
Expand Down
84 changes: 75 additions & 9 deletions Intersect.Server/Entities/Npc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,67 @@ private static bool PredicateUnableToCastSpells(Status status)
}
}

public override int CanMove(int moveDir)
{
var canMove = base.CanMove(moveDir);
if ((canMove == -1 || canMove == -4) && IsFleeing() && Options.Instance.NpcOpts.AllowResetRadius)
{
var yOffset = 0;
var xOffset = 0;
var tile = new TileHelper(MapId, X, Y);
switch (moveDir)
{
case 0: //Up
yOffset--;

break;
case 1: //Down
yOffset++;

break;
case 2: //Left
xOffset--;

break;
case 3: //Right
xOffset++;

break;
case 4: //NW
yOffset--;
xOffset--;

break;
case 5: //NE
yOffset--;
xOffset++;

break;
case 6: //SW
yOffset++;
xOffset--;

break;
case 7: //SE
yOffset++;
xOffset++;

break;
}

if (tile.Translate(xOffset, yOffset))
{
//If this would move us past our reset radius then we cannot move.
var dist = GetDistanceBetween(AggroCenterMap, tile.GetMap(), AggroCenterX, tile.GetX(), AggroCenterY, tile.GetY());
if (dist > Math.Max(Options.Npc.ResetRadius, Base.ResetRadius))
{
return -2;
}
}
}
return canMove;
}

private void TryCastSpells()
{
var target = Target;
Expand Down Expand Up @@ -687,6 +748,19 @@ private void TryCastSpells()
PacketSender.SendEntityCastTime(this, spellId);
}

public bool IsFleeing()
{
if (Base.FleeHealthPercentage > 0)
{
var fleeHpCutoff = GetMaxVital(Vitals.Health) * ((float)Base.FleeHealthPercentage / 100f);
if (GetVital(Vitals.Health) < fleeHpCutoff)
{
return true;
}
}
return false;
}

// TODO: Improve NPC movement to be more fluid like a player
//General Updating
public override void Update(long timeMs)
Expand All @@ -709,15 +783,7 @@ public override void Update(long timeMs)
}
}

var fleeing = false;
if (Base.FleeHealthPercentage > 0)
{
var fleeHpCutoff = GetMaxVital(Vitals.Health) * ((float)Base.FleeHealthPercentage / 100f);
if (GetVital(Vitals.Health) < fleeHpCutoff)
{
fleeing = true;
}
}
var fleeing = IsFleeing();

if (MoveTimer < Globals.Timing.Milliseconds)
{
Expand Down

0 comments on commit 06d8869

Please sign in to comment.