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 } // StatisticsSnapshot represents a snapshot of statistics without mutex type StatisticsSnapshot struct { TotalRecipes int32 TotalRecipeBooks int32 RecipesByTier map[int8]int32 RecipesBySkill map[int32]int32 RecipeLookups int64 RecipeBookLookups int64 PlayerRecipeLoads int64 ComponentQueries int64 } // 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() StatisticsSnapshot { s.mutex.RLock() defer s.mutex.RUnlock() snapshot := StatisticsSnapshot{ 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 }