summaryrefslogtreecommitdiff |
diff options
-rw-r--r-- | src/battle/mechanic/action/btl_action_skill.erl | 111 | ||||
-rw-r--r-- | src/battle/struct/btl_character.erl | 38 | ||||
-rw-r--r-- | src/shared/struct/inventory/shr_equipment.erl | 89 |
3 files changed, 227 insertions, 11 deletions
diff --git a/src/battle/mechanic/action/btl_action_skill.erl b/src/battle/mechanic/action/btl_action_skill.erl index 548eafe..7e6579b 100644 --- a/src/battle/mechanic/action/btl_action_skill.erl +++ b/src/battle/mechanic/action/btl_action_skill.erl @@ -17,6 +17,88 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec pay_for_cast + ( + non_neg_integer(), + btl_character_turn_update:type() + ) + -> btl_character_turn_update:type(). +pay_for_cast (ActorIX, S0Update) -> + S0Battle = btl_character_turn_update:get_battle(S0Update), + S0Actor = btl_battle:get_character(ActorIX, S0Battle), + BaseActor = btl_character:get_base_character(S0Actor), + Equipment = shr_character:get_equipment(BaseActor), + Skill = shr_equipment:get_skill(Equipment), + + SkillCost = shr_skill:get_cost(Skill), + S0SkillPoints = btl_character:get_skill_points(S0Actor), + S1SkillPoints = (S0SkillPoints - SkillCost), + + {S1Actor, ActorAtaxiaUpdate} = + case (S1SkillPoints < 0) of + true -> error({skill, points, S0SkillPoints, Skill}); + false -> + btl_character:ataxia_set_skill_points(S1SkillPoints, S0Actor) + end, + + {S1Battle, BattleAtaxiaUpdate} = + btl_battle:ataxia_set_character + ( + ActorIX, + S1Actor, + ActorAtaxiaUpdate, + S0Battle + ), + + S1Update = + btl_character_turn:ataxia_set_battle + ( + S1Battle, + BattleAtaxiaUpdate, + S0Update + ), + + {S1Update, Skill}. + +-spec cast_skill + ( + btl_action:type(), + btl_character_turn_update:type() + ) + -> btl_character_turn_update:type(). +cast_skill (Action, S0Update) -> + ActorIX = btl_action:get_actor_index(Action), + {S1Update, Skill} = pay_for_cast(ActorIX, S0Update), + + S2Update = + erlang:apply + ( + shr_skill:get_module(Skill), + cast, + [Skill, Action, S1Update] + ), + + {none, S3Update} = + btl_condition:apply_to_character + ( + ActorIX, + ?CONDITION_TRIGGER_HAS_CAST_SKILL, + Action, + none, + S2Update + ), + + {none, S3Update} = + btl_condition:apply_to_battle + ( + ?CONDITION_TRIGGER_A_CHARACTER_HAS_CAST_SKILL, + Action, + none, + S2Update + ), + + S3Update. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -27,4 +109,31 @@ btl_character_turn_update:type() ) -> btl_character_turn_update:type(). -handle (_Action, S0Update) -> S0Update. % TODO +handle (S0Action, S0Update) -> + ActorIX = btl_action:get_actor_index(S0Action), + + S0PerformAction = true, + + {{S1Action, S1PerformAction}, S1Update} = + btl_condition:apply_to_character + ( + ActorIX, + ?CONDITION_TRIGGER_ABOUT_TO_CAST_SKILL, + none, + {S0Action, S0PerformAction}, + S0Update + ), + + {{S2Action, S2PerformAction}, S2Update} = + btl_condition:apply_to_battle + ( + ?CONDITION_TRIGGER_A_CHARACTER_IS_ABOUT_TO_CAST_SKILL, + none, + {S1Action, S1PerformAction}, + S1Update + ), + + case S2PerformAction of + true -> cast_skill(S2Action, S2Update); + false -> S2Update + end. diff --git a/src/battle/struct/btl_character.erl b/src/battle/struct/btl_character.erl index 6a4fe2f..422ee7d 100644 --- a/src/battle/struct/btl_character.erl +++ b/src/battle/struct/btl_character.erl @@ -4,6 +4,7 @@ -define(RANK_FIELD, <<"rnk">>). -define(LOCATION_FIELD, <<"lc">>). -define(CURRENT_HEALTH_FIELD, <<"he">>). +-define(SKILL_POINTS_FIELD, <<"sp">>). -define(IS_ACTIVE_FIELD, <<"ena">>). -define(IS_DEFEATED_FIELD, <<"dea">>). -define(BASE_CHAR_FIELD, <<"bas">>). @@ -22,6 +23,7 @@ rank :: rank(), location :: {non_neg_integer(), non_neg_integer()}, current_health :: integer(), %% Negative integers let us reverse attacks. + skill_points :: integer(), %% Negative integers let us reverse skill uses. is_active :: boolean(), is_defeated :: boolean(), base :: shr_character:unresolved(), @@ -37,6 +39,7 @@ rank :: rank(), location :: {non_neg_integer(), non_neg_integer()}, current_health :: integer(), %% Negative integers let us reverse attacks. + skill_points :: integer(), %% Negative integers let us reverse skill uses. is_active :: boolean(), is_defeated :: boolean(), base :: shr_character:type(), @@ -60,6 +63,7 @@ get_rank/1, get_location/1, get_current_health/1, + get_skill_points/1, get_is_alive/1, get_is_active/1, get_is_defeated/1, @@ -69,6 +73,7 @@ set_rank/2, set_location/3, set_current_health/2, + set_skill_points/2, set_is_active/2, set_is_defeated/2, set_base_character/2, @@ -77,6 +82,7 @@ ataxia_set_rank/2, ataxia_set_location/3, ataxia_set_current_health/2, + ataxia_set_skill_points/2, ataxia_set_is_active/2, ataxia_set_is_defeated/2, ataxia_set_base_character/2, @@ -87,6 +93,7 @@ get_rank_field/0, get_current_health_field/0, + get_skill_points_field/0, get_is_active_field/0, get_is_defeated_field/0, get_location_field/0, @@ -157,6 +164,10 @@ get_location (#btl_char_ref{ location = R }) -> R. get_current_health (#btl_char{ current_health = R }) -> R; get_current_health (#btl_char_ref{ current_health = R }) -> R. +-spec get_skill_points (either()) -> integer(). +get_skill_points (#btl_char{ skill_points = R }) -> R; +get_skill_points (#btl_char_ref{ skill_points = R }) -> R. + -spec get_is_alive (either()) -> boolean(). get_is_alive (#btl_char{ current_health = H, is_defeated = D }) -> ((not D) and (H > 0)); @@ -306,6 +317,27 @@ ataxia_set_current_health (Health, Char) -> ) }. +-spec set_skill_points + (integer(), type()) -> type(); + (integer(), unresolved()) -> unresolved(). +set_skill_points (SkillPoints, Char) when is_record(Char, btl_char) -> + Char#btl_char{ skill_points = SkillPoints }; +set_skill_points (SkillPoints, Char) when is_record(Char, btl_char_ref) -> + Char#btl_char_ref{ skill_points = SkillPoints }. + +-spec ataxia_set_skill_points + (integer(), type()) -> {type(), ataxic:basic()}; + (integer(), unresolved()) -> {unresolved(), ataxic:basic()}. +ataxia_set_skill_points (SkillPoints, Char) -> + { + set_skill_points(SkillPoints, Char), + ataxic:update_field + ( + get_skill_points_field(), + ataxic:constant(SkillPoints) + ) + }. + -spec set_is_active (boolean(), type()) -> type(); (boolean(), unresolved()) -> unresolved(). @@ -508,6 +540,7 @@ new rank = Rank, location = Location, current_health = shr_attributes:get_health(Attributes), + skill_points = 0, is_active = (PlayerIX == 0), is_defeated = false, base = Base, @@ -522,6 +555,7 @@ resolve (LocalOmnimods, CharRef) when is_record(CharRef, btl_char_ref) -> rank = CharRef#btl_char_ref.rank, location = CharRef#btl_char_ref.location, current_health = CharRef#btl_char_ref.current_health, + skill_points = CharRef#btl_char_ref.skill_points, is_active = CharRef#btl_char_ref.is_active, is_defeated = CharRef#btl_char_ref.is_defeated, base = shr_character:resolve(LocalOmnimods, CharRef#btl_char_ref.base), @@ -537,6 +571,7 @@ to_unresolved (Char) when is_record(Char, btl_char) -> rank = Char#btl_char.rank, location = Char#btl_char.location, current_health = Char#btl_char.current_health, + skill_points = Char#btl_char.skill_points, is_active = Char#btl_char.is_active, is_defeated = Char#btl_char.is_defeated, base = shr_character:to_unresolved(Char#btl_char.base), @@ -553,6 +588,8 @@ get_rank_field () -> #btl_char_ref.rank. get_location_field () -> #btl_char_ref.location. -spec get_current_health_field() -> non_neg_integer(). get_current_health_field () -> #btl_char_ref.current_health. +-spec get_skill_points_field() -> non_neg_integer(). +get_skill_points_field () -> #btl_char_ref.skill_points. -spec get_is_active_field() -> non_neg_integer(). get_is_active_field () -> #btl_char_ref.is_active. -spec get_is_defeated_field() -> non_neg_integer(). @@ -570,6 +607,7 @@ encode (CharRef) -> {?RANK_FIELD, CharRef#btl_char_ref.rank}, {?LOCATION_FIELD, shr_location:encode(CharRef#btl_char_ref.location)}, {?CURRENT_HEALTH_FIELD, CharRef#btl_char_ref.current_health}, + {?SKILL_POINTS_FIELD, CharRef#btl_char_ref.skill_points}, {?IS_ACTIVE_FIELD, CharRef#btl_char_ref.is_active}, {?IS_DEFEATED_FIELD, CharRef#btl_char_ref.is_defeated}, {?BASE_CHAR_FIELD, shr_character:encode(CharRef#btl_char_ref.base)}, diff --git a/src/shared/struct/inventory/shr_equipment.erl b/src/shared/struct/inventory/shr_equipment.erl index 25cc8fb..132f9b4 100644 --- a/src/shared/struct/inventory/shr_equipment.erl +++ b/src/shared/struct/inventory/shr_equipment.erl @@ -6,6 +6,7 @@ -define(PORTRAIT_FIELD, <<"pt">>). -define(GLYPH_BOARD_FIELD, <<"gb">>). -define(GLYPHS_FIELD, <<"gl">>). +-define(SKILL_FIELD, <<"sk">>). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -19,7 +20,8 @@ armor :: shr_armor:id(), portrait :: shr_portrait:id(), glyph_board :: shr_glyph_board:id(), - glyphs :: list(shr_glyph:id()) + glyphs :: list(shr_glyph:id()), + skill :: shr_skill:id() } ). @@ -32,7 +34,8 @@ armor :: shr_armor:type(), portrait :: shr_portrait:type(), glyph_board :: shr_glyph_board:type(), - glyphs :: list(shr_glyph:type()) + glyphs :: list(shr_glyph:type()), + skill :: shr_skill:type() } ). @@ -55,6 +58,7 @@ get_portrait/1, get_glyph_board/1, get_glyphs/1, + get_skill/1, set_primary_weapon/2, set_secondary_weapon/2, @@ -62,6 +66,7 @@ set_portrait/2, set_glyph_board/2, set_glyphs/2, + set_skill/2, ataxia_set_primary_weapon/2, ataxia_set_secondary_weapon/2, @@ -70,6 +75,7 @@ ataxia_set_glyph_board/2, ataxia_set_glyphs/2, ataxia_set_glyphs/3, + ataxia_set_skill/2, get_primary_weapon_id/1, get_secondary_weapon_id/1, @@ -77,6 +83,7 @@ get_portrait_id/1, get_glyph_board_id/1, get_glyph_ids/1, + get_skill_id/1, set_primary_weapon_id/2, set_secondary_weapon_id/2, @@ -84,6 +91,7 @@ set_portrait_id/2, set_glyph_board_id/2, set_glyph_ids/2, + set_skill_id/2, ataxia_set_primary_weapon_id/2, ataxia_set_secondary_weapon_id/2, @@ -91,7 +99,8 @@ ataxia_set_portrait_id/2, ataxia_set_glyph_board_id/2, ataxia_set_glyph_ids/2, - ataxia_set_glyph_ids/3 + ataxia_set_glyph_ids/3, + ataxia_set_skill_id/2 ] ). @@ -122,7 +131,8 @@ get_armor_field/0, get_portrait_field/0, get_glyph_board_field/0, - get_glyphs_field/0 + get_glyphs_field/0, + get_skill_field/0 ] ). @@ -157,6 +167,10 @@ get_glyph_board (#shr_eq_ref{ glyph_board = R }) -> shr_glyph_board:from_id(R). get_glyphs (#shr_eq{ glyphs = R }) -> R; get_glyphs (#shr_eq_ref{ glyphs = R }) -> lists:map(fun shr_glyph:from_id/1, R). +-spec get_skill (either()) -> shr_skill:type(). +get_skill (#shr_eq{ skill = R }) -> R; +get_skill (#shr_eq_ref{ skill = R }) -> shr_skill:from_id(R). + -spec get_primary_weapon_id (either()) -> shr_weapon:id(). get_primary_weapon_id (#shr_eq_ref{ primary = R }) -> R; get_primary_weapon_id (#shr_eq{ primary = R }) -> shr_weapon:get_id(R). @@ -181,6 +195,10 @@ get_glyph_board_id (#shr_eq{ glyph_board = R }) -> shr_glyph_board:get_id(R). get_glyph_ids (#shr_eq_ref{ glyphs = R }) -> R; get_glyph_ids (#shr_eq{ glyphs = R }) -> lists:map(fun shr_glyph:get_id/1, R). +-spec get_skill_id (either()) -> shr_skill:id(). +get_skill_id (#shr_eq_ref{ skill = R }) -> R; +get_skill_id (#shr_eq{ skill = R }) -> shr_skill:get_id(R). + -spec set_primary_weapon (shr_weapon:type(), type()) -> type(); (shr_weapon:type(), unresolved()) -> unresolved(). @@ -328,6 +346,27 @@ ataxia_set_glyphs (V, VUpdate, Eq) -> ) }. +-spec set_skill + (shr_skill:type(), type()) -> type(); + (shr_skill:type(), unresolved()) -> unresolved(). +set_skill (V, Eq) when is_record(Eq, shr_eq) -> + Eq#shr_eq{ skill = V }; +set_skill (V, Eq) when is_record(Eq, shr_eq_ref) -> + Eq#shr_eq_ref{ skill = shr_skill:get_id(V) }. + +-spec ataxia_set_skill + (shr_skill:type(), type()) -> {type(), ataxic:basic()}; + (shr_skill:type(), unresolved()) -> {unresolved(), ataxic:basic()}. +ataxia_set_skill (V, Eq) -> + { + set_skill(V, Eq), + ataxic:update_field + ( + get_skill_field(), + ataxic:constant(shr_skill:get_id(V)) + ) + }. + -spec set_primary_weapon_id (shr_weapon:id(), type()) -> type(); (shr_weapon:id(), unresolved()) -> unresolved(). @@ -466,6 +505,27 @@ ataxia_set_glyph_ids (V, VUpdate, Eq) -> ataxic:update_field(get_glyphs_field(), VUpdate) }. +-spec set_skill_id + (shr_skill:id(), type()) -> type(); + (shr_skill:id(), unresolved()) -> unresolved(). +set_skill_id (V, Eq) when is_record(Eq, shr_eq_ref) -> + Eq#shr_eq_ref{ skill = V }; +set_skill_id (V, Eq) when is_record(Eq, shr_eq) -> + Eq#shr_eq{ skill = shr_skill:from_id(V) }. + +-spec ataxia_set_skill_id + (shr_skill:id(), type()) -> {type(), ataxic:basic()}; + (shr_skill:id(), unresolved()) -> {unresolved(), ataxic:basic()}. +ataxia_set_skill_id (V, Eq) -> + { + set_skill_id(V, Eq), + ataxic:update_field + ( + get_skill_field(), + ataxic:constant(V) + ) + }. + -spec default () -> type(). default () -> DefaultGlyphBoard = shr_glyph_board:default(), @@ -481,7 +541,8 @@ default () -> ( fun (_E) -> shr_glyph:default() end, shr_glyph_board:get_slots(DefaultGlyphBoard) - ) + ), + skill = shr_skill:default() }. -spec default_unresolved () -> unresolved(). @@ -498,7 +559,8 @@ default_unresolved () -> ( fun (_E) -> shr_glyph:default_id() end, shr_glyph_board:get_slots(shr_glyph_board:default()) - ) + ), + skill = shr_skill:default_id() }. -spec decode (map()) -> unresolved(). @@ -510,7 +572,8 @@ decode (Map) -> armor = maps:get(?ARMOR_FIELD, Map), portrait = maps:get(?PORTRAIT_FIELD, Map), glyph_board = maps:get(?GLYPH_BOARD_FIELD, Map), - glyphs = maps:get(?GLYPHS_FIELD, Map) + glyphs = maps:get(?GLYPHS_FIELD, Map), + skill = maps:get(?SKILL_FIELD, Map) }. -spec encode (either()) -> {list({binary(), any()})}. @@ -522,7 +585,8 @@ encode (Eq) -> {?ARMOR_FIELD, get_armor_id(Eq)}, {?PORTRAIT_FIELD, get_portrait_id(Eq)}, {?GLYPH_BOARD_FIELD, get_glyph_board_id(Eq)}, - {?GLYPHS_FIELD, get_glyph_ids(Eq)} + {?GLYPHS_FIELD, get_glyph_ids(Eq)}, + {?SKILL_FIELD, get_skill_id(Eq)} ] }. @@ -535,7 +599,8 @@ resolve (EqRef) -> armor = shr_armor:from_id(EqRef#shr_eq_ref.armor), portrait = shr_portrait:from_id(EqRef#shr_eq_ref.portrait), glyph_board = shr_glyph_board:from_id(EqRef#shr_eq_ref.glyph_board), - glyphs = lists:map(fun shr_glyph:from_id/1, EqRef#shr_eq_ref.glyphs) + glyphs = lists:map(fun shr_glyph:from_id/1, EqRef#shr_eq_ref.glyphs), + skill = shr_skill:from_id(EqRef#shr_eq_ref.skill) }. -spec to_unresolved (type()) -> unresolved(). @@ -547,7 +612,8 @@ to_unresolved (Eq) -> armor = shr_armor:get_id(Eq#shr_eq.armor), portrait = shr_portrait:get_id(Eq#shr_eq.portrait), glyph_board = shr_glyph_board:get_id(Eq#shr_eq.glyph_board), - glyphs = lists:map(fun shr_glyph:get_id/1, Eq#shr_eq.glyphs) + glyphs = lists:map(fun shr_glyph:get_id/1, Eq#shr_eq.glyphs), + skill = shr_skill:get_id(Eq#shr_eq.skill) }. -spec get_primary_weapon_field () -> non_neg_integer(). @@ -562,6 +628,9 @@ get_armor_field () -> #shr_eq_ref.armor. -spec get_portrait_field () -> non_neg_integer(). get_portrait_field () -> #shr_eq_ref.portrait. +-spec get_skill_field () -> non_neg_integer(). +get_skill_field () -> #shr_eq_ref.skill. + -spec get_glyph_board_field () -> non_neg_integer(). get_glyph_board_field () -> #shr_eq_ref.glyph_board. |