Ultima Underworld/technical/conversations/1
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 #1 // string block 0x0e01 (3585), name Corby // // 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]global[0]; 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] == 1 ) { func_04c0(); } else { global[0] = 0; say( "Hast thou come to add to my torment?" ); locals[1] = 2; // "Of what torment dost thou speak?" locals[2] = 3; // "Of course not. If I may, I shall ease thy pain." locals[3] = 4; // "If my presence offends thee, I shall go." locals[4] = 5; // "Indeed I have, thou mewling child!" locals[5] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_031e(); break; case 2: func_064a(); break; case 3: func_05f6(); break; case 4: func_0063(); } // end if break; } // end switch } // end func void func_031e() { int locals[22]; say( "Why, the torment of lost hopes... Of disillusionment." ); locals[1] = 7; // "Tell me more." locals[2] = 8; // "Oh, is that all?" locals[3] = 9; // "Can I help?" locals[4] = 10; // "I shall leave thee to thy grief if thou wish it so." locals[5] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: if ( global[0] == 0 ) { func_039a(); } else { func_06a6(); } // end if break; case 2: func_059a(); break; case 3: func_064a(); break; case 4: func_05f6(); break; } // end switch } // end func void func_039a() { int locals[22]; global[0] = 1; say( "I shared the great dream of Sir Cabirus, that the Avatar's way could be pursued by all folk. We sought to gather all intelligent species here in the Abyss and teach them to live in harmony. Alas, it was not to be.\n" " The constant bickering proved too much for kindly Sir Cabirus, and he perished in his sleep. Some said he was poisoned, but I know he died of a broken spirit.\n" " His life's work was in this place, and as he watched it crumble, his heart broke as well." ); locals[1] = 12; // "I am sorry to hear that. Does aught remain of his dream?" locals[2] = 13; // "A terrible waste. Did nothing good come of it?" locals[3] = 14; // "He was a fool!" locals[4] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_03fb(); break; case 2: func_03fb(); break; case 3: func_04b3(); break; } // end switch } // end func void func_03fb() { int locals[22]; say( "Well, aye, Sir Cabirus did gather a number of artifacts with interesting properties. He thought the use of these artifacts might assist the colonists as they pursued the way of the Avatar. Unfortunately, the objects were misused by the folk he hoped to help." ); locals[1] = 16; // "How so?" locals[2] = 17; // "I am sorry to hear that" locals[3] = 18; // "Wouldst rather be alone?" locals[4] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_0457(); break; case 2: func_059a(); break; case 3: func_05f6(); break; } // end switch } // end func void func_0457() { int locals[22]; say( "Each of the eight items gathered by Sir Cabirus embodied one of the Virtues. But those who now possess the items keep them merely for their intrinsic value, not their higher purpose." ); locals[1] = 20; // "Such a fool was this Cabirus!" locals[2] = 21; // "A pity, but nothing can be done about it now." locals[3] = 22; // "Then I shall find these artifacts and put them to proper use." locals[4] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_04b3(); break; case 2: func_059a(); break; case 3: func_00e0(); break; } // end switch } // end func void func_04b3() { say( "Thou dare to profane his memory! Begone with thee!" ); func_00d1(); } // end func void func_04c0() { int locals[44]; if ( npc_attitude == 1 ) { say( "Hast thou returned to torment me further?" ); locals[1] = 25; // "If my presence offends thee, I shall go." locals[2] = 26; // "Indeed I have, thou mewling child!" locals[3] = 27; // "Get thee from my sight!" locals[4] = 28; // "Nay. I can help thee now." locals[5] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_05f6(); break; case 2: func_0063(); break; case 3: func_00c2(); break; case 4: func_064a(); } // end if } else { break; } // end switch say( "Hast thou indeed found a way to help?" ); locals[23] = 30; // "Aye. But thou must tell me of Sir Cabirus." locals[24] = 31; // "Get thee from my sight!" locals[25] = 32; // "Nay. I cannot help thee." locals[26] = 0; // "" locals[44] = babl_menu( 0, &locals[23] ); switch ( locals[44] ) { case 1: if ( global[0] == 0 ) { func_039a(); } else { func_06a6(); } // end if break; case 2: func_00d1(); break; case 3: func_059a(); break; } // end switch } // end func void func_059a() { int locals[22]; say( "Is that all thou hast to say? Get thee gone from here!" ); locals[1] = 34; // "Goodbye." locals[2] = 35; // "Get from here thyself!" locals[3] = 36; // "No, wait. I can help!" locals[4] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_00c2(); break; case 2: func_0063(); break; case 3: func_064a(); break; } // end switch } // end func void func_05f6() { int locals[22]; say( "Wait! My cause is lost, but perhaps I can yet help thee." ); locals[1] = 38; // "Canst tell me of Sir Cabirus?" locals[2] = 39; // "My thanks, but thou hast done enough." locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: if ( global[0] == 0 ) { func_039a(); } else { func_06a6(); } // end if break; case 2: func_00c2(); break; } // end switch } // end func void func_064a() { int locals[22]; say( "Well, I am beyond thy help!" ); locals[1] = 41; // "Oh? Well, fare thee well." locals[2] = 42; // "Indeed thou art." locals[3] = 43; // "Nay. None are truly hopeless." locals[4] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_00c2(); break; case 2: func_059a(); break; case 3: func_05f6(); break; } // end switch } // end func void func_06a6() { int locals[22]; say( "Art thou certain thou dost wish to hear my sorry tale again?" ); locals[1] = 45; // "Ah, no, what was I thinking?" locals[2] = 46; // "Certainly. It bears retelling!" locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_059a(); break; case 2: func_039a(); break; } // end switch } // end func