diff --git a/src/DiIiS-NA/D3-GameServer/GSSystem/ActorSystem/Actor.cs b/src/DiIiS-NA/D3-GameServer/GSSystem/ActorSystem/Actor.cs index 6032ff6..fd89313 100644 --- a/src/DiIiS-NA/D3-GameServer/GSSystem/ActorSystem/Actor.cs +++ b/src/DiIiS-NA/D3-GameServer/GSSystem/ActorSystem/Actor.cs @@ -204,6 +204,11 @@ namespace DiIiS_NA.GameServer.GSSystem.ActorSystem public int? MarkerSetSNO { get; private set; } public bool Hidden = false; + // TODO: check if the following is correct: @iamdroppy + // { + // get => Attributes[GameAttribute.Hidden]; + // set => Attributes[GameAttribute.Hidden] = value; + // } public bool AdjustPosition = true; @@ -239,7 +244,7 @@ namespace DiIiS_NA.GameServer.GSSystem.ActorSystem ActorSNO = new SNOHandle(SNOGroup.Actor, (int)sno); NameSNO = sno; //Logger.Info("Loaded actor {0}, id {1}, type {2}", this.ActorSNO.Name, this.DynamicID, this.ActorData.Type); - Quality = 0; + //Quality = 0; - removed, 0 is default and you can't change the quality HasLoot = true; if (ActorData.TagMap.ContainsKey(ActorKeys.TeamID)) @@ -369,7 +374,7 @@ namespace DiIiS_NA.GameServer.GSSystem.ActorSystem CheckPointPosition = position; if (this is Player) - world.BroadcastIfRevealed((ACDWorldPositionMessage), this); + world.BroadcastIfRevealed(ACDWorldPositionMessage, this); AfterChangeWorld(); if (this is Player plr) @@ -506,7 +511,7 @@ namespace DiIiS_NA.GameServer.GSSystem.ActorSystem int radius = (int)Math.Pow(2, i); for (int a = 0; a < 8; a++) { - float angle = (float)((0.125f * a) * (Math.PI * 2)); + float angle = (float)(0.125f * a * (Math.PI * 2)); Vector3D correctPosition = Position + new Vector3D((float)Math.Cos(angle) * radius, (float)Math.Sin(angle) * radius, 0); if (World.CheckLocationForFlag(correctPosition, DiIiS_NA.Core.MPQ.FileFormats.Scene.NavCellFlags.AllowWalk)) { @@ -557,7 +562,7 @@ namespace DiIiS_NA.GameServer.GSSystem.ActorSystem World.BroadcastIfRevealed(plr => new PlayHitEffectMessage { ActorID = DynamicID(plr), - HitDealer = (hitDealer.IsRevealedToPlayer(plr) ? hitDealer.DynamicID(plr) : DynamicID(plr)), + HitDealer = hitDealer.IsRevealedToPlayer(plr) ? hitDealer.DynamicID(plr) : DynamicID(plr), DamageType = hitEffect, CriticalDamage = false }, this); @@ -709,7 +714,7 @@ namespace DiIiS_NA.GameServer.GSSystem.ActorSystem public void AddPercentHP(int percentage, bool GuidingLight = false) { - float quantity = (percentage * Attributes[GameAttribute.Hitpoints_Max_Total]) / 100; + float quantity = percentage * Attributes[GameAttribute.Hitpoints_Max_Total] / 100; AddHP(quantity, GuidingLight); } @@ -762,7 +767,7 @@ namespace DiIiS_NA.GameServer.GSSystem.ActorSystem public void SetUsable(bool activated) { - Attributes[GameAttribute.Team_Override] = (activated ? -1 : 2); + Attributes[GameAttribute.Team_Override] = activated ? -1 : 2; Attributes[GameAttribute.Untargetable] = !activated; Attributes[GameAttribute.NPC_Is_Operatable] = activated; Attributes[GameAttribute.Operatable] = activated; @@ -818,8 +823,8 @@ namespace DiIiS_NA.GameServer.GSSystem.ActorSystem lock (player.RevealedObjects) { if (Hidden || Dead || !Visible || World == null) return false; - - var mysticHiddenWorlds = new WorldSno[] { + + var mysticHiddenWorlds = new[] { WorldSno.trdun_crypt_falsepassage_01, WorldSno.trdun_crypt_falsepassage_02, WorldSno.trdun_crypt_fields_flooded_memories_level01, @@ -833,7 +838,8 @@ namespace DiIiS_NA.GameServer.GSSystem.ActorSystem //Destroy Bonewall and Jondar if Exit_S on Second Level of Cathedral - if (World.SNO == WorldSno.a1trdun_level04 && (SNO == ActorSno._trdun_cath_bonewall_a_door || SNO == ActorSno._adventurer_d_templarintrounique)) return false; + if (World.SNO == WorldSno.a1trdun_level04 && SNO is ActorSno._trdun_cath_bonewall_a_door or ActorSno._adventurer_d_templarintrounique) + return false; if (SNO.IsUberWorldActor() && !World.SNO.IsUberWorld()) return false; if (SNO.IsAdventureModeActor() && World.Game.CurrentAct != 3000) return false; @@ -850,15 +856,15 @@ namespace DiIiS_NA.GameServer.GSSystem.ActorSystem if (!(this is Item) && GetScenesInRange().Count > 0 && !GetScenesInRange().OrderBy(scene => PowerMath.Distance2D(scene.Position, Position)).First().IsRevealedToPlayer(player)) return false; - uint objId = player.NewDynamicID(GlobalID, (this is Player && (!(this as Player).IsInPvPWorld || this == player)) ? (int)(this as Player).PlayerIndex : -1); + uint objId = player.NewDynamicID(GlobalID, this is Player thisPlayer && (!thisPlayer.IsInPvPWorld || this == player) ? thisPlayer.PlayerIndex : -1); player.RevealedObjects.Add(GlobalID, objId); - var gbidbank = new int[AffixList.Count]; + var gbIdBank = new int[AffixList.Count]; int i = 0; foreach (var affix in AffixList) { - gbidbank[i] = affix.AffixGbid; + gbIdBank[i] = affix.AffixGbid; i++; } /* @@ -873,13 +879,15 @@ namespace DiIiS_NA.GameServer.GSSystem.ActorSystem var msg = ACDEnterKnown(player); // normaly when we send acdenterknown for players own actor it's set to 0x09. But while sending the acdenterknown for another player's actor we should set it to 0x01. /raist - if ((this is Player) && this != player) - msg.Flags = 0x01; + if (this is Player) + { + msg.Flags = this == player ? 0x09 : 0x01; + } player.InGameClient.SendMessage(msg); // Collision Flags - if (!((this is Projectile) || (this is Item))) + if (this is not Projectile && this is not Item) { player.InGameClient.SendMessage(new ACDCollFlagsMessage { @@ -907,7 +915,7 @@ namespace DiIiS_NA.GameServer.GSSystem.ActorSystem if (this is Player || this is NPC || this is Goblin) player.InGameClient.SendMessage(new ACDCreateActorMessage(objId)); - TrickleMessage Trickle = new TrickleMessage() + TrickleMessage trickle = new TrickleMessage() { ActorId = DynamicID(player), ActorSNO = (int)SNO, @@ -920,10 +928,10 @@ namespace DiIiS_NA.GameServer.GSSystem.ActorSystem }; - if (this is Player) - Trickle.PlayerIndex = (this as Player).PlayerIndex; + if (this is Player playerTrickle) + trickle.PlayerIndex = playerTrickle.PlayerIndex; - player.InGameClient.SendMessage(Trickle); + player.InGameClient.SendMessage(trickle); // Actor group @@ -937,93 +945,103 @@ namespace DiIiS_NA.GameServer.GSSystem.ActorSystem #region Special cases - // set idle animation for zombies in tristram - ZHRAAT - if (World.SNO == WorldSno.trout_town) + + switch (World.SNO) { - if (Tags != null) - if (Tags.ContainsKey(MarkerKeys.Group1Hash)) - if (Tags[MarkerKeys.Group1Hash] == -1248096796) - PlayActionAnimation(AnimationSno.zombie_male_skinny_eating); - } - // set idle animation for workers - else if (World.SNO == WorldSno.trout_tristram_inn && SNO == ActorSno._omninpc_tristram_male_a) - PlayActionAnimation(AnimationSno.omninpc_male_hth_injured); - else if (SNO == ActorSno._leah) - player.InGameClient.SendMessage(new MessageSystem.Message.Definitions.Inventory.VisualInventoryMessage() + // set idle animation for zombies in tristram - ZHRAAT + case WorldSno.trout_town: { - ActorID = DynamicID(player), - EquipmentList = new VisualEquipment() - { - Equipment = new VisualItem[] + if (Tags != null) + if (Tags.ContainsKey(MarkerKeys.Group1Hash)) + if (Tags[MarkerKeys.Group1Hash] == -1248096796) + PlayActionAnimation(AnimationSno.zombie_male_skinny_eating); + break; + } + // set idle animation for workers + case WorldSno.trout_tristram_inn when SNO == ActorSno._omninpc_tristram_male_a: + PlayActionAnimation(AnimationSno.omninpc_male_hth_injured); + break; + default: + { + if (SNO == ActorSno._leah) + player.InGameClient.SendMessage(new MessageSystem.Message.Definitions.Inventory.VisualInventoryMessage() { - new() + ActorID = DynamicID(player), + EquipmentList = new VisualEquipment() { - GbId = -1, - DyeType = 0, - ItemEffectType = 0, - EffectLevel = -1, - }, - new() - { - GbId = -1, - DyeType = 0, - ItemEffectType = 0, - EffectLevel = -1, - }, - new() - { - GbId = -1, - DyeType = 0, - ItemEffectType = 0, - EffectLevel = -1, - }, - new() - { - GbId = -1, - DyeType = 0, - ItemEffectType = 0, - EffectLevel = -1, - }, - new() - { - GbId = unchecked((int)-2091504072), - DyeType = 0, - ItemEffectType = 0, - EffectLevel = -1, - }, - new() - { - GbId = -1,//0x6C3B0389, - DyeType = 0, - ItemEffectType = 0, - EffectLevel = -1, - }, - new() - { - GbId = -1, - DyeType = 0, - ItemEffectType = 0, - EffectLevel = -1, - }, - new() - { - GbId = -1, - DyeType = 0, - ItemEffectType = 0, - EffectLevel = -1, - }, - } - } - }); + Equipment = new VisualItem[] + { + new() + { + GbId = -1, + DyeType = 0, + ItemEffectType = 0, + EffectLevel = -1, + }, + new() + { + GbId = -1, + DyeType = 0, + ItemEffectType = 0, + EffectLevel = -1, + }, + new() + { + GbId = -1, + DyeType = 0, + ItemEffectType = 0, + EffectLevel = -1, + }, + new() + { + GbId = -1, + DyeType = 0, + ItemEffectType = 0, + EffectLevel = -1, + }, + new() + { + GbId = unchecked((int)-2091504072), + DyeType = 0, + ItemEffectType = 0, + EffectLevel = -1, + }, + new() + { + GbId = -1,//0x6C3B0389, + DyeType = 0, + ItemEffectType = 0, + EffectLevel = -1, + }, + new() + { + GbId = -1, + DyeType = 0, + ItemEffectType = 0, + EffectLevel = -1, + }, + new() + { + GbId = -1, + DyeType = 0, + ItemEffectType = 0, + EffectLevel = -1, + }, + } + } + }); + break; + } + } #endregion - if (this is NPC || this is InteractiveNPC) - { - //.Contains(AnimationSetKeys.Idle) - //if (this.AnimationSet.Animations.ContainsKey(AnimationSetKeys.Idle.ID)) - // this.SetIdleAnimation(this.AnimationSet.TagMapAnimDefault[AnimationSetKeys.Idle]); - //this.PlayAnimation(0, this.AnimationSet.TagMapAnimDefault[AnimationSetKeys.Idle]); - } + // if (this is NPC || this is InteractiveNPC) + // { + // //.Contains(AnimationSetKeys.Idle) + // //if (this.AnimationSet.Animations.ContainsKey(AnimationSetKeys.Idle.ID)) + // // this.SetIdleAnimation(this.AnimationSet.TagMapAnimDefault[AnimationSetKeys.Idle]); + // //this.PlayAnimation(0, this.AnimationSet.TagMapAnimDefault[AnimationSetKeys.Idle]); + // } //Logger.Trace("Reveal actor [{2}]{0} as {1}", this.GlobalID, objId, this.ActorSNO.Name); diff --git a/src/DiIiS-NA/D3-GameServer/GSSystem/GameSystem/Game.cs b/src/DiIiS-NA/D3-GameServer/GSSystem/GameSystem/Game.cs index 6ebe38c..6b175a7 100644 --- a/src/DiIiS-NA/D3-GameServer/GSSystem/GameSystem/Game.cs +++ b/src/DiIiS-NA/D3-GameServer/GSSystem/GameSystem/Game.cs @@ -31,6 +31,7 @@ using DiIiS_NA.GameServer.GSSystem.ActorSystem.Implementations.Hirelings; using DiIiS_NA.GameServer.GSSystem.GeneratorsSystem; using DiIiS_NA.GameServer.GSSystem.AISystem.Brains; using System.Diagnostics; +using System.Runtime.CompilerServices; using DiIiS_NA.Core.MPQ.FileFormats; using DiIiS_NA.D3_GameServer.Core.Types.SNO; using DiIiS_NA.D3_GameServer.GSSystem.GameSystem; @@ -408,8 +409,9 @@ namespace DiIiS_NA.GameServer.GSSystem.GameSystem /// Executes an action to all players in the game. /// /// Action to execute - public void BroadcastPlayers(Action action) + public void BroadcastPlayers(Action action, [CallerMemberName] string methodName = "") { + Logger.MethodTrace("Broadcasting to players", methodName); foreach (var player in Players) { action(player.Key, player.Value); @@ -421,8 +423,9 @@ namespace DiIiS_NA.GameServer.GSSystem.GameSystem /// /// Predicate to check /// Action to execute - public void BroadcastPlayers(Func predicate, Action action) + public void BroadcastPlayers(Func predicate, Action action, [CallerMemberName] string methodName = "") { + Logger.MethodTrace("Broadcasting to players", methodName); foreach (var player in Players.Where(s=>predicate(s.Key, s.Value))) { action(player.Key, player.Value); @@ -433,8 +436,9 @@ namespace DiIiS_NA.GameServer.GSSystem.GameSystem /// Executes an action to all worlds in the game. /// /// Action to execute - public void BroadcastWorlds(Action action) + public void BroadcastWorlds(Action action, [CallerMemberName] string methodName = "") { + Logger.MethodTrace("Broadcasting to players", methodName); foreach (var world in Worlds) { action(world); @@ -446,8 +450,9 @@ namespace DiIiS_NA.GameServer.GSSystem.GameSystem /// /// Predicate to check /// Action to execute - public void BroadcastWorlds(Func predicate, Action action) + public void BroadcastWorlds(Func predicate, Action action, [CallerMemberName] string methodName = "") { + Logger.MethodTrace("Broadcasting to players", methodName); foreach (var world in Worlds.Where(predicate)) { action(world); diff --git a/src/DiIiS-NA/D3-GameServer/GSSystem/GameSystem/QuestManager.cs b/src/DiIiS-NA/D3-GameServer/GSSystem/GameSystem/QuestManager.cs index 1b77c41..51830f7 100644 --- a/src/DiIiS-NA/D3-GameServer/GSSystem/GameSystem/QuestManager.cs +++ b/src/DiIiS-NA/D3-GameServer/GSSystem/GameSystem/QuestManager.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using System.Reflection; +using D3.Quests; using DiIiS_NA.Core.Extensions; using DiIiS_NA.Core.Helpers.Hash; using DiIiS_NA.Core.Helpers.Math; @@ -193,56 +194,51 @@ namespace DiIiS_NA.D3_GameServer.GSSystem.GameSystem { SaveQuestProgress(true); Logger.Trace($"$[white]$(Advance)$[/]$ Game {Game.GameId} Advanced to quest $[underline white]${Game.CurrentQuest}$[/]$, completed $[underline white]${Quests[Game.CurrentQuest].Completed}$[/]$"); - foreach (var player in Game.Players.Values) + Game.BroadcastPlayers((client, player) => { + if (Game.CurrentQuest == 312429) return; // open world quest + int xpReward = (int)(Quests[Game.CurrentQuest].RewardXp * Game.XpModifier); int goldReward = (int)(Quests[Game.CurrentQuest].RewardGold * Game.GoldModifier); - if (Game.CurrentQuest != 312429) // open world quest + player.InGameClient.SendMessage(new QuestStepCompleteMessage() { - player.InGameClient.SendMessage(new QuestStepCompleteMessage() - { - QuestStepComplete = D3.Quests.QuestStepComplete.CreateBuilder() + QuestStepComplete = QuestStepComplete.CreateBuilder() - .SetReward(D3.Quests.QuestReward.CreateBuilder() + .SetReward(QuestReward.CreateBuilder() .SetGoldGranted(goldReward) .SetXpGranted((ulong)xpReward) .SetSnoQuest(Game.CurrentQuest) - ) + ) .SetIsQuestComplete(true) .Build() - //snoQuest = this.Game.CurrentQuest, - //isQuestComplete = true, - //rewardXp = xpReward, - //rewardGold = goldReward - }); - player.InGameClient.SendMessage(new GameServer.MessageSystem.Message.Definitions.Base.FloatingAmountMessage() + }); + player.InGameClient.SendMessage(new GameServer.MessageSystem.Message.Definitions.Base.FloatingAmountMessage() + { + Place = new WorldPlace() { - Place = new WorldPlace() - { - Position = player.Position, - WorldID = player.World.DynamicID(player), - }, + Position = player.Position, + WorldID = player.World.DynamicID(player), + }, - Amount = xpReward, - Type = GameServer.MessageSystem.Message.Definitions.Base.FloatingAmountMessage.FloatType.Experience, - }); - player.InGameClient.SendMessage(new GameServer.MessageSystem.Message.Definitions.Base.FloatingAmountMessage() + Amount = xpReward, + Type = GameServer.MessageSystem.Message.Definitions.Base.FloatingAmountMessage.FloatType.Experience, + }); + player.InGameClient.SendMessage(new GameServer.MessageSystem.Message.Definitions.Base.FloatingAmountMessage() + { + Place = new WorldPlace() { - Place = new WorldPlace() - { - Position = player.Position, - WorldID = player.World.DynamicID(player), - }, + Position = player.Position, + WorldID = player.World.DynamicID(player), + }, - Amount = goldReward, - Type = GameServer.MessageSystem.Message.Definitions.Base.FloatingAmountMessage.FloatType.Gold, - }); - player.UpdateExp(xpReward); - player.Inventory.AddGoldAmount(goldReward); - player.AddAchievementCounter(74987243307173, (uint)goldReward); - player.CheckQuestCriteria(Game.CurrentQuest); - } - }; + Amount = goldReward, + Type = GameServer.MessageSystem.Message.Definitions.Base.FloatingAmountMessage.FloatType.Gold, + }); + player.UpdateExp(xpReward); + player.Inventory.AddGoldAmount(goldReward); + player.AddAchievementCounter(74987243307173, (uint)goldReward); + player.CheckQuestCriteria(Game.CurrentQuest); + }); } if (Quests[Game.CurrentQuest].NextQuest == -1) return; @@ -305,9 +301,9 @@ namespace DiIiS_NA.D3_GameServer.GSSystem.GameSystem player.InGameClient.SendMessage(new QuestStepCompleteMessage() { - QuestStepComplete = D3.Quests.QuestStepComplete.CreateBuilder() + QuestStepComplete = QuestStepComplete.CreateBuilder() - .SetReward(D3.Quests.QuestReward.CreateBuilder() + .SetReward(QuestReward.CreateBuilder() .SetGoldGranted(goldReward) .SetXpGranted((ulong)xpReward) .SetSnoQuest(Game.CurrentSideQuest) @@ -416,13 +412,8 @@ namespace DiIiS_NA.D3_GameServer.GSSystem.GameSystem public float QuestTimerEstimate = 0f; - public void LaunchRiftQuestTimer(float duration, Action onDone, int idSNO = 0) + public void LaunchRiftQuestTimer(float duration, Action onDone) { - foreach (var player in Game.Players.Values) - { - - }; - QuestTimerEstimate = duration; Game.QuestTimer = SteppedTickTimer.WaitSecondsStepped(Game, 1f, duration, new Action((q) => @@ -435,7 +426,7 @@ namespace DiIiS_NA.D3_GameServer.GSSystem.GameSystem public void LaunchQuestTimer(int questId, float duration, Action onDone, int masterId = 0) { - foreach (var player in Game.Players.Values) + Game.BroadcastPlayers((client, player) => { player.InGameClient.SendMessage(new QuestMeterMessage() { @@ -443,7 +434,7 @@ namespace DiIiS_NA.D3_GameServer.GSSystem.GameSystem annMeter = masterId, flMeter = 1f }); - }; + }); QuestTimerEstimate = duration; @@ -472,7 +463,7 @@ namespace DiIiS_NA.D3_GameServer.GSSystem.GameSystem Quests[Game.CurrentQuest].Steps[Game.CurrentStep].Objectives[objId].Counter++; var objective = Quests[Game.CurrentQuest].Steps[Game.CurrentStep].Objectives[objId]; - foreach (var player in Game.Players.Values) + Game.BroadcastPlayers((client, player) => player.InGameClient.SendMessage(new QuestCounterMessage() { snoQuest = Game.CurrentQuest, @@ -481,7 +472,7 @@ namespace DiIiS_NA.D3_GameServer.GSSystem.GameSystem TaskIndex = objId, Counter = objective.Counter, Checked = objective.Counter < objective.Limit ? 0 : 1, - }); + })); if (!Quests[Game.CurrentQuest].Steps[Game.CurrentStep].Objectives.Any(obj => obj.Counter < obj.Limit)) Advance(); @@ -1038,9 +1029,9 @@ namespace DiIiS_NA.D3_GameServer.GSSystem.GameSystem }); player.InGameClient.SendMessage(new QuestStepCompleteMessage() { - QuestStepComplete = D3.Quests.QuestStepComplete.CreateBuilder() + QuestStepComplete = QuestStepComplete.CreateBuilder() .SetIsQuestComplete(true) - .SetReward(D3.Quests.QuestReward.CreateBuilder() + .SetReward(QuestReward.CreateBuilder() .SetSnoQuest(BountySNOid) .SetXpGranted((ulong)xpReward) .SetGoldGranted((int)goldReward) diff --git a/src/DiIiS-NA/D3-GameServer/GSSystem/PlayerSystem/Player.cs b/src/DiIiS-NA/D3-GameServer/GSSystem/PlayerSystem/Player.cs index 2df5cf3..82b6c86 100644 --- a/src/DiIiS-NA/D3-GameServer/GSSystem/PlayerSystem/Player.cs +++ b/src/DiIiS-NA/D3-GameServer/GSSystem/PlayerSystem/Player.cs @@ -3745,9 +3745,9 @@ public class Player : Actor, IMessageConsumer, IUpdateable WarpFadeInSecods = 0f }); - if (SkillSet.HasSkill(460757)) + if (SkillSet.HasSkill(460757)) // P6_Necro_Devour foreach (var skill in SkillSet.ActiveSkills) - if (skill.snoSkill == 460757) + if (skill.snoSkill == 460757) // P6_Necro_Devour if (skill.snoRune == 3) World.BuffManager.AddBuff(this, this, new P6_Necro_Devour_Aura()); else @@ -3810,7 +3810,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable AllBuffs.Clear(); BetweenWorlds = false; - if (_CurrentHPValue != -1) + if (Math.Abs(_CurrentHPValue - (-1)) > 0.0001) { Attributes[GameAttribute.Hitpoints_Cur] = _CurrentHPValue; Attributes[GameAttribute.Resource_Cur, (int)Toon.HeroTable.PrimaryResource + 1] = _CurrentResourceValue; @@ -3828,7 +3828,8 @@ public class Player : Actor, IMessageConsumer, IUpdateable #region hero-state - public void WTF() + [Obsolete("Does this make sense?")] + private void WTF() { Attributes[GameAttribute.Power_Buff_0_Visual_Effect_None, 208468] = true; Attributes[GameAttribute.Thorns_Fixed_Total, 0] = 0;