163 lines
3.8 KiB
Go

package recipes
import (
"sync"
)
// RecipeComponent represents a component required for crafting
// Converted from C++ RecipeComp struct
type RecipeComponent struct {
ItemID int32
Slot int8
}
// RecipeProducts represents the products and byproducts for a crafting stage
// Converted from C++ RecipeProducts struct
type RecipeProducts struct {
ProductID int32
ByproductID int32
ProductQty int8
ByproductQty int8
}
// Recipe represents a crafting recipe in EverQuest II
// Converted from C++ Recipe class
type Recipe struct {
// Core recipe data
ID int32
SoeID int32 // SOE recipe ID (CRC)
BookID int32
Name string
Description string
BookName string
Book string
Device string
// Recipe requirements and properties
Level int8
Tier int8
Icon int16
Skill int32
Technique int32
Knowledge int32
Classes int32 // Bitmask of tradeskill classes
DeviceSubType int8
// Unknown fields from C++ (preserved for compatibility)
Unknown1 int8
Unknown2 int32
Unknown3 int32
Unknown4 int32
// Product information
ProductItemID int32
ProductName string
ProductQty int8
// Component titles
PrimaryBuildCompTitle string
Build1CompTitle string
Build2CompTitle string
Build3CompTitle string
Build4CompTitle string
FuelCompTitle string
// Component quantities
Build1CompQty int16
Build2CompQty int16
Build3CompQty int16
Build4CompQty int16
FuelCompQty int16
PrimaryCompQty int16
// Highest completed stage for player recipes
HighestStage int8
// Components map: slot -> list of item IDs
// Slots: 0=primary, 1-4=build slots, 5=fuel
Components map[int8][]int32
// Products map: stage -> products/byproducts
// Stages: 0-4 (5 total stages)
Products map[int8]*RecipeProducts
// Thread safety
mutex sync.RWMutex
}
// Statistics tracks recipe system usage patterns
type Statistics struct {
TotalRecipes int32
TotalRecipeBooks int32
RecipesByTier map[int8]int32
RecipesBySkill map[int32]int32
RecipeLookups int64
RecipeBookLookups int64
PlayerRecipeLoads int64
ComponentQueries int64
mutex sync.RWMutex
}
// NewStatistics creates a new statistics tracker
func NewStatistics() *Statistics {
return &Statistics{
RecipesByTier: make(map[int8]int32),
RecipesBySkill: make(map[int32]int32),
}
}
// IncrementRecipeLookups increments the recipe lookup counter
func (s *Statistics) IncrementRecipeLookups() {
s.mutex.Lock()
defer s.mutex.Unlock()
s.RecipeLookups++
}
// IncrementRecipeBookLookups increments the recipe book lookup counter
func (s *Statistics) IncrementRecipeBookLookups() {
s.mutex.Lock()
defer s.mutex.Unlock()
s.RecipeBookLookups++
}
// IncrementPlayerRecipeLoads increments the player recipe load counter
func (s *Statistics) IncrementPlayerRecipeLoads() {
s.mutex.Lock()
defer s.mutex.Unlock()
s.PlayerRecipeLoads++
}
// IncrementComponentQueries increments the component query counter
func (s *Statistics) IncrementComponentQueries() {
s.mutex.Lock()
defer s.mutex.Unlock()
s.ComponentQueries++
}
// GetSnapshot returns a snapshot of the current statistics
func (s *Statistics) GetSnapshot() Statistics {
s.mutex.RLock()
defer s.mutex.RUnlock()
snapshot := Statistics{
TotalRecipes: s.TotalRecipes,
TotalRecipeBooks: s.TotalRecipeBooks,
RecipesByTier: make(map[int8]int32),
RecipesBySkill: make(map[int32]int32),
RecipeLookups: s.RecipeLookups,
RecipeBookLookups: s.RecipeBookLookups,
PlayerRecipeLoads: s.PlayerRecipeLoads,
ComponentQueries: s.ComponentQueries,
}
for tier, count := range s.RecipesByTier {
snapshot.RecipesByTier[tier] = count
}
for skill, count := range s.RecipesBySkill {
snapshot.RecipesBySkill[skill] = count
}
return snapshot
}