| 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. | 


