mirror of
https://bitbucket.org/Ioncannon/project-meteor-server.git
synced 2025-04-02 19:42:05 -04:00
Merge branch 'ai-open' of https://bitbucket.org/takhlaq/ffxiv-classic-server into ai-open
This commit is contained in:
commit
6e1983031b
@ -88,6 +88,9 @@ namespace FFXIVClassic.Common
|
|||||||
|
|
||||||
public static float GetAngle(float x, float z, float x2, float z2)
|
public static float GetAngle(float x, float z, float x2, float z2)
|
||||||
{
|
{
|
||||||
|
if (x == x2)
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
var angle = (float)(Math.Atan((z2 - z) / (x2 - x)));
|
var angle = (float)(Math.Atan((z2 - z) / (x2 - x)));
|
||||||
return (float)(x > x2 ? angle + Math.PI : angle);
|
return (float)(x > x2 ? angle + Math.PI : angle);
|
||||||
}
|
}
|
||||||
@ -104,6 +107,9 @@ namespace FFXIVClassic.Common
|
|||||||
|
|
||||||
public bool IsWithinCircle(Vector3 centre, float radius)
|
public bool IsWithinCircle(Vector3 centre, float radius)
|
||||||
{
|
{
|
||||||
|
if (this.X == centre.X && this.Z == centre.Z)
|
||||||
|
return true;
|
||||||
|
|
||||||
float diffX = centre.X - this.X;
|
float diffX = centre.X - this.X;
|
||||||
float diffZ = centre.Z - this.Z;
|
float diffZ = centre.Z - this.Z;
|
||||||
|
|
||||||
|
@ -2154,8 +2154,8 @@ namespace FFXIVClassic_Map_Server
|
|||||||
{
|
{
|
||||||
conn.Open();
|
conn.Open();
|
||||||
|
|
||||||
var query = ("SELECT `id`, name, classJob, lvl, requirements, validTarget, aoeType, numHits, positionBonus, procRequirement, `range`, buffDuration, debuffDuration, " +
|
var query = ("SELECT `id`, name, classJob, lvl, requirements, validTarget, aoeType, aoeRange, aoeTarget, numHits, positionBonus, procRequirement, `range`, buffDuration, debuffDuration, " +
|
||||||
"castType, castTime, recastTime, mpCost, tpCost, animationType, effectAnimation, modelAnimation, animationDuration, aoeRange FROM server_battle_commands;");
|
"castType, castTime, recastTime, mpCost, tpCost, animationType, effectAnimation, modelAnimation, animationDuration, battleAnimation FROM server_battle_commands;");
|
||||||
|
|
||||||
MySqlCommand cmd = new MySqlCommand(query, conn);
|
MySqlCommand cmd = new MySqlCommand(query, conn);
|
||||||
|
|
||||||
@ -2188,7 +2188,9 @@ namespace FFXIVClassic_Map_Server
|
|||||||
battleCommand.modelAnimation = reader.GetUInt16("modelAnimation");
|
battleCommand.modelAnimation = reader.GetUInt16("modelAnimation");
|
||||||
battleCommand.animationDurationSeconds = reader.GetUInt16("animationDuration");
|
battleCommand.animationDurationSeconds = reader.GetUInt16("animationDuration");
|
||||||
battleCommand.aoeRange = reader.GetInt32("aoeRange");
|
battleCommand.aoeRange = reader.GetInt32("aoeRange");
|
||||||
battleCommand.battleAnimation = (uint)((battleCommand.animationType << 24) | (battleCommand.modelAnimation << 12) | (battleCommand.effectAnimation));
|
battleCommand.aoeTarget = (TargetFindAOETarget)reader.GetByte("aoeTarget");
|
||||||
|
|
||||||
|
battleCommand.battleAnimation = reader.GetUInt32("battleAnimation");
|
||||||
|
|
||||||
battleCommands.Add(id, battleCommand);
|
battleCommands.Add(id, battleCommand);
|
||||||
}
|
}
|
||||||
|
@ -96,6 +96,7 @@
|
|||||||
<Compile Include="actors\chara\ai\BattleCommand.cs" />
|
<Compile Include="actors\chara\ai\BattleCommand.cs" />
|
||||||
<Compile Include="actors\chara\ai\state\AttackState.cs" />
|
<Compile Include="actors\chara\ai\state\AttackState.cs" />
|
||||||
<Compile Include="actors\chara\ai\state\DeathState.cs" />
|
<Compile Include="actors\chara\ai\state\DeathState.cs" />
|
||||||
|
<Compile Include="actors\chara\ai\state\DespawnState.cs" />
|
||||||
<Compile Include="actors\chara\ai\state\MagicState.cs" />
|
<Compile Include="actors\chara\ai\state\MagicState.cs" />
|
||||||
<Compile Include="actors\chara\ai\state\State.cs" />
|
<Compile Include="actors\chara\ai\state\State.cs" />
|
||||||
<Compile Include="actors\chara\ai\state\WeaponSkillState.cs" />
|
<Compile Include="actors\chara\ai\state\WeaponSkillState.cs" />
|
||||||
|
@ -154,6 +154,8 @@ namespace FFXIVClassic_Map_Server
|
|||||||
case 0x00CC:
|
case 0x00CC:
|
||||||
LockTargetPacket lockTarget = new LockTargetPacket(subpacket.data);
|
LockTargetPacket lockTarget = new LockTargetPacket(subpacket.data);
|
||||||
session.GetActor().currentLockedTarget = lockTarget.actorID;
|
session.GetActor().currentLockedTarget = lockTarget.actorID;
|
||||||
|
session.GetActor().isAutoAttackEnabled = lockTarget.otherVal == 0x00000040;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
//Start Event
|
//Start Event
|
||||||
case 0x012D:
|
case 0x012D:
|
||||||
|
@ -365,10 +365,10 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
|
|
||||||
public void ChangeState(ushort newState)
|
public void ChangeState(ushort newState)
|
||||||
{
|
{
|
||||||
if (newState != currentMainState)
|
//if (newState != currentMainState)
|
||||||
{
|
{
|
||||||
currentMainState = newState;
|
currentMainState = newState;
|
||||||
updateFlags |= ActorUpdateFlags.State;
|
updateFlags |= (ActorUpdateFlags.State | ActorUpdateFlags.Position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,7 +402,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
if (positionUpdates != null && positionUpdates.Count > 0)
|
if (positionUpdates != null && positionUpdates.Count > 0)
|
||||||
{
|
{
|
||||||
// push latest for player
|
// push latest for player
|
||||||
var pos = positionUpdates[currentSubState == SetActorStatePacket.SUB_STATE_PLAYER ? positionUpdates.Count - 1 : 0];
|
var pos = positionUpdates[0];
|
||||||
oldPositionX = positionX;
|
oldPositionX = positionX;
|
||||||
oldPositionY = positionY;
|
oldPositionY = positionY;
|
||||||
oldPositionZ = positionZ;
|
oldPositionZ = positionZ;
|
||||||
@ -417,8 +417,8 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
//Program.Server.GetInstance().mLuaEngine.OnPath(actor, position, positionUpdates)
|
//Program.Server.GetInstance().mLuaEngine.OnPath(actor, position, positionUpdates)
|
||||||
|
|
||||||
positionUpdates.Remove(pos);
|
positionUpdates.Remove(pos);
|
||||||
packets.Add(CreatePositionUpdatePacket());
|
|
||||||
}
|
}
|
||||||
|
packets.Add(CreatePositionUpdatePacket());
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((updateFlags & ActorUpdateFlags.Speed) != 0)
|
if ((updateFlags & ActorUpdateFlags.Speed) != 0)
|
||||||
@ -434,8 +434,6 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
if ((updateFlags & ActorUpdateFlags.State) != 0)
|
if ((updateFlags & ActorUpdateFlags.State) != 0)
|
||||||
{
|
{
|
||||||
packets.Add(SetActorStatePacket.BuildPacket(actorId, currentMainState, currentSubState));
|
packets.Add(SetActorStatePacket.BuildPacket(actorId, currentMainState, currentSubState));
|
||||||
if (this is Character)
|
|
||||||
((Character)this).DoBattleAction(21001, 0x7C000062, new BattleAction(this.actorId, 0, 1, 0, 0, 1)); //Attack Mode
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateFlags = ActorUpdateFlags.None;
|
updateFlags = ActorUpdateFlags.None;
|
||||||
|
@ -321,6 +321,11 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public T FindActorInArea<T>(uint id) where T : Actor
|
||||||
|
{
|
||||||
|
return FindActorInArea(id) as T;
|
||||||
|
}
|
||||||
|
|
||||||
public Actor FindActorInZoneByUniqueID(string uniqueId)
|
public Actor FindActorInZoneByUniqueID(string uniqueId)
|
||||||
{
|
{
|
||||||
lock (mActorList)
|
lock (mActorList)
|
||||||
|
@ -67,6 +67,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
public bool isStatic = false;
|
public bool isStatic = false;
|
||||||
|
|
||||||
public bool isMovingToSpawn = false;
|
public bool isMovingToSpawn = false;
|
||||||
|
public bool isAutoAttackEnabled = true;
|
||||||
|
|
||||||
public uint modelId;
|
public uint modelId;
|
||||||
public uint[] appearanceIds = new uint[28];
|
public uint[] appearanceIds = new uint[28];
|
||||||
@ -98,6 +99,8 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
protected ushort hpBase, hpMaxBase, mpBase, mpMaxBase, tpBase;
|
protected ushort hpBase, hpMaxBase, mpBase, mpMaxBase, tpBase;
|
||||||
protected BattleTemp baseStats = new BattleTemp();
|
protected BattleTemp baseStats = new BattleTemp();
|
||||||
public ushort currentJob;
|
public ushort currentJob;
|
||||||
|
public ushort newMainState;
|
||||||
|
public float spawnX, spawnY, spawnZ;
|
||||||
|
|
||||||
public Character(uint actorID) : base(actorID)
|
public Character(uint actorID) : base(actorID)
|
||||||
{
|
{
|
||||||
@ -112,6 +115,10 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
// todo: base this on equip and shit
|
// todo: base this on equip and shit
|
||||||
SetMod((uint)Modifier.AttackRange, 3);
|
SetMod((uint)Modifier.AttackRange, 3);
|
||||||
SetMod((uint)Modifier.AttackDelay, (Program.Random.Next(30, 60) * 100));
|
SetMod((uint)Modifier.AttackDelay, (Program.Random.Next(30, 60) * 100));
|
||||||
|
|
||||||
|
spawnX = positionX;
|
||||||
|
spawnY = positionY;
|
||||||
|
spawnZ = positionZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SubPacket CreateAppearancePacket()
|
public SubPacket CreateAppearancePacket()
|
||||||
@ -305,7 +312,13 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
|
|
||||||
if ((updateFlags & ActorUpdateFlags.State) != 0)
|
if ((updateFlags & ActorUpdateFlags.State) != 0)
|
||||||
{
|
{
|
||||||
|
packets.Add(SetActorStatePacket.BuildPacket(actorId, currentMainState, currentSubState));
|
||||||
packets.Add(BattleActionX00Packet.BuildPacket(actorId, 0x72000062, 0));
|
packets.Add(BattleActionX00Packet.BuildPacket(actorId, 0x72000062, 0));
|
||||||
|
packets.Add(BattleActionX01Packet.BuildPacket(actorId, 0x7C000062, 21001, new BattleAction(actorId, 0, 1)));
|
||||||
|
|
||||||
|
// this is silly, but looks like state change goes full retard unless theyre sent in order
|
||||||
|
updateFlags &= ~ActorUpdateFlags.State;
|
||||||
|
//DoBattleAction(21001, 0x7C000062, new BattleAction(this.actorId, 0, 1, 0, 0, 1)); //Attack Mode
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: should probably add another flag for battleTemp since all this uses reflection
|
// todo: should probably add another flag for battleTemp since all this uses reflection
|
||||||
@ -357,9 +370,15 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
return (uint)GetMod((uint)Modifier.AttackRange);
|
return (uint)GetMod((uint)Modifier.AttackRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Engage(uint targid = 0)
|
public virtual bool Engage(uint targid = 0, ushort newMainState = 0xFFFF)
|
||||||
{
|
{
|
||||||
// todo: attack the things
|
// todo: attack the things
|
||||||
|
if (newMainState != 0xFFFF)
|
||||||
|
{
|
||||||
|
this.newMainState = newMainState;
|
||||||
|
}
|
||||||
|
else if (aiContainer.CanChangeState())
|
||||||
|
{
|
||||||
if (targid == 0)
|
if (targid == 0)
|
||||||
{
|
{
|
||||||
if (currentTarget != 0xC0000000)
|
if (currentTarget != 0xC0000000)
|
||||||
@ -367,16 +386,21 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
else if (currentLockedTarget != 0xC0000000)
|
else if (currentLockedTarget != 0xC0000000)
|
||||||
targid = currentLockedTarget;
|
targid = currentLockedTarget;
|
||||||
}
|
}
|
||||||
if (targid != 0)
|
//if (targid != 0)
|
||||||
{
|
{
|
||||||
aiContainer.Engage(Server.GetWorldManager().GetActorInWorld(targid) as Character);
|
aiContainer.Engage(zone.FindActorInArea<Character>(targid));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Disengage()
|
public virtual bool Disengage(ushort newMainState = 0xFFFF)
|
||||||
{
|
{
|
||||||
if (aiContainer != null)
|
if (newMainState != 0xFFFF)
|
||||||
|
{
|
||||||
|
this.newMainState = newMainState;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
aiContainer.Disengage();
|
aiContainer.Disengage();
|
||||||
return true;
|
return true;
|
||||||
@ -384,19 +408,22 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Cast(uint spellId, uint targetId = 0)
|
public virtual void Cast(uint spellId, uint targetId = 0)
|
||||||
{
|
{
|
||||||
aiContainer.Cast(Server.GetWorldManager().GetActorInWorld(targetId == 0 ? currentTarget : targetId) as Character, spellId);
|
if (aiContainer.CanChangeState())
|
||||||
|
aiContainer.Cast(zone.FindActorInArea<Character>(targetId == 0 ? currentTarget : targetId), spellId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Ability(uint abilityId, uint targetId = 0)
|
public virtual void Ability(uint abilityId, uint targetId = 0)
|
||||||
{
|
{
|
||||||
aiContainer.Ability(Server.GetWorldManager().GetActorInWorld(targetId == 0 ? currentTarget : targetId) as Character, abilityId);
|
if (aiContainer.CanChangeState())
|
||||||
|
aiContainer.Ability(zone.FindActorInArea<Character>(targetId == 0 ? currentTarget : targetId), abilityId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WeaponSkill(uint skillId)
|
public virtual void WeaponSkill(uint skillId, uint targetId = 0)
|
||||||
{
|
{
|
||||||
aiContainer.WeaponSkill(Server.GetWorldManager().GetActorInWorld(currentTarget) as Character, skillId);
|
if (aiContainer.CanChangeState())
|
||||||
|
aiContainer.WeaponSkill(zone.FindActorInArea<Character>(targetId == 0 ? currentTarget : targetId), skillId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Spawn(DateTime tick)
|
public virtual void Spawn(DateTime tick)
|
||||||
@ -414,7 +441,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
aiContainer.InternalDie(tick, 10);
|
aiContainer.InternalDie(tick, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void Despawn(DateTime tick)
|
public virtual void Despawn(DateTime tick)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -551,20 +578,23 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
//var packet = BattleActionX01Packet.BuildPacket(owner.actorId, owner.actorId, target.actorId, (uint)0x19001000, (uint)0x8000604, (ushort)0x765D, (ushort)BattleActionX01PacketCommand.Attack, (ushort)damage, (byte)0x1);
|
//var packet = BattleActionX01Packet.BuildPacket(owner.actorId, owner.actorId, target.actorId, (uint)0x19001000, (uint)0x8000604, (ushort)0x765D, (ushort)BattleActionX01PacketCommand.Attack, (ushort)damage, (byte)0x1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo: call onAttack/onDamageTaken
|
||||||
target.DelHP(action.amount);
|
target.DelHP(action.amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void OnCast(State state, BattleAction action, ref SubPacket errorPacket)
|
public virtual void OnCast(State state, BattleAction[] actions, ref BattleAction[] errors)
|
||||||
{
|
{
|
||||||
|
var spell = ((MagicState)state).GetSpell();
|
||||||
|
this.DelMP(spell.mpCost); // mpCost can be set in script e.g. if caster has something for free spells
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void OnWeaponSkill(State state, BattleAction action, ref SubPacket errorPacket)
|
public virtual void OnWeaponSkill(State state, BattleAction[] actions, ref BattleAction[] errors)
|
||||||
{
|
{
|
||||||
|
var skill = ((WeaponSkillState)state).GetWeaponSkill();
|
||||||
|
this.DelTP(skill.tpCost);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void OnAbility(State state, BattleAction action, ref SubPacket errorPacket)
|
public virtual void OnAbility(State state, BattleAction[] actions, ref BattleAction[] errors)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||||||
public readonly PathFind pathFind;
|
public readonly PathFind pathFind;
|
||||||
private TargetFind targetFind;
|
private TargetFind targetFind;
|
||||||
private ActionQueue actionQueue;
|
private ActionQueue actionQueue;
|
||||||
|
private DateTime lastActionTime;
|
||||||
|
|
||||||
public AIContainer(Character actor, Controller controller, PathFind pathFind, TargetFind targetFind)
|
public AIContainer(Character actor, Controller controller, PathFind pathFind, TargetFind targetFind)
|
||||||
{
|
{
|
||||||
@ -36,6 +37,16 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||||||
actionQueue = new ActionQueue(owner);
|
actionQueue = new ActionQueue(owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UpdateLastActionTime()
|
||||||
|
{
|
||||||
|
lastActionTime = DateTime.Now;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime GetLastActionTime()
|
||||||
|
{
|
||||||
|
return lastActionTime;
|
||||||
|
}
|
||||||
|
|
||||||
public void Update(DateTime tick)
|
public void Update(DateTime tick)
|
||||||
{
|
{
|
||||||
prevUpdate = latestUpdate;
|
prevUpdate = latestUpdate;
|
||||||
@ -186,13 +197,13 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||||||
public bool IsEngaged()
|
public bool IsEngaged()
|
||||||
{
|
{
|
||||||
// todo: check this is legit
|
// todo: check this is legit
|
||||||
return owner.currentMainState == SetActorStatePacket.MAIN_STATE_ACTIVE && owner.target != null;
|
return owner.currentMainState == SetActorStatePacket.MAIN_STATE_ACTIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsDead()
|
public bool IsDead()
|
||||||
{
|
{
|
||||||
return owner.currentMainState == SetActorStatePacket.MAIN_STATE_DEAD ||
|
return owner.currentMainState == SetActorStatePacket.MAIN_STATE_DEAD ||
|
||||||
owner.currentMainState == SetActorStatePacket.MAIN_STATE_DEAD2;
|
owner.currentMainState == SetActorStatePacket.MAIN_STATE_DEAD2 || owner.GetHP() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsRoaming()
|
public bool IsRoaming()
|
||||||
@ -253,10 +264,6 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||||||
{
|
{
|
||||||
// todo: use invalid target id
|
// todo: use invalid target id
|
||||||
// todo: this is retarded, call entity's changetarget function
|
// todo: this is retarded, call entity's changetarget function
|
||||||
owner.target = target;
|
|
||||||
owner.currentLockedTarget = target != null ? target.actorId : 0xC0000000;
|
|
||||||
owner.currentTarget = target != null ? target.actorId : 0xC0000000;
|
|
||||||
|
|
||||||
if (IsEngaged() || target == null)
|
if (IsEngaged() || target == null)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -293,8 +300,8 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||||||
GetTargetFind()?.Reset();
|
GetTargetFind()?.Reset();
|
||||||
|
|
||||||
owner.updateFlags |= ActorUpdateFlags.HpTpMp;
|
owner.updateFlags |= ActorUpdateFlags.HpTpMp;
|
||||||
|
|
||||||
ChangeTarget(null);
|
ChangeTarget(null);
|
||||||
|
owner.ChangeState(SetActorStatePacket.MAIN_STATE_PASSIVE);
|
||||||
ClearStates();
|
ClearStates();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||||||
public BattleCommandRequirements requirements;
|
public BattleCommandRequirements requirements;
|
||||||
public ValidTarget validTarget;
|
public ValidTarget validTarget;
|
||||||
public TargetFindAOEType aoeType;
|
public TargetFindAOEType aoeType;
|
||||||
|
public TargetFindAOETarget aoeTarget;
|
||||||
public byte numHits;
|
public byte numHits;
|
||||||
public BattleCommandPositionBonus positionBonus;
|
public BattleCommandPositionBonus positionBonus;
|
||||||
public BattleCommandProcRequirement procRequirement;
|
public BattleCommandProcRequirement procRequirement;
|
||||||
@ -105,11 +106,11 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||||||
if (aoeType == TargetFindAOEType.Box)
|
if (aoeType == TargetFindAOEType.Box)
|
||||||
{
|
{
|
||||||
// todo: read box width from sql
|
// todo: read box width from sql
|
||||||
targetFind.SetAOEBox(validTarget, range, aoeRange);
|
targetFind.SetAOEBox(validTarget, aoeTarget, range, aoeRange);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
targetFind.SetAOEType(validTarget, aoeType, range, aoeRange);
|
targetFind.SetAOEType(validTarget, aoeType, aoeTarget, range, aoeRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -183,8 +184,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||||||
if ((validTarget & ValidTarget.Enemy) != 0)
|
if ((validTarget & ValidTarget.Enemy) != 0)
|
||||||
{
|
{
|
||||||
if (target == user || target != null &&
|
if (target == user || target != null &&
|
||||||
target.currentSubState != (user.currentSubState == SetActorStatePacket.SUB_STATE_MONSTER ?
|
user.allegiance == target.allegiance)
|
||||||
SetActorStatePacket.SUB_STATE_PLAYER : SetActorStatePacket.SUB_STATE_MONSTER))
|
|
||||||
{
|
{
|
||||||
if (user is Player)
|
if (user is Player)
|
||||||
((Player)user).SendGameMessage(Server.GetWorldManager().GetActor(), 32519, 0x20, (uint)id);
|
((Player)user).SendGameMessage(Server.GetWorldManager().GetActor(), 32519, 0x20, (uint)id);
|
||||||
@ -194,14 +194,14 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||||||
|
|
||||||
if ((validTarget & (ValidTarget.PartyMember | ValidTarget.Player | ValidTarget.Ally)) != 0)
|
if ((validTarget & (ValidTarget.PartyMember | ValidTarget.Player | ValidTarget.Ally)) != 0)
|
||||||
{
|
{
|
||||||
if (target == null || target.currentSubState != user.currentSubState )
|
if (target == null || target.allegiance != user.allegiance)
|
||||||
{
|
{
|
||||||
if (user is Player)
|
if (user is Player)
|
||||||
((Player)user).SendGameMessage(Server.GetWorldManager().GetActor(), 32516, 0x20, (uint)id);
|
((Player)user).SendGameMessage(Server.GetWorldManager().GetActor(), 32516, 0x20, (uint)id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return targetFind.CanTarget(target, true, true);
|
return targetFind.CanTarget(target, true, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ushort CalculateCost(uint level)
|
public ushort CalculateCost(uint level)
|
||||||
|
@ -195,13 +195,13 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||||||
float baseSpeed = owner.GetSpeed();
|
float baseSpeed = owner.GetSpeed();
|
||||||
|
|
||||||
// todo: get actual speed crap
|
// todo: get actual speed crap
|
||||||
if (owner.currentSubState != SetActorStatePacket.SUB_STATE_NONE)
|
if (!(owner is Player))
|
||||||
{
|
{
|
||||||
if (owner.currentSubState == SetActorStatePacket.SUB_STATE_MONSTER)
|
if (owner is BattleNpc)
|
||||||
{
|
{
|
||||||
//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;
|
// baseSpeed += ConfigConstants.NPC_SPEED_MOD;
|
||||||
}
|
}
|
||||||
return baseSpeed;
|
return baseSpeed;
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ using FFXIVClassic_Map_Server.Actors;
|
|||||||
using FFXIVClassic.Common;
|
using FFXIVClassic.Common;
|
||||||
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.actors.group;
|
||||||
using FFXIVClassic_Map_Server.packets.send.actor;
|
using FFXIVClassic_Map_Server.packets.send.actor;
|
||||||
|
|
||||||
// port of dsp's ai code https://github.com/DarkstarProject/darkstar/blob/master/src/map/ai/
|
// port of dsp's ai code https://github.com/DarkstarProject/darkstar/blob/master/src/map/ai/
|
||||||
@ -48,9 +49,9 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||||||
enum TargetFindAOEType : byte
|
enum TargetFindAOEType : byte
|
||||||
{
|
{
|
||||||
None,
|
None,
|
||||||
/// <summary> Really a cylinder, uses extents parameter in SetAOEType </summary>
|
/// <summary> Really a cylinder, uses maxDistance parameter in SetAOEType </summary>
|
||||||
Circle,
|
Circle,
|
||||||
/// <summary> Create a cone with angle in radians </summary>
|
/// <summary> Create a cone with param in radians </summary>
|
||||||
Cone,
|
Cone,
|
||||||
/// <summary> Box using self/target coords and </summary>
|
/// <summary> Box using self/target coords and </summary>
|
||||||
Box
|
Box
|
||||||
@ -69,14 +70,14 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||||||
class TargetFind
|
class TargetFind
|
||||||
{
|
{
|
||||||
private Character owner;
|
private Character owner;
|
||||||
private Character target;
|
|
||||||
private Character masterTarget; // if target is a pet, this is the owner
|
private Character masterTarget; // if target is a pet, this is the owner
|
||||||
private TargetFindCharacterType findType;
|
private TargetFindCharacterType findType;
|
||||||
private ValidTarget validTarget;
|
private ValidTarget validTarget;
|
||||||
|
private TargetFindAOETarget aoeTarget;
|
||||||
private TargetFindAOEType aoeType;
|
private TargetFindAOEType aoeType;
|
||||||
private Vector3 targetPosition;
|
private Vector3 targetPosition;
|
||||||
private float extents;
|
private float maxDistance;
|
||||||
private float angle;
|
private float param;
|
||||||
private List<Character> targets;
|
private List<Character> targets;
|
||||||
|
|
||||||
public TargetFind(Character owner)
|
public TargetFind(Character owner)
|
||||||
@ -87,13 +88,13 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||||||
|
|
||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
this.target = null;
|
|
||||||
this.findType = TargetFindCharacterType.None;
|
this.findType = TargetFindCharacterType.None;
|
||||||
this.validTarget = ValidTarget.Enemy;
|
this.validTarget = ValidTarget.Enemy;
|
||||||
this.aoeType = TargetFindAOEType.None;
|
this.aoeType = TargetFindAOEType.None;
|
||||||
|
this.aoeTarget = TargetFindAOETarget.Target;
|
||||||
this.targetPosition = null;
|
this.targetPosition = null;
|
||||||
this.extents = 0.0f;
|
this.maxDistance = 0.0f;
|
||||||
this.angle = 0.0f;
|
this.param = 0.0f;
|
||||||
this.targets = new List<Character>();
|
this.targets = new List<Character>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,28 +111,29 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Call this before <see cref="FindWithinArea"/> <para/>
|
/// Call this before <see cref="FindWithinArea"/> <para/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="extents">
|
/// <param name="maxDistance">
|
||||||
/// <see cref="TargetFindAOEType.Circle"/> - radius of circle <para/>
|
/// <see cref="TargetFindAOEType.Circle"/> - radius of circle <para/>
|
||||||
/// <see cref="TargetFindAOEType.Cone"/> - height of cone <para/>
|
/// <see cref="TargetFindAOEType.Cone"/> - height of cone <para/>
|
||||||
/// <see cref="TargetFindAOEType.Box"/> - width of box / 2 (todo: set box length not just between user and target)
|
/// <see cref="TargetFindAOEType.Box"/> - width of box / 2 (todo: set box length not just between user and target)
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <param name="angle"> Angle in radians of cone </param>
|
/// <param name="param"> param in degrees of cone (todo: probably use radians and forget converting at runtime) </param>
|
||||||
public void SetAOEType(ValidTarget validTarget, TargetFindAOEType aoeType, float extents = -1.0f, float angle = -1.0f)
|
public void SetAOEType(ValidTarget validTarget, TargetFindAOEType aoeType, TargetFindAOETarget aoeTarget, float maxDistance = -1.0f, float param = -1.0f)
|
||||||
{
|
{
|
||||||
this.validTarget = validTarget;
|
this.validTarget = validTarget;
|
||||||
this.aoeType = aoeType;
|
this.aoeType = aoeType;
|
||||||
this.extents = extents != -1.0f ? extents : 0.0f;
|
this.maxDistance = maxDistance != -1.0f ? maxDistance : 0.0f;
|
||||||
this.angle = angle != -1.0f ? angle : 0.0f;
|
this.param = param != -1.0f ? param : 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetAOEBox(ValidTarget validTarget, float length, float width)
|
public void SetAOEBox(ValidTarget validTarget, TargetFindAOETarget aoeTarget, float length, float width)
|
||||||
{
|
{
|
||||||
this.validTarget = validTarget;
|
this.validTarget = validTarget;
|
||||||
this.aoeType = TargetFindAOEType.Box;
|
this.aoeType = TargetFindAOEType.Box;
|
||||||
|
this.aoeTarget = aoeTarget;
|
||||||
float x = owner.positionX - (float)Math.Cos(owner.rotation + (float)(Math.PI / 2)) * (length);
|
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);
|
float z = owner.positionZ + (float)Math.Sin(owner.rotation + (float)(Math.PI / 2)) * (length);
|
||||||
this.targetPosition = new Vector3(x, owner.positionY, z);
|
this.targetPosition = new Vector3(x, owner.positionY, z);
|
||||||
this.extents = width;
|
this.maxDistance = width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -140,7 +142,6 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||||||
public void FindTarget(Character target, ValidTarget flags)
|
public void FindTarget(Character target, ValidTarget flags)
|
||||||
{
|
{
|
||||||
validTarget = flags;
|
validTarget = flags;
|
||||||
this.target = null;
|
|
||||||
// todo: maybe this should only be set if successfully added?
|
// todo: maybe this should only be set if successfully added?
|
||||||
this.targetPosition = target.GetPosAsVector3();
|
this.targetPosition = target.GetPosAsVector3();
|
||||||
AddTarget(target, false);
|
AddTarget(target, false);
|
||||||
@ -150,21 +151,18 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||||||
/// <para> Call SetAOEType before calling this </para>
|
/// <para> Call SetAOEType before calling this </para>
|
||||||
/// Find targets within area set by <see cref="SetAOEType"/>
|
/// Find targets within area set by <see cref="SetAOEType"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void FindWithinArea(Character target, ValidTarget flags)
|
public void FindWithinArea(Character target, ValidTarget flags, TargetFindAOETarget aoeTarget)
|
||||||
{
|
{
|
||||||
validTarget = flags;
|
validTarget = flags;
|
||||||
// todo: maybe we should keep a snapshot which is only updated on each tick for consistency
|
// 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
|
// are we creating aoe circles around target or self
|
||||||
if ((aoeType & TargetFindAOEType.Circle) != 0 && validTarget != ValidTarget.Self)
|
if (aoeTarget == TargetFindAOETarget.Self)
|
||||||
this.targetPosition = owner.GetPosAsVector3();
|
this.targetPosition = owner.GetPosAsVector3();
|
||||||
else
|
else
|
||||||
this.targetPosition = target.GetPosAsVector3();
|
this.targetPosition = target.GetPosAsVector3();
|
||||||
|
|
||||||
masterTarget = TryGetMasterTarget(target) ?? target;
|
masterTarget = TryGetMasterTarget(target) ?? target;
|
||||||
|
|
||||||
// todo: should i set this yet or wait til checked if valid target
|
|
||||||
this.target = target;
|
|
||||||
|
|
||||||
// todo: this is stupid
|
// todo: this is stupid
|
||||||
bool withPet = (flags & ValidTarget.Ally) != 0 || masterTarget.allegiance != owner.allegiance;
|
bool withPet = (flags & ValidTarget.Ally) != 0 || masterTarget.allegiance != owner.allegiance;
|
||||||
|
|
||||||
@ -180,7 +178,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||||||
// todo: handle player parties
|
// todo: handle player parties
|
||||||
if (masterTarget.currentParty != null)
|
if (masterTarget.currentParty != null)
|
||||||
{
|
{
|
||||||
if ((validTarget & ValidTarget.Ally) != 0)
|
if ((validTarget & (ValidTarget.Ally | ValidTarget.PartyMember)) != 0)
|
||||||
AddAllInAlliance(masterTarget, withPet);
|
AddAllInAlliance(masterTarget, withPet);
|
||||||
else
|
else
|
||||||
AddAllInParty(masterTarget, withPet);
|
AddAllInParty(masterTarget, withPet);
|
||||||
@ -229,19 +227,24 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Find targets within a box using owner's coordinates and target's coordinates as length
|
/// Find targets within a box using owner's coordinates and target's coordinates as length
|
||||||
/// with corners being `extents` yalms to either side of self and target
|
/// with corners being `maxDistance` yalms to either side of self and target
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private bool IsWithinBox(Character target, bool withPet)
|
private bool IsWithinBox(Character target, bool withPet)
|
||||||
{
|
{
|
||||||
|
if (aoeTarget == TargetFindAOETarget.Self)
|
||||||
|
targetPosition = owner.GetPosAsVector3();
|
||||||
|
else
|
||||||
|
targetPosition = target.GetPosAsVector3();
|
||||||
|
|
||||||
var myPos = owner.GetPosAsVector3();
|
var myPos = owner.GetPosAsVector3();
|
||||||
var angle = Vector3.GetAngle(myPos, targetPosition);
|
var angle = Vector3.GetAngle(myPos, targetPosition);
|
||||||
|
|
||||||
// todo: actually check this works..
|
// todo: actually check this works..
|
||||||
var myCorner = myPos.NewHorizontalVector(angle, extents);
|
var myCorner = myPos.NewHorizontalVector(angle, maxDistance);
|
||||||
var myCorner2 = myPos.NewHorizontalVector(angle, -extents);
|
var myCorner2 = myPos.NewHorizontalVector(angle, -maxDistance);
|
||||||
|
|
||||||
var targetCorner = targetPosition.NewHorizontalVector(angle, extents);
|
var targetCorner = targetPosition.NewHorizontalVector(angle, maxDistance);
|
||||||
var targetCorner2 = targetPosition.NewHorizontalVector(angle, -extents);
|
var targetCorner2 = targetPosition.NewHorizontalVector(angle, -maxDistance);
|
||||||
|
|
||||||
return target.GetPosAsVector3().IsWithinBox(targetCorner2, myCorner);
|
return target.GetPosAsVector3().IsWithinBox(targetCorner2, myCorner);
|
||||||
}
|
}
|
||||||
@ -249,7 +252,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||||||
private bool IsWithinCone(Character target, bool withPet)
|
private bool IsWithinCone(Character target, bool withPet)
|
||||||
{
|
{
|
||||||
// todo: make this actual cone
|
// todo: make this actual cone
|
||||||
return owner.IsFacing(target, angle) && Utils.Distance(owner.positionX, owner.positionY, owner.positionZ, target.positionX, target.positionY, target.positionZ) < extents;
|
return owner.IsFacing(target, param) && Utils.Distance(owner.positionX, owner.positionY, owner.positionZ, target.positionX, target.positionY, target.positionZ) < maxDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddTarget(Character target, bool withPet)
|
private void AddTarget(Character target, bool withPet)
|
||||||
@ -264,25 +267,20 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||||||
private void AddAllInParty(Character target, bool withPet)
|
private void AddAllInParty(Character target, bool withPet)
|
||||||
{
|
{
|
||||||
// todo:
|
// todo:
|
||||||
/*
|
var party = target.currentParty as Party;
|
||||||
* foreach (var actor in target.currentParty.GetMembers())
|
if (party != null)
|
||||||
* {
|
{
|
||||||
* AddTarget(actor, withPet);
|
foreach (var actorId in party.members)
|
||||||
* }
|
{
|
||||||
*/
|
AddTarget(owner.zone.FindActorInArea(actorId) as Character, withPet);
|
||||||
AddTarget(target, withPet);
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddAllInAlliance(Character target, bool withPet)
|
private void AddAllInAlliance(Character target, bool withPet)
|
||||||
{
|
{
|
||||||
// todo:
|
// todo:
|
||||||
/*
|
AddAllInParty(target, withPet);
|
||||||
* foreach (var actor in target.currentParty.GetAllianceMembers())
|
|
||||||
* {
|
|
||||||
* AddTarget(actor, withPet);
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
AddTarget(target, withPet);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddAllBattleNpcs(Character target, bool withPet)
|
private void AddAllBattleNpcs(Character target, bool withPet)
|
||||||
@ -321,7 +319,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CanTarget(Character target, bool withPet = false, bool retarget = false)
|
public bool CanTarget(Character target, bool withPet = false, bool retarget = false, bool ignoreAOE = false)
|
||||||
{
|
{
|
||||||
// already targeted, dont target again
|
// already targeted, dont target again
|
||||||
if (target == null || !retarget && targets.Contains(target))
|
if (target == null || !retarget && targets.Contains(target))
|
||||||
@ -331,21 +329,18 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||||||
if ((validTarget & ValidTarget.Corpse) == 0 && target.IsDead())
|
if ((validTarget & ValidTarget.Corpse) == 0 && target.IsDead())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool targetingPlayer = target.currentSubState == SetActorStatePacket.SUB_STATE_PLAYER;
|
if ((validTarget & ValidTarget.Ally) != 0 && target.allegiance != owner.allegiance)
|
||||||
|
|
||||||
if ((validTarget & ValidTarget.Ally) != 0 && target.currentSubState != owner.currentSubState)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ((validTarget & ValidTarget.Enemy) != 0 && target.currentSubState != (owner.currentSubState == SetActorStatePacket.SUB_STATE_MONSTER ?
|
if ((validTarget & ValidTarget.Enemy) != 0 && target.allegiance == owner.allegiance)
|
||||||
SetActorStatePacket.SUB_STATE_PLAYER : SetActorStatePacket.SUB_STATE_MONSTER))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ((validTarget & ValidTarget.NPC) != 0 && target.currentSubState != SetActorStatePacket.SUB_STATE_NONE)
|
if ((validTarget & ValidTarget.NPC) != 0 && target.isStatic)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// todo: why is player always zoning?
|
// todo: why is player always zoning?
|
||||||
// cant target if zoning
|
// cant target if zoning
|
||||||
if (targetingPlayer && ((Player)target).playerSession.isUpdatesLocked)
|
if (target is Player && ((Player)target).playerSession.isUpdatesLocked)
|
||||||
{
|
{
|
||||||
owner.aiContainer.ChangeTarget(null);
|
owner.aiContainer.ChangeTarget(null);
|
||||||
return false;
|
return false;
|
||||||
@ -354,25 +349,36 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||||||
if (/*target.isZoning || owner.isZoning || */target.zone != owner.zone)
|
if (/*target.isZoning || owner.isZoning || */target.zone != owner.zone)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (validTarget == ValidTarget.Self && aoeType != TargetFindAOEType.None && owner != target)
|
if (validTarget == ValidTarget.Self && aoeType == TargetFindAOEType.None && owner != target)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// this is fuckin retarded, think of a better way l8r
|
||||||
|
if (!ignoreAOE)
|
||||||
|
{
|
||||||
// hit everything within zone or within aoe region
|
// hit everything within zone or within aoe region
|
||||||
if (extents == 255.0f || aoeType == TargetFindAOEType.Circle && target.GetPosAsVector3().IsWithinCircle(targetPosition ?? target.GetPosAsVector3(), extents))
|
if (maxDistance == -1.0f || aoeType == TargetFindAOEType.Circle && !IsWithinCircle(target, maxDistance))
|
||||||
return true;
|
return false;
|
||||||
|
|
||||||
if (aoeType == TargetFindAOEType.Cone && IsWithinCone(target, withPet))
|
if (aoeType == TargetFindAOEType.Cone && !IsWithinCone(target, withPet))
|
||||||
return true;
|
return false;
|
||||||
|
|
||||||
if (aoeType == TargetFindAOEType.Box && IsWithinBox(target, withPet))
|
if (aoeType == TargetFindAOEType.Box && !IsWithinBox(target, withPet))
|
||||||
return true;
|
return false;
|
||||||
|
|
||||||
if (aoeType == TargetFindAOEType.None && targets.Count != 0)
|
if (aoeType == TargetFindAOEType.None && targets.Count != 0)
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool IsWithinCircle(Character target, float maxDistance)
|
||||||
|
{
|
||||||
|
if (this.targetPosition == null)
|
||||||
|
this.targetPosition = aoeTarget == TargetFindAOETarget.Self ? owner.GetPosAsVector3() : masterTarget.GetPosAsVector3();
|
||||||
|
|
||||||
|
return target.GetPosAsVector3().IsWithinCircle(targetPosition, param);
|
||||||
|
}
|
||||||
|
|
||||||
private bool IsPlayer(Character target)
|
private bool IsPlayer(Character target)
|
||||||
{
|
{
|
||||||
if (target is Player)
|
if (target is Player)
|
||||||
@ -397,11 +403,11 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||||||
private bool IsBattleNpcOwner(Character target)
|
private bool IsBattleNpcOwner(Character target)
|
||||||
{
|
{
|
||||||
// i know i copied this from dsp but what even
|
// i know i copied this from dsp but what even
|
||||||
if (owner.currentSubState != SetActorStatePacket.SUB_STATE_PLAYER || target.currentSubState == SetActorStatePacket.SUB_STATE_PLAYER)
|
if (!(owner is Player) || target is Player)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// todo: check hate list
|
// todo: check hate list
|
||||||
if (owner.currentSubState == SetActorStatePacket.SUB_STATE_MONSTER && ((BattleNpc)owner).hateContainer.GetMostHatedTarget() != target)
|
if (owner is BattleNpc && ((BattleNpc)owner).hateContainer.GetMostHatedTarget() != target)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -410,7 +416,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
|||||||
|
|
||||||
public Character GetValidTarget(Character target, ValidTarget findFlags)
|
public Character GetValidTarget(Character target, ValidTarget findFlags)
|
||||||
{
|
{
|
||||||
if (target == null || target.currentSubState == SetActorStatePacket.SUB_STATE_PLAYER && ((Player)target).playerSession.isUpdatesLocked)
|
if (target == null || target is Player && ((Player)target).playerSession.isUpdatesLocked)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if ((findFlags & ValidTarget.Ally) != 0)
|
if ((findFlags & ValidTarget.Ally) != 0)
|
||||||
|
@ -23,6 +23,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
|
|||||||
|
|
||||||
private bool firstSpell = true;
|
private bool firstSpell = true;
|
||||||
private DateTime lastRoamUpdate;
|
private DateTime lastRoamUpdate;
|
||||||
|
private DateTime battleStartTime;
|
||||||
|
|
||||||
private new BattleNpc owner;
|
private new BattleNpc owner;
|
||||||
public BattleNpcController(BattleNpc owner) :
|
public BattleNpcController(BattleNpc owner) :
|
||||||
@ -65,6 +66,8 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
|
|||||||
var canEngage = this.owner.aiContainer.InternalEngage(target);
|
var canEngage = this.owner.aiContainer.InternalEngage(target);
|
||||||
if (canEngage)
|
if (canEngage)
|
||||||
{
|
{
|
||||||
|
//owner.ChangeState(SetActorStatePacket.MAIN_STATE_ACTIVE);
|
||||||
|
|
||||||
// reset casting
|
// reset casting
|
||||||
firstSpell = true;
|
firstSpell = true;
|
||||||
// todo: find a better place to put this?
|
// todo: find a better place to put this?
|
||||||
@ -77,6 +80,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
|
|||||||
// owner.ResetMoveSpeeds();
|
// owner.ResetMoveSpeeds();
|
||||||
owner.moveState = 2;
|
owner.moveState = 2;
|
||||||
lastActionTime = DateTime.Now;
|
lastActionTime = DateTime.Now;
|
||||||
|
battleStartTime = lastActionTime;
|
||||||
// todo: adjust cooldowns with modifiers
|
// todo: adjust cooldowns with modifiers
|
||||||
}
|
}
|
||||||
return canEngage;
|
return canEngage;
|
||||||
@ -100,7 +104,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
|
|||||||
neutralTime = lastActionTime;
|
neutralTime = lastActionTime;
|
||||||
owner.hateContainer.ClearHate();
|
owner.hateContainer.ClearHate();
|
||||||
owner.moveState = 1;
|
owner.moveState = 1;
|
||||||
lua.LuaEngine.CallLuaBattleAction(owner, "onDisengage", owner, target);
|
lua.LuaEngine.CallLuaBattleAction(owner, "onDisengage", owner, target, Utils.UnixTimeStampUTC(battleStartTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Cast(Character target, uint spellId)
|
public override void Cast(Character target, uint spellId)
|
||||||
@ -199,6 +203,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
Move();
|
Move();
|
||||||
|
lua.LuaEngine.CallLuaBattleAction(owner, "onCombatTick", owner, owner.target, Utils.UnixTimeStampUTC());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Move()
|
private void Move()
|
||||||
@ -230,7 +235,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
|
|||||||
owner.aiContainer.pathFind.FollowPath();
|
owner.aiContainer.pathFind.FollowPath();
|
||||||
if (!owner.aiContainer.pathFind.IsFollowingPath())
|
if (!owner.aiContainer.pathFind.IsFollowingPath())
|
||||||
{
|
{
|
||||||
if (owner.target.currentSubState == SetActorStatePacket.SUB_STATE_PLAYER)
|
if (owner.target is Player)
|
||||||
{
|
{
|
||||||
foreach (var chara in owner.zone.GetActorsAroundActor<Character>(owner, 1))
|
foreach (var chara in owner.zone.GetActorsAroundActor<Character>(owner, 1))
|
||||||
{
|
{
|
||||||
@ -355,5 +360,13 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
|
|||||||
{
|
{
|
||||||
ChangeTarget(owner.hateContainer.GetMostHatedTarget());
|
ChangeTarget(owner.hateContainer.GetMostHatedTarget());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void ChangeTarget(Character target)
|
||||||
|
{
|
||||||
|
owner.target = target;
|
||||||
|
owner.currentLockedTarget = target != null ? target.actorId : 0xC0000000;
|
||||||
|
owner.currentTarget = target != null ? target.actorId : 0xC0000000;
|
||||||
|
base.ChangeTarget(target);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,19 +11,35 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
|
|||||||
{
|
{
|
||||||
class PlayerController : Controller
|
class PlayerController : Controller
|
||||||
{
|
{
|
||||||
public PlayerController(Character owner) :
|
private new Player owner;
|
||||||
|
public PlayerController(Player owner) :
|
||||||
base(owner)
|
base(owner)
|
||||||
{
|
{
|
||||||
|
this.owner = owner;
|
||||||
this.lastUpdate = DateTime.Now;
|
this.lastUpdate = DateTime.Now;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update(DateTime tick)
|
public override void Update(DateTime tick)
|
||||||
{
|
{
|
||||||
// todo: handle player stuff on tick
|
// todo: handle player stuff on tick
|
||||||
|
if (owner.newMainState != owner.currentMainState)
|
||||||
|
{
|
||||||
|
//owner.updateFlags = ActorUpdateFlags.Combat;
|
||||||
|
if (owner.newMainState == SetActorStatePacket.MAIN_STATE_ACTIVE)
|
||||||
|
{
|
||||||
|
owner.Engage();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
owner.Disengage();
|
||||||
|
}
|
||||||
|
owner.currentMainState = (ushort)owner.newMainState;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ChangeTarget(Character target)
|
public override void ChangeTarget(Character target)
|
||||||
{
|
{
|
||||||
|
owner.target = target;
|
||||||
base.ChangeTarget(target);
|
base.ChangeTarget(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,21 +48,12 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
|
|||||||
var canEngage = this.owner.aiContainer.InternalEngage(target);
|
var canEngage = this.owner.aiContainer.InternalEngage(target);
|
||||||
if (canEngage)
|
if (canEngage)
|
||||||
{
|
{
|
||||||
// todo: find a better place to put this?
|
|
||||||
if (owner.GetState() != SetActorStatePacket.MAIN_STATE_ACTIVE)
|
|
||||||
owner.ChangeState(SetActorStatePacket.MAIN_STATE_ACTIVE);
|
|
||||||
|
|
||||||
|
|
||||||
// todo: check speed/is able to move
|
// todo: check speed/is able to move
|
||||||
// todo: too far, path to player if mob, message if player
|
// todo: too far, path to player if mob, message if player
|
||||||
|
if (owner.statusEffects.HasStatusEffect(StatusEffectId.Sleep))
|
||||||
// todo: actual stat based range
|
|
||||||
if (Utils.Distance(owner.positionX, owner.positionY, owner.positionZ, target.positionX, target.positionY, target.positionZ) > 10)
|
|
||||||
{
|
{
|
||||||
{
|
// That command cannot be performed.
|
||||||
// todo: out of range error
|
owner.SendGameMessage(Server.GetWorldManager().GetActor(), 32553, 0x20);
|
||||||
}
|
|
||||||
ChangeTarget(target);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// todo: adjust cooldowns with modifiers
|
// todo: adjust cooldowns with modifiers
|
||||||
|
@ -20,7 +20,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
|||||||
this.startTime = DateTime.Now;
|
this.startTime = DateTime.Now;
|
||||||
|
|
||||||
owner.ChangeState(SetActorStatePacket.MAIN_STATE_ACTIVE);
|
owner.ChangeState(SetActorStatePacket.MAIN_STATE_ACTIVE);
|
||||||
owner.aiContainer.ChangeTarget(target);
|
ChangeTarget(target);
|
||||||
attackTime = startTime;
|
attackTime = startTime;
|
||||||
owner.aiContainer.pathFind?.Clear();
|
owner.aiContainer.pathFind?.Clear();
|
||||||
// todo: should handle everything here instead of on next tick..
|
// todo: should handle everything here instead of on next tick..
|
||||||
@ -42,12 +42,13 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
if (target == null || owner.target != target || owner.target?.actorId != owner.currentLockedTarget)
|
|
||||||
owner.aiContainer.ChangeTarget(target = owner.zone.FindActorInArea(owner.currentLockedTarget == 0xC0000000 ? owner.currentTarget : owner.currentLockedTarget) as Character);
|
if ((target == null || owner.target != target || owner.target?.actorId != owner.currentLockedTarget) && owner.isAutoAttackEnabled)
|
||||||
|
owner.aiContainer.ChangeTarget(target = owner.zone.FindActorInArea<Character>(owner.currentLockedTarget));
|
||||||
|
|
||||||
if (target == null || target.IsDead())
|
if (target == null || target.IsDead())
|
||||||
{
|
{
|
||||||
if (owner.currentSubState == SetActorStatePacket.SUB_STATE_MONSTER)
|
if (owner is BattleNpc)
|
||||||
target = ((BattleNpc)owner).hateContainer.GetMostHatedTarget();
|
target = ((BattleNpc)owner).hateContainer.GetMostHatedTarget();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -110,7 +111,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
|||||||
|
|
||||||
owner.OnAttack(this, action, ref errorResult);
|
owner.OnAttack(this, action, ref errorResult);
|
||||||
// handle paralyze/intimidate/sleep/whatever in character thing
|
// handle paralyze/intimidate/sleep/whatever in character thing
|
||||||
owner.DoBattleAction((ushort)BattleActionX01PacketCommand.Attack, 0x19001000, errorResult == null ? action : errorResult);
|
owner.DoBattleAction((ushort)BattleActionX01PacketCommand.Attack, action.animation, errorResult == null ? action : errorResult);
|
||||||
|
|
||||||
//this.errorPacket = BattleActionX01Packet.BuildPacket(target.actorId, owner.actorId, target.actorId, 0, effectId, 0, (ushort)BattleActionX01PacketCommand.Attack, (ushort)damage, 0);
|
//this.errorPacket = BattleActionX01Packet.BuildPacket(target.actorId, owner.actorId, target.actorId, 0, effectId, 0, (ushort)BattleActionX01PacketCommand.Attack, (ushort)damage, 0);
|
||||||
}
|
}
|
||||||
@ -140,11 +141,17 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
|||||||
|
|
||||||
private bool IsAttackReady()
|
private bool IsAttackReady()
|
||||||
{
|
{
|
||||||
return Program.Tick >= attackTime;
|
// todo: this enforced delay should really be changed if it's not retail..
|
||||||
|
return Program.Tick >= attackTime && Program.Tick >= owner.aiContainer.GetLastActionTime().AddSeconds(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool CanAttack()
|
private bool CanAttack()
|
||||||
{
|
{
|
||||||
|
if (!owner.isAutoAttackEnabled)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (target == null)
|
if (target == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -162,7 +169,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
|||||||
// todo: use a mod for melee range
|
// todo: use a mod for melee range
|
||||||
else if (Utils.Distance(owner.positionX, owner.positionY, owner.positionZ, target.positionX, target.positionY, target.positionZ) > owner.GetAttackRange())
|
else if (Utils.Distance(owner.positionX, owner.positionY, owner.positionZ, target.positionX, target.positionY, target.positionZ) > owner.GetAttackRange())
|
||||||
{
|
{
|
||||||
if (owner.currentSubState == SetActorStatePacket.SUB_STATE_PLAYER)
|
if (owner is Player)
|
||||||
{
|
{
|
||||||
((Player)owner).SendGameMessage(Server.GetWorldManager().GetActor(), 32539, 0x20);
|
((Player)owner).SendGameMessage(Server.GetWorldManager().GetActor(), 32539, 0x20);
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
|||||||
: base(owner, null)
|
: base(owner, null)
|
||||||
{
|
{
|
||||||
owner.ChangeState(SetActorStatePacket.MAIN_STATE_DEAD);
|
owner.ChangeState(SetActorStatePacket.MAIN_STATE_DEAD);
|
||||||
|
owner.Disengage();
|
||||||
canInterrupt = false;
|
canInterrupt = false;
|
||||||
startTime = tick;
|
startTime = tick;
|
||||||
despawnTime = startTime.AddSeconds(timeToFadeOut);
|
despawnTime = startTime.AddSeconds(timeToFadeOut);
|
||||||
@ -25,7 +26,14 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
|||||||
// todo: handle raise etc
|
// todo: handle raise etc
|
||||||
if (tick >= despawnTime)
|
if (tick >= despawnTime)
|
||||||
{
|
{
|
||||||
owner.Spawn(Program.Tick);
|
if (owner is BattleNpc)
|
||||||
|
{
|
||||||
|
owner.Despawn(tick);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// todo: queue a warp for the player
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
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.packets.send.actor;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
||||||
|
{
|
||||||
|
class DespawnState : State
|
||||||
|
{
|
||||||
|
private DateTime endTime;
|
||||||
|
public DespawnState(Character owner, Character target, uint despawnTimeSeconds) :
|
||||||
|
base(owner, null)
|
||||||
|
{
|
||||||
|
startTime = Program.Tick;
|
||||||
|
endTime = startTime.AddSeconds(despawnTimeSeconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Update(DateTime tick)
|
||||||
|
{
|
||||||
|
if (tick >= endTime)
|
||||||
|
{
|
||||||
|
// todo: send packet to despawn the npc, set it so npc is despawned when requesting spawn packets
|
||||||
|
owner.zone.BroadcastPacketAroundActor(owner, RemoveActorPacket.BuildPacket(owner.actorId));
|
||||||
|
owner.QueuePositionUpdate(owner.spawnX, owner.spawnY, owner.spawnZ);
|
||||||
|
lua.LuaEngine.CallLuaBattleAction(owner, "onDespawn", owner);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -57,15 +57,14 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
|||||||
float spellSpeed = spell.castTimeSeconds;
|
float spellSpeed = spell.castTimeSeconds;
|
||||||
|
|
||||||
// command casting duration
|
// command casting duration
|
||||||
if (owner.currentSubState == SetActorStatePacket.SUB_STATE_PLAYER)
|
if (owner is Player)
|
||||||
{
|
{
|
||||||
// todo: modify spellSpeed based on modifiers and stuff
|
// todo: modify spellSpeed based on modifiers and stuff
|
||||||
((Player)owner).SendStartCastbar(spell.id, Utils.UnixTimeStampUTC(DateTime.Now.AddSeconds(spellSpeed)));
|
((Player)owner).SendStartCastbar(spell.id, Utils.UnixTimeStampUTC(DateTime.Now.AddSeconds(spellSpeed)));
|
||||||
|
}
|
||||||
owner.SendChant(0xF, 0x0);
|
owner.SendChant(0xF, 0x0);
|
||||||
owner.DoBattleAction(spell.id, 0x6F000002, new BattleAction(target.actorId, 30128, 1, 0, 1)); //You begin casting (6F000002: BLM, 6F000003: WHM)
|
owner.DoBattleAction(spell.id, 0x6F000002, new BattleAction(target.actorId, 30128, 1, 0, 1)); //You begin casting (6F000002: BLM, 6F000003: WHM)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Update(DateTime tick)
|
public override bool Update(DateTime tick)
|
||||||
@ -106,7 +105,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
|||||||
|
|
||||||
public override void OnComplete()
|
public override void OnComplete()
|
||||||
{
|
{
|
||||||
spell.targetFind.FindWithinArea(target, spell.validTarget);
|
spell.targetFind.FindWithinArea(target, spell.validTarget, spell.aoeTarget);
|
||||||
isCompleted = true;
|
isCompleted = true;
|
||||||
|
|
||||||
var targets = spell.targetFind.GetTargets();
|
var targets = spell.targetFind.GetTargets();
|
||||||
@ -119,7 +118,10 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
|||||||
actions[i++] = action;
|
actions[i++] = action;
|
||||||
}
|
}
|
||||||
|
|
||||||
owner.SendChant(0, 0);
|
// todo: this is fuckin stupid, probably only need *one* error packet, not an error for each action
|
||||||
|
var errors = (BattleAction[])actions.Clone();
|
||||||
|
|
||||||
|
owner.OnCast(this, actions, ref errors);
|
||||||
owner.DoBattleAction(spell.id, spell.battleAnimation, actions);
|
owner.DoBattleAction(spell.id, spell.battleAnimation, actions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,10 +140,6 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
|||||||
// todo: actually check proc rate/random chance of whatever effect
|
// todo: actually check proc rate/random chance of whatever effect
|
||||||
effectId = list[0].GetStatusEffectId();
|
effectId = list[0].GetStatusEffectId();
|
||||||
}
|
}
|
||||||
// todo: which is actually the swing packet
|
|
||||||
//this.errorPacket = BattleActionX01Packet.BuildPacket(target.actorId, owner.actorId, target.actorId, 0, effectId, 0, (ushort)BattleActionX01PacketCommand.Attack, (ushort)damage, 0);
|
|
||||||
//owner.zone.BroadcastPacketAroundActor(owner, errorPacket);
|
|
||||||
//errorPacket = null;
|
|
||||||
interrupt = true;
|
interrupt = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -159,7 +157,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
|||||||
|
|
||||||
private bool CanCast()
|
private bool CanCast()
|
||||||
{
|
{
|
||||||
return owner.CanCast(target, spell) && !HasMoved();
|
return owner.CanCast(target, spell) && spell.IsValidTarget(owner, target) && !HasMoved();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool HasMoved()
|
private bool HasMoved()
|
||||||
@ -169,13 +167,13 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
|||||||
|
|
||||||
public override void Cleanup()
|
public override void Cleanup()
|
||||||
{
|
{
|
||||||
if (owner.currentSubState == SetActorStatePacket.SUB_STATE_PLAYER)
|
owner.SendChant(0, 0);
|
||||||
|
|
||||||
|
if (owner is Player)
|
||||||
{
|
{
|
||||||
((Player)owner).SendEndCastbar();
|
((Player)owner).SendEndCastbar();
|
||||||
}
|
}
|
||||||
// command casting duration
|
owner.aiContainer.UpdateLastActionTime();
|
||||||
//var packets = new List<SubPacket>();
|
|
||||||
//owner.zone.BroadcastPacketsAroundActor(owner, packets);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public BattleCommand GetSpell()
|
public BattleCommand GetSpell()
|
||||||
|
@ -90,7 +90,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
|||||||
|
|
||||||
public override void OnComplete()
|
public override void OnComplete()
|
||||||
{
|
{
|
||||||
skill.targetFind.FindWithinArea(target, skill.validTarget);
|
skill.targetFind.FindWithinArea(target, skill.validTarget, skill.aoeTarget);
|
||||||
isCompleted = true;
|
isCompleted = true;
|
||||||
|
|
||||||
var targets = skill.targetFind.GetTargets();
|
var targets = skill.targetFind.GetTargets();
|
||||||
@ -104,10 +104,12 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
|||||||
// evasion, miss, dodge, etc to be handled in script, calling helpers from scripts/weaponskills.lua
|
// evasion, miss, dodge, etc to be handled in script, calling helpers from scripts/weaponskills.lua
|
||||||
action.amount = (ushort)lua.LuaEngine.CallLuaBattleCommandFunction(owner, skill, "weaponskill", "onSkillFinish", owner, target, skill, action);
|
action.amount = (ushort)lua.LuaEngine.CallLuaBattleCommandFunction(owner, skill, "weaponskill", "onSkillFinish", owner, target, skill, action);
|
||||||
actions[i++] = action;
|
actions[i++] = action;
|
||||||
|
|
||||||
//packets.Add(BattleActionX01Packet.BuildPacket(chara.actorId, owner.actorId, action.targetId, skill.battleAnimation, action.effectId, action.worldMasterTextId, skill.id, action.amount, action.param));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo: this is fuckin stupid, probably only need *one* error packet, not an error for each action
|
||||||
|
var errors = (BattleAction[])actions.Clone();
|
||||||
|
|
||||||
|
owner.OnWeaponSkill(this, actions, ref errors);
|
||||||
owner.DoBattleAction(skill.id, 0, actions);
|
owner.DoBattleAction(skill.id, 0, actions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,10 +128,6 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
|||||||
// todo: actually check proc rate/random chance of whatever effect
|
// todo: actually check proc rate/random chance of whatever effect
|
||||||
effectId = list[0].GetStatusEffectId();
|
effectId = list[0].GetStatusEffectId();
|
||||||
}
|
}
|
||||||
// todo: which is actually the swing packet
|
|
||||||
//this.errorPacket = BattleActionX01Packet.BuildPacket(target.actorId, owner.actorId, target.actorId, 0, effectId, 0, (ushort)BattleActionX01PacketCommand.Attack, (ushort)damage, 0);
|
|
||||||
//owner.zone.BroadcastPacketAroundActor(owner, errorPacket);
|
|
||||||
//errorPacket = null;
|
|
||||||
interrupt = true;
|
interrupt = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -139,12 +137,17 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
|||||||
|
|
||||||
private bool CanUse()
|
private bool CanUse()
|
||||||
{
|
{
|
||||||
return owner.CanWeaponSkill(target, skill);
|
return owner.CanWeaponSkill(target, skill) && skill.IsValidTarget(owner, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BattleCommand GetWeaponSkill()
|
public BattleCommand GetWeaponSkill()
|
||||||
{
|
{
|
||||||
return skill;
|
return skill;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Cleanup()
|
||||||
|
{
|
||||||
|
owner.aiContainer.UpdateLastActionTime();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.utils
|
|||||||
var scaledCost = spell.CalculateCost((uint)caster.charaWork.parameterSave.state_mainSkillLevel);
|
var scaledCost = spell.CalculateCost((uint)caster.charaWork.parameterSave.state_mainSkillLevel);
|
||||||
|
|
||||||
// todo: calculate cost for mob/player
|
// todo: calculate cost for mob/player
|
||||||
if (caster.currentSubState == SetActorStatePacket.SUB_STATE_MONSTER)
|
if (caster is BattleNpc)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
private uint despawnTime;
|
private uint despawnTime;
|
||||||
private uint spawnDistance;
|
private uint spawnDistance;
|
||||||
|
|
||||||
public float spawnX, spawnY, spawnZ;
|
|
||||||
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)
|
||||||
@ -174,6 +174,13 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Despawn(DateTime tick)
|
||||||
|
{
|
||||||
|
aiContainer.ClearStates();
|
||||||
|
// todo: probably didnt need to make a new state...
|
||||||
|
aiContainer.ForceChangeState(new DespawnState(this, null, 0));
|
||||||
|
}
|
||||||
|
|
||||||
public void OnRoam(DateTime tick)
|
public void OnRoam(DateTime tick)
|
||||||
{
|
{
|
||||||
// todo: move this to battlenpccontroller..
|
// todo: move this to battlenpccontroller..
|
||||||
@ -207,6 +214,8 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
public override void OnAttack(State state, BattleAction action, ref BattleAction error)
|
public override void OnAttack(State state, BattleAction action, ref BattleAction error)
|
||||||
{
|
{
|
||||||
base.OnAttack(state, action, ref error);
|
base.OnAttack(state, action, ref error);
|
||||||
|
// todo: move this somewhere else prolly and change based on model/appearance (so maybe in Character.cs instead)
|
||||||
|
action.animation = 0x11001000; // (temporary) wolf anim
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1757,13 +1757,23 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
{
|
{
|
||||||
// todo: should probably add another flag for battleTemp since all this uses reflection
|
// todo: should probably add another flag for battleTemp since all this uses reflection
|
||||||
packets = new List<SubPacket>();
|
packets = new List<SubPacket>();
|
||||||
|
|
||||||
|
// we only want the latest update for the player
|
||||||
|
if ((updateFlags & ActorUpdateFlags.Position) != 0)
|
||||||
|
{
|
||||||
|
if (positionUpdates.Count > 1)
|
||||||
|
positionUpdates.RemoveRange(1, positionUpdates.Count - 1);
|
||||||
|
}
|
||||||
|
|
||||||
if ((updateFlags & ActorUpdateFlags.HpTpMp) != 0)
|
if ((updateFlags & ActorUpdateFlags.HpTpMp) != 0)
|
||||||
{
|
{
|
||||||
var propPacketUtil = new ActorPropertyPacketUtil("charaWork.parameterSave", this);
|
var propPacketUtil = new ActorPropertyPacketUtil("charaWork.parameterSave", this);
|
||||||
|
|
||||||
propPacketUtil.AddProperty($"charaWork.parameterSave.hp[{currentJob}]");
|
// todo: should this be using job as index?
|
||||||
propPacketUtil.AddProperty($"charaWork.parameterSave.hpMax[{currentJob}]");
|
propPacketUtil.AddProperty($"charaWork.parameterSave.hp[{0}]");
|
||||||
propPacketUtil.AddProperty($"charaWork.parameterSave.state_mainSkill[{currentJob}]");
|
propPacketUtil.AddProperty($"charaWork.parameterSave.hpMax[{0}]");
|
||||||
|
propPacketUtil.AddProperty($"charaWork.parameterSave.state_mainSkill[{0}]");
|
||||||
|
propPacketUtil.AddProperty($"charaWork.parameterSave.state_mainSkillLevel");
|
||||||
|
|
||||||
packets.AddRange(propPacketUtil.Done());
|
packets.AddRange(propPacketUtil.Done());
|
||||||
}
|
}
|
||||||
@ -1937,6 +1947,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
//If the returned value is outside the hotbar, it indicates it wasn't found.
|
//If the returned value is outside the hotbar, it indicates it wasn't found.
|
||||||
private ushort FindFirstCommandSlotById(uint commandId)
|
private ushort FindFirstCommandSlotById(uint commandId)
|
||||||
{
|
{
|
||||||
|
commandId |= 0xA0F00000;
|
||||||
ushort firstSlot = (ushort)(charaWork.commandBorder + 30);
|
ushort firstSlot = (ushort)(charaWork.commandBorder + 30);
|
||||||
|
|
||||||
for (ushort i = charaWork.commandBorder; i < charaWork.commandBorder + 30; i++)
|
for (ushort i = charaWork.commandBorder; i < charaWork.commandBorder + 30; i++)
|
||||||
@ -1951,12 +1962,50 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
return firstSlot;
|
return firstSlot;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
private void UpdateHotbarTimer(uint commandId, uint recastTimeSeconds)
|
||||||
public void SendBattleActionX01Packet(uint anim, uint effect, uint text = 0x756D, uint command = 27260, uint param = 0x01, uint idek = 0x01)
|
|
||||||
{
|
{
|
||||||
var packet = BattleActionX01Packet.BuildPacket(actorId, actorId, currentTarget != 0xC0000000 ? currentTarget : currentLockedTarget, (uint)anim, (uint)effect, (ushort)text, (ushort)command, (ushort)param, (byte)idek);
|
ushort slot = FindFirstCommandSlotById(commandId);
|
||||||
QueuePacket(packet);
|
charaWork.parameterSave.commandSlot_recastTime[slot - charaWork.commandBorder] = Utils.UnixTimeStampUTC(DateTime.Now.AddSeconds(recastTimeSeconds));
|
||||||
}*/
|
var slots = new List<ushort>();
|
||||||
|
slots.Add(slot);
|
||||||
|
UpdateRecastTimers(slots);
|
||||||
|
}
|
||||||
|
|
||||||
|
private uint GetHotbarTimer(uint commandId)
|
||||||
|
{
|
||||||
|
ushort slot = FindFirstCommandSlotById(commandId);
|
||||||
|
return charaWork.parameterSave.commandSlot_recastTime[slot - charaWork.commandBorder];
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Cast(uint spellId, uint targetId = 0)
|
||||||
|
{
|
||||||
|
if (aiContainer.CanChangeState())
|
||||||
|
aiContainer.Cast(zone.FindActorInArea<Character>(targetId == 0 ? currentTarget : targetId), spellId);
|
||||||
|
else if (aiContainer.GetCurrentState() is MagicState)
|
||||||
|
// You are already casting.
|
||||||
|
SendGameMessage(Server.GetWorldManager().GetActor(), 32536, 0x20);
|
||||||
|
else
|
||||||
|
// Please wait a moment and try again.
|
||||||
|
SendGameMessage(Server.GetWorldManager().GetActor(), 32535, 0x20);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Ability(uint abilityId, uint targetId = 0)
|
||||||
|
{
|
||||||
|
if (aiContainer.CanChangeState())
|
||||||
|
aiContainer.Ability(zone.FindActorInArea<Character>(targetId == 0 ? currentTarget : targetId), abilityId);
|
||||||
|
else
|
||||||
|
// Please wait a moment and try again.
|
||||||
|
SendGameMessage(Server.GetWorldManager().GetActor(), 32535, 0x20);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WeaponSkill(uint skillId, uint targetId = 0)
|
||||||
|
{
|
||||||
|
if (aiContainer.CanChangeState())
|
||||||
|
aiContainer.WeaponSkill(zone.FindActorInArea<Character>(targetId == 0 ? currentTarget : targetId), skillId);
|
||||||
|
else
|
||||||
|
// Please wait a moment and try again.
|
||||||
|
SendGameMessage(Server.GetWorldManager().GetActor(), 32535, 0x20);
|
||||||
|
}
|
||||||
|
|
||||||
public override bool IsValidTarget(Character target, ValidTarget validTarget)
|
public override bool IsValidTarget(Character target, ValidTarget validTarget)
|
||||||
{
|
{
|
||||||
@ -1977,7 +2026,8 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
// enemy only
|
// enemy only
|
||||||
if ((validTarget & ValidTarget.Enemy) != 0)
|
if ((validTarget & ValidTarget.Enemy) != 0)
|
||||||
{
|
{
|
||||||
if (target.currentSubState == SetActorStatePacket.SUB_STATE_NONE)
|
// todo: this seems ambiguous
|
||||||
|
if (target.isStatic)
|
||||||
{
|
{
|
||||||
// That command cannot be performed on the current target.
|
// That command cannot be performed on the current target.
|
||||||
SendGameMessage(Server.GetWorldManager().GetActor(), 32547, 0x20);
|
SendGameMessage(Server.GetWorldManager().GetActor(), 32547, 0x20);
|
||||||
@ -1990,7 +2040,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// todo: pvp?
|
// todo: pvp?
|
||||||
if (target.currentSubState == currentSubState)
|
if (target.allegiance == allegiance)
|
||||||
{
|
{
|
||||||
// That command cannot be performed on an ally.
|
// That command cannot be performed on an ally.
|
||||||
SendGameMessage(Server.GetWorldManager().GetActor(), 32549, 0x20);
|
SendGameMessage(Server.GetWorldManager().GetActor(), 32549, 0x20);
|
||||||
@ -1998,14 +2048,15 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((validTarget & ValidTarget.Ally) != 0 && target.currentSubState != currentSubState)
|
if ((validTarget & ValidTarget.Ally) != 0 && target.allegiance != allegiance)
|
||||||
{
|
{
|
||||||
// That command cannot be performed on the current target.
|
// That command cannot be performed on the current target.
|
||||||
SendGameMessage(Server.GetWorldManager().GetActor(), 32547, 0x20);
|
SendGameMessage(Server.GetWorldManager().GetActor(), 32547, 0x20);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((validTarget & ValidTarget.NPC) != 0 && target.currentSubState == SetActorStatePacket.SUB_STATE_NONE)
|
// todo: isStatic seems ambiguous?
|
||||||
|
if ((validTarget & ValidTarget.NPC) != 0 && target.isStatic)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// todo: why is player always zoning?
|
// todo: why is player always zoning?
|
||||||
@ -2022,7 +2073,13 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
|
|
||||||
public override bool CanCast(Character target, BattleCommand spell)
|
public override bool CanCast(Character target, BattleCommand spell)
|
||||||
{
|
{
|
||||||
// todo: move the ability specific stuff to ability.cs
|
if (GetHotbarTimer(spell.id) > Utils.UnixTimeStampUTC())
|
||||||
|
{
|
||||||
|
// todo: this needs confirming
|
||||||
|
// Please wait a moment and try again.
|
||||||
|
SendGameMessage(Server.GetWorldManager().GetActor(), 32535, 0x20, (uint)spell.id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (target == null)
|
if (target == null)
|
||||||
{
|
{
|
||||||
// Target does not exist.
|
// Target does not exist.
|
||||||
@ -2046,6 +2103,13 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
public override bool CanWeaponSkill(Character target, BattleCommand skill)
|
public override bool CanWeaponSkill(Character target, BattleCommand skill)
|
||||||
{
|
{
|
||||||
// todo: see worldmaster ids 32558~32557 for proper ko message and stuff
|
// todo: see worldmaster ids 32558~32557 for proper ko message and stuff
|
||||||
|
if (GetHotbarTimer(skill.id) > Utils.UnixTimeStampUTC())
|
||||||
|
{
|
||||||
|
// todo: this needs confirming
|
||||||
|
// Please wait a moment and try again.
|
||||||
|
SendGameMessage(Server.GetWorldManager().GetActor(), 32535, 0x20, (uint)skill.id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (target == null)
|
if (target == null)
|
||||||
{
|
{
|
||||||
// Target does not exist.
|
// Target does not exist.
|
||||||
@ -2069,7 +2133,8 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
public override void OnAttack(State state, BattleAction action, ref BattleAction error)
|
public override void OnAttack(State state, BattleAction action, ref BattleAction error)
|
||||||
{
|
{
|
||||||
base.OnAttack(state, action, ref error);
|
base.OnAttack(state, action, ref error);
|
||||||
|
// todo: switch based on main weap (also probably move this anim assignment somewhere else)
|
||||||
|
action.animation = 0x19001000;
|
||||||
if (error == null)
|
if (error == null)
|
||||||
{
|
{
|
||||||
// melee attack animation
|
// melee attack animation
|
||||||
@ -2081,5 +2146,24 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
((BattleNpc)target).hateContainer.UpdateHate(this, action.amount);
|
((BattleNpc)target).hateContainer.UpdateHate(this, action.amount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnCast(State state, BattleAction[] actions, ref BattleAction[] errors)
|
||||||
|
{
|
||||||
|
// todo: update hotbar timers to skill's recast time (also needs to be done on class change or equip crap)
|
||||||
|
base.OnCast(state, actions, ref errors);
|
||||||
|
var spell = ((MagicState)state).GetSpell();
|
||||||
|
// todo: should just make a thing that updates the one slot cause this is dumb as hell
|
||||||
|
|
||||||
|
UpdateHotbarTimer(spell.id, spell.recastTimeSeconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnWeaponSkill(State state, BattleAction[] actions, ref BattleAction[] errors)
|
||||||
|
{
|
||||||
|
// todo: update hotbar timers to skill's recast time (also needs to be done on class change or equip crap)
|
||||||
|
base.OnWeaponSkill(state, actions, ref errors);
|
||||||
|
var skill = ((WeaponSkillState)state).GetWeaponSkill();
|
||||||
|
// todo: should just make a thing that updates the one slot cause this is dumb as hell
|
||||||
|
UpdateHotbarTimer(skill.id, skill.recastTimeSeconds);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
|||||||
playerActor.rotation = rot;
|
playerActor.rotation = rot;
|
||||||
playerActor.moveState = moveState;
|
playerActor.moveState = moveState;
|
||||||
|
|
||||||
GetActor().GetZone().UpdateActorPosition(GetActor());
|
//GetActor().GetZone().UpdateActorPosition(GetActor());
|
||||||
playerActor.QueuePositionUpdate(new Vector3(x,y,z));
|
playerActor.QueuePositionUpdate(new Vector3(x,y,z));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,12 +10,10 @@ Switches between active and passive mode states
|
|||||||
|
|
||||||
function onEventStarted(player, command, triggerName)
|
function onEventStarted(player, command, triggerName)
|
||||||
|
|
||||||
if (player:GetState() == 0) then
|
if (player.newMainState == 0x0000) then
|
||||||
player.ChangeState(2);
|
player.Engage(0, 0x0002);
|
||||||
player.Engage();
|
elseif (player.newMainState == 0x0002) then
|
||||||
elseif (player:GetState() == 2) then
|
player.Disengage(0x0000);
|
||||||
player:ChangeState(0);
|
|
||||||
player.Disengage();
|
|
||||||
end
|
end
|
||||||
player:endEvent();
|
player:endEvent();
|
||||||
sendSignal("playerActive");
|
sendSignal("playerActive");
|
||||||
|
@ -30,6 +30,8 @@ CREATE TABLE `server_battle_commands` (
|
|||||||
`requirements` smallint(5) unsigned NOT NULL,
|
`requirements` smallint(5) unsigned NOT NULL,
|
||||||
`validTarget` tinyint(3) unsigned NOT NULL,
|
`validTarget` tinyint(3) unsigned NOT NULL,
|
||||||
`aoeType` tinyint(3) unsigned NOT NULL,
|
`aoeType` tinyint(3) unsigned NOT NULL,
|
||||||
|
`aoeRange` int(10) NOT NULL DEFAULT '0',
|
||||||
|
`aoeTarget` tinyint(3) NOT NULL,
|
||||||
`numHits` tinyint(3) unsigned NOT NULL,
|
`numHits` tinyint(3) unsigned NOT NULL,
|
||||||
`positionBonus` tinyint(3) unsigned NOT NULL,
|
`positionBonus` tinyint(3) unsigned NOT NULL,
|
||||||
`procRequirement` tinyint(3) unsigned NOT NULL,
|
`procRequirement` tinyint(3) unsigned NOT NULL,
|
||||||
@ -45,7 +47,7 @@ CREATE TABLE `server_battle_commands` (
|
|||||||
`effectAnimation` smallint(5) unsigned NOT NULL,
|
`effectAnimation` smallint(5) unsigned NOT NULL,
|
||||||
`modelAnimation` smallint(5) unsigned NOT NULL,
|
`modelAnimation` smallint(5) unsigned NOT NULL,
|
||||||
`animationDuration` smallint(5) unsigned NOT NULL,
|
`animationDuration` smallint(5) unsigned NOT NULL,
|
||||||
`aoeRange` int(10) NOT NULL DEFAULT '0',
|
`battleAnimation` int(10) unsigned NOT NULL DEFAULT '0',
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
@ -57,148 +59,148 @@ CREATE TABLE `server_battle_commands` (
|
|||||||
LOCK TABLES `server_battle_commands` WRITE;
|
LOCK TABLES `server_battle_commands` WRITE;
|
||||||
/*!40000 ALTER TABLE `server_battle_commands` DISABLE KEYS */;
|
/*!40000 ALTER TABLE `server_battle_commands` DISABLE KEYS */;
|
||||||
set autocommit=0;
|
set autocommit=0;
|
||||||
INSERT INTO `server_battle_commands` VALUES (27100,'second_wind',2,6,3,1,0,1,0,0,5,0,0,0,0,45,0,0,14,519,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27100,'second_wind',2,6,3,1,0,0,0,1,0,0,5,0,0,0,0,45,0,0,14,519,2,2,234889735);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27101,'blindside',2,14,3,1,0,1,0,0,5,0,60,0,0,60,0,0,14,635,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27101,'blindside',2,14,3,1,0,0,0,1,0,0,5,0,60,0,0,60,0,0,14,635,2,2,234889851);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27102,'taunt',2,42,4,32,0,1,0,0,5,5,0,0,0,60,0,0,14,517,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27102,'taunt',2,42,4,32,0,0,0,1,0,0,5,5,0,0,0,60,0,0,14,517,2,2,234889733);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27103,'featherfoot',2,2,3,1,0,1,0,0,5,0,30,0,0,60,0,0,14,535,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27103,'featherfoot',2,2,3,1,0,0,0,1,0,0,5,0,30,0,0,60,0,0,14,535,2,2,234889751);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27104,'fists_of_fire',2,34,4,1,0,1,0,0,5,0,0,0,0,10,0,0,14,684,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27104,'fists_of_fire',2,34,4,1,0,0,0,1,0,0,5,0,0,0,0,10,0,0,14,684,2,2,234889900);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27105,'fists_of_earth',2,22,4,1,0,1,0,0,5,0,0,0,0,10,0,0,14,685,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27105,'fists_of_earth',2,22,4,1,0,0,0,1,0,0,5,0,0,0,0,10,0,0,14,685,2,2,234889901);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27106,'hundred_fists',15,50,0,0,0,1,0,0,5,0,0,0,0,900,0,0,14,712,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27106,'hundred_fists',15,50,0,0,0,0,0,1,0,0,5,0,0,0,0,900,0,0,14,712,2,2,234889928);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27107,'spinning_heel',15,35,0,0,0,1,0,0,5,0,0,0,0,120,0,0,14,718,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27107,'spinning_heel',15,35,0,0,0,0,0,1,0,0,5,0,0,0,0,120,0,0,14,718,2,2,234889934);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27108,'shoulder_tackle',15,30,0,0,0,1,0,0,5,0,0,0,0,60,0,0,18,1048,205,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27108,'shoulder_tackle',15,30,0,0,0,0,0,1,0,0,5,0,0,0,0,60,0,0,18,1048,205,2,302830616);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27109,'fists_of_wind',15,40,0,0,0,1,0,0,5,0,0,0,0,10,0,0,14,720,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27109,'fists_of_wind',15,40,0,0,0,0,0,1,0,0,5,0,0,0,0,10,0,0,14,720,2,2,234889936);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27110,'pummel',2,1,1,32,0,1,1,0,5,0,0,0,0,10,0,1000,18,1027,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27110,'pummel',2,1,1,32,0,0,0,1,1,0,5,0,0,0,0,10,0,1000,18,1027,1,2,301995011);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27111,'concussive_blow',2,10,1,32,0,1,4,0,5,30,0,0,0,30,0,1500,18,20,3,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27111,'concussive_blow',2,10,1,32,0,0,0,1,4,0,5,30,0,0,0,30,0,1500,18,20,3,2,302002196);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27112,'simian_thrash',2,50,4,32,0,1,0,0,5,0,0,0,0,80,0,2000,18,1003,202,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27112,'simian_thrash',2,50,4,32,0,0,0,1,0,0,5,0,0,0,0,80,0,2000,18,1003,202,2,302818283);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27113,'aura_pulse',2,38,4,32,1,1,0,0,5,30,0,0,0,40,0,1500,18,66,203,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27113,'aura_pulse',2,38,4,32,1,0,0,1,0,0,5,30,0,0,0,40,0,1500,18,66,203,2,302821442);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27114,'pounce',2,4,4,32,0,1,2,0,5,10,0,0,0,20,0,1500,18,8,3,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27114,'pounce',2,4,4,32,0,0,0,1,2,0,5,10,0,0,0,20,0,1500,18,8,3,2,302002184);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27115,'demolish',2,30,1,32,0,1,0,0,5,0,0,0,0,30,0,1500,18,1028,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27115,'demolish',2,30,1,32,0,0,0,1,0,0,5,0,0,0,0,30,0,1500,18,1028,2,2,301999108);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27116,'howling_fist',2,46,4,32,0,1,4,0,5,0,0,0,0,80,0,3000,18,1029,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27116,'howling_fist',2,46,4,32,0,0,0,1,4,0,5,0,0,0,0,80,0,3000,18,1029,2,2,301999109);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27117,'sucker_punch',2,26,1,32,0,1,4,0,5,0,0,0,0,15,0,1000,18,73,3,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27117,'sucker_punch',2,26,1,32,0,0,0,1,4,0,5,0,0,0,0,15,0,1000,18,73,3,2,302002249);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27118,'dragon_kick',15,45,0,0,0,1,0,0,5,0,0,0,0,60,0,2000,18,1041,204,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27118,'dragon_kick',15,45,0,0,0,0,0,1,0,0,5,0,0,0,0,60,0,2000,18,1041,204,2,302826513);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27119,'haymaker',2,18,4,32,0,1,0,1,5,0,0,0,0,5,0,250,18,23,201,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27119,'haymaker',2,18,4,32,0,0,0,1,0,1,5,0,0,0,0,5,0,250,18,23,201,2,302813207);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27140,'sentinel',3,22,3,1,0,1,0,0,5,0,15,0,0,90,0,0,14,526,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27140,'sentinel',3,22,3,1,0,0,0,1,0,0,5,0,15,0,0,90,0,0,14,526,2,2,234889742);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27141,'aegis_boon',3,6,8,1,0,1,0,0,5,0,30,0,0,60,0,0,14,583,21,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27141,'aegis_boon',3,6,8,1,0,0,0,1,0,0,5,0,30,0,0,60,0,0,14,583,21,2,234967623);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27142,'rampart',3,2,3,1,0,1,0,2,5,0,60,0,0,120,0,0,14,536,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27142,'rampart',3,2,3,1,0,0,0,1,0,2,5,0,60,0,0,120,0,0,14,536,2,2,234889752);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27143,'tempered_will',3,42,8,1,0,1,0,0,5,0,20,0,0,180,0,0,14,515,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27143,'tempered_will',3,42,8,1,0,0,0,1,0,0,5,0,20,0,0,180,0,0,14,515,2,2,234889731);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27144,'outmaneuver',3,34,8,1,0,1,0,0,5,0,30,0,0,90,0,0,14,512,21,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27144,'outmaneuver',3,34,8,1,0,0,0,1,0,0,5,0,30,0,0,90,0,0,14,512,21,2,234967552);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27145,'flash',3,14,3,32,0,1,0,0,5,0,0,0,0,30,0,0,14,696,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27145,'flash',3,14,3,32,0,0,0,1,0,0,5,0,0,0,0,30,0,0,14,696,2,2,234889912);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27146,'cover',16,30,0,0,0,1,0,0,5,0,15,0,0,60,0,0,14,725,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27146,'cover',16,30,0,0,0,0,0,1,0,0,5,0,15,0,0,60,0,0,14,725,2,2,234889941);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27147,'divine_veil',16,35,0,0,0,1,0,0,5,0,20,0,0,60,0,0,14,713,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27147,'divine_veil',16,35,0,0,0,0,0,1,0,0,5,0,20,0,0,60,0,0,14,713,2,2,234889929);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27148,'hallowed_ground',16,50,0,0,0,1,0,0,5,0,0,0,0,900,0,0,14,709,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27148,'hallowed_ground',16,50,0,0,0,0,0,1,0,0,5,0,0,0,0,900,0,0,14,709,2,2,234889925);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27149,'holy_succor',16,40,0,0,0,1,0,0,15,0,0,0,2,10,100,0,1,701,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27149,'holy_succor',16,40,0,0,0,0,0,1,0,0,15,0,0,0,2,10,100,0,1,701,1,2,16782013);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27150,'fast_blade',3,1,1,32,0,1,1,0,5,0,0,0,0,10,0,1000,18,1023,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27150,'fast_blade',3,1,1,32,0,0,0,1,1,0,5,0,0,0,0,10,0,1000,18,1023,1,2,301995007);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27151,'flat_blade',3,26,1,32,0,1,0,0,5,0,0,0,0,10,0,1500,18,1024,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27151,'flat_blade',3,26,1,32,0,0,0,1,0,0,5,0,0,0,0,10,0,1500,18,1024,2,2,301999104);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27152,'savage_blade',3,10,1,32,0,1,0,0,5,0,0,0,0,30,0,1000,18,1025,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27152,'savage_blade',3,10,1,32,0,0,0,1,0,0,5,0,0,0,0,30,0,1000,18,1025,1,2,301995009);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27153,'goring_blade',3,50,8,32,0,1,2,0,5,30,0,0,0,60,0,3000,18,1026,301,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27153,'goring_blade',3,50,8,32,0,0,0,1,2,0,5,30,0,0,0,60,0,3000,18,1026,301,2,303223810);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27154,'riot_blade',3,30,8,32,0,1,2,0,5,30,0,0,0,80,0,2000,18,75,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27154,'riot_blade',3,30,8,32,0,0,0,1,2,0,5,30,0,0,0,80,0,2000,18,75,2,2,301998155);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27155,'rage_of_halone',3,46,8,32,0,1,0,0,5,0,0,0,0,20,0,1500,18,1008,302,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27155,'rage_of_halone',3,46,8,32,0,0,0,1,0,0,5,0,0,0,0,20,0,1500,18,1008,302,2,303227888);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27156,'shield_bash',3,18,17,32,0,1,0,0,5,5,0,0,0,30,0,250,18,5,26,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27156,'shield_bash',3,18,17,32,0,0,0,1,0,0,5,5,0,0,0,30,0,250,18,5,26,2,302096389);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27157,'war_drum',3,38,24,32,1,1,0,2,5,0,0,0,0,60,0,500,14,502,21,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27157,'war_drum',3,38,24,32,1,0,0,1,0,2,5,0,0,0,0,60,0,500,14,502,21,2,234967542);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27158,'phalanx',3,4,8,1,0,1,0,0,5,0,0,0,0,5,0,250,18,32,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27158,'phalanx',3,4,8,1,0,0,0,1,0,0,5,0,0,0,0,5,0,250,18,32,1,2,301994016);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27159,'spirits_within',16,45,0,0,0,1,0,0,5,0,0,0,0,60,0,3000,18,1044,304,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27159,'spirits_within',16,45,0,0,0,0,0,1,0,0,5,0,0,0,0,60,0,3000,18,1044,304,2,303236116);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27180,'provoke',4,14,3,32,0,1,0,0,5,0,0,0,0,30,0,0,14,600,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27180,'provoke',4,14,3,32,0,0,0,1,0,0,5,0,0,0,0,30,0,0,14,600,2,2,234889816);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27181,'foresight',4,2,3,1,0,1,0,0,5,0,30,0,0,60,0,0,14,545,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27181,'foresight',4,2,3,1,0,0,0,1,0,0,5,0,30,0,0,60,0,0,14,545,2,2,234889761);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27182,'bloodbath',4,6,3,1,0,1,0,0,5,0,30,0,0,60,0,0,14,581,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27182,'bloodbath',4,6,3,1,0,0,0,1,0,0,5,0,30,0,0,60,0,0,14,581,2,2,234889797);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27183,'berserk',4,22,32,1,0,1,0,0,5,0,0,0,0,10,0,0,14,682,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27183,'berserk',4,22,32,1,0,0,0,1,0,0,5,0,0,0,0,10,0,0,14,682,2,2,234889898);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27184,'rampage',4,34,32,1,0,1,0,0,5,0,0,0,0,10,0,0,14,546,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27184,'rampage',4,34,32,1,0,0,0,1,0,0,5,0,0,0,0,10,0,0,14,546,2,2,234889762);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27185,'enduring_march',4,42,32,1,0,1,0,0,5,0,20,0,0,180,0,0,14,539,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27185,'enduring_march',4,42,32,1,0,0,0,1,0,0,5,0,20,0,0,180,0,0,14,539,2,2,234889755);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27186,'vengeance',17,30,0,1,0,1,0,0,5,0,0,0,0,150,0,0,14,714,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27186,'vengeance',17,30,0,1,0,0,0,1,0,0,5,0,0,0,0,150,0,0,14,714,2,2,234889930);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27187,'antagonize',17,35,0,1,0,1,0,0,5,0,0,0,0,120,0,0,14,715,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27187,'antagonize',17,35,0,1,0,0,0,1,0,0,5,0,0,0,0,120,0,0,14,715,2,2,234889931);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27188,'collusion',17,40,0,4,0,1,0,0,5,0,0,0,0,90,0,0,14,711,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27188,'collusion',17,40,0,4,0,0,0,1,0,0,5,0,0,0,0,90,0,0,14,711,2,2,234889927);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27189,'mighty_strikes',17,50,0,1,0,1,0,0,5,0,0,0,0,900,0,0,14,716,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27189,'mighty_strikes',17,50,0,1,0,0,0,1,0,0,5,0,0,0,0,900,0,0,14,716,2,2,234889932);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27190,'heavy_swing',4,1,1,32,0,1,1,0,5,0,0,0,0,10,0,1000,18,14,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27190,'heavy_swing',4,1,1,32,0,0,0,1,1,0,5,0,0,0,0,10,0,1000,18,14,1,2,301993998);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27191,'skull_sunder',4,10,1,32,0,1,0,0,5,0,0,0,0,30,0,1500,18,43,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27191,'skull_sunder',4,10,1,32,0,0,0,1,0,0,5,0,0,0,0,30,0,1500,18,43,1,2,301994027);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27192,'steel_cyclone',17,45,0,32,1,1,0,0,5,0,0,0,0,30,0,2000,18,1040,404,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27192,'steel_cyclone',17,45,0,32,1,0,0,1,0,0,5,0,0,0,0,30,0,2000,18,1040,404,2,303645712);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27193,'brutal_swing',4,4,1,32,0,1,4,0,5,0,0,0,0,20,0,1500,18,15,3,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27193,'brutal_swing',4,4,1,32,0,0,0,1,4,0,5,0,0,0,0,20,0,1500,18,15,3,2,302002191);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27194,'maim',4,26,1,32,0,1,0,0,5,0,0,0,0,30,0,1500,18,88,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27194,'maim',4,26,1,32,0,0,0,1,0,0,5,0,0,0,0,30,0,1500,18,88,1,2,301994072);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27195,'godsbane',4,50,32,32,0,1,0,0,5,0,0,0,0,60,0,3000,18,1014,402,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27195,'godsbane',4,50,32,32,0,0,0,1,0,0,5,0,0,0,0,60,0,3000,18,1014,402,2,303637494);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27196,'path_of_the_storm',4,38,32,32,0,1,2,0,5,0,0,0,0,30,0,1500,18,44,401,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27196,'path_of_the_storm',4,38,32,32,0,0,0,1,2,0,5,0,0,0,0,30,0,1500,18,44,401,2,303632428);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27197,'whirlwind',4,46,32,32,1,1,0,0,5,0,0,0,0,80,0,3000,18,1015,403,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27197,'whirlwind',4,46,32,32,1,0,0,1,0,0,5,0,0,0,0,80,0,3000,18,1015,403,2,303641591);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27198,'fracture',4,18,32,32,0,1,0,4,5,8,0,0,0,40,0,500,18,42,3,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27198,'fracture',4,18,32,32,0,0,0,1,0,4,5,8,0,0,0,40,0,500,18,42,3,2,302002218);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27199,'overpower',4,30,1,32,2,1,0,4,5,0,0,0,0,5,0,250,18,89,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27199,'overpower',4,30,1,32,2,0,0,1,0,4,5,0,0,0,0,5,0,250,18,89,1,2,301994073);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27220,'hawks_eye',7,6,3,1,0,1,0,0,5,0,15,0,0,90,0,0,14,516,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27220,'hawks_eye',7,6,3,1,0,0,0,1,0,0,5,0,15,0,0,90,0,0,14,516,2,2,234889732);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27221,'quelling_strikes',7,22,3,1,0,1,0,0,5,30,0,0,0,60,0,0,14,614,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27221,'quelling_strikes',7,22,3,1,0,0,0,1,0,0,5,30,0,0,0,60,0,0,14,614,2,2,234889830);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27222,'decoy',7,2,3,1,0,1,0,0,15,0,60,0,0,90,100,0,14,565,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27222,'decoy',7,2,3,1,0,0,0,1,0,0,15,0,60,0,0,90,100,0,14,565,2,2,234889781);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27223,'chameleon',7,42,3,1,0,1,0,0,5,0,0,0,0,180,0,0,14,504,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27223,'chameleon',7,42,3,1,0,0,0,1,0,0,5,0,0,0,0,180,0,0,14,504,2,2,234889720);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27224,'barrage',7,34,64,1,0,1,0,0,5,0,60,0,0,90,0,0,14,683,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27224,'barrage',7,34,64,1,0,0,0,1,0,0,5,0,60,0,0,90,0,0,14,683,2,2,234889899);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27225,'raging_strikes',7,14,64,1,0,1,0,0,5,0,0,0,0,10,0,0,14,632,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27225,'raging_strikes',7,14,64,1,0,0,0,1,0,0,5,0,0,0,0,10,0,0,14,632,2,2,234889848);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27226,'swiftsong',7,26,64,1,1,1,0,0,15,0,180,0,0,10,100,0,1,150,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27226,'swiftsong',7,26,64,1,1,0,0,1,0,0,15,0,180,0,0,10,100,0,1,150,1,2,16781462);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27227,'battle_voice',18,50,0,1,1,1,0,0,5,0,0,0,0,900,0,0,14,721,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27227,'battle_voice',18,50,0,1,1,0,0,1,0,0,5,0,0,0,0,900,0,0,14,721,2,2,234889937);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27228,'heavy_shot',7,1,1,32,0,1,0,0,5,0,0,0,0,10,0,1000,18,1036,4,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27228,'heavy_shot',7,1,1,32,0,0,0,1,0,0,5,0,0,0,0,10,0,1000,18,1036,4,2,302007308);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27229,'leaden_arrow',7,10,1,32,0,1,0,0,5,30,0,0,0,30,0,1500,18,1035,4,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27229,'leaden_arrow',7,10,1,32,0,0,0,1,0,0,5,30,0,0,0,30,0,1500,18,1035,4,2,302007307);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27230,'wide_volley',7,50,64,32,1,1,0,0,5,0,0,0,0,80,0,2000,18,18,703,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27230,'wide_volley',7,50,64,32,1,0,0,1,0,0,5,0,0,0,0,80,0,2000,18,18,703,2,304869394);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27231,'quick_nock',7,38,64,32,2,1,0,0,5,0,0,0,0,180,0,1000,18,1017,702,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27231,'quick_nock',7,38,64,32,2,0,0,1,0,0,5,0,0,0,0,180,0,1000,18,1017,702,2,304866297);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27232,'rain_of_death',18,45,0,32,1,1,0,0,5,0,0,0,0,30,0,3000,18,1037,704,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27232,'rain_of_death',18,45,0,32,1,0,0,1,0,0,5,0,0,0,0,30,0,3000,18,1037,704,2,304874509);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27233,'piercing_arrow',7,4,1,32,0,1,0,0,5,0,0,0,0,20,0,1000,18,1038,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27233,'piercing_arrow',7,4,1,32,0,0,0,1,0,0,5,0,0,0,0,20,0,1000,18,1038,1,2,301995022);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27234,'gloom_arrow',7,30,1,32,0,1,0,0,5,30,0,0,0,10,0,1000,18,1039,4,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27234,'gloom_arrow',7,30,1,32,0,0,0,1,0,0,5,30,0,0,0,10,0,1000,18,1039,4,2,302007311);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27235,'bloodletter',7,46,64,32,0,1,0,0,5,30,0,0,0,80,0,1500,18,53,701,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27235,'bloodletter',7,46,64,32,0,0,0,1,0,0,5,30,0,0,0,80,0,1500,18,53,701,2,304861237);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27236,'shadowbind',7,18,64,32,0,1,0,0,5,30,0,0,0,40,0,250,18,17,4,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27236,'shadowbind',7,18,64,32,0,0,0,1,0,0,5,30,0,0,0,40,0,250,18,17,4,2,302006289);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27237,'ballad_of_magi',18,30,0,1,1,1,0,0,15,0,0,0,3,10,100,0,1,709,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27237,'ballad_of_magi',18,30,0,1,1,0,0,1,0,0,15,0,0,0,3,10,100,0,1,709,1,2,16782021);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27238,'paeon_of_war',18,40,0,1,1,1,0,0,15,0,0,0,3,10,50,1000,1,710,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27238,'paeon_of_war',18,40,0,1,1,0,0,1,0,0,15,0,0,0,3,10,50,1000,1,710,1,2,16782022);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27239,'minuet_of_rigor',18,35,0,1,1,1,0,0,15,0,0,0,3,10,100,0,1,711,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27239,'minuet_of_rigor',18,35,0,1,1,0,0,1,0,0,15,0,0,0,3,10,100,0,1,711,1,2,16782023);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27258,'refill',7,1,0,1,0,1,0,0,5,0,0,0,0,0,0,0,0,0,0,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27258,'refill',7,1,0,1,0,0,0,1,0,0,5,0,0,0,0,0,0,0,0,0,0,2,0);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27259,'light_shot',7,1,0,32,0,1,0,0,5,0,0,0,0,0,0,0,0,0,0,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27259,'light_shot',7,1,0,32,0,0,0,1,0,0,5,0,0,0,0,0,0,0,0,0,0,2,0);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27260,'invigorate',8,14,3,1,0,1,0,0,5,0,30,0,0,90,0,0,14,575,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27260,'invigorate',8,14,3,1,0,0,0,1,0,0,5,0,30,0,0,90,0,0,14,575,2,2,234889791);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27261,'power_surge',8,34,128,1,0,1,0,0,5,0,0,0,0,10,0,0,14,686,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27261,'power_surge',8,34,128,1,0,0,0,1,0,0,5,0,0,0,0,10,0,0,14,686,2,2,234889902);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27262,'life_surge',8,22,128,1,0,1,0,0,5,0,0,0,0,15,0,250,14,687,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27262,'life_surge',8,22,128,1,0,0,0,1,0,0,5,0,0,0,0,15,0,250,14,687,2,2,234889903);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27263,'dread_spike',8,42,128,1,0,1,0,0,5,0,0,0,0,120,0,0,14,686,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27263,'dread_spike',8,42,128,1,0,0,0,1,0,0,5,0,0,0,0,120,0,0,14,686,2,2,234889902);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27264,'blood_for_blood',8,6,3,1,0,1,0,0,5,0,0,0,0,60,0,0,14,689,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27264,'blood_for_blood',8,6,3,1,0,0,0,1,0,0,5,0,0,0,0,60,0,0,14,689,2,2,234889905);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27265,'keen_flurry',8,26,3,1,0,1,0,0,5,0,0,0,0,90,0,0,14,569,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27265,'keen_flurry',8,26,3,1,0,0,0,1,0,0,5,0,0,0,0,90,0,0,14,569,2,2,234889785);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27266,'jump',19,30,0,32,0,1,0,0,5,0,0,0,0,60,0,0,18,1045,804,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27266,'jump',19,30,0,32,0,0,0,1,0,0,5,0,0,0,0,60,0,0,18,1045,804,2,305284117);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27267,'elusive_jump',19,40,0,1,0,1,0,0,5,0,0,0,0,180,0,0,18,1046,806,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27267,'elusive_jump',19,40,0,1,0,0,0,1,0,0,5,0,0,0,0,180,0,0,18,1046,806,2,305292310);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27268,'dragonfire_dive',19,50,0,32,1,1,0,0,5,0,0,0,0,900,0,0,18,1045,804,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27268,'dragonfire_dive',19,50,0,32,1,0,0,1,0,0,5,0,0,0,0,900,0,0,18,1045,804,2,305284117);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27269,'true_thrust',8,1,1,32,0,1,1,0,5,0,0,0,0,10,0,1000,18,1030,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27269,'true_thrust',8,1,1,32,0,0,0,1,1,0,5,0,0,0,0,10,0,1000,18,1030,2,2,301999110);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27270,'leg_sweep',8,30,1,32,1,1,0,0,5,8,0,0,0,30,0,1000,18,37,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27270,'leg_sweep',8,30,1,32,1,0,0,1,0,0,5,8,0,0,0,30,0,1000,18,37,1,2,301994021);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27271,'doom_spike',8,46,128,32,3,1,0,0,5,0,0,0,0,60,0,3000,18,83,801,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27271,'doom_spike',8,46,128,32,3,0,0,1,0,0,5,0,0,0,0,60,0,3000,18,83,801,2,305270867);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27272,'disembowel',19,35,0,32,0,1,0,0,5,0,0,0,0,30,0,750,18,1042,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27272,'disembowel',19,35,0,32,0,0,0,1,0,0,5,0,0,0,0,30,0,750,18,1042,2,2,301999122);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27273,'heavy_thrust',8,10,1,32,0,1,0,0,5,4,0,0,0,20,0,1500,18,1031,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27273,'heavy_thrust',8,10,1,32,0,0,0,1,0,0,5,4,0,0,0,20,0,1500,18,1031,1,2,301995015);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27274,'vorpal_thrust',8,2,1,32,0,1,2,0,5,0,0,0,0,20,0,1500,18,1032,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27274,'vorpal_thrust',8,2,1,32,0,0,0,1,2,0,5,0,0,0,0,20,0,1500,18,1032,2,2,301999112);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27275,'impulse_drive',8,18,1,32,0,1,4,0,5,0,0,0,0,30,0,1500,18,1033,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27275,'impulse_drive',8,18,1,32,0,0,0,1,4,0,5,0,0,0,0,30,0,1500,18,1033,2,2,301999113);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27276,'chaos_thrust',8,50,128,32,0,1,0,0,5,0,0,0,0,80,0,3000,18,40,802,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27276,'chaos_thrust',8,50,128,32,0,0,0,1,0,0,5,0,0,0,0,80,0,3000,18,40,802,2,305274920);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27277,'ring_of_talons',19,45,0,32,1,1,0,0,5,0,0,0,0,60,0,2000,18,1009,803,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27277,'ring_of_talons',19,45,0,32,1,0,0,1,0,0,5,0,0,0,0,60,0,2000,18,1009,803,2,305279985);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27278,'feint',8,4,1,32,0,1,0,8,5,0,0,0,0,10,0,250,18,39,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27278,'feint',8,4,1,32,0,0,0,1,0,8,5,0,0,0,0,10,0,250,18,39,2,2,301998119);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27279,'full_thrust',8,38,128,32,0,1,0,8,5,0,0,0,0,30,0,250,18,1034,801,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27279,'full_thrust',8,38,128,32,0,0,0,1,0,8,5,0,0,0,0,30,0,250,18,1034,801,2,305271818);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27300,'dark_seal',22,14,3,1,0,1,0,0,5,0,30,0,0,90,0,0,14,518,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27300,'dark_seal',22,14,3,1,0,0,0,1,0,0,5,0,30,0,0,90,0,0,14,518,2,2,234889734);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27301,'resonance',22,22,3,1,0,1,0,0,5,0,30,0,0,90,0,0,14,669,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27301,'resonance',22,22,3,1,0,0,0,1,0,0,5,0,30,0,0,90,0,0,14,669,2,2,234889885);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27302,'excruciate',22,38,256,1,0,1,0,0,5,0,30,0,0,90,0,0,14,694,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27302,'excruciate',22,38,256,1,0,0,0,1,0,0,5,0,30,0,0,90,0,0,14,694,2,2,234889910);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27303,'necrogenesis',22,6,3,1,0,1,0,0,5,0,30,0,0,90,0,0,14,695,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27303,'necrogenesis',22,6,3,1,0,0,0,1,0,0,5,0,30,0,0,90,0,0,14,695,2,2,234889911);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27304,'parsimony',22,2,256,1,0,1,0,0,5,0,30,0,0,90,0,0,14,568,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27304,'parsimony',22,2,256,1,0,0,0,1,0,0,5,0,30,0,0,90,0,0,14,568,2,2,234889784);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27305,'convert',26,30,0,1,0,1,0,0,5,0,0,0,0,450,0,0,14,724,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27305,'convert',26,30,0,1,0,0,0,1,0,0,5,0,0,0,0,450,0,0,14,724,2,2,234889940);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27306,'sleep',22,42,256,32,0,1,0,0,15,60,0,0,3,0,75,0,1,651,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27306,'sleep',22,42,256,32,0,0,0,1,0,0,15,60,0,0,3,0,75,0,1,651,1,2,16781963);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27307,'sanguine_rite',22,30,3,1,0,1,0,0,15,0,20,0,0,60,120,0,1,152,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27307,'sanguine_rite',22,30,3,1,0,0,0,1,0,0,15,0,20,0,0,60,120,0,1,152,1,2,16781464);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27308,'blizzard',22,4,256,32,0,1,0,0,15,30,0,0,3,10,90,0,1,502,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27308,'blizzard',22,4,256,32,0,0,0,1,0,0,15,30,0,0,3,10,90,0,1,502,1,2,16781814);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27309,'blizzara',22,26,256,32,1,1,0,0,15,30,0,0,0,40,150,0,1,506,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27309,'blizzara',22,26,256,32,1,0,0,1,0,0,15,30,0,0,0,40,150,0,1,506,1,2,16781818);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27310,'fire',22,10,3,32,1,1,0,0,15,0,0,0,3,8,105,0,1,501,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27310,'fire',22,10,3,32,1,0,0,1,0,0,15,0,0,0,3,8,105,0,1,501,1,2,16781813);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27311,'fira',22,34,3,32,1,1,0,0,15,0,0,0,5,16,180,0,1,504,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27311,'fira',22,34,3,32,1,0,0,1,0,0,15,0,0,0,5,16,180,0,1,504,1,2,16781816);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27312,'firaga',22,50,256,32,1,1,0,0,15,0,0,0,8,7,255,0,1,700,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27312,'firaga',22,50,256,32,1,0,0,1,0,0,15,0,0,0,8,7,255,0,1,700,1,2,16782012);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27313,'thunder',22,1,3,32,0,1,0,0,15,0,0,0,2,6,75,0,1,503,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27313,'thunder',22,1,3,32,0,0,0,1,0,0,15,0,0,0,2,6,75,0,1,503,1,2,16781815);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27314,'thundara',22,18,256,32,0,1,0,0,15,4,0,0,0,30,135,0,1,508,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27314,'thundara',22,18,256,32,0,0,0,1,0,0,15,4,0,0,0,30,135,0,1,508,1,2,16781820);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27315,'thundaga',22,46,256,32,0,1,0,0,15,0,0,0,5,45,195,0,1,509,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27315,'thundaga',22,46,256,32,0,0,0,1,0,0,15,0,0,0,5,45,195,0,1,509,1,2,16781821);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27316,'burst',26,50,0,32,0,1,0,0,15,0,0,0,4,900,90,0,1,705,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27316,'burst',26,50,0,32,0,0,0,1,0,0,15,0,0,0,4,900,90,0,1,705,1,2,16782017);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27317,'sleepga',26,45,0,32,1,1,0,0,15,0,0,0,4,0,100,0,1,704,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27317,'sleepga',26,45,0,32,1,0,0,1,0,0,15,0,0,0,4,0,100,0,1,704,1,2,16782016);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27318,'flare',26,40,0,32,1,1,0,0,15,0,0,0,8,120,200,0,1,706,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27318,'flare',26,40,0,32,1,0,0,1,0,0,15,0,0,0,8,120,200,0,1,706,1,2,16782018);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27319,'freeze',26,35,0,32,0,1,0,0,15,0,0,0,5,120,120,0,1,707,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27319,'freeze',26,35,0,32,0,0,0,1,0,0,15,0,0,0,5,120,120,0,1,707,1,2,16782019);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27340,'sacred_prism',23,34,3,1,0,1,0,0,5,0,60,0,0,90,0,0,14,690,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27340,'sacred_prism',23,34,3,1,0,0,0,1,0,0,5,0,60,0,0,90,0,0,14,690,2,2,234889906);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27341,'shroud_of_saints',23,38,512,1,0,1,0,0,5,0,20,0,0,180,0,0,14,691,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27341,'shroud_of_saints',23,38,512,1,0,0,0,1,0,0,5,0,20,0,0,180,0,0,14,691,2,2,234889907);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27342,'cleric_stance',23,10,512,1,0,1,0,0,5,0,0,0,0,30,0,0,14,692,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27342,'cleric_stance',23,10,512,1,0,0,0,1,0,0,5,0,0,0,0,30,0,0,14,692,2,2,234889908);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27343,'blissful_mind',23,14,512,1,0,1,0,0,5,0,0,0,0,30,0,0,14,693,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27343,'blissful_mind',23,14,512,1,0,0,0,1,0,0,5,0,0,0,0,30,0,0,14,693,2,2,234889909);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27344,'presence_of_mind',27,30,0,1,0,1,0,0,5,0,0,0,0,300,0,0,14,722,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27344,'presence_of_mind',27,30,0,1,0,0,0,1,0,0,5,0,0,0,0,300,0,0,14,722,2,2,234889938);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27345,'benediction',27,50,0,1,1,1,0,0,5,0,0,0,0,900,0,0,14,723,2,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27345,'benediction',27,50,0,1,1,0,0,1,0,0,5,0,0,0,0,900,0,0,14,723,2,2,234889939);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27346,'cure',23,2,3,2,0,1,0,0,15,0,0,0,2,5,40,0,1,101,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27346,'cure',23,2,3,2,0,0,0,1,0,0,15,0,0,0,2,5,40,0,1,101,1,2,16781413);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27347,'cura',23,30,512,2,0,1,0,0,15,0,0,0,2,5,100,0,1,103,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27347,'cura',23,30,512,2,0,0,0,1,0,0,15,0,0,0,2,5,100,0,1,103,1,2,16781415);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27348,'curaga',23,46,512,4,1,1,0,0,15,0,0,0,3,10,150,0,1,146,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27348,'curaga',23,46,512,4,1,0,0,1,0,0,15,0,0,0,3,10,150,0,1,146,1,2,16781458);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27349,'raise',23,18,512,2,0,1,0,0,15,0,0,0,10,300,150,0,1,148,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27349,'raise',23,18,512,2,0,0,0,1,0,0,15,0,0,0,10,300,150,0,1,148,1,2,16781460);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27350,'stoneskin',23,26,3,2,0,1,0,0,15,0,300,0,3,30,50,0,1,133,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27350,'stoneskin',23,26,3,2,0,0,0,1,0,0,15,0,300,0,3,30,50,0,1,133,1,2,16781445);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27351,'protect',23,6,3,4,1,1,0,0,15,0,300,0,3,30,80,0,1,1085,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27351,'protect',23,6,3,4,1,0,0,1,0,0,15,0,300,0,3,30,80,0,1,1085,1,2,16782397);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27352,'repose',23,50,0,32,0,1,0,0,15,0,0,0,3,0,80,0,1,151,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27352,'repose',23,50,0,32,0,0,0,1,0,0,15,0,0,0,3,0,80,0,1,151,1,2,16781463);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27353,'aero',23,4,3,32,0,1,0,0,15,0,0,0,3,6,75,0,1,510,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27353,'aero',23,4,3,32,0,0,0,1,0,0,15,0,0,0,3,6,75,0,1,510,1,2,16781822);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27354,'aerora',23,42,512,32,1,1,0,0,15,0,0,0,4,20,150,0,1,511,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27354,'aerora',23,42,512,32,1,0,0,1,0,0,15,0,0,0,4,20,150,0,1,511,1,2,16781823);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27355,'stone',23,1,3,32,0,1,0,0,15,0,0,0,2,6,75,0,1,513,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27355,'stone',23,1,3,32,0,0,0,1,0,0,15,0,0,0,2,6,75,0,1,513,1,2,16781825);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27356,'stonera',23,22,512,32,1,1,0,0,15,0,0,0,3,30,150,0,1,514,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27356,'stonera',23,22,512,32,1,0,0,1,0,0,15,0,0,0,3,30,150,0,1,514,1,2,16781826);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27357,'esuna',27,40,0,2,0,1,0,0,15,0,0,0,2,10,40,0,1,702,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27357,'esuna',27,40,0,2,0,0,0,1,0,0,15,0,0,0,2,10,40,0,1,702,1,2,16782014);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27358,'regen',27,35,0,2,0,1,0,0,15,0,0,0,2,5,20,0,1,703,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27358,'regen',27,35,0,2,0,0,0,1,0,0,15,0,0,0,2,5,20,0,1,703,1,2,16782015);
|
||||||
INSERT INTO `server_battle_commands` VALUES (27359,'holy',27,45,0,32,1,1,0,0,15,0,0,0,0,300,100,0,1,708,1,2,0);
|
INSERT INTO `server_battle_commands` VALUES (27359,'holy',27,45,0,32,1,0,0,1,0,0,15,0,0,0,0,300,100,0,1,708,1,2,16782020);
|
||||||
/*!40000 ALTER TABLE `server_battle_commands` ENABLE KEYS */;
|
/*!40000 ALTER TABLE `server_battle_commands` ENABLE KEYS */;
|
||||||
UNLOCK TABLES;
|
UNLOCK TABLES;
|
||||||
commit;
|
commit;
|
||||||
@ -212,4 +214,4 @@ commit;
|
|||||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||||
|
|
||||||
-- Dump completed on 2017-08-28 1:38:36
|
-- Dump completed on 2017-08-31 5:52:52
|
||||||
|
Loading…
Reference in New Issue
Block a user