aboutsummaryrefslogtreecommitdiff
path: root/go/game/targets.go
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fischer@muhq.space>2023-02-25 23:08:47 +0100
committerFlorian Fischer <florian.fischer@muhq.space>2025-08-20 15:57:06 +0200
commit3d36d1d0254b8aeecc889a2a49cbcced458cbe9c (patch)
tree38dd0851d8eaa6535d05b97f29f65fc35655a5ef /go/game/targets.go
parent19fb1a7e5c5883f49e944b6499fa1ced207a3e39 (diff)
downloadmuhqs-game-3d36d1d0254b8aeecc889a2a49cbcced458cbe9c.tar.gz
muhqs-game-3d36d1d0254b8aeecc889a2a49cbcced458cbe9c.zip
intermediate commit
* Implement move artifact action * Fix widget update memory leak * update the highlights not during on each frame * do not update the unchanged label of a button * Allow to exit the game by pressing 'q' * Implement some cards from the magic set * Improve permanent formatting * Some tweaks to UnitAI code
Diffstat (limited to 'go/game/targets.go')
-rw-r--r--go/game/targets.go96
1 files changed, 71 insertions, 25 deletions
diff --git a/go/game/targets.go b/go/game/targets.go
index 1e80c06d..fb393057 100644
--- a/go/game/targets.go
+++ b/go/game/targets.go
@@ -35,14 +35,7 @@ type (
}
)
-func fmtSel(sel interface{}) string {
- switch t := sel.(type) {
- case *Tile:
- return t.Position.String()
- default:
- return fmt.Sprintf("%d", t)
- }
-}
+var INVALID_TARGET_DESC = TargetDesc{}
func (t *Target) String() string {
if len(t.sel) == 0 {
@@ -50,12 +43,28 @@ func (t *Target) String() string {
}
if len(t.sel) == 1 {
- return fmtSel(t.sel[0])
+ return fmt.Sprintf("%v", t.sel[0])
}
s := "["
for _, sel := range t.sel {
- s += fmt.Sprintf("%s ", fmtSel(sel))
+ s += fmt.Sprintf("%v ", sel)
+ }
+ return s[:len(s)-1] + "]"
+}
+
+func (t *Targets) String() string {
+ if len(t.ts) == 0 {
+ return "no targets"
+ }
+
+ if len(t.ts) == 1 {
+ return t.ts[0].String()
+ }
+
+ s := "["
+ for _, t := range t.ts {
+ s += fmt.Sprintf("%v ", t)
}
return s[:len(s)-1] + "]"
}
@@ -114,6 +123,30 @@ func newPileDropTargets(s *State, a *PileDropAction) *Targets {
return targets
}
+func newArtifactMoveTargets(s *State, a *ArtifactMoveAction) *Targets {
+ targets := newTargets()
+ targets.ts = make([]*Target, 0, 2)
+
+ u := a.Source().(*Unit)
+ desc := newTargetDesc("available tile")
+ constraints := []TargetConstraintFunc{tileTargetConstraint}
+ constraints = append(constraints, availableTileConstraint(a, u.Card()))
+ constraints = append(constraints, moveConstraint(s, a, u))
+ moveTarget := newConstraintTarget(s, desc, conjunction(constraints...), a)
+ targets.ts = append(targets.ts, moveTarget)
+
+ constraints = []TargetConstraintFunc{tileTargetConstraint}
+ constraints = append(constraints, availableTileConstraint(a, a.Artifact.Card()))
+ constraints = append(constraints, func(t interface{}) error {
+ c := rangeTargetConstraint(moveTarget.sel[0], 1)
+ return c(t)
+ })
+ constraints = append(constraints, noPreviousSelectionConstraint(targets, 1))
+ targets.ts = append(targets.ts, newConstraintTarget(s, desc, conjunction(constraints...), a))
+
+ return targets
+}
+
func (d *TargetDesc) requirement() TargetRequirement {
switch d.req {
case "?":
@@ -458,13 +491,7 @@ func parseArtifactTargetConstraint(constraint string, s *State, action Action) [
return constraints
}
-func relaxedTileTarget(action Action, t interface{}) *Tile {
- // Strict case
- if _, ok := action.(*MoveAction); !ok {
- return t.(*Tile)
- }
-
- // Move actions allow to also move to Tile occupied by a crewable permanent
+func _relaxedTileTarget(t interface{}) *Tile {
switch t := t.(type) {
case *Tile:
return t
@@ -477,6 +504,21 @@ func relaxedTileTarget(action Action, t interface{}) *Tile {
return nil
}
+func relaxedTileTarget(action Action, t interface{}) *Tile {
+ switch action.(type) {
+ // Some actions allow to also move to Tile occupied by a crewable permanent
+ case *MoveAction:
+ return _relaxedTileTarget(t)
+ case *ArtifactMoveAction:
+ return _relaxedTileTarget(t)
+ case *ArtifactSwitchAction:
+ return _relaxedTileTarget(t)
+ // Strict case
+ default:
+ return t.(*Tile)
+ }
+}
+
func availableTileConstraint(action Action, card *Card) TargetConstraintFunc {
return func(t interface{}) (err error) {
tile := relaxedTileTarget(action, t)
@@ -492,19 +534,23 @@ func availableTileConstraint(action Action, card *Card) TargetConstraintFunc {
}
}
+func moveConstraint(s *State, action Action, u *Unit) TargetConstraintFunc {
+ return func(t interface{}) (err error) {
+ // Some actions allow also unit targets as though they were tiles
+ tile := relaxedTileTarget(action, t)
+ if slices.Contains(u.MoveRangeTiles(s.Map), tile) {
+ return nil
+ }
+ return fmt.Errorf("tile %v is not in %v's movement range", tile, u)
+ }
+}
+
func parseTileTargetConstraint(desc string, s *State, action Action) []TargetConstraintFunc {
constraints := []TargetConstraintFunc{}
if moveAction, ok := action.(*MoveAction); ok {
u := moveAction.Source().(*Unit)
- constraints = append(constraints, func(t interface{}) (err error) {
- tile := relaxedTileTarget(action, t)
- if slices.Contains(u.MoveRangeTiles(s.Map), tile) {
- return nil
- }
- return fmt.Errorf("tile %v is not in %v's movement range", tile, u)
- })
- // Move action allow also unit targets as though they were tiles
+ constraints = append(constraints, moveConstraint(s, action, u))
} else {
constraints = append(constraints, tileTargetConstraint)
}