diff --git a/OpenDiablo2.Common/Attributes/SkillInfoAttribute.cs b/OpenDiablo2.Common/Attributes/SkillInfoAttribute.cs
new file mode 100644
index 00000000..b65aa4a6
--- /dev/null
+++ b/OpenDiablo2.Common/Attributes/SkillInfoAttribute.cs
@@ -0,0 +1,40 @@
+/* OpenDiablo 2 - An open source re-implementation of Diablo 2 in C#
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+using OpenDiablo2.Common.Enums;
+using System;
+using System.Collections.Generic;
+
+namespace OpenDiablo2.Common.Attributes
+{
+ [AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
+ public class SkillInfoAttribute : Attribute
+ {
+ int a = 5;
+ public SkillInfoAttribute(eHero hero, int spriteIndex = 0, int level/*levelGroup*/ = 0, params eSkill[] skillsRequired)
+ {
+ Hero = hero;
+ SpriteIndex = spriteIndex;
+ Level = level;
+ SkillsRequired = skillsRequired ?? Array.Empty();
+ }
+
+ public eHero Hero { get; }
+ public int SpriteIndex { get; }
+ public int Level { get; }
+ public IReadOnlyList SkillsRequired { get; }
+ }
+}
diff --git a/OpenDiablo2.Common/Enums/eHero.cs b/OpenDiablo2.Common/Enums/eHero.cs
index 1a05e89b..1c4b48e2 100644
--- a/OpenDiablo2.Common/Enums/eHero.cs
+++ b/OpenDiablo2.Common/Enums/eHero.cs
@@ -1,14 +1,28 @@
-using System;
+/* OpenDiablo 2 - An open source re-implementation of Diablo 2 in C#
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
namespace OpenDiablo2.Common.Enums
{
public enum eHero
{
+ None,
Barbarian,
Necromancer,
Paladin,
diff --git a/OpenDiablo2.Common/Enums/eSkill.cs b/OpenDiablo2.Common/Enums/eSkill.cs
new file mode 100644
index 00000000..e04114c9
--- /dev/null
+++ b/OpenDiablo2.Common/Enums/eSkill.cs
@@ -0,0 +1,339 @@
+/* OpenDiablo 2 - An open source re-implementation of Diablo 2 in C#
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+using OpenDiablo2.Common.Attributes;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+
+namespace OpenDiablo2.Common.Enums
+{
+ public static class SkillsHelper
+ {
+ public static SkillInfoAttribute GetSkillInfo(this eSkill skill)
+ {
+ var attr = skill.GetType().GetCustomAttributes(typeof(SkillInfoAttribute), false).FirstOrDefault() as SkillInfoAttribute;
+ Debug.Assert(attr != null, $"Skill {skill} does not contain SkillInfo attribute.");
+ return attr;
+ }
+
+ public static IEnumerable GetHeroSkills(eHero hero)
+ {
+ foreach(var skill in (eSkill[])Enum.GetValues(typeof(eSkill)))
+ {
+ if(skill.GetSkillInfo()?.Hero == hero)
+ yield return skill;
+ }
+ }
+ }
+
+ //public int[] eSkillLevelTier
+ //{
+ // 1,
+ // 6,
+ // 12,
+ // 18,
+ // 24,
+ // 30
+ //};
+
+ public enum eSkill
+ {
+ /// Generic Skills
+ [SkillInfo(eHero.None, 1)]
+ Attack = 0,
+ [SkillInfo(eHero.None, 3)]
+ Throw = 2,
+ [SkillInfo(eHero.None, 2)]
+ Unsummon = 3,
+
+ /// Amazon
+ // Javelin and Spear Skills
+ [SkillInfo(eHero.Amazon, 4, 1)]
+ Jab = 10,
+ [SkillInfo(eHero.Amazon, 8, 6, Jab)]
+ PowerStrike = 14,
+ [SkillInfo(eHero.Amazon, 9, 6)]
+ PoisonJavelin = 15,
+ [SkillInfo(eHero.Amazon, 13, 12, Jab)]
+ Impale = 19,
+ [SkillInfo(eHero.Amazon, 14, 12, PoisonJavelin)]
+ LightningBolt = 20,
+ [SkillInfo(eHero.Amazon, 18, 18, LightningBolt, PowerStrike)]
+ ChargedStrike = 24,
+ [SkillInfo(eHero.Amazon, 19, 18, LightningBolt)]
+ PlagueJavelin = 25,
+ [SkillInfo(eHero.Amazon, 24, 24, Impale)]
+ Fend = 30,
+ [SkillInfo(eHero.Amazon, 28, 30, ChargedStrike)]
+ LightningStrike = 34,
+ [SkillInfo(eHero.Amazon, 29, 30, PlagueJavelin)]
+ LightningFury = 35,
+ // Passive and Magic Skills
+ [SkillInfo(eHero.Amazon, 2, 1)]
+ InnerSight = 8,
+ [SkillInfo(eHero.Amazon, 3, 1)]
+ CriticalStrike = 9,
+ [SkillInfo(eHero.Amazon, 7, 6)]
+ Dodge = 13,
+ [SkillInfo(eHero.Amazon, 11, 12, InnerSight)]
+ SlowMissles = 17,
+ [SkillInfo(eHero.Amazon, 12, 12, Dodge)]
+ Avoid = 18,
+ [SkillInfo(eHero.Amazon, 17, 18, CriticalStrike)]
+ Penetrate = 23,
+ [SkillInfo(eHero.Amazon, 22, 24, SlowMissles)]
+ Decoy = 28, // called Dopplezon
+ [SkillInfo(eHero.Amazon, 23, 24, Avoid)]
+ Evade = 29,
+ [SkillInfo(eHero.Amazon, 26, 30, Decoy, Evade)]
+ Valkyrie = 32,
+ [SkillInfo(eHero.Amazon, 27, 30, Penetrate)]
+ Pierce = 33,
+ // Bow and Crossbow Skills
+ [SkillInfo(eHero.Amazon, 0, 1)]
+ MagicArrow = 6,
+ [SkillInfo(eHero.Amazon, 1, 1)]
+ FireArrow = 7,
+ [SkillInfo(eHero.Amazon, 5, 6)]
+ ColdArrow = 11,
+ [SkillInfo(eHero.Amazon, 6, 6, MagicArrow)]
+ MultipleShot = 12,
+ [SkillInfo(eHero.Amazon, 10, 12, FireArrow)]
+ ExplodingArrow = 16,
+ [SkillInfo(eHero.Amazon, 15, 18, ColdArrow)]
+ IceArrow = 21,
+ [SkillInfo(eHero.Amazon, 16, 18, MultipleShot)]
+ GuidedArrow = 22,
+ [SkillInfo(eHero.Amazon, 20, 24, GuidedArrow)]
+ Strafe = 26,
+ [SkillInfo(eHero.Amazon, 21, 24, ExplodingArrow)]
+ ImmolationArrow = 27,
+ [SkillInfo(eHero.Amazon, 25, 30, IceArrow)]
+ FreezingArrow = 31,
+
+ /// Assassin
+ // Martial Arts
+ TigerStrike,
+ DragonTalon,
+ FistsOfFire,
+ DragonClaw,
+ CobraStrike,
+ ClawsOfThunder,
+ DragonTail,
+ BladesOfIce,
+ DragonFlight,
+ PhoenixStrike,
+ // Shadow Disciplines
+ ClawMastery,
+ PsychicHammer,
+ BurstOfSpeed,
+ WeaponBlock,
+ CloakOfShadows,
+ Fade,
+ ShadowWarrior,
+ MindBlast,
+ Venom,
+ ShadowMaster,
+ // Traps
+ FireBlast,
+ ShockWeb,
+ BladeSentinel,
+ ChargedBoltSentry,
+ WakeOfFire,
+ BladeFury,
+ LightningSentry,
+ WakeOfInferno,
+ DeathSentry,
+ BladeShield,
+
+ /// Necromancer
+ // Summoning Spells
+ SkeletonMastery,
+ RaiseSkeleton,
+ ClayGolem,
+ GolemMastery,
+ RaiseSkeletalMage,
+ BloodGolem,
+ SummonResist,
+ IronGolem,
+ FireGolem,
+ Revive,
+ // Poison and Bone Spells
+ Teeth,
+ BoneArmor,
+ PoisonDagger,
+ CorpseExplosion,
+ BoneWall,
+ PoisonExplosion,
+ BoneSpear,
+ BonePrision,
+ PoisonNova,
+ BoneSpirit,
+ // Curses
+ AmplifyDamage,
+ DimVision,
+ Weaken,
+ IronMaiden,
+ Terror,
+ Confuse,
+ LifeTap,
+ Attract,
+ Decrepify,
+ LowerResist,
+
+ /// Barbarian
+ // Warcries
+ Howl,
+ FindPotion,
+ Taunt,
+ Shout,
+ FindItem,
+ BattleCry,
+ BattleOrders,
+ GrimWard,
+ WarCry,
+ BattleCommand,
+ // Combat Masteries
+ SwordMastery,
+ AxeMastery,
+ MaceMastery,
+ PoleArmMastery,
+ ThrowingMastery,
+ SpearMastery,
+ IncreasedStamina,
+ IronSkin,
+ IncreasedSpeed,
+ NaturalResistance,
+ // Combat Skills
+ Bash,
+ Leap,
+ DoubleSwing,
+ Stun,
+ DoubleThrow,
+ LeapAttack,
+ Concentrate,
+ Frenzy,
+ Whirlwind,
+ Berserk,
+
+ /// Paladin
+ // Defensive Auras
+ Prayer,
+ ResistFire,
+ Defiance,
+ ResistCold,
+ Cleansing,
+ ResistLightning,
+ Vigor,
+ Meditation,
+ Redemption,
+ Salvation,
+ // Offensive Auras
+ Might,
+ HolyFire,
+ Thorns,
+ BlessedAim,
+ Concentration,
+ HolyFreeze,
+ HolyShock,
+ Sanctuary,
+ Fanaticism,
+ Conviction,
+ // Combat Skills
+ Sacrafice,
+ Smite,
+ HolyBolt,
+ Zeal,
+ Charge,
+ Vengeance,
+ BlessedHammer,
+ Conversion,
+ HolyShield,
+ FistOfTheHeavens,
+
+ /// Sorceress
+ // Cold Spells
+ IceBolt,
+ FrozenArmor,
+ FrostNova,
+ IceBlast,
+ ShiverArmor,
+ GlacialSpike,
+ Blizzard,
+ ChillingArmor,
+ FrozenOrb,
+ ColdMastery,
+ // Lightning Spells
+ ChargedBolt,
+ StaticField,
+ Telekinesis,
+ Nova,
+ Lightning,
+ ChainLightning,
+ Teleport,
+ ThunderStorm,
+ EnergyShield,
+ LightningMastery,
+ // Fire Spells
+ FireBolt,
+ Warmth,
+ Inferno,
+ Blaze,
+ FireBall,
+ FireWall,
+ Enchant,
+ Meteor,
+ FireMastery,
+ Hydra,
+
+ /// Druid
+ // Elemental
+ Firestorm,
+ MoltenBoulder,
+ ArcticBlast,
+ Fissure,
+ CycloneArmor,
+ Twister,
+ Volcano,
+ Tornado,
+ Armageddon,
+ Hurricane,
+ // Shape Shifting
+ Werewolf,
+ Lycanthropy,
+ Werebear,
+ FeralRage,
+ Maul,
+ Rabies,
+ FireClaw,
+ Hunger,
+ ShockWave,
+ Fury,
+ // Summoning
+ Raven,
+ PoisonCreeper,
+ OakSage,
+ SummonSpiritWolf,
+ CarrionVine,
+ heartOfWolverine,
+ SummonDireWolf,
+ SolarCreeper,
+ SpiritOfBarbs,
+ SummonGrizzly
+ }
+}
diff --git a/OpenDiablo2.Common/OpenDiablo2.Common.csproj b/OpenDiablo2.Common/OpenDiablo2.Common.csproj
index 47fc1aa0..ed3f2d74 100644
--- a/OpenDiablo2.Common/OpenDiablo2.Common.csproj
+++ b/OpenDiablo2.Common/OpenDiablo2.Common.csproj
@@ -60,6 +60,7 @@
+
@@ -80,6 +81,7 @@
+
diff --git a/OpenDiablo2.Common/ResourcePaths.cs b/OpenDiablo2.Common/ResourcePaths.cs
index c0235391..61bb0034 100644
--- a/OpenDiablo2.Common/ResourcePaths.cs
+++ b/OpenDiablo2.Common/ResourcePaths.cs
@@ -141,6 +141,15 @@ namespace OpenDiablo2.Common
public const string SkillsPanelPaladin = @"data\global\ui\SPELLS\skltree_p_back.DC6";
public const string SkillsPanelSorcerer = @"data\global\ui\SPELLS\skltree_s_back.DC6";
+ public const string GenericSkills = @"data\global\ui\SPELLS\Skillicon.DC6";
+ public const string AmazonSkills = @"data\global\ui\SPELLS\AmSkillicon.DC6";
+ public const string BarbarianSkills = @"data\global\ui\SPELLS\BaSkillicon.DC6";
+ public const string DruidSkills = @"data\global\ui\SPELLS\DrSkillicon.DC6";
+ public const string AssassinSkills = @"data\global\ui\SPELLS\AsSkillicon.DC6";
+ public const string NecromancerSkills = @"data\global\ui\SPELLS\NeSkillicon.DC6";
+ public const string PaladinSkills = @"data\global\ui\SPELLS\PaSkillicon.DC6";
+ public const string SorcererSkills = @"data\global\ui\SPELLS\SoSkillicon.DC6";
+
public const string RunButton = @"data\global\ui\PANEL\runbutton.dc6";
public const string MenuButton = @"data\global\ui\PANEL\menubutton.DC6";
public const string GoldCoinButton = @"data\global\ui\panel\goldcoinbtn.dc6";
@@ -341,6 +350,31 @@ namespace OpenDiablo2.Common
throw new ArgumentException($"Unknown hero type: {hero}");
}
}
+
+ public static string GetHeroSkillsIcons(eHero hero)
+ {
+ switch (hero)
+ {
+ case eHero.None:
+ return GenericSkills;
+ case eHero.Amazon:
+ return AmazonSkills;
+ case eHero.Assassin:
+ return AssassinSkills;
+ case eHero.Barbarian:
+ return BarbarianSkills;
+ case eHero.Druid:
+ return DruidSkills;
+ case eHero.Necromancer:
+ return NecromancerSkills;
+ case eHero.Paladin:
+ return PaladinSkills;
+ case eHero.Sorceress:
+ return SorcererSkills;
+ default:
+ throw new ArgumentException($"Unknown hero type: {hero}");
+ }
+ }
}
}