Ultima Underworld/technical/conversations/208
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 #208 // string block 0x0ed0 (3792), name Cardon // // 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]global[0]; 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] == 1 ) { func_0566(); } // end if say( "Who art thou? What >cough< what dost thou want?" ); locals[1] = 2; // "Here, thou seemest hurt. Can I help thee?" locals[2] = 3; // "I hope thou art not contagious. Good-bye!" locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_02ef(); break; case 2: func_00c2(); break; } // end switch } // end func void func_02ef() { int locals[22]; say( "Canst heal my wounds? Or >cough< hast thou any port?" ); locals[1] = 5; // "Here is some port." locals[2] = 6; // "I would give it if I had it." locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_0337(); break; case 2: func_03b8(); break; } // end switch } // end func void func_0337() { int locals[16]; locals[15] = 0; locals[13] = show_inv( 2, &locals[6], &locals[1] ); while ( locals[13] > 0 ) { locals[14] = 1; if ( locals[14] <= locals[13] ) { if ( locals[0] == 190 ) { locals[15] = locals[14]; locals[11] = locals[5]; } // end if locals[14] = locals[14] + 1; } // while } // end if if ( locals[15] > 0 ) { locals[16] = 1; give_to_npc( 2, &locals[11], &locals[16] ); say( "I thank thee greatly!" ); func_03c5(); } else { say( "What, dost thou mock me? Begone with ye!" ); func_00d1(); } // end if } // end func void func_03b8() { say( "At least thou seemest in better condition than I." ); func_03c5(); } // end func void func_03c5() { int locals[22]; say( "Here is some advice for thee: Beware, for death is everywhere!" ); locals[1] = 11; // "Then what art thou doing here?" locals[2] = 12; // "This, I knew without thy help! Begone!" locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_040d(); break; case 2: func_00e0(); break; } // end switch } // end func void func_040d() { int locals[22]; say( "I'm here to rescue my brother. He's in the prisons." ); locals[1] = 14; // "Where are these prisons?" locals[2] = 15; // "I cannot help thee." locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_0455(); break; case 2: func_057e(); break; } // end switch } // end func void func_0455() { int locals[22]; say( "Several cells lie to the north and west of here. He rots in one of those." ); locals[1] = 17; // "Who holds him prisoner?" locals[2] = 18; // "I wish I could help thee, but I must solve my own problems." locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_049d(); break; case 2: func_057e(); break; } // end switch } // end func void func_049d() { int locals[22]; say( "He is in the clutches of the evil wizard who dominates this area. My brother came to explore this place months ago and I have not heard from him since. I believe he has run afoul of this vile and violent mage." ); locals[1] = 20; // "Tell me of this wizard." locals[2] = 21; // "If I find him, I shall set him free." locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_04e5(); break; case 2: func_057e(); break; } // end switch } // end func void func_04e5() { int locals[22]; say( "Rumor has it that he is the reason no one can cast spells on this level. Also, he uses monsters as henchmen to guard the way to his lair. But I have figured out how to get by these guards!" ); locals[1] = 23; // "How can one get past the guards?" locals[2] = 24; // "Seeing the shape thou art in, I shall make my own plans." locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_052d(); break; case 2: func_057e(); break; } // end switch } // end func void func_052d() { int locals[22]; global[0] = 1; say( "A medallion of passage! I had one but I lost it while in battle in the haunted mines to the southeast. Now I am too weak to recover it, and just wish to return home. But perhaps thou..." ); locals[1] = 26; // "Say no more! I will seek out these mines now." locals[2] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); if ( locals[22] == 1 ) { func_057e(); } // end if } // end func void func_0566() { if ( !global[0] ) { say( "Thou dost not wish to hear all I would tell thee? Well, hear this, for it may prevent thee from ending up like I have. A medallion of passage is needed to pass by the guards. It lies in the haunted mines in the southeast. Now go, if thou art determined to brave the perils of these caves!" ); remove_talker( 0 ); func_00e0(); } // end if } // end func void func_057e() { int locals[22]; remove_talker( 0 ); say( "Is that so? Well, farewell, then. I will rejoin my comrades up above." ); locals[1] = 29; // "Farewell." locals[2] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); if ( locals[22] == 1 ) { func_00e0(); } // end if } // end func void func_05b7() { int locals[44]; setup_to_barter( 0 ); while ( !private[1] ) { locals[1] = 30; // "I make thee this offer." locals[2] = 31; // "I demand thou givest me these items." locals[3] = 32; // "Excuse me, I must think about this deal." locals[4] = 33; // "I do not wish to barter any further." locals[5] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_0668(); break; case 2: func_06c2(); break; case 3: do_judgement( 0 ); break; case 4: do_decline( 0 ); private[1] = 1; break; } // end switch } // while locals[23] = 34; // "Farewell." locals[24] = 0; // "" locals[44] = babl_menu( 0, &locals[23] ); if ( locals[44] == 1 ) { private[1] = 1; } // end if } // end func void func_0668() { int locals[15]; locals[0] = -1; locals[6] = -1; locals[11] = 35; // "I accept thy offer." locals[12] = 36; // "No, I do not like this deal." locals[13] = 37; // "Dost thou take me for a fool?" locals[14] = 38; // "I am weary of this haggling." locals[15] = 39; // "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_06c2() { int locals[24]; say( "Dost thou intend to rob me?" ); locals[1] = 41; // "Yes, I must." locals[2] = 42; // "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] = 43; // "If thou dost insist, thou canst have them." locals[24] = 44; // "No! Thou shalt not take them!" if ( do_demand( 2, &locals[24], &locals[23] ) ) { private[1] = 1; } else { func_008b(); } // end if } // end func