aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fischer@muhq.space>2025-09-03 12:37:52 +0200
committerFlorian Fischer <florian.fischer@muhq.space>2025-09-03 12:39:42 +0200
commit67faa0f3bf6fb047d19372c9b671a45887b99f6e (patch)
tree359daa9bf5f3ccd04678598b6fa17e60d5fcc768
parent1f6b30ebec826fe886829c2618ed0b109009e3b8 (diff)
downloadmuhqs-game-67faa0f3bf6fb047d19372c9b671a45887b99f6e.tar.gz
muhqs-game-67faa0f3bf6fb047d19372c9b671a45887b99f6e.zip
implement the patrician
-rw-r--r--data/cards/exp1/patrician.yml21
-rw-r--r--go/game/action.go12
-rw-r--r--go/game/cardImplementations.go40
-rw-r--r--go/game/cardImplementations_test.go40
-rw-r--r--latex/cards/de/exp1/patrician.tex14
-rw-r--r--latex/cards/en/exp1/patrician.tex14
-rw-r--r--latex/sets/de/exp1.tex1
7 files changed, 142 insertions, 0 deletions
diff --git a/data/cards/exp1/patrician.yml b/data/cards/exp1/patrician.yml
new file mode 100644
index 00000000..d83cf7e4
--- /dev/null
+++ b/data/cards/exp1/patrician.yml
@@ -0,0 +1,21 @@
+type: unit
+name:
+ en: Patrician
+ de: Patrizier
+health: 1
+movement: 1
+buy: 7
+upkeep: 2
+effect:
+ en:
+ - "2: Gain +1 movement this turn"
+ - "3: Gain +1 attack this turn"
+ - "5: Gain +1 armor this turn"
+ - "7: Draw a card"
+ - "9: Create a Recruit token in range 1"
+ de:
+ - "2: Gain +1 movement this turn"
+ - "3: Gain +1 attack this turn"
+ - "5: Gain +1 armor this turn"
+ - "7: Draw a card"
+ - "9: Create a Recruit token in range 1"
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")
+ }
+}
diff --git a/latex/cards/de/exp1/patrician.tex b/latex/cards/de/exp1/patrician.tex
new file mode 100644
index 00000000..b34be5e7
--- /dev/null
+++ b/latex/cards/de/exp1/patrician.tex
@@ -0,0 +1,14 @@
+\documentclass{standalone}
+\usepackage[ngerman]{babel}
+\input{common.tex}
+
+\begin{document}
+\begin{tikzpicture}
+\cardtypeUnit{Patrizier}
+\cardbuycost{7}
+\cardsplitcontent{Leben: 1\\Bewegung: 1}{2: Gain +1 movement this turn\\ 3: Gain +1 attack this turn\\ 5: Gain +1 armor this turn\\ 7: Draw a card\\ 9: Create a Recruit token in range 1}
+\cardplaycost{2}
+\cardmodule{exp1}
+\cardborder
+\end{tikzpicture}
+\end{document}
diff --git a/latex/cards/en/exp1/patrician.tex b/latex/cards/en/exp1/patrician.tex
new file mode 100644
index 00000000..ae55d711
--- /dev/null
+++ b/latex/cards/en/exp1/patrician.tex
@@ -0,0 +1,14 @@
+\documentclass{standalone}
+\usepackage[english]{babel}
+\input{common.tex}
+
+\begin{document}
+\begin{tikzpicture}
+\cardtypeUnit{Patrician}
+\cardbuycost{7}
+\cardsplitcontent{Health: 1\\Movement: 1}{2: Gain +1 movement this turn\\ 3: Gain +1 attack this turn\\ 5: Gain +1 armor this turn\\ 7: Draw a card\\ 9: Create a Recruit token in range 1}
+\cardplaycost{2}
+\cardmodule{exp1}
+\cardborder
+\end{tikzpicture}
+\end{document}
diff --git a/latex/sets/de/exp1.tex b/latex/sets/de/exp1.tex
index 187b5b56..fee8baae 100644
--- a/latex/sets/de/exp1.tex
+++ b/latex/sets/de/exp1.tex
@@ -25,6 +25,7 @@
\includestandalone{cards/de/exp1/illusionist}
\includestandalone{cards/de/exp1/illusion}
\includestandalone{cards/de/exp1/macabre_clown}
+\includestandalone{cards/de/exp1/patrician}
\includestandalone{cards/de/exp1/power_to_the_people!}
\includestandalone{cards/de/exp1/push!}
\includestandalone{cards/de/exp1/ramm}