Ultima Underworld/technical/conversations/137
Technical Details Warning |
While the encyclopedic nature of the codex means that many articles will have information that could spoil some minor aspects of the game for newer players, this article is known to contain technical information about the game, game engine, data files, logic, etc. This information is not generally useful to the typical game players.
Continue reading at your own discretion. |
This page contains decompiled conversation code from Ultima Underworld. The original files came from Paul Carr and are currently archived here.
This file has been modified from that source (by Sir Robin) in the following ways:
- local variables holding pointers to string text have had that string text specified in a comment on that same line. This should make the conversation code easier to read.
- strings (both dereferenced ones in the code and also the ones added to comments as specified above) have been highlighted for easier reading
- function definitions have been anchored and function calls have been linked, to make it easier to follow the flow of the code
Start viewing the flow at main
// cnvdasm - ultima underworld conversation script disassembler / decompiler // // loading game strings // // conversation #137 // string block 0x0e89 (3721), name Linnet // // converting to graph // searching functions // replacing expression opcodes // folding expressions // adding control structures // fixing up functions extern int private[31]; void main() { private[1] = 0; func_029d(); func_0012(); } // end func void func_0012() { private[0] = 1; } // end func void func_0020() { int locals[1]; if ( (((npc_goal == 5 || npc_goal == 6) || npc_goal == 9) && npc_gtarg == 1 || npc_attitude == 0) ) { locals[1] = 0; } else { locals[1] = 1; } // end if return locals[1]; } // end func void func_0063() { npc_gtarg = 1; npc_attitude = 1; npc_goal = 6; func_0012(); } // end func void func_007c() { npc_goal = 1; func_0012(); } // end func void func_008b() { npc_gtarg = 1; npc_goal = 5; npc_attitude = 1; func_0012(); } // end func void func_00a4() { npc_attitude = 6; } // end func void func_00b1() { npc_attitude = param1[0]play_hunger; func_0012(); } // end func void func_00c2() { npc_attitude = 2; func_0012(); } // end func void func_00d1() { npc_attitude = 1; func_0012(); } // end func void func_00e0() { func_0012(); } // end func void func_00ea() { param1[1] = game_days; param1[2] = game_mins; } // end func void func_0106() { int locals[4]; locals[2] = game_days - param2[1]; locals[3] = game_mins - param2[2]; if ( locals[3] < 0 ) { locals[3] = locals[3] + 1440; locals[2] = locals[2] - 1; } // end if if ( locals[2] >= param1[1] && locals[3] >= param1[2] ) { locals[1] = 1; } else { locals[1] = 0; } // end if return locals[1]; } // end func void func_018f() { param1[1] = game_days - param3[1]; param1[2] = game_mins - param3[2]; if ( param1[2] < 0 ) { param1[2] = param1[2] + 1440; param1[1] = param1[1] - 1; } // end if param1[1] = param2[1] - param1[1]; param1[2] = param2[2] - param1[2]; if ( param1[2] < 0 ) { param1[2] = param1[2] + 1440; param1[1] = param1[1] - 1; } // end if } // end func void func_0243() { param1[1] = game_days - param2[1]; param1[2] = game_mins - param2[2]; if ( param1[2] < 0 ) { param1[2] = param1[2] + 1440; param1[1] = param1[1] - 1; } // end if } // end func void func_029d() { if ( private[0] == 0 ) { func_0602(); private[2] = 0; private[3] = 0; } // end if if ( private[0] ) { func_0559(); } else { func_02c4(); } // end if } // end func void func_02c4() { int locals[22]; say( "Hail, stranger. `Tis indeed a rare pleasure to encounter a new face amongst the denizens of the Abyss. What hast brought thee hither?" ); locals[1] = 2; // "I must prove I am innocent of a kidnapping." locals[2] = 3; // "I'd rather not dwell on it." locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_0319(); break; case 2: func_030c(); break; } // end switch } // end func void func_030c() { say( "Suit thyself, friend. `Tis thy business, not mine." ); func_0657(); } // end func void func_0319() { int locals[22]; say( "A terrible crime, indeed. I would fain believe thou art innocent of such, for thy face has honor in it. Thou dost wear it like few I have beheld in my many years in the Abyss. May I help thee in any way?" ); locals[1] = 6; // "Why art thou here?" locals[2] = 7; // "Hast thou heard aught of a princess?" locals[3] = 8; // "Canst thou tell me aught of this region of the Abyss?" locals[4] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_0375(); break; case 2: func_03bd(); break; case 3: func_04ad(); break; } // end switch } // end func void func_0375() { int locals[22]; say( "Like thee, I was unjustly accused of killing a man. I swear to thee I never struck him. I merely held him down whilst my brother kicked him. He should not have treated our sister as he did. And only a weak man could perish from such slight injuries." ); locals[1] = 10; // "Methinks thou art guilty as an accomplice." locals[2] = 11; // "Indeed, Almric's justice is a blind archer, oft missing the mark." locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_04ff(); break; case 2: func_050c(); break; } // end switch } // end func void func_03bd() { int locals[26]; if ( private[3] == 3 ) { say( "I fear I canst tell thee nothing new." ); locals[1] = 1; while ( locals[1] <= 3 ) { private[4][0] = 0; locals[1] = locals[1] + 1; } // while } else { locals[1] = random( 1, &locals[2] ); locals[2] = 3; while ( private[4][0] == 1 ) { locals[1] = random( 1, &locals[3] ); locals[3] = 3; } // while private[3] = private[3] + 1; locals[4] = locals[1]; if ( 1 == locals[4] ) { say( "It is said the trolls have captured a new dweller in the Abyss.\m" ); } else { if ( 2 == locals[4] ) { say( "I have heard there is to be a human sacrifice in Cabirus' old quarters on the lowest level.\m" ); } else { if ( 3 == locals[4] ) { say( "A Knight told me that a maiden's body had been found in the lower levels.\m" ); } // end if } // end if } // end if if ( private[2] == 1 ) { say( "In their search for some new advantage over the trolls, the Knights explore more widely than I. Mayhap they can tell thee more.\n" " Still, be careful, lest thou become the next casualty in their senseless battle with the trolls." ); func_0657(); } else { say( "It may be the Knights can tell thee something, for they travel more of the Abyss than I." ); locals[5] = 18; // "Tell me of these Knights." locals[6] = 19; // "I have problems enough of my own." locals[7] = 0; // "" locals[26] = babl_menu( 0, &locals[5] ); switch ( locals[26] ) { case 1: func_04ad(); break; case 2: func_0657(); } // end if } // end if break; } // end switch } // end func void func_04ad() { int locals[22]; say( "There is much tension on this level of the Abyss. The Knights inhabit the western area, and a pack of Trolls live in the eastern reaches.\n" " Even while Sir Cabirus was alive, there was an uneasy peace between them. After Cabirus' death, there was some strife, as each group attempted to gain power over the other, but these days there is relative peace.\m" ); say( "Perhaps the greatest danger in this area now is Rodrick, known as the Chaos Knight. He lives by the old banquet hall to the north. He is the foe of both the Knights and the Trolls, but neither has been able to defeat him yet. I hear that Dorna Ironfist has put a price upon his head." ); private[2] = 1; locals[1] = 22; // "Thank thee for thy information." locals[2] = 23; // "Hast thou heard news of a captive virgin in the Abyss?" locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_0657(); func_00e0(); break; case 2: func_03bd(); break; } // end switch } // end func void func_04ff() { say( "And methinks thou art a self-righteous ass, who wouldst be well-suited in the company of the pompous Knights with their overweening morals. Thy inflated ego wouldst find much company there." ); func_00d1(); } // end func void func_050c() { int locals[22]; say( "In sooth, thou speakest with a wisdom beyond thy years, friend. What I wouldst not give to teach that tyrant Almric a lesson about justice and honor! I would deal him a buffeting that would leave his heirs dizzy for generations to come.\m" ); say( "Would I could aid thee more, friend, but I know little. I have heard tell that a maiden is held captive near Cabirus's quarters far below. Perhaps the Knights could tell thee more." ); locals[1] = 27; // "What dost thou know of the Knights?" locals[2] = 28; // "I will take thy advice to heart." locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_04ad(); break; case 2: func_0657(); func_00e0(); break; } // end switch } // end func void func_0559() { int locals[44]; say( "Well met, friend. How dost thou in thy quest?" ); if ( private[2] == 0 ) { locals[1] = 30; // "Not well. Hast thou any news for me?" locals[2] = 31; // "Well. I must soon head to the lower levels." locals[3] = 33; // "Canst thou tell me more of this area?" locals[4] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_03bd(); break; case 2: say( "In sooth, I am sorry to hear thee pronounce thy own death sentence. Good luck, for thou wilt need it if you are to have any hope of surviving below." ); func_00e0(); break; case 3: func_04ad(); } // end if } else { break; } // end switch locals[23] = 34; // "Not well. Hast thou any news for me?" locals[24] = 35; // "Well. I must soon head to the lower levels." locals[25] = 0; // "" locals[44] = babl_menu( 0, &locals[23] ); switch ( locals[44] ) { case 1: func_03bd(); break; case 2: say( "In sooth, I am sorry to hear thee pronounce thy own death sentence. Good luck, for thou wilt need it to have any hope of surviving below." ); func_00e0(); break; } // end switch } // end func void func_0602() { private[9][1] = 1011; private[9][2] = 1002; private[9][3] = 1003; private[9][4] = 1000; private[9][5] = -1; private[30][1] = 161; private[30][2] = 160; private[30][3] = -1; set_likes_dislikes( 2, 61, 40 ); } // end func void func_0657() { int locals[22]; say( "Wouldst thou be interested in a trade?" ); locals[1] = 38; // "Yes." locals[2] = 39; // "No." locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_06a4(); break; case 2: goto label_069c; break; } // end switch label_069c:; return locals[1]; } // end func void func_06a4() { int locals[44]; setup_to_barter( 0 ); while ( !private[1] ) { locals[1] = 40; // "I make thee this offer." locals[2] = 41; // "I demand thou givest me these items." locals[3] = 42; // "I beg thy pardon, I must think about this deal." locals[4] = 43; // "I do not wish to barter any further." locals[5] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_0755(); break; case 2: func_0797(); break; case 3: do_judgement( 0 ); break; case 4: do_decline( 0 ); private[1] = 1; break; } // end switch } // while locals[23] = 44; // "Farewell." locals[24] = 0; // "" locals[44] = babl_menu( 0, &locals[23] ); if ( locals[44] == 1 ) { private[1] = 1; } // end if } // end func void func_0755() { int locals[5]; locals[1] = 45; // "Thou hast a deal!" locals[2] = 46; // "Thy offer does not interest me" locals[3] = 47; // "What kind of fool dost thou take me for?" locals[4] = 48; // "I grow weary of this petty haggling." locals[5] = 49; // "That is no trade!" if ( do_offer( 5, &locals[5], &locals[4], &locals[3], &locals[2], &locals[1] ) ) { private[1] = 1; } // end if } // end func void func_0797() { int locals[24]; say( "Art thou attempting to intimidate me into surrendering my possessions?" ); locals[1] = 51; // "Yes, I will deal thee grievous injury if thou dost not comply." locals[2] = 52; // "No, thou mistakest my meaning entirely." locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: break; case 2: return; break; } // end switch locals[23] = 53; // "If thou art desperate enough to steal, I will not oppose thee." locals[24] = 54; // "Miscreant! I shall teach thee a lesson!" if ( do_demand( 2, &locals[24], &locals[23] ) ) { private[1] = 1; } else { func_008b(); } // end if } // end func