1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-06-20 14:15:23 +00:00

HeroTypeConfig Data Loaded from MPQs (#35)

* Game loads experience config data
* Stored based on hero type, handed off during spawnnewplayer
* Update LevelExperienceConfig.cs
* HeroTypeConfigs loaded from mpq data
* Update PlayerState.cs
* Update PlayerState.cs
This commit is contained in:
nicholasdechiara 2018-12-05 22:28:09 -05:00 committed by Tim Sarbin
parent 4085dc493b
commit f564df0117
8 changed files with 214 additions and 7 deletions

View File

@ -14,10 +14,13 @@ namespace OpenDiablo2.Common.UT
private PlayerState MakePlayer()
{
HeroTypeConfig herotypeconfig = new HeroTypeConfig(vitality: 20, strength: 20, dexterity: 20,
energy: 20, health: 50, mana: 40, stamina: 30,
energy: 20, health: 50, mana: 40, stamina: 30, manaRegen: 20,
perlevelhealth: 3, perlevelmana: 1.5, perlevelstamina: 1,
pervitalityhealth: 2, pervitalitystamina: 1, perenergymana: 1.5,
baseatkrating: -30, basedefrating: -30, perdexterityatkrating: 5, perdexteritydefrating: 4);
baseatkrating: -30, basedefrating: -30, perdexterityatkrating: 5, perdexteritydefrating: 4,
walkVelocity: 6, runVelocity: 9, runDrain: 20, walkFrames: 8, runFrames: 8, swingFrames: 8,
spellFrames: 8, getHitFrames: 8, bowFrames: 8, startingSkill: 0, baseWeaponClass: "hth",
itemNames: new List<string>(), itemLocs: new List<string>(), itemCounts: new List<int>());
LevelExperienceConfig expconfig = new LevelExperienceConfig(new List<long>()
{
0, // level 0

View File

@ -12,5 +12,6 @@ namespace OpenDiablo2.Common.Interfaces
List<LevelDetail> LevelDetails { get; }
List<Item> Items { get; }
Dictionary<eHero, ILevelExperienceConfig> ExperienceConfigs { get; }
Dictionary<eHero, IHeroTypeConfig> HeroTypeConfigs { get; }
}
}

View File

@ -15,6 +15,7 @@ namespace OpenDiablo2.Common.Interfaces.Mobs
int StartingHealth { get; }
int StartingMana { get; }
int StartingStamina { get; }
int StartingManaRegen { get; }
double PerLevelHealth { get; } // NOTE: these are doubles because some classes have
// e.g. 1.5 mana per level, which means they get 1 mana on even levels (e.g. -> 2)
@ -31,5 +32,23 @@ namespace OpenDiablo2.Common.Interfaces.Mobs
int BaseDefenseRating { get; }
int PerDexterityDefenseRating { get; }
int WalkVelocity { get; }
int RunVelocity { get; }
int RunDrain { get; }
int WalkFrames { get; }
int RunFrames { get; }
int SwingFrames { get; }
int SpellFrames { get; }
int GetHitFrames { get; }
int BowFrames { get; }
int StartingSkill { get; }
string BaseWeaponClass { get; }
IEnumerable<string> ItemNames { get; }
IEnumerable<string> ItemLocs { get; }
IEnumerable<int> ItemCounts { get; }
}
}

View File

@ -16,6 +16,7 @@ namespace OpenDiablo2.Common.Models.Mobs
public int StartingHealth { get; protected set; }
public int StartingMana { get; protected set; }
public int StartingStamina { get; protected set; }
public int StartingManaRegen { get; protected set; }
public double PerLevelHealth { get; protected set; }
public double PerLevelMana { get; protected set; }
@ -31,11 +32,34 @@ namespace OpenDiablo2.Common.Models.Mobs
public int BaseDefenseRating { get; protected set; }
public int PerDexterityDefenseRating { get; protected set; }
public int WalkVelocity { get; protected set; }
public int RunVelocity { get; protected set; }
public int RunDrain { get; protected set; }
public int WalkFrames { get; protected set; }
public int RunFrames { get; protected set; }
public int SwingFrames { get; protected set; }
public int SpellFrames { get; protected set; }
public int GetHitFrames { get; protected set; }
public int BowFrames { get; protected set; }
public int StartingSkill { get; protected set; }
public string BaseWeaponClass { get; protected set; }
public IEnumerable<string> ItemNames { get; }
public IEnumerable<string> ItemLocs { get; }
public IEnumerable<int> ItemCounts { get; }
public HeroTypeConfig(int vitality, int strength, int dexterity, int energy,
int health, int mana, int stamina,
int health, int mana, int stamina, int manaRegen,
double perlevelhealth, double perlevelmana, double perlevelstamina,
double pervitalityhealth, double pervitalitystamina, double perenergymana,
int baseatkrating, int basedefrating, int perdexterityatkrating, int perdexteritydefrating)
int baseatkrating, int basedefrating, int perdexterityatkrating, int perdexteritydefrating,
int walkVelocity, int runVelocity, int runDrain,
int walkFrames, int runFrames, int swingFrames, int spellFrames, int getHitFrames, int bowFrames,
int startingSkill,
string baseWeaponClass,
List<string> itemNames, List<string> itemLocs, List<int> itemCounts)
{
StartingDexterity = dexterity;
StartingVitality = vitality;
@ -44,6 +68,7 @@ namespace OpenDiablo2.Common.Models.Mobs
StartingMana = mana;
StartingHealth = health;
StartingStamina = stamina;
StartingManaRegen = manaRegen;
PerLevelHealth = perlevelhealth;
PerLevelMana = perlevelmana;
@ -57,6 +82,102 @@ namespace OpenDiablo2.Common.Models.Mobs
BaseDefenseRating = basedefrating;
PerDexterityAttackRating = perdexterityatkrating;
PerDexterityDefenseRating = perdexteritydefrating;
WalkVelocity = walkVelocity;
RunVelocity = runVelocity;
RunDrain = runDrain;
WalkFrames = walkFrames;
RunFrames = runFrames;
SwingFrames = swingFrames;
SpellFrames = spellFrames;
GetHitFrames = getHitFrames;
BowFrames = bowFrames;
StartingSkill = startingSkill;
BaseWeaponClass = baseWeaponClass;
ItemNames = itemNames;
ItemLocs = itemLocs;
ItemCounts = itemCounts;
}
}
public static class HeroTypeConfigHelper
{
public static IHeroTypeConfig ToHeroTypeConfig(this string[] row)
{
// rows:
// 0 1 2 3 4 5 6 7
// class str dex int vit tot stamina hpadd
// 8 9 10 11
// PercentStr PercentDex PercentInt PercentVit
// 12 13 14 15
// ManaRegen ToHitFactor WalkVelocity RunVelocity
// 16 17 18 19 20
// RunDrain Comment LifePerLevel StaminaPerLevel ManaPerLevel
// 21 22 23
// LifePerVitality StaminaPerVitality ManaPerMagic
// 24 25 26 27 28 29
// #walk #run #swing #spell #gethit #bow
// 30 31 32
// BlockFactor StartSkill baseWClass
// 33 34 35 36 37 38
// item1 item1loc item1count item2 item2loc item2count
// 39 40 41 42 43 44
// item3 item3loc item3count item4 item4loc item4count
// 45 46 47 48 49 50
// item5 item5loc item5count item6 item6loc item6count
// 51 52 53 54 55 56
// item7 item7loc item7count item8 item8loc item8count
// 57 58 59 60 61 62
// item9 item9loc item9count item10 item10loc item10count
List<string> itemNames = new List<string>();
List<string> itemLocs = new List<string>();
List<int> itemCounts = new List<int>();
for(int i = 33; i <= 60; i+=3)
{
itemNames.Add(row[i]);
itemLocs.Add(row[i + 1]);
itemCounts.Add(Convert.ToInt32(row[i + 2]));
}
return new HeroTypeConfig(
vitality: Convert.ToInt32(row[4]),
strength: Convert.ToInt32(row[1]),
dexterity: Convert.ToInt32(row[2]),
energy: Convert.ToInt32(row[3]),
health: Convert.ToInt32(row[7]),
mana: 0,
stamina: Convert.ToInt32(row[6]),
manaRegen: Convert.ToInt32(row[12]),
perlevelhealth: Convert.ToInt32(row[18]) / 4.0,
perlevelmana: Convert.ToInt32(row[20]) / 4.0,
perlevelstamina: Convert.ToInt32(row[19]) / 4.0,
pervitalityhealth: Convert.ToInt32(row[21]) / 4.0,
pervitalitystamina: Convert.ToInt32(row[22]) / 4.0,
perenergymana: Convert.ToInt32(row[23]) / 4.0,
baseatkrating: Convert.ToInt32(row[13]),
basedefrating: Convert.ToInt32(row[30]),
perdexterityatkrating: 5,
perdexteritydefrating: 4,
walkVelocity: Convert.ToInt32(row[14]),
runVelocity: Convert.ToInt32(row[15]),
runDrain: Convert.ToInt32(row[16]),
walkFrames: Convert.ToInt32(row[24]),
runFrames: Convert.ToInt32(row[25]),
swingFrames: Convert.ToInt32(row[26]),
spellFrames: Convert.ToInt32(row[27]),
getHitFrames: Convert.ToInt32(row[28]),
bowFrames: Convert.ToInt32(row[29]),
startingSkill: Convert.ToInt32(row[31]),
baseWeaponClass: row[32],
itemNames: itemNames,
itemLocs: itemLocs,
itemCounts: itemCounts);
}
}
}

View File

@ -25,6 +25,13 @@ namespace OpenDiablo2.Common.Models.Mobs
protected Stat Stamina;
protected Stat Mana;
protected Stat ManaRegen;
protected Stat WalkVelocity;
protected Stat RunVelocity;
protected Stat RunDrain;
public long Experience { get; protected set; }
@ -38,6 +45,7 @@ namespace OpenDiablo2.Common.Models.Mobs
this.ClientHash = clientHash;
Stamina = new Stat(0, 0, 0, true);
Mana = new Stat(0, 0, 0, true);
ManaRegen = new Stat(0, heroconfig.StartingManaRegen, heroconfig.StartingManaRegen, true);
Vitality = new Stat(0, vitality, vitality, true);
Strength = new Stat(0, strength, strength, true);
@ -47,6 +55,10 @@ namespace OpenDiablo2.Common.Models.Mobs
AttackRating = new Stat(0, 0, 0, false);
DefenseRating = new Stat(0, 0, 0, false);
WalkVelocity = new Stat(0, heroconfig.WalkVelocity, 100, false); // TODO: what should max velocity be? (replace the 100)
RunVelocity = new Stat(0, heroconfig.RunVelocity, 100, false); // TODO: what should max velocity be?
RunDrain = new Stat(0, heroconfig.RunDrain, heroconfig.RunDrain, true);
Experience = experience; // how much total exp do they have
HeroType = herotype;
@ -183,6 +195,10 @@ namespace OpenDiablo2.Common.Models.Mobs
{
Mana.AddCurrent(-mana);
}
public int GetManaRegen()
{
return ManaRegen.GetCurrent();
}
#endregion Mana
#region Stamina
@ -204,6 +220,21 @@ namespace OpenDiablo2.Common.Models.Mobs
}
#endregion Stamina
#region Movement
public int GetRunVelocity()
{
return RunVelocity.GetCurrent();
}
public int GetWalkVeloicty()
{
return WalkVelocity.GetCurrent();
}
public int GetRunDrain()
{
return RunDrain.GetCurrent();
}
#endregion Movement
// TODO: when a player equips an item, apply the relevant modifiers to their stats
// TODO: when a player unequips an item, remove the relevant modifiers from their stats
}

View File

@ -139,6 +139,7 @@ namespace OpenDiablo2.Common
// --- Character Data ---
public static string Experience = "data\\global\\excel\\experience.txt";
public static string CharStats = "data\\global\\excel\\charstats.txt";
public static string GeneratePathForItem(string spriteName)
{

View File

@ -21,6 +21,7 @@ namespace OpenDiablo2.Core
public List<LevelDetail> LevelDetails { get; internal set; }
public List<Item> Items { get; internal set; } = new List<Item>();
public Dictionary<eHero, ILevelExperienceConfig> ExperienceConfigs { get; internal set; } = new Dictionary<eHero, ILevelExperienceConfig>();
public Dictionary<eHero, IHeroTypeConfig> HeroTypeConfigs { get; internal set; } = new Dictionary<eHero, IHeroTypeConfig>();
public EngineDataManager(IMPQProvider mpqProvider)
{
@ -134,6 +135,7 @@ namespace OpenDiablo2.Core
private void LoadCharacterData()
{
LoadExperienceConfig();
LoadHeroTypeConfig();
}
private void LoadExperienceConfig()
@ -147,5 +149,19 @@ namespace OpenDiablo2.Core
ExperienceConfigs = data;
}
private void LoadHeroTypeConfig()
{
var data = mpqProvider
.GetTextFile(ResourcePaths.CharStats)
.Skip(1)
.Where(x => !String.IsNullOrWhiteSpace(x))
.Select(x => x.Split('\t'))
.Where(x => x[0] != "Expansion")
.ToArray()
.ToDictionary(x => (eHero)Enum.Parse(typeof(eHero),x[0]), x => x.ToHeroTypeConfig());
HeroTypeConfigs = data;
}
}
}

View File

@ -34,19 +34,34 @@ namespace OpenDiablo2.GameServer_
public int SpawnNewPlayer(int clientHash, string playerName, eHero heroType)
{
ILevelExperienceConfig expConfig = null;
try
IHeroTypeConfig heroConfig = null;
if (engineDataManager.ExperienceConfigs.ContainsKey(heroType))
{
expConfig = engineDataManager.ExperienceConfigs[heroType];
}
catch(Exception e)
else
{
log.Error("Error: Experience Config not loaded for '" + heroType.ToString() + "'.");
expConfig = new LevelExperienceConfig(new List<long>() { 100 });
// TODO: should we have a more robust default experience config?
// or should we just fail in some way here?
}
if (engineDataManager.HeroTypeConfigs.ContainsKey(heroType))
{
heroConfig = engineDataManager.HeroTypeConfigs[heroType];
}
else
{
log.Error("Error: Hero Config not loaded for '" + heroType.ToString() + "'.");
heroConfig = new HeroTypeConfig(10, 10, 10, 10, 10, 10, 10, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 9,
1, 10, 10, 10, 10, 10, 10, 0, "hth", new List<string>(), new List<string>(), new List<int>());
// TODO: should we have a more robust default hero config?
// or should we just fail in some way here?
// ... we should probably just fail here
}
var newPlayer = new PlayerState(clientHash, playerName, mobManager.GetNextAvailableMobId(), 1, 20.0f, 20.0f, 10, 10, 10, 10, 0, heroType,
new HeroTypeConfig(10, 10, 10, 50, 50, 50, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), expConfig);
heroConfig, expConfig);
mobManager.AddPlayer(newPlayer);
return newPlayer.Id;