summaryrefslogtreecommitdiff |
diff options
Diffstat (limited to 'src/battle')
-rw-r--r-- | src/battle/src/Struct/Character.elm | 33 | ||||
-rw-r--r-- | src/battle/src/Struct/Model.elm | 105 | ||||
-rw-r--r-- | src/battle/src/Struct/RangeIndicator.elm | 78 | ||||
-rw-r--r-- | src/battle/src/Struct/TurnResult.elm | 8 | ||||
-rw-r--r-- | src/battle/src/Struct/TurnResultAnimator.elm | 78 | ||||
-rw-r--r-- | src/battle/src/View/Character.elm | 8 | ||||
-rw-r--r-- | src/battle/src/View/Controlled/Targets.elm | 2 | ||||
-rw-r--r-- | src/battle/src/View/Map/Character.elm | 4 | ||||
-rw-r--r-- | src/battle/src/View/MessageBoard/Animator/Attack.elm | 2 |
9 files changed, 203 insertions, 115 deletions
diff --git a/src/battle/src/Struct/Character.elm b/src/battle/src/Struct/Character.elm index 88356f5..73531f0 100644 --- a/src/battle/src/Struct/Character.elm +++ b/src/battle/src/Struct/Character.elm @@ -4,7 +4,7 @@ module Struct.Character exposing Rank(..), Unresolved, get_index, - get_player_ix, + get_player_index, get_rank, get_current_health, get_sane_current_health, @@ -19,11 +19,14 @@ module Struct.Character exposing set_defeated, get_base_character, set_base_character, + get_melee_attack_range, decoder, resolve ) -- Elm ------------------------------------------------------------------------- +import Set + import Json.Decode import Json.Decode.Pipeline @@ -34,6 +37,7 @@ import Battle.Struct.Statistics -- Battle Characters ----------------------------------------------------------- import BattleCharacters.Struct.Character import BattleCharacters.Struct.Equipment +import BattleCharacters.Struct.Weapon -- Battle Map ------------------------------------------------------------------ import BattleMap.Struct.Location @@ -105,14 +109,37 @@ fix_health previous_max_health char = -------------------------------------------------------------------------------- -- EXPORTED -------------------------------------------------------------------- -------------------------------------------------------------------------------- +get_melee_attack_range : Type -> Int +get_melee_attack_range c = + if (is_alive c) + then + ( + let + active_weapon = + (BattleCharacters.Struct.Character.get_active_weapon + (get_base_character c) + ) + in + case + (BattleCharacters.Struct.Weapon.get_defense_range active_weapon) + of + 0 -> + (BattleCharacters.Struct.Weapon.get_attack_range + active_weapon + ) + + _ -> 0 + ) + else 0 + get_index : Type -> Int get_index c = c.ix get_rank : Type -> Rank get_rank c = c.rank -get_player_ix : Type -> Int -get_player_ix c = c.player_ix +get_player_index : Type -> Int +get_player_index c = c.player_ix get_current_health : Type -> Int get_current_health c = c.health diff --git a/src/battle/src/Struct/Model.elm b/src/battle/src/Struct/Model.elm index 1d36d1f..c4fe728 100644 --- a/src/battle/src/Struct/Model.elm +++ b/src/battle/src/Struct/Model.elm @@ -46,6 +46,7 @@ import BattleCharacters.Struct.Weapon -- Battle Map ------------------------------------------------------------------ import BattleMap.Struct.Location import BattleMap.Struct.Map +import BattleMap.Struct.Marker import BattleMap.Struct.Tile -- Local Module ---------------------------------------------------------------- @@ -110,6 +111,52 @@ type alias Type = -------------------------------------------------------------------------------- -- LOCAL ----------------------------------------------------------------------- -------------------------------------------------------------------------------- +regenerate_attack_of_opportunity_markers_of_char : ( + Int -> + Struct.Character.Type -> + Type -> + Type + ) +regenerate_attack_of_opportunity_markers_of_char char_ix char model = + if ((Struct.Character.get_player_index char) == model.player_ix) + then model + else + let + marker_name = ("matk_c" ++ (String.fromInt char_ix)) + map_without_this_marker = + (BattleMap.Struct.Map.remove_marker marker_name model.map) + in + case (Struct.Character.get_melee_attack_range char) of + 0 -> {model | map = map_without_this_marker} + attack_range -> + {model | + map = + (BattleMap.Struct.Map.add_marker + marker_name + (BattleMap.Struct.Marker.new_melee_attack + char_ix + (BattleMap.Struct.Location.add_neighborhood_to_set + (BattleMap.Struct.Map.get_width + map_without_this_marker + ) + (BattleMap.Struct.Map.get_height + map_without_this_marker + ) + attack_range + (Struct.Character.get_location char) + (Set.empty) + ) + ) + map_without_this_marker + ) + } + +regenerate_attack_of_opportunity_markers : Int -> Type -> Type +regenerate_attack_of_opportunity_markers char_ix model = + case (Array.get char_ix model.characters) of + Nothing -> model + (Just char) -> + (regenerate_attack_of_opportunity_markers_of_char char_ix char model) -------------------------------------------------------------------------------- -- EXPORTED -------------------------------------------------------------------- @@ -168,7 +215,12 @@ new flags = add_character : Struct.Character.Type -> Type -> Type add_character char model = - {model | characters = (Array.push char model.characters)} + let characters = model.characters in + (regenerate_attack_of_opportunity_markers_of_char + (Array.length characters) + char + {model | characters = (Array.push char characters)} + ) add_weapon : BattleCharacters.Struct.Weapon.Type -> Type -> Type add_weapon wp model = @@ -315,10 +367,17 @@ move_animator_to_next_step model = case model.animator of Nothing -> model (Just animator) -> - {model | - animator = - (Struct.TurnResultAnimator.maybe_trigger_next_step animator) - } + case (Struct.TurnResultAnimator.maybe_trigger_next_step animator) of + Nothing -> + (Set.foldl + (regenerate_attack_of_opportunity_markers) + {model | animator = Nothing } + (Struct.TurnResultAnimator.get_animated_character_indices + animator + ) + ) + + just_next_animator -> {model | animator = just_next_animator } apply_animator_step : Type -> Type apply_animator_step model = @@ -367,39 +426,3 @@ invalidate err model = clear_error : Type -> Type clear_error model = {model | error = Nothing} - -generate_danger_zone : Type -> (Set.Set BattleMap.Struct.Location.Ref) -generate_danger_zone model = - (Array.foldl - (\char danger_zone -> - let - char_weapon = - (BattleCharacters.Struct.Character.get_active_weapon - (Struct.Character.get_base_character char) - ) - in - if - ( - (Struct.Character.is_alive char) - && ((Struct.Character.get_player_ix char) /= model.player_ix) - && - ( - (BattleCharacters.Struct.Weapon.get_defense_range char_weapon) - == 0 - ) - ) - then - (BattleMap.Struct.Location.add_neighborhood_to_set - (BattleMap.Struct.Map.get_width model.map) - (BattleMap.Struct.Map.get_height model.map) - (BattleCharacters.Struct.Weapon.get_attack_range - char_weapon - ) - (Struct.Character.get_location char) - danger_zone - ) - else danger_zone - ) - (Set.empty) - model.characters - ) diff --git a/src/battle/src/Struct/RangeIndicator.elm b/src/battle/src/Struct/RangeIndicator.elm index 064e1fd..bc67a16 100644 --- a/src/battle/src/Struct/RangeIndicator.elm +++ b/src/battle/src/Struct/RangeIndicator.elm @@ -30,7 +30,7 @@ type alias TileSearchLocation = (BattleMap.Struct.Location.Ref, Int) type alias Type = { distance : Int, - required_battles : Int, + dangers_count : Int, taxicab_dist : Int, atk_range : Int, path : (List BattleMap.Struct.Direction.Type), @@ -49,7 +49,7 @@ type alias SearchParameters = type alias LocatedIndicator = { location_ref : BattleMap.Struct.Location.Ref, - required_battles : Int, + dangers_count : Int, indicator : Type } -------------------------------------------------------------------------------- @@ -66,7 +66,7 @@ get_closest max_dist (ref, ignored_param) indicator current_best = if (is_closer max_dist indicator current_best.indicator) then { - required_battles = indicator.required_battles, + dangers_count = indicator.dangers_count, location_ref = ref, indicator = indicator } @@ -97,7 +97,7 @@ generate_neighbor : ( ) generate_neighbor search_params neighbor_loc dir src_indicator = let - (node_cost, node_battles) = + (node_cost, node_dangers_count) = (search_params.tile_data_function neighbor_loc) new_dist = if (node_cost == Constants.Movement.cost_when_occupied_tile) @@ -105,7 +105,6 @@ generate_neighbor search_params neighbor_loc dir src_indicator = else (src_indicator.distance + node_cost) new_atk_range = (src_indicator.atk_range + 1) new_taxicab_dist = (search_params.taxicab_dist_fun neighbor_loc) - new_battle_count = (src_indicator.required_battles + node_battles) can_defend = (new_taxicab_dist > search_params.minimum_defense_range) in if (new_dist > search_params.maximum_distance) @@ -116,14 +115,12 @@ generate_neighbor search_params neighbor_loc dir src_indicator = distance = (search_params.maximum_distance + 1), atk_range = (src_indicator.atk_range + 1), taxicab_dist = new_taxicab_dist, - required_battles = new_battle_count, + dangers_count = src_indicator.dangers_count, path = (dir :: src_indicator.path), marker = if (can_defend) - then - Struct.Marker.CanAttackCanDefend - else - Struct.Marker.CanAttackCantDefend + then Struct.Marker.CanAttackCanDefend + else Struct.Marker.CanAttackCantDefend } ) else @@ -132,22 +129,21 @@ generate_neighbor search_params neighbor_loc dir src_indicator = { distance = new_dist, atk_range = 0, - required_battles = new_battle_count, + dangers_count = + (src_indicator.dangers_count + node_dangers_count), taxicab_dist = new_taxicab_dist, path = (dir :: src_indicator.path), marker = if (can_defend) - then - Struct.Marker.CanGoToCanDefend - else - Struct.Marker.CanGoToCantDefend + then Struct.Marker.CanGoToCanDefend + else Struct.Marker.CanGoToCantDefend } ) candidate_is_acceptable : (SearchParameters -> Int -> Type -> Bool) -candidate_is_acceptable search_params cost candidate = +candidate_is_acceptable search_params node_cost candidate = ( - (cost /= Constants.Movement.cost_when_out_of_bounds) + (node_cost /= Constants.Movement.cost_when_out_of_bounds) && ( (candidate.distance <= search_params.maximum_distance) @@ -172,8 +168,8 @@ candidate_is_an_improvement (List.all -- Does it improve on all possible solutions that have less (or as much) -- battles? - (\req_battles -> - let index = (loc_ref, req_battles) in + (\dangers_count -> + let index = (loc_ref, dangers_count) in case (Dict.get index candidate_solutions) of (Just alternative) -> (is_closer @@ -193,7 +189,7 @@ candidate_is_an_improvement Nothing -> True ) - (List.range 0 candidate.required_battles) + (List.range 0 candidate.dangers_count) ) handle_neighbors : ( @@ -209,13 +205,13 @@ handle_neighbors src results search_params dir remaining = src_loc = (BattleMap.Struct.Location.from_ref src.location_ref) neighbor_loc = (BattleMap.Struct.Location.neighbor dir src_loc) neighbor_loc_ref = (BattleMap.Struct.Location.get_ref neighbor_loc) - (candidate_cost, candidate) = + (neighbor_node_cost, candidate) = (generate_neighbor search_params neighbor_loc dir src.indicator) - candidate_index = (neighbor_loc_ref, candidate.required_battles) + candidate_index = (neighbor_loc_ref, candidate.dangers_count) in if ( - (candidate_is_acceptable search_params candidate_cost candidate) + (candidate_is_acceptable search_params neighbor_node_cost candidate) && (candidate_is_an_improvement search_params @@ -237,12 +233,12 @@ find_closest_in search_params remaining = (Dict.foldl (get_closest search_params.maximum_distance) { - required_battles = 9999, + dangers_count = 9999, location_ref = (-1, -1), indicator = { - required_battles = 9999, - distance = Constants.Movement.cost_when_out_of_bounds, + dangers_count = 9999, + distance = (search_params.maximum_distance + 1), path = [], atk_range = Constants.Movement.cost_when_out_of_bounds, taxicab_dist = Constants.Movement.cost_when_out_of_bounds, @@ -275,7 +271,7 @@ insert_in_dictionary : ( ) insert_in_dictionary located_indicator dict = (Dict.insert - (located_indicator.location_ref, located_indicator.required_battles) + (located_indicator.location_ref, located_indicator.dangers_count) located_indicator.indicator dict ) @@ -312,7 +308,7 @@ search result remaining search_params = (Dict.remove ( finalized_clos_loc_ind.location_ref, - finalized_clos_loc_ind.required_battles + finalized_clos_loc_ind.dangers_count ) remaining ) @@ -327,18 +323,27 @@ search result remaining search_params = ) cleanup : ( + Int -> (Dict.Dict TileSearchLocation Type) -> (Dict.Dict BattleMap.Struct.Location.Ref Type) ) -cleanup search_results = +cleanup max_dist search_results = (Dict.foldl (\ - (candidate_location, candidate_battles) candidate result -> + (candidate_location, candidate_dangers_count) candidate result -> case (Dict.get candidate_location result) of (Just current_best) -> - if (current_best.required_battles < candidate_battles) + if + ( + (current_best.atk_range == 0) + && (candidate.atk_range == 0) + && (current_best.dangers_count < candidate_dangers_count) + ) then result - else (Dict.insert candidate_location candidate result) + else + if (is_closer max_dist candidate current_best) + then (Dict.insert candidate_location candidate result) + else result Nothing -> (Dict.insert candidate_location candidate result) ) @@ -358,6 +363,7 @@ generate : ( ) generate location max_dist def_range atk_range tile_data_fun = (cleanup + max_dist (search Dict.empty (Dict.insert @@ -367,13 +373,11 @@ generate location max_dist def_range atk_range tile_data_fun = path = [], atk_range = 0, taxicab_dist = 0, - required_battles = 0, + dangers_count = 0, marker = if (def_range == 0) - then - Struct.Marker.CanGoToCanDefend - else - Struct.Marker.CanGoToCantDefend + then Struct.Marker.CanGoToCanDefend + else Struct.Marker.CanGoToCantDefend } Dict.empty ) diff --git a/src/battle/src/Struct/TurnResult.elm b/src/battle/src/Struct/TurnResult.elm index 7325e93..71768c3 100644 --- a/src/battle/src/Struct/TurnResult.elm +++ b/src/battle/src/Struct/TurnResult.elm @@ -207,7 +207,7 @@ apply_player_defeat pdefeat characters players = (Array.map (\c -> ( - if ((Struct.Character.get_player_ix c) == pdefeat.player_index) + if ((Struct.Character.get_player_index c) == pdefeat.player_index) then (Struct.Character.set_defeated True c) else c ) @@ -231,7 +231,11 @@ apply_inverse_player_defeat pdefeat characters players = (Array.map (\c -> ( - if ((Struct.Character.get_player_ix c) == pdefeat.player_index) + if + ( + (Struct.Character.get_player_index c) + == pdefeat.player_index + ) then (Struct.Character.set_defeated False c) else c ) diff --git a/src/battle/src/Struct/TurnResultAnimator.elm b/src/battle/src/Struct/TurnResultAnimator.elm index 7f7938e..d4445f7 100644 --- a/src/battle/src/Struct/TurnResultAnimator.elm +++ b/src/battle/src/Struct/TurnResultAnimator.elm @@ -5,9 +5,13 @@ module Struct.TurnResultAnimator exposing maybe_new, maybe_trigger_next_step, waits_for_focus, - get_current_animation + get_current_animation, + get_animated_character_indices ) +-- Elm ------------------------------------------------------------------------- +import Set + -- Local Module ---------------------------------------------------------------- import Struct.TurnResult @@ -22,6 +26,7 @@ type Animation = type alias Type = { + animated_character_ixs : (Set.Set Int), remaining_animations : (List Animation), current_animation : Animation, wait_focus : Bool @@ -30,7 +35,10 @@ type alias Type = -------------------------------------------------------------------------------- -- LOCAL ----------------------------------------------------------------------- -------------------------------------------------------------------------------- -turn_result_to_animations : Struct.TurnResult.Type -> (List Animation) +turn_result_to_animations : ( + Struct.TurnResult.Type -> + ((List Animation), (Set.Set Int)) + ) turn_result_to_animations turn_result = case turn_result of (Struct.TurnResult.Attacked attack) -> @@ -38,26 +46,39 @@ turn_result_to_animations turn_result = attacker_ix = (Struct.TurnResult.get_actor_index turn_result) defender_ix = (Struct.TurnResult.get_attack_defender_index attack) in - [ - (Focus attacker_ix), - (Focus defender_ix), - (AttackSetup (attacker_ix, defender_ix)), - (TurnResult turn_result) - ] + ( + [ + (Focus attacker_ix), + (Focus defender_ix), + (AttackSetup (attacker_ix, defender_ix)), + (TurnResult turn_result) + ], + (Set.fromList [defender_ix, attacker_ix]) + ) _ -> - [ - (Focus (Struct.TurnResult.get_actor_index turn_result)), - (TurnResult turn_result) - ] + let actor_ix = (Struct.TurnResult.get_actor_index turn_result) in + ( + [ + (Focus actor_ix), + (TurnResult turn_result) + ], + (Set.singleton actor_ix) + ) turn_result_to_animations_foldl : ( Struct.TurnResult.Type -> - (List Animation) -> - (List Animation) + ((List Animation), (Set.Set Int)) -> + ((List Animation), (Set.Set Int)) ) -turn_result_to_animations_foldl turn_result current_animations = - (List.append current_animations (turn_result_to_animations turn_result)) +turn_result_to_animations_foldl turn_result (animations, char_ixs) = + let + (new_animations, new_char_ixs) = (turn_result_to_animations turn_result) + in + ( + (List.append animations new_animations), + (Set.union new_char_ixs char_ixs) + ) maybe_go_to_next_animation : Type -> (Maybe Type) maybe_go_to_next_animation tra = @@ -84,17 +105,23 @@ maybe_new : (List Struct.TurnResult.Type) -> Bool -> (Maybe Type) maybe_new turn_results wait_focus = case (List.head turn_results) of (Just head) -> - (Just - { - remaining_animations = + ( + let + (animations, character_ixs) = (List.foldl (turn_result_to_animations_foldl) - [] + ([], (Set.empty)) turn_results - ), - current_animation = Inactive, - wait_focus = wait_focus - } + ) + in + (Just + { + remaining_animations = animations, + current_animation = Inactive, + wait_focus = wait_focus, + animated_character_ixs = character_ixs + } + ) ) _ -> Nothing @@ -118,3 +145,6 @@ get_current_animation tra = tra.current_animation waits_for_focus : Type -> Bool waits_for_focus tra = tra.wait_focus + +get_animated_character_indices : Type -> (Set.Set Int) +get_animated_character_indices tra = tra.animated_character_ixs diff --git a/src/battle/src/View/Character.elm b/src/battle/src/View/Character.elm index 1213dc9..c5082c9 100644 --- a/src/battle/src/View/Character.elm +++ b/src/battle/src/View/Character.elm @@ -48,7 +48,7 @@ get_alliance_class : ( (Html.Attribute Struct.Event.Type) ) get_alliance_class model char = - if ((Struct.Character.get_player_ix char) == model.player_ix) + if ((Struct.Character.get_player_index char) == model.player_ix) then (Html.Attributes.class "character-ally") else @@ -105,7 +105,7 @@ get_icon_body_html char = (Html.Attributes.class ( "asset-character-team-body-" - ++ (String.fromInt (Struct.Character.get_player_ix char)) + ++ (String.fromInt (Struct.Character.get_player_index char)) ) ) ] @@ -178,7 +178,7 @@ get_portrait_html viewer_ix char = [ (Html.Attributes.class ( - if ((Struct.Character.get_player_ix char) == viewer_ix) + if ((Struct.Character.get_player_index char) == viewer_ix) then "character-ally" else @@ -189,7 +189,7 @@ get_portrait_html viewer_ix char = ( "character-portrait-team-" ++ - (String.fromInt (Struct.Character.get_player_ix char)) + (String.fromInt (Struct.Character.get_player_index char)) ) ), (Html.Events.onClick diff --git a/src/battle/src/View/Controlled/Targets.elm b/src/battle/src/View/Controlled/Targets.elm index f057cba..4b36f03 100644 --- a/src/battle/src/View/Controlled/Targets.elm +++ b/src/battle/src/View/Controlled/Targets.elm @@ -32,7 +32,7 @@ get_target_info_html model char_ref = "Attacking " ++ char.name ++ " (player " - ++ (String.fromInt (Struct.Character.get_player_ix char)) + ++ (String.fromInt (Struct.Character.get_player_index char)) ++ "): " ++ (String.fromInt diff --git a/src/battle/src/View/Map/Character.elm b/src/battle/src/View/Map/Character.elm index 65c1f03..4b69ebc 100644 --- a/src/battle/src/View/Map/Character.elm +++ b/src/battle/src/View/Map/Character.elm @@ -80,7 +80,7 @@ get_alliance_class : ( (Html.Attribute Struct.Event.Type) ) get_alliance_class model char = - if ((Struct.Character.get_player_ix char) == model.player_ix) + if ((Struct.Character.get_player_index char) == model.player_ix) then (Html.Attributes.class "character-ally") else @@ -137,7 +137,7 @@ get_body_html char = (Html.Attributes.class ( "asset-character-team-body-" - ++ (String.fromInt (Struct.Character.get_player_ix char)) + ++ (String.fromInt (Struct.Character.get_player_index char)) ) ) ] diff --git a/src/battle/src/View/MessageBoard/Animator/Attack.elm b/src/battle/src/View/MessageBoard/Animator/Attack.elm index 9fd419c..4378c5a 100644 --- a/src/battle/src/View/MessageBoard/Animator/Attack.elm +++ b/src/battle/src/View/MessageBoard/Animator/Attack.elm @@ -194,7 +194,7 @@ get_attacker_card maybe_attack char = ) [ (View.Controlled.CharacterCard.get_minimal_html - (Struct.Character.get_player_ix char) + (Struct.Character.get_player_index char) char ) ] |