fix transmute package
This commit is contained in:
parent
fa47af5ffe
commit
cc49aac689
@ -2,16 +2,16 @@ package transmute
|
||||
|
||||
// Item flags that disqualify items from transmutation
|
||||
const (
|
||||
NoZone = 1 << 0 // NO_ZONE flag
|
||||
NoValue = 1 << 1 // NO_VALUE flag
|
||||
Temporary = 1 << 2 // TEMPORARY flag
|
||||
NoDestroy = 1 << 3 // NO_DESTROY flag
|
||||
NoTransmute = 1 << 14 // NO_TRANSMUTE flag (16384)
|
||||
NoZone = int32(1 << 0) // NO_ZONE flag
|
||||
NoValue = int32(1 << 1) // NO_VALUE flag
|
||||
Temporary = int32(1 << 2) // TEMPORARY flag
|
||||
NoDestroy = int32(1 << 3) // NO_DESTROY flag
|
||||
NoTransmute = int32(1 << 14) // NO_TRANSMUTE flag (16384)
|
||||
)
|
||||
|
||||
// Item flags2 that disqualify items from transmutation
|
||||
const (
|
||||
Ornate = 1 << 0 // ORNATE flag
|
||||
Ornate = int32(1 << 0) // ORNATE flag
|
||||
)
|
||||
|
||||
// Item tiers/rarities
|
||||
|
@ -2,25 +2,49 @@ package transmute
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"eq2emu/internal/database"
|
||||
"zombiezen.com/go/sqlite"
|
||||
"zombiezen.com/go/sqlite/sqlitex"
|
||||
)
|
||||
|
||||
// DatabaseImpl provides a default implementation of the Database interface
|
||||
type DatabaseImpl struct {
|
||||
db *database.DB
|
||||
conn *sqlite.Conn
|
||||
}
|
||||
|
||||
// NewDatabase creates a new database implementation
|
||||
func NewDatabase(db *database.DB) *DatabaseImpl {
|
||||
return &DatabaseImpl{db: db}
|
||||
func NewDatabase(conn *sqlite.Conn) *DatabaseImpl {
|
||||
return &DatabaseImpl{conn: conn}
|
||||
}
|
||||
|
||||
// OpenDB opens a database connection for transmutation system
|
||||
func OpenDB(path string) (*DatabaseImpl, error) {
|
||||
conn, err := sqlite.OpenConn(path, sqlite.OpenReadWrite|sqlite.OpenCreate|sqlite.OpenWAL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open database: %w", err)
|
||||
}
|
||||
|
||||
// Enable foreign keys
|
||||
if err := sqlitex.ExecTransient(conn, "PRAGMA foreign_keys = ON;", nil); err != nil {
|
||||
conn.Close()
|
||||
return nil, fmt.Errorf("failed to enable foreign keys: %w", err)
|
||||
}
|
||||
|
||||
return &DatabaseImpl{conn: conn}, nil
|
||||
}
|
||||
|
||||
// Close closes the database connection
|
||||
func (dbi *DatabaseImpl) Close() error {
|
||||
if dbi.conn != nil {
|
||||
return dbi.conn.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LoadTransmutingTiers loads transmuting tiers from the database
|
||||
func (dbi *DatabaseImpl) LoadTransmutingTiers() ([]*TransmutingTier, error) {
|
||||
// Create transmuting_tiers table if it doesn't exist
|
||||
if err := dbi.db.Exec(`
|
||||
if err := sqlitex.ExecuteScript(dbi.conn, `
|
||||
CREATE TABLE IF NOT EXISTS transmuting_tiers (
|
||||
min_level INTEGER NOT NULL,
|
||||
max_level INTEGER NOT NULL,
|
||||
@ -31,20 +55,21 @@ func (dbi *DatabaseImpl) LoadTransmutingTiers() ([]*TransmutingTier, error) {
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (min_level, max_level)
|
||||
)
|
||||
`); err != nil {
|
||||
`, &sqlitex.ExecOptions{}); err != nil {
|
||||
return nil, fmt.Errorf("failed to create transmuting_tiers table: %w", err)
|
||||
}
|
||||
|
||||
// Check if table is empty and populate with default data
|
||||
var count int
|
||||
row, err := dbi.db.QueryRow("SELECT COUNT(*) FROM transmuting_tiers")
|
||||
var count int64
|
||||
err := sqlitex.Execute(dbi.conn, "SELECT COUNT(*) FROM transmuting_tiers", &sqlitex.ExecOptions{
|
||||
ResultFunc: func(stmt *sqlite.Stmt) error {
|
||||
count = stmt.ColumnInt64(0)
|
||||
return nil
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to count transmuting tiers: %w", err)
|
||||
}
|
||||
if row != nil {
|
||||
count = row.Int(0)
|
||||
row.Close()
|
||||
}
|
||||
|
||||
// If empty, populate with default EQ2 transmuting tiers
|
||||
if count == 0 {
|
||||
@ -55,19 +80,20 @@ func (dbi *DatabaseImpl) LoadTransmutingTiers() ([]*TransmutingTier, error) {
|
||||
|
||||
// Load all tiers from database
|
||||
var tiers []*TransmutingTier
|
||||
err = dbi.db.Query("SELECT min_level, max_level, fragment_id, powder_id, infusion_id, mana_id FROM transmuting_tiers ORDER BY min_level",
|
||||
func(row *database.Row) error {
|
||||
err = sqlitex.Execute(dbi.conn, "SELECT min_level, max_level, fragment_id, powder_id, infusion_id, mana_id FROM transmuting_tiers ORDER BY min_level", &sqlitex.ExecOptions{
|
||||
ResultFunc: func(stmt *sqlite.Stmt) error {
|
||||
tier := &TransmutingTier{
|
||||
MinLevel: int32(row.Int64(0)),
|
||||
MaxLevel: int32(row.Int64(1)),
|
||||
FragmentID: int32(row.Int64(2)),
|
||||
PowderID: int32(row.Int64(3)),
|
||||
InfusionID: int32(row.Int64(4)),
|
||||
ManaID: int32(row.Int64(5)),
|
||||
MinLevel: int32(stmt.ColumnInt64(0)),
|
||||
MaxLevel: int32(stmt.ColumnInt64(1)),
|
||||
FragmentID: int32(stmt.ColumnInt64(2)),
|
||||
PowderID: int32(stmt.ColumnInt64(3)),
|
||||
InfusionID: int32(stmt.ColumnInt64(4)),
|
||||
ManaID: int32(stmt.ColumnInt64(5)),
|
||||
}
|
||||
tiers = append(tiers, tier)
|
||||
return nil
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load transmuting tiers: %w", err)
|
||||
@ -94,19 +120,26 @@ func (dbi *DatabaseImpl) populateDefaultTiers() error {
|
||||
{90, 100, 1037, 1038, 1039, 1040},
|
||||
}
|
||||
|
||||
return dbi.db.Transaction(func(txDB *database.DB) error {
|
||||
for _, tier := range defaultTiers {
|
||||
err := txDB.Exec(`
|
||||
INSERT INTO transmuting_tiers (min_level, max_level, fragment_id, powder_id, infusion_id, mana_id)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
`, tier.minLevel, tier.maxLevel, tier.fragmentID, tier.powderID, tier.infusionID, tier.manaID)
|
||||
// Use transaction for atomic inserts
|
||||
endFn, err := sqlitex.ImmediateTransaction(dbi.conn)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to start transaction: %w", err)
|
||||
}
|
||||
defer endFn(&err)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to insert tier %d-%d: %w", tier.minLevel, tier.maxLevel, err)
|
||||
}
|
||||
for _, tier := range defaultTiers {
|
||||
err = sqlitex.Execute(dbi.conn, `
|
||||
INSERT INTO transmuting_tiers (min_level, max_level, fragment_id, powder_id, infusion_id, mana_id)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
`, &sqlitex.ExecOptions{
|
||||
Args: []any{tier.minLevel, tier.maxLevel, tier.fragmentID, tier.powderID, tier.infusionID, tier.manaID},
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to insert tier %d-%d: %w", tier.minLevel, tier.maxLevel, err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO: When integrating with a real database system, replace this with actual database queries
|
||||
@ -167,10 +200,12 @@ func (dbi *DatabaseImpl) SaveTransmutingTier(tier *TransmutingTier) error {
|
||||
return fmt.Errorf("all material IDs must be positive")
|
||||
}
|
||||
|
||||
err := dbi.db.Exec(`
|
||||
err := sqlitex.Execute(dbi.conn, `
|
||||
INSERT OR REPLACE INTO transmuting_tiers (min_level, max_level, fragment_id, powder_id, infusion_id, mana_id)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
`, tier.MinLevel, tier.MaxLevel, tier.FragmentID, tier.PowderID, tier.InfusionID, tier.ManaID)
|
||||
`, &sqlitex.ExecOptions{
|
||||
Args: []any{tier.MinLevel, tier.MaxLevel, tier.FragmentID, tier.PowderID, tier.InfusionID, tier.ManaID},
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to save transmuting tier %d-%d: %w", tier.MinLevel, tier.MaxLevel, err)
|
||||
@ -185,7 +220,9 @@ func (dbi *DatabaseImpl) DeleteTransmutingTier(minLevel, maxLevel int32) error {
|
||||
return fmt.Errorf("invalid level range: %d-%d", minLevel, maxLevel)
|
||||
}
|
||||
|
||||
err := dbi.db.Exec("DELETE FROM transmuting_tiers WHERE min_level = ? AND max_level = ?", minLevel, maxLevel)
|
||||
err := sqlitex.Execute(dbi.conn, "DELETE FROM transmuting_tiers WHERE min_level = ? AND max_level = ?", &sqlitex.ExecOptions{
|
||||
Args: []any{minLevel, maxLevel},
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete transmuting tier %d-%d: %w", minLevel, maxLevel, err)
|
||||
}
|
||||
@ -195,26 +232,31 @@ func (dbi *DatabaseImpl) DeleteTransmutingTier(minLevel, maxLevel int32) error {
|
||||
|
||||
// GetTransmutingTierByLevel gets a specific transmuting tier by level range
|
||||
func (dbi *DatabaseImpl) GetTransmutingTierByLevel(itemLevel int32) (*TransmutingTier, error) {
|
||||
row, err := dbi.db.QueryRow("SELECT min_level, max_level, fragment_id, powder_id, infusion_id, mana_id FROM transmuting_tiers WHERE min_level <= ? AND max_level >= ?", itemLevel, itemLevel)
|
||||
var tier *TransmutingTier
|
||||
|
||||
err := sqlitex.Execute(dbi.conn, "SELECT min_level, max_level, fragment_id, powder_id, infusion_id, mana_id FROM transmuting_tiers WHERE min_level <= ? AND max_level >= ?", &sqlitex.ExecOptions{
|
||||
Args: []any{itemLevel, itemLevel},
|
||||
ResultFunc: func(stmt *sqlite.Stmt) error {
|
||||
tier = &TransmutingTier{
|
||||
MinLevel: int32(stmt.ColumnInt64(0)),
|
||||
MaxLevel: int32(stmt.ColumnInt64(1)),
|
||||
FragmentID: int32(stmt.ColumnInt64(2)),
|
||||
PowderID: int32(stmt.ColumnInt64(3)),
|
||||
InfusionID: int32(stmt.ColumnInt64(4)),
|
||||
ManaID: int32(stmt.ColumnInt64(5)),
|
||||
}
|
||||
return nil
|
||||
},
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to query transmuting tier for level %d: %w", itemLevel, err)
|
||||
}
|
||||
|
||||
if row == nil {
|
||||
if tier == nil {
|
||||
return nil, fmt.Errorf("no transmuting tier found for level %d", itemLevel)
|
||||
}
|
||||
|
||||
defer row.Close()
|
||||
|
||||
tier := &TransmutingTier{
|
||||
MinLevel: int32(row.Int64(0)),
|
||||
MaxLevel: int32(row.Int64(1)),
|
||||
FragmentID: int32(row.Int64(2)),
|
||||
PowderID: int32(row.Int64(3)),
|
||||
InfusionID: int32(row.Int64(4)),
|
||||
ManaID: int32(row.Int64(5)),
|
||||
}
|
||||
|
||||
return tier, nil
|
||||
}
|
||||
|
||||
@ -237,12 +279,14 @@ func (dbi *DatabaseImpl) UpdateTransmutingTier(oldMinLevel, oldMaxLevel int32, n
|
||||
return fmt.Errorf("all material IDs must be positive")
|
||||
}
|
||||
|
||||
err := dbi.db.Exec(`
|
||||
err := sqlitex.Execute(dbi.conn, `
|
||||
UPDATE transmuting_tiers
|
||||
SET min_level=?, max_level=?, fragment_id=?, powder_id=?, infusion_id=?, mana_id=?
|
||||
WHERE min_level=? AND max_level=?
|
||||
`, newTier.MinLevel, newTier.MaxLevel, newTier.FragmentID, newTier.PowderID,
|
||||
newTier.InfusionID, newTier.ManaID, oldMinLevel, oldMaxLevel)
|
||||
`, &sqlitex.ExecOptions{
|
||||
Args: []any{newTier.MinLevel, newTier.MaxLevel, newTier.FragmentID, newTier.PowderID,
|
||||
newTier.InfusionID, newTier.ManaID, oldMinLevel, oldMaxLevel},
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update transmuting tier %d-%d: %w", oldMinLevel, oldMaxLevel, err)
|
||||
@ -252,21 +296,20 @@ func (dbi *DatabaseImpl) UpdateTransmutingTier(oldMinLevel, oldMaxLevel int32, n
|
||||
}
|
||||
|
||||
// TransmutingTierExists checks if a transmuting tier exists for the given level range
|
||||
func (db *DatabaseImpl) TransmutingTierExists(minLevel, maxLevel int32) (bool, error) {
|
||||
// Placeholder implementation
|
||||
// In a real implementation:
|
||||
// SELECT COUNT(*) FROM transmuting WHERE min_level = ? AND max_level = ?
|
||||
|
||||
tiers, err := db.LoadTransmutingTiers()
|
||||
func (dbi *DatabaseImpl) TransmutingTierExists(minLevel, maxLevel int32) (bool, error) {
|
||||
var count int64
|
||||
|
||||
err := sqlitex.Execute(dbi.conn, "SELECT COUNT(*) FROM transmuting_tiers WHERE min_level = ? AND max_level = ?", &sqlitex.ExecOptions{
|
||||
Args: []any{minLevel, maxLevel},
|
||||
ResultFunc: func(stmt *sqlite.Stmt) error {
|
||||
count = stmt.ColumnInt64(0)
|
||||
return nil
|
||||
},
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return false, err
|
||||
return false, fmt.Errorf("failed to check tier existence: %w", err)
|
||||
}
|
||||
|
||||
for _, tier := range tiers {
|
||||
if tier.MinLevel == minLevel && tier.MaxLevel == maxLevel {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
return false, nil
|
||||
return count > 0, nil
|
||||
}
|
||||
|
1257
internal/transmute/transmute_test.go
Normal file
1257
internal/transmute/transmute_test.go
Normal file
File diff suppressed because it is too large
Load Diff
@ -31,8 +31,8 @@ const (
|
||||
// TransmuteResult represents the outcome of a transmutation
|
||||
type TransmuteResult struct {
|
||||
Success bool // Whether transmutation was successful
|
||||
CommonMaterial *Item // Common material received (if any)
|
||||
RareMaterial *Item // Rare material received (if any)
|
||||
CommonMaterial Item // Common material received (if any)
|
||||
RareMaterial Item // Rare material received (if any)
|
||||
ErrorMessage string // Error message if unsuccessful
|
||||
SkillIncrease bool // Whether player received skill increase
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user