aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--go/game/action.go34
-rw-r--r--go/game/playerControl.go7
-rw-r--r--go/game/state.go45
-rw-r--r--go/game/trigger.go6
4 files changed, 81 insertions, 11 deletions
diff --git a/go/game/action.go b/go/game/action.go
index 4f433845..a8b27314 100644
--- a/go/game/action.go
+++ b/go/game/action.go
@@ -2,6 +2,7 @@ package game
import (
"fmt"
+ "log"
)
type (
@@ -12,6 +13,7 @@ type (
type Action interface {
Source() interface{}
+ Controller() *Player
Targets() *Targets
Target() *Target // Shortcut for to select the first target
@@ -25,6 +27,7 @@ type Action interface {
type PassPriority struct{ player *Player }
func (a *PassPriority) Source() interface{} { return a.player }
+func (a *PassPriority) Controller() *Player { return a.player }
func (*PassPriority) Targets() *Targets { return nil }
func (*PassPriority) Target() *Target { return nil }
func (*PassPriority) NeedsActionCostChoice() bool { return false }
@@ -40,6 +43,7 @@ type TargetSelection struct {
}
func (sel *TargetSelection) Source() interface{} { return sel.player }
+func (sel *TargetSelection) Controller() *Player { return sel.player }
func (sel *TargetSelection) Targets() *Targets { return sel.targets }
func (sel *TargetSelection) Target() *Target { return sel.targets.ts[0] }
func (*TargetSelection) NeedsActionCostChoice() bool { return false }
@@ -67,7 +71,20 @@ type ActionBase struct {
costFunc ActionCostFunc
}
-func (a *ActionBase) Source() interface{} { return a.source }
+func (a *ActionBase) Source() interface{} { return a.source }
+func (a *ActionBase) Controller() *Player {
+ switch t := a.source.(type) {
+ case *Player:
+ return t
+ case Permanent:
+ return t.Controller()
+ default:
+ log.Panicf("Unhandled source type %v", t)
+ return nil
+ }
+
+ return nil
+}
func (a *ActionBase) resolve(s *State) { a.resolveFunc(s) }
func (a *ActionBase) PayCosts(s *State) bool { return a.costFunc(s) }
func (a *ActionBase) Targets() *Targets { return a.targets }
@@ -102,6 +119,21 @@ func (a *TriggeredAction) String() string {
return fmt.Sprintf("%v ! %v", a.event, a.source)
}
+// Wrapper action to pass all triggered actions through the PlayerControl
+type DeclareTriggeredActionsAction struct {
+ actions []*TriggeredAction
+}
+
+func (sel *DeclareTriggeredActionsAction) Source() interface{} { return nil }
+func (sel *DeclareTriggeredActionsAction) Controller() *Player { return nil }
+func (sel *DeclareTriggeredActionsAction) Targets() *Targets { return nil }
+func (sel *DeclareTriggeredActionsAction) Target() *Target { return nil }
+func (*DeclareTriggeredActionsAction) NeedsActionCostChoice() bool { return false }
+func (sel *DeclareTriggeredActionsAction) CheckTargets(s *State) error { return nil }
+func (*DeclareTriggeredActionsAction) PayCosts(*State) bool { return true }
+func (*DeclareTriggeredActionsAction) resolve(*State) {}
+func (*DeclareTriggeredActionsAction) String() string { return "declared triggered actions" }
+
type PileDropAction struct {
ActionBase
pile []Permanent
diff --git a/go/game/playerControl.go b/go/game/playerControl.go
index eea6a19b..94c8be7e 100644
--- a/go/game/playerControl.go
+++ b/go/game/playerControl.go
@@ -12,6 +12,7 @@ const (
ResolvedActionNotification
PriorityNotification
TargetSelectionPrompt
+ DeclareTriggeredActionsPrompt
)
func (n PlayerNotificationType) String() string {
@@ -24,6 +25,8 @@ func (n PlayerNotificationType) String() string {
return "PriorityNotification"
case TargetSelectionPrompt:
return "TargetSelectionPrompt"
+ case DeclareTriggeredActionsPrompt:
+ return "DeclareTriggeredActionsPrompt"
default:
log.Panicf("Unhandled notification %d", n)
return ""
@@ -86,6 +89,10 @@ func newHandCardSelectionPrompt(p *Player, min, max int) PlayerNotification {
return newTargetSelectionPrompt(a, desc)
}
+func newDeclareTriggeredActionsPrompt(triggeredActions []*TriggeredAction) PlayerNotification {
+ return PlayerNotification{DeclareTriggeredActionsPrompt, triggeredActions, nil}
+}
+
type PlayerControl interface {
Player() *Player
RecvAction() Action
diff --git a/go/game/state.go b/go/game/state.go
index 6bb3dbf0..36dc3e77 100644
--- a/go/game/state.go
+++ b/go/game/state.go
@@ -106,7 +106,7 @@ func (s *State) removeTriggers(triggers []Trigger) {
}
func (s *State) handleTriggers() {
- var actions []Action
+ var actions []*TriggeredAction
var triggersToRemove []Trigger
for _, e := range s.events {
@@ -126,9 +126,11 @@ func (s *State) handleTriggers() {
s.removeTriggers(triggersToRemove)
- orderedActions := s.orderTriggeredActions(actions)
- for _, a := range orderedActions {
- s.declareAction(a)
+ if len(actions) > 0 {
+ orderedActions := s.orderTriggeredActions(actions)
+ for _, a := range orderedActions {
+ s.declareAction(a)
+ }
}
}
@@ -360,9 +362,38 @@ func (s *State) declareAction(a Action) {
s.broadcastNotification(newDeclaredActionNotification(a, err))
}
-func (s *State) orderTriggeredActions(actions []Action) []Action {
- // TODO: implement ordering
- return actions
+func (s *State) orderTriggeredActions(triggeredActions []*TriggeredAction) []Action {
+ playerActions := make(map[*Player][]*TriggeredAction)
+ for _, action := range triggeredActions {
+ p := action.Controller()
+ if actions, found := playerActions[p]; found {
+ playerActions[p] = append(actions, action)
+ } else {
+ playerActions[p] = []*TriggeredAction{action}
+ }
+ }
+
+ orderedActions := []Action{}
+ nPlayers := len(s.Players)
+ for i := 0; i < nPlayers; i++ {
+ p := s.Players[(i+s.ActivePlayer.Id-1)%nPlayers]
+
+ actions := playerActions[p]
+ p.Ctrl.SendNotification(newDeclareTriggeredActionsPrompt(actions))
+
+ switch a := p.Ctrl.RecvAction().(type) {
+ case *DeclareTriggeredActionsAction:
+ pActions := make([]Action, 0, len(a.actions))
+ for _, a := range a.actions {
+ pActions = append(pActions, a)
+ }
+ orderedActions = append(orderedActions, pActions...)
+ default:
+ log.Panicf("Unexpected action type %T after DeclareTriggerPrompt", a)
+ }
+ }
+
+ return orderedActions
}
func (s *State) allPassing(skipFirst bool) bool {
diff --git a/go/game/trigger.go b/go/game/trigger.go
index 39901d71..8fe4ae89 100644
--- a/go/game/trigger.go
+++ b/go/game/trigger.go
@@ -61,7 +61,7 @@ func newEotEvent() Event {
type Trigger interface {
Card() *Card
String() string
- trigger(*State, Event) ([]Action, bool)
+ trigger(*State, Event) ([]*TriggeredAction, bool)
}
type triggerBase struct {
@@ -80,11 +80,11 @@ func (t *triggerBase) String() string {
return t.desc
}
-func (t *triggerBase) trigger(s *State, e Event) ([]Action, bool) {
+func (t *triggerBase) trigger(s *State, e Event) ([]*TriggeredAction, bool) {
triggered, remove := t.condition(s, e)
if !triggered {
return nil, remove
}
- return []Action{newTriggeredAction(e, t, t.resolveFunc, t.costFunc)}, remove
+ return []*TriggeredAction{newTriggeredAction(e, t, t.resolveFunc, t.costFunc)}, remove
}