diff --git a/FFXIVClassic Common Class Lib/FFXIVClassic Common Class Lib.csproj b/FFXIVClassic Common Class Lib/FFXIVClassic Common Class Lib.csproj index b30b954f..a2c8c826 100644 --- a/FFXIVClassic Common Class Lib/FFXIVClassic Common Class Lib.csproj +++ b/FFXIVClassic Common Class Lib/FFXIVClassic Common Class Lib.csproj @@ -10,7 +10,7 @@ Properties FFXIVClassic.Common FFXIVClassic.Common - v4.5 + v4.5.1 512 @@ -38,6 +38,26 @@ false true + + true + bin\Debug\ + DEBUG;TRACE + true + full + x64 + prompt + MinimumRecommendedRules.ruleset + + + bin\x64\Release\ + TRACE + true + true + pdbonly + x64 + prompt + MinimumRecommendedRules.ruleset + ..\packages\DotNetZip.1.10.1\lib\net20\DotNetZip.dll @@ -90,4 +110,4 @@ --> - + \ No newline at end of file diff --git a/FFXIVClassic Common Class Lib/app.config b/FFXIVClassic Common Class Lib/app.config index 143834c2..e418f4e3 100644 --- a/FFXIVClassic Common Class Lib/app.config +++ b/FFXIVClassic Common Class Lib/app.config @@ -1,9 +1,9 @@ - + - - + + - \ No newline at end of file + diff --git a/FFXIVClassic Lobby Server/FFXIVClassic Lobby Server.csproj b/FFXIVClassic Lobby Server/FFXIVClassic Lobby Server.csproj index 962c3676..ddd0697a 100644 --- a/FFXIVClassic Lobby Server/FFXIVClassic Lobby Server.csproj +++ b/FFXIVClassic Lobby Server/FFXIVClassic Lobby Server.csproj @@ -10,7 +10,7 @@ Properties FFXIVClassic_Lobby_Server FFXIVClassic_Lobby_Server - v4.5 + v4.5.1 512 false publish\ @@ -28,6 +28,7 @@ false true cc1ba6f5 + AnyCPU @@ -50,6 +51,28 @@ 4 true + + true + bin\Debug\ + DEBUG;TRACE + true + full + x64 + prompt + MinimumRecommendedRules.ruleset + true + + + bin\x64\Release\ + TRACE + true + true + pdbonly + x64 + prompt + MinimumRecommendedRules.ruleset + true + ..\packages\Cyotek.CircularBuffer.1.0.0.0\lib\net20\Cyotek.Collections.Generic.CircularBuffer.dll diff --git a/FFXIVClassic Lobby Server/app.config b/FFXIVClassic Lobby Server/app.config index 143834c2..e418f4e3 100644 --- a/FFXIVClassic Lobby Server/app.config +++ b/FFXIVClassic Lobby Server/app.config @@ -1,9 +1,9 @@ - + - - + + - \ No newline at end of file + diff --git a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj index e5f93603..ad15389b 100644 --- a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj +++ b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj @@ -40,6 +40,28 @@ Always + + true + bin\Debug\ + DEBUG;TRACE + true + full + x64 + prompt + MinimumRecommendedRules.ruleset + true + + + bin\x64\Release\ + TRACE + true + true + pdbonly + x64 + prompt + MinimumRecommendedRules.ruleset + true + ..\packages\Cyotek.CircularBuffer.1.0.0.0\lib\net20\Cyotek.Collections.Generic.CircularBuffer.dll diff --git a/FFXIVClassic Map Server/WorldManager.cs b/FFXIVClassic Map Server/WorldManager.cs index 77c61050..2ab4afff 100644 --- a/FFXIVClassic Map Server/WorldManager.cs +++ b/FFXIVClassic Map Server/WorldManager.cs @@ -511,7 +511,6 @@ namespace FFXIVClassic_Map_Server battleNpc.SetMod((uint)Modifier.Defense, reader.GetUInt32("def")); battleNpc.SetMod((uint)Modifier.Evasion, reader.GetUInt32("eva")); - battleNpc.dropListId = reader.GetUInt32("dropListId"); battleNpc.spellListId = reader.GetUInt32("spellListId"); battleNpc.skillListId = reader.GetUInt32("skillListId"); @@ -644,12 +643,48 @@ namespace FFXIVClassic_Map_Server battleNpc.SetMod((uint)Modifier.Defense, reader.GetUInt32("def")); battleNpc.SetMod((uint)Modifier.Evasion, reader.GetUInt32("eva")); + if (battleNpc.poolMods != null) + { + foreach (var a in battleNpc.poolMods.mobModList) + { + battleNpc.SetMobMod(a.Value.id, (long)(a.Value.value)); + } + foreach (var a in battleNpc.poolMods.modList) + { + battleNpc.SetMod(a.Key, (long)(a.Value.value)); + } + } + + if (battleNpc.genusMods != null) + { + foreach (var a in battleNpc.genusMods.mobModList) + { + battleNpc.SetMobMod(a.Key, (long)(a.Value.value)); + } + foreach (var a in battleNpc.genusMods.modList) + { + battleNpc.SetMod(a.Key, (long)(a.Value.value)); + } + } + + if(battleNpc.spawnMods != null) + { + foreach (var a in battleNpc.spawnMods.mobModList) + { + battleNpc.SetMobMod(a.Key, (long)(a.Value.value)); + } + + foreach (var a in battleNpc.spawnMods.modList) + { + battleNpc.SetMod(a.Key, (long)(a.Value.value)); + } + } + battleNpc.dropListId = reader.GetUInt32("dropListId"); battleNpc.spellListId = reader.GetUInt32("spellListId"); battleNpc.skillListId = reader.GetUInt32("skillListId"); - battleNpc.SetMaxHP(1000); - battleNpc.SetHP(1000); battleNpc.SetBattleNpcId(reader.GetUInt32("bnpcId")); + battleNpc.SetRespawnTime(reader.GetUInt32("respawnTime")); battleNpc.CalculateBaseStats(); battleNpc.RecalculateStats(); //battleNpc.SetMod((uint)Modifier.ResistFire, ) @@ -679,7 +714,7 @@ namespace FFXIVClassic_Map_Server try { conn.Open(); - var query = $"SELECT {primaryKey}, modId, modVal, isMobMod FROM {tableName} GROUP BY {primaryKey};"; + var query = $"SELECT {primaryKey}, modId, modVal, isMobMod FROM {tableName}"; MySqlCommand cmd = new MySqlCommand(query, conn); @@ -688,9 +723,9 @@ namespace FFXIVClassic_Map_Server while (reader.Read()) { var id = reader.GetUInt32(primaryKey); - ModifierList modList = new ModifierList(id); + ModifierList modList = list.TryGetValue(id, out modList) ? modList : new ModifierList(id); modList.SetModifier(reader.GetUInt16("modId"), reader.GetInt64("modVal"), reader.GetBoolean("isMobMod")); - list.Add(id, modList); + list[id] = modList; } } } diff --git a/FFXIVClassic Map Server/actors/Actor.cs b/FFXIVClassic Map Server/actors/Actor.cs index 15b70eb3..4e397668 100644 --- a/FFXIVClassic Map Server/actors/Actor.cs +++ b/FFXIVClassic Map Server/actors/Actor.cs @@ -438,9 +438,6 @@ namespace FFXIVClassic_Map_Server.Actors updateFlags = ActorUpdateFlags.None; zone.BroadcastPacketsAroundActor(this, packets); - - SetActorPropetyPacket hpInfo = new SetActorPropetyPacket("charaWork/exp"); - hpInfo.AddTarget(); } } diff --git a/FFXIVClassic Map Server/actors/area/Area.cs b/FFXIVClassic Map Server/actors/area/Area.cs index 2d245fe3..c44b71d4 100644 --- a/FFXIVClassic Map Server/actors/area/Area.cs +++ b/FFXIVClassic Map Server/actors/area/Area.cs @@ -419,8 +419,8 @@ namespace FFXIVClassic_Map_Server.Actors public virtual List GetMonsters() { return GetAllActors(); - } - + } + public virtual List GetAllies() { return GetAllActors(); @@ -500,8 +500,8 @@ namespace FFXIVClassic_Map_Server.Actors npc = new Npc(mActorList.Count + 1, actorClass, uniqueId, this, x, y, z, rot, state, animId, null); npc.LoadEventConditions(actorClass.eventConditions); - npc.SetMaxHP(300); - npc.SetHP(300); + //npc.SetMaxHP(30000); + //npc.SetHP(30000); AddActorToZone(npc); @@ -669,12 +669,12 @@ namespace FFXIVClassic_Map_Server.Actors { foreach (Actor a in mActorList.Values.ToList()) a.Update(tick); - + if ((tick - lastUpdateScript).TotalMilliseconds > 1500) { - LuaEngine.GetInstance().CallLuaFunctionForReturn(LuaEngine.GetScriptPath(this), "onUpdate", true, this, tick); + //LuaEngine.GetInstance().CallLuaFunctionForReturn(LuaEngine.GetScriptPath(this), "onUpdate", true, this, tick); lastUpdateScript = tick; - } + } } } diff --git a/FFXIVClassic Map Server/actors/area/Zone.cs b/FFXIVClassic Map Server/actors/area/Zone.cs index 1286657f..07c2937f 100644 --- a/FFXIVClassic Map Server/actors/area/Zone.cs +++ b/FFXIVClassic Map Server/actors/area/Zone.cs @@ -132,6 +132,18 @@ namespace FFXIVClassic_Map_Server.actors.area return actor; } } + + foreach (List paList in contentAreas.Values) + { + foreach (PrivateArea pa in paList) + { + Actor actor = pa.FindActorInArea(id); + if (actor != null) + return actor; + } + } + + return null; } else @@ -184,7 +196,7 @@ namespace FFXIVClassic_Map_Server.actors.area { if (this.pathCalls > 0) { - Program.Log.Debug("Number of pathfinding calls {0} average time {1}ms", pathCalls, (float)(pathCallTime / pathCalls)); + Program.Log.Debug("Number of pathfinding calls {0} average time {1}ms", pathCalls, (float)(pathCallTime / pathCalls)); } lastUpdate = tick; } diff --git a/FFXIVClassic Map Server/actors/chara/Character.cs b/FFXIVClassic Map Server/actors/chara/Character.cs index 6c497bdf..491792b0 100644 --- a/FFXIVClassic Map Server/actors/chara/Character.cs +++ b/FFXIVClassic Map Server/actors/chara/Character.cs @@ -229,10 +229,10 @@ namespace FFXIVClassic_Map_Server.Actors public void DoBattleAction(ushort commandId, uint animationId, BattleAction[] actions) { int currentIndex = 0; - + //AoE abilities only ever hit 16 people, so we probably won't need this loop anymore while (true) { - if (actions.Length - currentIndex >= 18) + if (actions.Length - currentIndex >= 10) zone.BroadcastPacketAroundActor(this, BattleActionX18Packet.BuildPacket(actorId, animationId, commandId, actions, ref currentIndex)); else if (actions.Length - currentIndex > 1) zone.BroadcastPacketAroundActor(this, BattleActionX10Packet.BuildPacket(actorId, animationId, commandId, actions, ref currentIndex)); @@ -243,7 +243,9 @@ namespace FFXIVClassic_Map_Server.Actors } else break; - animationId = 0; //If more than one packet is sent out, only send the animation once to avoid double playing. + + //I think aoe effects play on all hit enemies. Firaga does at least + //animationId = 0; //If more than one packet is sent out, only send the animation once to avoid double playing. } } @@ -298,7 +300,7 @@ namespace FFXIVClassic_Map_Server.Actors public virtual void OnPath(Vector3 point) { - lua.LuaEngine.CallLuaBattleFunction(this, "onPath", this, point); + //lua.LuaEngine.CallLuaBattleFunction(this, "onPath", this, point); updateFlags |= ActorUpdateFlags.Position; this.isAtSpawn = false; @@ -332,7 +334,7 @@ namespace FFXIVClassic_Map_Server.Actors if ((updateFlags & ActorUpdateFlags.HpTpMp) != 0) { - var propPacketUtil = new ActorPropertyPacketUtil("charaWork.parameterSave", this); + var propPacketUtil = new ActorPropertyPacketUtil("charaWork/stateAtQuicklyForAll", this); propPacketUtil.AddProperty("charaWork.parameterSave.mp"); propPacketUtil.AddProperty("charaWork.parameterSave.mpMax"); @@ -455,6 +457,7 @@ namespace FFXIVClassic_Map_Server.Actors { // todo: actual despawn timer aiContainer.InternalDie(tick, 10); + ChangeSpeed(0.0f, 0.0f, 0.0f, 0.0f); } public virtual void Despawn(DateTime tick) @@ -528,6 +531,20 @@ namespace FFXIVClassic_Map_Server.Actors updateFlags |= ActorUpdateFlags.HpTpMp; } + public void SetMP(uint mp) + { + charaWork.parameterSave.mpMax = (short)mp; + if (mp > charaWork.parameterSave.hpMax[0]) + SetMaxMP(mp); + + updateFlags |= ActorUpdateFlags.HpTpMp; + } + + public void SetMaxMP(uint mp) + { + charaWork.parameterSave.mp = (short)mp; + updateFlags |= ActorUpdateFlags.HpTpMp; + } // todo: the following functions are virtuals since we want to check hidden item bonuses etc on player for certain conditions public virtual void AddHP(int hp) { @@ -547,7 +564,7 @@ namespace FFXIVClassic_Map_Server.Actors } } - public short GetJob() + public short GetClass() { return charaWork.parameterSave.state_mainSkill[0]; } @@ -599,8 +616,30 @@ namespace FFXIVClassic_Map_Server.Actors public void RecalculateStats() { - if (GetMod((uint)Modifier.Hp) != 0) + uint hpMod = (uint) GetMod((uint)Modifier.Hp); + if (hpMod != 0) { + SetMaxHP(hpMod); + uint hpp = (uint) GetMod((uint) Modifier.HpPercent); + uint hp = hpMod; + if(hpp != 0) + { + hp = (uint) Math.Ceiling(((float)hpp / 100.0f) * hpMod); + } + SetHP(hp); + } + + uint mpMod = (uint)GetMod((uint)Modifier.Mp); + if (mpMod != 0) + { + SetMaxMP(mpMod); + uint mpp = (uint)GetMod((uint)Modifier.MpPercent); + uint mp = mpMod; + if (mpp != 0) + { + mp = (uint)Math.Ceiling(((float)mpp / 100.0f) * mpMod); + } + SetMP(mp); } // todo: recalculate stats and crap updateFlags |= ActorUpdateFlags.HpTpMp; @@ -635,14 +674,8 @@ 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); } - target.OnDamageTaken(this, action, DamageTakenType.Ability); // todo: call onAttack/onDamageTaken - target.DelHP(action.amount); - if (target is BattleNpc) - { - ((BattleNpc)target).lastAttacker = this; - ((BattleNpc)target).hateContainer.UpdateHate(this, action.amount); - } + BattleUtils.DamageTarget(this, target, action, DamageTakenType.Attack); AddTP(115); target.AddTP(100); } @@ -651,13 +684,14 @@ namespace FFXIVClassic_Map_Server.Actors { var spell = ((MagicState)state).GetSpell(); // damage is handled in script - this.DelMP(spell.mpCost); // mpCost can be set in script e.g. if caster has something for free spells + var spellCost = spell.CalculateCost((uint)this.GetLevel()); + this.DelMP(spellCost); // mpCost can be set in script e.g. if caster has something for free spells - foreach (var action in actions) - zone.FindActorInArea(action.targetId).OnDamageTaken(this, action, DamageTakenType.Magic); + foreach (BattleAction action in actions) + if (zone.FindActorInArea(action.targetId) is Character chara) + BattleUtils.DamageTarget(this, chara, action, DamageTakenType.Magic); - if (target is BattleNpc) - ((BattleNpc)target).lastAttacker = this; + lua.LuaEngine.GetInstance().OnSignal("spellUsed"); } public virtual void OnWeaponSkill(State state, BattleAction[] actions, ref BattleAction[] errors) @@ -666,11 +700,11 @@ namespace FFXIVClassic_Map_Server.Actors // damage is handled in script this.DelTP(skill.tpCost); - foreach (var action in actions) - zone.FindActorInArea(action.targetId)?.OnDamageTaken(this, action, DamageTakenType.Weaponskill); + foreach (BattleAction action in actions) + if (zone.FindActorInArea(action.targetId) is Character chara) + BattleUtils.DamageTarget(this, chara, action, DamageTakenType.Weaponskill); - if (target is BattleNpc) - ((BattleNpc)target).lastAttacker = this; + lua.LuaEngine.GetInstance().OnSignal("weaponskillUsed"); } public virtual void OnAbility(State state, BattleAction[] actions, ref BattleAction[] errors) @@ -756,22 +790,22 @@ namespace FFXIVClassic_Map_Server.Actors public bool IsDiscipleOfWar() { - return currentJob < CLASSID_THM; + return GetClass() < CLASSID_THM; } public bool IsDiscipleOfMagic() { - return currentJob >= CLASSID_THM && currentJob < CLASSID_CRP; + return GetClass() >= CLASSID_THM && currentJob < CLASSID_CRP; } public bool IsDiscipleOfHand() { - return currentJob >= CLASSID_CRP && currentJob < CLASSID_MIN; + return GetClass() >= CLASSID_CRP && currentJob < CLASSID_MIN; } public bool IsDiscipleOfLand() { - return currentJob >= CLASSID_MIN; + return GetClass() >= CLASSID_MIN; } #endregion lua helpers #endregion ai stuff diff --git a/FFXIVClassic Map Server/actors/chara/ai/controllers/AllyController.cs b/FFXIVClassic Map Server/actors/chara/ai/controllers/AllyController.cs index 5f748f72..4098e2bb 100644 --- a/FFXIVClassic Map Server/actors/chara/ai/controllers/AllyController.cs +++ b/FFXIVClassic Map Server/actors/chara/ai/controllers/AllyController.cs @@ -5,6 +5,7 @@ using System.Text; using System.Threading.Tasks; using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.actors.chara.npc; +using FFXIVClassic.Common; namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers { @@ -17,10 +18,11 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers { this.owner = owner; } - - // server really likes to hang whenever scripts iterate area's actorlist - protected override void DoCombatTick(DateTime tick, List contentGroupCharas = null) + + protected List GetContentGroupCharas() { + List contentGroupCharas = null; + if (owner.currentContentGroup != null) { contentGroupCharas = new List(owner.currentContentGroup.GetMemberCount()); @@ -32,20 +34,46 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers contentGroupCharas.Add(chara); } } + + return contentGroupCharas; + } + + //Iterate over players in the group and if they are fighting, assist them + protected override void TryAggro(DateTime tick) + { + //lua.LuaEngine.CallLuaBattleFunction(owner, "tryAggro", owner, GetContentGroupCharas()); + + foreach(Character chara in GetContentGroupCharas()) + { + if(chara.IsPlayer()) + { + if(owner.aiContainer.GetTargetFind().CanTarget((Character) chara.target) && chara.target is BattleNpc && ((BattleNpc)chara.target).hateContainer.HasHateForTarget(chara)) + { + owner.Engage(chara.target.actorId); + owner.hateContainer.AddBaseHate((Character) chara.target); + break; + } + } + } + //base.TryAggro(tick); + } + + // server really likes to hang whenever scripts iterate area's actorlist + protected override void DoCombatTick(DateTime tick, List contentGroupCharas = null) + { + if (contentGroupCharas == null) + { + contentGroupCharas = GetContentGroupCharas(); + } + base.DoCombatTick(tick, contentGroupCharas); } + protected override void DoRoamTick(DateTime tick, List contentGroupCharas = null) { - if (owner.currentContentGroup != null) + if (contentGroupCharas == null) { - contentGroupCharas = new List(owner.currentContentGroup.GetMemberCount()); - foreach (var charaId in owner.currentContentGroup.GetMembers()) - { - var chara = owner.zone.FindActorInArea(charaId); - - if (chara != null) - contentGroupCharas.Add(chara); - } + contentGroupCharas = GetContentGroupCharas(); } base.DoRoamTick(tick, contentGroupCharas); } diff --git a/FFXIVClassic Map Server/actors/chara/ai/controllers/BattleNpcController.cs b/FFXIVClassic Map Server/actors/chara/ai/controllers/BattleNpcController.cs index 19356009..6711ccad 100644 --- a/FFXIVClassic Map Server/actors/chara/ai/controllers/BattleNpcController.cs +++ b/FFXIVClassic Map Server/actors/chara/ai/controllers/BattleNpcController.cs @@ -39,12 +39,20 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers public override void Update(DateTime tick) { lastUpdate = tick; + // todo: handle aggro/deaggro and other shit here - if (owner.aiContainer.IsEngaged()) + if (!owner.aiContainer.IsEngaged()) { - DoCombatTick(tick); + TryAggro(tick); } - else if (!owner.IsDead()) + + if(owner.aiContainer.IsEngaged()) + { + //DoCombatTick(tick); + } + + //Only move if owner isn't dead and is either too far away from their spawn point or is meant to roam + if (!owner.IsDead() && (owner.isMovingToSpawn || owner.GetMobMod((uint) MobModifier.Roams) > 0)) { DoRoamTick(tick); } @@ -63,6 +71,38 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers return false; } + //If the owner isn't moving to spawn, iterate over nearby enemies and + //aggro the first one that is within 10 levels and can be detected, then engage + protected virtual void TryAggro(DateTime tick) + { + if (tick >= neutralTime && !owner.isMovingToSpawn) + { + if (!owner.neutral && owner.IsAlive()) + { + foreach (var chara in owner.zone.GetActorsAroundActor(owner, 50)) + { + if (owner.allegiance == chara.allegiance) + continue; + + if (owner.aiContainer.pathFind.AtPoint() && owner.detectionType != DetectionType.None) + { + uint levelDifference = (uint)Math.Abs(owner.GetLevel() - chara.GetLevel()); + + if (levelDifference <= 10 || (owner.detectionType & DetectionType.IgnoreLevelDifference) != 0 && CanAggroTarget(chara)) + { + owner.hateContainer.AddBaseHate(chara); + break; + } + } + } + } + } + + if (owner.hateContainer.GetHateList().Count > 0) + { + Engage(owner.hateContainer.GetMostHatedTarget()); + } + } public override bool Engage(Character target) { var canEngage = this.owner.aiContainer.InternalEngage(target); @@ -77,6 +117,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers owner.ChangeState(SetActorStatePacket.MAIN_STATE_ACTIVE); owner.moveState = 2; + //owner.SetMod((uint)Modifier.Speed, 5); lastActionTime = DateTime.Now; battleStartTime = lastActionTime; // todo: adjust cooldowns with modifiers @@ -127,12 +168,6 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers protected virtual void DoRoamTick(DateTime tick, List contentGroupCharas = null) { - if (owner.hateContainer.GetHateList().Count > 0) - { - Engage(owner.hateContainer.GetMostHatedTarget()); - return; - } - if (tick >= waitTime) { neutralTime = tick.AddSeconds(5); @@ -148,7 +183,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers } } - waitTime = tick.AddSeconds(10); + waitTime = tick.AddSeconds(owner.GetMobMod((uint) MobModifier.RoamDelay)); owner.OnRoam(tick); if (CanMoveForward(0.0f) && !owner.aiContainer.pathFind.IsFollowingPath()) @@ -157,31 +192,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers owner.aiContainer.pathFind.SetPathFlags(PathFindFlags.None); owner.aiContainer.pathFind.PathInRange(owner.spawnX, owner.spawnY, owner.spawnZ, 1.5f, 50.0f); } - lua.LuaEngine.CallLuaBattleFunction(owner, "onRoam", owner, contentGroupCharas); - } - - - if (tick >= neutralTime) - { - if (!owner.neutral && owner.IsAlive()) - { - foreach (var chara in owner.zone.GetActorsAroundActor(owner, 50)) - { - if (owner.allegiance == chara.allegiance) - continue; - - if (!owner.isMovingToSpawn && owner.aiContainer.pathFind.AtPoint() && owner.detectionType != DetectionType.None) - { - uint levelDifference = (uint)Math.Abs(owner.GetLevel() - chara.GetLevel()); - - if (levelDifference <= 10 || (owner.detectionType & DetectionType.IgnoreLevelDifference) != 0 && CanAggroTarget(chara)) - { - owner.hateContainer.AddBaseHate(chara); - break; - } - } - } - } + //lua.LuaEngine.CallLuaBattleFunction(owner, "onRoam", owner, contentGroupCharas); } if (owner.aiContainer.pathFind.IsFollowingPath() && owner.aiContainer.CanFollowPath()) @@ -200,7 +211,9 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers return; } + Move(); + if ((tick - lastCombatTickScript).TotalSeconds > 2) { lua.LuaEngine.CallLuaBattleFunction(owner, "onCombatTick", owner, owner.target, Utils.UnixTimeStampUTC(tick), contentGroupCharas); diff --git a/FFXIVClassic Map Server/actors/chara/ai/helpers/TargetFind.cs b/FFXIVClassic Map Server/actors/chara/ai/helpers/TargetFind.cs index 585dafb9..ab374ea3 100644 --- a/FFXIVClassic Map Server/actors/chara/ai/helpers/TargetFind.cs +++ b/FFXIVClassic Map Server/actors/chara/ai/helpers/TargetFind.cs @@ -159,6 +159,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai /// public void FindWithinArea(Character target, ValidTarget flags, TargetFindAOETarget aoeTarget) { + targets.Clear(); validTarget = flags; // are we creating aoe circles around target or self if (aoeTarget == TargetFindAOETarget.Self) @@ -174,59 +175,63 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai if (masterTarget != null) targets.Add(masterTarget); - if (IsPlayer(owner)) + if (aoeType != TargetFindAOEType.None) { - if (masterTarget is Player) + if (IsPlayer(owner)) { - findType = TargetFindCharacterType.PlayerToPlayer; - - if (masterTarget.currentParty != null) + if (masterTarget is Player) { - if ((validTarget & (ValidTarget.Ally | ValidTarget.PartyMember)) != 0) - AddAllInAlliance(masterTarget, withPet); + findType = TargetFindCharacterType.PlayerToPlayer; + + if (masterTarget.currentParty != null) + { + if ((validTarget & (ValidTarget.Ally | ValidTarget.PartyMember)) != 0) + AddAllInAlliance(masterTarget, withPet); + else + AddAllInParty(masterTarget, withPet); + } else - AddAllInParty(masterTarget, withPet); + { + AddTarget(masterTarget, withPet); + } } else { - AddTarget(masterTarget, withPet); + findType = TargetFindCharacterType.PlayerToBattleNpc; + AddAllBattleNpcs(masterTarget, false); } } else { - findType = TargetFindCharacterType.PlayerToBattleNpc; - AddAllBattleNpcs(masterTarget, false); - } - } - else - { - // todo: this needs checking.. - if (masterTarget is Player || owner.allegiance == CharacterTargetingAllegiance.Player) - findType = TargetFindCharacterType.BattleNpcToPlayer; - else - findType = TargetFindCharacterType.BattleNpcToBattleNpc; - - // todo: configurable pet aoe buff - if (findType == TargetFindCharacterType.BattleNpcToBattleNpc && TryGetMasterTarget(target) != null) - withPet = true; - - // todo: does ffxiv have call for help flag? - //if ((findFlags & ValidTarget.HitAll) != 0) - //{ - // AddAllInZone(masterTarget, withPet); - //} - - AddAllInAlliance(target, withPet); - - if (findType == TargetFindCharacterType.BattleNpcToPlayer) - { - if (owner.allegiance == CharacterTargetingAllegiance.Player) - AddAllInZone(masterTarget, withPet); + // todo: this needs checking.. + if (masterTarget is Player || owner.allegiance == CharacterTargetingAllegiance.Player) + findType = TargetFindCharacterType.BattleNpcToPlayer; else - AddAllInHateList(); + findType = TargetFindCharacterType.BattleNpcToBattleNpc; + + // todo: configurable pet aoe buff + if (findType == TargetFindCharacterType.BattleNpcToBattleNpc && TryGetMasterTarget(target) != null) + withPet = true; + + // todo: does ffxiv have call for help flag? + //if ((findFlags & ValidTarget.HitAll) != 0) + //{ + // AddAllInZone(masterTarget, withPet); + //} + + AddAllInAlliance(target, withPet); + + if (findType == TargetFindCharacterType.BattleNpcToPlayer) + { + if (owner.allegiance == CharacterTargetingAllegiance.Player) + AddAllInZone(masterTarget, withPet); + else + AddAllInHateList(); + } } } - + if(targets.Count > 16) + targets.RemoveRange(16, targets.Count - 16); } /// @@ -288,7 +293,8 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai private void AddAllBattleNpcs(Character target, bool withPet) { - var actors = owner.zone.GetActorsAroundActor(owner, 50); + int dist = (int)maxDistance; + var actors = owner.zone.GetActorsAroundActor(target, dist); foreach (BattleNpc actor in actors) { @@ -375,12 +381,13 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai private bool IsWithinCircle(Character target, float maxDistance) { // todo: make y diff modifiable? - if (Math.Abs(owner.positionX - target.positionY) > 6.0f) - return false; + + //if (Math.Abs(owner.positionX - target.positionY) > 6.0f) + // return false; if (this.targetPosition == null) this.targetPosition = aoeTarget == TargetFindAOETarget.Self ? owner.GetPosAsVector3() : masterTarget.GetPosAsVector3(); - return target.GetPosAsVector3().IsWithinCircle(targetPosition, param); + return target.GetPosAsVector3().IsWithinCircle(targetPosition, maxDistance); } private bool IsPlayer(Character target) diff --git a/FFXIVClassic Map Server/actors/chara/ai/state/AttackState.cs b/FFXIVClassic Map Server/actors/chara/ai/state/AttackState.cs index 79f63178..56087d39 100644 --- a/FFXIVClassic Map Server/actors/chara/ai/state/AttackState.cs +++ b/FFXIVClassic Map Server/actors/chara/ai/state/AttackState.cs @@ -129,6 +129,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state private bool CanAttack() { + return false; if (!owner.isAutoAttackEnabled) { return false; diff --git a/FFXIVClassic Map Server/actors/chara/ai/state/DeathState.cs b/FFXIVClassic Map Server/actors/chara/ai/state/DeathState.cs index 0bb584bf..61d76a62 100644 --- a/FFXIVClassic Map Server/actors/chara/ai/state/DeathState.cs +++ b/FFXIVClassic Map Server/actors/chara/ai/state/DeathState.cs @@ -15,7 +15,9 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state : base(owner, null) { owner.Disengage(); - owner.ChangeState(SetActorStatePacket.MAIN_STATE_DEAD2); + //owner.ChangeState(SetActorStatePacket.MAIN_STATE_DEAD2); + var deathStatePacket = SetActorStatePacket.BuildPacket(owner.actorId, SetActorStatePacket.MAIN_STATE_DEAD, owner.currentSubState); + owner.zone.BroadcastPacketAroundActor(owner, deathStatePacket); canInterrupt = false; startTime = tick; despawnTime = startTime.AddSeconds(timeToFadeOut); diff --git a/FFXIVClassic Map Server/actors/chara/ai/state/MagicState.cs b/FFXIVClassic Map Server/actors/chara/ai/state/MagicState.cs index 9d40df1b..8e28554e 100644 --- a/FFXIVClassic Map Server/actors/chara/ai/state/MagicState.cs +++ b/FFXIVClassic Map Server/actors/chara/ai/state/MagicState.cs @@ -110,16 +110,16 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state var i = 0; foreach (var chara in targets) { - var action = new BattleAction(target.actorId, spell.worldMasterTextId, spell.battleAnimation, 0, (byte)HitDirection.None, 1); + var action = new BattleAction(chara.actorId, spell.worldMasterTextId, spell.battleAnimation, 0, (byte)HitDirection.None, 1); action.amount = (ushort)lua.LuaEngine.CallLuaBattleCommandFunction(owner, spell, "magic", "onMagicFinish", owner, chara, spell, action); actions[i++] = action; } // 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); + } public override void TryInterrupt() diff --git a/FFXIVClassic Map Server/actors/chara/ai/state/WeaponSkillState.cs b/FFXIVClassic Map Server/actors/chara/ai/state/WeaponSkillState.cs index f918c8be..f9bbefad 100644 --- a/FFXIVClassic Map Server/actors/chara/ai/state/WeaponSkillState.cs +++ b/FFXIVClassic Map Server/actors/chara/ai/state/WeaponSkillState.cs @@ -88,7 +88,6 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state { skill.targetFind.FindWithinArea(target, skill.validTarget, skill.aoeTarget); isCompleted = true; - var targets = skill.targetFind.GetTargets(); BattleAction[] actions = new BattleAction[targets.Count]; @@ -100,11 +99,11 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state // 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); actions[i++] = action; + chara.Engage(chara.actorId, 1); } // 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, skill.battleAnimation, actions); } diff --git a/FFXIVClassic Map Server/actors/chara/ai/utils/BattleUtils.cs b/FFXIVClassic Map Server/actors/chara/ai/utils/BattleUtils.cs index 37a7197e..ed2a1050 100644 --- a/FFXIVClassic Map Server/actors/chara/ai/utils/BattleUtils.cs +++ b/FFXIVClassic Map Server/actors/chara/ai/utils/BattleUtils.cs @@ -76,18 +76,24 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.utils return damage; } - public static void DamageTarget(Character attacker, Character defender, BattleAction action) + public static void DamageTarget(Character attacker, Character defender, BattleAction action, DamageTakenType type) { - // todo: other stuff too - if (defender is BattleNpc) + if (defender != null) { - if (!((BattleNpc)defender).hateContainer.HasHateForTarget(attacker)) + // todo: other stuff too + if (defender is BattleNpc) { - ((BattleNpc)defender).hateContainer.AddBaseHate(attacker); + var bnpc = defender as BattleNpc; + if (!bnpc.hateContainer.HasHateForTarget(attacker)) + { + bnpc.hateContainer.AddBaseHate(attacker); + } + bnpc.hateContainer.UpdateHate(attacker, action.amount); + bnpc.lastAttacker = attacker; } - ((BattleNpc)defender).hateContainer.UpdateHate(attacker, action.amount); + defender.DelHP((short)action.amount); + defender.OnDamageTaken(attacker, action, type); } - defender.DelHP((short)action.amount); } public static int CalculateSpellDamage(Character attacker, Character defender, BattleCommand spell) diff --git a/FFXIVClassic Map Server/actors/chara/npc/BattleNpc.cs b/FFXIVClassic Map Server/actors/chara/npc/BattleNpc.cs index 160f8050..4b94313a 100644 --- a/FFXIVClassic Map Server/actors/chara/npc/BattleNpc.cs +++ b/FFXIVClassic Map Server/actors/chara/npc/BattleNpc.cs @@ -172,7 +172,7 @@ namespace FFXIVClassic_Map_Server.Actors packets = new List(); if ((updateFlags & ActorUpdateFlags.HpTpMp) != 0) { - var propPacketUtil = new ActorPropertyPacketUtil("charaWork.parameterSave", this); + var propPacketUtil = new ActorPropertyPacketUtil("charaWork/stateAtQuicklyForAll", this); propPacketUtil.AddProperty("charaWork.parameterSave.hp[0]"); propPacketUtil.AddProperty("charaWork.parameterSave.hpMax[0]"); @@ -272,6 +272,10 @@ namespace FFXIVClassic_Map_Server.Actors if (lastAttacker is Player) { + //I think this is, or should be odne in DoBattleAction. Packet capture had the message in the same packet as an attack + // defeat/defeats + //((Player)lastAttacker).QueuePacket(BattleActionX01Packet.BuildPacket(lastAttacker.actorId, 0, 0, new BattleAction(actorId, 30108, 0))); + if (lastAttacker.currentParty != null && lastAttacker.currentParty is Party) { foreach (var memberId in ((Party)lastAttacker.currentParty).members) @@ -279,14 +283,9 @@ namespace FFXIVClassic_Map_Server.Actors var partyMember = zone.FindActorInArea(memberId); // onDeath(monster, player, killer) lua.LuaEngine.CallLuaBattleFunction(this, "onDeath", this, partyMember, lastAttacker); - // defeat/defeats - - if (lastAttacker is Player) - ((Player)lastAttacker).QueuePacket(BattleActionX01Packet.BuildPacket(lastAttacker.actorId, 0, 0, new BattleAction(actorId, 30108, 0))); - - if(partyMember is Player) - ((Player)partyMember).AddExp(1500, (byte)partyMember.GetJob(), 5); + if (partyMember is Player) + ((Player)partyMember).AddExp(1500, (byte)partyMember.GetClass(), 5); } } else @@ -298,6 +297,7 @@ namespace FFXIVClassic_Map_Server.Actors } positionUpdates?.Clear(); aiContainer.InternalDie(tick, despawnTime); + //this.ResetMoveSpeeds(); // todo: reset cooldowns lua.LuaEngine.GetInstance().OnSignal("mobkill"); diff --git a/FFXIVClassic Map Server/actors/chara/npc/MobModifier.cs b/FFXIVClassic Map Server/actors/chara/npc/MobModifier.cs index 21a75d53..fe2600e6 100644 --- a/FFXIVClassic Map Server/actors/chara/npc/MobModifier.cs +++ b/FFXIVClassic Map Server/actors/chara/npc/MobModifier.cs @@ -32,5 +32,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.npc AbilityScript = 21, // call my script's onAbility whenever i finish using an ability CallForHelp = 22, // actor with this id outside of target's party with this can attack me FreeForAll = 23, // any actor can attack me + Roams = 24, // Do I walk around? + RoamDelay = 25 // What is the delay between roam ticks } } \ No newline at end of file diff --git a/FFXIVClassic Map Server/actors/chara/player/Player.cs b/FFXIVClassic Map Server/actors/chara/player/Player.cs index f71843b8..5ac7fd6d 100644 --- a/FFXIVClassic Map Server/actors/chara/player/Player.cs +++ b/FFXIVClassic Map Server/actors/chara/player/Player.cs @@ -557,6 +557,9 @@ namespace FFXIVClassic_Map_Server.Actors if (currentContentGroup != null) currentContentGroup.SendGroupPackets(playerSession); + + if (currentParty != null) + currentParty.SendGroupPackets(playerSession); } private void SendRemoveInventoryPackets(List slots) @@ -1625,7 +1628,7 @@ namespace FFXIVClassic_Map_Server.Actors //Update Instance List aroundMe = new List(); - if (zone != null) + if (zone != null) aroundMe.AddRange(zone.GetActorsAroundActor(this, 50)); if (zone2 != null) aroundMe.AddRange(zone2.GetActorsAroundActor(this, 50)); @@ -1714,6 +1717,7 @@ namespace FFXIVClassic_Map_Server.Actors //currentParty.members.Remove(this); if (partyGroup.members.Count == 0) Server.GetWorldManager().NoMembersInParty((Party)currentParty); + currentParty = null; } @@ -1755,7 +1759,7 @@ namespace FFXIVClassic_Map_Server.Actors if ((updateFlags & ActorUpdateFlags.HpTpMp) != 0) { - var propPacketUtil = new ActorPropertyPacketUtil("charaWork.parameterSave", this); + var propPacketUtil = new ActorPropertyPacketUtil("charaWork/stateAtQuicklyForAll", this); // todo: should this be using job as index? propPacketUtil.AddProperty($"charaWork.parameterSave.hp[{0}]"); @@ -1768,9 +1772,6 @@ namespace FFXIVClassic_Map_Server.Actors } base.PostUpdate(tick, packets); - SetActorPropetyPacket hpInfo = new SetActorPropetyPacket("charaWork/exp"); - hpInfo.AddTarget(); - QueuePacket(hpInfo.BuildPacket(actorId)); } public override void Die(DateTime tick) @@ -1801,7 +1802,6 @@ namespace FFXIVClassic_Map_Server.Actors public void UpdateHotbarCommands(List slotsToUpdate) { ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("charaWork/command", this); - ActorPropertyPacketUtil compatibiltyUtil = new ActorPropertyPacketUtil("charaWork/commandDetailForSelf", this); foreach (ushort slot in slotsToUpdate) { propPacketUtil.AddProperty($"charaWork.command[{slot}]"); @@ -2184,9 +2184,9 @@ namespace FFXIVClassic_Map_Server.Actors { // 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 - + // todo: should just make a thing that updates the one slot cause this is dumb as hell UpdateHotbarTimer(spell.id, spell.recastTimeSeconds); LuaEngine.GetInstance().OnSignal("spellUse"); } @@ -2309,27 +2309,23 @@ namespace FFXIVClassic_Map_Server.Actors Database.LoadHotbar(this); } + //Gets the id of the player's current job. If they aren't a job, gets the id of their class public byte GetCurrentClassOrJob() { if (currentJob != 0) return (byte) currentJob; - return charaWork.parameterSave.state_mainSkill[0]; } public void hpstuff(uint hp) { SetMaxHP(hp); - SetHP(hp); + SetHP(hp); mpMaxBase = (ushort)hp; charaWork.parameterSave.mpMax = (short)hp; charaWork.parameterSave.mp = (short)hp; - AddTP(0); - //SendCharaExpInfo(); - //ActorPropertyPacketUtil exp = new ActorPropertyPacketUtil("charaWork/exp", this); - SetActorPropetyPacket hpInfo = new SetActorPropetyPacket("charaWork/exp"); - hpInfo.AddTarget(); - QueuePacket(hpInfo.BuildPacket(actorId)); + AddTP(3000); + updateFlags |= ActorUpdateFlags.HpTpMp; } } diff --git a/FFXIVClassic Map Server/actors/director/Director.cs b/FFXIVClassic Map Server/actors/director/Director.cs index 04d1740f..e2a566a6 100644 --- a/FFXIVClassic Map Server/actors/director/Director.cs +++ b/FFXIVClassic Map Server/actors/director/Director.cs @@ -161,6 +161,9 @@ namespace FFXIVClassic_Map_Server.actors.director { members.Add(actor); + if (actor is Player) + ((Player)actor).AddDirector(this); + if (contentGroup != null) contentGroup.AddMember(actor); } diff --git a/FFXIVClassic Map Server/actors/group/ContentGroup.cs b/FFXIVClassic Map Server/actors/group/ContentGroup.cs index bebeb49c..950bbad0 100644 --- a/FFXIVClassic Map Server/actors/group/ContentGroup.cs +++ b/FFXIVClassic Map Server/actors/group/ContentGroup.cs @@ -42,6 +42,7 @@ namespace FFXIVClassic_Map_Server.actors.group public void Start() { isStarted = true; + SendGroupPacketsAll(members); } @@ -50,7 +51,8 @@ namespace FFXIVClassic_Map_Server.actors.group if (actor == null) return; - members.Add(actor.actorId); + if(!members.Contains(actor.actorId)) + members.Add(actor.actorId); if (actor is Character) ((Character)actor).SetCurrentContentGroup(this); @@ -121,7 +123,6 @@ namespace FFXIVClassic_Map_Server.actors.group } session.QueuePacket(GroupMembersEndPacket.buildPacket(session.id, session.GetActor().zoneId, time, this)); - } public override uint GetTypeId() diff --git a/FFXIVClassic Map Server/actors/group/Party.cs b/FFXIVClassic Map Server/actors/group/Party.cs index 436cc9d9..385c5a77 100644 --- a/FFXIVClassic Map Server/actors/group/Party.cs +++ b/FFXIVClassic Map Server/actors/group/Party.cs @@ -63,12 +63,24 @@ namespace FFXIVClassic_Map_Server.actors.group List groupMembers = new List(); groupMembers.Add(new GroupMember(id, -1, 0, false, true, Server.GetWorldManager().GetActorInWorld(id).customDisplayName)); foreach (uint charaId in members) - { - if (charaId != id) - groupMembers.Add(new GroupMember(charaId, -1, 0, false, true, Server.GetWorldManager().GetActorInWorld(charaId).customDisplayName)); + { + var chara = Server.GetWorldManager().GetActorInWorld(charaId); + if (charaId != id && chara != null) + groupMembers.Add(new GroupMember(charaId, -1, 0, false, true, chara.customDisplayName)); } return groupMembers; } + public void AddMember(uint memberId) + { + members.Add(memberId); + SendGroupPacketsAll(members); + } + + public void RemoveMember(uint memberId) + { + members.Remove(memberId); + SendGroupPacketsAll(members); + } } } diff --git a/FFXIVClassic Map Server/dataobjects/ZoneConnection.cs b/FFXIVClassic Map Server/dataobjects/ZoneConnection.cs index 4a7fcc98..786a604d 100644 --- a/FFXIVClassic Map Server/dataobjects/ZoneConnection.cs +++ b/FFXIVClassic Map Server/dataobjects/ZoneConnection.cs @@ -24,7 +24,7 @@ namespace FFXIVClassic_Map_Server.dataobjects public void FlushQueuedSendPackets() { - if (!socket.Connected) + if (socket == null || !socket.Connected) return; while (SendPacketQueue.Count > 0) diff --git a/FFXIVClassic Map Server/lua/LuaEngine.cs b/FFXIVClassic Map Server/lua/LuaEngine.cs index 7d28ab28..d4f50f72 100644 --- a/FFXIVClassic Map Server/lua/LuaEngine.cs +++ b/FFXIVClassic Map Server/lua/LuaEngine.cs @@ -478,10 +478,18 @@ namespace FFXIVClassic_Map_Server.lua { if (!script.Globals.Get(funcName).IsNil()) { - Coroutine coroutine = script.CreateCoroutine(script.Globals[funcName]).Coroutine; - DynValue value = coroutine.Resume(args2); - ResolveResume(player, coroutine, value); - + try + { + Coroutine coroutine = script.CreateCoroutine(script.Globals[funcName]).Coroutine; + DynValue value = coroutine.Resume(args2); + ResolveResume(player, coroutine, value); + } + catch(Exception e) + { + player.SendMessage(0x20, "", e.Message); + player.EndEvent(); + + } } else { diff --git a/FFXIVClassic Map Server/packets/send/Actor/SetActorPropetyPacket.cs b/FFXIVClassic Map Server/packets/send/Actor/SetActorPropetyPacket.cs index aabba72e..eec4278b 100644 --- a/FFXIVClassic Map Server/packets/send/Actor/SetActorPropetyPacket.cs +++ b/FFXIVClassic Map Server/packets/send/Actor/SetActorPropetyPacket.cs @@ -112,7 +112,6 @@ namespace FFXIVClassic_Map_Server.packets.send.actor { string[] split = name.Split('.'); int arrayIndex = 0; - if (!(split[0].Equals("work") || split[0].Equals("charaWork") || split[0].Equals("playerWork") || split[0].Equals("npcWork") || split[0].Equals("guildleveWork"))) return false; diff --git a/FFXIVClassic Map Server/packets/send/Actor/battle/BattleActionX18Packet.cs b/FFXIVClassic Map Server/packets/send/Actor/battle/BattleActionX18Packet.cs index 2fe2279f..d2411857 100644 --- a/FFXIVClassic Map Server/packets/send/Actor/battle/BattleActionX18Packet.cs +++ b/FFXIVClassic Map Server/packets/send/Actor/battle/BattleActionX18Packet.cs @@ -35,33 +35,33 @@ namespace FFXIVClassic_Map_Server.packets.send.actor.battle binWriter.Write((UInt16)commandId); binWriter.Write((UInt16)0x810); //? - binWriter.Seek(0x58, SeekOrigin.Begin); + binWriter.Seek(0x28, SeekOrigin.Begin); for (int i = 0; i < max; i++) binWriter.Write((UInt32)actionList[listOffset + i].targetId); - binWriter.Seek(0xA0, SeekOrigin.Begin); + binWriter.Seek(0x70, SeekOrigin.Begin); for (int i = 0; i < max; i++) binWriter.Write((UInt16)actionList[listOffset + i].amount); - binWriter.Seek(0xC4, SeekOrigin.Begin); + binWriter.Seek(0x94, SeekOrigin.Begin); for (int i = 0; i < max; i++) binWriter.Write((UInt16)actionList[listOffset + i].worldMasterTextId); - binWriter.Seek(0xE8, SeekOrigin.Begin); + binWriter.Seek(0xB8, SeekOrigin.Begin); for (int i = 0; i < max; i++) binWriter.Write((UInt32)actionList[listOffset + i].effectId); - binWriter.Seek(0x130, SeekOrigin.Begin); + binWriter.Seek(0x100, SeekOrigin.Begin); for (int i = 0; i < max; i++) binWriter.Write((Byte)actionList[listOffset + i].param); - binWriter.Seek(0x142, SeekOrigin.Begin); + binWriter.Seek(0x112, SeekOrigin.Begin); for (int i = 0; i < max; i++) binWriter.Write((Byte)actionList[listOffset + i].unknown); listOffset += max; } - } + } return new SubPacket(OPCODE, sourceActorId, data); } diff --git a/FFXIVClassic World Server/App.config b/FFXIVClassic World Server/App.config index 329f3599..0860683f 100644 --- a/FFXIVClassic World Server/App.config +++ b/FFXIVClassic World Server/App.config @@ -1,7 +1,7 @@ - + diff --git a/FFXIVClassic World Server/FFXIVClassic World Server.csproj b/FFXIVClassic World Server/FFXIVClassic World Server.csproj index 2bf7f335..bc28d6b8 100644 --- a/FFXIVClassic World Server/FFXIVClassic World Server.csproj +++ b/FFXIVClassic World Server/FFXIVClassic World Server.csproj @@ -9,7 +9,7 @@ Properties FFXIVClassic_World_Server FFXIVClassic World Server - v4.5 + v4.5.1 512 true @@ -48,6 +48,26 @@ prompt 4 + + true + bin\Debug\ + DEBUG;TRACE + full + x64 + prompt + MinimumRecommendedRules.ruleset + true + + + bin\x64\Release\ + TRACE + true + pdbonly + x64 + prompt + MinimumRecommendedRules.ruleset + true + ..\packages\Cyotek.CircularBuffer.1.0.0.0\lib\net20\Cyotek.Collections.Generic.CircularBuffer.dll @@ -190,7 +210,8 @@ - + +