Page 2 of 2

Re: The call for SI Fixes

Posted: Wed Jun 13, 2012 8:23 pm
by marzo
To repeat myself from the other thread: Adding these to SI fixes certainly match the vision I have of it; when my new computer is full configured, I will include those fixes in it. Moreover, if there are any other NPCs that also fail to give XP for this reason, I would appreciate knowing so they can be fixed too.

Re: The call for SI Fixes

Posted: Wed Jun 13, 2012 11:58 pm
by Malignant Manor
I found some other instances searching for (UI_reduce_health(npcNum, ") "0x0037, 0x0000);".

Should likely give xp
Bane Shamino Func013D
Goblin King Func0162
Bane Iolo Func0370
Bane Dupre Func038A
Hazard the Trapper Func0395
Rotoluncia's Automaton Func0419

Should not give xp
Ghost (id 6) Func0151 seems to die after saying goodbye

Re: The call for SI Fixes

Posted: Thu Jun 14, 2012 2:04 am
by Malignant Manor
Here's the functions with a decent amount of work done. They should all compile except one that has atends. I really don't want to be messing with those gotos and weird decompiled logic either. As before, these are all untested.

Code: Select all

// GoblinKing allows xp on death patch
extern void delayedBark 0x97F (var npc, var bark, var delay);

void GoblinKing object#(0x162) ()
{
	if (event != DOUBLECLICK) {
		if ((event != STARTED_TALKING || event != DEATH) && UI_get_item_flag(item, SI_ZOMBIE)) {
			if (event == DEATH && UI_get_item_flag(item, SI_ZOMBIE)) {
				UI_clear_item_flag(item, SI_TOURNAMENT);
				delayedBark(item, "@Thou hast slain me...@", 0);
				UI_reduce_health(item, 55, 1);
			}
			return;
		}
	}
	GoblinKing.original();
}


//Bane Iolo allows xp on death patch
void AntiIolo object#(0x370) ()
{
	if (!(event == PATH_SUCCESS)) goto labelFunc0370_001E;
	UI_execute_usecode_array(item, [0x23, 0x59, 2, 0x6C, 0x6B]);
	labelFunc0370_001E:
		if (!(event == PATH_FAILURE)) goto labelFunc0370_002E;
		UI_set_schedule_type(item, WANDER);
	labelFunc0370_002E:
		if (!(event == DEATH))
			return;
		if (!(!gflags[0xCE])) goto labelFunc0370_003E;
		abort;
	labelFunc0370_003E:
		if (!gflags[0xCF]) goto labelFunc0370_0045;
		abort;
	labelFunc0370_0045:
		if (!(UI_get_oppressor(item) == 0))
			return;
		if (!(UI_get_weapon(AVATAR) == 0x326))
			return;
		UI_show_npc_face0(0xFEE0, 0); // face different than npc number
		message("\"Thou hast beaten me, vile human. I will remember this day!\"");
		say();
		UI_remove_npc_face0();
		var pos = UI_get_object_position(item);
		UI_set_schedule_type(item, WAIT);
		UI_set_opponent(AVATAR, 1);
		UI_move_object(item, [0x8E, 0x2E, 0]);
		UI_clear_item_flag(IOLO, DEAD);
		UI_set_item_flag(IOLO, SI_ZOMBIE);
		UI_clear_item_flag(IOLO, SI_TOURNAMENT);
		UI_move_object(IOLO, pos);
		UI_reduce_health(IOLO, 55, 1);
		gflags[0xD2] = true;
		gflags[0xD5] = true;
	labelFunc0370_00D9:
		return;
}

// Bane Dupre allows xp on death patch
void AntiDupre object# (0x38A) ()
{
	if (!(event == PATH_SUCCESS)) goto labelFunc038A_001E;
	UI_execute_usecode_array(item, [0x23, 0x59, 2, 0x6C, 0x6B]);
	labelFunc038A_001E:
		if (!(event == PATH_FAILURE)) goto labelFunc038A_002E;
		UI_set_schedule_type(item, WANDER);
	labelFunc038A_002E:
		if (!(event == DEATH)) goto labelFunc038A_00D9;
		if (!(!gflags[0xCE])) goto labelFunc038A_003E;
		abort;
	labelFunc038A_003E:
		if (!gflags[0xCF]) goto labelFunc038A_0045;
		abort;
	labelFunc038A_0045:
		if (!(UI_get_oppressor(item) == 0)) goto labelFunc038A_00D9;
		if (!(UI_get_weapon(AVATAR) == 0x326)) goto labelFunc038A_00D9;
		UI_show_npc_face0(0xFEE6, 0); // face different than npc number
		message("\"Vanquished! By a mere mortal!\"");
		say();
		var pos = UI_get_object_position(item);
		UI_set_schedule_type(item, WAIT);
		UI_set_opponent(AVATAR, 1);
		UI_move_object(item, [0x8E, 0x2E, 0]);
		UI_clear_item_flag(DUPRE, DEAD);
		UI_move_object(DUPRE, pos);
		UI_set_item_flag(DUPRE, SI_ZOMBIE);
		UI_clear_item_flag(DUPRE, SI_TOURNAMENT);
		UI_reduce_health(DUPRE, 55, 1);
		gflags[0xD1] = true;
		gflags[0xD3] = true;
	labelFunc038A_00D9:
		if (!(event == SCRIPTED)) goto labelFunc038A_00F3;
		UI_show_npc_face0(0xFEE6, 0); // face different than npc number
		message("\"Puny mortal!\"");
		say();
		UI_remove_npc_face0();
	labelFunc038A_00F3:
		return;
}

// Hazard the Trapper allows xp on death patch (wont't even compile because of atends)
extern void delayedBark 0x97F (var npc, var bark, var delay);
extern void makePartyFaceNPC object#(0x7D1) ();
extern Func09AD 0x9AD (var var0000);

void Hazard 0x395 ()
{
	var var0000 = false;
	var pos = UI_get_object_position(AVATAR);
	if (!((pos[X] > 0x498) && ((pos[X]  0x1AF) && (pos[Y] makePartyFaceNPC();
		delayedBark(0x395, "@Thou shalt not take me!@", 3);
		Func09AD(item);
	labelFunc0395_00C0:
		if (!((event == DOUBLECLICK) && var0000)) goto labelFunc0395_00F0;
		UI_item_say(AVATAR, "@Stand fast, Trapper!@");
		0x395->makePartyFaceNPC();
		delayedBark(0x395, "@At last!@", 3);
		UI_set_schedule_type(item, TALK);
	labelFunc0395_00F0:
		if (!(event == STARTED_TALKING)) goto labelFunc0395_01C3;
		UI_run_schedule(item);
		UI_clear_item_say(item);
		UI_show_npc_face0(0xFEE8, 0); // face different from npc number
		message("\"We have stalked each other long enough!\"");
		say();
		UI_add_answer(["Are you The Trapper?", "bye"]);
	labelFunc0395_011D:
		converse (0) atend labelFunc0395_01C2;
		case "Are you The Trapper?" atend labelFunc0395_013A:;
		UI_remove_answer("Are you The Trapper?");
		message("\"Forgo the pretense, I am Hazard the Trapper as thou dost know well by now.\"");
		say();
		UI_add_answer("Murderer!");
	labelFunc0395_013A:
		case "Murderer!" atend labelFunc0395_015D:;
		UI_remove_answer("Murderer!");
		message("\"That charge is most unfair! The Gwani are merely animals! I kill them as I would a bear, or a leopard.\"* \"Their skins keep many a man warm when they venture into these icy regions. Why, I would kill a man if he dared to steal mine.\"* \"Aye, their skins are the most profitable, too.\"");
		say();
		UI_add_answer(["animals", "profit", "Gwani"]);
	labelFunc0395_015D:
		case "profit" atend labelFunc0395_0170:;
		UI_remove_answer("profit");
		message("\"Aye, the best skins I take are those I peel from those beasts while they still live. I have not killed a Gwani before skinning it in years, and I shan't stop till the last one is gone!\"");
		say();
	labelFunc0395_0170:
		case "animals" atend labelFunc0395_018A:;
		UI_remove_answer("animals");
		message("\"Trapping them is too easy. 'Tis a wonder they survive out here at all! Why, they are as docile as sheep!\"* \"A leopard at least is sport. It would sever mine arm if I gave it the chance. Slaughtering the Gwani is doing them a favor.\"");
		say();
		UI_add_answer("Stop the killing.");
	labelFunc0395_018A:
		case "Gwani" atend labelFunc0395_019D:;
		UI_remove_answer("Gwani");
		message("\"They provide me a fat living. Thou art daft to be concerned for the likes of them!\"* \"And if thou hast a plan for stopping me then I think thou shouldst leave now, lest I skin thee alive, too!\"");
		say();
	labelFunc0395_019D:
		case "Stop the killing." atend labelFunc0395_01AE:;
		message("\"No one tells me what I can and cannot kill! Prepare to join thy Gwani friends on my wall, Avatar.\"");
		say();
		Func09AD(item);
		abort;
	labelFunc0395_01AE:
		case "bye" atend labelFunc0395_01BF:;
		message("\"From the look in thine eye I can see that this is far from over. Truly this is farewell, Avatar.\"");
		say();
		Func09AD(item);
		abort;
	labelFunc0395_01BF:
		goto labelFunc0395_011D;
	labelFunc0395_01C2:
		break;
	labelFunc0395_01C3:
		return;
}

// Rotoluncia's Automaton allows xp on death patch
extern Func0809 0x809 ();
extern var getPoliteTitle 0x954 ();
extern var getAvatarName 0x953 ();
extern void delayedBark 0x97F (var npc, var bark, var delay);
extern var giveItemsToPartyMember 0x99B (var cont, var count, var shapenum, var quality, var framenum, var flag1, var flag2);

void Func0419 0x419 ()
{
	var var0000;
	var var0001;
	var var0002;
	var var0003;
	var var0004;
	var var0006;
	var var0007;

	if (!UI_get_item_flag(item, SI_ZOMBIE)) goto labelFunc0419_000F;
	Func0809();
	abort;
	labelFunc0419_000F:
		var0000 = getPoliteTitle();
		var0001 = UI_is_pc_female();
		var0002 = getAvatarName();
		if (!(event == DOUBLECLICK)) goto labelFunc0419_0052;
		UI_item_say(AVATAR, "@Excuse me...@");
		delayedBark(AUTO_MESSENGER, (("@At thy service, " + var0000) + "!@"), 2);
		UI_set_schedule_type(AUTO_MESSENGER, TALK);
	labelFunc0419_0052:
		if (!(event == PROXIMITY)) goto labelFunc0419_00DC;
		var0003 = UI_get_random(6);
		if (!(var0003 == 1)) goto labelFunc0419_0078;
		UI_item_say(AUTO_MESSENGER, "@Please leave...@");
	labelFunc0419_0078:
		if (!(var0003 == 2)) goto labelFunc0419_008C;
		UI_item_say(AUTO_MESSENGER, "@Rangers!@");
	labelFunc0419_008C:
		if (!(var0003 == 3)) goto labelFunc0419_00A0;
		UI_item_say(AUTO_MESSENGER, "@Leave!@");
	labelFunc0419_00A0:
		if (!(var0003 == 4)) goto labelFunc0419_00B4;
		UI_item_say(AUTO_MESSENGER, "@Beware!@");
	labelFunc0419_00B4:
		if (!(var0003 == 5)) goto labelFunc0419_00C8;
		UI_item_say(AUTO_MESSENGER, "@Do not touch that!@");
	labelFunc0419_00C8:
		if (!(var0003 == 6)) goto labelFunc0419_00DC;
		UI_item_say(AUTO_MESSENGER, "@Go quickly!@");
	labelFunc0419_00DC:
		if (!(event == STARTED_TALKING)) goto labelFunc0419_02DA;
		UI_run_schedule(AUTO_MESSENGER);
		UI_clear_item_say(AUTO_MESSENGER);
		UI_show_npc_face0(0xFED6, 0);
		if (!(!gflags[0xE9])) goto labelFunc0419_0150;
		if (!gflags[0xD7]) goto labelFunc0419_0116;
		message("\"Again we meet, ");
		message(var0000);
		message(". My mistress hath dispatched me to see if thou hast yet read the scroll she sent?\"");
		say();
		goto labelFunc0419_013D;
	labelFunc0419_0116:
		message("\"Pardon, ");
		message(var0000);
		message(". I bring thee greetings from my mistress, the sorceress Rotoluncia. This scroll is from her.\"");
		say();
		var0004 = giveItemsToPartyMember(AVATAR, 1, 0x2C3, 0x1F, 6, 12, true);
		gflags[0xD7] = true;
	labelFunc0419_013D:
		UI_add_answer(["Rotoluncia", "scroll", "servant"]);
		goto labelFunc0419_01C1;
	labelFunc0419_0150:
		var pos = UI_get_object_position(item);
		if (!((pos[X]  0x992) && ((pos[Y]  0x700))))) goto labelFunc0419_01AA;
		message("\"This is the manor of the Enchantress Rotoluncia! Thou canst not enter without permission!\"");
		say();
		UI_add_answer(["Rotoluncia"]);
		if (!gflags[0xEA]) goto labelFunc0419_01A7;
		UI_add_answer(["kidnap", "Where is she?"]);
	labelFunc0419_01A7:
		goto labelFunc0419_01C1;
	labelFunc0419_01AA:
		message("\"I must be about my duties.\"");
		say();
		delayedBark(item, "@Pardom me...@", 0);
		UI_set_schedule_type(item, WANDER);
		abort;
	labelFunc0419_01C1:
		UI_add_answer("bye");
	labelFunc0419_01C8:
		converse (0) atend labelFunc0419_02D9;
		case "Rotoluncia" atend labelFunc0419_01F0:;
		UI_remove_answer("Rotoluncia");
		message("\"My mistress commands many powerful and strange magics, and sits upon the Council of Mages.\"");
		say();
		if (!(!gflags[0xEA])) goto labelFunc0419_01EC;
		message("\"She is terrible to her enemies, but tolerant of those who aid her.\"");
		say();
		goto labelFunc0419_01F0;
	labelFunc0419_01EC:
		message("\"As thou now knowest, she is most terrible to those who do not bend to her will.\"");
		say();
	labelFunc0419_01F0:
		case "kidnap" atend labelFunc0419_0207:;
		UI_remove_answer("kidnap");
		message("\"I am forbidden to discuss this subject with thee!\"");
		say();
		var0006 = true;
	labelFunc0419_0207:
		case "Where is she?" atend labelFunc0419_021E:;
		UI_remove_answer("Where is she?");
		message("\"I must not tell! In fact, thou shouldst leave here at once.\"");
		say();
		var0006 = true;
	labelFunc0419_021E:
		case "scroll" atend labelFunc0419_0231:;
		message("\"'Tis not an ordinary scroll, but one of the magical variety. I assure thee that it is entirely free of harmful magic.\"");
		say();
		UI_remove_answer("scroll");
	labelFunc0419_0231:
		case "servant" atend labelFunc0419_0248:;
		message("\"The Mages of Moonshade are quite powerful, and have found the way to acquire servants such as myself.\"");
		say();
		message("\"My mistress says that automatons are more trustworthy, since we can neither be corrupted nor tortured.\"");
		say();
		UI_remove_answer("servant");
	labelFunc0419_0248:
		case "bye" atend labelFunc0419_02D6:;
		if (!gflags[0xEA]) goto labelFunc0419_025A;
		gflags[0xEB] = true;
	labelFunc0419_025A:
		if (!((!gflags[0xE9]) && (!gflags[0xEA]))) goto labelFunc0419_0285;
		UI_remove_npc_face0();
		delayedBark(AVATAR, "@Good day.@", 0);
		delayedBark(AUTO_MESSENGER, "@Do not forget the scroll.@", 2);
		goto labelFunc0419_02D3;
	labelFunc0419_0285:
		if (!(gflags[0xEA] && var0006)) goto labelFunc0419_02C5;
		message("\"Thou dost look at me oddly... I think I have said too much!\"");
		say();
		message("\"Now I must kill thee...\"");
		say();
		UI_set_alignment(AUTO_MESSENGER, 3);
		delayedBark(AUTO_MESSENGER, "@Must kill!@", 0);
		UI_set_schedule_type(AUTO_MESSENGER, IN_COMBAT);
		UI_set_oppressor(AVATAR, AUTO_MESSENGER);
		abort;
		goto labelFunc0419_02D3;
	labelFunc0419_02C5:
		message("\"If thou dost not leave quickly, I must call the Rangers!\"");
		say();
		UI_set_schedule_type(AUTO_MESSENGER, TEND_SHOP);
	labelFunc0419_02D3:
		goto labelFunc0419_02D9;
	labelFunc0419_02D6:
		goto labelFunc0419_01C8;
	labelFunc0419_02D9:
		break;
	labelFunc0419_02DA:
		if (!((event == DEATH) && UI_get_item_flag(item, SI_TOURNAMENT))) goto labelFunc0419_0334;
		if (!(gflags[0xEA] && (!UI_get_item_flag(ROTOLUNCIA, DEAD)))) goto labelFunc0419_031D;
		UI_show_npc_face0(0xFED6, 0);
		message("\"Rotoluncia shall avenge my loss...\"");
		say();
		gflags[0xEB] = true;
		UI_set_alignment(ROTOLUNCIA, 3);
		UI_remove_npc_face0();
	labelFunc0419_031D:
		UI_clear_item_flag(AUTO_MESSENGER,SI_TOURNAMENT);
		UI_reduce_health(AUTO_MESSENGER, 55, 1);
	labelFunc0419_0334:
		return;
}
Edit: changed GoblinKing

Re: The call for SI Fixes

Posted: Thu Jun 14, 2012 10:10 am
by Rabenrecht
From my recent experience:
Lydia (the tatoo lady) and
the Goblins surrounding the Fawn Tower do not give exp.

Re: The call for SI Fixes

Posted: Thu Jun 14, 2012 2:09 pm
by Malignant Manor
Oops, I had forgotten the invisible pikeman.

Gobl19-Gobl23 (Npc 119-123) call Func09B7() on death; Which sets the death flag before creating a goblin body and setting the tournament flag

Code: Select all

	UI_set_item_flag(item, Death);
	UI_remove_npc(item);
	var0007 = UI_create_new_object(0x019E); // body
	if (!var0007) goto labelFunc09B7_014E;
	UI_set_item_frame(var0007, 4);
	UI_set_item_flag(var0007, SI_TOURNAMENT);
Lydia (0x448) when in tournament mode calls UI_reduce_health(npcnum, 0x0032, 0x0000) and this is how I found the others.


New functions that need fixed
0xE4 invisible pikeman (pikeman id E) // why the heck do all the other innocent pikemen give xp, it should be the other way around)
0x41F Rotoluncia
0x448 Lydia
0x42C Selina
0x439 Kalen //assassin
0x455 Auto1 // attacks party in gargoyle city arena
0x457 Auto2 // attacks party in gargoyle city arena
0x45C Auto3 // attacks party in gargoyle city arena
0x45D Auto4 // attacks party in gargoyle city arena
0x4CB Hench2 // attacks avatar, ambush at bank? in dead room
0x4CC Hench3 // attacks avatar, ambush at bank? in dead room
0x4DE Death Knight // tries to kill you and Stefano
0x9B7 Gobl19-Gobl23 // tower near fawn


Probably needs fixed
0x103 ranger // this kills id 1 (Ernesto) without giving xp (if all other rangers are good then this should be enabled for all of them)

Should be fine
0x402 Shamino
0x6C4 Selena // teleports away

Not sure
0x445 Marsten // if he doesn't attack you (or doesn't hav hostile alignment) the Avatar would be killing in cold blood but he explains his evil plan in death speech
0x44D Spektor // same as Marsten

Re: The call for SI Fixes

Posted: Tue Jul 31, 2012 3:36 am
by Malignant Manor
There's a bug in the original usecode where only one jawbone is recognized. This happens with the the iris door and the gates (function 0x7df).

Tracker 3551558 has a saved game for the original engine that shows this happening.

(I noticed this a long time ago and forgot to ever mention it until this bug report came up.)

Re: The call for SI Fixes

Posted: Tue Jul 31, 2012 8:57 pm
by Mortegro
Mortegro and Bucia do not acknowledge Rotoluncia's death in their dialogues.
This is especially glaring with Mortegro since he takes over her seat in the
council.

That glitch still exist in my game and i have the updated exult

Another glitch im having issue with is Petra Body Swipe

Re: The call for SI Fixes

Posted: Wed Aug 01, 2012 3:01 am
by Dominus
Petra body seitch - read http://exult.info/forum/viewtopic.php?p=335557#p335557

And do Mortego and Buccia normally aknowledge Rotus death? If yes, this is an actual Exult bug and not something for Si Fixes ;)
So please bug report and such ;)

Re: The call for SI Fixes

Posted: Wed Aug 01, 2012 10:59 am
by William
I recently played through SI last week, and I didn't have trouble in changing bodies with Petra.

I don't think that Mortegro or Bucia ever acknowledge Rotuluncia's death in the original either. You never have cause to ask Mortegro about her, but Bucia is the town's information person, so perhaps she could mention it.

I'd really enjoy if some of the minor things were able to be fixed, such as npc activities like eating at inn/waitering, reliably turning on and off light sources, and fixing spent light sources. These are the details that always wowed me about the game, and it just isn't the same when diners are sitting in the middle of the room, or cloaks pile up infinitely at the weaver.

Re: The call for SI Fixes

Posted: Wed Aug 01, 2012 12:24 pm
by Jaesun
I just loaded up the original via DOSBox, as I have a number of saves and both Bucia and Mortegro never acknowledge Rotuluncia's death. Apparently news move slow there.

Re: The call for SI Fixes

Posted: Wed Aug 01, 2012 12:51 pm
by Dominus
William, this thread is about fixes/enhancements to the original. Things that Exult doesn't do correctly yet (like the schedules waiting/eating/sitting) belong elsewhere ;)

Re: The call for SI Fixes

Posted: Sat Aug 11, 2012 4:24 am
by Mortegro
I'll do another play through of the game and see if these two bugs repeat themselfs.

Re: The call for SI Fixes

Posted: Mon Jun 20, 2016 4:56 am
by Knight Captain
With the teleported lab apparatus, I was under the impression that it was originally Erstam's, but Vasculio stole it from it from him. This is in line with the theft of Serpent Teeth. Ducio may have repaired it for Vasculio at some point.

Re: The call for submissions for the

Posted: Mon Jun 20, 2016 6:00 am
by Knight Captain
The existing conversation functions about the hand for Mortegro and Erstam exist but can't be reached without manually setting the flag.

Re: The call for submissions for the

Posted: Thu Jun 23, 2016 1:54 am
by Knight Captain
From looking at the Usecode related to the dragon's riddles, there are a number of misspellings: "dificult" "rythym" "afterall" "tresure" and perhaps others. The non-standard "fiercesome" fits well though, and "daresay" is used correctly.

Re: The call for submissions for the

Posted: Thu Jun 23, 2016 10:49 pm
by Knight Captain
Would it make sense to reorder the lost items scroll so the text follows the logical order of the party rejoining?

Re: The call for submissions for the

Posted: Wed Jul 06, 2016 10:28 pm
by Knight Captain

Re: The call for submissions for the

Posted: Thu Jul 07, 2016 1:35 pm
by Knight Captain

Re: The call for submissions for the

Posted: Tue Jul 12, 2016 3:16 pm
by Knight Captain
I've got the following ready in my Github fork:

items\scroll.uc has been respaced and reordered to reflect the order the companions rejoin the party.
npcs\delin.uc has been added, and after talking to Jendon about daemon artifacts Delin can now be asked about Batlin.
npcs\edrin.uc has been added, and his response about his dreams / Siranush will change if you have completed the Dream Realm.
npcs\neyobi.uc has been added, and she will now have a schedule once cured and woken up by double-clicking on her.

Usecode.uc in the sifixes\src folder needs to be updated too.
Mortegro does not acknowledge that I have the severed hand in my inventory when I speak to him about it.
I was not able to recreate this problem with Mortegro.

Re: The call for submissions for the

Posted: Wed Jul 13, 2016 4:25 pm
by Knight Captain
Usecode.uc has been updated in the Edrin patch branch.

Re: The call for submissions for the

Posted: Thu Jul 14, 2016 12:07 am
by Knight Captain
A workaround for the imperfect code of Kylista handling the breastplate has been created as well. It was much more of a pain than I anticipated.

Re: The call for submissions for the

Posted: Thu Jul 14, 2016 1:00 am
by Knight Captain
In addition to the ability to walk into the Fawn trial with weapons in hand, shouldn't the three spawned guards turn to face the Oracle when everyone else does? And shouldn't the gatekeeper guard always be facing the defendant?