| summaryrefslogtreecommitdiff | 
diff options
| author | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2017-09-22 22:09:26 +0200 | 
|---|---|---|
| committer | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2017-09-22 22:09:26 +0200 | 
| commit | dbad54ad228df4b70f56bf6be1380b6ae3064ac3 (patch) | |
| tree | d912846d4948ebdee175ce3b6a7b97048e5995ce | |
| parent | 5345adad33566e39570f067e61780e1af2dae4a7 (diff) | |
First shot at range indicators.
| -rw-r--r-- | client/Makefile | 6 | ||||
| -rw-r--r-- | client/elm/battlemap/src/Battlemap/Location.elm | 20 | ||||
| -rw-r--r-- | client/elm/battlemap/src/Battlemap/RangeIndicator.elm | 214 | ||||
| -rw-r--r-- | client/elm/battlemap/src/Model.elm | 9 | ||||
| -rw-r--r-- | client/elm/battlemap/src/Shim/Model.elm | 3 | ||||
| -rw-r--r-- | client/elm/battlemap/src/Update/SelectCharacter.elm | 11 | 
6 files changed, 260 insertions, 3 deletions
| diff --git a/client/Makefile b/client/Makefile index 5746f57..41a4273 100644 --- a/client/Makefile +++ b/client/Makefile @@ -1,6 +1,10 @@  TARGETS = battlemap +PAGES = $(addsuffix .html,$(TARGETS)) -all: $(TARGETS) $(addsuffix .html,$(TARGETS)) +all: $(TARGETS) $(PAGES) + +upload_demo: $(PAGES) +	scp -r $^ dreamhost:~/tacticians.online/  $(TARGETS):  	$(MAKE) -C elm/$@ index.html diff --git a/client/elm/battlemap/src/Battlemap/Location.elm b/client/elm/battlemap/src/Battlemap/Location.elm index 4f70e49..36f0c4d 100644 --- a/client/elm/battlemap/src/Battlemap/Location.elm +++ b/client/elm/battlemap/src/Battlemap/Location.elm @@ -22,3 +22,23 @@ neighbor loc dir =  get_ref : Type -> Ref  get_ref l =     (l.x, l.y) + +from_ref : Ref -> Type +from_ref (x, y) = +   {x = x, y = y} + +dist : Type -> Type -> Int +dist loc_a loc_b = +   if (loc_a.x > loc_b.x) +   then +      if (loc_a.y > loc_b.y) +      then +         ((loc_a.x - loc_b.x) + (loc_a.y - loc_b.y)) +      else +         ((loc_a.x - loc_b.x) + (loc_b.y - loc_a.y)) +   else +      if (loc_a.y > loc_b.y) +      then +         ((loc_b.x - loc_a.x) + (loc_a.y - loc_b.y)) +      else +         ((loc_b.x - loc_a.x) + (loc_b.y - loc_a.y)) diff --git a/client/elm/battlemap/src/Battlemap/RangeIndicator.elm b/client/elm/battlemap/src/Battlemap/RangeIndicator.elm new file mode 100644 index 0000000..3311f42 --- /dev/null +++ b/client/elm/battlemap/src/Battlemap/RangeIndicator.elm @@ -0,0 +1,214 @@ +module Battlemap.RangeIndicator exposing (Type, generate) + +import Dict +import List + +import Battlemap +import Battlemap.Direction +import Battlemap.Location + +import Util.List + +type alias Type = +   { +      distance: Int, +      path: (List Battlemap.Direction.Type), +      node_cost: Int +   } + +generate_grid : ( +      Battlemap.Location.Type -> +      Int -> +      Int -> +      Int -> +      Int -> +      (List Battlemap.Location.Type) -> +      (List Battlemap.Location.Type) +   ) +generate_grid src max_dist curr_dist curr_y_mod curr_x_mod curr_list = +   if (curr_x_mod > curr_dist) +   then +      if (curr_y_mod > max_dist) +      then +         curr_list +      else +         let +            new_limit = (max_dist - (abs curr_y_mod)) +         in +         (generate_grid +            src +            max_dist +            new_limit +            (curr_y_mod + 1) +            (-new_limit) +            curr_list +         ) +   else +         (generate_grid +            src +            max_dist +            curr_dist +            curr_y_mod +            (curr_x_mod + 1) +            ({x = (src.x + curr_x_mod), y = (src.y + curr_y_mod)} :: curr_list) +         ) + +get_closest : ( +      Battlemap.Location.Ref -> +      Type -> +      (Battlemap.Location.Ref, Type) -> +      (Battlemap.Location.Ref, Type) +   ) +get_closest ref indicator (prev_ref, prev_indicator) = +   if (indicator.distance < prev_indicator.distance) +   then +      (ref, indicator) +   else +      (prev_ref, prev_indicator) + +handle_neighbors : ( +      Battlemap.Location.Type -> +      Type -> +      (Dict.Dict Battlemap.Location.Ref Type) -> +      (List Battlemap.Direction.Type) -> +      (Dict.Dict Battlemap.Location.Ref Type) +   ) +handle_neighbors loc indicator remaining directions = +   case (Util.List.pop directions) of +      Nothing -> remaining +      (Just (head, tail)) -> +         let +            neighbor_loc = (Battlemap.Location.neighbor loc head) +            neighbor_indicator = +               (Dict.get +                  (Battlemap.Location.get_ref neighbor_loc) +                  remaining +               ) +         in +            case neighbor_indicator of +               Nothing -> (handle_neighbors loc indicator remaining tail) +               (Just neighbor) -> +                  let +                     new_dist = (indicator.distance + neighbor.node_cost) +                  in +                     (handle_neighbors +                        loc +                        indicator +                        ( +                           if (new_dist < neighbor.distance) +                           then +                              (Dict.insert +                                 (Battlemap.Location.get_ref neighbor_loc) +                                 {neighbor | +                                    distance = new_dist, +                                    path = (head :: indicator.path) +                                 } +                                 remaining +                              ) +                           else +                              remaining +                        ) +                        tail +                     ) + +search : ( +      (Dict.Dict Battlemap.Location.Ref Type) -> +      (Dict.Dict Battlemap.Location.Ref Type) -> +      Int -> +      (Dict.Dict Battlemap.Location.Ref Type) +   ) +search result remaining dist = +   if (Dict.isEmpty remaining) +   then +      result +   else +      let +         (min_loc_ref, min) = +            (Dict.foldl +               (get_closest) +               ( +                  (-1,-1), +                  { +                     distance = (dist + 1), +                     path = [], +                     node_cost = 99 +                  } +               ) +               remaining +            ) +      in +         (search +            (Dict.insert min_loc_ref min result) +            (handle_neighbors +               (Battlemap.Location.from_ref min_loc_ref) +               min +               (Dict.remove min_loc_ref remaining) +               [ +                  Battlemap.Direction.Left, +                  Battlemap.Direction.Right, +                  Battlemap.Direction.Up, +                  Battlemap.Direction.Down +               ] +            ) +            dist +         ) + +grid_to_range_indicators : ( +      Battlemap.Type -> +      Battlemap.Location.Type -> +      Int -> +      (List Battlemap.Location.Type) -> +      (Dict.Dict Battlemap.Location.Ref Type) -> +      (Dict.Dict Battlemap.Location.Ref Type) +   ) +grid_to_range_indicators battlemap location dist grid result = +   case (Util.List.pop grid) of +      Nothing -> result +      (Just (head, tail)) -> +         if (Battlemap.has_location battlemap head) +         then +            -- TODO: test if the current char can cross that tile. +            -- TODO: get tile cost. +            (grid_to_range_indicators +               battlemap +               location +               dist +               tail +               (Dict.insert +                  (Battlemap.Location.get_ref head) +                  { +                     distance = +                        ( +                           if ((location.x == head.x) && (location.y == head.y)) +                           then +                              0 +                           else +                              (dist + 1) +                        ), +                     path = [], +                     node_cost = 1 +                  } +                  result +               ) +            ) +         else +            (grid_to_range_indicators battlemap location dist tail result) + +generate : ( +      Battlemap.Type -> +      Battlemap.Location.Type -> +      Int -> +      (Dict.Dict Battlemap.Location.Ref Type) +   ) +generate battlemap location dist = +   (search +      Dict.empty +      (grid_to_range_indicators +         battlemap +         location +         dist +         (generate_grid location dist 0 (-dist) (-dist) []) +         Dict.empty +      ) +      dist +   ) diff --git a/client/elm/battlemap/src/Model.elm b/client/elm/battlemap/src/Model.elm index b8782f2..3bc240e 100644 --- a/client/elm/battlemap/src/Model.elm +++ b/client/elm/battlemap/src/Model.elm @@ -4,6 +4,8 @@ import Dict  import Battlemap  import Battlemap.Navigator +import Battlemap.Location +import Battlemap.RangeIndicator  import Character @@ -15,7 +17,12 @@ type alias Type =        battlemap: Battlemap.Type,        navigator: (Maybe Battlemap.Navigator.Type),        selection: (Maybe String), -      characters: (Dict.Dict Character.Ref Character.Type) +      characters: (Dict.Dict Character.Ref Character.Type), +      range_indicator: +         (Dict.Dict +            Battlemap.Location.Ref +            Battlemap.RangeIndicator.Type +         )     }  model : Type diff --git a/client/elm/battlemap/src/Shim/Model.elm b/client/elm/battlemap/src/Shim/Model.elm index 517f80d..0371b53 100644 --- a/client/elm/battlemap/src/Shim/Model.elm +++ b/client/elm/battlemap/src/Shim/Model.elm @@ -46,5 +46,6 @@ generate =                    Dict.empty                 )              ) -         ) +         ), +      range_indicator = Dict.empty     } diff --git a/client/elm/battlemap/src/Update/SelectCharacter.elm b/client/elm/battlemap/src/Update/SelectCharacter.elm index b80eda7..7ee8dfa 100644 --- a/client/elm/battlemap/src/Update/SelectCharacter.elm +++ b/client/elm/battlemap/src/Update/SelectCharacter.elm @@ -8,6 +8,7 @@ import Battlemap  import Battlemap.Direction  import Battlemap.Navigator  import Battlemap.Tile +import Battlemap.RangeIndicator  import Model @@ -30,5 +31,15 @@ apply_to model char_id =                       char.movement_points                    )                 ) +         ), +      range_indicator = +         (case (Dict.get char_id model.characters) of +            Nothing -> Dict.empty +            (Just char) -> +               (Battlemap.RangeIndicator.generate +                  model.battlemap +                  char.location +                  char.movement_points +               )           )     } | 


