forked from elanthia-online/dr-scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfind.lic
117 lines (103 loc) · 3.98 KB
/
find.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
=begin
Documentation: https://elanthipedia.play.net/Lich_script_repository#find
=end
custom_require.call(%w[common-travel])
class Find
def initialize
arg_definitions = [
[
{ name: 'town', options: ['crossing', 'dirge', 'shard', 'boar'], optional: true, description: 'Town/area to search' },
{ name: 'npc', regex: /^(?!follow)([\w\s\-']+)$/i, optional: true, description: 'Unique name/noun of the NPC to find' },
{ name: 'follow', regex: /^follow$/i, optional: true, description: 'Follow the NPC once it is found' }
]
]
args = parse_args(arg_definitions, true)
# Show help menu if no NPC specified.
# IMPORTANT: When 'npc' argument was required then the first argument to the script
# was always assigned to that variable. This made trying to specify the optional town difficult.
# For example `;find shard guard` would assign "npc=shard, flex=[guard]".
# I think it has something to do with how `parse_args` may be giving priority to assign all the
# required arguments first then assign out the optional ones.
# I found that if I made all the arguments optional then the arguments get assigned in the order they're given.
# So `;find shard guard` becomes "town=shard, npc=guard".
# As a trade-off, the script itself now checks if 'npc' is blank and shows the help menu manually.
if args.npc.nil? || args.npc.empty?
force_start_script('find', ['help'])
exit
end
area = get_town_and_region(args.town, args.npc)
rooms = get_rooms(area.town, area.region)
if search?(rooms, args.npc) && args.follow
follow(args.npc)
end
end
# What geographical area are we searching in?
# Use this data to look up the actual rooms to explore.
def get_town_and_region(town, npc)
town = format_town(town)
case npc
when /ozursus/i
town = 'Crossing' if town.nil? || town.empty?
region = 'asemath_academy' if town == 'Crossing'
when /shaman/i
town = 'Dirge' if town.nil? || town.empty?
region = 'rooms'
when /theurgist/i
town = 'Shard' if town.nil? || town.empty?
region = 'rooms'
when /monk/i
town = 'Boar Clan' if town.nil? || town.empty?
region = 'pilgrimage_trail' if town == 'Boar Clan'
end
town = 'Crossing' if town.nil? || town.empty?
region = 'rooms' if region.nil? || region.empty?
return OpenStruct.new(
:town => town,
:region => region
)
end
# If no town provided then 'Crossing' is used as default.
# Anything that starts with 'boar' is expanded to 'Boar Clan'.
# Each word in the town is capitalized to match values in base-town.yaml.
def format_town(town)
town = '' if town.nil?
case town
when /^boar/i
town = 'Boar Clan'
end
town.split(' ').map(&:capitalize).join(' ')
end
# Determine the rooms to search for the requested NPC in the suggested town.
def get_rooms(town, region)
rooms = get_data('town')[town]['wandering_npcs'][region]
# Start search from the room we're in if it's
# in our search path, otherwise go to beginning.
# This also allows you to stop/start a search
# without always going back to the beginning.
start_index = rooms.index(Room.current.id) || 0
rooms.rotate(start_index)
end
def search?(room_ids, npc)
return true if in_room?(npc)
return true if room_ids.any? do |room_id|
DRCT.walk_to(room_id)
in_room?(npc)
end
DRC.message("***STATUS*** Failed to find an NPC named '#{npc}', there might be a room missing from the search path")
false
end
def follow(npc)
DRC.message("***STATUS*** Following '#{npc}' until you stop the script")
loop do
pause 1
next if in_room?(npc)
DRC.message("***STATUS*** '#{npc}' has moved; searching adjacent rooms")
break unless search?(Room.current.wayto.keys, npc)
end
end
def in_room?(npc)
DRRoom.npcs.any? { |room_npc| room_npc =~ /\b#{npc}\b/i }
end
end
# Don't auto-run during unit tests
Find.new unless $_TEST_MODE_