eq2go/internal/housing/README.md

266 lines
7.8 KiB
Markdown

# 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