aboutsummaryrefslogtreecommitdiff
path: root/go
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fischer@muhq.space>2025-08-06 15:23:17 +0200
committerFlorian Fischer <florian.fischer@muhq.space>2025-08-20 15:57:34 +0200
commit04dc78977c3d15e60bec5a4d19416ded1b94907d (patch)
treee511b3de7780299f6244fd3a12e635121ff7e35e /go
parent1e3de1f520e77e827525dd64e9b748cb54ce454d (diff)
downloadmuhqs-game-04dc78977c3d15e60bec5a4d19416ded1b94907d.tar.gz
muhqs-game-04dc78977c3d15e60bec5a4d19416ded1b94907d.zip
update missionary
Limit the range of the missionary's full action but increase its effectivnes. The missionary could only really be used unthreatened over multiple turns. Since any unit can be disbanded during upkeep before it is evangelized, the missionary is only a slow destroy effect. Now it is way more potent controlling cheaper units with the first action but it has to be close to the enemy unit making it more vulnerable.
Diffstat (limited to 'go')
-rw-r--r--go/game/cardImplementations.go11
-rw-r--r--go/game/cardImplementations_test.go59
-rw-r--r--go/game/permanent.go6
3 files changed, 70 insertions, 6 deletions
diff --git a/go/game/cardImplementations.go b/go/game/cardImplementations.go
index 007c2335..3d43fe42 100644
--- a/go/game/cardImplementations.go
+++ b/go/game/cardImplementations.go
@@ -81,18 +81,17 @@ type missionaryImpl struct{ cardImplementationBase }
func (*missionaryImpl) fullActions(u *Unit) []*FullAction {
resolvePrototype := func(a Action) ActionResolveFunc {
- u := a.Source().(*Unit)
target := a.Target().sel[0].(*Unit)
return func(s *LocalState) {
- target.adjustMarks(UnitMarks.Faith, 2)
- if target.Marks(UnitMarks.Faith) > target.Card().BuyCosts.Costs(s) {
- target.controller = u.Controller()
+ target.adjustMarks(UnitMarks.Faith, 5)
+ if target.Card().BuyCosts != nil && target.Marks(UnitMarks.Faith) >= target.Card().BuyCosts.Costs(s) {
+ target.changeController(a.Controller())
}
}
}
s := u.Controller().gameState
- a := newFullAction(u, resolvePrototype, "put faith ...")
- a.targets = newTargets(newTarget(s, newTargetDesc("unit"), a))
+ a := newFullAction(u, resolvePrototype, "put 5 faith ...")
+ a.targets = newTargets(newTarget(s, newTargetDesc("unit in range 3"), a))
return []*FullAction{a}
}
diff --git a/go/game/cardImplementations_test.go b/go/game/cardImplementations_test.go
index b962677c..5160816e 100644
--- a/go/game/cardImplementations_test.go
+++ b/go/game/cardImplementations_test.go
@@ -131,3 +131,62 @@ symbols:
t.Fatal("unexpected valid target")
}
}
+
+func TestMissionary(t *testing.T) {
+ mapDef := `map: |1-
+ SSS
+ SSS
+ SHS
+symbols:
+ S: street
+ H: house
+`
+ s := NewLocalState()
+
+ m, _ := readMap(strings.NewReader(mapDef))
+ s.SetMap(m)
+
+ player := s.AddNewPlayer("p", NewDeck())
+ opo := s.AddNewPlayer("o", NewDeck())
+
+ mis := s.addNewUnit(NewCard("base/missionary"), Position{0, 0}, player)
+ king := s.addNewUnit(NewCard("misc/king"), Position{0, 2}, opo)
+ k := s.addNewUnit(NewCard("base/knight"), Position{2, 0}, opo)
+ r := s.addNewUnit(NewCard("base/recruit"), Position{2, 1}, opo)
+
+ a := mis.FullActions[0]
+ err := a.Target().AddSelection(king)
+ if err != nil {
+ t.Fatal("invalid target:", err)
+ }
+
+ for range 20 {
+ a.resolve(s)
+ if king.controller != king.owner {
+ t.Fatal("king not controlled by its owner")
+ }
+ }
+
+ a.Target().ClearSelection()
+ _ = a.Target().AddSelection(k)
+
+ a.resolve(s)
+ if k.controller != k.owner {
+ t.Fatal("knight not controlled by its owner")
+ }
+
+ s.ResolveAction(a)
+ if k.controller != player {
+ t.Fatal("knight not controlled by player")
+ }
+
+ // recruit
+ a.Target().ClearSelection()
+ _ = a.Target().AddSelection(r)
+ s.ResolveAction(a)
+ if r.controller != player {
+ t.Fatal("recruit not controlled by player")
+ }
+
+ // TODO: test return to owner
+}
diff --git a/go/game/permanent.go b/go/game/permanent.go
index 09a8829c..503084a2 100644
--- a/go/game/permanent.go
+++ b/go/game/permanent.go
@@ -19,6 +19,7 @@ type Permanent interface {
ContainingPerm() Permanent
Pile() []Permanent
Controller() *Player
+ changeController(*Player)
Owner() *Player
Effects() []string
HasEffect(string) bool
@@ -89,6 +90,11 @@ func (p *permanentBase) Pile() []Permanent { return p.pile }
func (p *permanentBase) Controller() *Player { return p.controller }
func (p *permanentBase) Owner() *Player { return p.owner }
+func (p *permanentBase) changeController(c *Player) {
+ p.controller = c
+
+}
+
func FmtPermanent(p Permanent) string {
typeIndicator := strings.ToUpper(p.Card().Type.String()[:1])