264 lines
5.9 KiB
Go

package fightlogs
import (
"fmt"
"strings"
"time"
"dk/internal/database"
)
// FightLog represents a single action in a fight
type FightLog struct {
ID int
FightID int
Type int
Data int
Name string
Created int64
}
// Action type constants
const (
ActionAttackHit = 1
ActionAttackMiss = 2
ActionSpellHeal = 3
ActionSpellHurt = 4
ActionRunSuccess = 5
ActionRunFail = 6
ActionGeneric = 7
ActionMonsterAttack = 8
ActionMonsterMiss = 9
ActionMonsterSpell = 10
ActionMonsterDeath = 11
)
// New creates a new FightLog with sensible defaults
func New(fightID int) *FightLog {
return &FightLog{
FightID: fightID,
Type: ActionGeneric,
Data: 0,
Name: "",
Created: time.Now().Unix(),
}
}
// Validate checks if fight log has valid values
func (fl *FightLog) Validate() error {
if fl.FightID <= 0 {
return fmt.Errorf("fight log FightID must be positive")
}
if fl.Created <= 0 {
return fmt.Errorf("fight log Created timestamp must be positive")
}
return nil
}
// CRUD operations
func (fl *FightLog) Delete() error {
return database.Exec("DELETE FROM fight_logs WHERE id = %d", fl.ID)
}
func (fl *FightLog) Insert() error {
id, err := database.Insert("fight_logs", fl, "ID")
if err != nil {
return err
}
fl.ID = int(id)
return nil
}
// Query functions
func Find(id int) (*FightLog, error) {
var log FightLog
err := database.Get(&log, "SELECT * FROM fight_logs WHERE id = %d", id)
if err != nil {
return nil, fmt.Errorf("fight log with ID %d not found", id)
}
return &log, nil
}
func ByFightID(fightID int) ([]*FightLog, error) {
var logs []*FightLog
err := database.Select(&logs, "SELECT * FROM fight_logs WHERE fight_id = %d ORDER BY created ASC, id ASC", fightID)
return logs, err
}
func DeleteByFightID(fightID int) error {
return database.Exec("DELETE FROM fight_logs WHERE fight_id = %d", fightID)
}
// Helper functions for adding different types of actions
func AddAction(fightID int, action string) error {
log := &FightLog{
FightID: fightID,
Type: ActionGeneric,
Name: action,
Created: time.Now().Unix(),
}
return log.Insert()
}
func AddAttackHit(fightID, damage int) error {
log := &FightLog{
FightID: fightID,
Type: ActionAttackHit,
Data: damage,
Created: time.Now().Unix(),
}
return log.Insert()
}
func AddAttackMiss(fightID int) error {
log := &FightLog{
FightID: fightID,
Type: ActionAttackMiss,
Created: time.Now().Unix(),
}
return log.Insert()
}
func AddSpellHeal(fightID int, spellName string, healAmount int) error {
log := &FightLog{
FightID: fightID,
Type: ActionSpellHeal,
Data: healAmount,
Name: spellName,
Created: time.Now().Unix(),
}
return log.Insert()
}
func AddSpellHurt(fightID int, spellName string, damage int) error {
log := &FightLog{
FightID: fightID,
Type: ActionSpellHurt,
Data: damage,
Name: spellName,
Created: time.Now().Unix(),
}
return log.Insert()
}
func AddRunSuccess(fightID int) error {
log := &FightLog{
FightID: fightID,
Type: ActionRunSuccess,
Created: time.Now().Unix(),
}
return log.Insert()
}
func AddRunFail(fightID int) error {
log := &FightLog{
FightID: fightID,
Type: ActionRunFail,
Created: time.Now().Unix(),
}
return log.Insert()
}
func AddMonsterAttack(fightID int, monsterName string, damage int) error {
log := &FightLog{
FightID: fightID,
Type: ActionMonsterAttack,
Data: damage,
Name: monsterName,
Created: time.Now().Unix(),
}
return log.Insert()
}
func AddMonsterMiss(fightID int, monsterName string) error {
log := &FightLog{
FightID: fightID,
Type: ActionMonsterMiss,
Name: monsterName,
Created: time.Now().Unix(),
}
return log.Insert()
}
func AddMonsterSpell(fightID int, monsterName, spellName string, damage int) error {
log := &FightLog{
FightID: fightID,
Type: ActionMonsterSpell,
Data: damage,
Name: monsterName + "|" + spellName,
Created: time.Now().Unix(),
}
return log.Insert()
}
func AddMonsterDeath(fightID int, monsterName string) error {
log := &FightLog{
FightID: fightID,
Type: ActionMonsterDeath,
Name: monsterName,
Created: time.Now().Unix(),
}
return log.Insert()
}
// Convert logs to human-readable strings
func GetActions(fightID int) ([]string, error) {
logs, err := ByFightID(fightID)
if err != nil {
return nil, err
}
result := make([]string, len(logs))
for i, log := range logs {
result[i] = log.ToString()
}
return result, nil
}
func GetLastAction(fightID int) (string, error) {
var log FightLog
err := database.Get(&log, "SELECT * FROM fight_logs WHERE fight_id = %d ORDER BY created DESC, id DESC LIMIT 1", fightID)
if err != nil {
return "", nil // No logs found
}
return log.ToString(), nil
}
// Helper methods
func (fl *FightLog) CreatedTime() time.Time {
return time.Unix(fl.Created, 0)
}
func (fl *FightLog) ToString() string {
switch fl.Type {
case ActionAttackHit:
return fmt.Sprintf("You attacked for %d damage!", fl.Data)
case ActionAttackMiss:
return "You missed your attack!"
case ActionSpellHeal:
return fmt.Sprintf("You cast %s and healed %d HP!", fl.Name, fl.Data)
case ActionSpellHurt:
return fmt.Sprintf("You cast %s and dealt %d damage!", fl.Name, fl.Data)
case ActionRunSuccess:
return "You successfully ran away!"
case ActionRunFail:
return "You failed to run away!"
case ActionGeneric:
return fl.Name
case ActionMonsterAttack:
return fmt.Sprintf("%s attacks for %d damage!", fl.Name, fl.Data)
case ActionMonsterMiss:
return fmt.Sprintf("%s missed its attack!", fl.Name)
case ActionMonsterSpell:
parts := strings.Split(fl.Name, "|")
if len(parts) == 2 {
return fmt.Sprintf("%s casts %s for %d damage!", parts[0], parts[1], fl.Data)
}
return fmt.Sprintf("%s casts a spell for %d damage!", fl.Name, fl.Data)
case ActionMonsterDeath:
return fmt.Sprintf("%s has been defeated!", fl.Name)
default:
return "Unknown action"
}
}