! End of the parser proper: the remaining routines are its front end. ! ---------------------------------------------------------------------------- Object InformLibrary "(Inform Library)" with play [ i j k l; #Ifdef TARGET_ZCODE; standard_interpreter = HDR_TERPSTANDARD-->0; transcript_mode = ((HDR_GAMEFLAGS-->0) & 1); sys_statusline_flag = ( (HDR_TERPFLAGS->0) & 2 ) / 2; #Ifnot; ! TARGET_GLULX GGInitialise(); #Endif; ! TARGET_ ChangeDefault(cant_go, CANTGO__TX); #Ifdef TARGET_ZCODE; dict_start = HDR_DICTIONARY-->0; dict_entry_size = dict_start->(dict_start->0 + 1); dict_start = dict_start + dict_start->0 + 4; dict_end = dict_start + (dict_start - 2)-->0 * dict_entry_size; #Ifdef DEBUG; if (dict_start > 0 && dict_end < 0 && ((-dict_start) - dict_end) % dict_entry_size == 0) print "** Warning: grammar properties might not work correctly **^"; #Endif; ! DEBUG buffer->0 = INPUT_BUFFER_LEN; buffer2->0 = INPUT_BUFFER_LEN; buffer3->0 = INPUT_BUFFER_LEN; parse->0 = 15; parse2->0 = 15; #Endif; ! TARGET_ZCODE real_location = thedark; player = selfobj; actor = player; #Ifdef TARGET_ZCODE; top_object = #largest_object-255; #Endif; ! TARGET_ZCODE selfobj.capacity = MAX_CARRIED; ! ### change? #Ifdef LanguageInitialise; LanguageInitialise(); #Endif; ! LanguageInitialise new_line; LibraryExtensions.RunAll(ext_initialise); j = Initialise(); last_score = score; move player to location; while (parent(location) ~= 0) location = parent(location); real_location = location; actor = player; ! resync, because player may have been changed in initialise() actors_location = location; objectloop (i in player) give i moved ~concealed; if (j ~= 2) Banner(); MoveFloatingObjects(); lightflag = OffersLight(parent(player)); if (lightflag == 0) { real_location = location; location = thedark; } ; for (i=1 : i<=100 : i++) j = random(i); #Ifdef EnglishNaturalLanguage; old_itobj = itobj; old_himobj = himobj; old_herobj = herobj; #Endif;! EnglishNaturalLanguage while (~~deadflag) { ! everything happens in this loop #Ifdef EnglishNaturalLanguage; PronounOldEnglish(); old_itobj = PronounValue('it'); old_himobj = PronounValue('him'); old_herobj = PronounValue('her'); #Endif; ! EnglishNaturalLanguage .very__late__error; if (score ~= last_score) { if (notify_mode == 1) NotifyTheScore(); last_score = score; } .late__error; inputobjs-->0 = 0; inputobjs-->1 = 0; inputobjs-->2 = 0; inputobjs-->3 = 0; meta=false; ! The Parser writes its results into inputobjs and meta, ! a flag indicating a "meta-verb". This can only be set for ! commands by the player, not for orders to others. InformParser.parse_input(inputobjs); action = inputobjs-->0; ! -------------------------------------------------------------- ! Reverse "give fred biscuit" into "give biscuit to fred" if (action == ##GiveR or ##ShowR) { i = inputobjs-->2; inputobjs-->2 = inputobjs-->3; inputobjs-->3 = i; if (action == ##GiveR) action = ##Give; else action = ##Show; } ! Convert "P, tell me about X" to "ask P about X" if (action == ##Tell && inputobjs-->2 == player && actor ~= player) { inputobjs-->2 = actor; actor = player; action = ##Ask; } ! Convert "ask P for X" to "P, give X to me" if (action == ##AskFor && inputobjs-->2 ~= player && actor == player) { actor = inputobjs-->2; inputobjs-->2 = inputobjs-->3; inputobjs-->3 = player; action = ##Give; } ! For old, obsolete code: special_word contains the topic word ! in conversation if (action == ##Ask or ##Tell or ##Answer) special_word = special_number1; ! -------------------------------------------------------------- multiflag = false; onotheld_mode = notheld_mode; notheld_mode = false; ! For implicit taking and multiple object detection .begin__action; inp1 = 0; inp2 = 0; i = inputobjs-->1; if (i >= 1) inp1 = inputobjs-->2; if (i >= 2) inp2 = inputobjs-->3; ! inp1 and inp2 hold: object numbers, or 0 for "multiple object", ! or 1 for "a number or dictionary address" if (inp1 == 1) noun = special_number1; else noun = inp1; if (inp2 == 1) { if (inp1 == 1) second = special_number2; else second = special_number1; } else second = inp2; ! -------------------------------------------------------------- if (actor ~= player) { ! The player's "orders" property can refuse to allow conversation ! here, by returning true. If not, the order is sent to the ! other person's "orders" property. If that also returns false, ! then: if it was a misunderstood command anyway, it is converted ! to an Answer action (thus "floyd, grrr" ends up as ! "say grrr to floyd"). If it was a good command, it is finally ! offered to the Order: part of the other person's "life" ! property, the old-fashioned way of dealing with conversation. j = RunRoutines(player, orders); if (j == 0) { j = RunRoutines(actor, orders); if (j == 0) { if (action == ##NotUnderstood) { inputobjs-->3 = actor; actor = player; action = ##Answer; jump begin__action; } if (RunLife(actor, ##Order) == 0) L__M(##Order, 1, actor); } } jump turn__end; } ! -------------------------------------------------------------- ! Generate the action... if ((i == 0) || (i == 1 && inp1 ~= 0) || (i == 2 && inp1 ~= 0 && inp2 ~= 0)) { self.begin_action(action, noun, second, 0); jump turn__end; } ! ...unless a multiple object must be substituted. First: ! (a) check the multiple list isn't empty; ! (b) warn the player if it has been cut short because too long; ! (c) generate a sequence of actions from the list ! (stopping in the event of death or movement away). multiflag = true; j = multiple_object-->0; if (j == 0) { L__M(##Miscellany, 2); jump late__error; } if (toomany_flag) { toomany_flag = false; L__M(##Miscellany, 1); } i = location; for (k=1 : k<=j : k++) { if (deadflag) break; if (location ~= i) { L__M(##Miscellany, 51); break; } l = multiple_object-->k; PronounNotice(l); print (name) l, ": "; if (inp1 == 0) { inp1 = l; self.begin_action(action, l, second, 0); inp1 = 0; } else { inp2 = l; self.begin_action(action, noun, l, 0); inp2 = 0; } } ! -------------------------------------------------------------- .turn__end; ! No time passes if either (i) the verb was meta, or ! (ii) we've only had the implicit take before the "real" ! action to follow. if (notheld_mode == 1) { NoteObjectAcquisitions(); continue; } if (meta) continue; if (~~deadflag) self.end_turn_sequence(); else if (START_MOVE ~= 1) turns++; } ! end of while() if (deadflag ~= 2) AfterLife(); if (deadflag == 0) jump very__late__error; print "^^ "; #Ifdef TARGET_ZCODE; #IfV5; style bold; #Endif; ! V5 #Ifnot; ! TARGET_GLULX glk($0086, 5); ! set alert style #Endif; ! TARGET_ print "***"; if (deadflag == 1) L__M(##Miscellany, 3); if (deadflag == 2) L__M(##Miscellany, 4); if (deadflag > 2) { print " "; DeathMessage(); print " "; } print "***"; #Ifdef TARGET_ZCODE; #IfV5; style roman; #Endif; ! V5 #Ifnot; ! TARGET_GLULX glk($0086, 0); ! set normal style #Endif; ! TARGET_ #Ifdef NO_SCORE; print "^^"; #Ifnot; print "^^^"; #Endif; ! NO_SCORE ScoreSub(); DisplayStatus(); AfterGameOver(); ], ! end of 'play' property end_turn_sequence [; AdvanceWorldClock(); if (deadflag) return; RunTimersAndDaemons(); if (deadflag) return; RunEachTurnProperties(); if (deadflag) return; TimePasses(); if (deadflag) return; AdjustLight(); if (deadflag) return; NoteObjectAcquisitions(); ], begin_action [ a n s source sa sn ss; sa = action; sn = noun; ss = second; action = a; noun = n; second = s; #Ifdef DEBUG; if (debug_flag & 2 ~= 0) TraceAction(source); #Ifnot; source = 0; #Endif; ! DEBUG #Iftrue (Grammar__Version == 1); if ((meta || BeforeRoutines() == false) && action < 256) ActionPrimitive(); #Ifnot; if ((meta || BeforeRoutines() == false) && action < 4096) ActionPrimitive(); #Endif; ! Grammar__Version action = sa; noun = sn; second = ss; ], has proper; [ AdvanceWorldClock; turns++; if (the_time ~= NULL) { if (time_rate >= 0) the_time=the_time+time_rate; else { time_step--; if (time_step == 0) { the_time++; time_step = -time_rate; } } the_time = the_time % 1440; } ];