(badly) ported dsp's pathfind code

- added distance for vectors
- todo: why does it go retard
This commit is contained in:
Tahir Akhlaq
2017-08-16 17:25:32 +01:00
parent 68657e1edc
commit 1856cc0634
9 changed files with 98 additions and 29 deletions

View File

@@ -10,6 +10,8 @@ using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.actors.area;
using FFXIVClassic_Map_Server.packets.send.actor;
// port of https://github.com/DarkstarProject/darkstar/blob/master/src/map/ai/helpers/pathfind.h
namespace FFXIVClassic_Map_Server.actors.chara.ai
{
// todo: path flags, check for obstacles etc
@@ -24,6 +26,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
private Character owner;
private List<Vector3> path;
private bool canFollowPath;
float distanceFromPoint;
private PathFindFlags pathFlags;
@@ -87,6 +90,8 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
public void PathInRange(float x, float y, float z, float minRange, float maxRange = 5.0f)
{
var dest = owner.FindRandomPoint(x, y, z, minRange, maxRange);
// todo: this is dumb..
distanceFromPoint = owner.meleeRange;
PreparePath(dest.X, dest.Y, dest.Z);
}
@@ -98,7 +103,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
public bool IsFollowingPath()
{
return path.Count > 0;
return path?.Count > 0;
}
public bool IsFollowingScriptedPath()
@@ -112,12 +117,53 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
{
var point = path[0];
owner.OnPath(point);
owner.QueuePositionUpdate(point);
path.Remove(point);
StepTo(point);
if (path.Count == 0)
owner.LookAt(point.X, point.Y);
if (AtPoint(point))
{
path.Remove(point);
owner.OnPath(point);
}
}
}
public bool AtPoint(Vector3 point)
{
if (distanceFromPoint == 0)
return owner.positionX == point.X && owner.positionZ == point.Z;
else
return Utils.Distance(owner.positionX, owner.positionY, owner.positionZ, point.X, point.Y, point.Z) <= (distanceFromPoint + 1.5f);
}
public void StepTo(Vector3 point, bool run = false)
{
float speed = GetSpeed();
float stepDistance = (speed / 10) / 2;
float distanceTo = Utils.Distance(owner.positionX, owner.positionY, owner.positionZ, point.X, point.Y, point.Z);
owner.LookAt(point.X, point.Y);
if (distanceTo <= distanceFromPoint + stepDistance + 1.5f)
{
if (distanceFromPoint == 0)
{
owner.QueuePositionUpdate(point);
}
else
{
float x = owner.positionX - (float)Math.Cos(owner.rotation + (float)(Math.PI / 2)) * (distanceTo - distanceFromPoint);
float z = owner.positionZ + (float)Math.Sin(owner.rotation + (float)(Math.PI / 2)) * (distanceTo - distanceFromPoint);
owner.QueuePositionUpdate(x, owner.positionY, z);
}
}
else
{
float x = owner.positionX - (float)Math.Cos(owner.rotation + (float)(Math.PI / 2)) * (distanceTo - distanceFromPoint);
float z = owner.positionZ + (float)Math.Sin(owner.rotation + (float)(Math.PI / 2)) * (distanceTo - distanceFromPoint);
owner.QueuePositionUpdate(x, owner.positionY, z);
}
}
@@ -126,6 +172,8 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
// todo:
path?.Clear();
pathFlags = PathFindFlags.None;
distanceFromPoint = 0.0f;
}
private float GetSpeed()
@@ -137,7 +185,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
{
if (owner.currentSubState == SetActorStatePacket.SUB_STATE_MONSTER)
{
owner.ChangeSpeed(0.0f, SetActorSpeedPacket.DEFAULT_WALK - 2.0f, SetActorSpeedPacket.DEFAULT_RUN - 2.0f, SetActorSpeedPacket.DEFAULT_ACTIVE - 2.0f);
//owner.ChangeSpeed(0.0f, SetActorSpeedPacket.DEFAULT_WALK - 2.0f, SetActorSpeedPacket.DEFAULT_RUN - 2.0f, SetActorSpeedPacket.DEFAULT_ACTIVE - 2.0f);
}
// baseSpeed += ConfigConstants.SPEED_MOD;
}

View File

@@ -82,7 +82,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
if (Utils.Distance(owner.positionX, owner.positionY, owner.positionZ, target.positionX, target.positionY, target.positionZ) > 10)
{
owner.aiContainer.pathFind.SetPathFlags(PathFindFlags.None);
owner.aiContainer.pathFind.PreparePath(target.positionX, target.positionY, target.positionZ);
owner.aiContainer.pathFind.PathInRange(target.positionX, target.positionY, target.positionZ, 1.5f, owner.meleeRange);
ChangeTarget(target);
return false;
}
@@ -193,18 +193,19 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
return;
}
var targetPos = owner.target.GetPosAsVector3();
var targetPos = new Vector3(owner.target.positionX, owner.target.positionY, owner.target.positionZ);
var distance = Utils.Distance(owner.positionX, owner.positionY, owner.positionZ, targetPos.X, targetPos.Y, targetPos.Z);
if (distance > owner.meleeRange - 0.2f || owner.aiContainer.CanFollowPath())
{
if (CanMoveForward(distance))
{
owner.LookAt(targetPos.X, targetPos.Y);
if (!owner.aiContainer.pathFind.IsFollowingPath() && distance > 3)
{
// pathfind if too far otherwise jump to target
owner.aiContainer.pathFind.SetPathFlags(distance > 3 ? PathFindFlags.None : PathFindFlags.IgnoreNav );
owner.aiContainer.pathFind.PreparePath(targetPos, 0.7f, 5);
owner.aiContainer.pathFind.SetPathFlags(distance > 5 ? PathFindFlags.None : PathFindFlags.IgnoreNav );
owner.aiContainer.pathFind.PreparePath(targetPos, 0.5f, 5);
}
owner.aiContainer.pathFind.FollowPath();
if (!owner.aiContainer.pathFind.IsFollowingPath())
@@ -213,7 +214,11 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
{
foreach (var battlenpc in owner.zone.GetActorsAroundActor<BattleNpc>(owner, 1))
{
battlenpc.aiContainer.pathFind.PathInRange(targetPos, 1.5f, 1.5f);
if (battlenpc == owner)
continue;
float mobDistance = Utils.Distance(owner.positionX, owner.positionY, owner.positionZ, battlenpc.positionX, battlenpc.positionY, battlenpc.positionZ);
if (mobDistance < 0.3f && (battlenpc.updateFlags & ActorUpdateFlags.Position) == 0)
battlenpc.aiContainer.pathFind.PathInRange(targetPos, 1.5f, 1.5f);
}
}
}
@@ -277,7 +282,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
if (verticalDistance > 8)
return false;
var distance = Utils.Distance(owner.positionX, owner.positionY, owner.positionZ, target.positionX, target.positionY, target.positionZ);
var distance = Utils.Distance(owner.positionX, owner.positionY, owner.positionZ, target.oldPositionX, target.oldPositionY, target.oldPositionZ);
bool detectSight = forceSight || (owner.aggroType & AggroType.Sight) != 0;
bool hasSneak = false;

View File

@@ -43,7 +43,9 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
// todo: actual stat based range
if (Utils.Distance(owner.positionX, owner.positionY, owner.positionZ, target.positionX, target.positionY, target.positionZ) > 10)
{
owner.aiContainer.pathFind.PreparePath(target.positionX, target.positionY, target.positionZ);
{
// todo: out of range error
}
ChangeTarget(target);
return false;
}

View File

@@ -87,12 +87,13 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
lua.LuaEngine.CallLuaBattleAction(owner, "onAttack", false, owner, target, damage);
foreach (var player in owner.zone.GetActorsAroundActor<Player>(owner, 50))
player.QueuePacket(BattleActionX01Packet.BuildPacket(player.actorId, owner.actorId, target.actorId, 223001, 18, 0, (ushort)BattleActionX01PacketCommand.Attack, (ushort)damage, 0));
if (target is Player)
((Player)target).SendPacket("139.bin");
player.QueuePacket(BattleActionX01Packet.BuildPacket(player.actorId, owner.actorId, target.actorId, 0, 537094006, 0, 27260, (ushort)damage, 0));
//if (target is Player)
// ((Player)target).SendPacket("139.bin");
target.AddHP((short)damage);
attackTime = attackTime.AddMilliseconds(owner.GetAttackDelayMs());
owner.LookAt(target);
//this.errorPacket = BattleActionX01Packet.BuildPacket(target.actorId, owner.actorId, target.actorId, 0, effectId, 0, (ushort)BattleActionX01PacketCommand.Attack, (ushort)damage, 0);
}