Run-time support for dialogue.
Global latest_performed_beat = 0; Global line_performance_count = 0; Array DialogueTopicPool --> 20; [ DirectorEmptyLiveSubjectList; DialogueTopicPool-->0 = 0; ]; [ DirectorAddLiveSubjectList obj i o2; for (i=0:i<20:i++) { o2 = DialogueTopicPool-->i; if (o2 == obj) return; if (o2 == 0) break; } for (i=18:i>0:i--) DialogueTopicPool-->i = DialogueTopicPool-->(i-1); DialogueTopicPool-->0 = obj; DialogueTopicPool-->19 = 0; ]; [ DirectorRemoveLiveSubjectList obj i j; for (i=0:i<20:i++) { if (DialogueTopicPool-->i == 0) return; if (DialogueTopicPool-->i == obj) { for (j=i:j<19:j++) DialogueTopicPool-->j = DialogueTopicPool-->(j+1); } } DialogueTopicPool-->19 = 0; ]; [ DirectorLiveSubjectList list len i; if ((list==0) || (BlkValueWeakKind(list) ~= LIST_OF_TY)) return 0; len = 0; while (DialogueTopicPool-->len) len++; LIST_OF_TY_SetLength(list, len); for (i=0: i<len: i++) LIST_OF_TY_PutItem(list, i+1, DialogueTopicPool-->i); return list; ]; [ DirectorAlterLiveSubjectList list len i; if ((list==0) || (BlkValueWeakKind(list) ~= LIST_OF_TY)) return 0; len = BlkValueRead(list, LIST_LENGTH_F); if (len > 19) len = 19; for (i=0: i<len: i++) DialogueTopicPool-->i = BlkValueRead(list, LIST_ITEM_BASE+i); DialogueTopicPool-->len = 0; DialogueTopicPool-->19 = 0; ]; [ DirectorBegin; DirectorEmptyLiveSubjectList(); latest_performed_beat = 0; director_sp = 0; DirectorStackChoices-->0 = BlkValueCreate(LIST_OF_TY); BlkValueWrite(DirectorStackChoices-->0, LIST_ITEM_KOV_F, DIALOGUE_CHOICE_TY); rfalse; ]; Constant MAX_BEAT_PERFORMANCE_NESTING = 20; Global director_sp = 0; Array DirectorStackBeat --> MAX_BEAT_PERFORMANCE_NESTING; Array DirectorStackAgain --> MAX_BEAT_PERFORMANCE_NESTING; Array DirectorStackLastPC --> MAX_BEAT_PERFORMANCE_NESTING; Array DirectorStackPC --> MAX_BEAT_PERFORMANCE_NESTING; Array DirectorStackChoices --> MAX_BEAT_PERFORMANCE_NESTING; Array DirectorStackMin --> MAX_BEAT_PERFORMANCE_NESTING; Array DirectorStackStart --> MAX_BEAT_PERFORMANCE_NESTING; Array DirectorStackLastSpeaker --> MAX_BEAT_PERFORMANCE_NESTING; Array DirectorStackLastInterlocutor --> MAX_BEAT_PERFORMANCE_NESTING; [ DirectorPush db max pc; if (director_sp >= MAX_BEAT_PERFORMANCE_NESTING) "*** Director stack overflow: too many open beats ***"; DirectorStackBeat-->director_sp = db; DirectorStackAgain-->director_sp = -1; DirectorStackLastPC-->director_sp = 0; DirectorStackPC-->director_sp = pc; DirectorStackMin-->director_sp = max; DirectorStackStart-->director_sp = 0; DirectorStackLastSpeaker-->director_sp = nothing; DirectorStackLastInterlocutor-->director_sp = nothing; if (DirectorStackChoices-->director_sp == 0) { DirectorStackChoices-->director_sp = BlkValueCreate(LIST_OF_TY); BlkValueWrite(DirectorStackChoices-->director_sp, LIST_ITEM_KOV_F, DIALOGUE_CHOICE_TY); } else { LIST_OF_TY_SetLength(DirectorStackChoices-->director_sp, 0); } director_sp++; if (debug_dialogue >= 2) { print "-- Push to: "; DirectorTraceStack(); } ]; [ DirectorPop; director_sp--; if (debug_dialogue >= 2) { print "-- Pop to: "; DirectorTraceStack(); } ]; [ DirectorPerform db without_detecting tab; if ((db == 0) || (db > NO_DIALOGUE_BEATS)) rfalse; if (debug_dialogue) { print "-- Performing ", (PrintDialogueBeatName) db, "^"; } WriteGProperty(DIALOGUE_BEAT_TY, db, performed, 1); latest_performed_beat = db; DirectorPush(db, 0, 0); DirectorStackStart-->(director_sp - 1) = 1; tab = TableOfDialogueBeats-->db; if ((tab-->3) && (without_detecting == false)) DetectSceneChange(); if (tab-->1) (tab-->1)(DialogueTopicPool, true); DirectorRun(0); if ((tab-->3) && (without_detecting == false)) DetectSceneChange(); if (debug_dialogue) { print "-- Performance of ", (PrintDialogueBeatName) db, " ended^"; } ]; [ DirectorBeatBeingPerformed db x; if ((db >= 1) && (db <= NO_DIALOGUE_BEATS)) for (x=0: x<director_sp: x++) if (DirectorStackBeat-->x == db) rtrue; rfalse; ]; [ DirectorPerformTiedBeat db; if (DirectorBeatBeingPerformed(db) == false) { DirectorPerform(db, true); } ]; [ PERFORM_OPENING_BEAT_R db; db = InitialSituation-->START_BEAT_INIS; if (db) DirectorPerform(db); rfalse; ]; [ DirectorTraceStack j structure pc instruction depth tab; if (director_sp > 0) { print "["; for (j=0: j<director_sp: j++) { if (j > 0) print " --> "; if (DirectorStackStart-->j) print "$"; print (PrintDialogueBeatName) DirectorStackBeat-->j; pc = DirectorStackPC-->j; if (pc == -1) print "+return"; else { tab = TableOfDialogueBeats-->(DirectorStackBeat-->j); structure = tab-->2; instruction = (structure-->pc)/100; depth = (structure-->pc)%100; if (DirectorStackAgain-->j >= 0) print "[*", DirectorStackAgain-->j, "]"; print "+", pc, " ", "L", depth, "/", DirectorStackMin-->j, " "; switch (instruction) { 0: print "STOP"; 1: print (PrintDialogueLineName) structure-->(pc+1); 2: print (PrintDialogueChoiceName) structure-->(pc+1); 3: switch (structure-->(pc+1)) { 2: print "TEXT-D"; 3: print "ACTION-D"; 4: print "CONTROL-D"; default: print "(*** unknown dtd ***)"; } default: print "*** unknown instruction ***"; } } if (LIST_OF_TY_GetLength(DirectorStackChoices-->j) > 0) { print " {"; LIST_OF_TY_Say(DirectorStackChoices-->j); print "}"; } } print "]^"; } else { print "[Director stack empty]^"; } ]; [ DirectorRun structure pc last_pc instruction depth next_instruction tab; while (true) { if (director_sp == 0) return; if (deadflag) { director_sp = 0; return; } if (LIST_OF_TY_GetLength(DirectorStackChoices-->(director_sp-1)) > 0) return; tab = TableOfDialogueBeats-->(DirectorStackBeat-->(director_sp-1)); if ((tab-->3) && (scene_status-->(tab-->3 - 1) == 0)) { DirectorPop(); return; } structure = tab-->2; pc = DirectorStackPC-->(director_sp-1); if (pc == -1) { DirectorPop(); return; } last_pc = pc; DirectorStackLastPC-->(director_sp-1) = last_pc; instruction = (structure-->pc)/100; depth = (structure-->pc)%100; if (instruction == 0) { DirectorPop(); return; } if (depth < DirectorStackMin-->(director_sp-1)) { DirectorPop(); return; } pc = pc + 2; while ((structure-->pc)%100 > depth) pc = pc + 2; if (structure-->pc == 0) pc = -1; else if (((structure-->pc)%100) < DirectorStackMin-->(director_sp-1)) pc = -1; if (debug_dialogue >= 2) { print "-- Instruction ("; if (pc >= 0) print "next is ", pc; else print "last"; print "): "; DirectorTraceStack(); } DirectorStackPC-->(director_sp-1) = pc; switch (instruction) { 1: Line if (DirectorPerformLine(structure-->(last_pc+1))) { next_instruction = structure-->(last_pc+2); if ((next_instruction) && (next_instruction % 100 == depth+1)) { DirectorPush(DirectorStackBeat-->(director_sp-1), depth+1, last_pc+2); DirectorRun(); } } 2: Choice print "*** Encountered choice node ***^"; 3: Decision DirectorStackAgain-->(director_sp-1) = last_pc; DirectorPerformDecision(structure-->(last_pc+1)); default: "*** Bad node ***"; } } ]; Global director_current_speaker; Global director_current_interlocutor; Global director_current_style = 1; [ DirectorCurrentLineSpeaker; return director_current_speaker; ]; [ DirectorCurrentLineInterlocutor; return director_current_interlocutor; ]; [ DirectorCurrentLineStyle; return director_current_style; ]; Global director_speaker_list; [ DirectorSelectConverser val select_speaker nonverbal speaker len i best best_score this_score x best_count; speaker = val; if (metaclass(val) == Routine) { if (director_speaker_list == 0) { director_speaker_list = BlkValueCreate(LIST_OF_TY); BlkValueWrite(director_speaker_list, LIST_ITEM_KOV_F, OBJECT_TY); } else { LIST_OF_TY_SetLength(director_speaker_list, 0); } objectloop (speaker ofclass K2_thing) if ((speaker ~= player) && (val(speaker))) LIST_OF_TY_InsertItem(director_speaker_list, speaker); len = LIST_OF_TY_GetLength(director_speaker_list); if (len == 0) return nothing; best = -1; best_score = -1; best_count = 0; for (i=1: i<=len: i++) { speaker = LIST_OF_TY_GetItem(director_speaker_list, i, nonverbal); this_score = DirectorScoreConverser(speaker, select_speaker, nonverbal); if (this_score > best_score) { best = speaker; best_score = this_score; best_count = 1; } else if (this_score == best_score) { best_count++; } print (name) speaker, " scores ", this_score, "^"; } if (best_count < 1) "*** impossibly low ***"; print best_count, " option(s)^"; if (best_count == 1) return best; x = random(best_count); for (i=1: i<=len: i++) { speaker = LIST_OF_TY_GetItem(director_speaker_list, i); this_score = DirectorScoreConverser(speaker, select_speaker); if (this_score == best_score) { x--; if (x == 0) return speaker; } } return best; } return speaker; ]; [ DirectorScoreConverser speaker select_speaker nonverbal this_score; if (select_speaker) { if (OnStage(speaker, -1)) this_score = this_score + 16; if (DirectorTestAccessible(player, speaker, nonverbal)) this_score = this_score + 8; if (speaker == DirectorStackLastInterlocutor-->(director_sp-1)) this_score = this_score + 4; if (speaker ofclass K8_person) this_score = this_score + 2; if (speaker ~= DirectorStackLastSpeaker-->(director_sp-1)) this_score = this_score + 1; } else { if (OnStage(speaker, -1)) this_score = this_score + 16; if (DirectorTestAccessible(player, speaker, nonverbal)) this_score = this_score + 8; if (speaker == DirectorStackLastSpeaker-->(director_sp-1)) this_score = this_score + 4; if (speaker ofclass K8_person) this_score = this_score + 2; if (speaker ~= DirectorStackLastInterlocutor-->(director_sp-1)) this_score = this_score + 1; } return this_score; ]; [ DirectorPerformLine dl tab fn action_fn speaker interlocutor manner mentioning nonverbal; if (dl == 0) rfalse; line_performance_count++; Must either be unperformed or recurring if ((GProperty(DIALOGUE_LINE_TY, dl, performed)) && (GProperty(DIALOGUE_LINE_TY, dl, recurring) == 0)) rfalse; tab = TableOfDialogueLines-->dl; Must be available fn = tab-->0; if ((fn) && (fn() == false)) rfalse; if ((tab-->7) & 2) nonverbal = true; A speaker matching the description must be found, unless it's narration if (tab-->1) { speaker = DirectorSelectConverser(tab-->1, true, nonverbal); if ((speaker == nothing) || (DirectorTestAccessible(player, speaker, nonverbal) == false)) rfalse; } if (tab-->2) { interlocutor = DirectorSelectConverser(tab-->2, false, nonverbal); if ((interlocutor == nothing) || (DirectorTestAccessible(speaker, interlocutor, nonverbal) == false)) rfalse; } manner = tab-->4; action_fn = tab-->6; If the line is "after ..." some action, that action must succeed if (action_fn) if (action_fn(3, speaker) == false) rfalse; DirectorStackLastSpeaker-->(director_sp-1) = speaker; DirectorStackLastInterlocutor-->(director_sp-1) = interlocutor; DivideParagraphPoint(); director_current_speaker = speaker; director_current_interlocutor = interlocutor; director_current_style = manner; if (PERFORMING_DIALOGUE == 0) "*** no activity ***"; else { BeginActivity(PERFORMING_DIALOGUE, dl); if ((ForActivity(PERFORMING_DIALOGUE, dl)) && (RulebookFailed())) rfalse; EndActivity(PERFORMING_DIALOGUE, dl); } director_current_speaker = nothing; director_current_interlocutor = nothing; director_current_style = 1; DivideParagraphPoint(); WriteGProperty(DIALOGUE_LINE_TY, dl, performed, 1); if (action_fn) { action_fn(2, speaker); action_fn(1, speaker); } mentioning = tab-->5; switch (metaclass(mentioning)) { Object: DirectorAddLiveSubjectList(mentioning); Routine: mentioning(); } rtrue; ]; [ DirectorGetChoice list structure instruction depth dc tab pc fn; LIST_OF_TY_SetLength(list, 0); if (director_sp == 0) rfalse; tab = TableOfDialogueBeats-->(DirectorStackBeat-->(director_sp-1)); structure = tab-->2; pc = DirectorStackLastPC-->(director_sp-1); instruction = (structure-->pc)/100; depth = (structure-->pc)%100; pc = pc + 2; while ((structure-->pc)%100 > depth) { if ((structure-->pc)%100 == depth+1) { dc = structure-->(pc+1); tab = TableOfDialogueChoices-->dc; if ((GProperty(DIALOGUE_CHOICE_TY, dc, performed) == 0) || (GProperty(DIALOGUE_CHOICE_TY, dc, recurring))) { Must be available fn = tab-->1; if ((fn == 0) || (fn())) LIST_OF_TY_InsertItem(list, dc); } } pc = pc + 2; } ]; [ DirectorPerformDecision decision dc tab count n structure spc i list pc; list = DirectorStackChoices-->(director_sp-1); DirectorGetChoice(list); count = LIST_OF_TY_GetLength(list); if (debug_dialogue >= 2) { if (count == 0) { print "-- no available options^"; } else if (decision == 2 or 3) { print "-- available options: "; LIST_OF_TY_Say(list); print "^"; } } if (count == 0) return; switch (decision) { 1: "*** blank dtd ***"; 2: DivideParagraphPoint(); if (OFFERING_A_DIALOGUE_CHOICE == 0) "*** no activity ***"; else { BeginActivity(OFFERING_A_DIALOGUE_CHOICE, list); if ((ForActivity(OFFERING_A_DIALOGUE_CHOICE, list)) && (RulebookFailed())) rfalse; EndActivity(OFFERING_A_DIALOGUE_CHOICE, list); } DivideParagraphPoint(); n = DirectorPickANumber(count); dc = LIST_OF_TY_GetItem(list, n); LIST_OF_TY_SetLength(list, 0); tab = TableOfDialogueChoices-->dc; style bold; TEXT_TY_Say(tab-->2); style roman; print "^"; say__p = 1; DivideParagraphPoint(); DirectorExerciseChoice(dc); 3: rfalse; 4: dc = LIST_OF_TY_GetItem(list, 1); LIST_OF_TY_SetLength(list, 0); if (dc) DirectorPerformChoice(dc); else "*** c = 0 ***"; default: "*** unknown dtd ***"; } rfalse; ]; [ DirectorBeforeAction N list was dc i fn chose tab; return DirectorScreenActionChoices(BEFORE_DSEL); ]; [ DirectorInsteadAction N list was dc i fn chose tab; return DirectorScreenActionChoices(INSTEAD_OF_DSEL); ]; [ DirectorAfterAction N list was dc i fn chose tab; return DirectorScreenActionChoices(AFTER_DSEL); ]; [ DirectorScreenActionChoices wanted N list was dc i fn chose tab suppress_otherwise; if (director_sp > 0) { if (debug_dialogue >= 2) { print "-- found: "; DirectorTraceStack(); } list = DirectorStackChoices-->(director_sp-1); N = LIST_OF_TY_GetLength(list); if (N > 0) { for (i=1: i<=N: i++) { dc = LIST_OF_TY_GetItem(list, i); tab = TableOfDialogueChoices-->dc; print "-- type: ", tab-->0, "^"; if ((tab-->0 == OTHERWISE_DSEL) && (suppress_otherwise == false)) { chose = dc; break; } else { fn = tab-->2; if ((fn) && (fn())) { if (tab-->0 == wanted) { chose = dc; break; } else { suppress_otherwise = true; } } } } if (debug_dialogue >= 2) { if (chose) { print "-- selected ", (PrintDialogueChoiceName) chose, " at stage ", wanted, "^"; } else { print "-- no selection at stage ", wanted, "^"; } } if ((chose) || (wanted == -1)) { LIST_OF_TY_SetLength(list, 0); if (chose) DirectorExerciseChoice(chose); while (director_sp > 0) { was = director_sp; if (debug_dialogue) { print "-- Resuming ", (PrintDialogueBeatName) DirectorStackBeat-->(director_sp-1), "^"; } DirectorRun(); if (was == director_sp) break; } if (director_sp > 0) { if (debug_dialogue) { print "-- Stack not empty: "; DirectorTraceStack(); } } rtrue; } if (debug_dialogue >= 2) { print "-- gave up: "; DirectorTraceStack(); } } } rfalse; ]; [ DirectorCurrentChoiceList i L; if (director_sp == 0) return DirectorStackChoices-->0; return DirectorStackChoices-->(director_sp-1); ]; [ DirectorExerciseChoice dc structure pc spc tab; WriteGProperty(DIALOGUE_CHOICE_TY, dc, performed, 1); tab = TableOfDialogueBeats-->(DirectorStackBeat-->(director_sp-1)); structure = tab-->2; pc = DirectorStackLastPC-->(director_sp-1); spc = pc + 2; while (((structure-->spc)/100 ~= 2) || (structure-->(spc+1) ~= dc)) spc = spc + 2; spc = spc + 2; DirectorPush(DirectorStackBeat-->(director_sp-1), (structure-->pc) % 100 + 2, spc); DirectorRun(); ]; [ DirectorPickANumber max i j wa wl sign base digit_count n digit; for (::) { print ">"; #Ifdef TARGET_ZCODE; if (location == nothing || parent(player) == nothing) read buffer2 parse2; else read buffer2 parse2 DrawStatusLine; j = parse2->1; wa = buffer2 + parse2->5; wl = parse2->4; #Ifnot; TARGET_GLULX; if (location ~= nothing && parent(player) ~= nothing) DrawStatusLine(); KeyboardPrimitive(buffer2, parse2); j = parse2-->0; wa = buffer2 + parse2-->3; wl = parse2-->2; #Endif; TARGET_ if (j) { at least one word entered sign = 1; base = 10; digit_count = 0; if (wa->0 ~= '-' or '$' or '0' or '1' or '2' or '3' or '4' or '5' or '6' or '7' or '8' or '9') jump Retry; if (wa->0 == '-') { sign = -1; wl--; wa++; } if (wl == 0) jump Retry; n = 0; while (wl > 0) { if (wa->0 >= 'a') digit = wa->0 - 'a' + 10; else digit = wa->0 - '0'; digit_count++; switch (base) { 2: if (digit_count == 17) jump Retry; 10: #Iftrue (WORDSIZE == 2); if (digit_count == 6) jump Retry; if (digit_count == 5) { if (n > 3276) jump Retry; if (n == 3276) { if (sign == 1 && digit > 7) jump Retry; if (sign == -1 && digit > 8) jump Retry; } } #Ifnot; i.e., if (WORDSIZE == 4) if (digit_count == 11) jump Retry; if (digit_count == 10) { if (n > 214748364) jump Retry; if (n == 214748364) { if (sign == 1 && digit > 7) jump Retry; if (sign == -1 && digit > 8) jump Retry; } } #Endif; 16: if (digit_count == 5) jump Retry; } if (digit >= 0 && digit < base) n = base*n + digit; else jump Retry; wl--; wa++; } n = n*sign; if ((n < 1) || (n > max)) jump Retry; return n; } .Retry; print "(Please type an option in the range 1 to ", max, " and press return.)^^"; } ]; Constant NEW_CHOICE_DSEL = 1; Constant TEXTUAL_DSEL = 2; Constant AGAIN_DSEL = 3; Constant STOP_DSEL = 4; Constant ENDING_DSEL = 5; Constant ENDING_SAYING_DSEL = 6; Constant ENDING_FINALLY_DSEL = 7; Constant ENDING_FINALLY_SAYING_DSEL = 8; Constant OTHERWISE_DSEL = 9; Constant INSTEAD_OF_DSEL = 10; Constant AFTER_DSEL = 11; Constant BEFORE_DSEL = 12; Constant PERFORM_DSEL = 13; [ DirectorPerformChoice dc tab fn pc enough; if (dc == 0) rfalse; WriteGProperty(DIALOGUE_CHOICE_TY, dc, performed, 1); tab = TableOfDialogueChoices-->dc; switch (tab-->0) { AGAIN_DSEL: if (debug_dialogue >= 2) { print "-- again^"; } while (director_sp > 0) { if (debug_dialogue >= 2) { print "-- again at: "; DirectorTraceStack(); } DirectorPop(); if (DirectorStackAgain-->(director_sp-1) >= 0) { DirectorStackPC-->(director_sp-1) = DirectorStackAgain-->(director_sp-1); break; } } rtrue; STOP_DSEL: if (debug_dialogue >= 2) { print "-- stop at: "; DirectorTraceStack(); } while (director_sp > 0) { enough = false; if (DirectorStackStart-->(director_sp-1)) enough = true; DirectorPop(); if (enough) break; } if (debug_dialogue >= 2) { print "-- after stop: "; DirectorTraceStack(); } rtrue; ENDING_DSEL, ENDING_SAYING_DSEL, ENDING_FINALLY_DSEL, ENDING_FINALLY_SAYING_DSEL: if (debug_dialogue >= 2) { print "-- ending at: "; DirectorTraceStack(); } deadflag = tab-->2; if (tab-->0 == ENDING_FINALLY_DSEL or ENDING_FINALLY_SAYING_DSEL) story_complete = true; rtrue; PERFORM_DSEL: DirectorPerform(tab-->2); rtrue; default: print "*** Unimplemented choice ***^"; rfalse; } rtrue; ]; [ DirectorListLiveTopics i t; for (i=0: i<20: i++) { t = DialogueTopicPool-->i; if (t == 0) return; print (name) t, "^"; } ]; [ DirectorBeatAvailable db fn tab; if ((db == 0) || (db > NO_DIALOGUE_BEATS)) rfalse; tab = TableOfDialogueBeats-->db; fn = tab-->0; if (fn) { return (fn)(latest_performed_beat); } rtrue; ]; [ DirectorBeatRelevant db fn tab; if ((db == 0) || (db > NO_DIALOGUE_BEATS)) rfalse; tab = TableOfDialogueBeats-->db; fn = tab-->1; if (fn) { return (fn)(DialogueTopicPool); } rfalse; ]; [ DirectorBeatPrintStructure db tab pc which depth i; if ((db == 0) || (db > NO_DIALOGUE_BEATS)) return; print (PrintDialogueBeatName) db; print " ("; if (DirectorBeatAvailable(db)) print "available"; else print "unavailable"; print ", "; if (DirectorBeatRelevant(db)) print "relevant"; else print "irrelevant"; print "):^"; tab = TableOfDialogueBeats-->db; tab = tab-->2; if (tab) { pc = 0; while (tab-->pc) { which = (tab-->pc)/100; depth = (tab-->pc)%100; for (i=0: i<depth: i++) print " "; switch (which) { 1: print "Line ", (PrintDialogueLineName) tab-->(pc+1), "^"; 2: print "Choice ", (PrintDialogueChoiceName) tab-->(pc+1), "^"; 3: print "Decision of type ", tab-->(pc+1), "^"; default: print "*** Unimplemented ***^"; } pc = pc + 2; } } ]; [ DirectorLineAvailable dl tab i; if ((dl == 0) || (dl > NO_DIALOGUE_LINES)) rfalse; tab = TableOfDialogueLines-->dl; if (tab-->0) { return (tab-->0)(); } rtrue; ]; Global director_is_active = false; [ DirectorActivate; director_is_active = true; line_performance_count = 0; ]; [ DirectorDeactivate; director_is_active = false; ]; [ DirectorTestAccessible from to nonverbal; if (nonverbal) return TestVisibility(from, to); return TestAudibility(from, to); ]; [ DirectorBeatAvailableToPlayer db tab i speaker; if ((GProperty(DIALOGUE_BEAT_TY, db, performed) == 0) || (GProperty(DIALOGUE_BEAT_TY, db, recurring))) { tab = TableOfDialogueBeats-->db; i = 4; while (true) { speaker = tab-->i; if (speaker == nothing) rtrue; if (TestAudibility(player, speaker) == false) rfalse; i++; } } rfalse; ]; [ DirectorLiveRequiredList list db len i tab speaker; if ((list==0) || (BlkValueWeakKind(list) ~= LIST_OF_TY)) return 0; len = 0; tab = TableOfDialogueBeats-->db; i = 4; while (true) { speaker = tab-->i; if (speaker == nothing) break; len++; i++; } LIST_OF_TY_SetLength(list, len); for (i=0: i<len: i++) LIST_OF_TY_PutItem(list, i+1, tab-->(i+4)); return list; ]; [ DIALOGUE_DIRECTION_R db i topic fn tab; if (director_is_active == false) rfalse; If nothing much has happened this turn... if ((director_sp == 0) && (line_performance_count == 0)) { for (db=1: db<=NO_DIALOGUE_BEATS: db++) { if (DirectorBeatAvailableToPlayer(db)) { tab = TableOfDialogueBeats-->db; fn = tab-->0; if ((fn == 0) || ((fn)(latest_performed_beat))) { fn = tab-->1; if ((fn) && (fn(DialogueTopicPool))) { DirectorPerform(db); line_performance_count = 0; rfalse; } } } } for (db=1: db<=NO_DIALOGUE_BEATS: db++) { if (GProperty(DIALOGUE_BEAT_TY, db, spontaneous)) { if (DirectorBeatAvailableToPlayer(db)) { DirectorEmptyLiveSubjectList(); DirectorPerform(db); line_performance_count = 0; rfalse; } } } } line_performance_count = 0; rfalse; ]; Array DirectorMiniPool --> 0 0; [ DirectorIntervenes obj tab fn db saved; saved = DirectorMiniPool-->0; DirectorMiniPool-->0 = obj; for (db=1: db<=NO_DIALOGUE_BEATS: db++) { if (DirectorBeatAvailableToPlayer(db)) { tab = TableOfDialogueBeats-->db; fn = tab-->0; if ((fn == 0) || ((fn)(latest_performed_beat))) { fn = tab-->1; if ((fn) && (fn(DirectorMiniPool))) { DirectorMiniPool-->0 = saved; DirectorPerform(db); rtrue; } } } } DirectorMiniPool-->0 = saved; rfalse; ]; [ DirectorTestLineContainment X db tX tb tab structure pc instruction wanted; print "I.e. whether ", (PrintDialogueLineName) X, " is in ", (PrintDialogueBeatName) db, "^"; if (tb ~= DIALOGUE_BEAT_TY) { print "*** Not a db ***"; rfalse; } if (tX ~= DIALOGUE_LINE_TY or DIALOGUE_CHOICE_TY) { print "*** Not a dl/dc ***"; rfalse; } if ((db < 1) || (db > NO_DIALOGUE_BEATS)) rfalse; if (tX == DIALOGUE_LINE_TY) { if ((X < 1) || (X > NO_DIALOGUE_LINES)) rfalse; wanted = 1; } else { if ((X < 1) || (X > NO_DIALOGUE_CHOICES)) rfalse; wanted = 2; } tab = TableOfDialogueBeats-->db; structure = tab-->2; pc = 0; instruction = (structure-->pc)/100; while (instruction) { if ((instruction == wanted) && (structure-->(pc+1) == X)) rtrue; pc = pc + 2; instruction = (structure-->pc)/100; } rfalse; ]; [ DirectorLineContent dl text tab; if ((dl == 0) || (dl > NO_DIALOGUE_LINES)) return text; tab = TableOfDialogueLines-->dl; BlkValueCopy(text, tab-->3); return text; ]; [ DirectorLineNarrated dl tab; if ((dl == 0) || (dl > NO_DIALOGUE_LINES)) rfalse; tab = TableOfDialogueLines-->dl; if (tab-->1 == 0) rtrue; rfalse; ]; [ DirectorLineNonverbal dl tab; if ((dl == 0) || (dl > NO_DIALOGUE_LINES)) rfalse; tab = TableOfDialogueLines-->dl; if ((tab-->7) & 2) rtrue; rfalse; ]; [ DirectorChoiceStoryEnding dc tab; if ((dc == 0) || (dc > NO_DIALOGUE_CHOICES)) rfalse; tab = TableOfDialogueChoices-->dc; if (tab-->0 == ENDING_DSEL or ENDING_SAYING_DSEL or ENDING_FINALLY_DSEL or ENDING_FINALLY_SAYING_DSEL) rtrue; rfalse; ]; [ DirectorChoiceContent dc text tab; if ((dc == 0) || (dc > NO_DIALOGUE_CHOICES)) return text; tab = TableOfDialogueChoices-->dc; BlkValueCopy(text, tab-->2); return text; ]; [ DirectorChoiceFlowing dc tab type; if ((dc == 0) || (dc > NO_DIALOGUE_CHOICES)) rfalse; tab = TableOfDialogueChoices-->dc; type = tab-->0; if (type == NEW_CHOICE_DSEL or AGAIN_DSEL or STOP_DSEL or PERFORM_DSEL or ENDING_DSEL or ENDING_SAYING_DSEL or ENDING_FINALLY_DSEL or ENDING_FINALLY_SAYING_DSEL) rtrue; rfalse; ];