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 + ) ) } |