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

WIP Unique Ship/Captain Encounters

Indeed that is definitely a good place to start.
You can look at the governor.c dialog file. And also the very first function at the top of quests_common.c .
If you trace it from those points, you should get a pretty good idea of how that works.

For Random Town Events with Rumours, I think the code for that is somewhere in TownTable.c .

If you have any questions on it, I'll be near my computer during the weekend so can look at some code myself.
I've had a bit of a think through this feature and I've got some potential fancy ideas for later if you're interested.
But first things first. :cheeky
 
Actually, if I can get some code in place for rumour-based encounters then I could pretty much spawn them on a guaranteed basis, which would be great for testing. It’s quite reliable anyway with the pirates, I just had to look for warships and 9/10 times the Black Pearl was with them. :cheeky

I think for tonight I’m going to crack on with something else I had in mind - undead crew!

Alright, Black Pearl and Flying Dutchman now have cursed crew! :cool
 
Last edited:
As I said I have a few new characters listed in CommonQuest.c but I cannot seem to be able to load them.

This is throwing an error and was causing a CTD (I’ve prevented that, see here)...

ref char = CharacterFromID("HectorBarbossa")​

Does this require a new game or can I reinitialise the list (F11 doesn’t help)?
 
Last edited:
Unfortunately character init updates require a new game.
There is a way to initialize them through console though.
I think there's an example in Reinit.c
 
That’s what I figured. Therefore, the method I’ve been using so far, that is manipulating the fantoms as they are generated, is probably a good option if it is to be compatible with save games. Having said that, I’m looking at using FindFreeRandomOfficer() to place the characters onto a random guy who’s just sitting in some tavern getting drunk. It’s kind of working already, I just haven’t got so far as to spawn them yet. I even have a dump log for Davy Jones. :yes
 

Attachments

  • compile.log
    1.7 KB · Views: 119
Therefore, the method I’ve been using so far, that is manipulating the fantoms as they are generated, is probably a good option if it is to be compatible with save games.
I really do not care about savegame compatibility. All I care about is having the functionality as simple as possible and the code as clean as possible.

If necessary, Reinit.c can be updated to add the necessary characters in a savegame for you.
We've done that in the past, but I haven't bothered for a long time because supporting savegame compatibility is a lot of additional effort that I cannot afford to spend.
 
This is true, but when it comes to testing things it would be a royal pain to have to start a new game every time.
I’ll look at the reinit file, at least if I know something is working then it’s much less of a bother to make a new game.
 
I’ll look at the reinit file, at least if I know something is working then it’s much less of a bother to make a new game.
This is the section I was referring to:
Code:
  if(GetCharacterIndex("B_keeper") == -1)
   {
     n = FindBlankCharSlot();
     CHARACTERS_QUANTITY++; // NK 05-04-05
     if(n != -1)
     {
       makeref(ch,Characters[n]);
       ch.old.name = "Ye Keeper"; // MAXIMUS 16.10.2006
       ch.old.lastname = "o' ye Hoarde"; // MAXIMUS 16.10.2006
       ch.name    = TranslateString("","Ye Keeper");
       ch.lastname    = TranslateString("","o' ye Hoarde");
       ch.id     = "B_keeper";
       ch.model   = "admiral";
       ch.sex = "man";
       ch.act.type = "citizen";
       ch.location = "none";
       ch.location.group = "goto";
       ch.location.locator = "goto1";
       ch.dialog.filename = "B_hoardkeeper.c";
       ch.nation = ENGLAND;
       ch.rank    = 1;
       ch.reputation = "None";
       ch.experience = "0";

       ch.skill.Leadership = 6;
       ch.skill.Fencing = 3;
       ch.skill.Sailing = 4;
       ch.skill.Accuracy = 9;
       ch.skill.Cannons = 5;
       ch.skill.Grappling = 5;
       ch.skill.Repair = 6;
       ch.skill.Defence = 8;
       ch.skill.Commerce = 7;
       ch.skill.Sneak = 8;
       ch.money = 10;
       LAi_SetStayType(ch);
       LAi_SetHP(ch, 200.0, 200.0);
       if(show) Log_SetStringToLog(TranslateString("","BK Keeper initialised."));
     }
   }
Allows you to init new characters without starting a new game.
 
Oh, then I can just grab him and change his ID and stuff?

Anyway, I’ve got this far at least...

seadogs2_0002.tga.jpg

But I either see the exact same Spanish sloop show up every single time, or no ship at all. :unsure

I’ve simplified the function like so...
Code:
void GenerateQuestShip(string character_id, int iNation)
{
   ref PChar = GetMainCharacter()

   ref rFantom = characterFromID("HectorBarbossa")

   ref Shiptype   = GetShipByID(rFantom.Ship.Type)
   int iShipType   = Shiptype.index

   pchar.quest.generate_kill_quest         = "begin"
   pchar.quest.generate_kill_quest.money     = 50000
   pchar.quest.generate_kill_quest.town     = GetCurrentTownID()
   pchar.quest.generate_kill_quest.destination   = Islands[GetCharacterCurrentIsland(Pchar)].id
   pchar.quest.generate_kill_quest.nation     = PIRATE
   pchar.quest.generate_kill_quest.shipname   = rFantom.Ship.Name
}
I’ve replaced all occurrences of “Quest Pirate” in the governor dialogue file, that gets me as far as seeing the description for the Black Pearl. If I do the same in quests_common.c then that’s where I get no ship because “Story_Pirate“ or “Quest_ships” (I can’t remember which it was) came back as empty for some reason.

I can understand no ship showing up if something isn’t quite right, but I have no idea where it’s getting this sloop from. :shrug
 
Last edited:
I think I got this. I don’t need to reinit, the file which holds my characters is seemingly reloaded anyway so it has the same effect. Now I’m using FindBlankCharSlot() the ship has been spawned.

seadogs2_0000.tga.jpg seadogs2_0004.tga.jpg
 
All you should need to do is call the function to put the character you want at sea.
Follow the quest cases and you should find some sea group code that you need.
The regular Pirate Hunting uses the Quest Pirate ID, but you need it to use something else.

I'll try to come back with some details in an hour or so.
 
Looks like the end of the Standard Storyline now! :cheeky

This was, by the way, the code I was referring to:
Code:
       //NK, use fantom calls way up top.
       Group_AddCharacter("Story_Pirate", "Quest pirate");
       //Log_SetStringToLog("prepare_for_kill_pirate");
       Group_SetGroupCommander("Story_Pirate", "Quest pirate");
       Group_SetTaskAttack("Story_Pirate", PLAYER_GROUP, true);
       //Group_SetAddress("Story_Pirate", Characters[GetMainCharacterIndex()].location, "Quest_ships", "Quest_ship_3");
       Group_SetAddress("Story_Pirate", Pchar.location, "Quest_ships", GetRandomQuestShipLocator(pchar.location)); // PB: Add some variety

       Group_LockTask("Story_Pirate");

You could repurpose that for you like this:
Code:
       Group_AddCharacter("MM_Group1", "HectorBarbossa");
       Group_SetGroupCommander("MM_Group1", "HectorBarbossa");
       Group_SetAddress("MM_Group1", "Turks", "Quest_ships", GetRandomQuestShipLocator("Turks")); // PB: Add some variety
This will make Barbossa's ship appear at Turks on a random quest ship locator.
With some randomization, you can make different ships show up at different islands.

And this is how you can write something to the Tavern News:
Code:
string sLogTitle, sLogEntry;
sLogTitle = "Black Pearl sighted at Turks";
sLogEntry = "Captain Barbossa's feared ship has been sighted in the vicinity of Grand Turk.";
WriteNewLogEntry(sLogTitle, sLogEntry, "General", false);
 
For the moment I’m back to generating the ships at sea so that I can fine-tune it a bit more. Now that I understand the quest side of things better, when I look at it again it should be a doddle. I had two separate lists for the characters before but I’m trying use just one which would be compatible with both map encounters and quests.
 
I think if you use the approach I currently have in mind, you don't need to edit the existing generation codes at all.
It could all be handled through a daily call to one function and then your own function could handle everything else together with ordinary quest coding.
Only thing is you probably couldn't generate them as worldmap encounters.
But if there is Tavern News to mention the island, then you may not even want that.
 
My script can be used by both, that is entirely the idea.

I suppose I could upload it now, and another shot of Hector going down. :yes

seadogs2_0001.tga.jpg
 

Attachments

  • Unique.7z
    102.6 KB · Views: 101
Last edited:
I actually have dynamic music in place for unique pirate encounters (nothing yet if they’re navy, like Horatio Nelson). :diomed

So if I go into battle and the Black Pearl is there, the storm music will play. If I sink her, the victory music is different but if she escapes then it’s the usual fanfare. If I catch her again then it reverts back to the storm music. This is always reset after returning to the map. If I’m a pirate, and certainly if the unique character is not hostile (else the storm music plays), then the “Yo-Ho-Ho” song will be playing. Again, in the case of the latter the music will revert back to normal after leaving the sea, so if I go to battle as a pirate against normal ships then generic music will be used.

My next move is to look at the inventories for the characters and also their crew. I will at least give them more appropriate weapons, maybe some armour as well to beef them up (although they have about 500 health anyway due to the rank of the characters), and I will also look at applying a better chance to find rarer items. I’m also considering the risk of becoming cursed by setting foot on the Black Pearl or the Flying Dutchman.
 
Getting cursed that way sounds weird to me.

The Curse of Davy Jones that we have in the game locks you out from land.
But that should affect only the captain of the Flying Dutchman and therefore only happens if you start the game as Davy Jones.

The cursed coins technically should curse you only if you take one from the chest on Isla de Muerta.
To make that feature more visible, in the game it can also happen if you find such a coin anywhere else IF the curse is in effect (differs per storyline).
But just setting foot on the Pearl shouldn't do it.
 
Thinking more about it, there are two things that might make sense:

- Have some cursed coins in the Black Pearl's weapons locker or captain's chest for the player to
Loot.
- Give the Chest of Davy Jones to the player if you kill the Dutchman's Captain.
(This one will be SO annoying for the players! But IS movie accurate. :whipa )
 
Back
Top