package recipes import ( "sync" ) // MasterRecipeBookList manages all recipe books in the system // Converted from C++ MasterRecipeBookList class type MasterRecipeBookList struct { recipeBooks map[int32]*Recipe // Book ID -> Recipe (represents recipe book) mutex sync.RWMutex stats *Statistics } // NewMasterRecipeBookList creates a new master recipe book list // Converted from C++ MasterRecipeBookList::MasterRecipeBookList constructor func NewMasterRecipeBookList() *MasterRecipeBookList { return &MasterRecipeBookList{ recipeBooks: make(map[int32]*Recipe), stats: NewStatistics(), } } // AddRecipeBook adds a recipe book to the master list // Converted from C++ MasterRecipeBookList::AddRecipeBook func (mrbl *MasterRecipeBookList) AddRecipeBook(recipe *Recipe) bool { if recipe == nil || recipe.BookID <= 0 { return false } mrbl.mutex.Lock() defer mrbl.mutex.Unlock() // Check for duplicate book ID if _, exists := mrbl.recipeBooks[recipe.BookID]; exists { return false } mrbl.recipeBooks[recipe.BookID] = recipe mrbl.stats.TotalRecipeBooks++ return true } // GetRecipeBook retrieves a recipe book by book ID // Converted from C++ MasterRecipeBookList::GetRecipeBooks func (mrbl *MasterRecipeBookList) GetRecipeBook(bookID int32) *Recipe { mrbl.mutex.RLock() defer mrbl.mutex.RUnlock() mrbl.stats.IncrementRecipeBookLookups() if recipe, exists := mrbl.recipeBooks[bookID]; exists { return recipe } return nil } // ClearRecipeBooks removes all recipe books from the master list // Converted from C++ MasterRecipeBookList::ClearRecipeBooks func (mrbl *MasterRecipeBookList) ClearRecipeBooks() { mrbl.mutex.Lock() defer mrbl.mutex.Unlock() mrbl.recipeBooks = make(map[int32]*Recipe) mrbl.stats.TotalRecipeBooks = 0 } // Size returns the total number of recipe books // Converted from C++ MasterRecipeBookList::Size func (mrbl *MasterRecipeBookList) Size() int32 { mrbl.mutex.RLock() defer mrbl.mutex.RUnlock() return int32(len(mrbl.recipeBooks)) } // GetAllRecipeBooks returns all recipe books func (mrbl *MasterRecipeBookList) GetAllRecipeBooks() map[int32]*Recipe { mrbl.mutex.RLock() defer mrbl.mutex.RUnlock() // Return a copy to prevent external modification result := make(map[int32]*Recipe) for id, recipe := range mrbl.recipeBooks { result[id] = recipe } return result } // GetStatistics returns a snapshot of the current statistics func (mrbl *MasterRecipeBookList) GetStatistics() Statistics { return mrbl.stats.GetSnapshot() } // PlayerRecipeList manages recipes for a specific player // Converted from C++ PlayerRecipeList class type PlayerRecipeList struct { recipes map[int32]*Recipe // Recipe ID -> Recipe mutex sync.RWMutex } // NewPlayerRecipeList creates a new player recipe list // Converted from C++ PlayerRecipeList::PlayerRecipeList constructor func NewPlayerRecipeList() *PlayerRecipeList { return &PlayerRecipeList{ recipes: make(map[int32]*Recipe), } } // AddRecipe adds a recipe to the player's list // Converted from C++ PlayerRecipeList::AddRecipe func (prl *PlayerRecipeList) AddRecipe(recipe *Recipe) bool { if recipe == nil || !recipe.IsValid() { return false } prl.mutex.Lock() defer prl.mutex.Unlock() // Check for duplicate ID if _, exists := prl.recipes[recipe.ID]; exists { return false } prl.recipes[recipe.ID] = recipe return true } // GetRecipe retrieves a recipe by ID from the player's list // Converted from C++ PlayerRecipeList::GetRecipe func (prl *PlayerRecipeList) GetRecipe(recipeID int32) *Recipe { prl.mutex.RLock() defer prl.mutex.RUnlock() if recipe, exists := prl.recipes[recipeID]; exists { return recipe } return nil } // RemoveRecipe removes a recipe from the player's list // Converted from C++ PlayerRecipeList::RemoveRecipe func (prl *PlayerRecipeList) RemoveRecipe(recipeID int32) bool { prl.mutex.Lock() defer prl.mutex.Unlock() if _, exists := prl.recipes[recipeID]; exists { delete(prl.recipes, recipeID) return true } return false } // ClearRecipes removes all recipes from the player's list // Converted from C++ PlayerRecipeList::ClearRecipes func (prl *PlayerRecipeList) ClearRecipes() { prl.mutex.Lock() defer prl.mutex.Unlock() prl.recipes = make(map[int32]*Recipe) } // Size returns the total number of recipes for this player // Converted from C++ PlayerRecipeList::Size func (prl *PlayerRecipeList) Size() int32 { prl.mutex.RLock() defer prl.mutex.RUnlock() return int32(len(prl.recipes)) } // GetRecipes returns all recipes for this player // Converted from C++ PlayerRecipeList::GetRecipes func (prl *PlayerRecipeList) GetRecipes() map[int32]*Recipe { prl.mutex.RLock() defer prl.mutex.RUnlock() // Return a copy to prevent external modification result := make(map[int32]*Recipe) for id, recipe := range prl.recipes { result[id] = recipe } return result } // GetRecipesBySkill returns recipes for a specific skill func (prl *PlayerRecipeList) GetRecipesBySkill(skillID int32) []*Recipe { prl.mutex.RLock() defer prl.mutex.RUnlock() var result []*Recipe for _, recipe := range prl.recipes { if recipe.Skill == skillID { result = append(result, recipe) } } return result } // GetRecipesByTier returns recipes for a specific tier func (prl *PlayerRecipeList) GetRecipesByTier(tier int8) []*Recipe { prl.mutex.RLock() defer prl.mutex.RUnlock() var result []*Recipe for _, recipe := range prl.recipes { if recipe.Tier == tier { result = append(result, recipe) } } return result } // PlayerRecipeBookList manages recipe books for a specific player // Converted from C++ PlayerRecipeBookList class type PlayerRecipeBookList struct { recipeBooks map[int32]*Recipe // Book ID -> Recipe mutex sync.RWMutex } // NewPlayerRecipeBookList creates a new player recipe book list // Converted from C++ PlayerRecipeBookList::PlayerRecipeBookList constructor func NewPlayerRecipeBookList() *PlayerRecipeBookList { return &PlayerRecipeBookList{ recipeBooks: make(map[int32]*Recipe), } } // AddRecipeBook adds a recipe book to the player's list // Converted from C++ PlayerRecipeBookList::AddRecipeBook func (prbl *PlayerRecipeBookList) AddRecipeBook(recipe *Recipe) bool { if recipe == nil || recipe.BookID <= 0 { return false } prbl.mutex.Lock() defer prbl.mutex.Unlock() // Check for duplicate book ID if _, exists := prbl.recipeBooks[recipe.BookID]; exists { return false } prbl.recipeBooks[recipe.BookID] = recipe return true } // GetRecipeBook retrieves a recipe book by book ID from the player's list // Converted from C++ PlayerRecipeBookList::GetRecipeBook func (prbl *PlayerRecipeBookList) GetRecipeBook(bookID int32) *Recipe { prbl.mutex.RLock() defer prbl.mutex.RUnlock() if recipe, exists := prbl.recipeBooks[bookID]; exists { return recipe } return nil } // HasRecipeBook checks if the player has a specific recipe book // Converted from C++ PlayerRecipeBookList::HasRecipeBook func (prbl *PlayerRecipeBookList) HasRecipeBook(bookID int32) bool { prbl.mutex.RLock() defer prbl.mutex.RUnlock() _, exists := prbl.recipeBooks[bookID] return exists } // ClearRecipeBooks removes all recipe books from the player's list // Converted from C++ PlayerRecipeBookList::ClearRecipeBooks func (prbl *PlayerRecipeBookList) ClearRecipeBooks() { prbl.mutex.Lock() defer prbl.mutex.Unlock() prbl.recipeBooks = make(map[int32]*Recipe) } // Size returns the total number of recipe books for this player func (prbl *PlayerRecipeBookList) Size() int32 { prbl.mutex.RLock() defer prbl.mutex.RUnlock() return int32(len(prbl.recipeBooks)) } // GetRecipeBooks returns all recipe books for this player // Converted from C++ PlayerRecipeBookList::GetRecipeBooks func (prbl *PlayerRecipeBookList) GetRecipeBooks() map[int32]*Recipe { prbl.mutex.RLock() defer prbl.mutex.RUnlock() // Return a copy to prevent external modification result := make(map[int32]*Recipe) for id, recipe := range prbl.recipeBooks { result[id] = recipe } return result }