I have been experiencing a pretty bad bug recently. I don't know in which game version it was introduced, but it is in my current game version. The bug occurs when a ship has more cargo than it can hold, so this most applies to smaller ships. The problem originally manifested itself with the two Cutters and could be circumvented by increasing their cargo capacity. It turned out that this problem got caused by my GiveShip2Character function. If you have a big ship and give yourself a different one, the cargo of the previous ship is kept. So if you go from a big ship to a small ship, you still have the cargo of the big ship, which the small ship cannot hold. The result is a crash to desktop on the changing of the day on the worldmap.
To fix this, I added some auto supply code (=simplified auto buy code from the store) into the GiveShip2Character function:<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->void GiveShip2Character(ref char, string shiptype, string shipname, int nat, bool hirecrew, bool getsupplies)
{
int i;
char.ship.type = shiptype;
char.ship.name = shipname;
aref arship; makearef(arship, char.ship); DeleteAttribute(arship,"stats");
SetRandomStatsToShip(arship, GetCharacterShipType(char), nat);
ResetCannons(char);
DeleteAttribute(&char,"ship.masts");
ProcessSailRepair(&char,100.0);
ProcessHullRepair(&char, 100.0);
if(hirecrew || sti(GetCrewQuantity(&char)) > sti(GetMaxCrewQuantity(&char))) SetCrewQuantity(&char, GetMaxCrewQuantity(&char));
if(getsupplies || sti(GetCargoLoad(&char)) > sti(GetCargoMaxSpace(&char)))
{
for(i=0;i<GOODS_QUANTITY;i++)
{
int getQty = 0;
if(i == GOOD_WHEAT && FOOD_ON)
{
getQty = 1+makeint(makefloat(GetCrewQuantity(&char)) * FOOD_PER_CREW * WHEAT_DAYS);
}
if(i == GOOD_RUM && FOOD_ON)
{
getQty = 1+makeint(makefloat(GetCrewQuantity(&char)) * FOOD_PER_CREW * RUM_DAYS);
}
if(i == GOOD_GUNPOWDER && CANNONPOWDER_MOD && GetMaxCannonQuantity(&char) > 0)
{
ref rCannon; makeref(rCannon,Cannon[GetCaracterShipCannonsType(&char)]);
int needPwdr = 0;
float averageQty = 0.0;
if (USE_REAL_CANNONS) { averageQty = makefloat(GetCargoGoods(&char,GOOD_BALLS) + GetCargoGoods(&char,GOOD_GRAPES) + GetCargoGoods(&char,GOOD_KNIPPELS))/3; }
else { averageQty = makefloat(GetCargoGoods(&char,GOOD_BALLS) + GetCargoGoods(&char,GOOD_GRAPES) + GetCargoGoods(&char,GOOD_KNIPPELS) + GetCargoGoods(&char,GOOD_BOMBS))/4; }
float canCharge = makefloat(averageQty/makefloat(GetMaxCannonQuantity(&char)));
if(CheckAttribute(rCannon,"gunpowder")) needPwdr = sti(rCannon.gunpowder);
getQty = makeint((makefloat(GetMaxCannonQuantity(&char)) * needPwdr * canCharge) + (makefloat(GetCrewQuantity(&char)) * 3));
}
if(i == GOOD_BALLS)
{
getQty = makeint(makefloat(GetMaxCannonQuantity(&char)) * BALLS_PER);
}
if(i == GOOD_GRAPES)
{
getQty = makeint(makefloat(GetMaxCannonQuantity(&char)) * GRAPE_PER);
}
if(i == GOOD_KNIPPELS)
{
getQty = makeint(makefloat(GetMaxCannonQuantity(&char)) * CHAIN_PER);
}
if(i == GOOD_BOMBS && USE_REAL_CANNONS)
{
getQty = makeint(makefloat(GetMaxCannonQuantity(&char)) * BOMBS_PER);
}
if(i == GOOD_SAILCLOTH)
{
getQty = makeint(makefloat(GetCharacterShipHP(&char)) * SAIL_PER);
}
if(i == GOOD_PLANKS)
{
getQty = makeint(makefloat(GetCharacterShipHP(&char)) * PLANKS_PER);
}
string goodsName = Goods.name;
char.Ship.Cargo.Goods.(goodsName) = getQty;
}
}
}<!--c2--></div><!--ec2-->
This seems to have partly fixed it, but now I find out that the problem is even more complicated. I can even cause this same problem without using the GiveShip2Character function at all. If I get myself a Gunboat and perform an auto buy at the store, I get the exact same problem. If I dump all cargo, I don't have that problem. Apparently some of the small ships simply cannot hold as much cargo as they need for ammunition, gunpowder, food and rum. Can anybody replicate this bug in his/her game version? Just buy a Gunboat, perform an Auto Buy at the Store, then go to the worldmap and wait until the changing of the day. Please report here which game version you have and whether you experience this problem or not.
To fix this, I added some auto supply code (=simplified auto buy code from the store) into the GiveShip2Character function:<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->void GiveShip2Character(ref char, string shiptype, string shipname, int nat, bool hirecrew, bool getsupplies)
{
int i;
char.ship.type = shiptype;
char.ship.name = shipname;
aref arship; makearef(arship, char.ship); DeleteAttribute(arship,"stats");
SetRandomStatsToShip(arship, GetCharacterShipType(char), nat);
ResetCannons(char);
DeleteAttribute(&char,"ship.masts");
ProcessSailRepair(&char,100.0);
ProcessHullRepair(&char, 100.0);
if(hirecrew || sti(GetCrewQuantity(&char)) > sti(GetMaxCrewQuantity(&char))) SetCrewQuantity(&char, GetMaxCrewQuantity(&char));
if(getsupplies || sti(GetCargoLoad(&char)) > sti(GetCargoMaxSpace(&char)))
{
for(i=0;i<GOODS_QUANTITY;i++)
{
int getQty = 0;
if(i == GOOD_WHEAT && FOOD_ON)
{
getQty = 1+makeint(makefloat(GetCrewQuantity(&char)) * FOOD_PER_CREW * WHEAT_DAYS);
}
if(i == GOOD_RUM && FOOD_ON)
{
getQty = 1+makeint(makefloat(GetCrewQuantity(&char)) * FOOD_PER_CREW * RUM_DAYS);
}
if(i == GOOD_GUNPOWDER && CANNONPOWDER_MOD && GetMaxCannonQuantity(&char) > 0)
{
ref rCannon; makeref(rCannon,Cannon[GetCaracterShipCannonsType(&char)]);
int needPwdr = 0;
float averageQty = 0.0;
if (USE_REAL_CANNONS) { averageQty = makefloat(GetCargoGoods(&char,GOOD_BALLS) + GetCargoGoods(&char,GOOD_GRAPES) + GetCargoGoods(&char,GOOD_KNIPPELS))/3; }
else { averageQty = makefloat(GetCargoGoods(&char,GOOD_BALLS) + GetCargoGoods(&char,GOOD_GRAPES) + GetCargoGoods(&char,GOOD_KNIPPELS) + GetCargoGoods(&char,GOOD_BOMBS))/4; }
float canCharge = makefloat(averageQty/makefloat(GetMaxCannonQuantity(&char)));
if(CheckAttribute(rCannon,"gunpowder")) needPwdr = sti(rCannon.gunpowder);
getQty = makeint((makefloat(GetMaxCannonQuantity(&char)) * needPwdr * canCharge) + (makefloat(GetCrewQuantity(&char)) * 3));
}
if(i == GOOD_BALLS)
{
getQty = makeint(makefloat(GetMaxCannonQuantity(&char)) * BALLS_PER);
}
if(i == GOOD_GRAPES)
{
getQty = makeint(makefloat(GetMaxCannonQuantity(&char)) * GRAPE_PER);
}
if(i == GOOD_KNIPPELS)
{
getQty = makeint(makefloat(GetMaxCannonQuantity(&char)) * CHAIN_PER);
}
if(i == GOOD_BOMBS && USE_REAL_CANNONS)
{
getQty = makeint(makefloat(GetMaxCannonQuantity(&char)) * BOMBS_PER);
}
if(i == GOOD_SAILCLOTH)
{
getQty = makeint(makefloat(GetCharacterShipHP(&char)) * SAIL_PER);
}
if(i == GOOD_PLANKS)
{
getQty = makeint(makefloat(GetCharacterShipHP(&char)) * PLANKS_PER);
}
string goodsName = Goods.name;
char.Ship.Cargo.Goods.(goodsName) = getQty;
}
}
}<!--c2--></div><!--ec2-->
This seems to have partly fixed it, but now I find out that the problem is even more complicated. I can even cause this same problem without using the GiveShip2Character function at all. If I get myself a Gunboat and perform an auto buy at the store, I get the exact same problem. If I dump all cargo, I don't have that problem. Apparently some of the small ships simply cannot hold as much cargo as they need for ammunition, gunpowder, food and rum. Can anybody replicate this bug in his/her game version? Just buy a Gunboat, perform an Auto Buy at the Store, then go to the worldmap and wait until the changing of the day. Please report here which game version you have and whether you experience this problem or not.