| 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
 | -module(btl_next_turn).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-export
(
   [
      update_if_needed/1
   ]
).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-spec set_player_turn_to_next (btl_battle:type())
   -> {btl_battle:type(), ataxic:basic()}.
set_player_turn_to_next (Battle) ->
   Players = btl_battle:get_players(Battle),
   CurrentPlayerTurn = btl_battle:get_current_player_turn(Battle),
   NextPlayerTurn = btl_player_turn:next(Players, CurrentPlayerTurn),
   UpdatedBattle = btl_battle:set_current_player_turn(NextPlayerTurn, Battle),
   DBQuery =
      ataxic:update_field
      (
         btl_battle:get_current_player_turn_field(),
         ataxic:constant(NextPlayerTurn)
      ),
   {UpdatedBattle, DBQuery}.
-spec reset_next_player_timeline (btl_battle:type())
   -> {btl_battle:type(), btl_player:type(), ataxic:basic()}.
reset_next_player_timeline (Battle) ->
   NextPlayerTurn = btl_battle:get_current_player_turn(Battle),
   NextPlayerIX = btl_player_turn:get_player_ix(NextPlayerTurn),
   NextPlayer = btl_battle:get_player(NextPlayerIX, Battle),
   UpdatedNextPlayer = btl_player:reset_timeline(NextPlayer),
   UpdatedBattle =
      btl_battle:set_player(NextPlayerIX, UpdatedNextPlayer, Battle),
   DBQuery =
      ataxic:update_field
      (
         btl_battle:get_players_field(),
         ataxic_sugar:update_orddict_element
         (
            NextPlayerIX,
            ataxic:update_field
            (
               btl_player:get_timeline_field(),
               ataxic:constant([])
            )
         )
      ),
   {UpdatedBattle, UpdatedNextPlayer, DBQuery}.
-spec activate_next_players_characters (btl_battle:type(), btl_player:type())
   -> {btl_battle:type(), ataxic:basic()}.
activate_next_players_characters (Battle, NextPlayer) ->
   NextPlayerIX = btl_player:get_index(NextPlayer),
   Characters = btl_battle:get_characters(Battle),
   {UpdatedCharacters, AtaxicUpdates} =
      orddict:fold
      (
         fun (IX, Character, {Prev, Updates}) ->
            case (btl_character:get_player_index(Character) == NextPlayerIX) of
               true ->
                  {
                     orddict:store
                     (
                        IX,
                        btl_character:set_is_active(true, Character),
                        Prev
                     ),
                     [
                        ataxic_sugar:update_orddict_element
                        (
                           IX,
                           ataxic:update_field
                           (
                              btl_character:get_is_active_field(),
                              ataxic:constant(true)
                           )
                        )|Updates
                     ]
                  };
               false -> {Prev, Updates}
            end
         end,
         {Characters, []},
         Characters
      ),
   DBQuery =
      ataxic:update_field
      (
         btl_battle:get_characters_field(),
         ataxic:sequence(AtaxicUpdates)
      ),
   UpdatedBattle = btl_battle:set_characters(UpdatedCharacters, Battle),
   {UpdatedBattle, DBQuery}.
-spec update
   (
      btl_character_turn_update:type()
   )
   -> btl_character_turn_update:type().
update (Update) ->
   Data = btl_character_turn_update:get_data(Update),
   Battle = btl_character_turn_data:get_battle(Data),
   {S0Battle, DBQuery0} = set_player_turn_to_next(Battle),
   {S1Battle, NextPlayer, DBQuery1} = reset_next_player_timeline(S0Battle),
   {S2Battle, DBQuery2} =
      activate_next_players_characters(S1Battle, NextPlayer),
   S0Data = btl_character_turn_data:set_battle(S2Battle, Data),
   S0Update =
      btl_character_turn_update:add_to_timeline
      (
         btl_turn_result:new_player_turn_started
         (
            btl_player:get_index(NextPlayer)
         ),
         DBQuery0,
         Update
      ),
   S1Update = btl_character_turn_update:set_data(S0Data, S0Update),
   S2Update =
      lists:foldl
      (
         fun btl_character_turn_update:add_to_db/2,
         S1Update,
         [DBQuery1,DBQuery2]
      ),
   S2Update.
-spec requires_update (btl_character_turn_update:type()) -> boolean().
requires_update (Update) ->
   Data = btl_character_turn_update:get_data(Update),
   Battle = btl_character_turn_data:get_battle(Data),
   Characters = btl_battle:get_characters(Battle),
   (not
      (lists:any
         (
            fun ({_IX, Char}) ->
               btl_character:get_is_active(Char)
            end,
            orddict:to_list(Characters)
         )
      )
   ).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-spec update_if_needed
   (
      btl_character_turn_update:type()
   )
   -> btl_character_turn_update:type().
update_if_needed (Update) ->
   case requires_update(Update) of
      true -> update(Update);
      _ -> Update
   end.
 |