• 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] Sailing Mod

Something similar to that is done in the PotC DirectSail mod, I think. :yes
 
I find an interesting parameter "worldMap.island" (not "worldMap.islands"), and I think it should play an important part if I manage to solve the direct sail puzzle. However, I can't find the code that assign its value, or even get it initialized. other than the "void setWDMPointXZ(string _location)" function in "\Character\RPGUtilite.c", and I am pretty sure that is only used once when start a new game character.

This parameter "worldMap.island" is used several times in "\WorldMap\worldmap.c" and "\WorldMap\worldmap_reload.c". I believe this parameter has something to do with which island map the ship is sailing on, as the CoAS map is not a single whole one, but several small ones, each contains 2 settlement at most(one regular and one pirate). This is even the case for the settlements on the Latin-American main land and Cuba(2 different maps exist, cuba1 and cuba2).

I think one way to manage direct sail is that set a new function that calculate the ship's distance with all the island and closest one, and if it is not the island on the current map the ship is sailing on, reload and login to the new map. But the catch is, it is very possible that loading screen is needed when the map changes, similar to the way when you are on the island and traveling through the jungles.
 
We had to resort to loading screens in the PotC Build Mod DirectSail mod as well, but that's a small price to pay for being able to do it.
 
Someone help me check these codes! Why my following functions "int getRTclosestIsland()" can't works correctly?

float getRTplayerShipX()
{
float zeroX = MakeFloat(worldMap.zeroX);
float SeaX = stf(pchar.Ship.Pos.x);
int scale = WDM_MAP_TO_SEA_SCALE;
if (worldMap.island == "Cuba1" || worldMap.island == "Cuba2" || worldMap.island == "Beliz" || worldMap.island == "SantaCatalina"
|| worldMap.island == "PortoBello" || worldMap.island == "Cartahena" || worldMap.island == "Maracaibo"
|| worldMap.island == "Caracas" || worldMap.island == "Cumana")
{
scale = 25;
}
float RTplayerShipX = (SeaX/scale) + zeroX;
return RTplayerShipX;
}
float getRTplayerShipZ()
{
float zeroZ = MakeFloat(worldMap.zeroZ);
float SeaZ = stf(pchar.Ship.Pos.z);
int scale = WDM_MAP_TO_SEA_SCALE;
if (worldMap.island == "Cuba1" || worldMap.island == "Cuba2" || worldMap.island == "Beliz" || worldMap.island == "SantaCatalina"
|| worldMap.island == "PortoBello" || worldMap.island == "Cartahena" || worldMap.island == "Maracaibo"
|| worldMap.island == "Caracas" || worldMap.island == "Cumana")
{
scale = 25;
}
float RTplayerShipZ = (SeaZ/scale) + zeroZ;
return RTplayerShipZ;
}
int getRTclosestIsland()
{
float RTplayerShipX = getRTplayerShipX();
float RTplayerShipZ = getRTplayerShipZ();
string sIslandNow = worldMap.island;
float distance = float iDistanceNow = GetDistance2D(stf(RTplayerShipX), stf(RTplayerShipZ),
stf(worldMap.islands.(sIslandNow).position.x),
stf(worldMap.islands.(sIslandNow).position.z));
int nextisland = FindIsland(worldMap.island);
ref rIsland;
string islandTemp;
for (int inum=0; inum<=26; inum++)
{
rIsland = GetIslandByIndex(inum);//makeref(rIsland, Islands[inum]);
islandTemp = sti(rIsland.id);
distance = GetDistance2D(stf(RTplayerShipX), stf(RTplayerShipZ),
stf(worldMap.islands.(islandTemp).position.x),
stf(worldMap.islands.(islandTemp).position.z));
if (distance < iDistanceNow)
{
nextisland = FindIsland(islandTemp);
}
}
return nextisland;
}

I thought it should return the nearest island ID by calculating world map position in sea mode...but CTD happened.
 
Game can start, but when the function is called, an window will show up, and says "Runtime Error".
 
I meant this:

Open "engine.ini" in your main game folder.
- Find the "debuginfo = 0" line and change it to "debuginfo = 1".
- Find the "runtimelog = 0" line and change it to "runtimelog = 1".
- Find the "tracefilesoff = 1" line and change it to "tracefilesoff = 0".
- Start the game and wait until the error occurs.
- Now find compile.log, system.log and the possible error.log in your main game folder.
It should look like this:
Code:
tracefilesoff = 0
[script]
debuginfo = 1
codefiles = 0
runtimelog = 1
 
Then in your CoAS directory you should have a file called error.log that will tell us the problem ;)
 
Thanks. I'm getting something here. The distance calculation seems work fine from now. And I am also able to trigger the loading screen at sea when the ship is closer to another island than the one already been loaded. During the last test, I sail from Nevis, direction is southeast, and I successfully load into Antigua map. But the ship doesn't appear in the right possition...
My map changing code is:
void ChangeSeaMap()
{
DeleteSeaEnvironment();
EmptyAllFantomCharacter();
EmptyAllFantomShips();
wdmEmptyAllDeadQuestEncounter();
pchar.location = "";
PGG_DailyUpdate();
Siege_DailyUpdate();
wdmUpdateAllEncounterLivetime();
Flag_Rerise();

worldMap.playerShipX = getRTplayerShipX();
worldMap.playerShipZ = getRTplayerShipZ();
worldMap.playerShipAY = getRTplayerShipAY();
int nextisland = getRTclosestIsland();
ref rIsland = GetIslandByIndex(nextisland);
worldMap.island = rIsland.id;

ClearAllLogStrings();
ReloadProgressStart();
wdmRemoveOldEncounters();
worldMap.playerInStorm = "0";
wdmReset();
CreateEntity(&worldMap,"worldmap");
worldMap.isLoaded = "true";
worldMap.update = "";
// CreateEntity(&wdm_fader, "fader");
// if(IsEntity(wdm_fader) == 0) Trace("Fader not created!!!");
float fadeInTime = 0.5;
SetSchemeForMap();
PostEvent("EventWorldMapInit", 830);
ReloadProgressEnd();
PostEvent("EventTimeUpdate", 1000);
worldMap.addQuestEncounters = "updateQuest";

wdmLockReload = false;

wdmReloadToSea();
}
 
I believe that my version of "sailing mod" is now functional. It is at best a BETA test version, no worldmap encounter, no storm... but it can change island map with the loading screen automatically showing up, if a different closer island is found.
I've put all the functions in the file "\islands\Islands_loader.c", which is an empty in the original game. I add the following codes into the function "void Whr_WindChange()" located in the file "\Weather\WhrWeather.c", so that when every hour the wind, weather change, my code will be executed to determine whether login to a new map or not.
int nextisland = getRTclosestIsland();
if (nextisland != FindIsland(worldMap.island)) ChangeSeaMapNew();

I still get some weird "error.log" as well, but it doesn't seem to effect the game, and I really don't understand it. The log show as below:
RUNTIME ERROR - file: ships\ships_init.c; line: 7
invalid index 44 [size:44]
RUNTIME ERROR - file: ships\ships_init.c; line: 7
function 'InitShips' stack error
RUNTIME ERROR - file: weather\WhrWeather.c; line: 894
missed attribute: maxseaheight
RUNTIME ERROR - file: weather\WhrWeather.c; line: 894
no rAP data

BTW, I realise that if your ship isn't amazingly fast, sailing like this is an absolutely perfect way to kill your time. Still, there is an parameter "WDM_MAP_TO_SEA_SCALE" that could determine the distance between different islands in sea mode. It is at the very beginning of the file "\WorldMap\worldmap_globals.c", the smaller this parameter is, the smaller the distance will be.
 

Attachments

  • Islands_loader.c
    3.6 KB · Views: 209
Did you look to see how the world map generates the towns, here's one entery for one of the towns in islands_init.
Code:
/////////////////////////////////////////////////////////////////////////
/// Barbados (Bridgetown)
/////////////////////////////////////////////////////////////////////////
n = 0;
Islands[n].id = "Barbados";
Islands[n].model = "barbados";
Islands[n].filespath.models = "islands\barbados";
Islands[n].refl_model = "barbados_refl";
Islands[n].locators = "barbados_locators";
Islands[n].visible = true;
Islands[n].LoadGroup.g1 = "IslandShips1";
Islands[n].jungle.patch = "Barbados_jungle";
Islands[n].jungle.texture = "junglesprites";
Islands[n].jungle.scale = 12.5;
//Islands[n].ImmersionDistance = 3500;
//Islands[n].ImmersionDepth = 250;
Islands[n].TexturePath = "BARBADOS";

Islands[n].reload.l1.label = "Bridgetown Port";
Islands[n].reload.l1.name = "reload_1";
Islands[n].reload.l1.go = "Bridgetown_town";
Islands[n].reload.l1.emerge = "reload1";
Islands[n].reload.l1.radius = 300.0;
Islands[n].reload.l1.istown = true;
Islands[n].reload.l1.pic = 0;
Islands[n].reload.l1.tex = "t1";

Islands[n].reload.l2.label = "Bridgetown Fort";
Islands[n].reload.l2.name = "reload_fort1";
Islands[n].reload.l2.go = "Bridgetown_fort";
Islands[n].reload.l2.GoAfterBoard.location = "reload_1";
Islands[n].reload.l2.emerge = "sea";
Islands[n].reload.l2.radius = 600.0;
Islands[n].reload.l2.fortname = "fort_Bridgetown";
Islands[n].reload.l2.colonyname = "Bridgetown";
Islands[n].reload.l2.fort.model = "Barbados_fort1";
Islands[n].reload.l2.fort.locators = "barbados_fort1_locators";
Islands[n].reload.l2.pic = 1;
Islands[n].reload.l2.tex = "t1";

Islands[n].reload.l3.label = "Mayak2";
Islands[n].reload.l3.name = "reload_2";
Islands[n].reload.l3.go = "Mayak2";
Islands[n].reload.l3.emerge = "sea";
Islands[n].reload.l3.radius = 300.0;
Islands[n].reload.l3.pic = 1;
Islands[n].reload.l3.tex = "t1";

Islands[n].reload.l4.label = "Shore4";
Islands[n].reload.l4.name = "reload_3";
Islands[n].reload.l4.go = "Shore4";
Islands[n].reload.l4.emerge = "sea";
Islands[n].reload.l4.radius = 300.0;
Islands[n].reload.l4.pic = 1;
Islands[n].reload.l4.tex = "t1";

Islands[n].reload.l5.label = "Shore5";
Islands[n].reload.l5.name = "reload_4";
Islands[n].reload.l5.go = "Shore5";
Islands[n].reload.l5.emerge = "sea";
Islands[n].reload.l5.radius = 300.0;
Islands[n].reload.l5.pic = 1;
Islands[n].reload.l5.tex = "t1";

// Islands[n].net.deathmatch.l1..lxx - deathmatch and team deathmatch locators
// Islands[n].net.convoy.l1..l2 - defend convoy(l1 start point)
// Islands[n].net.fort.l1..lxx - 
// boal 16.04.04 -->
Islands[n].Trade.Export.id1 = GOOD_SANDAL;
Islands[n].Trade.Export.id2 = GOOD_WEAPON;
Islands[n].Trade.Export.id3 = GOOD_COFFEE;
Islands[n].Trade.Export.id4 = GOOD_OIL;
Islands[n].Trade.Export.id5 = GOOD_POWDER;
Islands[n].Trade.Export.id6 = GOOD_SUGAR;
Islands[n].Trade.Export.id7 = GOOD_PAPRIKA;
Islands[n].Trade.Export.id8 = GOOD_MOLASES;
Islands[n].Trade.Export.id9 = GOOD_GIN;
Islands[n].Trade.Export.id10 = GOOD_SOAP;
Islands[n].Trade.Export.id11 = GOOD_ALMONDS;

Islands[n].Trade.Import.id1 = GOOD_CINNAMON;
Islands[n].Trade.Import.id2 = GOOD_FOOD;
Islands[n].Trade.Import.id3 = GOOD_BRICK;
Islands[n].Trade.Import.id4 = GOOD_FRUITS;
Islands[n].Trade.Import.id5 = GOOD_PLANKS;
Islands[n].Trade.Import.id6 = GOOD_COPRA;
Islands[n].Trade.Import.id7 = GOOD_ALE;
Islands[n].Trade.Import.id8 = GOOD_COPPER;
Islands[n].Trade.Import.id9 = GOOD_GINGER;
Islands[n].Trade.Import.id10 = GOOD_NUTMEG;

Islands[n].Trade.Contraband.id1 = GOOD_LINEN;
Islands[n].Trade.Contraband.id2 = GOOD_CHOCOLATE;
Islands[n].Trade.Contraband.id3 = GOOD_SAILCLOTH;
Islands[n].Trade.Contraband.id4 = GOOD_CLOTHES;
Islands[n].Trade.Contraband.id5 = GOOD_FLAX;
// boal 16.04.04 <--
Islands[n].InterfaceTextures.t1 = "battle_interface\moor_7.tga";
Islands[n].InterfaceTextures.t1.h = 4;
Islands[n].InterfaceTextures.t1.v = 1;

SendMessage(&locator,"le",LM_LOCATE_I,&Islands[n]);


And i'm not sure what this does, the file is Program\Locations == locations_loader
Code:
int FindLocation(string id)
{
/*
for(int i = 0; i < nLocationsNum; i++)
{
if(Locations[i].id == id)
{
return i;
}
}

return -1;
*/

return NativeFindLocation(&locations, id);

}


I also found this in Program\Locations == locations_camera
Code:
/*void locCameraSetRadius(float fRadius)
{
SendMessage(&locCamera, "lf", MSG_CAMERA_SET_RADIUS, fRadius);
}
*/


And this in Program\Locations == locations.C
Code:
/*
void LocationTestProcess()
{
SetReloadProgressBackImage("Loading\initialization.tga.tx");
ReloadProgressStart();
LocationInit();
Locations_TestAll();
ReloadProgressEnd();
}
*/

and finally this in Program == seadogs.C
Code:
bEnableIslandSailTo        = false;

Not sure if any of that is of help to you.
 
That sounds really cool, njuczy! If you can get the island-to-island stuff to work, that's already a big battle won. The other two things are indeed encounters/storms and trying to get the passage of time on the worldmap and in 3D sailing mode to match up. Especially that last one is something that we never managed to figure out properly in PotC. :facepalm
 
A quick update, every so often i look back at this and search for things to look at and change. Now i can see the fort even though i can't sail to it and i'm miles away from the island (see pictures bellow) i'm thinking if the value at what is generated in the player's field of view is increased then we might be able to sail to and from towns but i have not tested this out yet and need to locate the code that effects player's view radius.






Question:
Would changing this
Code:
locations[n].reload.l30.autoreload = "0";

to read as
Code:
locations[n].reload.l30.autoreload = "1";

mean the game reloads that location?
 
Autoreload generally means that if you're on that locator, you're immediately reloaded to the next location.
This as opposed to having to press [space] to do it.
 
Well i think now that GOF 1.0 is almost finished i will be playing around with this and see what happens, i still think that it is possible to get the islands to generate the towns. If not at least generate the shores and have the ability to ancore in them which should then update the game so that it generates the town etc on the island. If i come up with anything of interest i will update you guy's but for now i am just letting you know what i will be up to. Hopefully i can get it working and we will see it in a future version of GOF, i will be going back over the same tracks to see what those out comes was because i can't remember and need to get to know each code and value again. I should really keep some kind of log for this so i can go back over things i had changed and what the effects of those changes (if any) had. Anyway i have already made some changes ready for testing later on tonight.

Update:
Just a random thourght, but is it possible to intergrate the weather updating to the player's position in the caribbean. So the game will update the weather every hour but also will update any islands the player is close to so they have their ports, shores, jungles etc all generate?

I was thinking because this should rule out any need for a loading screen and should also mean the lag if any coursed by the game generating the towns would not be so bad because you could be over 5000 yards from a island and the game would update that/those islands well before you are close enough to see the islands change.
 
Back
Top