Ultima Underworld/technical/conversations/232
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 #232 // string block 0x0ee8 (3816), name Carasso // // 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[22]; if ( private[0] ) { func_076c(); } else { say( "What dost thou want here? Art thou here to let the monsters upon me?" ); locals[1] = 2; // "I seek information about the demon who dwells in these depths." locals[2] = 3; // "I am seeking the bones of a great wizard." locals[3] = 4; // "I am @GS8. I mean thee no harm." locals[4] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_0302(); break; case 2: func_034a(); break; case 3: func_0392(); } // end if break; } // end switch } // end func void func_0302() { int locals[22]; say( "Why dost thou seek a demon? Art thou in league with it?" ); locals[1] = 6; // "I plan to destroy this demon." locals[2] = 7; // "I am not in league, but why art thou here?" locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_03da(); break; case 2: func_046a(); break; } // end switch } // end func void func_034a() { int locals[22]; say( "There are many bones down here. I do not intend to allow mine to join them." ); locals[1] = 9; // "I will not harm thee, but thou mayst be able to help me." locals[2] = 10; // "They shall if thou dost not tell me what I want to know!" locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_046a(); break; case 2: func_0563(); break; } // end switch } // end func void func_0392() { int locals[22]; say( "And why art thou here?" ); locals[1] = 12; // "I am on a quest. And why art thou residing in these fearsome depths?" locals[2] = 13; // "Better I should ask thee. Art thou in league with the wizard, Tyball?" locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_046a(); break; case 2: func_05bf(); break; } // end switch } // end func void func_03da() { int locals[22]; say( "Ah, good luck to thee. I am not sure, but there is a large chamber in the center of the lava, guarded by many of the most fearsome creatures I have ever heard tell of. I stole a key to the door which leads to the chamber's portal, but I fled for my life when I saw what was beyond. I cannot say if there is a demon there." ); locals[1] = 15; // "Where is this door?" locals[2] = 16; // "Please tell me more." locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_0422(); break; case 2: func_046a(); break; } // end switch } // end func void func_0422() { int locals[22]; say( "It is to the south, down the main hall. It is unmistakable, with devilish devices upon it. If thou dost wish to enter the door, I will give thee the key, as I do not intend to use it again!" ); locals[1] = 18; // "Yes, that would be very helpful." locals[2] = 19; // "No, I will find another way and avoid the beasts." locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_04b7(); break; case 2: func_051b(); break; } // end switch } // end func void func_046a() { int locals[22]; say( "I came to these depths on a quest to find the legendary gold mines. While I was exploring, an evil magic was done, and I became trapped here, my return blocked by a powerful wizard.\n" " I have been here for weeks now, trying to survive and find another way home. I have had almost no food, as the creatures I have killed are too foul to eat." ); private[5] = 1; locals[1] = 21; // "The way home is open for thee now. Leave now!" locals[2] = 22; // "Here is some food. Wilt thou tell me more of thy exploring?" locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_00d1(); break; case 2: func_061b(); break; } // end switch } // end func void func_04b7() { int locals[23]; say( "Here is the key. If thou'rt smarter than brave, thou wilt not use it, but wilt make thy escape with me." ); locals[1] = 1016; if ( take_from_npc( 1, &locals[1] ) == 2 ) { say( "I will leave it for you here." ); } // end if private[4] = 1; locals[2] = 25; // "I must finish my quest. But why dost thou stay here?" locals[3] = 26; // "I may or may not find use for it. Thank thee, I must make haste." locals[4] = 0; // "" locals[23] = babl_menu( 0, &locals[2] ); switch ( locals[23] ) { case 1: func_046a(); break; case 2: func_00e0(); break; } // end switch } // end func void func_051b() { int locals[22]; say( "The only way I have seen is across the lava, and if thou dost not burn from the heat, there are fearsome creatures of fire dwelling there!" ); locals[1] = 28; // "I may be able to cross nonetheless. Canst thou tell me anything more?" locals[2] = 29; // "I shall cross regardless. Thank thee for thy help." locals[3] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_046a(); break; case 2: func_00e0(); break; } // end switch } // end func void func_0563() { int locals[22]; say( "Hah! I have faced worse threats than thee in these depths. Prepare thyself!" ); locals[1] = 31; // "I apologize for my harshness. Please tell me about thy journey." locals[2] = 32; // "Die then, foolish one!" locals[3] = 33; // "I am sorry. I will leave thee in peace." locals[4] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_046a(); break; case 2: func_008b(); break; case 3: func_00d1(); break; } // end switch } // end func void func_05bf() { int locals[22]; say( "I know no such person. I know only that I am trapped here by a wizard." ); locals[1] = 35; // "How didst thou come to be trapped?" locals[2] = 36; // "Then I will take my leave before I am trapped as well." locals[3] = 37; // "Fear not, the wizard is dead. I will leave thee to make thy escape." locals[4] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); switch ( locals[22] ) { case 1: func_046a(); break; case 2: func_00c2(); break; case 3: func_00c2(); break; } // end switch } // end func void func_061b() { int locals[36]; locals[13] = 0; label_0625:; locals[11] = show_inv( 2, &locals[6], &locals[1] ); if ( locals[11] > 0 ) { locals[12] = 1; while ( locals[12] <= locals[11] ) { if ( locals[0] == 1011 ) { locals[14] = 1; give_to_npc( 2, &locals[5], &locals[14] ); } // end if locals[12] = locals[12] + 1; } // while give_to_npc( 2, &locals[6], &locals[11] ); func_06de(); } else { if ( locals[13] > 2 ) { say( "Thou art toying with me most cruelly! Leave me!" ); func_00d1(); } // end if say( "But thou art empty-handed! Dost thou truly wish to give me some food?" ); locals[15] = 40; // "Yes, I'm sorry, here it is..." locals[16] = 41; // "No, I have no food to give thee." locals[17] = 0; // "" locals[36] = babl_menu( 0, &locals[15] ); switch ( locals[36] ) { case 1: locals[13] = locals[13] + 1; goto label_0625; break; case 2: func_0738(); } // end if break; } // end switch } // end func void func_06de() { int locals[24]; if ( private[3] ) { say( "I thank thee kindly. May thy quest come to a happier end than mine!" ); locals[1] = 3; func_00b1( &locals[1] ); } // end if say( "I thank thee most kindly. Here, I found this wand with some bones far to the southwest of here. I believe that the bones were those of a great wizard. They were near a Knight's remains. There was more, but I had to flee a fearsome stone creature before I could gather it up." ); locals[2] = 152; take_from_npc( 1, &locals[2] ); private[3] = 1; locals[3] = 44; // "Thank thee. I will be on my way now." locals[4] = 0; // "" locals[24] = babl_menu( 0, &locals[3] ); if ( locals[24] == 1 ) { func_00c2(); } // end if } // end func void func_0738() { int locals[22]; say( "Well, leave me then, as I must rest before I make another attempt at escape." ); locals[1] = 46; // "Goodbye, then." locals[2] = 0; // "" locals[22] = babl_menu( 0, &locals[1] ); if ( locals[22] == 1 ) { func_00c2(); } // end if } // end func void func_076c() { int locals[46]; say( "Hello again." ); locals[1] = !private[5]; locals[2] = !private[4]; locals[3] = !private[3]; locals[25] = locals[1]; locals[4] = 48; // "Canst thou tell me about thyself?" locals[26] = locals[2]; locals[5] = 49; // "Canst thou tell me where the key to the door to the demon is?" locals[27] = locals[3]; locals[6] = 50; // "I have some food for thee." locals[28] = 1; locals[7] = 51; // "It is good to see thee again, but farewell for now." locals[8] = 0; // "" locals[46] = babl_fmenu( 0, &locals[4], &locals[25] ); switch ( locals[46] ) { case 48: func_046a(); break; case 49: func_0422(); break; case 50: func_061b(); break; case 51: func_00e0(); break; } // end switch } // end func