Ultima Underworld/technical/conversations/6

From Ultima Codex
Jump to navigation Jump to search

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 #6 // string block 0x0e06 (3590), name Marrowsuck // // 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[313]; if ( private[0] ) { } else { private[2] = 0; private[3] = 0; private[4] = 0; private[5] = 0; say( "Who be you?" ); locals[7] = 2; // "I am @GS8. Who art thou?" locals[8] = 3; // "None of thy business!" locals[9] = 0; // "" locals[28] = babl_menu( 0, &locals[7] ); switch ( locals[28] ) { case 1: goto label_02ff; break; case 2: goto label_07a6; break; } // end switch label_02ff:; label_02ff:; say( "Huh. Me Marrowsuck, the tailor." ); locals[29] = 5; // "A tailor? Thou art a Ghoul, art thou not?" locals[30] = 6; // "Excellent! I have need of thy services." locals[31] = 0; // "" locals[50] = babl_menu( 0, &locals[29] ); switch ( locals[50] ) { case 1: goto label_033f; break; case 2: goto label_037f; break; } // end switch label_033f:; say( "You think ghoul no make good tailor?" ); locals[51] = 8; // "I'd expect thou wouldst eat a tailor rather than be one." locals[52] = 9; // "No, I'm sure thou art an excellent tailor." locals[53] = 0; // "" locals[72] = babl_menu( 0, &locals[51] ); switch ( locals[72] ) { case 1: goto label_03bf; break; case 2: goto label_037f; break; } // end switch label_037f:; label_037f:; label_037f:; say( "Me very good tailor. What you need?" ); locals[73] = 11; // "Canst thou make me some clothing?" locals[74] = 12; // "What hast thou in my size?" locals[75] = 0; // "" locals[94] = babl_menu( 0, &locals[73] ); switch ( locals[94] ) { case 1: goto label_0483; break; case 2: goto label_07ef; break; } // end switch label_03bf:; say( "Very funny! Me good tailor before, me good tailor now! What you need with me?" ); locals[95] = 14; // "Nothing." locals[96] = 15; // "I have need of a good tailor." locals[97] = 0; // "" locals[116] = babl_menu( 0, &locals[95] ); switch ( locals[116] ) { case 1: func_00c2(); break; case 2: goto label_037f; } // end if break; } // end switch if ( private[4] ) { } else { if ( private[2] ) { if ( private[5] ) { } else { } // end if locals[117] = npc_attitude; if ( 1 == locals[117] ) { say( "Get 'way from me. You not good customer!" ); } else { if ( 2 == locals[117] ) { say( "Hello." ); } else { if ( 3 == locals[117] ) { say( "Good see you again! How you be?" ); } // end if } // end if } // end if locals[118] = 19; // "Your pardon, I must be going." locals[119] = 20; // "I need thy skill as a tailor." locals[120] = 0; // "" locals[139] = babl_menu( 0, &locals[118] ); switch ( locals[139] ) { case 1: func_00e0(); break; case 2: goto label_0483; break; } // end switch label_0483:; label_0483:; say( "Let me see what you got to work with." ); } // end if locals[140] = 22; // "How is this?" locals[141] = 23; // "I don't have anything." locals[142] = 0; // "" locals[161] = babl_menu( 0, &locals[140] ); switch ( locals[161] ) { case 1: goto label_04c3; break; case 2: goto label_0544; break; } // end switch label_04c3:; locals[162] = 285; if ( !find_barter( 1, &locals[162] ) ) { say( "Me no see any good material there. You got any cloth or animal skin or something like that?" ); } else { locals[163] = 284; if ( find_barter( 1, &locals[163] ) ) { say( "Me can make dragonskin and ironsilk thread into boots for you. Why me do that for you?" ); } else { say( "Me can make dragon skin into boots for you. But me also need ironsilk thread - only thread good for stitching dragon skin. Why me do that for you?" ); } // end if locals[164] = 27; // "What dost thou mean?" locals[165] = 28; // "Because I asked thee to." locals[166] = 29; // "Ah . . . Dost require payment of some kind?" locals[167] = 0; // "" locals[185] = babl_menu( 0, &locals[164] ); switch ( locals[185] ) { case 1: goto label_0552; break; case 2: goto label_0552; break; case 3: goto label_0592; break; } // end switch label_0544:; say( "No have material, eh? Me no can make anything without material. So long." ); locals[186] = 2; func_00b1( &locals[186] ); label_0552:; label_0552:; say( "Me no Avatar, do tough things for free! Me want good pay for good work!" ); locals[187] = 32; // "As it should be. In what coin dost thou desire payment?" locals[188] = 33; // "Mmmm. Very well. How shall I pay thee?" locals[189] = 0; // "" locals[208] = babl_menu( 0, &locals[187] ); switch ( locals[208] ) { case 1: goto label_0592; break; case 2: goto label_0592; break; } // end switch label_0592:; label_0592:; label_0592:; say( "Me want food for my work. Just about anybody will do. Maybe a Goblin. Green ones be tender." ); locals[209] = 35; // "Very well. I shall pay thee in food, although it may not be a Goblin." locals[210] = 36; // "I am sorry. I cannot pay thee." locals[211] = 0; // "" locals[230] = babl_menu( 0, &locals[209] ); switch ( locals[230] ) { case 1: goto label_05de; break; case 2: say( "Okay, no pay, no boots." ); locals[231] = 2; func_00b1( &locals[231] ); break; } // end switch label_05de:; private[2] = 1; say( "Okay. Give me dragon scales and thread and then me make boots." ); } // end if locals[232] = 39; // "Very well. Here they are." locals[233] = 40; // "I am sorry. I do not have them." locals[234] = 0; // "" locals[253] = babl_menu( 0, &locals[232] ); switch ( locals[253] ) { case 1: break; case 2: say( "Me need them to make boots. Come back when you have them." ); locals[254] = 2; func_00b1( &locals[254] ); break; } // end switch locals[4] = find_barter( 1, &locals[255] ); locals[255] = 285; locals[5] = find_barter( 1, &locals[256] ); locals[256] = 284; if ( (!locals[4] || !locals[5]) ) { say( "Me no see scales and thread!" ); } else { private[5] = 1; locals[257] = -1; give_ptr_npc( 2, &locals[257], &locals[4] ); locals[258] = -1; give_ptr_npc( 2, &locals[258], &locals[5] ); func_00ea( 37 ); private[9][1] = 0; private[9][2] = 30; say( "Okay. Come back in half hour with food and me give you boots." ); locals[259] = 44; // "Excellent. I shall return then." locals[260] = 45; // "Canst thou work more quickly?" locals[261] = 0; // "" locals[280] = babl_menu( 0, &locals[259] ); switch ( locals[280] ) { case 1: locals[281] = 2; func_00b1( &locals[281] ); break; case 2: say( "No. Me have to make special. Half hour." ); locals[282] = 2; func_00b1( &locals[282] ); } // end if break; } // end switch if ( !func_0106( 40, 37 ) ) { func_018f( &locals[1], 40, 37 ); if ( locals[2] == 1 ) { locals[6] = 47; } else { locals[6] = 48; } // end if say( "Me said it would be half hour. Come back in @SI1C2 @SS6." ); locals[283] = 2; func_00b1( &locals[283] ); } // end if if ( !private[3] ) { private[3] = 1; locals[284] = 285; do_inv_delete( 1, &locals[284] ); locals[285] = 284; do_inv_delete( 1, &locals[285] ); locals[286] = 47; do_inv_create( 1, &locals[286] ); } // end if say( "Okay, me make boots. You got food to pay?" ); if ( say( "" ) ) { _asm ??? (0x0544) _asm ??? (0x0033) locals[287] = 2; func_00b1( &locals[287] ); } // end if say( "Okay, here your boots. So long." ); private[4] = 1; locals[288] = 47; if ( take_from_npc( 1, &locals[288] ) == 2 ) { say( "You arms full, I leave on floor." ); } // end if locals[289] = 2; func_00b1( &locals[289] ); label_07a6:; say( "Fine! Me no talk to you, neither!" ); locals[290] = 55; // "Wait! I'm sorry. I am @GS8." locals[291] = 56; // "In that case, good-bye!" locals[292] = 0; // "" locals[311] = babl_menu( 0, &locals[290] ); switch ( locals[311] ) { case 1: goto label_02ff; break; case 2: locals[312] = 1; func_00b1( &locals[312] ); break; } // end switch label_07ef:; say( "Me got some little stuff, look like your size. Here!" ); func_094b(); func_00e0(); } // end if say( "Hey, me already give you boots." ); locals[313] = 2; func_00b1( &locals[313] ); } // end func void func_0807() { int locals[26]; } // end if locals[3] = 59; // "Here you are." locals[4] = 61; // "Oh, sorry. I don't have any." locals[5] = 0; // "" locals[24] = babl_menu( 0, &locals[3] ); switch ( locals[24] ) { case 1: locals[2] = find_barter( 1, &locals[25] ); locals[25] = 1011; if ( locals[2] == 0 ) { say( "Hey, me no see any food!" ); } else { break; case 2: locals[1] = 0; goto label_0886; break; } // end switch locals[26] = -1; give_ptr_npc( 2, &locals[26], &locals[2] ); locals[1] = 1; goto label_0886; label_0886:; label_0886:; return locals[1]; } // end func void func_088e() { private[12][1] = 1011; private[12][2] = 1012; private[12][3] = 1013; private[12][4] = -1; private[33][1] = 1019; private[33][2] = 1002; private[33][3] = 1000; private[33][4] = 1001; private[33][5] = 1003; private[33][6] = 1019; private[33][7] = -1; set_likes_dislikes( 2, 64, 43 ); } // end func void func_08fb() { int locals[22]; if ( !func_0020() ) { } else { say( "You want trade some things?" ); locals[1] = 63; // "Yes" locals[2] = 64; // "No" locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_094b(); break; case 2: return; } // end if break; } // end switch } // end func void func_094b() { int locals[44]; setup_to_barter( 0 ); while ( !private[1] ) { locals[1] = 65; // "I make thee this offer." locals[2] = 66; // "I demand thou givest me these items." locals[3] = 67; // "I beg thy pardon, I must think about this deal." locals[4] = 68; // "I do not wish to barter any further." locals[5] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_09fc(); break; case 2: func_0a3e(); break; case 3: do_judgement( 0 ); break; case 4: do_decline( 0 ); private[1] = 1; break; } // end switch } // while locals[23] = 69; // "Farewell" locals[24] = 0; // "" locals[44] = babl_menu( 0, &locals[23] ); if ( locals[44] == 1 ) { private[1] = 1; } // end if } // end func void func_09fc() { int locals[5]; locals[1] = 70; // "Okay, me take it." locals[2] = 71; // "No, me no like this deal." locals[3] = 72; // "You think me stupid?" locals[4] = 73; // "Me tired of this." locals[5] = 74; // "You being silly." if ( do_offer( 5, &locals[5], &locals[4], &locals[3], &locals[2], &locals[1] ) ) { private[1] = 1; } // end if } // end func void func_0a3e() { int locals[24]; say( "Hey! You try and rob me?" ); locals[1] = 76; // "Yes, I must." locals[2] = 77; // "No, you 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] = 78; // "Well, okay. Me give to you." locals[24] = 79; // "No! Me won't give them!" if ( do_demand( 2, &locals[24], &locals[23] ) ) { private[1] = 1; } else { func_008b(); } // end if } // end func