| summaryrefslogtreecommitdiff | 
diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/battle/mechanic/btl_turn_actions_management.erl | 55 | ||||
| -rw-r--r-- | src/battle/mechanic/turn_action/btl_turn_actions_attack.erl | 4 | ||||
| -rw-r--r-- | src/battle/mechanic/turn_action/btl_turn_actions_move.erl | 154 | ||||
| -rw-r--r-- | src/battle/mechanic/turn_action/btl_turn_actions_switch_weapon.erl | 4 | ||||
| -rw-r--r-- | src/battle/struct/btl_action.erl | 92 | ||||
| -rw-r--r-- | src/shared/struct/map/shr_map_marker.erl | 162 | ||||
| -rw-r--r-- | src/shared/struct/map/shr_tile_instance.erl | 6 | 
7 files changed, 383 insertions, 94 deletions
| diff --git a/src/battle/mechanic/btl_turn_actions_management.erl b/src/battle/mechanic/btl_turn_actions_management.erl index d33fbad..eefe812 100644 --- a/src/battle/mechanic/btl_turn_actions_management.erl +++ b/src/battle/mechanic/btl_turn_actions_management.erl @@ -37,17 +37,48 @@ deactivate_character (Update) ->     S1Update. --spec handle_action -( -   btl_action:type(), -   btl_character_turn_update:type() -) --> btl_character_turn_update:type(). -handle_action (BattleAction, Update) -> -   case btl_action:get_category(BattleAction) of -      move -> btl_turn_actions_move:handle(BattleAction, Update); -      switch_weapon -> btl_turn_actions_switch_weapon:handle(Update); -      attack -> btl_turn_actions_attack:handle(BattleAction, Update) +-spec main_character_is_alive +   ( +      btl_character_turn_update:type() +   ) +   -> {boolean(), btl_character_turn_update:type()}. +main_character_is_alive (Update) -> +   {S0Update, MainCharacter} = btl_character_turn_update:get_character(Update), +   {btl_character:get_is_alive(MainCharacter), S0Update}. + +-spec handle_actions +   ( +      list(btl_action:type()), +      btl_character_turn_update:type() +   ) +   -> btl_character_turn_update:type(). +handle_actions ([], Update) -> Update; +handle_actions ([BattleAction|FutureBattleActions], Update) -> +   {MainCharacterIsAlive, S0Update} = main_character_is_alive(Update), + +   ActionResult = +      case {MainCharacterIsAlive, btl_action:get_category(BattleAction)} of +         {false, _} -> {ok, S0Update}; +         {true, move} -> btl_turn_actions_move:handle(BattleAction, S0Update); +         {true, switch_weapon} -> +            btl_turn_actions_switch_weapon:handle(S0Update); +         {true, attack} -> +            btl_turn_actions_attack:handle(BattleAction, S0Update); +         {true, interrupted_move} -> +            btl_turn_actions_move:handle(BattleAction, S0Update); +         {true, defend} -> +            % TODO: Attack of Opportunity +            Update +      end, + +   case ActionResult of +      {ok, NewUpdate} -> handle_actions(FutureBattleActions, NewUpdate); +      {events, NewEvents, NewUpdate} -> +         handle_actions +         ( +            (NewEvents ++ FutureBattleActions), +            NewUpdate +         )     end.  -spec update_timeline @@ -98,7 +129,7 @@ update_timeline (Update) ->  handle (Update, Request) ->     Actions = btl_character_turn_request:get_actions(Request), -   S0Update = lists:foldl(fun handle_action/2, Update, Actions), +   S0Update = handle_actions(Actions, Update),     S1Update = deactivate_character(S0Update),     S2Update = update_timeline(S1Update),     S3Update = btl_turn_progression:handle(S2Update), diff --git a/src/battle/mechanic/turn_action/btl_turn_actions_attack.erl b/src/battle/mechanic/turn_action/btl_turn_actions_attack.erl index e36c7e3..af4c53b 100644 --- a/src/battle/mechanic/turn_action/btl_turn_actions_attack.erl +++ b/src/battle/mechanic/turn_action/btl_turn_actions_attack.erl @@ -151,7 +151,7 @@ get_attack_sequence (Character, TargetCharacter) ->        btl_action:type(),        btl_character_turn_update:type()     ) -   -> btl_character_turn_update:type(). +   -> {ok, btl_character_turn_update:type()}.  handle (BattleAction, Update) ->     {S0Update, Battle} = btl_character_turn_update:get_battle(Update),     {S1Update, Character} = btl_character_turn_update:get_character(S0Update), @@ -336,4 +336,4 @@ handle (BattleAction, Update) ->              )        end, -   S6Update. +   {ok, S6Update}. diff --git a/src/battle/mechanic/turn_action/btl_turn_actions_move.erl b/src/battle/mechanic/turn_action/btl_turn_actions_move.erl index a0cd138..70b42c9 100644 --- a/src/battle/mechanic/turn_action/btl_turn_actions_move.erl +++ b/src/battle/mechanic/turn_action/btl_turn_actions_move.erl @@ -18,16 +18,23 @@  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  -spec cross     ( +      non_neg_integer(),        shr_map:type(),        list(shr_location:type()),        list(shr_direction:enum()),        non_neg_integer(),        shr_location:type()     ) -   -> {shr_location:type(), non_neg_integer()}. -cross (_Map, _ForbiddenLocations, [], Cost, Location) -> -   {Location, Cost}; -cross (Map, ForbiddenLocations, [Step|NextSteps], Cost, Location) -> +   -> +   { +      shr_location:type(), +      list(shr_direction:type()), +      non_neg_integer(), +      list(shr_map_marker:type()) +   }. +cross (_PlayerIX, _Map, _ForbiddenLocations, [], Cost, Location) -> +   {Location, [], Cost, []}; +cross (PlayerIX, Map, ForbiddenLocations, [Step|NextSteps], Cost, Location) ->     NextLocation = shr_location:apply_direction(Step, Location),     NextTileInstance = shr_map:get_tile_instance(NextLocation, Map),     NextTileClassID = shr_tile_instance:get_tile_id(NextTileInstance), @@ -43,20 +50,60 @@ cross (Map, ForbiddenLocations, [Step|NextSteps], Cost, Location) ->           ForbiddenLocations        ), -   IsForbidden = false, +   false = IsForbidden, + +   Interruptions = +      list:foldl +      ( +         fun (MarkerName, CurrentInterruptions) -> +            case shr_map:get_marker(MarkerName, Map) of +               {ok, Marker} -> +                  case shr_map_marker:interrupts_movement(PlayerIX, Marker) of +                     true -> [Marker|CurrentInterruptions]; +                     _ -> CurrentInterruptions +                  end; + +               error -> +                  %% TODO: Error. +                  CurrentInterruptions +            end +         end, +         [], +         shr_tile_instance:get_triggers(NextTileInstance) +      ), + +   case Interruptions of +      [] -> +         cross +         ( +            PlayerIX, +            Map, +            ForbiddenLocations, +            NextSteps, +            NextCost, +            NextLocation +         ); -   cross(Map, ForbiddenLocations, NextSteps, NextCost, NextLocation). +      _ -> {NextLocation, NextSteps, NextCost, Interruptions} +   end.  -spec cross     ( +      non_neg_integer(),        shr_map:type(),        list(shr_location:type()),        list(shr_direction:enum()),        shr_location:type()     ) -   -> {shr_location:type(), non_neg_integer()}. -cross (Map, ForbiddenLocations, Path, Location) -> -   cross(Map, ForbiddenLocations, Path, 0, Location). +   -> +   { +      shr_location:type(), +      list(shr_direction:type()), +      non_neg_integer(), +      list(shr_map_marker:type()) +   }. +cross (PlayerIX, Map, ForbiddenLocations, Path, Location) -> +   cross(PlayerIX, Map, ForbiddenLocations, Path, 0, Location).  -spec get_path_cost_and_destination     ( @@ -67,6 +114,8 @@ cross (Map, ForbiddenLocations, Path, Location) ->     {        non_neg_integer(),        shr_location:type(), +      list(shr_direction:type()), +      list(shr_map_marker:type()),        btl_character_turn_update:type()     }.  get_path_cost_and_destination (Update, Path) -> @@ -75,6 +124,9 @@ get_path_cost_and_destination (Update, Path) ->     CharacterIX = btl_character_turn_update:get_character_ix(S1Update),     Map = btl_battle:get_map(Battle), +   % FIXME: This is recalculated at every move action, despite there be no need +   % to: The client will not allow the character to go somewhere that would +   % only be freed because of an event.     ForbiddenLocations =        orddict:fold        ( @@ -91,42 +143,35 @@ get_path_cost_and_destination (Update, Path) ->           btl_battle:get_characters(Battle)        ), -   {NewLocation, Cost} = +   {NewLocation, RemainingPath, Cost, Interruptions} =        cross        ( +         btl_character:get_player_index(Character),           Map,           ForbiddenLocations,           Path,           btl_character:get_location(Character)        ), -   {Cost, NewLocation, S1Update}. +   {Cost, NewLocation, RemainingPath, Interruptions, S1Update}. --spec assert_character_can_move +-spec get_movement_points     ( -      btl_character:type(), -      non_neg_integer() +      btl_action:type(), +      btl_character:type()     ) -   -> ('ok' | 'error'). -assert_character_can_move (Char, Cost) -> -   CharacterMovementPoints = -      shr_statistics:get_movement_points -      ( -         shr_character:get_statistics +   -> non_neg_integer(). +get_movement_points (Action, Char) -> +   case btl_action:get_category(Action) of +      interrupted_move -> btl_action:get_movement_points(Action); +      _ -> +         shr_statistics:get_movement_points           ( -            btl_character:get_base_character(Char) +            shr_character:get_statistics +            ( +               btl_character:get_base_character(Char) +            )           ) -      ), - -   case (Cost =< CharacterMovementPoints) of -      true -> ok; -      false -> -         io:format -         ( -            "~n[E] Character trying to move ~p dist with ~p points.~n", -            [Cost, CharacterMovementPoints] -         ), -         error     end.  -spec commit_move @@ -183,14 +228,51 @@ commit_move (Character, Update, Path, NewLocation) ->        btl_action:type(),        btl_character_turn_update:type()     ) -   -> btl_character_turn_update:type(). +   -> +   ( +      {'ok', btl_character_turn_update:type()} +      | {'events', list(btl_action:type()), btl_character_turn_update:type()} +   ).  handle (BattleAction, Update) ->     {S0Update, Character} = btl_character_turn_update:get_character(Update), +     Path = btl_action:get_path(BattleAction), -   {PathCost, NewLocation, S1Update} = +   {PathCost, NewLocation, RemainingPath, Interruptions, S1Update} =        get_path_cost_and_destination(S0Update, Path), -   ok = assert_character_can_move(Character, PathCost), +   MovementPoints = get_movement_points(BattleAction, Character), + +   true = (MovementPoints >= PathCost), + +   S2Update = commit_move(Character, S1Update, Path, NewLocation), -   commit_move(Character, S1Update, Path, NewLocation). +   case RemainingPath of +      [] -> {ok, S2Update}; +      _ -> +         {events, +            ( +               lists:foldl +               ( +                  fun (Marker, CurrentActions) -> +                     ( +                        btl_action:from_map_marker(Character, Marker) +                        ++ +                        CurrentActions +                     ) +                  end, +                  [], +                  Interruptions +               ) +               ++ +               [ +                  btl_action:new_interrupted_move +                  ( +                     RemainingPath, +                     (MovementPoints - PathCost) +                  ) +               ] +            ), +            S2Update +         } +   end. diff --git a/src/battle/mechanic/turn_action/btl_turn_actions_switch_weapon.erl b/src/battle/mechanic/turn_action/btl_turn_actions_switch_weapon.erl index 24b361a..8e4aeab 100644 --- a/src/battle/mechanic/turn_action/btl_turn_actions_switch_weapon.erl +++ b/src/battle/mechanic/turn_action/btl_turn_actions_switch_weapon.erl @@ -24,7 +24,7 @@     (        btl_character_turn_update:type()     ) -   -> btl_character_turn_update:type(). +   -> {'ok', btl_character_turn_update:type()}.  handle (Update) ->     {S0Update, Character} = btl_character_turn_update:get_character(Update),     CharacterIX = btl_character_turn_update:get_character_ix(S0Update), @@ -52,4 +52,4 @@ handle (Update) ->           S1Update        ), -   S2Update. +   {ok, S2Update}. diff --git a/src/battle/struct/btl_action.erl b/src/battle/struct/btl_action.erl index 34dd46e..52f41d8 100644 --- a/src/battle/struct/btl_action.erl +++ b/src/battle/struct/btl_action.erl @@ -13,6 +13,15 @@  -record  ( +   interrupted_move, +   { +      path :: list(shr_direction:enum()), +      movement_points :: non_neg_integer() +   } +). + +-record +(     switch_weapon,     {     } @@ -26,8 +35,32 @@     }  ). --type category() :: ('move' | 'switch_weapon' | 'attack' | 'nothing'). --opaque type() :: (#move{} | #switch_weapon{} | #attack{}). +-record +( +   defend, +   { +      target_ix :: non_neg_integer() +   } +). + + +-type category() :: +   ( +      'move' +      | 'interrupted_move' +      | 'switch_weapon' +      | 'attack' +      | 'defend' +      | 'nothing' +   ). +-opaque type() :: +   ( +      #move{} +      | #interrupted_move{} +      | #switch_weapon{} +      | #attack{} +      | #defend{} +   ).  -export_type([category/0, type/0]). @@ -37,6 +70,7 @@  -export  (     [ +      from_map_marker/2,        maybe_decode_move/1,        maybe_decode_weapon_switch/1,        maybe_decode_attack/1, @@ -47,7 +81,15 @@  -export  (     [ +      new_interrupted_move/2 +   ] +). + +-export +( +   [        get_path/1, +      get_movement_points/1,        get_target_ix/1,        get_category/1     ] @@ -86,17 +128,57 @@ can_follow (_, _) -> false.  -spec get_path (type()) -> list(shr_direction:type()).  get_path (Action) when is_record(Action, move) ->     Action#move.path; +get_path (Action) when is_record(Action, interrupted_move) -> +   Action#interrupted_move.path;  get_path (_) ->     []. +-spec get_movement_points (type()) -> non_neg_integer(). +get_movement_points (Action) when is_record(Action, interrupted_move) -> +   Action#interrupted_move.movement_points; +get_movement_points (_) -> 0. +  -spec get_target_ix (type()) -> non_neg_integer().  get_target_ix (Action) when is_record(Action, attack) ->     Action#attack.target_ix; +get_target_ix (Action) when is_record(Action, defend) -> +   Action#defend.target_ix;  get_target_ix (_) -> -   []. +   0. + +-spec new_interrupted_move +   ( +      list(shr_direction:type()), +      non_neg_integer() +   ) +   -> type(). +new_interrupted_move (Path, MovementPoints) -> +   #interrupted_move{ path = Path, movement_points = MovementPoints }.  -spec get_category (type()) -> category().  get_category (Action) when is_record(Action, attack) -> attack;  get_category (Action) when is_record(Action, move) -> move; -get_category (Action) when is_record(Action, switch_weapon) -> switch_weapon. - +get_category (Action) when is_record(Action, switch_weapon) -> switch_weapon; +get_category (Action) when is_record(Action, interrupted_move) -> +   interrupted_move; +get_category (Action) when is_record(Action, defend) -> +  defend. + +-spec from_map_marker +   ( +      btl_character:type(), +      shr_map_marker:type() +   ) +   -> list(type()). +from_map_marker (_Character, Marker) -> +   case shr_map_marker:get_category(Marker) of +      matk -> +         [ +            #defend +            { +               target_ix = shr_map_marker:get_character_index(Marker) +            } +         ]; + +      _ -> [] +   end. diff --git a/src/shared/struct/map/shr_map_marker.erl b/src/shared/struct/map/shr_map_marker.erl index 2403ae7..84cad36 100644 --- a/src/shared/struct/map/shr_map_marker.erl +++ b/src/shared/struct/map/shr_map_marker.erl @@ -1,5 +1,15 @@  -module(shr_map_marker). +-define(OWNER_IX_FIELD, <<"oix">>). +-define(LOCATIONS_FIELD, <<"l">>). +-define(DATA_FIELD, <<"d">>). + +-define(DATA_TYPE_FIELD, <<"t">>). +-define(MATK_TYPE_VALUE, <<"matk">>). +-define(SPAWN_TYPE_VALUE, <<"spawn">>). + +-define(MATK_CHARACTER_IX_FIELD, <<"cix">>). +  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -15,17 +25,37 @@  (     spawn_mrk,     { -      player_ix :: non_neg_integer() +   } +). + +-record +( +   marker, +   { +      owner_ix :: (non_neg_integer() | -1), +      data :: (data()), +      locations :: list(shr_location:type())     }  ).  -type name() :: binary(). +-type category() :: (matk | spawn).  -opaque melee_attack_zone() :: #matk_mrk{}.  -opaque spawn_zone() :: #spawn_mrk{}. --opaque type() :: -   {list(shr_location:type()), (melee_attack_zone() | spawn_zone())}. +-opaque data() :: (#matk_mrk{} | #spawn_mrk{}). +-opaque type() :: #marker{}. --export_type([name/0, type/0, melee_attack_zone/0, spawn_zone/0]). +-export_type +( +   [ +      name/0, +      type/0, +      category/0, +      data/0, +      melee_attack_zone/0, +      spawn_zone/0 +   ] +).  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -35,7 +65,17 @@     [        player_can_see/2,        get_locations/1, -      get_name/1 +      get_name/1, +      get_owner_index/1, +      get_category/1, +      interrupts_movement/2 +   ] +). + +-export +( +   [ +      get_character_index/1     ]  ). @@ -50,53 +90,103 @@  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec encode_data (data()) -> {list({binary(), any()})}. +encode_data (MarkerData) when is_record(MarkerData, matk_mrk) -> +   { +      [ +         { ?DATA_TYPE_FIELD, ?MATK_TYPE_VALUE }, +         { ?MATK_CHARACTER_IX_FIELD, MarkerData#matk_mrk.character_ix } +      ] +   }; +encode_data (MarkerData) when is_record(MarkerData, spawn_mrk) -> +   { +      [ +         { ?DATA_TYPE_FIELD, ?SPAWN_TYPE_VALUE } +      ] +   }. + +-spec decode_data (map()) -> data(). +decode_data (Map) -> +   case maps:get(?DATA_TYPE_FIELD, Map) of +      ?MATK_TYPE_VALUE -> +         #matk_mrk +         { +            character_ix = maps:get(?MATK_CHARACTER_IX_FIELD, Map) +         }; + +      ?SPAWN_TYPE_VALUE -> #spawn_mrk{}; + +      _Other -> +         % TODO: error. +         #spawn_mrk{} +   end.  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec interrupts_movement (non_neg_integer(), type()) -> boolean(). +interrupts_movement (PlayerIX, Marker) -> +   ( +      (PlayerIX /= Marker#marker.owner_ix) +      and is_record(Marker#marker.data, matk_mrk) +   ). +  -spec get_locations (type()) -> list(shr_location:type()). -get_locations ({L, _}) -> L. +get_locations (Marker) -> Marker#marker.locations. --spec encode (type()) -> {list(any())}. -encode ({L, MarkerData}) when is_record(MarkerData, matk_mrk) -> -   { -      [ -         { <<"t">>, <<"matk">> }, -         { <<"cix">>, MarkerData#matk_mrk.character_ix }, -         { <<"l">>, lists:map(fun shr_location:encode/1, L) } -      ] -   }; -encode ({L, MarkerData}) when is_record(MarkerData, spawn_mrk) -> +-spec get_owner_index (type()) -> (non_neg_integer() | -1). +get_owner_index (Marker) -> Marker#marker.owner_ix. + +-spec get_category (type()) -> category(). +get_category (Marker) -> +   case Marker#marker.data of +      #matk_mrk{} -> matk; +      #spawn_mrk{} -> spawn +   end. + +-spec encode (type()) -> {list({binary(), any()})}. +encode (Marker) ->     {        [ -         { <<"t">>, <<"spawn">> }, -         { <<"pix">>, MarkerData#spawn_mrk.player_ix }, -         { <<"l">>, lists:map(fun shr_location:encode/1, L) } +         { +            ?LOCATIONS_FIELD, +            lists:map(fun shr_location:encode/1, Marker#marker.locations) +         }, +         { ?OWNER_IX_FIELD, Marker#marker.owner_ix }, +         { ?DATA_FIELD, encode_data(Marker#marker.data) }        ]     }. +  -spec decode (map()) -> type().  decode (Map) -> -   Data = maps:get(<<"d">>, Map), +   #marker     { -      lists:map(fun shr_location:decode/1, maps:get(<<"l">>, Map)), -      ( -         case maps:get(<<"t">>, Data) of -            <<"mtak">> -> #matk_mrk{ character_ix = maps:get(<<"cix">>, Data) }; -            <<"spawn">> -> #spawn_mrk{ player_ix = maps:get(<<"pix">>, Data) } -         end -      ) +      locations = maps:get(?LOCATIONS_FIELD, Map), +      owner_ix = maps:get(?OWNER_IX_FIELD, Map), +      data = decode_data(maps:get(?DATA_FIELD, Map))     }.  -spec player_can_see (integer(), type()) -> boolean(). -player_can_see (PlayerIX, _Marker) -> (PlayerIX >= 0). +player_can_see (_PlayerIX, _Marker) -> true.  -spec get_name (type()) -> binary(). -get_name ({_Location, MarkerData}) when is_record(MarkerData, matk_mrk) -> -   Prefix = <<"matk_c">>, -   CharacterIXString = integer_to_binary(MarkerData#matk_mrk.character_ix), -   <<Prefix/binary, CharacterIXString/binary>>; -get_name ({_Location, MarkerData}) when is_record(MarkerData, spawn_mrk) -> -   Prefix = <<"spawn_p">>, -   PlayerIXString = integer_to_binary(MarkerData#spawn_mrk.player_ix), -   <<Prefix/binary, PlayerIXString/binary>>. +get_name (Marker) -> +   case Marker#marker.data of +      #matk_mrk{ character_ix = CIX } -> +         Prefix = <<"matk_c">>, +         CharacterIXString = integer_to_binary(CIX), +         <<Prefix/binary, CharacterIXString/binary>>; + +      #spawn_mrk{} -> +         Prefix = <<"spawn_p">>, +         PlayerIXString = integer_to_binary(Marker#marker.owner_ix), +         <<Prefix/binary, PlayerIXString/binary>> +   end. + +-spec get_character_index (type()) -> (non_neg_integer() | -1). +get_character_index (Marker) -> +   case Marker#marker.data of +      #matk_mrk{ character_ix = IX } -> IX; +      _ -> -1 +   end. diff --git a/src/shared/struct/map/shr_tile_instance.erl b/src/shared/struct/map/shr_tile_instance.erl index 9f95378..3c3621f 100644 --- a/src/shared/struct/map/shr_tile_instance.erl +++ b/src/shared/struct/map/shr_tile_instance.erl @@ -32,7 +32,8 @@  (     [        get_tile_id/1, -      get_variant_id/1 +      get_variant_id/1, +      get_triggers/1     ]  ). @@ -49,6 +50,9 @@ get_tile_id ({TileID, _, _, _}) -> TileID.  -spec get_variant_id (type()) -> shr_tile:variant_id().  get_variant_id ({_, VariantID, _, _}) -> VariantID. +-spec get_triggers (type()) -> list(trigger_name()). +get_triggers ({_, _, _, Triggers}) -> Triggers. +  -spec decode (map()) -> type().  decode (Map) ->     L = maps:get(<<"b">>, Map), | 


