Ultima Underworld/technical/conversations/27
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 #27 // string block 0x0e1b (3611), name Garamon // // 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] ) { func_0755(); } // end if private[2] = 1; private[3] = 1; say( "Thou hast done well. And now that my bones are at last at rest I can speak freely to thee. But my spirit cannot rest while yet this peril remains.\n" " We must open a gate, near where the foul creature my brother summoned lies bound. We must return it to the plane from whence it came." ); locals[1] = 2; // "Is there no other way?" locals[2] = 3; // "How can we open such a gate?" locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_02f6(); break; case 2: func_032a(); break; } // end switch } // end func void func_02f6() { int locals[22]; say( "No other power can defeat it. Even banishing it to another place will do it no harm -- may in fact restore to it its full power, if that place be like to its own -- but it will at least remove the threat to Britannia!" ); locals[1] = 5; // "How can this be done?" locals[2] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); if ( locals[22] == 1 ) { func_032a(); } // end if } // end func void func_032a() { int locals[45]; locals[1] = get_quest( 1, &locals[2] ); locals[2] = 5; say( "For this I will need a great deal of magical energy. This will be no gentle luring such as brought thee here, but an unimaginable vortex of interplanar energy." ); locals[24] = locals[1]; locals[3] = 7; // "Might Tyball's Orb have sufficed, had it not been destroyed?" locals[25] = 1; locals[4] = 8; // "Where can we find such powerful magic?" locals[5] = 0; // "" locals[45] = babl_fmenu( 0, &locals[3], &locals[24] ); switch ( locals[45] ) { case 7: func_0398(); break; case 8: func_0398(); break; } // end switch } // end func void func_0398() { int locals[22]; say( "Tyball's Orb would be perilous to use, even if it were intact. The power we tap must be carefully chosen... As thou may have guessed, I am a little out of touch with thy world. I had hoped thou might provide an answer." ); locals[1] = 10; // "I'm afraid I have no idea." locals[2] = 11; // "What be the qualifications for what thou needest?" locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_03e0(); break; case 2: func_03e0(); break; } // end switch } // end func void func_03e0() { int locals[22]; say( "It would be best if the source were absolutely pure -- my brother found the danger in tapping powers whose source thou knowest not -- and 'twould be best if Britannia herself were somehow involved." ); locals[1] = 13; // "How dost thou mean, "Britannia involved?"" locals[2] = 14; // "The source must be pure?" locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_0428(); break; case 2: func_04c5(); break; } // end switch } // end func void func_0428() { int locals[43]; say( "'Twould help to invoke one of the Elements. We work for Britannia's succor, and we must hope she would lend what aid she could." ); locals[22] = private[2]; locals[1] = 16; // "The Elements?" locals[23] = private[3]; locals[2] = 17; // "Thou speakest as though Britannia is alive." locals[24] = 1; locals[3] = 18; // "But the source of the magic must be pure?" locals[4] = 0; // "" locals[43] = babl_fmenu( 0, &locals[1], &locals[22] ); switch ( locals[43] ) { case 16: func_04a1(); break; case 17: func_04b3(); break; case 18: break; } // end switch func_04c5(); } // end func void func_04a1() { private[2] = 0; say( "The classical four: earth, air, fire, and water." ); return; } // end func void func_04b3() { private[3] = 0; say( "Indeed she is, a green and living entity. Not conscious as we know it, but perhaps aware that we work to her ends." ); return; } // end func void func_04c5() { say( "Yes, the source, which, if we are fortunate, may even wake Britannia to our aid, should be as pure as possible. Else we risk ending like my brother." ); func_04d2(); } // end func void func_04d2() { int locals[25]; while ( 1 ) { locals[2] = 22; // "My mind is a blank." locals[3] = 23; // "Other..." locals[4] = 0; // "" locals[23] = babl_menu( 0, &locals[2] ); switch ( locals[23] ) { case 1: func_055b(); break; case 2: locals[1] = babl_ask( 0 ); locals[24] = 24; (contains( 2, &locals[1], &locals[24] ) || contains( 2, &locals[1], &locals[25] )); // expr. has value on stack! if ( locals[25] = 25 ) { func_057c(); } else { say( "No, that will not do. Perhaps something else..." ); private[5] = private[5] + 1; } // end if break; } // end switch } // while } // end func void func_055b() { if ( private[5] < 3 ) { say( "Perhaps thou shouldst ponder the problem for a bit longer. But think carefully and quickly, for the fate of Britannia is at stake!" ); func_00e0(); } else { private[5] = 0; say( "Perhaps some item or items imbued with Virtue might be of use, if any exist. Dost thou know of any such items?" ); func_04d2(); } // end if } // end func void func_057c() { private[4] = 1; say( "Yes, of course! Those would do admirably. Now, we must find a means to unleash their stored Virtue. We must find some latent source of power that can be released by applying the energy of the Talismans." ); func_058e(); } // end func void func_058e() { int locals[25]; while ( 1 ) { locals[2] = 30; // "I cannot think of anything appropriate." locals[3] = 31; // "Other..." locals[4] = 0; // "" locals[23] = babl_menu( 0, &locals[2] ); switch ( locals[23] ) { case 1: func_0617(); break; case 2: locals[1] = babl_ask( 0 ); locals[24] = 32; (contains( 2, &locals[1], &locals[24] ) || contains( 2, &locals[1], &locals[25] )); // expr. has value on stack! if ( locals[25] = 33 ) { func_0638(); } else { say( "No, we need a great source of power that might easily be released." ); private[7] = private[7] + 1; } // end if break; } // end switch } // while } // end func void func_0617() { if ( private[7] < 3 ) { say( "Well, I hope that thou art able to solve the problem quickly, for the fate of Britannia itself hangs in the balance!" ); func_00e0(); } else { private[7] = 0; say( "Perhaps some natural landmark that contains the ability to release great power will do the trick." ); func_058e(); } // end if } // end func void func_0638() { int locals[22]; say( "Yes, of course! If all eight Talismans be thrust into the volcano's maw, one at a time, I could ride the wave of such power to open the vortex. Ah, thou art wise as well as valorous! Wilt thou make such a sacrifice?" ); private[6] = 1; locals[1] = 38; // "Think again, ghost. Thou knowest not the troubles I went through to obtain those!" locals[2] = 39; // "Aye, though it pains me sorely to lose such tools as these." locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_0685(); break; case 2: func_06cd(); break; } // end switch } // end func void func_0685() { int locals[22]; say( "But thou must! Thy sacrifice shall save all of this world! Surely thou cannot place thine own travails and successes against such a stake as that!" ); locals[1] = 41; // "Very well, thou art correct. I shall do it!" locals[2] = 42; // "I shall think on it." locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_00e0(); break; case 2: func_00c2(); break; } // end switch } // end func void func_06cd() { int locals[22]; say( "Excellent! Make haste to the lowest place, where thou must cast all eight into the Abyss -- hold back not one, upon thy peril! When they are consumed by earth's own fire, I shall leash the torrent to gape wide my gate. With Fortune's smile, we shall send our foe screeching back to its Hell!" ); locals[1] = 44; // "Where can I find a way into the volcano?" locals[2] = 45; // "Very well! Look for me there!" locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_0715(); break; case 2: func_00e0(); break; } // end switch } // end func void func_0715() { int locals[23]; say( "The Chamber of Virtue is located on the lowest level of the Abyss. It lies at the very center of the volcano, where the energy fields of the Stygian are their strongest. 'Tis said that a special three-part key is needed to enter, but I know not the veracity of this legend." ); locals[1] = 47; // "I will make my way there." locals[2] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); if ( locals[22] == 1 ) { } // end if say( "Hurry! There is little time to lose!" ); locals[23] = 3; func_00b1( &locals[23] ); } // end func void func_0755() { if ( private[6] ) { say( "Hurry, @GS8, there is no time to lose! Thou must cast all eight of Cabirus' Talismans into the volcano on the lowest level of the Abyss. Do not fail in thy quest!" ); func_00e0(); } // end if if ( private[4] ) { say( "Yes? Hast thou discovered a source of energy with which the power of Cabirus' Talismans can be released?" ); func_058e(); } // end if say( "Yes? Hast thou thought of a pure source of power and virtue which may provide me with the requisite amount of magical energy?" ); func_04d2(); } // end func