aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fischer@muhq.space>2024-03-25 18:27:29 +0100
committerFlorian Fischer <florian.fischer@muhq.space>2025-08-20 15:57:10 +0200
commitc8b2b38cd43c2a54b02a19637e45660a39fe8d1b (patch)
tree556959eb4471c464e14d630da5041728e90853ef
parentb23404015416016d0a4896505cd4f08c0c334e75 (diff)
downloadmuhqs-game-c8b2b38cd43c2a54b02a19637e45660a39fe8d1b.tar.gz
muhqs-game-c8b2b38cd43c2a54b02a19637e45660a39fe8d1b.zip
add new trigger and event implementations
-rw-r--r--go/game/trigger.go86
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)
+}