diff --git a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj
index e86ac93e..ca8e7814 100644
--- a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj
+++ b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj
@@ -140,6 +140,7 @@
+
@@ -256,7 +257,7 @@
-
+
diff --git a/FFXIVClassic Map Server/actors/Actor.cs b/FFXIVClassic Map Server/actors/Actor.cs
index 24ee9ffb..c28855a9 100644
--- a/FFXIVClassic Map Server/actors/Actor.cs
+++ b/FFXIVClassic Map Server/actors/Actor.cs
@@ -185,7 +185,7 @@ namespace FFXIVClassic_Map_Server.Actors
public SubPacket CreateStatePacket()
{
- return SetActorStatePacket.BuildPacket(actorId, currentMainState, currentSubState);
+ return SetActorStatePacket.BuildPacket(actorId, currentMainState, 0);
}
public List GetEventConditionPackets()
diff --git a/FFXIVClassic Map Server/actors/chara/Character.cs b/FFXIVClassic Map Server/actors/chara/Character.cs
index c25b2479..c0bc10ba 100644
--- a/FFXIVClassic Map Server/actors/chara/Character.cs
+++ b/FFXIVClassic Map Server/actors/chara/Character.cs
@@ -167,9 +167,9 @@ namespace FFXIVClassic_Map_Server.Actors
return SetActorIconPacket.BuildPacket(actorId, currentActorIcon);
}
- public SubPacket CreateIdleAnimationPacket()
+ public SubPacket CreateSubStatePacket()
{
- return SetActorSubStatePacket.BuildPacket(actorId, 0, 0, 0, 0, 0, 0, animationId);
+ return SetActorSubStatePacket.BuildPacket(actorId, currentSubState);
}
public void SetQuestGraphic(Player player, int graphicNum)
@@ -219,12 +219,6 @@ namespace FFXIVClassic_Map_Server.Actors
zone.BroadcastPacketAroundActor(this, PlayAnimationOnActorPacket.BuildPacket(actorId, animId));
}
- public void SendChant(int left, int right)
- {
- SetActorSubStatePacket.BuildPacket(actorId, 0, left, right, 0, 0, 0, 0).DebugPrintSubPacket();
- zone.BroadcastPacketAroundActor(this, SetActorSubStatePacket.BuildPacket(actorId, 0, left, right, 0, 0, 0, 0));
- }
-
public void DoBattleAction(ushort commandId, uint animationId)
{
zone.BroadcastPacketAroundActor(this, BattleActionX00Packet.BuildPacket(actorId, animationId, commandId));
diff --git a/FFXIVClassic Map Server/actors/chara/ai/state/AbilityState.cs b/FFXIVClassic Map Server/actors/chara/ai/state/AbilityState.cs
index d8f877aa..a32a5f01 100644
--- a/FFXIVClassic Map Server/actors/chara/ai/state/AbilityState.cs
+++ b/FFXIVClassic Map Server/actors/chara/ai/state/AbilityState.cs
@@ -57,7 +57,8 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
// todo: modify spellSpeed based on modifiers and stuff
((Player)owner).SendStartCastbar(skill.id, Utils.UnixTimeStampUTC(DateTime.Now.AddMilliseconds(castTime)));
}
- owner.SendChant(0xf, 0x0);
+ owner.GetSubState().chantId = 0xf0;
+ owner.SubstateModified();
//You ready [skill] (6F000002: BLM, 6F000003: WHM, 0x6F000008: BRD)
owner.DoBattleAction(skill.id, (uint)0x6F000000 | skill.castType, new BattleAction(target.actorId, 30126, 1, 0, 1));
}
@@ -144,7 +145,8 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
public override void Cleanup()
{
- owner.SendChant(0, 0);
+ owner.GetSubState().chantId = 0x0;
+ owner.SubstateModified();
owner.aiContainer.UpdateLastActionTime(skill.animationDurationSeconds);
}
}
diff --git a/FFXIVClassic Map Server/actors/chara/ai/state/MagicState.cs b/FFXIVClassic Map Server/actors/chara/ai/state/MagicState.cs
index b12b781c..9b2d51b7 100644
--- a/FFXIVClassic Map Server/actors/chara/ai/state/MagicState.cs
+++ b/FFXIVClassic Map Server/actors/chara/ai/state/MagicState.cs
@@ -63,8 +63,9 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
//There are no positional spells, so just check onCombo, need to check first because certain spells change aoe type/accuracy
//If owner is a player and the spell being used is part of the current combo
- if (owner is Player p && p.GetClass() == spell.job)
+ if (owner is Player && ((Player)owner).GetClass() == spell.job)
{
+ Player p = (Player)owner;
if (spell.comboStep == 1 || ((p.playerWork.comboNextCommandId[0] == spell.id || p.playerWork.comboNextCommandId[1] == spell.id)))
{
lua.LuaEngine.CallLuaBattleCommandFunction(owner, spell, "magic", "onCombo", owner, target, spell);
@@ -84,7 +85,8 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
// todo: modify spellSpeed based on modifiers and stuff
((Player)owner).SendStartCastbar(spell.id, Utils.UnixTimeStampUTC(DateTime.Now.AddMilliseconds(spellSpeed)));
}
- owner.SendChant(0xf, 0x0);
+ owner.GetSubState().chantId = 0xf0;
+ owner.SubstateModified();
owner.DoBattleAction(spell.id, (uint) 0x6F000000 | spell.castType, new BattleAction(target.actorId, 30128, 1, 0, 1)); //You begin casting (6F000002: BLM, 6F000003: WHM, 0x6F000008: BRD)
}
}
@@ -120,7 +122,8 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
// todo: send paralyzed/sleep message etc.
if (errorResult != null)
{
- owner.SendChant(0, 0);
+ owner.GetSubState().chantId = 0x0;
+ owner.SubstateModified();
owner.DoBattleAction(spell.id, errorResult.animation, errorResult);
errorResult = null;
}
@@ -181,7 +184,8 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
public override void Cleanup()
{
- owner.SendChant(0, 0);
+ owner.GetSubState().chantId = 0x0;
+ owner.SubstateModified();
if (owner is Player)
{
diff --git a/FFXIVClassic Map Server/actors/chara/ai/state/WeaponSkillState.cs b/FFXIVClassic Map Server/actors/chara/ai/state/WeaponSkillState.cs
index e88fc853..efdb755f 100644
--- a/FFXIVClassic Map Server/actors/chara/ai/state/WeaponSkillState.cs
+++ b/FFXIVClassic Map Server/actors/chara/ai/state/WeaponSkillState.cs
@@ -58,8 +58,9 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
skill.CallLuaFunction(owner, "onPositional", owner, target, skill);
//Combo stuff
- if (owner is Player p)
+ if (owner is Player)
{
+ Player p = (Player)owner;
//If skill is part of owner's class/job, it can be used in a combo
if (skill.job == p.GetClass() || skill.job == p.GetCurrentClassOrJob())
{
@@ -86,7 +87,8 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
// todo: modify spellSpeed based on modifiers and stuff
((Player)owner).SendStartCastbar(skill.id, Utils.UnixTimeStampUTC(DateTime.Now.AddMilliseconds(castTime)));
}
- owner.SendChant(0xf, 0x0);
+ owner.GetSubState().chantId = 0xf0;
+ owner.SubstateModified();
//You ready [skill] (6F000002: BLM, 6F000003: WHM, 0x6F000008: BRD)
owner.DoBattleAction(skill.id, (uint)0x6F000000 | skill.castType, new BattleAction(target.actorId, 30126, 1, 0, 1));
}
diff --git a/FFXIVClassic Map Server/actors/chara/npc/BattleNpc.cs b/FFXIVClassic Map Server/actors/chara/npc/BattleNpc.cs
index a9a90b35..c63fb0f9 100644
--- a/FFXIVClassic Map Server/actors/chara/npc/BattleNpc.cs
+++ b/FFXIVClassic Map Server/actors/chara/npc/BattleNpc.cs
@@ -77,7 +77,7 @@ namespace FFXIVClassic_Map_Server.Actors
{
this.aiContainer = new AIContainer(this, new BattleNpcController(this), new PathFind(this), new TargetFind(this));
- this.currentSubState = SetActorStatePacket.SUB_STATE_MONSTER;
+ //this.currentSubState = SetActorStatePacket.SUB_STATE_MONSTER;
//this.currentMainState = SetActorStatePacket.MAIN_STATE_ACTIVE;
//charaWork.property[2] = 1;
@@ -108,7 +108,7 @@ namespace FFXIVClassic_Map_Server.Actors
subpackets.Add(CreateNamePacket());
subpackets.Add(CreateStatePacket());
- subpackets.Add(CreateIdleAnimationPacket());
+ subpackets.Add(CreateSubStatePacket());
subpackets.Add(CreateInitStatusPacket());
subpackets.Add(CreateSetActorIconPacket());
subpackets.Add(CreateIsZoneingPacket());
@@ -276,7 +276,7 @@ namespace FFXIVClassic_Map_Server.Actors
if (IsAlive())
{
// todo: does retail
- if (lastAttacker is Pet && lastAttacker.aiContainer.GetController()?.GetPetMaster() is Player)
+ if (lastAttacker is Pet && lastAttacker.aiContainer.GetController() != null && lastAttacker.aiContainer.GetController().GetPetMaster() is Player)
{
lastAttacker = lastAttacker.aiContainer.GetController().GetPetMaster();
}
@@ -285,7 +285,8 @@ namespace FFXIVClassic_Map_Server.Actors
{
//I think this is, or should be odne in DoBattleAction. Packet capture had the message in the same packet as an attack
// defeat/defeats
- actionContainer?.AddEXPAction(new BattleAction(actorId, 30108, 0));
+ if (actionContainer != null)
+ actionContainer.AddEXPAction(new BattleAction(actorId, 30108, 0));
if (lastAttacker.currentParty != null && lastAttacker.currentParty is Party)
{
foreach (var memberId in ((Party)lastAttacker.currentParty).members)
@@ -295,8 +296,8 @@ namespace FFXIVClassic_Map_Server.Actors
lua.LuaEngine.CallLuaBattleFunction(this, "onDeath", this, partyMember, lastAttacker);
// todo: add actual experience calculation and exp bonus values.
- if (partyMember is Player player)
- BattleUtils.AddBattleBonusEXP(player, this, actionContainer);
+ if (partyMember is Player)
+ BattleUtils.AddBattleBonusEXP((Player)partyMember, this, actionContainer);
}
}
else
@@ -306,7 +307,9 @@ namespace FFXIVClassic_Map_Server.Actors
//((Player)lastAttacker).QueuePacket(BattleActionX01Packet.BuildPacket(lastAttacker.actorId, 0, 0, new BattleAction(actorId, 30108, 0)));
}
}
- positionUpdates?.Clear();
+
+ if (positionUpdates != null)
+ positionUpdates.Clear();
aiContainer.InternalDie(tick, despawnTime);
//this.ResetMoveSpeeds();
// todo: reset cooldowns
@@ -315,7 +318,7 @@ namespace FFXIVClassic_Map_Server.Actors
}
else
{
- var err = $"[{actorId}][{GetUniqueId()}] {positionX} {positionY} {positionZ} {GetZone().GetName()} tried to die ded";
+ var err = String.Format("[{0}][{1}] {2} {3} {4} {5} tried to die ded", actorId, GetUniqueId(), positionX, positionY, positionZ, GetZone().GetName());
Program.Log.Error(err);
//throw new Exception(err);
}
diff --git a/FFXIVClassic Map Server/actors/chara/npc/Npc.cs b/FFXIVClassic Map Server/actors/chara/npc/Npc.cs
index a534f6d6..a351e73b 100644
--- a/FFXIVClassic Map Server/actors/chara/npc/Npc.cs
+++ b/FFXIVClassic Map Server/actors/chara/npc/Npc.cs
@@ -63,6 +63,8 @@ namespace FFXIVClassic_Map_Server.Actors
this.actorClassId = actorClass.actorClassId;
+ this.currentSubState.motionPack = (ushort) animationId;
+
LoadNpcAppearance(actorClass.actorClassId);
className = actorClass.classPath.Substring(actorClass.classPath.LastIndexOf("/") + 1);
@@ -201,7 +203,7 @@ namespace FFXIVClassic_Map_Server.Actors
subpackets.Add(CreateNamePacket());
subpackets.Add(CreateStatePacket());
- subpackets.Add(CreateIdleAnimationPacket());
+ subpackets.Add(CreateSubStatePacket());
subpackets.Add(CreateInitStatusPacket());
subpackets.Add(CreateSetActorIconPacket());
subpackets.Add(CreateIsZoneingPacket());
diff --git a/FFXIVClassic Map Server/actors/chara/npc/Pet.cs b/FFXIVClassic Map Server/actors/chara/npc/Pet.cs
index 27e9490e..3068d023 100644
--- a/FFXIVClassic Map Server/actors/chara/npc/Pet.cs
+++ b/FFXIVClassic Map Server/actors/chara/npc/Pet.cs
@@ -17,8 +17,7 @@ namespace FFXIVClassic_Map_Server.Actors
ushort actorState, uint animationId, string customDisplayName)
: base(actorNumber, actorClass, uniqueId, spawnedArea, posX, posY, posZ, rot, actorState, animationId, customDisplayName)
{
- this.aiContainer = new AIContainer(this, new PetController(this), new PathFind(this), new TargetFind(this));
- this.currentSubState = SetActorStatePacket.SUB_STATE_MONSTER;
+ this.aiContainer = new AIContainer(this, new PetController(this), new PathFind(this), new TargetFind(this));
this.hateContainer = new HateContainer(this);
}
}
diff --git a/FFXIVClassic Map Server/actors/chara/player/Player.cs b/FFXIVClassic Map Server/actors/chara/player/Player.cs
index e5f43ba5..e3f3c468 100644
--- a/FFXIVClassic Map Server/actors/chara/player/Player.cs
+++ b/FFXIVClassic Map Server/actors/chara/player/Player.cs
@@ -131,7 +131,6 @@ namespace FFXIVClassic_Map_Server.Actors
playerSession = cp;
actorName = String.Format("_pc{0:00000000}", actorID);
className = "Player";
- currentSubState = SetActorStatePacket.SUB_STATE_PLAYER;
moveSpeeds[0] = SetActorSpeedPacket.DEFAULT_STOP;
moveSpeeds[1] = SetActorSpeedPacket.DEFAULT_WALK;
@@ -288,7 +287,7 @@ namespace FFXIVClassic_Map_Server.Actors
subpackets.Add(CreateNamePacket());
subpackets.Add(_0xFPacket.BuildPacket(actorId));
subpackets.Add(CreateStatePacket());
- subpackets.Add(CreateIdleAnimationPacket());
+ subpackets.Add(CreateSubStatePacket());
subpackets.Add(CreateInitStatusPacket());
subpackets.Add(CreateSetActorIconPacket());
subpackets.Add(CreateIsZoneingPacket());