aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fischer@muhq.space>2023-02-07 14:58:22 +0100
committerFlorian Fischer <florian.fischer@muhq.space>2025-01-27 16:43:47 +0100
commit495940be9dfe0aa09c7940c3ad78968e354eb8e6 (patch)
tree3fb9a64fea22dbe4a58e27989d434dc492e5b49e
parent000b3230a77106ef49c5a581db7120e2ef6e56b1 (diff)
downloadmuhqs-game-495940be9dfe0aa09c7940c3ad78968e354eb8e6.tar.gz
muhqs-game-495940be9dfe0aa09c7940c3ad78968e354eb8e6.zip
intermediate commit
* implement most of the kraken cards * unify permanent marks * add state based actions hook for card implementations
-rw-r--r--go/TODO1
-rw-r--r--go/game/card.go23
-rw-r--r--go/game/cardImplementations.go232
-rw-r--r--go/game/cardParsing.go20
-rw-r--r--go/game/map.go4
-rw-r--r--go/game/marks.go68
-rw-r--r--go/game/permanent.go93
-rw-r--r--go/game/player.go6
-rw-r--r--go/game/state.go8
-rw-r--r--go/game/tile.go19
-rw-r--r--go/game/unit.go50
11 files changed, 380 insertions, 144 deletions
diff --git a/go/TODO b/go/TODO
index 590bb641..23274884 100644
--- a/go/TODO
+++ b/go/TODO
@@ -3,7 +3,6 @@
* implement Pile UI hint
* implement spell target parsing / selection
* implement triggers
-* implement area of effects
* implement draft
* implement game log
* finish AIs
diff --git a/go/game/card.go b/go/game/card.go
index 8b4cd889..c24e7585 100644
--- a/go/game/card.go
+++ b/go/game/card.go
@@ -76,12 +76,14 @@ type cardImplementation interface {
fullActions(*Unit) []*FullAction
freeActions(Permanent) []*FreeAction
+ stateBasedActions(*State, Permanent)
+
onEntering(*Tile)
onLeaving(*Tile)
onPlay(*State, *Player, *Targets)
- onPile(Permanent)
- onUnpile(Permanent)
- onDrop(Permanent)
+ onPile(containing Permanent)
+ onUnpile(containing Permanent)
+ onDrop(dropped Permanent)
}
// Default implementation of the cardImplementation interface.
@@ -93,12 +95,15 @@ type cardImplementationBase struct{}
func (*cardImplementationBase) spawnTiles(*State, *Player) []*Tile { return nil }
func (*cardImplementationBase) fullActions(*Unit) []*FullAction { return nil }
func (*cardImplementationBase) freeActions(Permanent) []*FreeAction { return nil }
-func (*cardImplementationBase) onEntering(*Tile) {}
-func (*cardImplementationBase) onLeaving(*Tile) {}
-func (*cardImplementationBase) onPlay(*State, *Player, *Targets) {}
-func (*cardImplementationBase) onPile(Permanent) {}
-func (*cardImplementationBase) onUnpile(Permanent) {}
-func (*cardImplementationBase) onDrop(Permanent) {}
+
+func (*cardImplementationBase) stateBasedActions(*State, Permanent) {}
+
+func (*cardImplementationBase) onEntering(*Tile) {}
+func (*cardImplementationBase) onLeaving(*Tile) {}
+func (*cardImplementationBase) onPlay(*State, *Player, *Targets) {}
+func (*cardImplementationBase) onPile(Permanent) {}
+func (*cardImplementationBase) onUnpile(Permanent) {}
+func (*cardImplementationBase) onDrop(Permanent) {}
// Map of all card implementations
var cardImplementations map[string]cardImplementation
diff --git a/go/game/cardImplementations.go b/go/game/cardImplementations.go
index 271c88ea..cb32ab2c 100644
--- a/go/game/cardImplementations.go
+++ b/go/game/cardImplementations.go
@@ -1,14 +1,12 @@
package game
-type farmerImplementation struct {
- cardImplementationBase
-}
+import (
+ "log"
+)
-type advisorImplementation struct {
- cardImplementationBase
-}
+type advisorImpl struct{ cardImplementationBase }
-func (impl *advisorImplementation) fullActions(u *Unit) []*FullAction {
+func (impl *advisorImpl) fullActions(u *Unit) []*FullAction {
resolvePrototype := func(a Action) ActionResolveFunc {
u := a.Source().(*Unit)
return func(s *State) {
@@ -23,61 +21,229 @@ func (impl *advisorImplementation) fullActions(u *Unit) []*FullAction {
return []*FullAction{NewFullAction(u, resolvePrototype, "draw 1. exile 1")}
}
-type missionaryImplementation struct {
- cardImplementationBase
-}
+type missionaryImpl struct{ cardImplementationBase }
-func (impl *missionaryImplementation) fullActions(u *Unit) []*FullAction {
+func (impl *missionaryImpl) fullActions(u *Unit) []*FullAction {
resolvePrototype := func(a Action) ActionResolveFunc {
u := a.Source().(*Unit)
target := a.Targets().sel[0].(*Unit)
return func(s *State) {
- faith, found := target.States[UnitMarks.Faith]
- if !found {
- target.States[UnitMarks.Faith] = 2
- } else {
- target.States[UnitMarks.Faith] = faith + 2
- if faith+2 > target.Card().BuyCost {
- target.controller = u.Controller()
- }
+ target.addMarks(UnitMarks.Faith, 2)
+ if target.Marks(UnitMarks.Faith) > target.Card().BuyCost {
+ target.controller = u.Controller()
}
}
}
return []*FullAction{NewFullAction(u, resolvePrototype, "put faith ...")}
}
-type swordImplementation struct {
- cardImplementationBase
-}
+type swordImpl struct{ cardImplementationBase }
-func (*swordImplementation) onPile(p Permanent) {
+func (*swordImpl) onPile(p Permanent) {
if u, ok := p.(*Unit); ok && !INVALID_ATTACK(u.Attack) {
u.Attack.attacks[0] += 1
}
}
-func (*swordImplementation) onUnpile(p Permanent) {
+func (*swordImpl) onUnpile(p Permanent) {
if u, ok := p.(*Unit); ok && !INVALID_ATTACK(u.Attack) {
u.Attack.attacks[0] -= 1
}
}
-type tidesChangeImplementation struct {
+type tidesChangeImpl struct{ cardImplementation }
+
+func (*tidesChangeImpl) onPlay(s *State, _ *Player, _ *Targets) {
+ s.Map.redistributeStoreCards(s.Rand)
+}
+
+type dejaVuImpl struct{ cardImplementation }
+
+func (*dejaVuImpl) onPlay(s *State, _ *Player, _ *Targets) {
+ for _, p := range s.Players {
+ if !p.IsKraken() {
+ p.Resource = s.Map.ResourceGain
+ }
+ }
+}
+
+type devourThePoorImpl struct{ cardImplementation }
+
+func (*devourThePoorImpl) onPlay(s *State, kraken *Player, _ *Targets) {
+ for _, u := range s.EnemyUnits(kraken) {
+ if u.Card().BuyCost < 7 {
+ s.DestroyPermanent(u)
+ }
+ }
+}
+
+type drownedSailorImpl struct{ cardImplementation }
+
+func (*drownedSailorImpl) onPile(containing Permanent) {
+ if u, ok := containing.(*Unit); ok && u.Movement.Swimming {
+ u.Attack.attacks[0] += 1
+ }
+}
+
+func (*drownedSailorImpl) onUnpile(containing Permanent) {
+ if u, ok := containing.(*Unit); ok && u.Movement.Swimming {
+ u.Attack.attacks[0] -= 1
+ }
+}
+
+func (*drownedSailorImpl) onDrop(sailor Permanent) {
+ sailor.Controller().gameState.DestroyPermanent(sailor)
+}
+
+// TODO: implement death trigger
+// TODO: implement hook for the containing permanent on pile
+type flyingDutchmenImpl struct{ cardImplementation }
+
+type frostPylonAoE struct{}
+
+func (*frostPylonAoE) onEntering(Permanent) {
+ // TODO: prevent actions and grant new full action
+}
+
+func (*frostPylonAoE) onLeaving(Permanent) {
+ // TODO: remove effect
+}
+
+type frostPylon struct {
cardImplementation
+ aoe frostPylonAoE
}
-func (*tidesChangeImplementation) onPlay(s *State, _ *Player, _ *Targets) {
- s.Map.redistributeStoreCards(s.Rand)
+func (*frostPylon) spawnTiles(s *State, kraken *Player) (spawns []*Tile) {
+ for _, u := range s.EnemyUnits(kraken) {
+ spawns = append(spawns, TilesInRange(s.Map, u, 1)...)
+ }
+ return
+}
+
+func (*frostPylon) stateBasedActions(s *State, p Permanent) {
+ if p.Marks(PermanentMarks.Crack) >= 3 {
+ s.DestroyPermanent(p)
+ }
+}
+
+func (i *frostPylon) onEntering(t *Tile) {
+ s := t.Permanent.Controller().gameState
+ for _, tile := range TilesInRange(s.Map, t.Permanent, 1) {
+ tile.addEffect(&i.aoe)
+ }
+}
+
+func (i *frostPylon) onLeaving(t *Tile) {
+ s := t.Permanent.Controller().gameState
+ for _, tile := range TilesInRange(s.Map, t.Permanent, 1) {
+ tile.removeEffect(&i.aoe)
+ }
+}
+
+type giganticHailImpl struct{ cardImplementation }
+
+func (*giganticHailImpl) onPlay(s *State, kraken *Player, _ *Targets) {
+ emptyTiles := s.Map.FreeTiles()
+ choices := len(emptyTiles)
+ for i := 0; i < 3; i++ {
+ if choices == 0 {
+ return
+ }
+
+ choice := s.Rand.Intn(choices - 1)
+ s.AddNewArtifact(NewCard("kraken/ice_berg"), emptyTiles[choice].Position, kraken)
+ emptyTiles[choice] = emptyTiles[choices-1]
+ choices--
+ }
+}
+
+type soldOutImpl struct{ cardImplementation }
+
+func (*soldOutImpl) onPlay(s *State, kraken *Player, _ *Targets) {
+ nStores := len(s.Map.Stores)
+ storePositions := make([]Position, 0, nStores)
+ for pos := range s.Map.Stores {
+ storePositions = append(storePositions, pos)
+ }
+
+ storePos := storePositions[s.Rand.Intn(nStores-1)]
+ s.Map.StoreOn(storePos).MoveInto(s.Exile)
+
+ storeTile := s.Map.TileAt(storePos)
+ storeTile.neutralize()
+}
+
+type supriseImpl struct{ cardImplementation }
+
+func (*supriseImpl) onPlay(s *State, kraken *Player, _ *Targets) {
+ // TODO: implement modification of next spawn tile
+}
+
+type tentacleSlapImpl struct{ cardImplementation }
+
+func (*tentacleSlapImpl) onPlay(s *State, kraken *Player, _ *Targets) {
+ x := 0
+ for _, p := range s.Players {
+ if p.IsKraken() {
+ continue
+ }
+
+ x += p.Hand.Size()
+ p.discardHand()
+ }
+
+ gain := 5 - x
+ if gain > 0 {
+ kraken.gainResource(gain)
+ }
+}
+
+type unholyCannonballImpl struct{ cardImplementation }
+
+func (*unholyCannonballImpl) onPlay(s *State, kraken *Player, _ *Targets) {
+ krakenTiles := s.Map.FilterTiles(func(t *Tile) bool { return t.Raw == "the kraken" })
+ if len(krakenTiles) != 1 {
+ log.Fatal("No kraken tile found in Map")
+ }
+
+ enemiesInRange2 := []*Unit{}
+ for _, u := range s.EnemyUnits(kraken) {
+ if u.Tile() == nil {
+ continue
+ }
+
+ if IsPositionInRange(u.Tile().Position, krakenTiles[0].Position, 2) {
+ enemiesInRange2 = append(enemiesInRange2, u)
+ break
+ }
+ }
+
+ if len(enemiesInRange2) == 0 {
+ kraken.gainResource(5)
+ } else {
+ for _, u := range enemiesInRange2 {
+ u.addMarks(UnitStates.Panic, 1)
+ }
+ }
}
func init() {
cardImplementations = map[string]cardImplementation{
- "base/advisor": &advisorImplementation{},
- "base/missionary": &missionaryImplementation{},
- "base/sword": &swordImplementation{},
-
- "misc/farmer": &farmerImplementation{},
+ "base/advisor": &advisorImpl{},
+ "base/missionary": &missionaryImpl{},
+ "base/sword": &swordImpl{},
- "kraken/tides_change!": &tidesChangeImplementation{},
+ "kraken/deja_vu!": &dejaVuImpl{},
+ "kraken/devour_the_poor!": &devourThePoorImpl{},
+ "kraken/drowned_sailor": &drownedSailorImpl{},
+ "kraken/flying_dutchmen": &flyingDutchmenImpl{},
+ "kraken/frost_pylon": &frostPylon{},
+ "kraken/gigantic_hail": &giganticHailImpl{},
+ "kraken/sold_out!": &soldOutImpl{},
+ "kraken/suprise!": &supriseImpl{},
+ "kraken/tentacle_slap": &tentacleSlapImpl{},
+ "kraken/tides_change!": &tidesChangeImpl{},
+ "kraken/unholy_cannonball": &unholyCannonballImpl{},
}
}
diff --git a/go/game/cardParsing.go b/go/game/cardParsing.go
index df78ade6..de1c7be4 100644
--- a/go/game/cardParsing.go
+++ b/go/game/cardParsing.go
@@ -12,12 +12,14 @@ type dynamicCardImplementation struct {
spawnTilesFunc func(*State, *Player) []*Tile
genFullActions func(*Unit) []*FullAction
genFreeActions func(Permanent) []*FreeAction
- _onEntering func(*Tile)
- _onLeaving func(*Tile)
- _onPlay func(*State, *Player, *Targets)
- _onPile func(Permanent)
- _onUnpile func(Permanent)
- _onDrop func(Permanent)
+
+ _stateBasedActions func(*State, Permanent)
+ _onEntering func(*Tile)
+ _onLeaving func(*Tile)
+ _onPlay func(*State, *Player, *Targets)
+ _onPile func(Permanent)
+ _onUnpile func(Permanent)
+ _onDrop func(Permanent)
}
func (impl *dynamicCardImplementation) spawnTiles(s *State, p *Player) []*Tile {
@@ -41,6 +43,12 @@ func (impl *dynamicCardImplementation) freeActions(p Permanent) []*FreeAction {
return nil
}
+func (impl *dynamicCardImplementation) stateBasedActions(s *State, p Permanent) {
+ if impl._stateBasedActions != nil {
+ impl._stateBasedActions(s, p)
+ }
+}
+
func (impl *dynamicCardImplementation) onEntering(t *Tile) {
if impl._onEntering != nil {
impl._onEntering(t)
diff --git a/go/game/map.go b/go/game/map.go
index 2115e0b0..b86debad 100644
--- a/go/game/map.go
+++ b/go/game/map.go
@@ -269,6 +269,10 @@ func (m *Map) AllTiles() []*Tile {
return m.FilterTiles(func(*Tile) bool { return true })
}
+func (m *Map) FreeTiles() []*Tile {
+ return m.FilterTiles(func(t *Tile) bool { return t.IsFree() })
+}
+
func (m *Map) distributeStoreCards(cards PileOfCards, rand *rand.Rand) {
nStores := len(m.Stores)
stores := make([]*Store, 0, nStores)
diff --git a/go/game/marks.go b/go/game/marks.go
new file mode 100644
index 00000000..a3ea0e32
--- /dev/null
+++ b/go/game/marks.go
@@ -0,0 +1,68 @@
+package game
+
+import (
+ "log"
+)
+
+type PermanentMark int
+
+const (
+ crack PermanentMark = iota + 1
+ paralysis
+ poison
+ panic_
+ rage
+ ward
+ faith
+)
+
+func (mark PermanentMark) String() string {
+ switch mark {
+ case crack:
+ return "crack"
+ case paralysis:
+ return "paralysis"
+ case poison:
+ return "poison"
+ case panic_:
+ return "panic"
+ case rage:
+ return "rage"
+ case ward:
+ return "ward"
+ case faith:
+ return "faith"
+ default:
+ log.Fatalf("Unknown permanent mark %d", mark)
+ return ""
+ }
+}
+
+var (
+ PermanentMarks = struct {
+ Crack PermanentMark
+ }{
+ Crack: crack,
+ }
+
+ unitStates = []PermanentMark{paralysis, poison, panic_, rage}
+ UnitStates = struct {
+ Paralysis PermanentMark
+ Poison PermanentMark
+ Panic PermanentMark
+ Rage PermanentMark
+ }{
+ Paralysis: paralysis,
+ Poison: poison,
+ Panic: panic_,
+ Rage: rage,
+ }
+
+ UnitMarks = struct {
+ Ward PermanentMark
+ Faith PermanentMark
+ }{
+ Ward: ward,
+ Faith: faith,
+ }
+)
diff --git a/go/game/permanent.go b/go/game/permanent.go
index 596e3c69..9188a206 100644
--- a/go/game/permanent.go
+++ b/go/game/permanent.go
@@ -14,12 +14,15 @@ type Permanent interface {
Tile() *Tile
SetTile(*Tile)
Damage() int
+ ContainingPerm() Permanent
Pile() []Permanent
Controller() *Player
Owner() *Player
Effects() []string
HasEffect(string) bool
XEffect(string) (int, error)
+ Marks(PermanentMark) int
+ addMarks(PermanentMark, int)
String() string
Fight(p Permanent)
@@ -29,8 +32,9 @@ type Permanent interface {
AvailActions() []Action
IsAvailableTile(*Tile) bool
- SetContainingPerm(p Permanent)
- AddPermanentToPile(p Permanent)
+ setContainingPerm(p Permanent)
+ addPermanentToPile(p Permanent)
+ clearPile()
RemovePermanentFromPile(p Permanent)
onPile(containing Permanent)
onUnpile(containing Permanent)
@@ -46,6 +50,7 @@ type PermanentBase struct {
controller *Player
owner *Player
tmpEffects []string
+ marks map[PermanentMark]int
}
func NewPermanentBase(card *Card, tile *Tile, owner *Player) PermanentBase {
@@ -61,33 +66,14 @@ func NewPermanentBase(card *Card, tile *Tile, owner *Player) PermanentBase {
}
}
-func (p *PermanentBase) Card() *Card {
- return p.card
-}
-
-func (p *PermanentBase) Tile() *Tile {
- return p.tile
-}
-
-func (p *PermanentBase) SetTile(t *Tile) {
- p.tile = t
-}
-
-func (p *PermanentBase) Damage() int {
- return p.damage
-}
-
-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) Card() *Card { return p.card }
+func (p *PermanentBase) Tile() *Tile { return p.tile }
+func (p *PermanentBase) SetTile(t *Tile) { p.tile = t }
+func (p *PermanentBase) Damage() int { return p.damage }
+func (p *PermanentBase) ContainingPerm() Permanent { return p.containingPerm }
+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) String() string {
if p.Tile() != nil {
@@ -143,18 +129,30 @@ func (p *PermanentBase) XEffect(effect string) (int, error) {
return x, err
}
-func (p *PermanentBase) IsAvailableTile(tile *Tile) bool {
- return tile.IsAvailableForCard(p.card)
+func (p *PermanentBase) Marks(mark PermanentMark) int {
+ if amount, found := p.marks[mark]; found {
+ return amount
+ }
+
+ return 0
}
-func (p *PermanentBase) SetContainingPerm(containing Permanent) {
- p.containingPerm = containing
+func (p *PermanentBase) addMarks(mark PermanentMark, amount int) {
+ if amount, found := p.marks[mark]; found {
+ p.marks[mark] += amount
+ } else {
+ p.marks[mark] = amount
+ }
}
-func (p *PermanentBase) AddPermanentToPile(a Permanent) {
- p.pile = append(p.pile, a)
+func (p *PermanentBase) IsAvailableTile(tile *Tile) bool {
+ return tile.IsAvailableForCard(p.card)
}
+func (p *PermanentBase) setContainingPerm(containing Permanent) { p.containingPerm = containing }
+func (p *PermanentBase) addPermanentToPile(a Permanent) { p.pile = append(p.pile, a) }
+func (p *PermanentBase) clearPile() { p.pile = nil }
+
func (p *PermanentBase) RemovePermanentFromPile(rm Permanent) {
for i, piled := range p.pile {
if piled != rm {
@@ -167,23 +165,32 @@ func (p *PermanentBase) RemovePermanentFromPile(rm Permanent) {
}
}
-func (b *PermanentBase) onPile(p Permanent) { b.Card().Impl.onPile(p) }
-func (b *PermanentBase) onUnpile(p Permanent) { b.Card().Impl.onUnpile(p) }
-func (b *PermanentBase) onDrop(p Permanent) {
- b.onUnpile(p)
- b.Card().Impl.onDrop(p)
+func (b *PermanentBase) onPile(containing Permanent) { b.Card().Impl.onPile(containing) }
+func (b *PermanentBase) onUnpile(containing Permanent) { b.Card().Impl.onUnpile(containing) }
+func (b *PermanentBase) onDrop(dropped Permanent) {
+ b.onUnpile(dropped.ContainingPerm())
+ b.Card().Impl.onDrop(dropped)
}
func AddPermanentToPile(containing, p Permanent) {
- p.SetContainingPerm(containing)
- containing.AddPermanentToPile(p)
+ p.setContainingPerm(containing)
+ containing.addPermanentToPile(p)
p.onPile(containing)
}
func RemovePermanentFromPile(containing, rm Permanent) {
containing.RemovePermanentFromPile(rm)
rm.onUnpile(containing)
- rm.SetContainingPerm(nil)
+ rm.setContainingPerm(nil)
+}
+
+func DropPile(containing Permanent) {
+ for _, p := range containing.Pile() {
+ p.onDrop(p)
+ p.setContainingPerm(nil)
+ }
+
+ // TODO: reset the containing's pile
}
func enterTile(p Permanent, t *Tile) {
diff --git a/go/game/player.go b/go/game/player.go
index b1cb6916..cb89e1ae 100644
--- a/go/game/player.go
+++ b/go/game/player.go
@@ -92,6 +92,12 @@ func (p *Player) BuyPhase() {
p.gameState.Stack.Resolve()
}
+func (p *Player) discardHand() {
+ for _, c := range p.Hand.Cards() {
+ p.DiscardCard(c)
+ }
+}
+
func (p *Player) DiscardCard(c *Card) {
p.Hand.MoveCard(c, p.DiscardPile)
}
diff --git a/go/game/state.go b/go/game/state.go
index 01cee403..5a4714f7 100644
--- a/go/game/state.go
+++ b/go/game/state.go
@@ -96,9 +96,11 @@ func (s *State) Loop() []*Player {
}
func (s *State) stateBasedActions() {
- for _, u := range s.Units {
- if u.IsDestroyed() {
- s.DestroyPermanent(u)
+ for _, p := range s.Permanents {
+ p.Card().Impl.stateBasedActions(s, p)
+
+ if p.IsDestroyed() {
+ s.DestroyPermanent(p)
}
}
}
diff --git a/go/game/tile.go b/go/game/tile.go
index a7bf2b26..510497f8 100644
--- a/go/game/tile.go
+++ b/go/game/tile.go
@@ -150,3 +150,22 @@ func (t *Tile) leaving(p Permanent) {
effect.onLeaving(p)
}
}
+
+func (t *Tile) addEffect(effect areaEffect) {
+ t.effects = append(t.effects, effect)
+}
+
+func (t *Tile) removeEffect(effect areaEffect) {
+ for i, e := range t.effects {
+ if e == effect {
+ t.effects[i] = t.effects[len(t.effects)-1]
+ t.effects = t.effects[:len(t.effects)-1]
+ break
+ }
+ }
+}
+
+func (t *Tile) neutralize() {
+ t.Type = TileTypes.Neutral
+ t.Water = false
+}
diff --git a/go/game/unit.go b/go/game/unit.go
index 82aa8528..a2934296 100644
--- a/go/game/unit.go
+++ b/go/game/unit.go
@@ -4,53 +4,6 @@ import (
"log"
)
-type UnitMark int
-
-const (
- paralysis UnitMark = iota + 1
- poison
- panic_
- rage
- ward
- faith
-)
-
-func (mark UnitMark) String() string {
- switch mark {
- case paralysis:
- return "paralysis"
- case poison:
- return "poison"
- case panic_:
- return "panic"
- case rage:
- return "rage"
- case ward:
- return "ward"
- case faith:
- return "faith"
- default:
- log.Fatalf("Unhandled unit mark %d", mark)
- return ""
- }
-}
-
-var UnitMarks = struct {
- Paralysis UnitMark
- Poison UnitMark
- Panic UnitMark
- Rage UnitMark
- Ward UnitMark
- Faith UnitMark
-}{
- Paralysis: paralysis,
- Poison: poison,
- Panic: panic_,
- Rage: rage,
- Ward: ward,
- Faith: faith,
-}
-
const (
DEFAULT_AVAIL_MOVE_ACTIONS = 1
DEFAULT_AVAIL_ATTACK_ACTIONS = 1
@@ -64,7 +17,6 @@ type Unit struct {
Upkeep int
FullActions []*FullAction
FreeActions []*FreeAction
- States map[UnitMark]int
// Effects []Effects
AvailMoveActions int
additionalMoveActions int
@@ -97,7 +49,6 @@ func NewUnit(card *Card, tile *Tile, owner *Player) *Unit {
Movement: movement,
Attack: attack,
Upkeep: upkeep,
- States: make(map[UnitMark]int),
AvailMoveActions: DEFAULT_AVAIL_MOVE_ACTIONS,
AvailAttackActions: DEFAULT_AVAIL_ATTACK_ACTIONS,
}
@@ -120,6 +71,7 @@ func (u *Unit) resetBaseActions() {
}
func (u *Unit) onUpkeep() {
+ // TODO: handle state marks
u.resetBaseActions()
}