aboutsummaryrefslogtreecommitdiff
path: root/go/game/events.go
blob: f62e125a547412ebdef5e416a456b78641dc44c5 (plain)
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
package game

import (
	"fmt"

	"muhq.space/muhqs-game/go/log"
	"muhq.space/muhqs-game/go/utils"
)

type eventType int

const (
	destruction eventType = iota
	eot
	sacrifice
	play
	target
	etb
	damageDealt
	shuffle
	declaredAction
	resolvedAction
	discard
	phaseChange
)

var EventTypes = struct {
	Destruction    eventType
	Eot            eventType
	Sacrifice      eventType
	Play           eventType
	Target         eventType
	Etb            eventType
	DamageDealt    eventType
	Shuffle        eventType
	DeclaredAction eventType
	ResolvedAction eventType
	Discard        eventType
	PhaseChange    eventType
}{
	Destruction:    destruction,
	Eot:            eot,
	Sacrifice:      sacrifice,
	Play:           play,
	Target:         target,
	Etb:            etb,
	DamageDealt:    damageDealt,
	Shuffle:        shuffle,
	DeclaredAction: declaredAction,
	ResolvedAction: resolvedAction,
	Discard:        discard,
	PhaseChange:    phaseChange,
}

func (e eventType) String() string {
	switch e {
	case destruction:
		return "destruction"
	case eot:
		return "eot"
	case sacrifice:
		return "sacrifice"
	case play:
		return "play"
	case target:
		return "target"
	case etb:
		return "etb"
	case damageDealt:
		return "damageDealt"
	case shuffle:
		return "shuffle"
	case declaredAction:
		return "declaredAction"
	case resolvedAction:
		return "resolvedAction"
	case discard:
		return "discard"
	case phaseChange:
		return "phaseChange"
	}

	log.Panicf("Unknown eventType: %d", e)
	return ""
}

type Event struct {
	eventType eventType
	sources   []any
	affected  []any
}

func (e Event) String() string {
	if e.eventType == phaseChange {
		return fmt.Sprintf("%s", e.sources[0])
	}

	if len(e.sources) == 0 {
		return e.eventType.String()
	}

	return fmt.Sprintf("%v:%v", e.sources, e.eventType)
}

func newEotEvent() Event {
	return Event{eventType: eot}
}

func newTargetEvent(source any, targets *Targets) Event {
	affected := make([]any, 0, len(targets.ts))
	for _, t := range targets.ts {
		affected = append(affected, t.sel...)
	}
	return Event{eventType: target, sources: []any{source}, affected: affected}
}

func newShuffleEvent(p *Player, affected []PileOfCards) Event {
	return Event{
		eventType: shuffle,
		sources:   []any{p},
		affected:  utils.TypedSliceToInterfaceSlice(affected),
	}
}

func newDeclaredActionEvent(action Action) Event {
	return Event{eventType: declaredAction, sources: []any{action}}
}

func newResolvedActionEvent(action Action, err error) Event {
	return Event{
		eventType: resolvedAction,
		affected:  []any{action, err},
	}
}

func newPhaseChangeEvent(old, next PhaseType) Event {
	return Event{eventType: phaseChange, sources: []any{old}, affected: []any{next}}
}

func (s *LocalState) fireEvent(e Event) {
	log.Game(e)
	s.events = append(s.events, e)
}