277 lines
9.3 KiB
Go
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"
|
|
}
|
|
} |