From 80358376b9300a0d73cb8b62dfa9fdd65240ca66 Mon Sep 17 00:00:00 2001 From: nsensfel Date: Tue, 28 Nov 2017 13:38:04 +0100 Subject: Starting to work on attacks. I find it difficult to keep the code tidy in Erlang... --- src/battlemap.erl | 5 +- src/battlemap_instance.erl | 14 +-- src/character.erl | 7 +- src/character_instance.erl | 17 ++++ src/character_shim.erl | 1 + src/database_shim.erl | 3 +- src/timed_cache_data.hrl | 4 +- www/handler/battlemap/character_turn.yaws | 150 ++++++++++++++++++++++++------ 8 files changed, 161 insertions(+), 40 deletions(-) diff --git a/src/battlemap.erl b/src/battlemap.erl index d8940e9..ba89733 100644 --- a/src/battlemap.erl +++ b/src/battlemap.erl @@ -1,5 +1,8 @@ -module(battlemap). - +-export([dist/2]). -include("timed_cache_data.hrl"). -include("battlemap/cross.erl"). + +dist ({OX, OY}, {DX, DY}) -> + (abs(OX - DX) + abs(OY + DY)). diff --git a/src/battlemap_instance.erl b/src/battlemap_instance.erl index 3f4b6cd..afe6e32 100644 --- a/src/battlemap_instance.erl +++ b/src/battlemap_instance.erl @@ -27,13 +27,13 @@ can_play_char_instance ) -> ( ( - array:get - ( - BattlemapInstance#battlemap_instance.curr_player, - BattlemapInstance#battlemap_instance.players - ) - =:= - PlayerID + array:get + ( + BattlemapInstance#battlemap_instance.curr_player, + BattlemapInstance#battlemap_instance.players + ) + =:= + PlayerID ) and lists:member(CharInstID, BattlemapInstance#battlemap_instance.rem_chars) diff --git a/src/character.erl b/src/character.erl index f596570..4da1684 100644 --- a/src/character.erl +++ b/src/character.erl @@ -2,10 +2,15 @@ -export ( [ - get_movement_points/1 + get_movement_points/1, + get_attack_range/1, + get_max_health/1 ] ). -include("timed_cache_data.hrl"). get_movement_points (Char) -> Char#character.mov_pts. +get_attack_range (Char) -> Char#character.atk_rg. + +get_max_health (Char) -> Char#character.health. diff --git a/src/character_instance.erl b/src/character_instance.erl index a38be5d..e1cf7fe 100644 --- a/src/character_instance.erl +++ b/src/character_instance.erl @@ -3,6 +3,8 @@ ( [ set_location/3, + mod_health/3, + is_dead/1, % is_alive is reserved. get_location/1, get_owner/1 ] @@ -17,6 +19,21 @@ set_location (CharInst, X, Y) -> y = Y }. +mod_health (CharInst, MaxHealth, HealthMod) -> + NewHealth = (CharInst#character_instance.health + HealthMod), + if + (NewHealth < 0) -> + CharInst#character_instance{ health = 0 }; + + (NewHealth > MaxHealth) -> + CharInst#character_instance{ health = MaxHealth }; + + true -> + CharInst#character_instance{ health = NewHealth } + end. + +is_dead (CharInst) -> (CharInst#character_instance.health == 0). + get_location (CharInst) -> {CharInst#character_instance.x, CharInst#character_instance.y}. diff --git a/src/character_shim.erl b/src/character_shim.erl index 0ab33cb..47d9cac 100644 --- a/src/character_shim.erl +++ b/src/character_shim.erl @@ -19,6 +19,7 @@ generate_char (N) -> name = IDAsString, % Name icon = IDAsString, % Icon portrait = IDAsString, % Portrait + health = (rand:uniform(5) + 1), mov_pts = (rand:uniform(10) + 10), % Movement Points atk_rg = (rand:uniform(5) - 1) % Attack Range }. diff --git a/src/database_shim.erl b/src/database_shim.erl index 1966b6b..c840009 100644 --- a/src/database_shim.erl +++ b/src/database_shim.erl @@ -41,7 +41,8 @@ generate_char_instances (Battlemap, Characters) -> { x = rand:uniform(Battlemap#battlemap.width - 1), y = rand:uniform(Battlemap#battlemap.height - 1), - team = (rand:uniform(2) - 1) + team = (rand:uniform(2) - 1), + health = Char#character.health } } end, diff --git a/src/timed_cache_data.hrl b/src/timed_cache_data.hrl index 23441d3..89e0f41 100644 --- a/src/timed_cache_data.hrl +++ b/src/timed_cache_data.hrl @@ -1,9 +1,9 @@ %% TODO: add types. -record(battlemap, {id, width, height, content, instances}). -record(battlemap_instance, {id, chars, curr_player, players, rem_chars, last_turn}). --record(character, {id, name, icon, portrait, mov_pts, atk_rg}). +-record(character, {id, name, icon, portrait, health, mov_pts, atk_rg}). -record(character_turn, {id, path, target}). -record(player, {id, battlemaps, characters}). %% Not stored in its own timed cache. --record(character_instance, {x, y, team}). +-record(character_instance, {x, y, health, team}). diff --git a/www/handler/battlemap/character_turn.yaws b/www/handler/battlemap/character_turn.yaws index 83a3570..2b3f818 100644 --- a/www/handler/battlemap/character_turn.yaws +++ b/www/handler/battlemap/character_turn.yaws @@ -12,6 +12,21 @@ target_id } ). +-record +( + query_state, + { + input, + battlemap, + battlemap_inst, + main_char, + main_char_inst, + main_char_new_loc, + target_char, + target_char_inst + } +). + -include("/my/src/tacticians-server/src/timed_cache_data.hrl"). @@ -28,54 +43,133 @@ parse_input (Req) -> target_id = maps:get(<<"target_id">>, JSONReqMap) }. -handle (Req) -> - %%%% Parse - Input = parse_input(Req), - %%%% Fetch +fetch_data (Input) -> Battlemap = timed_cache:fetch(battlemap_db, Input#input.battlemap_id), - BattlemapInstance = + BattlemapInst = timed_cache:fetch ( battlemap_instance_db, <<"0">> ), - Character = timed_cache:fetch(character_db, Input#input.char_id), - CharInst = + MainChar = timed_cache:fetch(character_db, Input#input.char_id), + MainCharInst = battlemap_instance:get_char_instance ( - BattlemapInstance, + BattlemapInst, Input#input.char_id ), - %%%% Calc + 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 ( - BattlemapInstance, - Input#input.player_id, - Input#input.char_id - ), + 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 ( - Battlemap, - character_instance:get_location(CharInst), - character:get_movement_points(Character), - Input#input.path, - battlemap_instance:get_char_instances(BattlemapInstance) + 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 + ) ), - NewBattlemapInstance = - battlemap_instance:set_char_instance - ( - battlemap_instance:post_play_char_instance + QueryState#query_state + { + battlemap_inst = + battlemap_instance:set_char_instance ( - BattlemapInstance, - Input#input.char_id + 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 + ) ), - Input#input.char_id, - character_instance:set_location(CharInst, 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">>, NewBattlemapInstance), + database_shim:commit + ( + battlemap_instance_db, + <<"0">>, + NQueryState#query_state.battlemap_inst + ), %%%% Reply jiffy:encode([[<<"okay">>]]). -- cgit v1.2.3-70-g09d2