Refactor, new menu, issue feature update
It's now possible to make issue options enabled or disabled conditional upon having taken other actions with that issue before.
This commit is contained in:
@ -114,25 +114,29 @@ type BasicPolicy struct {
|
||||
NothingChanged cardsim.Message
|
||||
Do func(*Player) (cardsim.Message, error)
|
||||
Undo func(*Player) error
|
||||
CanDo func(*Player) bool
|
||||
CanDo func(*BasicPolicy, *Player) bool
|
||||
|
||||
currentlyEnacted bool
|
||||
CurrentlyEnacted bool
|
||||
LastEnactedPolicy Policy
|
||||
LastEnactedIdx int
|
||||
}
|
||||
|
||||
// YesWeCan returns true. It's the default value for BasicPolicy.CanDo / BasicPolicy.CanUndo.
|
||||
func YesWeCan(*Player) bool {
|
||||
func YesWeCan(*BasicPolicy, *Player) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// LastEnacted notifies b about the last-enacted policy in its group. It updates
|
||||
// b.currentlyEnacted accordingly.
|
||||
func (b *BasicPolicy) LastEnacted(_ int, p Policy) {
|
||||
b.currentlyEnacted = b.Is(p)
|
||||
func (b *BasicPolicy) LastEnacted(i int, p Policy) {
|
||||
b.LastEnactedPolicy = p
|
||||
b.LastEnactedIdx = i
|
||||
b.CurrentlyEnacted = b.Is(p)
|
||||
}
|
||||
|
||||
// OptionText implements CardOption.
|
||||
func (b *BasicPolicy) OptionText(*Player) (cardsim.Message, error) {
|
||||
if b.currentlyEnacted {
|
||||
if b.CurrentlyEnacted {
|
||||
if b.EnactedDesc == nil {
|
||||
return nil, ErrUnimplemented
|
||||
}
|
||||
@ -149,7 +153,7 @@ func (b *BasicPolicy) Enact(p *Player) (cardsim.Message, error) {
|
||||
if b.Do == nil {
|
||||
return nil, ErrUnimplemented
|
||||
}
|
||||
if b.currentlyEnacted {
|
||||
if b.CurrentlyEnacted {
|
||||
p.ActionsRemaining++
|
||||
if b.NothingChanged == nil {
|
||||
b.NothingChanged = cardsim.MsgStr("You continue your current approach.")
|
||||
@ -161,7 +165,7 @@ func (b *BasicPolicy) Enact(p *Player) (cardsim.Message, error) {
|
||||
|
||||
// Unenact implements Policy.
|
||||
func (b *BasicPolicy) Unenact(p *Player) error {
|
||||
if !b.currentlyEnacted {
|
||||
if !b.CurrentlyEnacted {
|
||||
return ErrPolicyNotEnacted
|
||||
}
|
||||
if b.Undo == nil {
|
||||
@ -172,13 +176,13 @@ func (b *BasicPolicy) Unenact(p *Player) error {
|
||||
|
||||
// Enabled implements CardOption.
|
||||
func (b *BasicPolicy) Enabled(p *Player) bool {
|
||||
if b.currentlyEnacted {
|
||||
if b.CurrentlyEnacted {
|
||||
return true
|
||||
}
|
||||
if b.CanDo == nil {
|
||||
panic(ErrUnimplemented)
|
||||
}
|
||||
return b.CanDo(p)
|
||||
return b.CanDo(b, p)
|
||||
}
|
||||
|
||||
func (b *BasicPolicy) Is(p Policy) bool {
|
||||
@ -192,22 +196,22 @@ func (b *BasicPolicy) Is(p Policy) bool {
|
||||
// policy. Which policy is used is determined by what the previous policy for
|
||||
// the card was (as reported via a call to LastEnacted):
|
||||
//
|
||||
// * If no policy has yet been enacted, use FirstTime.
|
||||
// * If a policy has been enacted, use the Policy at the slot in Variants
|
||||
// that corresponds to the slot (on the Card) of the currently-enacted policy.
|
||||
// * If the policy retrieved in this way returns ErrUnimplemented, throw away
|
||||
// its response and use Default instead. For Enabled, which does not have
|
||||
// an error component to its return value, look for ErrUnimplemented as the
|
||||
// argument to a Panic call, instead.
|
||||
// * If the policy retrieved in this way returns ErrKeepMessage when Enact
|
||||
// is called, it calls Default for the side effects but ignores its message,
|
||||
// retaining the message from the original call. This is to avoid having to
|
||||
// repeat the same Enact function except with different text each time.
|
||||
// OptionText does this too, even though OptionText doesn't have side effects,
|
||||
// so the same helper function can create a "constant message" callback
|
||||
// that works the same for both fields so someone implementing a card won't
|
||||
// accidentally fail to enact their policy's effects by using the wrong one
|
||||
// in the wrong slot.
|
||||
// - If no policy has yet been enacted, use FirstTime.
|
||||
// - If a policy has been enacted, use the Policy at the slot in Variants
|
||||
// that corresponds to the slot (on the Card) of the currently-enacted policy.
|
||||
// - If the policy retrieved in this way returns ErrUnimplemented, throw away
|
||||
// its response and use Default instead. For Enabled, which does not have
|
||||
// an error component to its return value, look for ErrUnimplemented as the
|
||||
// argument to a Panic call, instead.
|
||||
// - If the policy retrieved in this way returns ErrKeepMessage when Enact
|
||||
// is called, it calls Default for the side effects but ignores its message,
|
||||
// retaining the message from the original call. This is to avoid having to
|
||||
// repeat the same Enact function except with different text each time.
|
||||
// OptionText does this too, even though OptionText doesn't have side effects,
|
||||
// so the same helper function can create a "constant message" callback
|
||||
// that works the same for both fields so someone implementing a card won't
|
||||
// accidentally fail to enact their policy's effects by using the wrong one
|
||||
// in the wrong slot.
|
||||
type VerbosePolicy struct {
|
||||
Default Policy
|
||||
FirstTime Policy
|
||||
@ -254,7 +258,7 @@ func (v *VerbosePolicy) fillDefaults() {
|
||||
for len(v.Variants) <= v.lastIdx {
|
||||
v.Variants = append(v.Variants, v.Default)
|
||||
}
|
||||
if v.lastIdx > 0 && v.Variants[v.lastIdx] == nil {
|
||||
if v.lastIdx >= 0 && v.Variants[v.lastIdx] == nil {
|
||||
v.Variants[v.lastIdx] = v.Default
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user