# Housing Package The housing package provides a complete housing system for EverQuest II servers, allowing players to purchase, manage, and customize their in-game homes. ## Overview This package implements a streamlined housing system with three core components: - **House**: Represents purchasable house types/zones with costs and requirements - **CharacterHouse**: Represents houses owned by specific characters - **HousingManager**: Orchestrates all housing operations including purchases, upkeep, and packet communication ## Features ### House Management - Multiple house types with different costs, requirements, and features - Alignment and guild level restrictions - Vault storage slots and exit coordinates - Configurable costs in coins and status points ### Character Houses - Individual house ownership tracking - Upkeep payment system with automatic processing - House settings (name, visit permissions, notes) - Access control lists for other players - Item placement and management - Transaction history tracking ### System Features - Automatic upkeep processing with configurable grace periods - Foreclosure system for unpaid upkeep - Maximum house limits per player - Integrated packet building for client communication - Database persistence with MySQL support - Comprehensive logging and error handling ## Usage ### Basic Setup ```go import "eq2emu/internal/housing" // Create housing manager logger := &MyLogger{} // Implement housing.Logger interface config := housing.HousingConfig{ EnableUpkeep: true, EnableForeclosure: true, UpkeepGracePeriod: 7 * 24 * 3600, // 7 days in seconds MaxHousesPerPlayer: 10, EnableStatistics: true, } hm := housing.NewHousingManager(db, logger, config) // Initialize and load house data ctx := context.Background() if err := hm.Initialize(ctx); err != nil { log.Fatal("Failed to initialize housing:", err) } ``` ### House Purchase Flow ```go // Player wants to purchase house type 1 playerManager := &MyPlayerManager{} // Implement housing.PlayerManager interface characterID := int32(12345) houseTypeID := int32(1) house, err := hm.PurchaseHouse(ctx, characterID, houseTypeID, playerManager) if err != nil { // Handle purchase error (insufficient funds, requirements not met, etc.) return err } // House purchased successfully fmt.Printf("Player %d purchased house %s", characterID, house.Settings.HouseName) ``` ### Upkeep Management ```go // Pay upkeep for a specific house houseUniqueID := int64(98765) err := hm.PayUpkeep(ctx, houseUniqueID, playerManager) if err != nil { // Handle upkeep payment error return err } // Automatic upkeep processing runs in background // No manual intervention needed ``` ### Packet Communication ```go // Send house purchase UI to client house, exists := hm.GetHouse(houseTypeID) if exists { err := hm.SendHousePurchasePacket(characterID, clientVersion, house) // Packet sent to client } // Send player's house list to client err := hm.SendCharacterHousesPacket(characterID, clientVersion) // Housing list packet sent to client ``` ## Architecture ### Core Types - **House**: Static house type definitions loaded from database - **CharacterHouse**: Player-owned house instances with settings and history - **HousingManager**: Central coordinator for all housing operations ### Database Integration The housing system integrates with MySQL databases using the centralized database package: ```sql -- House type definitions character_house_zones (id, name, cost_coins, cost_status, ...) -- Player house instances character_houses (unique_id, char_id, house_id, upkeep_due, ...) ``` ### Packet Integration Integrates with the centralized packet system using XML-driven packet definitions: - Uses `packets.GetPacket()` to load packet definitions - Builds packets with `packets.NewPacketBuilder()` - Supports multiple client versions automatically ## Configuration ### HousingConfig Options - `EnableUpkeep`: Enable automatic upkeep processing - `EnableForeclosure`: Allow foreclosure of houses with overdue upkeep - `UpkeepGracePeriod`: Grace period in seconds before foreclosure - `MaxHousesPerPlayer`: Maximum houses per character - `EnableStatistics`: Enable housing statistics tracking ### House Types House types are configured in the database with these properties: - **Cost**: Coin and status point requirements - **Upkeep**: Weekly maintenance costs - **Alignment**: Good/Evil/Neutral/Any restrictions - **Guild Level**: Minimum guild level required - **Vault Slots**: Number of storage slots provided - **Zone Info**: Location and exit coordinates ## Constants The package provides extensive constants for: - **House Types**: Cottage, Mansion, Keep, etc. - **Access Levels**: Owner, Friend, Visitor, Guild Member - **Transaction Types**: Purchase, Upkeep, Deposit, etc. - **Permission Flags**: Enter, Place Items, Vault Access, etc. - **Status Codes**: Active, Upkeep Due, Foreclosed, etc. See `constants.go` for complete listings and default values. ## Interfaces ### Logger Interface Implement this interface to provide logging: ```go type Logger interface { LogInfo(system, format string, args ...interface{}) LogError(system, format string, args ...interface{}) LogDebug(system, format string, args ...interface{}) LogWarning(system, format string, args ...interface{}) } ``` ### PlayerManager Interface Implement this interface to integrate with player systems: ```go type PlayerManager interface { CanPlayerAffordHouse(characterID int32, coinCost, statusCost int64) (bool, error) DeductPlayerCoins(characterID int32, amount int64) error DeductPlayerStatus(characterID int32, amount int64) error GetPlayerAlignment(characterID int32) (int8, error) GetPlayerGuildLevel(characterID int32) (int8, error) } ``` ## Utility Functions ### Currency Formatting ```go housing.FormatCurrency(15250) // Returns "1g 52s 50c" housing.FormatCurrency(1000) // Returns "10s" housing.FormatCurrency(50) // Returns "50c" ``` ### Upkeep Date Formatting ```go housing.FormatUpkeepDue(time.Now().Add(24 * time.Hour)) // "Due in 1 days" housing.FormatUpkeepDue(time.Now().Add(-24 * time.Hour)) // "Overdue (1 days)" ``` ## Testing The package includes comprehensive tests with mock implementations: ```bash go test ./internal/housing/ -v ``` Tests cover: - House and CharacterHouse creation - Purchase validation (funds, alignment, guild level) - Upkeep processing and foreclosure - Packet building integration - Currency and date formatting - Full system integration scenarios ## Error Handling The housing system provides detailed error codes and messages: - `HouseErrorInsufficientFunds`: Player cannot afford purchase/upkeep - `HouseErrorAlignmentRestriction`: Player alignment doesn't meet requirements - `HouseErrorGuildLevelRestriction`: Player guild level too low - `HouseErrorMaxHousesReached`: Player at house limit - `HouseErrorHouseNotFound`: Invalid house type requested See `constants.go` for complete error code definitions. ## Performance The housing system is designed for efficiency: - **In-Memory Caching**: House types and character houses cached in memory - **Lazy Loading**: Character houses loaded on first access - **Background Processing**: Upkeep processing runs asynchronously - **Optimized Queries**: Direct SQL queries without ORM overhead - **Minimal Allocations**: Reuses data structures where possible ## Thread Safety All housing operations are thread-safe: - `sync.RWMutex` protects shared data structures - Database operations use connection pooling - Concurrent access to houses is properly synchronized ## Future Enhancements Potential areas for extension: - House decoration and furniture systems - Guild halls with special permissions - Real estate marketplace for player trading - Rental system for temporary housing - Advanced statistics and reporting - Integration with crafting systems