192 lines
7.9 KiB
Go

package tradeskills
import (
"sync"
"time"
)
// TradeskillEvent represents a tradeskill event that can occur during crafting.
// Events require player counter-actions and affect crafting outcomes.
type TradeskillEvent struct {
Name string // Event name (max 250 characters)
Icon int16 // Icon ID for UI display
Technique uint32 // Associated technique/skill ID
SuccessProgress int16 // Progress gained on successful counter
SuccessDurability int16 // Durability change on successful counter
SuccessHP int16 // HP change on successful counter
SuccessPower int16 // Power change on successful counter
SuccessSpellID uint32 // Spell cast on successful counter
SuccessItemID uint32 // Item given on successful counter
FailProgress int16 // Progress change on failed counter (can be negative)
FailDurability int16 // Durability change on failed counter (can be negative)
FailHP int16 // HP change on failed counter (can be negative)
FailPower int16 // Power change on failed counter (can be negative)
}
// Tradeskill represents an active crafting session for a player.
// Contains all state needed to track crafting progress and events.
type Tradeskill struct {
PlayerID uint32 // ID of the crafting player
TableSpawnID uint32 // ID of the crafting table spawn
RecipeID uint32 // ID of the recipe being crafted
CurrentProgress int32 // Current crafting progress (0-1000)
CurrentDurability int32 // Current item durability (0-1000)
NextUpdateTime time.Time // When the next crafting update should occur
UsedComponents []ComponentUsage // List of components being consumed
CurrentEvent *TradeskillEvent // Current active event (if any)
EventChecked bool // Whether the current event has been checked/resolved
EventCountered bool // Whether the current event was successfully countered
StartTime time.Time // When crafting began
LastUpdate time.Time // When crafting was last updated
}
// ComponentUsage tracks a component being used in crafting.
type ComponentUsage struct {
ItemUniqueID uint32 // Unique ID of the item being used
Quantity int16 // Quantity being consumed
}
// TradeskillManager manages all active tradeskill sessions.
// Handles crafting updates, event processing, and session lifecycle.
type TradeskillManager struct {
tradeskillList map[uint32]*Tradeskill // Map of player ID to their tradeskill session
mutex sync.RWMutex // Protects concurrent access to tradeskillList
// Configuration values (loaded from rules)
critFailChance float32 // Chance of critical failure
critSuccessChance float32 // Chance of critical success
failChance float32 // Chance of regular failure
successChance float32 // Chance of regular success
eventChance float32 // Chance of triggering an event
// Statistics
stats TradeskillManagerStats
}
// TradeskillManagerStats tracks usage statistics for the tradeskill system.
type TradeskillManagerStats struct {
ActiveSessions int32 // Number of currently active crafting sessions
TotalSessionsStarted int32 // Total sessions started since startup
TotalSessionsCompleted int32 // Total sessions completed since startup
TotalSessionsCancelled int32 // Total sessions cancelled since startup
TotalEventsTriggered int32 // Total events triggered since startup
TotalEventsCountered int32 // Total events successfully countered since startup
LastUpdate time.Time // When stats were last updated
}
// MasterTradeskillEventsList manages all available tradeskill events.
// Events are organized by technique for efficient lookup during crafting.
type MasterTradeskillEventsList struct {
eventList map[uint32][]*TradeskillEvent // Map of technique ID to list of events
mutex sync.RWMutex // Protects concurrent access to eventList
totalEvents int32 // Total number of events loaded
}
// CraftingOutcome represents the result of a crafting update.
type CraftingOutcome struct {
Success bool // Whether the crafting step was successful
CriticalSuccess bool // Whether it was a critical success
CriticalFailure bool // Whether it was a critical failure
ProgressChange int32 // Change in progress
DurabilityChange int32 // Change in durability
EventTriggered *TradeskillEvent // Event that was triggered (if any)
Completed bool // Whether crafting is now complete
Failed bool // Whether crafting has failed
ComponentsUsed []ComponentUsage // Components consumed this update
}
// CraftingRequest represents a request to begin crafting.
type CraftingRequest struct {
PlayerID uint32 // ID of the player crafting
RecipeID uint32 // ID of the recipe to craft
TableSpawnID uint32 // ID of the crafting table
Components []ComponentUsage // Components to use for crafting
Quantity int32 // Quantity to craft (for mass production)
}
// EventCounterRequest represents a player's attempt to counter a tradeskill event.
type EventCounterRequest struct {
PlayerID uint32 // ID of the player attempting the counter
SpellIcon int16 // Icon of the spell/ability used to counter
}
// TradeskillStats provides detailed statistics about tradeskill usage.
type TradeskillStats struct {
TotalEvents int32 // Total events in master list
EventsByTechnique map[uint32]int32 // Number of events per technique
ActiveSessions int32 // Currently active crafting sessions
RecentCompletions int32 // Completions in last hour
AverageSessionTime time.Duration // Average time per crafting session
}
// Copy creates a deep copy of a TradeskillEvent.
func (te *TradeskillEvent) Copy() *TradeskillEvent {
if te == nil {
return nil
}
return &TradeskillEvent{
Name: te.Name,
Icon: te.Icon,
Technique: te.Technique,
SuccessProgress: te.SuccessProgress,
SuccessDurability: te.SuccessDurability,
SuccessHP: te.SuccessHP,
SuccessPower: te.SuccessPower,
SuccessSpellID: te.SuccessSpellID,
SuccessItemID: te.SuccessItemID,
FailProgress: te.FailProgress,
FailDurability: te.FailDurability,
FailHP: te.FailHP,
FailPower: te.FailPower,
}
}
// IsValidTechnique checks if the given technique ID is valid.
func IsValidTechnique(technique uint32) bool {
validTechniques := map[uint32]bool{
TechniqueSkillFletching: true,
TechniqueSkillTailoring: true,
TechniqueSkillTransmuting: true,
TechniqueSkillAlchemy: true,
TechniqueSkillScribing: true,
TechniqueSkillJewelcrafting: true,
TechniqueSkillProvisioning: true,
TechniqueSkillArtistry: true,
TechniqueSkillCarpentry: true,
TechniqueSkillMetalworking: true,
TechniqueSkillMetalshaping: true,
TechniqueSkillStoneworking: true,
}
return validTechniques[technique]
}
// IsComplete checks if the tradeskill session has completed successfully.
func (ts *Tradeskill) IsComplete() bool {
return ts.CurrentProgress >= MaxProgress
}
// IsFailed checks if the tradeskill session has failed (durability reached zero).
func (ts *Tradeskill) IsFailed() bool {
return ts.CurrentDurability <= MinDurability
}
// NeedsUpdate checks if the tradeskill session needs to be updated.
func (ts *Tradeskill) NeedsUpdate() bool {
return time.Now().After(ts.NextUpdateTime)
}
// Reset resets the tradeskill session to initial state.
func (ts *Tradeskill) Reset() {
ts.CurrentProgress = MinProgress
ts.CurrentDurability = MaxDurability
ts.CurrentEvent = nil
ts.EventChecked = false
ts.EventCountered = false
ts.UsedComponents = nil
ts.StartTime = time.Now()
ts.LastUpdate = time.Now()
ts.NextUpdateTime = time.Now().Add(CraftingUpdateInterval)
}