Class: Lich::Common::Inventory::Item
- Inherits:
-
Object
- Object
- Lich::Common::Inventory::Item
- Defined in:
- documented/common/inventory.rb
Overview
A single item from an inventoryManager response: one exist id, its
identity, physical data, container facets, and links into the tree.
Weight is intrinsic (location-independent -- a nodachi weighs the same in a pocket or in a weight-nullifying eddy). Container load is read from the wire via #in_encum when present, else summed from direct children.
Constant Summary collapse
- LEADING_ARTICLE =
Leading article dropped from the GameObj bridge name (per the GameObj author's guidance,
before_namestays nil so it does not collide with the DR get-command context stored there). /\A(an?|some|the)\s+/i- NAME_MARKER =
Simu highlight markers that wrap the core noun phrase inside
long(e.g.a $_gnarled rowan crook$_ wound with knotted yarn): the text between the markers is the name, the text after them is the descriptor. /\$_(.*?)\$_/
Instance Attribute Summary collapse
-
#adjective ⇒ String
readonly
The adjective segment (may be empty).
-
#article ⇒ String
readonly
Leading article/pre-noun words (e.g. "a scuffed").
-
#capacity_lbs ⇒ Integer?
readonly
Weight capacity in pounds, or nil when unknown (no in_max/on_max, or the NO_WEIGHT_LIMIT_SENTINEL).
-
#children ⇒ Array<Item>
readonly
Direct children (both "in" and "on").
-
#flags ⇒ Array<String>
readonly
Flag tokens, e.g.
-
#id ⇒ String
readonly
The exist id (game object id) as a string.
-
#in_encum ⇒ Integer?
readonly
Raw container load from the wire (0 for a weight-nullifying container), or nil when the wire omits it.
-
#in_selector ⇒ String?
readonly
The container's
in_selectorverb hint, or nil. -
#name ⇒ String
readonly
Assembled short display name (e.g. "a scuffed pack").
-
#noun ⇒ String
readonly
The noun (e.g. "pack"); used for classification.
-
#parent_id ⇒ String?
readonly
Parent exist id, "player", "room", or nil.
-
#parent_item ⇒ Item?
readonly
The parent Item, or nil for a top-level item.
-
#relation ⇒ String?
readonly
The
locrelation: "worn", "in", "on", "room". -
#weight ⇒ Integer
readonly
Intrinsic weight in pounds (0 when absent).
Instance Method Summary collapse
-
#add_child(child) ⇒ void
private
Attaches a child during tree construction.
-
#at_feet? ⇒ Boolean
Whether the item is on the ground at the player's feet.
-
#closed? ⇒ Boolean
Whether the container is closed (still enumerated).
-
#container? ⇒ Boolean
Whether this item can hold other items: it either has children or advertises a weight cap.
-
#contents(relation = nil) ⇒ Array<Item>
Direct children, optionally filtered by relation.
-
#effective_weight(visited, depth) ⇒ Integer
protected
private
Recursive weight traversal backing #total_weight.
-
#finalize! ⇒ void
private
Freezes the child list once the tree is fully wired.
-
#held? ⇒ Boolean
Whether the item is held in either hand.
-
#in_left_hand? ⇒ Boolean
Whether the item is in the player's left hand.
-
#in_right_hand? ⇒ Boolean
Whether the item is in the player's right hand.
-
#in_room? ⇒ Boolean
Whether the item is on the ground in the room (shared; the feed lists the whole room's ground loot, not only the player's).
-
#initialize(fields) ⇒ Item
constructor
private
A new instance of Item.
-
#link_parent(parent) ⇒ void
private
Records the parent item during tree construction.
-
#locked? ⇒ Boolean
Whether the container is locked.
-
#long ⇒ String?
The long description, entity-decoded and with Simu's
$_highlight markers removed (they wrap the core name on the wire; see NAME_MARKER). -
#opaque? ⇒ Boolean
Whether the interior is unknown.
-
#register_gameobj(place_worn:, open_container_ids:) ⇒ GameObj
private
Mirrors this item into GameObj for a committed snapshot.
-
#sellable ⇒ String?
Sellable classification, derived like #type from the item's own noun/name via #bridge_gameobj.
-
#space_left ⇒ Integer?
Remaining weight capacity in pounds, or
nilwhen either capacity or used weight is unknown (never raises on a nil operand). -
#total_weight ⇒ Integer
Total effective weight of this item and everything it carries, in pounds.
-
#type ⇒ String?
Type classification (e.g. "weapon,edged"), derived from this item's own noun/name via its backing GameObj (see #bridge_gameobj).
-
#used_lbs ⇒ Integer?
Weight currently used by this container, in pounds: #in_encum when the wire provides it (authoritative for magical containers), else the sum of each direct child's effective #total_weight -- so items nested inside child containers are counted too (a plain child contributes just its own #weight; a child eddy contributes only its own).
-
#worn? ⇒ Boolean
Whether the item is worn on the player (relation
worn-- NOT merely parentplayer, which also covers hands/feet).
Constructor Details
#initialize(fields) ⇒ Item
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a new instance of Item.
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'documented/common/inventory.rb', line 201 def initialize(fields) @id = freeze_str(fields[:id]) @article = freeze_str(fields[:article]) @adjective = freeze_str(fields[:adjective]) @noun = freeze_str(fields[:noun]) @name = freeze_str(fields[:name]) @long = freeze_str(fields[:long]) @relation = freeze_str(fields[:relation]) @parent_id = freeze_str(fields[:parent_id]) @weight = fields[:weight] @capacity_lbs = fields[:capacity_lbs] @in_encum = fields[:in_encum] @in_selector = freeze_str(fields[:in_selector]) # Frozen (deeply) so a consumer cannot mutate shared snapshot state via # e.g. +item.flags << "locked"+; the flag tokens are frozen too. @flags = fields[:flags].map(&:freeze).freeze @has_max = fields[:has_max] @children = [] end |
Instance Attribute Details
#adjective ⇒ String (readonly)
Returns the adjective segment (may be empty).
150 151 152 |
# File 'documented/common/inventory.rb', line 150 def adjective @adjective end |
#article ⇒ String (readonly)
Returns leading article/pre-noun words (e.g. "a scuffed").
147 148 149 |
# File 'documented/common/inventory.rb', line 147 def article @article end |
#capacity_lbs ⇒ Integer? (readonly)
Returns weight capacity in pounds, or nil when unknown (no in_max/on_max, or the NO_WEIGHT_LIMIT_SENTINEL).
181 182 183 |
# File 'documented/common/inventory.rb', line 181 def capacity_lbs @capacity_lbs end |
#children ⇒ Array<Item> (readonly)
Returns direct children (both "in" and "on").
194 195 196 |
# File 'documented/common/inventory.rb', line 194 def children @children end |
#flags ⇒ Array<String> (readonly)
Returns flag tokens, e.g. ["closed", "locked"].
191 192 193 |
# File 'documented/common/inventory.rb', line 191 def flags @flags end |
#id ⇒ String (readonly)
Returns the exist id (game object id) as a string.
144 145 146 |
# File 'documented/common/inventory.rb', line 144 def id @id end |
#in_encum ⇒ Integer? (readonly)
Returns raw container load from the wire (0 for a weight-nullifying container), or nil when the wire omits it.
185 186 187 |
# File 'documented/common/inventory.rb', line 185 def in_encum @in_encum end |
#in_selector ⇒ String? (readonly)
Returns the container's in_selector verb hint, or nil.
188 189 190 |
# File 'documented/common/inventory.rb', line 188 def in_selector @in_selector end |
#name ⇒ String (readonly)
Returns assembled short display name (e.g. "a scuffed pack").
156 157 158 |
# File 'documented/common/inventory.rb', line 156 def name @name end |
#noun ⇒ String (readonly)
Returns the noun (e.g. "pack"); used for classification.
153 154 155 |
# File 'documented/common/inventory.rb', line 153 def noun @noun end |
#parent_id ⇒ String? (readonly)
Returns parent exist id, "player", "room", or nil.
174 175 176 |
# File 'documented/common/inventory.rb', line 174 def parent_id @parent_id end |
#parent_item ⇒ Item? (readonly)
Returns the parent Lich::Common::Inventory::Item, or nil for a top-level item.
197 198 199 |
# File 'documented/common/inventory.rb', line 197 def parent_item @parent_item end |
#relation ⇒ String? (readonly)
Returns the loc relation: "worn", "in", "on", "room".
171 172 173 |
# File 'documented/common/inventory.rb', line 171 def relation @relation end |
#weight ⇒ Integer (readonly)
Returns intrinsic weight in pounds (0 when absent).
177 178 179 |
# File 'documented/common/inventory.rb', line 177 def weight @weight end |
Instance Method Details
#add_child(child) ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Attaches a child during tree construction.
367 368 369 |
# File 'documented/common/inventory.rb', line 367 def add_child(child) @children << child end |
#at_feet? ⇒ Boolean
Returns whether the item is on the ground at the player's feet.
273 274 275 |
# File 'documented/common/inventory.rb', line 273 def at_feet? @relation == 'atfeet' end |
#closed? ⇒ Boolean
Returns whether the container is closed (still enumerated).
233 234 235 |
# File 'documented/common/inventory.rb', line 233 def closed? @flags.include?('closed') end |
#container? ⇒ Boolean
Whether this item can hold other items: it either has children or advertises a weight cap. (A max-less holder -- e.g. a ring-holder with rings ON it -- is still a container.)
228 229 230 |
# File 'documented/common/inventory.rb', line 228 def container? !@children.empty? || @has_max end |
#contents(relation = nil) ⇒ Array<Item>
Direct children, optionally filtered by relation. An opaque (locked)
container returns [] (contents unknown), never a false "empty".
290 291 292 293 294 295 |
# File 'documented/common/inventory.rb', line 290 def contents(relation = nil) return [] if opaque? return @children.dup if relation.nil? @children.select { |child| child.relation == relation.to_s } end |
#effective_weight(visited, depth) ⇒ Integer (protected)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Recursive weight traversal backing #total_weight. Kept internal so the
public query takes no arguments; protected so a parent Lich::Common::Inventory::Item can pass
the shared +visited+/+depth+ accumulators down to its children (a cycle
guard + depth cap) without exposing them as public API.
435 436 437 438 439 440 441 442 443 444 445 |
# File 'documented/common/inventory.rb', line 435 def effective_weight(visited, depth) return 0 if depth > MAX_TREE_DEPTH || visited.include?(@id) visited.add(@id) own = @weight return own unless container? return own if opaque? return own + @in_encum unless @in_encum.nil? own + @children.sum { |child| child.effective_weight(visited, depth + 1) } end |
#finalize! ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Freezes the child list once the tree is fully wired.
384 385 386 |
# File 'documented/common/inventory.rb', line 384 def finalize! @children.freeze end |
#held? ⇒ Boolean
Returns whether the item is held in either hand.
268 269 270 |
# File 'documented/common/inventory.rb', line 268 def held? in_right_hand? || in_left_hand? end |
#in_left_hand? ⇒ Boolean
Returns whether the item is in the player's left hand.
263 264 265 |
# File 'documented/common/inventory.rb', line 263 def in_left_hand? @relation == 'lefthand' end |
#in_right_hand? ⇒ Boolean
Returns whether the item is in the player's right hand.
258 259 260 |
# File 'documented/common/inventory.rb', line 258 def in_right_hand? @relation == 'righthand' end |
#in_room? ⇒ Boolean
Returns whether the item is on the ground in the room (shared; the feed lists the whole room's ground loot, not only the player's).
279 280 281 |
# File 'documented/common/inventory.rb', line 279 def in_room? @relation == 'room' end |
#link_parent(parent) ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Records the parent item during tree construction.
376 377 378 |
# File 'documented/common/inventory.rb', line 376 def link_parent(parent) @parent_item = parent end |
#locked? ⇒ Boolean
Returns whether the container is locked.
238 239 240 |
# File 'documented/common/inventory.rb', line 238 def locked? @flags.include?('locked') end |
#long ⇒ String?
The long description, entity-decoded and with Simu's $_ highlight
markers removed (they wrap the core name on the wire; see NAME_MARKER).
164 165 166 167 168 |
# File 'documented/common/inventory.rb', line 164 def long return @long if @long.nil? @long.gsub('$_', '') end |
#opaque? ⇒ Boolean
Whether the interior is unknown. A LOCKED container emits zero children by game design (treasure boxes populate only on open; gem pouches aggregate), so it is opaque -- never conclude it is empty.
247 248 249 |
# File 'documented/common/inventory.rb', line 247 def opaque? locked? end |
#register_gameobj(place_worn:, open_container_ids:) ⇒ GameObj
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Mirrors this item into GameObj for a committed snapshot. Only the two
registries the extended feed authoritatively owns are written: worn ->
@@inv and +in+/+on+ -> @@contents[parent] (both via the staging-aware
GameObj.new_inv, so the caller's +begin_inv+/+begin_container+ cycle
publishes them atomically). Hands and room loot are left to the classic
+
406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 |
# File 'documented/common/inventory.rb', line 406 def register_gameobj(place_worn:, open_container_ids:) before, name, after = descriptive_parts @gameobj = case @relation when 'worn' place_worn ? GameObj.new_inv(@id, @noun, name, nil, before, after) : GameObj.index_or_create(@id, @noun, name, before, after) when 'in', 'on' if open_container_ids.include?(@parent_id) GameObj.new_inv(@id, @noun, name, @parent_id, before, after) else GameObj.index_or_create(@id, @noun, name, before, after) end else GameObj.index_or_create(@id, @noun, name, before, after) end backfill_names(@gameobj, before, after) end |
#sellable ⇒ String?
Sellable classification, derived like #type from the item's own noun/name via #bridge_gameobj.
358 359 360 |
# File 'documented/common/inventory.rb', line 358 def sellable bridge_gameobj.sellable end |
#space_left ⇒ Integer?
Remaining weight capacity in pounds, or nil when either capacity or
used weight is unknown (never raises on a nil operand). Not clamped --
may be negative if a container is overfull.
322 323 324 325 326 |
# File 'documented/common/inventory.rb', line 322 def space_left return nil if @capacity_lbs.nil? || used_lbs.nil? @capacity_lbs - used_lbs end |
#total_weight ⇒ Integer
Total effective weight of this item and everything it carries, in pounds. A container subtree contributes the container's own #weight plus (#in_encum when present, else the recursive contribution of its children) -- so a weight-nullifying eddy adds only its own weight, not the heavy contents inside it. Cycle-safe (visited set + depth cap; see the internal #effective_weight traversal).
338 339 340 |
# File 'documented/common/inventory.rb', line 338 def total_weight effective_weight(Set.new, 0) end |
#type ⇒ String?
Type classification (e.g. "weapon,edged"), derived from this item's own noun/name via its backing GameObj (see #bridge_gameobj).
348 349 350 |
# File 'documented/common/inventory.rb', line 348 def type bridge_gameobj.type end |
#used_lbs ⇒ Integer?
Weight currently used by this container, in pounds: #in_encum when
the wire provides it (authoritative for magical containers), else the
sum of each direct child's effective #total_weight -- so items nested
inside child containers are counted too (a plain child contributes just
its own #weight; a child eddy contributes only its own). nil for a
non-container or an opaque (locked) container, where it is not meaningful.
307 308 309 310 311 312 313 |
# File 'documented/common/inventory.rb', line 307 def used_lbs return nil unless container? return nil if opaque? return @in_encum unless @in_encum.nil? @children.sum(&:total_weight) end |
#worn? ⇒ Boolean
Returns whether the item is worn on the player (relation
worn -- NOT merely parent player, which also covers hands/feet).
253 254 255 |
# File 'documented/common/inventory.rb', line 253 def worn? @relation == 'worn' end |