From 488f6377e6f6fd3099bb927a986d548fbc1eb63f Mon Sep 17 00:00:00 2001 From: Florian Fischer Date: Fri, 15 Aug 2025 20:52:55 +0200 Subject: implement mace and add damage dealt events/triggers --- go/game/trigger.go | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 85 insertions(+), 6 deletions(-) (limited to 'go/game/trigger.go') diff --git a/go/game/trigger.go b/go/game/trigger.go index 34caf9b1..b061ea78 100644 --- a/go/game/trigger.go +++ b/go/game/trigger.go @@ -5,6 +5,8 @@ import ( "log" "golang.org/x/exp/slices" + + "muhq.space/muhqs-game/go/utils" ) type eventType int @@ -16,6 +18,7 @@ const ( play target etb + damageDealt ) var EventTypes = struct { @@ -25,6 +28,7 @@ var EventTypes = struct { Play eventType Target eventType Etb eventType + DamageDealt eventType }{ Destruction: destruction, Eot: eot, @@ -32,6 +36,7 @@ var EventTypes = struct { Play: play, Target: target, Etb: etb, + DamageDealt: damageDealt, } func (e eventType) String() string { @@ -48,6 +53,8 @@ func (e eventType) String() string { return "target" case etb: return "etb" + case damageDealt: + return "damageDealt" } log.Panicf("Unknown evenType: %d", e) @@ -80,6 +87,11 @@ func newTargetEvent(source any, targets *Targets) Event { return Event{eventType: target, sources: []any{source}, affected: affected} } +func (s *LocalState) fireEvent(e Event) { + log.Println("fire event:", e) + s.events = append(s.events, e) +} + type Trigger interface { Source() any String() string @@ -90,7 +102,7 @@ type Trigger interface { type triggerBase struct { source any condition func(*LocalState, Event) (bool, bool) - resolveFunc ActionResolveFunc + resolveFunc func(*LocalState, Event) ActionResolveFunc costFunc ActionCostFunc desc string } @@ -115,10 +127,10 @@ func (t *triggerBase) trigger(s *LocalState, e Event) ([]*TriggeredAction, bool) return nil, remove } - return []*TriggeredAction{newTriggeredAction(e, t, t.resolveFunc, t.costFunc)}, remove + return []*TriggeredAction{newTriggeredAction(e, t, t.resolveFunc(s, e), t.costFunc)}, remove } -func newTargetedTrigger(p Permanent, singleshot bool, resolveFunc ActionResolveFunc, desc string) Trigger { +func newTargetedTrigger(p Permanent, singleshot bool, resolveFunc func(*LocalState, Event) ActionResolveFunc, desc string) Trigger { t := triggerBase{source: p, resolveFunc: resolveFunc, desc: desc} t.condition = func(_ *LocalState, event Event) (bool, bool) { c := event.eventType == EventTypes.Target && @@ -129,7 +141,7 @@ func newTargetedTrigger(p Permanent, singleshot bool, resolveFunc ActionResolveF return &t } -func newDeathTrigger(p Permanent, singleshot bool, resolveFunc ActionResolveFunc, permCond func(Permanent) bool, desc string) Trigger { +func newDeathTrigger(p Permanent, singleshot bool, resolveFunc func(*LocalState, Event) ActionResolveFunc, permCond func(Permanent) bool, desc string) Trigger { t := triggerBase{source: p, resolveFunc: resolveFunc, desc: desc} t.condition = func(_ *LocalState, event Event) (bool, bool) { if event.eventType != EventTypes.Sacrifice && event.eventType != EventTypes.Destruction { @@ -144,14 +156,81 @@ func newDeathTrigger(p Permanent, singleshot bool, resolveFunc ActionResolveFunc return &t } -func newOwnDeathTrigger(p Permanent, resolveFunc ActionResolveFunc, desc string) Trigger { +func newOwnDeathTrigger(p Permanent, resolveFunc func(*LocalState, Event) 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 { +func newEnemyDeathTrigger(p Permanent, resolveFunc func(*LocalState, Event) ActionResolveFunc, desc string) Trigger { return newDeathTrigger(p, true, resolveFunc, func(destroyedPerm Permanent) bool { return p.Controller().IsEnemy(destroyedPerm.Controller()) }, desc) } + +func newDamageDealtTrigger(source any, singleshot bool, cond func(Event) bool, resolveFunc func(*LocalState, Event) ActionResolveFunc, desc string) Trigger { + t := triggerBase{source: source, resolveFunc: resolveFunc, desc: desc} + t.condition = func(_ *LocalState, event Event) (bool, bool) { + if event.eventType != EventTypes.DamageDealt { + return false, false + } + + return cond(event), singleshot + } + return &t +} + +func newDamageDealtByTrigger(source any, singleshot bool, resolveFunc func(*LocalState, Event) ActionResolveFunc, desc string) Trigger { + return newDamageDealtTrigger(source, singleshot, + func(e Event) bool { return slices.Contains(e.sources, source) }, + resolveFunc, desc) +} + +func newDamageDealtToTrigger(p Permanent, singleshot bool, resolveFunc func(*LocalState, Event) ActionResolveFunc, desc string) Trigger { + return newDamageDealtTrigger(p, singleshot, + func(e Event) bool { return slices.Contains(e.affected, p.(any)) }, + resolveFunc, desc) +} + +func (s *LocalState) addTrigger(trigger Trigger) { + s.triggers = append(s.triggers, trigger) +} + +func (s *LocalState) removeTriggers(triggers []Trigger) { + for _, t := range triggers { + s.triggers = utils.RemoveFromUnorderedSlice(s.triggers, t) + } +} + +func (s *LocalState) removeTrigger(trigger Trigger) { + s.removeTriggers([]Trigger{trigger}) +} + +func (s *LocalState) handleTriggers() { + var actions []*TriggeredAction + var triggersToRemove []Trigger + + for _, e := range s.events { + for _, t := range s.triggers { + a, remove := t.trigger(s, e) + if a != nil { + actions = append(actions, a...) + } + if remove { + triggersToRemove = append(triggersToRemove, t) + } + } + } + + // Reset occured events + s.events = nil + + s.removeTriggers(triggersToRemove) + + if len(actions) > 0 { + orderedActions := s.orderTriggeredActions(actions) + for _, a := range orderedActions { + s.declareAction(a) + } + } +} -- cgit v1.2.3