220 lines
6.4 KiB
Go
220 lines
6.4 KiB
Go
package factions
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"eq2emu/internal/database"
|
|
)
|
|
|
|
// LoadAllFactions loads all factions from the database
|
|
func LoadAllFactions(db *database.Database) ([]*Faction, error) {
|
|
// Create factions table if it doesn't exist
|
|
_, err := db.Exec(`
|
|
CREATE TABLE IF NOT EXISTS factions (
|
|
id INTEGER PRIMARY KEY,
|
|
name TEXT NOT NULL,
|
|
type TEXT,
|
|
description TEXT,
|
|
negative_change INTEGER DEFAULT 0,
|
|
positive_change INTEGER DEFAULT 0,
|
|
default_value INTEGER DEFAULT 0
|
|
)
|
|
`)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to create factions table: %w", err)
|
|
}
|
|
|
|
rows, err := db.Query("SELECT id, name, type, description, negative_change, positive_change, default_value FROM factions")
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to load factions: %w", err)
|
|
}
|
|
defer rows.Close()
|
|
|
|
var factions []*Faction
|
|
for rows.Next() {
|
|
faction := &Faction{
|
|
db: db,
|
|
isNew: false,
|
|
}
|
|
|
|
err := rows.Scan(&faction.ID, &faction.Name, &faction.Type, &faction.Description,
|
|
&faction.NegativeChange, &faction.PositiveChange, &faction.DefaultValue)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to scan faction: %w", err)
|
|
}
|
|
|
|
factions = append(factions, faction)
|
|
}
|
|
|
|
if err = rows.Err(); err != nil {
|
|
return nil, fmt.Errorf("error iterating factions: %w", err)
|
|
}
|
|
|
|
return factions, nil
|
|
}
|
|
|
|
// LoadFactionRelations loads faction relationships from the database
|
|
func LoadFactionRelations(db *database.Database) (map[int32][]int32, map[int32][]int32, error) {
|
|
// Create faction_relations table if it doesn't exist
|
|
_, err := db.Exec(`
|
|
CREATE TABLE IF NOT EXISTS faction_relations (
|
|
faction_id INTEGER NOT NULL,
|
|
related_faction_id INTEGER NOT NULL,
|
|
is_hostile INTEGER NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (faction_id, related_faction_id),
|
|
FOREIGN KEY (faction_id) REFERENCES factions(id),
|
|
FOREIGN KEY (related_faction_id) REFERENCES factions(id)
|
|
)
|
|
`)
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("failed to create faction_relations table: %w", err)
|
|
}
|
|
|
|
hostile := make(map[int32][]int32)
|
|
friendly := make(map[int32][]int32)
|
|
|
|
rows, err := db.Query("SELECT faction_id, related_faction_id, is_hostile FROM faction_relations")
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("failed to load faction relations: %w", err)
|
|
}
|
|
defer rows.Close()
|
|
|
|
for rows.Next() {
|
|
var factionID, relatedID int32
|
|
var isHostile bool
|
|
|
|
if err := rows.Scan(&factionID, &relatedID, &isHostile); err != nil {
|
|
return nil, nil, fmt.Errorf("failed to scan faction relation: %w", err)
|
|
}
|
|
|
|
if isHostile {
|
|
hostile[factionID] = append(hostile[factionID], relatedID)
|
|
} else {
|
|
friendly[factionID] = append(friendly[factionID], relatedID)
|
|
}
|
|
}
|
|
|
|
if err = rows.Err(); err != nil {
|
|
return nil, nil, fmt.Errorf("error iterating faction relations: %w", err)
|
|
}
|
|
|
|
return hostile, friendly, nil
|
|
}
|
|
|
|
// SaveFactionRelation saves a faction relationship to the database
|
|
func SaveFactionRelation(db *database.Database, factionID, relatedFactionID int32, isHostile bool) error {
|
|
hostileFlag := 0
|
|
if isHostile {
|
|
hostileFlag = 1
|
|
}
|
|
|
|
_, err := db.Exec(`
|
|
INSERT OR REPLACE INTO faction_relations (faction_id, related_faction_id, is_hostile)
|
|
VALUES (?, ?, ?)
|
|
`, factionID, relatedFactionID, hostileFlag)
|
|
|
|
if err != nil {
|
|
return fmt.Errorf("failed to save faction relation %d -> %d: %w", factionID, relatedFactionID, err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// DeleteFactionRelation deletes a faction relationship from the database
|
|
func DeleteFactionRelation(db *database.Database, factionID, relatedFactionID int32, isHostile bool) error {
|
|
hostileFlag := 0
|
|
if isHostile {
|
|
hostileFlag = 1
|
|
}
|
|
|
|
_, err := db.Exec("DELETE FROM faction_relations WHERE faction_id = ? AND related_faction_id = ? AND is_hostile = ?",
|
|
factionID, relatedFactionID, hostileFlag)
|
|
|
|
if err != nil {
|
|
return fmt.Errorf("failed to delete faction relation %d -> %d: %w", factionID, relatedFactionID, err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// LoadPlayerFactions loads player faction values from the database
|
|
func LoadPlayerFactions(db *database.Database, playerID int32) (map[int32]int32, error) {
|
|
// Create player_factions table if it doesn't exist
|
|
_, err := db.Exec(`
|
|
CREATE TABLE IF NOT EXISTS player_factions (
|
|
player_id INTEGER NOT NULL,
|
|
faction_id INTEGER NOT NULL,
|
|
faction_value INTEGER NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (player_id, faction_id),
|
|
FOREIGN KEY (faction_id) REFERENCES factions(id)
|
|
)
|
|
`)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to create player_factions table: %w", err)
|
|
}
|
|
|
|
factionValues := make(map[int32]int32)
|
|
rows, err := db.Query("SELECT faction_id, faction_value FROM player_factions WHERE player_id = ?", playerID)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to load player factions for player %d: %w", playerID, err)
|
|
}
|
|
defer rows.Close()
|
|
|
|
for rows.Next() {
|
|
var factionID, factionValue int32
|
|
if err := rows.Scan(&factionID, &factionValue); err != nil {
|
|
return nil, fmt.Errorf("failed to scan player faction: %w", err)
|
|
}
|
|
factionValues[factionID] = factionValue
|
|
}
|
|
|
|
if err = rows.Err(); err != nil {
|
|
return nil, fmt.Errorf("error iterating player factions: %w", err)
|
|
}
|
|
|
|
return factionValues, nil
|
|
}
|
|
|
|
// SavePlayerFaction saves a player's faction value to the database
|
|
func SavePlayerFaction(db *database.Database, playerID, factionID, factionValue int32) error {
|
|
_, err := db.Exec(`
|
|
INSERT OR REPLACE INTO player_factions (player_id, faction_id, faction_value)
|
|
VALUES (?, ?, ?)
|
|
`, playerID, factionID, factionValue)
|
|
|
|
if err != nil {
|
|
return fmt.Errorf("failed to save player faction %d/%d: %w", playerID, factionID, err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// SaveAllPlayerFactions saves all faction values for a player
|
|
func SaveAllPlayerFactions(db *database.Database, playerID int32, factionValues map[int32]int32) error {
|
|
tx, err := db.Begin()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to begin transaction: %w", err)
|
|
}
|
|
defer tx.Rollback()
|
|
|
|
// Clear existing faction values for this player
|
|
_, err = tx.Exec("DELETE FROM player_factions WHERE player_id = ?", playerID)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to clear player factions: %w", err)
|
|
}
|
|
|
|
// Insert all current faction values
|
|
for factionID, factionValue := range factionValues {
|
|
_, err = tx.Exec(`
|
|
INSERT INTO player_factions (player_id, faction_id, faction_value)
|
|
VALUES (?, ?, ?)
|
|
`, playerID, factionID, factionValue)
|
|
|
|
if err != nil {
|
|
return fmt.Errorf("failed to insert player faction %d/%d: %w", playerID, factionID, err)
|
|
}
|
|
}
|
|
|
|
return tx.Commit()
|
|
}
|