| 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/shared | |
| 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/shared')
| -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() +            ] +         ) +      ) +   }. | 


