250 lines
6.3 KiB
Go
250 lines
6.3 KiB
Go
package ground_spawn
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"eq2emu/internal/database"
|
|
)
|
|
|
|
// DatabaseAdapter implements the Database interface using the internal database wrapper
|
|
type DatabaseAdapter struct {
|
|
db *database.DB
|
|
}
|
|
|
|
// NewDatabaseAdapter creates a new database adapter using the database wrapper
|
|
func NewDatabaseAdapter(db *database.DB) *DatabaseAdapter {
|
|
return &DatabaseAdapter{
|
|
db: db,
|
|
}
|
|
}
|
|
|
|
// LoadGroundSpawnEntries loads harvest entries for a ground spawn
|
|
func (da *DatabaseAdapter) LoadGroundSpawnEntries(groundspawnID int32) ([]*GroundSpawnEntry, error) {
|
|
query := `
|
|
SELECT min_skill_level, min_adventure_level, bonus_table, harvest_1, harvest_3,
|
|
harvest_5, harvest_imbue, harvest_rare, harvest_10, harvest_coin
|
|
FROM groundspawn_entries
|
|
WHERE groundspawn_id = ?
|
|
ORDER BY min_skill_level ASC
|
|
`
|
|
|
|
var entries []*GroundSpawnEntry
|
|
|
|
err := da.db.Query(query, func(row *database.Row) error {
|
|
entry := &GroundSpawnEntry{}
|
|
var bonusTable int32
|
|
|
|
entry.MinSkillLevel = int16(row.Int(0))
|
|
entry.MinAdventureLevel = int16(row.Int(1))
|
|
bonusTable = int32(row.Int(2))
|
|
entry.Harvest1 = float32(row.Float(3))
|
|
entry.Harvest3 = float32(row.Float(4))
|
|
entry.Harvest5 = float32(row.Float(5))
|
|
entry.HarvestImbue = float32(row.Float(6))
|
|
entry.HarvestRare = float32(row.Float(7))
|
|
entry.Harvest10 = float32(row.Float(8))
|
|
entry.HarvestCoin = float32(row.Float(9))
|
|
|
|
entry.BonusTable = bonusTable == 1
|
|
entries = append(entries, entry)
|
|
|
|
return nil
|
|
}, groundspawnID)
|
|
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to query groundspawn entries: %w", err)
|
|
}
|
|
|
|
return entries, nil
|
|
}
|
|
|
|
// LoadGroundSpawnItems loads harvest items for a ground spawn
|
|
func (da *DatabaseAdapter) LoadGroundSpawnItems(groundspawnID int32) ([]*GroundSpawnEntryItem, error) {
|
|
query := `
|
|
SELECT item_id, is_rare, grid_id, quantity
|
|
FROM groundspawn_items
|
|
WHERE groundspawn_id = ?
|
|
ORDER BY item_id ASC
|
|
`
|
|
|
|
var items []*GroundSpawnEntryItem
|
|
|
|
err := da.db.Query(query, func(row *database.Row) error {
|
|
item := &GroundSpawnEntryItem{}
|
|
|
|
item.ItemID = int32(row.Int(0))
|
|
item.IsRare = int8(row.Int(1))
|
|
item.GridID = int32(row.Int(2))
|
|
item.Quantity = int16(row.Int(3))
|
|
|
|
items = append(items, item)
|
|
|
|
return nil
|
|
}, groundspawnID)
|
|
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to query groundspawn items: %w", err)
|
|
}
|
|
|
|
return items, nil
|
|
}
|
|
|
|
// SaveGroundSpawn saves a ground spawn to the database
|
|
func (da *DatabaseAdapter) SaveGroundSpawn(gs *GroundSpawn) error {
|
|
if gs == nil {
|
|
return fmt.Errorf("ground spawn cannot be nil")
|
|
}
|
|
|
|
query := `
|
|
INSERT OR REPLACE INTO groundspawns (
|
|
id, name, x, y, z, heading, respawn_timer, collection_skill,
|
|
number_harvests, attempts_per_harvest, groundspawn_entry_id,
|
|
randomize_heading, zone_id, created_at, updated_at
|
|
)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, datetime('now'), datetime('now'))
|
|
`
|
|
|
|
randomizeHeading := 0
|
|
if gs.GetRandomizeHeading() {
|
|
randomizeHeading = 1
|
|
}
|
|
|
|
// TODO: Get actual zone ID from spawn
|
|
zoneID := int32(1)
|
|
|
|
err := da.db.Exec(query,
|
|
gs.GetID(),
|
|
gs.GetName(),
|
|
gs.GetX(),
|
|
gs.GetY(),
|
|
gs.GetZ(),
|
|
int16(gs.GetHeading()),
|
|
300, // Default 5 minutes respawn timer
|
|
gs.GetCollectionSkill(),
|
|
gs.GetNumberHarvests(),
|
|
gs.GetAttemptsPerHarvest(),
|
|
gs.GetGroundSpawnEntryID(),
|
|
randomizeHeading,
|
|
zoneID,
|
|
)
|
|
|
|
if err != nil {
|
|
return fmt.Errorf("failed to save ground spawn %d: %w", gs.GetID(), err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// LoadAllGroundSpawns loads all ground spawns from the database
|
|
func (da *DatabaseAdapter) LoadAllGroundSpawns() ([]*GroundSpawn, error) {
|
|
query := `
|
|
SELECT id, name, x, y, z, heading, collection_skill, number_harvests,
|
|
attempts_per_harvest, groundspawn_entry_id, randomize_heading
|
|
FROM groundspawns
|
|
WHERE zone_id = ?
|
|
ORDER BY id ASC
|
|
`
|
|
|
|
// TODO: Support multiple zones
|
|
zoneID := int32(1)
|
|
|
|
var groundSpawns []*GroundSpawn
|
|
|
|
err := da.db.Query(query, func(row *database.Row) error {
|
|
id := int32(row.Int(0))
|
|
name := row.Text(1)
|
|
x := float32(row.Float(2))
|
|
y := float32(row.Float(3))
|
|
z := float32(row.Float(4))
|
|
heading := float32(row.Float(5))
|
|
collectionSkill := row.Text(6)
|
|
numberHarvests := int8(row.Int(7))
|
|
attemptsPerHarvest := int8(row.Int(8))
|
|
groundspawnEntryID := int32(row.Int(9))
|
|
randomizeHeading := int32(row.Int(10))
|
|
|
|
config := GroundSpawnConfig{
|
|
GroundSpawnID: groundspawnEntryID,
|
|
CollectionSkill: collectionSkill,
|
|
NumberHarvests: numberHarvests,
|
|
AttemptsPerHarvest: attemptsPerHarvest,
|
|
RandomizeHeading: randomizeHeading == 1,
|
|
Location: SpawnLocation{
|
|
X: x,
|
|
Y: y,
|
|
Z: z,
|
|
Heading: heading,
|
|
GridID: 1, // TODO: Load from database
|
|
},
|
|
Name: name,
|
|
Description: fmt.Sprintf("A %s node", collectionSkill),
|
|
}
|
|
|
|
gs := NewGroundSpawn(config)
|
|
gs.SetID(id)
|
|
|
|
groundSpawns = append(groundSpawns, gs)
|
|
|
|
return nil
|
|
}, zoneID)
|
|
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to query groundspawns: %w", err)
|
|
}
|
|
|
|
return groundSpawns, nil
|
|
}
|
|
|
|
// DeleteGroundSpawn deletes a ground spawn from the database
|
|
func (da *DatabaseAdapter) DeleteGroundSpawn(id int32) error {
|
|
query := `DELETE FROM groundspawns WHERE id = ?`
|
|
|
|
err := da.db.Exec(query, id)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to delete ground spawn %d: %w", id, err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// LoadPlayerHarvestStatistics loads harvest statistics for a player
|
|
func (da *DatabaseAdapter) LoadPlayerHarvestStatistics(playerID int32) (map[string]int64, error) {
|
|
query := `
|
|
SELECT skill_name, harvest_count
|
|
FROM player_harvest_stats
|
|
WHERE player_id = ?
|
|
`
|
|
|
|
stats := make(map[string]int64)
|
|
|
|
err := da.db.Query(query, func(row *database.Row) error {
|
|
skillName := row.Text(0)
|
|
harvestCount := row.Int64(1)
|
|
|
|
stats[skillName] = harvestCount
|
|
|
|
return nil
|
|
}, playerID)
|
|
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to query player harvest stats: %w", err)
|
|
}
|
|
|
|
return stats, nil
|
|
}
|
|
|
|
// SavePlayerHarvestStatistic saves a player's harvest statistic
|
|
func (da *DatabaseAdapter) SavePlayerHarvestStatistic(playerID int32, skillName string, count int64) error {
|
|
query := `
|
|
INSERT OR REPLACE INTO player_harvest_stats (player_id, skill_name, harvest_count, updated_at)
|
|
VALUES (?, ?, ?, datetime('now'))
|
|
`
|
|
|
|
err := da.db.Exec(query, playerID, skillName, count)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to save player harvest stat: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|