SwitchingCard.IsValid: control drawability.
Cards can now specify conditions that must be met for them to be drawn into the hand. Additionally, this improves the documentation of SwitchingCard.
This commit is contained in:
parent
d434e50897
commit
de7092cf4b
@ -42,11 +42,56 @@ type Policy interface {
|
|||||||
// previously, and undoes it before doing a different one. It is always valid
|
// previously, and undoes it before doing a different one. It is always valid
|
||||||
// to draw.
|
// to draw.
|
||||||
type SwitchingCard struct {
|
type SwitchingCard struct {
|
||||||
Name cardsim.Message
|
// Name contains the name of the card, displayed as its title in the
|
||||||
Desc cardsim.Message
|
// action selection menu and in the card detail page itself.
|
||||||
IsUrgent bool
|
Name cardsim.Message
|
||||||
After func(Card, *Player, CardOption) error
|
|
||||||
Policies []Policy
|
// Desc contains the event description for the card, displayed in the
|
||||||
|
// card detail page.
|
||||||
|
Desc cardsim.Message
|
||||||
|
|
||||||
|
// IsUrgent marks a card as urgent. If the player has any urgent cards
|
||||||
|
// in hand, they cannot act on any non-urgent cards (or permanent actions
|
||||||
|
// not marked as urgent).
|
||||||
|
IsUrgent bool
|
||||||
|
|
||||||
|
// After is invoked after the player has chosen to act on this card and
|
||||||
|
// the chosen option has been fully enacted. If the card should be returned
|
||||||
|
// to the deck, After is responsible for doing this!
|
||||||
|
//
|
||||||
|
// If After is not provided, ShuffleIntoBottomHalf is used as a fallback.
|
||||||
|
//
|
||||||
|
// The first argument to After is the card itself. This will be type
|
||||||
|
// *SwitchingCard. It's represented as Card so general "After" functions
|
||||||
|
// that can be used with multiple card types (for example,
|
||||||
|
// ShuffleIntoBottomHalf) can be trivially implemented.
|
||||||
|
//
|
||||||
|
// If the card cannot be drawn into the hand because it has an IsValid
|
||||||
|
// check and the check fails, After is invoked with a nil CardOption.
|
||||||
|
// ShuffleIntoBottomHalf works just fine with a nil argument here.
|
||||||
|
// (It doesn't care about the CardOption at all.)
|
||||||
|
After func(Card, *Player, CardOption) error
|
||||||
|
|
||||||
|
// IsValid is used to check whether the card can be drawn into the hand.
|
||||||
|
// If it cannot, After is immediately invoked (whenever the card was
|
||||||
|
// being drawn, which is probably the "draw" stage of the turn but can
|
||||||
|
// happen any time if something else causes the player to draw cards) with
|
||||||
|
// a nil CardOption (because no option was selected) and the SwitchingCard
|
||||||
|
// does not invoke any option and does not change its active policy.
|
||||||
|
//
|
||||||
|
// The first argument to IsValid is the card itself. This will be type
|
||||||
|
// *SwitchingCard. It's presented via the Card interface to support
|
||||||
|
// general validity functions that could be used with arbitrary kinds of Card.
|
||||||
|
IsValid func(Card, *Player) bool
|
||||||
|
|
||||||
|
// Policies contains the options the player may choose between. Policy is
|
||||||
|
// a more specific type than CardOption; a Policy can be un-enacted.
|
||||||
|
// Unenactment of the previous policy before selecting a new one is the
|
||||||
|
// core feature of SwitchingCard.
|
||||||
|
Policies []Policy
|
||||||
|
|
||||||
|
// lastPolicy stores the last policy selected for this card. It's used
|
||||||
|
// extensively by SwitchingCard's logic.
|
||||||
lastPolicy Policy
|
lastPolicy Policy
|
||||||
|
|
||||||
// ShowUnavailable controls whether options for which Enabled() = false
|
// ShowUnavailable controls whether options for which Enabled() = false
|
||||||
@ -66,7 +111,12 @@ func (s *SwitchingCard) Urgent(*Player) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Drawn implements Card.
|
// Drawn implements Card.
|
||||||
func (s *SwitchingCard) Drawn(*Player) bool {
|
func (s *SwitchingCard) Drawn(p *Player) bool {
|
||||||
|
if s.IsValid != nil && !s.IsValid(s, p) {
|
||||||
|
err := s.Then(p, nil)
|
||||||
|
p.ReportError(err) // can't do anything with the error right now
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,6 +168,11 @@ func (s *SwitchingCard) Then(p *Player, o CardOption) error {
|
|||||||
return errs.Emit()
|
return errs.Emit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CurrentlyEnacted returns the currently enacted Policy, if any.
|
||||||
|
func (s *SwitchingCard) CurrentlyEnacted() Policy {
|
||||||
|
return s.lastPolicy
|
||||||
|
}
|
||||||
|
|
||||||
// BasicPolicy is a straightfoward implementation of Policy. If the currently
|
// BasicPolicy is a straightfoward implementation of Policy. If the currently
|
||||||
// enacted option is re-enacted, it refunds the player's action point.
|
// enacted option is re-enacted, it refunds the player's action point.
|
||||||
type BasicPolicy struct {
|
type BasicPolicy struct {
|
||||||
|
Loading…
Reference in New Issue
Block a user