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

[WIP] Limit special ship type to certain country

Game refuses to load? Can you enable error logging and show me the error.log file?
I'm sure it should at least load!

Other idea: Can you upload your current PROGRAM folder somewhere and I'll add the code myself.
 
Ok i will get all the files for programs uploaded, it'll have to be the files from CMV3.2 though because i had to uninstall the other copy of COAS after the simple mod from Ugeen didn't work, all i did was install the simple mod, i didn't make any of those files compatable with any other files. I wanted to see if it all worked and how it had changed etc.

Here you go bud. For Pieter
 
Stick attached two files in your PROGRAM\SEA_AI folder and see if the game runs.
I found a slight error in the code I posted before, but it's fixed in these files.
Should hopefully run. If it does, you can start adding refShip.nation lines in ships_init.c . :doff
 
Thanks Pieter, it works fine now. I will start to test the nations out and see how it all goes. :onya

Update:
The game loads fine even with new enteries made for the pirates however the Shnyava is available for all nations but pirates, the one for pirates has added cargo spacem speed and crew. I attacked a pirate ship and the Shnyava for all nations was been used by the pirate and not the one that it should have. I need to see if it is been generated at the shipyard aswell. So far i have started off with the pirate Bermuda Sloop but i have yet to see the one for all nations been generated both at sea and at a shipyard.
 
No, I hadn't seen that yet.

What did you do for testing? Try, for example, taking all black-and-yellow type ships and adding a line refShip.nation = ENGLAND; to them.
Then go into the game and check if you see any of those ships under non-English flags anymore.
 
Oh... note that my modification probably does NOT prevent these ships from showing up in other nations' shipyards;
it's purely an on-sea modification.

If anybody has the time, I do recommend to go ahead and try this; it could add quite a lot to the game. :yes
 
In PROGRAM\SEA_AI\sea.c find this code:
Code:
		int iNumFantomShips = Fantom_GenerateEncounter(sGName, &oResult, iEncounterType, iNumWarShips, iNumMerchantShips);
Replace it with:
Code:
int iNation = sti(rEncounter.Nation);
int iNumFantomShips = Fantom_GenerateEncounter(sGName, &oResult, iEncounterType, iNumWarShips, iNumMerchantShips, iNation); // NK
Now open PROGRAM\SEA_AI\AIFantom.c and find this code:
Code:
int Fantom_GenerateEncounter(string sGroupName, object oResult, int iEType, int iNumWarShips, int iNumMerchantShips)
Replace it with:
Code:
int Fantom_GenerateEncounter(string sGroupName, object oResult, int iEType, int iNumWarShips, int iNumMerchantShips, int iNation) // NK
Then find this code in the same file:
Code:
iShipType = Fantom_GetShipType(iMerchantClassMin, iMerchantClassMax, "Merchant");
Replace with:
Code:
iShipType = Fantom_GetShipType(iMerchantClassMin, iMerchantClassMax, "Merchant", iNation); // NK
Then find this code in the same file:
Code:
iShipType = Fantom_GetShipType(iWarClassMin, iWarClassMax, "War");
Replace with:
Code:
iShipType = Fantom_GetShipType(iWarClassMin, iWarClassMax, "War", iNation); // NK
And at last find:
Code:
int Fantom_GetShipType(int iClassMin, int iClassMax, string sShipType)
And replace it with:
Code:
int Fantom_GetShipType(int iClassMin, int iClassMax, string sShipType, int iNation) // NK
We have now enabled ourselves to code in nation-specific ship type encounters!
Now it's time to add in the nation-specific code to the Fantom_GetShipType function:
Code:
int Fantom_GetShipType(int iClassMin, int iClassMax, string sShipType)
{
int iShips[50];
int i, iShipsNum;
iShipsNum = 0;

for (i=SHIP_TARTANE; i<=SHIP_MANOWAR; i++)  //ýíêàóíòåðû òîëüêî äî ìàíîâàðà, êâåñòîâûå êîðàáëè îòäåëüíî
{
object rShip = GetShipByType(i);
if (!checkAttribute(rship, "class"))
{
trace ("bad ship is: " + rship.name);
}
int iClass = MakeInt(rShip.Class);

if (iClass > iClassMin) { continue; }
if (iClass < iClassMax) { continue; }
if (sti(rShip.CanEncounter) != true) { continue; }
if (sti(rShip.Type.(sShipType)) != true) { continue; }
if (CheckAttribute(rShip, "nation") && sti(rShip.nation) != iNation) { continue; } // PB: Limiting Ships to Certain Nations

iShips[iShipsNum] = i;
iShipsNum++;
}
if (iShipsNum==0) 
{
Trace("Can't find ship type '" + sShipType + "' with ClassMin = " + iClassMin + " and ClassMax = " + iClassMax);
return INVALID_SHIP_TYPE;
}

int iBaseShipType = iShips[rand(iShipsNum - 1)];
//trace(ShipsTypes[iBaseShipType].name);
int iRealShipType = GenerateShip(iBaseShipType, 0);
return iRealShipType;
}
Now you can add code lines in PROGRAM\SHIPS\ships_init.c for nation-specific ships, for example refShip.nation = ENGLAND; will make the ship appear only in English squadrons.

The above code is adjusted for CoAS, but is not tested. It is adapted from the PotC Build Mod simple version (we've got more advanced code in place for this now), where it works perfectly fine.

This seems quite logic to me, thanks Pieter (sorry for warming up an old soup). But how can I make a ship appearing for 2 or 3 nations with this code? Lets say refShip.nation = ENGLAND as well as ... = PIRATE??
 
That code was in place in CMV3.0 or CMV3.1 but we couldn't get it to work and as far as i know the code is still in place in the files. As for what code to add to the ships, we have.

Code:
//Nation
refShip.england = 1.0; //
refShip.france = 1.0; //
refShip.holland = 1.0; //
refShip.pirate = 1.0; //
refShip.spain = 1.0; //

Change the 1.0 to 0.0 for the nations you dop not want to have generate that ship, but we couldn't get it to work and to make sure their was no bad side effects from the code all ships enteries was checked and all enteries now have the exact same entery as the one above. Originally that was changed so that we would see ships spacifically generated by certain nations like the none quest ship Soliel Royal for France, Dutch Fleut for Holland, Victory for England etc etc. We even had some spacific ship enteries for pirates, like 2 enteries for the Lugger. 1 entery for nations and 1 entery for the pirates which the ship was faster, able to hold more cargo and carry more crew, the kind of differences you would expect to see between a ship from a nation and a exact same ship but as a pirate ship.
 
So you say the codeline "refShip.england = 1.0" would be like "refShip.nation = ENGLAND" but able to be combined with others, altthough there is no proof that it works? Maybe a stupid question (I not a program ace at all), but would it be possible to set several "refShip.nation = ..." entries for one ship? Has anyone tried this?
 
So you say the codeline "refShip.england = 1.0" would be like "refShip.nation = ENGLAND" but able to be combined with others, altthough there is no proof that it works? Maybe a stupid question (I not a program ace at all), but would it be possible to set several "refShip.nation = ..." entries for one ship? Has anyone tried this?

I tried it once. I was trying to do an Authentic Period mod where I got rid of the Movie/spooky ships and some of the late 18th century ships. I may have done something else wrong, but I could never get the game to start after I did it, so I gave up.

MK
 
We did have some ships set to be generated by more than 1 nation.
Code:
//Nation 
refShip.england = 1.0; // 
refShip.france = 0.0; // 
refShip.holland = 0.0; // 
refShip.pirate = 1.0; // 
refShip.spain = 1.0; //

In the above example the ship would be generated by pirates, Spanish and English. France and Holland would never generate that ship but we couldn't get it to work and the nations that was disabled still generated them.
 
The code I posted above is the simple version that allows ships to be set to one nation only.
This does NOT work together with the PotC-style code that you say you added to the ships_init.c file.
I know the PotC style code is what you would want to use and it'd be easy enough to do so too.
The only reason why I posted the simpler version instead is to be able to check if it worked at all before going a bit more fancy.

I have rewritten my instructions for CoAS to use the PotC-style ships_init.c code; see if that works better:

In PROGRAM\SEA_AI\sea.c find this code:
Code:
		int iNumFantomShips = Fantom_GenerateEncounter(sGName, &oResult, iEncounterType, iNumWarShips, iNumMerchantShips);
Replace it with:
Code:
int iNation = sti(rEncounter.Nation);
int iNumFantomShips = Fantom_GenerateEncounter(sGName, &oResult, iEncounterType, iNumWarShips, iNumMerchantShips, iNation); // NK
Now open PROGRAM\SEA_AI\AIFantom.c and find this code:
Code:
int Fantom_GenerateEncounter(string sGroupName, object oResult, int iEType, int iNumWarShips, int iNumMerchantShips)
Replace it with:
Code:
int Fantom_GenerateEncounter(string sGroupName, object oResult, int iEType, int iNumWarShips, int iNumMerchantShips, int iNation) // NK
Then find this code in the same file:
Code:
iShipType = Fantom_GetShipType(iMerchantClassMin, iMerchantClassMax, "Merchant");
Replace with:
Code:
iShipType = Fantom_GetShipType(iMerchantClassMin, iMerchantClassMax, "Merchant", iNation); // NK
Then find this code in the same file:
Code:
iShipType = Fantom_GetShipType(iWarClassMin, iWarClassMax, "War");
Replace with:
Code:
iShipType = Fantom_GetShipType(iWarClassMin, iWarClassMax, "War", iNation); // NK
And at last find:
Code:
int Fantom_GetShipType(int iClassMin, int iClassMax, string sShipType)
And replace it with:
Code:
int Fantom_GetShipType(int iClassMin, int iClassMax, string sShipType, int iNation) // NK
We have now enabled ourselves to code in nation-specific ship type encounters!
Now it's time to add in the nation-specific code to the Fantom_GetShipType function:
Code:
int Fantom_GetShipType(int iClassMin, int iClassMax, string sShipType)
{
int iShips[50];
int i, iShipsNum;
iShipsNum = 0;

for (i=SHIP_TARTANE; i<=SHIP_MANOWAR; i++)  //ýíêàóíòåðû òîëüêî äî ìàíîâàðà, êâåñòîâûå êîðàáëè îòäåëüíî
{
object rShip = GetShipByType(i);
if (!checkAttribute(rship, "class"))
{
trace ("bad ship is: " + rship.name);
}
int iClass = MakeInt(rShip.Class);

if (iClass > iClassMin) { continue; }
if (iClass < iClassMax) { continue; }
if (sti(rShip.CanEncounter) != true) { continue; }
if (sti(rShip.Type.(sShipType)) != true) { continue; }
// PB: Note that this code is all that's different -->
if (iNation >= 0 && iNation < NATIONS_QUANTITY) {
string sNation = GetNationNameByType(iNation);
if (sNation == "britain") {sNation = "england";} // Screwface : Fix for other nations type under English flag
if (CheckAttribute(rShip, sNation) == true && stf(rShip.(sNation)) < FRAND(1.0)) continue;
}
// PB: Note that this code is all that's different <--

iShips[iShipsNum] = i;
iShipsNum++;
}
if (iShipsNum==0) 
{
Trace("Can't find ship type '" + sShipType + "' with ClassMin = " + iClassMin + " and ClassMax = " + iClassMax);
return INVALID_SHIP_TYPE;
}

int iBaseShipType = iShips[rand(iShipsNum - 1)];
//trace(ShipsTypes[iBaseShipType].name);
int iRealShipType = GenerateShip(iBaseShipType, 0);
return iRealShipType;
}
Now you can add code lines in PROGRAM\SHIPS\ships_init.c for nation-specific ships, for example refShip.england = 0.0; will make the ship no longer appear in English squadrons.
 
Oh... that looks so great, adding much realism to the game. unfortunatly, those commands looks verry complicated for me :modding Well, isn't it any "simplified way" to have teh same result?
 
Its crashes allready due to this code "if (sti(rShip.CanEncounter) != true) { continue; }"
> error-log says "invailid continue"

any Idea?
 
I must have messed something up in the first place, after taking over your entire code-lines (first I tried it without the "screwface-fix") the error log tells me:

COMPILE ERROR - file: sea_ai\AIFantom.c; line: 65
missed ')'

- meaning this:

if (iNation >= 0 && iNation < NATIONS_QUANTITY) {

it seems the engine doesn't like it at all :shrug
 
Try using MAX_NATIONS instead of NATIONS_QUANTITY; that might work better.
And believe it or not, that error message might actually mean progress! :cheeky
 
Back
Top