class Olib::Item

this is the structure for a base Object wraps an instance of GameObj and adds the ability for tags, queries

Constants

SOLD
TYPES
WORTHLESS
WRONG_SHOP

Attributes

container[RW]
props[RW]

Public Class Methods

new(obj, container = nil) click to toggle source

When created, it should be passed an instance of GameObj

Example:

Olib::Item.new(GameObj.right_hand)
Calls superclass method Olib::Gameobj_Extender::new
# File lib/Olib/core/item.rb, line 71
def initialize(obj, container = nil)
  @container          = container
  @props              = Hash.new
  @props[:name]       = obj.name
  @props[:after_name] = obj.after_name
  @props[:before_name]= obj.before_name
  @props[:desc]       = [obj.before_name, obj.name, obj.after_name].compact.join(" ")
  @props[:noun]       = obj.noun
  define :tags, []
  obj.type.split(",").map { |t| tag(t) }

  #tag @props[:name]

  if is?("jar") && @props[:after_name] =~ /containing (.*+?)/
    tag Dictionary.gems[:singularize].call @props[:after_name].gsub("containing", "").strip
  end

  if is?("gem")
    tag Dictionary.gems[:singularize].call @props[:name]
  end

  if is?("jar") && @props[:after_name].nil?
    tag("empty")
  end

  if Vars.teleporter && Vars.teleporter == @props[:name]
    tag("teleporter")
  end

  super(obj)
end
type_methods() click to toggle source
# File lib/Olib/core/item.rb, line 54
def self.type_methods
  TYPES.map { |type|
    if type.class == Array then
      [ Olib.methodize(type.first).to_sym, type.first ]
    elsif ["x"].include?(type.chars.last)
      [ Olib.methodize(type + "es").to_sym, type ]
    else
      [ Olib.methodize(type + "s").to_sym, type ]
    end
  }
end

Public Instance Methods

==(other) click to toggle source
# File lib/Olib/core/item.rb, line 161
def ==(other)
  @id == other.id
end
_drag(target) click to toggle source
# File lib/Olib/core/item.rb, line 223
def _drag(target)
  Olib.wrap("_drag ##{@id} ##{target.id}") { |line|
    # order of operations is important here for jars
    raise Olib::Errors::DoesntExist          if line =~ Dictionary.put[:failure][:ne]
    raise Olib::Errors::Mundane              if line =~ Dictionary.put[:success]
    
    if line =~ Dictionary.put[:failure][:full]
      tag "full"
      raise Olib::Errors::ContainerFull
    end
  }
  self
end
_inspect() click to toggle source
# File lib/Olib/core/item.rb, line 467
def _inspect

  return self if has? "inspect"

  in_inspect = false

  Olib.wrap_stream(action "inspect") { |line|

    raise Olib::Errors::Mundane  if line =~ /^<prompt/ and in_inspect

    # skip first inspect line because it"s useless for info
    if line =~ /You carefully inspect|You carefully count|goat/
      in_inspect = true
    end


    if in_inspect
      
      if line =~ /^You estimate that (?:.*?) can store (?:a|an|some) ([a-zA-Z -]+) amount with enough space for ([a-zA-Z ]+)/
        @props["space"]           = $1
        @props["number_of_items"] = $2
      end
        

      
      if line =~ /^You determine that you could wear the (.*?) ([a-zA-Z ]+)/
        @props["location"]= $2
      end
      
      if line =~ /allows you to conclude that it is ([a-zA-Z ]+)/

        if line =~ Dictionary.size
          @props["shield_type"] = $1
        else
          Dictionary.armors.each do |type, re| @props["armor_type"] = type if line =~ re end
        end
        
      end

      if line =~ /suitable for use in unarmed combat/
        @props["weapon_type"]= "uac"
      end

      if line =~ /requires skill in ([a-zA-Z ]+) to use effectively/
    
        @props["weapon_type"]= $1
        if line =~ /It appears to be a modified ([a-zA-Z -]+)/
          @props["weapon_base"]= $1
        else
          @props["weapon_base"]= @noun
        end
      end            
      
      if line =~ /^It looks like this item has been mainly crafted out of ([a-zA-Z -]+)./
        @props["material"]= $1
        raise Olib::Errors::Mundane
      end
      
      if line =~ /can hold liquids/
        @props["liquid_container"]=true
      end

    end
    
  }
  
  return self
end
acquire_from_shop() click to toggle source
# File lib/Olib/core/item.rb, line 183
def acquire_from_shop
  take
  if pullable?
    return pull
  else
    Olib.wrap(action "buy"){ |line|
      raise Olib::Errors::InsufficientFunds if line =~ /The merchant frowns/
      if line =~ /You hand over/
        Char.deplete_wealth cost
        raise Olib::Errors::Mundane
      end
    }
  end
  self
end
action(verb) click to toggle source
# File lib/Olib/core/item.rb, line 287
def action(verb)
  "#{verb} ##{@id}"
end
add(*items) click to toggle source
# File lib/Olib/core/item.rb, line 291
def add(*items)
  items.each do |item|
    item._drag(self)
  end
  self
end
affordable?() click to toggle source
# File lib/Olib/core/item.rb, line 169
def affordable?
  take
  return true if pullable?
  cost <= Char.smart_wealth
end
analyze() click to toggle source
# File lib/Olib/core/item.rb, line 394
def analyze
  fput "analyze ##{@id}"
  should_detect = false
  begin
    Timeout::timeout(1) do
      while(line = get)
        next                        if Olib::Dictionary.ignorable?(line)
        next                        if line =~ /sense that the item is free from merchant alteration restrictions|and sense that the item is largely free from merchant alteration restrictions|these can all be altered by a skilled merchant|please keep the messaging in mind when designing an alterations|there is no recorded information on that item|The creator has also provided the following information/
        @props["max_light"] = true  if line =~ /light as it can get/
        @props["max_deep"]  = true  if line =~ /pockets could not possibly get any deeper/
        @props["max_deep"]  = false if line =~ /pockets deepened/
        @props["max_light"] = false if line =~ /talented merchant lighten/
        if line =~ /Casting Elemental Detection/
          should_detect = true 
          next 
        end
        break                       if line =~ /pockets deepened|^You get no sense of whether|light as it can get|pockets could not possibly get any deeper|talented merchant lighten/
        @props["analyze"] = String.new unless @props["analyze"]
        @props["analyze"].concat line.strip
        @props["analyze"].concat " "
      end
    end
  
  rescue Timeout::Error
    # Silent
  end
  detect if should_detect
  temp_analysis = @props["analyze"].split(".").map(&:strip).map(&:downcase).reject {|ln| ln.empty? }
  @props["analyze"] = temp_analysis unless temp_analysis.empty?
  return self
end
buy() click to toggle source
# File lib/Olib/core/item.rb, line 143
def buy
  Char.deplete_wealth cost
  fput action "buy"
  self
end
buyable?() click to toggle source
# File lib/Olib/core/item.rb, line 175
def buyable?
  is? "buyable"
end
cost() click to toggle source
# File lib/Olib/core/item.rb, line 179
def cost
  @props["cost"]
end
crawl() click to toggle source
# File lib/Olib/core/item.rb, line 137
def crawl
  take
  tap._inspect.read.look
  self
end
define(key, val) click to toggle source
# File lib/Olib/core/item.rb, line 298
def define(key, val)
  @props[key] = val
  self
end
drop() click to toggle source
# File lib/Olib/core/item.rb, line 461
def drop
  Script.log("#{Time.now} > dropped #{to_s}")
  fput action "drop"
  self
end
exists?() click to toggle source
# File lib/Olib/core/item.rb, line 157
def exists?
  GameObj[@id].nil?
end
give(target, onfailure=nil) click to toggle source
# File lib/Olib/core/item.rb, line 332
def give(target, onfailure=nil)
  Olib.wrap_stream("give ##{@id} to #{target}", 30) { |line|
    raise Olib::Errors::Mundane if line=~ /This looks perfect/

    if line =~ /glances at you and moves out of your reach./
      raise Olib::Errors::Fatal.new "You appear to have an invalid NPC definition"
    end

  }

  self
end
has?(key) click to toggle source
# File lib/Olib/core/item.rb, line 149
def has?(key)
  !@props[key].nil?
end
in() click to toggle source
# File lib/Olib/core/item.rb, line 199
def in
  return self if has? "contents"
  Olib.wrap(action "look in") { |line|
    if line=~/^There is nothing in there.|You gaze through (.*?) and see.../
      raise Olib::Errors::Mundane
    end
    
    # handle jar data
    if line =~ /Inside (.*?) you see (?<number>[\d]+) portion(|s) of (?<type>.*?).  It is (more than |less than|)(?<percent>[a-z ]+)./ 
      data = line.match(/Inside (.*?) you see (?<number>[\d]+) portion(|s) of (?<type>.*?).  It is (more than |less than|)(?<percentage>[a-z ]+)./)
      tag data[:percentage] == "full" ? "full" : "partial"
      define :number, data[:number].to_i
      raise Olib::Errors::Mundane
    end

    #handle empty jars
    if line =~ /The (.*?) is empty./
      tag "empty"
      raise Olib::Errors::Mundane
    end
  }
  self
end
is?(tag) click to toggle source

determine if Item is something

example:

item.is?("jar")
# File lib/Olib/core/item.rb, line 112
def is?(tag)
  @props[:tags].include?(tag)
end
look() click to toggle source
# File lib/Olib/core/item.rb, line 536
def look
  return self if has? "show"
  Olib.wrap(action "look") { |line|
    raise Olib::Errors::Mundane if line=~/^You see nothing unusual.|^You can"t quite get a good look at/
    define "show", line  unless line=~/prompt time|You take a closer look/
  }
  self
end
missing?(key) click to toggle source
# File lib/Olib/core/item.rb, line 153
def missing?(key)
  !has?(key)
end
price() click to toggle source
# File lib/Olib/core/item.rb, line 555
def price
  return self if(has? "price" or has? "info")
  Olib.wrap(action "get") { |line|

    if line =~ /(\d+) silvers/
      define "price", line.match(/(?<price>\d+) silvers/)[:price]
      raise Olib::Errors::Mundane
    end

    if line =~ /You can"t pick that up/
      define "info", true
      raise Olib::Errors::Mundane
    end

    Script.log "unmatched price: #{line}"
    
  }
  self
end
pull(onfailure=nil) click to toggle source
# File lib/Olib/core/item.rb, line 303
def pull(onfailure=nil)
  refresh_instance = false
  original_right   = GameObj.right_hand
  original_left    = GameObj.left_hand
  Olib.wrap(action "pull") { |line|
    
    if line =~ /^You pull/
      if line =~ /There (are|is) ([\d]+) left/
        refresh_instance = true
      end
      raise Olib::Errors::Mundane
    end

    if line =~ /I"m afraid that you can"t pull that./
      if onfailure
        onfailure.call(self)
      else 
        raise Olib::Errors::DoesntExist 
      end
    end
  }
  # for stacked items in shops
  if refresh_instance
    return Item.new(GameObj.left_hand) if original_left.nil? && !GameObj.left_hand.nil?
    return Item.new(GameObj.right_hand)
  end
  self
end
pullable?() click to toggle source
# File lib/Olib/core/item.rb, line 165
def pullable?
  is? "pullable"
end
read() click to toggle source
# File lib/Olib/core/item.rb, line 575
def read
  return self if has? "read"
  scroll    = false
  multiline = false
  Olib.wrap_stream(action "read") {  |line|

    raise Olib::Errors::Mundane  if line =~ /^<prompt/ and (multiline or scroll)
    raise Olib::Errors::Mundane if line =~ /There is nothing there to read|You can"t do that./

    # if we are in a multiline state
    @props["read"] = @props["read"].concat line if multiline

    # capture spell
    if scroll && line =~ /\(([0-9]+)\) ([a-zA-Z"\s]+)/
        spell = OpenStruct.new(name: $2, num: $1.to_i)
        #Client.notify "Spell detected ... (#{$1}) #{$2}"
        @props["spells"].push spell

    # begin scroll
    elsif line =~ /It takes you a moment to focus on the/
      scroll = true
      @props["spells"] = Array.new 

    # open multiline
    elsif line =~ /^In the (.*?) language, it reads/
      multiline          = true
      @props["read"]     = "#{line}\n"
      @props["language"] = $1

    # alert to unknown
    elsif line =~ /but the language is not one you know.  It looks like it"s written in (.*?)./
      Script.log "Please find a friend that can read for #{$1} in #{XMLData.room_title}"
      echo "Please find a friend that can read for #{$1} in #{XMLData.room_title}"
      raise Olib::Errors::Mundane
   
    end
    
  }
  return self
end
remove(onfailure=nil) click to toggle source
# File lib/Olib/core/item.rb, line 345
def remove(onfailure=nil)
  
  unless GameObj.inv.map(&:id).include? @id
    if onfailure
      onfailure.call(self)
    else 
      raise Olib::Errors::DoesntExist 
    end
  end
  
  Olib.wrap(action "remove") { |line|        
    if line =~ /You cannot remove|You better get a sharp knife/
      if onfailure
        onfailure.call(self)
      else 
        raise Olib::Errors::DoesntExist 
      end
    end
      
    raise Olib::Errors::Mundane if GameObj.right_hand.id == @id || GameObj.left_hand.id == @id
  }

  self
end
sell() click to toggle source
# File lib/Olib/core/item.rb, line 272
def sell
  take
  case result = dothistimeout("sell ##{@id}", 3, (SOLD | WRONG_SHOP | WORTHLESS))
  when SOLD        then [:sold, OpenStruct.new(name: self.name, price: $1.to_i)]
  when WRONG_SHOP  then [:wrong_shop, self]
  when WORTHLESS   then [:worthless, self]
  else                  [:unhandled_case, result]
  end
end
shake() click to toggle source
# File lib/Olib/core/item.rb, line 241
def shake
  # make sure we have a count so we need to match fewer lines
  self.in if is? "jar" and missing? :number
  
  Olib.wrap(action "shake"){ |line|
    raise Olib::Errors::Fatal    if line =~ /you realize that it is empty/
    if line =~ /fall into your/
      @props[:number] = @props[:number]-1
      raise Olib::Errors::Fatal.new "Jar is now empty\n you should rescue this to handle it gracefully" if @props[:number] == 0
      raise Olib::Errors::Mundane
    end
  }
  self
end
shop_sell(amt) click to toggle source
# File lib/Olib/core/item.rb, line 256
def shop_sell(amt)
  if GameObj.right_hand.id != @id
    raise Olib::Errors::Fatal
  end

  Olib.wrap("shop sell #{amt}") {|line|
    raise Olib::Errors::Mundane if line =~ /^You place your/
    raise Olib::Errors::Fatal   if line =~ /There"s no more room for anything else right now./
  }

end
stash() click to toggle source
# File lib/Olib/core/item.rb, line 237
def stash
  _drag GameObj[props["container"]]
end
tag(*tags) click to toggle source
# File lib/Olib/core/item.rb, line 116
def tag(*tags)
  @props[:tags].concat(tags)
  self
end
tags() click to toggle source
# File lib/Olib/core/item.rb, line 125
def tags
  @props[:tags]
end
take() click to toggle source
# File lib/Olib/core/item.rb, line 426
def take
  return self if has? "cost"

  Olib.wrap(action "get") { |line|
    raise Errors::DoesntExist    if line=~ Olib::Dictionary.get[:failure][:ne]
    raise Errors::HandsFull      if line=~ Olib::Dictionary.get[:failure][:hands_full]
    raise Errors::TooHeavy       if line=~ Olib::Dictionary.get[:failure][:weight]
    
    if line=~ Olib::Dictionary.get[:success] 
      raise Olib::Errors::Mundane
    end  

    if line =~ Olib::Dictionary.get[:failure][:buy]
      define "cost", line.match(Olib::Dictionary.get[:failure][:buy])[:cost].to_i
      raise Olib::Errors::Mundane
    end

    if line =~ /let me help you with that/
      raise Olib::Errors::Mundane
    end

    if line=~ /You"ll have to buy it if you want it/
      tag "buyable"
      raise Olib::Errors::Mundane
    end

    if line=~ /You can PULL/
      tag "pullable"
      raise Olib::Errors::Mundane
    end

  }
  self
end
tap() click to toggle source
# File lib/Olib/core/item.rb, line 545
def tap
  return self if has? "description"
  Olib.wrap(action "tap") { |line|
    next unless line=~ /You tap (.*?) (on|in)/
    define "description", $1 
    raise Olib::Errors::Mundane         
  }
  self
end
to_s() click to toggle source
# File lib/Olib/core/item.rb, line 103
def to_s
  @props.to_s
end
turn() click to toggle source
# File lib/Olib/core/item.rb, line 282
def turn
  fput action "turn"
  self
end
untag(*remove) click to toggle source
# File lib/Olib/core/item.rb, line 121
def untag(*remove)
  @props[:tags] = @props[:tags].select { |tag| !remove.include?(tag) }
end
use(&block) click to toggle source
# File lib/Olib/core/item.rb, line 129
def use(&block)
  Use.new(self, &block)
end
wear(onfailure=nil) click to toggle source
# File lib/Olib/core/item.rb, line 370
def wear(onfailure=nil)
  if GameObj.right_hand.id != @id || GameObj.left_hand.id != @id
    if onfailure
      onfailure.call(self)
    else 
      raise Olib::Errors::DoesntExist 
    end      
  end

  Olib.wrap(action "wear") { |line|        
    if line =~ /You can"t wear that.|You can only wear/
      if onfailure
        onfailure.call(self)
      else 
        raise Olib::Errors::DoesntExist 
      end
    end
    raise Olib::Errors::Mundane if GameObj.inv.map(&:id).include? @id
  }

  self

end
worn?() click to toggle source
# File lib/Olib/core/item.rb, line 133
def worn?
  GameObj.inv.collect { |item| item.id }.include? @id
end