• New Horizons on Maelstrom
    Maelstrom New Horizons


    Visit our website www.piratehorizons.com to quickly find download links for the newest versions of our New Horizons mods Beyond New Horizons and Maelstrom New Horizons!

Sao Feng side mission bug

JackSparrow1

Powder Monkey
I have a bug in Sao Feng side mission. After I save his bodguards and priest I go to Puerto Rico and leave the priest and questbook (and your walktrough) says I must go to Jamaica and speak to father Bernard. I do it but there is only standard priest conversation, nothing about this mission. What is wrong with this?
 
Sometimes things just do not trigger. :shrug This can be caused by other things that happen in the game

Have you gone back to a save before you arrive in Jamaica and tried again?

Or a save when you arrive in Jamaica & fast travel to the church - so that you talk to Father Bernard without talking to any other people.

Do you have any error logs from where the dialog with Father Bernard fails. ?

:cheers
 
Same issue as above. Tried reloading and playing again from a further save (carrying letter from Jamaica to Puerto Rico). Sinking or taking over Crimson Blood doesn't matter - both lead to the same problem. Might be linked to the fact that the Ammand quest was done before starting Sao Feng's or the trigger for the Maltese Knight leaving - is he supposed to disappear before or after talking to Bernard for the final time? Mine stays put the whole time. And are the 2 bodyguard women supposed to follow you around all the time without even being passengers (they even enter the church)?

The conversation with Bernard doesn't generate any relevant error logs. Any idea how to bypass this one point in the storyline?
 
Same issue as above. Tried reloading and playing again from a further save (carrying letter from Jamaica to Puerto Rico). Sinking or taking over Crimson Blood doesn't matter - both lead to the same problem. Might be linked to the fact that the Ammand quest was done before starting Sao Feng's or the trigger for the Maltese Knight leaving - is he supposed to disappear before or after talking to Bernard for the final time? Mine stays put the whole time. And are the 2 bodyguard women supposed to follow you around all the time without even being passengers (they even enter the church)?

The conversation with Bernard doesn't generate any relevant error logs. Any idea how to bypass this one point in the storyline?


If you have captured the Crimson Blood & the Maltese Knight (Jaoquin de masse ) is a companion - you have given him either the Crimson Blood or the Black Pearl to sail.

When you arrive back in Port Royale Jamaica after freeing Sao Fengs bodyguards and the Priest and returning priest to San Juan Church - Jaoquin de masse should sail away with the ship you gave him - you should talk to yourself on the jetty saying :

"What!? That looks like the Blood sailing away. DAMN YOU MASSE!",

and the Quest book should update with an entry under the Ship Stolen header. - Jaoquin de masse should be removed from your passengers / officers.

If Jaoquin de masse does not have a ship then I think he talks to you and leaves when you arrive on Port Royale jetty.


Then you go to see Father Bernard in Port Royale church and the soldiers should appear in the church.

I am not sure if Sao Fengs Bodyguards follow you into the church or not - but they should stay with you until you go back to Sao Feng and return them to him . :yes


in the file both_reaction.c this code sets up the dialog with Father Bernard:--->>
Code:
case "return_priest_complete2":
pchar.quest.ANIMISTS = "completed";

//if (IsPassenger(characterFromID("Jaoquin de masse")) || IsOfficer(characterFromID("Jaoquin de masse")))
if (!LAi_IsDead(characterFromID("Jaoquin de masse")) || !LAi_IsDead(characterFromID("Mergildo Hurtado")))
{
pchar.quest.Jaoquin_back_church.win_condition.l1 = "location";
pchar.quest.Jaoquin_back_church.win_condition.l1.location = "Redmond_Church";
pchar.quest.Jaoquin_back_church.win_condition = "Jaoquin_back_church";

pchar.quest.ship_moor.win_condition.l1 = "location";
pchar.quest.ship_moor.win_condition.l1.location = "Redmond_port";
pchar.quest.ship_moor.win_condition = "Ship_moor";

pchar.quest.ship_moor1.win_condition.l1 = "location";
pchar.quest.ship_moor1.win_condition.l1.location = "Redmond_Shore_01";
pchar.quest.ship_moor1.win_condition = "Ship_moor1";

pchar.quest.ship_moor2.win_condition.l1 = "location";
pchar.quest.ship_moor2.win_condition.l1.location = "Redmond_Shore_02";
pchar.quest.ship_moor2.win_condition = "Ship_moor2";
}

pchar.quest.return_priest_complete3.win_condition.l1 = "ExitFromLocation";
pchar.quest.return_priest_complete3.win_condition.l1.location = "Muelle_Church";
pchar.quest.return_priest_complete3.win_condition = "return_priest_complete3";
break;

case "return_priest_complete3":
changeCharacterAddress(characterfromID("padre Domingues"), "Muelle_church", "goto11");
LAi_SetStayType(characterFromID("padre Domingues"));
Characters[GetCharacterIndex("padre Domingues")].dialog.CurrentNode  = "First time";
break;

which is when you return the Priest to the San Juan Church & talk to him there.

it sets up this code in Father Bernard_dialog.c

Code:
if (CheckQuestAttribute("ANIMISTS", "completed") && npchar.quest.ANIMISTS != "completed")
{
dialog.snd = "Voice\FATB\FATB009";
dialog.text = DLG_TEXT[29];
link.l1 = DLG_TEXT[30];
link.l1.go = "destroyed_sekt";
}



case "destroyed_sekt":
if (CheckAttribute(Pchar, "ANIMISTS") == "women_returned")
{
if(AUTO_SKILL_SYSTEM)
{
AddPartyExpChar(pchar, "Leadership", 7000);
AddPartyExpChar(pchar, "Sneak", 70);
}
else { AddPartyExp(pchar, 7000); }
//PlayStereoSound("INTERFACE\took_item.wav");
//AddMoneyToCharacter(pchar, 15000);
dialog.snd = "Voice\FATB\FATB010";
dialog.text = DLG_TEXT[168];
link.l1 = DLG_TEXT[35];
link.l1.go = "exit";
npchar.quest.ANIMISTS = "completed";
CloseQuestHeader("Sao Feng");
addDialogExitQuest("guards_in_church");
}
else
{
if(AUTO_SKILL_SYSTEM)
{
AddPartyExpChar(pchar, "Leadership", 7000);
AddPartyExpChar(pchar, "Sneak", 70);
}
else { AddPartyExp(pchar, 7000); }
//PlayStereoSound("INTERFACE\took_item.wav");
//AddMoneyToCharacter(pchar, 15000);
dialog.snd = "Voice\FATB\FATB010";
dialog.text = DLG_TEXT[33];
link.l1 = DLG_TEXT[34];
link.l1.go = "exit";
npchar.quest.ANIMISTS = "completed";
//CloseQuestHeader("animists");
addDialogExitQuest("guards_in_church");
}
break;

which means the dialog with Father Bernard should be


"No. Let's talk about something else.",
"There's more - my men and I have destroyed the sect.",

followed by either

"The Lord has provided us with a miracle! However I have heard how you delt with my first request and can not have you getting away with impersonating a man of god.",

"I suppose you have called the guards, I will escape for I'm Captain Jack Sparrow",

or

"The Lord has provided us with a miracle! However I have heard how you delt with my first request and can not have you getting away with impersinating a man of god, also it appears you still have the women with you. I think you are the kidnapper!",

"I'm so sorry but I'm afraid I have to get to Singapore to return the women and you can't stop me. (THINKS: Damn Ammand the Corsair must have told him).",

and then the soldiers should arrive

The conversation with Bernard doesn't generate any relevant error logs. Any idea how to bypass this one point in the storyline?

Have you tried going & talking to Sao Feng after talking to Father Bernard - and see if the story continues ( SF bodyguards leave you etc )

:cheers
 
Have you tried going & talking to Sao Feng after talking to Father Bernard - and see if the story continues ( SF bodyguards leave you etc )

Yeah, tried it directly after seeing the priest in San Juan, then after trying Bernard's (non-plot advancing standard priest) dialogue and even before heading to San Juan to be safe. No dice. Sao Feng semms to have a dialogue set of a governor (offering amnesty, stating international relations etc.) and that's it.

I think the problem might be with the Maltese Knight - from what you said, he should leave upon disembarking in Port Royal - I'm not getting this event no matter what (no jetty self-dialogue and his ship/himself is still in my ships/passangers list).

I'm not familiar with these particular scripting mechanics, but from what see in the fragment you've posted - the dialogue with Bernard, which I'm not getting is dependand solely on the current dialogue node being equal to "destroyed_sekt". This value doesn't seem to be set in the previous snippet (from both_reactions.c) so it must be set somewhere else - perhaps in the event with the Maltese Knight leaving? As I said this is also something that never happens for me, regardless of what I do with the Crimson Blood.

One more thing that I've noticed from this code is that after seeing the Spanish priest along with the women, he is supposed to have some dialogue options available (standard priest, I'm guessing). I however, I'm unable to talk to him at all after the initial exchange ("thanks for rescuing me and the ladies" etc.) and he just stands there next to the exit. Not sure if this has anything to do with the actual problem, but at this point I'm considering any inconsistencies.
 
I'm not familiar with these particular scripting mechanics, but from what see in the fragment you've posted - the dialogue with Bernard, which I'm not getting is dependand solely on the current dialogue node being equal to "destroyed_sekt". This value doesn't seem to be set in the previous snippet (from both_reactions.c) so it must be set somewhere else - perhaps in the event with the Maltese Knight leaving? As I said this is also something that never happens for me, regardless of what I do with the Crimson Blood.

One more thing that I've noticed from this code is that after seeing the Spanish priest along with the women, he is supposed to have some dialogue options available (standard priest, I'm guessing). I however, I'm unable to talk to him at all after the initial exchange ("thanks for rescuing me and the ladies" etc.) and he just stands there next to the exit. Not sure if this has anything to do with the actual problem, but at this point I'm considering any inconsistencies.


If you want to have a look at the code the files are in PROGRAM \ storyline \ LegendJackSparrow \ Quest --- for both_reaction.c ( this contains all the Pirate Lord Side-quests -- just do a search for sao Feng -- to find the correct section.

All the dialog code files are in PROGRAM \ storyline \ LegendJackSparrow \ DIALOGS - this contains all the dialog code files for each character --- the actual dialog text is in the h files in the ENGLISH sub-folder.


The Maltese Knight did cause problems when the quest was first writtten - but I thought they had all been solved ( unfortunately the person who wrote the quest has not been very active here recently. ) :shrug

If you want to see the original discussion about problems with Jaoquin de masse have a look at the posts in this thread and see if they help

---->>>> http://forum.piratesahoy.net/index.php/topic/15168-jack-sparrow-sao-feng-sidequest-crimson-blood-boarding/page__view__findpost__p__353707


All help in fixing this or any other bugs that are found is appreciated. :yes

:nk
 
If you want to see the original discussion about problems with Jaoquin de masse have a look at the posts in this thread and see if they help

---->>>> http://forum.pirates...post__p__353707

Alas this thread mainly deals with difficulties regarding boarding the Blood - not really my issue. The fight in the captain's cabin happens sometimes, but generally this part seems managable. Apart from de Masse's dialogue terminating eralier than I can expect from the script, everything (including setting him as captain) works.

Anyway I've managed to (somewhat) resolve the issue by editing both_reactions.c. I'll explain it in the following paragraphs, though don't expect an elegant solution - this is a pretty dirty hack that gets me Bernard's dialogue and allows for the quest to finish. Note that de Masse STILL doesn't leave on Jamaica and stays as an officer. This might be a separate issue or something too convoluted for my sleep-deprived brain to grasp right now on a short time budget. Oh well, guess there are more violent ways to get rid of him ;).

In Bernard's dialogue file I've hunted down the "destroyed_sekt" value I've mentioned before. Turns out it is triggered like this :

if (CheckQuestAttribute("ANIMISTS", "completed") && npchar.quest.ANIMISTS != "completed")
{
dialog.snd = "Voice\FATB\FATB009";
dialog.text = DLG_TEXT[29];
link.l1 = DLG_TEXT[30];
link.l1.go = "destroyed_sekt";
}

So in order to trigger it an attribute "ANIMISTS" needs to be equal to "completed". I couldn't really find the piece of code that does this in the storyline, since there's a lot of what I'd call "dirty coding" in there. but there's an interesting snippet in both_reactions.c :

case "destroy_ANIMISTS_complete":
//pchar.quest.ANIMISTS = "completed";
pchar.quest.ANIMISTS = "comp";
if(AUTO_SKILL_SYSTEM)
{
AddPartyExpChar(pchar, "Leadership", 50000);
AddPartyExpChar(pchar, "Sneak", 5000);
}
else { AddPartyExp(pchar, 50000); }
ChangeCharacterReputation(pchar, 10);
//pchar.reputation = makeint(pchar.reputation) +10;
//GiveItem2Character(pchar, "blade20");

LAi_QuestDelay("destroy_ANIMISTS_complete_2", 6.0);

See the second line? That's the piece I've been looking for! But for some reason it's commented out and the attribute replaced with "comp"...well that's no fun at all. Since the quest seems to work for other people then obviously the value "completed" has to be set *somewhere*...but I really couldn't be bothered to look for it any longer and even if I found it a solution would probably involve some sort of major restructoring of the script flow control - again no fun at all. So I just changed the fragment to :

case "destroy_ANIMISTS_complete":
pchar.quest.ANIMISTS = "completed"; //BRUTE-FORCE BYPASS
//pchar.quest.ANIMISTS = "comp"; //BRUTE-FORCE BYPASS
if(AUTO_SKILL_SYSTEM)
{
AddPartyExpChar(pchar, "Leadership", 50000);
AddPartyExpChar(pchar, "Sneak", 5000);
}
else { AddPartyExp(pchar, 50000); }
ChangeCharacterReputation(pchar, 10);
//pchar.reputation = makeint(pchar.reputation) +10;
//GiveItem2Character(pchar, "blade20");

LAi_QuestDelay("destroy_ANIMISTS_complete_2", 6.0);

In other words the attribute "completed is now assigned after beating the animist boss. This slightly screws up Dominuguez's second "imprisoned" dialogue but it has no bearing on the storyline. Afterwards everything goes as planned (aside de Masse not leaving - haven't determined if it's related, but than again, he wasn't going anywhere even before I made the change...)

For anyone currently seeing the Bernard dialogue issue my advice is - force the quest to advance by replacing the snipped I've posted. Do this before defeating the animist boss in the cave, as it's this event that triggers the replaced code. After finishing the quest, close the game and change the code fragment back to the original, just to be safe (alhough it's unlikely that this one attribute would mess up other things).

I'd try to look deeper into this problem and do it properly, but it's really a pain to debug stuff without any proper scripts / tools to see what's going on with the values / line executions while testing. How the hell do you guys debug the "bigger" things? By playing and seeing the results / error logs? That's a freaking nightmare...

Anyway, thanks for the tips, Talisman.
 
So in order to trigger it an attribute "ANIMISTS" needs to be equal to "completed". I couldn't really find the piece of code that does this in the storyline, since there's a lot of what I'd call "dirty coding" in there. but there's an interesting snippet in both_reactions.c :

case "destroy_ANIMISTS_complete":
//pchar.quest.ANIMISTS = "completed";
pchar.quest.ANIMISTS = "comp";
if(AUTO_SKILL_SYSTEM)
{
AddPartyExpChar(pchar, "Leadership", 50000);
AddPartyExpChar(pchar, "Sneak", 5000);
}
else { AddPartyExp(pchar, 50000); }
ChangeCharacterReputation(pchar, 10);
//pchar.reputation = makeint(pchar.reputation) +10;
//GiveItem2Character(pchar, "blade20");

LAi_QuestDelay("destroy_ANIMISTS_complete_2", 6.0);

See the second line? That's the piece I've been looking for! But for some reason it's commented out and the attribute replaced with "comp"...well that's no fun at all. Since the quest seems to work for other people then obviously the value "completed" has to be set *somewhere*...but I really couldn't be bothered to look for it any longer and even if I found it a solution would probably involve some sort of major restructoring of the script flow control - again no fun at all. So I just changed the fragment to :

case "destroy_ANIMISTS_complete":
pchar.quest.ANIMISTS = "completed"; //BRUTE-FORCE BYPASS
//pchar.quest.ANIMISTS = "comp"; //BRUTE-FORCE BYPASS
if(AUTO_SKILL_SYSTEM)
{
AddPartyExpChar(pchar, "Leadership", 50000);
AddPartyExpChar(pchar, "Sneak", 5000);
}
else { AddPartyExp(pchar, 50000); }
ChangeCharacterReputation(pchar, 10);
//pchar.reputation = makeint(pchar.reputation) +10;
//GiveItem2Character(pchar, "blade20");

LAi_QuestDelay("destroy_ANIMISTS_complete_2", 6.0);

In other words the attribute "completed is now assigned after beating the animist boss. This slightly screws up Dominuguez's second "imprisoned" dialogue but it has no bearing on the storyline. Afterwards everything goes as planned (aside de Masse not leaving - haven't determined if it's related, but than again, he wasn't going anywhere even before I made the change...)

For anyone currently seeing the Bernard dialogue issue my advice is - force the quest to advance by replacing the snipped I've posted. Do this before defeating the animist boss in the cave, as it's this event that triggers the replaced code. After finishing the quest, close the game and change the code fragment back to the original, just to be safe (alhough it's unlikely that this one attribute would mess up other things).

I'd try to look deeper into this problem and do it properly, but it's really a pain to debug stuff without any proper scripts / tools to see what's going on with the values / line executions while testing. How the hell do you guys debug the "bigger" things? By playing and seeing the results / error logs? That's a freaking nightmare...

Anyway, thanks for the tips, Talisman.


I have checked the both_reaction.c file & the pchar.quest.ANIMISTS = "completed";

that is commented out here

Code:
case "destroy_ANIMISTS_complete":
//pchar.quest.ANIMISTS = "completed";
pchar.quest.ANIMISTS = "comp";
if(AUTO_SKILL_SYSTEM)
{
AddPartyExpChar(pchar, "Leadership", 50000);
AddPartyExpChar(pchar, "Sneak", 5000);
}
else { AddPartyExp(pchar, 50000); }
ChangeCharacterReputation(pchar, 10);
//pchar.reputation = makeint(pchar.reputation) +10;
//GiveItem2Character(pchar, "blade20");

LAi_QuestDelay("destroy_ANIMISTS_complete_2", 6.0);

is reinstated ( actioned ?) here - I think further on in the quest :-->>

Code:
case "return_priest_complete3":
pchar.quest.ANIMISTS = "completed";

//if (IsPassenger(characterFromID("Jaoquin de masse")) || IsOfficer(characterFromID("Jaoquin de masse")))
if (!LAi_IsDead(characterFromID("Jaoquin de masse")) || !LAi_IsDead(characterFromID("Mergildo Hurtado")))
{
pchar.quest.Jaoquin_back_church.win_condition.l1 = "location";
pchar.quest.Jaoquin_back_church.win_condition.l1.location = "Redmond_Church";
pchar.quest.Jaoquin_back_church.win_condition = "Jaoquin_back_church";

pchar.quest.ship_moor.win_condition.l1 = "location";
pchar.quest.ship_moor.win_condition.l1.location = "Redmond_port";
pchar.quest.ship_moor.win_condition = "Ship_moor";

pchar.quest.ship_moor1.win_condition.l1 = "location";
pchar.quest.ship_moor1.win_condition.l1.location = "Redmond_Shore_01";
pchar.quest.ship_moor1.win_condition = "Ship_moor1";

pchar.quest.ship_moor2.win_condition.l1 = "location";
pchar.quest.ship_moor2.win_condition.l1.location = "Redmond_Shore_02";
pchar.quest.ship_moor2.win_condition = "Ship_moor2";
}

pchar.quest.return_priest_complete4.win_condition.l1 = "ExitFromLocation";
pchar.quest.return_priest_complete4.win_condition.l1.location = "Muelle_Church";
pchar.quest.return_priest_complete4.win_condition = "return_priest_complete4";
break;

What the --- pchar.quest.ANIMISTS = "comp" --- is there for I don't know -- & I can't find a link to it. :shrug

How the hell do you guys debug the "bigger" things? By playing and seeing the results / error logs? That's a freaking nightmare...


:yes

Any suggestions for making this easier will be gratefully received. :drunk
 
is reinstated ( actioned ?) here - I think further on in the quest :-->>

Yeah, after getting some sleep I spared another 10 min. and noticed this as well. The way these quest branches activate and their naming conventions are a bit to non-intuitive for my programming tastes. In any case, from the final conversation with Dominiguez my script flow seems to go to some branch called "return_priest_complete2" which again I couldn't locate in the script. It's either a dead / not completed branch or the author intended to go to "return_priest_complete3" which, unlike it's predecessor sets up things correctly and both enables Bernard's dialogue as well as de Masse's "departure". In light of this I propose another solution that I believe is wholly superior to the previous one :

in padre Dominigues_dialogue.c (\PROGRAM\Storyline\LegendJackSparrow\dialogs) :
case "Thank_You":
dialog.text = DLG_TEXT[143];
link.l1 = DLG_TEXT[144];
link.l1.go = "exit";
AddDialogExitQuest("return_priest_complete2");
break;

Change this fragment to :

case "Thank_You":
dialog.text = DLG_TEXT[143];
link.l1 = DLG_TEXT[144];
link.l1.go = "exit";
AddDialogExitQuest("return_priest_complete3"); // FIX - ORIGINAL VALUE : "return_priest_complete2"
break;

This is activated after I see Dominiguez for the final time and then everything plays out correctly for me including de Masse leaving with or without the Blood, after speaking to Bernard.

Not sure if this can be treated as a proper bugfix, since there's always the possibility that it could screw things up for people who previously had no issues with this quest. For now I reccomend this only for those with problems like mine (Bernard not advancing plot, de Masse not leaving). If anyone ever spares the time for an in depth analysis of how this effects the bigger picture, maybe it could be confirmed if this is the proper way to do it or not. I for one am satisfied with the result, can't really expect much more after 15 min. of work on someone else's rather dirty code, while not really familiar with the whole mod structure ;).

Any suggestions for making this easier will be gratefully received.

I was actually hoping you guys have some decent tools at your disposal when writing these scripts ;). Not much I can suggest right now, since such "addon" interpreted technologies are always a pain to debug. It would probably be feasible to write a whole framework of scripts for displaying most of the debug info that a decent dev env does (at least current script line scecution status, values of node structutres etc.), maybe re-using the GUI interfaces already developed to show this in a convenient way. This however is not something I could write "of the top of my mind" without getting deeply involved with the fundamentals of how the mod works - low-level dirty deeds in other words ;). I'm pretty convinced Akella had something like this. It would be madness to make their game designers work without that. Why not try pestering them about this for a bit? ;)
 
is reinstated ( actioned ?) here - I think further on in the quest :-->>

Yeah, after getting some sleep I spared another 10 min. and noticed this as well. The way these quest branches activate and their naming conventions are a bit to non-intuitive for my programming tastes. In any case, from the final conversation with Dominiguez my script flow seems to go to some branch called "return_priest_complete2" which again I couldn't locate in the script. It's either a dead / not completed branch or the author intended to go to "return_priest_complete3" which, unlike it's predecessor sets up things correctly and both enables Bernard's dialogue as well as de Masse's "departure". In light of this I propose another solution that I believe is wholly superior to the previous one :

in padre Dominigues_dialogue.c (\PROGRAM\Storyline\LegendJackSparrow\dialogs) :
case "Thank_You":
dialog.text = DLG_TEXT[143];
link.l1 = DLG_TEXT[144];
link.l1.go = "exit";
AddDialogExitQuest("return_priest_complete2");
break;

Change this fragment to :

case "Thank_You":
dialog.text = DLG_TEXT[143];
link.l1 = DLG_TEXT[144];
link.l1.go = "exit";
AddDialogExitQuest("return_priest_complete3"); // FIX - ORIGINAL VALUE : "return_priest_complete2"
break;

This is activated after I see Dominiguez for the final time and then everything plays out correctly for me including de Masse leaving with or without the Blood, after speaking to Bernard.

Not sure if this can be treated as a proper bugfix, since there's always the possibility that it could screw things up for people who previously had no issues with this quest. For now I reccomend this only for those with problems like mine (Bernard not advancing plot, de Masse not leaving). If anyone ever spares the time for an in depth analysis of how this effects the bigger picture, maybe it could be confirmed if this is the proper way to do it or not. I for one am satisfied with the result, can't really expect much more after 15 min. of work on someone else's rather dirty code, while not really familiar with the whole mod structure ;).


Having looked at it --- I think this is a proper bug-fix :--->>>

The file both_reaction.c seems to have been changed for some reason

In Build 14 Beta 1 Patch 6 the code is

Code:
case "return_priest_complete":
DoReloadCharacterToLocation("Muelle_Church", "reload", "reload1");
changeCharacterAddressGroup(characterfromID("padre Domingues"), "Muelle_Church", "goto", "goto1");
LAi_SetActorType(characterFromID("padre Domingues"));
LAi_ActorDialog(characterFromID("padre Domingues"), pchar, "", 2.0, 1.0);
characters[GetCharacterIndex("padre Domingues")].dialog.currentnode = "Thank_You";

LAi_ActorFollowEverywhere(characterFromID("Sao Feng's Body1"), "", 60.0);
LAi_ActorFollowEverywhere(characterFromID("Sao Feng's Body2"), "", 60.0);

AddQuestRecord("Sao Feng", 41);
//CloseQuestHeader("Sao Feng");
break;

case "return_priest_complete2":
pchar.quest.ANIMISTS = "completed";

//if (IsPassenger(characterFromID("Jaoquin de masse")) || IsOfficer(characterFromID("Jaoquin de masse")))
if (!LAi_IsDead(characterFromID("Jaoquin de masse")) || !LAi_IsDead(characterFromID("Mergildo Hurtado")))
{
pchar.quest.Jaoquin_back_church.win_condition.l1 = "location";
pchar.quest.Jaoquin_back_church.win_condition.l1.location = "Redmond_Church";
pchar.quest.Jaoquin_back_church.win_condition = "Jaoquin_back_church";

pchar.quest.ship_moor.win_condition.l1 = "location";
pchar.quest.ship_moor.win_condition.l1.location = "Redmond_port";
pchar.quest.ship_moor.win_condition = "Ship_moor";

pchar.quest.ship_moor1.win_condition.l1 = "location";
pchar.quest.ship_moor1.win_condition.l1.location = "Redmond_Shore_01";
pchar.quest.ship_moor1.win_condition = "Ship_moor1";

pchar.quest.ship_moor2.win_condition.l1 = "location";
pchar.quest.ship_moor2.win_condition.l1.location = "Redmond_Shore_02";
pchar.quest.ship_moor2.win_condition = "Ship_moor2";
}

pchar.quest.return_priest_complete3.win_condition.l1 = "ExitFromLocation";
pchar.quest.return_priest_complete3.win_condition.l1.location = "Muelle_Church";
pchar.quest.return_priest_complete3.win_condition = "return_priest_complete3";
break;

case "return_priest_complete3":
changeCharacterAddress(characterfromID("padre Domingues"), "Muelle_church", "goto11");
LAi_SetStayType(characterFromID("padre Domingues"));
Characters[GetCharacterIndex("padre Domingues")].dialog.CurrentNode  = "First time";
break;

case "Ship_moor":
pchar.location.from_sea = "Redmond_port";
break;

case "Ship_moor1":
pchar.location.from_sea = "Redmond_Shore_01";
break;

case "Ship_moor2":
pchar.location.from_sea = "Redmond_Shore_02";
break;


However in Build 14 Beta 1 Patch 7 onwards the code is changed to:-


Code:
case "return_priest_complete":
DoReloadCharacterToLocation("Muelle_Church", "reload", "reload1");
changeCharacterAddressGroup(characterfromID("padre Domingues"), "Muelle_Church", "goto", "goto1");
LAi_SetActorType(characterFromID("padre Domingues"));
LAi_ActorDialog(characterFromID("padre Domingues"), pchar, "", 2.0, 1.0);
characters[GetCharacterIndex("padre Domingues")].dialog.currentnode = "Thank_You";

LAi_ActorFollowEverywhere(characterFromID("Sao Feng's Body1"), "", 60.0);
LAi_ActorFollowEverywhere(characterFromID("Sao Feng's Body2"), "", 60.0);

AddQuestRecord("Sao Feng", 41);
//CloseQuestHeader("Sao Feng");
break;

case "return_priest_complete3":
pchar.quest.ANIMISTS = "completed";

//if (IsPassenger(characterFromID("Jaoquin de masse")) || IsOfficer(characterFromID("Jaoquin de masse")))
if (!LAi_IsDead(characterFromID("Jaoquin de masse")) || !LAi_IsDead(characterFromID("Mergildo Hurtado")))
{
pchar.quest.Jaoquin_back_church.win_condition.l1 = "location";
pchar.quest.Jaoquin_back_church.win_condition.l1.location = "Redmond_Church";
pchar.quest.Jaoquin_back_church.win_condition = "Jaoquin_back_church";

pchar.quest.ship_moor.win_condition.l1 = "location";
pchar.quest.ship_moor.win_condition.l1.location = "Redmond_port";
pchar.quest.ship_moor.win_condition = "Ship_moor";

pchar.quest.ship_moor1.win_condition.l1 = "location";
pchar.quest.ship_moor1.win_condition.l1.location = "Redmond_Shore_01";
pchar.quest.ship_moor1.win_condition = "Ship_moor1";

pchar.quest.ship_moor2.win_condition.l1 = "location";
pchar.quest.ship_moor2.win_condition.l1.location = "Redmond_Shore_02";
pchar.quest.ship_moor2.win_condition = "Ship_moor2";
}

pchar.quest.return_priest_complete4.win_condition.l1 = "ExitFromLocation";
pchar.quest.return_priest_complete4.win_condition.l1.location = "Muelle_Church";
pchar.quest.return_priest_complete4.win_condition = "return_priest_complete4";
break;

case "return_priest_complete4":
changeCharacterAddress(characterfromID("padre Domingues"), "Muelle_church", "goto11");
LAi_SetStayType(characterFromID("padre Domingues"));
Characters[GetCharacterIndex("padre Domingues")].dialog.CurrentNode  = "First time";
break;

case "Ship_moor":
pchar.location.from_sea = "Redmond_port";
break;

case "Ship_moor1":
pchar.location.from_sea = "Redmond_Shore_01";
break;

case "Ship_moor2":
pchar.location.from_sea = "Redmond_Shore_02";
break;


Which is causing the problems

Beta 1 Patch 7 was the last patch released shortly before Beta 2


Why case "return_priest_complete2": and case "return_priest_complete3": --- were changed to --- case "return_priest_complete3": and case "return_priest_complete4": respectively

I don't know :shrug and since it was done recently I don't think the original writer did it.

So I think the correct fix would be to return the 2 cases to their names in Beta 1 Patch 6 -- since these problems have only been reported with recent versions of the game.


Any suggestions for making this easier will be gratefully received.

I was actually hoping you guys have some decent tools at your disposal when writing these scripts . Not much I can suggest right now, since such "addon" interpreted technologies are always a pain to debug. It would probably be feasible to write a whole framework of scripts for displaying most of the debug info that a decent dev env does (at least current script line scecution status, values of node structutres etc.), maybe re-using the GUI interfaces already developed to show this in a convenient way. This however is not something I could write "of the top of my mind" without getting deeply involved with the fundamentals of how the mod works - low-level dirty deeds in other words . I'm pretty convinced Akella had something like this. It would be madness to make their game designers work without that. Why not try pestering them about this for a bit?

:shrug
I will check with some of those who know more about the mod that I do and see what I can find out.

We do have some tools from Akella - they can be downloaded from the downloads section here --->>> http://forum.piratesahoy.net/index.php/files/category/5-modding-tools/


:drunk
 
So I think the correct fix would be to return the 2 cases to their names in Beta 1 Patch 6 -- since these problems have only been reported with recent versions of the game.

This is just my opinion as a programmer (as opposed to someone very familiar with the mod), but unless you are sure this will be totally fine, then I think the change I proposed runs less risks of later problems. I'll explain this logic below :

The case code sections below "return_priest_completeX" statements (X either blank or a number) can be thought of as "definitions" for these labels. Likewise, the part in padre Dominiguez_dialog.c which assigns the dialogue node to the second (or third in my proposal) label can be thought of as a "user" of these definitions. If I change the way a "user" utilizes the definitions and not the definitions themselves - then I should be able to expect that the only possible new problems that arise will be limited to the scope of the "user" I modified. In other words, nothing other than the consequences (direct or indirect) following Dominiquez's "Thanks" dialogue should be affected by the change, whereas in your proposal it's possible that there exist other sections of code that depend on "return_priest_complete3" and "return_priest_complete4" to be as they currently are and will fail after a change of "definitions", creating rather hard to spot bugs.

In essecne what I'm saying is : by changing those labels back to what they were you are actually doing something very similar to what was done in Beta 1 P7 - I doubt that operation was done just for the heck of it, there was probably some bug-related reason for it. As we can see it created a nasty, hidden problem that does not surface easily. I would be willing to bet that whoever did this was either unaware of the unchanged call to "label 2" in Dominiguez dialogue or planned to change it and simply forgot. In short : unless you are absolutely certain that restoring the old labels will not screw over whatever was done since P7 - I would recommend going with my suggestion ;).

By the way - I'm guessing you're seeing those diffrences if Beta version through some sort of SVN repository? Shouldn't that tell you who made the change? (i.e. the culprit! :cheeky )

We do have some tools from Akella - they can be downloaded from the downloads section here --->>>

I've taken a look at this page and can see that you mainly have tools to deal with the various resources of the game - they're quite essential of course, though I was thinking of some sort of support architecture for testing the scripts themselves. This scripting language is quite powerful (perhaps too powerful) so I would think Akella would provide something to accelerate testing it. Though it's possible to work without it (as you guys seemingly have), it just takes an incomperably larger effort to ensure correctness = more man hours of work = longer developement time = less profit. That's why I'm so surprised nothing better than the shabby error logs i available ;).
 
First of all, please let me welcome you to the forum, Finalmenator!
A new member with actual coding knowledge? You're most welcome indeed!

Most people here, including myself, are mainly self-taught on the whole modding business and we might be a bit unprofessional by comparison with real coders like yourself.
That is why we always look out for people like yourself to join in as self-taught can only take us this far.

Now some notes on what I know of the above:

This code change actually WAS made by the original coder fairly recently. From "Build Info.txt" in your main game folder:
Build 14 Beta 1 Patch 7:
[TRUNCATED]
- Storyline updates:
. Padre Domingues quest fix by Captain Maggee

Unfortunately have no SVN of any kind; the comments in the code plus the changelog in "Build Info.txt" are the best we have.

As far as I'm aware, there are no additional code debuggers. At least, I have never heard of anything like that.
Personally, I generally just use the Windows search engine to search for a certain code term in the entire PROGRAM folder.
So far, that has served me pretty well, but I'm not sure if all other coders make use of that.

We generally find the exact differences between various releases by comparing the code files from installs with WinMerge.
At least, that's the thing I do.
 
Thanks for the welcome ;), so far I've been playing the mod for a good couple of hours and find the results of your work quite entertaining.

Most people here, including myself, are mainly self-taught on the whole modding business and we might be a bit unprofessional by comparison with real coders like yourself.
I like to think that most (if not all) programmers are selft-taught. Even those like myself, who majored in computer science durring collage usually find that you are "given" very little knowledge and need to struggle to learn all you'll need by yourself before the next lab class :cheeky. In any case - I wasn't in any way implying that your work looks unprofessional. I merely remarked, that the framgents I've been looking at are "dirty" as in not very intuitively structured, therefore possibly misleading for anyone other than the author. This is a sign of rushed coding, not necessarily unprofessional. The difference is simple : most of us initally end up with "dirty" code to some degree (unless it's something very simple or very well planned out), but it's in a project's best interest (and our own! Sooner or later we'll forget how our code works and if it's all convoluted tricks and hacks it'll take effort to figure it out again) that this dirt be reasonably "cleaned up". Though I admit that in this mod's case, you seem to be rather restricted by Akella's standard of handling things, so many good practises probably don't apply. Furthermore you guys seem to know about a lot of those that do (I've taken a quick look at your modding tutorial), so I'm not going to preach about the subject ;).

Unfortunately have no SVN of any kind; the comments in the code plus the changelog in "Build Info.txt" are the best we have.
I guess I just assumed you would have one, but now that I thinks about it - it's understandable that you wouldn't. Repositories need resources (self hosting usually doesn't cut it, unless you already run a server), someone with the time and know-how to look after them and all of it's users need to have some experience with using one. I mentioned an SVN in regard to "ownership" of code, but that feature is not why I thought you would have one - the ability to possess and manage different versions of the code is (useful in cases like this one).

As far as I'm aware, there are no additional code debuggers. At least, I have never heard of anything like that.
Personally, I generally just use the Windows search engine to search for a certain code term in the entire PROGRAM folder.
So far, that has served me pretty well, but I'm not sure if all other coders make use of that.

That's a pitty. Most games run on some sort of interpreted script language so usually, engine programmers include a framework to assist game designers with their script debugging. Nowdays this usually constitutes of a "console" that allows one to see the state of the data currently in execution (like values of dialogue nodes), so you can know precisely how your script behaves and why at any given moment - immensly helpful when ironing out bugs as you don't have to guess where the flow of code went, when something goes wrong (as I had to, in this case). It's possible that this sort of funcionality was implemented as external scripts (maybe part of whatever toolkit the game designers used) which were not included in the end product by Akella - that's why I suggested asking them about it.

We generally find the exact differences between various releases by comparing the code files from installs with WinMerge.
At least, that's the thing I do.
Reasonable in the absence of svn. Though it's likely a pain when you have to compare 6+ versions together to find what you're looking for, if you guys even find it feasible to keep that many ;).

Anyway, I seem to have strayed considerably off-topic here so I'll only add that unless someone finds compelling reasons for revision of the Bernard dialogue issue, I'd consider it resolved ;). Although I'm curious what the "Padre Dominiguez quest fix" involved for those case labels to change in such a weird way. Seems like all the more reason not to restore them to the original state and change individual call arguments instead...
 
Personally, I do try to write what coding I do in a way that is understandable, with some comments to explain what does what. Otherwise I lose track myself of what it does.
In the past, I didn't always do it like that and now I find myself wondering what it was that I did several years ago. So you've definitely got a point. :facepalm

I wasn't implying that you were implying that our work looks unprofessional. Instead, I was saying that I know that MY work at least IS unprofessional. :razz

We did use to have an SVN for a short while and I quite liked it too, but then the server went down and we never got it back.
We also had a hard time convincing everybody to make use of it, so it ended up with two people using it and everybody else just sticking to the old ways.

We do have a "console" of some kind, which is PROGRAM\console.c that we modded in.
It allows executing any code while running the game, which is really very helpful.
Then the following code I have found to be very useful to find the state of the attributes assigned to any object:
Code:
			object obj_var;
ref refobj; makeref(refobj, sea);
trace("obj_var attributes:");
DumpAttributes(refobj);

aref aref_var; makearef(aref_var, pchar);
trace("aref_var attributes:");
DumpAttributes(aref_var);
It's not ideal, but all little bits help.

When something actually triggers an error, the error logs are really very useful.
But it can indeed be a pain to figure things out when you KNOW something isn't going right, but it isn't wrong enough to cause an error message.

Would it be possible for you to post your proper fix files so I can WinMerge them for inclusion into the next modpack release?
 
Personally, I do try to write what coding I do in a way that is understandable, with some comments to explain what does what. Otherwise I lose track myself of what it does.
In the past, I didn't always do it like that and now I find myself wondering what it was that I did several years ago. So you've definitely got a point.
It's a common phenomenon, so common in fact that every CS freshman is all but physically pressured to document (mostly by comments) as much as possible, use meaningful names for all variables/constants/labels (many of those I've seen in the script adhere to this, but those 4 for the priest could definetly be better), avoid non-obvious flow control (infamous GOTO statement) and many, many other things ;). Resistance is futile, those who do not submit are later assimi... - I mean eliminated by their own impossibly unmanageble projects ;).

For all my complaints about such things - don't think that I'm suggesting re-writing the code to clean it up. This goes againts the "first commandment" of software engineers ("Thou shalt not touch working code!") ;). Re-designing should only be done by the author and probably when he remebers most things about it relatively well. The exception to this would be a situation when the code "works" so clunkily, that it might as well be out of commision for some time. The part I've looked at does not qualify - the bug seems to be rather rare (so far only 2 reported cases), it affects a side storyline and is relatively non-critical (in the sense that it doesn't screw up the rest of the game or make your laptop explode on your crotch :cheeky ) - a medium priority issue at most. Re-writing the code now to be more in line with good practises is just asking for more trouble. As long as it works to a satisfactory level it should stay as it is.

We also had a hard time convincing everybody to make use of it, so it ended up with two people using it and everybody else just sticking to the old ways.
To be honest, the first time I was required to use a repository (a CVS in this case) it was unpleasant to say the least. The thing can be very clunky and obstruct work, if not used with care and experiance. It didn't help that the team was small, and the workload divided well enough for a repository to be all but unecessary - it's meant for bigger projects with a lot of people working on highly related things. So I'm not the least bit surprised you'd have a tough time getting people to accept it.

We do have a "console" of some kind, which is PROGRAM\console.c that we modded in.
After looking at this snippet I've remembered something I meant to ask earlier : do you maintain some form of API documentation for this project? By "API" I mean the procedures the mod makes use of (both built into the engine / language and your own, which are intended to be re-used). I for one can only guess what exactly "trace()" does (among many others), such a documentation would allow just about anyone to quickly be able to grasp unfamiliar code. If there's no such central knowledge base then everything must be gotten by "word of mouth" (i.e. you could explain the details to me, but it doesn't help anyone else unfamiliar with it).

When something actually triggers an error, the error logs are really very useful.
But it can indeed be a pain to figure things out when you KNOW something isn't going right, but it isn't wrong enough to cause an error message.

Ah, but I presume that error logs will only be written if the script actually has a syntax error, or a procedure recevies some totally unexpected ("junk") data. Synatax errors aside, the second one is traditionally called a "null reference" - and it is a mild problem. The reason is : it's easy to detect and pinpoint. One could say that "error logs" in interpreted languages like this one exist purely to help with this one type of programmer errors. The truly "sinister" bugs are always those that arise from doing something technically correctly - just not what you actually intended. The dialogue issue of this thread is a fine example. That's why good debugging tools let you run the bugged code, while giving access to the state of data that controls execution - so you can see when it takes unexpected values.

Would it be possible for you to post your proper fix files so I can WinMerge them for inclusion into the next modpack release?
Well sure I can, though it's only one changed line in one file (padre Dominiguez_dialogue.c, as I've noted above). You might want to first ask Talisman about it though - his proposal would also work, if he's certain no other trouble would result from it (which I've also discussed above). If you've decided to use my suggestion and want the whole file - please specify how you'd like it delivered to you (whether I should mail it to you, upload to a specific ftp, or some other way).
 
Would it be possible for you to post your proper fix files so I can WinMerge them for inclusion into the next modpack release?
Well sure I can, though it's only one changed line in one file (padre Dominiguez_dialogue.c, as I've noted above). You might want to first ask Talisman about it though - his proposal would also work, if he's certain no other trouble would result from it (which I've also discussed above).


I think it would be best to use finalmenator's solution to the problem - for the time being.

I don't know why Capt Maggee changed the code & what it is supposed to achieve - I have not played the Jack Sparrow story recently :whipa - I will have to do so soon and see what happens.
So changing the cases in both_reaction.c back to what they were could cause unknown problems.

If you've decided to use my suggestion and want the whole file - please specify how you'd like it delivered to you (whether I should mail it to you, upload to a specific ftp, or some other way).

You can just attach the padre Dominiguez_dialogue.c file to a post in this thread using the full post editor . - Pieter should pick it up from there.

Thanks for all your help
:cheers
 
Okay then, here it is. Just for completeness sake : the file location is "\PROGRAM\Storyline\LegendJackSparrow\dialogs".

Thanks for all your help
Thanks again for the advice on how to go about this. I probably wouldn't have bothered if you hadn't narrowed it down to a reasonable scope.
 

Attachments

  • padre Domingues_dialog.c
    16.3 KB · Views: 199
:gday mate!

A real coder! Welcome to Amateur Hour. Most everyone here is self taught. :mm If you are willing to help, there is a shipload of things that need fixing. :bow
 
As far as that API is concerned, we do have the "Keywords used in POTC but defined in engine" section in "Documentation\New Horizons Tutorials & History.pdf".
Other than that, we don't really have anything. I usually figure out what things do that ARE defined in the PROGRAM folder by using the Windows search engine in the PROGRAM folder and finding where the function is defined.
Is that sort-of what you're looking for?

In any case, trace() basically just makes an entry in compile.log when it is executed, which is useful tracking if certain lines of code are executed and can be used to give additional information as well.
 
Back
Top