summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornsensfel <SpamShield0@noot-noot.org>2018-06-15 13:47:17 +0200
committernsensfel <SpamShield0@noot-noot.org>2018-06-15 13:47:17 +0200
commit36992b435c76326bc575f75efbafac54dc2757a0 (patch)
tree336bbe09bf38ffa1f66504307ab136b2e3df6972 /src/battlemap
parent1e14bb938ab22976a63342bbd7b7fd2611588338 (diff)
Cleans up RangeIndicator.elm, tries marker icons.
Not satisfied with the current look of those markers, though.
Diffstat (limited to 'src/battlemap')
-rw-r--r--src/battlemap/src/Struct/Navigator.elm2
-rw-r--r--src/battlemap/src/Struct/RangeIndicator.elm352
-rw-r--r--src/battlemap/www/style.css74
3 files changed, 273 insertions, 155 deletions
diff --git a/src/battlemap/src/Struct/Navigator.elm b/src/battlemap/src/Struct/Navigator.elm
index 1b3f170..46ad92c 100644
--- a/src/battlemap/src/Struct/Navigator.elm
+++ b/src/battlemap/src/Struct/Navigator.elm
@@ -80,7 +80,7 @@ new start_loc mov_dist atk_dist def_dist cost_fun =
start_loc
mov_dist
atk_dist
- 0
+ def_dist
(cost_fun)
),
cost_fun = cost_fun
diff --git a/src/battlemap/src/Struct/RangeIndicator.elm b/src/battlemap/src/Struct/RangeIndicator.elm
index 06b34ec..2b70ecd 100644
--- a/src/battlemap/src/Struct/RangeIndicator.elm
+++ b/src/battlemap/src/Struct/RangeIndicator.elm
@@ -6,8 +6,6 @@ module Struct.RangeIndicator exposing
get_path
)
--- FIXME: This module is still too much of a mess...
-
-- Elm -------------------------------------------------------------------------
import Dict
import List
@@ -31,6 +29,19 @@ type alias Type =
marker: Struct.Marker.Type
}
+type alias SearchParameters =
+ {
+ maximum_distance: Int,
+ maximum_attack_range: Int,
+ minimum_defense_range: Int,
+ cost_function: (Struct.Location.Type -> Int)
+ }
+
+type alias LocatedIndicator =
+ {
+ location_ref: Struct.Location.Ref,
+ indicator: Type
+ }
--------------------------------------------------------------------------------
-- LOCAL -----------------------------------------------------------------------
--------------------------------------------------------------------------------
@@ -38,186 +49,238 @@ get_closest : (
Int ->
Struct.Location.Ref ->
Type ->
- (Struct.Location.Ref, Type) ->
- (Struct.Location.Ref, Type)
+ LocatedIndicator ->
+ LocatedIndicator
)
-get_closest dist ref indicator (prev_ref, prev_indicator) =
- if
+get_closest max_dist ref indicator current_best =
+ if (is_closer max_dist indicator current_best.indicator)
+ then
+ {
+ location_ref = ref,
+ indicator = indicator
+ }
+ else
+ current_best
+
+is_closer : Int -> Type -> Type -> Bool
+is_closer max_dist candidate current =
(
- (indicator.distance < prev_indicator.distance)
+ -- It's closer when moving
+ (candidate.distance < current.distance)
||
(
- (indicator.distance > dist)
- && (prev_indicator.distance > dist)
- && (indicator.atk_range < prev_indicator.atk_range)
+ -- Or neither are reachable by moving,
+ (max_dist <= candidate.distance)
+ && (max_dist <= current.distance)
+ -- but the new one is closer when attacking.
+ && (candidate.atk_range < current.atk_range)
)
)
- then
- (ref, indicator)
- else
- (prev_ref, prev_indicator)
-is_closer : Int -> Int -> Type -> Bool
-is_closer new_dist new_range neighbor =
+generate_neighbor : (
+ SearchParameters ->
+ Struct.Location.Type ->
+ Struct.Direction.Type ->
+ Type ->
+ (Int, Type)
+ )
+generate_neighbor search_params neighbor_loc dir src_indicator =
+ let
+ node_cost = (search_params.cost_function neighbor_loc)
+ new_dist = (src_indicator.distance + node_cost)
+ new_atk_range = (src_indicator.atk_range + 1)
+ new_true_range = (src_indicator.true_range + 1)
+ can_defend = (new_true_range > search_params.minimum_defense_range)
+ in
+ if (new_dist > search_params.maximum_distance)
+ then
+ (
+ node_cost,
+ {
+ distance = (search_params.maximum_distance + 1),
+ atk_range = new_atk_range,
+ true_range = new_true_range,
+ path = (dir :: src_indicator.path),
+ marker =
+ if (can_defend)
+ then
+ Struct.Marker.CanAttackCanDefend
+ else
+ Struct.Marker.CanAttackCantDefend
+ }
+ )
+ else
+ (
+ node_cost,
+ {
+ distance = new_dist,
+ atk_range = 0,
+ true_range = new_true_range,
+ path = (dir :: src_indicator.path),
+ marker =
+ if (can_defend)
+ then
+ Struct.Marker.CanGoToCanDefend
+ else
+ Struct.Marker.CanGoToCantDefend
+ }
+ )
+
+candidate_is_acceptable : (SearchParameters -> Int -> Type -> Bool)
+candidate_is_acceptable search_params cost candidate =
+ (cost /= Constants.Movement.cost_when_out_of_bounds)
+ &&
(
- (new_dist < neighbor.distance)
+ (candidate.distance <= search_params.maximum_distance)
||
- (
- (neighbor.distance > new_dist)
- && (new_range < neighbor.atk_range)
- )
+ (candidate.atk_range <= search_params.maximum_attack_range)
)
+candidate_is_an_improvement : (
+ SearchParameters ->
+ Struct.Location.Ref ->
+ Type ->
+ (Dict.Dict Struct.Location.Ref Type) ->
+ Bool
+ )
+candidate_is_an_improvement search_params loc_ref candidate alternatives =
+ case (Dict.get loc_ref alternatives) of
+ (Just alternative) ->
+ (is_closer search_params.maximum_distance candidate alternative)
+
+ Nothing ->
+ True
handle_neighbors : (
- Type ->
- Struct.Location.Type ->
- Int ->
- Int ->
- Int ->
+ LocatedIndicator ->
(Dict.Dict Struct.Location.Ref Type) ->
- (Struct.Location.Type -> Int) ->
+ SearchParameters ->
Struct.Direction.Type ->
(Dict.Dict Struct.Location.Ref Type) ->
(Dict.Dict Struct.Location.Ref Type)
)
-handle_neighbors
- src_indicator src_loc
- dist
- atk_range def_range
- results cost_fun dir rem =
+handle_neighbors src results search_params dir remaining =
let
+ src_loc = (Struct.Location.from_ref src.location_ref)
neighbor_loc = (Struct.Location.neighbor dir src_loc)
+ neighbor_loc_ref = (Struct.Location.get_ref neighbor_loc)
in
- case (Dict.get (Struct.Location.get_ref neighbor_loc) results) of
- (Just _) -> rem
+ case (Dict.get neighbor_loc_ref results) of
+ (Just _) ->
+ -- A minimal path for this location has already been found
+ remaining
Nothing ->
let
- node_cost = (cost_fun neighbor_loc)
- new_dist = (src_indicator.distance + node_cost)
- new_atk_range = (src_indicator.atk_range + 1)
- new_true_range = (src_indicator.true_range + 1)
- can_defend = (new_true_range >= def_range)
+ (candidate_cost, candidate) =
+ (generate_neighbor
+ search_params
+ neighbor_loc
+ dir
+ src.indicator
+ )
in
if
- (
- (
- case
- (Dict.get
- (Struct.Location.get_ref neighbor_loc)
- rem
- )
- of
- (Just neighbor) ->
- (is_closer new_dist new_atk_range neighbor)
-
- Nothing ->
- True
- )
- &&
- (node_cost /= Constants.Movement.cost_when_out_of_bounds)
- &&
- (
- (new_dist <= dist)
- ||
- (new_atk_range <= atk_range)
- )
+ (
+ (candidate_is_acceptable
+ search_params
+ candidate_cost
+ candidate
)
- then
- (Dict.insert
- (Struct.Location.get_ref neighbor_loc)
- (
- if (new_dist > dist)
- then
- {
- distance = (dist + 1),
- atk_range = new_atk_range,
- true_range = new_true_range,
- path = (dir :: src_indicator.path),
- marker =
- if (can_defend)
- then
- Struct.Marker.CanAttackCanDefend
- else
- Struct.Marker.CanAttackCantDefend
- }
- else
- {
- distance = new_dist,
- atk_range = 0,
- true_range = new_true_range,
- path = (dir :: src_indicator.path),
- marker =
- if (can_defend)
- then
- Struct.Marker.CanGoToCanDefend
- else
- Struct.Marker.CanGoToCantDefend
- }
- )
- rem
+ &&
+ (candidate_is_an_improvement
+ search_params
+ neighbor_loc_ref
+ candidate
+ remaining
)
+ )
+ then
+ (Dict.insert neighbor_loc_ref candidate remaining)
else
- rem
+ remaining
+
+find_closest_in : (
+ SearchParameters ->
+ (Dict.Dict Struct.Location.Ref Type) ->
+ LocatedIndicator
+ )
+find_closest_in search_params remaining =
+ (Dict.foldl
+ (get_closest search_params.maximum_distance)
+ {
+ location_ref = (-1, -1),
+ indicator =
+ {
+ distance = Constants.Movement.cost_when_out_of_bounds,
+ path = [],
+ atk_range = Constants.Movement.cost_when_out_of_bounds,
+ true_range = Constants.Movement.cost_when_out_of_bounds,
+ marker = Struct.Marker.CanAttackCanDefend
+ }
+ }
+ remaining
+ )
+
+resolve_marker_type : SearchParameters -> Type -> Type
+resolve_marker_type search_params indicator =
+ {indicator |
+ marker =
+ case
+ (
+ (indicator.atk_range > 0),
+ (indicator.true_range <= search_params.minimum_defense_range)
+ )
+ of
+ (True, True) -> Struct.Marker.CanAttackCantDefend
+ (True, False) -> Struct.Marker.CanAttackCanDefend
+ (False, True) -> Struct.Marker.CanGoToCantDefend
+ (False, False) -> Struct.Marker.CanGoToCanDefend
+ }
+
+insert_in_dictionary : (
+ LocatedIndicator ->
+ (Dict.Dict Struct.Location.Ref Type) ->
+ (Dict.Dict Struct.Location.Ref Type)
+ )
+insert_in_dictionary located_indicator dict =
+ (Dict.insert
+ located_indicator.location_ref
+ located_indicator.indicator
+ dict
+ )
search : (
(Dict.Dict Struct.Location.Ref Type) ->
(Dict.Dict Struct.Location.Ref Type) ->
- Int ->
- Int ->
- Int ->
- (Struct.Location.Type -> Int) ->
+ SearchParameters ->
(Dict.Dict Struct.Location.Ref Type)
)
-search result remaining dist atk_range def_range cost_fun =
+search result remaining search_params =
if (Dict.isEmpty remaining)
then
result
else
let
- (min_loc_ref, min) =
- (Dict.foldl
- (get_closest dist)
- (
- (-1,-1),
- {
- distance = Constants.Movement.cost_when_out_of_bounds,
- path = [],
- atk_range = Constants.Movement.cost_when_out_of_bounds,
- true_range = Constants.Movement.cost_when_out_of_bounds,
- marker = Struct.Marker.CanAttackCanDefend
- }
- )
- remaining
- )
+ closest_located_indicator = (find_closest_in search_params remaining)
+ finalized_clos_loc_ind =
+ {closest_located_indicator|
+ indicator =
+ (resolve_marker_type
+ search_params
+ closest_located_indicator.indicator
+ )
+ }
in
(search
- (Dict.insert
- min_loc_ref
- {min |
- marker =
- case
- ((min.atk_range > 0), (min.true_range <= def_range))
- of
- (True, True) -> Struct.Marker.CanAttackCantDefend
- (True, False) -> Struct.Marker.CanAttackCanDefend
- (False, True) -> Struct.Marker.CanGoToCantDefend
- (False, False) -> Struct.Marker.CanGoToCanDefend
- }
- result
- )
+ (insert_in_dictionary finalized_clos_loc_ind result)
(List.foldl
(handle_neighbors
- min
- (Struct.Location.from_ref min_loc_ref)
- dist
- atk_range
- def_range
+ finalized_clos_loc_ind
result
- (cost_fun)
+ search_params
)
- (Dict.remove min_loc_ref remaining)
+ (Dict.remove finalized_clos_loc_ind.location_ref remaining)
[
Struct.Direction.Left,
Struct.Direction.Right,
@@ -225,10 +288,7 @@ search result remaining dist atk_range def_range cost_fun =
Struct.Direction.Down
]
)
- dist
- atk_range
- def_range
- (cost_fun)
+ search_params
)
--------------------------------------------------------------------------------
@@ -242,7 +302,7 @@ generate : (
(Struct.Location.Type -> Int) ->
(Dict.Dict Struct.Location.Ref Type)
)
-generate location dist atk_range def_range cost_fun =
+generate location max_dist atk_range def_range cost_fun =
(search
Dict.empty
(Dict.insert
@@ -261,10 +321,12 @@ generate location dist atk_range def_range cost_fun =
}
Dict.empty
)
- dist
- atk_range
- def_range
- (cost_fun)
+ {
+ maximum_distance = max_dist,
+ maximum_attack_range = atk_range,
+ minimum_defense_range = def_range,
+ cost_function = (cost_fun)
+ }
)
get_marker : Type -> Struct.Marker.Type
diff --git a/src/battlemap/www/style.css b/src/battlemap/www/style.css
index 04bce9a..4b1db1b 100644
--- a/src/battlemap/www/style.css
+++ b/src/battlemap/www/style.css
@@ -463,7 +463,6 @@
.battlemap-marker-icon {z-index: 2;}
.battlemap-path-icon-above-markers {z-index: 3;}
.battlemap-character-icon {z-index: 4;}
-.battlemap-marker-icon.battlemap-navigator-non-interactive {z-index: 5;}
.battlemap-marker-icon,
.battlemap-character-icon,
@@ -549,29 +548,31 @@
opacity: 0.3;
transition: opacity 0.3s ease-out;
}
+
.battlemap-can-go-to-cant-defend-marker.battlemap-navigator-interactive
{
background:
repeating-linear-gradient(
-55deg,
- rgba(255,255,255,0.3),
- rgba(255,255,255,0.3) 3px,
- rgba(0,0,0,0.3) 3px,
- rgba(0,0,0,0.3) 7px
+ rgb(255,255,255),
+ rgb(255,255,255) 3px,
+ rgba(0,0,0,0) 3px,
+ rgba(0,0,0,0) 7px
);
opacity: 0.3;
transition: opacity 0.3s ease-out;
}
-.battlemap-can-go-to-can-defend-marker.battlemap-navigator-interactive:hover
+.battlemap-can-go-to-can-defend-marker.battlemap-navigator-interactive:hover,
+.battlemap-can-go-to-cant-defend-marker.battlemap-navigator-interactive:hover
{
- background-color: rgba(255, 255, 255, 0.9);
- opacity: 1;
+ opacity: 0.9;
}
.battlemap-can-attack-can-defend-marker.battlemap-navigator-interactive
{
- background-color:rgba(0,0,0,0.7);
+ background-color: #000;
+ opacity: 0.7;
width: 28px;
/*min-width: 28px;
max-width: 28px;*/
@@ -580,14 +581,69 @@
border-radius: 0;
}
+.battlemap-can-attack-cant-defend-marker.battlemap-navigator-interactive
+{
+ background:
+ repeating-linear-gradient(
+ -55deg,
+ rgba(255,255,255,0),
+ rgba(255,255,255,0) 3px,
+ rgb(0,0,0) 3px,
+ rgb(0,0,0) 7px
+ );
+ width: 28px;
+ /*min-width: 28px;
+ max-width: 28px;*/
+ opacity: 0.7;
+ height: 28px;
+ margin: 2px 0 0 2px;
+ border-radius: 0;
+}
+
.battlemap-can-attack-can-defend-marker.battlemap-navigator-non-interactive
{
background-image: url(/asset/svg/marker/blade.svg);
+}
+
+.battlemap-can-attack-cant-defend-marker.battlemap-navigator-non-interactive
+{
+ background-image:
+ url(/asset/svg/marker/blade.svg),
+ url(/asset/svg/marker/brokenshield.svg);
+}
+
+.battlemap-can-go-to-cant-defend-marker.battlemap-navigator-non-interactive
+{
+ background-image:
+ url(/asset/svg/marker/pawprint.svg),
+ url(/asset/svg/marker/brokenshield.svg);
+}
+
+.battlemap-can-attack-cant-defend-marker.battlemap-navigator-non-interactive,
+.battlemap-can-go-to-cant-defend-marker.battlemap-navigator-non-interactive
+{
+ width: 24px;
+ height: 24px;
+ background-position: top left, bottom right;
+ background-size: 50%, 50%;
+ background-repeat: no-repeat, no-repeat;
+ margin: 2px;
}
.battlemap-can-go-to-can-defend-marker.battlemap-navigator-non-interactive
{
background-image: url(/asset/svg/marker/pawprint.svg);
+}
+
+.battlemap-can-attack-can-defend-marker.battlemap-navigator-non-interactive,
+.battlemap-can-attack-cant-defend-marker..battlemap-navigator-non-interactive
+{
+ z-index: 5;
+}
+
+.battlemap-can-go-to-can-defend-marker,
+.battlemap-can-go-to-cant-defend-marker
+{
z-index: 3;
}