-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprocessor.go
More file actions
161 lines (138 loc) · 4.77 KB
/
processor.go
File metadata and controls
161 lines (138 loc) · 4.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
package processor
import (
"fmt"
"log"
)
// Actor defines the interface for any entity that can participate in combat.
// This allows for flexible implementation of combatants, summoned creatures, environmental hazards, etc.
type Actor interface {
ID() string
IsAlive() bool
CurrentHP() int
MaxHP() int
TakeDamage(amount int)
Heal(amount int)
// Add any other core combatant behaviors here
}
// ActionType is an identifier for different kinds of actions.
type ActionType string
const (
ActionTypeAttack ActionType = "attack"
ActionTypeHeal ActionType = "heal"
ActionTypeMove ActionType = "move"
// Add more action types as needed
)
// Action defines the interface for any action that can be performed by an Actor.
// This allows for custom action logic without modifying the core processor.
type Action interface {
Type() ActionType
Name() string
Perform(processor *Processor, performer Actor, targets []Actor) error
// Add any other common action properties/behaviors
}
// BasicCombatant is a concrete implementation of the Actor interface.
type BasicCombatant struct {
CharacterID string
Health int
MaxHealth int
}
// NewBasicCombatant creates a new BasicCombatant instance.
func NewBasicCombatant(id string, hp int) *BasicCombatant {
return &BasicCombatant{
CharacterID: id,
Health: hp,
MaxHealth: hp,
}
}
func (c *BasicCombatant) ID() string { return c.CharacterID }
func (c *BasicCombatant) IsAlive() bool { return c.Health > 0 }
func (c *BasicCombatant) CurrentHP() int { return c.Health }
func (c *BasicCombatant) MaxHP() int { return c.MaxHealth }
func (c *BasicCombatant) TakeDamage(amount int) {
log.Printf("Combatant %s taking %d damage.", c.CharacterID, amount)
c.Health -= amount
if c.Health < 0 {
c.Health = 0
}
log.Printf("Combatant %s HP: %d/%d.", c.CharacterID, c.Health, c.MaxHealth)
}
func (c *BasicCombatant) Heal(amount int) {
log.Printf("Combatant %s healing %d.", c.CharacterID, amount)
c.Health += amount
if c.Health > c.MaxHealth {
c.Health = c.MaxHealth
}
log.Printf("Combatant %s HP: %d/%d.", c.CharacterID, c.Health, c.MaxHealth)
}
// BasicAttackAction is a concrete implementation of the Action interface for a simple attack.
type BasicAttackAction struct {
DamageAmount int
}
func (a *BasicAttackAction) Type() ActionType { return ActionTypeAttack }
func (a *BasicAttackAction) Name() string { return "Basic Attack" }
func (a *BasicAttackAction) Perform(processor *Processor, performer Actor, targets []Actor) error {
if !performer.IsAlive() {
return fmt.Errorf("performer %s is not alive and cannot perform action", performer.ID())
}
if len(targets) == 0 {
return fmt.Errorf("no targets specified for Basic Attack")
}
log.Printf("%s performs a Basic Attack (%d damage) on %v.", performer.ID(), a.DamageAmount, targets[0].ID())
// For simplicity, this basic attack only targets the first target
targets[0].TakeDamage(a.DamageAmount)
return nil
}
// Processor manages the turn-based combat state.
type Processor struct {
Actors []Actor
// currentTurn int
// actionQueue []ActionInstance
// eventBus *EventBus
}
// NewProcessor creates a new combat Processor.
func NewProcessor() *Processor {
return &Processor{
Actors: make([]Actor, 0),
}
}
// AddActor adds an Actor to the combat.
func (p *Processor) AddActor(actor Actor) {
p.Actors = append(p.Actors, actor)
log.Printf("Added actor: %s (HP: %d/%d)", actor.ID(), actor.CurrentHP(), actor.MaxHP())
}
// FindActorByID finds an actor in the processor by their ID.
func (p *Processor) FindActorByID(id string) Actor {
for _, actor := range p.Actors {
if actor.ID() == id {
return actor
}
}
return nil
}
// ProcessAction executes a given action.
func (p *Processor) ProcessAction(action Action, performer Actor, targets []Actor) error {
log.Printf("Processing action: %s by %s on %v", action.Name(), performer.ID(), func() []string { ids := make([]string, len(targets)); for i, t := range targets { ids[i] = t.ID() }; return ids }())
return action.Perform(p, performer, targets)
}
// GetAliveActors returns a slice of all actors that are currently alive.
func (p *Processor) GetAliveActors() []Actor {
aliveActors := make([]Actor, 0)
for _, actor := range p.Actors {
if actor.IsAlive() {
aliveActors = append(aliveActors, actor)
}
}
return aliveActors
}
// GetActorStatus provides a summary string for an actor's current status.
func (p *Processor) GetActorStatus(actor Actor) string {
if actor == nil {
return "Actor is nil"
}
status := ""
if !actor.IsAlive() {
status += "[DEAD] "
}
status += fmt.Sprintf("%s (HP: %d/%d)", actor.ID(), actor.CurrentHP(), actor.MaxHP())
return status
}