| summaryrefslogtreecommitdiff | 
diff options
Diffstat (limited to 'src/special/spe_battle.erl')
| -rw-r--r-- | src/special/spe_battle.erl | 361 | 
1 files changed, 264 insertions, 97 deletions
| diff --git a/src/special/spe_battle.erl b/src/special/spe_battle.erl index edc18df..d907224 100644 --- a/src/special/spe_battle.erl +++ b/src/special/spe_battle.erl @@ -13,70 +13,92 @@  %% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% DB ACCESS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec reserve_id () -> binary(). -reserve_id () -> -   %% TODO Unimplemented. -   <<"0">>. +%%%% USED IDS COLLECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec update_ordset +   ( +      ordsets:ordset(any()), +      ordsets:ordset(any()) +   ) +   -> ataxic:basic(). +update_ordset (New, Old) -> +   AddedElements = ordsets:subtract(New, Old), --spec commit (btl_battle:type()) -> ok. -commit (_Battle) -> -   %% TODO Unimplemented. -   ok. +   ataxic:sequence +   ( +      lists:map +      ( +         fun (V) -> +            ataxic:apply_function +            ( +               ordsets, +               add_element, +               [ +                  ataxic:constant(V), +                  ataxic:current_value() +               ] +            ) +         end, +         ordsets:to_list(AddedElements) +      ) +   ). -%%%% USED IDS COLLECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  -spec get_equipment_ids     ( -      list(btl_character:type()) +      orddict:orddict(non_neg_integer(), btl_character:type())     ) -   -> {ordsets:ordset(binary()), ordsets:ordset(binary())}. +   -> +   { +      ordsets:ordset(shr_portrait:id()), +      ordsets:ordset(shr_weapon:id()), +      ordsets:ordset(shr_armor:id()) +   }.  get_equipment_ids (Characters) -> -   {UsedWeaponIDs, UsedArmorIDs} = -      lists:foldl +   { +      UsedPortraitIDs, +      UsedWeaponIDs, +      UsedArmorIDs +   } = +      orddict:fold        ( -         fun (Character, {UWIDs, UAIDs}) -> +         fun (_IX, Character, {UPIDs, UWIDs, UAIDs}) ->              {MWpID, SWpID} = btl_character:get_weapon_ids(Character),              AID = btl_character:get_armor_id(Character), +            PID = btl_character:get_portrait_id(Character),              { +               ordsets:add_element(PID, UPIDs),                 ordsets:add_element(MWpID, ordsets:add_element(SWpID, UWIDs)),                 ordsets:add_element(AID, UAIDs)              }           end, -         {ordsets:new(), ordsets:new()}, +         {ordsets:new(), ordsets:new(), ordsets:new()},           Characters        ), -   {UsedWeaponIDs, UsedArmorIDs}. +   {UsedPortraitIDs, UsedWeaponIDs, UsedArmorIDs}. + --spec get_tile_ids +%%%% ROSTERS HANDLING %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec get_forbidden_locations     ( -      array:array(shr_tile:instance()) +      btl_battle:type()     ) -   -> ordsets:ordset(binary()). -get_tile_ids (TileInstances) -> -   UsedTileIDs = -      array:sparse_foldl -      ( -         fun (_IX, TileInstance, CurrentTileIDs) -> -            ordsets:add_element -            ( -               shr_tile:extract_main_class_id(TileInstance), -               CurrentTileIDs -            ) -         end, -         ordsets:new(), -         TileInstances -      ), - -   UsedTileIDs. +   -> ordsets:ordset(btl_location:type()). +get_forbidden_locations (Battle) -> +   orddict:fold +   ( +      fun (_IX, Char, Set) -> +         ordsets:add_element(btl_character:get_location(Char), Set) +      end, +      ordsets:new(), +      btl_battle:get_characters(Battle) +   ). -%%%% ROSTERS HANDLING %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  -spec find_random_location     (        btl_map:type(), -      ordsets:ordset({non_neg_integer(), non_neg_integer()}) +      ordsets:ordset(btl_location:type())     ) -   -> {{non_neg_integer(), non_neg_integer()}, shr_tile:type()}. +   -> {btl_location:type(), shr_tile:type()}.  find_random_location (Map, ForbiddenLocations) ->     MapWidth = btl_map:get_width(Map),     MapHeight = btl_map:get_height(Map), @@ -151,114 +173,182 @@ create_character (PlayerIX, RosterChar, Map, ForbiddenLocations) ->  -spec handle_characters     ( -      list(rst_character:type()), +      list({non_neg_integer(), rst_character:type()}),        non_neg_integer(), -      list(btl_character:type()),        btl_map:type(), -      ordsets:ordset(btl_location:type()) +      ordsets:ordset(btl_location:type()), +      non_neg_integer(), +      orddict:orddict(non_neg_integer(), btl_character:type()), +      list(ataxic:basic())     ) -   -> list(btl_character:type()). -handle_characters ([], _PlayerIX, Characters, _Map, _UsedLocations) -> -   Characters; +   -> +   { +      orddict:orddict(non_neg_integer(), btl_character:type()), +      list(ataxic:basic()) +   }.  handle_characters  ( -   [RosterCharacter|NextRosterCharacters], -   PlayerIX, +   [], +   _PlayerIX, +   _Map, +   _UsedLocations, +   _NextCharIX,     Characters, +   AtaxicUpdates +) -> +   {Characters, AtaxicUpdates}; +handle_characters +( +   [{_, RosterCharacter}|NextRosterCharacters], +   PlayerIX,     Map, -   UsedLocations +   UsedLocations, +   NextCharIX, +   Characters, +   AtaxicUpdates  ) ->     NewCharacter =        create_character(PlayerIX, RosterCharacter, Map, UsedLocations), +   NewCharacters = orddict:store(NextCharIX, NewCharacter, Characters), + +   NewUpdate = +      ataxic:apply_function +      ( +         orddict, +         store, +         [ +            ataxic:constant(NextCharIX), +            ataxic:constant(NewCharacter), +            ataxic:current_value() +         ] +      ), +     handle_characters     (        NextRosterCharacters,        PlayerIX, -      [NewCharacter|Characters],        Map, -      [btl_character:get_location(NewCharacter)|UsedLocations] +      [btl_character:get_location(NewCharacter)|UsedLocations], +      (NextCharIX + 1), +      NewCharacters, +      [NewUpdate|AtaxicUpdates]     ).  -spec handle_roster     (        rst_roster:type(), -      non_neg_integer(),        btl_map:type(), -      ordsets:ordset(btl_location:type()) +      ordsets:ordset(btl_location:type()), +      btl_battle:type()     ) -   -> {list(btl_character:type()), btl_player:type()}. +   -> {btl_battle:type(), ataxic:basic()}.  handle_roster  (     Roster, -   PlayersCount,     Map, -   UsedLocations +   UsedLocations, +   Battle  ) -> -   NewPlayer = btl_player:new(PlayersCount, 0, rst_roster:get_owner(Roster)), -   NewCharacters = +   Players = btl_battle:get_players(Battle), +   NextPlayerIX = orddict:size(Players), +   NewPlayer = btl_player:new(NextPlayerIX, 0, rst_roster:get_owner(Roster)), +   NewPlayers = orddict:store(NextPlayerIX, NewPlayer, Players), + +   Characters = btl_battle:get_characters(Battle), +   {NewCharacters, CharactersUpdates} =        handle_characters        ( -         array:to_list(rst_roster:get_characters(Roster)), -         PlayersCount, -         [], +         orddict:to_list(rst_roster:get_characters(Roster)), +         NextPlayerIX,           Map, -         UsedLocations +         UsedLocations, +         orddict:size(Characters), +         Characters, +         []        ), -   {NewCharacters, NewPlayer}. +   NewBattle = +      btl_battle:set_characters +      ( +         NewCharacters, +         btl_battle:set_players +         ( +            NewPlayers, +            Battle +         ) +      ), + +   Update = +      ataxic:sequence +      ( +         [ +            ataxic:update_field +            ( +               btl_battle:get_players_field(), +               ataxic:apply_function +               ( +                  orddict, +                  store, +                  [ +                     ataxic:constant(NextPlayerIX), +                     ataxic:constant(NewPlayer), +                     ataxic:current_value() +                  ] +               ) +            ), +            ataxic:update_field +            ( +               btl_battle:get_characters_field(), +               ataxic:sequence(CharactersUpdates) +            ) +         ] +      ), +   {NewBattle, Update}.  %%%% BATTLE CREATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec generate_battle -   ( -      binary(), -      map_map:type(), -      rst_roster:type() -   ) -   -> btl_battle:type(). -generate_battle (ID, Map, Roster) -> +-spec generate_battle (map_map:type(), rst_roster:type()) -> btl_battle:type(). +generate_battle (Map, Roster) ->     TileInstances = map_map:get_tile_instances(Map),     BattleMap = -      btl_map:from_array +      btl_map:from_instances_tuple        (           map_map:get_width(Map),           map_map:get_height(Map),           TileInstances        ), -   {Characters, FirstPlayer} = -      handle_roster(Roster, 0, BattleMap, ordsets:new()), -   {UsedWeaponIDs, UsedArmorIDs} = get_equipment_ids(Characters), -   UsedTileIDs = get_tile_ids(TileInstances), +   Battle = btl_battle:new(BattleMap), +   {S0Battle, _AtaxicUpdate} = +      handle_roster(Roster, BattleMap, ordsets:new(), Battle), + +   {UsedPortraitIDs, UsedWeaponIDs, UsedArmorIDs} = +      get_equipment_ids(btl_battle:get_characters(S0Battle)), -   Battle = -      btl_battle:new +   S1Battle = +      btl_battle:set_used_portrait_ids        ( -         ID, -         [FirstPlayer], -         BattleMap, -         Characters, -         UsedWeaponIDs, -         UsedArmorIDs, -         UsedTileIDs +         UsedPortraitIDs, +         btl_battle:set_used_weapon_ids +         ( +            UsedWeaponIDs, +            btl_battle:set_used_armor_ids +            ( +               UsedArmorIDs, +               S0Battle +            ) +         )        ), -   Battle. +   S1Battle.  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec generate -   ( -      map_map:type(), -      rst_roster:type() -   ) -   -> btl_battle:type(). +-spec generate (map_map:type(), rst_roster:type()) -> btl_battle:type().  generate (Map, Roster) -> -   ID = reserve_id(), -   Battle = generate_battle(ID, Map, Roster), -   ok = commit(Battle), +   Battle = generate_battle(Map, Roster),     Battle.  -spec add_to @@ -266,6 +356,83 @@ generate (Map, Roster) ->        rst_roster:type(),        btl_battle:type()     ) -   -> btl_battle:type(). -add_to (_Roster, Battle) -> -   Battle. +   -> {btl_battle:type(), ataxic:basic()}. +add_to (Roster, Battle) -> +   BattleMap = btl_battle:get_map(Battle), +   ForbiddenLocations = get_forbidden_locations(Battle), + +   {S0Battle, AtaxicUpdate} = +      handle_roster +      ( +         Roster, +         BattleMap, +         ForbiddenLocations, +         Battle +      ), + +   {UsedPortraitIDs, UsedWeaponIDs, UsedArmorIDs} = +      get_equipment_ids(rst_roster:get_characters(Roster)), + +   OldPortraitIDs = btl_battle:get_used_portrait_ids(Battle), +   PortraitIDsUpdate = +      ataxic:update_field +      ( +         btl_battle:get_used_portrait_ids_field(), +         update_ordset(UsedPortraitIDs, OldPortraitIDs) +      ), + +   OldWeaponIDs = btl_battle:get_used_portrait_ids(Battle), +   WeaponIDsUpdate = +      ataxic:update_field +      ( +         btl_battle:get_used_weapon_ids_field(), +         update_ordset(UsedWeaponIDs, OldWeaponIDs) +      ), + +   OldArmorIDs = btl_battle:get_used_armor_ids(Battle), +   ArmorIDsUpdate = +      ataxic:update_field +      ( +         btl_battle:get_used_armor_ids_field(), +         update_ordset(UsedArmorIDs, OldArmorIDs) +      ), + +   S1Battle = +      btl_battle:set_used_armor_ids +      ( +         ordsets:union(UsedArmorIDs, OldArmorIDs), +         btl_battle:set_used_weapon_ids +         ( +            ordsets:union(UsedWeaponIDs, OldWeaponIDs), +            btl_battle:set_used_portrait_ids +            ( +               ordsets:union(UsedPortraitIDs, OldPortraitIDs), +               S0Battle +            ) +         ) +      ), + +   Update = +      ataxic:sequence +      ( +         [ +            ataxic:update_field +            ( +               btl_battle:get_used_portrait_ids_field(), +               PortraitIDsUpdate +            ), +            ataxic:update_field +            ( +               btl_battle:get_used_weapon_ids_field(), +               WeaponIDsUpdate +            ), +            ataxic:update_field +            ( +               btl_battle:get_used_armor_ids_field(), +               ArmorIDsUpdate +            ), +            AtaxicUpdate +         ] +      ), + +   {S1Battle, Update}. | 


