NathanKell
...
On adding ships when using the PRS2 system (active since Build 10, or maybe 9. I forget. But, anyway, it's surely in 11.)
A ship for PRS2 must have the following things assigned.
*the ID. This must be unique to the ship. Also, you must add this to the ships lookup table.
*the model name.
*the type name (frigate, brig, etc.)
*the Battle Interface pic (the tiny pic you see during battle)
*the regular interface pic (the big pic you see in interfaces)
*a walk file, for the little people.
It may also have special NK/HFM toggles (see below).
Note that IDs, like any other string property, must be given in quotes. However, one may "add" (concatenate) strings together. And, for ships predating PRS2, to ease in my adding IDs, I took advantage of this to autogenerate them as the model name, and then, if the ship has a nation, an underscore and the nation number.
A note on the nation number. POTC uses numbers for nations.
These are defined in Globals.c, as follows:
What a #define does is tells the compiler to substitute the second piece for the first piece every time the first is found in code. So if, _outside quotes_, ENGLAND is found in a C file, 0 will be substituted on launching POTC.
So, I wrote the IDs as follows, accessing two `previously-defined` attributes of the ship (model name and nation)
ship.id = ship.name + "_" + ship.nation;
(which would lead, for the English Lugger2, to "Lugger2_0").
Now, the power of PRS2 for adding ships is that, for each of the properties above but the ID and model name, we can reference other ships for those properties, or use a special property (all) to make things even easier. The all property is set as the ID of another ship--note that this other ship must appear _above_ the new ship--and will use the above properties of that ship.
But you can also manually set other properties, in which case they'll overwrite the "all" call.
Note that if a property is not assigned, and refship.all is not assigned, then the property will default to the ship's model name. This is what happens for all stock POTC ships.
Note 2: If you want to add new entries to pictures.ini for the ship (and have the textures for those entries), you then set those properties (BIPic, the two BigPic ones) accordingly.
Here's how it works.
Let's say we're adding Catalina's Xebec CT. (ships_init.c)
First, we get a new ship in the array, and advance the counter.
Next, we give it an ID.
And add an entry to the ships lookup table based on that ID (this is required!)
Then, we assign a model directory.
Next, we tell it to get all properties from the English Xebec1:
But, we overwrite sname (it'll have a different type name).
NOTE: We must then add a XebecCT entry to common.ini!
Since the Xebec CT will be used by all nations, we do _not_ add a refShip.nation property. If we wanted it to be used only by pirates, however, we would add:
Note that PIRATE is _outside quotes_, and is thus changed to the integer 3 on running POTC, as it should. Make sure that if you add a nation to a ship the nation number define is _outside_ quotes.
Now, we can assign the regular ship properties. It's suggested you take an existing ship and copy/paste, and then change what stats you want to.
Now, we have to take the NK/HFM mod into account.
This mod makes some changes to every ship's stats, and assigns rig type and best / closest point of sail.
There are four ways to interface your ship with NK/HFM.
The first, and simplest, is to add nothing. Your ship will be processed based on its model name, as if it were a stock POTC ship. This XebecCT will processed like other Xebecs (Lateen rig, +3kts max speed, +5 degrees turn rate, war and trade type, accel and braking x0.25 and x0.1 respectively) if we add no switch.
Note that all ships receive the same accel/braking mods; however, type and stat changes, and rig assigns, are model name specific.
The switches available are:
No_NK_HFM
No_NK_HFM_modstats
No_NK_HFM_modaccel
No_NK_HFM_modtype
The first is the simplest. Just add
in your ship definition.
Note: if the first three letters of the ship's model name are not recognized by NK/HFM (i.e. no stock POTC ship model starts that way) you will have to add this switch!
HOWEVER: If you add this switch, you will have to add the above stuff manually or POTC will do weird things.
So, if you add that switch, you will need to divide your Z Accel by 4 and your Z braking by 10, and you will need to assign rig stats.
Rig stats are as follows.
First, there's rig type. This is based on the first three letters of the model's name (exception: Galeoth's rigtype is "Gat").
Then, there's closest and best point of sail. This is based on the type of masts and sails used, as follows:
So we'd use:
Note for the sailors: These are given as percents of max `off-wind`, so 1.0 is running before the wind and 0 is into the eye. The above are also _way_ generous.
And I'd love better numbers to use!
The other NK/HFM switches are to selectively disable pieces. So if you want rigtype assigns and accel changes to be done by NK/HFM but want the stats to stay unmodified and set the ship's type yourself (as we do for the Xebec CT) we would add the following:
That's it!
Description of specific properties added by PRS2:
These override refShip.name for each case
-Walk is for the big walktype switch in shipwalk.c. Case for this must exist there.
*This is autogenerated (= *.name) on final loop if it does not already exist.
-BIPic is the little pic in Battle Interface (i.e. when sailing). Case for this must exist in BI.c (battleinterface.c)
*This is autogenerated (= *.name) on final loop if it does not already exist.
-BigPic is the big pic name (in Ships, hold, shipyard, etc.) Must have matching entry in pictures.ini
*This is autogenerated (= *.name) on final loop if it does not already exist.
-BigPicTex is for GetShipTexture() and is -1 for unused, 1 for Galeoths (and BP/Fearless) and 0 for else.
*This is autogenerated (= 0) on final loop if it does not already exist.
-BigPicTexName is for GetShipTextureName() and is "", "SHIPS1", and "SHIPS16" respectively as above.
*This is autogenerated (= SHIPS16) on final loop if it does not already exist.
-SName is for the ship's type name (this is displayed by spyglass, and by BigPic in interfaces), so you can have the same model but a different name.
: This is NOT directly displayed; it is run through XI_ConvertString, so you must have an entry for this in langcommon.ini
*This is autogenerated (= *.name) on final loop if it does not already exist.
-All is for all the above properties, as a shortcut. If this exists, at final loop all above are set equal to this. For properties != name, the appropriate property is found from that ship. If some properties are already set, they will not be overwritten (i.e. set all to one but define walk, all but walk will be overwritten by all's link).
*THE SHIP LINKED TO MUST ALREADY HAVE BEEN PROCESSED!
A ship for PRS2 must have the following things assigned.
*the ID. This must be unique to the ship. Also, you must add this to the ships lookup table.
*the model name.
*the type name (frigate, brig, etc.)
*the Battle Interface pic (the tiny pic you see during battle)
*the regular interface pic (the big pic you see in interfaces)
*a walk file, for the little people.
It may also have special NK/HFM toggles (see below).
Note that IDs, like any other string property, must be given in quotes. However, one may "add" (concatenate) strings together. And, for ships predating PRS2, to ease in my adding IDs, I took advantage of this to autogenerate them as the model name, and then, if the ship has a nation, an underscore and the nation number.
A note on the nation number. POTC uses numbers for nations.
These are defined in Globals.c, as follows:
Code:
#define ENGLAND 0
#define FRANCE 1
#define SPAIN 2
#define PIRATE 3
#define HOLLAND 4
#define PORTUGAL 5
What a #define does is tells the compiler to substitute the second piece for the first piece every time the first is found in code. So if, _outside quotes_, ENGLAND is found in a C file, 0 will be substituted on launching POTC.
So, I wrote the IDs as follows, accessing two `previously-defined` attributes of the ship (model name and nation)
ship.id = ship.name + "_" + ship.nation;
(which would lead, for the English Lugger2, to "Lugger2_0").
Now, the power of PRS2 for adding ships is that, for each of the properties above but the ID and model name, we can reference other ships for those properties, or use a special property (all) to make things even easier. The all property is set as the ID of another ship--note that this other ship must appear _above_ the new ship--and will use the above properties of that ship.
But you can also manually set other properties, in which case they'll overwrite the "all" call.
Note that if a property is not assigned, and refship.all is not assigned, then the property will default to the ship's model name. This is what happens for all stock POTC ships.
Note 2: If you want to add new entries to pictures.ini for the ship (and have the textures for those entries), you then set those properties (BIPic, the two BigPic ones) accordingly.
Here's how it works.
Let's say we're adding Catalina's Xebec CT. (ships_init.c)
First, we get a new ship in the array, and advance the counter.
Code:
makeref(refShip,ShipsTypes[n]);
n++;
Code:
refShip.id = "XebecCT";
Code:
curid = refShip.id; ShipLookupTable.id.(curid) = `n-1`; // PS
Code:
refShip.name = "XebecCT";
Code:
refShip.all = "Xebec1_0";
Code:
refShip.sname = "XebecCT";
Since the Xebec CT will be used by all nations, we do _not_ add a refShip.nation property. If we wanted it to be used only by pirates, however, we would add:
Code:
refShip.nation = PIRATE;
Now, we can assign the regular ship properties. It's suggested you take an existing ship and copy/paste, and then change what stats you want to.
Code:
refShip.Class = 4;
refShip.Cannon = CANNON_TYPE_CANNON_LBS16;
refShip.MaxCaliber = 24;
refShip.Weight = Tonnes2CWT(250);
refShip.Capacity = 1600;
refShip.CannonsQuantity = 20;
refShip.MaxCrew = 125;
refShip.MinCrew = 20;
refShip.SpeedRate = 14.5;
refShip.TurnRate = 50;
refShip.Price = 33000;
refShip.HP = 2100;
refShip.SP = 100;
refShip.AbordageLocation = "BOARDING_XEBEC";
refShip.WaterLine = 0.0;
refShip.SpeedDependWeight = 0.2;
refShip.SubSeaDependWeight = 0.2;
refShip.TurnDependWeight = 0.4;
refShip.CanEncounter = true; //if you don't want the ship to be encounter change this to false
refShip.Type.War = true;
refShip.Type.Trade = false;
refShip.InertiaAccelerationX = 1.5; refShip.InertiaBrakingX = 2.0;
refShip.InertiaAccelerationY = 15; refShip.InertiaBrakingY = 10;
refShip.InertiaAccelerationZ = 9.0; refShip.InertiaBrakingZ = 6.0;
Now, we have to take the NK/HFM mod into account.
This mod makes some changes to every ship's stats, and assigns rig type and best / closest point of sail.
There are four ways to interface your ship with NK/HFM.
The first, and simplest, is to add nothing. Your ship will be processed based on its model name, as if it were a stock POTC ship. This XebecCT will processed like other Xebecs (Lateen rig, +3kts max speed, +5 degrees turn rate, war and trade type, accel and braking x0.25 and x0.1 respectively) if we add no switch.
Note that all ships receive the same accel/braking mods; however, type and stat changes, and rig assigns, are model name specific.
The switches available are:
No_NK_HFM
No_NK_HFM_modstats
No_NK_HFM_modaccel
No_NK_HFM_modtype
The first is the simplest. Just add
Code:
refShip.No_NK_HFM = true;
Note: if the first three letters of the ship's model name are not recognized by NK/HFM (i.e. no stock POTC ship model starts that way) you will have to add this switch!
HOWEVER: If you add this switch, you will have to add the above stuff manually or POTC will do weird things.
So, if you add that switch, you will need to divide your Z Accel by 4 and your Z braking by 10, and you will need to assign rig stats.
Rig stats are as follows.
First, there's rig type. This is based on the first three letters of the model's name (exception: Galeoth's rigtype is "Gat").
Code:
refShip.rigtype = "Xeb";
Then, there's closest and best point of sail. This is based on the type of masts and sails used, as follows:
Code:
Type: Closest Point / Best Point of Sail
`Gaff-riggers` (sloops, schooners): 0.15 0.625
Lateen (Xebec, Tartane): 0.2 0.6
Luggers (Lugger, Galeoth): 0.225 0.625
`Full-rigged` ships (Corvette, Frig): 0.3 0.8
`Old-Time` `square-riggers` (Caravel, 0.375 0.875
Galleon, MoW, anything without Jibs)
So we'd use:
Code:
refShip.ClosestPoint = 0.2;
refShip.BestPoint = 0.6;
Note for the sailors: These are given as percents of max `off-wind`, so 1.0 is running before the wind and 0 is into the eye. The above are also _way_ generous.
And I'd love better numbers to use!
The other NK/HFM switches are to selectively disable pieces. So if you want rigtype assigns and accel changes to be done by NK/HFM but want the stats to stay unmodified and set the ship's type yourself (as we do for the Xebec CT) we would add the following:
Code:
refShip.No_NK_HFM_modstats = true;
refShip.No_NK_HFM_modtype = true;
That's it!
Description of specific properties added by PRS2:
These override refShip.name for each case
-Walk is for the big walktype switch in shipwalk.c. Case for this must exist there.
*This is autogenerated (= *.name) on final loop if it does not already exist.
-BIPic is the little pic in Battle Interface (i.e. when sailing). Case for this must exist in BI.c (battleinterface.c)
*This is autogenerated (= *.name) on final loop if it does not already exist.
-BigPic is the big pic name (in Ships, hold, shipyard, etc.) Must have matching entry in pictures.ini
*This is autogenerated (= *.name) on final loop if it does not already exist.
-BigPicTex is for GetShipTexture() and is -1 for unused, 1 for Galeoths (and BP/Fearless) and 0 for else.
*This is autogenerated (= 0) on final loop if it does not already exist.
-BigPicTexName is for GetShipTextureName() and is "", "SHIPS1", and "SHIPS16" respectively as above.
*This is autogenerated (= SHIPS16) on final loop if it does not already exist.
-SName is for the ship's type name (this is displayed by spyglass, and by BigPic in interfaces), so you can have the same model but a different name.

*This is autogenerated (= *.name) on final loop if it does not already exist.
-All is for all the above properties, as a shortcut. If this exists, at final loop all above are set equal to this. For properties != name, the appropriate property is found from that ship. If some properties are already set, they will not be overwritten (i.e. set all to one but define walk, all but walk will be overwritten by all's link).
*THE SHIP LINKED TO MUST ALREADY HAVE BEEN PROCESSED!