aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fischer@muhq.space>2023-02-04 13:01:50 +0100
committerFlorian Fischer <florian.fischer@muhq.space>2025-01-27 16:43:46 +0100
commite13a0c10d627c10b52d0b0d694214cce8d1044e8 (patch)
treeb8784c31c9d2e1b80721a86c4135ec08b6396d9c
parent3e92fa1272ff37ef8ccf0d295925a66a4787110f (diff)
downloadmuhqs-game-e13a0c10d627c10b52d0b0d694214cce8d1044e8.tar.gz
muhqs-game-e13a0c10d627c10b52d0b0d694214cce8d1044e8.zip
change attack action target to 'attackable enemy permanent'
Implement attackable constraint.
-rw-r--r--go/game/action.go2
-rw-r--r--go/game/targets.go63
2 files changed, 62 insertions, 3 deletions
diff --git a/go/game/action.go b/go/game/action.go
index 4894d47d..b41a08bf 100644
--- a/go/game/action.go
+++ b/go/game/action.go
@@ -169,7 +169,7 @@ type AttackAction struct {
ActionBase
}
-const attackActionTargetDesc = "attackable permanent"
+const attackActionTargetDesc = "attackable enemy permanent"
func NewAttackAction(u *Unit) *AttackAction {
a := &AttackAction{ActionBase{
diff --git a/go/game/targets.go b/go/game/targets.go
index 1a8c7ab3..11918fdf 100644
--- a/go/game/targets.go
+++ b/go/game/targets.go
@@ -84,6 +84,10 @@ func (t *Targets) Options() [][]interface{} {
}
func (t *Targets) NextOptions() []interface{} {
+ if len(t.constrains) == 0 {
+ return nil
+ }
+
next := len(t.sel)
return t.constrains[next].options(t.s)
}
@@ -110,7 +114,9 @@ func (t *Targets) CheckTargets(s *State) error {
func targetConstrain(desc string, s *State, action Action) TargetConstrainFunc {
constrains := []TargetConstrainFunc{}
- if strings.Contains(desc, "unit") {
+ if strings.Contains(desc, "permanent") {
+ constrains = append(constrains, parsePermanentTargetConstrain(desc, s, action)...)
+ } else if strings.Contains(desc, "unit") {
constrains = append(constrains, parseUnitTargetConstrain(desc, s, action)...)
} else if strings.Contains(desc, "artifact") {
constrains = append(constrains, parseArtifactTargetConstrain(desc, s, action)...)
@@ -154,6 +160,24 @@ func enemyPermanentTargetConstrain(action Action) TargetConstrainFunc {
}
}
+func attackableTargetConstrain(action Action) TargetConstrainFunc {
+ return func(t interface{}) (err error) {
+ p, _ := t.(Permanent)
+ if !p.Attackable() {
+ err = fmt.Errorf("Permanent %s isnot attackable", p)
+ }
+
+ if attackAction, ok := action.(*AttackAction); ok {
+ attacker := attackAction.Source().(*Unit)
+ if !IsPositionInRange(attacker.Tile().Position, p.Tile().Position, attacker.Attack.MaxRange()) {
+ err = fmt.Errorf("Position %s of target %s not in attack range %d of source's position %s",
+ p.Tile().Position, p, attacker.Attack.MaxRange(), attacker.Tile().Position)
+ }
+ }
+ return
+ }
+}
+
func rangeTargetConstrain(source interface{}, r int) TargetConstrainFunc {
var sourcePos Position
switch source := source.(type) {
@@ -175,6 +199,38 @@ func rangeTargetConstrain(source interface{}, r int) TargetConstrainFunc {
}
}
+var permanentTargetConstrain TargetConstrainFunc = func(t interface{}) (err error) {
+ _, ok := t.(Permanent)
+ if !ok {
+ err = fmt.Errorf("target is %T not Permanent", t)
+ }
+ return
+}
+
+func parsePermanentTargetConstrain(desc string, s *State, action Action) []TargetConstrainFunc {
+ constrains := []TargetConstrainFunc{permanentTargetConstrain}
+
+ if strings.Contains(desc, "enemy permanent") {
+ constrains = append(constrains, enemyPermanentTargetConstrain(action))
+ }
+
+ if strings.Contains(desc, "attackable ") {
+ log.Println("adding attackable contrained")
+ constrains = append(constrains, attackableTargetConstrain(action))
+ }
+
+ if strings.Contains(desc, " in range ") {
+ tokens := strings.SplitN(desc, " in range ", 2)
+ r, err := strconv.Atoi(tokens[1])
+ if err != nil {
+ log.Fatalf("Invalid range %s in target constrain %s", tokens[1], desc)
+ }
+ constrains = append(constrains, rangeTargetConstrain(action, r))
+ }
+
+ return constrains
+}
+
var unitTargetConstrain TargetConstrainFunc = func(t interface{}) (err error) {
_, ok := t.(*Unit)
if !ok {
@@ -296,7 +352,10 @@ func (c *TargetConstrain) options(s *State) (options []interface{}) {
}
func targetCandidates(desc string, s *State) []interface{} {
- if strings.Contains(desc, "unit") || strings.Contains(desc, "artifact") {
+ if strings.Contains(desc, "unit") ||
+ strings.Contains(desc, "artifact") ||
+ strings.Contains(desc, "permanent") {
+
return utils.TypedSliceToInterfaceSlice(s.Permanents)
} else if strings.Contains(desc, "tile") {
return utils.TypedSliceToInterfaceSlice(s.Map.AllTiles())