aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fischer@muhq.space>2025-08-12 08:25:58 +0200
committerFlorian Fischer <florian.fischer@muhq.space>2025-08-20 15:57:36 +0200
commit8a00fc998d0e803e835c800b50d9c8e4cdb287a0 (patch)
tree55dfcb32b434deb06ba89fe8e7714964ad3a5221
parent661cfcad1cb8ff95bb0c86efab19263b3e49b9a0 (diff)
downloadmuhqs-game-8a00fc998d0e803e835c800b50d9c8e4cdb287a0.tar.gz
muhqs-game-8a00fc998d0e803e835c800b50d9c8e4cdb287a0.zip
support parsing of simple equipment effects
-rw-r--r--go/game/cardImplementations.go24
-rw-r--r--go/game/cardParsing.go74
-rw-r--r--go/game/map_test.go13
-rw-r--r--go/game/unit_test.go4
4 files changed, 89 insertions, 26 deletions
diff --git a/go/game/cardImplementations.go b/go/game/cardImplementations.go
index 161de212..2a627a94 100644
--- a/go/game/cardImplementations.go
+++ b/go/game/cardImplementations.go
@@ -95,16 +95,6 @@ func (*missionaryImpl) fullActions(u *Unit) []*FullAction {
return []*FullAction{a}
}
-type swordImpl struct{ cardImplementationBase }
-
-func (*swordImpl) onPile(p Permanent) { adjustMelee(p, 1) }
-func (*swordImpl) onUnpile(p Permanent) { adjustMelee(p, -1) }
-
-type greatSwordImpl struct{ cardImplementationBase }
-
-func (*greatSwordImpl) onPile(p Permanent) { adjustMelee(p, 2) }
-func (*greatSwordImpl) onUnpile(p Permanent) { adjustMelee(p, -2) }
-
type misinformationImpl struct{ cardImplementationBase }
func (*misinformationImpl) onPlay(a *PlayAction) {
@@ -158,11 +148,6 @@ func (*recruiterImpl) additionalSpawnsFor(p Permanent, ct CardType) []*Tile {
return TilesInRange(s.Map(), p, 1)
}
-type shieldImpl struct{ cardImplementationBase }
-
-func (*shieldImpl) onPile(p Permanent) { adjustHealth(p, 1) }
-func (*shieldImpl) onUnpile(p Permanent) { adjustHealth(p, -1) }
-
type taxCollectorImpl struct{ cardImplementationBase }
func (*taxCollectorImpl) fullActions(u *Unit) []*FullAction {
@@ -178,11 +163,6 @@ func (*taxCollectorImpl) fullActions(u *Unit) []*FullAction {
return []*FullAction{a}
}
-type towerShieldImpl struct{ cardImplementationBase }
-
-func (*towerShieldImpl) onPile(p Permanent) { adjustHealth(p, 2) }
-func (*towerShieldImpl) onUnpile(p Permanent) { adjustHealth(p, -2) }
-
type wormtongueImpl struct{ cardImplementationBase }
func (*wormtongueImpl) fullActions(u *Unit) []*FullAction {
@@ -714,14 +694,10 @@ func init() {
cardImplementations = map[string]cardImplementation{
"base/advisor": &advisorImpl{},
"base/missionary": &missionaryImpl{},
- "base/sword": &swordImpl{},
- "base/greatsword": &greatSwordImpl{},
"base/misinformation": &misinformationImpl{},
"base/pioneer": &pioneerImpl{},
"base/recruiter": &recruiterImpl{},
- "base/shield": &shieldImpl{},
"base/tax_collector": &taxCollectorImpl{},
- "base/tower_shield": &towerShieldImpl{},
"base/wormtongue": &wormtongueImpl{},
"base/pikeman": &pikemanImpl{},
diff --git a/go/game/cardParsing.go b/go/game/cardParsing.go
index 3b1e7cdb..9091c1fc 100644
--- a/go/game/cardParsing.go
+++ b/go/game/cardParsing.go
@@ -125,6 +125,13 @@ func (impl *dynamicCardImplementation) parseEffect(effect string) {
if strings.Contains(effect, "can be played") {
impl.parsePlayModification(effect)
}
+ // TODO: support gets and has effects
+ if strings.Contains(effect, "equipped unit gets") {
+ impl.parseEquipmentGetEffect(effect)
+ }
+ if strings.Contains(effect, "equipped unit has") {
+ impl.parseEquipmentHasEffect(effect)
+ }
}
func (impl *dynamicCardImplementation) parseFullAction(fullAction string) {
@@ -248,3 +255,70 @@ func (impl *dynamicCardImplementation) parsePlayModification(effect string) {
log.Println("Play modification for other cards are not implemented")
}
}
+
+func (impl *dynamicCardImplementation) parseEquipmentGetEffect(effect string) {
+ tokens := strings.SplitAfterN(effect, "equipped unit gets ", 2)
+ tokens = tokens[1:]
+
+ tokens = strings.Split(tokens[0], " and ")
+
+ var (
+ apply []func(Permanent)
+ remove []func(Permanent)
+ )
+
+ for _, token := range tokens {
+ x, err := parseXEffect(token)
+ if err == nil {
+ if strings.Contains(x.raw, "movement") {
+ apply = append(apply, func(p Permanent) { adjustMovement(p, x.x) })
+ remove = append(apply, func(p Permanent) { adjustMovement(p, -1*x.x) })
+ continue
+ } else if strings.Contains(x.raw, "melee") {
+ apply = append(apply, func(p Permanent) { adjustMelee(p, x.x) })
+ remove = append(apply, func(p Permanent) { adjustMelee(p, -1*x.x) })
+ continue
+ } else if strings.Contains(x.raw, "health") {
+ apply = append(apply, func(p Permanent) { adjustHealth(p, x.x) })
+ remove = append(apply, func(p Permanent) { adjustHealth(p, -1*x.x) })
+ continue
+ }
+ }
+ }
+
+ if len(apply) == 0 {
+ return
+ }
+
+ impl._onPile = func(p Permanent) {
+ for _, a := range apply {
+ a(p)
+ }
+ }
+ impl._onUnpile = func(p Permanent) {
+ for _, r := range remove {
+ r(p)
+ }
+ }
+}
+
+func (impl *dynamicCardImplementation) parseEquipmentHasEffect(effect string) {
+ tokens := strings.SplitAfterN(effect, "equipped unit has ", 2)
+ tokens = tokens[1:]
+
+ tokens = strings.Split(tokens[0], " and ")
+ if len(tokens) == 0 {
+ return
+ }
+
+ impl._onPile = func(p Permanent) {
+ for _, token := range tokens {
+ p.addTmpEffect(token)
+ }
+ }
+ impl._onUnpile = func(p Permanent) {
+ for _, token := range tokens {
+ p.removeTmpEffect(token)
+ }
+ }
+}
diff --git a/go/game/map_test.go b/go/game/map_test.go
index bc17dd55..038cde93 100644
--- a/go/game/map_test.go
+++ b/go/game/map_test.go
@@ -17,6 +17,19 @@ func parseMapString(t *testing.T, mapDef string) *Map {
return m
}
+func newEmpty2x2Map() *Map {
+ mapDef := `map: |1-
+ __
+ __
+
+symbols:
+ _: neutral
+`
+ m, _ := readMap(strings.NewReader(mapDef))
+
+ return m
+}
+
func TestParseMapEndingStreets(t *testing.T) {
mapDef := `map: |1-
HST
diff --git a/go/game/unit_test.go b/go/game/unit_test.go
index b93f658d..d6ad271c 100644
--- a/go/game/unit_test.go
+++ b/go/game/unit_test.go
@@ -71,12 +71,12 @@ symbols:
}
if f.Attack.Valid() {
- t.Fatalf("fisher has still a valid atack")
+ t.Fatalf("fisher has still a valid attack")
}
addPermanentToPile(a, sword)
if a.Attack.attacks[0] != 2 {
- t.Fatalf("archer's mele attack is not 2")
+ t.Fatalf("archer's melee attack is not 2")
}
}