forked from elanthia-online/dr-scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathastrology.lic
More file actions
751 lines (657 loc) · 24.1 KB
/
astrology.lic
File metadata and controls
751 lines (657 loc) · 24.1 KB
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
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
# frozen_string_literal: true
=begin
Documentation: https://elanthipedia.play.net/Lich_script_repository#astrology
=end
# Automates astrology training for Moon Mage characters.
#
# Handles observation, prediction, and ritual cycles based on
# user YAML configuration.
#
# @note Requires Moon Mage guild membership.
#
# @note Required settings keys:
# - `astrology_training` [Array<String>] training methods to cycle
# - `have_telescope` [Boolean] whether character owns a telescope
# - `telescope_name` [String] telescope item noun
#
# @note Optional settings keys:
# - `astral_plane_training` [Hash, nil] astral plane config
# - `divination_tool` [Hash, nil] divination tool config
# - `divination_bones_storage` [Hash, nil] bones storage config
# - `astrology_force_visions` [Boolean] force predict future
# - `astrology_use_full_pools` [Boolean] require pool level 10
# - `astrology_pool_target` [Integer] minimum pool level for prediction
#
# @example Basic usage
# ;astrology
#
# @example Run Read the Ripples only
# ;astrology rtr
#
# @see DRCMM Moon Mage operations for observation
# @see DRCA Arcana operations for buff management
# @see https://elanthipedia.play.net/Lich_script_repository#astrology
class Astrology
# Maps game output patterns to numeric understanding levels (0-10)
# for tracking celestial prediction pool progress.
#
# @example Matches
# "You have a feeble understanding of the celestial influences over" => 1
# "You have a complete understanding of the celestial influences over" => 10
#
# @see #check_pools
POOL_PATTERNS = {
/You have no understanding of the celestial influences over/ => 0,
/You have a feeble understanding of the celestial influences over/ => 1,
/You have a weak understanding of the celestial influences over/ => 2,
/You have a fledgling understanding of the celestial influences over/ => 3,
/You have a modest understanding of the celestial influences over/ => 4,
/You have a decent understanding of the celestial influences over/ => 5,
/You have a significant understanding of the celestial influences over/ => 6,
/You have a potent understanding of the celestial influences over/ => 7,
/You have an insightful understanding of the celestial influences over/ => 8,
/You have a powerful understanding of the celestial influences over/ => 9,
/You have a complete understanding of the celestial influences over/ => 10
}.freeze
# Start pattern for predict state all output capture.
PREDICT_STATE_START = /celestial influences/.freeze
# End pattern for predict state all output capture.
PREDICT_STATE_END = /Roundtime/i.freeze
# Patterns indicating observation completed (success or acceptable completion).
# Used by non-telescope observation to determine if done.
#
# @example Matches
# "You learned something useful from your observation of Katamba."
# "Although you were nearly overwhelmed ..., you still learned more of the future."
#
# @see #observe_routine
OBSERVE_SUCCESS_PATTERNS = [
'While the sighting', # Partial success
'You learned something useful', # Full success
'Clouds obscure', # Weather blocking (observation done)
'You learn nothing', # Circle too low (observation done)
'too close to the sun', # Solar conjunction (observation done)
'too faint for you', # Telescope needed (observation done)
'below the horizon', # Body not visible (observation done)
'You have not pondered', # Observation cooldown (done, no XP)
'You are unable to make use', # Cooldown followup (done, no XP)
'you still learned more' # Nearly overwhelmed but still learned
].freeze
# Perceive targets for attunement training.
PERCEIVE_TARGETS = ['', 'mana', 'moons', 'planets', 'psychic', 'transduction', 'perception', 'moonlight'].freeze
# Maximum recursion depth for check_heavens retries on daylight/bad-search.
MAX_HEAVENS_RETRIES = 3
# Maximum recursion depth for observe_routine error recovery (telescope).
MAX_OBSERVE_RETRIES = 5
# Maximum iterations for non-telescope observation before giving up.
MAX_OBSERVE_ITERATIONS = 20
# Loads settings, parses arguments, and sets up instance variables.
# Does not run training -- call {#run} to start.
#
# @return [void]
def initialize
unless DRStats.moon_mage?
Lich::Messaging.msg('bold', 'Astrology: This script is only for Moon Mages. Exiting.')
exit
end
@settings = get_settings
arg_definitions = [
[],
[{ name: 'rtr', regex: /rtr/i, description: 'Runs Read the Ripples' }]
]
@args = parse_args(arg_definitions)
# Make sure that our Circle is up-to-date -- avoid using stale data for new characters who joined the guild
DRC.bput('info', 'Circle:') if DRStats.circle.zero?
@equipment_manager = EquipmentManager.new
constellations_data = get_data('constellations')
@constellations = constellations_data.constellations
@finished_messages = constellations_data.observe_finished_messages
@success_messages = constellations_data.observe_success_messages
@injured_messages = constellations_data.observe_injured_messages
@force_visions = @settings.astrology_force_visions
@divination_tool = @settings.divination_tool
@divination_bones_storage = @settings.divination_bones_storage
@have_telescope = @settings.have_telescope
@telescope_storage = @settings.telescope_storage
@telescope_name = @settings.telescope_name
@astral_place_source = @settings.astral_plane_training&.[]('train_source')
@astral_plane_destination = @settings.astral_plane_training&.[]('train_destination')
@prediction_pool_target = @settings.astrology_use_full_pools ? 10 : @settings.astrology_pool_target
@rtr_data = nil
@prediction_skills = @settings.astrology_prediction_skills.dup
debug_log("Flags['rtr-expire'].nil? #{Flags['rtr-expire'].nil?}")
debug_log("Flags['rtr-expire'] = #{Flags['rtr-expire']}")
end
# Runs the astrology training or Read the Ripples routine.
#
# @return [void]
def run
do_buffs(@settings)
if @args.rtr
check_ripples(@settings)
else
train_astrology(@settings)
end
end
# Casts configured astrology buff spells, separating RtR data for later use.
#
# @param settings [OpenStruct, nil] user settings from get_settings
# @return [void]
def do_buffs(settings)
return unless settings
return unless settings.waggle_sets['astrology']
empty_hands
buffs = settings.waggle_sets['astrology']
@rtr_data = buffs.select { |spell| spell.eql?('Read the Ripples') }
.values
.first
buffs = buffs.reject { |spell| spell.eql?('Read the Ripples') }
# Check if all buffs are already active
all_buffs_active = buffs.all? do |_, value|
value['use_auto_mana'] && DRSpells.active_spells.include?(value['name'])
end
if all_buffs_active
debug_log('All buffs are already active.')
return
end
buffs.each_value do |value|
next unless value['use_auto_mana']
DRCA.check_discern(value, settings)
end
buffs = buffs.reject { |_, value| DRSpells.active_spells.include?(value['name']) }
DRCA.cast_spells(buffs, settings) unless buffs.empty?
end
# Observes the heavens and returns visible celestial bodies within circle range.
#
# @return [Array<Hash>, nil] visible body data hashes, or nil if indoors
def visible_bodies
result = []
all_bodies = @constellations
case DRCMM.observe('heavens')
when "That's a bit hard to do while inside"
Lich::Messaging.msg('bold', 'Astrology: Must be outdoors to observe sky. Exiting.')
return nil
end
loop do
line = get?
break unless line
break if line =~ /^Roundtime/i
result << all_bodies.find { |body| /\b#{Regexp.escape(body['name'].split.last)}\b/i =~ line && line !~ /below the horizon/ }
end
result.compact.select { |data| data['circle'] <= DRStats.circle }
end
# Trains Attunement by perceiving all targets if XP is below threshold.
#
# @return [void]
def check_attunement
return if DRSkill.getxp('Attunement') > 30
PERCEIVE_TARGETS.each do |target|
DRC.bput("perceive #{target}", 'roundtime')
waitrt?
end
end
# Parses predict state output and returns pool understanding levels.
#
# @return [Hash{String => Integer}] pool name to level (0-10)
def check_pools
pools = {
'lore' => 0,
'magic' => 0,
'survival' => 0,
'offensive combat' => 0,
'defensive combat' => 0,
'future events' => 0
}
lines = Lich::Util.issue_command(
'predict state all',
PREDICT_STATE_START,
PREDICT_STATE_END,
timeout: 10,
usexml: false,
silent: true,
quiet: true
)
if lines.nil?
Lich::Messaging.msg('bold', 'Astrology: Failed to capture predict state output. Using default pool values.')
waitrt?
return pools
end
lines.select! { |line| line =~ /celestial influences/ }
pools.each_key do |name|
matching_line = lines.find { |line| line =~ /#{Regexp.escape(name)}/ }
next unless matching_line
POOL_PATTERNS.each do |pattern, value|
if pattern =~ matching_line
pools[name] = value
break
end
end
end
debug_log("pools: #{pools}")
waitrt?
pools
end
# Studies the sky to build future events pool, then predicts an event.
#
# @param pools [Hash{String => Integer}] current pool levels
# @return [void]
def check_events(pools)
waitrt?
prev_size = pools['future events']
start_time = Time.now
timeout = 10
until Time.now - start_time > timeout
result = DRCMM.study_sky
waitrt?
return if result =~ /You are unable to sense additional information|detect any portents/
new_pools = check_pools
break if new_pools['future events'] == prev_size
break if new_pools['future events'] == 10
prev_size = new_pools['future events']
end
DRCMM.predict('event')
end
# Predicts the weather for training XP.
#
# @return [void]
def check_weather
debug_log('Checking the weather.')
DRCMM.predict('weather')
waitrt?
end
# Checks whether Read the Ripples is active, polling briefly for lag.
#
# @return [Boolean] true if RtR is currently active
def rtr_active?
# DRSpells.active_spells sometimes shows RtR as inactive even though it is active
100.times do
pause 0.01
return true if DRSpells.active_spells.include?('Read the Ripples')
end
false
end
# Casts Read the Ripples and observes bodies as visions appear.
#
# @param settings [OpenStruct] user settings for spell casting
# @return [void]
def check_ripples(settings)
unless @rtr_data
Lich::Messaging.msg('bold', 'Astrology: No Read the Ripples spell data configured. Skipping ripples check.')
return
end
unless settings
Lich::Messaging.msg('bold', 'Astrology: No settings provided to check_ripples. Skipping.')
return
end
if Flags['rtr-expire'] == false
debug_log('RtR expire flag indicates spell recently expired. Skipping.')
return
end
empty_hands
DRCA.cast_spell(@rtr_data, settings)
perc_time = Time.now - 61
Flags.add('rtr-expire', get_data('spells').spell_data['Read the Ripples']['expire']) if rtr_active?
get_telescope
while rtr_active?
line = get?
if perc_time + 60 < Time.now
DRCA.perc_mana
perc_time = Time.now
end
res = @constellations.find { |body| /As your consciousness drifts amongst the currents of Fate, .* #{Regexp.escape(body['name'])}/i =~ line }
observe_routine(res['name']) unless res.nil?
end
store_telescope
nil
end
# Trains via astral plane travel for high-circle Moon Mages.
#
# @return [void]
def check_astral
return unless DRStats.circle > 99
unless @astral_place_source
debug_log('No astral_plane_training train_source configured. Skipping.')
return
end
unless @astral_plane_destination
debug_log('No astral_plane_training train_destination configured. Skipping.')
return
end
if !UserVars.astral_plane_exp_timer.nil? && Time.now - UserVars.astral_plane_exp_timer < 3600
debug_log('Astral plane training on cooldown. Skipping.')
return
end
DRC.wait_for_script_to_complete('bescort', ['ways', @astral_plane_destination])
UserVars.astral_plane_exp_timer = Time.now
DRC.wait_for_script_to_complete('bescort', ['ways', @astral_place_source])
Lich::Messaging.msg('plain', 'Astrology: Completed astral plane training.')
end
# Stores telescope if held, then empties both hands via EquipmentManager.
#
# @return [void]
def empty_hands
DRCMM.store_telescope?(@telescope_name, @telescope_storage) if DRCI.in_hands?(@telescope_name)
@equipment_manager.empty_hands
end
# Aligns and predicts for each pool that meets the target threshold.
#
# @param pools [Hash{String => Integer}] current pool levels
# @return [void]
def predict_all(pools)
skillset_to_pool = {
'offensive combat' => @prediction_skills['offense'],
'defensive combat' => @prediction_skills['defense'],
'magic' => @prediction_skills['magic'],
'survival' => @prediction_skills['survival'],
'lore' => @prediction_skills['lore'],
'future events' => 'future events'
}
pools.reject { |_skill, size| size < @prediction_pool_target }
.each_key do |skill|
break if DRSkill.getxp('Astrology') > 30
align_routine(skillset_to_pool[skill])
end
end
# Observes the best available celestial body, using telescope if configured.
#
# @param depth [Integer] recursion depth for daylight retry limiting
# @return [void]
def check_heavens(depth: 0)
if depth > MAX_HEAVENS_RETRIES
Lich::Messaging.msg('bold', 'Astrology: Max observation retries reached. Aborting check_heavens.')
return
end
empty_hands
vis_bodies = visible_bodies
unless vis_bodies
Lich::Messaging.msg('bold', 'Astrology: Could not observe visible bodies. Aborting check_heavens.')
return
end
night = vis_bodies.find { |body| body['constellation'] }
best_eye_data = vis_bodies
.select { |data| @have_telescope || !data['telescope'] }
.max_by { |data| [data['pools'].values.compact.size, data['circle']] }
unless best_eye_data
Lich::Messaging.msg('bold', 'Astrology: No observable celestial bodies found. Aborting check_heavens.')
return
end
debug_log("best_eye_data = #{best_eye_data}")
waitrt?
if @have_telescope
observe_with_telescope(best_eye_data, night, depth)
else
observe_without_telescope(best_eye_data, depth)
end
pause 2
waitrt?
end
# Checks if an observation result indicates completion.
# Uses substring matching for both array and string results.
#
# @param result [Array<String>, String, nil] observation result
# @return [Boolean] true if observation is finished
def check_observation_finished?(result)
return false unless result
finished_pattern = Regexp.union(@finished_messages)
if result.is_a?(Array)
result.any? { |line| line.match?(finished_pattern) }
else
result.match?(finished_pattern)
end
end
# Checks if an observation result indicates success.
# Uses substring matching for both array and string results.
#
# @param result [Array<String>, String, nil] observation result
# @return [Boolean] true if observation was successful
def check_observation_success?(result)
return false unless result
if result.is_a?(Array)
result.any? { |line| @success_messages.any? { |msg| line.include?(msg) } }
else
@success_messages.any? { |msg| result.include?(msg) }
end
end
# Stores telescope, heals at safe room, walks back, and re-buffs.
#
# @return [void]
def get_healed
store_telescope
snapshot = Room.current.id
DRC.wait_for_script_to_complete('safe-room', ['force'])
DRCT.walk_to(snapshot)
do_buffs(@settings)
get_telescope
end
# Observes a celestial body, handling telescope and error recovery.
#
# @param body [String] celestial body name
# @param depth [Integer] recursion depth for telescope error recovery
# @return [String, Array<String>, nil] raw game output from the observation
def observe_routine(body, depth: 0)
if depth > MAX_OBSERVE_RETRIES
Lich::Messaging.msg('bold', 'Astrology: Max observe retries reached. Aborting observation.')
return nil
end
Flags.add('bad-search', 'is foiled by the (daylight|darkness)', 'turns up fruitless')
begin
if @have_telescope
case DRCMM.center_telescope(body)
when /Center what/
get_telescope
return observe_routine(body, depth: depth + 1)
when /open it/
DRC.bput('open my telescope', 'extend your telescope')
return observe_routine(body, depth: depth + 1)
when /The pain is too much/, /Your vision is too fuzzy/
get_healed
return observe_routine(body, depth: depth + 1)
end
result = DRCMM.peer_telescope
injuries, closed = check_telescope_result(result)
if injuries
get_healed
return observe_routine(body, depth: depth + 1)
elsif closed
DRC.bput('open my telescope', 'extend your telescope')
return observe_routine(body, depth: depth + 1)
end
result
else
DRCMM.observe(body)
end
end
end
# Checks telescope peer result for injuries or closed telescope.
#
# @param result [Array<String>, String] telescope peer output
# @return [Array(Boolean, Boolean)] [injuries, closed]
def check_telescope_result(result)
injuries = false
closed = false
if result.is_a?(Array)
injuries = result.any? { |line| line.match?(Regexp.union(@injured_messages)) }
closed = result.any? { |line| line.start_with?("You'll need to open it") }
else
case result
when /The pain is too much/, /Your vision is too fuzzy/
injuries = true
when /open it/
closed = true
end
end
[injuries, closed]
end
# Aligns to a skill and predicts using configured divination method.
#
# @param skill [String, nil] prediction skill name, or 'future events'
# @return [void]
def align_routine(skill = nil)
debug_log("align_routine called with skill: #{skill.inspect}")
if skill == 'future events'
DRCMM.predict('event')
return
end
DRCMM.align(skill)
waitrt?
if !@divination_bones_storage.nil? && !@divination_bones_storage.empty? && @force_visions != true
DRCMM.roll_bones(@divination_bones_storage)
elsif !@divination_tool.nil? && !@divination_tool.empty? && @force_visions != true
DRCMM.use_div_tool(@divination_tool)
else
DRCMM.predict('future')
end
waitrt?
pause
pause 0.5 while stunned?
DRC.fix_standing
end
# Main training loop that cycles through configured training tasks.
#
# @param settings [OpenStruct] user settings
# @return [void]
def train_astrology(settings)
loop do
unless settings
Lich::Messaging.msg('bold', 'Astrology: No settings provided. Exiting training loop.')
return
end
unless settings.astrology_training.is_a?(Array)
Lich::Messaging.msg('bold', 'Astrology: astrology_training is not an array. Exiting training loop.')
return
end
if settings.astrology_training.none?
Lich::Messaging.msg('bold', 'Astrology: astrology_training is empty. Exiting training loop.')
return
end
settings.astrology_training.each do |task|
break if DRSkill.getxp('Astrology') >= 32
case task
when 'ways'
check_astral
when 'observe'
check_heavens
when 'rtr'
check_ripples(settings)
when 'weather'
check_weather
when 'events'
check_events(check_pools)
when 'attunement'
check_attunement
else
Lich::Messaging.msg('bold', "Astrology: Unknown training task '#{task}'. Skipping.")
end
end
if DRSkill.getxp('Astrology') >= 32
Lich::Messaging.msg('plain', 'Astrology: Reached target Astrology XP. Training complete.')
break
else
predict_all(check_pools)
DRCMM.predict('analyze')
waitrt?
end
end
end
private
# Retrieves telescope from storage if configured.
#
# @return [Boolean, nil] result of get_telescope?, or nil if no telescope
def get_telescope
DRCMM.get_telescope?(@telescope_name, @telescope_storage) if @have_telescope
end
# Stores telescope to storage if configured.
#
# @return [Boolean, nil] result of store_telescope?, or nil if no telescope
def store_telescope
DRCMM.store_telescope?(@telescope_name, @telescope_storage) if @have_telescope
end
# Logs a debug message prefixed with "Astrology:" if debug mode is enabled.
#
# @param msg [String] message to log
# @return [void]
def debug_log(msg)
Lich::Messaging.msg('plain', "Astrology: #{msg}") if UserVars.astrology_debug
end
# Checks if an observe result matches any success pattern.
#
# @param observe_result [String, nil] raw observe output
# @return [Boolean] true if observation succeeded
def observe_success?(observe_result)
OBSERVE_SUCCESS_PATTERNS.any? { |pattern| observe_result&.include?(pattern) }
end
# Telescope observation path for check_heavens.
#
# @param best_eye_data [Hash] best naked-eye body data
# @param night [Hash, nil] a constellation body if nighttime, nil otherwise
# @param depth [Integer] current recursion depth
# @return [void]
def observe_with_telescope(best_eye_data, night, depth)
things_to_try = @constellations.select do |data|
data['telescope'] &&
data['circle'] <= DRStats.circle &&
data['circle'] > best_eye_data['circle'] &&
(night || !data['constellation']) &&
data['pools'].values.compact.size > best_eye_data['pools'].values.compact.size
end
things_to_try << best_eye_data
things_to_try.sort_by! { |data| -data['circle'] }
debug_log("things_to_try = #{things_to_try}")
begin
things_to_try.find do |data|
result = nil
finished = nil
get_telescope
MAX_OBSERVE_ITERATIONS.times do
if Flags['bad-search'] == 'is foiled by the daylight'
return check_heavens(depth: depth + 1)
end
if Flags['bad-search'] == 'turns up fruitless'
Flags.reset('bad-search')
next
end
result = observe_routine(data['name'])
break if result.nil?
finished = check_observation_finished?(result)
debug_log("result: #{result}")
debug_log("finished_messages: #{Regexp.union(@finished_messages)}")
debug_log("finished: #{finished}")
break if finished
end
check_observation_success?(result)
end
ensure
store_telescope
end
end
# Non-telescope observation path for check_heavens.
#
# @param best_eye_data [Hash] best naked-eye body data
# @param depth [Integer] current recursion depth
# @return [void]
def observe_without_telescope(best_eye_data, depth)
MAX_OBSERVE_ITERATIONS.times do
result = observe_routine(best_eye_data['name'])
break if observe_success?(result)
if Flags['bad-search']
return check_heavens(depth: depth + 1)
end
end
end
end
before_dying do
Flags.delete('bad-search')
Flags.delete('rtr-expire')
settings = get_settings
telescope_storage = settings.telescope_storage
telescope_name = settings.telescope_name
divination_tool = settings.divination_tool
if DRCI.in_hands?(telescope_name)
DRCMM.store_telescope?(telescope_name, telescope_storage)
end
if divination_tool && divination_tool['name'] && DRCI.in_hands?(divination_tool['name'])
DRCMM.store_div_tool?(divination_tool)
end
end
# Call this last to avoid the need for forward declarations
Astrology.new.run