1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-06-20 22:25:24 +00:00

Game loads experience config data (#34)

* Game loads experience config data
* Stored based on hero type, handed off during spawnnewplayer
This commit is contained in:
nicholasdechiara 2018-12-04 23:20:31 -05:00 committed by Tim Sarbin
parent a3208e26f2
commit 4085dc493b
8 changed files with 95 additions and 13 deletions

View File

@ -18,7 +18,7 @@ namespace OpenDiablo2.Common.UT
perlevelhealth: 3, perlevelmana: 1.5, perlevelstamina: 1,
pervitalityhealth: 2, pervitalitystamina: 1, perenergymana: 1.5,
baseatkrating: -30, basedefrating: -30, perdexterityatkrating: 5, perdexteritydefrating: 4);
LevelExperienceConfig expconfig = new LevelExperienceConfig(new List<int>()
LevelExperienceConfig expconfig = new LevelExperienceConfig(new List<long>()
{
0, // level 0
0, // level 1

View File

@ -1,4 +1,6 @@
using System.Collections.Generic;
using OpenDiablo2.Common.Enums;
using OpenDiablo2.Common.Interfaces.Mobs;
using OpenDiablo2.Common.Models;
namespace OpenDiablo2.Common.Interfaces
@ -9,5 +11,6 @@ namespace OpenDiablo2.Common.Interfaces
List<LevelType> LevelTypes { get; }
List<LevelDetail> LevelDetails { get; }
List<Item> Items { get; }
Dictionary<eHero, ILevelExperienceConfig> ExperienceConfigs { get; }
}
}

View File

@ -8,7 +8,7 @@ namespace OpenDiablo2.Common.Interfaces.Mobs
{
public interface ILevelExperienceConfig
{
int GetTotalExperienceForLevel(int level);
long GetTotalExperienceForLevel(int level);
int GetMaxLevel();
}
}

View File

@ -1,4 +1,5 @@
using OpenDiablo2.Common.Interfaces.Mobs;
using OpenDiablo2.Common.Enums;
using OpenDiablo2.Common.Interfaces.Mobs;
using System;
using System.Collections.Generic;
using System.Linq;
@ -9,14 +10,14 @@ namespace OpenDiablo2.Common.Models.Mobs
{
public class LevelExperienceConfig : ILevelExperienceConfig
{
private List<int> ExperiencePerLevel = new List<int>();
private List<long> ExperiencePerLevel = new List<long>();
public LevelExperienceConfig(List<int> expperlevel)
public LevelExperienceConfig(List<long> expperlevel)
{
ExperiencePerLevel = expperlevel;
}
public int GetTotalExperienceForLevel(int level)
public long GetTotalExperienceForLevel(int level)
{
if(ExperiencePerLevel.Count <= level)
{
@ -30,4 +31,42 @@ namespace OpenDiablo2.Common.Models.Mobs
return ExperiencePerLevel.Count - 1;
}
}
public static class LevelExperienceConfigHelper
{
public static Dictionary<eHero, ILevelExperienceConfig> ToLevelExperienceConfigs(this string[][] data)
{
Dictionary<eHero, ILevelExperienceConfig> result = new Dictionary<eHero, ILevelExperienceConfig>();
for (int i = 1; i < data[0].Length; i++)
{
// i starts at 1 because we want to skip the first column
// the first column is just the row titles
string heroname = data[i][0]; // first row is the hero name
eHero herotype = default(eHero);
if(!Enum.TryParse<eHero>(heroname, out herotype))
{
continue; // skip this hero if we can't parse the name into a valid hero type
}
int maxlevel = -1;
if(!int.TryParse(data[1][i], out maxlevel))
{
maxlevel = -1;// we don't need to fail in this case since maxlevel
// can be inferred from the number of experience listings
}
List<long> expperlevel = new List<long>();
for (int o = 2; o < data.Length && (o-2 < maxlevel || maxlevel == -1); o++)
{
long exp = 0;
if(!long.TryParse(data[o][i], out exp))
{
throw new Exception("Could not parse experience number '" + data[o][i] + "'.");
}
expperlevel.Add(exp);
}
result.Add(herotype, new LevelExperienceConfig(expperlevel));
}
return result;
}
}
}

View File

@ -26,12 +26,12 @@ namespace OpenDiablo2.Common.Models.Mobs
protected Stat Stamina;
protected Stat Mana;
public int Experience { get; protected set; }
public long Experience { get; protected set; }
public PlayerState() : base() { }
public PlayerState(int clientHash, string name, int id, int level, float x, float y,
int vitality, int strength, int energy, int dexterity, int experience, eHero herotype,
int vitality, int strength, int energy, int dexterity, long experience, eHero herotype,
IHeroTypeConfig heroconfig, ILevelExperienceConfig expconfig)
: base(name, id, level, 0, x, y)
{
@ -63,11 +63,11 @@ namespace OpenDiablo2.Common.Models.Mobs
}
#region Level and Experience
public int GetExperienceToLevel()
public long GetExperienceToLevel()
{
return GetExperienceTotalToLevel() - Experience;
}
public int GetExperienceTotalToLevel()
public long GetExperienceTotalToLevel()
{
return ExperienceConfig.GetTotalExperienceForLevel(Level + 1);
}
@ -75,7 +75,7 @@ namespace OpenDiablo2.Common.Models.Mobs
{
return ExperienceConfig.GetMaxLevel();
}
public bool AddExperience(int amount)
public bool AddExperience(long amount)
{
// returns true if you level up from this
Experience += amount;

View File

@ -137,6 +137,9 @@ namespace OpenDiablo2.Common
public static string Armor = "data\\global\\excel\\armor.txt";
public static string Misc = "data\\global\\excel\\misc.txt";
// --- Character Data ---
public static string Experience = "data\\global\\excel\\experience.txt";
public static string GeneratePathForItem(string spriteName)
{
return $"data\\global\\items\\{spriteName}.dc6";

View File

@ -4,8 +4,11 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenDiablo2.Common;
using OpenDiablo2.Common.Enums;
using OpenDiablo2.Common.Interfaces;
using OpenDiablo2.Common.Interfaces.Mobs;
using OpenDiablo2.Common.Models;
using OpenDiablo2.Common.Models.Mobs;
namespace OpenDiablo2.Core
{
@ -17,6 +20,7 @@ namespace OpenDiablo2.Core
public List<LevelType> LevelTypes { get; internal set; }
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 EngineDataManager(IMPQProvider mpqProvider)
{
@ -27,6 +31,8 @@ namespace OpenDiablo2.Core
LoadLevelDetails();
LoadItemData();
LoadCharacterData();
}
private void LoadLevelTypes()
@ -124,5 +130,22 @@ namespace OpenDiablo2.Core
return data;
}
private void LoadCharacterData()
{
LoadExperienceConfig();
}
private void LoadExperienceConfig()
{
var data = mpqProvider
.GetTextFile(ResourcePaths.Experience)
.Where(x => !String.IsNullOrWhiteSpace(x))
.Select(x => x.Split('\t'))
.ToArray()
.ToLevelExperienceConfigs();
ExperienceConfigs = data;
}
}
}

View File

@ -12,15 +12,17 @@ namespace OpenDiablo2.GameServer_
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private readonly IMobManager mobManager;
private readonly IEngineDataManager engineDataManager;
public int Seed { get; private set; }
public IEnumerable<PlayerState> Players => mobManager.Players;
const double Deg2Rad = Math.PI / 180.0;
public GameServer(IMobManager mobManager)
public GameServer(IMobManager mobManager, IEngineDataManager engineDataManager)
{
this.mobManager = mobManager;
this.engineDataManager = engineDataManager;
}
public void InitializeNewGame()
@ -31,8 +33,20 @@ namespace OpenDiablo2.GameServer_
public int SpawnNewPlayer(int clientHash, string playerName, eHero heroType)
{
ILevelExperienceConfig expConfig = null;
try
{
expConfig = engineDataManager.ExperienceConfigs[heroType];
}
catch(Exception e)
{
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?
}
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), new LevelExperienceConfig(new List<int>() { 100 }));
new HeroTypeConfig(10, 10, 10, 50, 50, 50, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), expConfig);
mobManager.AddPlayer(newPlayer);
return newPlayer.Id;