Class: Demiurge::Container
- Inherits:
-
ActionItem
- Object
- StateItem
- ActionItem
- Demiurge::Container
- Defined in:
- lib/demiurge/container.rb
Overview
Container is the parent class of Locations, Zones and other items that can contain items.
Constant Summary
Constants inherited from ActionItem
Instance Attribute Summary
Attributes inherited from StateItem
Instance Method Summary collapse
-
#can_accomodate_agent?(agent, position) ⇒ Boolean
This method determines if a given agent can exist at the specified position inside this container.
-
#contents ⇒ Array<Demiurge::StateItem>
Gets the contents array as items, not names.
-
#contents_names ⇒ Array<String>
Gets the array of item names of all items contained in this container.
-
#ensure_contains(item_name) ⇒ void
This makes sure the given item name is listed in the container's contents.
-
#ensure_does_not_contain(item_name) ⇒ void
This makes sure the given item name is not listed in the container's contents.
-
#finished_init ⇒ void
The finished_init hook is called after all items are loaded.
-
#initialize(name, engine, state) ⇒ void
constructor
Constructor - set up contents.
-
#intentions_for_next_step ⇒ Array<Intention>
This determines the intentions for the next tick for this container and for all items inside it.
-
#item_change_location(item, old_pos, new_pos) ⇒ void
This is a callback to indicate that an item has changed from one location to another.
-
#item_change_position(item, old_pos, new_pos) ⇒ void
This is a callback to indicate that an item has changed position, but remains inside this location.
-
#move_item_inside(item) ⇒ void
This makes sure the given StateItem is contained in this container.
-
#receive_offer(action_name, intention) ⇒ void
When an item has an Intention, that Intention is offered in order to be potentially modified or cancelled by environmental effects.
Methods inherited from ActionItem
#__state_internal, #get_action, #get_actions_with_tags, #location, #location_name, #position, #register_actions, #run_action, #zone, #zone_name
Methods inherited from StateItem
#agent?, from_name_type, #get_structure, #state, #state_type, #zone?
Constructor Details
#initialize(name, engine, state) ⇒ void
Constructor - set up contents
13 14 15 16 |
# File 'lib/demiurge/container.rb', line 13 def initialize(name, engine, state) super state["contents"] ||= [] end |
Instance Method Details
#can_accomodate_agent?(agent, position) ⇒ Boolean
This method determines if a given agent can exist at the specified position inside this container. By default, a container can accomodate anyone or anything. Subclass to change this behavior. This should take into account the size, shape and current condition of the agent, and might take into account whether the agent has certain movement abilities.
183 184 185 |
# File 'lib/demiurge/container.rb', line 183 def can_accomodate_agent?(agent, position) true end |
#contents ⇒ Array<Demiurge::StateItem>
Gets the contents array as items, not names.
31 32 33 |
# File 'lib/demiurge/container.rb', line 31 def contents state["contents"].map { |name| @engine.item_by_name(name) } end |
#contents_names ⇒ Array<String>
Gets the array of item names of all items contained in this container.
23 24 25 |
# File 'lib/demiurge/container.rb', line 23 def contents_names state["contents"] end |
#ensure_contains(item_name) ⇒ void
This method returns an undefined value.
This makes sure the given item name is listed in the container's contents. It does not make sure that the item currently exists, or that its position is set to this container.
58 59 60 61 62 |
# File 'lib/demiurge/container.rb', line 58 def ensure_contains(item_name) raise("Pass only item names to ensure_contains!") unless item_name.is_a?(String) @state["contents"] |= [item_name] nil end |
#ensure_does_not_contain(item_name) ⇒ void
This method returns an undefined value.
This makes sure the given item name is not listed in the container's contents. It does not make sure the item exists, nor do anything with the item's position.
73 74 75 76 77 |
# File 'lib/demiurge/container.rb', line 73 def ensure_does_not_contain(item_name) raise("Pass only item names to ensure_does_not_contain!") unless item_name.is_a?(String) @state["contents"] -= [item_name] nil end |
#finished_init ⇒ void
This method returns an undefined value.
The finished_init hook is called after all items are loaded. For containers, this makes sure all items set as contents of this container also have it correctly set as their position.
41 42 43 44 45 46 47 |
# File 'lib/demiurge/container.rb', line 41 def finished_init # Can't move all items inside until they all exist, which isn't guaranteed until init is finished. state["contents"].each do |item| move_item_inside(@engine.item_by_name(item)) end nil end |
#intentions_for_next_step ⇒ Array<Intention>
This determines the intentions for the next tick for this container and for all items inside it.
192 193 194 195 196 197 198 199 |
# File 'lib/demiurge/container.rb', line 192 def intentions_for_next_step intentions = super @state["contents"].each do |item_name| item = @engine.item_by_name(item_name) intentions += item.intentions_for_next_step end intentions end |
#item_change_location(item, old_pos, new_pos) ⇒ void
This method returns an undefined value.
This is a callback to indicate that an item has changed from one location to another. This will normally require removing the item from its first location and adding it to a new location. A different callback is called when the item changes position within a single location.
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/demiurge/container.rb', line 129 def item_change_location(item, old_pos, new_pos) old_loc = old_pos.split("#")[0] old_loc_item = @engine.item_by_name(old_loc) old_loc_item.ensure_does_not_contain(item.name) new_loc = new_pos.split("#")[0] new_loc_item = @engine.item_by_name(new_loc) new_loc_item.ensure_contains(item.name) item.state["position"] = new_pos old_zone = old_loc_item.zone_name new_zone = new_loc_item.zone_name if new_zone != old_zone item.state["zone"] = new_zone end nil end |
#item_change_position(item, old_pos, new_pos) ⇒ void
This method returns an undefined value.
This is a callback to indicate that an item has changed position, but remains inside this location. Other than changing the item's position state variable, this may not require any changes. A different callback is called when the item changes from one location to another.
112 113 114 115 |
# File 'lib/demiurge/container.rb', line 112 def item_change_position(item, old_pos, new_pos) item.state["position"] = new_pos nil end |
#move_item_inside(item) ⇒ void
This method returns an undefined value.
This makes sure the given StateItem is contained in this container. It sets the item's position to be in this container, and if there is an old location it attempts to properly remove the item from it.
88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/demiurge/container.rb', line 88 def move_item_inside(item) old_pos = item.position if old_pos old_loc_name = old_pos.split("#")[0] old_loc = @engine.item_by_name(old_loc_name) old_loc.ensure_does_not_contain(item.name) end @state["contents"] |= [ item.name ] nil end |
#receive_offer(action_name, intention) ⇒ void
This method returns an undefined value.
When an item has an Intention, that Intention is offered in order to be potentially modified or cancelled by environmental effects. For instance, a room might have a muddy floor that slows walking or prevents running, or an icy floor that causes sliding around. That offer is normally coordinated through the item's location. The location will receive this callback (#receive_offer) and make appropriate modifications to the Intention. Any other items or agents that want to modify the Intention will have to coordinate with the appropriate item location.
162 163 164 165 166 167 168 169 170 |
# File 'lib/demiurge/container.rb', line 162 def receive_offer(action_name, intention) # Run handlers, if any on_actions = @state["on_action_handlers"] if on_actions && (on_actions[action_name] || on_actions["all"]) run_action(on_actions["all"], intention, current_intention: intention) if on_actions["all"] run_action(on_actions[action_name], intention, current_intention: intention) if on_actions[action_name] end nil end |