diff options
| author | Florian Fischer <florian.fischer@muhq.space> | 2025-09-03 12:37:52 +0200 |
|---|---|---|
| committer | Florian Fischer <florian.fischer@muhq.space> | 2025-09-03 12:39:42 +0200 |
| commit | 67faa0f3bf6fb047d19372c9b671a45887b99f6e (patch) | |
| tree | 359daa9bf5f3ccd04678598b6fa17e60d5fcc768 /go/game | |
| parent | 1f6b30ebec826fe886829c2618ed0b109009e3b8 (diff) | |
| download | muhqs-game-67faa0f3bf6fb047d19372c9b671a45887b99f6e.tar.gz muhqs-game-67faa0f3bf6fb047d19372c9b671a45887b99f6e.zip | |
implement the patrician
Diffstat (limited to 'go/game')
| -rw-r--r-- | go/game/action.go | 12 | ||||
| -rw-r--r-- | go/game/cardImplementations.go | 40 | ||||
| -rw-r--r-- | go/game/cardImplementations_test.go | 40 |
3 files changed, 92 insertions, 0 deletions
diff --git a/go/game/action.go b/go/game/action.go index 856ea6bc..91ea223c 100644 --- a/go/game/action.go +++ b/go/game/action.go @@ -660,6 +660,18 @@ type FreeAction struct { desc string } +// newControllerCostFunc returns a new cost function checking the controller's resource and decreasing it accordingly. +func newControllerResourceCostFunc(p Permanent, amount int) ActionCostFunc { + return func(s *LocalState) bool { + c := p.Controller() + if c.Resource < amount { + return false + } + c.Resource -= amount + return true + } +} + func NewFreeAction(p Permanent, resolveProto ActionFuncPrototype, costFunc ActionCostFunc, desc string, ) *FreeAction { diff --git a/go/game/cardImplementations.go b/go/game/cardImplementations.go index 58bbc75e..478e1681 100644 --- a/go/game/cardImplementations.go +++ b/go/game/cardImplementations.go @@ -755,6 +755,45 @@ func (*illusionImpl) onETB(s *LocalState, p Permanent) { }, p.Card().getEffects()[0])) } +type patricianImpl struct{ cardImplementationBase } + +func (*patricianImpl) freeActions(p Permanent) []*FreeAction { + u := p.(*Unit) + m := NewFreeAction(u, func(a Action) ActionResolveFunc { + return func(s *LocalState) { + s.addEotEffect(newMovementModificationEffect(u, 1)) + } + }, newControllerResourceCostFunc(u, 2), "2: +1 movement") + + a := NewFreeAction(u, func(a Action) ActionResolveFunc { + return func(s *LocalState) { + s.addEotEffect(newAttackModificationEffect(u, 1)) + } + }, newControllerResourceCostFunc(u, 3), "3: +1 attack") + + ar := NewFreeAction(u, func(a Action) ActionResolveFunc { + return func(s *LocalState) { + s.addEotEffect(newTmpEffect(p, "+1 armor")) + } + }, newControllerResourceCostFunc(u, 5), "5: +1 armor") + + d := NewFreeAction(u, func(a Action) ActionResolveFunc { + return func(s *LocalState) { + a.Controller().DrawN(1) + } + }, newControllerResourceCostFunc(u, 7), "7: Draw 1") + + r := NewFreeAction(u, func(a Action) ActionResolveFunc { + return func(s *LocalState) { + t := a.Target().sel[0].(*Tile) + s.addNewUnit(NewCard("base/recruit"), t.Position, u.Controller()) + } + }, newControllerResourceCostFunc(u, 9), "9: CreateRecruit") + r.targets = newTargets(newTarget(p.Controller().gameState, newTargetDesc("adjacent available tile"), r)) + + return []*FreeAction{m, a, ar, d, r} +} + func init() { cardImplementations = map[string]cardImplementation{ "base/advisor": &advisorImpl{}, @@ -805,5 +844,6 @@ func init() { "exp1/illusion": &illusionImpl{}, "exp1/illusionist": &illusionistImpl{}, + "exp1/patrician": &patricianImpl{}, } } diff --git a/go/game/cardImplementations_test.go b/go/game/cardImplementations_test.go index eb3ec567..4a353443 100644 --- a/go/game/cardImplementations_test.go +++ b/go/game/cardImplementations_test.go @@ -256,3 +256,43 @@ func TestBanner(t *testing.T) { t.Fatal("wormtongue not sped up by banner") } } + +func TestPatrician(t *testing.T) { + s, _, player, _ := newMockState() + p := s.addNewUnit(NewCard("exp1/patrician"), Position{1, 0}, player) + fas := p.FreeActions + if len(fas) != 5 { + t.Fatal("patrician does not have 5 free actions") + } + + player.Resource = 5 + s.declareAction(fas[0]) + if player.Resource != 3 { + t.Fatal("patrician move did not cost 2 resource") + } + s.stack.pop() + if p.Movement.Range != 2 { + t.Fatal("patrician movement is not increased") + } + + player.Resource = 5 + s.declareAction(fas[1]) + if player.Resource != 2 { + t.Fatal("patrician attack did not cost 3 resource") + } + s.stack.pop() + if p.Attack.DamageInRange(1) != 1 { + t.Fatal("patrician has no melee") + } + + player.Resource = 5 + s.declareAction(fas[2]) + if player.Resource != 0 { + t.Fatal("patrician armor did not cost 5 resource") + } + s.stack.pop() + x, err := p.XEffect("armor") + if err != nil || x != 1 { + t.Fatal("patrician has no armor") + } +} |
