1
Fork 0
mirror of https://bitbucket.org/Ioncannon/project-meteor-server.git synced 2025-04-23 21:27:46 +00:00

added some more ai stubs

- created mob class
- added pathfind and targetfind helper classes (todo: actually add stuff to them)
- added action queue helper class (todo: add shit to it)
This commit is contained in:
Tahir Akhlaq 2017-06-12 20:13:26 +01:00
parent 04890660c0
commit 3bcaa4cc3e
15 changed files with 376 additions and 8 deletions

View file

@ -85,14 +85,18 @@
<Compile Include="actors\area\PrivateAreaContent.cs" /> <Compile Include="actors\area\PrivateAreaContent.cs" />
<Compile Include="actors\area\SpawnLocation.cs" /> <Compile Include="actors\area\SpawnLocation.cs" />
<Compile Include="actors\area\Zone.cs" /> <Compile Include="actors\area\Zone.cs" />
<Compile Include="actors\chara\ai\ActionQueue.cs" />
<Compile Include="actors\chara\ai\AIContainer.cs" /> <Compile Include="actors\chara\ai\AIContainer.cs" />
<Compile Include="actors\chara\ai\controllers\Controller.cs" /> <Compile Include="actors\chara\ai\controllers\Controller.cs" />
<Compile Include="actors\chara\ai\controllers\MobController.cs" /> <Compile Include="actors\chara\ai\controllers\MobController.cs" />
<Compile Include="actors\chara\ai\controllers\PlayerController.cs" /> <Compile Include="actors\chara\ai\controllers\PlayerController.cs" />
<Compile Include="actors\chara\ai\PathFind.cs" />
<Compile Include="actors\chara\ai\state\AttackState.cs" /> <Compile Include="actors\chara\ai\state\AttackState.cs" />
<Compile Include="actors\chara\ai\state\State.cs" /> <Compile Include="actors\chara\ai\state\State.cs" />
<Compile Include="actors\chara\ai\TargetFind.cs" />
<Compile Include="actors\chara\ai\utils\AttackUtils.cs" /> <Compile Include="actors\chara\ai\utils\AttackUtils.cs" />
<Compile Include="actors\chara\npc\ActorClass.cs" /> <Compile Include="actors\chara\npc\ActorClass.cs" />
<Compile Include="actors\chara\npc\Mob.cs" />
<Compile Include="actors\chara\npc\NpcWork.cs" /> <Compile Include="actors\chara\npc\NpcWork.cs" />
<Compile Include="actors\chara\AetheryteWork.cs" /> <Compile Include="actors\chara\AetheryteWork.cs" />
<Compile Include="actors\chara\player\Equipment.cs" /> <Compile Include="actors\chara\player\Equipment.cs" />

View file

@ -956,8 +956,8 @@ namespace FFXIVClassic_Map_Server
{ {
lock (zoneList) lock (zoneList)
{ {
foreach (Area area in zoneList.Values) foreach (Zone zone in zoneList.Values)
area.Update(MILIS_LOOPTIME); zone.Update(MILIS_LOOPTIME);
} }
} }

View file

@ -152,7 +152,7 @@ namespace FFXIVClassic_Map_Server.Actors
{ {
updateMs = 150; updateMs = 150;
} }
if (diffTime.Milliseconds >= updateMs && hasMoved) if (hasMoved && diffTime.Milliseconds >= updateMs)
{ {
hasMoved = (this.positionUpdates != null && this.positionUpdates.Count > 0); hasMoved = (this.positionUpdates != null && this.positionUpdates.Count > 0);
if (hasMoved) if (hasMoved)

View file

@ -167,6 +167,7 @@ namespace FFXIVClassic_Map_Server.actors.area
{ {
// todo: again, this is retarded but debug stuff // todo: again, this is retarded but debug stuff
var diffTime = DateTime.Now - lastUpdate; var diffTime = DateTime.Now - lastUpdate;
base.Update(deltaTime);
// arbitrary cap // arbitrary cap
if (diffTime.Milliseconds >= 33) if (diffTime.Milliseconds >= 33)

View file

@ -228,6 +228,13 @@ namespace FFXIVClassic_Map_Server.Actors
// todo: other ai helpers // todo: other ai helpers
// time elapsed since last ai update // time elapsed since last ai update
if (aiContainer != null)
{
this.aiContainer.Update(DateTime.Now);
}
/*
var diffTime = (DateTime.Now - lastAiUpdate); var diffTime = (DateTime.Now - lastAiUpdate);
if (this is Player) if (this is Player)
@ -386,7 +393,9 @@ namespace FFXIVClassic_Map_Server.Actors
lastAiUpdate = DateTime.Now; lastAiUpdate = DateTime.Now;
} }
} }
} */
}
} }
} }

View file

@ -6,27 +6,118 @@ using System.Threading.Tasks;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.actors.chara.ai.state; 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;
// port of ai code in dsp by kjLotus // port of ai code in dsp by kjLotus
namespace FFXIVClassic_Map_Server.actors.chara.ai namespace FFXIVClassic_Map_Server.actors.chara.ai
{ {
// todo: actually implement stuff // todo: actually implement stuff
// todo: use spell/ability/ws/mobskill objects instead of looking up ids
class AIContainer class AIContainer
{ {
private Character owner; private Character owner;
private Controller controller; private Controller controller;
private List<State> states; private Stack<State> states;
private DateTime latestUpdate; private DateTime latestUpdate;
private DateTime prevUpdate; private DateTime prevUpdate;
private PathFind pathFind;
private TargetFind targetFind;
public AIContainer(Actors.Character actor) public AIContainer(Character actor, Controller controller, PathFind pathFind, TargetFind targetFind)
{ {
this.owner = actor; this.owner = actor;
this.states = new Stack<State>();
this.controller = controller;
this.pathFind = pathFind;
this.targetFind = targetFind;
latestUpdate = DateTime.Now;
prevUpdate = latestUpdate;
}
public void Update(DateTime tick)
{
prevUpdate = latestUpdate;
latestUpdate = tick;
// todo: trigger listeners
// todo: action queues
}
public void Engage(Character target)
{
if (controller != null)
controller.Engage(target);
else
InternalEngage(target);
}
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)
{ {
this.controller = controller; this.controller = controller;
} }
public bool CanChangeState()
{
return states.Count == 0 || states.First().CanInterrupt();
}
public void ChangeState(State state)
{
if (states.Count < 10)
{
states.Push(state);
}
else
{
throw new Exception("shit");
}
}
public void InternalEngage(Character target)
{
}
public void InternalDisengage()
{
}
public void InternalCast(Character target, uint spellId)
{
}
public void InternalWeaponSkill(Character target, uint weaponSkillId)
{
}
public void InternalMobSkill(Character target, uint mobSkillId)
{
}
} }
} }

View file

@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Map_Server.Actors;
using MoonSharp;
using MoonSharp.Interpreter;
namespace FFXIVClassic_Map_Server.actors.chara.ai
{
class Action
{
public DateTime startTime;
public uint durationMs;
public bool checkState;
// todo: lua function
Script script;
}
class ActionQueue
{
private Character owner;
private Queue<Action> actionQueue;
private Queue<Action> timerQueue;
public bool IsEmpty { get { return actionQueue.Count > 0 || timerQueue.Count > 0; } }
public ActionQueue(Character owner)
{
}
public void PushAction(Action action)
{
}
public void Update(DateTime tick)
{
}
public void HandleAction(Action action)
{
}
}
}

View file

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Map_Server.Actors;
namespace FFXIVClassic_Map_Server.actors.chara.ai
{
class PathFind
{
private Character owner;
public PathFind(Character owner)
{
this.owner = owner;
}
}
}

View file

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Map_Server.Actors;
namespace FFXIVClassic_Map_Server.actors.chara.ai
{
class TargetFind
{
private Character owner;
public TargetFind(Character owner)
{
this.owner = owner;
}
}
}

View file

@ -3,10 +3,67 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using FFXIVClassic_Map_Server.Actors;
namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
{ {
class Controller abstract class Controller
{ {
protected Character owner;
protected DateTime lastUpdate;
protected bool canUpdate = true;
protected bool autoAttackEnabled = true;
protected bool castingEnabled = true;
protected bool weaponSkillEnabled = true;
protected PathFind pathFind;
protected TargetFind targetFind;
public abstract void Update(DateTime tick);
public abstract bool Engage(Character target);
public abstract bool Disengage();
public abstract void Cast(Character target, uint spellId);
public virtual void WeaponSkill(Character target, uint weaponSkillId) { }
public virtual void MobSkill(Character target, uint mobSkillId) { }
public abstract void Ability(Character target, uint abilityId);
public abstract void RangedAttack(Character target);
public virtual void Spawn() { }
public virtual void Despawn() { }
public virtual void ChangeTarget(Character target)
{
owner.aiContainer.InternalEngage(target);
}
public bool IsAutoAttackEnabled()
{
return autoAttackEnabled;
}
public void SetAutoAttackEnabled(bool isEnabled)
{
autoAttackEnabled = isEnabled;
}
public bool IsCastingEnabled()
{
return castingEnabled;
}
public void SetCastingEnabled(bool isEnabled)
{
castingEnabled = isEnabled;
}
public bool IsWeaponSkillEnabled()
{
return weaponSkillEnabled;
}
public void SetWeaponSkillEnabled(bool isEnabled)
{
weaponSkillEnabled = isEnabled;
}
} }
} }

View file

@ -3,10 +3,59 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using FFXIVClassic_Map_Server.Actors;
namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
{ {
class MobController : Controller class MobController : Controller
{ {
public MobController(Character owner)
{
this.owner = owner;
this.lastUpdate = DateTime.Now;
}
public override void Update(DateTime tick)
{
}
public override bool Engage(Character target)
{
// todo: check distance, last swing time, status effects
return true;
}
private bool TryEngage(Character target)
{
// todo:
return true;
}
public override bool Disengage()
{
// todo:
return true;
}
public override void Cast(Character target, uint spellId)
{
}
public override void Ability(Character target, uint abilityId)
{
}
public override void RangedAttack(Character target)
{
}
public override void MobSkill(Character target, uint mobSkillId)
{
}
} }
} }

View file

@ -3,10 +3,53 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using FFXIVClassic_Map_Server.Actors;
namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
{ {
class PlayerController : Controller class PlayerController : Controller
{ {
public PlayerController(Character owner)
{
this.owner = owner;
this.lastUpdate = DateTime.Now;
}
public override void Update(DateTime tick)
{
}
public override void ChangeTarget(Character target)
{
base.ChangeTarget(target);
}
public override bool Engage(Character target)
{
// todo: check distance, last swing time, status effects
return true;
}
public override bool Disengage()
{
// todo:
return true;
}
public override void Cast(Character target, uint spellId)
{
}
public override void Ability(Character target, uint abilityId)
{
}
public override void RangedAttack(Character target)
{
}
} }
} }

View file

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.actors.chara.npc;
using FFXIVClassic_Map_Server.actors;
using FFXIVClassic_Map_Server.actors.chara;
using FFXIVClassic_Map_Server.actors.chara.ai;
using FFXIVClassic_Map_Server.actors.chara.ai.controllers;
namespace FFXIVClassic_Map_Server.Actors
{
class Mob : Npc
{
public Mob(int actorNumber, ActorClass actorClass, string uniqueId, Area spawnedArea, float posX, float posY, float posZ, float rot,
ushort actorState, uint animationId, string 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));
}
}
}

View file

@ -17,6 +17,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using FFXIVClassic_Map_Server.actors.chara.ai;
namespace FFXIVClassic_Map_Server.Actors namespace FFXIVClassic_Map_Server.Actors
{ {
@ -84,8 +85,7 @@ namespace FFXIVClassic_Map_Server.Actors
isStatic = true; isStatic = true;
} }
} }
this.aiContainer = new AIContainer(this, null, new PathFind(this), new TargetFind(this));
GenerateActorName((int)actorNumber);
} }
public Npc(int actorNumber, ActorClass actorClass, string uniqueId, Area spawnedArea, float posX, float posY, float posZ, float rot, uint layout, uint instance) public Npc(int actorNumber, ActorClass actorClass, string uniqueId, Area spawnedArea, float posX, float posY, float posZ, float rot, uint layout, uint instance)

View file

@ -18,6 +18,8 @@ using FFXIVClassic_Map_Server.packets.send.actor.inventory;
using FFXIVClassic_Map_Server.actors.group; using FFXIVClassic_Map_Server.actors.group;
using FFXIVClassic_Map_Server.packets.send.group; using FFXIVClassic_Map_Server.packets.send.group;
using FFXIVClassic_Map_Server.packets.WorldPackets.Send.Group; using FFXIVClassic_Map_Server.packets.WorldPackets.Send.Group;
using FFXIVClassic_Map_Server.actors.chara.ai;
using FFXIVClassic_Map_Server.actors.chara.ai.controllers;
namespace FFXIVClassic_Map_Server.Actors namespace FFXIVClassic_Map_Server.Actors
{ {
@ -247,6 +249,7 @@ namespace FFXIVClassic_Map_Server.Actors
Database.LoadPlayerCharacter(this); Database.LoadPlayerCharacter(this);
lastPlayTimeUpdate = Utils.UnixTimeStampUTC(); lastPlayTimeUpdate = Utils.UnixTimeStampUTC();
this.aiContainer = new AIContainer(this, new PlayerController(this), null, new TargetFind(this));
} }
public List<SubPacket> Create0x132Packets(uint playerActorId) public List<SubPacket> Create0x132Packets(uint playerActorId)