diff --git a/bescort.lic b/bescort.lic
index 70b8fb3105..2bac60a369 100644
--- a/bescort.lic
+++ b/bescort.lic
@@ -237,6 +237,7 @@ class Bescort
@settings = get_settings
@equipment_manager = EquipmentManager.new(@settings)
+ @flying_mount = @settings.flying_mount
pause
@@ -323,7 +324,7 @@ class Bescort
mode = mode.downcase
case mode
when 'mount'
- DRC.bput("get my #{type}", /You get/, /You pick up/, /You are already holding/, /What were you referring/)
+ DRCI.get_item?(type)
case type
when /broom|dirigible/i
case DRC.bput("mount my #{type}", /You mount your/, /You are already mounted/, /What were you referring/)
@@ -349,15 +350,14 @@ class Bescort
case type
when /broom|dirigible/i
DRC.bput('dismount', /Your .* floats down to the ground/, /You climb off/)
- @equipment_manager.empty_hands
when /carpet|rug/i
DRC.bput('dismount', /Your .* floats down to the ground/, /You climb off/)
DRC.bput("roll #{type}", /You roll up/, /You can't roll/)
- DRC.bput("stow my #{type}", /You put/, /You pick up/, /Stow what?/)
else
DRC.message("#{type} is not a valid type of flying mount.")
exit
end
+ DRCI.put_away_item?(type)
end
end
@@ -468,18 +468,16 @@ class Bescort
manual_go2(start_room)
move('go stream bank')
# Once in the stream then you're in a safe room, get mount or remove gear.
- flying_mount = @settings.flying_mount
@equipment_manager.empty_hands
- have_changed_gear = flying_mount ? false : @equipment_manager.wear_equipment_set?('swimming')
- if flying_mount
- use_flying_mount(flying_mount, 'mount')
+ have_changed_gear = @flying_mount ? false : @equipment_manager.wear_equipment_set?('swimming')
+ if @flying_mount
+ use_flying_mount(@flying_mount, 'mount')
move(moveset.first) # mount travels all three rooms at once
else
moveset.each { |dir| swim(dir) }
end
- use_flying_mount(flying_mount, 'dismount') if flying_mount
+ use_flying_mount(@flying_mount, 'dismount') if @flying_mount
# While in the stream then you're in a safe room, dismount or wear gear.
- @equipment_manager.empty_hands
@equipment_manager.wear_equipment_set?('standard') if have_changed_gear
move('go stream bank')
# You're now among cave trolls!
@@ -1076,13 +1074,12 @@ class Bescort
end
def faldesu(mode)
- flying_mount = @settings.flying_mount
unless mode =~ /haven|crossing/i
echo 'You must specify haven or crossing for traversing the faldesu river'
exit
end
- if flying_mount
+ if @flying_mount
swim_faldesu(mode =~ /haven/i)
return
end
@@ -1108,40 +1105,45 @@ class Bescort
path = mode == 'shard' ? $ICE_PATH_SHARD : $ICE_PATH_HIB
@equipment_manager.empty_hands
- settings = get_settings
- footwear = settings.footwear
+ footwear = @settings.footwear
move_fast = false
footwear_removed = false
skates_worn = false
- # If the footwear setting has been defined then respect that
- # and only try to remove it. If you're not wearing this item
- # then obviously nothing on your feet will be removed.
- # You might:
- # - have incorrect yaml
- # - put something else on (or nothing on)
- # - already wearing your skates
- if footwear
- if DRCI.remove_item?(footwear)
- footwear_removed = true
- DRCI.put_away_item?(footwear)
+ if @flying_mount
+ move_fast = true
+ use_flying_mount(@flying_mount, 'mount', 'glide')
+ path = mode == 'shard' ? %w[se se sw sw se] : %w[nw ne ne nw sw]
+ else
+ # If the footwear setting has been defined then respect that
+ # and only try to remove it. If you're not wearing this item
+ # then obviously nothing on your feet will be removed.
+ # You might:
+ # - have incorrect yaml
+ # - put something else on (or nothing on)
+ # - already wearing your skates
+ if footwear
+ if DRCI.remove_item?(footwear)
+ footwear_removed = true
+ DRCI.put_away_item?(footwear)
+ end
end
- end
- # If you have some skates then try to get and wear them.
- # Note, if you're already wearing the skates then we won't
- # be able to "get" them, and that's why the attempt to wear
- # is not conditional upon you getting them to your hands.
- if DRCI.exists?('skates')
- DRCI.get_item?('skates')
- if DRCI.wear_item?('skates')
- skates_worn = true
- else
- DRCI.put_away_item?('skates')
+ # If you have some skates then try to get and wear them.
+ # Note, if you're already wearing the skates then we won't
+ # be able to "get" them, and that's why the attempt to wear
+ # is not conditional upon you getting them to your hands.
+ if DRCI.exists?('skates')
+ DRCI.get_item?('skates')
+ if DRCI.wear_item?('skates')
+ skates_worn = true
+ else
+ DRCI.put_away_item?('skates')
+ end
end
- end
- move_fast = skates_worn
+ move_fast = skates_worn
+ end
# Despite our best efforts, if bescort starts moving you fast
# and the game gives you warnings to slow down, SLOW DOWN!
@@ -1174,6 +1176,10 @@ class Bescort
DRCI.get_item?(footwear)
DRCI.wear_item?(footwear)
end
+
+ if @flying_mount
+ use_flying_mount(@flying_mount, 'dismount')
+ end
end
def swim(dir)
@@ -1183,13 +1189,12 @@ class Bescort
end
def swim_faldesu(north)
- flying_mount = @settings.flying_mount
start = north ? 1375 : 473
manual_go2(start)
moveset = north ? %w[north northwest northeast] : %w[south southwest southeast]
move 'dive river'
- if flying_mount
- use_flying_mount(flying_mount, 'mount')
+ if @flying_mount
+ use_flying_mount(@flying_mount, 'mount')
if north
move n
move nw
@@ -1198,8 +1203,7 @@ class Bescort
move sw
end
move 'go bridge'
- use_flying_mount(flying_mount, 'dismount')
- @equipment_manager.empty_hands
+ use_flying_mount(@flying_mount, 'dismount')
else
swim(moveset[0]) while XMLData.room_exits.include?(moveset[0])
swim(moveset[1]) while XMLData.room_exits.include?('east')
@@ -1477,9 +1481,8 @@ class Bescort
end
def segoltha(mode)
- flying_mount = @settings.flying_mount
@equipment_manager.empty_hands
- have_changed_gear = flying_mount ? false : @equipment_manager.wear_equipment_set?('swimming')
+ have_changed_gear = @flying_mount ? false : @equipment_manager.wear_equipment_set?('swimming')
move_count = 0
if mode =~ /^n/i
dir_of_travel = 'north'
@@ -1495,8 +1498,8 @@ class Bescort
exit
end
- if flying_mount
- use_flying_mount(flying_mount, 'mount', 'skim')
+ if @flying_mount
+ use_flying_mount(@flying_mount, 'mount', 'skim')
if dir_of_travel == 'south'
move 'go bank'
move 'west'
@@ -1511,7 +1514,7 @@ class Bescort
move 'east'
move 'go slope'
end
- use_flying_mount(flying_mount, 'dismount')
+ use_flying_mount(@flying_mount, 'dismount')
return
end
@@ -1640,7 +1643,7 @@ class Bescort
DRCA.release_cyclics
unless DRCA.cast_spell({ 'abbrev' => 'rezz',
'mana' => 5,
- 'cyclic' => true }, get_settings)
+ 'cyclic' => true }, @settings)
echo('Failed to cast Resurrection! Try again or use the puzzle to enter.')
exit
end
@@ -2014,7 +2017,6 @@ class Bescort
def get_fare?(amount, town, room)
return false unless @settings.bescort_fare_handling
- settings = get_settings
echo 'GETTING MONEY, YOU SLOB.'
echo "Heading to #{town} for public transportation fare"
pause 1
@@ -2025,7 +2027,7 @@ class Bescort
echo 'You might be a necromancer! Get some money manually!'
return false
end
- settings.hometown = town
+ @settings.hometown = town
succeeded = false
DRCM.minimize_coins(amount).each { |each_amount| succeeded = DRCM.get_money_from_bank(each_amount, settings) }
echo "Put some fare money in the #{town} bank!" unless succeeded
diff --git a/circlecheck.lic b/circlecheck.lic
index abec25212c..ac22ea55e1 100644
--- a/circlecheck.lic
+++ b/circlecheck.lic
@@ -339,7 +339,7 @@ $GuildReqs = {
},
hard_reqs: ['Evasion', 'Parry Ability', 'Expertise', 'Inner Fire', 'Tactics'],
- restricted: ['Sorcery', 'Thievery', 'Utility', 'Targeted Magic', 'Offhand Weapon']
+ restricted: ['Sorcery', 'Thievery', 'Targeted Magic', 'Offhand Weapon']
},
'Necromancer' => {
diff --git a/combat-trainer.lic b/combat-trainer.lic
index 7accbfb68c..f824e1c39f 100644
--- a/combat-trainer.lic
+++ b/combat-trainer.lic
@@ -84,16 +84,18 @@ class SetupProcess
private
- def armor_hysteresis?
+ def armor_hysteresis?(game_state)
return false unless @armor_hysteresis
return false if @cycle_armors.keys.any? { |skill| DRSkill.getxp(skill) < 25 }
all_swap_pieces = @cycle_armors.keys.map { |armortype| @cycle_armors[armortype] }.flatten
if @cycle_armors.keys.all? { |skill| DRSkill.getxp(skill) > 32 }
if @last_worn_type != @default_armor && @cycle_armors.keys.include?(@default_armor)
+ game_state.sheath_whirlwind_offhand
@equipment_manager.worn_items(all_swap_pieces).each { |item| @equipment_manager.remove_item(item) }
@equipment_manager.wear_items(@equipment_manager.desc_to_items(@cycle_armors[@default_armor]))
@last_worn_type = @default_armor
+ game_state.wield_whirlwind_offhand
end
end
true
@@ -113,7 +115,7 @@ class SetupProcess
end
def check_armor_swap(game_state)
- return if armor_hysteresis?
+ return if armor_hysteresis?(game_state)
return if Time.now - @last_cycle_time < @cycle_armors_time
return if game_state.loaded
diff --git a/data/base-spells.yaml b/data/base-spells.yaml
index 33d9d10ade..b7dd0db984 100644
--- a/data/base-spells.yaml
+++ b/data/base-spells.yaml
@@ -142,6 +142,8 @@ prep_messages:
- Please don't do that here
- You cannot use the tattoo while maintaining the effort to stay hidden
- As you attempt to prepare the spell, a sense of overwhelming peace washes over you
+# You tried to target a spell but there is nothing left to face
+- There is nothing else to face
cast_messages:
- Converging in midair, angular ripples assemble a slender hexagonal rod whorled with faintly shifting fractals
diff --git a/dependency.lic b/dependency.lic
index fbbe2e33b4..4b17dea9c3 100644
--- a/dependency.lic
+++ b/dependency.lic
@@ -10,7 +10,7 @@ require 'ostruct'
require 'digest/sha1'
require 'monitor'
-$DEPENDENCY_VERSION = '1.6.6'
+$DEPENDENCY_VERSION = '1.7.1'
$MIN_RUBY_VERSION = '3.2.2'
no_pause_all
@@ -20,6 +20,7 @@ while Script.running?('repository')
echo("Repository is running, pausing for 10 seconds.")
pause 10
end
+
class Object
# IMPORT FUTURE LAWLZ
def itself
@@ -184,13 +185,21 @@ install = args.install
class ScriptManager
attr_reader :autostarts
- attr_accessor :developer, :ignore_dependency
def initialize(debug)
unless XMLData.game =~ /^DR/
echo("This script is not intended for usage with games other than Dragonrealms. Exiting now")
exit
end
+ unless LICH_VERSION.match?(/^5/)
+ _respond("*****************************************************************************")
+ _respond("* Unsupported Lich versions detected. *")
+ _respond("* Please see https://github.com/rpherbig/dr-scripts/wiki/First-Time-Setup *")
+ _respond("* For an update path. *")
+ _respond("*****************************************************************************")
+ exit
+ end
+
@debug = debug
@paste_bin_token = 'dca351a27a8af501a8d3123e29af7981'
@paste_bin_url = 'https://pastebin.com/api/api_post.php'
@@ -199,9 +208,7 @@ class ScriptManager
@status_branch = Settings['status_branch'] || 'master'
update_status_url
# Gating setting lich_url on lich version
- unless LICH_VERSION.match?(/^5/)
- @lich_url = 'https://api.github.com/repos/dragon-realms/dr-lich/git/trees/master'
- end
+
UserVars.autostart_scripts ||= []
UserVars.autostart_scripts.uniq!
UserVars.autostart_scripts = UserVars.autostart_scripts - ['dependency']
@@ -210,15 +217,10 @@ class ScriptManager
Settings['autostart'] = Settings['autostart'] - ['dependency']
# Setting Settings['lich_fork_sha'] to nil if using lich5. This setting isn't used anymore.
- if LICH_VERSION.match?(/^5/)
- Settings['lich_fork_sha'] = nil if Settings['lich_fork_sha']
- end
Settings['base_versions'] ||= {}
CharSettings['next_ruby_version_check_datetime'] = Time.now
- @developer = Settings['dependency-developer'] || false
- @ignore_dependency = Settings['ignore-dependency'] || false
@add_autos = []
@remove_autos = []
update_autostarts
@@ -228,11 +230,6 @@ class ScriptManager
@request_authorization = manage_github_token
@versions = nil
-
- # Gating lich fork code to non-lich5
- unless LICH_VERSION.match?(/^5/)
- @enable_fork = LICH_VERSION =~ /f/
- end
end
def updated_dependency?
@@ -307,8 +304,6 @@ class ScriptManager
def run_queue
validate_supported_ruby_version
- Settings['dependency-developer'] = @developer
- Settings['ignore-dependency'] = @ignore_dependency
Settings['status_repo'] = @status_repo
Settings['status_branch'] = @status_branch
update = false
@@ -323,16 +318,6 @@ class ScriptManager
@remove_autos.each { |script| Settings['autostart'].delete(script) }
@remove_autos = []
end
- # No lich fork with lich5
- unless LICH_VERSION.match?(/^5/)
- if @disable_fork
- stop_download_lich
- @disable_fork = nil
- elsif @enable_fork
- download_lich
- @enable_fork = nil
- end
- end
submit_thieving_update(*@thievery_queue.pop) unless @thievery_queue.empty?
submit_shop_update(@shop_update_queue.pop) unless @shop_update_queue.empty?
@@ -388,46 +373,12 @@ class ScriptManager
end
end
- unless LICH_VERSION.match?(/^5/)
- def queue_lich
- @enable_fork = true
- end
-
- def unqueue_lich
- @disable_fork = true
- end
-
- def download_lich
- return if @developer
-
- lich_data = make_request(@lich_url)['tree'].find { |data| data['path'] == 'lich.rbw' }
- if LICH_VERSION =~ /f/ && Settings['lich_fork_sha'] == lich_data['sha']
- echo('latest version of lich fork already downloaded.')
- return
- end
- blob = make_request(lich_data['url'])
- File.open('lich.rbw', 'w') { |file| file.print(Base64.decode64(blob['content'])) }
- Settings['lich_fork_sha'] = lich_data['sha']
- echo('New version of lich installed, please restart Lich.')
- end
-
- def stop_download_lich
- Settings['lich_fork_sha'] = nil
- end
- end
-
def download_script(filename, force = false)
return if filename.nil? || filename.empty?
- if filename == 'dependency.lic' && @ignore_dependency
- respond 'ignoring dependency download due to ignore_dependency setting'
- respond "use '#{$clean_lich_char}e check_dependency' to check the value."
- return
- end
echo("downloading:#{filename}") if @debug
info = get_file_status(filename)
return unless info
- return if @developer
return if get_versions[filename] == info['sha'] && !force
echo("info:#{info}") if @debug
@@ -480,8 +431,6 @@ class ScriptManager
end
def check_base_files
- return if @developer
-
verify_or_make_dir File.join(SCRIPT_DIR, 'profiles')
profile_tree_url = get_status['tree'].find { |element| element['path'] == 'profiles' }['url']
make_request(profile_tree_url)['tree']
@@ -496,8 +445,6 @@ class ScriptManager
end
def check_data_files
- return if @developer
-
verify_or_make_dir File.join(SCRIPT_DIR, 'data')
profile_tree_url = get_status['tree'].find { |element| element['path'] == 'data' }['url']
make_request(profile_tree_url)['tree']
@@ -873,9 +820,10 @@ class SlackbotManager
private
def register_slackbot
- return if @slackbot
return unless @username
+ return unless @slackbot.nil?
+ echo("Registering Slackbot")
custom_require.call('slackbot')
@slackbot = SlackBot.new
end
@@ -1622,7 +1570,7 @@ def verify_script(script_names)
.each do |name|
echo "Failed to find a script named '#{name}'"
echo "Please report this to "
- echo "or to Discord "
+ echo "or to Discord "
state = false
end
state
@@ -1665,11 +1613,6 @@ end
def replace_all
managed_scripts
.each do |script|
- if script == 'dependency.lic' && $manager.ignore_dependency
- respond 'ignoring replace dependency due to ignore_dependency setting'
- respond "use '#{$clean_lich_char}e check_dependency' to check the value."
- next
- end
new_name = "#{script}.#{Time.now.to_i}.bak"
respond "Renaming existing script #{script} to #{new_name}"
File.rename(File.join(SCRIPT_DIR, "#{script}"), File.join(SCRIPT_DIR, "#{new_name}"))
@@ -1711,73 +1654,6 @@ def stop_autostart(script_names)
end
end
-def set_dev_mode
- echo "Now turning dev mode on"
- $manager.developer = true
- echo "Developer mode now set to: #{$manager.developer}"
-end
-
-def unset_dev_mode
- echo "Now turning dev mode off"
- $manager.developer = false
- echo "Developer mode now set to: #{$manager.developer}"
-end
-
-def check_dev_mode
- echo "Developer mode set to: #{$manager.developer}"
-end
-
-def toggle_developer_mode
- echo "THIS METHOD IS NO LONGER USED. USE '#{$clean_lich_char}e set_dev_mode' and '#{$clean_lich_char}e unset_dev_mode'."
-end
-
-def ignore_dependency
- echo "Now ignoring dependency updates"
- $manager.ignore_dependency = true
- echo "ignore_dependency now set to: #{$manager.ignore_dependency}"
-end
-
-def unignore_dependency
- echo "Now processing dependency updates"
- $manager.ignore_dependency = false
- echo "ignore_dependency now set to: #{$manager.ignore_dependency}"
-end
-
-def check_dependency
- echo "ignore_dependency is set to: #{$manager.ignore_dependency}"
- echo "Use '#{$clean_lich_char}e ignore_dependency' and '#{$clean_lich_char}e unignore_dependency' to change."
-end
-
-unless LICH_VERSION.match?(/^5/)
- def use_lich_fork
- echo 'Now switching onto the DR lich fork...'
- start_script('repository', ['unset-lich-updatable'])
- pause 1 while Script.running?('repository')
- echo 'Turning off updates from main lich branch on go2...'
- start_script('repository', ['unset-updatable', 'go2'])
- $manager.queue_lich
- end
-
- def use_lich_main
- echo 'Now switching onto the lich mainline...'
- start_script('repository', ['set-lich-updatable'])
- pause 1 while Script.running?('repository')
-
- echo 'Turning updates from main lich branch on go2 back on...'
- start_script('repository', ['set-updatable', 'go2'])
- pause 1 while Script.running?('repository')
-
- start_script('repository', ['download-lich'])
- pause
- pause 1 while Script.running?('repository')
- echo('New version of lich installed, please restart Lich.')
- end
-
- def toggle_lich_fork
- echo "THIS METHOD IS NO LONGER USED. USE #{$clean_lich_char}e use_lich_fork and #{$clean_lich_char}e use_lich_main"
- end
-end
-
def set_custom_status_repo(repo, branch = 'master')
$manager.set_custom_status_repo(repo, branch)
end
@@ -1912,14 +1788,6 @@ $manager.check_data_files
$manager.start_scripts
$manager.make_map_edits
-if LICH_VERSION.match?(/^4/)
- _respond("*****************************************************************************")
- _respond("* Lich version 4 detected. This version of lich was deprecated in mid-2022. *")
- _respond("* Please see https://github.com/rpherbig/dr-scripts/wiki/First-Time-Setup *")
- _respond("* For an update path. *")
- _respond("*****************************************************************************")
-end
-
if $manager.updated_dependency?
echo('Update found for dependency.lic')
update_d
diff --git a/help-me.lic b/help-me.lic
index 7ef59b4fa2..7d672e5eb8 100644
--- a/help-me.lic
+++ b/help-me.lic
@@ -39,8 +39,6 @@ class HelpMe
message_body += "\n"
message_body += "Game Client: #{$frontend}"
message_body += "\n"
- message_body += "Dev Mode: #{$manager.developer}"
- message_body += "\n"
Dir[File.join(SCRIPT_DIR, 'profiles/*.yaml')].map { |item| File.path(item) }.select { |path| path.include?("#{checkname}-") }.each do |path|
message_body += "\n****" * 3
diff --git a/inventory-manager.lic b/inventory-manager.lic
index b299de26e8..ea65722643 100644
--- a/inventory-manager.lic
+++ b/inventory-manager.lic
@@ -2,7 +2,7 @@
Documentation: https://elanthipedia.play.net/Lich_script_repository#inventory-manager
=end
-custom_require.call(%w[common])
+custom_require.call(%w[common common-items])
class InventoryManager
def initialize
@@ -15,14 +15,17 @@ class InventoryManager
{ name: 'desc', regex: /\w+/i, optional: true, description: "Optional specific count by description. Use quotes for multiple word strings, i.e., \"purple pouch\"." }
],
[
-
{ name: 'save', regex: /save/i, description: "Save new or update current character's items to the database." },
{ name: 'vault_book', regex: /vault_book/i, optional: true, description: "Retrieves, reads, and save from vault book." },
{ name: 'vault_regular', regex: /vault_regular/i, optional: true, description: "Rummages your vault to save items NOTE: must be standing by your open vault." },
{ name: 'storage_box', regex: /storage_box/i, optional: true, description: "Rummages caravan storage box for items." },
{ name: 'family_vault', regex: /family_vault/i, optional: true, description: "Rummages your family vault to save items NOTE: must be standing by your open vault." },
{ name: 'register', regex: /register/i, optional: true, description: "Reads contents of deed register." },
- { name: 'eddy', regex: /eddy/i, optional: true, description: "Save the contents of an eddy (HE 436 Gift)." }
+ { name: 'eddy', regex: /eddy/i, optional: true, description: "Save the contents of an eddy (HE 436 Gift)." },
+ { name: 'scrolls', regex: /scrolls/i, optional: true, description: "Save spell scrolls tracked with sort-scrolls or stack-scrolls." },
+ { name: 'home', regex: /home/i, optional: true, description: "Save home inventory." },
+ { name: 'servant', regex: /servant/i, optional: true, description: "Save shadow servant inventory." },
+ { name: 'shop', regex: /shop/i, optional: true, description: "Save your Trader shop inventory." }
],
[
{ name: 'search', regex: /search/i, description: 'Start a search across all characters for specified item.' },
@@ -39,6 +42,8 @@ class InventoryManager
]
args = parse_args(arg_definitions)
+ @settings = get_settings
+ @inventory_ignores = @settings.inventory_manager_ignores
setup
@@ -51,9 +56,18 @@ class InventoryManager
elsif args.register
add_register_inv
elsif args.eddy
+ DRC.message('*WARNING: Character inventory includes items found within Eddy. Using both will duplicate Eddy items.')
add_eddy_inv
elsif args.storage_box
add_storage_box_inv
+ elsif args.scrolls
+ add_scrolls
+ elsif args.home
+ add_home
+ elsif args.servant
+ add_shadow_servant
+ elsif args.shop
+ add_trader_shop
elsif args.save
add_current_inv
elsif args.count
@@ -65,7 +79,7 @@ class InventoryManager
elsif args.list
list_character_inv(args.name)
else
- DRC.message 'Type ;inventory-manager help for a usage guide'
+ DRC.message('Type ;inventory-manager help for a usage guide')
end
end
@@ -78,300 +92,361 @@ class InventoryManager
end
if !File.exist?(@item_db_path)
- DRC.message "Something very wrong is occuring. You don't have a file to open and I can't create one!"
- DRC.message "item-db saves the file to: /lich/scripts/itemDB/inventory.yaml"
+ DRC.message("Something very wrong is occuring. You don't have a file to open and I can't create one!")
+ DRC.message("item-db saves the file to: /lich/scripts/itemDB/inventory.yaml")
exit
end
@item_data = OpenStruct.new(YAML.load_file(@item_db_path)).to_h
+
+ # The legacy version of this script posted character inventory without an identifier.
+ # Adding a version check and 'upgrade' mechanism to fix these entries, otherwise they would exist
+ # forever unless the entire character was deleted.
+ @version_string = 'version'.to_sym
+
+ version = @item_data[@version_string][0]
+
+ if version != '2.00'
+ @item_data.each do |_k, v|
+ v.each { |item|
+ next if valid_data_row(item)
+
+ item.concat(" (character)")
+ }
+ end
+ @item_data[@version_string] = ['2.00']
+ File.open(@item_db_path, 'w') { |file| file.write(@item_data.to_yaml(line_width: -1)) }
+ end
+ end
+
+ def valid_data_row(item)
+ if item.include?('(vault)') || item.include?('(register)') || item.include?('(eddy)') || item.include?('(caravan_box)') || item.include?('(Family)')
+ true
+ else
+ false
+ end
+ end
+
+ def get_item_data(inventory_type)
+ if @item_data[@active_character]
+ @item_data[@active_character] = @item_data[@active_character].select { |line| !line.include? "(#{inventory_type})" }
+ else
+ @item_data[@active_character] = []
+ end
+ end
+
+ def save_item_data(inventory_type)
+ DRC.message("Saving #{inventory_type} data for #{@active_character}!")
+ # .to_yaml limits to 80 chars by default, line_width: -1 bypasses this limit
+ File.open(@item_db_path, 'w') { |file| file.write(@item_data.to_yaml(line_width: -1)) }
end
def get_inv_count(desc)
count, closed = 0, 0
- # Counting all items in inventory
if desc.nil?
- DRC.bput('inv list', 'You have:')
- while (line = get)
- break if line =~ /INVENTORY HELP/i
-
+ # Counting all items in inventory
+ capture = Lich::Util.issue_command('inv list', /^You have:/)
+ capture.each do |line|
item = line.lstrip
+
+ next if item.empty?
+ next if item.start_with?(*@inventory_ignores)
+
count += 1
closed += 1 if item.match?(/(closed)/)
end
- DRC.message "You have #{count} items, #{closed} of which are (closed) containers."
+ DRC.message("You have #{count} items, #{closed} of which are (closed) containers.")
else
# Counting items matching the description, i.e., inv count pouch
- DRC.bput("inv search #{desc}", 'You rummage')
- while (line = get)
- break if line =~ /INVENTORY HELP/i
+ capture = Lich::Util.issue_command("inv search #{desc}", /rummage about your person/)
+ capture.each do |line|
+ item = line.lstrip
+
+ next if item.empty?
+ next if item.start_with?(*@inventory_ignores)
count += 1
end
- DRC.message "You have #{count} items matching \"#{desc}\"."
+ DRC.message("You have #{count} items matching \"#{desc}\".")
end
end
- def add_vault_book_inv
- if @item_data[@active_character]
- @item_data[@active_character] = @item_data[@active_character].select { |line| !line.include? 'vault' }
- else
- @item_data[@active_character] = []
+ def check_inventory(command, end_pattern, inventory_type, rummage_length = 0)
+ using_sorter = false
+ if Script.running?('sorter')
+ stop_script('sorter')
+ using_sorter = true
end
- unless DRCI.get_item_if_not_held?("vault book")
- DRC.message "Unable to find your vault book, exiting!"
- exit
- end
+ get_item_data(inventory_type)
- DRC.bput('read my vault book', 'Vault Inventory:')
- while (line = get)
- break if line =~ /The last note/i
+ capture = Lich::Util.issue_command(command, end_pattern)
- item = line.lstrip.concat(' (vault)')
- @item_data[@active_character] << item
- end
+ lines = capture
+ # when rummaging, this block splits the items, including the last two that are split by and instead of a comma
+ if command.start_with?("rummage")
+ container = capture[0]
+ lines = container[rummage_length, container.length - (rummage_length + 1)].split(",")
- DRCI.stow_item?("vault book")
+ last_item = lines.length - 1
- DRC.message("Saving vault data for #{@active_character}!")
- File.open(@item_db_path, 'w') { |file| file.write(@item_data.to_yaml) }
- end
+ last_two_items = lines[last_item].split(" and ")
- def add_current_inv
- if @item_data[@active_character]
- @item_data[@active_character] = @item_data[@active_character].select { |line| (line.include?('vault') || line.include?('eddy')) }
- else
- @item_data[@active_character] = []
+ lines[last_item] = last_two_items[0]
+ lines[last_item + 1] = last_two_items[1]
end
- DRC.bput('inv list', 'You have:')
- while (line = get)
- break if line =~ /Roundtime/i
-
+ container = ""
+ lines.each do |line|
item = line.lstrip
+
+ next if item.empty?
+ next if item.start_with?(*@inventory_ignores)
+
+ # if the item starts with a -, it's in a container
if item[0].eql? '-'
item[0] = ''
- item.concat(' (in container)')
- else
+ item.concat(" (in container - #{container})")
+ elsif inventory_type == 'character'
+ # We don't want the inventory_type here as it's extra noise, so we do a .to_s so container doesn't get updated by changing item later
+ container = (item.include?("eddy") ? "eddy" : item).to_s
item.concat(' (worn)')
+ elsif (command == 'read my vault book' || inventory_type == 'shadow_servant')
+ # When reading the vault book, items in a container are prefixed by 6 spaces
+ if line =~ /\s{6}(?:a|an|some) /
+ item.concat(" (in container - #{container})")
+ else
+ container = item.to_s
+ end
+ elsif inventory_type == 'home'
+ if !item.start_with?("Attached:")
+ item = clean_home_string(item)
+ container = item.to_s
+ else
+ item = clean_home_string(item)
+ item.concat(" (attached to #{container})")
+ end
end
+
+ item.concat(" (#{inventory_type})")
+
@item_data[@active_character] << item
end
- DRC.message "Saving inventory data for #{@active_character}!"
- File.open(@item_db_path, 'w') { |file| file.write(@item_data.to_yaml) }
- end
+ save_item_data(inventory_type)
- def add_register_inv
- if @item_data[@active_character]
- @item_data[@active_character] = @item_data[@active_character].select { |line| !line.include? 'register' }
- else
- @item_data[@active_character] = []
+ if using_sorter
+ start_script('sorter') unless Script.running?('sorter')
end
+ end
+
+ def clean_home_string(string)
+ # We remove the category by finding the : in the string, plus drop the period at the end
+ colon = string.index(":") + 2
+ string[colon..-2]
+ end
- case DRC.bput("get my register", 'You get', 'What were', 'You are already holding that')
- when 'What were'
- DRC.message "Unable to find your register, exiting!"
+ def add_vault_book_inv
+ unless DRCI.get_item_if_not_held?("vault book")
+ DRC.message("Unable to find your vault book, exiting!")
exit
end
- DRC.bput("turn my register to contents", 'You flip your deed register', 'already at the table of contents')
+ check_inventory("read my vault book", /^Vault Inventory:/, 'vault')
- case DRC.bput("read my register", 'Stored Deeds', 'stored any deeds in this register')
- when 'stored any deeds in this register'
- exit
- when 'Stored Deeds'
- while (line = get)
- break if line =~ /Currently stored/i
+ DRCI.stow_item?("vault book")
+ end
- item = line.lstrip.concat(' (register)')
- @item_data[@active_character] << item
- end
+ def add_current_inv
+ check_inventory("inv list", /^You have:/, 'character')
+ end
+
+ def add_register_inv
+ unless DRCI.get_item_if_not_held?("register")
+ DRC.message("Unable to find your register, exiting!")
+ exit
end
- DRC.bput('stow my register', 'You put')
+ DRC.bput("turn my register to contents", 'You flip your deed register', 'already at the table of contents')
+
+ check_inventory("read my register", /^Stored Deeds:/, 'register')
- DRC.message "Saving register data for #{@active_character}!"
- File.open(@item_db_path, 'w') { |file| file.write(@item_data.to_yaml) }
+ DRCI.stow_item?("register")
end
def add_eddy_inv
- if @item_data[@active_character]
- @item_data[@active_character] = @item_data[@active_character].select { |line| !line.include? 'eddy' }
- else
- @item_data[@active_character] = []
- end
+ checkInventory("inv eddy", /^Inside a/, 'eddy')
+ end
- using_sorter = false
- if Script.running?('sorter')
- stop_script('sorter')
- using_sorter = true
- end
+ def add_storage_box_inv
+ check_inventory("rummage storage boc", /^You rummage through a storage box/, 'caravan_box', 41)
+ end
- item_list = DRC.bput('look in my watery portal', /In the swirling eddy .*/i, 'What were')
- .slice!("In the swirling eddy you see")
- .split(",")
- item_list.each_with_index do |item, itr|
- if itr < item_list.length - 1
- @item_data[@active_character] << item.lstrip.concat(' (eddy)')
- else
- item.split("and")
- .each do |item2|
- @item_data[@active_character] << item2.strip.concat(" (eddy)").tr('.', '')
- end
- end
- end
+ def add_family_vault
+ check_inventory("rummage vault", /^You rummage through a secure vault/, 'Family', 42)
+ end
- DRC.message "Saving eddy data for #{@active_character}!"
- File.open(@item_db_path, 'w') { |file| file.write(@item_data.to_yaml) }
- if using_sorter
- start_script('sorter') unless Script.running?('sorter')
- end
+ def add_vault_regular_inv
+ check_inventory("rummage vault", /^You rummage through a secure vault/, 'vault', 42)
end
- def add_storage_box_inv
- if @item_data[@active_character]
- @item_data[@active_character] = @item_data[@active_character].select { |line| !line.include? 'caravan_box' }
- else
- @item_data[@active_character] = []
+ def add_scrolls
+ stacker_container = (@settings.scroll_sorter['stacker_container'] || @settings.stacker_container)
+ unless stacker_container
+ DRC.message("You have no stacker_container defined for sort-scrolls or stack-scrolls!")
+ exit
end
- using_sorter = false
- if Script.running?('sorter')
- stop_script('sorter')
- using_sorter = true
- end
+ get_item_data('spell_scroll')
- item_list = DRC.bput('rummage storage box', /through a storage box and see .*/i, 'What were')
- .slice!("You rummage through a storage box and see")
- .split(",")
- item_list.each_with_index do |item, itr|
- if itr < item_list.length - 1
- @item_data[@active_character] << item.lstrip.concat(' (caravan_box)')
- else
- item.split("and")
- .each do |item2|
- @item_data[@active_character] << item2.strip.concat(" (caravan_box)").tr('.', '')
- end
+ stacker = @settings.scroll_sorter['stacker']
+ scroll_stackers = @settings.scroll_stackers
+
+ DRCI.open_container?("my #{stacker_container}")
+
+ spells = []
+
+ if stacker
+ # stacker is defined, so they're using sort-scrolls - get all ten books and parse them
+ 10.times do
+ DRCI.get_item_safe?("tenth #{stacker}", stacker_container)
+ spells.concat(check_scroll_stacker(stacker))
+ DRCI.put_away_item?(stacker, stacker_container)
+ end
+ else
+ # no stacker variable, so they are using stack-scrolls. loop through their scroll stackers and parse them
+ scroll_stackers.each do |scroll_stacker|
+ DRCI.get_item_safe?(scroll_stacker, stacker_container)
+ spells.concat(check_scroll_stacker(scroll_stacker))
+ DRCI.put_away_item?(scroll_stacker, stacker_container)
end
end
- DRC.message("Saving caravan box data for #{@active_character}!")
- File.open(@item_db_path, 'w') { |file| file.write(@item_data.to_yaml) }
- if using_sorter
- start_script('sorter') unless Script.running?('sorter')
+ spells.sort.each do |spell|
+ @item_data[@active_character] << spell
end
+
+ save_item_data('spell_scroll')
+
+ DRCI.close_container?("my #{stacker_container}") if @settings.scroll_sorter['close_container']
end
- def add_family_vault
- if @item_data['Family']
- @item_data['Family'] = @item_data['Family'].select { |line| !line.include? 'Family' }
- else
- @item_data['Family'] = []
+ def check_scroll_stacker(stacker)
+ spells = []
+ capture = Lich::Util.issue_command("flip my #{stacker.split.last}", /^You flip through the #{stacker.split.last}, checking each section before closing it.$/)
+ capture.each do |line|
+ if line =~ /The (.+) section has (\d+)/
+ spell = "#{Regexp.last_match(1)} (#{Regexp.last_match(2)})"
+ spell.concat(" (spell_scroll)")
+ spells << spell
+ end
end
+ spells
+ end
- using_sorter = false
- if Script.running?('sorter')
- stop_script('sorter')
- using_sorter = true
- end
+ def add_home
+ check_inventory("home recall", /^The home contains:/, 'home')
+ end
- item_list = DRC.bput('rummage vault', /through a vault and see .*/i, 'What were')
- .slice!("You rummage through a vault and see")
- .split(",")
- item_list.each_with_index do |item, itr|
- if itr < item_list.length - 1
- @item_data['Family'] << item.lstrip.concat(' (Family)')
- else
- item.split("and")
- .each do |item2|
- @item_data['Family'] << item2.strip.concat(" (Family)").tr('.', '')
- end
- end
+ def add_shadow_servant
+ unless DRStats.moon_mage?
+ DRC.message("You're not a Moon Mage!")
+ exit
end
- DRC.message("Saving family vault data!")
- File.open(@item_db_path, 'w') { |file| file.write(@item_data.to_yaml) }
- if using_sorter
- start_script('sorter') unless Script.running?('sorter')
+ unless DRRoom.npcs.include?('Servant')
+ DRC.message("Your Shadow Servant isn't present.")
+ exit
end
+
+ DRC.bput('prepare PG', 'You raise')
+ pause 3
+
+ check_inventory('cast servant', /^Within the belly/, 'shadow_servant')
end
- def add_vault_regular_inv
- if @item_data[@active_character]
- @item_data[@active_character] = @item_data[@active_character].select { |line| !line.include? 'vault' }
- else
- @item_data[@active_character] = []
+ def add_trader_shop
+ unless DRStats.trader?
+ DRC.message("You're not a Trader!")
+ exit
end
- using_sorter = false
- if Script.running?('sorter')
- stop_script('sorter')
- using_sorter = true
+ get_item_data('trader_shop')
+
+ surfaces = Hash.new
+ capture = Lich::Util.issue_command("shop customer", /^The following items contain goods for sale:/)
+ capture.each do |line|
+ line = line.lstrip
+
+ # this extracts the command from the shop surface and uses that to find what's on/in it
+ # because the surfaces aren't always just 'a glass table' (ex: a knotted flax cargo net)
+ # command looks like shop #123456789
+ if line =~ /^(.*?)<\/d>/
+ surfaces[Regexp.last_match(2)] = Regexp.last_match(1)
+ end
end
- item_list = DRC.bput('rummage vault', /through a secure vault and see .*/i, 'What were')
- .slice!("You rummage through a secure vault and see")
- .split(",")
- item_list.each_with_index do |item, itr|
- if itr < item_list.length - 1
- @item_data[@active_character] << item.lstrip.concat(' (vault)')
- else
- item.split("and")
- .each do |item2|
- @item_data[@active_character] << item2.strip.concat(" (vault)").tr('.', '')
+ surfaces.each do |surface|
+ capture = Lich::Util.issue_command(surface[1], /, you see:/)
+ capture.each do |line|
+ line = line.lstrip
+
+ if line =~ /^(.*?)<\/d>/
+ @item_data[@active_character] << "#{Regexp.last_match(2)} (#{surface[0]}) (trader_shop)"
end
end
end
- DRC.message("Saving vault data for #{@active_character}!")
- File.open(@item_db_path, 'w') { |file| file.write(@item_data.to_yaml) }
- if using_sorter
- start_script('sorter') unless Script.running?('sorter')
- end
+ save_item_data('trader_shop')
end
def list_character_inv(name)
if name.nil?
- DRC.message "There is inventory data for:"
+ DRC.message("There is inventory data for:")
@item_data.each do |k, v|
+ next if k == @version_string
+
inv_count = 0
v.each do |_data|
inv_count += 1
end
- DRC.message "#{k} - #{inv_count}"
+ DRC.message("#{k} - #{inv_count}")
end
return
end
name_sym = name.capitalize.to_sym
if @item_data.has_key?(name_sym)
- DRC.message "Inventory for #{name.capitalize}"
- @item_data[name_sym].each { |item| DRC.message " - #{item}" }
+ DRC.message("Inventory for #{name.capitalize}")
+ @item_data[name_sym].each { |item| DRC.message(" - #{item}") }
else
- DRC.message "No data found for the character #{name.capitalize}!"
+ DRC.message("No data found for the character #{name.capitalize}!")
end
end
def search_for_item(item)
total_found = 0
@item_data.each do |k, v|
+ next if k == @version_string
+
total_found = 0
- DRC.message "Checking #{k}:"
+ DRC.message("Checking #{k}:")
v.each { |data|
if data.downcase.include?(item)
total_found += 1
- DRC.message "Match #{total_found}): #{data}"
+ DRC.message("Match #{total_found}): #{data}")
end
}
- DRC.message "Found #{total_found} matches on #{k}\n"
+ DRC.message("Found #{total_found} match#{(total_found > 1 ? 'es' : '')} on #{k}\n")
end
end
- def remove_character_data(name)
- @item_data.delete(name.capitalize.to_sym)
- File.open(@item_db_path, 'w') { |file| file.write(@item_data.to_yaml) }
- DRC.message "Removed #{name.capitalize}'s data!"
+ def remove_character_data(name_to_remove)
+ return if name_to_remove == "version"
+
+ @item_data.delete(name_to_remove.capitalize.to_sym)
+ File.open(@item_db_path, 'w') { |file| file.write(@item_data.to_yaml(line_width: -1)) }
+ DRC.message("Removed #{name_to_remove.capitalize}'s data!")
end
end
diff --git a/pick.lic b/pick.lic
index c7207e98ac..f6c1c13021 100644
--- a/pick.lic
+++ b/pick.lic
@@ -415,7 +415,11 @@ class Pick
def try_unlock_box_with_key(box)
return unless @settings.use_skeleton_key
- return unless DRCI.get_item_if_not_held?(@settings.skeleton_key)
+
+ unless DRCI.get_item_if_not_held?(@settings.skeleton_key)
+ echo("Couldn't get skeleton key. Exiting.")
+ exit
+ end
result = DRC.bput("turn my #{@settings.skeleton_key} at my #{box['noun']}", "^You turn", "that doesn't seem to do much", "I could not find", "What were you referring")
waitrt?
diff --git a/profiles/base-empty.yaml b/profiles/base-empty.yaml
index c1746a6385..2a4f750e55 100644
--- a/profiles/base-empty.yaml
+++ b/profiles/base-empty.yaml
@@ -62,6 +62,7 @@ empty_values:
hunting_info: []
hunting_nemesis: []
ignored_npcs: []
+ inventory_manager_ignores: []
lichbot_buffs: []
listen_skills: []
lockpick_buffs: {}
diff --git a/profiles/base.yaml b/profiles/base.yaml
index 16614e1b29..76ca006fcc 100644
--- a/profiles/base.yaml
+++ b/profiles/base.yaml
@@ -2178,6 +2178,31 @@ sorter:
sort_look_items_command: true
ignore_categories: lootables|trash
+# https://elanthipedia.play.net/Lich_script_repository#inventory-manager
+inventory_manager_ignores:
+ - '['
+ - '<'
+ - 'Roundtime'
+ - 'You have'
+ - 'Vault Inventory'
+ - 'Done'
+ - 'The last note'
+ - 'a brass hook'
+ - 'a steel wire rack'
+ - 'a small shelf'
+ - 'a top drawer'
+ - 'a middle drawer'
+ - 'a bottom drawer'
+ - 'a large shelf'
+ - 'Inside a'
+ - 'Page'
+ - 'Stored Deeds'
+ - 'Currently store'
+ - 'Maximum:'
+ - 'The home contains'
+ - 'Within the belly'
+ - 'Your Servant is holding'
+
stabbity:
# Settings for script card-collector, defines bag to draw cards from(fresh) and bag to store duplicates and your case (duplicates)
diff --git a/remedy.lic b/remedy.lic
index a51663e5bf..52620fec0a 100644
--- a/remedy.lic
+++ b/remedy.lic
@@ -15,6 +15,8 @@ class Remedy
@belt = @settings.alchemy_belt
@training_spells = @settings.crafting_training_spells
@stock = get_data('crafting')['remedies'][@settings.hometown]
+ @stamp = @settings.mark_crafted_goods
+ @cube = @settings.cube_armor_piece
arg_definitions = [
[
@@ -177,6 +179,8 @@ class Remedy
DRCC.stow_crafting_item("remed book", @bag, @forging_belt)
end
+ DRC.bput("touch my #{@cube}", /^Warm vapor swirls around your head in a misty halo/, /^A thin cloud of vapor manifests with no particular effect./, /^Touch what/) if @cube
+
if ('red flower').include?(@herb1)
@herb1 = 'dried flower' unless DRCI.exists?('red flower')
elsif ('blue flower').include?(@herb1)
@@ -397,11 +401,18 @@ class Remedy
DRC.bput('release symb', "But you haven't", 'You release', 'Repeat this command')
end
+ def stamp_item(noun)
+ DRCC.get_crafting_item('stamp', @bag, @bag_items, @belt)
+ DRC.bput("mark my #{noun} with my stamp", 'carefully hammer the stamp', 'You cannot figure out how to do that', 'too badly damaged', /score the surface with the stamp/)
+ DRCC.stow_crafting_item('stamp', @bag, @belt)
+ end
+
def finish
waitrt?
stow_item(DRC.left_hand)
fput("get my #{@noun} from my #{@container}")
stow_item(DRC.right_hand)
+ stamp_item(@noun) if @stamp
magic_cleanup
exit
end
diff --git a/validate.lic b/validate.lic
index 560ea4c0c0..08d99675bd 100644
--- a/validate.lic
+++ b/validate.lic
@@ -17,13 +17,6 @@ class DRYamlValidator
setup_data
- if $manager.developer
- respond("")
- echo "**WARNING**: You are on developer or dev mode. That suggests you are a developer."
- echo "**WARNING**: If you are on dev mode, you should be capable of solving most issues yourself."
- echo "**WARNING**: Support by Lich contributors will be limited or declined."
- end
-
respond("")
respond(" CHECKING: That #{checkname}-setup.yaml exists in the proper folder.")
if profiles.grep(/#{checkname}-setup/).empty?