corrected mob to use correct substate

- added global tick
- stubbed some more functions
- added checks for engaged/dead
- todo: everything else
This commit is contained in:
Tahir Akhlaq 2017-06-14 20:01:15 +01:00
parent b9bfe5e985
commit 2c9ae60bbf
9 changed files with 131 additions and 36 deletions

View File

@ -18,6 +18,7 @@ namespace FFXIVClassic_Map_Server
public static Logger Log; public static Logger Log;
public static Server Server; public static Server Server;
public static Random Random; public static Random Random;
public static DateTime Tick;
static void Main(string[] args) static void Main(string[] args)
{ {
@ -59,7 +60,7 @@ namespace FFXIVClassic_Map_Server
{ {
Random = new Random(); Random = new Random();
Server = new Server(); Server = new Server();
Tick = DateTime.Now;
Server.StartServer(); Server.StartServer();
while (startServer) while (startServer)

View File

@ -954,11 +954,12 @@ namespace FFXIVClassic_Map_Server
public void ZoneThreadLoop(Object state) public void ZoneThreadLoop(Object state)
{ {
// todo: spawn new thread for each zone on startup
lock (zoneList) lock (zoneList)
{ {
var tick = DateTime.Now; Program.Tick = DateTime.Now;
foreach (Zone zone in zoneList.Values) foreach (Zone zone in zoneList.Values)
zone.Update(tick); zone.Update(Program.Tick);
} }
} }

View File

@ -160,7 +160,7 @@ namespace FFXIVClassic_Map_Server.Actors
var pos = positionUpdates[0]; var pos = positionUpdates[0];
if (this is Character) if (this is Character)
((Character)this).OnPath(ref pos); ((Character)this).OnPath(pos);
positionX = pos.X; positionX = pos.X;
positionY = pos.Y; positionY = pos.Y;
@ -642,6 +642,31 @@ namespace FFXIVClassic_Map_Server.Actors
return new Vector3(positionX + x, positionY, positionZ + z); return new Vector3(positionX + x, positionY, positionZ + z);
} }
public Player GetAsPlayer()
{
return currentSubState == SetActorStatePacket.SUB_STATE_PLAYER && this is Player ? ((Player)this) : null;
}
public Mob GetAsMob()
{
return currentSubState == SetActorStatePacket.SUB_STATE_MONSTER && this is Mob ? ((Mob)this) : null;
}
public Npc GetAsNpc()
{
return currentSubState != SetActorStatePacket.SUB_STATE_PLAYER && this is Npc ? ((Npc)this) : null;
}
public Actor GetAsActor()
{
return this is Actor ? ((Actor)this) : null;
}
public Character GetAsCharacter()
{
return this is Character ? ((Character)this) : null;
}
} }
} }

View File

@ -412,7 +412,7 @@ namespace FFXIVClassic_Map_Server.Actors
AddActorToZone(npc); AddActorToZone(npc);
} }
public Npc SpawnActor(uint classId, string uniqueId, float x, float y, float z, float rot = 0, ushort state = 0, uint animId = 0) public Npc SpawnActor(uint classId, string uniqueId, float x, float y, float z, float rot = 0, ushort state = 0, uint animId = 0, bool isMob = true)
{ {
ActorClass actorClass = Server.GetWorldManager().GetActorClass(classId); ActorClass actorClass = Server.GetWorldManager().GetActorClass(classId);
@ -426,7 +426,12 @@ namespace FFXIVClassic_Map_Server.Actors
else else
zoneId = actorId; zoneId = actorId;
Npc npc = new Npc(mActorList.Count + 1, actorClass, uniqueId, this, x, y, z, rot, state, animId, null); Npc npc;
if(isMob)
npc = new Mob(mActorList.Count + 1, actorClass, uniqueId, this, x, y, z, rot, state, animId, null);
else
npc = new Npc(mActorList.Count + 1, actorClass, uniqueId, this, x, y, z, rot, state, animId, null);
npc.LoadEventConditions(actorClass.eventConditions); npc.LoadEventConditions(actorClass.eventConditions);

View File

@ -209,7 +209,7 @@ namespace FFXIVClassic_Map_Server.Actors
} }
} }
public void OnPath(ref Vector3 point) public void OnPath(Vector3 point)
{ {
if (positionUpdates != null && positionUpdates.Count > 0) if (positionUpdates != null && positionUpdates.Count > 0)
{ {

View File

@ -8,7 +8,7 @@ using FFXIVClassic_Map_Server.actors.chara.ai.state;
using FFXIVClassic_Map_Server.actors.chara.ai.controllers; using FFXIVClassic_Map_Server.actors.chara.ai.controllers;
using FFXIVClassic_Map_Server.packets.send.actor; using FFXIVClassic_Map_Server.packets.send.actor;
// port of ai code in dsp by kjLotus // port of ai code in dsp by kjLotus (https://github.com/DarkstarProject/darkstar/blob/master/src/map/ai)
namespace FFXIVClassic_Map_Server.actors.chara.ai namespace FFXIVClassic_Map_Server.actors.chara.ai
{ {
// todo: actually implement stuff // todo: actually implement stuff
@ -22,6 +22,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
private DateTime prevUpdate; private DateTime prevUpdate;
private PathFind pathFind; private PathFind pathFind;
private TargetFind targetFind; private TargetFind targetFind;
private ActionQueue actionQueue;
public AIContainer(Character actor, Controller controller, PathFind pathFind, TargetFind targetFind) public AIContainer(Character actor, Controller controller, PathFind pathFind, TargetFind targetFind)
{ {
@ -32,6 +33,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
this.targetFind = targetFind; this.targetFind = targetFind;
latestUpdate = DateTime.Now; latestUpdate = DateTime.Now;
prevUpdate = latestUpdate; prevUpdate = latestUpdate;
actionQueue = new ActionQueue(owner);
} }
public void Update(DateTime tick) public void Update(DateTime tick)
@ -46,36 +48,23 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
} }
public DateTime GetLatestUpdate() public void InterruptStates()
{ {
return latestUpdate; while (states.Count > 0 && states.Peek().CanInterrupt())
{
states.Peek().SetInterrupted(true);
states.Peek().Cleanup();
states.Pop();
}
} }
public void Engage(Character target) public void ClearStates()
{ {
if (controller != null) while (states.Count > 0)
controller.Engage(target); {
else states.Peek().Cleanup();
InternalEngage(target); states.Pop();
} }
public bool IsEngaged()
{
// todo: check this is legit
return owner.currentMainState == SetActorStatePacket.MAIN_STATE_ACTIVE;
}
public void Disengage()
{
if (controller != null)
controller.Disengage();
else
InternalDisengage();
}
public void Cast(Character target, uint spellId)
{
} }
public void ChangeController(Controller controller) public void ChangeController(Controller controller)
@ -100,6 +89,75 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
} }
} }
public DateTime GetLatestUpdate()
{
return latestUpdate;
}
public bool IsSpawned()
{
// todo: set a flag when finished spawning
return true;
}
public bool IsEngaged()
{
// todo: check this is legit
return owner.currentMainState == SetActorStatePacket.MAIN_STATE_ACTIVE;
}
public bool IsDead()
{
return owner.currentMainState == SetActorStatePacket.MAIN_STATE_DEAD ||
owner.currentMainState == SetActorStatePacket.MAIN_STATE_DEAD2;
}
public bool IsRoaming()
{
// todo: check mounted?
return owner.currentMainState == SetActorStatePacket.MAIN_STATE_PASSIVE;
}
public void Engage(Character target)
{
if (controller != null)
controller.Engage(target);
else
InternalEngage(target);
}
public void Disengage()
{
if (controller != null)
controller.Disengage();
else
InternalDisengage();
}
public void Cast(Character target, uint spellId)
{
if (controller != null)
controller.Cast(target, spellId);
else
InternalCast(target, spellId);
}
public void WeaponSkill(Character target, uint weaponSkillId)
{
if (controller != null)
controller.WeaponSkill(target, weaponSkillId);
else
InternalWeaponSkill(target, weaponSkillId);
}
public void MobSkill(Character target, uint mobSkillId)
{
if (controller != null)
controller.MobSkill(target, mobSkillId);
else
InternalMobSkill(target, mobSkillId);
}
public void InternalEngage(Character target) public void InternalEngage(Character target)
{ {

View File

@ -20,7 +20,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
} }
public override void Update(ref DateTime time) public override void Update(DateTime time)
{ {
} }

View File

@ -28,13 +28,15 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
this.interrupt = false; this.interrupt = false;
} }
public virtual void Update(ref DateTime time) { } public virtual void Update(DateTime tick) { }
public virtual void OnStart() { } public virtual void OnStart() { }
public virtual void OnInterrupt() { } public virtual void OnInterrupt() { }
public virtual void OnComplete() { } public virtual void OnComplete() { }
public virtual void TryInterrupt() { } public virtual void TryInterrupt() { }
public virtual void Cleanup() { }
public bool CanInterrupt() public bool CanInterrupt()
{ {
return canInterrupt; return canInterrupt;
@ -44,5 +46,6 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
{ {
this.interrupt = interrupt; this.interrupt = interrupt;
} }
} }
} }

View File

@ -9,6 +9,7 @@ using FFXIVClassic_Map_Server.actors;
using FFXIVClassic_Map_Server.actors.chara; using FFXIVClassic_Map_Server.actors.chara;
using FFXIVClassic_Map_Server.actors.chara.ai; using FFXIVClassic_Map_Server.actors.chara.ai;
using FFXIVClassic_Map_Server.actors.chara.ai.controllers; using FFXIVClassic_Map_Server.actors.chara.ai.controllers;
using FFXIVClassic_Map_Server.packets.send.actor;
namespace FFXIVClassic_Map_Server.Actors namespace FFXIVClassic_Map_Server.Actors
{ {
@ -19,6 +20,7 @@ namespace FFXIVClassic_Map_Server.Actors
: base(actorNumber, actorClass, uniqueId, spawnedArea, posX, posY, posZ, rot, actorState, animationId, customDisplayName) : base(actorNumber, actorClass, uniqueId, spawnedArea, posX, posY, posZ, rot, actorState, animationId, customDisplayName)
{ {
this.aiContainer = new AIContainer(this, new MobController(this), new PathFind(this), new TargetFind(this)); this.aiContainer = new AIContainer(this, new MobController(this), new PathFind(this), new TargetFind(this));
this.currentSubState = SetActorStatePacket.SUB_STATE_MONSTER;
} }
} }
} }