359 lines
10 KiB
Go
359 lines
10 KiB
Go
package classes
|
|
|
|
import (
|
|
"strings"
|
|
)
|
|
|
|
// classMap contains the mapping of class names to IDs
|
|
var classMap = map[string]int8{
|
|
"COMMONER": ClassCommoner,
|
|
"FIGHTER": ClassFighter,
|
|
"WARRIOR": ClassWarrior,
|
|
"GUARDIAN": ClassGuardian,
|
|
"BERSERKER": ClassBerserker,
|
|
"BRAWLER": ClassBrawler,
|
|
"MONK": ClassMonk,
|
|
"BRUISER": ClassBruiser,
|
|
"CRUSADER": ClassCrusader,
|
|
"SHADOWKNIGHT": ClassShadowknight,
|
|
"PALADIN": ClassPaladin,
|
|
"PRIEST": ClassPriest,
|
|
"CLERIC": ClassCleric,
|
|
"TEMPLAR": ClassTemplar,
|
|
"INQUISITOR": ClassInquisitor,
|
|
"DRUID": ClassDruid,
|
|
"WARDEN": ClassWarden,
|
|
"FURY": ClassFury,
|
|
"SHAMAN": ClassShaman,
|
|
"MYSTIC": ClassMystic,
|
|
"DEFILER": ClassDefiler,
|
|
"MAGE": ClassMage,
|
|
"SORCERER": ClassSorcerer,
|
|
"WIZARD": ClassWizard,
|
|
"WARLOCK": ClassWarlock,
|
|
"ENCHANTER": ClassEnchanter,
|
|
"ILLUSIONIST": ClassIllusionist,
|
|
"COERCER": ClassCoercer,
|
|
"SUMMONER": ClassSummoner,
|
|
"CONJUROR": ClassConjuror,
|
|
"NECROMANCER": ClassNecromancer,
|
|
"SCOUT": ClassScout,
|
|
"ROGUE": ClassRogue,
|
|
"SWASHBUCKLER": ClassSwashbuckler,
|
|
"BRIGAND": ClassBrigand,
|
|
"BARD": ClassBard,
|
|
"TROUBADOR": ClassTroubador,
|
|
"DIRGE": ClassDirge,
|
|
"PREDATOR": ClassPredator,
|
|
"RANGER": ClassRanger,
|
|
"ASSASSIN": ClassAssassin,
|
|
"ANIMALIST": ClassAnimalist,
|
|
"BEASTLORD": ClassBeastlord,
|
|
"SHAPER": ClassShaper,
|
|
"CHANNELER": ClassChanneler,
|
|
"ARTISAN": ClassArtisan,
|
|
"CRAFTSMAN": ClassCraftsman,
|
|
"PROVISIONER": ClassProvisioner,
|
|
"WOODWORKER": ClassWoodworker,
|
|
"CARPENTER": ClassCarpenter,
|
|
"OUTFITTER": ClassOutfitter,
|
|
"ARMORER": ClassArmorer,
|
|
"WEAPONSMITH": ClassWeaponsmith,
|
|
"TAILOR": ClassTailor,
|
|
"SCHOLAR": ClassScholar,
|
|
"JEWELER": ClassJeweler,
|
|
"SAGE": ClassSage,
|
|
"ALCHEMIST": ClassAlchemist,
|
|
}
|
|
|
|
// displayNameMap contains the display names for each class ID
|
|
var displayNameMap = map[int8]string{
|
|
ClassCommoner: "Commoner",
|
|
ClassFighter: "Fighter",
|
|
ClassWarrior: "Warrior",
|
|
ClassGuardian: "Guardian",
|
|
ClassBerserker: "Berserker",
|
|
ClassBrawler: "Brawler",
|
|
ClassMonk: "Monk",
|
|
ClassBruiser: "Bruiser",
|
|
ClassCrusader: "Crusader",
|
|
ClassShadowknight: "Shadowknight",
|
|
ClassPaladin: "Paladin",
|
|
ClassPriest: "Priest",
|
|
ClassCleric: "Cleric",
|
|
ClassTemplar: "Templar",
|
|
ClassInquisitor: "Inquisitor",
|
|
ClassDruid: "Druid",
|
|
ClassWarden: "Warden",
|
|
ClassFury: "Fury",
|
|
ClassShaman: "Shaman",
|
|
ClassMystic: "Mystic",
|
|
ClassDefiler: "Defiler",
|
|
ClassMage: "Mage",
|
|
ClassSorcerer: "Sorcerer",
|
|
ClassWizard: "Wizard",
|
|
ClassWarlock: "Warlock",
|
|
ClassEnchanter: "Enchanter",
|
|
ClassIllusionist: "Illusionist",
|
|
ClassCoercer: "Coercer",
|
|
ClassSummoner: "Summoner",
|
|
ClassConjuror: "Conjuror",
|
|
ClassNecromancer: "Necromancer",
|
|
ClassScout: "Scout",
|
|
ClassRogue: "Rogue",
|
|
ClassSwashbuckler: "Swashbuckler",
|
|
ClassBrigand: "Brigand",
|
|
ClassBard: "Bard",
|
|
ClassTroubador: "Troubador",
|
|
ClassDirge: "Dirge",
|
|
ClassPredator: "Predator",
|
|
ClassRanger: "Ranger",
|
|
ClassAssassin: "Assassin",
|
|
ClassAnimalist: "Animalist",
|
|
ClassBeastlord: "Beastlord",
|
|
ClassShaper: "Shaper",
|
|
ClassChanneler: "Channeler",
|
|
ClassArtisan: "Artisan",
|
|
ClassCraftsman: "Craftsman",
|
|
ClassProvisioner: "Provisioner",
|
|
ClassWoodworker: "Woodworker",
|
|
ClassCarpenter: "Carpenter",
|
|
ClassOutfitter: "Outfitter",
|
|
ClassArmorer: "Armorer",
|
|
ClassWeaponsmith: "Weaponsmith",
|
|
ClassTailor: "Tailor",
|
|
ClassScholar: "Scholar",
|
|
ClassJeweler: "Jeweler",
|
|
ClassSage: "Sage",
|
|
ClassAlchemist: "Alchemist",
|
|
}
|
|
|
|
// GetClassID returns the class ID for a given class name
|
|
// Converted from C++ Classes::GetClassID
|
|
func GetClassID(name string) int8 {
|
|
className := strings.ToUpper(strings.TrimSpace(name))
|
|
if classID, exists := classMap[className]; exists {
|
|
return classID
|
|
}
|
|
return -1 // Invalid class
|
|
}
|
|
|
|
// GetClassName returns the uppercase class name for a given ID
|
|
// Converted from C++ Classes::GetClassName
|
|
func GetClassName(classID int8) string {
|
|
// Search through class map to find the name
|
|
for name, id := range classMap {
|
|
if id == classID {
|
|
return name
|
|
}
|
|
}
|
|
return "" // Invalid class ID
|
|
}
|
|
|
|
// GetClassNameCase returns the friendly display name for a given class ID
|
|
// Converted from C++ Classes::GetClassNameCase
|
|
func GetClassNameCase(classID int8) string {
|
|
if displayName, exists := displayNameMap[classID]; exists {
|
|
return displayName
|
|
}
|
|
return "" // Invalid class ID
|
|
}
|
|
|
|
// GetBaseClass returns the base class ID for a given class
|
|
// Converted from C++ Classes::GetBaseClass
|
|
func GetBaseClass(classID int8) int8 {
|
|
if classID >= ClassWarrior && classID <= ClassPaladin {
|
|
return ClassFighter
|
|
}
|
|
if (classID >= ClassCleric && classID <= ClassDefiler) || (classID == ClassShaper || classID == ClassChanneler) {
|
|
return ClassPriest
|
|
}
|
|
if classID >= ClassSorcerer && classID <= ClassNecromancer {
|
|
return ClassMage
|
|
}
|
|
if classID >= ClassRogue && classID <= ClassBeastlord {
|
|
return ClassScout
|
|
}
|
|
return ClassCommoner // Default for unknown classes
|
|
}
|
|
|
|
// GetSecondaryBaseClass returns the secondary base class ID for specialized classes
|
|
// Converted from C++ Classes::GetSecondaryBaseClass
|
|
func GetSecondaryBaseClass(classID int8) int8 {
|
|
switch classID {
|
|
case ClassGuardian, ClassBerserker:
|
|
return ClassWarrior
|
|
case ClassMonk, ClassBruiser:
|
|
return ClassBrawler
|
|
case ClassShadowknight, ClassPaladin:
|
|
return ClassCrusader
|
|
case ClassTemplar, ClassInquisitor:
|
|
return ClassCleric
|
|
case ClassWarden, ClassFury:
|
|
return ClassDruid
|
|
case ClassMystic, ClassDefiler:
|
|
return ClassShaman
|
|
case ClassWizard, ClassWarlock:
|
|
return ClassSorcerer
|
|
case ClassIllusionist, ClassCoercer:
|
|
return ClassEnchanter
|
|
case ClassConjuror, ClassNecromancer:
|
|
return ClassSummoner
|
|
case ClassSwashbuckler, ClassBrigand:
|
|
return ClassRogue
|
|
case ClassTroubador, ClassDirge:
|
|
return ClassBard
|
|
case ClassRanger, ClassAssassin:
|
|
return ClassPredator
|
|
case ClassBeastlord:
|
|
return ClassAnimalist
|
|
case ClassChanneler:
|
|
return ClassShaper
|
|
}
|
|
return ClassCommoner // Default for unknown classes
|
|
}
|
|
|
|
// GetTSBaseClass returns the tradeskill base class ID
|
|
// Converted from C++ Classes::GetTSBaseClass
|
|
func GetTSBaseClass(classID int8) int8 {
|
|
// This function maps tradeskill class IDs to their base tradeskill progression levels
|
|
// The C++ code uses offset of 42 between adventure and tradeskill class systems
|
|
if classID+42 >= ClassArtisan {
|
|
return ClassArtisan - 44 // Returns 1 (base artisan level)
|
|
}
|
|
return classID // For non-tradeskill classes, return as-is
|
|
}
|
|
|
|
// GetSecondaryTSBaseClass returns the secondary tradeskill base class ID
|
|
// Converted from C++ Classes::GetSecondaryTSBaseClass
|
|
func GetSecondaryTSBaseClass(classID int8) int8 {
|
|
ret := classID + 42
|
|
|
|
if ret == ClassArtisan {
|
|
return ClassArtisan - 44
|
|
} else if ret >= ClassCraftsman && ret < ClassOutfitter {
|
|
return ClassCraftsman - 44
|
|
} else if ret >= ClassOutfitter && ret < ClassScholar {
|
|
return ClassOutfitter - 44
|
|
} else if ret >= ClassScholar {
|
|
return ClassScholar - 44
|
|
}
|
|
|
|
return classID
|
|
}
|
|
|
|
// IsValidClassID checks if a class ID is valid
|
|
func IsValidClassID(classID int8) bool {
|
|
return classID >= MinClassID && classID <= MaxClassID
|
|
}
|
|
|
|
// IsAdventureClass checks if a class is an adventure class
|
|
func IsAdventureClass(classID int8) bool {
|
|
return classID >= ClassCommoner && classID <= ClassChanneler
|
|
}
|
|
|
|
// IsTradeskillClass checks if a class is a tradeskill class
|
|
func IsTradeskillClass(classID int8) bool {
|
|
return classID >= ClassArtisan && classID <= ClassAlchemist
|
|
}
|
|
|
|
// GetClassType returns the type of class (adventure, tradeskill, etc.)
|
|
func GetClassType(classID int8) string {
|
|
if IsAdventureClass(classID) {
|
|
return ClassTypeAdventure
|
|
}
|
|
if IsTradeskillClass(classID) {
|
|
return ClassTypeTradeskill
|
|
}
|
|
return ClassTypeSpecial
|
|
}
|
|
|
|
// GetAllClasses returns all class IDs and their display names
|
|
func GetAllClasses() map[int8]string {
|
|
result := make(map[int8]string)
|
|
for classID, displayName := range displayNameMap {
|
|
result[classID] = displayName
|
|
}
|
|
return result
|
|
}
|
|
|
|
// GetClassInfo returns comprehensive information about a class
|
|
func GetClassInfo(classID int8) map[string]any {
|
|
info := make(map[string]any)
|
|
|
|
if !IsValidClassID(classID) {
|
|
info["valid"] = false
|
|
return info
|
|
}
|
|
|
|
info["valid"] = true
|
|
info["class_id"] = classID
|
|
info["name"] = GetClassName(classID)
|
|
info["display_name"] = GetClassNameCase(classID)
|
|
info["base_class"] = GetBaseClass(classID)
|
|
info["secondary_base_class"] = GetSecondaryBaseClass(classID)
|
|
info["type"] = GetClassType(classID)
|
|
info["is_adventure"] = IsAdventureClass(classID)
|
|
info["is_tradeskill"] = IsTradeskillClass(classID)
|
|
|
|
return info
|
|
}
|
|
|
|
// GetClassHierarchy returns the full class hierarchy for a given class
|
|
func GetClassHierarchy(classID int8) []int8 {
|
|
if !IsValidClassID(classID) {
|
|
return nil
|
|
}
|
|
|
|
hierarchy := []int8{classID}
|
|
|
|
// Add secondary base class if it exists
|
|
secondary := GetSecondaryBaseClass(classID)
|
|
if secondary != ClassCommoner && secondary != classID {
|
|
hierarchy = append(hierarchy, secondary)
|
|
}
|
|
|
|
// Add base class
|
|
base := GetBaseClass(classID)
|
|
if base != ClassCommoner && base != classID {
|
|
// Check if base is already in hierarchy (from secondary)
|
|
found := false
|
|
for _, id := range hierarchy {
|
|
if id == base {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
hierarchy = append(hierarchy, base)
|
|
}
|
|
}
|
|
|
|
// Always add Commoner as the root
|
|
if classID != ClassCommoner {
|
|
hierarchy = append(hierarchy, ClassCommoner)
|
|
}
|
|
|
|
return hierarchy
|
|
}
|
|
|
|
// IsSameArchetype checks if two classes share the same base archetype
|
|
func IsSameArchetype(classID1, classID2 int8) bool {
|
|
if !IsValidClassID(classID1) || !IsValidClassID(classID2) {
|
|
return false
|
|
}
|
|
return GetBaseClass(classID1) == GetBaseClass(classID2)
|
|
}
|
|
|
|
// GetArchetypeClasses returns all classes of a given archetype
|
|
func GetArchetypeClasses(archetypeID int8) []int8 {
|
|
var classes []int8
|
|
|
|
for classID := MinClassID; classID <= MaxClassID; classID++ {
|
|
if GetBaseClass(classID) == archetypeID {
|
|
classes = append(classes, classID)
|
|
}
|
|
}
|
|
|
|
return classes
|
|
} |