summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2017-09-22 22:09:26 +0200
committerNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2017-09-22 22:09:26 +0200
commitdbad54ad228df4b70f56bf6be1380b6ae3064ac3 (patch)
treed912846d4948ebdee175ce3b6a7b97048e5995ce
parent5345adad33566e39570f067e61780e1af2dae4a7 (diff)
First shot at range indicators.
-rw-r--r--client/Makefile6
-rw-r--r--client/elm/battlemap/src/Battlemap/Location.elm20
-rw-r--r--client/elm/battlemap/src/Battlemap/RangeIndicator.elm214
-rw-r--r--client/elm/battlemap/src/Model.elm9
-rw-r--r--client/elm/battlemap/src/Shim/Model.elm3
-rw-r--r--client/elm/battlemap/src/Update/SelectCharacter.elm11
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
+ )
)
}