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

Rethinking ships in POTC: new project?

Now, _today's_ post.
And in the first few weeks in session, too! Fingers crossed here for ya JMV.

iamthejarha: I think it also has something to do with the position of the mast; further forward and she's a sloop, more in the middle and she's a cutter. But JMV is the expert and I await his post on it too. <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/smile.gif" style="vertical-align:middle" emoid=":)" border="0" alt="smile.gif" />

Re: `nation-stat` gen: what I mean is:
Let's take, say, Yacht.
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->    makeref(refShip,ShipsTypes[n]);

    n++;

    refShip.Name      = "Yacht1";

    // see below: refShip.Nation      = FRANCE;

    // ditto refShip.id    = refShip.Name + "_" + refShip.Nation;

    // ditto curid = refShip.id; ShipLookupTable.id.(curid) = `n-1`; // PS

    // <snip extra properties>

    MakeMultiNation(sti(refship.index));<!--c2--></div><!--ec2-->

And then:
Finally finished it, cross your fingers that it works.

What it's supposed to do is:
At the top of ships_init is an object that has one set of attributes for each nation, with the attributes for each nation being the multiplier to each base ship stat for that nation (i.e. England: 1.05x speed, turn; 0.95x max crew, 1.05x min crew).
The function, MakeMultiNation, will:
1. Make a copy of the ship's attributes (we'll be overwriting the original so we need the copy)
2. Check to see if it should be run (if ship has attribute skipmultinat, we stop the function, but first make sure the ship has an ID).
3. Generate a list of nations the ship will be copied for; if the ship has attribute(s) refShip.skipnat(nationnum) = true, we skip that nation number, i.e. if refship.skipnat0 = true we skip England.
4. We loop once for each nation (skipping those nations we found to skip).
A. Copy the original attributes into the current slot.
B. Go through all attributes in the shipstats.(current nation) and multiply each original ship's attribute by the one in shipstats.(current nation). I.e. origship.speedrate = 10.0; shipstats.n0.speedrate = 1.05; so refship.speedrate = 10.5;
C. Handle MaxCaliber separately because it's not a straight multiplier and it has a cap.
D. Detect if attribute should be an int or float (hardcoded for now, only speedrate and turnrate are treated as floats). If it should be int, round it.
E. Handle models
i. delete all models in refship.
ii. Go through origship's list of models. If the model has no nation assigned, and has no skipnation assigned, copy it. If it has skipnation assigned AND current nation is skipnation, or if it has nation assigned and current nation is NOT that, skip.
iii. If no models found for current nation copy origship model 0 over.
F. Assign refship.id (based on origship.id if there, else origship.name) and refship.nation (based on current nation).
G. increment ship slot and begin loop again
H. Return next slot so we can deal with the _next_ ship.


Extra attributes:
First, determine if ship has ID. If not, do not add ID, let makemultinat autogenerate it.
(Mostly we _will_ be giving rather than autogenerating IDs, since we will be using multiple models).
Then, _do not add nation attribute_. Well, you can, but it'll be overwritten. <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/smile.gif" style="vertical-align:middle" emoid=":)" border="0" alt="smile.gif" />
Then, if some nations do not get the ship, add refShip.skipnatX = true for each nation that doesn't get it.
Then, you add the models tree.
refShip.models.mX = modelname
And, if `nation-specific`, refShip.models.mX.nation = nationnumber.
And, if `nation-specific` all but one, refShip.models.mX.nation = nationnumber to skip.
However, if two or more (but not all and not `all-but`-one) nations get the model, you have to add each manually.
Lastly, add refship.models.qty = number of models.

Example:
Lugger
refShip.models.m0 = "Lugger1";
refShip.models.m1 = "Lugger2";
refShip.models.m2 = "LuggerPirate";
refShip.models.m2.nation = PIRATE;
refship.models.m3 = "LuggerNavy";
refShip.models.m3.skipnation = PIRATE;
refship.models.m4 = "LuggerEngFra"; //for Britain and France.
refShip.models.m4.nation = ENGLAND;
refship.models.m5 = "LuggerEngFra"; //for Britain and France.
refShip.models.m5.nation = FRANCE;
refship.models.qty = 6;
 
<img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/icon_praise.gif" style="vertical-align:middle" emoid=":bow" border="0" alt="icon_praise.gif" /> Very nice, Nathan. I even understood it. It's REALLLLY very nice. <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/onya.gif" style="vertical-align:middle" emoid=":onya" border="0" alt="onya.gif" />
 
ah! a much better idea, nathan. <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/icon_praise.gif" style="vertical-align:middle" emoid=":bow" border="0" alt="icon_praise.gif" /> that way we won't have to rewrite virtually the whole game, heh.

perhaps there could also be a few more of the rare 'individual' designs, like manowar_gub, to add a bit of variety.



btw i think you should be introduced to the [ list ] tag <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/laugh.gif" style="vertical-align:middle" emoid="xD:" border="0" alt="laugh.gif" /> <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/icon_wink.gif" style="vertical-align:middle" emoid=";)" border="0" alt="icon_wink.gif" />

NathanKell said:
The function, MakeMultiNation, will:
  • Make a copy of the ship's attributes (we'll be overwriting the original so we need the copy)
  • Check to see if it should be run (if ship has attribute skipmultinat, we stop the function, but first make sure the ship has an ID).
  • Generate a list of nations the ship will be copied for; if the ship has attribute(s) refShip.skipnat(nationnum) = true, we skip that nation number, i.e. if refship.skipnat0 = true we skip England.
  • We loop once for each nation (skipping those nations we found to skip).
    • Copy the original attributes into the current slot.
    • Go through all attributes in the shipstats.(current nation) and multiply each original ship's attribute by the one in shipstats.(current nation). I.e. origship.speedrate = 10.0; shipstats.n0.speedrate = 1.05; so refship.speedrate = 10.5;
    • Handle MaxCaliber separately because it's not a straight multiplier and it has a cap.
    • Detect if attribute should be an int or float (hardcoded for now, only speedrate and turnrate are treated as floats). If it should be int, round it.
    • Handle models
      • delete all models in refship.
      • Go through origship's list of models. If the model has no nation assigned, and has no skipnation assigned, copy it. If it has skipnation assigned AND current nation is skipnation, or if it has nation assigned and current nation is NOT that, skip.
      • If no models found for current nation copy origship model 0 over.
        • Assign refship.id (based on origship.id if there, else origship.name) and refship.nation (based on current nation).
        • increment ship slot and begin loop again
        • Return next slot so we can deal with the _next_ ship.
 
I hate markup. <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/tongue.gif" style="vertical-align:middle" emoid=":blah:" border="0" alt="tongue.gif" /> {It gets my fingers further out of sync with my head}
Well, not reading it, just writing it. Thanks for the makeover. <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/smile.gif" style="vertical-align:middle" emoid=":)" border="0" alt="smile.gif" />
Also, you could still only define one model to one set of stats; this just _lets_ you assign more than one.

Cat, thank you. I'm in my new `try-to`-`speak-English` phase. <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/smile.gif" style="vertical-align:middle" emoid=":)" border="0" alt="smile.gif" />

But, on the code front, bad news. Both assigning a temp object (as originally posted) and also temporarily overwriting shipstypes[n].name and then sendmessaging and then putting it back don't work.
Well, don't work _reliably_. I mean, they sorta work for pchar but not for loading multiple ships.
And sometimes I get _really_ weird results, i.e. one of JMV's schooners instead of a lugger. Heh.
I think the engine needs to "check back" with the ship at various points, so the `model-and`-stats needs to be unified and stay current.

BTW if anyone wants the code as it is now, you're welcome to it; I haven't bothered to post it because it isn't really usable.

So I guess we _do_ have to rewrite `game-ship` interfacing. Whee.

However, over supper I think I got a handle on how (and, really, it won't be _soo_ bad... <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/wink.gif" style="vertical-align:middle" emoid=";)" border="0" alt="wink.gif" /> ).

The solution as I see it is to just use two arrays.
The first lists only models, with default stats. The stats _should never be checked by the game though_.
The latter lists only stats (i.e. per nation, plus unique ships), with links to models.

When the engine places or manipulates a ship, we pass it the former (one model, one entry in the array); when the scripts query stats, we use the latter.

Actually, here's a question.

Do we want to still have hard stats like they are now, or do we want _really_ dynamic stats?
(I covered this a bit, earlier).

Let's take fantom generation (i.e. reload to sea and load the `wdmap-encounter` ships).

When a ship is assigned to a fantom, do we:
1. Pick from a set of shipstats
or 2. Pick from the `generic-type`-stats and then randomly change them a bit (based on nation of course, but with some random fluctuation).

The latter will take _somewhat_ more memory; i.e. if two (or more) characters share the same set of shipstats, then in the latter approach both (or all) will have local copies of those stats, whereas under the former case they'd both be "linked" to the master stats of that subtype (frigate english 5, perchance).

Either way they could still have different models of course.

However, the beauty of approach 2 is that no two characters would _have_ to have identical sets of shipstats, and in fact in practice wouldn't. Two characters with the _exact_ same _base_ ship might have 5% variation in speed, say.

All this without having to create a new ship entry before runtime; handled on the fly.

However, it _will_ slow down loading since stats will have to be created if they aren't already there.
But we do this for the captains already, and in a much more complex way; so I don't think it'll be really perceptively slower.


Plus, doing it _this_ way means you can _customize_ your ship. Want a handier ship? Sacrifice a knot of speed and you got it!
And it means going "ship hunting" is more important, since not all English luggers are the same...

But it also means that ship berthing gets more complex as you have to save the ship's stats as well as its id...
-------


I think I prefer the latter approach (as if it weren't clear), and I don't feel it's really any harder to make than the former.

I mean, it's easier (at least for some of us, heh) to write a function that will create the modified shipstats for each character than it is to manually create all the entries. (Well, manually create a set of entries; we wouldn't have near the variety).
 
So, here's how I envision the system to work.

We have a `markedly-shrunken` ships array.

It has one entry per ship model/texture combo (since we can't do `multiple-textures`-`per-model`... <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/sad.gif" style="vertical-align:middle" emoid=":(" border="0" alt="sad.gif" /> )

Then, whenever stats for the ship are checked, we check char.ship.stats.* instead of refship.*

For premade characters, or characters whose ships are manually given, you can manually do the stats. Want Clair Larousse's brig to have certain stats? Write them into his char init.
But also we make a function, void MakeShipStats(ref char, int nation_override);
if nation_override != -1, we use that instead of the char's nation.

Then, we look up the nation multipliers (per above, and I'll post the array if you like, it's usually either 1.05x or 0.95x a stat, or you can just check the ships spreadsheet and do a little excelmath) and multiply the base stats with them * 0.97 + (frnd()*0.06) for a little extra variation.

Of course the experts here decide what those multipliers _should_ be; the set I'm using now is just what came stock with the game plus Verruckt's pirate ship stat mults (averaged).

We do that for each stat, and record each final stat into char.ship.stats.*

We run that func when we create fantoms, or if we ever find a character which has attribute ship but not attribute ship.stats.

They'll be preserved on swap because swap copies the entire attribute tree.
 
Oh, yeah, we also have to mod locations_loader (or actually now we _don't_ because we're leaving shipstypes alone). That's where `ships-for`-locations are loaded.
 
Oh, it's a shame to waste this much code. <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/laugh.gif" style="vertical-align:middle" emoid="xD:" border="0" alt="laugh.gif" />
Maybe someday we'll figure out how we can stick with one array.
And snippets of this may be useful elsewhere, who knows.
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->object shipstats; //`nation-specific` stat modifiers. Modifier is a float multiplier for the stat.



//English      

shipstats.n0.MaxCaliber  =    1.00;

shipstats.n0.Weight  =    1.00;

shipstats.n0.Capacity  =    0.9;

shipstats.n0.MaxCrew  =    0.95;

shipstats.n0.MinCrew  =    1.05;

shipstats.n0.SpeedRate  =    1.05;

shipstats.n0.TurnRate  =    1.05;

shipstats.n0.Price  =    1.00;

shipstats.n0.HP  =    1.00;

     

//French

shipstats.n1.MaxCaliber  =    1.00;

shipstats.n1.Weight  =    1.00;

shipstats.n1.Capacity  =    1.00;

shipstats.n1.MaxCrew  =    1.00;

shipstats.n1.MinCrew  =    1.00;

shipstats.n1.SpeedRate  =    1.00;

shipstats.n1.TurnRate  =    1.00;

shipstats.n1.Price  =    1.00;

shipstats.n1.HP  =    1.00;

     

//Spanish

shipstats.n2.MaxCaliber  =    1.00;

shipstats.n2.Weight  =    1.00;

shipstats.n2.Capacity  =    1.05;

shipstats.n2.MaxCrew  =    1.05;

shipstats.n2.MinCrew  =    1.00;

shipstats.n2.SpeedRate  =    0.95;

shipstats.n2.TurnRate  =    0.95;

shipstats.n2.Price  =    1.00;

shipstats.n2.HP  =    1.05;



//Pirate

shipstats.n3.MaxCaliber  =    1.50;

shipstats.n3.Weight  =    0.95;

shipstats.n3.Capacity  =    0.80;

shipstats.n3.MaxCrew  =    1.00;

shipstats.n3.MinCrew  =    1.00;

shipstats.n3.SpeedRate  =    1.10;

shipstats.n3.TurnRate  =    1.10;

shipstats.n3.Price  =    1.06;

shipstats.n3.HP  =    0.80;



//Dutch

shipstats.n4.MaxCaliber  =    1.00;

shipstats.n4.Weight  =    0.95;

shipstats.n4.Capacity  =    1.00;

shipstats.n4.MaxCrew  =    0.95;

shipstats.n4.MinCrew  =    1.00;

shipstats.n4.SpeedRate  =    1.05;

shipstats.n4.TurnRate  =    1.00;

shipstats.n4.Price  =    1.00;

shipstats.n4.HP  =    0.95;



//Portuguese

shipstats.n5.MaxCaliber  =    1.00;

shipstats.n5.Weight  =    1.05;

shipstats.n5.Capacity  =    1.00;

shipstats.n5.MaxCrew  =    1.05;

shipstats.n5.MinCrew  =    1.00;

shipstats.n5.SpeedRate  =    1.00;

shipstats.n5.TurnRate  =    1.05;

shipstats.n5.Price  =    1.00;

shipstats.n5.HP  =    0.95;



int MakeMultiNation(int idx)

{

    object ship;

    CopyAttributes(&ship, &ShipsTypes[idx]); //note, this is NOT an instance, it's a copy

    ref refShip = GetShipByType(idx); //this IS the instance



    int a, n, m, i, j; //attributes to change, nation incr, models incr, temp incr, temp incr

    string atrstr, atrname; //attribute tempstring, attribute name

    aref natstats; //`nation-specific` stat modifiers.

    bool isint = true; //is the attribute an int or a float? `hard-coded` for now.





    //do we skip this function?

    if(CheckAttribute(refShip,"skipmultinat"))

    {

 if(sti(refShip.skipmultinat))

 {

     //yes, we do.

     //does the ship have an ID? If not, generate it.

     if(!CheckAttribute(refShip,"id"))

     {

   if(CheckAttribute(refShip,"nation")) refShip.id = refShip.name + "_" + refShip.nation;

   else refShip.id = refShip.name;

     }

     return;

 }

    }

    bool skipnat[MAX_NATIONS];

    for(i = 0; i < MAX_NATIONS; i++) skipnat = false; //set defaults

    

    for(i = 0; i < MAX_NATIONS; i++) //fill array

    {

 atrstr = "skipnat" + i;

 if(CheckAttribute(refShip,atrstr)) skipnat = sti(refShip.(atrstr)); //do we skip this nation?

    }

    i = idx; //we start with the current ship

    for(n = 0; n < MAX_NATIONS; n++)

    {

 makeref(refShip, ShipsTypes[idx]); //make the reference. Since idx increments below, we're moving through the array

 if(skipnat[n]) continue; //do we skip this nation?

 //delete old attributes of refShip:

 //should work but doesn't - DeleteAttribute(refShip,"");

 for(i = 0; i < GetAttributesNum(refShip); i++) { DeleteAttribute(refShip, GetAttributeName(GetAttributeN(refShip, i))); }

 copyattributes(&refShip, &ship); //copy all ship attributes over

 atrstr = "n"+n;

 makearef(natstats,shipstats.(atrstr));

 for(a = 0; a < GetAttributesNum(natstats); a++)

 {

     isint = true;

     atrname = GetAttributeName(GetAttributeN(natstats,a));

     if(atrname == "speedrate" || atrname == "turnrate") isint = false;

     refShip.(atrname) = makefloat(ship.(atrname)) * makefloat(natstats.(atrname));

     if(isint) refShip.(atrname) = makeint(refShip.(atrname));

     if(atrname == "MaxCaliber" && stf(natstats.MaxCaliber) != 1.0)

     {

   //special manual handling for caliber

   if(stf(natstats.MaxCaliber) > 1.0)

   {

       switch(ship.MaxCaliber)

       {

     case "12": refShip.MaxCaliber = 16; break;

     case "16": refShip.MaxCaliber = 24; break;

     refShip.MaxCaliber = 32;

       }

   }

   else

   {

       switch(ship.MaxCaliber)

       {

     case "32": refShip.MaxCaliber = 24; break;

     case "24": refShip.MaxCaliber = 16; break;

     refShip.MaxCaliber = 12;

       }

   }

     }

 }

 //handle models

 DeleteAttribute(refShip,"models"); //blank slate

 m = 0;

 // NOTE: THERE MUST BE AT LEAST ONE MODEL FOR EACH NATION!!!!!

 // if there isn't, model.m0 is used.

 for(i = 0; i < sti(ship.models.qty); i++)

 {

     atrstr = "m" + i;

     atrname = "m" + m;

     //if nation attr exists for model and it doesn't match current nation we skip the model

     if(CheckAttribute(ship,"models."+atrstr+".nation")) { if(sti(ship.models.(atrstr).nation) != n) continue; }

     if(CheckAttribute(ship,"models."+atrstr+".skipnation")) { if(sti(ship.models.(atrstr).skipnation) == n) continue; }



     //copy model

     refShip.models.(atrname) = ship.models.(atrstr);

     m++;

 }

 if(m == 0) refShip.models.m0 = ship.models.m0; // default to m0 if no models

 refShip.name = refShip.models.m0; //default name is model 0.



 //handle ID and nation

 string id = ship.name;

 if(CheckAttribute(ship,"id")) id = ship.id;

 refShip.ID = id + "_" + n;

 refShip.nation = n;



 idx++; //advance to next ship slot

    }



    return idx; //gives back the idx for the next ship slot

}<!--c2--></div><!--ec2-->
 
ehhh... lemme get this straight... <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/unsure.gif" style="vertical-align:middle" emoid=":?" border="0" alt="unsure.gif" /> wasn't the function 'makemultination' running within ships_init.c, creating a number of definitions automatically where currently we have them manually entered? if so, why would overwriting the definition within ships_init.c cause a problem? surely if it's in ships_init.c then it's not 'initialised' yet? i would understand if 'makemultination' was running after the game had already been started.
 
Oh, I wasn't clear then. (Whodathunkit, eh? <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/laugh.gif" style="vertical-align:middle" emoid="xD:" border="0" alt="laugh.gif" /> )

I mean, the `multiple-models`-`per-entry` part, which was the soul of the mod. I mean, the other part _does_ work, or at least should, with no trouble; but there's little point in using that to autogenerate the entries but stay with the current ships system.

So, I'm rewriting the ships system. Easier that way.
And, actually, it's much easier than I feared. Code is your friend; make the engine do the work.
So instead of doing innumerable CheckAttribute calls to see if the local version exists, I just wrote a function to automate that.
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->string GetLocalShipAttrib(ref chr, ref ship, string attrib) //pass this the chr and the shipstypes[] entry and the attribute name. Will return local version if there.

{

    string tmpstr;

    if(CheckAttribute(chr,"ship.stats."+attrib)) return chr.ship.stats.(attrib);

    return ship.(attrib);

}<!--c2--></div><!--ec2-->

So now I just find all stX(rship.attribute) lines and replace them with GetLocal... lines.
A'course, it'll be trouble for the funcs where _only_ the ship is passed and not the character, and _that's_ where the rewrite comes in.
 
<!--`QuoteBegin-NathanKell`+--><div class='quotetop'>QUOTE(NathanKell)</div><div class='quotemain'><!--QuoteEBegin-->Oh, I wasn't clear then. (Whodathunkit, eh?  xD: )[/quote]

oh no, probably you wrote it clear, i just didn't read it clear <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/happy.gif" style="vertical-align:middle" emoid="^_^" border="0" alt="happy.gif" />

ah well, nothing like an entire overhaul of the whole program to... destroy your will to live... <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/wink.gif" style="vertical-align:middle" emoid=";)" border="0" alt="wink.gif" />
 
LOL, yeah. I'm thanking WinAMP and my IDE right now...

Actually, interesting coincidence...I just got to _your_ mod... <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/laugh.gif" style="vertical-align:middle" emoid="xD:" border="0" alt="laugh.gif" />
{nat ship icons I mean}
So I had to implement _another_ function:
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->bool CheckShipAttribute(ref chr, ref ship, string attrib)

{

    if(CheckAttribute(chr,"ship.stats."+attrib)) return true;

    if(CheckAttribute(ship,attrib)) return true;

    return false;

}<!--c2--></div><!--ec2-->

Rather than checking getlocalshipattribute() == "error" which is so inelegant. <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/smile.gif" style="vertical-align:middle" emoid=":)" border="0" alt="smile.gif" />


Well, to be fair I would have had to have done that eventually anyway. <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/laugh.gif" style="vertical-align:middle" emoid="xD:" border="0" alt="laugh.gif" />
 
Oh, yeah, one other thing.
If you could go through your mods and change the code so you use those functions instead of your traditional calls I'd really appreciate it. <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/smile.gif" style="vertical-align:middle" emoid=":)" border="0" alt="smile.gif" />

Just replace all CheckAttribute calls with the latter function, and all {ship}.someattribute calls with the former function, i.e.
refship.speedrate -> GetLocalShipAttrib(chr, refship, "speedrate")

Thanks. <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/smile.gif" style="vertical-align:middle" emoid=":)" border="0" alt="smile.gif" />


This applies to everyone who's written a mod checking ship properties, actually; I'd greatly appreciate if you'd go through your mods and change the calls.
It'd greatly decrease my workload. <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/smile.gif" style="vertical-align:middle" emoid=":)" border="0" alt="smile.gif" />
(As well as avoiding my misunderstanding and thus misfixing your code. <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/wink.gif" style="vertical-align:middle" emoid=";)" border="0" alt="wink.gif" /> ).

Oh, also, a note.
Even if we don't fix all the calls to shipstypes[] the mod will still work; it can be tested at any point, since the worst that will happen is the ship will no longer have `nation-modified` stats, just base ones.


Second note.

Would someone like to volunteer to go through ships_init and prune all `non-base` ships?
Hopefully the same person(s) going through it right now, so the work gets done only once of course. <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/smile.gif" style="vertical-align:middle" emoid=":)" border="0" alt="smile.gif" />

What needs to be done is,
1. Merge the changes from reinit.c to the base ship (usually the French version).
2. Delete all other versions of the ship _that use the same model_.

So for yacht, say, you delete all but one version of each model, and then make the stats however you like. And make sure to delete the nation attribute too, and change ID so it's just refship.name.

I.e.
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->makeref(refShip,ShipsTypes[n]);

n++;

refShip.Name      = "Yacht1";

refShip.id    = refShip.Name; //unless unique and needs new ID, i.e. frigate super

curid = refShip.id; ShipLookupTable.id.(curid) = `n-1`; // PS

refShip.Class     = 6; //make these stats on down whatever you want as the base stats

refShip.Cannon    = CANNON_TYPE_CANNON_LBS12;

refShip.MaxCaliber   = 12;

refShip.Weight      = Tonnes2CWT(200);

refShip.Capacity  = 800;

refShip.CannonsQuantity = 16;

refShip.MaxCrew   = 60;

refShip.MinCrew   = 12;

refShip.SpeedRate  = 9.0;

refShip.TurnRate  = 30;

refShip.Price     = 19000;

refShip.HP     = 700;

refShip.SP     = 100;

refShip.AbordageLocation = "BOARDING_BARQUE";



refShip.WaterLine = 0.03;

refShip.SpeedDependWeight = 0.3;

refShip.SubSeaDependWeight = 0.3;

refShip.TurnDependWeight = 0.8;



refShip.InertiaAccelerationX    = 2.0;    refShip.InertiaBrakingX  = 2.0;

refShip.InertiaAccelerationY    = 8;    refShip.InertiaBrakingY  = 4.0;

refShip.InertiaAccelerationZ    = 4.0;    refShip.InertiaBrakingZ  = 2.0;





refShip.Height.Bombs.Y  = 1.0;  refShip.Height.Bombs.DY  = 1.0;

refShip.Height.Grapes.Y  = 2.0;  refShip.Height.Grapes.DY    = 1.0;

refShip.Height.Knippels.Y    = 15.0;  refShip.Height.Knippels.DY    = 10.0;

refShip.Height.Balls.Y  = 1.0;  refShip.Height.Balls.DY  = 1.0;



//delete all other YACHT1 entries.<!--c2--></div><!--ec2-->

Note the lines that were deleted.
 
Argh, I keep forgetting things.

We should probably tie inertia to weight y'know, so when weight gets modified (for Holland and Portugal) inertia does too. Whatcha'all think?
 
Argh #2.
How to handle when no one _owns_ the ship yet...
(I.e. when viewing an `in-stock` ship at a shipyard)
I guess create a temporary object and do the stats there, then copy from there to char when char buys ship.
Argh, it gets more complicated.

Calling it a night.
 
<!--`QuoteBegin-NathanKell`+--><div class='quotetop'>QUOTE(NathanKell)</div><div class='quotemain'><!--QuoteEBegin-->Oh, yeah, one other thing.
If you could go through your mods and change the code so you use those functions instead of your traditional calls I'd really appreciate it. <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/smile.gif" style="vertical-align:middle" emoid=":)" border="0" alt="smile.gif" />

Just replace all CheckAttribute calls with the latter function, and all {ship}.someattribute calls with the former function, i.e.
refship.speedrate -> GetLocalShipAttrib(chr, refship, "speedrate")

Thanks. <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/smile.gif" style="vertical-align:middle" emoid=":)" border="0" alt="smile.gif" />[/quote]

sure. it won't be as simple as that though... if you lay up a ship, the ship berthing mod just stores the ship type idx rather than all the ship's stats... shouldn't be too complicated to change over though *prays* <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/icon_wink.gif" style="vertical-align:middle" emoid=";)" border="0" alt="icon_wink.gif" />

at the shipyard, i reckon the best way would be to store the stats in the scrollimage's properties. you could set GameInterface.shipslist.pic?.shipstats.xxx . (have a look at the 'fillscroll' function in any of the interfaces that have a scrollimage control). then when you bought the ship it would transfer the properties to the character.
 
1. Do you store 'em in an array, or in an attribute tree?
If the latter, you can just copyattributes(&destination, char.ship.stats) and that'll take care of it.

2. Yeah, that's a better way than a separate object, you bet. Thanks! <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/smile.gif" style="vertical-align:middle" emoid=":)" border="0" alt="smile.gif" />
 
Oh, by the way. Going this route obviates the need for your `allow-different`-`nation-ships`-`at-shipyards` mod, because the nation stuff will be handled in the shipyard interface.
(But this also means I had to rewrite setrandomstats so it gets passed an aref to the ship attribute rather than a ref to chr, and so nat _must_ be passed because it can no longer detect it from chr, and also to make a separate int idx argument, for ship idx (since chr will no longer necessarily have chr.ship.idx). But this also makes it much more flexible, with nothing being read from chr, just written there).

So you'll now have to invoke it as (for characters)
SetRandomStatsToShip(chr.ship, sti(chr.ship.idx), sti(chr.nation));
 
Actually, it looks better to put them in the shipwright's shipyard attribute, along with the ship idx.
But thanks for putting me on the path, _way_ easier than using _yet another_ temp object.
 
You know, I might as well keep that old MakeMultiNat function. Or at least something like it.

I.e. for adding multiple skins.
Idea being:
Instead of making a whole new bloody entry for each skin, if you're just adding a new skin and want the stats the same, you do the whole refship.models. whatever thing, and I'll write a function to take that info and spread it out over multiple models.
 
Success at midnight! (Well, 9:40).

It works.

Random stats, all that good stuff.

I'm shamelessly passing the buck on shipberthing to you, Kieron, unless you want me to take a crack at it <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/laugh.gif" style="vertical-align:middle" emoid="xD:" border="0" alt="laugh.gif" /> ; I'll send over the code.

Wahoo!
 
Back
Top