Ultima Underworld/technical/conversations/194

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 #194 // string block 0x0ec2 (3778), name Dominus // // 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[216]; private[2] = x_skills( 2, &locals[20], &locals[19] ); locals[19] = 15; locals[20] = 10001; if ( private[0] ) { say( "Ah, 'tis thee again. Hast thou brought any items for me to identify?" ); locals[21] = 2; // "Yes, here is one." locals[22] = 3; // "No, not now." locals[23] = 0; // "" locals[42] = babl_menu( 0, &locals[21] ); switch ( locals[42] ) { case 1: goto label_041a; break; case 2: say( "Please return when thou hast need of my services." ); locals[43] = 2; func_00b1( &locals[43] ); } // end if break; } // end switch say( "Ah, 'tis a new face I see. I imagine that thou hast managed to find many a strange object on thy journey to these depths." ); locals[44] = 6; // "None to speak of." locals[45] = 7; // "Yes, I have collected a few." locals[46] = 0; // "" locals[65] = babl_menu( 0, &locals[44] ); switch ( locals[65] ) { case 1: goto label_034e; break; case 2: goto label_03b4; break; } // end switch label_034e:; say( "I am surprised to hear that. Well, if any items thou hast found are beyond thy ability to recognize, I would be happy to identify them for a small fee." ); locals[66] = 9; // "I think I can manage by myself." locals[67] = 10; // "Canst thou identify this for me?" locals[68] = 11; // "I will return if I need thy services." locals[69] = 0; // "" locals[87] = babl_menu( 0, &locals[66] ); switch ( locals[87] ) { case 1: locals[88] = 2; func_00b1( &locals[88] ); break; case 2: goto label_041a; break; case 3: locals[89] = 2; func_00b1( &locals[89] ); break; } // end switch label_03b4:; say( "Well, I would be willing to identify some of thy items for a small fee." ); locals[90] = 13; // "I think I can manage by myself." locals[91] = 14; // "Canst thou identify this for me?" locals[92] = 15; // "I will return if I need thy services." locals[93] = 0; // "" locals[111] = babl_menu( 0, &locals[90] ); switch ( locals[111] ) { case 1: locals[112] = 2; func_00b1( &locals[112] ); break; case 2: goto label_041a; break; case 3: locals[113] = 2; func_00b1( &locals[113] ); break; } // end switch label_041a:; label_041a:; label_041a:; label_041a:; label_041a:; label_041a:; locals[3] = show_inv( 2, &locals[10], &locals[5] ); switch ( locals[3] ) { case 1: locals[17] = locals[5]; locals[18] = locals[10]; locals[4] = 10 - private[2] / 6; say( "I will require @SI4 gold pieces to identify that item for thee." ); label_0452:; if ( func_0623( &locals[4] ) ) { locals[2] = identify_inv( 4, &locals[115], &locals[15], &locals[114], &locals[18] ); locals[114] = 1; locals[115] = 3; if ( !func_071c( &locals[18], &locals[17] ) ) { locals[116] = 1; locals[117] = 7; locals[118] = -1; locals[119] = -1; locals[120] = -1; locals[121] = -1; locals[122] = -1; locals[123] = -1; x_obj_stuff( 9, &locals[123], &locals[122], &locals[121], &locals[120], &locals[119], &locals[118], &locals[117], &locals[116], &locals[18] ); say( "That is @SS15. Will there be anything else?" ); } // end if locals[124] = 18; // "Yes, canst thou identify this?" locals[125] = 19; // "No, that is all." locals[126] = 0; // "" locals[145] = babl_menu( 0, &locals[124] ); switch ( locals[145] ) { case 1: goto label_041a; break; case 2: locals[146] = 2; func_00b1( &locals[146] ); } // end if } else { break; } // end switch say( "I'm sorry, but I cannot help thee if thou canst not pay an appropriate price." ); locals[147] = 21; // "Goodbye, then." locals[148] = 22; // "I will pay thee the price thou dost request." locals[149] = 0; // "" locals[168] = babl_menu( 0, &locals[147] ); switch ( locals[168] ) { case 1: locals[169] = 2; func_00b1( &locals[169] ); break; case 2: say( "Well then! Where are my @SI4 pieces of gold?" ); goto label_0452; break; } // end switch break; case 0: say( "I don't identify invisible items! Is there something thou dost wish me to identify?" ); locals[170] = 25; // "Yes, here it is." locals[171] = 26; // "No, not now." locals[172] = 0; // "" locals[191] = babl_menu( 0, &locals[170] ); switch ( locals[191] ) { case 1: goto label_041a; break; case 2: say( "Well, come back when thou art ready." ); locals[192] = 2; func_00b1( &locals[192] ); break; } // end switch break; say( "Please, please, one at a time!" ); locals[193] = 29; // "I'm sorry. Canst thou identify this?" locals[194] = 30; // "Oh, never mind." locals[195] = 0; // "" locals[214] = babl_menu( 0, &locals[193] ); locals[214] == 1; // expr. has value on stack! goto label_041a; } // end switch if ( locals[214] == 2 ) { locals[215] = 2; func_00b1( &locals[215] ); } // end if locals[216] = 3; func_00b1( &locals[216] ); } // end func void func_0623() { int locals[42]; locals[21] = 31; // "Here thou art." locals[22] = 32; // "I cannot afford thy services." locals[23] = 0; // "" locals[42] = babl_menu( 0, &locals[21] ); switch ( locals[42] ) { case 1: break; case 2: locals[1] = 0; goto label_0714; break; } // end switch locals[3] = show_inv( 2, &locals[6], &locals[11] ); if ( locals[3] == 0 ) { locals[1] = 0; } else { locals[4] = 0; locals[5] = 0; locals[2] = 1; while ( locals[2] <= locals[3] ) { if ( (locals[10] == 160 || locals[10] == 161) ) { locals[4] = locals[4] + count_inv( 1, &locals[5] ); locals[5] = locals[5] + 1; locals[15] = locals[5]; } // end if locals[2] = locals[2] + 1; } // while if ( locals[4] >= param1[0]play_hunger ) { give_to_npc( 2, &locals[16], &locals[5] ); locals[1] = 1; } else { locals[1] = 0; } // end if } // end if label_0714:; return locals[1]; } // end func void func_071c() { int locals[10]; locals[2] = param2[0]play_hunger; if ( 10 == locals[2] ) { say( "That's the Sword of Justice, one of the Talismans of Virtue created by Cabirus. Not too many finer weapons wilt thou see." ); } else { if ( 54 == locals[2] ) { say( "That is the Ring of Humility. It has no magic powers, but still the Virtuous energy given it by Cabirus is undeniable." ); } else { if ( 55 == locals[2] ) { say( "That is the Shield of Valor, one of Cabirus' Talismans. It will protect your front side admirably, but 'twill not help thee if thou dost turn thy back on an enemy." ); } else { if ( 151 == locals[2] ) { say( "That is the Taper of Sacrifice, one of the Talismans of Virtue created by Cabirus. Its light may not be great, but it will never fail thee." ); } else { if ( 147 == locals[2] ) { say( "That is the Taper of Sacrifice, one of the Talismans of Virtue created by Cabirus. Its light may not be great, but it will never fail thee." ); } else { if ( 174 == locals[2] ) { say( "Ah, that is the Cup of Wonder. 'Twas fashioned by Sir Cabirus himself, as one of his Talismans. Beautiful, is it not?" ); } else { if ( 191 == locals[2] ) { say( "The Wine of Compassion that is, one of Cabirus' Talismans. It was of a fine vintage, but perhaps it is past its prime now." ); } else { if ( 310 == locals[2] ) { say( "That is the Book of Honesty, one of the Talismans of Cabirus. It is said that the power of truth contained in the tome is such that its pages cannot be torn out." ); } else { if ( 287 == locals[2] ) { say( "That is the Standard of Honor, one of Cabirus' Talismans. It was to be a symbol of courage throughout all Britannia." ); } else { locals[1] = 0; } // end if } // end if } // end if } // end if } // end if } // end if } // end if } // end if } // end if locals[3] = 1; locals[4] = 7; locals[5] = -1; locals[6] = -1; locals[7] = -1; locals[8] = -1; locals[9] = -1; locals[10] = -1; x_obj_stuff( 9, &locals[10], &locals[9], &locals[8], &locals[7], &locals[6], &locals[5], &locals[4], &locals[3], param1 ); say( "Will there be anything else?" ); locals[1] = 1; goto label_081a; label_081a:; return locals[1]; } // end func void func_0822() { int locals[44]; setup_to_barter( 0 ); while ( !private[1] ) { locals[1] = 43; // "I make thee this offer." locals[2] = 44; // "I demand thou givest me these items." locals[3] = 45; // "Excuse me, I must think about this deal." locals[4] = 46; // "I do not wish to barter any further." locals[5] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_08d3(); break; case 2: func_092d(); break; case 3: do_judgement( 0 ); break; case 4: do_decline( 0 ); private[1] = 1; break; } // end switch } // while locals[23] = 47; // "Farewell." locals[24] = 0; // "" locals[44] = babl_menu( 0, &locals[23] ); if ( locals[44] == 1 ) { private[1] = 1; } // end if } // end func void func_08d3() { int locals[15]; locals[0] = -1; locals[6] = -1; locals[11] = 48; // "I accept thy offer." locals[12] = 49; // "No, I do not like this deal." locals[13] = 50; // "Dost thou take me for a fool?" locals[14] = 51; // "I am weary of this haggling." locals[15] = 52; // "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_092d() { int locals[24]; say( "Dost thou intend to rob me?" ); locals[1] = 54; // "Yes, I must." locals[2] = 55; // "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] = 56; // "If thou dost insist, thou canst have them." locals[24] = 57; // "No! Thou shalt not take them!" if ( do_demand( 2, &locals[24], &locals[23] ) ) { private[1] = 1; } else { func_008b(); } // end if } // end func