264 lines
5.9 KiB
Go
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"
|
|
}
|
|
}
|