summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/battlemap')
-rw-r--r--src/battlemap/bm_shim.erl14
-rw-r--r--src/battlemap/game-logic/bm_next_turn.erl4
-rw-r--r--src/battlemap/game-logic/bm_turn_actions.erl163
-rw-r--r--src/battlemap/query/bm_character_turn.erl8
-rw-r--r--src/battlemap/query/bm_load_state.erl15
-rw-r--r--src/battlemap/reply/bm_add_char.erl11
-rw-r--r--src/battlemap/struct/bm_character.erl25
7 files changed, 214 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().