From 3fcf06b681705cfceb05833e5ee57a7ddc6445b3 Mon Sep 17 00:00:00 2001 From: Florian Fischer Date: Wed, 8 Feb 2023 12:04:44 +0100 Subject: implement most of nautics cards --- go/game/action.go | 7 ++- go/game/cardImplementations.go | 121 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 112 insertions(+), 16 deletions(-) diff --git a/go/game/action.go b/go/game/action.go index 934f5645..fbcad0a7 100644 --- a/go/game/action.go +++ b/go/game/action.go @@ -216,16 +216,17 @@ func (a *AttackAction) String() string { type FullAction struct { ActionBase desc string + tag string } func NewFullAction(u *Unit, proto ActionFuncPrototype, desc string) *FullAction { a := &FullAction{ - ActionBase{ + ActionBase: ActionBase{ source: u, Card: u.Card(), }, - desc, + desc: desc, } a.resolveFunc = func(s *State) { @@ -250,7 +251,7 @@ func (a *FullAction) String() string { return fmt.Sprintf("↻ %s", a.desc) } - return fmt.Sprintf("%v: %s ↻@%v", u.Controller(), u.Card().Name, a.targets) + return fmt.Sprintf("%s: %s ↻@%v", u.Controller().Name, u.Card().Name, a.targets) } type FreeAction struct { diff --git a/go/game/cardImplementations.go b/go/game/cardImplementations.go index 5d28c06c..63c97ca7 100644 --- a/go/game/cardImplementations.go +++ b/go/game/cardImplementations.go @@ -6,7 +6,7 @@ import ( type advisorImpl struct{ cardImplementationBase } -func (impl *advisorImpl) fullActions(u *Unit) []*FullAction { +func (*advisorImpl) fullActions(u *Unit) []*FullAction { resolvePrototype := func(a Action) ActionResolveFunc { u := a.Source().(*Unit) return func(s *State) { @@ -23,7 +23,7 @@ func (impl *advisorImpl) fullActions(u *Unit) []*FullAction { type missionaryImpl struct{ cardImplementationBase } -func (impl *missionaryImpl) fullActions(u *Unit) []*FullAction { +func (*missionaryImpl) fullActions(u *Unit) []*FullAction { resolvePrototype := func(a Action) ActionResolveFunc { u := a.Source().(*Unit) target := a.Targets().sel[0].(*Unit) @@ -51,6 +51,102 @@ func (*swordImpl) onUnpile(p Permanent) { } } +type fishTrapAoE struct{} + +func (*fishTrapAoE) onEntering(p Permanent) { + if p.Card().Name != "nautics/fisher" { + return + } + + fisher := p.(*Unit) + fishTrapAction := func(a Action) ActionResolveFunc { + u := a.Source().(*Unit) + return func(s *State) { + controller := u.Controller() + controller.gainResource(2) + } + } + + fa := NewFullAction(fisher, fishTrapAction, "gain 2 resource") + fa.tag = "fishTrapAction" + fisher.FullActions = append(fisher.FullActions, fa) +} + +func (*fishTrapAoE) onLeaving(p Permanent) { + if p.Card().Name != "nautics/fisher" { + return + } + + fisher := p.(*Unit) + for i, fa := range fisher.FullActions { + if fa.tag != "fishTrapAction" { + continue + } + fisher.FullActions[i] = fisher.FullActions[len(fisher.FullActions)-1] + fisher.FullActions = fisher.FullActions[:len(fisher.FullActions)-1] + break + } +} + +type fishTrapImpl struct { + cardImplementation + aoe fishTrapAoE +} + +func (i *fishTrapImpl) onEntering(t *Tile) { + s := t.Permanent.Controller().gameState + for _, tile := range TilesInRange(s.Map, t.Permanent, 1) { + tile.addEffect(&i.aoe) + } +} + +func (i *fishTrapImpl) onLeaving(t *Tile) { + s := t.Permanent.Controller().gameState + for _, tile := range TilesInRange(s.Map, t.Permanent, 1) { + tile.removeEffect(&i.aoe) + } +} + +type fisherImpl struct{ cardImplementationBase } + +func (*fisherImpl) fullActions(u *Unit) []*FullAction { + s := u.Controller().gameState + resolvePrototype := func(a Action) ActionResolveFunc { + u := a.Source().(*Unit) + return func(s *State) { + t := a.Targets().sel[0].(*Tile) + s.AddNewArtifact(NewCard("nautics/fish_trap"), t.Position, u.Controller()) + } + } + a := NewFullAction(u, resolvePrototype, "create fish trap") + a.targets = newTargets(s, []string{"adjacent water tile"}, a) + return []*FullAction{a} +} + +type captainImpl struct{ cardImplementationBase } + +func (*captainImpl) onPile(containing Permanent) { + // TODO: implement static effect +} + +func (*captainImpl) onUnpile(containing Permanent) { + // TODO: remove static effect +} + +type sailorImpl struct{ cardImplementationBase } + +func (*sailorImpl) onPile(containing Permanent) { + if u, ok := containing.(*Unit); ok && u.Movement.Swimming { + u.Movement.Range += 1 + } +} + +func (*sailorImpl) onUnpile(containing Permanent) { + if u, ok := containing.(*Unit); ok && u.Movement.Swimming { + u.Movement.Range -= 1 + } +} + type tidesChangeImpl struct{ cardImplementation } func (*tidesChangeImpl) onPlay(s *State, _ *Player, _ *Targets) { @@ -77,19 +173,13 @@ func (*devourThePoorImpl) onPlay(s *State, kraken *Player, _ *Targets) { } } -type drownedSailorImpl struct{ cardImplementation } - -func (*drownedSailorImpl) onPile(containing Permanent) { - if u, ok := containing.(*Unit); ok && u.Movement.Swimming { - u.Attack.attacks[0] += 1 - } +type drownedSailorImpl struct { + cardImplementation + sailorImpl } -func (*drownedSailorImpl) onUnpile(containing Permanent) { - if u, ok := containing.(*Unit); ok && u.Movement.Swimming { - u.Attack.attacks[0] -= 1 - } -} +func (i *drownedSailorImpl) onPile(containing Permanent) { i.sailorImpl.onPile(containing) } +func (i *drownedSailorImpl) onUnpile(containing Permanent) { i.sailorImpl.onUnpile(containing) } func (*drownedSailorImpl) onDrop(sailor Permanent) { sailor.Controller().gameState.DestroyPermanent(sailor) @@ -234,6 +324,11 @@ func init() { "base/missionary": &missionaryImpl{}, "base/sword": &swordImpl{}, + "nautics/captain": &captainImpl{}, + "nautics/fish_trap": &fishTrapImpl{}, + "nautics/fisher": &fisherImpl{}, + "nautics/sailor": &sailorImpl{}, + "kraken/deja_vu!": &dejaVuImpl{}, "kraken/devour_the_poor!": &devourThePoorImpl{}, "kraken/drowned_sailor": &drownedSailorImpl{}, -- cgit v1.2.3