Ultima Underworld/technical/conversations/113

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 #113 // string block 0x0e71 (3697), name head bandit // // 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[89]; if ( npc_attitude != 3 ) { if ( private[0] == 0 ) { say( "What art thou doing here? " ); } else { say( "What art thou doing here again? " ); } // end if say( "Leave now before I call the guards." ); locals[2] = 4; // "Excuse me. I shall leave now." locals[3] = 5; // "Arm thyself, knave!" locals[4] = 6; // "Can we not discuss this?" locals[5] = 0; // "" locals[23] = babl_menu( 0, &locals[2] ); switch ( locals[23] ) { case 1: func_00b1( 21 ); break; case 2: func_069a(); break; case 3: func_0401(); } // end if } else { break; } // end switch if ( private[0] == 0 ) { say( "Hullo, @GS8. I have been told of thee. What is it thou doth need?" ); } else { say( "Hello again, @GS8. What can I do for thee?" ); } // end if locals[1] = !private[0]; locals[45] = 1; locals[24] = 9; // "Sorry to have bothered thee. Goodbye." locals[46] = 1; locals[25] = 10; // "I seek treasure and fame!" locals[47] = locals[1]; locals[26] = 11; // "I look for information and trade." locals[48] = private[0]; locals[27] = 12; // "I seek more information and trade." locals[28] = 0; // "" locals[66] = babl_fmenu( 0, &locals[24], &locals[45] ); switch ( locals[66] ) { case 9: locals[67] = 2; func_00b1( &locals[67] ); break; case 10: func_04b5(); break; case 11: break; case 12: break; } // end switch say( "Which can I do for thee now, @GS8?" ); locals[68] = 14; // "Some information please." locals[69] = 15; // "Some bartering." locals[70] = 0; // "" locals[89] = babl_menu( 0, &locals[68] ); switch ( locals[89] ) { case 1: func_0514(); break; case 2: func_06c7(); break; } // end switch func_00b1( 21 ); } // end func void func_0401() { int locals[44]; say( "I have nothing to discuss. Please deal with my underlings first before thou dost continue to bother me. Go now." ); locals[1] = 17; // "Goodbye." locals[2] = 18; // "But wait, I need to talk to thee." locals[3] = 19; // "I defer to no one!" locals[4] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_00b1( 21 ); break; case 2: break; case 3: func_069a(); break; } // end switch say( "Thou hast bothered me too much already. Leave!" ); locals[23] = 21; // "Goodbye." locals[24] = 22; // "Thou must hear me out!" locals[25] = 23; // "Thou doth force me to rash actions!" locals[26] = 0; // "" locals[44] = babl_menu( 0, &locals[23] ); switch ( locals[44] ) { case 1: func_00b1( 21 ); break; case 2: func_069a(); break; case 3: func_069a(); break; } // end switch } // end func void func_04b5() { int locals[22]; say( "Do not come here then! We guard ours to the death! Leave!" ); locals[1] = 25; // "Oh, thou hast some, then?" locals[2] = 26; // "Then give it all to me!" locals[3] = 27; // "Goodbye." locals[4] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_069a(); break; case 2: func_069a(); break; case 3: func_00b1( 21 ); break; } // end switch } // end func void func_0514() { int locals[36]; say( "What information dost thou seek?" ); label_051c:; locals[3] = 29; // "What about ... " locals[4] = 30; // "I must go now." locals[5] = 0; // "" locals[24] = babl_menu( 0, &locals[3] ); switch ( locals[24] ) { case 1: break; case 2: func_00b1( 21 ); break; } // end switch locals[2] = babl_ask( 0 ); locals[25] = 31; if ( contains( 2, &locals[2], &locals[25] ) ) { say( "He is kept prisoner by the Green Lizardmen." ); } else { locals[26] = 33; ((contains( 2, &locals[2], &locals[26] ) || contains( 2, &locals[2], &locals[27] )) || contains( 2, &locals[2], &locals[28] )); // expr. has value on stack! locals[27] = 34; if ( locals[28] = 35 ) { say( "All I've heard is that the Gray Lizardmen know more." ); } else { locals[29] = 37; (contains( 2, &locals[2], &locals[29] ) || contains( 2, &locals[2], &locals[30] )); // expr. has value on stack! if ( locals[30] = 38 ) { say( "The crazy one to the north has stolen many types of lights, including our candles!" ); } else { locals[31] = 40; (contains( 2, &locals[2], &locals[31] ) || contains( 2, &locals[2], &locals[32] )); // expr. has value on stack! if ( locals[32] = 41 ) { say( "A great one, was Sir Cabirus. After he died, things all went haywire. The races of the Abyss split off into many small groups like our own. Dealing with the others can be a touchy task. " ); } else { locals[33] = 43; if ( contains( 2, &locals[2], &locals[33] ) ) { say( "The Eight Talismans? I do not know much, save the Gray Lizardmen know all about the Sword of Justice." ); } else { locals[34] = 45; if ( contains( 2, &locals[2], &locals[34] ) ) { say( "They are the rulers of this level. There are Green ones, Red ones, and the mysterious Gray Ones, who are called the Quiet Ones. They even speak a little of our tongue." ); } else { locals[1] = random( 1, &locals[35] ); locals[35] = 4; locals[36] = locals[1]; if ( 1 == locals[36] ) { say( "I am sorry I cannot help thee there." ); } else { if ( 2 == locals[36] ) { say( "What does this mean, "@SS2"?" ); } else { if ( 3 == locals[36] ) { say( "I do not know." ); } else { if ( 4 == locals[36] ) { say( "Sorry. I don't understand." ); } // end if } // end if } // end if } // end if } // end if } // end if } // end if } // end if } // end if } // end if say( "Can I tell thee anything else?" ); goto label_051c; } // end func void func_069a() { int locals[3]; say( "Defend thyself!" ); locals[1] = 13; locals[2] = 0; locals[3] = 10; set_race_attitude( 3, &locals[3], &locals[2], &locals[1] ); func_008b(); } // end func void func_06c7() { int locals[44]; setup_to_barter( 0 ); while ( !private[1] ) { locals[1] = 53; // "I make thee this offer." locals[2] = 54; // "I demand thou givest me these items." locals[3] = 55; // "Excuse me, I must think about this deal." locals[4] = 56; // "I do not wish to barter any further." locals[5] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_0778(); break; case 2: func_07d2(); break; case 3: do_judgement( 0 ); break; case 4: do_decline( 0 ); private[1] = 1; break; } // end switch } // while locals[23] = 57; // "Farewell." locals[24] = 0; // "" locals[44] = babl_menu( 0, &locals[23] ); if ( locals[44] == 1 ) { private[1] = 1; } // end if } // end func void func_0778() { int locals[15]; locals[0] = -1; locals[6] = -1; locals[11] = 58; // "I accept thy offer." locals[12] = 59; // "No, I do not like this deal." locals[13] = 60; // "Dost thou take me for a fool?" locals[14] = 61; // "I am weary of this haggling." locals[15] = 62; // "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_07d2() { int locals[24]; say( "Dost thou intend to rob me?" ); locals[1] = 64; // "Yes, I must." locals[2] = 65; // "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] = 66; // "If thou dost insist, thou canst have them." locals[24] = 67; // "No! Thou shalt not take them!" if ( do_demand( 2, &locals[24], &locals[23] ) ) { private[1] = 1; } else { func_008b(); } // end if } // end func