summaryrefslogtreecommitdiff
blob: f406efd00dda091bcae3fc191b35bc9e1bca4891 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
-module(character_turn).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-include("../../include/yaws_api.hrl").

-record
(
   input,
   {
      session_token,
      player_id,
      battlemap_id,
      instance_id,
      char_id,
      path,
      target_id
   }
).

-record
(
   query_state,
   {
      input,
      battlemap,
      battlemap_inst,
      main_char,
      main_char_inst,
      main_char_new_loc,
      target_char,
      target_char_inst
   }
).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-export([out/1]).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
parse_input (Req) ->
   JSONReqMap = jiffy:decode(Req, [return_maps]),
   PlayerID = maps:get(<<"player_id">>, JSONReqMap),
   SessionToken =  maps:get(<<"session_token">>, JSONReqMap),
   database_shim:assert_session_is_valid(PlayerID, SessionToken),
   #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 = maps:get(<<"target_id">>, JSONReqMap)
   }.

fetch_data (Input) ->
   Battlemap = timed_cache:fetch(battlemap_db, Input#input.battlemap_id),
   BattlemapInst =
      timed_cache:fetch
      (
         battlemap_instance_db,
         <<"0">>
      ),
   MainChar = timed_cache:fetch(character_db, Input#input.char_id),
   MainCharInst =
      battlemap_instance:get_char_instance
      (
         BattlemapInst,
         Input#input.char_id
      ),
   case Input#input.target_id of
      <<"">> ->
         TargetChar = nothing,
         TargetCharInst = nothing;

      TargetID ->
         TargetChar = timed_cache:fetch(character_db, 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
   }.

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
      (
         QueryState#query_state.battlemap_inst,
         QueryState#query_state.input#input.player_id,
         QueryState#query_state.input#input.char_id
      ).

handle_main_char_movement (QueryState) ->
   {X, Y} =
      battlemap:cross
      (
         QueryState#query_state.battlemap,
         character_instance:get_location(QueryState#query_state.main_char_inst),
         character:get_movement_points(QueryState#query_state.main_char),
         QueryState#query_state.input#input.path,
         battlemap_instance:get_char_instances
         (
            QueryState#query_state.battlemap_inst
         )
      ),
   QueryState#query_state
   {
      battlemap_inst =
         battlemap_instance:set_char_instance
         (
            battlemap_instance:post_play_char_instance
            (
               QueryState#query_state.battlemap_inst,
               QueryState#query_state.input#input.char_id
            ),
            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}
   }.

handle_target (QueryState)
   when (QueryState#query_state.target_char_inst == nothing) ->
   QueryState;
handle_target (QueryState) ->
   TargetLoc =
      character_instance:get_location(QueryState#query_state.main_char_inst),
   Dist =
      battlemap:dist(QueryState#query_state.main_char_new_loc, TargetLoc),
   true =
      (Dist =< character:get_attack_range(QueryState#query_state.main_char)),
   %% TODO: test for (and handle) riposte.
   QueryState#query_state
   {
      battlemap_inst =
         battlemap_instance:set_char_instance
         (
            QueryState#query_state.battlemap_inst,
            QueryState#query_state.input#input.target_id,
            character_instance:mod_health
            (
               QueryState#query_state.target_char_inst,
               -1,
               character:get_max_health(QueryState#query_state.main_char)
            )
         )
   }.

handle (Req) ->
   %%%% Parse
   Input = parse_input(Req),
   %%%% Fetch
   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,
      <<"0">>,
      NQueryState#query_state.battlemap_inst
   ),
   %%%% Reply
   jiffy:encode([[<<"okay">>]]).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
out(A) ->
   {
      content,
      "application/json; charset=UTF-8",
      handle(A#arg.clidata)
   }.