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

Fixed Problems with ship in Havana in "Ardent"

Grey Roger

Sea Dog
Staff member
Administrator
Storm Modder
In "Ardent", you escape from prison, rescue your crew from the slave camp, return to Havana, then you go to the tavern to find out about the payroll ship while your crew go to the port to steal a ship. When you get to port, they've stolen a war tartane (the smallest ship I could find which has a deck, so the 30 or so crew you rescued could perhaps fit inside). The ship is supposed to be unarmed, assigned so:
Code:
GiveShip2Character(PChar,"TartaneWar","Esme",CANNON_TYPE_NONECANNON,SPAIN,false,false);
That's never stuck properly; when you put to sea, the ship somehow acquires cannons, but you have no ammo so you're still unarmed. With that proviso, it's worked fine.

But not in the 23rd September update. When I put to sea, the first thing I noticed was that the framerate was abysmally slow - I can't measure exact framerate but it was visibly choppier than normal. The next thing I noticed was that my food had disappeared, which meant that when the hour changed, crew starved and morale dropped. See first attached savegame.

"error.log" shows a lot of reports which seem to be something to do with cannons. So I changed the line to:
Code:
GiveShip2Character(PChar,"TartaneWar","Esme",CANNON_TYPE_LONG_LBS4,SPAIN,false,true);
Now when I put to sea, the port cannons are loaded but the starboard cannons aren't. The food has still disappeared. Even more weird: now I have cannons and ammo, I can press "1" to reload the guns, all guns now load - and the food reappears! And for final weirdness, if I fire the guns, there's the yell from the crewman, the bar at the side of the compass goes down to show guns firing, and there's a total lack of bangs or smoke and fire from the ship's side. See second attached savegame. (I had another savegame from just before I went to the port, which is how I have two savegames in port, one before and one after the code change.)

None of the above happens in the basic 28th July version. I can go to the store to buy cannonballs and ammo, the ship somehow acquires cannons when I put to sea, they're all properly loaded, I still have food, and when I fire the cannons there are proper bangs, flashes and smoke. So whatever is fouling things up, it's in the 23rd September update.
 

Attachments

  • compile.log
    4.6 KB · Views: 207
  • error.log
    92.5 KB · Views: 209
  • system.log
    1.2 KB · Views: 200
  • -=Player=- Cuba.zip
    611.1 KB · Views: 194
  • -=Player=- Cuba2.zip
    609.5 KB · Views: 177
Uhm.... @Levis, any clue what's going on there? :shock

The ship is supposed to be unarmed, assigned so:
Code:
GiveShip2Character(PChar,"TartaneWar","Esme",CANNON_TYPE_NONECANNON,SPAIN,false,false);
That's never stuck properly; when you put to sea, the ship somehow acquires cannons
I don't think I ever took that possibility into account.
Probably the GiveShip2Character function is currently giving you a maximum number of cannons of type "none", which of course makes no sense. :facepalm
 
I had these same problems when working on the captain generation. I thought it was due to my captains first not initializing right and i fixed it by giving them an extra attribute, but it looks like something worse broke :S.
When assigning a ship to a captain with no cannons it indeed does a lot of strange things because a certain function isn't called. if you give a certain attribute to the character it will be called and everything is set right. but now you say there is more wrong?

I have to look into this more closely, just one quick question @Grey Roger this is a new savegame right? you didn't bypass the savegame compatibility right?
 
It's supposed to assign the ship to me, not to a NPC captain. Captain generation should not be involved. ;)

The problem happens even when I change the command so that the ship does have cannons right from the start:
So I changed the line to:
Code:
GiveShip2Character(PChar,"TartaneWar","Esme",CANNON_TYPE_LONG_LBS4,SPAIN,false,true);
Having used the workaround of pressing "1" to reload the cannons, I then continued the storyline by sailing to Santiago. You're supposed to steal another ship there, which is given to you thus:
Code:
GiveShip2Character(PChar,"Shnyava2","Tonina",CANNON_TYPE_CARRONADE_LBS12,SPAIN,false,true);
That one worked correctly. So it only seems to be the "TartaneWar" which is causing trouble.
I have to look into this more closely, just one quick question @Grey Roger this is a new savegame right? you didn't bypass the savegame compatibility right?
Yes. Fresh install - I have a copy of a stock game installation whose only purpose is to be copied to a new folder as a base for a new install, this being a lot quicker than a genuine fresh install from CD. The 28th July installer went on top of that, then the 23rd September zip file followed. Then I started a whole new game. What I do have is a savegame from just before I went to Havana port, so I changed the code to assign the ship with 4lb cannon and auto-supply enabled, then loaded that savegame and continued to port, with the results described above.
 
hmmm....if what you describe is true it could very well be in the tartane indeed.

The without guns I can confirm, and I will fix that very soon(ish).
For now you will probably fix it by setting this for pchar:

pchar.ship.cannons.borts = true;

if you set that attribute before using the GiveShip2Character and after it you set:

pchar.ship.cannons.Charge.Type = GOOD_BALLS;

it will probably work without any problems.
 
Last edited:
Here is determined how the cannons are done:
Code:
if (cannon_type != CANNON_TYPE_NONECANNON) {
        ResetCannons(char);
        if (cannon_type < 0 || cannon_type >= CANNON_TYPES_QUANTITY) cannon_type = sti(rShip.Cannon);
/*        int max_caliber = sti(rShip.MaxCaliber);
        int cannon_model = GetCannonType(cannon_type);
        if (sti(GetAttribute(Cannon[cannon_type],"caliber")) > max_caliber) {
            string sCannonType = "long gun";
            if (cannon_model == CANNON_NAME_CARRONADE) sCannonType = "carronade";
            cannon_type = GetCannonByTypeAndCaliber(sCannonType, max_caliber);
        }*/
        char.Ship.Cannons.Type = cannon_type;
    } else {
        SetNoneCannonsOnShip(char);
    }
This happens if there are no cannons:
Code:
void SetNoneCannonsOnShip(ref ch)
{
    if (!CheckAttribute(ch,"ship.cannons.borts")) return;
    aref arship; makearef(arship, ch.Ship);
    ch.Ship.Cannons.Borts.cannonf.qty = 0;
    ch.Ship.Cannons.Borts.cannonb.qty = 0;
    ch.Ship.Cannons.Borts.cannonl.qty = 0;
    ch.Ship.Cannons.Borts.cannonr.qty = 0;
    ch.Ship.Cannons.Type = CANNON_TYPE_NONECANNON;
}
compare to this one if there are cannons:
Code:
void ResetCannons(ref ch)
{
    if(!CheckAttribute(ch,"ship.cannons.borts")) return;
    aref arship; makearef(arship, ch.ship);
    ref rship = GetShipByType(GetCharacterShipType(ch));
    ch.ship.cannons.borts.cannonf.qty = GetLocalShipAttrib(&arship, &rship, "cannons.borts.cannonf.qty");
    ch.ship.cannons.borts.cannonb.qty = GetLocalShipAttrib(&arship, &rship, "cannons.borts.cannonb.qty");
    ch.ship.cannons.borts.cannonl.qty = GetLocalShipAttrib(&arship, &rship, "cannons.borts.cannonl.qty");
    ch.ship.cannons.borts.cannonr.qty = GetLocalShipAttrib(&arship, &rship, "cannons.borts.cannonr.qty");
}

The problem I had with captains was the check in ResetCannons which made it return the function instantly. This might be the case for your character too.

Note that his function hasn't be changed since the 4.1 release, so if something is making it react differently then before it seems to be the fixes @Pieter Boelen and I attempted in the cargo functions which probably are called in SupplyShip()
 
This happens if there are no cannons:
Code:
void SetNoneCannonsOnShip(ref ch)
{
if (!CheckAttribute(ch,"ship.cannons.borts")) return;
aref arship; makearef(arship, ch.Ship);
ch.Ship.Cannons.Borts.cannonf.qty = 0;
ch.Ship.Cannons.Borts.cannonb.qty = 0;
ch.Ship.Cannons.Borts.cannonl.qty = 0;
ch.Ship.Cannons.Borts.cannonr.qty = 0;
ch.Ship.Cannons.Type = CANNON_TYPE_NONECANNON;
}
Maybe remove these two lines then?
Code:
  if (!CheckAttribute(ch,"ship.cannons.borts")) return;
  aref arship; makearef(arship, ch.Ship);
They look quite superfluous as they aren't used anywhere. But they can abort the function, probably unintentionally.

the fixes @Pieter Boelen and I attempted in the cargo functions
What did I recently do in the cargo funcions? :unsure
 
Maybe remove these two lines then?
Code:
  if (!CheckAttribute(ch,"ship.cannons.borts")) return;
  aref arship; makearef(arship, ch.Ship);
They look quite superfluous as they aren't used anywhere. But they can abort the function, probably unintentionally.


What did I recently do in the cargo funcions? :unsure
The crashes on the world map concerning a function which could end up in and endless loop. i remeber fixing that but I believe afterwards you sugested something else also or found it to be somewhere else also. But I don't remember exactly.
 
The old problem with assigning the ship to have no cannons is that, when I put to sea, it has cannons anyway. Will 'pchar.ship.cannons.borts = true;' fix that?

The problem with food disappearing is new - it only happens in the 23rd September update, not in the 28th July version. It happens even if I have changed the quest code so that the ship is assigned with 4lb cannons and with supplies automatically loaded. It gets an additional 1 food and 1 rum, plus the quest code gives 3 food and 2 rum, so the second savegame should show a ship with 4lb guns, ammo for them, and a total of 4 food and 3 rum. Then you put to sea and the food disappears.
 
The crashes on the world map concerning a function which could end up in and endless loop. i remeber fixing that but I believe afterwards you sugested something else also or found it to be somewhere else also. But I don't remember exactly.
Can't remember now. I didn't change anything, that much I do remember.

The old problem with assigning the ship to have no cannons is that, when I put to sea, it has cannons anyway. Will 'pchar.ship.cannons.borts = true;' fix that?
For that, please try again in the 28 July 2016 version, but with the two lines removed as suggested in post #7 above.
With a bit of luck, that will help.

@Levis: Do you have any idea why that "ship.cannons.borts" check is in place?
It seems quite weird to me, since if a character has never had a ship before, wouldn't that unintentionally abort the function?
 
This is what supplyship does:
Code:
void SupplyShip(ref char)
{
    float SupplyScalar = SupplyScalarByCharacter       (char);
    float crewQty      = makefloat(GetCrewQuantity     (char));
    float canQty       = makefloat(GetMaxCannonQuantity(char));
    float shipHP       = makefloat(GetCharacterShipHP  (char));
    if(FOOD_ON)                AddCharacterGoods(char, GOOD_WHEAT   , 1+makeint(crewQty * FOOD_PER_CREW * WHEAT_DAYS * SupplyScalar));
    if(FOOD_ON)                AddCharacterGoods(char, GOOD_RUM     , 1+makeint(crewQty * FOOD_PER_CREW * RUM_DAYS   * SupplyScalar));
                            AddCharacterGoods(char, GOOD_BALLS   ,   makeint(canQty  * BALLS_PER                  * SupplyScalar));
                            AddCharacterGoods(char, GOOD_GRAPES  ,   makeint(canQty  * GRAPE_PER                  * SupplyScalar));
                            AddCharacterGoods(char, GOOD_KNIPPELS,   makeint(canQty  * CHAIN_PER                  * SupplyScalar));
    if(!USE_REAL_CANNONS)    AddCharacterGoods(char, GOOD_BOMBS   ,   makeint(canQty  * BOMBS_PER                  * SupplyScalar));
    if(CANNONPOWDER_MOD && canQty > 0.0)
    {
        int PowderPerShot = 0;
        ref rCannon; makeref(rCannon,Cannon[GetCaracterShipCannonsType(char)]);
        int shotQty = GetCargoGoods(&char,GOOD_BALLS) + GetCargoGoods(&char,GOOD_GRAPES) + GetCargoGoods(&char,GOOD_KNIPPELS) + GetCargoGoods(&char,GOOD_BOMBS);
        if(CheckAttribute(rCannon,"gunpowder")) PowderPerShot = sti(rCannon.gunpowder);
        AddCharacterGoods(char, GOOD_GUNPOWDER, makeint(POWDER_PER * shotQty * PowderPerShot * SupplyScalar));
    }
    AddCharacterGoods(char, GOOD_SAILCLOTH, makeint(shipHP * SAIL_PER   * SupplyScalar));
    AddCharacterGoods(char, GOOD_PLANKS   , makeint(shipHP * PLANKS_PER * SupplyScalar));
}

I had to change teh SetCharacterGoods function to prevent a nasty crash. so only thing I can imagine is that this did it. Nothing else has been changed since 4.1 release as far as I can see.
But that should only make sure the quantity of 0 can't be set for goods ....
I will take a look with a clean savegame aswell if I can find out what is happening here....
 
@Levis: Do you have any idea why that "ship.cannons.borts" check is in place?
It seems quite weird to me, since if a character has never had a ship before, wouldn't that unintentionally abort the function?

I think it's there because the function originally was used for other things as well and prevented cannons to be set when there are no cannons. But this is managed by other checks by now. That's my guess at least.
 
Am I right in thinking that 'SupplyShip' is used to generate the automatic supplies provided by auto-buy, and by assigning a ship using 'GiveShip2Character' with the last argument set to "true"? If so, that's not the problem - originally I had it set to "false" so 'SupplyShip' wouldn't have been used, while my attempted fix by changing it to "true" resulted in the ship getting a proper load of supplies.

What's not working is when I put to sea. That's when the cannons start acting silly, and when the food disappears.

The problem with the ship starting out with "CANNON_TYPE_NONECANNON" and then gaining guns when it puts to sea is minor, it's been there pretty much since the start, and hasn't caused trouble before.

The real problem is the disappearing food. The other real problems are that even if the ship is given "CANNON_TYPE_LONG_LBS4" and correctly shows them when at sea, they don't load correctly at once, and don't fire after you've reloaded them. These are all related to the 23rd September update, as they don't happen in the 28th July install. So...
For that, please try again in the 28 July 2016 version, but with the two lines removed as suggested in post #7 above.
With a bit of luck, that will help.
... I can try that, but it won't solve the big problems because the big problems don't happen in the 28th July version.
 
The problem with the ship starting out with "CANNON_TYPE_NONECANNON" and then gaining guns when it puts to sea is minor, it's been there pretty much since the start, and hasn't caused trouble before.
It is still unintentional and I was hoping my suggestion would solve at least that.

... I can try that, but it won't solve the big problems because the big problems don't happen in the 28th July version.
That's for @Levis to figure out then, I'm afraid. I'm still on 28th July myself.
 
as soon as I'm home I can look into this but for now I can't explaint it because as far as I know nothing concerning the cannons is changed ... so it must be somewhere in a deep function... I need to dive into that.
 
So @Grey Roger if I understand right:
GiveShip2Character(PChar,"TartaneWar","Esme",CANNON_TYPE_NONECANNON,SPAIN,false,false);
Generatest the ship BUT you have all kind of weird errors AND the food has dissapaired?
Questions: you didn't generate food during the process so you added the food yourself? Which commands did you use? Did the character used to have a ship before? If so how was this ship removed?


GiveShip2Character(PChar,"TartaneWar","Esme",CANNON_TYPE_LONG_LBS4,SPAIN,false,true);
Generates the ship right but some cannons aren't loaded right. After a reload the cannons do reload right but only after this reloading the food you assigned yourself AND the food generated by this function is gone.
Questions How did you add the food and how many?

GiveShip2Character(PChar,"Shnyava2","Tonina",CANNON_TYPE_CARRONADE_LBS12,SPAIN,false,true);
isn't giving any problems at all.
 
Here's the entire quest case:
Code:
     case "port_gate":
       RestoreOfficers(PChar.id);
//       GiveShip2Character(PChar,"TartaneWar","Esme",CANNON_TYPE_NONECANNON,SPAIN,false,false);
       GiveShip2Character(PChar,"TartaneWar","Esme",CANNON_TYPE_LONG_LBS4,SPAIN,false,true);
       DeleteAttribute(PChar, "isnotcaptain");
       AddCharacterGoods(PChar, GOOD_RUM, 2);
       AddCharacterGoods(PChar, GOOD_WHEAT, 3);
       AddCharacterGoods(PChar, GOOD_SAILCLOTH, 3);
       AddCharacterGoods(PChar, GOOD_PLANKS, 6);
       SetCrewQuantity(PChar, sti(PChar.quest.crew_left));
       setCharacterShipLocation(Pchar, "Cuba_port");
     break;

So:
So @Grey Roger if I understand right:
GiveShip2Character(PChar,"TartaneWar","Esme",CANNON_TYPE_NONECANNON,SPAIN,false,false);
Generatest the ship BUT you have all kind of weird errors AND the food has dissapaired?
Questions: you didn't generate food during the process so you added the food yourself? Which commands did you use? Did the character used to have a ship before? If so how was this ship removed?
The food (and other supplies) are added by the 'AddCharacterGoods' lines.
The log files as included in the first post are created. The food disappears.

The character's original ship is removed very near the start of the game like this:
Code:
       DeleteAttribute(pchar, "Ship");
       pchar.Ship.Type = SHIP_NOTUSED_TYPE_NAME;
       pchar.Ship.Name = "";
       PChar.isnotcaptain = true;

Question: should I have the 'DeleteAttribute(PChar, "isnotcaptain")' line before the 'GiveShip2Character' line? The "Hornblower" storyline also sets the attribute and then deletes it after a 'GiveShip2Character' line, and that's always worked. Mind you, "Ardent" always worked before 23rd September too.

GiveShip2Character(PChar,"TartaneWar","Esme",CANNON_TYPE_LONG_LBS4,SPAIN,false,true);
Generates the ship right but some cannons aren't loaded right. After a reload the cannons do reload right but only after this reloading the food you assigned yourself AND the food generated by this function is gone.
Questions How did you add the food and how many?
This generates the ship correctly but only the cannons on one side are loaded. The food has disappeared. After reloading the cannons, the food is back. Auto-supply provides 1 each additional food and rum, plus the 3 and 2 added by my code, for a total of 4 food and 3 rum.

Also after loading, the cannons do not fire - that is, the crewman calls out, the bar beside the compass goes down, and ammo is removed, but there are no smoke, fire, sound, or cannonballs heading away from the ship.

GiveShip2Character(PChar,"Shnyava2","Tonina",CANNON_TYPE_CARRONADE_LBS12,SPAIN,false,true);
isn't giving any problems at all.
Correct.
 
Question: should I have the 'DeleteAttribute(PChar, "isnotcaptain")' line before the 'GiveShip2Character' line? The "Hornblower" storyline also sets the attribute and then deletes it after a 'GiveShip2Character' line, and that's always worked. Mind you, "Ardent" always worked before 23rd September too.
Should not matter. :no
 
For that, please try again in the 28 July 2016 version, but with the two lines removed as suggested in post #7 above.
With a bit of luck, that will help.
It didn't make any difference to the 28th July version. It did seem to make a difference in the 23rd September version, but probably not the way you expected.

Setting "CANNON_TYPE_NONECANNON" isn't enough. The ship now shows as having 8 cannons of type "None". Perhaps that function is supposed to correct this; if so, it fails. So I tried this:
Code:
       GiveShip2Character(PChar,"TartaneWar","Esme",CANNON_TYPE_NONECANNON,SPAIN,false,false);
       makearef(arShip, PChar.ship.stats);
       arship.CannonsQuantity = 0;
And that did it. The ship now really shows up as having no cannons, both right after it's been assigned while I'm standing in Port Royale port and after I put to sea.

In the 23rd September version, if the two lines in 'SetNoneCannonsOnShip' are removed, it also works in that the ship has no cannons, though the problem with food disappearing remains - and because I have no guns, I can't reload them to get the food back. If those lines are not removed then the game crashes when I put to sea.
 
Setting "CANNON_TYPE_NONECANNON" isn't enough. The ship now shows as having 8 cannons of type "None".
:rofl :rofl :rofl

Then how about this?
Code:
void SetNoneCannonsOnShip(ref ch)
{
//if (!CheckAttribute(ch,"ship.cannons.borts")) return;
//aref arship; makearef(arship, ch.Ship);
ch.Ship.Cannons.Borts.cannonf.qty = 0;
ch.Ship.Cannons.Borts.cannonb.qty = 0;
ch.Ship.Cannons.Borts.cannonl.qty = 0;
ch.Ship.Cannons.Borts.cannonr.qty = 0;
ch.Ship.Cannons.Type = CANNON_TYPE_NONECANNON;
ch.Ship.stats.CannonsQuantity = 0;
}

It didn't make any difference to the 28th July version. It did seem to make a difference in the 23rd September version
Unexpected indeed! :shock
 
Back
Top