Ultima Underworld/technical/conversations/191
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 #191 // string block 0x0ebf (3775), name Ranthru // // 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() { int locals[22]; if ( private[0] ) { if ( private[2] ) { if ( private[3] ) { func_0809(); } else { func_05b7(); } // end if } else { func_031e(); } // end if } else { private[2] = 0; private[3] = 0; say( "I have not seen thee in these parts before. Art thou in league with Vilus?" ); locals[1] = 2; // "Vilus? I have not heard of such a person." locals[2] = 3; // "Indeed I am." locals[3] = 4; // "Most assuredly I am not." locals[4] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_041e(); break; case 2: func_037a(); break; case 3: func_0583(); } // end if break; } // end switch } // end func void func_031e() { int locals[22]; say( "Not again! Thou, who art a servant of Vilus surely!" ); locals[1] = 6; // "Yes, thou hast found me out." locals[2] = 7; // "Thou art mistaken." locals[3] = 8; // "Who is Vilus?" locals[4] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_037a(); break; case 2: func_0583(); break; case 3: func_041e(); break; } // end switch } // end func void func_037a() { int locals[22]; say( "I was sure of it. Please, spare my life!" ); locals[1] = 10; // "That I cannot do!" locals[2] = 11; // "Why art thou afraid of me?" locals[3] = 12; // "I am afraid thou didst misunderstand me." locals[4] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_008b(); break; case 2: func_03d6(); break; case 3: func_03d6(); break; } // end switch } // end func void func_03d6() { int locals[22]; say( "Dost thou toy with me? I thought thou wert in league with Vilus, a mage almost as evil as he is insane, and almost as insane as he is powerful!" ); locals[1] = 14; // "And so I am. Prepare to die!" locals[2] = 15; // "No, I am not. Tell me of this Vilus." locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_008b(); break; case 2: func_041e(); break; } // end switch } // end func void func_041e() { int locals[22]; say( "Vilus used to be a Seer like the rest of us. A brilliant mage he was, but perhaps too much so for his own good. While exploring a method of casting powerful magic without runestones, he was overtaken by insanity." ); locals[1] = 17; // "And where is he now?" locals[2] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); if ( locals[22] == 1 ) { func_0452(); } // end if } // end func void func_0452() { int locals[22]; say( "Whether he be alive or dead, I know not. He took over the caves to the northeast, filling them with vicious creatures and devious traps. No sane person ventures there any longer, least of all myself. Wilt thou run an errand there for me?" ); locals[1] = 19; // "Assuredly. I have no fear of this Vilus." locals[2] = 20; // "Not if it as dangerous as thou sayst." locals[3] = 21; // "What wouldst thou have me do?" locals[4] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_04f6(); break; case 2: func_04ae(); break; case 3: func_04f6(); break; } // end switch } // end func void func_04ae() { int locals[22]; say( "Oh, it's not really as dangerous as all that. A few creatures here and there... nothing that thou couldst not deal with easily." ); locals[1] = 23; // "Perhaps I will run this errand for thee." locals[2] = 24; // "And what dost thou want done in this place?" locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_04f6(); break; case 2: func_04f6(); break; } // end switch } // end func void func_04f6() { int locals[22]; private[2] = 1; say( "Vilus took a powerful book from the Library and failed to return it. It is named "On the Properties of Runestones." Return it to me and I shall teach thee to use thy magical abilities to their fullest." ); locals[1] = 26; // "It is as good as done." locals[2] = 27; // "Wait! I have it right here." locals[3] = 28; // "I have no time for this errand." locals[4] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_0557(); break; case 2: func_068f(); break; case 3: func_056d(); break; } // end switch } // end func void func_0557() { int locals[1]; say( "I thank thee greatly. Good luck in thy travels." ); locals[1] = 2; func_00b1( &locals[1] ); } // end func void func_056d() { int locals[1]; say( "I am disappointed to hear that. If thou dost happen to find the book anyway, please let me know." ); locals[1] = 1; func_00b1( &locals[1] ); } // end func void func_0583() { int locals[22]; say( "I am glad to hear it! I am sure that if thou wert allied with Vilus, I would be dead already." ); locals[1] = 32; // "Who is this Vilus?" locals[2] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); if ( locals[22] == 1 ) { func_041e(); } // end if } // end func void func_05b7() { int locals[22]; say( "Ah, 'tis thee again. From a distance I mistook thee for one of Vilus' servants. Hast thou found "On the Properties of Runestones" for me yet?" ); locals[1] = 34; // "Yes, here it is." locals[2] = 35; // "Nay, it has eluded me." locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_068f(); break; case 2: func_05ff(); break; } // end switch } // end func void func_05ff() { int locals[1]; say( "I am sure that that fiend Vilus has hidden it most deviously. I wish that I could aid thee in thy search!" ); locals[1] = 2; func_00b1( &locals[1] ); } // end func void func_0615() { int locals[9]; locals[3] = 0; locals[4] = -1; locals[5] = -1; locals[6] = -1; locals[7] = -1; locals[8] = -1; locals[9] = -1; x_obj_stuff( 9, &locals[9], &locals[8], &locals[7], &locals[2], &locals[6], &locals[5], &locals[4], &locals[3], param2 ); if ( locals[2] == param1[0]play_hunger ) { locals[1] = 1; } else { locals[1] = 0; } // end if return locals[1]; } // end func void func_068f() { int locals[68]; locals[16] = 0; locals[15] = 0; locals[13] = show_inv( 2, &locals[6], &locals[1] ); while ( locals[13] > 0 ) { locals[14] = 1; if ( locals[14] <= locals[13] ) { if ( locals[0] >= 304 && locals[0] <= 311 ) { locals[16] = 1; locals[17] = 160; if ( func_0615( &locals[17], &locals[5] ) ) { locals[15] = locals[14]; locals[11] = locals[5]; } // end if } // end if locals[14] = locals[14] + 1; } // while } // end if if ( locals[15] > 0 ) { locals[18] = 1; give_to_npc( 2, &locals[6], &locals[18] ); private[3] = 1; say( "Marvelous! I hope that it was not too much trouble to retrieve it." ); locals[19] = 38; // "He snaps his fingers and you are briefly bathed in a blue glow." print( 1, &locals[19] ); say( "There, thou shouldst find that thy spellcasting skill is greater now." ); locals[20] = 9; locals[21] = 10000; x_skills( 2, &locals[21], &locals[20] ); locals[22] = 9; locals[23] = 10000; x_skills( 2, &locals[23], &locals[22] ); locals[24] = 3; func_00b1( &locals[24] ); } else { if ( locals[16] ) { say( "I'm afraid that this is not the book I requested." ); locals[25] = 41; // "Perhaps this is it." locals[26] = 42; // "Sorry, I do not have thy book." locals[27] = 0; // "" locals[46] = babl_menu( 0, &locals[25] ); switch ( locals[46] ) { case 1: func_068f(); break; case 2: func_00e0(); } // end if } else { break; } // end switch say( "Yes? Where is it?" ); locals[47] = 44; // "Here it is." locals[48] = 45; // "Sorry, I do not have it." locals[49] = 0; // "" locals[68] = babl_menu( 0, &locals[47] ); switch ( locals[68] ) { case 1: func_068f(); break; case 2: func_00e0(); } // end if break; } // end switch } // end func void func_0809() { int locals[1]; say( "Greetings, @GS8! I am indebted to thee for bringing me that book. Do stop in sometime when I am not so busy." ); locals[1] = 3; func_00b1( &locals[1] ); } // end func void func_081f() { int locals[44]; setup_to_barter( 0 ); while ( !private[1] ) { locals[1] = 47; // "I make thee this offer." locals[2] = 48; // "I demand thou givest me these items." locals[3] = 49; // "Excuse me, I must think about this deal." locals[4] = 50; // "I do not wish to barter any further." locals[5] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_08d0(); break; case 2: func_092a(); break; case 3: do_judgement( 0 ); break; case 4: do_decline( 0 ); private[1] = 1; break; } // end switch } // while locals[23] = 51; // "Farewell." locals[24] = 0; // "" locals[44] = babl_menu( 0, &locals[23] ); if ( locals[44] == 1 ) { private[1] = 1; } // end if } // end func void func_08d0() { int locals[15]; locals[0] = -1; locals[6] = -1; locals[11] = 52; // "I accept thy offer." locals[12] = 53; // "No, I do not like this deal." locals[13] = 54; // "Dost thou take me for a fool?" locals[14] = 55; // "I am weary of this haggling." locals[15] = 56; // "Surely thou art joking." if ( do_offer( 7, &locals[15], &locals[14], &locals[13], &locals[12], &locals[11], &locals[6], &locals[1] ) ) { private[1] = 1; } // end if } // end func void func_092a() { int locals[24]; say( "Dost thou intend to rob me?" ); locals[1] = 58; // "Yes, I must." locals[2] = 59; // "No, thou dost misunderstand me." locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: break; case 2: return; break; } // end switch locals[23] = 60; // "If thou dost insist, thou canst have them." locals[24] = 61; // "No! Thou shalt not take them!" if ( do_demand( 2, &locals[24], &locals[23] ) ) { private[1] = 1; } else { func_008b(); } // end if } // end func