inform6lib 0.1.1 → 0.1.3
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 +4 -4
- data/Rakefile +1 -1
- data/lib/inform/English.h.rb +31 -63
- data/lib/inform/Parser.h.rb +3 -3
- data/lib/inform/VerbLib.h.rb +1 -1
- data/lib/inform/infix.h.rb +1 -1
- data/lib/inform/parserm.h.rb +400 -512
- data/lib/inform/verblibm.h.rb +171 -135
- metadata +3 -3
data/lib/inform/parserm.h.rb
CHANGED
|
@@ -60,7 +60,6 @@
|
|
|
60
60
|
# which supports the referencing of Special Global Variables like
|
|
61
61
|
# $LAST_MATCH_INFO by their screaming snake case names.
|
|
62
62
|
require 'English'
|
|
63
|
-
require 'set'
|
|
64
63
|
|
|
65
64
|
require_relative 'linklpa.h'
|
|
66
65
|
|
|
@@ -249,7 +248,7 @@ module Parser
|
|
|
249
248
|
if !defined?(MAX_TIMERS)
|
|
250
249
|
MAX_TIMERS = 32 # Max number timers/daemons active at once
|
|
251
250
|
end # if !defined?(MAX_TIMERS)
|
|
252
|
-
@the_timers = [
|
|
251
|
+
@the_timers = []
|
|
253
252
|
@active_timers # Number of timers/daemons actives
|
|
254
253
|
|
|
255
254
|
@score # The current score
|
|
@@ -516,7 +515,7 @@ module Parser
|
|
|
516
515
|
|
|
517
516
|
# If you want to use the third-person of the narrative voice, you will
|
|
518
517
|
# need to replace this selfobj with your own.
|
|
519
|
-
SelfObj = Object("(self object)") {
|
|
518
|
+
SelfObj = Inform::Ephemeral::Object.new("(self object)") {
|
|
520
519
|
with {
|
|
521
520
|
def short_name; return L__M(:Miscellany, 18); end
|
|
522
521
|
def description; return L__M(:Miscellany, 19); end
|
|
@@ -540,22 +539,22 @@ module Parser
|
|
|
540
539
|
@selfobj ||= SelfObj
|
|
541
540
|
end
|
|
542
541
|
|
|
543
|
-
def selfobj=(
|
|
544
|
-
@selfobj =
|
|
542
|
+
def selfobj=(obj)
|
|
543
|
+
@selfobj = obj
|
|
545
544
|
end
|
|
546
545
|
|
|
547
546
|
InitalState = Struct.new(:memo).new
|
|
548
547
|
|
|
549
548
|
def self.initial_state
|
|
550
|
-
InitalState.memo ||= Inform::Parser.instance_variables.
|
|
551
|
-
|
|
549
|
+
InitalState.memo ||= Inform::Parser.instance_variables.to_h do |variable|
|
|
550
|
+
[variable, Inform::Parser.instance_variable_get(variable)]
|
|
552
551
|
end
|
|
553
552
|
end
|
|
554
553
|
|
|
555
554
|
def initialize_state
|
|
556
555
|
DidScopeAction.clear # TODO: Remove
|
|
557
|
-
Inform::Parser.initial_state.each_pair do |
|
|
558
|
-
self.instance_variable_set(
|
|
556
|
+
Inform::Parser.initial_state.each_pair do |key, value|
|
|
557
|
+
self.instance_variable_set(key, value)
|
|
559
558
|
end
|
|
560
559
|
end
|
|
561
560
|
|
|
@@ -816,7 +815,9 @@ module Parser
|
|
|
816
815
|
# Note that there are three different places where a return can happen.
|
|
817
816
|
# ----------------------------------------------------------------------------
|
|
818
817
|
|
|
819
|
-
|
|
818
|
+
QuotesSayCommandPattern = %r{^['"]}
|
|
819
|
+
ConversationStarterPattern = %r{\w+, }
|
|
820
|
+
WordOrCommaSplitPattern = %r{\s+|(?=,)|(?<=,)}
|
|
820
821
|
|
|
821
822
|
def Parser__parse
|
|
822
823
|
@meta = false
|
|
@@ -843,23 +844,28 @@ module Parser
|
|
|
843
844
|
|
|
844
845
|
if @held_back_mode
|
|
845
846
|
@held_back_mode = false
|
|
846
|
-
|
|
847
|
+
return ReParse()
|
|
847
848
|
end
|
|
848
849
|
|
|
849
850
|
# Handle the apostrophe shorthand for the Say command
|
|
850
|
-
@input = "say '#{@input[1..]}'" if @input
|
|
851
|
+
@input = "say '#{@input[1..]}'" if QuotesSayCommandPattern.match?(@input)
|
|
851
852
|
|
|
852
853
|
# Get the words from the player's input
|
|
853
|
-
@words = @input.split
|
|
854
|
+
# @words = @input.split
|
|
855
|
+
@words = @input.split(WordOrCommaSplitPattern)
|
|
854
856
|
|
|
855
|
-
|
|
857
|
+
ReParse()
|
|
858
|
+
end
|
|
859
|
+
# def Parser__parse
|
|
856
860
|
|
|
861
|
+
def ReParse
|
|
857
862
|
@parser_inflection = :name
|
|
858
863
|
|
|
859
864
|
# Initially assume the command is aimed at the player, and the verb
|
|
860
865
|
# is the first word
|
|
861
866
|
|
|
862
867
|
# num_words = WordCount()
|
|
868
|
+
@num_words = @words.length
|
|
863
869
|
@wn = 0 # Our words "buffer" is indexed from 0, unlike Inform
|
|
864
870
|
|
|
865
871
|
if defined? LanguageToInformese
|
|
@@ -912,14 +918,19 @@ module Parser
|
|
|
912
918
|
@location ||= @actors_location # TODO: Necessary?
|
|
913
919
|
@usual_grammar_after = nil
|
|
914
920
|
|
|
915
|
-
|
|
921
|
+
AlmostReParse()
|
|
922
|
+
end
|
|
923
|
+
# def ReParse
|
|
916
924
|
|
|
925
|
+
def AlmostReParse
|
|
917
926
|
@scope_token = nil
|
|
918
927
|
@action_to_be = nil
|
|
919
928
|
|
|
920
|
-
|
|
929
|
+
BeginCommand()
|
|
930
|
+
end
|
|
921
931
|
|
|
922
|
-
|
|
932
|
+
def BeginCommand()
|
|
933
|
+
# Begin from what we currently think is the verb word
|
|
923
934
|
|
|
924
935
|
@wn = @verb_wordnum
|
|
925
936
|
# @verb_word = NextWordStopped() # TODO: FIXME?
|
|
@@ -938,7 +949,7 @@ module Parser
|
|
|
938
949
|
|
|
939
950
|
@verb_word = AGAIN1__WD if @verb_word == AGAIN2__WD || @verb_word == AGAIN3__WD
|
|
940
951
|
if @verb_word == AGAIN1__WD
|
|
941
|
-
raise
|
|
952
|
+
raise RepeatedCommand if @actor != @player
|
|
942
953
|
raise NothingToRepeat if history.empty?
|
|
943
954
|
@input = history.last
|
|
944
955
|
@words = @input.split
|
|
@@ -956,8 +967,6 @@ module Parser
|
|
|
956
967
|
# return DoOops()
|
|
957
968
|
end
|
|
958
969
|
|
|
959
|
-
initialize_state
|
|
960
|
-
|
|
961
970
|
if @match_list then @match_list.clear else @match_list = [] end
|
|
962
971
|
if @multiple_object then @multiple_object.clear else @multiple_object = [] end
|
|
963
972
|
if @pattern then @pattern.clear else @pattern = [] end
|
|
@@ -1005,7 +1014,7 @@ module Parser
|
|
|
1005
1014
|
end # DEBUG
|
|
1006
1015
|
@wn = @verb_wordnum; @indef_mode = false; @token_filter = nil
|
|
1007
1016
|
l = NounDomain(Compass)
|
|
1008
|
-
#
|
|
1017
|
+
# return ReParse() if l == REPARSE_CODE
|
|
1009
1018
|
|
|
1010
1019
|
if l
|
|
1011
1020
|
# If it is a direction, send back the results:
|
|
@@ -1031,41 +1040,23 @@ module Parser
|
|
|
1031
1040
|
# tell the wizard that she is an idiot.)
|
|
1032
1041
|
|
|
1033
1042
|
if @actor == @player
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
else
|
|
1039
|
-
@verb = UnknownVerb(@verb)
|
|
1040
|
-
if @verb.nil?
|
|
1041
|
-
@best_etype = VerbUnrecognized
|
|
1042
|
-
raise @best_etype
|
|
1043
|
-
else
|
|
1044
|
-
log.debug "jump VerbAccepted"
|
|
1045
|
-
# jump VerbAccepted
|
|
1046
|
-
end
|
|
1043
|
+
j = 2
|
|
1044
|
+
while j <= @num_words
|
|
1045
|
+
i = NextWord(); j += 1
|
|
1046
|
+
return Conversation() if i == @comma_word
|
|
1047
1047
|
end
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
raise @best_etype
|
|
1051
|
-
end
|
|
1052
|
-
|
|
1053
|
-
# Conversation()
|
|
1054
|
-
|
|
1055
|
-
@actor = l
|
|
1056
|
-
@actors_location = ScopeCeiling(l)
|
|
1057
|
-
if defined?(DEBUG)
|
|
1058
|
-
if @parser_trace >= 1
|
|
1059
|
-
println "[Actor is " + the(@actor) + " in " + @actors_location + "]"
|
|
1048
|
+
@verb = UnknownVerb(@verb)
|
|
1049
|
+
return VerbAccepted() unless @verb.nil?
|
|
1060
1050
|
end
|
|
1061
|
-
|
|
1062
|
-
return
|
|
1051
|
+
@best_etype = VerbUnrecognized
|
|
1052
|
+
return GiveError()
|
|
1053
|
+
# raise @best_etype
|
|
1063
1054
|
end
|
|
1064
|
-
# of first-word-not-a-verb
|
|
1055
|
+
# end of first-word-not-a-verb
|
|
1065
1056
|
|
|
1066
1057
|
VerbAccepted()
|
|
1067
1058
|
end
|
|
1068
|
-
# def
|
|
1059
|
+
# def BeginCommand
|
|
1069
1060
|
|
|
1070
1061
|
############################################################################
|
|
1071
1062
|
#
|
|
@@ -1143,46 +1134,41 @@ module Parser
|
|
|
1143
1134
|
|
|
1144
1135
|
return true
|
|
1145
1136
|
end
|
|
1146
|
-
# def
|
|
1137
|
+
# def VerbAccepted
|
|
1147
1138
|
|
|
1148
1139
|
# NextWord nudges the word number wn on by one each time, so we've now
|
|
1149
1140
|
# advanced past a comma. (A comma is a word all on its own in the table.)
|
|
1150
1141
|
|
|
1151
1142
|
def Conversation
|
|
1152
|
-
j = @wn
|
|
1153
|
-
if j == 1
|
|
1154
|
-
raise UnexpectedComma
|
|
1155
|
-
end
|
|
1143
|
+
j = @wn
|
|
1144
|
+
raise UnexpectedComma if j == 1
|
|
1156
1145
|
|
|
1157
1146
|
# Use NounDomain (in the context of "animate creature") to see if the
|
|
1158
1147
|
# words make sense as the name of someone held or nearby
|
|
1159
1148
|
|
|
1160
|
-
@wn =
|
|
1149
|
+
@wn = 0; @lookahead = :held
|
|
1161
1150
|
@scope_reason = TALKING_REASON
|
|
1162
1151
|
l = NounDomain(@player,@actors_location,6)
|
|
1163
1152
|
@scope_reason = PARSING_REASON
|
|
1164
1153
|
throw :ReParse if l == REPARSE_CODE
|
|
1165
|
-
raise MissingAddressee if l ==
|
|
1154
|
+
raise MissingAddressee if l == false
|
|
1166
1155
|
|
|
1167
|
-
Conversation2()
|
|
1156
|
+
Conversation2(l, j)
|
|
1168
1157
|
end
|
|
1169
1158
|
|
|
1170
|
-
def Conversation2
|
|
1159
|
+
def Conversation2(l, j)
|
|
1171
1160
|
|
|
1172
1161
|
# The object addressed must at least be "talkable" if not actually "animate"
|
|
1173
1162
|
# (the distinction allows, for instance, a microphone to be spoken to,
|
|
1174
1163
|
# without the parser thinking that the microphone is human).
|
|
1175
1164
|
|
|
1176
|
-
if l.hasnt? :animate, :talkable
|
|
1177
|
-
raise InanimateAddressee
|
|
1178
|
-
end
|
|
1165
|
+
raise InanimateAddressee if l.hasnt? :animate, :talkable
|
|
1179
1166
|
|
|
1180
1167
|
# Check that there aren't any mystery words between the end of the person's
|
|
1181
1168
|
# name and the comma (eg, throw out "dwarf sdfgsdgs, go north").
|
|
1182
1169
|
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
end
|
|
1170
|
+
@wn += 1
|
|
1171
|
+
raise SpeechImpediment if @wn != j
|
|
1186
1172
|
|
|
1187
1173
|
# The player has now successfully named someone. Adjust "him", "her", "it":
|
|
1188
1174
|
|
|
@@ -1191,15 +1177,14 @@ module Parser
|
|
|
1191
1177
|
# Set the global variable "actor", adjust the number of the first word,
|
|
1192
1178
|
# and begin parsing again from there.
|
|
1193
1179
|
|
|
1194
|
-
@verb_wordnum = j
|
|
1180
|
+
@verb_wordnum = j
|
|
1195
1181
|
|
|
1196
1182
|
# Stop things like "me, again":
|
|
1197
1183
|
|
|
1198
1184
|
if l == @player
|
|
1199
1185
|
@wn = @verb_wordnum
|
|
1200
1186
|
if [AGAIN1__WD, AGAIN2__WD, AGAIN3__WD].include?(NextWordStopped())
|
|
1201
|
-
|
|
1202
|
-
jump ReType
|
|
1187
|
+
raise RepeatedCommand
|
|
1203
1188
|
end
|
|
1204
1189
|
end
|
|
1205
1190
|
|
|
@@ -1316,7 +1301,8 @@ module Parser
|
|
|
1316
1301
|
prepositions = @line_token[@pcount].split(/\//).map { |s| s[1..-2] }
|
|
1317
1302
|
@pcount += 1 while @line_ttype[@pcount] == :preposition
|
|
1318
1303
|
|
|
1319
|
-
if ElementaryTokens.include?(@line_ttype[@pcount]) &&
|
|
1304
|
+
if ElementaryTokens.include?(@line_ttype[@pcount]) &&
|
|
1305
|
+
@line_tdata[@pcount] == :noun
|
|
1320
1306
|
|
|
1321
1307
|
# Advance past the last preposition
|
|
1322
1308
|
|
|
@@ -1402,6 +1388,7 @@ module Parser
|
|
|
1402
1388
|
@scope_reason = PARSING_REASON
|
|
1403
1389
|
AnalyseToken(token)
|
|
1404
1390
|
|
|
1391
|
+
# TODO: FIXME
|
|
1405
1392
|
# if @action_to_be == :AskTo && ElementaryTokens.include?(@found_ttype) &&
|
|
1406
1393
|
# @found_tdata == :topic
|
|
1407
1394
|
# l = @results[2]
|
|
@@ -1414,7 +1401,8 @@ module Parser
|
|
|
1414
1401
|
|
|
1415
1402
|
if defined?(DEBUG) && @parser_trace >= 10
|
|
1416
1403
|
new_line
|
|
1417
|
-
println "Parsing the current word '#{current_word}'
|
|
1404
|
+
println "Parsing the current word '#{current_word}' " +
|
|
1405
|
+
"as a #{@found_ttype} in this grammar:"
|
|
1418
1406
|
println grammar.to_s
|
|
1419
1407
|
println ">>Before invoking ParseToken(#{@found_ttype})..."
|
|
1420
1408
|
println ">>...The found token data is #{@found_tdata}"
|
|
@@ -1603,7 +1591,8 @@ module Parser
|
|
|
1603
1591
|
# We continue the outer "for" loop, trying the next line in the grammar.
|
|
1604
1592
|
|
|
1605
1593
|
@best_etype = @etype if @etype > @best_etype
|
|
1606
|
-
@nextbest_etype = @etype if @etype != AskScope &&
|
|
1594
|
+
@nextbest_etype = @etype if @etype != AskScope &&
|
|
1595
|
+
!@etype.nil? && @etype > @nextbest_etype
|
|
1607
1596
|
|
|
1608
1597
|
# ...unless the line was something like "take all" which failed because
|
|
1609
1598
|
# nothing matched the "all", in which case we stop and give an error now.
|
|
@@ -1615,14 +1604,17 @@ module Parser
|
|
|
1615
1604
|
|
|
1616
1605
|
# The grammar is exhausted: every line has failed to match.
|
|
1617
1606
|
|
|
1607
|
+
GiveError()
|
|
1608
|
+
end
|
|
1609
|
+
# def BestGrammar
|
|
1610
|
+
|
|
1618
1611
|
############################################################################
|
|
1619
1612
|
#
|
|
1620
1613
|
# H: Cheaply parse otherwise unrecognised conversation and return
|
|
1621
1614
|
#
|
|
1622
1615
|
############################################################################
|
|
1623
1616
|
|
|
1624
|
-
|
|
1625
|
-
|
|
1617
|
+
def GiveError
|
|
1626
1618
|
if defined?(DEBUG) && @parser_trace >= 10
|
|
1627
1619
|
println ">>@etype is #{@etype}"
|
|
1628
1620
|
println ">>@best_etype is #{@best_etype}"
|
|
@@ -1633,26 +1625,25 @@ module Parser
|
|
|
1633
1625
|
# If the command was addressed to somebody else (eg, "dwarf, sfgh") then
|
|
1634
1626
|
# it is taken as conversation which the parser has no business in disallowing.
|
|
1635
1627
|
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
# end
|
|
1628
|
+
if @actor != @player
|
|
1629
|
+
unless @usual_grammar_after.nil?
|
|
1630
|
+
@verb_wordnum = @usual_grammar_after
|
|
1631
|
+
return AlmostReParse()
|
|
1632
|
+
end
|
|
1633
|
+
@wn = @verb_wordnum
|
|
1634
|
+
@special_word = NextWord()
|
|
1635
|
+
if @special_word == @comma_word
|
|
1636
|
+
@special_word = NextWord()
|
|
1637
|
+
@verb_wordnum += 1
|
|
1638
|
+
end
|
|
1639
|
+
@special_number = TryNumber(@verb_wordnum)
|
|
1640
|
+
@results[0] = :NotUnderstood
|
|
1641
|
+
@results[1] = 2
|
|
1642
|
+
@results[2] = 1; @special_number1 = @special_word
|
|
1643
|
+
@results[3] = @actor
|
|
1644
|
+
@consult_from = @verb_wordnum; @consult_words = @num_words-@consult_from+1
|
|
1645
|
+
return true
|
|
1646
|
+
end
|
|
1656
1647
|
|
|
1657
1648
|
############################################################################
|
|
1658
1649
|
#
|
|
@@ -1679,7 +1670,7 @@ module Parser
|
|
|
1679
1670
|
# ...being careful not to go all the way back, to avoid infinite repetition
|
|
1680
1671
|
# of a deferred command causing an error.
|
|
1681
1672
|
end
|
|
1682
|
-
# def
|
|
1673
|
+
# def GiveError
|
|
1683
1674
|
|
|
1684
1675
|
############################################################################
|
|
1685
1676
|
#
|
|
@@ -1896,7 +1887,7 @@ module Parser
|
|
|
1896
1887
|
# (F) Return the conclusion of parsing an object list
|
|
1897
1888
|
# ----------------------------------------------------------------------------
|
|
1898
1889
|
|
|
1899
|
-
CommaWordPattern = %r{,$}
|
|
1890
|
+
CommaWordPattern = %r{,$}
|
|
1900
1891
|
|
|
1901
1892
|
# rubocop: disable Layout/EmptyLinesAroundBlockBody
|
|
1902
1893
|
def ParseToken(given_ttype, given_tdata, token_n, token)
|
|
@@ -2041,7 +2032,10 @@ module Parser
|
|
|
2041
2032
|
|
|
2042
2033
|
end
|
|
2043
2034
|
|
|
2044
|
-
|
|
2035
|
+
# TODO: Remove (2026-08-21)
|
|
2036
|
+
# token = given_ttype
|
|
2037
|
+
# TODO: Test
|
|
2038
|
+
token = given_tdata
|
|
2045
2039
|
prev_indef_wanted = 0
|
|
2046
2040
|
|
|
2047
2041
|
############################################################################
|
|
@@ -2116,7 +2110,9 @@ module Parser
|
|
|
2116
2110
|
end
|
|
2117
2111
|
end
|
|
2118
2112
|
|
|
2119
|
-
if [ME1__WD, ME2__WD, ME3__WD].include?(o)
|
|
2113
|
+
if [ME1__WD, ME2__WD, ME3__WD].include?(o)
|
|
2114
|
+
@pronoun_word = o; @pronoun_obj = selfobj
|
|
2115
|
+
end
|
|
2120
2116
|
|
|
2121
2117
|
@allow_plurals = true; desc_wn = @wn;
|
|
2122
2118
|
|
|
@@ -2197,7 +2193,8 @@ module Parser
|
|
|
2197
2193
|
@wn = desc_wn
|
|
2198
2194
|
throw :TryAgain2
|
|
2199
2195
|
end
|
|
2200
|
-
@etype = CannotUnderstandSentence if @multiflag &&
|
|
2196
|
+
@etype = CannotUnderstandSentence if @multiflag &&
|
|
2197
|
+
[UnexpectedMultiple, TooFew].include?(@etype)
|
|
2201
2198
|
@etype = CantSee()
|
|
2202
2199
|
return FailToken(desc_wn, prev_indef_wanted)
|
|
2203
2200
|
end # Choose best error
|
|
@@ -2749,7 +2746,8 @@ module Parser
|
|
|
2749
2746
|
next unless @pattern[j]
|
|
2750
2747
|
|
|
2751
2748
|
if defined?(DEBUG)
|
|
2752
|
-
println "[Gluing in inference with pattern code " +
|
|
2749
|
+
println "[Gluing in inference with pattern code " +
|
|
2750
|
+
@pattern[j] + "]" if @parser_trace >= 5
|
|
2753
2751
|
end # DEBUG
|
|
2754
2752
|
|
|
2755
2753
|
# Conveniently, parse2[1] is the first word in both ZCODE and GLULX.
|
|
@@ -2975,7 +2973,8 @@ module Parser
|
|
|
2975
2973
|
end
|
|
2976
2974
|
@multi_context = context
|
|
2977
2975
|
if defined?(DEBUG)
|
|
2978
|
-
println " Made multiple object of size
|
|
2976
|
+
println " Made multiple object of size " +
|
|
2977
|
+
"#{@multiple_object.length}]" if @parser_trace >= 4
|
|
2979
2978
|
end # DEBUG
|
|
2980
2979
|
return 1
|
|
2981
2980
|
end
|
|
@@ -3007,7 +3006,8 @@ module Parser
|
|
|
3007
3006
|
println " Grouped into #{n} possibilities by name:"
|
|
3008
3007
|
for i in (0...@number_matched)
|
|
3009
3008
|
if @match_classes[i] > 0
|
|
3010
|
-
print " " + The(@match_list[i]) +
|
|
3009
|
+
print " " + The(@match_list[i]) +
|
|
3010
|
+
" (#{@match_list[i].object_id}) --- group #{@match_classes[i]}\n"
|
|
3011
3011
|
end
|
|
3012
3012
|
end
|
|
3013
3013
|
end
|
|
@@ -3097,7 +3097,8 @@ module Parser
|
|
|
3097
3097
|
# entries which fail the basic requirements of the descriptors.
|
|
3098
3098
|
# ----------------------------------------------------------------------------
|
|
3099
3099
|
|
|
3100
|
-
def ScoreMatchL(context, match_list = [], match_scores = [],
|
|
3100
|
+
def ScoreMatchL(context, match_list = [], match_scores = [],
|
|
3101
|
+
number_matched = 0, threshold = 0)
|
|
3101
3102
|
threshold += 1 if (@indef_type & OTHER_BIT) != 0
|
|
3102
3103
|
threshold += 1 if (@indef_type & MY_BIT) != 0
|
|
3103
3104
|
threshold += 1 if (@indef_type & THAT_BIT) != 0
|
|
@@ -3129,7 +3130,8 @@ module Parser
|
|
|
3129
3130
|
for i in (0...number_matched)
|
|
3130
3131
|
obj = match_list[i]; its_owner = parent(obj); its_score = 0; met = 0
|
|
3131
3132
|
|
|
3132
|
-
# met+=1 if (@indef_type & OTHER_BIT) != 0 &&
|
|
3133
|
+
# met+=1 if (@indef_type & OTHER_BIT) != 0 &&
|
|
3134
|
+
# obj != @itobj && obj != @himobj && obj != @herobj
|
|
3133
3135
|
met += 1 if (@indef_type & MY_BIT) != 0 && (its_owner == @actor)
|
|
3134
3136
|
met += 1 if (@indef_type & THAT_BIT) != 0 && (its_owner == @actors_location)
|
|
3135
3137
|
met += 1 if (@indef_type & LIT_BIT) != 0 && obj.has?(:light)
|
|
@@ -3209,7 +3211,9 @@ module Parser
|
|
|
3209
3211
|
if defined?(DEBUG)
|
|
3210
3212
|
if @parser_trace >= 4
|
|
3211
3213
|
if best < 0 then println " Best guess ran out of choices"
|
|
3212
|
-
else
|
|
3214
|
+
else
|
|
3215
|
+
println " Best guess " + the(@match_list[earliest]) +
|
|
3216
|
+
" (#{@match_list[earliest]})"
|
|
3213
3217
|
end
|
|
3214
3218
|
end
|
|
3215
3219
|
end # DEBUG
|
|
@@ -3301,7 +3305,8 @@ module Parser
|
|
|
3301
3305
|
|
|
3302
3306
|
# def PrintInferredCommand(from = 0)
|
|
3303
3307
|
# singleton_noun = false
|
|
3304
|
-
# if from != 0 && from == (@pcount-1) &&
|
|
3308
|
+
# if from != 0 && from == (@pcount-1) &&
|
|
3309
|
+
# @pattern[from].object? # > 1 && @pattern[from] < REPARSE_CODE
|
|
3305
3310
|
# singleton_noun = true
|
|
3306
3311
|
# end
|
|
3307
3312
|
|
|
@@ -3310,7 +3315,8 @@ module Parser
|
|
|
3310
3315
|
|
|
3311
3316
|
# def PrintInferredCommand(from = nil)
|
|
3312
3317
|
# singleton_noun = false
|
|
3313
|
-
# if from != 0 && from == @pcount-1 &&
|
|
3318
|
+
# if from != 0 && from == @pcount-1 &&
|
|
3319
|
+
# @pattern[from].object? # && @pattern[from] < REPARSE_CODE
|
|
3314
3320
|
# singleton_noun = true
|
|
3315
3321
|
# end
|
|
3316
3322
|
# if singleton_noun == true
|
|
@@ -3593,10 +3599,7 @@ module Parser
|
|
|
3593
3599
|
if @parser_trace >= 6
|
|
3594
3600
|
println "[DSA on " + the(thing) + " with reason = " + scope_reason.to_s +
|
|
3595
3601
|
" p1 = #{@parser_one} p2 = #{@parser_two}]"
|
|
3596
|
-
|
|
3597
|
-
if name(thing) == 'Nels'
|
|
3598
|
-
caller.each { |t| println t }
|
|
3599
|
-
elsif DidScopeAction[thing][scope_reason] > 1
|
|
3602
|
+
if DidScopeAction[thing][scope_reason] > 1
|
|
3600
3603
|
println "Did DoScopeAction(#{thing}) with reason = #{scope_reason} more than once!"
|
|
3601
3604
|
caller.each { |t| println t }
|
|
3602
3605
|
end
|
|
@@ -3604,13 +3607,13 @@ module Parser
|
|
|
3604
3607
|
end # DEBUG
|
|
3605
3608
|
case scope_reason
|
|
3606
3609
|
when REACT_BEFORE_REASON
|
|
3607
|
-
return unless thing.react_before?(action)
|
|
3610
|
+
return unless thing.react_before?(@action)
|
|
3608
3611
|
if defined?(DEBUG)
|
|
3609
3612
|
println "[Considering react_before for " + the(thing) + "]" if @parser_trace >= 2
|
|
3610
3613
|
end
|
|
3611
3614
|
@parser_one ||= RunRoutines(thing, :react_before)
|
|
3612
3615
|
when REACT_AFTER_REASON
|
|
3613
|
-
return unless thing.react_after?(action)
|
|
3616
|
+
return unless thing.react_after?(@action)
|
|
3614
3617
|
if defined?(DEBUG)
|
|
3615
3618
|
println "[Considering react_after for " + the(thing) + "]" if @parser_trace >= 2
|
|
3616
3619
|
end # DEBUG
|
|
@@ -3790,7 +3793,8 @@ module Parser
|
|
|
3790
3793
|
println ">>...Matches are [#{matches_}] ([#{object_ids_}])"
|
|
3791
3794
|
end
|
|
3792
3795
|
println ">>...No matches yet" if @match_list.empty?
|
|
3793
|
-
println ">>...Matched by #{@match_length} word" +
|
|
3796
|
+
println ">>...Matched by #{@match_length} word" +
|
|
3797
|
+
(!@match_length.nil? && @match_length == 1 ? 's' : '')
|
|
3794
3798
|
println ">>...Match is #{obj} (#{obj.object_id})"
|
|
3795
3799
|
already_in_list = @match_list.include?(obj) ? 'Yes' : 'No'
|
|
3796
3800
|
println ">>...Is object id #{obj.object_id} already in the match list? #{already_in_list}"
|
|
@@ -3866,7 +3870,8 @@ module Parser
|
|
|
3866
3870
|
|
|
3867
3871
|
def TryGivenObject(obj)
|
|
3868
3872
|
if defined?(DEBUG)
|
|
3869
|
-
println " Trying " + the(obj) +
|
|
3873
|
+
println " Trying " + the(obj) +
|
|
3874
|
+
" (#{obj.object_id}) at word #{@wn + 1}" if @parser_trace >= 5
|
|
3870
3875
|
end # DEBUG
|
|
3871
3876
|
|
|
3872
3877
|
@dict_flags_of_noun = 0
|
|
@@ -4060,7 +4065,7 @@ module Parser
|
|
|
4060
4065
|
return NextWord()
|
|
4061
4066
|
end
|
|
4062
4067
|
|
|
4063
|
-
def WordAddress(wordnum); @
|
|
4068
|
+
def WordAddress(wordnum); @buffer[wordnum]; end
|
|
4064
4069
|
|
|
4065
4070
|
def WordLength(wordnum); @words[wordnum] ? @words[wordnum].length : 0; end
|
|
4066
4071
|
|
|
@@ -4196,20 +4201,20 @@ module Parser
|
|
|
4196
4201
|
i = @lightflag
|
|
4197
4202
|
@lightflag = OffersLight(parent(@player))
|
|
4198
4203
|
|
|
4199
|
-
if
|
|
4204
|
+
if i == false && @lightflag == true
|
|
4200
4205
|
@location = @real_location
|
|
4201
4206
|
log.debug "Looking after light adjustment for #{@player}" # TODO: Remove
|
|
4202
|
-
return _invoke :Look
|
|
4207
|
+
return _invoke :Look if flag == false
|
|
4203
4208
|
end
|
|
4204
4209
|
|
|
4205
|
-
if
|
|
4210
|
+
if i == true && @lightflag == false
|
|
4206
4211
|
@real_location = @location; @location = thedark
|
|
4207
|
-
|
|
4212
|
+
if flag == false
|
|
4208
4213
|
NoteArrival()
|
|
4209
4214
|
return L__M(:Miscellany, 9)
|
|
4210
4215
|
end
|
|
4211
4216
|
end
|
|
4212
|
-
@location = thedark if
|
|
4217
|
+
@location = thedark if i == false && @lightflag == false
|
|
4213
4218
|
end
|
|
4214
4219
|
|
|
4215
4220
|
def OffersLight(i)
|
|
@@ -4219,8 +4224,10 @@ module Parser
|
|
|
4219
4224
|
if i.has?(:container)
|
|
4220
4225
|
return OffersLight(parent(i)) if i.has?(:open) || i.has?(:transparent)
|
|
4221
4226
|
else
|
|
4222
|
-
return OffersLight(parent(i)) if i.has?(:enterable) ||
|
|
4227
|
+
return OffersLight(parent(i)) if i.has?(:enterable) ||
|
|
4228
|
+
i.has?(:transparent) || i.has?(:supporter)
|
|
4223
4229
|
end
|
|
4230
|
+
|
|
4224
4231
|
false
|
|
4225
4232
|
end
|
|
4226
4233
|
|
|
@@ -4271,7 +4278,7 @@ module Parser
|
|
|
4271
4278
|
i = @player; i = parent(i) until parent(i).nil?
|
|
4272
4279
|
@location = i; @real_location = @location
|
|
4273
4280
|
return RunTimeError(10) unless parent(@player)
|
|
4274
|
-
|
|
4281
|
+
MoveFloatingObjects()
|
|
4275
4282
|
@lightflag = OffersLight(parent(@player))
|
|
4276
4283
|
@location = thedark unless @lightflag
|
|
4277
4284
|
@print_player_flag = flag
|
|
@@ -4358,7 +4365,7 @@ module Parser
|
|
|
4358
4365
|
alias ShowverbSub ShowVerbSub
|
|
4359
4366
|
|
|
4360
4367
|
KnownNumberProperties = %i[number capacity time_left].freeze
|
|
4361
|
-
MethodWriterPattern = %r{=$}
|
|
4368
|
+
MethodWriterPattern = %r{=$}
|
|
4362
4369
|
|
|
4363
4370
|
def ShowobjSub
|
|
4364
4371
|
f = 0
|
|
@@ -4765,7 +4772,9 @@ module Parser
|
|
|
4765
4772
|
if defined? LanguagePrintShortName
|
|
4766
4773
|
return true if LanguagePrintShortName(o)
|
|
4767
4774
|
end # LanguagePrintShortName
|
|
4768
|
-
return true if @indef_mode &&
|
|
4775
|
+
return true if @indef_mode &&
|
|
4776
|
+
o.respond_to?(:short_name_indef) &&
|
|
4777
|
+
PrintOrRun(o, :short_name_indef, 1) != false
|
|
4769
4778
|
return true if !o.&(:short_name).nil? && PrintOrRun(o, :short_name, 1) != false
|
|
4770
4779
|
print o
|
|
4771
4780
|
end
|
|
@@ -4951,7 +4960,7 @@ module Parser
|
|
|
4951
4960
|
|
|
4952
4961
|
class NothingToRepeat < StandardError; end
|
|
4953
4962
|
|
|
4954
|
-
class
|
|
4963
|
+
class RepeatedCommand < StandardError; end
|
|
4955
4964
|
|
|
4956
4965
|
class SpeechImpediment < StandardError; end
|
|
4957
4966
|
|
|
@@ -4980,203 +4989,9 @@ class NoVerbRoutine < StandardError; end
|
|
|
4980
4989
|
|
|
4981
4990
|
class CycleError < StandardError; end
|
|
4982
4991
|
|
|
4983
|
-
# The Inform module
|
|
4984
|
-
module Inform
|
|
4985
|
-
# The Rules module defines functional additions to the Session state
|
|
4986
|
-
# machine. The additional functionality supports user interface patterns
|
|
4987
|
-
# commonly found in interactive fiction games, specifically those created
|
|
4988
|
-
# using Inform. Supporting the principle of least surprise mandates that
|
|
4989
|
-
# the expectations held by the users of such games should be satisfied.
|
|
4990
|
-
# TODO: Perhaps this should go in the mudlib
|
|
4991
|
-
module Rules
|
|
4992
|
-
def ask(s = nil)
|
|
4993
|
-
println s if s.is_a?(String)
|
|
4994
|
-
if session
|
|
4995
|
-
@previous ||= session.state
|
|
4996
|
-
session.state = :asked
|
|
4997
|
-
end
|
|
4998
|
-
# true
|
|
4999
|
-
session.state
|
|
5000
|
-
end
|
|
5001
|
-
|
|
5002
|
-
def yesorno(s = nil)
|
|
5003
|
-
print s.to_s unless s.nil?
|
|
5004
|
-
unless session.nil?
|
|
5005
|
-
@previous ||= session.state
|
|
5006
|
-
session.state = :asked
|
|
5007
|
-
end
|
|
5008
|
-
session&.state || false
|
|
5009
|
-
end
|
|
5010
|
-
|
|
5011
|
-
def asked
|
|
5012
|
-
yesorno?
|
|
5013
|
-
end
|
|
5014
|
-
|
|
5015
|
-
def yesorno?
|
|
5016
|
-
reset_io # TODO: Remove this. Why is the buffer getting a newline character added to it?
|
|
5017
|
-
case @buffer.split.first
|
|
5018
|
-
when /^(y|yes)$/i
|
|
5019
|
-
println(resume)
|
|
5020
|
-
responded
|
|
5021
|
-
when /^(n|no)$/i
|
|
5022
|
-
prompt
|
|
5023
|
-
responded
|
|
5024
|
-
else
|
|
5025
|
-
L__M(:Quit, 1); print "> "
|
|
5026
|
-
session&.state
|
|
5027
|
-
end
|
|
5028
|
-
end
|
|
5029
|
-
|
|
5030
|
-
def disambiguate
|
|
5031
|
-
session.state = :disambiguating unless session.nil?
|
|
5032
|
-
false
|
|
5033
|
-
end
|
|
5034
|
-
|
|
5035
|
-
def disambiguating
|
|
5036
|
-
WhichOne() if @ambiguity
|
|
5037
|
-
session.state = :playing unless session.nil?
|
|
5038
|
-
end
|
|
5039
|
-
|
|
5040
|
-
def complete
|
|
5041
|
-
session.state = :completing unless session.nil?
|
|
5042
|
-
false
|
|
5043
|
-
end
|
|
5044
|
-
|
|
5045
|
-
def completing
|
|
5046
|
-
Incomplete() if @ambiguity
|
|
5047
|
-
session.state = :playing unless session.nil?
|
|
5048
|
-
end
|
|
5049
|
-
|
|
5050
|
-
SolicitedStates = %i[asked yesorno? solicited].freeze
|
|
5051
|
-
def solicit(s = nil)
|
|
5052
|
-
if !session.nil? && !SolicitedStates.include?(session.state)
|
|
5053
|
-
prompt s if s.is_a?(String)
|
|
5054
|
-
@previous ||= session.state
|
|
5055
|
-
end
|
|
5056
|
-
session.state = :solicited unless session.nil?
|
|
5057
|
-
end
|
|
5058
|
-
|
|
5059
|
-
def disambiguated
|
|
5060
|
-
session.state = :playing unless session.nil?
|
|
5061
|
-
queue @input
|
|
5062
|
-
end
|
|
5063
|
-
|
|
5064
|
-
def completed
|
|
5065
|
-
session.state = :playing unless session.nil?
|
|
5066
|
-
queue @input
|
|
5067
|
-
end
|
|
5068
|
-
|
|
5069
|
-
def solicited
|
|
5070
|
-
responded? @input
|
|
5071
|
-
end
|
|
5072
|
-
|
|
5073
|
-
def responded
|
|
5074
|
-
session&.state = previous_state = @previous
|
|
5075
|
-
@previous = nil
|
|
5076
|
-
session&.state || previous_state
|
|
5077
|
-
end
|
|
5078
|
-
|
|
5079
|
-
def asked?
|
|
5080
|
-
session&.state == :asked
|
|
5081
|
-
end
|
|
5082
|
-
|
|
5083
|
-
def disambiguating?
|
|
5084
|
-
session&.state == :disambiguating
|
|
5085
|
-
end
|
|
5086
|
-
|
|
5087
|
-
def completing?
|
|
5088
|
-
session&.state == :completing
|
|
5089
|
-
end
|
|
5090
|
-
|
|
5091
|
-
def solicited?
|
|
5092
|
-
session&.state == :solicited
|
|
5093
|
-
end
|
|
5094
|
-
|
|
5095
|
-
def responded?(_s)
|
|
5096
|
-
reset_io # TODO: Remove this. Why is the buffer getting a newline character added to it?
|
|
5097
|
-
if @buffer.empty?
|
|
5098
|
-
prompt
|
|
5099
|
-
else
|
|
5100
|
-
responded
|
|
5101
|
-
@consult_words = @input = @buffer.dup
|
|
5102
|
-
result = resume
|
|
5103
|
-
println(result)
|
|
5104
|
-
if result == :playing
|
|
5105
|
-
reset_prompt
|
|
5106
|
-
prompt
|
|
5107
|
-
end
|
|
5108
|
-
end
|
|
5109
|
-
session&.state
|
|
5110
|
-
end
|
|
5111
|
-
|
|
5112
|
-
More = Struct.new(:text, :page_index)
|
|
5113
|
-
|
|
5114
|
-
DefaultMoreParameters = {
|
|
5115
|
-
page_index: 0, limit: 10, help: nil, done: :playing
|
|
5116
|
-
}.freeze
|
|
5117
|
-
|
|
5118
|
-
# This method supports the MoreSub verb implementation.
|
|
5119
|
-
def more(text = nil, params = {})
|
|
5120
|
-
params = DefaultMoreParameters.merge(params)
|
|
5121
|
-
unless session
|
|
5122
|
-
println text
|
|
5123
|
-
return params[:done]
|
|
5124
|
-
end
|
|
5125
|
-
input = @buffer.dup
|
|
5126
|
-
@more ||= More.new([], params[:page_index])
|
|
5127
|
-
|
|
5128
|
-
if text
|
|
5129
|
-
@more.text = text
|
|
5130
|
-
else
|
|
5131
|
-
text = @more.text
|
|
5132
|
-
end
|
|
5133
|
-
|
|
5134
|
-
case input
|
|
5135
|
-
when /\?/
|
|
5136
|
-
println params[:help] || "<Help for More goes here>"
|
|
5137
|
-
when /^(q|quit)$/
|
|
5138
|
-
@more = nil
|
|
5139
|
-
@prompt = nil
|
|
5140
|
-
prompt
|
|
5141
|
-
return session.state = params[:done]
|
|
5142
|
-
else
|
|
5143
|
-
text = @more.text.split('\n') if @more.text.is_a? String
|
|
5144
|
-
unless text.is_a?(Array)
|
|
5145
|
-
println "[Error: Format problem using the more command -- cannot handle given text.]"
|
|
5146
|
-
return session.state = params[:done]
|
|
5147
|
-
end
|
|
5148
|
-
|
|
5149
|
-
println text[@more.page_index, params[:limit]].join("\n")
|
|
5150
|
-
|
|
5151
|
-
@more.page_index += params[:limit]
|
|
5152
|
-
end
|
|
5153
|
-
|
|
5154
|
-
percent_complete = [100, (100 * (@more.page_index.to_f / text.length)).floor].min
|
|
5155
|
-
@more = nil unless @more.page_index < @more.text.length
|
|
5156
|
-
|
|
5157
|
-
new_line
|
|
5158
|
-
print "--More--(#{percent_complete}%)"
|
|
5159
|
-
|
|
5160
|
-
if percent_complete < 100
|
|
5161
|
-
prompt " [?]: "
|
|
5162
|
-
session.state = :more
|
|
5163
|
-
else
|
|
5164
|
-
new_line
|
|
5165
|
-
prompt nil
|
|
5166
|
-
session.state = params[:done]
|
|
5167
|
-
end
|
|
5168
|
-
end
|
|
5169
|
-
# def more
|
|
5170
|
-
end
|
|
5171
|
-
# module Rules
|
|
5172
|
-
end
|
|
5173
|
-
# module Inform
|
|
5174
|
-
|
|
5175
4992
|
# The InformLibrary class.
|
|
5176
4993
|
# Inform 6 defines this as an Object.
|
|
5177
4994
|
class InformLibrary < Inform::Ephemeral::Object
|
|
5178
|
-
REGISTRY = Struct.new(:memo).new(defined?(Java) ? java.util.concurrent.ConcurrentHashMap.new : {})
|
|
5179
|
-
include Inform::Rules
|
|
5180
4995
|
include Inform::Parser
|
|
5181
4996
|
|
|
5182
4997
|
attr_accessor :player
|
|
@@ -5204,48 +5019,45 @@ class InformLibrary < Inform::Ephemeral::Object
|
|
|
5204
5019
|
def play
|
|
5205
5020
|
@real_location = thedark
|
|
5206
5021
|
@player = selfobj; @actor = @player
|
|
5207
|
-
|
|
5022
|
+
log.debug "Setting capacity of #{selfobj.identity} to #{MAX_CARRIED}"
|
|
5023
|
+
selfobj.&(:capacity, MAX_CARRIED) # ### change?
|
|
5024
|
+
log.debug " selfobj.&(:capacity): #{selfobj.&(:capacity)}"
|
|
5208
5025
|
|
|
5209
5026
|
new_line
|
|
5210
5027
|
LibraryExtensions.RunAll(:ext_initialise)
|
|
5211
5028
|
j = Initialise()
|
|
5029
|
+
# Ruby doesn't automatically print implicitly returned strings :(
|
|
5212
5030
|
println j if j.is_a?(String)
|
|
5031
|
+
@last_score = @score
|
|
5213
5032
|
move @player, @location
|
|
5214
|
-
light_adjusted @player
|
|
5215
5033
|
|
|
5216
5034
|
@location = @location.parent until @location.parent.nil?
|
|
5217
5035
|
@real_location = @location
|
|
5218
5036
|
@actor = @player # resync, because player may have been changed in initialise()
|
|
5219
5037
|
Banner() if j != 2
|
|
5038
|
+
MoveFloatingObjects()
|
|
5220
5039
|
@lightflag = OffersLight(@player.parent)
|
|
5221
5040
|
if @lightflag == false
|
|
5222
5041
|
@real_location = @location
|
|
5223
5042
|
@location = @thedark
|
|
5224
5043
|
end
|
|
5225
|
-
OBIT_HEAD() if deadflag
|
|
5226
|
-
@player.mute if deadflag
|
|
5044
|
+
OBIT_HEAD() if deadflag != 0
|
|
5227
5045
|
invoke :Look
|
|
5228
|
-
deadflag ? :death : :playing
|
|
5046
|
+
deadflag != 0 ? :death : :playing
|
|
5229
5047
|
end
|
|
5230
5048
|
|
|
5231
5049
|
def playing
|
|
5232
|
-
@player.unmute if @player.respond_to?(:unmute) &&
|
|
5050
|
+
@player.unmute if @player.respond_to?(:unmute) && deadflag != 0
|
|
5233
5051
|
enqueue(command: @buffer.dup)
|
|
5234
5052
|
|
|
5235
|
-
|
|
5236
|
-
|
|
5237
|
-
|
|
5053
|
+
if deadflag != 0
|
|
5054
|
+
log.debug "#{@player} is entering the death state" # TODO: Remove
|
|
5055
|
+
:death
|
|
5238
5056
|
end
|
|
5239
5057
|
|
|
5240
|
-
|
|
5241
|
-
return very__late__error if deadflag == 0
|
|
5058
|
+
return session.state if respond_to?(:session) && !session.nil?
|
|
5242
5059
|
|
|
5243
|
-
|
|
5244
|
-
ScoreSub()
|
|
5245
|
-
DisplayStatus()
|
|
5246
|
-
AfterGameOver()
|
|
5247
|
-
log.debug "#{@player} is entering the death state" # TODO: Remove
|
|
5248
|
-
:death
|
|
5060
|
+
__method__
|
|
5249
5061
|
end
|
|
5250
5062
|
|
|
5251
5063
|
def stop
|
|
@@ -5286,18 +5098,48 @@ class InformLibrary < Inform::Ephemeral::Object
|
|
|
5286
5098
|
|
|
5287
5099
|
@results = [nil, 0, nil, nil]; @meta = false
|
|
5288
5100
|
|
|
5289
|
-
|
|
5290
|
-
catch
|
|
5101
|
+
# i = 0
|
|
5102
|
+
# catch(:continue) do
|
|
5103
|
+
# rubocop: disable Lint/UnreachableLoop
|
|
5104
|
+
while @deadflag == 0 # everything happens in this loop
|
|
5105
|
+
return very__late__error()
|
|
5106
|
+
end
|
|
5107
|
+
# rubocop: enable Lint/UnreachableLoop
|
|
5108
|
+
# end
|
|
5109
|
+
AfterLife() if deadflag != 2
|
|
5110
|
+
return very__late__error if deadflag == 0
|
|
5111
|
+
|
|
5112
|
+
OBIT_HEAD()
|
|
5113
|
+
ScoreSub()
|
|
5114
|
+
DisplayStatus()
|
|
5115
|
+
AfterGameOver()
|
|
5116
|
+
end
|
|
5117
|
+
|
|
5118
|
+
def very__late__error
|
|
5119
|
+
if @score != @last_score
|
|
5120
|
+
NotifyTheScore() if @notify_mode == true
|
|
5121
|
+
@last_score = @score
|
|
5122
|
+
end
|
|
5123
|
+
late__error()
|
|
5124
|
+
rescue NoVerbRoutine, NotImplemented
|
|
5125
|
+
"Sorry, that action is not yet implemented."
|
|
5126
|
+
rescue NoMethodError => e
|
|
5127
|
+
parser_error e, "Sorry, there was a program error involving a missing method."
|
|
5128
|
+
rescue TypeError => e
|
|
5129
|
+
parser_error e, "Sorry, there was a program error involving the wrong type of object."
|
|
5130
|
+
rescue StandardError => e
|
|
5131
|
+
parser_error e, "Sorry, there was an unhandled program error."
|
|
5132
|
+
end
|
|
5133
|
+
|
|
5134
|
+
def late__error
|
|
5135
|
+
|
|
5291
5136
|
# The Parser writes its results into @results and @meta,
|
|
5292
5137
|
# a flag indicating a "meta-verb". This can only be set for
|
|
5293
5138
|
# commands by the player, not for orders to others.
|
|
5294
5139
|
|
|
5295
|
-
parse_input
|
|
5296
|
-
|
|
5297
|
-
return if deadflag && !@meta
|
|
5298
|
-
end
|
|
5299
|
-
# ReParse
|
|
5140
|
+
parse_input
|
|
5300
5141
|
|
|
5142
|
+
# (Port note: inputobjs is now just results.)
|
|
5301
5143
|
@action = @results[0]
|
|
5302
5144
|
|
|
5303
5145
|
# --------------------------------------------------------------
|
|
@@ -5329,119 +5171,18 @@ class InformLibrary < Inform::Ephemeral::Object
|
|
|
5329
5171
|
@multiflag = false; @onotheld_mode = @notheld_mode; @notheld_mode = false
|
|
5330
5172
|
# For implicit taking and multiple object detection
|
|
5331
5173
|
|
|
5332
|
-
|
|
5333
|
-
@inp1 = nil; @inp2 = nil; i = @results[1]
|
|
5334
|
-
@inp1 = @results[2] if i >= 1
|
|
5335
|
-
@inp2 = @results[3] if i >= 2
|
|
5336
|
-
|
|
5337
|
-
# inp1 and inp2 hold: object numbers, or 0 for "multiple object",
|
|
5338
|
-
# or 1 for "a number or dictionary address"
|
|
5339
|
-
|
|
5340
|
-
if @inp1 == 1 then @noun = @special_number1 else @noun = @inp1 end
|
|
5341
|
-
if @inp2 == 1
|
|
5342
|
-
if @inp1 == 1 then @second = @special_number2
|
|
5343
|
-
else @second = @special_number1
|
|
5344
|
-
end
|
|
5345
|
-
else @second = @inp2
|
|
5346
|
-
end
|
|
5347
|
-
|
|
5348
|
-
# --------------------------------------------------------------
|
|
5349
|
-
|
|
5350
|
-
# TODO: FIXME
|
|
5351
|
-
# act_requester = nil
|
|
5352
|
-
#
|
|
5353
|
-
# if @actor != @player
|
|
5354
|
-
#
|
|
5355
|
-
# # The player's "orders" property can refuse to allow conversation
|
|
5356
|
-
# # here, by returning true. If not, the order is sent to the
|
|
5357
|
-
# # other person's "orders" property. If that also returns false,
|
|
5358
|
-
# # then: if it was a misunderstood command anyway, it is converted
|
|
5359
|
-
# # to an Answer action (thus "floyd, grrr" ends up as
|
|
5360
|
-
# # "say grrr to floyd"). If it was a good command, it is finally
|
|
5361
|
-
# # offered to the Order: part of the other person's "life"
|
|
5362
|
-
# # property, the old-fashioned way of dealing with conversation.
|
|
5363
|
-
#
|
|
5364
|
-
# j = RunRoutines(@player, :orders)
|
|
5365
|
-
# unless j
|
|
5366
|
-
# j = RunRoutines(@actor, :orders)
|
|
5367
|
-
# unless j
|
|
5368
|
-
# if action == :NotUnderstood
|
|
5369
|
-
# @results[3] = @actor; @actor = @player; @action = :Answer
|
|
5370
|
-
# #jump begin__action
|
|
5371
|
-
# end
|
|
5372
|
-
# if RunLife(@actor, :Order) == 0; L__M(:Order, 1, @actor); end
|
|
5373
|
-
# end
|
|
5374
|
-
# end
|
|
5375
|
-
# return # jump turn__end
|
|
5376
|
-
# end
|
|
5377
|
-
|
|
5378
|
-
# --------------------------------------------------------------
|
|
5379
|
-
# Generate the action...
|
|
5380
|
-
|
|
5381
|
-
if (i == 0) ||
|
|
5382
|
-
(i == 1 && @inp1 != 0) ||
|
|
5383
|
-
(i == 2 && @inp1 != 0 && @inp2 != 0) ||
|
|
5384
|
-
(i == @parameters && @inp1 != 0 && @inp2 != 0)
|
|
5385
|
-
result = self.begin_action(@action, @noun, @second, 0)
|
|
5386
|
-
# jump turn__end
|
|
5387
|
-
else
|
|
5388
|
-
|
|
5389
|
-
# ...unless a multiple object must be substituted. First:
|
|
5390
|
-
# (a) check the multiple list isn't empty;
|
|
5391
|
-
# (b) warn the player if it has been cut short because too long;
|
|
5392
|
-
# (c) generate a sequence of actions from the list
|
|
5393
|
-
# (stopping in the event of death or movement away).
|
|
5394
|
-
|
|
5395
|
-
@multiflag = true
|
|
5396
|
-
if @multiple_object.empty?
|
|
5397
|
-
return L__M(:Miscellany, 2)
|
|
5398
|
-
# jump late__error
|
|
5399
|
-
end
|
|
5400
|
-
if @toomany_flag
|
|
5401
|
-
@toomany_flag = false
|
|
5402
|
-
print L__M(:Miscellany, 1)
|
|
5403
|
-
end
|
|
5404
|
-
i = @location
|
|
5405
|
-
for l in @multiple_object
|
|
5406
|
-
return if deadflag
|
|
5407
|
-
return L__M(:Miscellany, 51) if @location != i
|
|
5408
|
-
PronounNotice(l)
|
|
5409
|
-
@second = @results[3]
|
|
5410
|
-
print "#{l}: "
|
|
5411
|
-
if @inp1 == 0
|
|
5412
|
-
@inp1 = l; zmsnp self.begin_action(@action, l, @second, 0); @inp1 = 0
|
|
5413
|
-
else
|
|
5414
|
-
@inp2 = l; zmsnp self.begin_action(@action, @noun, l, 0); @inp2 = 0
|
|
5415
|
-
end
|
|
5416
|
-
end
|
|
5417
|
-
end
|
|
5418
|
-
|
|
5419
|
-
# --------------------------------------------------------------
|
|
5420
|
-
|
|
5421
|
-
# label :turn__end do
|
|
5174
|
+
begin__action()
|
|
5422
5175
|
|
|
5423
|
-
|
|
5424
|
-
|
|
5425
|
-
|
|
5426
|
-
|
|
5427
|
-
NoteObjectAcquisitions()
|
|
5428
|
-
println(result, should_prompt: false)
|
|
5429
|
-
return true if result == false
|
|
5430
|
-
next
|
|
5431
|
-
end
|
|
5432
|
-
return result if @meta
|
|
5433
|
-
if defined? SINGLE_PLAYER
|
|
5434
|
-
self.end_turn_sequence() unless deadflag
|
|
5435
|
-
end
|
|
5436
|
-
println(result) if result.is_a?(String)
|
|
5437
|
-
# return result if defined? result
|
|
5438
|
-
return true
|
|
5439
|
-
end
|
|
5440
|
-
# 2.times do # NotHeld
|
|
5441
|
-
rescue RepeatedOrder
|
|
5442
|
-
return L__M(:Miscellany, REPEATED_ORDER)
|
|
5176
|
+
return session.state if respond_to?(:session) && !session.nil?
|
|
5177
|
+
true
|
|
5178
|
+
rescue RepeatedCommand
|
|
5179
|
+
return L__M(:Miscellany, REPEATED_COMMAND)
|
|
5443
5180
|
rescue NothingToRepeat
|
|
5444
5181
|
return L__M(:Miscellany, NOTHING_TO_REPEAT)
|
|
5182
|
+
rescue UnexpectedComma
|
|
5183
|
+
return L__M(:Miscellany, UNEXPECTED_COMMA)
|
|
5184
|
+
rescue MissingAddressee
|
|
5185
|
+
return L__M(:Miscellany, MISSING_ADDRESSEE)
|
|
5445
5186
|
rescue InanimateAddressee
|
|
5446
5187
|
return L__M(:Miscellany, CANT_TALK, noun)
|
|
5447
5188
|
rescue SpeechImpediment
|
|
@@ -5519,46 +5260,125 @@ class InformLibrary < Inform::Ephemeral::Object
|
|
|
5519
5260
|
return L__M(:Miscellany, NO_OBJECT)
|
|
5520
5261
|
rescue CycleError
|
|
5521
5262
|
return L__M(:Miscellany, TREE_ERROR)
|
|
5522
|
-
rescue NoVerbRoutine, NotImplemented
|
|
5523
|
-
return "Sorry, that action is not yet implemented."
|
|
5524
|
-
rescue NoMethodError => e
|
|
5525
|
-
log.error "Error parsing user command: #{e.class}: #{e}"
|
|
5526
|
-
e.backtrace.each { |t| log.error t }
|
|
5527
|
-
log.error "Parser was #{self.identity}"
|
|
5528
|
-
log.error "Input was: #{@input}"
|
|
5529
|
-
log.error "Actor was: #{@actor}"
|
|
5530
|
-
log.error "Action was: #{@action}"
|
|
5531
|
-
return "Sorry, something went wrong."
|
|
5532
|
-
rescue TypeError => e
|
|
5533
|
-
log.error "Error parsing user command: #{e.class}: #{e}"
|
|
5534
|
-
e.backtrace.each { |t| log.error t }
|
|
5535
|
-
log.error "Parser was #{self.identity}"
|
|
5536
|
-
log.error "Input was: #{@input}"
|
|
5537
|
-
log.error "Actor was: #{@actor}"
|
|
5538
|
-
log.error "Action was: #{@action}"
|
|
5539
|
-
return "Sorry, something went wrong."
|
|
5540
|
-
rescue StandardError => e
|
|
5541
|
-
log.error "Error parsing user command: #{e.class}: #{e}"
|
|
5542
|
-
e.backtrace.each { |t| log.error t }
|
|
5543
|
-
log.error "Parser was #{self.identity}"
|
|
5544
|
-
log.error "Input was: #{@input}"
|
|
5545
|
-
log.error "Actor was: #{@actor}"
|
|
5546
|
-
log.error "Action was: #{@action}"
|
|
5547
|
-
return "Sorry, something went seriously wrong."
|
|
5548
5263
|
end
|
|
5549
|
-
# def
|
|
5264
|
+
# def late__error
|
|
5265
|
+
|
|
5266
|
+
def begin__action()
|
|
5267
|
+
@inp1 = nil; @inp2 = nil; i = @results[1]
|
|
5268
|
+
@inp1 = @results[2] if i >= 1
|
|
5269
|
+
@inp2 = @results[3] if i >= 2
|
|
5270
|
+
|
|
5271
|
+
# inp1 and inp2 hold: object numbers, or 0 for "multiple object",
|
|
5272
|
+
# or 1 for "a number or dictionary address"
|
|
5273
|
+
|
|
5274
|
+
if @inp1 == 1 then @noun = @special_number1 else @noun = @inp1 end
|
|
5275
|
+
if @inp2 == 1
|
|
5276
|
+
if @inp1 == 1 then @second = @special_number2
|
|
5277
|
+
else @second = @special_number1
|
|
5278
|
+
end
|
|
5279
|
+
else @second = @inp2
|
|
5280
|
+
end
|
|
5281
|
+
|
|
5282
|
+
# --------------------------------------------------------------
|
|
5283
|
+
|
|
5284
|
+
if @actor != @player
|
|
5285
|
+
|
|
5286
|
+
# The player's "orders" property can refuse to allow conversation
|
|
5287
|
+
# here, by returning true. If not, the order is sent to the
|
|
5288
|
+
# other person's "orders" property. If that also returns false,
|
|
5289
|
+
# then: if it was a misunderstood command anyway, it is converted
|
|
5290
|
+
# to an Answer action (thus "floyd, grrr" ends up as
|
|
5291
|
+
# "say grrr to floyd"). If it was a good command, it is finally
|
|
5292
|
+
# offered to the Order: part of the other person's "life"
|
|
5293
|
+
# property, the old-fashioned way of dealing with conversation.
|
|
5294
|
+
|
|
5295
|
+
j = RunRoutines(@player, :orders)
|
|
5296
|
+
if j == false || j.nil?
|
|
5297
|
+
j = RunRoutines(@actor, :orders)
|
|
5298
|
+
if j == false || j.nil?
|
|
5299
|
+
if @action == :NotUnderstood
|
|
5300
|
+
@results[3] = @actor; @actor = @player; @action = :Answer
|
|
5301
|
+
return begin__action()
|
|
5302
|
+
end
|
|
5303
|
+
if RunLife(@actor, :Order) == 0 then L__M(:Order, 1, @actor); end
|
|
5304
|
+
end
|
|
5305
|
+
end
|
|
5306
|
+
return turn__end()
|
|
5307
|
+
end
|
|
5308
|
+
|
|
5309
|
+
# --------------------------------------------------------------
|
|
5310
|
+
# Generate the action...
|
|
5311
|
+
|
|
5312
|
+
if (i == 0) ||
|
|
5313
|
+
(i == 1 && @inp1 != 0) ||
|
|
5314
|
+
(i == 2 && @inp1 != 0 && @inp2 != 0) ||
|
|
5315
|
+
(i == @parameters && @inp1 != 0 && @inp2 != 0)
|
|
5316
|
+
result = self.begin_action(@action, @noun, @second, 0)
|
|
5317
|
+
print_routine_result(result)
|
|
5318
|
+
return turn__end(result)
|
|
5319
|
+
end
|
|
5320
|
+
|
|
5321
|
+
# ...unless a multiple object must be substituted. First:
|
|
5322
|
+
# (a) check the multiple list isn't empty;
|
|
5323
|
+
# (b) warn the player if it has been cut short because too long;
|
|
5324
|
+
# (c) generate a sequence of actions from the list
|
|
5325
|
+
# (stopping in the event of death or movement away).
|
|
5326
|
+
|
|
5327
|
+
@multiflag = true
|
|
5328
|
+
if @multiple_object.empty?
|
|
5329
|
+
return L__M(:Miscellany, 2)
|
|
5330
|
+
return late__error() # rubocop: disable Lint/UnreachableCode
|
|
5331
|
+
end
|
|
5332
|
+
if @toomany_flag
|
|
5333
|
+
@toomany_flag = false
|
|
5334
|
+
print L__M(:Miscellany, 1)
|
|
5335
|
+
end
|
|
5336
|
+
i = @location
|
|
5337
|
+
for l in @multiple_object
|
|
5338
|
+
return if deadflag != 0
|
|
5339
|
+
return L__M(:Miscellany, 51) if @location != i
|
|
5340
|
+
PronounNotice(l)
|
|
5341
|
+
@second = @results[3]
|
|
5342
|
+
print "#{l}: "
|
|
5343
|
+
if @inp1.nil?
|
|
5344
|
+
@inp1 = l; result = self.begin_action(@action, l, @second, 0); @inp1 = nil
|
|
5345
|
+
else
|
|
5346
|
+
@inp2 = l; result = self.begin_action(@action, @noun, l, 0); @inp2 = nil
|
|
5347
|
+
end
|
|
5348
|
+
print_routine_result(result)
|
|
5349
|
+
end
|
|
5350
|
+
turn__end(result)
|
|
5351
|
+
end
|
|
5352
|
+
# def begin__action
|
|
5353
|
+
|
|
5354
|
+
# --------------------------------------------------------------
|
|
5355
|
+
|
|
5356
|
+
def turn__end(result = nil)
|
|
5357
|
+
|
|
5358
|
+
# No time passes if either (i) the verb was meta, or
|
|
5359
|
+
# (ii) we've only had the implicit take before the "real"
|
|
5360
|
+
# action to follow.
|
|
5361
|
+
# if @notheld_mode then NoteObjectAcquisitions(); throw :continue; end
|
|
5362
|
+
if @notheld_mode then NoteObjectAcquisitions(); return true; end
|
|
5363
|
+
# throw :continue if @meta
|
|
5364
|
+
return true if @meta
|
|
5365
|
+
unless defined?(MULTI_PLAYER)
|
|
5366
|
+
self.end_turn_sequence() if deadflag == 0
|
|
5367
|
+
end
|
|
5368
|
+
result
|
|
5369
|
+
end
|
|
5550
5370
|
|
|
5551
5371
|
def end_turn_sequence
|
|
5552
5372
|
AdvanceWorldClock()
|
|
5553
|
-
return if deadflag
|
|
5373
|
+
return if deadflag != 0
|
|
5554
5374
|
RunTimersAndDaemons()
|
|
5555
|
-
return if deadflag
|
|
5375
|
+
return if deadflag != 0
|
|
5556
5376
|
RunEachTurnProperties()
|
|
5557
|
-
return if deadflag
|
|
5377
|
+
return if deadflag != 0
|
|
5558
5378
|
TimePasses()
|
|
5559
|
-
return if deadflag
|
|
5379
|
+
return if deadflag != 0
|
|
5560
5380
|
AdjustLight()
|
|
5561
|
-
return if deadflag
|
|
5381
|
+
return if deadflag != 0
|
|
5562
5382
|
NoteObjectAcquisitions()
|
|
5563
5383
|
end
|
|
5564
5384
|
|
|
@@ -5575,7 +5395,8 @@ class InformLibrary < Inform::Ephemeral::Object
|
|
|
5575
5395
|
end # DEBUG
|
|
5576
5396
|
|
|
5577
5397
|
contextualize
|
|
5578
|
-
|
|
5398
|
+
before = BeforeRoutines(a)
|
|
5399
|
+
if (!@verb.nil? && @verb.meta?) || before == false
|
|
5579
5400
|
rv = ActionPrimitive(a)
|
|
5580
5401
|
end
|
|
5581
5402
|
return rv
|
|
@@ -5589,9 +5410,9 @@ class InformLibrary < Inform::Ephemeral::Object
|
|
|
5589
5410
|
color :black_on_white
|
|
5590
5411
|
bgcolor :white
|
|
5591
5412
|
print "***"
|
|
5592
|
-
L__M(:Miscellany, 3) if deadflag
|
|
5413
|
+
L__M(:Miscellany, 3) if deadflag != 0
|
|
5593
5414
|
L__M(:Miscellany, 4) if deadflag == 2
|
|
5594
|
-
if deadflag !=
|
|
5415
|
+
if deadflag != 0 && deadflag != 1 && deadflag != 2
|
|
5595
5416
|
print " "
|
|
5596
5417
|
DeathMessage()
|
|
5597
5418
|
print " "
|
|
@@ -5609,7 +5430,7 @@ class InformLibrary < Inform::Ephemeral::Object
|
|
|
5609
5430
|
end
|
|
5610
5431
|
|
|
5611
5432
|
def AdvanceWorldClock
|
|
5612
|
-
return
|
|
5433
|
+
return if defined?(MULTI_PLAYER)
|
|
5613
5434
|
@turns += 1
|
|
5614
5435
|
if !@the_time.nil?
|
|
5615
5436
|
if @time_rate >= 0 then @the_time = @the_time + @time_rate
|
|
@@ -5625,10 +5446,10 @@ class InformLibrary < Inform::Ephemeral::Object
|
|
|
5625
5446
|
end
|
|
5626
5447
|
|
|
5627
5448
|
def RunTimersAndDaemons
|
|
5628
|
-
return if
|
|
5449
|
+
return if defined?(MULTI_PLAYER)
|
|
5629
5450
|
if defined?(DEBUG)
|
|
5630
5451
|
if (@debug_flag & 4) != 0
|
|
5631
|
-
@
|
|
5452
|
+
@the_timers.each do |the_timer|
|
|
5632
5453
|
next if the_timer.nil?
|
|
5633
5454
|
print name(the_timer & !WORD_HIGHBIT) + ": "
|
|
5634
5455
|
if (the_timer & WORD_HIGHBIT) != 0 then print "daemon"
|
|
@@ -5640,21 +5461,21 @@ class InformLibrary < Inform::Ephemeral::Object
|
|
|
5640
5461
|
end
|
|
5641
5462
|
end # DEBUG
|
|
5642
5463
|
|
|
5643
|
-
@
|
|
5464
|
+
@the_timers.each do |the_timer|
|
|
5644
5465
|
break if deadflag != 0
|
|
5645
5466
|
next if the_timer.nil?
|
|
5646
|
-
if (
|
|
5647
|
-
elsif the_timer
|
|
5467
|
+
if the_timer.respond_to?(:daemon) then RunRoutines(the_timer, :daemon)
|
|
5468
|
+
elsif (the_timer.&(:time_left) || nil) == 0
|
|
5648
5469
|
StopTimer(the_timer)
|
|
5649
|
-
RunRoutines(the_timer, time_out)
|
|
5470
|
+
RunRoutines(the_timer, :time_out)
|
|
5650
5471
|
else
|
|
5651
|
-
the_timer
|
|
5472
|
+
the_timer.&(:time_left, the_timer.|(:time_left, 0) - 1)
|
|
5652
5473
|
end
|
|
5653
5474
|
end
|
|
5654
5475
|
end
|
|
5655
5476
|
|
|
5656
5477
|
def RunEachTurnProperties
|
|
5657
|
-
return
|
|
5478
|
+
return if defined?(MULTI_PLAYER)
|
|
5658
5479
|
@scope_reason = scope_reason = EACH_TURN_REASON; @verb_word = nil
|
|
5659
5480
|
DoScopeAction(@location, scope_reason)
|
|
5660
5481
|
SearchScope(ScopeCeiling(@player), @player, nil)
|
|
@@ -5671,7 +5492,7 @@ class InformLibrary < Inform::Ephemeral::Object
|
|
|
5671
5492
|
end
|
|
5672
5493
|
|
|
5673
5494
|
def AfterGameOver
|
|
5674
|
-
return
|
|
5495
|
+
return if defined?(MULTI_PLAYER)
|
|
5675
5496
|
prompt
|
|
5676
5497
|
@temp_global = 0
|
|
5677
5498
|
i = @parse[1]
|
|
@@ -5700,13 +5521,15 @@ class InformLibrary < Inform::Ephemeral::Object
|
|
|
5700
5521
|
|
|
5701
5522
|
def R_Process(a, i, j)
|
|
5702
5523
|
s1 = @inp1; s2 = @inp2
|
|
5703
|
-
@inp1 = i; @inp2 = j;
|
|
5524
|
+
@inp1 = i; @inp2 = j; result = self.begin_action(a, i, j, 1)
|
|
5525
|
+
print_routine_result(result)
|
|
5526
|
+
ensure
|
|
5704
5527
|
@inp1 = s1; @inp2 = s2
|
|
5705
5528
|
end
|
|
5706
5529
|
|
|
5707
5530
|
def NoteObjectAcquisitions
|
|
5708
|
-
return
|
|
5709
|
-
player.objectloop
|
|
5531
|
+
return if defined?(MULTI_PLAYER)
|
|
5532
|
+
player.objectloop do |i|
|
|
5710
5533
|
if i.hasnt?(:moved)
|
|
5711
5534
|
give i, :moved
|
|
5712
5535
|
if i.has?(:scored)
|
|
@@ -5775,24 +5598,27 @@ class InformLibrary < Inform::Ephemeral::Object
|
|
|
5775
5598
|
|
|
5776
5599
|
def ZRegion(z)
|
|
5777
5600
|
return 0 if z.nil?
|
|
5778
|
-
|
|
5601
|
+
return 1 if z.object?
|
|
5602
|
+
case z # Left over from Inform 5
|
|
5779
5603
|
# when NilClass then 0
|
|
5780
|
-
when
|
|
5604
|
+
when Class then 1
|
|
5781
5605
|
when Symbol then 2
|
|
5782
5606
|
when String then 3
|
|
5783
5607
|
end
|
|
5784
5608
|
end
|
|
5785
5609
|
|
|
5786
|
-
def PrintOrRun(obj, prop, flag =
|
|
5610
|
+
def PrintOrRun(obj, prop, flag = false)
|
|
5787
5611
|
si = obj.inflib; obj.inflib = inflib
|
|
5788
|
-
return RunRoutines(obj, prop) if obj.properties.include?(prop)
|
|
5612
|
+
# return RunRoutines(obj, prop) if obj.properties.include?(prop)
|
|
5613
|
+
return RunRoutines(obj, prop) if obj.properties[prop].is_a?(Array)
|
|
5789
5614
|
if obj.respond_to?(prop) && !obj.method(prop).nil?
|
|
5790
5615
|
result = obj.send(prop)
|
|
5791
5616
|
if result.is_a?(Class) || result.nil? || obj.linked?(prop)
|
|
5792
5617
|
return RunTimeError(2, obj, prop)
|
|
5793
5618
|
elsif result.is_a?(String)
|
|
5794
5619
|
print result.to_s
|
|
5795
|
-
|
|
5620
|
+
raise "Why is flag true?" if flag == true
|
|
5621
|
+
new_line if flag == false
|
|
5796
5622
|
return true
|
|
5797
5623
|
else
|
|
5798
5624
|
return result
|
|
@@ -5804,12 +5630,12 @@ class InformLibrary < Inform::Ephemeral::Object
|
|
|
5804
5630
|
obj.inflib = si
|
|
5805
5631
|
end
|
|
5806
5632
|
|
|
5807
|
-
def PrintOrRunVar(var, flag)
|
|
5633
|
+
def PrintOrRunVar(var, flag = false)
|
|
5808
5634
|
if var.respond_to?(:name)
|
|
5809
5635
|
print var.name
|
|
5810
5636
|
elsif var.is_a?(String)
|
|
5811
5637
|
print var
|
|
5812
|
-
new_line if flag ==
|
|
5638
|
+
new_line if flag == false
|
|
5813
5639
|
elsif var.respond_to?(:call)
|
|
5814
5640
|
return var.call
|
|
5815
5641
|
else
|
|
@@ -5819,15 +5645,77 @@ class InformLibrary < Inform::Ephemeral::Object
|
|
|
5819
5645
|
end
|
|
5820
5646
|
|
|
5821
5647
|
def ValueOrRun(obj, prop)
|
|
5822
|
-
|
|
5823
|
-
|
|
5648
|
+
if obj.properties.key?(prop)
|
|
5649
|
+
value = obj.&(prop)
|
|
5650
|
+
return value.number? ? value.to_i : value
|
|
5651
|
+
elsif obj.respond_to?(prop)
|
|
5652
|
+
value = obj.send(prop)
|
|
5653
|
+
return value.number? ? value.to_i : value
|
|
5654
|
+
end
|
|
5655
|
+
return RunRoutines(obj, prop)
|
|
5824
5656
|
end
|
|
5825
5657
|
|
|
5826
5658
|
def RunRoutines(obj, prop)
|
|
5827
5659
|
obj = @real_location if obj == thedark && prop.notin?(:initial, :short_name, :description, :life)
|
|
5828
5660
|
return false if prop.nil?
|
|
5829
|
-
|
|
5830
|
-
|
|
5661
|
+
|
|
5662
|
+
value = obj.&(prop)
|
|
5663
|
+
return print_routine_result(value) unless value.nil?
|
|
5664
|
+
|
|
5665
|
+
reacts_to?(obj, prop)
|
|
5666
|
+
end
|
|
5667
|
+
|
|
5668
|
+
# ----------------------------------------------------------------------------
|
|
5669
|
+
|
|
5670
|
+
def StartTimer(obj, timer)
|
|
5671
|
+
return false if @the_timers.include?(obj)
|
|
5672
|
+
if @the_timers.length >= MAX_TIMERS
|
|
5673
|
+
RunTimeError(4)
|
|
5674
|
+
return
|
|
5675
|
+
end
|
|
5676
|
+
if obj.&(:time_left) == 0
|
|
5677
|
+
RunTimeError(5,obj)
|
|
5678
|
+
return
|
|
5679
|
+
end
|
|
5680
|
+
@the_timers << obj
|
|
5681
|
+
obj.&(:time_left, timer)
|
|
5682
|
+
end
|
|
5683
|
+
|
|
5684
|
+
def StopTimer(obj)
|
|
5685
|
+
return false unless @the_timers.include?(obj)
|
|
5686
|
+
if obj.&(:time_left) == 0
|
|
5687
|
+
RunTimeError(5,obj)
|
|
5688
|
+
return
|
|
5689
|
+
end
|
|
5690
|
+
@the_timers.delete(obj)
|
|
5691
|
+
obj.&(:time_left, 0)
|
|
5692
|
+
end
|
|
5693
|
+
|
|
5694
|
+
def StartDaemon(obj)
|
|
5695
|
+
return false if @the_timers.include?(obj)
|
|
5696
|
+
RunTimeError(4) if @the_timers.length >= MAX_TIMERS
|
|
5697
|
+
@the_timers << obj
|
|
5698
|
+
end
|
|
5699
|
+
|
|
5700
|
+
def StopDaemon(obj)
|
|
5701
|
+
return false unless @the_timers.include?(obj)
|
|
5702
|
+
@the_timers.delete(obj)
|
|
5703
|
+
end
|
|
5704
|
+
|
|
5705
|
+
# ----------------------------------------------------------------------------
|
|
5706
|
+
|
|
5707
|
+
def DisplayStatus
|
|
5708
|
+
if @sys_statusline_flag == 0 then @sline1 = @score; @sline2 = @turns
|
|
5709
|
+
else @sline1 = @the_time/60; @sline2 = @the_time%60; end
|
|
5710
|
+
end
|
|
5711
|
+
|
|
5712
|
+
def SetTime(t, s)
|
|
5713
|
+
@the_time = t; @time_rate = s; @time_step = 0
|
|
5714
|
+
@time_step = 0 - s if s < 0
|
|
5715
|
+
end
|
|
5716
|
+
|
|
5717
|
+
def NotifyTheScore
|
|
5718
|
+
print "\n["; L__M(:Miscellany, 50, @score - @last_score); print ".]\n"
|
|
5831
5719
|
end
|
|
5832
5720
|
# ----------------------------------------------------------------------------
|
|
5833
5721
|
end
|