• 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!

Solved Dutchman Quest Revisions (Test Game Download Included)

Trace statement for companion:
Code:
           if(sti(iCompanionIndex)==0) trace("Calling Companion GetCharacter with a zero " + iCompanionIndex);
New Errors:
 

Attachments

  • compile.log
    30.7 KB · Views: 251
  • error.log
    492 bytes · Views: 246
  • system.log
    9.3 KB · Views: 242
Well, it's none of those...I think I might have found it for you. TakeNItems calls GetCharacter, and TakeNItems is used in the Item2Char/Equip functions. I see that they don't take char index values, but a char reference, so change them in the SpawnDutchman function:

GiveItem2Character(qChar, "blade19");
EquipCharacterByItem(qChar, "blade19");
GiveItem2Character(qChar, "gun6");
EquipCharacterByItem(qChar, "gun6");

to

GiveItem2Character(&characters[qChar], "blade19");
EquipCharacterByItem(&characters[qChar], "blade19");
GiveItem2Character(&characters[qChar], "gun6");
EquipCharacterByItem(&characters[qChar], "gun6");
 
New Errors (The change attributes function still is random - in short I can barely make heads or tails of it in it's current state):
 

Attachments

  • compile.log
    47.8 KB · Views: 234
  • error.log
    3.5 KB · Views: 251
  • system.log
    7.5 KB · Views: 225
Looking at some similar code for NPC_Death, it looks like the .character is supposed to be an index, not an ID name. That might explain why so many index 0 as the quest check function is called often. Change this part:

Code:
case "spawn_dutchman":
       //login Davy Jones

       //generate encounter
            int qChar = SpawnDutchman();

            Pchar.quest.dutchman_KillJones.win_condition.l1 = "NPC_Death";
            Pchar.quest.dutchman_KillJones.win_condition.l1.character = qChar;
            PChar.quest.dutchman_KillJones.win_condition = "dutchman_KillJones";
       break;

       case "dutchman_KillJones":
           //Kill Jones by function
           //Play a sound here "Damn you jack sparrow" (sound sample filtered from original movie)
           chr = GetCharacter(GetCharacterIndex("Davy Jones"));
           if( CheckAttribute(chr,"Killer.status") && sti(chr.Killer.status)!=KILL_BY_ABORDAGE )
           {
                trace("Flying Dutchman Killed by Cannonfire");
                SetQuestHeader("Dutchman");
                AddQuestRecord("Dutchman", "2_failed");
                LAi_group_Delete("FlyingDutchman"); //Sea group
                Pchar.quest.dutchman_Respawn.win_condition.l1 = "ExitFromLocation";
                Pchar.quest.dutchman_Respawn.win_condition.l1.location = "Grenada";
                PChar.quest.dutchman_Respawn.win_condition = "spawn_dutchman";
            }
            else
            {
               SetQuestHeader("Dutchman");
               AddQuestRecord("Dutchman", "3_captured");
               trace("*** Davy Jones Killed by Abordage");
               DoQuestCheckDelay("dutchman_dead", 2.0);

            }
       break;
 
Last edited:
New Errors (That function didn't update the logbook, I am almost convinced that the spawn code I put in is responsible.The models are still random and the character still doesn't get assigned the blade and gun on spawn...) At least there's no Error log this time:
 

Attachments

  • compile.log
    13 KB · Views: 238
  • system.log
    10 KB · Views: 227
The good news is that it looks like changing .character = qChar fixed the index zero problem and that is resolved. I also see that the "Special Character" trace shows output, so we know that the boarding function finds the "copyme" attribute and calls ChangeAttributesFromCharacter. Perhaps the copy function needs some work. First, see what comes back by tracing the _SetBoardingCaptain. Put these statements near the end of that function to see if the correct attributes show as correctly copied:

trace("Standin capt .model = " + chr.model);
trace("Standin capt .equip.gun = " + chr.equip.gun);
trace("Standin capt .equip.blade = " + chr.equip.blade);
trace("Standin capt .location = " + chr.location);
 
From all the trace statements I am getting Invalid Expression and Invalid Syntax.....

Nevermind, I added a trace for the CopyChref at the end of the change attributes function(I am starting to think that the function should return a ref) and in the set Boarding captain function I added the original trace functions. Testing now!
 
Last edited:
Ok Some new errors to pick your brain at.... Apparently the change attributes function itself is not the problem, however the character is not being spawned, instead the character generated with random data is instead. Also the error.log is possibly the cause of the suicide error where sometimes during an encounter your ship will be sunk, even with god mode on after the first volley is fired by the opponent's cannons...
 

Attachments

  • compile.log
    15.9 KB · Views: 230
  • error.log
    399 bytes · Views: 242
  • system.log
    10.1 KB · Views: 213
Interesting...I note that the create fantom character sends a message for the character to be 'entered'. I wonder if that puts a hard set on the model being used, because looking at newer code of COAS, there is another function that gets called to SetNewModelToChar during the boarding load. Similar to that ChangeAttributesFromCharacter function, this appears to be a new method for that boarding. So, let's try that. Add this function, like you did for that ChangeAttributes... function:

Code:
void SetNewModelToChar(ref chref)
{
    float liveTime = 0.1;
    int colors = argb(64, 64, 64, 64);
    int colore = argb(0, 32, 32, 32);

    if (IsEntity(chref))
    {
        if(CheckAttribute(chref, "model"))
        {
            SendMessage(chref, "lss",   MSG_CHARACTER_SETMODEL, chref.model, chref.model.animation);
        }
        if(CheckAttribute(chref, "equip.gun"))
        {
            SendMessage(chref, "ls",    MSG_CHARACTER_SETGUN,   chref.equip.gun);
        }
        if(CheckAttribute(chref, "equip.blade"))
        {
            //SendMessage(chref, "lsfll", MSG_CHARACTER_SETBLADE, chref.equip.blade, liveTime, colors, colore);
            SendMessage(chref, "llsfll", MSG_CHARACTER_SETBLADE, 0, chref.equip.blade, liveTime, colors, colore);
        }
    }
}

Then in the _SetBoardingCaptain function, just before LAi_group_MoveCharacter(chr, LAI_GROUP_BRDENEMY):

Code:
SetNewModelToChar(chr);
LAi_group_MoveCharacter(chr, LAI_GROUP_BRDENEMY);
 
The right character spawns and the right sword. The gun is missing though (not sure If cabin fights usually have guns... It is mainly just a sword duel, but the main character can use his gun - so why not the enemy char)... I may want to tweak Jones's HP so that it is higher, but overall a great start.... The win conditions still aren't working though....
 
The logs from the latest run:
 

Attachments

  • compile.log
    10.6 KB · Views: 194
  • system.log
    7.4 KB · Views: 212
Looking into your gun problem, I think it's because 'they' screwed up. the SetNewModelToChar uses chref.gun.equip, which is populated with the item id of the gun. Every other function, such as EquipCharacterByItem, which calls SetEquipedItemToCharacter, where it then needs the model of the gun, looks up the item by id, then sends a MSG_CHARACTER_SETGUN message of the .model for that gun item when needed. But in this case, since we are copying the attributes of the Davy character to the standin character, then calling SetNewModelToChar, which then sends MSG_CHARACTER_SETGUN the gun.equip, that message wants the model name, but is given the gun item id, instead.

The only reason that SetNewModelToChar works in COAS, is because the gun ids were changed to match the model name.

I did a search for "gun, and see that there are many places where the gun ids are hardcoded/assigned (e.g. "gun1" "gun7"). If you don't want to search for them all, and change them in the code and in the items init (this would obviously require a new game, too), I also see that there really aren't that many in Models\Ammo. For this, to quickly test, copy pistol6, rename the copy to gun6 and see if the gun shows up on the character. Then, if it shows and verifies my thinking, a quick, but not ideal fix, would be to copy all 7, renaming the Ammo models gun1 through gun7.
 
That worked, but the character does not use it in the fight with the player character... And the win conditions are still not working right... Also Error log returns...
 

Attachments

  • compile.log
    10.6 KB · Views: 225
  • error.log
    550 bytes · Views: 222
  • system.log
    7.1 KB · Views: 211
Well, well. You have discovered a bug that still exists to this day in all subsequent versions (COAS, GOF, etc.). Granted, it's unnoticed in the later versions, but only due to the id and model names coincidentally match. Let's fix the bugged SetNewModelToChar function. First, go ahead and delete those ammo models GunsX.gm that you had copied from the PistolX.gm. Then change the function:

Code:
void SetNewModelToChar(ref chref)
{
    float liveTime = 0.1;
    int colors = argb(64, 64, 64, 64);
    int colore = argb(0, 32, 32, 32);

    aref arItm;
    string modelName;
    object emptyItm;

    if (IsEntity(chref))
    {
        if(CheckAttribute(chref, "model"))
        {
            SendMessage(chref, "lss",   MSG_CHARACTER_SETMODEL, chref.model, chref.model.animation);
        }
        if(CheckAttribute(chref, "equip.gun"))
        {
            modelName = chref.equip.gun;
            makearef(arItm,emptyItm);
            if(modelName!="")
            {
                Items_FindItem(modelName,&arItm);
            }
            if(CheckAttribute(arItm,"model"))    {modelName = arItm.model;}
            //SendMessage(chref, "ls",    MSG_CHARACTER_SETGUN,   chref.equip.gun);
            SendMessage(chref, "ls",    MSG_CHARACTER_SETGUN,   modelName);
        }
        if(CheckAttribute(chref, "equip.blade"))
        {
            modelName = chref.equip.blade;
            makearef(arItm,emptyItm);
            if(modelName!="")
            {
                Items_FindItem(modelName,&arItm);
            }
            if(CheckAttribute(arItm,"model"))    {modelName = arItm.model;}
            //SendMessage(chref, "lsfll", MSG_CHARACTER_SETBLADE, chref.equip.blade, liveTime, colors, colore);
            //SendMessage(chref, "llsfll", MSG_CHARACTER_SETBLADE, 0, chref.equip.blade, liveTime, colors, colore);
            SendMessage(chref, "llsfll", MSG_CHARACTER_SETBLADE, 0, modelName, liveTime, colors, colore);
        }
    }
}

As for your character not using the gun, I wonder if it may just be a case that their skills are low in that area, so perhaps disfavored? Let's grant them higher skills based on their rank, and the GunProfessional perk to see. Replace this part of SpawnDutchman:

Code:
int SpawnDutchman()
{

    int nRank = 20;

    int qChar = GetCharacterIndex("Davy Jones");
    if(qChar < 0) { //New
        qChar = GenerateCharacter(PIRATE, WITH_SHIP, "officer", MAN, 1, BOSS);
        characters[qChar].id = "Davy Jones";
        characters[qChar].name = "Davy";
        characters[qChar].location = "Grenada";
        characters[qChar].lastname = "Jones";
        characters[qChar].model = "pirate_5";
        characters[qChar].copyme = true;
        FaceMaker(&characters[qChar]);
        characters[qChar].rank = nRank;
        LAi_NPC_Equip(&characters[qChar], nRank, true, true);
        GiveItem2Character(&characters[qChar], "blade19");
        EquipCharacterByItem(&characters[qChar], "blade19");
        GiveItem2Character(&characters[qChar], "gun6");
        EquipCharacterByItem(&characters[qChar], "gun6");
        characters[qChar].perks.list.GunProfessional = "1";
        characters[qChar].Ship.Type = GenerateShip(SHIP_DUTCHMAN, 1);
        characters[qChar].Ship.Cannons.Type = CANNON_TYPE_CANNON_LBS48;
        characters[qChar].ship.name = "The Flying Dutchman";
        characters[qChar].skill.cannons = 5;
        characters[qChar].skill.grappling = 5;
        characters[qChar].skill.accuracy = 5;
        characters[qChar].skill.defense = 10;
        //characters[qChar].skill.Fencing = 10;
        //characters[qChar].skill.Gun = 10;
        characters[qChar].cannotsurrender = 1;
    }

During the encounter, try to stay at a distance for as long as you can to see if the NPC will eventually draw the gun. We'll investigate the win conditions after these last details are ironed out.

Also, that error log: Those errors both occur in LAi_SetBoardingCaptainLevelHP due to a missing chr.ship attribute. That function is only called in one place, LAi_SetBoardingCaptain, but last I saw in the function we never get to the line that calls LAi_SetBoardingCaptainLevelHP because it is in the block of "Random character" instead of the "Special character" trace. So unless you changed that around, I can't see how that line was ever called in your test because I only see the Special character log in compile.log, not a single Random character trace.
 
Fixed that (accidentally moved the setboardingcaptainlevelhp function) New Errors and Report:
In the cabin fight, Davy Jones never drew his gun despite dancing around the cabin as best I could for 10 minutes. Also, in coas, The player character's weapon reloads during aboardage and land encounters, but in CT it doesn't reload at all... Only on land when not in a threatening situation does that code execute... The insta-killed bug at battle with the Dutchman happened again so the error log should probably reflect that.

Logs Below:
 

Attachments

  • compile.log
    23.7 KB · Views: 215
  • error.log
    3.2 KB · Views: 219
  • system.log
    13.9 KB · Views: 214
Also, in coas, The player character's weapon reloads during aboardage and land encounters, but in CT it doesn't reload at all... Only on land when not in a threatening situation does that code execute...

Interesting. I've never played CT, so was unaware of that. Since the PC gun doesn't reload, I suspect that is the problem with the NPC gun. Probably also explains why the original boarding captain code doesn't even give the NPC a gun. I bet though the NPC has a gun, it is probably 'not loaded' from the outset (for instance, and since guns don't recharge while engaged in CT, it never charges up. Will need to look around to see if there is a way to at least give the NPC an initial charge prior to the cabin fight, so at least both the PC and NPC start off on even footing of getting a loaded gun at the beginning, then equally neither getting a reload during the fight.
 
The only other gun now that rivals the Gun from Davy Jones is Duelist's Dream, a quad charge pistol (used to be double). So the player will be at a disadvantage on average if Jones pulls the gun on an inexperienced player (4 shots is usually enough to kill any character). The only other guns that come close are the muskets and the blunderbuss and they are single shot weapons...
 
Let's see what this says...in LAi_boarding.c, in the SetBoardingCaptain, insert two trace statements for the charge values:

SetNewModelToChar(chr);
trace("charge max " + chr.chr_ai.charge_max);
trace("charge curr " + chr.chr_ai.charge);
LAi_group_MoveCharacter(chr, LAI_GROUP_BRDENEMY);
 
The charge max trace is giving me errors:
 

Attachments

  • compile.log
    10.9 KB · Views: 224
  • error.log
    157 bytes · Views: 224
  • system.log
    8.2 KB · Views: 220
Interesting. I think it's possible not having a max charge could contribute to the 'not using gun'. Add another trace with it:

trace("charge max _enemy " + boarding_enemy.chr_ai.charge_max);

EquipCharacterByItem, calling SetEquipedItemToCharacter should have set it for Davy. So let's verify that, and see if perhaps the char copy needs adjusting.
 
Back
Top