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

ship generation depending on player ship

Tingyun

Corsair
Storm Modder
In AIShip, there is a ship generation function that uses the player's ship tier, and caps the AI ship generated at 1 bigger or smaller than that.

When I was debugging perks and staring at compile logs, I noticed that ships were being generated within this +1 -1 tier range, so very possibly it was this function (or another like it). This was just sitting in town, not starting quests, so I'm assuming it was some normal ship. Or was it instead some quest ship that I wasn't aware of? I hadn't started any quests, but maybe one was around from some means I am unaware of.

Or maybe make it somehow dependent on the GetShipCap() setting from internal settings, like elsewhere? This one seems to bypass that setting, which seems odd.

Here is the lines I am speaking of, and the full code below:

rCharacter.ship.type = GetShipID(Force_GetShipType(GetCharacterShipClass(GetMainCharacter()) - 1, GetCharacterShipClass(GetMainCharacter()) +1, ftype, sti(rCharacter.nation)));

Code:
void Ship_Add2Sea(int iCharacterIndex, bool bFromCoast, string sFantomType)
{
  if (iCharacterIndex<0) return;
  ref rCharacter = GetCharacter(iCharacterIndex);
  if (CharacterIsDead(rCharacter))
  {
    TraceAndLog("Ship_Add2Sea ERROR: Please post your compile.log file at piratesahoy.net!");
    Trace("Trying to log in dead captain:");
    DumpAttributes(rCharacter);
    return;
  }
  aref arCharacter; makearef(arCharacter, Characters[sti(rCharacter.
index)]);
  DeleteAttribute(arCharacter,"skillsnatmult"); // NK PRS3 04-09-15 as lookup to speed up national skill mult
  DeleteAttribute(arCharacter,"ship.changedammo"); // NK 04-09-15 clears "we already changed ammo this round" attribute
  DeleteAttribute(arCharacter,"ship.lasttgt"); // NK 04-09-16 clears "we last fired on this char idx" attribute
  DeleteAttribute(arCharacter,"ship.attackpcharset"); // NK 04-09-16 clears "we're already set to attack pchar" attribute
  DeleteAttribute(arCharacter,"seatime"); // NK 04-09-16 deletes seatime tree
  DeleteAttribute(arCharacter,"surrendered"); // NK surrender 05-04-20
  DeleteAttribute(arCharacter,"oldnation");
// KK -->
  DeleteAttribute(arCharacter, "nation.known");
  DeleteAttribute(arCharacter, "unknownShip");
// <-- KK
  if (iCharacterIndex == GetMainCharacterIndex()) { // NK 04-09-16 clears timer attribute, -21 for updatetime
    rCharacter.seatime = 0;
    rCharacter.lastupdateseatime = 0;
  }
  //trace("starting sa2s for " + rCharacter.id + " and prev numships " + iNumShips+ ", did delete attr");

  int iShipType = GetCharacterShipType(rCharacter); // PS
  if (iShipType < 0 || iShipType >= SHIP_TYPES_QUANTITY_WITH_FORT)
  {
    Trace("Character.id = " + rCharacter.id + ", have invalid ship type = " + iShipType + ", and try load to sea");
    //return; // NK 04-09-12 fix so you never crash on bad ship type. -->
    if(!LAi_IsDead(rCharacter))
    {
      if(DEBUG_CAPTAIN_CREATION>1) Trace("CAPTAIN CREATION: Resetting stuff for "+rCharacter.id+" because it isn't dead");
      if(sti(rCharacter.nation) == PIRATE) rCharacter.fantomtype = "pirate"; //SCREWFACE : PIRATE is a nation - type is "pirate";
      string ftype = "war"; if(CheckAttribute(rCharacter,"fantomtype")) ftype = rCharacter.fantomtype;
      rCharacter.ship.type = GetShipID(Force_GetShipType(GetCharacterShipClass(GetMainCharacter()) - 1, GetCharacterShipClass(GetMainCharacter()) +1, ftype, sti(rCharacter.nation)));
      iShipType = GetCharacterShipType(rCharacter);
      LAi_Create_Officer(0, rCharacter); // NK
      Fantom_SetRandomMoney(rCharacter, ftype);
      Fantom_SetCannons(rCharacter, ftype);
      Fantom_SetSails(rCharacter, ftype);
    }
    // NK <--
  }
 
Last edited:
Also, I might be reading it wrong, but it goes to the createofficer function instead of createcaptain? The last line below.

rCharacter.ship.type = GetShipID(Force_GetShipType(GetCharacterShipClass(GetMainCharacter()) - 1, GetCharacterShipClass(GetMainCharacter()) +1, ftype, sti(rCharacter.nation)));
iShipType = GetCharacterShipType(rCharacter);
LAi_Create_Officer(0, rCharacter); // NK
 
Last edited:
it should never get in that place anyways ...
as far as I know this is only a failsafe to prevent erros. Did you get the message of "Character,id = ..... has invalid ship type .. etc" ?
 
No, but I saw a "ship generated between tier 5 and tier 7" note in the compile log while watching perk selection. Not sure why it was called. I was a tier 6 ship at the time, just walking to the tavern to hire test officers. Not doing anything else or playing.

It could also be a different function, thst happened to fall in the range of plus 1 and minus 1 by sheer chance.

Since it is a failsafe, would there be any harm in changing it to 1, 8, and then changing it so it calls the createcaptain function properly instead of the createofficer one? At least having it use the createcaptain function seems to make sense, on the chance that an error does call it.
 
That's probably because of the force_ship_type. could very well be from smugglers for example. Did you stay a night in the tavern or something like that?
 
No, just started a new game and walked to the tavern. Did not do anything else, I was starting new characters all the time because I am not certain about save compatibility with changing the perk assignment catagories (I was testing differnt ones to try to achieve the effects we discussed).

So, nothing but new game, walk to tavern.
 
No, just started a new game and walked to the tavern. Did not do anything else, I was starting new characters all the time because I am not certain about save compatibility with changing the perk assignment catagories (I was testing differnt ones to try to achieve the effects we discussed).

So, nothing but new game, walk to tavern.
new game will also trigger some island maintenance probably.
Set the smuggling debug to a higher value, then you can see why the ship is created
 
I'll do so and watch for it, if you say this isn't called except for errors, it will probably have been the smuggling thing or something. :)

Since this is intended as a failsafe, shouldn't we swap out
LAi_Create_Officer(0, rCharacter); // NK

with the new captain creation function call, or is it not that easy to just cut and paste? Just curious.

Obviously fixing the quest ship generation is a higher priority, just curious how this works. :)
 
Back
Top