338 lines
11 KiB
Go
338 lines
11 KiB
Go
package recipes
|
|
|
|
import "eq2emu/internal/database"
|
|
|
|
// RecipeSystemAdapter provides integration interfaces for the recipe system
|
|
// Enables seamless integration with player, database, item, and client systems
|
|
type RecipeSystemAdapter interface {
|
|
// Player Integration
|
|
GetPlayerRecipeList(characterID int32) *PlayerRecipeList
|
|
GetPlayerRecipeBookList(characterID int32) *PlayerRecipeBookList
|
|
LoadPlayerRecipes(characterID int32) error
|
|
LoadPlayerRecipeBooks(characterID int32) error
|
|
|
|
// Recipe Management
|
|
GetRecipe(recipeID int32) *Recipe
|
|
GetRecipeBook(bookID int32) *Recipe
|
|
ValidateRecipe(recipe *Recipe) bool
|
|
CanPlayerUseRecipe(characterID int32, recipeID int32) bool
|
|
|
|
// Progress Tracking
|
|
UpdateRecipeProgress(characterID int32, recipeID int32, stage int8) error
|
|
GetRecipeProgress(characterID int32, recipeID int32) int8
|
|
|
|
// System Operations
|
|
GetStatistics() RecipeManagerStats
|
|
Validate() []string
|
|
Size() (recipes int32, recipeBooks int32)
|
|
}
|
|
|
|
// DatabaseRecipeAdapter handles database operations for recipes
|
|
// Abstracts database interactions for easier testing and multiple database support
|
|
type DatabaseRecipeAdapter interface {
|
|
// Recipe Loading
|
|
LoadAllRecipes() ([]*Recipe, error)
|
|
LoadAllRecipeBooks() ([]*Recipe, error)
|
|
LoadRecipeComponents(recipeID int32) (map[int8][]int32, error)
|
|
|
|
// Player Recipe Operations
|
|
LoadPlayerRecipes(characterID int32) ([]*Recipe, error)
|
|
LoadPlayerRecipeBooks(characterID int32) ([]*Recipe, error)
|
|
SavePlayerRecipe(characterID int32, recipeID int32) error
|
|
SavePlayerRecipeBook(characterID int32, recipebookID int32) error
|
|
UpdatePlayerRecipe(characterID int32, recipeID int32, highestStage int8) error
|
|
|
|
// Validation and Utilities
|
|
RecipeExists(recipeID int32) bool
|
|
RecipeBookExists(bookID int32) bool
|
|
GetRecipesByTier(tier int8) ([]*Recipe, error)
|
|
GetRecipesBySkill(skillID int32) ([]*Recipe, error)
|
|
}
|
|
|
|
// PlayerRecipeAdapter integrates with player management systems
|
|
// Provides player-specific recipe functionality and validation
|
|
type PlayerRecipeAdapter interface {
|
|
// Player Validation
|
|
PlayerExists(characterID int32) bool
|
|
GetPlayerLevel(characterID int32) int32
|
|
GetPlayerTradeskillLevel(characterID int32, skillID int32) int32
|
|
GetPlayerClass(characterID int32) int8
|
|
|
|
// Recipe Access Control
|
|
CanPlayerLearnRecipe(characterID int32, recipeID int32) bool
|
|
CanPlayerUseRecipeBook(characterID int32, bookID int32) bool
|
|
HasPlayerLearnedRecipe(characterID int32, recipeID int32) bool
|
|
HasPlayerRecipeBook(characterID int32, bookID int32) bool
|
|
|
|
// Experience and Progression
|
|
AwardTradeskillExperience(characterID int32, skillID int32, experience int32) error
|
|
UpdateTradeskillLevel(characterID int32, skillID int32, level int32) error
|
|
|
|
// Notifications
|
|
NotifyRecipeLearned(characterID int32, recipeID int32) error
|
|
NotifyRecipeBookObtained(characterID int32, bookID int32) error
|
|
}
|
|
|
|
// ItemRecipeAdapter integrates with item management systems
|
|
// Handles item-related recipe operations and validation
|
|
type ItemRecipeAdapter interface {
|
|
// Item Validation
|
|
ItemExists(itemID int32) bool
|
|
GetItemName(itemID int32) string
|
|
GetItemIcon(itemID int32) int16
|
|
GetItemLevel(itemID int32) int32
|
|
IsItemTradeskillTool(itemID int32) bool
|
|
|
|
// Recipe Component Validation
|
|
ValidateRecipeComponents(recipeID int32) bool
|
|
GetComponentItemName(itemID int32) string
|
|
GetComponentQuantityRequired(recipeID int32, itemID int32) int16
|
|
|
|
// Inventory Integration
|
|
PlayerHasComponents(characterID int32, recipeID int32) bool
|
|
ConsumeRecipeComponents(characterID int32, recipeID int32) error
|
|
AwardRecipeProduct(characterID int32, itemID int32, quantity int8) error
|
|
|
|
// Recipe Book Items
|
|
IsRecipeBookItem(itemID int32) bool
|
|
GetRecipeBookRecipes(bookID int32) ([]int32, error)
|
|
ConsumeRecipeBook(characterID int32, bookID int32) error
|
|
}
|
|
|
|
// ClientRecipeAdapter handles client communication for recipes
|
|
// Manages packet building and client-side recipe display
|
|
type ClientRecipeAdapter interface {
|
|
// Recipe Display
|
|
SendRecipeList(characterID int32) error
|
|
SendRecipeBookList(characterID int32) error
|
|
SendRecipeDetails(characterID int32, recipeID int32) error
|
|
|
|
// Recipe Learning
|
|
SendRecipeLearned(characterID int32, recipeID int32) error
|
|
SendRecipeBookObtained(characterID int32, bookID int32) error
|
|
SendRecipeProgress(characterID int32, recipeID int32, stage int8) error
|
|
|
|
// Tradeskill Interface
|
|
SendTradeskillWindow(characterID int32, deviceID int32) error
|
|
SendRecipeComponents(characterID int32, recipeID int32) error
|
|
SendCraftingResults(characterID int32, success bool, itemID int32, quantity int8) error
|
|
|
|
// Error Messages
|
|
SendRecipeError(characterID int32, errorMessage string) error
|
|
SendInsufficientComponents(characterID int32, recipeID int32) error
|
|
SendInvalidRecipe(characterID int32, recipeID int32) error
|
|
}
|
|
|
|
// EventRecipeAdapter handles recipe-related event processing
|
|
// Manages recipe learning, crafting events, and system notifications
|
|
type EventRecipeAdapter interface {
|
|
// Recipe Events
|
|
OnRecipeLearned(characterID int32, recipeID int32) error
|
|
OnRecipeBookObtained(characterID int32, bookID int32) error
|
|
OnRecipeCrafted(characterID int32, recipeID int32, success bool) error
|
|
OnCraftingStarted(characterID int32, recipeID int32) error
|
|
OnCraftingCompleted(characterID int32, recipeID int32, stage int8) error
|
|
|
|
// Achievement Integration
|
|
CheckCraftingAchievements(characterID int32, recipeID int32) error
|
|
UpdateCraftingStatistics(characterID int32, recipeID int32, success bool) error
|
|
|
|
// Guild Integration
|
|
NotifyGuildCrafting(characterID int32, recipeID int32) error
|
|
UpdateGuildCraftingContributions(characterID int32, recipeID int32) error
|
|
}
|
|
|
|
// RecipeAware interface for entities that can interact with recipes
|
|
// Provides basic recipe interaction capabilities for players and NPCs
|
|
type RecipeAware interface {
|
|
// Recipe Knowledge
|
|
GetKnownRecipes() []int32
|
|
GetRecipeBooks() []int32
|
|
KnowsRecipe(recipeID int32) bool
|
|
HasRecipeBook(bookID int32) bool
|
|
|
|
// Recipe Learning
|
|
LearnRecipe(recipeID int32) error
|
|
ObtainRecipeBook(bookID int32) error
|
|
ForgetRecipe(recipeID int32) error
|
|
|
|
// Crafting Capabilities
|
|
CanCraftRecipe(recipeID int32) bool
|
|
GetCraftingLevel(skillID int32) int32
|
|
GetMaxCraftingStage(recipeID int32) int8
|
|
}
|
|
|
|
// CraftingRecipeAdapter integrates with crafting system
|
|
// Handles active crafting sessions and recipe execution
|
|
type CraftingRecipeAdapter interface {
|
|
// Crafting Session Management
|
|
StartCraftingSession(characterID int32, recipeID int32, deviceID int32) error
|
|
ProcessCraftingStage(characterID int32, stage int8) error
|
|
CompleteCraftingSession(characterID int32, success bool) error
|
|
CancelCraftingSession(characterID int32) error
|
|
|
|
// Crafting Validation
|
|
ValidateCraftingDevice(deviceID int32, recipeID int32) bool
|
|
ValidateCraftingComponents(characterID int32, recipeID int32) bool
|
|
ValidateCraftingSkill(characterID int32, recipeID int32) bool
|
|
|
|
// Progress Tracking
|
|
GetCraftingProgress(characterID int32) (recipeID int32, stage int8, success bool)
|
|
UpdateCraftingStage(characterID int32, stage int8) error
|
|
|
|
// Resource Management
|
|
ConsumeCraftingResources(characterID int32, recipeID int32, stage int8) error
|
|
AwardCraftingProducts(characterID int32, recipeID int32, stage int8) error
|
|
CalculateCraftingSuccess(characterID int32, recipeID int32, stage int8) bool
|
|
}
|
|
|
|
// RecipeSystemDependencies aggregates all recipe system dependencies
|
|
// Provides a single interface for system-wide recipe functionality
|
|
type RecipeSystemDependencies struct {
|
|
Database DatabaseRecipeAdapter
|
|
Player PlayerRecipeAdapter
|
|
Item ItemRecipeAdapter
|
|
Client ClientRecipeAdapter
|
|
Event EventRecipeAdapter
|
|
Crafting CraftingRecipeAdapter
|
|
RecipeSystem RecipeSystemAdapter
|
|
}
|
|
|
|
// RecipeManagerAdapter provides high-level recipe management operations
|
|
// Simplifies recipe system access for external systems
|
|
type RecipeManagerAdapter struct {
|
|
manager *RecipeManager
|
|
dependencies *RecipeSystemDependencies
|
|
}
|
|
|
|
// NewRecipeManagerAdapter creates a new recipe manager adapter with dependencies
|
|
func NewRecipeManagerAdapter(db *database.DB, deps *RecipeSystemDependencies) *RecipeManagerAdapter {
|
|
return &RecipeManagerAdapter{
|
|
manager: NewRecipeManager(db),
|
|
dependencies: deps,
|
|
}
|
|
}
|
|
|
|
// GetManager returns the underlying recipe manager
|
|
func (rma *RecipeManagerAdapter) GetManager() *RecipeManager {
|
|
return rma.manager
|
|
}
|
|
|
|
// GetDependencies returns the system dependencies
|
|
func (rma *RecipeManagerAdapter) GetDependencies() *RecipeSystemDependencies {
|
|
return rma.dependencies
|
|
}
|
|
|
|
// Initialize loads all recipes and recipe books from the database
|
|
func (rma *RecipeManagerAdapter) Initialize() error {
|
|
if err := rma.manager.LoadRecipes(); err != nil {
|
|
return err
|
|
}
|
|
return rma.manager.LoadRecipeBooks()
|
|
}
|
|
|
|
// PlayerLearnRecipe handles complete recipe learning workflow
|
|
func (rma *RecipeManagerAdapter) PlayerLearnRecipe(characterID int32, recipeID int32) error {
|
|
// Validate recipe exists
|
|
recipe := rma.manager.GetRecipe(recipeID)
|
|
if recipe == nil {
|
|
return ErrRecipeNotFound
|
|
}
|
|
|
|
// Check player can learn recipe
|
|
if rma.dependencies.Player != nil {
|
|
if !rma.dependencies.Player.CanPlayerLearnRecipe(characterID, recipeID) {
|
|
return ErrCannotLearnRecipe
|
|
}
|
|
}
|
|
|
|
// Save recipe to database
|
|
if err := rma.manager.SavePlayerRecipe(characterID, recipeID); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Notify client
|
|
if rma.dependencies.Client != nil {
|
|
if err := rma.dependencies.Client.SendRecipeLearned(characterID, recipeID); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// Fire event
|
|
if rma.dependencies.Event != nil {
|
|
return rma.dependencies.Event.OnRecipeLearned(characterID, recipeID)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// PlayerObtainRecipeBook handles complete recipe book acquisition workflow
|
|
func (rma *RecipeManagerAdapter) PlayerObtainRecipeBook(characterID int32, bookID int32) error {
|
|
// Validate recipe book exists
|
|
book := rma.manager.GetRecipeBook(bookID)
|
|
if book == nil {
|
|
return ErrRecipeBookNotFound
|
|
}
|
|
|
|
// Check player can use recipe book
|
|
if rma.dependencies.Player != nil {
|
|
if !rma.dependencies.Player.CanPlayerUseRecipeBook(characterID, bookID) {
|
|
return ErrCannotUseRecipeBook
|
|
}
|
|
}
|
|
|
|
// Save recipe book to database
|
|
if err := rma.manager.SavePlayerRecipeBook(characterID, bookID); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Consume recipe book item
|
|
if rma.dependencies.Item != nil {
|
|
if err := rma.dependencies.Item.ConsumeRecipeBook(characterID, bookID); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// Notify client
|
|
if rma.dependencies.Client != nil {
|
|
if err := rma.dependencies.Client.SendRecipeBookObtained(characterID, bookID); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// Fire event
|
|
if rma.dependencies.Event != nil {
|
|
return rma.dependencies.Event.OnRecipeBookObtained(characterID, bookID)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// ValidateRecipeSystem performs comprehensive system validation
|
|
func (rma *RecipeManagerAdapter) ValidateRecipeSystem() []string {
|
|
issues := rma.manager.Validate()
|
|
|
|
// Add dependency validation
|
|
if rma.dependencies == nil {
|
|
issues = append(issues, "recipe system dependencies not configured")
|
|
return issues
|
|
}
|
|
|
|
if rma.dependencies.Database == nil {
|
|
issues = append(issues, "database adapter not configured")
|
|
}
|
|
|
|
if rma.dependencies.Player == nil {
|
|
issues = append(issues, "player adapter not configured")
|
|
}
|
|
|
|
if rma.dependencies.Item == nil {
|
|
issues = append(issues, "item adapter not configured")
|
|
}
|
|
|
|
if rma.dependencies.Client == nil {
|
|
issues = append(issues, "client adapter not configured")
|
|
}
|
|
|
|
return issues
|
|
} |