Olib 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,62 +1,74 @@
1
+ require 'Olib/interface/queryable'
2
+ require 'net/http'
3
+ require 'json'
1
4
  # a collection for managing all of the creatures in a room
2
- module Olib
3
- class Creatures
4
- def Creatures.first
5
- all.first
6
- end
7
5
 
8
- def Creatures.all
9
- GameObj.npcs
10
- .map { |creature| Creature.new(creature) }
11
- .select { |creature| !creature.dead? }
12
- .select { |creature| !creature.ignorable? }
13
- .select { |creature| !creature.tags.include?('animate') }
14
- .select { |creature| !creature.gone? } || []
15
- end
6
+ class Creatures < Interface::Queryable
16
7
 
17
- def Creatures.each(&block)
18
- all.each(&block)
19
- end
8
+ METADATA_URL = "https://cdn.rawgit.com/ondreian/gemstone_data_project/c40a5dfb/creatures.json"
9
+
10
+ ARCHETYPES = [
11
+ :undead, :living, :weak, :grimswarm,
12
+ :antimagic, :flying, :lowly, :bandit,
13
+ :aggressive,
14
+ ]
20
15
 
21
- def Creatures.[](exp)
22
- regexp = exp.class == String ? /#{exp}/ : exp
16
+ STATES = [
17
+ :dead, :sleeping, :webbed, :immobile,
18
+ :stunned, :prone, :sitting,
19
+ :kneeling, :flying
20
+ ]
23
21
 
24
- filter { |creature| creature.name =~ regexp || creature.id == exp }
22
+ def Creatures.fetch_metadata!
23
+ begin
24
+ JSON.parse Net::HTTP.get URI METADATA_URL
25
+ rescue
26
+ puts $!
27
+ puts $!.backtrace[0..1]
28
+ []
25
29
  end
26
-
27
- def Creatures.filter(&block);
28
- all.select(&block)
30
+ end
31
+
32
+ METADATA = fetch_metadata!
33
+ BY_NAME = METADATA.reduce(Hash.new) do |by_name, record|
34
+ by_name[record["name"]] = record
35
+ by_name
36
+ end
37
+
38
+ def Creatures.unsafe
39
+ (GameObj.npcs || [])
40
+ .map do |obj| Creature.new obj end
41
+ .reject do |creature| creature.gone? end
42
+ end
43
+
44
+ def Creatures.fetch
45
+ unsafe.select do |creature|
46
+ creature.aggressive?
47
+ end.reject do |creature|
48
+ creature.tags.include?(:companion) ||
49
+ creature.tags.include?(:familiar) ||
50
+ creature.gone? ||
51
+ creature.name =~ /nest/
29
52
  end
53
+ end
30
54
 
31
- def Creatures.bandits; filter { |creature| creature.is?('bandit') } ;end;
32
- def Creatures.ignoreable; filter { |creature| creature.is?('ignoreable') };end;
33
- def Creatures.flying; filter { |creature| creature.is?('flying') } ;end;
34
- def Creatures.living; filter { |creature| creature.is?('living') } ;end;
35
- def Creatures.antimagic; filter { |creature| creature.is?('antimagic') } ;end;
36
- def Creatures.undead; filter { |creature| creature.is?('undead') } ;end;
37
-
38
- def Creatures.grimswarm; filter { |creature| creature.is?('grimswarm') } ;end;
39
- def Creatures.invasion; filter { |creature| creature.is?('invasion') } ;end;
40
-
41
- def Creatures.escortees
42
- GameObj.npcs
43
- .map {|creature| Creature.new(creature) }
44
- .select {|creature| creature.is?('escortee') }
55
+ [ARCHETYPES, STATES].flatten.each do |state|
56
+ Creatures.define_singleton_method(state) do
57
+ select do |creature|
58
+ [creature.tags, creature.status].flatten.include?(state)
59
+ end
45
60
  end
61
+ end
46
62
 
47
- def Creatures.stunned; all.select(&:stunned?) ;end;
48
- def Creatures.active; all.select(&:active?) ;end;
49
- def Creatures.dead; all.select(&:dead?) ;end;
50
- def Creatures.prone; all.select(&:prone?) ;end;
51
-
52
- def Creatures.ambushed?
53
- last_line = $_SERVERBUFFER_.reverse.find { |line| line =~ /<pushStream id='room'\/>|An? .*? fearfully exclaims, "It's an ambush!"|#{Olib::Dictionary.bandit_traps.values.join('|')}/ }
54
- echo "detected ambush..." if !last_line.nil? && last_line !~ /pushStream id='room'/
63
+ def self.living
64
+ reject do |creature|
65
+ creature.undead?
66
+ end
67
+ end
55
68
 
56
- !last_line.nil? && last_line !~ /pushStream id='room'/
69
+ def self.bounty
70
+ select do |creature|
71
+ creature.name.include?(Bounty.creature)
57
72
  end
58
73
  end
59
74
  end
60
-
61
- class Creatures < Olib::Creatures
62
- end
@@ -1,18 +1,23 @@
1
1
  # for defining containers ala lootsack and using them across scripts
2
+ require "Olib/core/extender"
3
+ require "Olib/core/item"
2
4
 
3
- require 'Olib/core/extender'
4
-
5
- class String
6
- def to_class
7
- Kernel.const_get self
8
- rescue NameError
9
- nil
5
+ class Regexp
6
+ def or(re)
7
+ Regexp.new self.to_s + "|" + re.to_s
10
8
  end
9
+ end
10
+
11
+ def class_exists?(class_name)
12
+ klass = Module.const_get(class_name)
13
+ return klass.is_a?(Class)
14
+ rescue NameError
15
+ return false
16
+ end
11
17
 
12
- def is_a_defined_class?
13
- true if self.to_class
14
- rescue NameError
15
- false
18
+ class GameObj
19
+ def to_container
20
+ Olib::Container.new self.id
16
21
  end
17
22
  end
18
23
 
@@ -20,20 +25,35 @@ module Olib
20
25
  class Container < Gameobj_Extender
21
26
  attr_accessor :ref, :nested, :containers, :ontop
22
27
 
28
+
29
+ Item.type_methods.each do |method, tag|
30
+ type =tag.split.map(&:capitalize).join('_')
31
+ if class_exists?(type)
32
+ define_method(method.to_sym) do
33
+ find_by_tags(tag).map do |item|
34
+ Kernel.const_get(type).new item
35
+ end
36
+ end
37
+ else
38
+ define_method(method.to_sym) do find_by_tags(tag) end
39
+ end
40
+ end
41
+
42
+
23
43
  def initialize(id=nil)
24
44
  # extract the class name to attempt to lookup the item by your settings
25
45
  # ex: class Lootsack
26
46
  # ex: class Gemsack
27
- name = if self.class.name.include?("::") then self.class.name.downcase.split('::').last.strip else self.class.name.downcase end
28
- candidates = Olib.Inventory[Vars[name]]
47
+ name = if self.class.name.include?("::") then self.class.name.downcase.split("::").last.strip else self.class.name.downcase end
48
+ candidates = Inventory[Vars[name]]
29
49
  raise Olib::Errors::DoesntExist.new("#{name} could not be initialized are you sure you:\n ;var set #{name}=<something>") if candidates.empty? && id.nil?
30
-
50
+ @id = id
31
51
  @ref = GameObj[id] || candidates.first
32
52
  @ontop = Array.new
33
53
 
34
54
  unless GameObj[@ref.id].contents
35
55
  tops = [
36
- 'table'
56
+ "table"
37
57
  ]
38
58
 
39
59
  action = tops.include?(@ref.noun) ? "look on ##{@ref.id}" : "look in ##{@ref.id}"
@@ -46,9 +66,8 @@ module Olib
46
66
  end
47
67
 
48
68
  def contents
49
- [
50
- @ontop,
51
- GameObj[@ref.id].contents.map { |item| Item.new(item) }
69
+ [ @ontop,
70
+ GameObj[@ref.id].contents.map do |item| Item.new(item, self) end
52
71
  ].flatten
53
72
  end
54
73
 
@@ -66,7 +85,7 @@ module Olib
66
85
 
67
86
  def find_by_tags(*tags)
68
87
  contents.select { |item|
69
- !tags.map {|tag| item.is?(tag) }.include? false
88
+ !tags.map {|tag| item.is?(tag) }.include?(false)
70
89
  }
71
90
  end
72
91
 
@@ -80,7 +99,7 @@ module Olib
80
99
  def
81
100
 
82
101
  def __verbs__
83
- @verbs = 'open close analyze inspect weigh'.split(' ').map(&:to_sym)
102
+ @verbs = "open close analyze inspect weigh".split(" ").map(&:to_sym)
84
103
  singleton = (class << self; self end)
85
104
  @verbs.each do |verb|
86
105
  singleton.send :define_method, verb do
@@ -134,68 +153,114 @@ module Olib
134
153
  self
135
154
  end
136
155
 
156
+ def rummage
157
+ Rummage.new(self)
158
+ end
159
+
137
160
  def nested?
138
161
  @nested
139
162
  end
140
163
 
141
- def gems
142
- find_by_tags('gem')
164
+ def full?
165
+ is? "full"
143
166
  end
144
167
 
145
- def magic_items
146
- find_by_tags('magic')
147
- end
168
+ def add(*items)
169
+ _id = @id
170
+ items.each { |item|
148
171
 
149
- def jewelry
150
- find_by_tags('jewelry')
172
+ result = Olib.do "_drag ##{item.class == String ? item : item.id} ##{_id}", /#{[Olib::Dictionary.put[:success], Olib::Dictionary.put[:failure].values].flatten.join("|")}/
173
+ if result =~ /won"t fit in the/
174
+ tag "full"
175
+ raise Errors::ContainerFull
176
+ end
177
+ }
178
+ self
151
179
  end
152
180
 
153
- def skins
154
- find_by_tags('skin')
181
+ def method_missing(name, *args)
182
+ where(noun: name.to_s)
155
183
  end
156
184
 
157
- def boxes
158
- find_by_tags('boxes')
185
+ def to_s
186
+ "<Container:#{@id} @name=#{@name} @contents=[#{contents}]>"
159
187
  end
188
+ end
189
+ end
160
190
 
161
- def scrolls
162
- find_by_tags('scroll')
163
- end
191
+ class Rummage
192
+ SUCCESS = /and remove/
193
+ FAIL = /but can't seem|^But your hands are full|^You can only rummage for|^What/
164
194
 
165
- def full?
166
- is? 'full'
167
- end
195
+ @@message = OpenStruct.new(
196
+ success: SUCCESS,
197
+ fail: FAIL,
198
+ either: SUCCESS.or(FAIL)
199
+ )
168
200
 
169
- def add(item)
170
- result = Olib.do "_drag ##{item.id} ##{@id}", /#{[Olib::Dictionary.put[:success], Olib::Dictionary.put[:failure].values].flatten.join('|')}/
171
- tag 'full' if result =~ /won't fit in the/
172
- self
173
- end
201
+ def Rummage.message
202
+ @@message
174
203
  end
175
204
 
176
- class Lootsack < Container
205
+ attr_accessor :container
177
206
 
207
+ def initialize(container)
208
+ @container = container
178
209
  end
179
-
180
- def Olib.Lootsack
181
- return @@lootsack if @@lootsack
182
- @@lootsack = Lootsack.new
183
- @@lootsack
210
+
211
+ def perform(mod, query)
212
+ res = Olib.do "rummage ##{@container.id} #{mod} #{query}", Rummage.message.either
213
+ [!res.match(FAIL), res]
214
+ end
215
+
216
+ def spell(number)
217
+ perform "spell", number
218
+ end
219
+
220
+ def runestone(rune)
221
+ perform "runestone", rune
222
+ end
223
+
224
+ def ingredient(str)
225
+ perform "ingredient", str
226
+ end
227
+
228
+ def holy(tier)
229
+ perform "holy", tier
184
230
  end
231
+ end
185
232
 
233
+ # globalize
234
+ class Container < Olib::Container
186
235
  end
187
236
 
188
237
  module Containers
189
238
  @@containers = {}
190
239
 
191
240
  def Containers.define(name)
192
- @@containers[name] = Object.const_set(name.capitalize, Class.new(Olib::Container)).new
241
+ container = Class.new(Olib::Container)
242
+ @@containers[name] = Object.const_set(name.capitalize, container).new
193
243
  @@containers[name]
194
244
  end
195
245
 
196
246
  def Containers.method_missing(name)
197
247
  return @@containers[name] if @@containers[name]
198
248
  return Containers.define(name)
199
- end
249
+ end
200
250
 
251
+ def Containers.[](name)
252
+ begin
253
+ Containers.define(name)
254
+ rescue Exception => e
255
+ nil
256
+ end
257
+ end
258
+
259
+ def Containers.right_hand
260
+ Olib::Container.new(GameObj.right_hand.id)
261
+ end
262
+
263
+ def Containers.left_hand
264
+ Olib::Container.new(GameObj.left_hand.id)
265
+ end
201
266
  end
@@ -1,4 +1,5 @@
1
- # used to wrap and extend a GameObj item
1
+ # TODO:
2
+ # this should be refactored to use a mixin pattern
2
3
  module Olib
3
4
  class Gameobj_Extender
4
5
  attr_accessor :type
@@ -1,38 +1,100 @@
1
- require 'Olib/core/extender'
1
+ require "ostruct"
2
+ require "Olib/core/extender"
3
+ require "Olib/core/use"
4
+
5
+ class GameObj
6
+ def to_item
7
+ Olib::Item.new self
8
+ end
9
+ end
2
10
 
3
11
  module Olib
4
12
  # this is the structure for a base Object
5
13
  # wraps an instance of GameObj and adds the ability for tags, queries
6
14
  class Item < Olib::Gameobj_Extender
15
+ TYPES = [
16
+ "reagent",
17
+ ["spirit beast talismans", true],
18
+ "alchemy product",
19
+ ["alchemy equipment", true],
20
+ "note",
21
+ ["cursed", true],
22
+ ["ammo", true],
23
+ "box",
24
+ "gem",
25
+ "herb",
26
+ ["food", true],
27
+ ["uncommon", true],
28
+ "valuable",
29
+ "plinite",
30
+ ["ebongate", true],
31
+ ["quest", true],
32
+ ["jewelry", true],
33
+ ["junk", true],
34
+ "lockpick",
35
+ "magic",
36
+ "scroll",
37
+ "skin",
38
+ "wand",
39
+ "toy",
40
+ ["armor", true],
41
+ "weapon",
42
+ ["clothing", true],
43
+ "instrument",
44
+ "jar",
45
+ "lm trap",
46
+ "lm tool",
47
+ "scarab",
48
+ #"consignment",
49
+ #"gemshop",
50
+ #"pawnshop",
51
+ #"furrier"
52
+ ]
53
+
54
+ def self.type_methods
55
+ TYPES.map { |type|
56
+ if type.class == Array then
57
+ [ Olib.methodize(type.first).to_sym, type.first ]
58
+ elsif ["x"].include?(type.chars.last)
59
+ [ Olib.methodize(type + "es").to_sym, type ]
60
+ else
61
+ [ Olib.methodize(type + "s").to_sym, type ]
62
+ end
63
+ }
64
+ end
65
+
7
66
  attr_accessor :props, :container
8
67
  # When created, it should be passed an instance of GameObj
9
68
  #
10
69
  # Example:
11
70
  # Olib::Item.new(GameObj.right_hand)
12
- def initialize(obj)
71
+ def initialize(obj, container = nil)
72
+ @container = container
13
73
  @props = Hash.new
14
74
  @props[:name] = obj.name
15
75
  @props[:after_name] = obj.after_name
16
76
  @props[:before_name]= obj.before_name
17
- @props[:desc] = [obj.before_name, obj.name, obj.after_name].compact.join(' ')
77
+ @props[:desc] = [obj.before_name, obj.name, obj.after_name].compact.join(" ")
18
78
  @props[:noun] = obj.noun
19
79
  define :tags, []
20
- obj.type.split(',').map { |t| tag(t) }
80
+ obj.type.split(",").map { |t| tag(t) }
81
+
82
+ #tag @props[:name]
21
83
 
22
- if is?('jar') && @props[:after_name] =~ /containing (.*+?)/
23
- tag Dictionary.gems[:singularize].call @props[:after_name].gsub('containing', '').strip
84
+ if is?("jar") && @props[:after_name] =~ /containing (.*+?)/
85
+ tag Dictionary.gems[:singularize].call @props[:after_name].gsub("containing", "").strip
24
86
  end
25
87
 
26
- if is?('gem')
88
+ if is?("gem")
27
89
  tag Dictionary.gems[:singularize].call @props[:name]
28
90
  end
29
91
 
30
- if is?('jar') && @props[:after_name].nil?
31
- tag('empty')
92
+ if is?("jar") && @props[:after_name].nil?
93
+ tag("empty")
32
94
  end
33
95
 
34
96
  if Vars.teleporter && Vars.teleporter == @props[:name]
35
- tag('teleporter')
97
+ tag("teleporter")
36
98
  end
37
99
 
38
100
  super(obj)
@@ -64,6 +126,10 @@ module Olib
64
126
  @props[:tags]
65
127
  end
66
128
 
129
+ def use(&block)
130
+ Use.new(self, &block)
131
+ end
132
+
67
133
  def worn?
68
134
  GameObj.inv.collect { |item| item.id }.include? @id
69
135
  end
@@ -76,7 +142,7 @@ module Olib
76
142
 
77
143
  def buy
78
144
  Char.deplete_wealth cost
79
- fput action 'buy'
145
+ fput action "buy"
80
146
  self
81
147
  end
82
148
 
@@ -92,8 +158,12 @@ module Olib
92
158
  GameObj[@id].nil?
93
159
  end
94
160
 
161
+ def ==(other)
162
+ @id == other.id
163
+ end
164
+
95
165
  def pullable?
96
- is? 'pullable'
166
+ is? "pullable"
97
167
  end
98
168
 
99
169
  def affordable?
@@ -103,11 +173,11 @@ module Olib
103
173
  end
104
174
 
105
175
  def buyable?
106
- is? 'buyable'
176
+ is? "buyable"
107
177
  end
108
178
 
109
179
  def cost
110
- @props['cost']
180
+ @props["cost"]
111
181
  end
112
182
 
113
183
  def acquire_from_shop
@@ -127,8 +197,8 @@ module Olib
127
197
  end
128
198
 
129
199
  def in
130
- return self if has? 'contents'
131
- Olib.wrap(action 'look in') { |line|
200
+ return self if has? "contents"
201
+ Olib.wrap(action "look in") { |line|
132
202
  if line=~/^There is nothing in there.|You gaze through (.*?) and see.../
133
203
  raise Olib::Errors::Mundane
134
204
  end
@@ -136,14 +206,14 @@ module Olib
136
206
  # handle jar data
137
207
  if line =~ /Inside (.*?) you see (?<number>[\d]+) portion(|s) of (?<type>.*?). It is (more than |less than|)(?<percent>[a-z ]+)./
138
208
  data = line.match(/Inside (.*?) you see (?<number>[\d]+) portion(|s) of (?<type>.*?). It is (more than |less than|)(?<percentage>[a-z ]+)./)
139
- tag data[:percentage] == 'full' ? "full" : "partial"
209
+ tag data[:percentage] == "full" ? "full" : "partial"
140
210
  define :number, data[:number].to_i
141
211
  raise Olib::Errors::Mundane
142
212
  end
143
213
 
144
214
  #handle empty jars
145
215
  if line =~ /The (.*?) is empty./
146
- tag 'empty'
216
+ tag "empty"
147
217
  raise Olib::Errors::Mundane
148
218
  end
149
219
  }
@@ -157,7 +227,7 @@ module Olib
157
227
  raise Olib::Errors::Mundane if line =~ Dictionary.put[:success]
158
228
 
159
229
  if line =~ Dictionary.put[:failure][:full]
160
- tag 'full'
230
+ tag "full"
161
231
  raise Olib::Errors::ContainerFull
162
232
  end
163
233
  }
@@ -165,12 +235,12 @@ module Olib
165
235
  end
166
236
 
167
237
  def stash
168
- _drag GameObj[props['container']]
238
+ _drag GameObj[props["container"]]
169
239
  end
170
240
 
171
241
  def shake
172
242
  # make sure we have a count so we need to match fewer lines
173
- self.in if is? 'jar' and missing? :number
243
+ self.in if is? "jar" and missing? :number
174
244
 
175
245
  Olib.wrap(action "shake"){ |line|
176
246
  raise Olib::Errors::Fatal if line =~ /you realize that it is empty/
@@ -190,27 +260,27 @@ module Olib
190
260
 
191
261
  Olib.wrap("shop sell #{amt}") {|line|
192
262
  raise Olib::Errors::Mundane if line =~ /^You place your/
193
- raise Olib::Errors::Fatal if line =~ /There's no more room for anything else right now./
263
+ raise Olib::Errors::Fatal if line =~ /There"s no more room for anything else right now./
194
264
  }
195
265
 
196
266
  end
197
267
 
268
+ SOLD = /([\d]+) silver/
269
+ WRONG_SHOP = /That's not quite my field/
270
+ WORTHLESS = /worthless/
271
+
198
272
  def sell
199
- price = 0
200
273
  take
201
- Olib.wrap( action "sell" ){ |line|
202
- raise Olib::Errors::Fatal.new "#{to_s} is not sellable here" if GameObj.right_hand.id == @id
203
-
204
- if line =~ /([\d]+) silver/
205
- price = $1.to_i
206
- raise Olib::Errors::Mundane
207
- end
208
- }
209
- price
274
+ case result = dothistimeout("sell ##{@id}", 3, (SOLD | WRONG_SHOP | WORTHLESS))
275
+ when SOLD then [:sold, OpenStruct.new(name: self.name, price: $1.to_i)]
276
+ when WRONG_SHOP then [:wrong_shop, self]
277
+ when WORTHLESS then [:worthless, self]
278
+ else [:unhandled_case, result]
279
+ end
210
280
  end
211
281
 
212
282
  def turn
213
- fput action 'turn'
283
+ fput action "turn"
214
284
  self
215
285
  end
216
286
 
@@ -219,9 +289,9 @@ module Olib
219
289
  end
220
290
 
221
291
  def add(*items)
222
- items.each { |item|
292
+ items.each do |item|
223
293
  item._drag(self)
224
- }
294
+ end
225
295
  self
226
296
  end
227
297
 
@@ -243,7 +313,7 @@ module Olib
243
313
  raise Olib::Errors::Mundane
244
314
  end
245
315
 
246
- if line =~ /I'm afraid that you can't pull that./
316
+ if line =~ /I"m afraid that you can"t pull that./
247
317
  if onfailure
248
318
  onfailure.call(self)
249
319
  else
@@ -307,7 +377,7 @@ module Olib
307
377
  end
308
378
 
309
379
  Olib.wrap(action "wear") { |line|
310
- if line =~ /You can't wear that.|You can only wear/
380
+ if line =~ /You can"t wear that.|You can only wear/
311
381
  if onfailure
312
382
  onfailure.call(self)
313
383
  else
@@ -329,18 +399,18 @@ module Olib
329
399
  while(line = get)
330
400
  next if Olib::Dictionary.ignorable?(line)
331
401
  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/
332
- @props['max_light'] = true if line =~ /light as it can get/
333
- @props['max_deep'] = true if line =~ /pockets could not possibly get any deeper/
334
- @props['max_deep'] = false if line =~ /pockets deepened/
335
- @props['max_light'] = false if line =~ /talented merchant lighten/
402
+ @props["max_light"] = true if line =~ /light as it can get/
403
+ @props["max_deep"] = true if line =~ /pockets could not possibly get any deeper/
404
+ @props["max_deep"] = false if line =~ /pockets deepened/
405
+ @props["max_light"] = false if line =~ /talented merchant lighten/
336
406
  if line =~ /Casting Elemental Detection/
337
407
  should_detect = true
338
408
  next
339
409
  end
340
410
  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/
341
- @props['analyze'] = String.new unless @props['analyze']
342
- @props['analyze'].concat line.strip
343
- @props['analyze'].concat " "
411
+ @props["analyze"] = String.new unless @props["analyze"]
412
+ @props["analyze"].concat line.strip
413
+ @props["analyze"].concat " "
344
414
  end
345
415
  end
346
416
 
@@ -348,15 +418,15 @@ module Olib
348
418
  # Silent
349
419
  end
350
420
  detect if should_detect
351
- temp_analysis = @props['analyze'].split('.').map(&:strip).map(&:downcase).reject {|ln| ln.empty? }
352
- @props['analyze'] = temp_analysis unless temp_analysis.empty?
421
+ temp_analysis = @props["analyze"].split(".").map(&:strip).map(&:downcase).reject {|ln| ln.empty? }
422
+ @props["analyze"] = temp_analysis unless temp_analysis.empty?
353
423
  return self
354
424
  end
355
425
 
356
426
  def take
357
- return self if has? 'cost'
427
+ return self if has? "cost"
358
428
 
359
- Olib.wrap(action 'get') { |line|
429
+ Olib.wrap(action "get") { |line|
360
430
  raise Errors::DoesntExist if line=~ Olib::Dictionary.get[:failure][:ne]
361
431
  raise Errors::HandsFull if line=~ Olib::Dictionary.get[:failure][:hands_full]
362
432
  raise Errors::TooHeavy if line=~ Olib::Dictionary.get[:failure][:weight]
@@ -366,7 +436,7 @@ module Olib
366
436
  end
367
437
 
368
438
  if line =~ Olib::Dictionary.get[:failure][:buy]
369
- define 'cost', line.match(Olib::Dictionary.get[:failure][:buy])[:cost].to_i
439
+ define "cost", line.match(Olib::Dictionary.get[:failure][:buy])[:cost].to_i
370
440
  raise Olib::Errors::Mundane
371
441
  end
372
442
 
@@ -374,13 +444,13 @@ module Olib
374
444
  raise Olib::Errors::Mundane
375
445
  end
376
446
 
377
- if line=~ /You'll have to buy it if you want it/
378
- tag 'buyable'
447
+ if line=~ /You"ll have to buy it if you want it/
448
+ tag "buyable"
379
449
  raise Olib::Errors::Mundane
380
450
  end
381
451
 
382
452
  if line=~ /You can PULL/
383
- tag 'pullable'
453
+ tag "pullable"
384
454
  raise Olib::Errors::Mundane
385
455
  end
386
456
 
@@ -396,15 +466,15 @@ module Olib
396
466
 
397
467
  def _inspect
398
468
 
399
- return self if has? 'inspect'
469
+ return self if has? "inspect"
400
470
 
401
471
  in_inspect = false
402
472
 
403
- Olib.wrap_stream(action 'inspect') { |line|
473
+ Olib.wrap_stream(action "inspect") { |line|
404
474
 
405
475
  raise Olib::Errors::Mundane if line =~ /^<prompt/ and in_inspect
406
476
 
407
- # skip first inspect line because it's useless for info
477
+ # skip first inspect line because it"s useless for info
408
478
  if line =~ /You carefully inspect|You carefully count|goat/
409
479
  in_inspect = true
410
480
  end
@@ -413,47 +483,47 @@ module Olib
413
483
  if in_inspect
414
484
 
415
485
  if line =~ /^You estimate that (?:.*?) can store (?:a|an|some) ([a-zA-Z -]+) amount with enough space for ([a-zA-Z ]+)/
416
- @props['space'] = $1
417
- @props['number_of_items'] = $2
486
+ @props["space"] = $1
487
+ @props["number_of_items"] = $2
418
488
  end
419
489
 
420
490
 
421
491
 
422
492
  if line =~ /^You determine that you could wear the (.*?) ([a-zA-Z ]+)/
423
- @props['location']= $2
493
+ @props["location"]= $2
424
494
  end
425
495
 
426
496
  if line =~ /allows you to conclude that it is ([a-zA-Z ]+)/
427
497
 
428
498
  if line =~ Dictionary.size
429
- @props['shield_type'] = $1
499
+ @props["shield_type"] = $1
430
500
  else
431
- Dictionary.armors.each do |type, re| @props['armor_type'] = type if line =~ re end
501
+ Dictionary.armors.each do |type, re| @props["armor_type"] = type if line =~ re end
432
502
  end
433
503
 
434
504
  end
435
505
 
436
506
  if line =~ /suitable for use in unarmed combat/
437
- @props['weapon_type']= "uac"
507
+ @props["weapon_type"]= "uac"
438
508
  end
439
509
 
440
510
  if line =~ /requires skill in ([a-zA-Z ]+) to use effectively/
441
511
 
442
- @props['weapon_type']= $1
512
+ @props["weapon_type"]= $1
443
513
  if line =~ /It appears to be a modified ([a-zA-Z -]+)/
444
- @props['weapon_base']= $1
514
+ @props["weapon_base"]= $1
445
515
  else
446
- @props['weapon_base']= @noun
516
+ @props["weapon_base"]= @noun
447
517
  end
448
518
  end
449
519
 
450
520
  if line =~ /^It looks like this item has been mainly crafted out of ([a-zA-Z -]+)./
451
- @props['material']= $1
521
+ @props["material"]= $1
452
522
  raise Olib::Errors::Mundane
453
523
  end
454
524
 
455
525
  if line =~ /can hold liquids/
456
- @props['liquid_container']=true
526
+ @props["liquid_container"]=true
457
527
  end
458
528
 
459
529
  end
@@ -464,34 +534,34 @@ module Olib
464
534
  end
465
535
 
466
536
  def look
467
- return self if has? 'show'
468
- Olib.wrap(action 'look') { |line|
469
- raise Olib::Errors::Mundane if line=~/^You see nothing unusual.|^You can't quite get a good look at/
470
- define 'show', line unless line=~/prompt time|You take a closer look/
537
+ return self if has? "show"
538
+ Olib.wrap(action "look") { |line|
539
+ raise Olib::Errors::Mundane if line=~/^You see nothing unusual.|^You can"t quite get a good look at/
540
+ define "show", line unless line=~/prompt time|You take a closer look/
471
541
  }
472
542
  self
473
543
  end
474
544
 
475
545
  def tap
476
- return self if has? 'description'
477
- Olib.wrap(action 'tap') { |line|
546
+ return self if has? "description"
547
+ Olib.wrap(action "tap") { |line|
478
548
  next unless line=~ /You tap (.*?) (on|in)/
479
- define 'description', $1
549
+ define "description", $1
480
550
  raise Olib::Errors::Mundane
481
551
  }
482
552
  self
483
553
  end
484
554
 
485
555
  def price
486
- return self if(has? 'price' or has? 'info')
487
- Olib.wrap(action 'get') { |line|
556
+ return self if(has? "price" or has? "info")
557
+ Olib.wrap(action "get") { |line|
488
558
 
489
559
  if line =~ /(\d+) silvers/
490
- define 'price', line.match(/(?<price>\d+) silvers/)[:price]
560
+ define "price", line.match(/(?<price>\d+) silvers/)[:price]
491
561
  raise Olib::Errors::Mundane
492
562
  end
493
563
 
494
- if line =~ /You can't pick that up/
564
+ if line =~ /You can"t pick that up/
495
565
  define "info", true
496
566
  raise Olib::Errors::Mundane
497
567
  end
@@ -503,38 +573,36 @@ module Olib
503
573
  end
504
574
 
505
575
  def read
506
- return self if has? 'read'
576
+ return self if has? "read"
507
577
  scroll = false
508
578
  multiline = false
509
- Olib.wrap_stream(action 'read') { |line|
579
+ Olib.wrap_stream(action "read") { |line|
510
580
 
511
581
  raise Olib::Errors::Mundane if line =~ /^<prompt/ and (multiline or scroll)
512
- raise Olib::Errors::Mundane if line =~ /There is nothing there to read|You can't do that./
582
+ raise Olib::Errors::Mundane if line =~ /There is nothing there to read|You can"t do that./
513
583
 
514
584
  # if we are in a multiline state
515
- @props['read'] = @props['read'].concat line if multiline
585
+ @props["read"] = @props["read"].concat line if multiline
516
586
 
517
587
  # capture spell
518
- if scroll && line =~ /\(([0-9]+)\) ([a-zA-Z'\s]+)/
519
- n = $1
520
- name = $2
521
- spell = {'n' => $1, 'name' => $2}
588
+ if scroll && line =~ /\(([0-9]+)\) ([a-zA-Z"\s]+)/
589
+ spell = OpenStruct.new(name: $2, num: $1.to_i)
522
590
  #Client.notify "Spell detected ... (#{$1}) #{$2}"
523
- @props['spells'].push spell
591
+ @props["spells"].push spell
524
592
 
525
593
  # begin scroll
526
594
  elsif line =~ /It takes you a moment to focus on the/
527
595
  scroll = true
528
- @props['spells'] = Array.new
596
+ @props["spells"] = Array.new
529
597
 
530
598
  # open multiline
531
599
  elsif line =~ /^In the (.*?) language, it reads/
532
600
  multiline = true
533
- @props['read'] = "#{line}\n"
534
- @props['language'] = $1
601
+ @props["read"] = "#{line}\n"
602
+ @props["language"] = $1
535
603
 
536
604
  # alert to unknown
537
- elsif line =~ /but the language is not one you know. It looks like it's written in (.*?)./
605
+ elsif line =~ /but the language is not one you know. It looks like it"s written in (.*?)./
538
606
  Script.log "Please find a friend that can read for #{$1} in #{XMLData.room_title}"
539
607
  echo "Please find a friend that can read for #{$1} in #{XMLData.room_title}"
540
608
  raise Olib::Errors::Mundane