diff --git a/src/DiIiS-NA/Core/Logging/Logger.cs b/src/DiIiS-NA/Core/Logging/Logger.cs index 52b893b..8e3a012 100644 --- a/src/DiIiS-NA/Core/Logging/Logger.cs +++ b/src/DiIiS-NA/Core/Logging/Logger.cs @@ -107,7 +107,7 @@ namespace DiIiS_NA.Core.Logging { #if DEBUG var fileName = Path.GetFileName(filePath); - Log(Level.MethodTrace, $"$[underline white]${fileName}:{lineNumber}$[/]$ $[darkolivegreen3_2]${methodName}()$[/]$: $[black on white]$" + message + "$[/]$", null); + Log(Level.MethodTrace, $"$[underline white]${fileName}:{lineNumber}$[/]$ $[darkolivegreen3_2]${methodName}()$[/]$: " + message, null); #else Log(Level.MethodTrace, $"$[darkolivegreen3_2]${methodName}()$[/]$: " + message, null); #endif diff --git a/src/DiIiS-NA/Core/Storage/GameDBSession.cs b/src/DiIiS-NA/Core/Storage/GameDBSession.cs index 6c8d1ef..f64916d 100644 --- a/src/DiIiS-NA/Core/Storage/GameDBSession.cs +++ b/src/DiIiS-NA/Core/Storage/GameDBSession.cs @@ -13,23 +13,17 @@ namespace DiIiS_NA.Core.Storage private static Object _globalSessionLock = new object(); private Object _sessionLock = new object(); private IStatelessSession _gameSession = null; - private readonly Logger Logger = LogManager.CreateLogger("DB"); + private readonly Logger Logger = LogManager.CreateLogger(nameof(GameDBSession)); public GameDBSession() { lock (_globalSessionLock) { - this._gameSession = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession(); + _gameSession = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession(); } } - private IStatelessSession GameSession - { - get - { - return this._gameSession; - } - } + private IStatelessSession GameSession => _gameSession; public void SessionSave(Object obj) { @@ -39,8 +33,8 @@ namespace DiIiS_NA.Core.Storage { try { - using (IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession()) - session.Insert(obj); + using IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession(); + session.Insert(obj); } catch (Exception e) { @@ -74,8 +68,8 @@ namespace DiIiS_NA.Core.Storage { try { - using (IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession()) - session.Update(obj); + using IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession(); + session.Update(obj); } catch (Exception e) { @@ -109,8 +103,8 @@ namespace DiIiS_NA.Core.Storage { try { - using (IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession()) - session.Delete(obj); + using IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession(); + session.Delete(obj); } catch (Exception e) { @@ -157,8 +151,8 @@ namespace DiIiS_NA.Core.Storage { try { - using (IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession()) - return session.Query().ToList(); + using IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession(); + return session.Query().ToList(); } catch (Exception e) { @@ -189,8 +183,8 @@ namespace DiIiS_NA.Core.Storage { try { - using (IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession()) - return session.QueryOver().Where(predicate).List().ToList(); + using IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession(); + return session.QueryOver().Where(predicate).List().ToList(); } catch (Exception e) { @@ -221,8 +215,8 @@ namespace DiIiS_NA.Core.Storage { try { - using (IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession()) - return (T)session.QueryOver().Where(predicate).List().FirstOrDefault(); + using IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession(); + return (T)session.QueryOver().Where(predicate).List().FirstOrDefault(); } catch (Exception e) { diff --git a/src/DiIiS-NA/D3-GameServer/CommandManager/CommandManager.cs b/src/DiIiS-NA/D3-GameServer/CommandManager/CommandManager.cs index 55e7023..d1f6300 100644 --- a/src/DiIiS-NA/D3-GameServer/CommandManager/CommandManager.cs +++ b/src/DiIiS-NA/D3-GameServer/CommandManager/CommandManager.cs @@ -24,17 +24,28 @@ namespace DiIiS_NA.GameServer.CommandManager foreach (var type in Assembly.GetExecutingAssembly().GetTypes()) { if (!type.IsSubclassOf(typeof(CommandGroup))) continue; - var attributes = (CommandGroupAttribute[])type.GetCustomAttributes(typeof(CommandGroupAttribute), true); if (attributes.Length == 0) continue; - var groupAttribute = attributes[0]; + if (groupAttribute.Name == null) continue; + if (CommandsConfig.Instance.DisabledGroupsData.Contains(groupAttribute.Name)) + { + Logger.Trace($"Command group {groupAttribute.Name} is disabled."); + continue; + } if (CommandGroups.ContainsKey(groupAttribute)) Logger.Warn("There exists an already registered command group named '{0}'.", groupAttribute.Name); var commandGroup = (CommandGroup)Activator.CreateInstance(type); - commandGroup.Register(groupAttribute); - CommandGroups.Add(groupAttribute, commandGroup); + if (commandGroup != null) + { + commandGroup.Register(groupAttribute); + CommandGroups.Add(groupAttribute, commandGroup); + } + else + { + Logger.Warn("Failed to create an instance of command group '{0}'.", groupAttribute.Name); + } } } diff --git a/src/DiIiS-NA/D3-GameServer/CommandManager/Commands/DropCommand.cs b/src/DiIiS-NA/D3-GameServer/CommandManager/Commands/DropCommand.cs index 274f9ef..475e2d2 100644 --- a/src/DiIiS-NA/D3-GameServer/CommandManager/Commands/DropCommand.cs +++ b/src/DiIiS-NA/D3-GameServer/CommandManager/Commands/DropCommand.cs @@ -4,8 +4,7 @@ using DiIiS_NA.LoginServer.Battle; namespace DiIiS_NA.GameServer.CommandManager; -[CommandGroup("drop", "Drops an epic item for your class.\nOptionally specify the number of items: !drop [1-20]", - Account.UserLevels.Owner)] +[CommandGroup("drop", "Drops an epic item for your class.\nOptionally specify the number of items: !drop [1-20]", Account.UserLevels.Owner)] public class DropCommand : CommandGroup { [DefaultCommand] @@ -29,16 +28,16 @@ public class DropCommand : CommandGroup try { for (var i = 0; i < amount; i++) - player.World.SpawnRandomEquip(player, player, 11, player.Level, toonClass: player.Toon.Class, + player.World.SpawnRandomEquip(player, player, 11, /*player.Level,*/ toonClass: player.Toon.Class, canBeUnidentified: false); } catch { for (var i = 0; i < amount; i++) - player.World.SpawnRandomEquip(player, player, 8, player.Level, toonClass: player.Toon.Class, + player.World.SpawnRandomEquip(player, player, 8, /*player.Level,*/ toonClass: player.Toon.Class, canBeUnidentified: false); } - return $"Dropped {amount} random equipment."; + return $"Dropped {amount} random epic equipment."; } } \ No newline at end of file diff --git a/src/DiIiS-NA/D3-GameServer/CommandManager/CommandsConfig.cs b/src/DiIiS-NA/D3-GameServer/CommandManager/CommandsConfig.cs index 16ab2f3..ce50d78 100644 --- a/src/DiIiS-NA/D3-GameServer/CommandManager/CommandsConfig.cs +++ b/src/DiIiS-NA/D3-GameServer/CommandManager/CommandsConfig.cs @@ -13,8 +13,20 @@ namespace DiIiS_NA.GameServer.CommandManager get => GetString(nameof(CommandPrefix), "!")[0]; set => Set(nameof(CommandPrefix), value); } + + public string DisabledGroups + { + get => GetString(nameof(DisabledGroups), ""); + set => Set(nameof(DisabledGroups), value); + } - public static CommandsConfig Instance = new(); + public string[] DisabledGroupsData + => DisabledGroups + .Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries) + .Select(s=>s.Replace(CommandPrefix.ToString(), "")) + .ToArray(); + + public static readonly CommandsConfig Instance = new(); private CommandsConfig() : base("Commands") { } } } diff --git a/src/DiIiS-NA/D3-GameServer/Core/Types/Math/Vector3D.cs b/src/DiIiS-NA/D3-GameServer/Core/Types/Math/Vector3D.cs index 9bcdc55..d271cf4 100644 --- a/src/DiIiS-NA/D3-GameServer/Core/Types/Math/Vector3D.cs +++ b/src/DiIiS-NA/D3-GameServer/Core/Types/Math/Vector3D.cs @@ -113,41 +113,24 @@ namespace DiIiS_NA.GameServer.Core.Types.Math return ((x * x) + (y * y)) + (z * z); } - public static bool operator ==(Vector3D a, Vector3D b) - { - if (ReferenceEquals(null, a)) - return ReferenceEquals(null, b); - return a.Equals(b); - } + public static bool operator ==(Vector3D a, Vector3D b) => a?.Equals(b) ?? ReferenceEquals(null, b); - public static bool operator !=(Vector3D a, Vector3D b) - { - return !(a == b); - } + public static bool operator !=(Vector3D a, Vector3D b) => !(a == b); public static bool operator >(Vector3D a, Vector3D b) { - if (ReferenceEquals(null, a)) - return !ReferenceEquals(null, b); - return a.X > b.X - && a.Y > b.Y - && a.Z > b.Z; + return ReferenceEquals(null, a) + ? !ReferenceEquals(null, b) + : a.X > b.X + && a.Y > b.Y + && a.Z > b.Z; } - public static Vector3D operator +(Vector3D a, Vector3D b) - { - return new Vector3D(a.X + b.X, a.Y + b.Y, a.Z + b.Z); - } + public static Vector3D operator +(Vector3D a, Vector3D b) => new Vector3D(a.X + b.X, a.Y + b.Y, a.Z + b.Z); - public static Vector3D operator -(Vector3D a, Vector3D b) - { - return new Vector3D(a.X - b.X, a.Y - b.Y, a.Z - b.Z); - } + public static Vector3D operator -(Vector3D a, Vector3D b) => new Vector3D(a.X - b.X, a.Y - b.Y, a.Z - b.Z); - public static bool operator <(Vector3D a, Vector3D b) - { - return !(a > b); - } + public static bool operator <(Vector3D a, Vector3D b) => !(a > b); public static bool operator >=(Vector3D a, Vector3D b) { @@ -174,9 +157,9 @@ namespace DiIiS_NA.GameServer.Core.Types.Math var v = o as Vector3D; if (v != null) { - return System.Math.Abs(X - v.X) < 0.0001 - && System.Math.Abs(Y - v.Y) < 0.0001 - && System.Math.Abs(Z - v.Z) < 0.0001; + return System.Math.Abs(X - v.X) < Globals.FLOAT_TOLERANCE + && System.Math.Abs(Y - v.Y) < Globals.FLOAT_TOLERANCE + && System.Math.Abs(Z - v.Z) < Globals.FLOAT_TOLERANCE; } return false; } diff --git a/src/DiIiS-NA/D3-GameServer/Core/Types/SNO/ActorSno.cs b/src/DiIiS-NA/D3-GameServer/Core/Types/SNO/ActorSno.cs index 586439a..d1b4091 100644 --- a/src/DiIiS-NA/D3-GameServer/Core/Types/SNO/ActorSno.cs +++ b/src/DiIiS-NA/D3-GameServer/Core/Types/SNO/ActorSno.cs @@ -20690,7 +20690,7 @@ namespace DiIiS_NA.D3_GameServer.Core.Types.SNO ActorSno._p73_fallenlunatic_a_nonspawner, }; // all '_vo' and 'voiceo' actors except 'voodoomask` and and cosmetic pets - private static readonly ActorSno[] soundActors = new ActorSno[] + private static readonly ActorSno[] _soundActors = new ActorSno[] { ActorSno._lustmissle_volume, ActorSno._a1dun_caves_nephalem_altar_volume, @@ -20713,7 +20713,7 @@ namespace DiIiS_NA.D3_GameServer.Core.Types.SNO ActorSno._p43_ad_valor_bloodstone_volume, }; // all 'door' actors - private static readonly ActorSno[] doors = new ActorSno[] + private static readonly ActorSno[] _doors = new ActorSno[] { ActorSno._trdun_cath_wooddoor_a, ActorSno._door_intactc_caout_towns, @@ -21156,7 +21156,7 @@ namespace DiIiS_NA.D3_GameServer.Core.Types.SNO ActorSno._kanai_cube_uber_fx, }; // all 'adventuremode' actors - private static readonly ActorSno[] adventureModeActors = new ActorSno[] + private static readonly ActorSno[] AdventureModeActors = new ActorSno[] { ActorSno._x1_lore_adventuremode_zknephalem, ActorSno._x1_lore_adventuremode_zkplans, @@ -21168,7 +21168,7 @@ namespace DiIiS_NA.D3_GameServer.Core.Types.SNO ActorSno._x1_adventuremode_hubbantertrigger, }; #endregion - public static readonly ActorSno[] nephalemPortalBosses = new ActorSno[] + public static readonly ActorSno[] NephalemPortalBosses = new ActorSno[] { ActorSno._x1_lr_boss_mistressofpain, ActorSno._x1_lr_boss_angel_corrupt_a, @@ -21227,17 +21227,17 @@ namespace DiIiS_NA.D3_GameServer.Core.Types.SNO public static bool IsAdventureModeActor(this ActorSno actorSno) { - return adventureModeActors.Contains(actorSno); + return AdventureModeActors.Contains(actorSno); } public static bool IsTargetable(this ActorSno actorSno) { - return !spawners.Contains(actorSno) && !soundActors.Contains(actorSno); + return !spawners.Contains(actorSno) && !_soundActors.Contains(actorSno); } public static bool IsDoorOrBarricade(this ActorSno actorSno) { - return doors.Contains(actorSno) || barricades.Contains(actorSno); + return _doors.Contains(actorSno) || barricades.Contains(actorSno); } public static bool IsWoodwraithOrWasp(this ActorSno actorSno) diff --git a/src/DiIiS-NA/D3-GameServer/GSSystem/ActorSystem/Implementations/Artisans/Nephalem.cs b/src/DiIiS-NA/D3-GameServer/GSSystem/ActorSystem/Implementations/Artisans/Nephalem.cs index 94d5c7c..57a0367 100644 --- a/src/DiIiS-NA/D3-GameServer/GSSystem/ActorSystem/Implementations/Artisans/Nephalem.cs +++ b/src/DiIiS-NA/D3-GameServer/GSSystem/ActorSystem/Implementations/Artisans/Nephalem.cs @@ -50,11 +50,5 @@ namespace DiIiS_NA.D3_GameServer.GSSystem.ActorSystem.Implementations.Artisans base.OnCraft(player); player.CurrentArtisan = ArtisanType.Nephalem; } - - public override bool Reveal(Player player) - { - - return base.Reveal(player); - } } } diff --git a/src/DiIiS-NA/D3-GameServer/GSSystem/ActorSystem/Monster.cs b/src/DiIiS-NA/D3-GameServer/GSSystem/ActorSystem/Monster.cs index 7a4a29f..788b34c 100644 --- a/src/DiIiS-NA/D3-GameServer/GSSystem/ActorSystem/Monster.cs +++ b/src/DiIiS-NA/D3-GameServer/GSSystem/ActorSystem/Monster.cs @@ -88,7 +88,7 @@ namespace DiIiS_NA.GameServer.GSSystem.ActorSystem public void UpdateStats() { var monsterLevels = (GameBalance)DiIiS_NA.Core.MPQ.MPQStorage.Data.Assets[SNOGroup.GameBalance][19760].Data; - bool fullHp = (Math.Abs(Attributes[GameAttribute.Hitpoints_Cur] - Attributes[GameAttribute.Hitpoints_Max_Total]) < 0.001); + bool fullHp = (Math.Abs(Attributes[GameAttribute.Hitpoints_Cur] - Attributes[GameAttribute.Hitpoints_Max_Total]) < Globals.FLOAT_TOLERANCE); Attributes[GameAttribute.Level] = World.Game.MonsterLevel; //this.Attributes[GameAttribute.Hitpoints_Max] = (int)monsterLevels.MonsterLevel[this.World.Game.MonsterLevel - 1].HPMin * (int)this.HPMultiplier * (int)this.World.Game.HPModifier; int monsterLevel = 1; diff --git a/src/DiIiS-NA/D3-GameServer/GSSystem/GameSystem/Game.cs b/src/DiIiS-NA/D3-GameServer/GSSystem/GameSystem/Game.cs index 6b175a7..e5c84d7 100644 --- a/src/DiIiS-NA/D3-GameServer/GSSystem/GameSystem/Game.cs +++ b/src/DiIiS-NA/D3-GameServer/GSSystem/GameSystem/Game.cs @@ -1256,7 +1256,7 @@ namespace DiIiS_NA.GameServer.GSSystem.GameSystem GameAccountId = new GameAccountHandle() { ID = (uint)joinedPlayer.Toon.GameAccount.BnetEntityId.Low, Program = 0x00004433, Region = 1 }, ToonName = joinedPlayer.Toon.Name, Team = 0x00000002, - Class = joinedPlayer.ClassSNO, + Class = joinedPlayer.ClassSno, snoActorPortrait = joinedPlayer.Toon.DBToon.Cosmetic4, Level = joinedPlayer.Toon.Level, AltLevel = (ushort)joinedPlayer.Toon.ParagonLevel, diff --git a/src/DiIiS-NA/D3-GameServer/GSSystem/GeneratorsSystem/WorldGenerator.cs b/src/DiIiS-NA/D3-GameServer/GSSystem/GeneratorsSystem/WorldGenerator.cs index 4616d93..809181f 100644 --- a/src/DiIiS-NA/D3-GameServer/GSSystem/GeneratorsSystem/WorldGenerator.cs +++ b/src/DiIiS-NA/D3-GameServer/GSSystem/GeneratorsSystem/WorldGenerator.cs @@ -386,8 +386,8 @@ namespace DiIiS_NA.GameServer.GSSystem.GeneratorsSystem RandomSpawnInWorldWithLevelArea(world, ActorSno._x1_deathmaiden_unique_fire_a); break; case WorldSno.trdun_leoric_level03: //Setting portal to the third floor of the Agony's Halls near the entrance to the Butcher. - Vector3D Scene0Pos = world.GetSceneBySnoId(78824).Position; - world.SpawnMonster(ActorSno._waypoint, new Vector3D(Scene0Pos.X + 149.0907f, Scene0Pos.Y + 106.7075f, Scene0Pos.Z)); + Vector3D sceneOfPos = world.GetSceneBySnoId(78824).Position; + world.SpawnMonster(ActorSno._waypoint, new Vector3D(sceneOfPos.X + 149.0907f, sceneOfPos.Y + 106.7075f, sceneOfPos.Z)); break; case WorldSno.x1_westm_graveyard_deathorb: FilterWaypoints(world); @@ -402,9 +402,9 @@ namespace DiIiS_NA.GameServer.GSSystem.GeneratorsSystem break; case WorldSno.trout_town: //mercenary var templar = world.GetActorBySNO(ActorSno._templar); - var hasmalth = world.GetActorBySNO(ActorSno._x1_malthael_npc); + var hasMalthaelNpc = world.GetActorBySNO(ActorSno._x1_malthael_npc); - if (hasmalth == null) + if (hasMalthaelNpc == null) { ActorSystem.Implementations.Hirelings.MalthaelHireling malthaelHire = new ActorSystem.Implementations.Hirelings.MalthaelHireling(world, ActorSno._x1_malthael_npc_nocollision, templar.Tags) { @@ -419,17 +419,17 @@ namespace DiIiS_NA.GameServer.GSSystem.GeneratorsSystem } foreach (var door in world.GetActorsBySNO(ActorSno._house_door_trout_newtristram)) door.Destroy(); - if (Game.CurrentAct == 3000) + if (Game.CurrentActEnum == ActEnum.OpenWorld) { - var TownDoor = world.GetActorBySNO(ActorSno._trout_newtristram_gate_town); - TownDoor.Attributes[GameAttribute.Team_Override] = 2; - TownDoor.Attributes[GameAttribute.Untargetable] = true; - TownDoor.Attributes[GameAttribute.NPC_Is_Operatable] = false; - TownDoor.Attributes[GameAttribute.Operatable] = false; - TownDoor.Attributes[GameAttribute.Operatable_Story_Gizmo] = false; - TownDoor.Attributes[GameAttribute.Disabled] = true; - TownDoor.Attributes[GameAttribute.Immunity] = true; - TownDoor.Attributes.BroadcastChangedIfRevealed(); + var townDoor = world.GetActorBySNO(ActorSno._trout_newtristram_gate_town); + townDoor.Attributes[GameAttribute.Team_Override] = 2; + townDoor.Attributes[GameAttribute.Untargetable] = true; + townDoor.Attributes[GameAttribute.NPC_Is_Operatable] = false; + townDoor.Attributes[GameAttribute.Operatable] = false; + townDoor.Attributes[GameAttribute.Operatable_Story_Gizmo] = false; + townDoor.Attributes[GameAttribute.Disabled] = true; + townDoor.Attributes[GameAttribute.Immunity] = true; + townDoor.Attributes.BroadcastChangedIfRevealed(); } break; case WorldSno.a1trdun_level04: //Cathedral Level 2 @@ -504,10 +504,12 @@ namespace DiIiS_NA.GameServer.GSSystem.GeneratorsSystem zoltunGhost.Attributes.BroadcastChangedIfRevealed(); break; case WorldSno.a3dun_ruins_frost_city_a_02: - foreach (var waypoint in world.GetActorsBySNO(ActorSno._waypoint)) waypoint.Destroy(); + foreach (var waypoint in world.GetActorsBySNO(ActorSno._waypoint)) + waypoint.Destroy(); break; case WorldSno.p43_ad_oldtristram: - foreach (var waypoint in world.GetActorsBySNO(ActorSno._trout_oldtristram_exit_gate)) waypoint.Destroy(); + foreach (var waypoint in world.GetActorsBySNO(ActorSno._trout_oldtristram_exit_gate)) + waypoint.Destroy(); break; case WorldSno.x1_tristram_adventure_mode_hub: @@ -561,14 +563,15 @@ namespace DiIiS_NA.GameServer.GSSystem.GeneratorsSystem public void RandomSpawnInWorldWithLevelArea(World world, ActorSno monsterSno, int levelArea = -1) { List scenes = world.Scenes.Values.ToList(); - if (levelArea != -1) scenes = scenes.Where(sc => sc.Specification.SNOLevelAreas[0] == levelArea && !sc.SceneSNO.Name.ToLower().Contains("filler")).ToList(); - else scenes = scenes.Where(sc => !sc.SceneSNO.Name.ToLower().Contains("filler")).ToList(); - Vector3D SSV = scenes.PickRandom().Position; + scenes = levelArea != -1 + ? scenes.Where(sc => sc.Specification.SNOLevelAreas[0] == levelArea && !sc.SceneSNO.Name.ToLower().Contains("filler")).ToList() + : scenes.Where(sc => !sc.SceneSNO.Name.ToLower().Contains("filler")).ToList(); + Vector3D randomScene = scenes.PickRandom().Position; Vector3D startingPoint = null; while (true) { - startingPoint = new Vector3D(SSV.X + RandomHelper.Next(0, 240), SSV.Y + RandomHelper.Next(0, 240), SSV.Z); + startingPoint = new Vector3D(randomScene.X + RandomHelper.Next(0, 240), randomScene.Y + RandomHelper.Next(0, 240), randomScene.Z); if (world.CheckLocationForFlag(startingPoint, DiIiS_NA.Core.MPQ.FileFormats.Scene.NavCellFlags.AllowWalk)) break; } @@ -1591,7 +1594,7 @@ namespace DiIiS_NA.GameServer.GSSystem.GeneratorsSystem { bool busy = false; foreach (var chunk in world.worldData.SceneParams.SceneChunks) - if (Math.Abs(chunk.PRTransform.Vector3D.X - x) < 0.001 & Math.Abs(chunk.PRTransform.Vector3D.Y - y) < 0.001) + if (Math.Abs(chunk.PRTransform.Vector3D.X - x) < Globals.FLOAT_TOLERANCE & Math.Abs(chunk.PRTransform.Vector3D.Y - y) < Globals.FLOAT_TOLERANCE) { busy = true; break; diff --git a/src/DiIiS-NA/D3-GameServer/GSSystem/ItemsSystem/Item.cs b/src/DiIiS-NA/D3-GameServer/GSSystem/ItemsSystem/Item.cs index 16db713..331171c 100644 --- a/src/DiIiS-NA/D3-GameServer/GSSystem/ItemsSystem/Item.cs +++ b/src/DiIiS-NA/D3-GameServer/GSSystem/ItemsSystem/Item.cs @@ -552,8 +552,7 @@ namespace DiIiS_NA.GameServer.GSSystem.ItemsSystem if (ratio > 1f) ratio = 1f; Attributes[GameAttribute.Block_Amount_Item_Min] += Math.Abs(scaleCapMin * ratio - Attributes[GameAttribute.Block_Amount_Item_Min, 0]); - Attributes[GameAttribute.Block_Amount_Item_Delta] += Math.Abs(scaleCapDelta * ratio - - Attributes[GameAttribute.Block_Amount_Item_Delta, 0]); + Attributes[GameAttribute.Block_Amount_Item_Delta] += Math.Abs(scaleCapDelta * ratio - Attributes[GameAttribute.Block_Amount_Item_Delta, 0]); } } } diff --git a/src/DiIiS-NA/D3-GameServer/GSSystem/MapSystem/World.cs b/src/DiIiS-NA/D3-GameServer/GSSystem/MapSystem/World.cs index 5ec3e88..490fbef 100644 --- a/src/DiIiS-NA/D3-GameServer/GSSystem/MapSystem/World.cs +++ b/src/DiIiS-NA/D3-GameServer/GSSystem/MapSystem/World.cs @@ -590,41 +590,36 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem public Actor SpawnMonster(ActorSno monsterSno, Vector3D position) { - if (monsterSno == ActorSno.__NONE) - { - return null; - } + if (monsterSno == ActorSno.__NONE) return null; + Logger.MethodTrace($"Spawning monster {monsterSno} at {position}"); var monster = ActorFactory.Create(this, monsterSno, new TagMap()); - if (monster != null) + if (monster == null) return null; + + monster.EnterWorld(position); + if (monster.AnimationSet == null) return monster; + var animationTag = new[] { AnimationSetKeys.Spawn, AnimationSetKeys.Spawn2 }.FirstOrDefault(x => monster.AnimationSet.TagMapAnimDefault.ContainsKey(x)); + + if (animationTag != null) { - monster.EnterWorld(position); - if (monster.AnimationSet != null) - { - var animationTag = new[] { AnimationSetKeys.Spawn, AnimationSetKeys.Spawn2 }.FirstOrDefault(x => monster.AnimationSet.TagMapAnimDefault.ContainsKey(x)); + monster.World.BroadcastIfRevealed(plr => new PlayAnimationMessage + { + ActorID = monster.DynamicID(plr), + AnimReason = 5, + UnitAniimStartTime = 0, + tAnim = new PlayAnimationMessageSpec[] + { + new() + { + Duration = 150, + AnimationSNO = monster.AnimationSet.TagMapAnimDefault[animationTag], + PermutationIndex = 0, + Speed = 1 + } + } - if (animationTag != null) - { - monster.World.BroadcastIfRevealed(plr => new PlayAnimationMessage - { - ActorID = monster.DynamicID(plr), - AnimReason = 5, - UnitAniimStartTime = 0, - tAnim = new PlayAnimationMessageSpec[] - { - new() - { - Duration = 150, - AnimationSNO = monster.AnimationSet.TagMapAnimDefault[animationTag], - PermutationIndex = 0, - Speed = 1 - } - } - - }, monster); - } - } + }, monster); } - return monster; + return monster; } private Queue> _flippyTimers = new(); @@ -640,19 +635,21 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem player.GroundItems[item.GlobalID] = item; // FIXME: Hacky. /komiga DropItem(source, null, item); } - public void PlayPieAnimation(Actor actor, Actor User, int PowerSNO, Vector3D TargetPosition) + + [Obsolete("Isn't used anymore. Is it useful?")] + public void PlayPieAnimation(Actor actor, Actor user, int powerSNO, Vector3D targetPosition) { BroadcastIfRevealed(plr => new ACDTranslateDetPathPieWedgeMessage { ann = (int)actor.DynamicID(plr), - StartPos = User.Position, - FirstTagetPos = User.Position, + StartPos = user.Position, + FirstTagetPos = user.Position, MoveFlags = 9, AnimTag = 1, PieData = new DPathPieData { - Field0 = TargetPosition, + Field0 = targetPosition, Field1 = 1, Field2 = 1, Field3 = 1 diff --git a/src/DiIiS-NA/D3-GameServer/GSSystem/PlayerSystem/Player.cs b/src/DiIiS-NA/D3-GameServer/GSSystem/PlayerSystem/Player.cs index f570f55..8235caa 100644 --- a/src/DiIiS-NA/D3-GameServer/GSSystem/PlayerSystem/Player.cs +++ b/src/DiIiS-NA/D3-GameServer/GSSystem/PlayerSystem/Player.cs @@ -2395,7 +2395,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable var rem = new List(); foreach (var fol in Followers.Where(f => Math.Abs(World.GetActorByGlobalId(f.Key).Attributes[GameAttribute.Summoned_By_SNO] - - oldSNOSkill) < 0.001)) + oldSNOSkill) < Globals.FLOAT_TOLERANCE)) rem.Add(fol.Key); foreach (var rm in rem) DestroyFollowerById(rm); @@ -2914,13 +2914,13 @@ public class Player : Actor, IMessageConsumer, IUpdateable //* private void TrainArtisan(GameClient client, RequestTrainArtisanMessage message) { - if (CurrentArtisan == null || !artisanTrainHelpers.ContainsKey(CurrentArtisan.Value)) + if (CurrentArtisan == null || !_artisanTrainHelpers.ContainsKey(CurrentArtisan.Value)) { Logger.Warn("Training for artisan {} is not supported", CurrentArtisan); return; } - var trainHelper = artisanTrainHelpers[CurrentArtisan.Value]; + var trainHelper = _artisanTrainHelpers[CurrentArtisan.Value]; if (trainHelper.HasMaxLevel) return; @@ -2947,7 +2947,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable if (trainHelper.Criteria is not null) GrantCriteria(trainHelper.Criteria.Value); - if (artisanTrainHelpers.All(x => x.Value.HasMaxLevel)) + if (_artisanTrainHelpers.All(x => x.Value.HasMaxLevel)) GrantCriteria(74987249993545); client.SendMessage(new CrafterLevelUpMessage @@ -2966,13 +2966,13 @@ public class Player : Actor, IMessageConsumer, IUpdateable public void UnlockTransmog(int transmogGBID) { - if (learnedTransmogs.Contains(transmogGBID)) return; + if (_learnedTransmogs.Contains(transmogGBID)) return; InGameClient.SendMessage(new UnlockTransmogMessage() { TransmogGBID = transmogGBID }); Logger.Trace("Learning transmog #{0}", transmogGBID); - learnedTransmogs.Add(transmogGBID); - mystic_data.LearnedRecipes = SerializeBytes(learnedTransmogs); - World.Game.GameDbSession.SessionUpdate(mystic_data); + _learnedTransmogs.Add(transmogGBID); + _mysticData.LearnedRecipes = SerializeBytes(_learnedTransmogs); + World.Game.GameDbSession.SessionUpdate(_mysticData); LoadCrafterData(); } @@ -3067,7 +3067,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable foreach (var timed_out in TimedActions.Where(t => t.TimedOut).ToList()) TimedActions.Remove(timed_out); - // Check the Killstreaks + // Check the kill streaks ExpBonusData.Check(0); ExpBonusData.Check(1); @@ -3165,27 +3165,29 @@ public class Player : Actor, IMessageConsumer, IUpdateable #region Necromancer summons - var switchertobool = false; - var switchertoboolTwo = false; - ActiveSkillSavedData NowSkillGolem = null; + var switcherToBool = false; + var switcherToBool2 = false; + ActiveSkillSavedData nowSkillGolen = null; foreach (var skill in SkillSet.ActiveSkills) if (skill.snoSkill == 453801) - switchertobool = true; + switcherToBool = true; foreach (var skill in SkillSet.ActiveSkills) if (skill.snoSkill == 451537) { - switchertoboolTwo = true; - NowSkillGolem = skill; + switcherToBool2 = true; + nowSkillGolen = skill; } - ActiveSkeletons = switchertobool; - EnableGolem = switchertoboolTwo; + ActiveSkeletons = switcherToBool; + EnableGolem = switcherToBool2; - var Killer = new PowerContext(); - Killer.User = this; - Killer.World = World; - Killer.PowerSNO = -1; + var killer = new PowerContext + { + User = this, + World = World, + PowerSNO = -1 + }; if (ActiveSkeletons) { @@ -3255,8 +3257,8 @@ public class Player : Actor, IMessageConsumer, IUpdateable { PetId = ActiveGolem.GlobalID }); - Killer.Target = ActiveGolem; - (ActiveGolem as Minion).Kill(Killer); + killer.Target = ActiveGolem; + (ActiveGolem as Minion).Kill(killer); } ActiveGolem = null; @@ -3386,20 +3388,14 @@ public class Player : Actor, IMessageConsumer, IUpdateable #endregion - public T RuneSelect(int PowerSNO, T none, T runeA, T runeB, T runeC, T runeD, T runeE) + public T RuneSelect(int powerSno, T none, T runeA, T runeB, T runeC, T runeD, T runeE) { - var Rune_A = Attributes[GameAttribute.Rune_A, PowerSNO]; - var Rune_B = Attributes[GameAttribute.Rune_B, PowerSNO]; - var Rune_C = Attributes[GameAttribute.Rune_C, PowerSNO]; - var Rune_D = Attributes[GameAttribute.Rune_D, PowerSNO]; - var Rune_E = Attributes[GameAttribute.Rune_E, PowerSNO]; - - if (Rune_A > 0) return runeA; - else if (Rune_B > 0) return runeB; - else if (Rune_C > 0) return runeC; - else if (Rune_D > 0) return runeD; - else if (Rune_E > 0) return runeE; - else return none; + if (Attributes[GameAttribute.Rune_A, powerSno] > 0) return runeA; + if (Attributes[GameAttribute.Rune_B, powerSno] > 0) return runeB; + if (Attributes[GameAttribute.Rune_C, powerSno] > 0) return runeC; + if (Attributes[GameAttribute.Rune_D, powerSno] > 0) return runeD; + if (Attributes[GameAttribute.Rune_E, powerSno] > 0) return runeE; + return none; } #region enter, leave, reveal handling @@ -3410,11 +3406,11 @@ public class Player : Actor, IMessageConsumer, IUpdateable public void RevealScenesToPlayer() { //List scenes_around = this.GetScenesInRegion(DefaultQueryProximityLenght * 2); - var scenes_around = World.Scenes.Values.ToList(); + var scenesAround = World.Scenes.Values.ToList(); if (!World.worldData.DynamicWorld) - scenes_around = GetScenesInRegion(DefaultQueryProximityLenght * 3); + scenesAround = GetScenesInRegion(DefaultQueryProximityLenght * 3); - foreach (var scene in scenes_around) // reveal scenes in player's proximity. + foreach (var scene in scenesAround) // reveal scenes in player's proximity. { if (scene.IsRevealedToPlayer(this)) // if the actors is already revealed skip it. continue; // if the scene is already revealed, skip it. @@ -3428,7 +3424,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable foreach (var scene in World.Scenes.Values) // unreveal far scenes { - if (!scene.IsRevealedToPlayer(this) || scenes_around.Contains(scene)) + if (!scene.IsRevealedToPlayer(this) || scenesAround.Contains(scene)) continue; if (scene.Parent != @@ -3444,9 +3440,9 @@ public class Player : Actor, IMessageConsumer, IUpdateable /// public void RevealActorsToPlayer() { - var Range = 200f; + var range = 200f; if (InGameClient.Game.CurrentEncounter.Activated) - Range = 360f; + range = 360f; var specialWorlds = new WorldSno[] { @@ -3457,9 +3453,9 @@ public class Player : Actor, IMessageConsumer, IUpdateable WorldSno.a1trdun_level05_templar }; - var actors_around = specialWorlds.Contains(World.SNO) ? World.Actors.Values.ToList() : GetActorsInRange(Range); + var actorsAround = specialWorlds.Contains(World.SNO) ? World.Actors.Values.ToList() : GetActorsInRange(range); - foreach (var actor in actors_around) // reveal actors in player's proximity. + foreach (var actor in actorsAround) // reveal actors in player's proximity. { if (actor is Player) // if the actors is already revealed, skip it. continue; @@ -3482,7 +3478,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable foreach (var actor in World.Actors.Values) // unreveal far actors { if ((actor is Player && (!World.IsPvP || actor == this)) || - actors_around.Contains(actor)) // if the actors is already revealed, skip it. + actorsAround.Contains(actor)) // if the actors is already revealed, skip it. continue; actor.Unreveal(this); @@ -3549,7 +3545,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable world.Reveal(this); Unreveal(this); - if (_CurrentHPValue == -1f) + if (Math.Abs(_CurrentHPValue - (-1f)) < Globals.FLOAT_TOLERANCE) DefaultQueryProximityRadius = 60; InGameClient.SendMessage(new EnterWorldMessage() @@ -3580,7 +3576,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable break; } - if (_CurrentHPValue == -1f) + if (Math.Abs(_CurrentHPValue - (-1f)) < Globals.FLOAT_TOLERANCE) AddPercentageHP(100); DefaultQueryProximityRadius = 100; @@ -3750,7 +3746,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable AllBuffs.Clear(); BetweenWorlds = false; - if (Math.Abs(_CurrentHPValue - (-1)) > 0.0001) + if (Math.Abs(_CurrentHPValue - (-1)) > Globals.FLOAT_TOLERANCE) { Attributes[GameAttribute.Hitpoints_Cur] = _CurrentHPValue; Attributes[GameAttribute.Resource_Cur, (int)Toon.HeroTable.PrimaryResource + 1] = _CurrentResourceValue; @@ -3850,7 +3846,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable } /// - /// Allows hero state message to be sent when hero's some property get's updated. + /// Allows hero state message to be sent when hero's some property gets updated. /// public void UpdateHeroState() { @@ -3940,7 +3936,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable //removing tomb try { - GetObjectsInRange(100.0f).Where(h => h.playerIndex == PlayerIndex).First().Destroy(); + GetObjectsInRange(100.0f).First(h => h.playerIndex == PlayerIndex).Destroy(); } catch { @@ -3949,8 +3945,8 @@ public class Player : Actor, IMessageConsumer, IUpdateable Teleport(spawnPosition); World.BuffManager.AddBuff(this, this, new ActorGhostedBuff()); - var old_skills = SkillSet.ActiveSkills.Select(s => s.snoSkill).ToList(); - foreach (var skill in old_skills) + var oldSkills = SkillSet.ActiveSkills.Select(s => s.snoSkill).ToList(); + foreach (var skill in oldSkills) { var power = PowerLoader.CreateImplementationForPowerSNO(skill); if (power != null && power.EvalTag(PowerKeys.SynergyPower) != -1) @@ -3998,13 +3994,12 @@ public class Player : Actor, IMessageConsumer, IUpdateable get { var baseStrength = 0.0f; + var multiplier = ParagonLevel > 0 ? GameServerConfig.Instance.StrengthParagonMultiplier : GameServerConfig.Instance.StrengthMultiplier; + baseStrength = Toon.HeroTable.CoreAttribute == GameBalance.PrimaryAttribute.Strength + ? Toon.HeroTable.Strength + (Level - 1) * 3 + : Toon.HeroTable.Strength + (Level - 1); - if (Toon.HeroTable.CoreAttribute == GameBalance.PrimaryAttribute.Strength) - baseStrength = Toon.HeroTable.Strength + (Level - 1) * 3; - else - baseStrength = Toon.HeroTable.Strength + (Level - 1); - - return baseStrength; + return baseStrength * multiplier; } } @@ -4015,17 +4010,18 @@ public class Player : Actor, IMessageConsumer, IUpdateable { get { - if (Toon.HeroTable.CoreAttribute == GameBalance.PrimaryAttribute.Dexterity) - return Toon.HeroTable.Dexterity + (Level - 1) * 3; - else - return Toon.HeroTable.Dexterity + (Level - 1); + var multiplier = ParagonLevel > 0 ? GameServerConfig.Instance.DexterityParagonMultiplier : GameServerConfig.Instance.DexterityMultiplier; + + return Toon.HeroTable.CoreAttribute == GameBalance.PrimaryAttribute.Dexterity + ? Toon.HeroTable.Dexterity + (Level - 1) * 3 * multiplier + : Toon.HeroTable.Dexterity + (Level - 1) * multiplier; } } public float TotalDexterity => Attributes[GameAttribute.Dexterity] + Inventory.GetItemBonus(GameAttribute.Dexterity_Item); - public float Vitality => Toon.HeroTable.Vitality + (Level - 1) * 2; + public float Vitality => Toon.HeroTable.Vitality + (Level - 1) * 2 * (ParagonLevel > 0 ? GameServerConfig.Instance.VitalityParagonMultiplier : GameServerConfig.Instance.VitalityMultiplier); public float TotalVitality => Attributes[GameAttribute.Vitality] + Inventory.GetItemBonus(GameAttribute.Vitality_Item); @@ -4034,10 +4030,10 @@ public class Player : Actor, IMessageConsumer, IUpdateable { get { - if (Toon.HeroTable.CoreAttribute == GameBalance.PrimaryAttribute.Intelligence) - return Toon.HeroTable.Intelligence + (Level - 1) * 3; - else - return Toon.HeroTable.Intelligence + (Level - 1); + var multiplier = ParagonLevel > 0 ? GameServerConfig.Instance.IntelligenceParagonMultiplier : GameServerConfig.Instance.IntelligenceMultiplier; + return Toon.HeroTable.CoreAttribute == GameBalance.PrimaryAttribute.Intelligence + ? Toon.HeroTable.Intelligence + (Level - 1) * 3 * multiplier + : Toon.HeroTable.Intelligence + (Level - 1) * multiplier; } } @@ -4325,15 +4321,15 @@ public class Player : Actor, IMessageConsumer, IUpdateable if (query.Count == 0) { //returns empty data - var hireling_empty = new HirelingInfo + var emptyHireling = new HirelingInfo { HirelingIndex = type, GbidName = 0x0000, Dead = false, Skill1SNOId = -1, Skill2SNOId = -1, Skill3SNOId = -1, Skill4SNOId = -1, annItems = -1 }; - return hireling_empty; + return emptyHireling; } - var hireling_full = new HirelingInfo + return new HirelingInfo { HirelingIndex = type, GbidName = 0x0000, @@ -4344,14 +4340,13 @@ public class Player : Actor, IMessageConsumer, IUpdateable Skill4SNOId = query.First().Skill4SNOId, annItems = -1 }; - return hireling_full; } private List Unserialize(string data) { - var recparts = data.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); + var parts = data.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); var ret = new List(); - foreach (var recid in recparts) ret.Add(Convert.ToInt32(recid, 10)); + foreach (var part in parts) ret.Add(Convert.ToInt32(part, 10)); return ret; } @@ -4380,34 +4375,35 @@ public class Player : Actor, IMessageConsumer, IUpdateable public void LearnRecipe(ArtisanType? artisan, int recipe) { Logger.Trace("Learning recipe #{0}, Artisan type: {1}", recipe, artisan); + /*var query = this.World.Game.GameDBSession.SessionQuerySingle( - dbi => - dbi.DBGameAccount.Id == this.Toon.GameAccount.PersistentID && - dbi.Artisan == artisan && - dbi.isHardcore == this.World.Game.IsHardcore);*/ - if (artisan == ArtisanType.Blacksmith) + dbi => + dbi.DBGameAccount.Id == this.Toon.GameAccount.PersistentID && + dbi.Artisan == artisan && + dbi.isHardcore == this.World.Game.IsHardcore);*/ + switch (artisan) { - learnedBlacksmithRecipes.Add(recipe); - blacksmith_data.LearnedRecipes = SerializeBytes(learnedBlacksmithRecipes); - World.Game.GameDbSession.SessionUpdate(blacksmith_data); - UpdateAchievementCounter(404, 1, 0); - } - else if (artisan == ArtisanType.Jeweler) - { - learnedJewelerRecipes.Add(recipe); - jeweler_data.LearnedRecipes = SerializeBytes(learnedJewelerRecipes); - World.Game.GameDbSession.SessionUpdate(jeweler_data); - UpdateAchievementCounter(404, 1, 1); + case ArtisanType.Blacksmith: + _learnedBlacksmithRecipes.Add(recipe); + _blacksmithData.LearnedRecipes = SerializeBytes(_learnedBlacksmithRecipes); + World.Game.GameDbSession.SessionUpdate(_blacksmithData); + UpdateAchievementCounter(404, 1, 0); + break; + case ArtisanType.Jeweler: + _learnedJewelerRecipes.Add(recipe); + _jewelerData.LearnedRecipes = SerializeBytes(_learnedJewelerRecipes); + World.Game.GameDbSession.SessionUpdate(_jewelerData); + UpdateAchievementCounter(404, 1, 1); + break; } LoadCrafterData(); } - public bool RecipeAvailable(GameBalance.RecipeTable recipe_definition) + public bool RecipeAvailable(GameBalance.RecipeTable recipeDefinition) { - if (recipe_definition.Flags == 0) return true; - return learnedBlacksmithRecipes.Contains(recipe_definition.Hash) || - learnedJewelerRecipes.Contains(recipe_definition.Hash); + if (recipeDefinition.Flags == 0) return true; + return _learnedBlacksmithRecipes.Contains(recipeDefinition.Hash) || _learnedJewelerRecipes.Contains(recipeDefinition.Hash); } public PlayerBannerMessage GetPlayerBanner() @@ -4420,69 +4416,69 @@ public class Player : Actor, IMessageConsumer, IUpdateable return new PlayerBannerMessage() { PlayerBanner = playerBanner }; } - private List learnedBlacksmithRecipes = new(); - private List learnedJewelerRecipes = new(); - private List learnedTransmogs = new(); + private List _learnedBlacksmithRecipes = new(); + private List _learnedJewelerRecipes = new(); + private List _learnedTransmogs = new(); - private DBCraft blacksmith_data = null; - private DBCraft jeweler_data = null; - private DBCraft mystic_data = null; - private Dictionary artisanTrainHelpers = new(); + private DBCraft _blacksmithData = null; + private DBCraft _jewelerData = null; + private DBCraft _mysticData = null; + private readonly Dictionary _artisanTrainHelpers = new(); public void LoadCrafterData() { - if (blacksmith_data == null) + if (_blacksmithData == null) { var craft_data = World.Game.GameDbSession.SessionQueryWhere(dbc => dbc.DBGameAccount.Id == Toon.GameAccount.PersistentID); - blacksmith_data = craft_data.Single(dbc => + _blacksmithData = craft_data.Single(dbc => dbc.Artisan == "Blacksmith" && dbc.isHardcore == World.Game.IsHardcore && dbc.isSeasoned == World.Game.IsSeasoned); - jeweler_data = craft_data.Single(dbc => + _jewelerData = craft_data.Single(dbc => dbc.Artisan == "Jeweler" && dbc.isHardcore == World.Game.IsHardcore && dbc.isSeasoned == World.Game.IsSeasoned); - mystic_data = craft_data.Single(dbc => + _mysticData = craft_data.Single(dbc => dbc.Artisan == "Mystic" && dbc.isHardcore == World.Game.IsHardcore && dbc.isSeasoned == World.Game.IsSeasoned); - artisanTrainHelpers[ArtisanType.Blacksmith] = - new ArtisanTrainHelper(blacksmith_data, ArtisanType.Blacksmith); - artisanTrainHelpers[ArtisanType.Jeweler] = new ArtisanTrainHelper(jeweler_data, ArtisanType.Jeweler); - artisanTrainHelpers[ArtisanType.Mystic] = new ArtisanTrainHelper(mystic_data, ArtisanType.Mystic); + _artisanTrainHelpers[ArtisanType.Blacksmith] = + new ArtisanTrainHelper(_blacksmithData, ArtisanType.Blacksmith); + _artisanTrainHelpers[ArtisanType.Jeweler] = new ArtisanTrainHelper(_jewelerData, ArtisanType.Jeweler); + _artisanTrainHelpers[ArtisanType.Mystic] = new ArtisanTrainHelper(_mysticData, ArtisanType.Mystic); } var blacksmith = D3.ItemCrafting.CrafterData.CreateBuilder() .SetLevel(InGameClient.Game.CurrentAct == 3000 - ? BlacksmithUnlocked == false && blacksmith_data.Level < 1 ? 1 : blacksmith_data.Level - : blacksmith_data.Level) + ? BlacksmithUnlocked == false && _blacksmithData.Level < 1 ? 1 : _blacksmithData.Level + : _blacksmithData.Level) .SetCooldownEnd(0) - .AddRangeRecipes(UnserializeBytes(blacksmith_data.LearnedRecipes)) + .AddRangeRecipes(UnserializeBytes(_blacksmithData.LearnedRecipes)) .Build(); - learnedBlacksmithRecipes = UnserializeBytes(blacksmith_data.LearnedRecipes); + _learnedBlacksmithRecipes = UnserializeBytes(_blacksmithData.LearnedRecipes); var jeweler = D3.ItemCrafting.CrafterData.CreateBuilder() .SetLevel(InGameClient.Game.CurrentAct == 3000 - ? JewelerUnlocked == false && jeweler_data.Level < 1 ? 1 : jeweler_data.Level - : jeweler_data.Level) + ? JewelerUnlocked == false && _jewelerData.Level < 1 ? 1 : _jewelerData.Level + : _jewelerData.Level) .SetCooldownEnd(0) - .AddRangeRecipes(UnserializeBytes(jeweler_data.LearnedRecipes)) + .AddRangeRecipes(UnserializeBytes(_jewelerData.LearnedRecipes)) .Build(); - learnedJewelerRecipes = UnserializeBytes(jeweler_data.LearnedRecipes); + _learnedJewelerRecipes = UnserializeBytes(_jewelerData.LearnedRecipes); var mystic = D3.ItemCrafting.CrafterData.CreateBuilder() .SetLevel(InGameClient.Game.CurrentAct == 3000 - ? MysticUnlocked == false && mystic_data.Level < 1 ? 1 : mystic_data.Level - : mystic_data.Level) + ? MysticUnlocked == false && _mysticData.Level < 1 ? 1 : _mysticData.Level + : _mysticData.Level) .SetCooldownEnd(0) .Build(); var transmog = D3.ItemCrafting.CrafterSavedData.CreateBuilder() .SetTransmogData(D3.GameBalance.BitPackedGbidArray.CreateBuilder() - .SetBitfield(ByteString.CopyFrom(mystic_data.LearnedRecipes))) + .SetBitfield(ByteString.CopyFrom(_mysticData.LearnedRecipes))) //.AddRangeUnlockedTransmogs(this.UnserializeBytes(mystic_data.LearnedRecipes)) .Build(); - learnedTransmogs = UnserializeBytes(mystic_data.LearnedRecipes); + _learnedTransmogs = UnserializeBytes(_mysticData.LearnedRecipes); if (BlacksmithUnlocked || InGameClient.Game.CurrentAct == 3000) InGameClient.SendMessage(new GenericBlobMessage(Opcodes.CraftingDataBlacksmithInitialMessage) @@ -4503,27 +4499,26 @@ public class Player : Actor, IMessageConsumer, IUpdateable public void LoadCurrencyData() { - var bloodShards = 0; - bloodShards = Toon.GameAccount.BloodShards; + var bloodShards = Toon.GameAccount.BloodShards; // TODO: is this needed? @iamdroppy Inventory.UpdateCurrencies(); } public void LoadMailData() { - var mail_data = + var mailData = World.Game.GameDbSession.SessionQueryWhere(dbm => dbm.DBToon.Id == Toon.PersistentID && dbm.Claimed == false); var mails = D3.Items.Mails.CreateBuilder(); - foreach (var mail in mail_data) + foreach (var mail in mailData) { - var mail_row = D3.Items.Mail.CreateBuilder() + var mailRow = D3.Items.Mail.CreateBuilder() .SetAccountTo(Toon.D3EntityID) .SetAccountFrom(Toon.D3EntityID) .SetMailId(mail.Id) .SetTitle(mail.Title) .SetBody(mail.Body); if (mail.ItemGBID != -1) - mail_row.SetAttachments(D3.Items.MailAttachments.CreateBuilder() + mailRow.SetAttachments(D3.Items.MailAttachments.CreateBuilder() .SetItems(D3.Items.ItemList.CreateBuilder() .AddItems(D3.Items.SavedItem.CreateBuilder() .SetId(D3.OnlineService.ItemId.CreateBuilder().SetIdLow(0).SetIdHigh(0x3C000002517A294)) @@ -4542,15 +4537,16 @@ public class Player : Actor, IMessageConsumer, IUpdateable ) ) ); - mails.AddMailsProp(mail_row); + mails.AddMailsProp(mailRow); } - var mail_contents = D3.GameMessage.MailContents.CreateBuilder() - .SetAppendMessages(false) - .SetMails(mails) - .Build(); - - InGameClient.SendMessage(new MailDigestMessage() { MailContents = mail_contents }); + InGameClient.SendMessage(new MailDigestMessage() + { + MailContents = D3.GameMessage.MailContents.CreateBuilder() + .SetAppendMessages(false) + .SetMails(mails) + .Build() + }); } //*/ @@ -4578,10 +4574,10 @@ public class Player : Actor, IMessageConsumer, IUpdateable public void LoadShownTutorials() { - var tutorials = new List(); - tutorials.Add(64); - for (var i = 0; i < 15; i++) - tutorials.Add(0); + // var tutorials = new List(); + // tutorials.Add(64); + // for (var i = 0; i < 15; i++) + // tutorials.Add(0); var seenTutorials = Toon.GameAccount.DBGameAccount.SeenTutorials; var state = D3.GameMessage.TutorialState.CreateBuilder() @@ -4590,13 +4586,13 @@ public class Player : Actor, IMessageConsumer, IUpdateable InGameClient.SendMessage(new GenericBlobMessage(Opcodes.TutorialStateMessage) { Data = state.ToByteArray() }); } - private List _unlockedAchievements = new(); - private List _unlockedCriterias = new(); + private readonly List _unlockedAchievements = new(); + private readonly List _unlockCriteria = new(); - private Dictionary AchievementCounters = new(); + private readonly Dictionary _achievementCounters = new(); - public int DodgesInARow = 0; - public int BlocksInARow = 0; + public int DodgesInARow { get; set; } = 0; + public int BlocksInARow { get; set; }= 0; public void GrantAchievement(ulong id) { @@ -4606,20 +4602,20 @@ public class Player : Actor, IMessageConsumer, IUpdateable _unlockedAchievements.Add(id); try { - var Achievement = AchievementSystem.AchievementManager.GetAchievementById(id); - long Platinum = -1; - foreach (var attr in Achievement.AttributesList) + var achievement = AchievementSystem.AchievementManager.GetAchievementById(id); + long platinum = -1; + foreach (var attr in achievement.AttributesList) if (attr.Key == "Reward Currency Quantity") - Platinum = long.Parse(attr.Value); + platinum = long.Parse(attr.Value); InGameClient.SendMessage(new MessageSystem.Message.Definitions.Platinum.PlatinumAchievementAwardedMessage { CurrentPlatinum = InGameClient.BnetClient.Account.GameAccount.Platinum, idAchievement = id, - PlatinumIncrement = Platinum + PlatinumIncrement = platinum }); - if (Platinum > 0) + if (platinum > 0) { - InGameClient.BnetClient.Account.GameAccount.Platinum += (int)Platinum; + InGameClient.BnetClient.Account.GameAccount.Platinum += (int)platinum; Inventory.UpdateCurrencies(); } @@ -4633,33 +4629,33 @@ public class Player : Actor, IMessageConsumer, IUpdateable public void AddAchievementCounter(ulong id, uint count) { - lock (AchievementCounters) + lock (_achievementCounters) { - if (!AchievementCounters.ContainsKey(id)) - AchievementCounters.Add(id, count); + if (!_achievementCounters.ContainsKey(id)) + _achievementCounters.Add(id, count); else - AchievementCounters[id] += count; + _achievementCounters[id] += count; } } public void CheckAchievementCounters() { - lock (AchievementCounters) + lock (_achievementCounters) { - foreach (var counter in AchievementCounters) + foreach (var counter in _achievementCounters) { if (counter.Value == 0) continue; UpdateSingleAchievementCounter(counter.Key, counter.Value); } - AchievementCounters.Clear(); + _achievementCounters.Clear(); } } public void GrantCriteria(ulong id) { - if (_unlockedCriterias.Contains(id)) return; - _unlockedCriterias.Add(id); + if (_unlockCriteria.Contains(id)) return; + _unlockCriteria.Add(id); try { GameServer.ClientSystem.GameServer.GSBackend.GrantCriteria(Toon.GameAccount.PersistentID, id); @@ -4824,13 +4820,13 @@ public class Player : Actor, IMessageConsumer, IUpdateable public int CastingSnoPower = -1; - public void StartCasting(int durationTicks, Action result, int skillsno = -1) + public void StartCasting(int durationTicks, Action result, int skillSno = -1) { IsCasting = true; CastResult = result; Attributes[GameAttribute.Looping_Animation_Start_Time] = World.Game.TickCounter; Attributes[GameAttribute.Looping_Animation_End_Time] = World.Game.TickCounter + durationTicks; - CastingSnoPower = skillsno; + CastingSnoPower = skillSno; if (CastingSnoPower != -1) { Attributes[GameAttribute.Buff_Icon_Start_Tick0, CastingSnoPower] = World.Game.TickCounter; @@ -4882,7 +4878,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable #region generic properties - public int ClassSNO => Toon.Gender == 0 ? Toon.HeroTable.SNOMaleActor : Toon.HeroTable.SNOFemaleActor; + public int ClassSno => Toon.Gender == 0 ? Toon.HeroTable.SNOMaleActor : Toon.HeroTable.SNOFemaleActor; public int AdditionalLootItems { @@ -4910,7 +4906,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable public int SecondaryResourceID => (int)Toon.HeroTable.SecondaryResource; - [Obsolete] + [Obsolete("Not used anymore. Should it be removed?")] public bool IsInTown { get @@ -4945,7 +4941,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable (Attributes[GameAttribute.Resource_Max_Percent_Bonus, resourceId] + 1), 0); } - public static List LevelBorders = new() + public static readonly List LevelBorders = new() { 0, 280, 2700, 4500, 6600, 9000, 11700, 14000, 16500, 19200, 22100, /* Level 0-10 */ 25200, 28500, 32000, 35700, 39600, 43700, 48000, 52500, 57200, 62100, /* Level 11-20 */ @@ -4958,7 +4954,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable 100000000 /* Level 61-70 */ }; - public static List ParagonLevelBorders = new() + public static readonly List ParagonLevelBorders = new() { //7200000,8640000,10800000,11520000,12960000,14400000,15840000,17280000,18720000,20160000,21600000,23040000,24480000,25920000,27360000, //28800000,30240000,31680000,33120000,34560000,36000000,37440000,38880000,40320,41760000,43200000,41760000,43200000,44640000,46080000, @@ -5141,9 +5137,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable }); Conversations.StartConversation(0x0002A777); //LevelUp Conversation - Attributes[GameAttribute.Alt_Experience_Next_Lo] = - Attributes[GameAttribute.Alt_Experience_Next_Lo] + - (int)ParagonLevelBorders[Attributes[GameAttribute.Alt_Level]]; + Attributes[GameAttribute.Alt_Experience_Next_Lo] += (int)ParagonLevelBorders[Attributes[GameAttribute.Alt_Level]]; // On level up, health is set to max Attributes[GameAttribute.Hitpoints_Cur] = Attributes[GameAttribute.Hitpoints_Max_Total]; // set resources to max as well @@ -5165,8 +5159,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable Level++; Attributes[GameAttribute.Level]++; Toon.LevelUp(); - if (World.Game.MonsterLevel + 1 == - Attributes[GameAttribute.Level]) //if this is suitable level to update + if (World.Game.MonsterLevel + 1 == Attributes[GameAttribute.Level]) //if this is suitable level to update World.Game.UpdateLevel(Attributes[GameAttribute.Level]); InGameClient.SendMessage(new PlayerLevel() @@ -5326,7 +5319,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable public void VacuumPickupHealthOrb(float radius = -1) { - if (Math.Abs(radius - -1) < 0.001) + if (Math.Abs(radius - -1) < Globals.FLOAT_TOLERANCE) radius = Attributes[GameAttribute.Gold_PickUp_Radius]; var itemList = GetItemsInRange(radius); foreach (var item in itemList) @@ -5501,12 +5494,11 @@ public class Player : Actor, IMessageConsumer, IUpdateable item.Destroy(); } - else if (item.ItemDefinition.Name == "p1_normal_rifts_Orb" || - item.ItemDefinition.Name == "p1_tiered_rifts_Orb") + else if (item.ItemDefinition.Name is "p1_normal_rifts_Orb" or "p1_tiered_rifts_Orb") { if (InGameClient.Game.ActiveNephalemTimer && InGameClient.Game.ActiveNephalemKilledMobs == false) { - InGameClient.Game.ActiveNephalemProgress += 15f; + InGameClient.Game.ActiveNephalemProgress += 15f * GameServerConfig.Instance.NephalemRiftProgressMultiplier; foreach (var plr in InGameClient.Game.Players.Values) { plr.InGameClient.SendMessage(new FloatDataMessage(Opcodes.DunggeonFinderProgressGlyphPickUp) @@ -5630,7 +5622,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable public Actor SpawnNephalemBoss(World world) { - var boss = world.SpawnMonster(ActorSnoExtensions.nephalemPortalBosses.PickRandom(), Position); + var boss = world.SpawnMonster(ActorSnoExtensions.NephalemPortalBosses.PickRandom(), Position); boss.Attributes[GameAttribute.Bounty_Objective] = true; boss.Attributes[GameAttribute.Is_Loot_Run_Boss] = true; boss.Attributes.BroadcastChangedIfRevealed(); @@ -5658,62 +5650,67 @@ public class Player : Actor, IMessageConsumer, IUpdateable return true; } - public void AddPercentageHP(int percentage, bool GuidingLight = false) + public void AddPercentageHP(int percentage, bool guidingLight = false) { var quantity = percentage * Attributes[GameAttribute.Hitpoints_Max_Total] / 100; - AddHP(quantity, GuidingLight); + AddHP(quantity, guidingLight); } - public void AddPercentageHP(float percentage, bool GuidingLight = false) + public void AddPercentageHP(float percentage, bool guidingLight = false) { var quantity = percentage * Attributes[GameAttribute.Hitpoints_Max_Total] / 100; - AddHP(quantity, GuidingLight); + AddHP(quantity, guidingLight); } public override void AddHP(float quantity, bool guidingLight = false) { if (Dead) return; - if (quantity == 0) return; - if (quantity > 0) + switch (quantity) { - if (Attributes[GameAttribute.Hitpoints_Cur] < Attributes[GameAttribute.Hitpoints_Max_Total]) + case 0: + return; + case > 0: { - if (Toon.Class == ToonClass.Barbarian) - if (SkillSet.HasPassive(205217)) - quantity += 0.01f * Attributes[GameAttribute.Health_Globe_Bonus_Health]; - - if (guidingLight) //Monk -> Guiding Light + if (Attributes[GameAttribute.Hitpoints_Cur] < Attributes[GameAttribute.Hitpoints_Max_Total]) { - var missingHP = - (Attributes[GameAttribute.Hitpoints_Max_Total] - Attributes[GameAttribute.Hitpoints_Cur]) / - Attributes[GameAttribute.Hitpoints_Max_Total]; - if (missingHP > 0.05f) - if (!World.BuffManager.HasBuff(this)) - World.BuffManager.AddBuff(this, this, - new GuidingLightBuff(Math.Min(missingHP, 0.3f), - TickTimer.WaitSeconds(World.Game, 10.0f))); + if (Toon.Class == ToonClass.Barbarian) + if (SkillSet.HasPassive(205217)) + quantity += 0.01f * Attributes[GameAttribute.Health_Globe_Bonus_Health]; + + if (guidingLight) //Monk -> Guiding Light + { + var missingHP = + (Attributes[GameAttribute.Hitpoints_Max_Total] - Attributes[GameAttribute.Hitpoints_Cur]) / + Attributes[GameAttribute.Hitpoints_Max_Total]; + if (missingHP > 0.05f) + if (!World.BuffManager.HasBuff(this)) + World.BuffManager.AddBuff(this, this, + new GuidingLightBuff(Math.Min(missingHP, 0.3f), + TickTimer.WaitSeconds(World.Game, 10.0f))); + } + + Attributes[GameAttribute.Hitpoints_Cur] = Math.Min( + Attributes[GameAttribute.Hitpoints_Cur] + quantity, + Attributes[GameAttribute.Hitpoints_Max_Total]); + + Attributes.BroadcastChangedIfRevealed(); + InGameClient.SendMessage(new FloatingNumberMessage + { + ActorID = DynamicID(this), + Number = quantity, + Type = FloatingNumberMessage.FloatType.Green + }); } - Attributes[GameAttribute.Hitpoints_Cur] = Math.Min( + break; + } + default: + Attributes[GameAttribute.Hitpoints_Cur] = Math.Max( Attributes[GameAttribute.Hitpoints_Cur] + quantity, - Attributes[GameAttribute.Hitpoints_Max_Total]); + 0); Attributes.BroadcastChangedIfRevealed(); - InGameClient.SendMessage(new FloatingNumberMessage - { - ActorID = DynamicID(this), - Number = quantity, - Type = FloatingNumberMessage.FloatType.Green - }); - } - } - else - { - Attributes[GameAttribute.Hitpoints_Cur] = Math.Max( - Attributes[GameAttribute.Hitpoints_Cur] + quantity, - 0); - - Attributes.BroadcastChangedIfRevealed(); + break; } } @@ -5731,9 +5728,9 @@ public class Player : Actor, IMessageConsumer, IUpdateable #region Resource Generate/Use - private int _DisciplineSpent = 0; - private int _HatredSpent = 0; - private int _WrathSpent = 0; + private int _disciplineSpent = 0; + private int _hatredSpent = 0; + private int _wrathSpent = 0; public void GeneratePrimaryResource(float amount) { @@ -5745,7 +5742,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable if (World.BuffManager.HasBuff(this)) //Monk -> The Guardian's Path 2H amount *= 1.35f; - _ModifyResourceAttribute(PrimaryResourceID, amount); + ModifyResourceAttribute(PrimaryResourceID, amount); } public void UsePrimaryResource(float amount, bool tick = false) @@ -5757,28 +5754,28 @@ public class Player : Actor, IMessageConsumer, IUpdateable amount = amount * (1f - DecreaseUseResourcePercent); if (Toon.Class == ToonClass.Crusader) { - _WrathSpent += (int)amount; + _wrathSpent += (int)amount; if (!tick && SkillSet.HasPassive(310775)) //Wrathful passive - AddHP(_WrathSpent * 15f * Attributes[GameAttribute.Level]); + AddHP(_wrathSpent * 15f * Attributes[GameAttribute.Level]); //Laws of Hope -> Faith's reward if (!tick && World.BuffManager.HasBuff(this)) if (World.BuffManager.GetFirstBuff(this).HealPerWrath) - AddHP(_WrathSpent * 15f * Attributes[GameAttribute.Level]); + AddHP(_wrathSpent * 15f * Attributes[GameAttribute.Level]); - if (_WrathSpent >= 20) //Akarat Champion -> Fire Starter + if (_wrathSpent >= 20) //Akarat Champion -> Fire Starter if (!tick && World.BuffManager.HasBuff(this)) World.BuffManager.GetFirstBuff(this).wrathBlast = true; } if (Toon.Class == ToonClass.DemonHunter) { - _HatredSpent += (int)amount; + _hatredSpent += (int)amount; - if (_HatredSpent >= 150 && _DisciplineSpent >= 50) + if (_hatredSpent >= 150 && _disciplineSpent >= 50) GrantAchievement(74987243307068); - AddTimedAction(6f, new Action((q) => _HatredSpent -= (int)amount)); + AddTimedAction(6f, new Action((q) => _hatredSpent -= (int)amount)); } if (Toon.Class == ToonClass.Barbarian) @@ -5813,12 +5810,12 @@ public class Player : Actor, IMessageConsumer, IUpdateable if (SkillSet.HasPassive(205398) && Attributes[GameAttribute.Hitpoints_Cur] < Attributes[GameAttribute.Hitpoints_Max_Total] * 0.35f) //Relentless (Barbarian) amount *= 0.25f; - _ModifyResourceAttribute(PrimaryResourceID, -amount); + ModifyResourceAttribute(PrimaryResourceID, -amount); } public void GenerateSecondaryResource(float amount) { - _ModifyResourceAttribute(SecondaryResourceID, amount); + ModifyResourceAttribute(SecondaryResourceID, amount); } public void UseSecondaryResource(float amount) @@ -5833,18 +5830,18 @@ public class Player : Actor, IMessageConsumer, IUpdateable if (Toon.Class == ToonClass.DemonHunter) { - _DisciplineSpent += (int)amount; + _disciplineSpent += (int)amount; - if (_HatredSpent >= 150 && _DisciplineSpent >= 50) + if (_hatredSpent >= 150 && _disciplineSpent >= 50) GrantAchievement(74987243307068); - AddTimedAction(6f, new Action((q) => _DisciplineSpent -= (int)amount)); + AddTimedAction(6f, new Action((q) => _disciplineSpent -= (int)amount)); } - _ModifyResourceAttribute(SecondaryResourceID, -amount); + ModifyResourceAttribute(SecondaryResourceID, -amount); } - private void _ModifyResourceAttribute(int resourceID, float amount) + private void ModifyResourceAttribute(int resourceID, float amount) { if (resourceID == -1 || amount == 0) return; var current = Attributes[GameAttribute.Resource_Cur, resourceID]; @@ -5857,7 +5854,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable Attributes[GameAttribute.Resource_Cur, resourceID] + amount, 0f); - if (current == Attributes[GameAttribute.Resource_Cur, resourceID]) return; + if (Math.Abs(current - Attributes[GameAttribute.Resource_Cur, resourceID]) < Globals.FLOAT_TOLERANCE) return; Attributes.BroadcastChangedIfRevealed(); } diff --git a/src/DiIiS-NA/D3-GameServer/GSSystem/PowerSystem/Payloads/DeathPayload.cs b/src/DiIiS-NA/D3-GameServer/GSSystem/PowerSystem/Payloads/DeathPayload.cs index a37fb56..38a07dd 100644 --- a/src/DiIiS-NA/D3-GameServer/GSSystem/PowerSystem/Payloads/DeathPayload.cs +++ b/src/DiIiS-NA/D3-GameServer/GSSystem/PowerSystem/Payloads/DeathPayload.cs @@ -266,9 +266,9 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads }, Target); if (Context?.User != null) - if (Math.Abs(Context.User.Attributes[GameAttribute.Item_Power_Passive, 247640] - 1) < 0.001 || - Math.Abs(Context.User.Attributes[GameAttribute.Item_Power_Passive, 249963] - 1) < 0.001 || - Math.Abs(Context.User.Attributes[GameAttribute.Item_Power_Passive, 249954] - 1) < 0.001 || + if (Math.Abs(Context.User.Attributes[GameAttribute.Item_Power_Passive, 247640] - 1) < Globals.FLOAT_TOLERANCE || + Math.Abs(Context.User.Attributes[GameAttribute.Item_Power_Passive, 249963] - 1) < Globals.FLOAT_TOLERANCE || + Math.Abs(Context.User.Attributes[GameAttribute.Item_Power_Passive, 249954] - 1) < Globals.FLOAT_TOLERANCE || (float)FastRandom.Instance.NextDouble() < 0.1f || Target.World.SNO == WorldSno.a1dun_random_level01) switch ((int)DeathDamageType.HitEffect) @@ -1066,7 +1066,7 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads { //death implementation Player player = (Player)Target; - if (Math.Abs(player.Attributes[GameAttribute.Item_Power_Passive, 248629] - 1) < 0.001) + if (Math.Abs(player.Attributes[GameAttribute.Item_Power_Passive, 248629] - 1) < Globals.FLOAT_TOLERANCE) player.PlayEffectGroup(248680); player.StopCasting(); Target.World.BuffManager.RemoveAllBuffs(Target, false); diff --git a/src/DiIiS-NA/D3-GameServer/GSSystem/PowerSystem/Payloads/HitPayload.cs b/src/DiIiS-NA/D3-GameServer/GSSystem/PowerSystem/Payloads/HitPayload.cs index fdc746f..e176e37 100644 --- a/src/DiIiS-NA/D3-GameServer/GSSystem/PowerSystem/Payloads/HitPayload.cs +++ b/src/DiIiS-NA/D3-GameServer/GSSystem/PowerSystem/Payloads/HitPayload.cs @@ -24,25 +24,22 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads public class HitPayload : Payload { public static readonly Logger Logger = LogManager.CreateLogger(); - public float TotalDamage; - public DamageType DominantDamageType; - public Dictionary ElementDamages; - public bool IsCriticalHit; - public bool IsDodged; - public bool IsWeaponDamage; + public float TotalDamage { get; set; } + public DamageType DominantDamageType { get; set; } + public Dictionary ElementDamages { get; set; } + public bool IsCriticalHit { get; set; } + public bool IsDodged { get; set; } + public bool IsWeaponDamage { get; set; } - public bool Successful = false; - public bool Blocked = false; + public bool Successful { get; set; } + public bool Blocked { get; set; } public bool AutomaticHitEffects = true; public Action OnDeath = null; private bool WaitTo(TickTimer timer) { - while (timer.TimedOut != true) - { - - } + while (timer.TimedOut != true) ; return true; } @@ -144,7 +141,7 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads if (criticalHit) { TotalDamage *= (1f + Context.User.Attributes[GameAttribute.Crit_Damage_Percent]); - if (Context.User is Player && (Context.User as Player).Toon.Class == ToonClass.Wizard && Context.User.Attributes[GameAttribute.Resource_On_Crit, 1] > 0) + if (Context.User is Player player && player.Toon.Class == ToonClass.Wizard && player.Attributes[GameAttribute.Resource_On_Crit, 1] > 0) if (FastRandom.Instance.NextDouble() < Context.GetProcCoefficient()) (Context.User as Player).GeneratePrimaryResource(Context.User.Attributes[GameAttribute.Resource_On_Crit, 1]); } @@ -170,10 +167,9 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads switch (Context.User) { - case Player: + case Player plr: if (IsWeaponDamage) { - var plr = Context.User as Player; TotalDamage = TotalDamage * (1 + (plr.PrimaryAttribute / 100f)); if (FastRandom.Instance.NextDouble() < Context.GetProcCoefficient()) plr.GeneratePrimaryResource(plr.Attributes[GameAttribute.Resource_On_Hit]); @@ -224,7 +220,7 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads if (FastRandom.Instance.NextDouble() < Context.GetProcCoefficient()) plr.GenerateSecondaryResource(1f); - if (plr.SkillSet.HasPassive(155721) && Target.Attributes[GameAttribute.Slow] == true) + if (plr.SkillSet.HasPassive(155721) && Target.Attributes[GameAttribute.Slow]) TotalDamage *= 1.20f; if (plr.SkillSet.HasPassive(155725)) @@ -239,12 +235,12 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads if (criticalHit) { - plr.AddTimedAction(1f, new Action((q) => plr.World.BuffManager.RemoveBuffs(plr, 155715))); - plr.AddTimedAction(2f, new Action((q) => + plr.AddTimedAction(1f, _ => plr.World.BuffManager.RemoveBuffs(plr, 155715)); + plr.AddTimedAction(2f, _ => { if (plr.SkillSet.HasPassive(155715)) plr.World.BuffManager.AddBuff(plr, plr, new SharpshooterBuff()); - })); + }); } break; case ToonClass.Wizard: @@ -373,17 +369,17 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads if (plr.World.BuffManager.HasBuff(plr)) //AkaratChampion -> Rally if (plr.World.BuffManager.GetFirstBuff(plr).CDRActive) if (FastRandom.Instance.NextDouble() < 0.5f * Context.GetProcCoefficient()) - foreach (var cdBuff in plr.World.BuffManager.GetBuffs(plr)) - if (!(cdBuff.TargetPowerSNO == 269032)) //do not CDR AkaratChampionBuff - cdBuff.Reduce(60); + foreach (var cooldownBuff in plr.World.BuffManager.GetBuffs(plr)) + if (cooldownBuff.TargetPowerSNO != 269032) //do not CDR AkaratChampionBuff + cooldownBuff.Reduce(60); break; } - if (Target is Monster) + if (Target is Monster monster) { - TotalDamage *= 1 + plr.Attributes[GameAttribute.Damage_Percent_Bonus_Vs_Monster_Type, (Target as Monster).MonsterType]; + TotalDamage *= 1 + plr.Attributes[GameAttribute.Damage_Percent_Bonus_Vs_Monster_Type, monster.MonsterType]; - if ((Target as Monster).Quality > 0) + if (monster.Quality > 0) TotalDamage *= 1 + plr.Attributes[GameAttribute.Damage_Percent_Bonus_Vs_Elites]; if (attackPayload.Targets.Actors.Count == 1 && !(attackPayload.Context is Buff) && attackPayload.AutomaticHitEffects) @@ -391,40 +387,37 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads float procCoeff = Context.GetProcCoefficient(); if (FastRandom.Instance.NextDouble() < plr.Attributes[GameAttribute.On_Hit_Fear_Proc_Chance] * procCoeff) - plr.World.BuffManager.AddBuff(plr, Target, new DebuffFeared(TickTimer.WaitSeconds(plr.World.Game, 1.5f))); + plr.World.BuffManager.AddBuff(plr, monster, new DebuffFeared(TickTimer.WaitSeconds(plr.World.Game, 1.5f))); if (FastRandom.Instance.NextDouble() < plr.Attributes[GameAttribute.On_Hit_Stun_Proc_Chance] * procCoeff) - plr.World.BuffManager.AddBuff(plr, Target, new DebuffStunned(TickTimer.WaitSeconds(plr.World.Game, 1.5f))); + plr.World.BuffManager.AddBuff(plr, monster, new DebuffStunned(TickTimer.WaitSeconds(plr.World.Game, 1.5f))); if (FastRandom.Instance.NextDouble() < plr.Attributes[GameAttribute.On_Hit_Blind_Proc_Chance] * procCoeff) - plr.World.BuffManager.AddBuff(plr, Target, new DebuffBlind(TickTimer.WaitSeconds(plr.World.Game, 1.5f))); + plr.World.BuffManager.AddBuff(plr, monster, new DebuffBlind(TickTimer.WaitSeconds(plr.World.Game, 1.5f))); if (FastRandom.Instance.NextDouble() < plr.Attributes[GameAttribute.On_Hit_Freeze_Proc_Chance] * procCoeff) - plr.World.BuffManager.AddBuff(plr, Target, new DebuffFrozen(TickTimer.WaitSeconds(plr.World.Game, 1.5f))); + plr.World.BuffManager.AddBuff(plr, monster, new DebuffFrozen(TickTimer.WaitSeconds(plr.World.Game, 1.5f))); if (FastRandom.Instance.NextDouble() < plr.Attributes[GameAttribute.On_Hit_Chill_Proc_Chance] * procCoeff) - plr.World.BuffManager.AddBuff(plr, Target, new DebuffChilled(0.3f, TickTimer.WaitSeconds(plr.World.Game, 2f))); + plr.World.BuffManager.AddBuff(plr, monster, new DebuffChilled(0.3f, TickTimer.WaitSeconds(plr.World.Game, 2f))); if (FastRandom.Instance.NextDouble() < plr.Attributes[GameAttribute.On_Hit_Slow_Proc_Chance] * procCoeff) - plr.World.BuffManager.AddBuff(plr, Target, new DebuffSlowed(0.3f, TickTimer.WaitSeconds(plr.World.Game, 2f))); + plr.World.BuffManager.AddBuff(plr, monster, new DebuffSlowed(0.3f, TickTimer.WaitSeconds(plr.World.Game, 2f))); if (FastRandom.Instance.NextDouble() < plr.Attributes[GameAttribute.On_Hit_Knockback_Proc_Chance] * procCoeff) - plr.World.BuffManager.AddBuff(plr, Target, new KnockbackBuff(3f)); + plr.World.BuffManager.AddBuff(plr, monster, new KnockbackBuff(3f)); } } } break; - case Minion: - var mn = Context.User as Minion; + case Minion mn: TotalDamage *= (1 + (mn.PrimaryAttribute / 100f)); TotalDamage *= mn.Master.Attributes[GameAttribute.Attacks_Per_Second_Total]; - if (mn.Master is Player) + if (mn.Master is Player mstr) { - var mstr = mn.Master as Player; - - if (mstr.SkillSet.HasPassive(209041) && (mn is CorpseSpider || mn is CorpseSpiderQueen)) + if (mstr.SkillSet.HasPassive(209041) && mn is CorpseSpider or CorpseSpiderQueen) mstr.World.BuffManager.AddBuff(mstr, mstr, new VisionQuestBuff()); if (mn.SNO == ActorSno._dh_companion_spider) @@ -438,137 +431,149 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads } - if (Target is Player playerTarget) //check for passives here (incoming damage) + switch (Target) { - if (!playerTarget.Attributes[GameAttribute.Cannot_Dodge] && FastRandom.Instance.NextDouble() < playerTarget.DodgeChance) - IsDodged = true; - - if (playerTarget.Toon.Class == ToonClass.Monk) //Monk defensive passives + //check for passives here (incoming damage) + case Player playerTarget: { - TotalDamage *= 0.7f; //Class damage reduction bonus + if (!playerTarget.Attributes[GameAttribute.Cannot_Dodge] && FastRandom.Instance.NextDouble() < playerTarget.DodgeChance) + IsDodged = true; - if (playerTarget.World.BuffManager.HasBuff(playerTarget)) //Tempest rush -> Slipstream - if (playerTarget.World.BuffManager.GetFirstBuff(playerTarget)._slipStream) - TotalDamage *= 0.8f; - - if (playerTarget.World.BuffManager.HasBuff(playerTarget)) //Epiphany -> Desert Shroud - if (playerTarget.World.BuffManager.GetFirstBuff(playerTarget).DesertShroud) - TotalDamage *= 0.5f; - - if (IsDodged) //Mantra of Evasion -> Backlash - if (playerTarget.World.BuffManager.HasBuff(playerTarget)) - if (playerTarget.World.BuffManager.GetFirstBuff(playerTarget).Backlash) - playerTarget.World.BuffManager.GetFirstBuff(playerTarget).BacklashTrigger = true; - } - - if (playerTarget.Toon.Class == ToonClass.Barbarian) //Barb defensive passives - { - TotalDamage *= 0.7f; //Class damage reduction bonus - - if (playerTarget.SkillSet.HasPassive(205491) && PowerMath.Distance2D(Context.User.Position, playerTarget.Position) > 6f) //Superstition (barbarian) - if (FastRandom.Instance.NextDouble() < Context.GetProcCoefficient()) - playerTarget.GeneratePrimaryResource(2f); - - if (playerTarget.SkillSet.HasPassive(205398) && (playerTarget.Attributes[GameAttribute.Hitpoints_Cur] - TotalDamage) < (playerTarget.Attributes[GameAttribute.Hitpoints_Max_Total] * 0.2f)) //Relentless (barbarian) - TotalDamage *= 0.5f; - } - - if (playerTarget.Toon.Class == ToonClass.Wizard) //Wizard defensive passives - { - if (playerTarget.SkillSet.HasPassive(208471)) //GlassCannon (Wizard) - TotalDamage *= 1.1f; - - if (playerTarget.SkillSet.HasPassive(208547) && TotalDamage > (playerTarget.Attributes[GameAttribute.Hitpoints_Max_Total] * 0.15f)) //Illusionist (Wizard) + switch (playerTarget.Toon.Class) { - foreach (var cdBuff in playerTarget.World.BuffManager.GetBuffs(playerTarget)) - if (cdBuff.TargetPowerSNO == 1769 || cdBuff.TargetPowerSNO == 168344) - cdBuff.Remove(); - } - - if (playerTarget.SkillSet.HasPassive(208474) && (playerTarget.Attributes[GameAttribute.Hitpoints_Cur] - TotalDamage) <= 0) //UnstableAnomaly (wizard) - { - if (playerTarget.World.BuffManager.GetFirstBuff(playerTarget) == null) + //Monk defensive passives + case ToonClass.Monk: { - playerTarget.AddPercentageHP(45); - playerTarget.World.BuffManager.AddBuff(playerTarget, playerTarget, new UnstableAnomalyCooldownBuff()); - playerTarget.World.PowerManager.RunPower(playerTarget, 30796); - playerTarget.GenerateSecondaryResource(25f); - foreach (var cdBuff in playerTarget.World.BuffManager.GetBuffs(playerTarget)) - if (cdBuff.TargetPowerSNO == 30796) - cdBuff.Remove(); + TotalDamage *= 0.7f; //Class damage reduction bonus + + if (playerTarget.World.BuffManager.HasBuff(playerTarget)) //Tempest rush -> Slipstream + if (playerTarget.World.BuffManager.GetFirstBuff(playerTarget)._slipStream) + TotalDamage *= 0.8f; + + if (playerTarget.World.BuffManager.HasBuff(playerTarget)) //Epiphany -> Desert Shroud + if (playerTarget.World.BuffManager.GetFirstBuff(playerTarget).DesertShroud) + TotalDamage *= 0.5f; + + if (IsDodged) //Mantra of Evasion -> Backlash + if (playerTarget.World.BuffManager.HasBuff(playerTarget)) + if (playerTarget.World.BuffManager.GetFirstBuff(playerTarget).Backlash) + playerTarget.World.BuffManager.GetFirstBuff(playerTarget).BacklashTrigger = true; + break; } - } - } + //Barb defensive passives + case ToonClass.Barbarian: + { + TotalDamage *= 0.7f; //Class damage reduction bonus - if (playerTarget.Toon.Class == ToonClass.WitchDoctor) //Witch Doctor defensive passives - { - if (playerTarget.SkillSet.HasPassive(217968)) //JungleFortitude (WD) - TotalDamage *= 0.85f; - } + if (playerTarget.SkillSet.HasPassive(205491) && PowerMath.Distance2D(Context.User.Position, playerTarget.Position) > 6f) //Superstition (barbarian) + if (FastRandom.Instance.NextDouble() < Context.GetProcCoefficient()) + playerTarget.GeneratePrimaryResource(2f); - if (playerTarget.Toon.Class == ToonClass.DemonHunter) //DH defensive passives - { - if (playerTarget.SkillSet.HasPassive(210801) && playerTarget.World.BuffManager.GetFirstBuff(playerTarget) == null) //Brooding (DH) - playerTarget.World.BuffManager.AddBuff(playerTarget, playerTarget, new BroodingCooldownBuff()); - } + if (playerTarget.SkillSet.HasPassive(205398) && (playerTarget.Attributes[GameAttribute.Hitpoints_Cur] - TotalDamage) < (playerTarget.Attributes[GameAttribute.Hitpoints_Max_Total] * 0.2f)) //Relentless (barbarian) + TotalDamage *= 0.5f; + break; + } + //Wizard defensive passives + case ToonClass.Wizard: + { + if (playerTarget.SkillSet.HasPassive(208471)) //GlassCannon (Wizard) + TotalDamage *= 1.1f; - if (playerTarget.Toon.Class == ToonClass.Crusader) //Crusader defensive passives - { - TotalDamage *= 0.7f; //Class damage reduction bonus - - if (playerTarget.SkillSet.HasPassive(310626)) //Vigilant - if (DominantDamageType != DamageType.Physical) - TotalDamage *= 0.95f; - - if (playerTarget.World.BuffManager.HasBuff(playerTarget)) //AkaratChampion resurrect once - if (playerTarget.World.BuffManager.GetFirstBuff(playerTarget).resurrectActive) - if ((playerTarget.Attributes[GameAttribute.Hitpoints_Cur] - TotalDamage) <= 0) + if (playerTarget.SkillSet.HasPassive(208547) && TotalDamage > (playerTarget.Attributes[GameAttribute.Hitpoints_Max_Total] * 0.15f)) //Illusionist (Wizard) { - playerTarget.World.BuffManager.GetFirstBuff(playerTarget).resurrectActive = false; - playerTarget.AddPercentageHP(100); + foreach (var cdBuff in playerTarget.World.BuffManager.GetBuffs(playerTarget)) + if (cdBuff.TargetPowerSNO == 1769 || cdBuff.TargetPowerSNO == 168344) + cdBuff.Remove(); } - if (playerTarget.World.BuffManager.HasBuff(playerTarget)) //Protect the Innocent - if (!playerTarget.World.BuffManager.GetFirstBuff(playerTarget).Primary) - if (playerTarget.World.BuffManager.GetFirstBuff(playerTarget).Redirect) - TotalDamage *= 0.8f; + if (playerTarget.SkillSet.HasPassive(208474) && (playerTarget.Attributes[GameAttribute.Hitpoints_Cur] - TotalDamage) <= 0) //UnstableAnomaly (wizard) + { + if (playerTarget.World.BuffManager.GetFirstBuff(playerTarget) == null) + { + playerTarget.AddPercentageHP(45); + playerTarget.World.BuffManager.AddBuff(playerTarget, playerTarget, new UnstableAnomalyCooldownBuff()); + playerTarget.World.PowerManager.RunPower(playerTarget, 30796); + playerTarget.GenerateSecondaryResource(25f); + foreach (var cdBuff in playerTarget.World.BuffManager.GetBuffs(playerTarget)) + if (cdBuff.TargetPowerSNO == 30796) + cdBuff.Remove(); + } + } + + break; + } + //Witch Doctor defensive passives + case ToonClass.WitchDoctor: + { + if (playerTarget.SkillSet.HasPassive(217968)) //JungleFortitude (WD) + TotalDamage *= 0.85f; + break; + } + //DH defensive passives + case ToonClass.DemonHunter: + { + if (playerTarget.SkillSet.HasPassive(210801) && playerTarget.World.BuffManager.GetFirstBuff(playerTarget) == null) //Brooding (DH) + playerTarget.World.BuffManager.AddBuff(playerTarget, playerTarget, new BroodingCooldownBuff()); + break; + } + //Crusader defensive passives + case ToonClass.Crusader: + { + TotalDamage *= 0.7f; //Class damage reduction bonus + + if (playerTarget.SkillSet.HasPassive(310626)) //Vigilant + if (DominantDamageType != DamageType.Physical) + TotalDamage *= 0.95f; + + if (playerTarget.World.BuffManager.HasBuff(playerTarget)) //AkaratChampion resurrect once + if (playerTarget.World.BuffManager.GetFirstBuff(playerTarget).resurrectActive) + if ((playerTarget.Attributes[GameAttribute.Hitpoints_Cur] - TotalDamage) <= 0) + { + playerTarget.World.BuffManager.GetFirstBuff(playerTarget).resurrectActive = false; + playerTarget.AddPercentageHP(100); + } + + if (playerTarget.World.BuffManager.HasBuff(playerTarget)) //Protect the Innocent + if (!playerTarget.World.BuffManager.GetFirstBuff(playerTarget).Primary) + if (playerTarget.World.BuffManager.GetFirstBuff(playerTarget).Redirect) + TotalDamage *= 0.8f; + break; + } + } + + TotalDamage *= 0.1f; + break; } + //check for passives here (incoming damage, minions) + case Minion { Master: Player playerOwner }: + { + var plr = playerOwner; - TotalDamage *= 0.1f; - } - else if (Target is Minion { Master: Player playerOwner }) //check for passives here (incoming damage, minions) - { - var plr = playerOwner; + var masterArmor = plr.Attributes[GameAttribute.Armor_Total]; + var attackLevel = attackPayload.Context.User.Attributes[GameAttribute.Level]; - var masterArmor = plr.Attributes[GameAttribute.Armor_Total]; - var attackLevel = attackPayload.Context.User.Attributes[GameAttribute.Level]; + TotalDamage *= ReductionFromArmor(masterArmor, attackLevel); - TotalDamage *= ReductionFromArmor(masterArmor, attackLevel); + if (plr.SkillSet.HasPassive(217968)) //JungleFortitude (WD) + TotalDamage *= 0.85f; - if (plr.SkillSet.HasPassive(217968)) //JungleFortitude (WD) - TotalDamage *= 0.85f; - - TotalDamage *= 0.1f; //hack for unkillable minions + TotalDamage *= 0.1f; //hack for unkillable minions + break; + } } } - private static float ReductionFromResistance(float resistance, int attackerLevel) - { - return 1f - (resistance / ((5 * attackerLevel) + resistance)); - } + private static float ReductionFromResistance(float resistance, int attackerLevel) => 1f - (resistance / ((5 * attackerLevel) + resistance)); - private static float ReductionFromArmor(float armor, int attackerLevel) - { - return 1f - (armor / ((50 * attackerLevel) + armor)); - } + private static float ReductionFromArmor(float armor, int attackerLevel) => 1f - (armor / ((50 * attackerLevel) + armor)); private void CheckItemProcs(Player user) { - if (Math.Abs(user.Attributes[GameAttribute.Item_Power_Passive, 247724] - 1) < 0.001 && FastRandom.Instance.NextDouble() < 0.2) + if (Math.Abs(user.Attributes[GameAttribute.Item_Power_Passive, 247724] - 1) < Globals.FLOAT_TOLERANCE && FastRandom.Instance.NextDouble() < 0.2) { user.PlayEffectGroup(247770); } - if (Math.Abs(user.Attributes[GameAttribute.Item_Power_Passive, 245741] - 1) < 0.001 && FastRandom.Instance.NextDouble() < 0.2) + if (Math.Abs(user.Attributes[GameAttribute.Item_Power_Passive, 245741] - 1) < Globals.FLOAT_TOLERANCE && FastRandom.Instance.NextDouble() < 0.2) { user.PlayEffectGroup(245747); } @@ -625,12 +630,12 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads else if (plr.Toon.Class == ToonClass.DemonHunter) //Awareness { - plr.AddTimedAction(1f, new Action((q) => plr.World.BuffManager.RemoveBuffs(plr, 324770))); - plr.AddTimedAction(2f, new Action((q) => + plr.AddTimedAction(1f, _ => plr.World.BuffManager.RemoveBuffs(plr, 324770)); + plr.AddTimedAction(2f, _ => { if (plr.SkillSet.HasPassive(324770)) plr.World.BuffManager.AddBuff(plr, plr, new AwarenessBuff()); - })); + }); } return; } @@ -675,12 +680,11 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads } } - if (Target.World != null) - Target.World.BuffManager.SendTargetPayload(Target, this); + Target.World?.BuffManager?.SendTargetPayload(Target, this); if (Context.User != null) - Target.World.BuffManager.SendTargetPayload(Context.User, this); + Target.World?.BuffManager?.SendTargetPayload(Context.User, this); - if (Target == null || Target.World == null) return; //in case Target was killed in OnPayload + if (Target?.World == null) return; //in case Target was killed in OnPayload if (Context.User is Player player) { @@ -702,20 +706,18 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads if (hireling.Attributes[GameAttribute.Hitpoints_On_Hit] > 0) hireling.AddHP(hireling.Attributes[GameAttribute.Hitpoints_On_Hit]); } - - // floating damage number - if (Target.World != null) + // make player damage red, all other damage white + var type = Target is Player ? + IsCriticalHit ? FloatingNumberMessage.FloatType.RedCritical : FloatingNumberMessage.FloatType.Red : + IsCriticalHit ? FloatingNumberMessage.FloatType.Golden : FloatingNumberMessage.FloatType.White; + if (Target.World is { } world) { - Target.World.BroadcastIfRevealed(plr => new FloatingNumberMessage + world.BroadcastIfRevealed(plr => new FloatingNumberMessage { ActorID = Target.DynamicID(plr), Number = TotalDamage, - // make player damage red, all other damage white - Type = IsCriticalHit ? - (Target is Player) ? FloatingNumberMessage.FloatType.RedCritical : FloatingNumberMessage.FloatType.Golden - : - (Target is Player) ? FloatingNumberMessage.FloatType.Red : FloatingNumberMessage.FloatType.White + Type = type }, Target); } @@ -737,15 +739,15 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads { // play override hitsound if any, otherwise just default to playing metal weapon hit for now int overridenSound = Context.EvalTag(PowerKeys.HitsoundOverride); - int hitsound = overridenSound != -1 ? overridenSound : 1; - if (hitsound > 0) - Target.PlayEffect(Effect.Hit, hitsound); + int hitSound = overridenSound != -1 ? overridenSound : 1; + if (hitSound > 0) + Target.PlayEffect(Effect.Hit, hitSound); } } // update hp - float new_hp = Math.Max(Target.Attributes[GameAttribute.Hitpoints_Cur] - TotalDamage, 0f); - Target.Attributes[GameAttribute.Hitpoints_Cur] = new_hp; + float newHp = Math.Max(Target.Attributes[GameAttribute.Hitpoints_Cur] - TotalDamage, 0f); + Target.Attributes[GameAttribute.Hitpoints_Cur] = newHp; Target.Attributes.BroadcastChangedIfRevealed(); //thorns @@ -766,21 +768,23 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads */ // if hp=0 do death - if (new_hp <= 0f) + if (newHp <= 0f) { - var deathload = new DeathPayload(Context, DominantDamageType, Target, Target.HasLoot); - deathload.AutomaticHitEffects = AutomaticHitEffects; + var deathPayload = new DeathPayload(Context, DominantDamageType, Target, Target.HasLoot) + { + AutomaticHitEffects = AutomaticHitEffects + }; - if (deathload.Successful) + if (deathPayload.Successful) { Target.Dead = true; try { if (OnDeath != null && AutomaticHitEffects) - OnDeath(deathload); + OnDeath(deathPayload); } catch { } - deathload.Apply(); + deathPayload.Apply(); } } else if (AutomaticHitEffects && Target.World != null && Target is not Player) @@ -800,13 +804,13 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads { if (Target.IsRevealedToPlayer(plr)) { - float BackSpeed = Target.WalkSpeed; + float backSpeed = Target.WalkSpeed; Target.WalkSpeed = 0f; - TickTimer Timeout = new SecondsTickTimer(Target.World.Game, 0.3f); - var Boom = Task.Factory.StartNew(() => WaitTo(Timeout)); - Boom.ContinueWith(delegate + TickTimer timeout = new SecondsTickTimer(Target.World.Game, 0.3f); + var boom = Task.Factory.StartNew(() => WaitTo(timeout)); + boom.ContinueWith(_ => { - Target.WalkSpeed = BackSpeed; + Target.WalkSpeed = backSpeed; }); } } diff --git a/src/DiIiS-NA/D3-GameServer/GSSystem/PowerSystem/PowerContext.cs b/src/DiIiS-NA/D3-GameServer/GSSystem/PowerSystem/PowerContext.cs index 5699932..71e9873 100644 --- a/src/DiIiS-NA/D3-GameServer/GSSystem/PowerSystem/PowerContext.cs +++ b/src/DiIiS-NA/D3-GameServer/GSSystem/PowerSystem/PowerContext.cs @@ -178,20 +178,17 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem public EffectActor SpawnEffect(ActorSno actorSNO, Vector3D position, float angle = 0, TickTimer timeout = null) { - if (Math.Abs(angle - (-1)) < 0.0001) + if (Math.Abs(angle - -1) < Globals.FLOAT_TOLERANCE) angle = (float)(Rand.NextDouble() * (Math.PI * 2)); if (timeout == null) { - if (_defaultEffectTimeout == null) - _defaultEffectTimeout = new SecondsTickTimer(World.Game, 2f); // default timeout of 2 seconds for now - + _defaultEffectTimeout ??= new SecondsTickTimer(World.Game, 2f); timeout = _defaultEffectTimeout; } var actor = new EffectActor(this, actorSNO, position); actor.Timeout = timeout; actor.Spawn(angle); - //187359 return actor; } diff --git a/src/DiIiS-NA/D3-GameServer/GSSystem/SkillsSystem/SkillSet.cs b/src/DiIiS-NA/D3-GameServer/GSSystem/SkillsSystem/SkillSet.cs index ff865e7..c8c29f5 100644 --- a/src/DiIiS-NA/D3-GameServer/GSSystem/SkillsSystem/SkillSet.cs +++ b/src/DiIiS-NA/D3-GameServer/GSSystem/SkillsSystem/SkillSet.cs @@ -11,35 +11,54 @@ namespace DiIiS_NA.GameServer.GSSystem.SkillsSystem { public class SkillSet { - public ToonClass @Class; - public Toon Toon { get; private set; } - public Player Player { get; private set; } + public ToonClass ToonClass { get; } + public Toon Toon { get; } + public Player Player { get; } - public ActiveSkillSavedData[] ActiveSkills; - public HotbarButtonData[] HotBarSkills; - public int[] PassiveSkills; + public ActiveSkillSavedData[] ActiveSkills { get; } + public HotbarButtonData[] HotBarSkills { get; } + public int[] PassiveSkills { get; } protected static readonly Logger Logger = LogManager.CreateLogger(); - public SkillSet(Player player, ToonClass @class, Toon toon) + public SkillSet(Player player, ToonClass toonClass, Toon toon) { - @Class = @class; + ToonClass = toonClass; Player = player; - var dbToon = player.Toon.DBToon; + // var dbToon = player.Toon.DBToon; var dbActiveSkills = player.Toon.DBActiveSkills; - ActiveSkills = new ActiveSkillSavedData[6] { - new ActiveSkillSavedData { snoSkill = dbActiveSkills.Skill0, - snoRune = dbActiveSkills.Rune0 }, - new ActiveSkillSavedData { snoSkill = dbActiveSkills.Skill1, - snoRune = dbActiveSkills.Rune1 }, - new ActiveSkillSavedData { snoSkill = dbActiveSkills.Skill2, - snoRune = dbActiveSkills.Rune2 }, - new ActiveSkillSavedData { snoSkill = dbActiveSkills.Skill3, - snoRune = dbActiveSkills.Rune3 }, - new ActiveSkillSavedData { snoSkill = dbActiveSkills.Skill4, - snoRune = dbActiveSkills.Rune4 }, - new ActiveSkillSavedData { snoSkill = dbActiveSkills.Skill5, - snoRune = dbActiveSkills.Rune5 }, + ActiveSkills = new ActiveSkillSavedData[6] + { + new() + { + snoSkill = dbActiveSkills.Skill0, + snoRune = dbActiveSkills.Rune0 + }, + new() + { + snoSkill = dbActiveSkills.Skill1, + snoRune = dbActiveSkills.Rune1 + }, + new() + { + snoSkill = dbActiveSkills.Skill2, + snoRune = dbActiveSkills.Rune2 + }, + new() + { + snoSkill = dbActiveSkills.Skill3, + snoRune = dbActiveSkills.Rune3 + }, + new() + { + snoSkill = dbActiveSkills.Skill4, + snoRune = dbActiveSkills.Rune4 + }, + new() + { + snoSkill = dbActiveSkills.Skill5, + snoRune = dbActiveSkills.Rune5 + }, }; PassiveSkills = new int[4] { @@ -51,18 +70,18 @@ namespace DiIiS_NA.GameServer.GSSystem.SkillsSystem //} HotBarSkills = new HotbarButtonData[6] { - new HotbarButtonData { SNOSkill = ActiveSkills[0].snoSkill, ItemAnn = ActiveSkills[0].snoRune, ItemGBId = -1, RuneType = -1 }, // left-click - new HotbarButtonData { SNOSkill = ActiveSkills[1].snoSkill, ItemAnn = ActiveSkills[1].snoRune, ItemGBId = -1, RuneType = -1 }, // right-click - new HotbarButtonData { SNOSkill = ActiveSkills[2].snoSkill, ItemAnn = ActiveSkills[2].snoRune, ItemGBId = -1, RuneType = -1 }, // bar-1 - new HotbarButtonData { SNOSkill = ActiveSkills[3].snoSkill, ItemAnn = ActiveSkills[3].snoRune, ItemGBId = -1, RuneType = -1 }, // bar-2 - new HotbarButtonData { SNOSkill = ActiveSkills[4].snoSkill, ItemAnn = ActiveSkills[4].snoRune, ItemGBId = -1, RuneType = -1 }, // bar-3 - new HotbarButtonData { SNOSkill = ActiveSkills[5].snoSkill, ItemAnn = ActiveSkills[5].snoRune, ItemGBId = -1, RuneType = -1 }, // bar-4 + new() { SNOSkill = ActiveSkills[0].snoSkill, ItemAnn = ActiveSkills[0].snoRune, ItemGBId = -1, RuneType = -1 }, // left-click + new() { SNOSkill = ActiveSkills[1].snoSkill, ItemAnn = ActiveSkills[1].snoRune, ItemGBId = -1, RuneType = -1 }, // right-click + new() { SNOSkill = ActiveSkills[2].snoSkill, ItemAnn = ActiveSkills[2].snoRune, ItemGBId = -1, RuneType = -1 }, // bar-1 + new() { SNOSkill = ActiveSkills[3].snoSkill, ItemAnn = ActiveSkills[3].snoRune, ItemGBId = -1, RuneType = -1 }, // bar-2 + new() { SNOSkill = ActiveSkills[4].snoSkill, ItemAnn = ActiveSkills[4].snoRune, ItemGBId = -1, RuneType = -1 }, // bar-3 + new() { SNOSkill = ActiveSkills[5].snoSkill, ItemAnn = ActiveSkills[5].snoRune, ItemGBId = -1, RuneType = -1 }, // bar-4 }; } public void UpdateSkills(int hotBarIndex, int SNOSkill, int SNORune, Toon toon) { - Logger.Debug("Update index {0} skill {1} rune {2}", hotBarIndex, SNOSkill, SNORune); + Logger.MethodTrace(string.Format("Update index {0} skill {1} rune {2}", hotBarIndex, SNOSkill, SNORune)); var dbActiveSkills = Player.Toon.DBActiveSkills; switch (hotBarIndex) { @@ -119,31 +138,12 @@ namespace DiIiS_NA.GameServer.GSSystem.SkillsSystem } } - public bool HasPassive(int passiveId) - { - if (PassiveSkills.Contains(passiveId)) - return true; - else - return false; - } + public bool HasPassive(int passiveId) => PassiveSkills.Contains(passiveId); - public bool HasSkill(int skillId) - { - return ActiveSkills.Any(s => s.snoSkill == skillId); - } + public bool HasSkill(int skillId) => ActiveSkills.Any(s => s.snoSkill == skillId); - public bool HasSkillWithRune(int skillId, int runeId) - { - return ActiveSkills.Any(s => s.snoSkill == skillId && s.snoRune == runeId); - } - - - public bool HasItemPassiveProc(int passiveId) - { - if ((float)FastRandom.Instance.NextDouble() < Player.Attributes[GameAttribute.Item_Power_Passive, passiveId]) - return true; - else - return false; - } + public bool HasSkillWithRune(int skillId, int runeId) => ActiveSkills.Any(s => s.snoSkill == skillId && s.snoRune == runeId); + + public bool HasItemPassiveProc(int passiveId) => (float)FastRandom.Instance.NextDouble() < Player.Attributes[GameAttribute.Item_Power_Passive, passiveId]; } } diff --git a/src/DiIiS-NA/D3-GameServer/GameServerConfig.cs b/src/DiIiS-NA/D3-GameServer/GameServerConfig.cs index dd81268..185860d 100644 --- a/src/DiIiS-NA/D3-GameServer/GameServerConfig.cs +++ b/src/DiIiS-NA/D3-GameServer/GameServerConfig.cs @@ -49,6 +49,14 @@ namespace DiIiS_NA.GameServer get => GetBoolean(nameof(CoreActive), true); set => Set(nameof(CoreActive), value); } + + public bool IWServer + { + get => GetBoolean(nameof(IWServer), true); + set => Set(nameof(IWServer), value); + } + + #region Game Mods /// /// Rate of experience gain. @@ -100,12 +108,6 @@ namespace DiIiS_NA.GameServer get => GetFloat(nameof(RateMonsterDMG), 1); set => Set(nameof(RateMonsterDMG), value); } - - public bool IWServer - { - get => GetBoolean(nameof(IWServer), true); - set => Set(nameof(IWServer), value); - } /// /// Percentage that a unique, legendary, set or special item created is unidentified @@ -196,7 +198,80 @@ namespace DiIiS_NA.GameServer get => GetBoolean(nameof(UnlockAllWaypoints), false); set => Set(nameof(UnlockAllWaypoints), value); } + + /// + /// Strength multiplier when you're not a paragon. + /// + public float StrengthMultiplier + { + get => GetFloat(nameof(StrengthMultiplier), 1f); + set => Set(nameof(StrengthMultiplier), value); + } + /// + /// Strength multiplier when you're a paragon. + /// + public float StrengthParagonMultiplier + { + get => GetFloat(nameof(StrengthParagonMultiplier), 1f); + set => Set(nameof(StrengthParagonMultiplier), value); + } + + /// + /// Dexterity multiplier when you're not a paragon. + /// + public float DexterityMultiplier + { + get => GetFloat(nameof(DexterityMultiplier), 1f); + set => Set(nameof(DexterityMultiplier), value); + } + + /// + /// Dexterity multiplier when you're a paragon. + /// + public float DexterityParagonMultiplier + { + get => GetFloat(nameof(DexterityParagonMultiplier), 1f); + set => Set(nameof(DexterityParagonMultiplier), value); + } + + /// + /// Intelligence multiplier when you're not a paragon. + /// + public float IntelligenceMultiplier + { + get => GetFloat(nameof(IntelligenceMultiplier), 1f); + set => Set(nameof(IntelligenceMultiplier), value); + } + + /// + /// Intelligence multiplier when you're a paragon. + /// + public float IntelligenceParagonMultiplier + { + get => GetFloat(nameof(IntelligenceParagonMultiplier), 1f); + set => Set(nameof(IntelligenceParagonMultiplier), value); + } + + /// + /// Vitality multiplier when you're not a paragon. + /// + public float VitalityMultiplier + { + get => GetFloat(nameof(VitalityMultiplier), 1f); + set => Set(nameof(VitalityMultiplier), value); + } + + /// + /// Vitality multiplier when you're a paragon. + /// + public float VitalityParagonMultiplier + { + get => GetFloat(nameof(VitalityParagonMultiplier), 1f); + set => Set(nameof(VitalityParagonMultiplier), value); + } + + #endregion public static GameServerConfig Instance { get; } = new(); diff --git a/src/DiIiS-NA/Extensions.cs b/src/DiIiS-NA/Extensions.cs index a66938c..469061f 100644 --- a/src/DiIiS-NA/Extensions.cs +++ b/src/DiIiS-NA/Extensions.cs @@ -4,7 +4,8 @@ using System.Configuration; namespace DiIiS_NA { - public static class Extensions + internal static class Globals { + public const float FLOAT_TOLERANCE = 0.0001f; } } \ No newline at end of file diff --git a/src/DiIiS-NA/REST/Http/Http.cs b/src/DiIiS-NA/REST/Http/Http.cs index dc49d19..b6a3b4f 100644 --- a/src/DiIiS-NA/REST/Http/Http.cs +++ b/src/DiIiS-NA/REST/Http/Http.cs @@ -30,7 +30,8 @@ namespace DiIiS_NA.REST.Http Found = 302, BadRequest = 400, NotFound = 404, - InternalServerError = 500 + InternalServerError = 500, + BadGateway = 502 } public class HttpHelper diff --git a/src/DiIiS-NA/REST/RestSession.cs b/src/DiIiS-NA/REST/RestSession.cs index ef945eb..93008ba 100644 --- a/src/DiIiS-NA/REST/RestSession.cs +++ b/src/DiIiS-NA/REST/RestSession.cs @@ -12,6 +12,7 @@ using DiIiS_NA.REST.Data.Authentication; using DiIiS_NA.REST.JSON; using DiIiS_NA.LoginServer.AccountsSystem; using System.IO; +using System.Net; using System.Net.Security; using System.Web; using DiIiS_NA.GameServer.MessageSystem; @@ -41,26 +42,19 @@ namespace DiIiS_NA.REST } else { - Logger.Info($"$[yellow]$REST Request: $[/]$ {httpRequest.Method} {httpRequest.Path}"); + Logger.Debug($"$[yellow]$REST Request: $[/]$ {httpRequest.Method} {httpRequest.Path}"); if (httpRequest.Path == "200") { } else if (httpRequest.Path.Contains("/client/alert")) { - switch (httpRequest.Method) - { - case "GET": - default: - HandleInfoRequest(httpRequest); - break; - } + HandleInfoRequest(httpRequest); } - else + else if (httpRequest.Path.Contains("/battlenet/login")) { switch (httpRequest.Method) { - case "GET": default: HandleConnectRequest(httpRequest); break; @@ -69,30 +63,34 @@ namespace DiIiS_NA.REST return; } } + else + { + #if DEBUG + Logger.Info($"$[red]$[404] REST Request: $[/]$ {httpRequest.Method} {httpRequest.Path}"); + SendResponseHtml(HttpCode.NotFound, "404 Not Found"); + #else + // sends 502 Bad Gateway to the client to prevent the client from trying to connect to the server again - in case it's a crawler or bad bot. + Logger.Info($"$[red]$[404/502] REST Request: $[/]$ {httpRequest.Method} {httpRequest.Path}"); + SendResponseHtml(HttpCode.BadGateway, "502 Bad Gateway"); + return; + #endif + } } AsyncRead(); } - public void HandleConnectRequest(HttpHeader request) + void HandleConnectRequest(HttpHeader request) { SendResponse(HttpCode.OK, SessionManager.Instance.GetFormInput()); } - public void HandleInfoRequest(HttpHeader request) + void HandleInfoRequest(HttpHeader request) { SendResponseHtml(HttpCode.OK, "Welcome to BlizzLess.Net" + "\nBuild " + Program.Build + "\nSupport: 2.7.4"); } - public static byte[] StringToByteArray(string hex) - { - return Enumerable.Range(0, hex.Length) - .Where(x => x % 2 == 0) - .Select(x => Convert.ToByte(hex.Substring(x, 2), 16)) - .ToArray(); - } - void SendResponse(HttpCode code, T response) { AsyncWrite(HttpHelper.CreateResponse(code, JSON.Json.CreateString(response))); @@ -107,7 +105,8 @@ namespace DiIiS_NA.REST { AsyncRead(); } - public void HandleLoginRequest(HttpHeader request) + + void HandleLoginRequest(HttpHeader request) { LogonData loginForm = Json.CreateObject(request.Content); LogonResult loginResult = new LogonResult();