mirror of
https://bitbucket.org/Ioncannon/project-meteor-server.git
synced 2025-06-11 23:14:39 +02:00
filled out abilities table (todo: range needs correcting)
- changed target find stuff to use windower's (need to check it actually works..)
This commit is contained in:
parent
ebd295bfa4
commit
86bf0eec81
6 changed files with 235 additions and 71 deletions
|
@ -1844,8 +1844,8 @@ namespace FFXIVClassic_Map_Server
|
|||
{
|
||||
conn.Open();
|
||||
|
||||
var query = ("SELECT `id`, name, classJob, lvl, requirements, validTarget, aoeTarget, aoeType, `range`, characterFind, statusDuration, " +
|
||||
"castTime, recastTime, mpCost, tpCost, animationType, effectAnimation, modelAnimation, animationDuration, positionBonus, procRequirement FROM abilities;");
|
||||
var query = ("SELECT `id`, name, classJob, lvl, requirements, validTarget, aoeType, numHits, positionBonus, procRequirement, `range`, buffDuration, debuffDuration, " +
|
||||
"castType, castTime, recastTime, mpCost, tpCost, animationType, effectAnimation, modelAnimation, animationDuration FROM abilities;");
|
||||
|
||||
MySqlCommand cmd = new MySqlCommand(query, conn);
|
||||
|
||||
|
@ -1860,22 +1860,23 @@ namespace FFXIVClassic_Map_Server
|
|||
ability.job = reader.GetByte(2);
|
||||
ability.level = reader.GetByte(3);
|
||||
ability.requirements = (AbilityRequirements)reader.GetUInt16(4);
|
||||
ability.validTarget = (TargetFindFlags)reader.GetByte(5);
|
||||
ability.aoeTarget = (TargetFindAOETarget)reader.GetByte(6);
|
||||
ability.aoeType = (TargetFindAOEType)reader.GetByte(7);
|
||||
ability.range = reader.GetInt32(8);
|
||||
ability.characterFind = (TargetFindCharacterType)reader.GetByte(9);
|
||||
ability.statusDurationSeconds = reader.GetUInt32(10);
|
||||
ability.castTimeSeconds = reader.GetUInt32(11);
|
||||
ability.recastTimeSeconds = reader.GetUInt32(12);
|
||||
ability.mpCost = reader.GetUInt16(13);
|
||||
ability.tpCost = reader.GetUInt16(14);
|
||||
ability.animationType = reader.GetByte(15);
|
||||
ability.effectAnimation = reader.GetUInt16(16);
|
||||
ability.modelAnimation = reader.GetUInt16(17);
|
||||
ability.animationDurationSeconds = reader.GetUInt16(18);
|
||||
ability.positionBonus = (AbilityPositionBonus)reader.GetByte(19);
|
||||
ability.procRequirement = (AbilityProcRequirement)reader.GetByte(20);
|
||||
ability.validTarget = (ValidTarget)reader.GetByte(5);
|
||||
ability.aoeType = (TargetFindAOEType)reader.GetByte(6);
|
||||
ability.numHits = reader.GetByte(7);
|
||||
ability.positionBonus = (AbilityPositionBonus)reader.GetByte(8);
|
||||
ability.procRequirement = (AbilityProcRequirement)reader.GetByte(9);
|
||||
ability.range = reader.GetInt32(10);
|
||||
ability.debuffDurationSeconds = reader.GetUInt32(11);
|
||||
ability.buffDurationSeconds = reader.GetUInt32(12);
|
||||
ability.castType = reader.GetByte(13);
|
||||
ability.castTimeSeconds = reader.GetUInt32(14);
|
||||
ability.recastTimeSeconds = reader.GetUInt32(15);
|
||||
ability.mpCost = reader.GetUInt16(16);
|
||||
ability.tpCost = reader.GetUInt16(17);
|
||||
ability.animationType = reader.GetByte(18);
|
||||
ability.effectAnimation = reader.GetUInt16(19);
|
||||
ability.modelAnimation = reader.GetUInt16(20);
|
||||
ability.animationDurationSeconds = reader.GetUInt16(21);
|
||||
|
||||
abilities.Add(id, ability);
|
||||
}
|
||||
|
|
|
@ -47,12 +47,15 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||
public byte job;
|
||||
public byte level;
|
||||
public AbilityRequirements requirements;
|
||||
public TargetFindFlags validTarget;
|
||||
public TargetFindAOETarget aoeTarget;
|
||||
public ValidTarget validTarget;
|
||||
public TargetFindAOEType aoeType;
|
||||
public byte numHits;
|
||||
public AbilityPositionBonus positionBonus;
|
||||
public AbilityProcRequirement procRequirement;
|
||||
public int range;
|
||||
public TargetFindCharacterType characterFind;
|
||||
public uint statusDurationSeconds;
|
||||
public uint debuffDurationSeconds;
|
||||
public uint buffDurationSeconds;
|
||||
public byte castType;
|
||||
public uint castTimeSeconds;
|
||||
public uint recastTimeSeconds;
|
||||
public ushort mpCost;
|
||||
|
@ -62,8 +65,6 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||
public ushort modelAnimation;
|
||||
public ushort animationDurationSeconds;
|
||||
|
||||
public AbilityPositionBonus positionBonus;
|
||||
public AbilityProcRequirement procRequirement;
|
||||
|
||||
public TargetFind targetFind;
|
||||
|
||||
|
@ -93,7 +94,15 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||
{
|
||||
// todo: set box length..
|
||||
targetFind = new TargetFind(user);
|
||||
targetFind.SetAOEType(aoeTarget, aoeType, aoeType == TargetFindAOEType.Box ? range / 2 : range, 40);
|
||||
if (aoeType == TargetFindAOEType.Box)
|
||||
{
|
||||
// todo: read box width from sql
|
||||
targetFind.SetAOEBox(validTarget, range, 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
targetFind.SetAOEType(validTarget, aoeType, range, 40);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,20 +13,21 @@ using FFXIVClassic_Map_Server.packets.send.actor;
|
|||
|
||||
namespace FFXIVClassic_Map_Server.actors.chara.ai
|
||||
{
|
||||
/// <summary> todo: what even do i summarise this as? </summary>
|
||||
enum TargetFindFlags : byte
|
||||
// https://github.com/Windower/POLUtils/blob/master/PlayOnline.FFXI/Enums.cs
|
||||
[Flags]
|
||||
public enum ValidTarget : ushort
|
||||
{
|
||||
None = 0x00,
|
||||
/// <summary> Able to target <see cref="Player"/>s even if not in target's party </summary>
|
||||
HitAll = 0x01,
|
||||
/// <summary> Able to target all <see cref="Player"/>s in target's party/alliance </summary>
|
||||
Alliance = 0x02,
|
||||
/// <summary> Able to target any <see cref="Pet"/> in target's party/alliance </summary>
|
||||
Pets = 0x04,
|
||||
/// <summary> Target all in zone, regardless of distance </summary>
|
||||
ZoneWide = 0x08,
|
||||
/// <summary> Able to target dead <see cref="Player"/>s </summary>
|
||||
Dead = 0x10,
|
||||
Self = 0x01,
|
||||
Player = 0x02,
|
||||
PartyMember = 0x04,
|
||||
Ally = 0x08,
|
||||
NPC = 0x10,
|
||||
Enemy = 0x20,
|
||||
Unknown = 0x40,
|
||||
Object = 0x60,
|
||||
CorpseOnly = 0x80,
|
||||
Corpse = 0x9D // CorpseOnly + NPC + Ally + Partymember + Self
|
||||
}
|
||||
|
||||
/// <summary> Targeting from/to different entity types </summary>
|
||||
|
@ -71,9 +72,8 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||
private Character target;
|
||||
private Character masterTarget; // if target is a pet, this is the owner
|
||||
private TargetFindCharacterType findType;
|
||||
private TargetFindFlags findFlags;
|
||||
private ValidTarget validTarget;
|
||||
private TargetFindAOEType aoeType;
|
||||
private TargetFindAOETarget aoeTarget;
|
||||
private Vector3 targetPosition;
|
||||
private float extents;
|
||||
private float angle;
|
||||
|
@ -89,9 +89,8 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||
{
|
||||
this.target = null;
|
||||
this.findType = TargetFindCharacterType.None;
|
||||
this.findFlags = TargetFindFlags.None;
|
||||
this.validTarget = ValidTarget.None;
|
||||
this.aoeType = TargetFindAOEType.None;
|
||||
this.aoeTarget = TargetFindAOETarget.Self;
|
||||
this.targetPosition = null;
|
||||
this.extents = 0.0f;
|
||||
this.angle = 0.0f;
|
||||
|
@ -117,20 +116,30 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||
/// <see cref="TargetFindAOEType.Box"/> - width of box / 2 (todo: set box length not just between user and target)
|
||||
/// </param>
|
||||
/// <param name="angle"> Angle in radians of cone </param>
|
||||
public void SetAOEType(TargetFindAOETarget aoeTarget, TargetFindAOEType aoeType, float extents = -1.0f, float angle = -1.0f)
|
||||
public void SetAOEType(ValidTarget validTarget, TargetFindAOEType aoeType, float extents = -1.0f, float angle = -1.0f)
|
||||
{
|
||||
this.aoeTarget = TargetFindAOETarget.Target;
|
||||
this.validTarget = validTarget;
|
||||
this.aoeType = aoeType;
|
||||
this.extents = extents != -1.0f ? extents : 0.0f;
|
||||
this.angle = angle != -1.0f ? angle : 0.0f;
|
||||
}
|
||||
|
||||
public void SetAOEBox(ValidTarget validTarget, float length, float width)
|
||||
{
|
||||
this.validTarget = validTarget;
|
||||
this.aoeType = TargetFindAOEType.Box;
|
||||
float x = owner.positionX - (float)Math.Cos(owner.rotation + (float)(Math.PI / 2)) * (length);
|
||||
float z = owner.positionZ + (float)Math.Sin(owner.rotation + (float)(Math.PI / 2)) * (length);
|
||||
this.targetPosition = new Vector3(x, owner.positionY, z);
|
||||
this.extents = width;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find and try to add a single target to target list
|
||||
/// </summary>
|
||||
public void FindTarget(Character target, TargetFindFlags flags)
|
||||
public void FindTarget(Character target, ValidTarget flags)
|
||||
{
|
||||
findFlags = flags;
|
||||
validTarget = flags;
|
||||
this.target = null;
|
||||
// todo: maybe this should only be set if successfully added?
|
||||
this.targetPosition = target.GetPosAsVector3();
|
||||
|
@ -141,12 +150,12 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||
/// <para> Call SetAOEType before calling this </para>
|
||||
/// Find targets within area set by <see cref="SetAOEType"/>
|
||||
/// </summary>
|
||||
public void FindWithinArea(Character target, TargetFindFlags flags)
|
||||
public void FindWithinArea(Character target, ValidTarget flags)
|
||||
{
|
||||
findFlags = flags;
|
||||
validTarget = flags;
|
||||
// todo: maybe we should keep a snapshot which is only updated on each tick for consistency
|
||||
// are we creating aoe circles around target or self
|
||||
if ((aoeType & TargetFindAOEType.Circle) != 0 && aoeTarget != TargetFindAOETarget.Self)
|
||||
if ((aoeType & TargetFindAOEType.Circle) != 0 && validTarget != ValidTarget.Self)
|
||||
this.targetPosition = owner.GetPosAsVector3();
|
||||
else
|
||||
this.targetPosition = target.GetPosAsVector3();
|
||||
|
@ -157,7 +166,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||
this.target = target;
|
||||
|
||||
// todo: this is stupid
|
||||
bool withPet = (flags & TargetFindFlags.Pets) != 0 || masterTarget.allegiance != owner.allegiance;
|
||||
bool withPet = (flags & ValidTarget.Ally) != 0 || masterTarget.allegiance != owner.allegiance;
|
||||
|
||||
if (IsPlayer(owner))
|
||||
{
|
||||
|
@ -168,7 +177,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||
// todo: handle player parties
|
||||
if (masterTarget.currentParty != null)
|
||||
{
|
||||
if ((findFlags & TargetFindFlags.Alliance) != 0)
|
||||
if ((validTarget & ValidTarget.Ally) != 0)
|
||||
AddAllInAlliance(masterTarget, withPet);
|
||||
else
|
||||
AddAllInParty(masterTarget, withPet);
|
||||
|
@ -197,7 +206,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||
withPet = true;
|
||||
|
||||
// todo: does ffxiv have call for help flag?
|
||||
//if ((findFlags & TargetFindFlags.HitAll) != 0)
|
||||
//if ((findFlags & ValidTarget.HitAll) != 0)
|
||||
//{
|
||||
// AddAllInZone(masterTarget, withPet);
|
||||
//}
|
||||
|
@ -276,7 +285,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||
private void AddAllBattleNpcs(Character target, bool withPet)
|
||||
{
|
||||
// 70 is client render distance so we'll go with that
|
||||
var actors = (findFlags & TargetFindFlags.ZoneWide) != 0 ? owner.zone.GetAllActors<BattleNpc>() : owner.zone.GetActorsAroundActor<BattleNpc>(owner, 70);
|
||||
var actors = owner.zone.GetActorsAroundActor<BattleNpc>(owner, (int)extents);
|
||||
|
||||
// todo: should we look for Characters instead in case player is charmed by BattleNpc
|
||||
foreach (BattleNpc actor in actors)
|
||||
|
@ -313,7 +322,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||
return false;
|
||||
|
||||
// cant target dead
|
||||
if ((findFlags & TargetFindFlags.Dead) == 0 && target.IsDead())
|
||||
if ((validTarget & ValidTarget.Corpse) == 0 && target.IsDead())
|
||||
return false;
|
||||
|
||||
bool targetingPlayer = target is Player;
|
||||
|
@ -323,11 +332,11 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||
if (/*target.isZoning || owner.isZoning || */target.zone != owner.zone || targetingPlayer && ((Player)target).playerSession.isUpdatesLocked)
|
||||
return false;
|
||||
|
||||
if (aoeTarget == TargetFindAOETarget.Self && aoeType != TargetFindAOEType.None && owner != target)
|
||||
if (validTarget == ValidTarget.Self && aoeType != TargetFindAOEType.None && owner != target)
|
||||
return false;
|
||||
|
||||
// hit everything within zone or within aoe region
|
||||
if ((findFlags & TargetFindFlags.ZoneWide) != 0 || aoeType == TargetFindAOEType.Circle && target.GetPosAsVector3().IsWithinCircle(targetPosition, extents))
|
||||
if (extents == 255.0f || aoeType == TargetFindAOEType.Circle && target.GetPosAsVector3().IsWithinCircle(targetPosition, extents))
|
||||
return true;
|
||||
|
||||
if (aoeType == TargetFindAOEType.Cone && IsWithinCone(target, withPet))
|
||||
|
@ -374,25 +383,25 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||
return false;
|
||||
}
|
||||
|
||||
public Character GetValidTarget(Character target, TargetFindFlags findFlags)
|
||||
public Character GetValidTarget(Character target, ValidTarget findFlags)
|
||||
{
|
||||
if (target == null || target.currentSubState == SetActorStatePacket.SUB_STATE_PLAYER && ((Player)target).playerSession.isUpdatesLocked)
|
||||
return null;
|
||||
|
||||
if ((findFlags & TargetFindFlags.Pets) != 0)
|
||||
if ((findFlags & ValidTarget.Ally) != 0)
|
||||
{
|
||||
return owner.pet;
|
||||
}
|
||||
|
||||
// todo: this is beyond retarded
|
||||
var oldFlags = this.findFlags;
|
||||
this.findFlags = findFlags;
|
||||
var oldFlags = this.validTarget;
|
||||
this.validTarget = findFlags;
|
||||
if (CanTarget(target, false, true))
|
||||
{
|
||||
this.findFlags = oldFlags;
|
||||
this.validTarget = oldFlags;
|
||||
return target;
|
||||
}
|
||||
this.findFlags = oldFlags;
|
||||
this.validTarget = oldFlags;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -209,7 +209,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
|
|||
{
|
||||
// pathfind if too far otherwise jump to target
|
||||
owner.aiContainer.pathFind.SetPathFlags(distance > 5 ? PathFindFlags.None : PathFindFlags.IgnoreNav );
|
||||
owner.aiContainer.pathFind.PreparePath(targetPos, 1.2f, 5);
|
||||
owner.aiContainer.pathFind.PreparePath(targetPos, 1.5f, 5);
|
||||
}
|
||||
owner.aiContainer.pathFind.FollowPath();
|
||||
if (!owner.aiContainer.pathFind.IsFollowingPath())
|
||||
|
|
|
@ -21,6 +21,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.utils
|
|||
}
|
||||
((BattleNpc)defender).hateContainer.UpdateHate(attacker, damage);
|
||||
}
|
||||
defender.DelHP((short)damage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue