mirror of
https://bitbucket.org/Ioncannon/project-meteor-server.git
synced 2025-04-02 19:42:05 -04:00
stubbed some more functions
This commit is contained in:
parent
84d5eee1fc
commit
7ab40a30f1
@ -204,7 +204,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||||||
public void MobSkill(Character target, uint mobSkillId)
|
public void MobSkill(Character target, uint mobSkillId)
|
||||||
{
|
{
|
||||||
if (controller != null)
|
if (controller != null)
|
||||||
controller.MobSkill(target, mobSkillId);
|
controller.MonsterSkill(target, mobSkillId);
|
||||||
else
|
else
|
||||||
InternalMobSkill(target, mobSkillId);
|
InternalMobSkill(target, mobSkillId);
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,17 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
|
|||||||
{
|
{
|
||||||
class BattleNpcController : Controller
|
class BattleNpcController : Controller
|
||||||
{
|
{
|
||||||
|
private DateTime lastActionTime;
|
||||||
|
private DateTime lastSpellCastTime;
|
||||||
|
private DateTime lastSkillTime;
|
||||||
|
private DateTime lastSpecialSkillTime; // todo: i dont think monsters have "2hr" cooldowns like ffxi
|
||||||
|
private DateTime deaggroTime;
|
||||||
|
private DateTime neutralTime;
|
||||||
|
private DateTime waitTime;
|
||||||
|
|
||||||
|
private bool firstSpell = true;
|
||||||
|
private DateTime lastRoamScript; // todo: what even is this used as
|
||||||
|
|
||||||
public BattleNpcController(Character owner)
|
public BattleNpcController(Character owner)
|
||||||
{
|
{
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
@ -17,15 +28,35 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
|
|||||||
|
|
||||||
public override void Update(DateTime tick)
|
public override void Update(DateTime tick)
|
||||||
{
|
{
|
||||||
// todo: handle aggro/deaggro and other shit here
|
var battleNpc = this.owner as BattleNpc;
|
||||||
((BattleNpc)this.owner).statusEffects.Update(tick);
|
|
||||||
|
if (battleNpc != null)
|
||||||
|
{
|
||||||
|
// todo: handle aggro/deaggro and other shit here
|
||||||
|
if (battleNpc.aiContainer.IsEngaged())
|
||||||
|
{
|
||||||
|
DoCombatTick(tick);
|
||||||
|
}
|
||||||
|
else if (!battleNpc.IsDead())
|
||||||
|
{
|
||||||
|
DoRoamTick(tick);
|
||||||
|
}
|
||||||
|
battleNpc.Update(tick);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Engage(Character target)
|
public override bool Engage(Character target)
|
||||||
{
|
{
|
||||||
// todo: check distance, last swing time, status effects
|
// todo: check distance, last swing time, status effects
|
||||||
this.owner.aiContainer.InternalEngage(target);
|
var canEngage = this.owner.aiContainer.InternalEngage(target);
|
||||||
return true;
|
if (canEngage)
|
||||||
|
{
|
||||||
|
// reset casting
|
||||||
|
firstSpell = true;
|
||||||
|
|
||||||
|
// todo: adjust cooldowns with modifiers
|
||||||
|
}
|
||||||
|
return canEngage;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool TryEngage(Character target)
|
private bool TryEngage(Character target)
|
||||||
@ -55,9 +86,19 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void MobSkill(Character target, uint mobSkillId)
|
public override void MonsterSkill(Character target, uint mobSkillId)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DoRoamTick(DateTime tick)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DoCombatTick(DateTime tick)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
|
|||||||
public abstract bool Disengage();
|
public abstract bool Disengage();
|
||||||
public abstract void Cast(Character target, uint spellId);
|
public abstract void Cast(Character target, uint spellId);
|
||||||
public virtual void WeaponSkill(Character target, uint weaponSkillId) { }
|
public virtual void WeaponSkill(Character target, uint weaponSkillId) { }
|
||||||
public virtual void MobSkill(Character target, uint mobSkillId) { }
|
public virtual void MonsterSkill(Character target, uint mobSkillId) { }
|
||||||
public abstract void Ability(Character target, uint abilityId);
|
public abstract void Ability(Character target, uint abilityId);
|
||||||
public abstract void RangedAttack(Character target);
|
public abstract void RangedAttack(Character target);
|
||||||
public virtual void Spawn() { }
|
public virtual void Spawn() { }
|
||||||
|
@ -13,18 +13,41 @@ using FFXIVClassic_Map_Server.packets.send.actor;
|
|||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.Actors
|
namespace FFXIVClassic_Map_Server.Actors
|
||||||
{
|
{
|
||||||
|
[Flags]
|
||||||
|
enum AggroType
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Sight,
|
||||||
|
Scent,
|
||||||
|
LowHp,
|
||||||
|
IgnoreLevelDifference
|
||||||
|
}
|
||||||
|
|
||||||
class BattleNpc : Npc
|
class BattleNpc : Npc
|
||||||
{
|
{
|
||||||
public HateContainer hateContainer;
|
public HateContainer hateContainer;
|
||||||
|
public AggroType aggroType;
|
||||||
|
|
||||||
public BattleNpc(int actorNumber, ActorClass actorClass, string uniqueId, Area spawnedArea, float posX, float posY, float posZ, float rot,
|
public BattleNpc(int actorNumber, ActorClass actorClass, string uniqueId, Area spawnedArea, float posX, float posY, float posZ, float rot,
|
||||||
ushort actorState, uint animationId, string customDisplayName)
|
ushort actorState, uint animationId, string customDisplayName)
|
||||||
: 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 BattleNpcController(this), new PathFind(this), new TargetFind(this));
|
this.aiContainer = new AIContainer(this, new BattleNpcController(this), new PathFind(this), new TargetFind(this));
|
||||||
|
|
||||||
this.currentSubState = SetActorStatePacket.SUB_STATE_MONSTER;
|
this.currentSubState = SetActorStatePacket.SUB_STATE_MONSTER;
|
||||||
|
//this.currentMainState = SetActorStatePacket.MAIN_STATE_ACTIVE;
|
||||||
|
|
||||||
|
//charaWork.property[2] = 1;
|
||||||
|
//npcWork.hateType = 1;
|
||||||
|
|
||||||
this.hateContainer = new HateContainer(this);
|
this.hateContainer = new HateContainer(this);
|
||||||
this.allegiance = CharacterTargetingAllegiance.BattleNpcs;
|
this.allegiance = CharacterTargetingAllegiance.BattleNpcs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Update(DateTime tick)
|
||||||
|
{
|
||||||
|
// todo:
|
||||||
|
this.statusEffects.Update(tick);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,6 +125,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
this.instance = instance;
|
this.instance = instance;
|
||||||
|
|
||||||
GenerateActorName((int)actorNumber);
|
GenerateActorName((int)actorNumber);
|
||||||
|
this.aiContainer = new AIContainer(this, null, new PathFind(this), new TargetFind(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
public SubPacket CreateAddActorPacket()
|
public SubPacket CreateAddActorPacket()
|
||||||
@ -393,7 +394,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
zone.DespawnActor(this);
|
zone.DespawnActor(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update(DateTime tick)
|
public override void Update(DateTime tick)
|
||||||
{
|
{
|
||||||
var deltaTime = (tick - aiContainer.GetLatestUpdate()).Milliseconds;
|
var deltaTime = (tick - aiContainer.GetLatestUpdate()).Milliseconds;
|
||||||
LuaEngine.GetInstance().CallLuaFunction(null, this, "onUpdate", true, deltaTime);
|
LuaEngine.GetInstance().CallLuaFunction(null, this, "onUpdate", true, deltaTime);
|
||||||
|
@ -129,6 +129,40 @@ namespace FFXIVClassic_Map_Server.lua
|
|||||||
player.EndEvent();
|
player.EndEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// // todo: this is dumb, should probably make a function for each action with different default return values
|
||||||
|
/// or just make generic function and pass default value as first arg after functionName
|
||||||
|
/// </summary>
|
||||||
|
public static void CallLuaMonsterAction(Character actor, string functionName, params object[] args)
|
||||||
|
{
|
||||||
|
// todo: should we call this for players too?
|
||||||
|
if (actor is BattleNpc)
|
||||||
|
{
|
||||||
|
// todo: check this is correct
|
||||||
|
string path = $"./scripts/unique/{actor.zone.zoneName}/Monster/{actor.customDisplayName}.lua";
|
||||||
|
|
||||||
|
// dont wanna throw an error if file doesnt exist
|
||||||
|
if (File.Exists(path))
|
||||||
|
{
|
||||||
|
var script = LoadGlobals();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
script.DoFile(path);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Program.Log.Error($"LuaEngine.CallLuaMonsterAction [{functionName}] {e.Message}");
|
||||||
|
}
|
||||||
|
DynValue res = new DynValue();
|
||||||
|
|
||||||
|
if (!script.Globals.Get(functionName).IsNil())
|
||||||
|
{
|
||||||
|
res = script.Call(script.Globals.Get(functionName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static string GetScriptPath(Actor target)
|
private static string GetScriptPath(Actor target)
|
||||||
{
|
{
|
||||||
if (target is Player)
|
if (target is Player)
|
||||||
|
@ -169,7 +169,7 @@ namespace FFXIVClassic_World_Server
|
|||||||
{
|
{
|
||||||
uint sessionId = subpacket.header.targetId;
|
uint sessionId = subpacket.header.targetId;
|
||||||
Session session = GetSession(sessionId);
|
Session session = GetSession(sessionId);
|
||||||
subpacket.DebugPrintSubPacket();
|
//subpacket.DebugPrintSubPacket();
|
||||||
if (subpacket.gameMessage.opcode >= 0x1000)
|
if (subpacket.gameMessage.opcode >= 0x1000)
|
||||||
{
|
{
|
||||||
//subpacket.DebugPrintSubPacket();
|
//subpacket.DebugPrintSubPacket();
|
||||||
|
Loading…
Reference in New Issue
Block a user