277 lines
9.3 KiB
Go

package alt_advancement
// AA tab/group constants based on group # from DB
const (
AA_CLASS = 0 // Class-specific advancement trees
AA_SUBCLASS = 1 // Subclass-specific advancement trees
AA_SHADOW = 2 // Shadows advancement (from Shadows of Luclin)
AA_HEROIC = 3 // Heroic advancement (from Destiny of Velious)
AA_TRADESKILL = 4 // Tradeskill advancement trees
AA_PRESTIGE = 5 // Prestige advancement (from Destiny of Velious)
AA_TRADESKILL_PRESTIGE = 6 // Tradeskill prestige advancement
AA_DRAGON = 7 // Dragon advancement
AA_DRAGONCLASS = 8 // Dragon class-specific advancement
AA_FARSEAS = 9 // Far Seas advancement
)
// AA tab names for display
var AATabNames = map[int8]string{
AA_CLASS: "Class",
AA_SUBCLASS: "Subclass",
AA_SHADOW: "Shadows",
AA_HEROIC: "Heroic",
AA_TRADESKILL: "Tradeskill",
AA_PRESTIGE: "Prestige",
AA_TRADESKILL_PRESTIGE: "Tradeskill Prestige",
AA_DRAGON: "Dragon",
AA_DRAGONCLASS: "Dragon Class",
AA_FARSEAS: "Far Seas",
}
// Maximum AA values per tab (from C++ packet data)
const (
MAX_CLASS_AA = 100 // 0x64
MAX_SUBCLASS_AA = 100 // 0x64
MAX_SHADOWS_AA = 70 // 0x46
MAX_HEROIC_AA = 50 // 0x32
MAX_TRADESKILL_AA = 40 // 0x28
MAX_PRESTIGE_AA = 25 // 0x19
MAX_TRADESKILL_PRESTIGE_AA = 25 // 0x19
MAX_DRAGON_AA = 100 // Estimated
MAX_DRAGONCLASS_AA = 100 // Estimated
MAX_FARSEAS_AA = 100 // Estimated
)
// AA template constants
const (
AA_TEMPLATE_PERSONAL_1 = 1 // Personal template 1
AA_TEMPLATE_PERSONAL_2 = 2 // Personal template 2
AA_TEMPLATE_PERSONAL_3 = 3 // Personal template 3
AA_TEMPLATE_SERVER_1 = 4 // Server template 1
AA_TEMPLATE_SERVER_2 = 5 // Server template 2
AA_TEMPLATE_SERVER_3 = 6 // Server template 3
AA_TEMPLATE_CURRENT = 7 // Current template (active in-game)
AA_TEMPLATE_BACKUP = 8 // Backup template
)
// AA template names for display
var AATemplateNames = map[int8]string{
AA_TEMPLATE_PERSONAL_1: "Personal Template 1",
AA_TEMPLATE_PERSONAL_2: "Personal Template 2",
AA_TEMPLATE_PERSONAL_3: "Personal Template 3",
AA_TEMPLATE_SERVER_1: "Server Template 1",
AA_TEMPLATE_SERVER_2: "Server Template 2",
AA_TEMPLATE_SERVER_3: "Server Template 3",
AA_TEMPLATE_CURRENT: "Current",
AA_TEMPLATE_BACKUP: "Backup",
}
// Expansion flag constants
const (
EXPANSION_NONE int32 = 0
EXPANSION_RUINS_OF_KUNARK int32 = 1 << 0 // 0x01
EXPANSION_SHADOWS_OF_LUCLIN int32 = 1 << 1 // 0x02
EXPANSION_DESERT_OF_FLAMES int32 = 1 << 2 // 0x04
EXPANSION_KINGDOM_OF_SKY int32 = 1 << 3 // 0x08
EXPANSION_ECHOES_OF_FAYDWER int32 = 1 << 4 // 0x10
EXPANSION_RISE_OF_KUNARK int32 = 1 << 5 // 0x20
EXPANSION_THE_SHADOW_ODYSSEY int32 = 1 << 6 // 0x40
EXPANSION_SENTINEL_FATE int32 = 1 << 7 // 0x80
EXPANSION_DESTINY_OF_VELIOUS int32 = 1 << 8 // 0x100
EXPANSION_AGE_OF_DISCOVERY int32 = 1 << 9 // 0x200
EXPANSION_CHAINS_OF_ETERNITY int32 = 1 << 10 // 0x400
EXPANSION_TEARS_OF_VEESHAN int32 = 1 << 11 // 0x800
EXPANSION_ALTAR_OF_MALICE int32 = 1 << 12 // 0x1000
EXPANSION_TERRORS_OF_THALUMBRA int32 = 1 << 13 // 0x2000
EXPANSION_KUNARK_ASCENDING int32 = 1 << 14 // 0x4000
EXPANSION_PLANES_OF_PROPHECY int32 = 1 << 15 // 0x8000
EXPANSION_CHAOS_DESCENDING int32 = 1 << 16 // 0x10000
EXPANSION_BLOOD_OF_LUCLIN int32 = 1 << 17 // 0x20000
EXPANSION_VISIONS_OF_VETROVIA int32 = 1 << 18 // 0x40000
EXPANSION_RENEWAL_OF_RO int32 = 1 << 19 // 0x80000
)
// AA system configuration defaults
const (
DEFAULT_ENABLE_AA_SYSTEM = true
DEFAULT_ENABLE_AA_CACHING = true
DEFAULT_ENABLE_AA_VALIDATION = true
DEFAULT_ENABLE_AA_LOGGING = true
DEFAULT_AA_POINTS_PER_LEVEL = 2
DEFAULT_AA_MAX_BANKED_POINTS = 100
AA_CACHE_SIZE = 10000
AA_UPDATE_INTERVAL = 30000 // 30 seconds in milliseconds
AA_PROCESSING_BATCH_SIZE = 100
)
// AA purchase and refund constants
const (
AA_PURCHASE_SUCCESS = 0
AA_PURCHASE_FAILED = 1
AA_REFUND_SUCCESS = 0
AA_REFUND_FAILED = 1
)
// AA validation error codes
const (
AA_ERROR_NONE = 0
AA_ERROR_NOT_FOUND = 1
AA_ERROR_INSUFFICIENT_POINTS = 2
AA_ERROR_LEVEL_TOO_LOW = 3
AA_ERROR_WRONG_CLASS = 4
AA_ERROR_PREREQUISITES_NOT_MET = 5
AA_ERROR_MAX_RANK_REACHED = 6
AA_ERROR_INVALID_RANK = 7
AA_ERROR_TREE_POINTS_REQUIRED = 8
AA_ERROR_EXPANSION_REQUIRED = 9
AA_ERROR_TEMPLATE_LOCKED = 10
AA_ERROR_DATABASE_ERROR = 11
AA_ERROR_SYSTEM_DISABLED = 12
)
// AA error messages
var AAErrorMessages = map[int]string{
AA_ERROR_NONE: "Success",
AA_ERROR_NOT_FOUND: "AA not found",
AA_ERROR_INSUFFICIENT_POINTS: "Insufficient AA points",
AA_ERROR_LEVEL_TOO_LOW: "Level requirement not met",
AA_ERROR_WRONG_CLASS: "Class requirement not met",
AA_ERROR_PREREQUISITES_NOT_MET: "Prerequisites not met",
AA_ERROR_MAX_RANK_REACHED: "Maximum rank already reached",
AA_ERROR_INVALID_RANK: "Invalid target rank",
AA_ERROR_TREE_POINTS_REQUIRED: "Insufficient points spent in tree",
AA_ERROR_EXPANSION_REQUIRED: "Expansion requirement not met",
AA_ERROR_TEMPLATE_LOCKED: "Template is locked",
AA_ERROR_DATABASE_ERROR: "Database error occurred",
AA_ERROR_SYSTEM_DISABLED: "AA system is disabled",
}
// GetMaxAAForTab returns the maximum AA points for a given tab
func GetMaxAAForTab(group int8) int32 {
switch group {
case AA_CLASS:
return MAX_CLASS_AA
case AA_SUBCLASS:
return MAX_SUBCLASS_AA
case AA_SHADOW:
return MAX_SHADOWS_AA
case AA_HEROIC:
return MAX_HEROIC_AA
case AA_TRADESKILL:
return MAX_TRADESKILL_AA
case AA_PRESTIGE:
return MAX_PRESTIGE_AA
case AA_TRADESKILL_PRESTIGE:
return MAX_TRADESKILL_PRESTIGE_AA
case AA_DRAGON:
return MAX_DRAGON_AA
case AA_DRAGONCLASS:
return MAX_DRAGONCLASS_AA
case AA_FARSEAS:
return MAX_FARSEAS_AA
default:
return 100 // Default maximum
}
}
// GetTabName returns the display name for an AA tab
func GetTabName(group int8) string {
if name, exists := AATabNames[group]; exists {
return name
}
return "Unknown"
}
// GetTemplateName returns the display name for an AA template
func GetTemplateName(templateID int8) string {
if name, exists := AATemplateNames[templateID]; exists {
return name
}
return "Unknown"
}
// IsExpansionRequired checks if a specific expansion is required
func IsExpansionRequired(flags int32, expansion int32) bool {
return (flags & expansion) != 0
}
// GetAAErrorMessage returns the error message for an AA error code
func GetAAErrorMessage(errorCode int) string {
if message, exists := AAErrorMessages[errorCode]; exists {
return message
}
return "Unknown error"
}
// ValidateTemplateID checks if a template ID is valid
func ValidateTemplateID(templateID int8) bool {
return templateID >= AA_TEMPLATE_PERSONAL_1 && templateID <= AA_TEMPLATE_BACKUP
}
// IsPersonalTemplate checks if a template is a personal template
func IsPersonalTemplate(templateID int8) bool {
return templateID >= AA_TEMPLATE_PERSONAL_1 && templateID <= AA_TEMPLATE_PERSONAL_3
}
// IsServerTemplate checks if a template is a server template
func IsServerTemplate(templateID int8) bool {
return templateID >= AA_TEMPLATE_SERVER_1 && templateID <= AA_TEMPLATE_SERVER_3
}
// IsCurrentTemplate checks if a template is the current active template
func IsCurrentTemplate(templateID int8) bool {
return templateID == AA_TEMPLATE_CURRENT
}
// ValidateAAGroup checks if an AA group is valid
func ValidateAAGroup(group int8) bool {
return group >= AA_CLASS && group <= AA_FARSEAS
}
// GetExpansionNameByFlag returns the expansion name for a flag
func GetExpansionNameByFlag(flag int32) string {
switch flag {
case EXPANSION_RUINS_OF_KUNARK:
return "Ruins of Kunark"
case EXPANSION_SHADOWS_OF_LUCLIN:
return "Shadows of Luclin"
case EXPANSION_DESERT_OF_FLAMES:
return "Desert of Flames"
case EXPANSION_KINGDOM_OF_SKY:
return "Kingdom of Sky"
case EXPANSION_ECHOES_OF_FAYDWER:
return "Echoes of Faydwer"
case EXPANSION_RISE_OF_KUNARK:
return "Rise of Kunark"
case EXPANSION_THE_SHADOW_ODYSSEY:
return "The Shadow Odyssey"
case EXPANSION_SENTINEL_FATE:
return "Sentinel's Fate"
case EXPANSION_DESTINY_OF_VELIOUS:
return "Destiny of Velious"
case EXPANSION_AGE_OF_DISCOVERY:
return "Age of Discovery"
case EXPANSION_CHAINS_OF_ETERNITY:
return "Chains of Eternity"
case EXPANSION_TEARS_OF_VEESHAN:
return "Tears of Veeshan"
case EXPANSION_ALTAR_OF_MALICE:
return "Altar of Malice"
case EXPANSION_TERRORS_OF_THALUMBRA:
return "Terrors of Thalumbra"
case EXPANSION_KUNARK_ASCENDING:
return "Kunark Ascending"
case EXPANSION_PLANES_OF_PROPHECY:
return "Planes of Prophecy"
case EXPANSION_CHAOS_DESCENDING:
return "Chaos Descending"
case EXPANSION_BLOOD_OF_LUCLIN:
return "Blood of Luclin"
case EXPANSION_VISIONS_OF_VETROVIA:
return "Visions of Vetrovia"
case EXPANSION_RENEWAL_OF_RO:
return "Renewal of Ro"
default:
return "Unknown Expansion"
}
}