Ultima Underworld/technical/conversations/25
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 #25 // string block 0x0e19 (3609), name Door // // 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]; locals[1] = gronk_door( 3, &locals[4], &locals[3], &locals[2] ); locals[2] = 4; locals[3] = 2; locals[4] = 1; if ( private[0] ) { func_033a(); } else { private[2] = 0; private[3] = 0; private[4] = 0; private[5] = 0; say( "So! Another young fool opens a door thoughtlessly. Open, close, open, close, that's all that anyone ever has the time for. Things were not like this when I was thy age, I can assure thee of that! Well? Hast thou anything to say for thyself?" ); locals[5] = 2; // "I'm sorry to disturb thee. I'll leave now." locals[6] = 3; // "Excuse me... art thou really a door?" locals[7] = 4; // "I mean to open thee, not to talk with thee!" locals[8] = 0; // "" locals[26] = babl_menu( 0, &locals[5] ); switch ( locals[26] ) { case 1: func_036a(); break; case 2: func_0389(); break; case 3: func_0377(); } // end if break; } // end switch } // end func void func_033a() { if ( private[2] ) { say( "Perhaps if thou wert more civil, thou couldst open more doors!" ); private[2] = 0; func_00e0(); } else { say( "Thou again! What dost thou want this time!" ); if ( private[4] ) { func_056c(); } else { if ( private[3] ) { func_061e(); } else { func_05c5(); } // end if } // end if } // end if } // end func void func_036a() { say( "Hmmph! Perhaps the next time thou wilt show greater civilty to thy elders!" ); func_00e0(); } // end func void func_0377() { private[2] = 1; say( "Bah! Such disrepect! I will open when I wish to open!" ); func_00e0(); } // end func void func_0389() { int locals[22]; say( "What do I look like, a drawbridge?" ); locals[1] = 10; // "In fact, thou bearest a remarkable resemblance to one." locals[2] = 11; // "Thy point is made. How didst thou come to be a door?" locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_036a(); break; case 2: func_03d1(); break; } // end switch } // end func void func_03d1() { int locals[22]; private[3] = 1; say( "I once was a young human like thyself. But I grew weary of the regular folk and their immense stupidity. I was a brilliant mage, and was constantly pestered with silly questions, such as "How does one cast Sheet Lightning?"\n" " Tiring of being hounded thus, I turned myself into a door in order to finally enjoy some peace and quiet. Obviously, it didn't work." ); locals[1] = 13; // "Now that thou dost mention it, how does one cast Sheet Lightning?" locals[2] = 14; // "Canst thou not turn thyself back into a human?" locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_041e(); break; case 2: func_0470(); break; } // end switch } // end func void func_041e() { int locals[22]; private[4] = 1; private[3] = 0; say( "Gaaah! I cannot believe thou wouldst ask that, of all questions! I should have known better than to mention that accursed spell.\n" " If thou must know, it is cast by using the Vas, Ort and Grav runestones. There. I hope that thou blowest thyself up with it." ); locals[1] = 16; // "Thank thee kindly, wise door." locals[2] = 17; // "At last! Now my power is increased even more!" locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_00e0(); break; case 2: func_036a(); break; } // end switch } // end func void func_0470() { int locals[22]; say( "Art thou implying that my power is not great enough to turn myself into whatever I want? If I wanted to, I could turn myself into a nutcracker and thee into a walnut! Wouldst thou like that?" ); locals[1] = 19; // "Surely not." locals[2] = 20; // "I'd like to see thee try!" locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_04b8(); break; case 2: func_036a(); break; } // end switch } // end func void func_04b8() { int locals[43]; say( "Well then, didst thou attempt to open me for a reason, or simply because my doorknob was a bright shiny object?" ); locals[22] = private[3]; locals[1] = 22; // "Thou didst mention a Sheet Lightning spell.." locals[23] = 1; locals[2] = 23; // "I wish to pass through to thy other side." locals[24] = 1; locals[3] = 24; // "No, I'm sorry to have disturbed thee." locals[4] = 0; // "" locals[43] = babl_fmenu( 0, &locals[1], &locals[22] ); switch ( locals[43] ) { case 22: func_041e(); break; case 23: func_0530(); break; case 24: func_036a(); break; } // end switch } // end func void func_0530() { int locals[4]; say( "Very well, if it means that thou wilt not bother me again." ); locals[1] = gronk_door( 3, &locals[4], &locals[3], &locals[2] ); locals[2] = 4; locals[3] = 2; locals[4] = 0; if ( locals[1] == 0 ) { say( "Unfortunately, my hinges seem to be somewhat rusty." ); } // end if func_00e0(); } // end func void func_056c() { int locals[22]; locals[1] = 27; // "Couldst thou please open for me?" locals[2] = 28; // "I forget how to cast Sheet Lightning." locals[3] = 29; // "I'm sorry, I didn't mean to bother thee." locals[4] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_0530(); break; case 2: func_0677(); break; case 3: func_036a(); break; } // end switch } // end func void func_05c5() { int locals[22]; locals[1] = 30; // "Canst thou tell me of thy history?" locals[2] = 31; // "Couldst thou please open for me?" locals[3] = 32; // "I'm sorry, I didn't mean to bother thee." locals[4] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_03d1(); break; case 2: func_0530(); break; case 3: func_036a(); break; } // end switch } // end func void func_061e() { int locals[22]; locals[1] = 33; // "Canst thou teach me the Sheet Lightning spell of which thou spoke?" locals[2] = 34; // "Couldst thou please open for me?" locals[3] = 35; // "I'm sorry, I didn't mean to bother thee." locals[4] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_041e(); break; case 2: func_0530(); break; case 3: func_036a(); break; } // end switch } // end func void func_0677() { if ( private[5] ) { say( "I refuse to help thee with that any more!" ); func_00e0(); } else { private[5] = 1; say( "Again!? For the last time, the spell is cast by using the Vas, Ort, and Grav runestones. I don't know why I'm bothering to tell thee. Thou obviously hast not the intelligence necessary to cast it." ); func_00e0(); } // end if } // end func void func_0695() { int locals[44]; setup_to_barter( 0 ); while ( !private[1] ) { locals[1] = 38; // "I make thee this offer." locals[2] = 39; // "I demand thou givest me these items." locals[3] = 40; // "Excuse me, I must think about this deal." locals[4] = 41; // "I do not wish to barter any further." locals[5] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_0746(); break; case 2: func_07a0(); break; case 3: do_judgement( 0 ); break; case 4: do_decline( 0 ); private[1] = 1; break; } // end switch } // while locals[23] = 42; // "Farewell." locals[24] = 0; // "" locals[44] = babl_menu( 0, &locals[23] ); if ( locals[44] == 1 ) { private[1] = 1; } // end if } // end func void func_0746() { int locals[15]; locals[0] = -1; locals[6] = -1; locals[11] = 43; // "I accept thy offer." locals[12] = 44; // "No, I do not like this deal." locals[13] = 45; // "Dost thou take me for a fool?" locals[14] = 46; // "I am weary of this haggling." locals[15] = 47; // "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_07a0() { int locals[24]; say( "Dost thou intend to rob me?" ); locals[1] = 49; // "Yes, I must." locals[2] = 50; // "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] = 51; // "If thou dost insist, thou canst have them." locals[24] = 52; // "No! Thou shalt not take them!" if ( do_demand( 2, &locals[24], &locals[23] ) ) { private[1] = 1; } else { func_008b(); } // end if } // end func