diff options
| author | Florian Fischer <florian.fischer@muhq.space> | 2023-02-25 23:08:47 +0100 |
|---|---|---|
| committer | Florian Fischer <florian.fischer@muhq.space> | 2025-08-20 15:57:06 +0200 |
| commit | 3d36d1d0254b8aeecc889a2a49cbcced458cbe9c (patch) | |
| tree | 38dd0851d8eaa6535d05b97f29f65fc35655a5ef /go/game/targets.go | |
| parent | 19fb1a7e5c5883f49e944b6499fa1ced207a3e39 (diff) | |
| download | muhqs-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.go | 96 |
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) } |
