diff options
| author | Florian Fischer <florian.fischer@muhq.space> | 2024-03-25 18:27:29 +0100 |
|---|---|---|
| committer | Florian Fischer <florian.fischer@muhq.space> | 2025-08-20 15:57:10 +0200 |
| commit | c8b2b38cd43c2a54b02a19637e45660a39fe8d1b (patch) | |
| tree | 556959eb4471c464e14d630da5041728e90853ef | |
| parent | b23404015416016d0a4896505cd4f08c0c334e75 (diff) | |
| download | muhqs-game-c8b2b38cd43c2a54b02a19637e45660a39fe8d1b.tar.gz muhqs-game-c8b2b38cd43c2a54b02a19637e45660a39fe8d1b.zip | |
add new trigger and event implementations
| -rw-r--r-- | go/game/trigger.go | 86 |
1 files changed, 78 insertions, 8 deletions
diff --git a/go/game/trigger.go b/go/game/trigger.go index 8fe4ae89..4af863e5 100644 --- a/go/game/trigger.go +++ b/go/game/trigger.go @@ -3,6 +3,8 @@ package game import ( "fmt" "log" + + "golang.org/x/exp/slices" ) type eventType int @@ -12,6 +14,8 @@ const ( eot sacrifice play + target + etb ) var EventTypes = struct { @@ -19,10 +23,15 @@ var EventTypes = struct { Eot eventType Sacrifice eventType Play eventType + Target eventType + Etb eventType }{ Destruction: destruction, Eot: eot, + Sacrifice: sacrifice, Play: play, + Target: target, + Etb: etb, } func (e eventType) String() string { @@ -35,15 +44,20 @@ func (e eventType) String() string { return "sacrifice" case play: return "play" + case target: + return "target" + case etb: + return "etb" } - log.Panicf("Unknown evenType", e) + log.Panicf("Unknown evenType: %d", e) return "" } type Event struct { eventType eventType sources []interface{} + affected []interface{} } func (e Event) String() string { @@ -58,26 +72,44 @@ func newEotEvent() Event { return Event{eventType: eot} } +func newTargetEvent(source interface{}, targets *Targets) Event { + affected := make([]interface{}, 0, len(targets.ts)) + for _, t := range targets.ts { + for _, sel := range t.sel { + affected = append(affected, sel) + } + } + return Event{eventType: target, sources: []interface{}{source}, affected: affected} +} + type Trigger interface { - Card() *Card + Source() interface{} String() string + Card() *Card trigger(*State, Event) ([]*TriggeredAction, bool) } type triggerBase struct { - card *Card + source interface{} condition func(*State, Event) (bool, bool) resolveFunc ActionResolveFunc costFunc ActionCostFunc desc string } +func (t *triggerBase) Source() interface{} { return t.source } +func (t *triggerBase) String() string { return t.desc } func (t *triggerBase) Card() *Card { - return t.card -} - -func (t *triggerBase) String() string { - return t.desc + switch t := t.source.(type) { + case *Card: + return t + case Permanent: + return t.Card() + default: + log.Panicf("Unhandled source type %v", t) + return nil + } + return nil } func (t *triggerBase) trigger(s *State, e Event) ([]*TriggeredAction, bool) { @@ -88,3 +120,41 @@ func (t *triggerBase) trigger(s *State, e Event) ([]*TriggeredAction, bool) { return []*TriggeredAction{newTriggeredAction(e, t, t.resolveFunc, t.costFunc)}, remove } + +func newTargetedTrigger(p Permanent, singleshot bool, resolveFunc ActionResolveFunc, desc string) Trigger { + t := triggerBase{source: p, resolveFunc: resolveFunc, desc: desc} + t.condition = func(_ *State, event Event) (bool, bool) { + c := event.eventType == EventTypes.Target && + slices.Contains(event.affected, p.(interface{})) + remove := singleshot && c + return c, remove + } + return &t +} + +func newDeathTrigger(p Permanent, singleshot bool, resolveFunc ActionResolveFunc, permCond func(Permanent) bool, desc string) Trigger { + t := triggerBase{source: p, resolveFunc: resolveFunc, desc: desc} + t.condition = func(_ *State, event Event) (bool, bool) { + if !(event.eventType == EventTypes.Sacrifice || event.eventType == EventTypes.Destruction) { + return false, false + } + destroyedPerm := event.affected[0].(Permanent) + + c := permCond(destroyedPerm) + remove := singleshot && c + return c, remove + } + return &t +} + +func newOwnDeathTrigger(p Permanent, resolveFunc ActionResolveFunc, desc string) Trigger { + return newDeathTrigger(p, true, resolveFunc, func(destroyedPerm Permanent) bool { + return p == destroyedPerm + }, desc) +} + +func newEnemyDeathTrigger(p Permanent, resolveFunc ActionResolveFunc, desc string) Trigger { + return newDeathTrigger(p, true, resolveFunc, func(destroyedPerm Permanent) bool { + return p.Controller().IsEnemy(destroyedPerm.Controller()) + }, desc) +} |
