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:
2023-04-04 13:22:43 -07:00
parent ccd141ddc5
commit e0dad09045
6 changed files with 169 additions and 211 deletions

View File

@ -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
}
}