| summaryrefslogtreecommitdiff | 
diff options
| author | nsensfel <SpamShield0@noot-noot.org> | 2018-07-02 18:06:08 +0200 | 
|---|---|---|
| committer | nsensfel <SpamShield0@noot-noot.org> | 2018-07-02 18:06:08 +0200 | 
| commit | 668e1ab70b66a44e40922a29225d2835b03190fa (patch) | |
| tree | 80f7fb37b8588035dd3558e4518ac4aa96df0126 /src | |
| parent | 5f8694f2ecae5084f9ad1332e69403f3f79de4bc (diff) | |
Working on player defeats...
Diffstat (limited to 'src')
| -rw-r--r-- | src/battlemap/bm_shim.erl | 14 | ||||
| -rw-r--r-- | src/battlemap/game-logic/bm_next_turn.erl | 4 | ||||
| -rw-r--r-- | src/battlemap/game-logic/bm_turn_actions.erl | 163 | ||||
| -rw-r--r-- | src/battlemap/query/bm_character_turn.erl | 8 | ||||
| -rw-r--r-- | src/battlemap/query/bm_load_state.erl | 15 | ||||
| -rw-r--r-- | src/battlemap/reply/bm_add_char.erl | 11 | ||||
| -rw-r--r-- | src/battlemap/struct/bm_character.erl | 25 | ||||
| -rw-r--r-- | src/shared/util/sh_array_util.erl | 47 | 
8 files changed, 261 insertions, 26 deletions
| diff --git a/src/battlemap/bm_shim.erl b/src/battlemap/bm_shim.erl index 1ff8ac3..67e82bf 100644 --- a/src/battlemap/bm_shim.erl +++ b/src/battlemap/bm_shim.erl @@ -7,7 +7,7 @@  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export([generate_random_battle/0 ]). +-export([generate_random_battle/0]).  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -37,7 +37,7 @@ generate_random_characters     Result;  generate_random_characters  ( -   MaxPlayerID, +   MaxPlayerIX,     0,     CharactersPerPlayer,     TotalCharacterCount, @@ -47,7 +47,7 @@ generate_random_characters  ) ->     generate_random_characters     ( -      (MaxPlayerID - 1), +      (MaxPlayerIX - 1),        CharactersPerPlayer,        CharactersPerPlayer,        TotalCharacterCount, @@ -57,7 +57,7 @@ generate_random_characters     );  generate_random_characters  ( -   MaxPlayerID, +   MaxPlayerIX,     PlayerCharacterCount,     CharactersPerPlayer,     TotalCharacterCount, @@ -69,20 +69,20 @@ generate_random_characters        bm_character:random        (           TotalCharacterCount, -         list_to_binary(integer_to_list(MaxPlayerID)), +         MaxPlayerIX,           bm_battlemap:get_width(Battlemap),           bm_battlemap:get_height(Battlemap),           ForbiddenLocations        ),     Character = -      case MaxPlayerID of +      case MaxPlayerIX of           0 -> bm_character:set_is_active(true, NewCharacter);           _ -> NewCharacter        end,     generate_random_characters     ( -      MaxPlayerID, +      MaxPlayerIX,        (PlayerCharacterCount - 1),        CharactersPerPlayer,        (TotalCharacterCount + 1), diff --git a/src/battlemap/game-logic/bm_next_turn.erl b/src/battlemap/game-logic/bm_next_turn.erl index 3cd63b4..56e7f7e 100644 --- a/src/battlemap/game-logic/bm_next_turn.erl +++ b/src/battlemap/game-logic/bm_next_turn.erl @@ -60,14 +60,14 @@ reset_next_player_timeline (Battle) ->  -spec activate_next_players_characters (bm_battle:type(), bm_player:type())     -> {bm_battle:type(), list(sh_db_query:op())}.  activate_next_players_characters (Battle, NextPlayer) -> -   NextPlayerID = bm_player:get_id(NextPlayer), +   NextPlayerIX = bm_player:get_index(NextPlayer),     Characters = bm_battle:get_characters(Battle),     {UpdatedCharacters, ModifiedIXs} =        sh_array_util:mapiff        (           fun (Character) -> -            (bm_character:get_owner_id(Character) == NextPlayerID) +            (bm_character:get_player_index(Character) == NextPlayerIX)           end,           fun (Character) ->              bm_character:set_is_active(true, Character) diff --git a/src/battlemap/game-logic/bm_turn_actions.erl b/src/battlemap/game-logic/bm_turn_actions.erl index 87e14aa..2dfcf63 100644 --- a/src/battlemap/game-logic/bm_turn_actions.erl +++ b/src/battlemap/game-logic/bm_turn_actions.erl @@ -16,6 +16,149 @@  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec handle_player_defeat +   ( +      non_neg_integer(), +      bm_character_turn_update:type() +   ) +   -> bm_character_turn_update:type(). +handle_player_defeat (PlayerIX, Update) -> +   Data = bm_character_turn_update:get_data(Update), +   Battle = bm_character_turn_data:get_battle(Data), +   Characters = bm_battle:get_characters(Battle), + +   %% FIXME: The controlled character might slip through. +   {UpdatedCharacters, ModifiedIXs} = +      sh_array_util:mapiff +      ( +         fun (Character) -> +            (bm_character:get_player_index(Character) == PlayerIX) +         end, +         fun (Character) -> +            bm_character:set_rank(defeated, Character) +         end, +         Characters +      ), + +   S1Update = +      lists:foldl +      ( +         fun (NextUpdate, IX) -> +            bm_character_turn_update:add_to_db +            ( +               sh_db_query:update_indexed +               ( +                  bm_battle:get_characters_field(), +                  IX, +                  [ +                     sh_db_query:set_field +                     ( +                        bm_character:get_rank_field(), +                        defeated +                     ) +                  ] +               ), +               NextUpdate +            ) +         end, +         Update, +         ModifiedIXs +      ), + +   %% TODO: Battle.player[PlayerIX].is_active <- false + +   UpdatedBattle = bm_battle:set_characters(UpdatedCharacters, Battle), +   UpdatedData = bm_character_turn_data:set_battle(UpdatedBattle, Data), +   S2Update = bm_character_turn_update:set_data(UpdatedData, S1Update), + +   DBQuery = +      sh_db_query:update_indexed +      ( +         bm_battle:get_players_field(), +         PlayerIX, +         [ +            sh_db_query:set_field +            ( +               bm_character:get_is_active_field(), +               false +            ) +         ] +      ), + +   S3Update = +      bm_character_turn_update:add_to_timeline +      ( +         bm_turn_result:new_player_lost(PlayerIX), +         DBQuery, +         S2Update +      ), + +   S3Update. + +-spec handle_victory_condition +   ( +      non_neg_integer(), +      integer(), +      bm_character_turn_update:type() +   ) +   -> bm_character_turn_update:type(). +handle_victory_condition (_, Health, Update) when (Health > 0) -> Update; +handle_victory_condition (CharIX, _Health, Update) -> +   Data = bm_character_turn_update:get_data(Update), +   Battle = bm_character_turn_data:get_battle(Data), +   Character = bm_battle:get_character(CharIX, Battle), +   Characters = bm_battle:get_characters(Battle), +   CharacterPlayerIX = bm_character:get_player_index(Character), + +   case bm_character:get_rank(Character) of +      optional -> +         %% Let's not assume there is a commander +         StillHasAliveChar = +            sh_array_util:any_indexed +            ( +               fun (IX, Char) -> +                  ( +                     (CharacterPlayerIX == bm_character:get_player_index(Char)) +                     and (IX /= CharIX) +                     and bm_character:get_is_alive(Char) +                  ) +               end, +               %% FIXME: Potential issue if it's the controlled player and Data +               %% is dirty. +               Characters +            ), + +         case StillHasAliveChar of +            true -> Update; +            _ -> handle_player_defeat(CharacterPlayerIX, Update) +         end; + +      commander -> handle_player_defeat(CharacterPlayerIX, Update); + +      target -> +         StillHasAliveChar = +            sh_array_util:any_indexed +            ( +               fun (IX, Char) -> +                  ( +                     (CharacterPlayerIX == bm_character:get_player_index(Char)) +                     and (IX /= CharIX) +                     and bm_character:get_is_alive(Char) +                     and (bm_character:get_rank(Char) == target) +                  ) +               end, +               %% FIXME: Potential issue if it's the controlled player and Data +               %% is dirty. +               Characters +            ), + +         case StillHasAliveChar of +            true -> Update; +            _ -> handle_player_defeat(CharacterPlayerIX, Update) +         end; + +      defeated -> Update +   end.  %%%% SWITCHING WEAPON %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  -spec handle_switch_weapon @@ -353,7 +496,25 @@ handle_attack (BattleAction, Update) ->           S0Update        ), -   bm_character_turn_update:set_data(S1Data, S1Update). +   S2Update = bm_character_turn_update:set_data(S1Data, S1Update), + +   S3Update = +      handle_victory_condition +      ( +         CharacterIX, +         RemainingAttackerHealth, +         S2Update +      ), + +   S4Update = +      handle_victory_condition +      ( +         TargetIX, +         RemainingDefenderHealth, +         S3Update +      ), + +   S4Update.  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/battlemap/query/bm_character_turn.erl b/src/battlemap/query/bm_character_turn.erl index 74def12..7a7476c 100644 --- a/src/battlemap/query/bm_character_turn.erl +++ b/src/battlemap/query/bm_character_turn.erl @@ -73,10 +73,14 @@ assert_user_is_current_player (Data, Request) ->     ) -> 'ok'.  assert_user_owns_played_character (Data, Request) ->     PlayerID = bm_character_turn_request:get_player_id(Request), +   Battle = bm_character_turn_data:get_battle(Data), +   Players = bm_battle:get_players(Battle),     Character = bm_character_turn_data:get_character(Data), -   CharacterOwnerID = bm_character:get_owner_id(Character), +   CharacterPlayerIX = bm_character:get_player_index(Character), +   CharacterPlayer = array:get(CharacterPlayerIX, Players), +   CharacterPlayerID = bm_player:get_id(CharacterPlayer), -   true = (PlayerID == CharacterOwnerID), +   true = (PlayerID == CharacterPlayerID),     ok. diff --git a/src/battlemap/query/bm_load_state.erl b/src/battlemap/query/bm_load_state.erl index 4b5b3ab..505ec3b 100644 --- a/src/battlemap/query/bm_load_state.erl +++ b/src/battlemap/query/bm_load_state.erl @@ -64,6 +64,19 @@ fetch_data (Input) ->  generate_reply (QueryState, Input) ->     PlayerID = Input#input.player_id,     Battle = QueryState#query_state.battle, +   Players = bm_battle:get_players(Battle), + +   PlayerIX = +      sh_array_util:first +      ( +         fun (Player) -> +            (bm_player:get_id(Player) == PlayerID) +         end, +         Players +      ), + +   true = (PlayerIX >= 0), +     SetTimeline =        bm_set_timeline:generate        ( @@ -78,7 +91,7 @@ generate_reply (QueryState, Input) ->           array:map           (              fun (IX, Character) -> -               bm_add_char:generate(IX, Character, PlayerID) +               bm_add_char:generate(IX, Character, PlayerIX)              end,              bm_battle:get_characters(Battle)           ) diff --git a/src/battlemap/reply/bm_add_char.erl b/src/battlemap/reply/bm_add_char.erl index 0fbaf82..d37c06e 100644 --- a/src/battlemap/reply/bm_add_char.erl +++ b/src/battlemap/reply/bm_add_char.erl @@ -44,13 +44,13 @@ attributes_as_json (Attributes) ->     (        non_neg_integer(),        bm_character:type(), -      bm_player:id() +      non_neg_integer()     )     -> {list(any())}. -generate (IX, Character, PlayerID) -> +generate (IX, Character, PlayerIX) ->     Attributes = bm_character:get_attributes(Character),     {ActiveWeapon, SecondaryWeapon} = bm_character:get_weapon_ids(Character), -   OwnerID = bm_character:get_owner_id(Character), +   CharacterPlayerIX = bm_character:get_player_index(Character),     Location = bm_character:get_location(Character),     { @@ -66,13 +66,12 @@ generate (IX, Character, PlayerID) ->              bm_character:get_current_health(Character)           },           {<<"lc">>, bm_location:encode(Location)}, -         {<<"pla">>, OwnerID}, +         {<<"pla">>, CharacterPlayerIX},           {              <<"ena">>,              (                 bm_character:get_is_active(Character) -               and -               (OwnerID == PlayerID) +               and (CharacterPlayerIX == PlayerIX)              )           },           {<<"att">>, attributes_as_json(Attributes)}, diff --git a/src/battlemap/struct/bm_character.erl b/src/battlemap/struct/bm_character.erl index 45b2361..7dec927 100644 --- a/src/battlemap/struct/bm_character.erl +++ b/src/battlemap/struct/bm_character.erl @@ -11,7 +11,7 @@     character,     {        id :: id(), -      owner_id :: bm_player:id(), +      player_ix :: non_neg_integer(),        name :: binary(),        rank :: rank(),        icon :: binary(), @@ -37,7 +37,7 @@  (     [        get_id/1, -      get_owner_id/1, +      get_player_index/1,        get_name/1,        get_rank/1,        get_icon/1, @@ -51,6 +51,7 @@        get_is_alive/1,        get_is_active/1, +      set_rank/2,        set_weapon_ids/2,        set_armor_id/2,        set_statistics/2, @@ -58,6 +59,7 @@        set_current_health/2,        set_is_active/2, +      get_rank_field/0,        get_statistics_field/0,        get_weapons_field/0,        get_location_field/0, @@ -108,8 +110,8 @@ find_random_location (BattlemapWidth, BattlemapHeight, ForbiddenLocations) ->  -spec get_id (type()) -> id().  get_id (Char) -> Char#character.id. --spec get_owner_id (type()) -> bm_player:id(). -get_owner_id (Char) -> Char#character.owner_id. +-spec get_player_index (type()) -> non_neg_integer(). +get_player_index (Char) -> Char#character.player_ix.  -spec get_name (type()) -> binary().  get_name (Char) -> Char#character.name. @@ -153,6 +155,13 @@ get_is_active (Char) ->        and get_is_alive(Char)     ). +-spec set_rank (rank(), type()) -> type(). +set_rank (Rank, Char) -> +   Char#character +   { +      rank = Rank +   }. +  -spec set_location     (        {non_neg_integer(), non_neg_integer()}, @@ -209,13 +218,13 @@ set_statistics (Stats, Char) ->  -spec random     (        non_neg_integer(), -      bm_player:id(), +      non_neg_integer(),        non_neg_integer(),        non_neg_integer(),        list({non_neg_integer(), non_neg_integer()})     )     -> type(). -random (ID, OwnerID, BattlemapWidth, BattlemapHeight, ForbiddenLocations) -> +random (ID, PlayerIX, BattlemapWidth, BattlemapHeight, ForbiddenLocations) ->     Location =        find_random_location(BattlemapWidth, BattlemapHeight, ForbiddenLocations),     WeaponIDs = {sh_weapon:random_id(), sh_weapon:random_id()}, @@ -228,7 +237,7 @@ random (ID, OwnerID, BattlemapWidth, BattlemapHeight, ForbiddenLocations) ->     #character     {        id = ID, -      owner_id = OwnerID, +      player_ix = PlayerIX,        name = list_to_binary("Char" ++ IDAsListString),        rank =           if @@ -246,6 +255,8 @@ random (ID, OwnerID, BattlemapWidth, BattlemapHeight, ForbiddenLocations) ->        is_active = false     }. +-spec get_rank_field() -> non_neg_integer(). +get_rank_field () -> #character.rank.  -spec get_statistics_field() -> non_neg_integer().  get_statistics_field () -> #character.statistics.  -spec get_weapons_field() -> non_neg_integer(). diff --git a/src/shared/util/sh_array_util.erl b/src/shared/util/sh_array_util.erl index 5f58b36..6d976bc 100644 --- a/src/shared/util/sh_array_util.erl +++ b/src/shared/util/sh_array_util.erl @@ -10,9 +10,12 @@  (     [        any/2, +      any_indexed/2,        none/2,        all/2, +      first/2, +        mapiff/3     ]  ). @@ -35,6 +38,38 @@ any_internals (Fun, Array, PrevIX) ->        _ -> any_internals(Fun, Array, IX)     end. +-spec first_internals +   ( +      fun((any()) -> boolean()), +      array:array(any()), +      non_neg_integer() +   ) +   -> integer(). +first_internals (_, _, 0) -> +   -1; +first_internals (Fun, Array, PrevIX) -> +   IX = (PrevIX - 1), +   case Fun(array:get(IX, Array)) of +      true -> IX; +      _ -> first_internals(Fun, Array, IX) +   end. + +-spec any_indexed_internals +   ( +      fun((non_neg_integer(), any()) -> boolean()), +      array:array(any()), +      non_neg_integer() +   ) +   -> boolean(). +any_indexed_internals (_, _, 0) -> +   false; +any_indexed_internals (Fun, Array, PrevIX) -> +   IX = (PrevIX - 1), +   case Fun(IX, array:get(IX, Array)) of +      true -> true; +      _ -> any_indexed_internals(Fun, Array, IX) +   end. +  -spec all_internals     (        fun((any()) -> boolean()), @@ -86,6 +121,18 @@ mapiff_internals (Cond, Map, Array, IXList, PrevIX) ->  any (Fun, Array) ->     any_internals(Fun, Array, array:size(Array)). +-spec first (fun((any()) -> boolean()), array:array(any())) -> integer(). +first (Fun, Array) -> +   first_internals(Fun, Array, array:size(Array)). + +-spec any_indexed +   ( +      fun((non_neg_integer(), any()) -> boolean()), +      array:array(any()) +   ) -> boolean(). +any_indexed (Fun, Array) -> +   any_indexed_internals(Fun, Array, array:size(Array)). +  -spec all (fun((any()) -> boolean()), array:array(any())) -> boolean().  all (Fun, Array) ->     all_internals(Fun, Array, array:size(Array)). | 


