Ultima Underworld/technical/conversations/20
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 #20 // string block 0x0e14 (3604), name Gulik // // 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[26]; private[3] = get_quest( 1, &locals[2] ); locals[2] = 1; if ( private[0] == 1 ) { func_053a(); } else { private[2] = 0; locals[1] = random( 1, &locals[3] ); locals[3] = 2; locals[4] = locals[1]; if ( 1 == locals[4] ) { say( "Who art thou?" ); } else { if ( 2 == locals[4] ) { say( "What is thy name, stranger?" ); } // end if } // end if locals[5] = 3; // "I am @GS8." locals[6] = 4; // "None of thy business!" locals[7] = 5; // "I might ask thee the same question." locals[8] = 0; // "" locals[26] = babl_menu( 0, &locals[5] ); switch ( locals[26] ) { case 1: private[2] = 1; func_0351(); break; case 2: func_00c2(); break; case 3: func_0351(); } // end if break; } // end switch } // end func void func_0351() { int locals[22]; say( "I am Gulik, called the Blessed." ); locals[1] = 7; // "Why art thou called that?" locals[2] = 8; // "Art thou the leader here?" locals[3] = 9; // "What is this place?" locals[4] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_05b8(); break; case 2: func_03ad(); break; case 3: func_04de(); break; } // end switch } // end func void func_03ad() { int locals[22]; say( "Our leader is Hagbard. Hast thou spoken to him?" ); locals[1] = 11; // "No. Should I?" locals[2] = 12; // "Why?" locals[3] = 13; // "Yes." locals[4] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_0755(); break; case 2: func_0755(); break; case 3: if ( private[3] ) { func_06e0(); } else { func_0412(); } // end if break; } // end switch } // end func void func_0412() { int locals[22]; say( "I did not hear thee talk with Hagbard! Why dost thou lie? Art thou a spy for Ketchaval?" ); locals[1] = 15; // "Who is Ketchaval?" locals[2] = 16; // "No! I am no spy." locals[3] = 17; // "Yes, indeed I am!" locals[4] = 18; // "Excuse me, I must be going." locals[5] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_0482(); break; case 2: func_0614(); break; case 3: func_008b(); break; case 4: func_00c2(); break; } // end switch } // end func void func_0482() { int locals[22]; say( "Not even a Gray spy would pretend such ignorance! Ketchaval is the King of the Gray Goblins. Therefore, if thou art a spy, thou must be from Vernix of the Greens!" ); locals[1] = 20; // "I am no spy!" locals[2] = 21; // "Yes! It is all true!" locals[3] = 22; // "Excuse me, I must be going." locals[4] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_0614(); break; case 2: func_008b(); break; case 3: func_00c2(); break; } // end switch } // end func void func_04de() { int locals[22]; say( "Thou art in the Great Stygian Abyss, where neither thou nor any other may ever hope to leave again. 'Tis worse than any prison, for there is no hope of parole or pardon, and no death so clean as an honest hanging." ); locals[1] = 24; // "Tell me more of this Abyss." locals[2] = 25; // "How didst thou come to be here?" locals[3] = 26; // "Have none ever escaped?" locals[4] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_079d(); break; case 2: func_07e5(); break; case 3: func_082d(); break; } // end switch } // end func void func_053a() { int locals[22]; if ( private[2] == 1 ) { say( "Greetings, @GS8! Hast thou spoken with Hagbard?" ); } else { say( "Hello again, stranger. Hast spoken to our leader?" ); } // end if locals[1] = 29; // "Who is he again?" locals[2] = 30; // "Yes." locals[3] = 31; // "No." locals[4] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_03ad(); break; case 2: if ( private[4] ) { func_0670(); } else { if ( private[3] ) { func_06e0(); } else { func_0412(); } // end if } // end if break; case 3: say( "Do so!" ); func_00e0(); break; } // end switch } // end func void func_05b8() { int locals[22]; say( "I have been called 'the Blessed' since my prison days, when I was considered lucky because I have a taste for cockroaches. I never went hungry, thou seest." ); locals[1] = 34; // "How very nice for thee... I must be going." locals[2] = 35; // "And is this place better than a prison?" locals[3] = 36; // "That's repulsive!" locals[4] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_00e0(); break; case 2: func_04de(); break; case 3: func_00c2(); break; } // end switch } // end func void func_0614() { int locals[22]; say( "Then thou shouldst speak with Hagbard. He is our leader." ); locals[1] = 38; // "Perhaps I will." locals[2] = 39; // "I will seek him out." locals[3] = 40; // "I have better things to do with my time." locals[4] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_00e0(); break; case 2: func_00e0(); break; case 3: func_00e0(); break; } // end switch } // end func void func_0670() { int locals[22]; say( "Greetings! What may I do for thee?" ); locals[1] = 42; // "I thank thee, but I must be going." locals[2] = 43; // "What didst thou say thy name was?" locals[3] = 44; // "Know ye anything of what lies below?" locals[4] = 45; // "How can one find useful items?" locals[5] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_00e0(); break; case 2: func_0351(); break; case 3: func_08bd(); break; case 4: func_08f1(); break; } // end switch } // end func void func_06e0() { int locals[22]; private[4] = 1; say( "Ah, I remember. He was talking to thee earlier! Well, may I help thee?" ); locals[1] = 47; // "I thank thee, but I must be going." locals[2] = 48; // "What didst thou say thy name was?" locals[3] = 49; // "Know ye anything of what lies below?" locals[4] = 50; // "How can one find useful items?" locals[5] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_00e0(); break; case 2: func_0351(); break; case 3: func_08bd(); break; case 4: func_08f1(); break; } // end switch } // end func void func_0755() { int locals[22]; say( "Thou needs must speak with Hagbard. He alone, of all of us, retains his sanity amidst the madness of this place." ); locals[1] = 52; // "Very well. I shall seek him out." locals[2] = 53; // "Before I do, what IS this place?" locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_00e0(); break; case 2: func_04de(); break; } // end switch } // end func void func_079d() { int locals[22]; say( "It was not always such. Once, a leader name Sir Cabirus (curst be his name!) had the foolish notion that this place could be colonized.\n" " When his folly caught up with him, the "civilization" of the under-earth fell, and we now scrabble to survive in its ruins. \n" " He died, and so escaped the punishment for his crime. Dreamers! They will be the death of us all!" ); locals[1] = 55; // "And thyself? How camest thou here?" locals[2] = 56; // "Perhaps he was merely an idealist." locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_07e5(); break; case 2: func_0875(); break; } // end switch } // end func void func_07e5() { int locals[22]; say( "I killed a man who needed killing. My crime was being caught." ); locals[1] = 58; // "Perhaps thou wouldst find peace if thou didst repent." locals[2] = 59; // "Well, I must be going. Fare thee well." locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_0875(); break; case 2: func_00e0(); break; } // end switch } // end func void func_082d() { int locals[22]; say( "Escape! Ha! There be no escape from this place, barring the Final Escape of death. When the colony fell, a mighty spell was laid on the Great Gate. Now it cannot be opened save from the outside." ); locals[1] = 61; // "Perhaps I know a way." locals[2] = 62; // "'Tis a great misfortune, surely. I sympathize with thee." locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_0875(); break; case 2: func_0614(); break; } // end switch } // end func void func_0875() { int locals[22]; say( "And perhaps thou art a fool! Good day to thee!" ); locals[1] = 64; // "Good day." locals[2] = 65; // "We shall see." locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_00c2(); break; case 2: func_00e0(); break; } // end switch } // end func void func_08bd() { int locals[22]; say( "Below us now? Why, the flaming heart of the volcano, I would surmise. And below that lie the bowels of Britannia. Think, friend, someday thou wilt be part of that, and not another body thrashing about in these caverns we call home." ); locals[1] = 67; // "I see. Goodbye!" locals[2] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); if ( locals[22] == 1 ) { func_00e0(); } // end if } // end func void func_08f1() { int locals[22]; say( "Ah, thou shouldst know that it is often easier to find useful items by bartering than simply by scavenging. Find thyself someone who is willing to trade, and give him the items thou dost not need in exchange for more useful ones.\m" ); say( "Keep in mind whom thou art dealing with. I hear that the Mountainfolk are fond of gold, for example, while Goblins may not be as attached to it." ); locals[1] = 70; // "Thank thee for thy help, and farewell." locals[2] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); if ( locals[22] == 1 ) { func_00e0(); } // end if } // end func void func_0928() { int locals[44]; setup_to_barter( 0 ); while ( !private[1] ) { locals[1] = 71; // "I make thee this offer." locals[2] = 72; // "I demand thou givest me these items." locals[3] = 73; // "Excuse me, I must think about this deal." locals[4] = 74; // "I do not wish to barter any further." locals[5] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_09d9(); break; case 2: func_0a33(); break; case 3: do_judgement( 0 ); break; case 4: do_decline( 0 ); private[1] = 1; break; } // end switch } // while locals[23] = 75; // "Farewell." locals[24] = 0; // "" locals[44] = babl_menu( 0, &locals[23] ); if ( locals[44] == 1 ) { private[1] = 1; } // end if } // end func void func_09d9() { int locals[15]; locals[0] = -1; locals[6] = -1; locals[11] = 76; // "I accept thy offer." locals[12] = 77; // "No, I do not like this deal." locals[13] = 78; // "Dost thou take me for a fool?" locals[14] = 79; // "I am weary of this haggling." locals[15] = 80; // "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_0a33() { int locals[24]; say( "Dost thou intend to rob me?" ); locals[1] = 82; // "Yes, I must." locals[2] = 83; // "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] = 84; // "If thou dost insist, thou canst have them." locals[24] = 85; // "No! Thou shalt not take them!" if ( do_demand( 2, &locals[24], &locals[23] ) ) { private[1] = 1; } else { func_008b(); } // end if } // end func