ModernUO/Projects/UOContent/Misc/ProfessionInfo.cs
Kamron Batman 47e16a03fe
feat: Moves network related events to UOContent using code generation (#1945)
### Summary
- Moves `CharacterCreated` event to UOContent using code generated event _CharacterCreatedEvent_.
- Moves `TargetByResourceMacro` event to UOContent using code generated event _TargetByResourceMacro_.
- Moves `GameLogin` event to UOContent using code generated event _GameLoginEvent_.
- Moves `ServerList` event to UOContent using code generated event _ServerListEvent_.
- Streamlines ProfessionInfo


> [!IMPORTANT]
> **Developer Note**
> Custom scripts that use any of these event sinks will need to be updated to use the new code generated events.
2024-09-06 16:57:10 -07:00

239 lines
7 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;
namespace Server;
public class ProfessionInfo
{
private static readonly ProfessionInfo[] _professions;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool VerifyProfession(int profIndex) => profIndex > 0 && profIndex < _professions.Length;
public static bool GetProfession(int profIndex, out ProfessionInfo profession)
{
if (!VerifyProfession(profIndex))
{
profession = null;
return false;
}
return (profession = _professions[profIndex]) != null;
}
private static bool TryGetSkillName(string name, out SkillName skillName)
{
if (Enum.TryParse(name, out skillName))
{
return true;
}
var lowerName = name?.ToLowerInvariant().RemoveOrdinal(" ");
if (!string.IsNullOrEmpty(lowerName))
{
foreach (var so in SkillInfo.Table)
{
if (lowerName == so.ProfessionSkillName.ToLowerInvariant())
{
skillName = (SkillName)so.SkillID;
return true;
}
}
}
return false;
}
static ProfessionInfo()
{
var file = Core.FindDataFile("prof.txt", false);
if (!File.Exists(file))
{
var parent = Path.Combine(Core.BaseDirectory, "Data/Professions");
file = Path.Combine(ExpansionInfo.GetEraFolder(parent), "prof.txt");
}
if (File.Exists(file))
{
var maxProf = 0;
List<ProfessionInfo> profs = [];
using var s = File.OpenText(file);
while (!s.EndOfStream)
{
var line = s.ReadLine();
if (string.IsNullOrWhiteSpace(line))
{
continue;
}
line = line.Trim();
if (!line.InsensitiveStartsWith("Begin"))
{
continue;
}
var prof = new ProfessionInfo();
var totalStats = 0;
var skillIndex = 0;
var totalSkill = 0;
while (!s.EndOfStream)
{
line = s.ReadLine();
if (string.IsNullOrWhiteSpace(line))
{
continue;
}
line = line.Trim();
if (line.InsensitiveStartsWith("End"))
{
if (prof.ID > 0 && totalStats >= 80 && totalSkill >= 100)
{
prof.FixSkills(); // Adjust skills array in case there are fewer skills than the default 4
profs.Add(prof);
}
break;
}
var cols = line.Split('\t', StringSplitOptions.RemoveEmptyEntries);
var key = cols[0].ToLowerInvariant();
var value = cols[1].Trim('"');
if (key == "type" && !value.InsensitiveEquals("profession"))
{
break;
}
switch (key)
{
case "truename":
{
prof.Name = value;
}
break;
case "nameid":
{
prof.NameID = Utility.ToInt32(value);
break;
}
case "descid":
{
prof.DescID = Utility.ToInt32(value);
break;
}
case "desc":
{
prof.ID = Utility.ToInt32(value);
if (prof.ID > maxProf)
{
maxProf = prof.ID;
}
}
break;
case "toplevel":
{
prof.TopLevel = Utility.ToBoolean(value);
break;
}
case "gump":
{
prof.GumpID = Utility.ToInt32(value);
break;
}
case "skill":
{
if (!TryGetSkillName(value, out var skillName))
{
break;
}
var skillValue = byte.Parse(cols[2]);
prof.Skills[skillIndex++] = (skillName, skillValue);
totalSkill += skillValue;
}
break;
case "stat":
{
if (!Enum.TryParse(value, out StatType stat))
{
break;
}
var statValue = byte.Parse(cols[2]);
prof.Stats[(int)stat >> 1] = statValue;
totalStats += statValue;
}
break;
}
}
}
_professions = new ProfessionInfo[maxProf + 1];
foreach (var p in profs)
{
_professions[p.ID] = p;
}
profs.Clear();
profs.TrimExcess();
}
else
{
_professions = new ProfessionInfo[1];
}
_professions[0] = new ProfessionInfo
{
Name = "Advanced Skills"
};
}
private (SkillName, byte)[] _skills;
private ProfessionInfo()
{
Name = string.Empty;
_skills = new (SkillName, byte)[4];
Stats = new byte[3];
}
public int ID { get; private set; }
public string Name { get; private set; }
public int NameID { get; private set; }
public int DescID { get; private set; }
public bool TopLevel { get; private set; }
public int GumpID { get; private set; }
public (SkillName, byte)[] Skills => _skills;
public byte[] Stats { get; }
public void FixSkills()
{
var index = _skills.Length - 1;
while (index >= 0)
{
var skill = _skills[index];
if (skill is not (SkillName.Alchemy, 0))
{
break;
}
index--;
}
Array.Resize(ref _skills, index + 1);
}
}