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

Discussion A question regarding ship hunting

Mad Jack Wolfe

Master Mariner
Storm Modder
Pirate Legend
Ship hunting has become a favourite pastime for me. I'll jump at the chance to take on unfriendly ships, and refuse to hunt any from countries with whom I have friendly relations (I've got a cozy relationship with Spain and France that benefits me much). A problem arises when the governor neglects to mention the nationality of the target vessel, however.

Case in point: the leader of the Nevis pirate colony tasked me with hunting down a 3rd-rate battleship, no country specified. I decided to accept the task assuming it would be British since I've been quite the thorn in their side. We sailed out and quickly found the prey, only to discover she was French. The last thing I wanted to do was sour my standing with France. Rather than engage the battleship, I sailed close enough to get her attention, staying just out of reach as she chased me north along the coast. The ploy worked, and I was able to lure her under the guns of the British fort. We sailed away as the battleship got carved up like a Christmas goose.

I knew that from previous experience, regardless of how the prey met their end, I would get credit for the kill. But this was the first time I tried it with an ally's ship. Not only did I get credit for the kill, but my standing with France also took a sizeable hit even though I never fired a shot (my unscrupulous doublecross notwithstanding).

Would it make sense to modify the ship hunting code to disqualify the player from getting credit for the kill if a different ship or fort gets to the prey first? And yes, I know I'm pretty much volunteering myself to do the work. :read
 
First, I'd like to know why the governor failed to mention the ship's nationality. As far as I can see, ship hunting quests come from "PROGRAM\DIALOGS\governor.c":
Code:
       case "kill_pirate":
           GenerateQuestShip("Quest pirate", iNation); // PB: Use Generic Function
           dialog.text = DLG_TEXT[18] + GetShipDescribe("Quest pirate", true, true, true, true) + DLG_TEXT[21] + FindIslandName(pchar.quest.generate_kill_quest.destination) + DLG_TEXT[22] + pchar.quest.generate_kill_quest.money + DLG_TEXT[23]; // KK
           link.l1 = DLG_TEXT[24];
           link.l1.go = "kill_pirate_agree";
           link.l2 = DLG_TEXT[25];
           link.l2.go = "kill_pirate_refused";
       break;
'GetShipDescribe("Quest pirate", true, true, true, true)' is what's supposed to tell you about the ship you're hunting, and is defined in "PROGRAM\Dialog_func.c". The first 'true' refers to the ship's nation - if that's set, 'GetShipDescribe' is supposed to show the ship's nation.

The Nevis pirate chief has to be using "governor.c" to generate ship-hunting quests because his own file, "Isenbrandt Jurcksen_dialog.c", doesn't have anything about them.

As for disallowing credit if someone else gets the kill, it does make sense, but it also breaks the quest if the enemy ship happens to spawn next to the fort, which has happened to me more than once. Also, what happens if it's a big enough ship that it can survive near the fort for a while, you engage it and do most of the work, then the fort or some other ship fires the last shot which sinks the target?
 
Case in point: the leader of the Nevis pirate colony tasked me with hunting down a 3rd-rate battleship, no country specified.
When you pay really close attention, could it be that there were TWO spaces prior to the number of cannons?
If so, perhaps this part is failing for some reason:
Code:
XI_ConvertString("sw_" + GetNationDescByType(sti(chr.nation)))
Problem could be in 'XI_ConvertString', 'GetNationDescByType' or (most likely) a missing/invalid chr.nation attribute.
 
Here's an example of what I've encountered.
E3EvT55.png
 
At the end of the definition of "GetShipDescribe" is this:
Code:
    if(HasSubStr(shipType,"0") || HasSubStr(shipType,"1") || HasSubStr(shipType,"2") || HasSubStr(shipType,"3") || HasSubStr(shipType,"4") || HasSubStr(shipType,"5") || HasSubStr(shipType,"6") || HasSubStr(shipType,"7") || HasSubStr(shipType,"8") || HasSubStr(shipType,"9"))
   {
       if(!HasSubStr(shipType," 0") && !HasSubStr(shipType," 1") && !HasSubStr(shipType," 2") && !HasSubStr(shipType," 3") && !HasSubStr(shipType," 4") && !HasSubStr(shipType," 5") && !HasSubStr(shipType," 6") && !HasSubStr(shipType," 7") && !HasSubStr(shipType," 8") && !HasSubStr(shipType," 9"))
       {
           shipDescribe = shipType;
       }
   }
If it's triggered then all the previous work done by "GetShipDescribe" to build up the ship's description is discarded and the ship description is just 'shipType', previously defined as 'shipType = XI_ConvertString(shipRef.Sname);'. For a battleship, 'Sname' is "SoL3R2", so 'shipType' will become "3rd Rate Battleship". And that's why it's not including the nationality, name or number of guns, and why it says "3rd Rate Battleship" instead of "3rd rate battleship".

Any idea why this piece of code is there?
 
Any idea why this piece of code is there?
I honestly haven't got the faintest clue. I don't recall ever seeing it or hearing about it.
Do you have any old mod versions to see if you can find a version that didn't have it yet?
I'm thinking that code might be really, really old. :shock
 
The oldest version I have is from Beta 3, and the definition of 'GetShipDescribe' is exactly the same as the latest version, including that bit.

@Mad Jack Wolfe: try copying this into "PROGRAM". First copy or rename the existing version of "Dialog_func.c" in case it breaks something. The difference is that the code to return a stripped down description if the ship type contains a number is now commented out.
 

Attachments

  • Dialog_func.c
    102.2 KB · Views: 205
The oldest version I have is from Beta 3, and the definition of 'GetShipDescribe' is exactly the same as the latest version, including that bit.
I went into my archives and found that it was added in Build 14 Alpha 8, dated on Sunday 27 July July 2008 (10-year old typo of mine there...).
This is what that version of the function looked like:
Code:
// MAXIMUS: can be used in any situation [used in Silehard-dialog] --> // KK -->
string GetShipDescribe(string charId, bool nation, bool nguns, bool shipname, bool accusative)
{
    ref chr, shipRef;
    int canQuantity;
    aref arShip;
    string shipType;
    string shipDescribe = "";

    chr = characterFromID(charId);
    shipRef = GetShipByType(GetCharacterShipType(chr));
    shipType = XI_ConvertString(shipRef.Sname);

    if (nation) shipDescribe += XI_ConvertString("sw_" + GetNationDescByType(sti(chr.nation))) + " ";
    if (nguns) shipDescribe += GetMaxCannonQuantity(chr) + XI_ConvertString("cannonsQuantity") + " ";
    shipDescribe += strlower(shipType);
    if (accusative) {
        switch (LanguageGetLanguage()) {
            case "Polish":
                int dl = strlen(shipDescribe);
                if (GetSymbol(shipDescribe, dl - 1) == "a") {
                    string tmpstr = "";
                    for (int i = 0; i < dl - 1; i++) {
                        if (GetSymbol(shipDescribe, i + 1) == " ")
                            tmpstr += "№";
                        else
                            tmpstr += strcut(shipDescribe, i, i);
                    }
                    tmpstr += "Ч";
                    shipDescribe = tmpstr;
                }
            break;
            // default:
        }
    }
    if (shipname) shipDescribe += " '" + chr.Ship.Name + "'";

    if(HasSubStr(shipType,"0") || HasSubStr(shipType,"1") || HasSubStr(shipType,"2") || HasSubStr(shipType,"3") || HasSubStr(shipType,"4") || HasSubStr(shipType,"5") || HasSubStr(shipType,"6") || HasSubStr(shipType,"7") || HasSubStr(shipType,"8") || HasSubStr(shipType,"9"))
    {
        if(!HasSubStr(shipType," 0") && !HasSubStr(shipType," 1") && !HasSubStr(shipType," 2") && !HasSubStr(shipType," 3") && !HasSubStr(shipType," 4") && !HasSubStr(shipType," 5") && !HasSubStr(shipType," 6") && !HasSubStr(shipType," 7") && !HasSubStr(shipType," 8") && !HasSubStr(shipType," 9"))
        {
            shipDescribe = shipType;
        }
    }
    return shipDescribe;
}
// MAXIMUS: can be used in any situation [used in Silehard-dialog] <-- // <-- KK

That already contained the relevant code, so apparently it was added by @konradk and @Maximus in that form already 10 years ago.
If you really want to know the reason, you could try sending them a PM; they have both been active this year, so it should be possible to get a hold of them.
 
The oldest version I have is from Beta 3, and the definition of 'GetShipDescribe' is exactly the same as the latest version, including that bit.

@Mad Jack Wolfe: try copying this into "PROGRAM". First copy or rename the existing version of "Dialog_func.c" in case it breaks something. The difference is that the code to return a stripped down description if the ship type contains a number is now commented out.
Thanks! I'll give it a try.

And I see your point about kill credit when multiple parties are going after the same prey. I wouldn't be happy if I'd spent time and effort wearing down a heavy man-o-war only to have it sunk by a lucky shot from some lugger.
 
I could always put 'GetShipDescribe' back to returning the short version. :p

Ideally, we'll need to figure out a way to return lower case only for those ship types which need it. The name "Centurion" should not really be lower case here.
 
By the way, for a Centurion class, 'refShip.SName' is "Centurion", so even the original version would have returned a full description. The next time you're asked to destroy a 3rd rate battleship, or anything else whose 'refShip.SName' contains a number, will tell you if it works properly.

A few descriptions in "RESOURCE\INI\TEXTS\ENGLISH\common.ini" already contain cannon numbers. This may be why the code was added to return only the basic description.
Code:
string = SoL1R1,"1st Rate Ship of the Line"
string = SoL1R2,"1st Rate Man O' War"
string = SoL1R3,"Man O' War"
string = SoL3R1,"64-Gun 3rd Rate"        // <---
string = SoL3R2,"3rd Rate Battleship"
string = SoL3R3,"Heavy Warship"
string = SoL3R4,"Heavy Battleship"
string = SoL4R1,"5th Rate Warship"
string = SoL4R2,"4th Rate Ship of the Line"
string = SoL4R3,"56-Gun 4th Rate"      // <---
string = SoL4R4,"60-Gun 4th Rate"      // <---
Of those, "SoL3R1" and "SoL4R3" don't seem to be used any more. At least, I can't find them in "Ships_init.c". But "SoL4R4" is used for "NL_Lineship". So with that end code commented out, you may be asked to hunt a "Dutch 60-gun 60-gun 4th rate". :facepalm Perhaps change the entry in "common.ini" to something like "4th rate Warship"? (And perhaps change the currently unused ones in case someone does use them later, as well as preserving the sequence.)
 
Back
Top