inform6lib 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +201 -0
- data/README.md +125 -0
- data/Rakefile +65 -0
- data/lib/inform/English.h.rb +1279 -0
- data/lib/inform/Grammar.h.inf.rb +350 -0
- data/lib/inform/Parser.h.rb +145 -0
- data/lib/inform/VerbLib.h.rb +77 -0
- data/lib/inform/infix.h.inf.rb +58 -0
- data/lib/inform/infix.h.rb +1064 -0
- data/lib/inform/linklpa.h.rb +139 -0
- data/lib/inform/linklv.h.rb +174 -0
- data/lib/inform/parserm.h.rb +5884 -0
- data/lib/inform/verblibm.h.rb +2481 -0
- metadata +57 -0
|
@@ -0,0 +1,2481 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: false
|
|
3
|
+
|
|
4
|
+
# rubocop: disable Lint/UselessAssignment
|
|
5
|
+
|
|
6
|
+
# ==============================================================================
|
|
7
|
+
# VerbLib: Core of standard verbs library.
|
|
8
|
+
#
|
|
9
|
+
# Supplied for use with Inform 6 -- Release 6/11 -- Serial number 040227
|
|
10
|
+
#
|
|
11
|
+
# Copyright Graham Nelson 1993-2004 but freely usable (see manuals)
|
|
12
|
+
#
|
|
13
|
+
# This file is automatically Included in your game file by "VerbLib".
|
|
14
|
+
# ==============================================================================
|
|
15
|
+
|
|
16
|
+
# Copyright Nels Nelson 2008-2022 but freely usable (see license)
|
|
17
|
+
#
|
|
18
|
+
# You should have received a copy of the Artistic License
|
|
19
|
+
# along with the Inform6 Ruby Port.
|
|
20
|
+
#
|
|
21
|
+
# If not, see <https://www.perlfoundation.org/artistic-license-20.html>.
|
|
22
|
+
|
|
23
|
+
# The Inform module
|
|
24
|
+
module Inform
|
|
25
|
+
NEWLINE_BIT = 1 # New-line after each entry
|
|
26
|
+
INDENT_BIT = 2 # Indent each entry by depth
|
|
27
|
+
FULLINV_BIT = 4 # Full inventory information after entry
|
|
28
|
+
ENGLISH_BIT = 8 # English sentence style, with commas and and
|
|
29
|
+
RECURSE_BIT = 16 # Recurse downwards with usual rules
|
|
30
|
+
ALWAYS_BIT = 32 # Always recurse downwards
|
|
31
|
+
TERSE_BIT = 64 # More terse English style
|
|
32
|
+
PARTINV_BIT = 128 # Only brief inventory information after entry
|
|
33
|
+
DEFART_BIT = 256 # Use the definite article in list
|
|
34
|
+
WORKFLAG_BIT = 512 # At top level (only), only list objects
|
|
35
|
+
# which have the "workflag" attribute
|
|
36
|
+
ISARE_BIT = 1024 # Print " is" or " are" before list
|
|
37
|
+
CONCEAL_BIT = 2048 # Omit objects with "concealed" or "scenery":
|
|
38
|
+
# if WORKFLAG_BIT also set, then does _not_
|
|
39
|
+
# apply at top level, but does lower down
|
|
40
|
+
NOARTICLE_BIT = 4096 # Print no articles, definite or not
|
|
41
|
+
|
|
42
|
+
EXTRAINDENT_BIT = 8192 # Used only by I7: extra indentation of 1 level
|
|
43
|
+
EXTRA_WORKFLAG_BIT = 16_384 # Ditto: like WORKFLAG_BIT but at level 1
|
|
44
|
+
|
|
45
|
+
# The Verbs module
|
|
46
|
+
module Verbs
|
|
47
|
+
include Inform::English
|
|
48
|
+
|
|
49
|
+
def Banner
|
|
50
|
+
if defined?(Story) && !Story.nil? && !Story.empty?
|
|
51
|
+
style :bold
|
|
52
|
+
print Story
|
|
53
|
+
style :roman
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
print Headline if defined?(Headline) && !Headline.nil? && !Headline.empty?
|
|
57
|
+
print " by " + Story_Author if defined?(Story_Author) && !Story_Author.nil? && !Story_Author.empty?
|
|
58
|
+
print "Release " + (HDR_GAMERELEASE & 0x03ff)
|
|
59
|
+
print " / Serial number "
|
|
60
|
+
print HDR_GAMESERIAL
|
|
61
|
+
# defined?(TARGET_)
|
|
62
|
+
print " / #{executable} v"; inversion
|
|
63
|
+
print " Library " + LibRelease.to_s + " "
|
|
64
|
+
if defined? STRICT_MODE
|
|
65
|
+
print "S"
|
|
66
|
+
end
|
|
67
|
+
# defined? STRICT_MODE
|
|
68
|
+
if defined? INFIX
|
|
69
|
+
print "X"
|
|
70
|
+
else
|
|
71
|
+
if defined? DEBUG
|
|
72
|
+
print "D"
|
|
73
|
+
end
|
|
74
|
+
# defined? DEBUG
|
|
75
|
+
end
|
|
76
|
+
# defined? INFIX
|
|
77
|
+
new_line
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def VersionSub
|
|
81
|
+
Banner()
|
|
82
|
+
if standard_interpreter > 0
|
|
83
|
+
print "Standard interpreter " + (standard_interpreter / 256) + "." + (standard_interpreter % 256) +
|
|
84
|
+
" (" + HDR_TERPNUMBER[0]
|
|
85
|
+
if version_number == 6
|
|
86
|
+
print '.' + HDR_TERPVERSION[0]
|
|
87
|
+
else
|
|
88
|
+
print HDR_TERPVERSION[0]
|
|
89
|
+
end
|
|
90
|
+
print ") / "
|
|
91
|
+
else
|
|
92
|
+
print "Interpreter " + HDR_TERPNUMBER[0] + " Version "
|
|
93
|
+
if version_number == 6
|
|
94
|
+
print HDR_TERPVERSION[0].to_s
|
|
95
|
+
else
|
|
96
|
+
print HDR_TERPVERSION[0]
|
|
97
|
+
end
|
|
98
|
+
print " / "
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def RunTimeError(n, p1 = nil, p2 = nil)
|
|
103
|
+
if defined? DEBUG
|
|
104
|
+
print "** Library error #{n} (p1,p2) **\n** "
|
|
105
|
+
case n
|
|
106
|
+
when 1 then print "preposition not found (this should not occur)"
|
|
107
|
+
when 2 then print "Property value not routine or string: \"#{p2}\" of \"#{p1}\"" +
|
|
108
|
+
" (#{p1})";
|
|
109
|
+
when 3 then print "Entry in property list not routine or string: \"#{p2}\" list of \"#{p1}\"" +
|
|
110
|
+
" (#{p1})"
|
|
111
|
+
when 4 then print "Too many timers/daemons are active simultaneously. " +
|
|
112
|
+
"The limit is the library constant MAX_TIMERS (currently #{MAX_TIMERS}) " +
|
|
113
|
+
"and should be increased"
|
|
114
|
+
when 5 then print "Object \"#{p1}\" has no \"time_left\" property"
|
|
115
|
+
when 7 then print "The object \"#{p1}\" can only be used as a player object if it has " +
|
|
116
|
+
"the \"number\" property"
|
|
117
|
+
when 8 then print "Attempt to take random entry from an empty table array"
|
|
118
|
+
when 9 then print "#{p1} is not a valid direction property number"
|
|
119
|
+
when 10 then print "The player-object is outside the object tree"
|
|
120
|
+
when 11 then print "The room \"#{p1}\" has no \"description\" property"
|
|
121
|
+
when 12 then print "Tried to set a non-existent pronoun using SetPronoun"
|
|
122
|
+
when 13 then print "A 'topic' token can only be followed by a preposition"
|
|
123
|
+
else
|
|
124
|
+
print "(unexplained)";
|
|
125
|
+
end
|
|
126
|
+
" **"
|
|
127
|
+
else
|
|
128
|
+
"** Library error #{n} (#{p1},#{p2}) **"
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# ----------------------------------------------------------------------------
|
|
133
|
+
# The WriteListFrom routine, a flexible object-lister taking care of
|
|
134
|
+
# plurals, inventory information, various formats and so on. This is used
|
|
135
|
+
# by everything in the library which ever wants to list anything.
|
|
136
|
+
#
|
|
137
|
+
# If there were no objects to list, it prints nothing and returns false;
|
|
138
|
+
# otherwise it returns true.
|
|
139
|
+
#
|
|
140
|
+
# o is the object, and style is a bitmap, whose bits are given by:
|
|
141
|
+
# ----------------------------------------------------------------------------
|
|
142
|
+
|
|
143
|
+
def NextEntry(o, odepth, lt_value = @lt_value, c_style = @c_style, &_block)
|
|
144
|
+
loop do
|
|
145
|
+
o = o.sibling
|
|
146
|
+
return nil if o.nil?
|
|
147
|
+
next if lt_value == true && o.list_together != lt_value
|
|
148
|
+
next if (c_style & WORKFLAG_BIT) != 0 && odepth == 0 && o.hasnt?(:workflag)
|
|
149
|
+
next if (c_style & CONCEAL_BIT) != 0 && o.hasany?(:concealed, :scenery)
|
|
150
|
+
return o
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def WillRecurs(o, c_style = @c_style)
|
|
155
|
+
return true if (c_style & ALWAYS_BIT) != 0
|
|
156
|
+
return false if (c_style & RECURSE_BIT) == 0
|
|
157
|
+
return true if o.hasany?(:transparent, :supporter)
|
|
158
|
+
return true if o.has?(:open, :container)
|
|
159
|
+
return false
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def ListEqual(o1, o2, c_style = @c_style)
|
|
163
|
+
return false if child(o1) && WillRecurs(o1)
|
|
164
|
+
return false if child(o2) && WillRecurs(o2)
|
|
165
|
+
if c_style & (FULLINV_BIT + PARTINV_BIT) != 0
|
|
166
|
+
return false if (o1.hasnt?(:worn) && o2.has?(:worn)) || (o2.hasnt?(:worn) && o1.has?(:worn))
|
|
167
|
+
return false if (o1.hasnt?(:light) && o2.has?(:light)) || (o2.hasnt?(:light) && o1.has?(:light))
|
|
168
|
+
if o1.has?(:container)
|
|
169
|
+
return false if o2.hasnt?(:container)
|
|
170
|
+
return false if o1.has?(:open) && o2.hasnt?(:open)
|
|
171
|
+
return false if o2.has?(:open) && o1.hasnt?(:open)
|
|
172
|
+
elsif o2.has?(:container)
|
|
173
|
+
return false
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
return Identical(o1, o2)
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def SortTogether(obj, value)
|
|
180
|
+
# println "Sorting together possessions of " + obj + " by value " + value
|
|
181
|
+
# x = child(obj)
|
|
182
|
+
# loop do
|
|
183
|
+
# break if x.nil?
|
|
184
|
+
# println the(x) + " no: " + x + " lt: " + x.list_together
|
|
185
|
+
# x = sibling(x)
|
|
186
|
+
# end
|
|
187
|
+
a = [] # out
|
|
188
|
+
b = [] # in
|
|
189
|
+
while child(obj)
|
|
190
|
+
if child(obj).list_together != value
|
|
191
|
+
a << child(obj)
|
|
192
|
+
else
|
|
193
|
+
b << child(obj)
|
|
194
|
+
end
|
|
195
|
+
child(obj).delete
|
|
196
|
+
end
|
|
197
|
+
b.each { |o| move o, obj } # out
|
|
198
|
+
a.each { |o| move o, obj } # in
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def SortOutList(obj)
|
|
202
|
+
# print "\n\nSorting out list from " + obj.name + "\n "
|
|
203
|
+
# i = child(@location)
|
|
204
|
+
# loop do
|
|
205
|
+
# break if i.nil?
|
|
206
|
+
# print i.name + " --> "
|
|
207
|
+
# i = sibling(i)
|
|
208
|
+
# end
|
|
209
|
+
# new_line
|
|
210
|
+
catch :AP_SOL do
|
|
211
|
+
i = obj
|
|
212
|
+
loop do
|
|
213
|
+
break if i.nil?
|
|
214
|
+
k = i.list_together
|
|
215
|
+
unless k.nil?
|
|
216
|
+
i = sibling(i)
|
|
217
|
+
loop do
|
|
218
|
+
break if i.nil? || i.list_together != k
|
|
219
|
+
i = sibling(i)
|
|
220
|
+
end
|
|
221
|
+
return false if i.nil?
|
|
222
|
+
l = sibling(i)
|
|
223
|
+
loop do
|
|
224
|
+
break if l.nil?
|
|
225
|
+
if l.list_together == k
|
|
226
|
+
SortTogether(parent(obj), k)
|
|
227
|
+
obj = parent(child(obj))
|
|
228
|
+
throw AP_SOL
|
|
229
|
+
end
|
|
230
|
+
l = sibling(l)
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
i = sibling(i)
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
# AP_SOL
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
def Print__Spaces(n)
|
|
240
|
+
return if n == 0
|
|
241
|
+
spaces n
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def WriteListFrom(o, style, depth = 0, &query)
|
|
245
|
+
if o.nil? || parent(o).nil? || (!query.nil? && parent(o).none?(&query))
|
|
246
|
+
print NOTHING__TX
|
|
247
|
+
new_line if style & NEWLINE_BIT != 0
|
|
248
|
+
return
|
|
249
|
+
end
|
|
250
|
+
if o == parent(child(o))
|
|
251
|
+
SortOutList(o)
|
|
252
|
+
o = parent(child(o))
|
|
253
|
+
end
|
|
254
|
+
# @c_style = style
|
|
255
|
+
# @wlf_indent = 0
|
|
256
|
+
WriteListR(o, depth, stack_pointer = 0, c_style = style, &query)
|
|
257
|
+
true
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
def WriteListR(o, depth, stack_pointer = 0,
|
|
261
|
+
c_style = @c_style, lt_value = @lt_value, listing_together = @listing_together,
|
|
262
|
+
listing_size = @listing_size, wlf_indent = @wlf_indent, &query)
|
|
263
|
+
return if o.nil? || parent(o).nil?
|
|
264
|
+
senc = 0
|
|
265
|
+
|
|
266
|
+
if depth > 0 && o == parent(child(o))
|
|
267
|
+
SortOutList(o)
|
|
268
|
+
o = parent(child(o))
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
loop do
|
|
272
|
+
return false if o.nil?
|
|
273
|
+
if (c_style & WORKFLAG_BIT) != 0 && depth == 0 && o.hasnt?(:workflag)
|
|
274
|
+
o = o.sibling
|
|
275
|
+
next
|
|
276
|
+
end
|
|
277
|
+
if (c_style & CONCEAL_BIT) != 0 && o.hasany?(:concealed, :scenery)
|
|
278
|
+
o = o.sibling
|
|
279
|
+
next
|
|
280
|
+
end
|
|
281
|
+
if o == @player || (!query.nil? && !query.call(o))
|
|
282
|
+
o = o.sibling
|
|
283
|
+
next
|
|
284
|
+
end
|
|
285
|
+
break
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
classes_p = @match_classes.is_a?(Array) ? @match_classes.dup : []
|
|
289
|
+
sizes_p = @match_list.is_a?(Array) ? @match_list.dup : []
|
|
290
|
+
|
|
291
|
+
i = o; j = 0; k = 0
|
|
292
|
+
loop do
|
|
293
|
+
break if i.nil?
|
|
294
|
+
classes_p[j] = 0
|
|
295
|
+
k += 1 if i.&:plural
|
|
296
|
+
i = NextEntry(i, depth, lt_value, c_style, &query)
|
|
297
|
+
j += 1
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
if (c_style & ISARE_BIT) != 0
|
|
301
|
+
if j == 1 && o.hasnt?(:pluralname) then print IS__TX
|
|
302
|
+
else print ARE__TX
|
|
303
|
+
end
|
|
304
|
+
if (c_style & NEWLINE_BIT) != 0 then println ":"
|
|
305
|
+
else print ' '
|
|
306
|
+
end
|
|
307
|
+
c_style = c_style - ISARE_BIT
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
stack_pointer += (j + 1)
|
|
311
|
+
|
|
312
|
+
if k < 2 # It takes two to plural
|
|
313
|
+
return EconomyVersion(o, j, depth, senc, stack_pointer,
|
|
314
|
+
c_style, lt_value,
|
|
315
|
+
listing_together, listing_size,
|
|
316
|
+
wlf_indent, &query)
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
n = 1; i = o; k = 0
|
|
320
|
+
loop do
|
|
321
|
+
break if k >= j
|
|
322
|
+
if classes_p[k] == 0
|
|
323
|
+
classes_p[k] = n; sizes_p[n] = 1
|
|
324
|
+
l = NextEntry(i, depth, lt_value, c_style, &query)
|
|
325
|
+
m = k + 1
|
|
326
|
+
loop do
|
|
327
|
+
break if l.nil? || m >= j
|
|
328
|
+
if classes_p[m] == 0 && i.&(:plural) && l.&(:plural)
|
|
329
|
+
if ListEqual(i, l)
|
|
330
|
+
sizes_p[n] += 1
|
|
331
|
+
classes_p[m] = n
|
|
332
|
+
end
|
|
333
|
+
end
|
|
334
|
+
l = NextEntry(l, depth, lt_value, c_style, &query)
|
|
335
|
+
m += 1
|
|
336
|
+
end
|
|
337
|
+
n += 1
|
|
338
|
+
end
|
|
339
|
+
i = NextEntry(i, depth, lt_value, c_style, &query)
|
|
340
|
+
k += 1
|
|
341
|
+
end
|
|
342
|
+
n -= 1
|
|
343
|
+
|
|
344
|
+
i = 1; j = o; k = 0
|
|
345
|
+
loop do
|
|
346
|
+
break if i > n
|
|
347
|
+
loop do
|
|
348
|
+
break if (classes_p[k] == i) || (classes_p[k] == -i)
|
|
349
|
+
k += 1; j = NextEntry(j, depth, lt_value, c_style, &query)
|
|
350
|
+
end
|
|
351
|
+
m = sizes_p[i]
|
|
352
|
+
if j.nil? then mr = nil
|
|
353
|
+
else
|
|
354
|
+
if !j.list_together.nil? || (!lt_value.nil? && [2, 3].include?(ZRegion(j.list_together)) &&
|
|
355
|
+
j.list_together == mr)
|
|
356
|
+
senc -= 1
|
|
357
|
+
end
|
|
358
|
+
mr = j.list_together
|
|
359
|
+
end
|
|
360
|
+
i += 1
|
|
361
|
+
senc += 1
|
|
362
|
+
end
|
|
363
|
+
senc -= 1
|
|
364
|
+
|
|
365
|
+
i = 1; j = o; k = 0; mr = nil
|
|
366
|
+
loop do
|
|
367
|
+
break if senc < 0
|
|
368
|
+
loop do
|
|
369
|
+
break if (classes_p[k] == i) || (classes_p[k] == -i)
|
|
370
|
+
k += 1; j = NextEntry(j, depth, lt_value, c_style, &query)
|
|
371
|
+
end
|
|
372
|
+
if j.nil? # TODO: FIXME and remove
|
|
373
|
+
log.warn "classes_p: #{classes_p.inspect}"
|
|
374
|
+
log.warn "classes_p k: #{k}, i: #{i}"
|
|
375
|
+
log.warn "FIXME: Too many entries in classes_p"
|
|
376
|
+
break
|
|
377
|
+
end
|
|
378
|
+
if !j.list_together.nil? || !lt_value.nil?
|
|
379
|
+
if j.list_together == mr
|
|
380
|
+
# Omit_FL2
|
|
381
|
+
i += 1
|
|
382
|
+
next
|
|
383
|
+
end
|
|
384
|
+
k2 = NextEntry(j, depth, lt_value, c_style, &query)
|
|
385
|
+
if k2.nil? || k2.list_together != j.list_together
|
|
386
|
+
# Omit_WL2
|
|
387
|
+
|
|
388
|
+
if WriteBeforeEntry(j, depth, -senc, c_style, wlf_indent) == 1
|
|
389
|
+
# Omit_FL2
|
|
390
|
+
i += 1
|
|
391
|
+
senc -= 1
|
|
392
|
+
next
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
if sizes_p[i] == 1
|
|
396
|
+
if (c_style & NOARTICLE_BIT) != 0 then print j.name
|
|
397
|
+
else
|
|
398
|
+
if (c_style & DEFART_BIT) != 0 then print the(j) else print a(j) end
|
|
399
|
+
end
|
|
400
|
+
else
|
|
401
|
+
PrefaceByArticle(j, 1, sizes_p[i]) if (c_style & DEFART_BIT) != 0
|
|
402
|
+
print number(sizes_p[i]) + " "
|
|
403
|
+
PrintOrRun(j, :plural, 1)
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
if sizes_p[i] > 1 && j.hasnt?(:pluralname)
|
|
407
|
+
give j, :pluralname
|
|
408
|
+
WriteAfterEntry(j, depth, stack_pointer,
|
|
409
|
+
c_style, lt_value,
|
|
410
|
+
listing_together,
|
|
411
|
+
listing_size)
|
|
412
|
+
take j, :pluralname
|
|
413
|
+
else
|
|
414
|
+
WriteAfterEntry(j, depth, stack_pointer,
|
|
415
|
+
c_style, lt_value,
|
|
416
|
+
listing_together,
|
|
417
|
+
listing_size)
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
# Omit_EL2
|
|
421
|
+
|
|
422
|
+
if (c_style & ENGLISH_BIT) != 0
|
|
423
|
+
print AND__TX if senc == 1
|
|
424
|
+
print COMMA__TX if senc > 1
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
# Omit_FL2
|
|
428
|
+
|
|
429
|
+
i += 1; senc -= 1
|
|
430
|
+
next
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
k2 = ZRegion(j.list_together)
|
|
434
|
+
if [2, 3].include?(k2)
|
|
435
|
+
q = j; listing_size = 1; l = k; m = i
|
|
436
|
+
loop do
|
|
437
|
+
break unless m < n && q.list_together == j.list_together
|
|
438
|
+
m += 1
|
|
439
|
+
loop do
|
|
440
|
+
break unless (classes_p[l] != m) && (classes_p[l] != -m)
|
|
441
|
+
l += 1; q = NextEntry(q, depth, lt_value, c_style, &query)
|
|
442
|
+
end
|
|
443
|
+
listing_size += 1 if q.list_together == j.list_together
|
|
444
|
+
end
|
|
445
|
+
# print " [" + listing_size.to_s + "] "
|
|
446
|
+
if listing_size == 1
|
|
447
|
+
# Omit_WL2
|
|
448
|
+
|
|
449
|
+
if WriteBeforeEntry(j, depth, -senc, c_style, wlf_indent) == 1
|
|
450
|
+
# Omit_FL2
|
|
451
|
+
i += 1; senc -= 1
|
|
452
|
+
next
|
|
453
|
+
end
|
|
454
|
+
|
|
455
|
+
if sizes_p[i] == 1
|
|
456
|
+
if (c_style & NOARTICLE_BIT) != 0 then print j.name
|
|
457
|
+
else
|
|
458
|
+
if (c_style & DEFART_BIT) != 0 then print the(j) else print a(j) end
|
|
459
|
+
end
|
|
460
|
+
else
|
|
461
|
+
PrefaceByArticle(j, 1, sizes_p[i]) if (c_style & DEFART_BIT) != 0
|
|
462
|
+
print number(sizes_p[i]) + " "
|
|
463
|
+
PrintOrRun(j, :plural, 1)
|
|
464
|
+
end
|
|
465
|
+
|
|
466
|
+
if sizes_p[i] > 1 && j.hasnt?(:pluralname)
|
|
467
|
+
give j, :pluralname
|
|
468
|
+
WriteAfterEntry(j, depth, stack_pointer,
|
|
469
|
+
c_style, lt_value,
|
|
470
|
+
listing_together,
|
|
471
|
+
listing_size)
|
|
472
|
+
take j, :pluralname
|
|
473
|
+
else
|
|
474
|
+
WriteAfterEntry(j, depth, stack_pointer,
|
|
475
|
+
c_style, lt_value,
|
|
476
|
+
listing_together,
|
|
477
|
+
listing_size)
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
# Omit_EL2
|
|
481
|
+
|
|
482
|
+
if (c_style & ENGLISH_BIT) != 0
|
|
483
|
+
print AND__TX if senc == 1
|
|
484
|
+
print COMMA__TX if senc > 1
|
|
485
|
+
end
|
|
486
|
+
|
|
487
|
+
# Omit_FL2
|
|
488
|
+
|
|
489
|
+
i += 1; senc -= 1
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
Print__Spaces(2 * (depth + wlf_indent)) if (c_style & INDENT_BIT) != 0
|
|
493
|
+
|
|
494
|
+
if k2 == 3
|
|
495
|
+
q = 0
|
|
496
|
+
listing_size.times { |l2| q += sizes_p[l2 + i] }
|
|
497
|
+
EnglishNumber(q); print " "
|
|
498
|
+
print j.list_together
|
|
499
|
+
print " (" if (c_style & ENGLISH_BIT) != 0
|
|
500
|
+
println ":" if (c_style & INDENT_BIT) != 0
|
|
501
|
+
end
|
|
502
|
+
q = c_style
|
|
503
|
+
if k2 != 3
|
|
504
|
+
@inventory_stage = 1
|
|
505
|
+
@parser_one = j; @parser_two = depth + wlf_indent
|
|
506
|
+
if RunRoutines(j, :list_together) == 1
|
|
507
|
+
# Omit__Sublist2
|
|
508
|
+
|
|
509
|
+
new_line if (q & NEWLINE_BIT) != 0 && (c_style & NEWLINE_BIT) == 0
|
|
510
|
+
c_style = q
|
|
511
|
+
mr = j.list_together
|
|
512
|
+
|
|
513
|
+
# Omit_EL2
|
|
514
|
+
|
|
515
|
+
if (c_style & ENGLISH_BIT) != 0
|
|
516
|
+
print AND__TX if senc == 1
|
|
517
|
+
print COMMA__TX if senc > 1
|
|
518
|
+
end
|
|
519
|
+
|
|
520
|
+
i += 1; senc -= 1
|
|
521
|
+
next
|
|
522
|
+
end
|
|
523
|
+
end
|
|
524
|
+
|
|
525
|
+
# if defined? TARGET_ZCODE
|
|
526
|
+
# push lt_value; push listing_together; push listing_size;
|
|
527
|
+
# else # TARGET_GLULX
|
|
528
|
+
# copy lt_value, sp; copy listing_together, sp; copy listing_size, sp
|
|
529
|
+
# end
|
|
530
|
+
# # defined? TARGET_GLULX
|
|
531
|
+
|
|
532
|
+
# @lt_value = j.list_together; @listing_together = j; @wlf_indent += 1
|
|
533
|
+
WriteListR(j, depth, stack_pointer,
|
|
534
|
+
c_style, lt_value = j.list_together,
|
|
535
|
+
listing_together = j, listing_size,
|
|
536
|
+
wlf_indent + 1, &query)
|
|
537
|
+
# ; @wlf_indent -= 1
|
|
538
|
+
|
|
539
|
+
# if defined? TARGET_ZCODE
|
|
540
|
+
# pull listing_size; pull listing_together; pull lt_value
|
|
541
|
+
# else # TARGET_GLULX
|
|
542
|
+
# copy sp, listing_size
|
|
543
|
+
# copy sp, listing_together
|
|
544
|
+
# copy sp, lt_value
|
|
545
|
+
# end
|
|
546
|
+
# # TARGET_ZCODE
|
|
547
|
+
|
|
548
|
+
if k2 == 3
|
|
549
|
+
print ")" if (q & ENGLISH_BIT) != 0
|
|
550
|
+
else
|
|
551
|
+
@inventory_stage = 2
|
|
552
|
+
@parser_one = j; @parser_two = depth + wlf_indent
|
|
553
|
+
RunRoutines(j, :list_together)
|
|
554
|
+
end
|
|
555
|
+
|
|
556
|
+
# label Omit__Sublist2
|
|
557
|
+
|
|
558
|
+
new_line if (q & NEWLINE_BIT) != 0 && (c_style & NEWLINE_BIT) == 0
|
|
559
|
+
c_style = q
|
|
560
|
+
mr = j.list_together
|
|
561
|
+
|
|
562
|
+
# Omit_EL2
|
|
563
|
+
|
|
564
|
+
if (c_style & ENGLISH_BIT) != 0
|
|
565
|
+
print AND__TX if senc == 1
|
|
566
|
+
print COMMA__TX if senc > 1
|
|
567
|
+
end
|
|
568
|
+
|
|
569
|
+
i += 1; senc -= 1
|
|
570
|
+
next
|
|
571
|
+
end
|
|
572
|
+
end
|
|
573
|
+
# if !j.list_together.nil? || !lt_value.nil?
|
|
574
|
+
|
|
575
|
+
# label Omit_WL2
|
|
576
|
+
|
|
577
|
+
if WriteBeforeEntry(j, depth, -senc, c_style, wlf_indent) == 1
|
|
578
|
+
# Omit_FL2
|
|
579
|
+
i += 1; senc -= 1
|
|
580
|
+
next
|
|
581
|
+
end
|
|
582
|
+
|
|
583
|
+
if sizes_p[i] == 1
|
|
584
|
+
if (c_style & NOARTICLE_BIT) != 0 then print j.name
|
|
585
|
+
else
|
|
586
|
+
if (c_style & DEFART_BIT) != 0 then print the(j) else print a(j) end
|
|
587
|
+
end
|
|
588
|
+
else
|
|
589
|
+
PrefaceByArticle(j, 1, sizes_p[i]) if (c_style & DEFART_BIT) != 0
|
|
590
|
+
print number(sizes_p[i]) + " "
|
|
591
|
+
PrintOrRun(j, :plural, 1)
|
|
592
|
+
end
|
|
593
|
+
|
|
594
|
+
if sizes_p[i] > 1 && j.hasnt?(:pluralname)
|
|
595
|
+
give j, :pluralname
|
|
596
|
+
WriteAfterEntry(j, depth, stack_pointer,
|
|
597
|
+
c_style, lt_value,
|
|
598
|
+
listing_together,
|
|
599
|
+
listing_size)
|
|
600
|
+
take j, :pluralname
|
|
601
|
+
else
|
|
602
|
+
WriteAfterEntry(j, depth, stack_pointer,
|
|
603
|
+
c_style, lt_value,
|
|
604
|
+
listing_together,
|
|
605
|
+
listing_size)
|
|
606
|
+
end
|
|
607
|
+
|
|
608
|
+
# label Omit_EL2
|
|
609
|
+
|
|
610
|
+
if (c_style & ENGLISH_BIT) != 0
|
|
611
|
+
print AND__TX if senc == 1
|
|
612
|
+
print COMMA__TX if senc > 1
|
|
613
|
+
end
|
|
614
|
+
|
|
615
|
+
# label Omit_FL2
|
|
616
|
+
|
|
617
|
+
i += 1; senc -= 1
|
|
618
|
+
end
|
|
619
|
+
# loop
|
|
620
|
+
return true
|
|
621
|
+
end
|
|
622
|
+
# def WriteListR
|
|
623
|
+
|
|
624
|
+
def EconomyVersion(o, j, depth, senc, stack_pointer = 0,
|
|
625
|
+
c_style = @c_style, lt_value = @lt_value,
|
|
626
|
+
listing_together = @listing_together,
|
|
627
|
+
listing_size = @listing_size,
|
|
628
|
+
wlf_indent = @wlf_indent, &query)
|
|
629
|
+
n = j; i = 1; j = o
|
|
630
|
+
loop do
|
|
631
|
+
break unless i <= n
|
|
632
|
+
if !j.list_together.nil? || (!lt_value.nil? &&
|
|
633
|
+
[2, 3].include?(ZRegion(j.list_together)) && j.list_together == mr)
|
|
634
|
+
senc -= 1
|
|
635
|
+
end
|
|
636
|
+
mr = j.list_together
|
|
637
|
+
j = NextEntry(j, depth, lt_value, c_style, &query)
|
|
638
|
+
i += 1; senc += 1
|
|
639
|
+
end
|
|
640
|
+
|
|
641
|
+
i = 1; j = o; mr = nil
|
|
642
|
+
loop do
|
|
643
|
+
break unless i <= senc
|
|
644
|
+
if !j.list_together.nil? || !lt_value.nil?
|
|
645
|
+
if j.list_together == mr
|
|
646
|
+
# Omit_FL
|
|
647
|
+
j = NextEntry(j, depth, lt_value, c_style, &query)
|
|
648
|
+
next
|
|
649
|
+
end
|
|
650
|
+
k = NextEntry(j, depth, lt_value, c_style, &query)
|
|
651
|
+
if k.nil? || (k.list_together != j.list_together)
|
|
652
|
+
# Omit_WL
|
|
653
|
+
|
|
654
|
+
if WriteBeforeEntry(j, depth, i - senc, c_style, wlf_indent) == 1
|
|
655
|
+
# Omit_FL
|
|
656
|
+
j = NextEntry(j, depth, lt_value, c_style, &query)
|
|
657
|
+
i += 1
|
|
658
|
+
next
|
|
659
|
+
end
|
|
660
|
+
|
|
661
|
+
if (c_style & NOARTICLE_BIT) != 0 then print j.name
|
|
662
|
+
else
|
|
663
|
+
if (c_style & DEFART_BIT) != 0 then print the(j) else print a(j) end
|
|
664
|
+
end
|
|
665
|
+
WriteAfterEntry(j, depth, stack_pointer,
|
|
666
|
+
c_style, lt_value,
|
|
667
|
+
listing_together,
|
|
668
|
+
listing_size)
|
|
669
|
+
|
|
670
|
+
# label Omit_EL
|
|
671
|
+
|
|
672
|
+
if (c_style & ENGLISH_BIT) != 0
|
|
673
|
+
print AND__TX if i == (senc - 1)
|
|
674
|
+
print COMMA__TX if i < (senc - 1)
|
|
675
|
+
end
|
|
676
|
+
|
|
677
|
+
# label Omit_FL
|
|
678
|
+
|
|
679
|
+
j = NextEntry(j, depth, lt_value, c_style, &query)
|
|
680
|
+
i += 1
|
|
681
|
+
next
|
|
682
|
+
end
|
|
683
|
+
|
|
684
|
+
k = ZRegion(j.list_together)
|
|
685
|
+
if [2, 3].include?(k)
|
|
686
|
+
Print__Spaces(2 * (depth + wlf_indent)) if (c_style & INDENT_BIT) != 0
|
|
687
|
+
if k == 3
|
|
688
|
+
q = j; l = 0
|
|
689
|
+
loop do
|
|
690
|
+
q = NextEntry(q, depth, lt_value, c_style, &query); l += 1
|
|
691
|
+
break if q.nil? || q.list_together != j.list_together
|
|
692
|
+
end
|
|
693
|
+
EnglishNumber(l); print " "
|
|
694
|
+
print j.list_together
|
|
695
|
+
print " (" if (c_style & ENGLISH_BIT) != 0
|
|
696
|
+
print ":\n" if (c_style & INDENT_BIT) != 0
|
|
697
|
+
end
|
|
698
|
+
q = c_style
|
|
699
|
+
if k != 3
|
|
700
|
+
@inventory_stage = 1
|
|
701
|
+
@parser_one = j; @parser_two = depth + wlf_indent
|
|
702
|
+
if RunRoutines(j, :list_together) == 1
|
|
703
|
+
# Omit__Sublist
|
|
704
|
+
|
|
705
|
+
new_line if (q & NEWLINE_BIT) != 0 && (c_style & NEWLINE_BIT) == 0
|
|
706
|
+
c_style = q
|
|
707
|
+
mr = j.list_together
|
|
708
|
+
|
|
709
|
+
# Omit_EL
|
|
710
|
+
|
|
711
|
+
if (c_style & ENGLISH_BIT) != 0
|
|
712
|
+
print AND__TX if i == (senc - 1)
|
|
713
|
+
print COMMA__TX if i < (senc - 1)
|
|
714
|
+
end
|
|
715
|
+
|
|
716
|
+
# Omit_FL
|
|
717
|
+
|
|
718
|
+
j = NextEntry(j, depth, lt_value, c_style, &query)
|
|
719
|
+
i += 1
|
|
720
|
+
next
|
|
721
|
+
end
|
|
722
|
+
end
|
|
723
|
+
|
|
724
|
+
# if defined? TARGET_ZCODE
|
|
725
|
+
# push lt_value; push listing_together; push listing_size
|
|
726
|
+
# else # defined? TARGET_GLULX
|
|
727
|
+
# copy lt_value, sp; copy listing_together, sp; copy listing_size, sp
|
|
728
|
+
# end
|
|
729
|
+
# # TARGET_ZCODE
|
|
730
|
+
|
|
731
|
+
# lt_value = j.list_together; listing_together = j; wlf_indent += 1
|
|
732
|
+
WriteListR(j, depth, stack_pointer,
|
|
733
|
+
c_style, lt_value = j.list_together,
|
|
734
|
+
listing_together = j, listing_size,
|
|
735
|
+
wlf_indent + 1, &query)
|
|
736
|
+
# ; @wlf_indent -= 1
|
|
737
|
+
|
|
738
|
+
# if defined? TARGET_ZCODE
|
|
739
|
+
# pull listing_size; pull listing_together; pull lt_value
|
|
740
|
+
# else # defined? TARGET_GLULX
|
|
741
|
+
# copy sp, listing_size; copy sp, listing_together; copy sp, lt_value
|
|
742
|
+
# end
|
|
743
|
+
# # TARGET_ZCODE
|
|
744
|
+
|
|
745
|
+
if k == 3
|
|
746
|
+
print ")" if (q & ENGLISH_BIT) != 0
|
|
747
|
+
else
|
|
748
|
+
@inventory_stage = 2
|
|
749
|
+
@parser_one = j; @parser_two = depth + wlf_indent
|
|
750
|
+
RunRoutines(j, :list_together)
|
|
751
|
+
end
|
|
752
|
+
|
|
753
|
+
# label Omit__Sublist
|
|
754
|
+
|
|
755
|
+
new_line if (q & NEWLINE_BIT) != 0 && (c_style & NEWLINE_BIT) == 0
|
|
756
|
+
c_style = q
|
|
757
|
+
mr = j.list_together
|
|
758
|
+
|
|
759
|
+
# Omit_EL
|
|
760
|
+
|
|
761
|
+
if (c_style & ENGLISH_BIT) != 0
|
|
762
|
+
print AND__TX if i == (senc - 1)
|
|
763
|
+
print COMMA__TX if i < (senc - 1)
|
|
764
|
+
end
|
|
765
|
+
|
|
766
|
+
# Omit_FL
|
|
767
|
+
|
|
768
|
+
j = NextEntry(j, depth, lt_value, c_style, &query)
|
|
769
|
+
i += 1
|
|
770
|
+
next
|
|
771
|
+
end
|
|
772
|
+
# if [2, 3].include?(k)
|
|
773
|
+
end
|
|
774
|
+
# if !j.list_together.nil? || !lt_value.nil?
|
|
775
|
+
|
|
776
|
+
# label Omit_WL
|
|
777
|
+
|
|
778
|
+
if WriteBeforeEntry(j, depth, i - senc, c_style, wlf_indent) == 1
|
|
779
|
+
# Omit_FL
|
|
780
|
+
j = NextEntry(j, depth, lt_value, c_style, &query)
|
|
781
|
+
i += 1
|
|
782
|
+
next
|
|
783
|
+
end
|
|
784
|
+
|
|
785
|
+
if (c_style & NOARTICLE_BIT) != 0 then print j.name
|
|
786
|
+
else
|
|
787
|
+
if (c_style & DEFART_BIT) != 0 then print the(j) else print a(j) end
|
|
788
|
+
end
|
|
789
|
+
WriteAfterEntry(j, depth, stack_pointer,
|
|
790
|
+
c_style, lt_value,
|
|
791
|
+
listing_together,
|
|
792
|
+
listing_size)
|
|
793
|
+
|
|
794
|
+
# label Omit_EL
|
|
795
|
+
|
|
796
|
+
if (c_style & ENGLISH_BIT) != 0
|
|
797
|
+
print AND__TX if i == (senc - 1)
|
|
798
|
+
print COMMA__TX if i < (senc - 1)
|
|
799
|
+
end
|
|
800
|
+
|
|
801
|
+
# label Omit_FL
|
|
802
|
+
|
|
803
|
+
j = NextEntry(j, depth, lt_value, c_style, &query)
|
|
804
|
+
i += 1
|
|
805
|
+
end
|
|
806
|
+
# loop do break unless i <= senc
|
|
807
|
+
end
|
|
808
|
+
# end EconomyVersion (WriteListR)
|
|
809
|
+
|
|
810
|
+
def WriteBeforeEntry(o, depth, sentencepos, c_style = @c_style, wlf_indent = 0)
|
|
811
|
+
flag = false
|
|
812
|
+
|
|
813
|
+
@inventory_stage = 1
|
|
814
|
+
Print__Spaces(2 * (depth + wlf_indent)) if (c_style & INDENT_BIT) != 0
|
|
815
|
+
if o.respond_to?(:invent) && (c_style & (PARTINV_BIT | FULLINV_BIT)) != 0 # This line changed
|
|
816
|
+
flag = PrintOrRun(o, :invent, 1)
|
|
817
|
+
if flag
|
|
818
|
+
if (c_style & ENGLISH_BIT) == 1
|
|
819
|
+
print AND__TX if sentencepos == -1
|
|
820
|
+
print COMMA__TX if sentencepos < -1
|
|
821
|
+
end
|
|
822
|
+
new_line if (c_style & NEWLINE_BIT) == 1
|
|
823
|
+
end
|
|
824
|
+
end
|
|
825
|
+
flag
|
|
826
|
+
end
|
|
827
|
+
|
|
828
|
+
def WriteAfterEntry(o, depth, stack_p,
|
|
829
|
+
c_style = @c_style, _lt_value = @lt_value,
|
|
830
|
+
_listing_together = @listing_together,
|
|
831
|
+
_listing_size = @listing_size, &query)
|
|
832
|
+
recurse_flag = false
|
|
833
|
+
parenth_flag = false
|
|
834
|
+
eldest_child = nil
|
|
835
|
+
child_count = 0
|
|
836
|
+
combo = nil
|
|
837
|
+
j = false
|
|
838
|
+
|
|
839
|
+
@inventory_stage = 2
|
|
840
|
+
if (c_style & PARTINV_BIT) == 1
|
|
841
|
+
# Begin the Inform6 Ruby Port addition
|
|
842
|
+
if o.respond_to?(:invent) && RunRoutines(o, :invent)
|
|
843
|
+
return true if (c_style & NEWLINE_BIT) == 0
|
|
844
|
+
print ""
|
|
845
|
+
return
|
|
846
|
+
end
|
|
847
|
+
# End the Inform6 Ruby Port addition
|
|
848
|
+
|
|
849
|
+
combo = 0
|
|
850
|
+
combo += 1 if o.has?(:light) && @location.hasnt?(:light)
|
|
851
|
+
combo += 2 if o.has?(:container) && o.hasnt?(:open)
|
|
852
|
+
if o.has?(:container) && (o.has?(:open) || o.has?(:transparent))
|
|
853
|
+
o.objectloop do |i|
|
|
854
|
+
if i.hasnt?(:concealed) && i.hasnt?(:scenery)
|
|
855
|
+
j = true; break
|
|
856
|
+
end
|
|
857
|
+
end
|
|
858
|
+
combo += 4 if j.nil?
|
|
859
|
+
end
|
|
860
|
+
L__M(:ListMiscellany, combo, o) if combo > 0
|
|
861
|
+
end
|
|
862
|
+
# end of PARTINV_BIT processing
|
|
863
|
+
|
|
864
|
+
if (c_style & FULLINV_BIT) != 0
|
|
865
|
+
if o.respond_to?(:invent) && RunRoutines(o, :invent)
|
|
866
|
+
return true if (c_style & NEWLINE_BIT) == 0
|
|
867
|
+
print ""
|
|
868
|
+
return
|
|
869
|
+
end
|
|
870
|
+
|
|
871
|
+
if o.has?(:light) && o.has?(:worn) then L__M(:ListMiscellany, 8, o); parenth_flag = true
|
|
872
|
+
else
|
|
873
|
+
if o.has?(:light) then L__M(:ListMiscellany, 9, o); parenth_flag = true end
|
|
874
|
+
if o.has?(:worn) then L__M(:ListMiscellany, 10, o); parenth_flag = true end
|
|
875
|
+
end
|
|
876
|
+
|
|
877
|
+
if o.has? :container
|
|
878
|
+
if o.has? :openable
|
|
879
|
+
if parenth_flag then print AND__TX
|
|
880
|
+
else L__M(:ListMiscellany, 11, o)
|
|
881
|
+
end
|
|
882
|
+
if o.has? :open
|
|
883
|
+
if child(o) then L__M(:ListMiscellany, 12, o)
|
|
884
|
+
else L__M(:ListMiscellany, 13, o)
|
|
885
|
+
end
|
|
886
|
+
else
|
|
887
|
+
if o.has?(:lockable) && o.has?(:locked) then L__M(:ListMiscellany, 15, o)
|
|
888
|
+
else L__M(:ListMiscellany, 14, o)
|
|
889
|
+
end
|
|
890
|
+
end
|
|
891
|
+
parenth_flag = true
|
|
892
|
+
else
|
|
893
|
+
if child(o) == 0 && o.has?(:transparent)
|
|
894
|
+
if parenth_flag then L__M(:ListMiscellany, 16, o)
|
|
895
|
+
else L__M(:ListMiscellany, 17, o)
|
|
896
|
+
end
|
|
897
|
+
end
|
|
898
|
+
end
|
|
899
|
+
end
|
|
900
|
+
|
|
901
|
+
print ")" if parenth_flag
|
|
902
|
+
end
|
|
903
|
+
# end of FULLINV_BIT processing
|
|
904
|
+
|
|
905
|
+
if (c_style & CONCEAL_BIT) != 0
|
|
906
|
+
child_count = 0
|
|
907
|
+
o.objectloop do |p|
|
|
908
|
+
if p.hasnt?(:concealed) && p.hasnt?(:scenery) then child_count += 1; eldest_child = p; end
|
|
909
|
+
end
|
|
910
|
+
else
|
|
911
|
+
child_count = children(o); eldest_child = child(o)
|
|
912
|
+
end
|
|
913
|
+
|
|
914
|
+
if child_count != 0 && (c_style & ALWAYS_BIT) != 0
|
|
915
|
+
L__M(:ListMiscellany, 18, o) if (c_style & ENGLISH_BIT) != 0
|
|
916
|
+
recurse_flag = true
|
|
917
|
+
end
|
|
918
|
+
|
|
919
|
+
if child_count != 0 && (c_style & RECURSE_BIT) != 0
|
|
920
|
+
if o.has? :supporter
|
|
921
|
+
if (c_style & ENGLISH_BIT) != 0
|
|
922
|
+
if (c_style & TERSE_BIT) != 0 then L__M(:ListMiscellany, 19, o)
|
|
923
|
+
else L__M(:ListMiscellany, 20, o)
|
|
924
|
+
end
|
|
925
|
+
if o.has? :animate then print WHOM__TX
|
|
926
|
+
else print WHICH__TX
|
|
927
|
+
end
|
|
928
|
+
end
|
|
929
|
+
recurse_flag = true
|
|
930
|
+
end
|
|
931
|
+
if o.has?(:container) && (o.has?(:open) || o.has?(:transparent))
|
|
932
|
+
if (c_style & ENGLISH_BIT) != 0
|
|
933
|
+
if (c_style & TERSE_BIT) != 0 then L__M(:ListMiscellany, 21, o)
|
|
934
|
+
else L__M(:ListMiscellany, 22, o)
|
|
935
|
+
end
|
|
936
|
+
if o.has? :animate then print WHOM__TX
|
|
937
|
+
else print WHICH__TX
|
|
938
|
+
end
|
|
939
|
+
end
|
|
940
|
+
recurse_flag = true
|
|
941
|
+
end
|
|
942
|
+
end
|
|
943
|
+
|
|
944
|
+
if recurse_flag && (c_style & ENGLISH_BIT) != 0
|
|
945
|
+
if child_count > 1 || (eldest_child && eldest_child.has?(:pluralname)) then print ARE2__TX
|
|
946
|
+
else print IS2__TX
|
|
947
|
+
end
|
|
948
|
+
end
|
|
949
|
+
|
|
950
|
+
new_line if (c_style & NEWLINE_BIT) != 0
|
|
951
|
+
|
|
952
|
+
return unless recurse_flag
|
|
953
|
+
|
|
954
|
+
o = child(o)
|
|
955
|
+
# if defined? TARGET_ZCODE
|
|
956
|
+
# push lt_value; @push listing_together; @push listing_size
|
|
957
|
+
# else # defined? TARGET_GLULX
|
|
958
|
+
# copy lt_value, sp; copy listing_together, sp; copy listing_size, sp
|
|
959
|
+
# end
|
|
960
|
+
# # TARGET_ZCODE
|
|
961
|
+
|
|
962
|
+
# @lt_value = 0; @listing_together = 0; @listing_size = 0
|
|
963
|
+
WriteListR(o, depth + 1, stack_p,
|
|
964
|
+
c_style, lt_value = nil,
|
|
965
|
+
listing_together = nil, listing_size = 0, &query)
|
|
966
|
+
# if defined? TARGET_ZCODE
|
|
967
|
+
# pull listing_size; pull listing_together; pull lt_value
|
|
968
|
+
# else # defined? TARGET_GLULX
|
|
969
|
+
# copy sp, listing_size; copy sp, listing_together; copy sp, lt_value
|
|
970
|
+
# end
|
|
971
|
+
# # TARGET_ZCODE
|
|
972
|
+
print ")" if (c_style & TERSE_BIT) != 0
|
|
973
|
+
end
|
|
974
|
+
# def WriteAfterEntry
|
|
975
|
+
|
|
976
|
+
# ----------------------------------------------------------------------------
|
|
977
|
+
# A cunning routine (which could have been a daemon, but isn't, for the
|
|
978
|
+
# sake of efficiency) to move objects which could be in many rooms about
|
|
979
|
+
# so that the player never catches one not in place
|
|
980
|
+
# ----------------------------------------------------------------------------
|
|
981
|
+
|
|
982
|
+
def MoveFloatingObjects
|
|
983
|
+
return if @location.nil? || @location == @player
|
|
984
|
+
flag = false
|
|
985
|
+
objectloop do |i|
|
|
986
|
+
address = i.&(:found_in)
|
|
987
|
+
if !address.nil? && i.hasnt?(:absent) && !IndirectlyContains(player, i)
|
|
988
|
+
if ZRegion(address) == 2
|
|
989
|
+
if !i.&(:found_in).nil? then move i, @location
|
|
990
|
+
else remove i
|
|
991
|
+
end
|
|
992
|
+
else
|
|
993
|
+
i.&(:found_in).each do |m|
|
|
994
|
+
if m == @location || m.in?(@location)
|
|
995
|
+
move i, @location if i.notin? @location
|
|
996
|
+
flag = true
|
|
997
|
+
end
|
|
998
|
+
end
|
|
999
|
+
remove i if flag == false && !parent(i).nil?
|
|
1000
|
+
end
|
|
1001
|
+
end
|
|
1002
|
+
end
|
|
1003
|
+
end
|
|
1004
|
+
|
|
1005
|
+
# ----------------------------------------------------------------------------
|
|
1006
|
+
# Two little routines for moving the player safely.
|
|
1007
|
+
# ----------------------------------------------------------------------------
|
|
1008
|
+
|
|
1009
|
+
def PlayerTo(newplace, flag = 0)
|
|
1010
|
+
move @player, newplace
|
|
1011
|
+
loop do
|
|
1012
|
+
parent_newplace = parent(newplace)
|
|
1013
|
+
break if parent_newplace.nil?
|
|
1014
|
+
newplace = parent_newplace
|
|
1015
|
+
end
|
|
1016
|
+
@location = newplace
|
|
1017
|
+
@real_location = @location; MoveFloatingObjects()
|
|
1018
|
+
AdjustLight(true)
|
|
1019
|
+
_invoke :Look if flag == 0
|
|
1020
|
+
if flag == 1 then NoteArrival(); ScoreArrival(); end
|
|
1021
|
+
LookSub(true) if flag == 2
|
|
1022
|
+
end
|
|
1023
|
+
|
|
1024
|
+
def MovePlayer(direc); _invoke :Go, direc; _invoke :Look; end
|
|
1025
|
+
|
|
1026
|
+
# ----------------------------------------------------------------------------
|
|
1027
|
+
# The handy YesOrNo routine, and some "meta" verbs
|
|
1028
|
+
# ----------------------------------------------------------------------------
|
|
1029
|
+
|
|
1030
|
+
# TODO: Figure out how this could work in a non-blocking IO system. FIXME
|
|
1031
|
+
# The read method would have to create an evented future promise or
|
|
1032
|
+
# something. That seems like it would cause this code to block on the
|
|
1033
|
+
# read command, and avoiding such blocking behavior was the entire point
|
|
1034
|
+
# of using Netty.
|
|
1035
|
+
def YesOrNo
|
|
1036
|
+
loop do
|
|
1037
|
+
@input = Inform::Runtime.instance.read
|
|
1038
|
+
DrawStatusLine() if !location.nil? && !parent(@player).nil?
|
|
1039
|
+
j = @input
|
|
1040
|
+
unless @input.empty? # at least one word entered
|
|
1041
|
+
i = @input.split.first
|
|
1042
|
+
return true if [YES1__WD, YES2__WD, YES3__WD].include?(i)
|
|
1043
|
+
return false if [NO1__WD, NO2__WD, NO3__WD].include?(i)
|
|
1044
|
+
end
|
|
1045
|
+
L__M(:Quit, 1); print "> "
|
|
1046
|
+
end
|
|
1047
|
+
end
|
|
1048
|
+
|
|
1049
|
+
# TODO: How could this work in a non-blocking IO system? FIXME
|
|
1050
|
+
def QuitSub
|
|
1051
|
+
L__M(:Quit, 2)
|
|
1052
|
+
quit if YesOrNo()
|
|
1053
|
+
end
|
|
1054
|
+
|
|
1055
|
+
def NotifyOnSub; notify_mode = 1; L__M(:NotifyOn); end
|
|
1056
|
+
def NotifyOffSub; notify_mode = 0; L__M(:NotifyOff); end
|
|
1057
|
+
|
|
1058
|
+
def Places1Sub
|
|
1059
|
+
j = 0
|
|
1060
|
+
k = 0
|
|
1061
|
+
L__M(:Places, 1)
|
|
1062
|
+
objectloop { |i| j += 1 if i.has?(:visited) }
|
|
1063
|
+
objectloop do |i|
|
|
1064
|
+
if i.has? :visited
|
|
1065
|
+
print i.name; k += 1
|
|
1066
|
+
if k == j then L__M(:Places, 2); return; end
|
|
1067
|
+
if k == j - 1 then print AND__TX
|
|
1068
|
+
else print COMMA__TX
|
|
1069
|
+
end
|
|
1070
|
+
end
|
|
1071
|
+
end
|
|
1072
|
+
end
|
|
1073
|
+
|
|
1074
|
+
# def Objects1Sub
|
|
1075
|
+
# j = 0
|
|
1076
|
+
# L__M(:Objects, 1)
|
|
1077
|
+
# objectloop do |i|
|
|
1078
|
+
# if i.has? :moved
|
|
1079
|
+
# f = 1; print the(i); j = parent(i)
|
|
1080
|
+
# unless j.nil?
|
|
1081
|
+
# if j == player
|
|
1082
|
+
# if i.has?(:worn) L__M(:Objects, 3)
|
|
1083
|
+
# else L__M(:Objects, 4)
|
|
1084
|
+
# end
|
|
1085
|
+
# new_line
|
|
1086
|
+
# break
|
|
1087
|
+
# end
|
|
1088
|
+
# if j.has?(:animate) then L__M(:Objects, 5); new_line; break; end
|
|
1089
|
+
# if j.has?(:visited) then L__M(:Objects, 6, j); new_line; break; end
|
|
1090
|
+
# if j.has?(:container) then L__M(:Objects, 8, j); new_line; break; end
|
|
1091
|
+
# if j.has?(:supporter) then L__M(:Objects, 9, j); new_line; break; end
|
|
1092
|
+
# if j.has?(:enterable) then L__M(:Objects, 7, j); new_line; break; end
|
|
1093
|
+
# end
|
|
1094
|
+
# end
|
|
1095
|
+
# L__M(:Objects, 10)
|
|
1096
|
+
# new_line
|
|
1097
|
+
# end
|
|
1098
|
+
# if (f == 0) L__M(##Objects, 2);
|
|
1099
|
+
# end
|
|
1100
|
+
|
|
1101
|
+
# See: metaverbs.rb
|
|
1102
|
+
|
|
1103
|
+
# ----------------------------------------------------------------------------
|
|
1104
|
+
# The scoring system
|
|
1105
|
+
# ----------------------------------------------------------------------------
|
|
1106
|
+
|
|
1107
|
+
# See: metaverbs.rb
|
|
1108
|
+
|
|
1109
|
+
# ----------------------------------------------------------------------------
|
|
1110
|
+
# Real verbs start here: Inventory
|
|
1111
|
+
# ----------------------------------------------------------------------------
|
|
1112
|
+
|
|
1113
|
+
def InvWideSub
|
|
1114
|
+
@inventory_style = ENGLISH_BIT + RECURSE_BIT + FULLINV_BIT
|
|
1115
|
+
invoke :Inv
|
|
1116
|
+
end
|
|
1117
|
+
|
|
1118
|
+
def InvTallSub
|
|
1119
|
+
@inventory_style = NEWLINE_BIT + RECURSE_BIT + INDENT_BIT + FULLINV_BIT
|
|
1120
|
+
invoke :Inv
|
|
1121
|
+
end
|
|
1122
|
+
|
|
1123
|
+
def InvSub
|
|
1124
|
+
return L__M(:Inv, 1) unless child(@player)
|
|
1125
|
+
return InvTallSub() if @inventory_style == 0
|
|
1126
|
+
|
|
1127
|
+
L__M(:Inv, 2)
|
|
1128
|
+
if (@inventory_style & NEWLINE_BIT) != 0 then L__M(:Inv, 3) else print " " end
|
|
1129
|
+
|
|
1130
|
+
WriteListFrom(child(@player), @inventory_style, 1)
|
|
1131
|
+
L__M(:Inv, 4) if (@inventory_style & ENGLISH_BIT) != 0
|
|
1132
|
+
|
|
1133
|
+
unless defined? MANUAL_PRONOUNS
|
|
1134
|
+
@player.objectloop { |x| PronounNotice(x) }
|
|
1135
|
+
end
|
|
1136
|
+
|
|
1137
|
+
AfterRoutines()
|
|
1138
|
+
end
|
|
1139
|
+
|
|
1140
|
+
# ----------------------------------------------------------------------------
|
|
1141
|
+
# The object tree and determining the possibility of moves
|
|
1142
|
+
# ----------------------------------------------------------------------------
|
|
1143
|
+
|
|
1144
|
+
def CommonAncestor(o1, o2)
|
|
1145
|
+
# Find the nearest object indirectly containing o1 and o2,
|
|
1146
|
+
# or return nil if there is no common ancestor.
|
|
1147
|
+
i = o1
|
|
1148
|
+
loop do
|
|
1149
|
+
break if i.nil?
|
|
1150
|
+
j = o2
|
|
1151
|
+
loop do
|
|
1152
|
+
break if j.nil?
|
|
1153
|
+
return i if j == i
|
|
1154
|
+
j = j.parent
|
|
1155
|
+
end
|
|
1156
|
+
i = i.parent
|
|
1157
|
+
end
|
|
1158
|
+
return nil
|
|
1159
|
+
end
|
|
1160
|
+
|
|
1161
|
+
def IndirectlyContains(o1, o2)
|
|
1162
|
+
return true if o1 == o2
|
|
1163
|
+
# Does o1 indirectly contain o2? (Same as testing if their common ancestor is o1.)
|
|
1164
|
+
return o1.descendants.include?(o2) # TODO: FIXME
|
|
1165
|
+
end
|
|
1166
|
+
|
|
1167
|
+
def ObjectScopedBySomething(item)
|
|
1168
|
+
i = item; return false unless i
|
|
1169
|
+
Inform::Object.each do |j|
|
|
1170
|
+
next unless j.respond_to?(:add_to_scope)
|
|
1171
|
+
return j if j.add_to_scope.include?(j)
|
|
1172
|
+
end
|
|
1173
|
+
return false
|
|
1174
|
+
end
|
|
1175
|
+
|
|
1176
|
+
def ObjectIsUntouchable(item, flag1 = nil, flag2 = nil, persona = nil)
|
|
1177
|
+
# Determine if there's any barrier preventing the player from moving
|
|
1178
|
+
# things to "item". Return false if no barrier; otherwise print a
|
|
1179
|
+
# suitable message and return true.
|
|
1180
|
+
# If flag1 is set, do not print any message.
|
|
1181
|
+
# If flag2 is set, also apply Take/Remove restrictions.
|
|
1182
|
+
# If persona is set, use that rather than the player.
|
|
1183
|
+
|
|
1184
|
+
flag1 = @player if flag1.nil?
|
|
1185
|
+
flag2 = @player if flag2.nil?
|
|
1186
|
+
persona = @player if persona.nil?
|
|
1187
|
+
|
|
1188
|
+
# If the item has been added to scope by something, it's first necessary
|
|
1189
|
+
# for that something to be touchable.
|
|
1190
|
+
|
|
1191
|
+
ancestor = CommonAncestor(persona, item)
|
|
1192
|
+
if ancestor.nil?
|
|
1193
|
+
ancestor = item
|
|
1194
|
+
loop do
|
|
1195
|
+
break unless ancestor && (i = ObjectScopedBySomething(ancestor)).nil?
|
|
1196
|
+
ancestor = parent(ancestor)
|
|
1197
|
+
end
|
|
1198
|
+
unless i.nil?
|
|
1199
|
+
return false
|
|
1200
|
+
# return false if ObjectIsUntouchable(i, flag1, flag2) # TODO: FIXME
|
|
1201
|
+
# An item immediately added to scope
|
|
1202
|
+
end
|
|
1203
|
+
else
|
|
1204
|
+
|
|
1205
|
+
# First, a barrier between the persona and the ancestor. The persona
|
|
1206
|
+
# can only be in a sequence of enterable objects, and only closed
|
|
1207
|
+
# containers form a barrier.
|
|
1208
|
+
|
|
1209
|
+
if persona != ancestor
|
|
1210
|
+
i = parent(persona)
|
|
1211
|
+
loop do
|
|
1212
|
+
break unless i != ancestor
|
|
1213
|
+
if i.has?(:container) && i.hasnt?(:open)
|
|
1214
|
+
return true if flag1
|
|
1215
|
+
return L__M(:Take, 9, i)
|
|
1216
|
+
end
|
|
1217
|
+
i = parent(i)
|
|
1218
|
+
end
|
|
1219
|
+
end
|
|
1220
|
+
|
|
1221
|
+
# Second, a barrier between the item and the ancestor. The item can
|
|
1222
|
+
# be carried by someone, part of a piece of machinery, in or on top
|
|
1223
|
+
# of something and so on.
|
|
1224
|
+
|
|
1225
|
+
if item != ancestor
|
|
1226
|
+
i = parent(item)
|
|
1227
|
+
loop do
|
|
1228
|
+
break unless !i.nil? && i != ancestor
|
|
1229
|
+
if flag2 && i.hasnt?(:container, :supporter) # && i.hasnt?(:supporter)
|
|
1230
|
+
if i.has?(:animate)
|
|
1231
|
+
return true if flag1
|
|
1232
|
+
return L__M(:Take, 6, i)
|
|
1233
|
+
end
|
|
1234
|
+
if i.has?(:transparent)
|
|
1235
|
+
return true if flag1
|
|
1236
|
+
return L__M(:Take, 7, i)
|
|
1237
|
+
end
|
|
1238
|
+
return true if flag1
|
|
1239
|
+
return L__M(:Take, 8, item)
|
|
1240
|
+
end
|
|
1241
|
+
if !i.nil? && i.has?(:container) && i.hasnt?(:open)
|
|
1242
|
+
return true if flag1
|
|
1243
|
+
return L__M(:Take, 9, i)
|
|
1244
|
+
end
|
|
1245
|
+
i = parent(i)
|
|
1246
|
+
end
|
|
1247
|
+
end
|
|
1248
|
+
end
|
|
1249
|
+
# if ancestor.nil?
|
|
1250
|
+
|
|
1251
|
+
return false
|
|
1252
|
+
end
|
|
1253
|
+
# def ObjectIsUntouchable
|
|
1254
|
+
|
|
1255
|
+
def AttemptToTakeObject(item)
|
|
1256
|
+
# Try to transfer the given item to the player: return false
|
|
1257
|
+
# if successful, true if unsuccessful, printing a suitable message
|
|
1258
|
+
# in the latter case.
|
|
1259
|
+
# People cannot ordinarily be taken.
|
|
1260
|
+
if item == @player then println L__M(:Take, 2); return true; end
|
|
1261
|
+
if item.has? :animate then println L__M(:Take, 3, item); return true; end
|
|
1262
|
+
|
|
1263
|
+
ancestor = CommonAncestor(@player, item)
|
|
1264
|
+
|
|
1265
|
+
if ancestor.nil?
|
|
1266
|
+
i = ObjectScopedBySomething(item)
|
|
1267
|
+
ancestor = CommonAncestor(@player, i) if i
|
|
1268
|
+
end
|
|
1269
|
+
|
|
1270
|
+
# Is the player indirectly inside the item?
|
|
1271
|
+
return L__M(:Take, 4, item) if ancestor == item
|
|
1272
|
+
|
|
1273
|
+
# Does the player already directly contain the item?
|
|
1274
|
+
return L__M(:Take, 5, item) if item.in? @player
|
|
1275
|
+
|
|
1276
|
+
# Can the player touch the item, or is there (e.g.) a closed container
|
|
1277
|
+
# in the way?
|
|
1278
|
+
return true if ObjectIsUntouchable(item, false, true)
|
|
1279
|
+
|
|
1280
|
+
# The item is now known to be accessible.
|
|
1281
|
+
|
|
1282
|
+
# Consult the immediate possessor of the item, if it's in a container
|
|
1283
|
+
# which the player is not in.
|
|
1284
|
+
|
|
1285
|
+
i = parent(item)
|
|
1286
|
+
if i != ancestor && i.hasany?(:container, :supporter)
|
|
1287
|
+
after_recipient = i
|
|
1288
|
+
k = @action; @action = :LetGo
|
|
1289
|
+
j = RunRoutines(i, :before)
|
|
1290
|
+
@action = k
|
|
1291
|
+
return true if j
|
|
1292
|
+
end
|
|
1293
|
+
|
|
1294
|
+
if item.has? :scenery then println L__M(:Take, 10, item); return true; end
|
|
1295
|
+
if item.has? :static then println L__M(:Take, 11, item); return true; end
|
|
1296
|
+
|
|
1297
|
+
# The item is now known to be available for taking. Is the player
|
|
1298
|
+
# carrying too much? If so, possibly juggle items into the rucksack
|
|
1299
|
+
# to make room.
|
|
1300
|
+
|
|
1301
|
+
k = 0; @player.objectloop { |j2| k += 1 if j2.hasnt? :worn }
|
|
1302
|
+
|
|
1303
|
+
if ValueOrRun(@player, :capacity) < k
|
|
1304
|
+
# TODO: FIXME
|
|
1305
|
+
# return L__M(:Take, 12) if SACK_OBJECT.nil?
|
|
1306
|
+
#
|
|
1307
|
+
# if SACK_OBJECT.parent != @player
|
|
1308
|
+
# return L__M(:Take, 12)
|
|
1309
|
+
# end
|
|
1310
|
+
# j = nil
|
|
1311
|
+
# @player.objectloop { |k|
|
|
1312
|
+
# if k != SACK_OBJECT && k.hasnt?(:worn) && k.hasnt?(:light); j = k; end
|
|
1313
|
+
# }
|
|
1314
|
+
#
|
|
1315
|
+
# if !j.nil?
|
|
1316
|
+
# L__M(:Take, 13, j)
|
|
1317
|
+
# @keep_silent = true; Insert j, SACK_OBJECT; keep_silent = false
|
|
1318
|
+
# return true if !j < SACK_OBJECT
|
|
1319
|
+
# end
|
|
1320
|
+
#
|
|
1321
|
+
# return L__M(:Take, 12)
|
|
1322
|
+
end
|
|
1323
|
+
|
|
1324
|
+
# Transfer the item.
|
|
1325
|
+
|
|
1326
|
+
@player.publish L__M(:Take, 15, noun)
|
|
1327
|
+
move item, @player
|
|
1328
|
+
|
|
1329
|
+
# Send "after" message to the object letting go of the item, if any.
|
|
1330
|
+
|
|
1331
|
+
unless after_recipient.nil?
|
|
1332
|
+
k = @action; @action = :LetGo
|
|
1333
|
+
j = RunRoutines(after_recipient, :after)
|
|
1334
|
+
@action = k
|
|
1335
|
+
return true if j
|
|
1336
|
+
end
|
|
1337
|
+
return false
|
|
1338
|
+
end
|
|
1339
|
+
|
|
1340
|
+
# ----------------------------------------------------------------------------
|
|
1341
|
+
# Object movement verbs
|
|
1342
|
+
# ----------------------------------------------------------------------------
|
|
1343
|
+
|
|
1344
|
+
def TakeSub
|
|
1345
|
+
i = parent(noun)
|
|
1346
|
+
if noun.notin?(@player) || !@onotheld_mode
|
|
1347
|
+
return true if AttemptToTakeObject(noun)
|
|
1348
|
+
end
|
|
1349
|
+
return true if AfterRoutines()
|
|
1350
|
+
@notheld_mode = @onotheld_mode
|
|
1351
|
+
return true if @notheld_mode || @keep_silent
|
|
1352
|
+
L__M(:Take, 1)
|
|
1353
|
+
end
|
|
1354
|
+
|
|
1355
|
+
def RemoveSub
|
|
1356
|
+
i = parent(noun)
|
|
1357
|
+
return L__M(:Remove, 1, noun) if i.has?(:container) && i.hasnt?(:open)
|
|
1358
|
+
return L__M(:Remove, 2, noun) if i != second
|
|
1359
|
+
return L__M(:Take, 6, i) if i.has? :animate
|
|
1360
|
+
return true if AttemptToTakeObject(noun)
|
|
1361
|
+
@action = :Remove; return true if AfterRoutines()
|
|
1362
|
+
@action = :Take; return true if AfterRoutines()
|
|
1363
|
+
return true if @keep_silent
|
|
1364
|
+
second = i if second.nil? || i == @location # TODO: FIXME
|
|
1365
|
+
return L__M(:Remove, 3, noun)
|
|
1366
|
+
end
|
|
1367
|
+
|
|
1368
|
+
def DropSub
|
|
1369
|
+
return L__M(:PutOn, 4) if noun == @player
|
|
1370
|
+
return L__M(:Drop, 1, noun) if noun.in? @player.parent
|
|
1371
|
+
return L__M(:Drop, 2, noun) if noun.notin? @player
|
|
1372
|
+
if noun.has? :worn
|
|
1373
|
+
L__M(:Drop, 3, noun)
|
|
1374
|
+
disrobe noun
|
|
1375
|
+
return true if noun.in?(@player) && noun.has?(:worn)
|
|
1376
|
+
end
|
|
1377
|
+
move noun, @player.parent
|
|
1378
|
+
return true if AfterRoutines()
|
|
1379
|
+
return true if @keep_silent
|
|
1380
|
+
@player.publish L__M(:Drop, 5, noun)
|
|
1381
|
+
return L__M(:Drop, 4, noun)
|
|
1382
|
+
end
|
|
1383
|
+
|
|
1384
|
+
def PutOnSub
|
|
1385
|
+
@receive_action = :PutOn
|
|
1386
|
+
# return drop noun end if second == $d_obj || @player.in?(second) # TODO: FIXME
|
|
1387
|
+
return invoke(:Drop, noun) if second == $d_obj || @player.in?(second)
|
|
1388
|
+
return L__M(:Drop, 1, noun) if parent(noun) == second
|
|
1389
|
+
return L__M(:PutOn, 1, noun) if parent(noun) != @player
|
|
1390
|
+
|
|
1391
|
+
ancestor = CommonAncestor(noun, second)
|
|
1392
|
+
return L__M(:PutOn, 2, noun) if ancestor == noun
|
|
1393
|
+
return if ObjectIsUntouchable(second)
|
|
1394
|
+
|
|
1395
|
+
if second != ancestor
|
|
1396
|
+
@action = :Receive
|
|
1397
|
+
if RunRoutines(second, :before) then @action = :PutOn; return; end
|
|
1398
|
+
@action = :PutOn
|
|
1399
|
+
end
|
|
1400
|
+
return L__M(:PutOn, 3, second) if second.hasnt? :supporter
|
|
1401
|
+
return L__M(:PutOn, 4) if ancestor == @player
|
|
1402
|
+
if noun.has? :worn
|
|
1403
|
+
L__M(:PutOn, 5, noun); disrobe noun; return if noun.has? :worn
|
|
1404
|
+
end
|
|
1405
|
+
|
|
1406
|
+
if children(second) >= ValueOrRun(second, :capacity)
|
|
1407
|
+
return L__M(:PutOn, 6, second)
|
|
1408
|
+
end
|
|
1409
|
+
|
|
1410
|
+
move noun, second
|
|
1411
|
+
|
|
1412
|
+
return if AfterRoutines()
|
|
1413
|
+
|
|
1414
|
+
if second != ancestor
|
|
1415
|
+
@action = :Receive
|
|
1416
|
+
if RunRoutines(second, :after) then @action = :PutOn; return true; end
|
|
1417
|
+
@action = :PutOn
|
|
1418
|
+
end
|
|
1419
|
+
return if @keep_silent
|
|
1420
|
+
@player.publish L__M(:PutOn, 9, noun)
|
|
1421
|
+
return L__M(:PutOn, 7) if @multiflag
|
|
1422
|
+
L__M(:PutOn, 8, noun)
|
|
1423
|
+
end
|
|
1424
|
+
|
|
1425
|
+
def InsertSub
|
|
1426
|
+
@receive_action = :Insert
|
|
1427
|
+
return drop noun if second == $d_obj || @player.in?(second)
|
|
1428
|
+
return L__M(:Drop, 1, noun) if noun.parent == second
|
|
1429
|
+
return L__M(:Insert, 1, noun) if noun.parent != @player
|
|
1430
|
+
|
|
1431
|
+
ancestor = CommonAncestor(noun, second)
|
|
1432
|
+
return L__M(:Insert, 5, noun) if ancestor == noun
|
|
1433
|
+
return if ObjectIsUntouchable(second)
|
|
1434
|
+
|
|
1435
|
+
if second != ancestor
|
|
1436
|
+
@action = :Receive
|
|
1437
|
+
if RunRoutines(second, :before) then @action = :Insert; return true; end
|
|
1438
|
+
@action = :Insert
|
|
1439
|
+
if second.has?(:container) && second.hasnt?(:open)
|
|
1440
|
+
return L__M(:Insert, 3, second)
|
|
1441
|
+
end
|
|
1442
|
+
end
|
|
1443
|
+
return L__M(:Insert, 2, second) if second.hasnt? :container
|
|
1444
|
+
|
|
1445
|
+
if noun.has? :worn
|
|
1446
|
+
L__M(:Insert, 6, noun); disrobe noun; return if noun.has? :worn
|
|
1447
|
+
end
|
|
1448
|
+
|
|
1449
|
+
if children(second) >= ValueOrRun(second, :capacity)
|
|
1450
|
+
return L__M(:Insert, 7, second)
|
|
1451
|
+
end
|
|
1452
|
+
|
|
1453
|
+
move noun, second
|
|
1454
|
+
|
|
1455
|
+
return true if AfterRoutines()
|
|
1456
|
+
|
|
1457
|
+
if second != ancestor
|
|
1458
|
+
@action = :Receive
|
|
1459
|
+
if RunRoutines(second, :after) then @action = :Insert; return true; end
|
|
1460
|
+
@action = :Insert
|
|
1461
|
+
end
|
|
1462
|
+
return true if @keep_silent
|
|
1463
|
+
@player.publish L__M(:Insert, 10, noun)
|
|
1464
|
+
return L__M(:Insert, 8, noun) if @multiflag
|
|
1465
|
+
L__M(:Insert, 9, noun)
|
|
1466
|
+
end
|
|
1467
|
+
|
|
1468
|
+
# ----------------------------------------------------------------------------
|
|
1469
|
+
# Empties and transfers are routed through the actions above
|
|
1470
|
+
# ----------------------------------------------------------------------------
|
|
1471
|
+
|
|
1472
|
+
def TransferSub
|
|
1473
|
+
return if noun.notin?(@player) && AttemptToTakeObject(noun)
|
|
1474
|
+
invoke :PutOn, noun, second if second.has? :supporter
|
|
1475
|
+
invoke :Drop, noun if second == $d_obj
|
|
1476
|
+
invoke :Insert, noun, second
|
|
1477
|
+
end
|
|
1478
|
+
|
|
1479
|
+
def EmptySub; @second = $d_obj; EmptyTSub(); end
|
|
1480
|
+
|
|
1481
|
+
def EmptyTSub
|
|
1482
|
+
return L__M(:EmptyT, 4) if noun == second
|
|
1483
|
+
return if ObjectIsUntouchable(noun)
|
|
1484
|
+
return L__M(:EmptyT, 1, noun) if noun.hasnt? :container
|
|
1485
|
+
return L__M(:EmptyT, 2, noun) if noun.hasnt? :open
|
|
1486
|
+
if second != $d_obj # && second != parent(@player)
|
|
1487
|
+
if second.hasnt? :supporter
|
|
1488
|
+
return L__M(:EmptyT, 1, second) if second.hasnt? :container
|
|
1489
|
+
return L__M(:EmptyT, 2, second) if second.hasnt? :open
|
|
1490
|
+
end
|
|
1491
|
+
end
|
|
1492
|
+
i = child(noun); k = children(noun)
|
|
1493
|
+
return L__M(:EmptyT, 3, noun) unless i
|
|
1494
|
+
loop do
|
|
1495
|
+
break if i.nil?
|
|
1496
|
+
j = i.sibling
|
|
1497
|
+
flag = false
|
|
1498
|
+
flag = true if ObjectIsUntouchable(noun)
|
|
1499
|
+
flag = true if noun.hasnt? :container
|
|
1500
|
+
flag = true if noun.hasnt? :open
|
|
1501
|
+
if second != $d_obj
|
|
1502
|
+
if second.hasnt? :supporter
|
|
1503
|
+
flag = true if second.hasnt? :container
|
|
1504
|
+
flag = true if second.hasnt? :open
|
|
1505
|
+
end
|
|
1506
|
+
end
|
|
1507
|
+
flag = true if k == 0
|
|
1508
|
+
k -= 1
|
|
1509
|
+
break if flag
|
|
1510
|
+
print i + ": " unless @keep_silent
|
|
1511
|
+
_invoke :Transfer, i, second
|
|
1512
|
+
i = j
|
|
1513
|
+
end
|
|
1514
|
+
end
|
|
1515
|
+
|
|
1516
|
+
# ----------------------------------------------------------------------------
|
|
1517
|
+
# Gifts
|
|
1518
|
+
# ----------------------------------------------------------------------------
|
|
1519
|
+
|
|
1520
|
+
def GiveSub
|
|
1521
|
+
return L__M(:Give, 1, noun) if parent(noun) != @player
|
|
1522
|
+
if second == @player
|
|
1523
|
+
@player.publish A(player) + " juggles " + a(noun) + " for a second or two."
|
|
1524
|
+
return L__M(:Give, 2, noun)
|
|
1525
|
+
end
|
|
1526
|
+
return false if RunLife(second, :Give)
|
|
1527
|
+
L__M(:Give, 3, second)
|
|
1528
|
+
end
|
|
1529
|
+
|
|
1530
|
+
def GiveRSub; _invoke :Give, second, noun; end
|
|
1531
|
+
|
|
1532
|
+
def ShowSub
|
|
1533
|
+
return L__M(:Show, 1, noun) if parent(noun) != @player
|
|
1534
|
+
_invoke :Examine, noun if second == @player
|
|
1535
|
+
return false if RunLife(second, :Show)
|
|
1536
|
+
L__M(:Show, 2, second)
|
|
1537
|
+
end
|
|
1538
|
+
|
|
1539
|
+
def ShowRSub; _invoke :Show, second, noun; end
|
|
1540
|
+
|
|
1541
|
+
# ----------------------------------------------------------------------------
|
|
1542
|
+
# Travelling around verbs
|
|
1543
|
+
# ----------------------------------------------------------------------------
|
|
1544
|
+
|
|
1545
|
+
def EnterSub
|
|
1546
|
+
# return go noun if noun.in?(Compass) || noun.has?(:door) # TODO: FIXME
|
|
1547
|
+
return invoke(:Go, noun) if noun.in?(Compass) || noun.has?(:door)
|
|
1548
|
+
|
|
1549
|
+
return L__M(:Enter, 1, noun) if @player.in? noun
|
|
1550
|
+
return L__M(:Enter, 2, noun) if noun.hasnt? :enterable
|
|
1551
|
+
return L__M(:Enter, 3, noun) if noun.has?(:container) && noun.hasnt?(:open)
|
|
1552
|
+
|
|
1553
|
+
if parent(@player) != parent(noun)
|
|
1554
|
+
ancestor = CommonAncestor(@player, noun)
|
|
1555
|
+
return L__M(:Enter, 4, noun) if ancestor == @player || ancestor.nil?
|
|
1556
|
+
loop do
|
|
1557
|
+
break if @player.in?(ancestor)
|
|
1558
|
+
j = parent(@player)
|
|
1559
|
+
k = @keep_silent
|
|
1560
|
+
if parent(j) != ancestor || noun != ancestor
|
|
1561
|
+
L__M(:Enter, 6, j)
|
|
1562
|
+
@keep_silent = true
|
|
1563
|
+
end
|
|
1564
|
+
_invoke :Exit
|
|
1565
|
+
@keep_silent = k
|
|
1566
|
+
return if @player.in?(j)
|
|
1567
|
+
end
|
|
1568
|
+
return if @player.in?(noun)
|
|
1569
|
+
if noun.notin?(ancestor)
|
|
1570
|
+
j = parent(noun)
|
|
1571
|
+
loop do
|
|
1572
|
+
break if parent(j) == ancestor
|
|
1573
|
+
j = parent(j)
|
|
1574
|
+
end
|
|
1575
|
+
L__M(:Enter, 7, j)
|
|
1576
|
+
_invoke :Enter, j
|
|
1577
|
+
return if @player.notin?(j)
|
|
1578
|
+
return invoke(:Enter, noun)
|
|
1579
|
+
end
|
|
1580
|
+
end
|
|
1581
|
+
|
|
1582
|
+
move @player, noun
|
|
1583
|
+
return true if AfterRoutines()
|
|
1584
|
+
return true if @keep_silent
|
|
1585
|
+
Locale(noun)
|
|
1586
|
+
@player.publish L__M(:Enter, 8, noun)
|
|
1587
|
+
L__M(:Enter, 5, noun)
|
|
1588
|
+
end
|
|
1589
|
+
|
|
1590
|
+
def GetOffSub
|
|
1591
|
+
_invoke :Exit if parent(@player) == noun
|
|
1592
|
+
L__M(:GetOff, 1, noun)
|
|
1593
|
+
end
|
|
1594
|
+
|
|
1595
|
+
def ExitSub
|
|
1596
|
+
parent_obj = parent(@player)
|
|
1597
|
+
return L__M(:Exit, 4, noun) if !noun.nil? && noun != parent_obj
|
|
1598
|
+
if parent_obj == @location || (@location == thedark && parent_obj == @real_location)
|
|
1599
|
+
if @location.&(:out_to) || (@location == thedark && @real_location.&(:out_to))
|
|
1600
|
+
invoke :Go, $out_obj
|
|
1601
|
+
end
|
|
1602
|
+
return L__M(:Exit, 1)
|
|
1603
|
+
end
|
|
1604
|
+
return L__M(:Exit, 2, parent_obj) if parent_obj.has?(:container) && parent_obj.hasnt?(:open)
|
|
1605
|
+
|
|
1606
|
+
move @player, parent(parent_obj)
|
|
1607
|
+
stand @player
|
|
1608
|
+
|
|
1609
|
+
return true if AfterRoutines()
|
|
1610
|
+
return true if @keep_silent
|
|
1611
|
+
@player.publish L__M(:Exit, 5, parent_obj)
|
|
1612
|
+
L__M(:Exit, 3, parent_obj)
|
|
1613
|
+
LookSub(true)
|
|
1614
|
+
end
|
|
1615
|
+
|
|
1616
|
+
def VagueGoSub; L__M(:VagueGo); end
|
|
1617
|
+
|
|
1618
|
+
def GoInSub; go $in_obj; end
|
|
1619
|
+
|
|
1620
|
+
def GoSub
|
|
1621
|
+
i = @player.parent
|
|
1622
|
+
return RunTimeError(10) if i.nil?
|
|
1623
|
+
RunRoutines(@player, :before) # Attempt to allow for route recollection TODO: Evaluate if necessary
|
|
1624
|
+
|
|
1625
|
+
# first, check if any PushDir object is touchable
|
|
1626
|
+
return if !second.nil? && !second.in?(Compass) && ObjectIsUntouchable(second)
|
|
1627
|
+
|
|
1628
|
+
old_loc = @location
|
|
1629
|
+
movewith = nil
|
|
1630
|
+
if (@location != thedark && i != @location) || (@location == thedark && i != @real_location)
|
|
1631
|
+
j = @location
|
|
1632
|
+
@location = @real_location if @location == thedark
|
|
1633
|
+
k = RunRoutines(i, :before); @location = j if k != 3
|
|
1634
|
+
if k
|
|
1635
|
+
movewith = i; i = i.parent
|
|
1636
|
+
else
|
|
1637
|
+
L__M(:Go,1,i) unless k
|
|
1638
|
+
return true
|
|
1639
|
+
end
|
|
1640
|
+
end
|
|
1641
|
+
|
|
1642
|
+
return L__M(:Go, 6, noun) if noun.door_dir.nil?
|
|
1643
|
+
|
|
1644
|
+
thedir = noun.door_dir
|
|
1645
|
+
|
|
1646
|
+
j = i.&(thedir)
|
|
1647
|
+
return true if j == true
|
|
1648
|
+
if j && j.is_a?(String) then print j.to_s; new_line; return false; end
|
|
1649
|
+
|
|
1650
|
+
unless j
|
|
1651
|
+
if i.respond_to?(:cant_go) && i.cant_go != CANTGO__TX then PrintOrRun(i, :cant_go)
|
|
1652
|
+
else L__M(:Go,2)
|
|
1653
|
+
end
|
|
1654
|
+
return false
|
|
1655
|
+
end
|
|
1656
|
+
|
|
1657
|
+
if j.has? :door
|
|
1658
|
+
return L__M(:Go, 2) if j.has? :concealed
|
|
1659
|
+
if j.hasnt? :open
|
|
1660
|
+
return L__M(:Go, 3, j) if noun == $u_obj
|
|
1661
|
+
return L__M(:Go, 4, j) if noun == $d_obj
|
|
1662
|
+
return L__M(:Go, 5, j)
|
|
1663
|
+
end
|
|
1664
|
+
k = RunRoutines(j,:door_to)
|
|
1665
|
+
if k == false then return L__M(:Go, 6, j) end
|
|
1666
|
+
if k == true then return true end
|
|
1667
|
+
j = k
|
|
1668
|
+
end
|
|
1669
|
+
|
|
1670
|
+
orig_loc = @real_location
|
|
1671
|
+
@player.publish L__M(:Go, 7, noun) unless @keep_silent
|
|
1672
|
+
|
|
1673
|
+
if movewith.nil? then move @player, j else move movewith, j end
|
|
1674
|
+
|
|
1675
|
+
light_adjusted @player
|
|
1676
|
+
|
|
1677
|
+
# Special addition for ensuring location is never forgotten after player logout.
|
|
1678
|
+
@player.link :location, j
|
|
1679
|
+
@player.descendants.each do |o|
|
|
1680
|
+
o.link :location, j if o.linked? :location
|
|
1681
|
+
end
|
|
1682
|
+
movewith.link :location, j if !movewith.nil? && movewith.linked?(:location)
|
|
1683
|
+
|
|
1684
|
+
@location = j; MoveFloatingObjects();
|
|
1685
|
+
if OffersLight(j)
|
|
1686
|
+
@location = j; @real_location = j; @lightflag = true
|
|
1687
|
+
else
|
|
1688
|
+
if old_loc == thedark
|
|
1689
|
+
DarkToDark()
|
|
1690
|
+
return true if @deadflag
|
|
1691
|
+
end
|
|
1692
|
+
@real_location = j
|
|
1693
|
+
@location = thedark; @lightflag = false
|
|
1694
|
+
end
|
|
1695
|
+
|
|
1696
|
+
@player.publish L__M(:Go, 8, ArrivalDir(j, orig_loc)) unless @keep_silent
|
|
1697
|
+
|
|
1698
|
+
return true if AfterRoutines()
|
|
1699
|
+
return true if @keep_silent
|
|
1700
|
+
LookSub(true)
|
|
1701
|
+
end
|
|
1702
|
+
|
|
1703
|
+
def ArrivalDir(dest, source = @real_location)
|
|
1704
|
+
link = dest.links.find { |l| l.to == source }
|
|
1705
|
+
return nil if link.nil?
|
|
1706
|
+
# TODO: Doesn't work for door objects FIXME
|
|
1707
|
+
direc = Compass.find { |dir| dir.door_dir == link.name.to_sym }
|
|
1708
|
+
end
|
|
1709
|
+
|
|
1710
|
+
# ----------------------------------------------------------------------------
|
|
1711
|
+
# Describing the world. SayWhatsOn(object) does just that (producing
|
|
1712
|
+
# no text if nothing except possibly "scenery" and "concealed" items are).
|
|
1713
|
+
# Locale(object) runs through the "tail end" of a Look-style room
|
|
1714
|
+
# description for the contents of the object, printing up suitable
|
|
1715
|
+
# descriptions as it goes.
|
|
1716
|
+
# ----------------------------------------------------------------------------
|
|
1717
|
+
|
|
1718
|
+
def SayWhatsOn(descon)
|
|
1719
|
+
return false if descon == parent(@player)
|
|
1720
|
+
f = descon.any? { |j| j.hasnt?(:concealed) && j.hasnt?(:scenery) }
|
|
1721
|
+
return false unless f
|
|
1722
|
+
println L__M(:Look, 4, descon)
|
|
1723
|
+
end
|
|
1724
|
+
|
|
1725
|
+
def NotSupportingThePlayer(o)
|
|
1726
|
+
i = parent(@player)
|
|
1727
|
+
loop do
|
|
1728
|
+
break if i.nil? || i == @visibility_ceiling
|
|
1729
|
+
return false if i == o
|
|
1730
|
+
i = parent(i)
|
|
1731
|
+
return true if !i.nil? && i.hasnt?(:supporter)
|
|
1732
|
+
end
|
|
1733
|
+
true
|
|
1734
|
+
end
|
|
1735
|
+
|
|
1736
|
+
def Locale(descin, text1 = nil, text2 = nil, flag = false)
|
|
1737
|
+
descin.each { |o| take o, :workflag }
|
|
1738
|
+
k = 0
|
|
1739
|
+
n = 0
|
|
1740
|
+
descin.each do |obj|
|
|
1741
|
+
# Only doing this because the player may no longer be concealed if
|
|
1742
|
+
# the player is to be visible to other players.
|
|
1743
|
+
next if obj == @player || obj.has?(:concealed)
|
|
1744
|
+
|
|
1745
|
+
next unless obj.hasnt?(:concealed) && NotSupportingThePlayer(obj)
|
|
1746
|
+
unless defined? MANUAL_PRONOUNS
|
|
1747
|
+
PronounNotice(obj)
|
|
1748
|
+
end
|
|
1749
|
+
|
|
1750
|
+
give obj, :workflag
|
|
1751
|
+
k += 1
|
|
1752
|
+
property = :initial; f2 = 0
|
|
1753
|
+
|
|
1754
|
+
if obj.hasnt? :scenery
|
|
1755
|
+
if (obj.has?(:door) || obj.has?(:container)) && obj.has?(:open) && obj.respond_to?(:when_open)
|
|
1756
|
+
property = :when_open; f2 = 1
|
|
1757
|
+
elsif (obj.has?(:door) || obj.has?(:container)) && obj.hasnt?(:open) && obj.respond_to?(:when_closed)
|
|
1758
|
+
property = :when_closed; f2 = 1
|
|
1759
|
+
elsif obj.has?(:switchable) && obj.has?(:on) && obj.respond_to?(:when_on)
|
|
1760
|
+
property = :when_on; f2 = 1
|
|
1761
|
+
elsif obj.has?(:switchable) && obj.hasnt?(:on) && obj.respond_to?(:when_off)
|
|
1762
|
+
property = :when_off; f2 = 1
|
|
1763
|
+
end
|
|
1764
|
+
|
|
1765
|
+
if obj.hasnt?(:moved) || obj.respond_to?(:describe) || f2 == 1
|
|
1766
|
+
if obj.respond_to?(:describe) && RunRoutines(obj, :describe)
|
|
1767
|
+
flag = true
|
|
1768
|
+
take obj, :workflag; k -= 1
|
|
1769
|
+
else
|
|
1770
|
+
j = obj.&property
|
|
1771
|
+
unless j.nil?
|
|
1772
|
+
new_line
|
|
1773
|
+
PrintOrRun(obj, property)
|
|
1774
|
+
flag = true
|
|
1775
|
+
take obj, :workflag; k -= 1
|
|
1776
|
+
SayWhatsOn(obj) if obj.has?(:supporter) && !child(obj).nil?
|
|
1777
|
+
end
|
|
1778
|
+
end
|
|
1779
|
+
end
|
|
1780
|
+
elsif obj.has?(:supporter) && !child(obj).nil?
|
|
1781
|
+
SayWhatsOn(obj)
|
|
1782
|
+
end
|
|
1783
|
+
end
|
|
1784
|
+
# descin.each do
|
|
1785
|
+
|
|
1786
|
+
return 0 if k == 0
|
|
1787
|
+
|
|
1788
|
+
if !text1.nil? && !text1.empty?
|
|
1789
|
+
new_line
|
|
1790
|
+
text1 = text2 if flag
|
|
1791
|
+
print text1 + " "
|
|
1792
|
+
WriteListFrom(child(descin), ENGLISH_BIT + RECURSE_BIT + PARTINV_BIT +
|
|
1793
|
+
TERSE_BIT + CONCEAL_BIT + WORKFLAG_BIT)
|
|
1794
|
+
return k + j
|
|
1795
|
+
end
|
|
1796
|
+
|
|
1797
|
+
if flag then println L__M(:Look, 5, descin)
|
|
1798
|
+
else println L__M(:Look, 6, descin)
|
|
1799
|
+
end
|
|
1800
|
+
end
|
|
1801
|
+
|
|
1802
|
+
# ----------------------------------------------------------------------------
|
|
1803
|
+
# Looking. LookSub(true) is allowed to abbreviate long descriptions, but
|
|
1804
|
+
# LookSub(false) (which is what happens when the Look action is generated)
|
|
1805
|
+
# isn't. (Except that these are over-ridden by the player-set lookmode.)
|
|
1806
|
+
# ----------------------------------------------------------------------------
|
|
1807
|
+
|
|
1808
|
+
def LMode1Sub; @lookmode = 1; print Story; L__M(:LMode1); end # Brief
|
|
1809
|
+
|
|
1810
|
+
def LMode2Sub; @lookmode = 2; print Story; L__M(:LMode2); end # Verbose
|
|
1811
|
+
|
|
1812
|
+
def LMode3Sub; @lookmode = 3; print Story; L__M(:LMode3); end # Superbrief
|
|
1813
|
+
|
|
1814
|
+
def ScoreArrival
|
|
1815
|
+
# unless @player.visited.include?(@location)
|
|
1816
|
+
# @player.visited.push @location
|
|
1817
|
+
# if @location.has? :scored
|
|
1818
|
+
# score = score + ROOM_SCORE
|
|
1819
|
+
# places_score = places_score + ROOM_SCORE
|
|
1820
|
+
# end
|
|
1821
|
+
# end
|
|
1822
|
+
end
|
|
1823
|
+
|
|
1824
|
+
def NoteArrival
|
|
1825
|
+
if @location == thedark
|
|
1826
|
+
@lastdesc = thedark
|
|
1827
|
+
return
|
|
1828
|
+
end
|
|
1829
|
+
return if @location == @lastdesc
|
|
1830
|
+
PrintOrRun(@location, :initial) if @location.respond_to? :initial
|
|
1831
|
+
descin = @location
|
|
1832
|
+
NewRoom()
|
|
1833
|
+
@lastdesc = descin
|
|
1834
|
+
end
|
|
1835
|
+
|
|
1836
|
+
def FindVisibilityLevels
|
|
1837
|
+
@visibility_levels = 1
|
|
1838
|
+
@visibility_ceiling = parent(@player)
|
|
1839
|
+
loop do
|
|
1840
|
+
break unless parent(@visibility_ceiling) &&
|
|
1841
|
+
(@visibility_ceiling.hasnt?(:container) || @visibility_ceiling.hasany?(:open, :transparent))
|
|
1842
|
+
@visibility_ceiling = parent(@visibility_ceiling)
|
|
1843
|
+
@visibility_levels += 1
|
|
1844
|
+
end
|
|
1845
|
+
@visibility_levels
|
|
1846
|
+
end
|
|
1847
|
+
|
|
1848
|
+
def LookSub(allow_abbrev = nil)
|
|
1849
|
+
allow_abbrev = false if allow_abbrev.nil?
|
|
1850
|
+
return RunTimeError(10) if parent(@player).nil?
|
|
1851
|
+
|
|
1852
|
+
if OffersLight(@real_location)
|
|
1853
|
+
@location = @real_location; @lightflag = true
|
|
1854
|
+
else
|
|
1855
|
+
@location = thedark; @lightflag = false
|
|
1856
|
+
end
|
|
1857
|
+
|
|
1858
|
+
if @location == thedark
|
|
1859
|
+
@visibility_levels = 0
|
|
1860
|
+
@visibility_ceiling = thedark
|
|
1861
|
+
NoteArrival()
|
|
1862
|
+
else
|
|
1863
|
+
@visibility_levels = FindVisibilityLevels()
|
|
1864
|
+
if @visibility_ceiling == @location
|
|
1865
|
+
NoteArrival()
|
|
1866
|
+
if @visibility_ceiling != @location
|
|
1867
|
+
# TODO: Remove or figure this out.
|
|
1868
|
+
log.warn "Not sure why this would ever happen"
|
|
1869
|
+
return "The visibility ceiling is no longer the same as the " +
|
|
1870
|
+
"location. This is probably a very serious error."
|
|
1871
|
+
end
|
|
1872
|
+
end
|
|
1873
|
+
end
|
|
1874
|
+
|
|
1875
|
+
# Printing the top line: e.g.
|
|
1876
|
+
# Octagonal Room (on the table) (as Frodo)
|
|
1877
|
+
new_line
|
|
1878
|
+
style :bold
|
|
1879
|
+
color :yellow
|
|
1880
|
+
if @visibility_levels == 0
|
|
1881
|
+
print DARKNESS__TX
|
|
1882
|
+
else
|
|
1883
|
+
if @visibility_ceiling != @location then print The(@visibility_ceiling)
|
|
1884
|
+
else print name(@visibility_ceiling)
|
|
1885
|
+
end
|
|
1886
|
+
end
|
|
1887
|
+
uncolor :yellow
|
|
1888
|
+
unstyle :bold
|
|
1889
|
+
|
|
1890
|
+
j = 1
|
|
1891
|
+
i = @player.parent
|
|
1892
|
+
loop do
|
|
1893
|
+
break unless j < @visibility_levels
|
|
1894
|
+
if i.has?(:supporter)
|
|
1895
|
+
L__M(:Look, 1, i)
|
|
1896
|
+
else
|
|
1897
|
+
L__M(:Look, 2, i)
|
|
1898
|
+
end
|
|
1899
|
+
j += 1
|
|
1900
|
+
i = i.parent
|
|
1901
|
+
end
|
|
1902
|
+
|
|
1903
|
+
L__M(:Look, 3, @player) if @print_player_flag
|
|
1904
|
+
L__M(:Look, 9, @player) if @player.respond_to?(:builder?) && @player.builder?
|
|
1905
|
+
new_line
|
|
1906
|
+
|
|
1907
|
+
# TODO: FIXME
|
|
1908
|
+
# if @location.outside?
|
|
1909
|
+
# # PrintOrRun(region, :description) if @player.prefers? :verbose_regions
|
|
1910
|
+
# # PrintOrRun(area, :description) if @player.prefers? :verbose_areas
|
|
1911
|
+
# end
|
|
1912
|
+
|
|
1913
|
+
# The room description (if visible)
|
|
1914
|
+
|
|
1915
|
+
if @lookmode < 3 && @visibility_ceiling == @location
|
|
1916
|
+
if allow_abbrev == false || @lookmode == 2 || !@player.visited.include?(@location)
|
|
1917
|
+
if @location.respond_to? :describe
|
|
1918
|
+
RunRoutines(@location, :describe)
|
|
1919
|
+
else
|
|
1920
|
+
if @location.respond_to?(:description)
|
|
1921
|
+
PrintOrRun(@location, :description)
|
|
1922
|
+
else
|
|
1923
|
+
RunTimeError(11, @location)
|
|
1924
|
+
end
|
|
1925
|
+
end
|
|
1926
|
+
end
|
|
1927
|
+
end
|
|
1928
|
+
|
|
1929
|
+
nl_flag = true if @visibility_ceiling == @location
|
|
1930
|
+
|
|
1931
|
+
if @visibility_levels == 0
|
|
1932
|
+
Locale(thedark)
|
|
1933
|
+
else
|
|
1934
|
+
i = @player
|
|
1935
|
+
j = @visibility_levels
|
|
1936
|
+
loop do
|
|
1937
|
+
break unless j > 0
|
|
1938
|
+
give i, :workflag
|
|
1939
|
+
i = parent(i)
|
|
1940
|
+
j -= 1
|
|
1941
|
+
end
|
|
1942
|
+
|
|
1943
|
+
j = @visibility_levels
|
|
1944
|
+
loop do
|
|
1945
|
+
break unless j > 0
|
|
1946
|
+
k = 0
|
|
1947
|
+
i = @player
|
|
1948
|
+
loop do
|
|
1949
|
+
break unless k < j
|
|
1950
|
+
i = parent(i)
|
|
1951
|
+
k += 1
|
|
1952
|
+
end
|
|
1953
|
+
if i.respond_to? :inside_description
|
|
1954
|
+
if nl_flag
|
|
1955
|
+
new_line
|
|
1956
|
+
else
|
|
1957
|
+
nl_flag = true
|
|
1958
|
+
end
|
|
1959
|
+
PrintOrRun(i, :inside_description)
|
|
1960
|
+
end
|
|
1961
|
+
nl_flag = true if Locale(i)
|
|
1962
|
+
j -= 1
|
|
1963
|
+
end
|
|
1964
|
+
end
|
|
1965
|
+
|
|
1966
|
+
LookRoutine()
|
|
1967
|
+
ScoreArrival()
|
|
1968
|
+
|
|
1969
|
+
@action = :Look
|
|
1970
|
+
return true if AfterRoutines()
|
|
1971
|
+
false
|
|
1972
|
+
end
|
|
1973
|
+
|
|
1974
|
+
def ExamineSub
|
|
1975
|
+
return L__M(:Examine, 1) if @location == thedark
|
|
1976
|
+
unless @keep_silent
|
|
1977
|
+
if noun.has? :animate
|
|
1978
|
+
@action = :LookAt
|
|
1979
|
+
if noun.in?(@player)
|
|
1980
|
+
@player.publish A(@player) + " looks at " + hisorher(@player, noun) + "."
|
|
1981
|
+
elsif noun != @player
|
|
1982
|
+
@player.publish A(@player) + " looks over at " + a(noun) + "."
|
|
1983
|
+
end
|
|
1984
|
+
else
|
|
1985
|
+
if noun.in?(@player)
|
|
1986
|
+
@player.publish A(@player) + " examines " + hisorher(@player, noun) + "."
|
|
1987
|
+
else
|
|
1988
|
+
@player.publish A(@player) + " examines " + a(noun) + "."
|
|
1989
|
+
end
|
|
1990
|
+
end
|
|
1991
|
+
end
|
|
1992
|
+
i = noun.description
|
|
1993
|
+
# if noun.values[:description].nil? && noun.properties[:description].nil? && noun.&(:description).nil?
|
|
1994
|
+
if i.nil?
|
|
1995
|
+
return _invoke :Search, noun if noun.has? :container
|
|
1996
|
+
if noun.has? :switchable then L__M(:Examine, 3, noun); return false; end
|
|
1997
|
+
return L__M(:Examine, 2, noun)
|
|
1998
|
+
end
|
|
1999
|
+
PrintOrRun(noun, :description)
|
|
2000
|
+
L__M(:Examine, 3, noun) if noun.has? :switchable
|
|
2001
|
+
return true if AfterRoutines()
|
|
2002
|
+
end
|
|
2003
|
+
|
|
2004
|
+
def LookUnderSub
|
|
2005
|
+
return L__M(:LookUnder, 1) if @location == thedark
|
|
2006
|
+
@player.publish L__M(:LookUnder, 3, noun)
|
|
2007
|
+
L__M(:LookUnder, 2)
|
|
2008
|
+
end
|
|
2009
|
+
|
|
2010
|
+
def VisibleContents(o)
|
|
2011
|
+
o ? o.count { |i| i != @player && i.hasnt?(:concealed, :scenery) } : 0
|
|
2012
|
+
end
|
|
2013
|
+
|
|
2014
|
+
def SearchSub
|
|
2015
|
+
return L__M(:Search, 1, noun) if @location == thedark
|
|
2016
|
+
return if ObjectIsUntouchable(noun)
|
|
2017
|
+
f = VisibleContents(noun)
|
|
2018
|
+
if noun.has? :supporter
|
|
2019
|
+
@player.publish L__M(:Search, 8, noun) unless @keep_silent
|
|
2020
|
+
return L__M(:Search, 2, noun) if f == 0
|
|
2021
|
+
return L__M(:Search, 3, noun)
|
|
2022
|
+
end
|
|
2023
|
+
return L__M(:Search, 4, noun) if noun.hasnt? :container
|
|
2024
|
+
return L__M(:Search, 5, noun) if noun.hasnt?(:transparent) && noun.hasnt?(:open)
|
|
2025
|
+
return true if AfterRoutines()
|
|
2026
|
+
|
|
2027
|
+
@player.publish L__M(:Search, 8, noun) unless @keep_silent
|
|
2028
|
+
return L__M(:Search, 6, noun) if f == 0
|
|
2029
|
+
L__M(:Search, 7, noun)
|
|
2030
|
+
end
|
|
2031
|
+
|
|
2032
|
+
# ----------------------------------------------------------------------------
|
|
2033
|
+
# Verbs which change the state of objects without moving them
|
|
2034
|
+
# ----------------------------------------------------------------------------
|
|
2035
|
+
|
|
2036
|
+
def UnlockSub
|
|
2037
|
+
return if ObjectIsUntouchable(noun)
|
|
2038
|
+
return L__M(:Unlock, 1, noun) if noun.hasnt? :lockable
|
|
2039
|
+
return L__M(:Unlock, 2, noun) if noun.hasnt? :locked
|
|
2040
|
+
return L__M(:Unlock, 3, second) if noun.&(:with_key) != second
|
|
2041
|
+
take noun, :locked
|
|
2042
|
+
return true if AfterRoutines()
|
|
2043
|
+
return true if @keep_silent
|
|
2044
|
+
@player.publish L__M(:Unlock, 5, noun)
|
|
2045
|
+
L__M(:Unlock, 4, noun)
|
|
2046
|
+
end
|
|
2047
|
+
|
|
2048
|
+
def LockSub
|
|
2049
|
+
return if ObjectIsUntouchable(noun)
|
|
2050
|
+
return L__M(:Lock, 1, noun) if noun.hasnt? :lockable
|
|
2051
|
+
return L__M(:Lock, 2, noun) if noun.has? :locked
|
|
2052
|
+
return L__M(:Lock, 3, noun) if noun.has? :open
|
|
2053
|
+
return L__M(:Lock, 4, second) if noun.&(:with_key) != second
|
|
2054
|
+
give noun, :locked
|
|
2055
|
+
return true if AfterRoutines()
|
|
2056
|
+
return true if @keep_silent
|
|
2057
|
+
@player.publish L__M(:Lock, 6, noun)
|
|
2058
|
+
L__M(:Lock, 5, noun)
|
|
2059
|
+
end
|
|
2060
|
+
|
|
2061
|
+
def SwitchonSub
|
|
2062
|
+
return if ObjectIsUntouchable(noun)
|
|
2063
|
+
return L__M(:SwitchOn, 1, noun) if noun.hasnt? :switchable
|
|
2064
|
+
return L__M(:SwitchOn, 2, noun) if noun.has? :on
|
|
2065
|
+
give noun, :on
|
|
2066
|
+
return true if AfterRoutines()
|
|
2067
|
+
return true if @keep_silent
|
|
2068
|
+
@player.publish L__M(:SwitchOn, 4, noun)
|
|
2069
|
+
L__M(:SwitchOn, 3, noun)
|
|
2070
|
+
end
|
|
2071
|
+
|
|
2072
|
+
def SwitchoffSub
|
|
2073
|
+
return if ObjectIsUntouchable(noun)
|
|
2074
|
+
return L__M(:SwitchOff, 1, noun) if noun.hasnt? :switchable
|
|
2075
|
+
return L__M(:SwitchOff, 2, noun) if noun.hasnt? :on
|
|
2076
|
+
take noun, :on
|
|
2077
|
+
return true if AfterRoutines()
|
|
2078
|
+
return true if @keep_silent
|
|
2079
|
+
@player.publish L__M(:SwitchOff, 4, noun)
|
|
2080
|
+
L__M(:SwitchOff, 3, noun)
|
|
2081
|
+
end
|
|
2082
|
+
|
|
2083
|
+
def OpenSub
|
|
2084
|
+
return if ObjectIsUntouchable(noun)
|
|
2085
|
+
return L__M(:Open, 1, noun) if noun.hasnt? :openable
|
|
2086
|
+
return L__M(:Open, 2, noun) if noun.has? :locked
|
|
2087
|
+
return L__M(:Open, 3, noun) if noun.has? :open
|
|
2088
|
+
give noun, :open
|
|
2089
|
+
return true if AfterRoutines()
|
|
2090
|
+
return true if @keep_silent
|
|
2091
|
+
@player.publish L__M(:Open, 6, noun)
|
|
2092
|
+
if noun.has?(:container) && noun.hasnt?(:transparent) &&
|
|
2093
|
+
@location != thedark &&
|
|
2094
|
+
VisibleContents(noun) != 0 && IndirectlyContains(noun, @player)
|
|
2095
|
+
return L__M(:Open, 4, noun)
|
|
2096
|
+
end
|
|
2097
|
+
L__M(:Open,5,noun)
|
|
2098
|
+
end
|
|
2099
|
+
|
|
2100
|
+
def CloseSub
|
|
2101
|
+
return if ObjectIsUntouchable(noun)
|
|
2102
|
+
return L__M(:Close, 1, noun) if noun.hasnt? :openable
|
|
2103
|
+
return L__M(:Close, 2, noun) if noun.hasnt? :open
|
|
2104
|
+
take noun, :open
|
|
2105
|
+
return true if AfterRoutines()
|
|
2106
|
+
return true if @keep_silent
|
|
2107
|
+
@player.publish L__M(:Close, 4, noun)
|
|
2108
|
+
L__M(:Close, 3, noun)
|
|
2109
|
+
end
|
|
2110
|
+
|
|
2111
|
+
def DisrobeSub
|
|
2112
|
+
return if ObjectIsUntouchable(noun)
|
|
2113
|
+
return L__M(:Disrobe, 1, noun) if noun.hasnt? :worn
|
|
2114
|
+
take noun, :worn
|
|
2115
|
+
return true if AfterRoutines()
|
|
2116
|
+
return true if @keep_silent
|
|
2117
|
+
@player.publish L__M(:Disrobe, 3, noun)
|
|
2118
|
+
L__M(:Disrobe, 2, noun)
|
|
2119
|
+
end
|
|
2120
|
+
|
|
2121
|
+
def WearSub
|
|
2122
|
+
return if ObjectIsUntouchable(noun)
|
|
2123
|
+
return L__M(:Wear, 1, noun) if noun.hasnt? :clothing
|
|
2124
|
+
return L__M(:Wear, 2, noun) if noun.parent != @player
|
|
2125
|
+
return L__M(:Wear, 3, noun) if noun.has? :worn
|
|
2126
|
+
give noun, :worn
|
|
2127
|
+
return true if AfterRoutines()
|
|
2128
|
+
return true if @keep_silent
|
|
2129
|
+
@player.publish L__M(:Wear, 5, noun)
|
|
2130
|
+
L__M(:Wear, 4, noun)
|
|
2131
|
+
end
|
|
2132
|
+
|
|
2133
|
+
def EatSub
|
|
2134
|
+
return if ObjectIsUntouchable(noun)
|
|
2135
|
+
return L__M(:Eat, 1, noun) if noun.hasnt? :edible
|
|
2136
|
+
if noun.has? :worn
|
|
2137
|
+
L__M(:Drop, 3, noun)
|
|
2138
|
+
_invoke :Disrobe, noun
|
|
2139
|
+
return true if noun.has?(:worn) && noun.in?(@player)
|
|
2140
|
+
end
|
|
2141
|
+
noun.destroy
|
|
2142
|
+
return true if AfterRoutines()
|
|
2143
|
+
return true if @keep_silent
|
|
2144
|
+
@player.publish L__M(:Eat, 3, noun)
|
|
2145
|
+
L__M(:Eat, 2, noun)
|
|
2146
|
+
end
|
|
2147
|
+
|
|
2148
|
+
# ----------------------------------------------------------------------------
|
|
2149
|
+
# Verbs which are really just stubs (anything which happens for these
|
|
2150
|
+
# actions must happen in before rules)
|
|
2151
|
+
# ----------------------------------------------------------------------------
|
|
2152
|
+
|
|
2153
|
+
def AllowPushDir
|
|
2154
|
+
return L__M(:PushDir, 2, noun) if parent(second) != Compass
|
|
2155
|
+
return L__M(:PushDir, 3, noun) if [$u_obj, $d_obj].include?(second)
|
|
2156
|
+
AfterRoutines(); i = noun; move i, @player
|
|
2157
|
+
invoke :Go, second
|
|
2158
|
+
if @location == thedark then move i, @real_location
|
|
2159
|
+
else move i, @location
|
|
2160
|
+
end
|
|
2161
|
+
end
|
|
2162
|
+
|
|
2163
|
+
def AnswerSub
|
|
2164
|
+
return false if !second.nil? && RunLife(second, :Answer)
|
|
2165
|
+
L__M(:Answer, 1, noun)
|
|
2166
|
+
end
|
|
2167
|
+
|
|
2168
|
+
def AskSub
|
|
2169
|
+
return false if RunLife(noun, :Ask)
|
|
2170
|
+
L__M(:Ask, 1, noun)
|
|
2171
|
+
end
|
|
2172
|
+
|
|
2173
|
+
def AskForSub
|
|
2174
|
+
inv if noun == @player
|
|
2175
|
+
L__M(:Order, 1, noun)
|
|
2176
|
+
end
|
|
2177
|
+
|
|
2178
|
+
def AskToSub
|
|
2179
|
+
return false if RunLife(noun, :AskTo)
|
|
2180
|
+
L__M(:Order, 1, noun)
|
|
2181
|
+
end
|
|
2182
|
+
|
|
2183
|
+
def AttackSub
|
|
2184
|
+
return if ObjectIsUntouchable(noun)
|
|
2185
|
+
return false if noun.has?(:animate) && RunLife(noun, :Attack)
|
|
2186
|
+
L__M(:Attack, 1, noun)
|
|
2187
|
+
end
|
|
2188
|
+
|
|
2189
|
+
def BlowSub; L__M(:Blow, 1, noun); end
|
|
2190
|
+
|
|
2191
|
+
def BurnSub; L__M(:Burn, 1, noun); end
|
|
2192
|
+
|
|
2193
|
+
def BuySub; L__M(:Buy, 1, noun); end
|
|
2194
|
+
|
|
2195
|
+
def ClimbSub; L__M(:Climb, 1, noun); end
|
|
2196
|
+
|
|
2197
|
+
def ConsultSub; L__M(:Consult, 1, noun); end
|
|
2198
|
+
|
|
2199
|
+
def CutSub; L__M(:Cut, 1, noun); end
|
|
2200
|
+
|
|
2201
|
+
def DigSub; L__M(:Dig, 1, noun); end
|
|
2202
|
+
|
|
2203
|
+
def DrinkSub; L__M(:Drink, 1, noun); end
|
|
2204
|
+
|
|
2205
|
+
def FillSub; L__M(:Fill, 1, noun); end
|
|
2206
|
+
|
|
2207
|
+
def JumpSub; L__M(:Jump, 1, noun); end
|
|
2208
|
+
|
|
2209
|
+
def JumpOverSub; L__M(:JumpOver, 1, noun); end
|
|
2210
|
+
|
|
2211
|
+
def KissSub
|
|
2212
|
+
return if ObjectIsUntouchable(noun)
|
|
2213
|
+
return false if RunLife(noun, :Kiss)
|
|
2214
|
+
return L__M(:Touch, 3, noun) if noun == @player
|
|
2215
|
+
# TODO: Publish a visible message
|
|
2216
|
+
L__M(:Kiss, 1, noun)
|
|
2217
|
+
end
|
|
2218
|
+
|
|
2219
|
+
def ListenSub; L__M(:Listen, 1, noun); end
|
|
2220
|
+
|
|
2221
|
+
def MildSub; L__M(:Mild, 1, noun); end
|
|
2222
|
+
|
|
2223
|
+
def NoSub; L__M(:No); end
|
|
2224
|
+
|
|
2225
|
+
def PraySub; L__M(:Pray, 1, noun); end
|
|
2226
|
+
|
|
2227
|
+
def PullSub
|
|
2228
|
+
return if ObjectIsUntouchable(noun)
|
|
2229
|
+
return L__M(:Pull, 1, noun) if noun.has? :static
|
|
2230
|
+
return L__M(:Pull, 2, noun) if noun.has? :scenery
|
|
2231
|
+
return L__M(:Pull, 4, noun) if noun.has? :animate
|
|
2232
|
+
return true if AfterRoutines()
|
|
2233
|
+
# TODO: Publish a visible message
|
|
2234
|
+
L__M(:Pull, 3, noun)
|
|
2235
|
+
end
|
|
2236
|
+
|
|
2237
|
+
def PushSub
|
|
2238
|
+
return if ObjectIsUntouchable(noun)
|
|
2239
|
+
return L__M(:Push, 1, noun) if noun.has? :static
|
|
2240
|
+
return L__M(:Push, 2, noun) if noun.has? :scenery
|
|
2241
|
+
return L__M(:Push, 4, noun) if noun.has? :animate
|
|
2242
|
+
return true if AfterRoutines()
|
|
2243
|
+
# TODO: Publish a visible message
|
|
2244
|
+
L__M(:Push, 3, noun)
|
|
2245
|
+
end
|
|
2246
|
+
|
|
2247
|
+
def PushDirSub
|
|
2248
|
+
return "You'll have to stand up first." if @player.hasany? :sitting, :kneeling, :prone
|
|
2249
|
+
L__M(:PushDir, 1, noun)
|
|
2250
|
+
end
|
|
2251
|
+
|
|
2252
|
+
def RubSub; @player.publish L__M(:Rub, 2, noun); L__M(:Rub, 1, noun); end
|
|
2253
|
+
|
|
2254
|
+
def SetSub; L__M(:Set, 1, noun); end
|
|
2255
|
+
|
|
2256
|
+
def SetToSub; L__M(:SetTo, 1, noun); end
|
|
2257
|
+
|
|
2258
|
+
def SingSub; @player.publish L__M(:Sing, 2, noun); L__M(:Sing, 1, noun); end
|
|
2259
|
+
|
|
2260
|
+
def SleepSub; @player.publish L__M(:Sleep, 2, noun); L__M(:Sleep, 1, noun); end
|
|
2261
|
+
|
|
2262
|
+
def SmellSub; @player.publish L__M(:Smell, 2, noun); L__M(:Smell, 1, noun); end
|
|
2263
|
+
|
|
2264
|
+
def SorrySub; @player.publish L__M(:Sorry, 2, noun); L__M(:Sorry, 1, noun); end
|
|
2265
|
+
|
|
2266
|
+
def SqueezeSub
|
|
2267
|
+
return if ObjectIsUntouchable(noun)
|
|
2268
|
+
if noun.has? :animate then return L__M(:Squeeze, 1, noun) end
|
|
2269
|
+
return true if AfterRoutines()
|
|
2270
|
+
L__M(:Squeeze, 2, noun)
|
|
2271
|
+
end
|
|
2272
|
+
|
|
2273
|
+
def StrongSub; L__M(:Strong, 1, noun); end
|
|
2274
|
+
|
|
2275
|
+
def SwimSub; L__M(:Swim, 1, noun); end
|
|
2276
|
+
|
|
2277
|
+
def SwingSub; L__M(:Swing, 1, noun); end
|
|
2278
|
+
|
|
2279
|
+
def TasteSub; L__M(:Taste, 1, noun); end
|
|
2280
|
+
|
|
2281
|
+
def TellSub
|
|
2282
|
+
return L__M(:Tell, 1, noun) if noun == @player
|
|
2283
|
+
return false if RunLife(noun, :Tell)
|
|
2284
|
+
L__M(:Tell, 2, noun)
|
|
2285
|
+
end
|
|
2286
|
+
|
|
2287
|
+
def ThinkSub
|
|
2288
|
+
@player.publish L__M(:Think, 2, noun)
|
|
2289
|
+
L__M(:Think, 1, noun)
|
|
2290
|
+
end
|
|
2291
|
+
|
|
2292
|
+
def ThrowAtSub
|
|
2293
|
+
return if ObjectIsUntouchable(noun)
|
|
2294
|
+
unless second.nil?
|
|
2295
|
+
@action = :ThrownAt
|
|
2296
|
+
if RunRoutines(second, :before) then @action = :ThrowAt; return true; end
|
|
2297
|
+
@action = :ThrowAt
|
|
2298
|
+
end
|
|
2299
|
+
if noun.has? :worn
|
|
2300
|
+
L__M(:Drop, 3, noun)
|
|
2301
|
+
disrobe noun
|
|
2302
|
+
return true if noun.has?(:worn) && noun.in?(@player)
|
|
2303
|
+
end
|
|
2304
|
+
unless second.nil?
|
|
2305
|
+
return L__M(:ThrowAt, 1) if second.hasnt? :animate
|
|
2306
|
+
return false if RunLife(second, :ThrowAt)
|
|
2307
|
+
end
|
|
2308
|
+
L__M(:ThrowAt, 2, noun)
|
|
2309
|
+
end
|
|
2310
|
+
|
|
2311
|
+
def TieSub; L__M(:Tie,1,noun); end
|
|
2312
|
+
|
|
2313
|
+
def TouchSub
|
|
2314
|
+
return L__M(:Touch, 3, noun) if noun == @player
|
|
2315
|
+
return if ObjectIsUntouchable(noun)
|
|
2316
|
+
return L__M(:Touch, 1, noun) if noun.has? :animate
|
|
2317
|
+
@player.publish L__M(:Touch,4,noun)
|
|
2318
|
+
L__M(:Touch,2,noun)
|
|
2319
|
+
end
|
|
2320
|
+
|
|
2321
|
+
def TurnSub
|
|
2322
|
+
return if ObjectIsUntouchable(noun)
|
|
2323
|
+
return L__M(:Turn, 1, noun) if noun.has? :static
|
|
2324
|
+
return L__M(:Turn, 2, noun) if noun.has? :scenery
|
|
2325
|
+
return L__M(:Turn, 4, noun) if noun.has? :animate
|
|
2326
|
+
L__M(:Turn, 3, noun)
|
|
2327
|
+
end
|
|
2328
|
+
|
|
2329
|
+
def WaitSub
|
|
2330
|
+
@player.publish L__M(:Wait, 2, noun)
|
|
2331
|
+
return true if AfterRoutines()
|
|
2332
|
+
L__M(:Wait, 1, noun)
|
|
2333
|
+
end
|
|
2334
|
+
|
|
2335
|
+
def WakeSub; L__M(:Wake, 1, noun); end
|
|
2336
|
+
|
|
2337
|
+
def WakeOtherSub
|
|
2338
|
+
return if ObjectIsUntouchable(noun)
|
|
2339
|
+
return false if RunLife(noun, :WakeOther)
|
|
2340
|
+
L__M(:WakeOther, 1, noun)
|
|
2341
|
+
end
|
|
2342
|
+
|
|
2343
|
+
def WaveSub
|
|
2344
|
+
return L__M(:Wave, 1, noun) if !noun.nil? && (noun.has?(:clothing, :worn) || noun.notin?(@player))
|
|
2345
|
+
@player.publish L__M(:Wave, 3, noun)
|
|
2346
|
+
L__M(:Wave, 2, noun)
|
|
2347
|
+
end
|
|
2348
|
+
|
|
2349
|
+
def WaveHandsSub
|
|
2350
|
+
if noun
|
|
2351
|
+
@player.publish L__M(:WaveHands, 4, noun)
|
|
2352
|
+
L__M(:WaveHands, 3, noun)
|
|
2353
|
+
else
|
|
2354
|
+
@player.publish L__M(:WaveHands, 2, noun)
|
|
2355
|
+
L__M(:WaveHands, 1, noun)
|
|
2356
|
+
end
|
|
2357
|
+
end
|
|
2358
|
+
|
|
2359
|
+
def YesSub; L__M(:Yes); end
|
|
2360
|
+
|
|
2361
|
+
# ----------------------------------------------------------------------------
|
|
2362
|
+
# Debugging verbs
|
|
2363
|
+
# ----------------------------------------------------------------------------
|
|
2364
|
+
|
|
2365
|
+
def XTestMove(obj, dest)
|
|
2366
|
+
if obj.is_a?(InformLibrary) || obj == LibraryMessages || obj.is_a?(Inform::System::Object)
|
|
2367
|
+
println "[Can't move #{obj.name}: it's a system object.]"
|
|
2368
|
+
return true
|
|
2369
|
+
end
|
|
2370
|
+
loop do
|
|
2371
|
+
break if dest.nil?
|
|
2372
|
+
println "[Can't move #{obj.name}: it would contain itself.]" if dest == obj
|
|
2373
|
+
dest = parent(dest)
|
|
2374
|
+
end
|
|
2375
|
+
false
|
|
2376
|
+
end
|
|
2377
|
+
|
|
2378
|
+
def XAbstractSub
|
|
2379
|
+
return if XTestMove(noun, second)
|
|
2380
|
+
move noun, second
|
|
2381
|
+
"[Abstracted.]"
|
|
2382
|
+
end
|
|
2383
|
+
|
|
2384
|
+
def XPurloinSub
|
|
2385
|
+
return if XTestMove(noun, player)
|
|
2386
|
+
move noun, player; give noun, :moved; take noun, :concealed
|
|
2387
|
+
"[Purloined.]"
|
|
2388
|
+
end
|
|
2389
|
+
|
|
2390
|
+
def XObj(obj, f = 0)
|
|
2391
|
+
if parent(obj) then print a(obj) else print obj end
|
|
2392
|
+
print " (#{obj.id}) "
|
|
2393
|
+
print "(in #{parent(obj)} #{parent(obj).id})" if f == 1 && parent(obj)
|
|
2394
|
+
new_line
|
|
2395
|
+
return true if child(obj).nil?
|
|
2396
|
+
if obj.is_a?(Class)
|
|
2397
|
+
WriteListFrom(child(obj), NEWLINE_BIT + INDENT_BIT + ALWAYS_BIT + NOARTICLE_BIT, 1)
|
|
2398
|
+
else
|
|
2399
|
+
WriteListFrom(child(obj), NEWLINE_BIT + INDENT_BIT + ALWAYS_BIT + FULLINV_BIT, 1)
|
|
2400
|
+
end
|
|
2401
|
+
new_line
|
|
2402
|
+
end
|
|
2403
|
+
|
|
2404
|
+
def XTreeSub
|
|
2405
|
+
raise Parser::VerbUnrecognized unless @player.builder?
|
|
2406
|
+
return XObj(noun, 1) unless noun.nil?
|
|
2407
|
+
objectloop { |i|
|
|
2408
|
+
XObj(i) if i.object? && parent(i).nil?
|
|
2409
|
+
}
|
|
2410
|
+
end
|
|
2411
|
+
|
|
2412
|
+
def GotoSub
|
|
2413
|
+
raise Parser::VerbUnrecognized unless @player.builder?
|
|
2414
|
+
log.debug "<Goto noun> #=> #{noun}"
|
|
2415
|
+
if !noun.is_a?(Inform::Object)
|
|
2416
|
+
"[Not a safe place.]"
|
|
2417
|
+
elsif noun != @player
|
|
2418
|
+
PlayerTo(noun)
|
|
2419
|
+
else
|
|
2420
|
+
"Cannot go to there."
|
|
2421
|
+
end
|
|
2422
|
+
end
|
|
2423
|
+
|
|
2424
|
+
def GonearSub
|
|
2425
|
+
raise Parser::VerbUnrecognized unless @player.builder?
|
|
2426
|
+
x = noun
|
|
2427
|
+
loop do
|
|
2428
|
+
break if parent(x).nil?
|
|
2429
|
+
x = parent(x)
|
|
2430
|
+
end
|
|
2431
|
+
PlayerTo(x)
|
|
2432
|
+
end
|
|
2433
|
+
|
|
2434
|
+
def Print_ScL(obj); println (@x_scope_count += 1) + ": " + a(obj) + " (" + obj.id + ")"; end
|
|
2435
|
+
|
|
2436
|
+
def ScopeSub
|
|
2437
|
+
raise Parser::VerbUnrecognized unless @player.admin?
|
|
2438
|
+
@x_scope_count = 0
|
|
2439
|
+
LoopOverScope(method(:Print_ScL), noun)
|
|
2440
|
+
"Nothing is in scope." if @x_scope_count == 0
|
|
2441
|
+
end
|
|
2442
|
+
|
|
2443
|
+
# ----------------------------------------------------------------------------
|
|
2444
|
+
# Finally: the mechanism for library text (the text is in the language defn)
|
|
2445
|
+
# ----------------------------------------------------------------------------
|
|
2446
|
+
|
|
2447
|
+
# def L__M(act, n, x1)
|
|
2448
|
+
# s = @sw__var
|
|
2449
|
+
# @sw__var = act
|
|
2450
|
+
# n = 1 if n == 0
|
|
2451
|
+
# L___M(n,x1)
|
|
2452
|
+
# ensure
|
|
2453
|
+
# @sw__var = s
|
|
2454
|
+
# end
|
|
2455
|
+
|
|
2456
|
+
# def L___M(n, x1)
|
|
2457
|
+
# s = @action
|
|
2458
|
+
# lm_n = n
|
|
2459
|
+
# lm_o = x1
|
|
2460
|
+
# @action = @sw__var
|
|
2461
|
+
# unless RunRoutines(LibraryMessages, :before).nil? then @action = s; return false end
|
|
2462
|
+
# unless LibraryExtensions.RunWhile(:ext_messages, nil).nil? then @action = s; return false end
|
|
2463
|
+
# @action = s
|
|
2464
|
+
# LanguageLM(n, x1)
|
|
2465
|
+
# end
|
|
2466
|
+
end
|
|
2467
|
+
# module Verbs
|
|
2468
|
+
end
|
|
2469
|
+
# module Inform
|
|
2470
|
+
|
|
2471
|
+
# rubocop: enable Lint/UselessAssignment
|
|
2472
|
+
|
|
2473
|
+
# The Inform module
|
|
2474
|
+
module Inform
|
|
2475
|
+
# The Parser module
|
|
2476
|
+
module Parser
|
|
2477
|
+
include Inform::Verbs
|
|
2478
|
+
end
|
|
2479
|
+
end
|
|
2480
|
+
|
|
2481
|
+
# ==============================================================================
|