summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornsensfel <SpamShield0@noot-noot.org>2019-02-15 18:18:54 +0100
committernsensfel <SpamShield0@noot-noot.org>2019-02-15 18:18:54 +0100
commit85b1e04a22e7564b702aa27c5f6467ad4d5f4416 (patch)
treed0a408eb97412feccdbcfe20b951669b6f6e6588 /src/shared/struct/map
parent9b91ff37a1e39f48631b5bee338c31318d1e2336 (diff)
Re-organizing shr_ structs.
Diffstat (limited to 'src/shared/struct/map')
-rw-r--r--src/shared/struct/map/shr_direction.erl38
-rw-r--r--src/shared/struct/map/shr_inventory.erl153
-rw-r--r--src/shared/struct/map/shr_location.erl90
-rw-r--r--src/shared/struct/map/shr_map.erl176
-rw-r--r--src/shared/struct/map/shr_map_marker.erl52
-rw-r--r--src/shared/struct/map/shr_tile.erl.m4133
6 files changed, 642 insertions, 0 deletions
diff --git a/src/shared/struct/map/shr_direction.erl b/src/shared/struct/map/shr_direction.erl
new file mode 100644
index 0000000..f0793b3
--- /dev/null
+++ b/src/shared/struct/map/shr_direction.erl
@@ -0,0 +1,38 @@
+-module(shr_direction).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-type enum() :: ('up' | 'down' | 'left' | 'right').
+-type type() :: enum().
+
+-export_type([enum/0, type/0]).
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-export
+(
+ [
+ decode/1,
+ encode/1
+ ]
+).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-spec decode (binary()) -> enum().
+decode (<<"U">>) -> up;
+decode (<<"D">>) -> down;
+decode (<<"L">>) -> left;
+decode (<<"R">>) -> right.
+
+-spec encode (enum()) -> binary().
+encode (up) -> <<"U">>;
+encode (down) -> <<"D">>;
+encode (left) -> <<"L">>;
+encode (right) -> <<"R">>.
diff --git a/src/shared/struct/map/shr_inventory.erl b/src/shared/struct/map/shr_inventory.erl
new file mode 100644
index 0000000..1f04533
--- /dev/null
+++ b/src/shared/struct/map/shr_inventory.erl
@@ -0,0 +1,153 @@
+-module(shr_inventory).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-type id() :: ataxia_id:type().
+-record
+(
+ inventory,
+ {
+ owner_id :: shr_player:id(),
+ portrait_ids :: ordsets:ordset(binary()),
+ glyph_ids :: ordsets:ordset(binary()),
+ glyph_board_ids :: ordsets:ordset(binary()),
+ weapon_ids :: ordsets:ordset(binary()),
+ armor_ids :: ordsets:ordset(binary())
+ }
+).
+
+-opaque type() :: #inventory{}.
+
+-export_type([type/0, id/0]).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%% Accessors
+-export
+(
+ [
+ get_owner_id/1,
+
+ get_portrait_ids/1,
+ get_glyph_ids/1,
+ get_glyph_board_ids/1,
+ get_weapon_ids/1,
+ get_armor_ids/1,
+
+ set_portrait_ids/2,
+ set_glyph_ids/2,
+ set_glyph_board_ids/2,
+ set_weapon_ids/2,
+ set_armor_ids/2
+ ]
+).
+
+-export
+(
+ [
+ get_portrait_ids_field/0,
+ get_glyph_ids_field/0,
+ get_glyph_board_ids_field/0,
+ get_weapon_ids_field/0,
+ get_armor_ids_field/0
+ ]
+).
+
+-export
+(
+ [
+ new/1
+ ]
+).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%% Accessors
+-spec get_owner_id (type()) -> shr_player:id().
+get_owner_id (Inv) -> Inv#inventory.owner_id.
+
+-spec get_portrait_ids (type()) -> ordsets:ordset(binary()).
+get_portrait_ids (Inv) -> Inv#inventory.portrait_ids.
+
+-spec get_glyph_ids (type()) -> ordsets:ordset(binary()).
+get_glyph_ids (Inv) -> Inv#inventory.glyph_ids.
+
+-spec get_glyph_board_ids (type()) -> ordsets:ordset(binary()).
+get_glyph_board_ids (Inv) -> Inv#inventory.glyph_board_ids.
+
+-spec get_weapon_ids (type()) -> ordsets:ordset(binary()).
+get_weapon_ids (Inv) -> Inv#inventory.weapon_ids.
+
+-spec get_armor_ids (type()) -> ordsets:ordset(binary()).
+get_armor_ids (Inv) -> Inv#inventory.armor_ids.
+
+-spec set_portrait_ids (ordsets:ordset(binary()), type()) -> type().
+set_portrait_ids (Value, Inv) ->
+ Inv#inventory
+ {
+ portrait_ids = Value
+ }.
+
+-spec set_glyph_ids (ordsets:ordset(binary()), type()) -> type().
+set_glyph_ids (Value, Inv) ->
+ Inv#inventory
+ {
+ glyph_ids = Value
+ }.
+
+-spec set_glyph_board_ids (ordsets:ordset(binary()), type()) -> type().
+set_glyph_board_ids (Value, Inv) ->
+ Inv#inventory
+ {
+ glyph_board_ids = Value
+ }.
+
+-spec set_weapon_ids (ordsets:ordset(binary()), type()) -> type().
+set_weapon_ids (Value, Inv) ->
+ Inv#inventory
+ {
+ weapon_ids = Value
+ }.
+
+-spec set_armor_ids (ordsets:ordset(binary()), type()) -> type().
+set_armor_ids (Value, Inv) ->
+ Inv#inventory
+ {
+ armor_ids = Value
+ }.
+
+-spec get_portrait_ids_field () -> non_neg_integer().
+get_portrait_ids_field () -> #inventory.portrait_ids.
+
+-spec get_glyph_ids_field () -> non_neg_integer().
+get_glyph_ids_field () -> #inventory.glyph_ids.
+
+-spec get_glyph_board_ids_field () -> non_neg_integer().
+get_glyph_board_ids_field () -> #inventory.glyph_board_ids.
+
+-spec get_weapon_ids_field () -> non_neg_integer().
+get_weapon_ids_field () -> #inventory.weapon_ids.
+
+-spec get_armor_ids_field () -> non_neg_integer().
+get_armor_ids_field () -> #inventory.armor_ids.
+
+-spec new (shr_player:id()) -> type().
+new (OwnerID) ->
+ EmptySet = ordsets:new(),
+
+ #inventory
+ {
+ owner_id = OwnerID,
+ portrait_ids = EmptySet,
+ glyph_ids = EmptySet,
+ glyph_board_ids = EmptySet,
+ weapon_ids = EmptySet,
+ armor_ids = EmptySet
+ }.
diff --git a/src/shared/struct/map/shr_location.erl b/src/shared/struct/map/shr_location.erl
new file mode 100644
index 0000000..ec62ff7
--- /dev/null
+++ b/src/shared/struct/map/shr_location.erl
@@ -0,0 +1,90 @@
+-module(shr_location).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-type type() :: ({non_neg_integer(), non_neg_integer()} | 'nowhere').
+
+-export_type([type/0]).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-export
+(
+ [
+ decode/1,
+ encode/1,
+ get_nowhere/0
+ ]
+).
+
+-export
+(
+ [
+ apply_direction/2,
+ dist/2
+ ]
+).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-spec validate ({integer(), integer()}) -> type().
+validate ({X, Y}) ->
+ if
+ (X < 0) -> nowhere;
+ (Y < 0) -> nowhere;
+ true -> {X, Y}
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-spec get_nowhere () -> type().
+get_nowhere () -> nowhere.
+
+-spec apply_direction (shr_direction:enum(), type()) -> type().
+apply_direction (left, {X, Y}) ->
+ validate({(X - 1), Y});
+apply_direction (right, {X, Y}) ->
+ validate({(X + 1), Y});
+apply_direction (up, {X, Y}) ->
+ validate({X, (Y - 1)});
+apply_direction (down, {X, Y}) ->
+ validate({X, (Y + 1)});
+apply_direction (_, nowhere) ->
+ error("Trying to move from 'nowhere'."),
+ nowhere.
+
+-spec dist(type(), type()) -> non_neg_integer().
+dist ({OX, OY}, {DX, DY}) ->
+ (abs(DY - OY) + abs(DX - OX));
+dist (_, _) ->
+ error("Trying to measure distance to 'nowhere'"),
+ 999.
+
+-spec encode (type()) -> {list(any())}.
+encode ({X, Y}) ->
+ {
+ [
+ {<<"x">>, X},
+ {<<"y">>, Y}
+ ]
+ };
+encode (nowhere) ->
+ {
+ [
+ {<<"x">>, -1},
+ {<<"y">>, -1}
+ ]
+ }.
+
+-spec decode (map()) -> type().
+decode (Map) ->
+ X = maps:get(<<"x">>, Map),
+ Y = maps:get(<<"y">>, Map),
+
+ true = (is_integer(X) and is_integer(Y)),
+
+ validate({X, Y}).
diff --git a/src/shared/struct/map/shr_map.erl b/src/shared/struct/map/shr_map.erl
new file mode 100644
index 0000000..b72c566
--- /dev/null
+++ b/src/shared/struct/map/shr_map.erl
@@ -0,0 +1,176 @@
+-module(shr_map).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-type id() :: ataxia_id:type().
+
+-record
+(
+ map,
+ {
+ owner :: shr_player:id(),
+ width :: non_neg_integer(),
+ height :: non_neg_integer(),
+ tile_instances :: shr_tile:instances_tuple(),
+ markers :: shr_map_marker:collection()
+ }
+).
+
+-opaque type() :: #map{}.
+
+-export_type([type/0, id/0]).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%% Accessors
+-export
+(
+ [
+ get_owner/1,
+ get_width/1,
+ get_height/1,
+ get_tile_instances/1,
+ get_tile_instance/2,
+ get_markers/1,
+ get_marker/2,
+
+ get_used_tile_ids/1
+ ]
+).
+
+%%%% Fields
+-export
+(
+ [
+ get_width_field/0,
+ get_height_field/0,
+ get_markers_field/0,
+ get_tile_instances_field/0
+ ]
+).
+
+%%%% Utility
+-export
+(
+ [
+ update_from_list/5,
+ default/1
+ ]
+).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-spec location_to_index
+ (
+ non_neg_integer(),
+ shr_location:type()
+ )
+ -> ('error' | non_neg_integer()).
+location_to_index (ArrayWidth, {X, Y}) ->
+ if
+ (X < 0) -> error;
+ (Y < 0) -> error;
+ (X >= ArrayWidth) -> error;
+ true -> ((Y * ArrayWidth) + X)
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%% Accessors
+-spec get_owner (type()) -> shr_player:id().
+get_owner (Map) -> Map#map.owner.
+
+-spec get_width (type()) -> non_neg_integer().
+get_width (Map) -> Map#map.width.
+
+-spec get_height (type()) -> non_neg_integer().
+get_height (Map) -> Map#map.height.
+
+-spec get_tile_instances (type()) -> shr_tile:instances_tuple().
+get_tile_instances (Map) -> Map#map.tile_instances.
+
+-spec get_tile_instance (shr_location:type(), type()) -> shr_tile:instance().
+get_tile_instance (Location, Map) ->
+ TileIX = location_to_index(Map#map.width, Location),
+ element((TileIX + 1), Map#map.tile_instances).
+
+-spec get_markers (type()) -> shr_map_marker:collection().
+get_markers (Map) -> Map#map.markers.
+
+-spec get_marker
+ (
+ shr_map_marker:name(),
+ type()
+ )
+ -> ('not_found' | {'ok', shr_map_marker:type()}).
+get_marker (Name, Map) ->
+ shr_map_marker:get(Name, Map#map.markers).
+
+%%%% Fields
+-spec get_width_field () -> non_neg_integer().
+get_width_field () -> #map.width.
+
+-spec get_height_field () -> non_neg_integer().
+get_height_field () -> #map.height.
+
+-spec get_markers_field () -> non_neg_integer().
+get_markers_field () -> #map.markers.
+
+-spec get_tile_instances_field () -> non_neg_integer().
+get_tile_instances_field () -> #map.tile_instances.
+
+%%%% Utility
+-spec get_used_tile_ids (type()) -> ordsets:ordset(shr_tile:class_id()).
+get_used_tile_ids (Map) ->
+ UsedTileIDs =
+ lists:foldl
+ (
+ fun (TileInstance, CurrentTileIDs) ->
+ ordsets:add_element
+ (
+ shr_tile:extract_main_class_id(TileInstance),
+ CurrentTileIDs
+ )
+ end,
+ ordsets:new(),
+ tuple_to_list(Map#map.tile_instances)
+ ),
+
+ UsedTileIDs.
+
+-spec update_from_list
+ (
+ type(),
+ non_neg_integer(),
+ non_neg_integer(),
+ shr_map_marker:collection(),
+ list(list(binary()))
+ )
+ -> type().
+update_from_list (Map, Width, Height, Markers, List) ->
+ TileInstances = lists:map(fun shr_tile:instance_from_binary_list/1, List),
+
+ Map#map
+ {
+ width = Width,
+ height = Height,
+ markers = Markers,
+ tile_instances = list_to_tuple(TileInstances)
+ }.
+
+-spec default (binary()) -> type().
+default (Owner) ->
+ DefaultTileInstance = shr_tile:default_tile_instance(),
+
+ #map
+ {
+ owner = Owner,
+ width = 32,
+ height = 32,
+ markers = shr_map_marker:empty_collection(),
+ tile_instances = list_to_tuple(lists:duplicate(1024, DefaultTileInstance))
+ }.
diff --git a/src/shared/struct/map/shr_map_marker.erl b/src/shared/struct/map/shr_map_marker.erl
new file mode 100644
index 0000000..35ba195
--- /dev/null
+++ b/src/shared/struct/map/shr_map_marker.erl
@@ -0,0 +1,52 @@
+-module(shr_map_marker).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-type name() :: binary().
+-type type() :: 'none'.
+-type collection() :: orddict:orddict(name(), type()).
+
+-export_type([name/0, type/0, collection/0]).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-export
+(
+ [
+ get/2,
+ empty_collection/0
+ ]
+).
+
+-export
+(
+ [
+ decode_collection/1,
+ encode_collection/1
+ ]
+).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-spec get (name(), collection()) -> ('not_found' | {'ok', type()}).
+get (Name, Collection) ->
+ case orddict:find(Name, Collection) of
+ error -> not_found;
+ Other -> Other
+ end.
+
+-spec empty_collection () -> collection().
+empty_collection () -> orddict:new().
+
+-spec encode_collection (collection()) -> list(any()).
+encode_collection (_Collection) -> [].
+
+-spec decode_collection (map()) -> collection().
+decode_collection (_Map) -> orddict:new().
diff --git a/src/shared/struct/map/shr_tile.erl.m4 b/src/shared/struct/map/shr_tile.erl.m4
new file mode 100644
index 0000000..7876f8f
--- /dev/null
+++ b/src/shared/struct/map/shr_tile.erl.m4
@@ -0,0 +1,133 @@
+-module(shr_tile).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-type class_id() :: binary().
+-type variant_id() :: binary().
+-type instances_tuple() :: tuple().
+
+-record
+(
+ tile,
+ {
+ id :: class_id(),
+ name :: binary(),
+ cost :: non_neg_integer(),
+ omnimods :: shr_omnimods:type(),
+ family :: variant_id(),
+ depth :: non_neg_integer()
+ }
+).
+
+-opaque instance() :: list(binary()).
+-opaque border() :: list(binary()).
+
+-opaque type() :: #tile{}.
+
+-export_type([type/0, class_id/0, variant_id/0, instance/0, border/0]).
+-export_type([instances_tuple/0]).
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-export
+(
+ [
+ get_class_id/1,
+ get_name/1,
+ get_cost/1,
+ get_omnimods/1,
+ from_class_id/1,
+ cost_when_oob/0
+ ]
+).
+
+-export
+(
+ [
+ instance_to_binary_list/1,
+ instance_from_binary_list/1,
+ default_tile_instance/0
+ ]
+).
+
+-export
+(
+ [
+ extract_main_class_id/1,
+ extract_variant_id/1,
+ extract_borders/1
+ ]
+).
+
+-export
+(
+ [
+ extract_border_main_class_id/1,
+ extract_border_variant_id/1
+ ]
+).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+-spec extract_main_class_id (instance()) -> class_id().
+extract_main_class_id (I) -> lists:nth(1, I).
+
+-spec extract_borders (instance()) -> list(border()).
+extract_borders (I) ->
+ [_|[_|Result]] = I,
+ Result.
+
+-spec extract_variant_id (instance()) -> variant_id().
+extract_variant_id (I) -> lists:nth(2, I).
+
+-spec extract_border_main_class_id (border()) -> class_id().
+extract_border_main_class_id (B) -> lists:nth(1, B).
+
+-spec extract_border_variant_id (border()) -> variant_id().
+extract_border_variant_id (B) -> lists:nth(2, B).
+
+-spec from_class_id (class_id()) -> type().
+m4_include(__MAKEFILE_DATA_DIR/tile/global.m4.conf)m4_dnl
+m4_include(__MAKEFILE_DATA_DIR/tile/special.m4d)m4_dnl
+m4_include(__MAKEFILE_DATA_DIR/tile/grassland.m4d)m4_dnl
+m4_include(__MAKEFILE_DATA_DIR/tile/mud.m4d)m4_dnl
+m4_include(__MAKEFILE_DATA_DIR/tile/water.m4d)m4_dnl
+from_class_id(_) ->
+ from_class_id(<<"0">>).
+
+-spec cost_when_oob () -> non_neg_integer().
+cost_when_oob () -> __TILE_COST_WHEN_OOB.
+
+-spec get_class_id (type()) -> class_id().
+get_class_id (Tile) -> Tile#tile.id.
+
+-spec get_cost (type()) -> non_neg_integer().
+get_cost (Tile) -> Tile#tile.cost.
+
+-spec get_name (type()) -> binary().
+get_name (Tile) -> Tile#tile.name.
+
+-spec get_omnimods (type()) -> shr_omnimods:type().
+get_omnimods (Tile) -> Tile#tile.omnimods.
+
+-spec instance_from_binary_list (list(binary())) -> instance().
+instance_from_binary_list (L) ->
+ LLength = length(L),
+
+ case (((LLength rem 2) == 0) and (LLength /= 0)) of
+ true -> L;
+ _ -> [<<"0">>, <<"0">>]
+ end.
+
+-spec instance_to_binary_list (instance()) -> list(binary()).
+instance_to_binary_list (I) -> I.
+
+-spec default_tile_instance () -> instance().
+default_tile_instance () -> [<<"1">>, <<"0">>].