summaryrefslogtreecommitdiff |
diff options
Diffstat (limited to 'src/battle')
-rw-r--r-- | src/battle/mechanic/action/btl_action_skill.erl | 111 | ||||
-rw-r--r-- | src/battle/struct/btl_character.erl | 38 |
2 files changed, 148 insertions, 1 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)}, |