From 789b2192bdf04df004b6edc7e36baa0a82abfd3f Mon Sep 17 00:00:00 2001 From: Lucca Faria Ferri Date: Mon, 30 Jan 2023 10:56:44 -0800 Subject: [PATCH] More Necromancer command skeleton updates; renamed resourcefull to resourceful --- .../CommandManager/GameCommands.cs | 16 ++-- .../GSSystem/ObjectsSystem/FixedMap.cs | 3 +- .../GSSystem/PlayerSystem/Player.cs | 17 ++-- .../Implementations/HeroSkills/Necromancer.cs | 78 ++++++++++++------- 4 files changed, 67 insertions(+), 47 deletions(-) diff --git a/src/DiIiS-NA/D3-GameServer/CommandManager/GameCommands.cs b/src/DiIiS-NA/D3-GameServer/CommandManager/GameCommands.cs index 01b70ab..2025a54 100644 --- a/src/DiIiS-NA/D3-GameServer/CommandManager/GameCommands.cs +++ b/src/DiIiS-NA/D3-GameServer/CommandManager/GameCommands.cs @@ -55,30 +55,30 @@ public class PowerfulCommand : CommandGroup } } -[CommandGroup("resourcefull", "Makes your character with full resource. Useful for testing.", +[CommandGroup("resourceful", "Makes your character with full resource. Useful for testing.", Account.UserLevels.Tester)] -public class ResourcefullCommand : CommandGroup +public class ResourcefulCommand : CommandGroup { [DefaultCommand] - public string Resourcefull(string[] @params, BattleClient invokerClient) + public string Resourceful(string[] @params, BattleClient invokerClient) { if (invokerClient?.InGameClient?.Player is not { } player) return "You must be in game to use this command."; - if (player.Attributes.FixedMap.Contains(FixedAttribute.Resourcefull)) + if (player.Attributes.FixedMap.Contains(FixedAttribute.Resourceful)) { - player.Attributes.FixedMap.Remove(FixedAttribute.Resourcefull); + player.Attributes.FixedMap.Remove(FixedAttribute.Resourceful); player.Attributes.BroadcastChangedIfRevealed(); - return "You are no longer Resourcefull."; + return "You are no longer Resourceful."; } - player.Attributes.FixedMap.Add(FixedAttribute.Resourcefull, (attributes) => + player.Attributes.FixedMap.Add(FixedAttribute.Resourceful, (attributes) => { attributes[GameAttribute.Resource_Cur, 1] = 100; }); player.Attributes.BroadcastChangedIfRevealed(); - return "You are full resource."; + return "You are now resourceful."; } } diff --git a/src/DiIiS-NA/D3-GameServer/GSSystem/ObjectsSystem/FixedMap.cs b/src/DiIiS-NA/D3-GameServer/GSSystem/ObjectsSystem/FixedMap.cs index 82ec63d..b962abb 100644 --- a/src/DiIiS-NA/D3-GameServer/GSSystem/ObjectsSystem/FixedMap.cs +++ b/src/DiIiS-NA/D3-GameServer/GSSystem/ObjectsSystem/FixedMap.cs @@ -9,7 +9,8 @@ namespace DiIiS_NA.GameServer.GSSystem.ObjectsSystem Invulnerable, Speed, Powerful, - Resourcefull + Resourceful, + AttackSpeed } public class FixedMap diff --git a/src/DiIiS-NA/D3-GameServer/GSSystem/PlayerSystem/Player.cs b/src/DiIiS-NA/D3-GameServer/GSSystem/PlayerSystem/Player.cs index f29b8c2..dc0b5ed 100644 --- a/src/DiIiS-NA/D3-GameServer/GSSystem/PlayerSystem/Player.cs +++ b/src/DiIiS-NA/D3-GameServer/GSSystem/PlayerSystem/Player.cs @@ -168,6 +168,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable public List NecroSkeletons = new() { }; public bool ActiveSkeletons = false; + public Actor ActiveGolem = null; public bool EnableGolem = false; @@ -189,13 +190,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable public int GearScore { - get - { - if (Inventory == null) - return 0; - else - return Inventory.GetGearScore(); - } + get => Inventory?.GetGearScore() ?? 0; private set { } } @@ -272,7 +267,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable } /// - /// NPC currently interaced with + /// NPC currently interacted with /// public InteractiveNPC SelectedNPC { get; set; } @@ -448,14 +443,12 @@ public class Player : Actor, IMessageConsumer, IUpdateable SetAttributesMovement(); SetAttributesMisc(); SetAttributesOther(); - if (Inventory == null) - Inventory = new Inventory(this); + Inventory ??= new Inventory(this); SetAttributesByItems(); //needs the Inventory SetAttributesByItemProcs(); SetAttributesByGems(); SetAttributesByItemSets(); - if (SkillSet == null) - SkillSet = new SkillSet(this, Toon.Class, Toon); + SkillSet ??= new SkillSet(this, Toon.Class, Toon); SetAttributesByPassives(); //needs the SkillSet SetAttributesByParagon(); SetNewAttributes(); diff --git a/src/DiIiS-NA/D3-GameServer/GSSystem/PowerSystem/Implementations/HeroSkills/Necromancer.cs b/src/DiIiS-NA/D3-GameServer/GSSystem/PowerSystem/Implementations/HeroSkills/Necromancer.cs index 4bd7651..43d71c9 100644 --- a/src/DiIiS-NA/D3-GameServer/GSSystem/PowerSystem/Implementations/HeroSkills/Necromancer.cs +++ b/src/DiIiS-NA/D3-GameServer/GSSystem/PowerSystem/Implementations/HeroSkills/Necromancer.cs @@ -21,6 +21,7 @@ using DiIiS_NA.GameServer.GSSystem.PlayerSystem; using DiIiS_NA.GameServer.MessageSystem.Message.Definitions.Pet; using DiIiS_NA.Core.Extensions; using DiIiS_NA.GameServer.GSSystem.AISystem.Brains; +using DiIiS_NA.GameServer.GSSystem.ObjectsSystem; namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Implementations { @@ -1990,36 +1991,42 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Implementations DamageType damageType = DamageType.Physical; bool greaterDamage = false; + /* + * Enforcer: Reduces the active Essence cost to 25. + * Frenzy: Commanded skeletons go into a frenzy, gaining 25% increased attack speed as long as they attacked the Commanded target (in addition to damage bonus). + * Dark Mending: Skeletal minions will heal the Necromancer for 0.5% of total Life per hit while being Commanded (i.e. as long as the skill is activated). + * Freezing Grasp: Damage type is changed to Cold, and the target of Command is frozen for 3 seconds. + * Kill Command: Damage type changes to Poison, and Command activation will instead make each Skeleton explode, killing them and dealing 215% damage as Poison to enemies within 15 yards each. They will still rush to their target before exploding. + */ + bool enforcer = Rune_A > 0, + frenzy = Rune_B > 0, + darkMending = Rune_C > 0, + freezingGrasp = Rune_D > 0, + killCommand = Rune_E > 0; + // Enforcer - if (Rune_A > 0) + if (enforcer) { - UsePrimaryResource(EvalTag(PowerKeys.ResourceCost) / 2); + UsePrimaryResource(25); } - // Frenzy - else if (Rune_B > 0) + else { UsePrimaryResource(EvalTag(PowerKeys.ResourceCost)); + if (darkMending) + { + ((Player)User).AddPercentageHP(25f); // add per hit : TODO: Life per hit while being Commanded (i.e. as long as the skill is activated). + } + else if (freezingGrasp) + { + damageType = DamageType.Cold; + } + else if (killCommand) + { + damageType = DamageType.Poison; + greaterDamage = true; // TODO: Implement Kill Command to Explode instead of attacking + } } - // Dark Mending - else if (Rune_C > 0) - { - UsePrimaryResource(EvalTag(PowerKeys.ResourceCost)); - damageType = DamageType.Cold; - } - // Freezing Grasp - else if (Rune_D > 0) - { - UsePrimaryResource(EvalTag(PowerKeys.ResourceCost)); - damageType = DamageType.Poison; - greaterDamage = true; - } - else if (Rune_E > 0) - { - UsePrimaryResource(EvalTag(PowerKeys.ResourceCost)); - greaterDamage = true; - damageType = DamageType.Poison; - Logger.Warn("Rune E not implemented for Necromancer's Command Skeletons"); - } + foreach (var skeleton in ((Player)User).NecroSkeletons) { @@ -2037,7 +2044,25 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Implementations skeleton.SetVisible(true); skeleton.Hidden = false; skeleton.PlayEffectGroup(474172); - + + // Commanded skeletons go into a frenzy, gaining 25% increased attack speed as long as they attacked the Commanded target (in addition to damage bonus). + if (frenzy) + { + if (!skeleton.Attributes.FixedMap.Contains(FixedAttribute.AttackSpeed)) + { + var originalAttackSpeed = skeleton.Attributes[GameAttribute.Attacks_Per_Second]; + skeleton.Attributes.FixedMap.Add(FixedAttribute.AttackSpeed, attr => attr[GameAttribute.Attacks_Per_Second] = originalAttackSpeed * 1.25f); + skeleton.Attributes.BroadcastChangedIfRevealed(); + } + } + else + { + if (skeleton.Attributes.FixedMap.Contains(FixedAttribute.AttackSpeed)) + { + skeleton.Attributes.FixedMap.Remove(FixedAttribute.AttackSpeed); + skeleton.Attributes.BroadcastChangedIfRevealed(); + } + } AttackPayload attack = new AttackPayload(this) { Target = Target @@ -2045,10 +2070,11 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Implementations attack.AddWeaponDamage(greaterDamage ? 2.15f : 1.0f, damageType); attack.OnHit = hit => { - if (Rune_C > 0) + if (freezingGrasp) { if (!HasBuff(hit.Target)) { + hit.Target.PlayEffect(Effect.IcyEffect); AddBuff(hit.Target, new DebuffFrozen(WaitSeconds(3.0f))); } }