forked from brycole/gemstone
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcommon.lic
646 lines (559 loc) · 22.8 KB
/
common.lic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
##### quiet
=begin
Suggestions and contributions are welcome: https://github.com/rpherbig/dr-scripts
A large set of helper functions for common actions shared by many scripts
Script was branched from Dragonrealms as of 01/18/2016 and brought to Gemstone.
Gemstone Branch: Kalros
v. 01
Changelog:
Removed methods that will never be usable in gemstone.
=end
$time_since_last_deposit = Time.now
$enhancive_container = 'spidersilk satchel'
$no_emblem = false
$lmas_audience_fwi = false
$pick_room = 20
$no_tpick = false
start_script "checkemail" if !running? "checkemail"
$FAILED_COMMAND = '*FAILED*'
$ORDINALS = %w(first second third fourth fifth sixth seventh eighth ninth tenth eleventh twelfth thirteenth)
#$combat_enhancives = ['alum-bound ironwood badge', 'soulstone inset silver armband']
$combat_enhancives = ['none']
$tpick_remove_enhancives = ['etched glaes aventail', 'garnet-set gold earring', 'alum-bound ironwood badge']
$exp_enhancives = ['coral and emerald crown']
$skin_enhancives = ['plain star ruby bracelet', 'coral and emerald crown', 'marquise-cut chrysoberyl stickpin']
$lock_enhancives = ['pearl studded bronze clasp', 'gem-encrusted mithril alloy neckchain', 'carved red dreamstone torc', 'twisted-wire vaalin bracelet', 'lapis-inlaid gold barrette', 'elegant gold pin', 'enruned mithril alloy pin', 'filigreed sterling silver earcuff', 'smoky topaz brooch']
$zone_now = "Ta'Illistim"
$armors = {'set of brushed mithril platemail' => 'brushed plate', 'imflass-winged golden rolaren greathelm' =>'rolaren greathelm'}
$armorshort = 'platemail'
delayed_start_script = <<-eos
sleep 5
wait_while { running?("repository")}
start_script 'map_mod'
eos
ExecScript.start(delayed_start_script, :quiet => false)
# blocking put
# bput is designed to be a more robust version of fput in situations where you know the desired response from the game
# unlike fput which will resend the same command repeatedly until it sees the desired message first from the game, bput only
# sends a given command one time (unless round time or type ahead errors occur) and then waits for the desired response.
# if the desired response isn't seen bput will eventually time out and echo debugging information.
# fput "forage grass", 'Roundtime' < This would never work because the game sends a response line "You search around..." before "Roundtime" is encountered.
# Similarly a command that can only succeed once can cause fput to hang.
# fput "get box", 'you pick up', 'get what?' < You have to deal with the failure case and just spam
# the command until failure in a noisy room with fput.
# bput "get box", 'you pick up', 'get what?' < lets you know with confidence if a box was picked up or if the item was missing.
module GSC
def bput(message, *matches)
waitrt?
timer = Time.now
log = []
matches.flatten!
matches.map! { |item| item.is_a?(Regexp) ? item : /#{item}/i }
clear
put message
while Time.now - timer < 15
response = get?
if response.nil?
pause 0.1
next
end
log += [response]
case response
when /(?:\.\.\.wait |Wait |\.\.\. wait )([0-9]+)/
pause Regexp.last_match(1).to_i
put message
timer = Time.now
next
when /Sorry, you may only type ahead/
pause 1
put message
timer = Time.now
next
end
matches.each do |match|
if (result = response.match(match))
waitrt?
return result.to_a.first
end
end
end
echo '*** No match was found after 15 seconds, dumping info'
echo "messages seen length: #{log.length}"
log.each { |message| echo "message: #{message}" }
echo "checked against #{matches}"
$FAILED_COMMAND
end
module_function :bput
def vaalin_lockpick(swap_pick)
vaalin_error = false
if GameObj.inv.find {|i| i.name =~ /twisted-wire vaalin bracelet/} and swap_pick == 'get'
bput 'rub my vaalin bracelet', 'Your vaalin bracelet begins'
elsif swap_pick == 'get'
vaalin_error = 'get_error' if GameObj.right_hand.name != 'vaalin lockpick' and GameObj.left_hand.name != 'vaalin lockpick'
end
if GameObj.right_hand.name == 'vaalin lockpick' or GameObj.left_hand.name == 'vaalin lockpick' and swap_pick == 'stow'
bput 'pull my vaalin lockpick', 'As you pull on your vaalin'
elsif swap_pick == 'stow'
vaalin_error = 'wear_error' if GameObj.inv.find {|i| i.name =~ /twisted-wire vaalin bracelet/}.nil?
end
if vaalin_error == 'get_error' or vaalin_error == 'wear_error'
echo "Error in vaalin lockpick script. Attempting to recover."
bput 'get my vaalin lockpick', "^You (get|reach|grab|already|remove)|^Get what"
bput 'get my vaalin bracelet', "^You (get|reach|grab|already|remove)|^Get what"
if GameObj.right_hand.name == 'vaalin lockpick' or GameObj.left_hand.name == 'vaalin lockpick'
return if swap_pick == 'get'
bput 'pull my vaalin lockpick', 'As you pull on your vaalin'
elsif GameObj.right_hand.name == 'vaalin bracelet' or GameObj.left_hand.name == 'vaalin bracelet'
bput 'wear my vaalin bracelet', "^You (attach|are)"
return if swap_pick == 'stow'
bput 'rub my vaalin bracelet', 'Your vaalin bracelet begins'
else
echo 'Could not recover from errior, vaalin lockpick could not be located.'
echo 'Pausing tpick until user returns.'
pause_script 'tpick'
end
end
end
module_function :vaalin_lockpick
def track_deposit(deposit_reason)
$silvers = 0
wait_while { running?('go2')}
$check_silvers = <<-eos
while line = get
break unless Room.current.id.to_s =~ /\\b(11|4686|3672)\\b/
if line =~ /You deposit (\\d+) silvers into your account|says, "That's a total of (\\d+) silvers|They add up to (\\d+) silvers/
echo "inside silver line"
echo line
echo $silvers += $1.to_i if $1
echo $silvers += $2.to_i if $2
echo $silvers += $3.to_i if $3
end
end
eos
ExecScript.start($check_silvers, :quiet => true)
put 'deposit all'
sleep 1
fput 'wealth'
#silvers = $silvers_from_coins.to_i + $silvers_from_notes.to_i
time_since_start = ((Time.now - $time_since_last_deposit) / 60.0).round(2)
silvers_per_hour = ($silvers / (time_since_start/60.0)).round
if deposit_reason !~ /loot/
$monster_silvers = silvers_per_hour
$creature_index += 1 if $monster_silvers < 150000
echo "Creature_index: #{$creature_index}" if $switch_hunting_debug
end
echo "Reason for deposit: #{deposit_reason}"
echo "Silvers: #{$silvers}"
echo "Time since last deposit: #{time_since_start} minutes."
echo "Silvers per hour: #{silvers_per_hour}"
File.open("silvers_per_hour.txt", 'a') { |file|
file.puts deposit_reason
file.puts "Per_hour: #{silvers_per_hour} Silvers: #{$silvers} Total_time: #{time_since_start}"
file.puts "-------"
}
$time_since_last_deposit = Time.now
end
module_function :track_deposit
def hook_squelch(remove_lines, downstream_add_name)
action = proc { |server_string|
if server_string =~ /#{remove_lines}/
nil
else
server_string
end
}
DownstreamHook.add(downstream_add_name, action)
end
module_function :hook_squelch
def open_satchel
$satchel_open = true
squelch_line = "title='Satchel'"
downstream_add_name = "hook_satchel"
hook_squelch(squelch_line, downstream_add_name)
bput 'open my spidersilk satchel', '^You open|^That is already'
DownstreamHook.remove(downstream_add_name)
end
module_function :open_satchel
def close_satchel
if $satchel_open
bput 'close my spidersilk satchel', '^You close|^That is already'
$satchel_open = false
end
end
module_function :close_satchel
def remove_enhancive(find_item)
@remove_items = Array.new
@container_id = GameObj[/#{$enhancive_container}/].id
find_item.each {|enhancive_name|
@container_id = GameObj[/#{"harness"}/].id if enhancive_name =~ /#{$armorshort}/
GameObj.inv.find {|i| @remove_items << i if i.name =~ /#{enhancive_name}/}
}
redo_loop = 0
@remove_items.each{ |i|
@item = i
put "_drag ##{i.id} ##{@container_id}"
waitfor "You"
sleep 0.5
waitrt?
if GameObj.right_hand.name != "Empty" or GameObj.left_hand.name != "Empty"
redo_loop += 1
if redo_loop > 5
fput 'put my plate in harness' if GameObj.right_hand.name =~ /#{$armorshort}/ or GameObj.left_hand.name =~ /#{$armorshort}/
fput 'stow right'
fput 'stow left'
end
sleep 1
sleep 1
waitrt?
waitrt?
redo
end
}
end
module_function :remove_enhancive
def wear_enhancive(find_item)
@wear_items = Array.new
@container_id = GameObj[/#{$enhancive_container}/].id
find_item.each {|enhancive_name|
@container_id = GameObj[/#{"harness"}/].id if enhancive_name =~ /#{$armorshort}/
GameObj[@container_id].contents.find{|z| @wear_items << z if z.name =~ /#{enhancive_name}/ }
}
@wear_items.each{ |i| put "_drag ##{i.id} wear";sleep 0.2;waitrt?}
end
module_function :wear_enhancive
def can_cast?(check_spell)
return true if Spell[check_spell].known? and Spell[check_spell].affordable?
return false
end
module_function :can_cast?
def find_teleport_setting
GSC.hook_squelch(".+", "find_setting")
silence_me
put 'tap my veniom band'
@start_time = Time.now
while line = get
break if Time.now > @start_time + 0.5
if line =~ /-> ?(\d+)/
UserVars.current_ring_setting = $1.to_i
break
end
end
DownstreamHook.remove("find_setting")
silence_me
end
module_function :find_teleport_setting
def goto_teleport_setting(goal)
max_settings = 12
goal = goal.to_i
echo UserVars.current_ring_setting
distance = (UserVars.current_ring_setting - goal)%max_settings
echo distance
command = 'pull'
if distance > max_settings / 2
distance = max_settings - distance
command = 'push'
end
(distance / 2).times {
bput "#{command} my veniom band", 'The band'
bput "#{command} my veniom band", 'The band'
}
(distance % 2).times {bput "#{command} my veniom band", 'The band'}
UserVars.current_ring_setting = goal
bput 'rub my veniom band', '^Obvious|^You get a sense|^You feel|^Something about'
#move_teleport_setting(distance, command)
end
module_function :goto_teleport_setting
def run_wait_script(script, var1)
start_script "#{script}", ["#{var1}"] if var1 !~ /xx/
start_script "#{script}" if var1 =~ /xx/
sleep 1
wait_while { running?("#{script}")}
waitrt?
sleep 1
end
module_function :run_wait_script
#def move_teleport_setting(steps, command)
# # break up steps by blocks of 2 for type ahead
# (steps / 2).times {
# put "#{command} band"
# put "#{command} band"
# waitfor "The band"
# }
# (steps % 2).times {put "#{command} band"}
#end
#module_function :move_teleport_setting
def wait_for_script_to_complete(name, args = [])
success = start_script(name, args)
if success
pause 2
pause 1 while Script.running?(name)
end
success
end
module_function :wait_for_script_to_complete
def remove_armor(armors)
@remove_items = Array.new
armors.each_key {|armor_long|
GameObj.inv.find {|i| @remove_items << i if i.name =~ /#{armor_long}/}
}
@remove_items.each{ |i|
container = 'spidersilk satchel'
container = 'harness' if i.name =~ /#{$armorshort}/
put "_drag ##{i.id} ##{GameObj[/#{container}/].id}";sleep 0.5;waitrt?
(put "_drag ##{i.id} ##{GameObj[/#{container}/].id}";sleep 0.5;waitrt?) if righthand == i.noun or lefthand == i.noun
}
end
module_function :remove_armor
def wear_armor(armors)
@wear_items = Array.new
armors.each_key {|long|
## armors[long] hash calls the noun(value) of the armor
armor_noun = armors[long]
@wear_items << armor_noun if GameObj.inv.find_all{|z| z.name =~ /#{long}/}.empty?
}
@wear_items.each{ |i| fput "get my #{i}";fput "wear my #{i}";sleep 0.5;waitrt?}
end
module_function :wear_armor
def forage(item)
snapshot = "#{checkright}#{checkleft}"
while "#{checkright}#{checkleft}" == snapshot
case bput("forage #{item}", 'Roundtime', 'The room is too cluttered to find anything here', 'You really need to have at least one hand free to forage properly')
when 'The room is too cluttered to find anything here'
fput('kick pile')
when 'You really need to have at least one hand free to forage properly'
empty_hands
end
waitrt?
end
end
module_function :forage
def hand_over(items, person)
items.each do |item|
fput("get my #{item}")
bput("give #{item} to #{person}", '^You offer your .* to')
waitfor('has accepted your offer')
end
end
module_function :hand_over
def rummage(parameter, container)
result = DRC.bput("rummage /#{parameter} my #{container}", 'but there is nothing in there like that\.', 'looking for .* and see .*', 'While it\'s closed', 'I don\'t know what you are referring to')
case result
when 'but there is nothing in there like that.', 'While it\'s closed', 'I don\'t know what you are referring to'
return []
end
text = extract_rummage_text(result)
list_to_nouns(text)
end
module_function :rummage
def extract_rummage_text(raw)
raw.match(/looking for .* and see (.*)\.$/).to_a[1]
end
module_function :extract_rummage_text
def get_boxes(container)
rummage('B', container)
end
module_function :get_boxes
def get_skins(container)
rummage('S', container)
end
module_function :get_skins
def get_gems(container)
rummage('G', container)
end
module_function :get_gems
def get_materials(container)
rummage('M', container)
end
module_function :get_materials
# Take a game formatted list "an arrow, silver coins and a deobar strongbox"
# And return an array ["an arrow", "silver coins", "a deobar strongbox"]
# is this ever useful compared to the list_to_nouns?
def list_to_array(list)
list.strip.split(/,|\sand\s/)
end
module_function :list_to_array
# Take a game formatted list "an arrow, silver coins and a deobar strongbox"
# And return an array of nouns ["arrow", "coins", "strongbox"]
def list_to_nouns(list)
list_to_array(list)
.map { |long_name| get_noun(long_name) }
.compact
.select { |noun| noun != '' }
end
module_function :list_to_nouns
def get_noun(long_name)
long_name.strip.scan(/[a-z\-]+$/i).first
end
module_function :get_noun
def empty_hands
fput 'stow right' until checkright.nil?
fput 'stow left' until checkleft.nil?
end
module_function :empty_hands
def walk_to(target_room, restart_on_fail = true)
return if target_room.nil?
room_num = target_room.to_i
return if room_num == Room.current.id.to_i
fput('stand') unless checkstanding
if Room.current.id.nil?
echo "In an unknown room, manually attempting to navigate to #{room_num}"
rooms = Map.list.select { |room| room.description.include?(XMLData.room_description.strip) && room.title.include?(XMLData.room_title) }
if rooms.empty? || rooms.length > 1
echo 'failed to find a matching room'
return
end
room = rooms.first
return if room_num == room.id
if room.wayto["#{room_num}"]
move room.wayto["#{room_num}"]
return
end
path = Map.findpath(room, Map[room_num])
move room.wayto["#{path.first}"]
walk_to(room_num)
return
end
start_script 'go2', ["#{room_num}"]
timer = Time.now
while Script.running?('go2')
if (Time.now - timer) > 30
kill_script 'go2'
timer = Time.now
start_script 'go2', ["#{room_num}"]
end
timer = Time.now if Script.running?('escort')
pause 0.5
end
# Consider just returning this boolean and letting callers decide what to do on a failed move.
if room_num != Room.current.id.to_i && restart_on_fail
echo "Failed to navigate to room #{room_num}, attempting again"
walk_to room_num
end
room_num == Room.current.id.to_i
end
module_function :walk_to
# Items class. Name is the noun of the object. Leather/metal boolean. Is the item worn (defaults to true). Does it hinder lockpicking? (false)
# full description is the line you would see if you looked at your inventory output.
# Item.new(name:'gloves', is_leather:true, is_worn:true, hinders_locks:true, description:'some coarse gargoyle-hide gloves with fitted seams')
class Item
attr_accessor :name, :is_leather, :is_worn, :hinders_lockpicking, :description, :container, :swappable, :tie_to
def initialize(name:nil, leather:nil, worn:true, hinders_locks:nil, description:nil, container:nil, swappable:false, tie_to:nil)
@name = name
@is_leather = leather
@is_worn = worn
@hinders_lockpicking = hinders_locks
@description = description
@container = container
@swappable = swappable
@tie_to = tie_to
end
def is_leather?
@is_leather
end
def is_worn?
@is_worn
end
attr_reader :name
def hinders_lockpicking?
@hinders_lockpicking
end
attr_reader :description
attr_reader :tie_to
end
class SpellData
attr_accessor :name, :abbrev, :min_prep, :cyclical, :after, :needs_moon, :cast, :expire, :skill, :cast_message, :before, :prep_message
def initialize(name:nil, abbrev:nil, min_prep:nil, cyclical:nil, after:nil, needs_moon:nil, cast:nil, expire:nil, skill:nil, cast_message:nil, before:nil, prep_message:nil)
@name = name
@abbrev = abbrev
@min_prep = min_prep
@cyclical = cyclical
@after = after
@needs_moon = needs_moon
@cast = cast
@expire = expire
@skill = skill
@cast_message = cast_message
@before = before
@prep_message = prep_message
end
end
@@Spells = {
'EY' => SpellData.new(name: 'Essence of Yew')
}
class SpellXXX
attr_accessor :mana, :cambrinth, :snap, :symbiosis
def initialize(abbrev:nil, spell_data:nil, mana:nil, cambrinth:nil, snap:false, symbiosis:nil)
if abbrev
@data = DRC.Spells[abbrev.upcase] || DRC.Spells.find { |key, _val| /^#{abbrev}/i =~ key }.last
else
@data = spell_data
end
fail(ArgumentError, 'Spell requires a known name or spell data object') unless @data
end
def method_missing(method, *args, &block)
@data.__send__ method, *args, &block
end
end
# windows only I believe.
def beep
echo("\a")
end
module_function :beep
def dispose_trash(item)
return if item.nil?
trashcan = DRRoom.room_objs
.map { |long_name| get_noun(long_name) }
.find { |obj| UserVars.trash_storage.include?(obj) }
if trashcan == 'gloop'
trashcan = 'bucket' if DRRoom.room_objs.include? 'bucket of viscous gloop'
trashcan = 'cauldron' if DRRoom.room_objs.include? 'small bubbling cauldron of viscous gloop'
end
if trashcan
bput("put my #{item} in #{trashcan}", '^You drop')
else
fput "drop my #{item}"
end
end
module_function :dispose_trash
def bind_wound(part, person = 'my')
bput("tend #{person} #{part}", 'You work carefully at tending', 'That area has already been tended to', 'That area is not bleeding')
waitrt?
end
module_function :bind_wound
def unwrap_wound(part)
waitrt?
case bput("unwrap my #{part}", 'You unwrap your bandages') # Are there other messages?
when $FAILED_COMMAND
pause 5
bind_wound(part)
end
waitrt?
end
module_function :unwrap_wound
def get_wealth
fput 'wealth'
wealth = matchfind '\\(? copper Kronars\\)\\.', 'No Kronars?'
wealth == '.' ? 0 : wealth.to_i
end
module_function :get_wealth
def ensure_copper_on_hand(copper)
wealth = get_wealth
return if wealth >= copper
walk_to 1900
withdrawals = minimize_coins(copper)
withdrawals.each { |amount| fput "withdraw #{amount}" }
end
module_function :ensure_copper_on_hand
def find_empty_room(search_rooms, idle_room, predicate = true)
loop do
search_rooms.each do |room_id|
walk_to(room_id)
return if checkpcs.nil? && predicate.call
end
walk_to(idle_room)
pause 30
end
end
module_function :find_empty_room
end
UserVars.trash_storage = %w(bin gloop barrel bucket)