Class: Demiurge::Container

Inherits:
ActionItem show all
Defined in:
lib/demiurge/container.rb

Overview

Container is the parent class of Locations, Zones and other items that can contain items.

Direct Known Subclasses

Location, Zone

Constant Summary

Constants inherited from ActionItem

ActionItem::ACTION_LEGAL_KEYS

Instance Attribute Summary

Attributes inherited from StateItem

#engine, #name

Instance Method Summary collapse

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

Parameters:

  • name (String)

    The Engine-unique item name

  • engine (Demiurge::Engine)

    The Engine this item is part of

  • state (Hash)

    State data to initialize from

Since:

  • 0.0.1



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.

Parameters:

  • agent (Demiurge::Agent)

    The agent being checked

  • position (String)

    The position being checked within this container

Returns:

  • (Boolean)

    Whether the agent can exist at that position

Since:

  • 0.0.1



183
184
185
# File 'lib/demiurge/container.rb', line 183

def can_accomodate_agent?(agent, position)
  true
end

#contentsArray<Demiurge::StateItem>

Gets the contents array as items, not names.

Returns:

Since:

  • 0.3.0



31
32
33
# File 'lib/demiurge/container.rb', line 31

def contents
  state["contents"].map { |name| @engine.item_by_name(name) }
end

#contents_namesArray<String>

Gets the array of item names of all items contained in this container.

Returns:

  • (Array<String>)

    The array of item names

Since:

  • 0.0.1



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.

Parameters:

  • item_name (String)

    The item name to ensure is listed in the container

See Also:

Since:

  • 0.0.1



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.

Parameters:

  • item_name (String)

    The item name

See Also:

Since:

  • 0.0.1



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_initvoid

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.

Since:

  • 0.0.1



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_stepArray<Intention>

This determines the intentions for the next tick for this container and for all items inside it.

Returns:

  • (Array<Intention>)

    The array of intentions for next tick

Since:

  • 0.0.1



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.

Parameters:

  • item (Demiurge::StateItem)

    The item changing position

  • old_pos (String)

    The pre-movement position, which is current when this is called

  • new_pos (String)

    The post-movement position, which should be current when this method completes

See Also:

Since:

  • 0.0.1



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.

Parameters:

  • item (Demiurge::StateItem)

    The item changing position

  • old_pos (String)

    The pre-movement position, which is current when this is called

  • new_pos (String)

    The post-movement position, which should be current when this method completes

See Also:

Since:

  • 0.0.1



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.

Parameters:

See Also:

Since:

  • 0.0.1



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.

Parameters:

  • action_name (String)

    The name of the action for this Intention.

  • intention (Demiurge::Intention)

    The Intention being offered

See Also:

Since:

  • 0.0.1



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