| summaryrefslogtreecommitdiff | 
diff options
| author | nsensfel <SpamShield0@noot-noot.org> | 2018-02-23 18:46:05 +0100 | 
|---|---|---|
| committer | nsensfel <SpamShield0@noot-noot.org> | 2018-02-23 18:46:05 +0100 | 
| commit | f512cb83df8dea9fb39bd98540b0616fe7607f6d (patch) | |
| tree | 1e11c44c66533a3ce6e55c1c7533f9a0c04a662d | |
| parent | acf9e9f1eb880ffb8ab918c40724eda566aefcc7 (diff) | |
Rewritting "character_turn.erl"...
| -rw-r--r-- | src/io/security.erl | 19 | ||||
| -rw-r--r-- | src/query/character_turn.erl | 437 | ||||
| -rw-r--r-- | src/query/character_turn/handle_character_attacking_2.erl | 59 | 
3 files changed, 328 insertions, 187 deletions
| diff --git a/src/io/security.erl b/src/io/security.erl new file mode 100644 index 0000000..fb7be8d --- /dev/null +++ b/src/io/security.erl @@ -0,0 +1,19 @@ +-module(security). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export([assert_identity/2]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +assert_identity (_PlayerID, _SessionToken) -> true. diff --git a/src/query/character_turn.erl b/src/query/character_turn.erl index 501c82b..d71c64a 100644 --- a/src/query/character_turn.erl +++ b/src/query/character_turn.erl @@ -9,11 +9,10 @@  (     input,     { -      session_token,        player_id, -      battlemap_id, -      instance_id, -      char_id, +      session_token, +      battlemap_instance_id, +      character_instance_id,        path,        target_id     } @@ -23,14 +22,9 @@  (     query_state,     { -      input, -      battlemap, -      battlemap_inst, -      main_char, -      main_char_inst, -      main_char_new_loc, -      target_char, -      target_char_inst +      battlemap_instance, +      character_instance, +      rolls     }  ). @@ -44,231 +38,300 @@  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  parse_input (Req) ->     JSONReqMap = jiffy:decode(Req, [return_maps]), -   PlayerID = maps:get(<<"player_id">>, JSONReqMap), -   SessionToken = maps:get(<<"session_token">>, JSONReqMap), -   Target = -      case maps:get(<<"targets_id">>, JSONReqMap) of -         [] -> <<"">>; -         [T] -> T -      end, +   CharacterInstanceID = binary_to_integer(maps:get(<<"cid">>, JSONReqMap)), +   TargetID = binary_to_integer(maps:get(<<"tid">>, JSONReqMap)),     #input     { -      player_id = PlayerID, -      battlemap_id = maps:get(<<"battlemap_id">>, JSONReqMap), -      instance_id = maps:get(<<"instance_id">>, JSONReqMap), -      char_id = maps:get(<<"char_id">>, JSONReqMap), -      path = maps:get(<<"path">>, JSONReqMap), -      target_id = Target +      player_id = maps:get(<<"pid">>, JSONReqMap), +      session_token = maps:get(<<"stk">>, JSONReqMap), +      battlemap_instance_id = maps:get(<<"bmp">>, JSONReqMap), +      character_instance_id = CharacterInstanceID, +      path = maps:get(<<"p">>, JSONReqMap), +      target_id = TargetID     }.  fetch_data (Input) -> -   Battlemap = -      timed_cache:fetch -      ( -         battlemap_db, -         Input#input.player_id, -         Input#input.battlemap_id -      ), -   BattlemapInst = +   BattlemapInstance =        timed_cache:fetch        (           battlemap_instance_db,           Input#input.player_id, -         <<"0">> -      ), -   MainChar = -      timed_cache:fetch -      ( -         character_db, -         Input#input.player_id, -         Input#input.char_id +         Input#input.battlemap_instance_id        ), -   MainCharInst = -      battlemap_instance:get_char_instance +   CharacterInstance = +      array:get        ( -         BattlemapInst, -         Input#input.char_id +         Input#input.character_instance_id, +         battlemap_instance:get_character_instances(BattlemapInstance)        ), -   case Input#input.target_id of -      <<"">> -> -         TargetChar = nothing, -         TargetCharInst = nothing; - -      TargetID -> -         TargetChar = -            timed_cache:fetch -            ( -               character_db, -               Input#input.player_id, -               TargetID -            ), -         TargetCharInst = -            battlemap_instance:get_char_instance -            ( -               BattlemapInst, -               TargetID -            ) -   end,     #query_state     { -      input = Input, -      battlemap = Battlemap, -      battlemap_inst = BattlemapInst, -      main_char = MainChar, -      main_char_inst = MainCharInst, -      main_char_new_loc = nothing, -      target_char = TargetChar, -      target_char_inst = TargetCharInst +      battlemap_instance = BattlemapInstance, +      character_instance = CharacterInstance, +      rolls = []     }. -assert_main_char_can_be_used (QueryState) -> -   false = character_instance:is_dead(QueryState#query_state.main_char_inst), -   true = -      battlemap_instance:can_play_char_instance +assert_character_can_be_played (QueryState, Input) -> +   %%% Var +   BattlemapInstance = QueryState#query_state.battlemap_instance, +   PlayerID = Input#input.player_id, +   ControlledCharacterInstance = QueryState#query_state.character_instance, +   %%% Asserts +   PlayerID = +      arrays:get        ( -         QueryState#query_state.battlemap_inst, -         QueryState#query_state.input#input.player_id, -         QueryState#query_state.input#input.char_id -      ). +         player_turn:get_player_id +         ( +            battlemap_instance:get_player_turn(BattlemapInstance) +         ), +         battlemap_instance:get_players(BattlemapInstance) +      ), +   PlayerID = +      character:get_owner +      ( +         character_instance:get_character(ControlledCharacterInstance) +      ), +   true = character_instance:is_active(ControlledCharacterInstance). -handle_main_char_movement (QueryState) -> -   {X, Y} = -      battlemap:cross +handle_character_moving (QueryState, Input) -> +   BattlemapInstance = QueryState#query_state.battlemap_instance, +   ControlledCharacterInstance = QueryState#query_state.character_instance, +   ControlledCharacter = +      character_instance:get_character(ControlledCharacterInstance), +   Path = Input#input.path, +   Battlemap = battlemap_instance:get_battlemap(BattlemapInstance), +   ForbiddenLocations = +      array:map        ( -         QueryState#query_state.battlemap, -         character_instance:get_location(QueryState#query_state.main_char_inst), +         fun (CharacterInstance) -> +            character_instance:get_location(CharacterInstance) +         end, +         battlemap_instance:get_character_instances(BattlemapInstance) +      ), +   {ok, NewLocation, _} = +      movement:cross +      ( +         Battlemap, +         character_instance:get_location(ControlledCharacterInstance),           statistics:get_movement_points           ( -            character_instance:get_statistics -            ( -               QueryState#query_state.main_char_inst -            ) +            character:get_statistics(ControlledCharacter)           ), -         QueryState#query_state.input#input.path, -         battlemap_instance:get_char_instances +         Path, +         ForbiddenLocations +      ), +   QueryState#query_state +   { +      character_instance = +         character_instance:set_location           ( -            QueryState#query_state.battlemap_inst +            NewLocation, +            ControlledCharacterInstance           ) -      ), +   }. + +handle_character_switching_weapons (QueryState) -> +   ControlledCharacterInstance = QueryState#query_state.character_instance, +   ControlledCharacter = +      character_instance:get_character(ControlledCharacterInstance),     QueryState#query_state     { -      battlemap_inst = -         battlemap_instance:set_char_instance +      character_instance = +         character_instance:set_character           ( -            battlemap_instance:post_play_char_instance +            character:set_weapons              ( -               QueryState#query_state.battlemap_inst, -               QueryState#query_state.input#input.char_id +               weapon_set:switch +               ( +                  character:get_weapons(ControlledCharacter) +               ), +               ControlledCharacter              ), -            QueryState#query_state.input#input.char_id, -            character_instance:set_location -            ( -               QueryState#query_state.main_char_inst, -               X, -               Y -            ) -         ), -      main_char_new_loc = {X, Y} +            ControlledCharacterInstance +         )     }. -handle_target (QueryState) -   when (QueryState#query_state.target_char_inst == nothing) -> -   QueryState; -handle_target (QueryState) -> -   TargetLoc = -      character_instance:get_location(QueryState#query_state.target_char_inst), -   Dist = -      battlemap:dist(QueryState#query_state.main_char_new_loc, TargetLoc), -   AtkWeapon = -      weapon:from_id -      ( -         character_instance:get_active_weapon -         ( -            QueryState#query_state.main_char_inst, -            QueryState#query_state.main_char -         ) -      ), -   {_, AtkRange} = weapon:get_ranges(AtkWeapon), -   io:format -   ( -      "~nAttack from ~p to ~p (wp: ~p, dist: ~p, range: ~p).~n", -      [ -         QueryState#query_state.main_char_new_loc, -         TargetLoc, -         weapon:get_id(AtkWeapon), -         Dist, -         AtkRange -      ] -   ), -   true = (Dist =< AtkRange), -   TargetStatistics = -      character_instance:get_statistics -      ( -         QueryState#query_state.target_char_inst -      ), -   {MinDamage, MaxDamage} = weapon:get_damages(AtkWeapon), -   Diff = max(1, MaxDamage - MinDamage), -   NewTargetCharInst = -      character_instance:mod_health +-include("character_turn/handle_character_attacking_2.erl"). + +get_type_of_turn (Input) -> +   case {Input#input.path, Input#input.target_id} of +      {[], -1} -> [nothing, nothing]; +      {[], _} -> [nothing, attack]; +      {[<<"S">>], -1} -> [switch, nothing]; +      {[<<"S">>], _} -> [switch, attack]; +      {_, -1} -> [move, nothing]; +      {_, _} -> [move, attack] +   end. + +finalize_character_instance (QueryState, Input) -> +   BattlemapInstance = QueryState#query_state.battlemap_instance, +   FinalizedCharacterInstance = +      character_instance:set_active        ( -         QueryState#query_state.target_char_inst, -         statistics:get_health(TargetStatistics), -         (MinDamage + rand:uniform(Diff) - 1) +         false, +         QueryState#query_state.character_instance        ), -   %% TODO: test for (and handle) riposte.     QueryState#query_state     { -      battlemap_inst = -         battlemap_instance:set_char_instance +      battlemap_instance = +         battlemap_instance:set_characters           ( -            QueryState#query_state.battlemap_inst, -            QueryState#query_state.input#input.target_id, -            NewTargetCharInst +            array:set +            ( +               Input#input.character_instance_id, +               FinalizedCharacterInstance, +               battlemap_instance:get_characters(BattlemapInstance) +            ), +            BattlemapInstance           ), -      target_char_inst = NewTargetCharInst +      character_instance = FinalizedCharacterInstance     }. -generate_reply (QueryState) -> -   case QueryState#query_state.target_char_inst of -      nothing -> [<<"okay">>]; +unnamed_function (IDs, CharacterInstances, _Owner, -1) -> +   {IDs, CharacterInstances}; +unnamed_function (IDs, CharacterInstances, Owner, I) -> +   CharacterInstance = array:get(I, CharacterInstances), +   Character = character_instance:get_character(CharacterInstance), +   case character:get_owner(Character) of +      OwnerID when (OwnerID == Owner) -> +         unnamed_function +         ( +            [I|IDs], +            array:set +            ( +               I, +               character_instance:set_is_active(true, CharacterInstance), +               CharacterInstances +            ), +            Owner, +            (I - 1) +         ); -      CharInst -> -         add_char:generate +      _ -> +         unnamed_function           ( -            QueryState#query_state.target_char, -            CharInst, +            IDs, +            CharacterInstances, +            Owner, +            (I - 1) +         ) +   end. + +start_next_players_turn (QueryState, Input) -> +   BattlemapInstance = QueryState#query_state.battlemap_instance, +   Players = battlemap_instance:get_players(BattlemapInstance), +   PlayerTurn = battlemap_instance:get_player_turn(BattlemapInstance), +   CurrentPlayerID = player_turn:get_player_id(PlayerTurn), +   CurrentTurnNumber = player_turn:get_number(PlayerTurn), +   CharacterInstances = +      battlemap_instance:get_character_instances(BattlemapInstance), + +   NextPlayer = ((CurrentPlayerID + 1) rem (array:size(Players))), +   NextPlayerTurn = +      player_turn:new +      ( +         case NextPlayer of +            0 -> (CurrentTurnNumber + 1); +            _ -> CurrentTurnNumber +         end, +         NextPlayer +      ), + +   {ActivatedCharacterInstancesID, UpdatedCharacterInstances} = +      unnamed_function +      ( +         [], +         CharacterInstances, +         array:get(NextPlayer, Players), +         array:size(CharacterInstances) +      ), +   { +      ActivatedCharacterInstancesID, +      QueryState#query_state +      { +         battlemap_instance = +            battlemap_instance:set_character_instances              ( -               battlemap_instance:can_play_char_instance +               UpdatedCharacterInstances, +               battlemap_instance:set_player_turn                 ( -                  QueryState#query_state.battlemap_inst, -                  QueryState#query_state.input#input.player_id, -                  QueryState#query_state.input#input.target_id +                  NextPlayerTurn, +                  BattlemapInstance                 ) -               and -               (not character_instance:is_dead(CharInst))              ) -         ) +      } +   }. + +finalize_character_turn (QueryState, Input) -> +   BattlemapInstance = QueryState#query_state.battlemap_instance, +   Players = battlemap_instance:get_players(BattlemapInstance), + +   CharacterInstanceRemains = +      array:foldl +      ( +         fun (_I, CharacterInstance, Prev) -> +            (Prev or character_instance:get_is_active(CharacterInstance)) +         end, +         Players +      ), + +   case CharacterInstanceRemains of +      true -> {false, {[], QueryState}}; +      false -> {true, start_next_players_turn(QueryState, Input)}     end. +play (QueryState, [], Input) -> +   finalize_character_turn +   ( +      finalize_character_instance(QueryState, Input), +      Input +   ); +play (QueryState, [nothing|Next], Input) -> +   play(QueryState, Next, Input); +play (QueryState, [move|Next], Input) -> +   play +   ( +      handle_character_moving(QueryState, Input), +      Next, +      Input +   ); +play (QueryState, [switch|Next], Input) -> +   play +   ( +      handle_character_switching_weapons(QueryState), +      Next, +      Input +   ); + +play (QueryState, [attack|Next], Input) -> +   play +   ( +      handle_character_attacking(QueryState, Input), +      Next, +      Input +   ). + +send_to_database (QueryState, TurnType, Input) -> +   unimplemented. + +update_cache (QueryState, TurnType, Input) -> +   unimplemented. + +generate_reply (QueryState, TurnType, Input) -> +   jiffy:encode([[<<"ok">>]]). +  handle (Req) -> -   %%%% Parse     Input = parse_input(Req), -   assert_player_identity(Req), -   %%%% Fetch +   security:assert_identity(Req#input.player_id, Req#input.session_token),     QueryState = fetch_data(Input), -   %%%% Calc -   assert_main_char_can_be_used(QueryState), -   NQueryState = handle_target(handle_main_char_movement(QueryState)), -   %%%% Commit -   database_shim:commit -   ( -      battlemap_instance_db, -      Input#input.player_id, -      <<"0">>, -      NQueryState#query_state.battlemap_inst -   ), -   %%%% Reply -   jiffy:encode([generate_reply(NQueryState)]). +   assert_character_can_be_played(Input, QueryState), +   TurnType = get_type_of_turn(Input), +   {IsNewTurn, {UpdatedCharacterInstancesID, PostPlayQueryState}} = +      play(QueryState, TurnType, Input), +   send_to_database(PostPlayQueryState, TurnType, Input), +   update_cache(PostPlayQueryState, TurnType, Input), +   generate_reply(PostPlayQueryState, TurnType, Input). +  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/query/character_turn/handle_character_attacking_2.erl b/src/query/character_turn/handle_character_attacking_2.erl new file mode 100644 index 0000000..3fd2687 --- /dev/null +++ b/src/query/character_turn/handle_character_attacking_2.erl @@ -0,0 +1,59 @@ +roll_hits (AttackerStatistics, DefenderStatistics) -> +   MissChance = +      max +      ( +         0, +         ( +            statistics:get_dodges(DefenderStatistics) +            - +            statistics:get_accuracy(AttackerStatistics) +         ) +      ), +   case roll:percentage() of +      X when (X < MissChance) -> misses; +      X when (X < (MissChance * 2)) -> grazes; +      _ -> hits +   end. + +roll_damage (AttackerStatistics, _DefenderStatistics) -> +   {MinimumDamage, MaximumDamage} = statistics:get_damages(AttackerStatistics), +   MaximumRoll = max(1, MaximumDamage - MinimumDamage), +   MinimumDamage + (rand:uniform(MaximumRoll) - 1). + +handle_character_attacking (QueryState, Input) -> +   BattlemapInstance = QueryState#query_state.battlemap_instance, +   ControlledCharacterInstance = QueryState#query_state.character_instance, +   ControlledCharacter = +      character_instance:get_character(ControlledCharacterInstance), +   ControlledCharacterStatistics = +      character:get_statistics(ControlledCharacter), +   TargettedCharacterInstance = +      array:get +      ( +         Input#input.target_id, +         battlemap_instance:get_characters(BattlemapInstance) +      ), +   TargettedCharacter = +      character_instance:get_character(TargettedCharacterInstance), +   TargettedCharacterStatistics = character:get_statistics(TargettedCharacter), +   RequiredRange = +      movement:steps_between +      ( +         character_instance:get_location(ControlledCharacterInstance), +         character_instance:get_location(TargettedCharacterInstance) +      ), +   {AttackingWeaponID, _} = character:get_weapon_ids(ControlledCharacter), +   AttackingWeapon = weapon:from_id(AttackingWeaponID), +   {_, AttackingWeaponRange} = weapon:get_ranges(AttackingWeapon), +   {DefendingWeaponID, _} = character:get_weapon_ids(TargettedCharacter), +   DefendingWeapon = weapon:from_id(DefendingWeaponID), +   {DefendingWeaponRange, _} = weapon:get_ranges(DefendingWeapon), + +   true = (RequiredRange =< AttackingWeaponRange), + +   {Rolls, HealthMod} = +      handle_attack +      ( +         ControlledCharacterStatistics, +         TargettedCharacterStatistics +      ). | 


