summaryrefslogtreecommitdiff |
diff options
author | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2019-06-12 09:57:13 +0200 |
---|---|---|
committer | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2019-06-12 09:57:13 +0200 |
commit | df54ba490259e1eb1e7c8133903417579ec4f400 (patch) | |
tree | b282afb878facd3039185055274ef3f5d0b4b322 /src | |
parent | d693f287201f3178f9cc36eee15af29694f67263 (diff) |
Adds more funs to handle map markers.
Using map markers to handle attacks of opportunity appears to be a bad
idea: while it does make their detection very cheap, this leads to
having frequent (and rather large) updates to the markers.
Diffstat (limited to 'src')
-rw-r--r-- | src/shared/reply/shr_set_map.erl | 2 | ||||
-rw-r--r-- | src/shared/struct/map/shr_map.erl | 291 | ||||
-rw-r--r-- | src/shared/struct/map/shr_map_marker.erl | 93 | ||||
-rw-r--r-- | src/shared/struct/map/shr_tile_instance.erl | 80 |
4 files changed, 459 insertions, 7 deletions
diff --git a/src/shared/reply/shr_set_map.erl b/src/shared/reply/shr_set_map.erl index 170f73c..e086ca5 100644 --- a/src/shared/reply/shr_set_map.erl +++ b/src/shared/reply/shr_set_map.erl @@ -19,7 +19,7 @@ -spec generate ( non_neg_integer(), - fun ((shr_tile_instance:trigger_name()) -> boolean()), + fun ((shr_map_marker:name()) -> boolean()), shr_map:type() ) -> {list(any())}. diff --git a/src/shared/struct/map/shr_map.erl b/src/shared/struct/map/shr_map.erl index 6db984b..363b938 100644 --- a/src/shared/struct/map/shr_map.erl +++ b/src/shared/struct/map/shr_map.erl @@ -55,6 +55,10 @@ -export ( [ + reset_marker/2, + ataxia_reset_marker/2, + add_to_marker/3, + ataxia_add_to_marker/3, update_from_list/5, default/1 ] @@ -184,3 +188,290 @@ default (Owner) -> markers = orddict:new(), tile_instances = list_to_tuple(lists:duplicate(1024, DefaultTileInstance)) }. + +-spec reset_marker (shr_map_marker:name(), shr_map:type()) -> shr_map:type(). +reset_marker (MarkerName, Map) -> + MapMarkers = Map#map.markers, + + case orddict:find(MarkerName, MapMarkers) of + error -> Map; + {ok, Marker} -> + MapWidth = Map#map.width, + MarkerLocations = shr_map_marker:get_locations(Marker), + UpdatedTileInstances = + lists:foldl + ( + fun (Location, TileInstances) -> + case location_to_index(MapWidth, Location) of + error -> TileInstances; + Index -> + TileInstance = element(Index, TileInstances), + + UpdatedTileInstance = + shr_tile_instance:remove_trigger + ( + MarkerName, + TileInstance + ), + + UpdatedTileInstances = + setelement + ( + Index, + TileInstances, + UpdatedTileInstance + ), + + UpdatedTileInstances + end + end, + Map#map.tile_instances, + MarkerLocations + ), + UpdatedMarker = shr_map_marker:set_locations([], Marker), + UpdatedMapMarkers = + orddict:store(MarkerName, UpdatedMarker, MapMarkers), + UpdatedMap = + Map#map + { + markers = UpdatedMapMarkers, + tile_instances = UpdatedTileInstances + }, + + UpdatedMap + end. + +-spec ataxia_reset_marker + ( + shr_map_marker:name(), + shr_map:type() + ) + -> {shr_map:type(), ataxic:basic()}. +ataxia_reset_marker (MarkerName, Map) -> + MapMarkers = Map#map.markers, + + case orddict:find(MarkerName, MapMarkers) of + error -> {Map, ataxic_sugar:nop()}; + {ok, Marker} -> + MapWidth = Map#map.width, + MarkerLocations = shr_map_marker:get_locations(Marker), + {UpdatedTileInstances, TileInstancesAtaxiaUpdates} = + lists:foldl + ( + fun (Location, {TileInstances, TileInstancesAtaxiaUpdates}) -> + case location_to_index(MapWidth, Location) of + error -> {TileInstances, TileInstancesAtaxiaUpdates}; + Index -> + TileInstance = element(Index, TileInstances), + + {UpdatedTileInstance, TileInstanceAtaxiaUpdate} = + shr_tile_instance:ataxia_remove_trigger + ( + MarkerName, + TileInstance + ), + + UpdatedTileInstances = + setelement + ( + Index, + TileInstances, + UpdatedTileInstance + ), + + TileInstancesAtaxiaUpdate = + ataxic:update_field + ( + Index, + TileInstanceAtaxiaUpdate + ), + + { + UpdatedTileInstances, + [ + TileInstancesAtaxiaUpdate + |TileInstancesAtaxiaUpdates + ] + } + end + end, + {Map#map.tile_instances, []}, + MarkerLocations + ), + {UpdatedMarker, MarkerAtaxiaUpdate} = + shr_map_marker:ataxia_set_locations([], Marker), + UpdatedMapMarkers = + orddict:store(MarkerName, UpdatedMarker, MapMarkers), + MapMarkersAtaxiaUpdate = + ataxic_sugar:update_orddict_element(MarkerName, MarkerAtaxiaUpdate), + UpdatedMap = + Map#map + { + markers = UpdatedMapMarkers, + tile_instances = UpdatedTileInstances + }, + + { + UpdatedMap, + ataxic:sequence + ( + [ + ataxic:update_field + ( + get_markers_field(), + MapMarkersAtaxiaUpdate + ), + ataxic:update_field + ( + get_tile_instances_field(), + ataxic:sequence(TileInstancesAtaxiaUpdates) + ) + ] + ) + } + end. + +-spec add_to_marker + ( + shr_map_marker:name(), + list(shr_location:type()), + shr_map:type() + ) + -> ({ok, shr_map:type()} | error). +add_to_marker (MarkerName, Locations, Map) -> + MapMarkers = Map#map.markers, + case orddict:find(MarkerName, MapMarkers) of + error -> error; + {ok, S0Marker} -> + UpdatedMarker = shr_map_marker:add_locations(Locations, S0Marker), + UpdatedMapMarkers = + orddict:store(MarkerName, UpdatedMarker, MapMarkers), + MapWidth = Map#map.width, + UpdatedTileInstances = + lists:foldl + ( + fun (Location, TileInstances) -> + case location_to_index(MapWidth, Location) of + error -> TileInstances; + Index -> + TileInstance = element(Index, TileInstances), + + UpdatedTileInstance = + shr_tile_instance:add_trigger + ( + MarkerName, + TileInstance + ), + UpdatedTileInstances = + setelement + ( + Index, + TileInstances, + UpdatedTileInstance + ), + + UpdatedTileInstances + end + end, + Map#map.tile_instances, + Locations + ), + UpdatedMap = + Map#map + { + markers = UpdatedMapMarkers, + tile_instances = UpdatedTileInstances + }, + + {ok, UpdatedMap} + end. + +-spec ataxia_add_to_marker + ( + shr_map_marker:name(), + list(shr_location:type()), + shr_map:type() + ) + -> ({ok, shr_map:type(), ataxic:basic()} | error). +ataxia_add_to_marker (MarkerName, Locations, Map) -> + MapMarkers = Map#map.markers, + case orddict:find(MarkerName, MapMarkers) of + error -> error; + {ok, Marker} -> + MapWidth = Map#map.width, + {UpdatedTileInstances, TileInstancesAtaxiaUpdates} = + lists:foldl + ( + fun (Location, {TileInstances, TileInstancesAtaxiaUpdates}) -> + case location_to_index(MapWidth, Location) of + error -> {TileInstances, TileInstancesAtaxiaUpdates}; + Index -> + TileInstance = element(Index, TileInstances), + + {UpdatedTileInstance, TileInstanceAtaxiaUpdate} = + shr_tile_instance:ataxia_add_trigger + ( + MarkerName, + TileInstance + ), + + UpdatedTileInstances = + setelement + ( + Index, + TileInstances, + UpdatedTileInstance + ), + + TileInstancesAtaxiaUpdate = + ataxic:update_field + ( + Index, + TileInstanceAtaxiaUpdate + ), + + { + UpdatedTileInstances, + [ + TileInstancesAtaxiaUpdate + |TileInstancesAtaxiaUpdates + ] + } + end + end, + {Map#map.tile_instances, []}, + Locations + ), + {UpdatedMarker, MarkerAtaxiaUpdate} = + shr_map_marker:ataxia_add_locations(Locations, Marker), + UpdatedMapMarkers = + orddict:store(MarkerName, UpdatedMarker, MapMarkers), + MapMarkersAtaxiaUpdate = + ataxic_sugar:update_orddict_element(MarkerName, MarkerAtaxiaUpdate), + UpdatedMap = + Map#map + { + markers = UpdatedMapMarkers, + tile_instances = UpdatedTileInstances + }, + + { + ok, + UpdatedMap, + ataxic:sequence + ( + [ + ataxic:update_field + ( + get_markers_field(), + MapMarkersAtaxiaUpdate + ), + ataxic:update_field + ( + get_tile_instances_field(), + ataxic:sequence(TileInstancesAtaxiaUpdates) + ) + ] + ) + } + end. diff --git a/src/shared/struct/map/shr_map_marker.erl b/src/shared/struct/map/shr_map_marker.erl index 84cad36..dac2f5e 100644 --- a/src/shared/struct/map/shr_map_marker.erl +++ b/src/shared/struct/map/shr_map_marker.erl @@ -82,6 +82,18 @@ -export ( [ + set_locations/2, + add_locations/2, + remove_locations/2, + ataxia_set_locations/2, + ataxia_add_locations/2, + ataxia_remove_locations/2 + ] +). + +-export +( + [ decode/1, encode/1 ] @@ -121,6 +133,9 @@ decode_data (Map) -> #spawn_mrk{} end. +-spec get_locations_field () -> non_neg_integer(). +get_locations_field () -> #marker.locations. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -190,3 +205,81 @@ get_character_index (Marker) -> #matk_mrk{ character_ix = IX } -> IX; _ -> -1 end. + +-spec set_locations (list(shr_location:type()), type()) -> type(). +set_locations (Locations, Marker) -> Marker#marker{ locations = Locations }. + +-spec ataxia_set_locations + ( + list(shr_location:type()), + type() + ) + -> {type(), ataxic:basic()}. +ataxia_set_locations (Locations, Marker) -> + { + set_locations(Locations, Marker), + ataxic:update_field + ( + get_locations_field(), + ataxic:constant([Locations]) + ) + }. + +-spec add_locations (list(shr_location:type()), type()) -> type(). +add_locations (Locations, Marker) -> + Marker#marker{ locations = (Locations ++ Marker#marker.locations) }. + +-spec ataxia_add_locations + ( + list(shr_location:type()), + type() + ) + -> {type(), ataxic:basic()}. +ataxia_add_locations (Locations, Marker) -> + { + add_locations(Locations, Marker), + ataxic:update_field + ( + get_locations_field(), + ataxic:apply_function + ( + lists, + append, + [ + ataxic:constant([Locations]), + ataxic:current_value() + ] + ) + ) + }. + +-spec remove_locations (list(shr_location:type()), type()) -> type(). +remove_locations (Locations, Marker) -> + Marker#marker + { + locations = lists:subtract(Marker#marker.locations, Locations) + }. + +-spec ataxia_remove_locations + ( + list(shr_location:type()), + type() + ) + -> {type(), ataxic:basic()}. +ataxia_remove_locations (Locations, Marker) -> + { + remove_locations(Locations, Marker), + ataxic:update_field + ( + get_locations_field(), + ataxic:apply_function + ( + lists, + subtract, + [ + ataxic:current_value(), + ataxic:constant([Locations]) + ] + ) + ) + }. diff --git a/src/shared/struct/map/shr_tile_instance.erl b/src/shared/struct/map/shr_tile_instance.erl index 3c3621f..1739207 100644 --- a/src/shared/struct/map/shr_tile_instance.erl +++ b/src/shared/struct/map/shr_tile_instance.erl @@ -4,17 +4,16 @@ %% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -type display_data() :: list(binary()). --type trigger_name() :: binary(). -opaque type() :: { shr_tile:id(), shr_tile:variant_id(), display_data(), - list(trigger_name()) + ordsets:ordset(shr_map_marker:name()) }. --export_type([type/0, trigger_name/0]). +-export_type([type/0]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -33,7 +32,12 @@ [ get_tile_id/1, get_variant_id/1, - get_triggers/1 + get_triggers/1, + + add_trigger/2, % TODO + remove_trigger/2, % TODO + ataxia_add_trigger/2, % TODO + ataxia_remove_trigger/2 % TODO ] ). @@ -41,6 +45,9 @@ %% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec get_triggers_field () -> non_neg_integer(). +get_triggers_field () -> 3. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -50,7 +57,7 @@ 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()). +-spec get_triggers (type()) -> list(shr_map_marker:name()). get_triggers ({_, _, _, Triggers}) -> Triggers. -spec decode (map()) -> type(). @@ -68,7 +75,12 @@ decode (Map) -> {TileID, VariantID, S0DisplayData, Triggers}. --spec encode (fun ((trigger_name()) -> boolean()), type()) -> {list(any())}. +-spec encode + ( + fun ((shr_map_marker:name()) -> boolean()), + type() + ) + -> {list(any())}. encode (VisibilityFun, {TileID, VariantID, DisplayData, Triggers}) -> { [ @@ -82,3 +94,59 @@ default () -> {<<"1">>, <<"0">>, [], []}. -spec error () -> type(). error () -> {<<"0">>, <<"0">>, [], []}. + +-spec add_trigger (shr_map_marker:name(), type()) -> type(). +add_trigger (TriggerName, {TileID, VariantID, DisplayData, Triggers}) -> + {TileID, VariantID, DisplayData, ordsets:add_element(TriggerName, Triggers)}. + +-spec ataxia_add_trigger + ( + shr_map_marker:name(), + type() + ) + -> {type(), ataxic:basic()}. +ataxia_add_trigger (TriggerName, TileInstance) -> + { + add_trigger(TriggerName, TileInstance), + ataxic:update_field + ( + get_triggers_field(), + ataxic:apply_function + ( + ordsets, + add_element, + [ + ataxic:constant(TriggerName), + ataxic:current_value() + ] + ) + ) + }. + +-spec remove_trigger (shr_map_marker:name(), type()) -> type(). +remove_trigger (TriggerName, {TileID, VariantID, DisplayData, Triggers}) -> + {TileID, VariantID, DisplayData, ordsets:del_element(TriggerName, Triggers)}. + +-spec ataxia_remove_trigger + ( + shr_map_marker:name(), + type() + ) + -> {type(), ataxic:basic()}. +ataxia_remove_trigger (TriggerName, TileInstance) -> + { + remove_trigger(TriggerName, TileInstance), + ataxic:update_field + ( + get_triggers_field(), + ataxic:apply_function + ( + ordsets, + del_element, + [ + ataxic:constant(TriggerName), + ataxic:current_value() + ] + ) + ) + }. |