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

DirectSail

Rigged

Landlubber
Storm Modder
Hi all,

Have created a more stable version of DirectSail.

Code:
/*
This scoop (from void InitIslands()) is stoc POTC I thought, 
don't know for sure. For this DirectSail to work correctly 
_all_ Islands[] must have the .id and set at least 
to "" (empty string)

for ( i = 0; i < MAX_ISLANDS; i++ )
{

DeleteAttribute( &Islands[i], "" );

Islands[ i ].id							= "";
Islands[ i ].reload_enable	= true;
Islands[ i ].visible				= true;

}
*/

// TODO : Adjust the radius of the island so that the next island is out of sight before 
//				the next island can show up.
// TODO : When entering the worldmap out of range of any island then go back to OpenSea, 
//				the coordinates are set to 0, 0. They should be converted too.
// TODO : Enter deck and cabins while sailing. (Try to get it keep sailing, change weather, 
//				get encounters etc.)
// TODO : Update weather (dynamicly changing over time)
// TODO : Integrate the EternalString as the interface just like the wind speed and direction.

void DirectSailUpdate()
{

// event added in void InitBattleInterface();
// event removed in void DeleteBattleInterface();
// event first called in StartBattleInterface();

FindNearestIsland();
if( CheckAttribute( MainCharacter, "location.ReloadTo" ) )
{
if( MainCharacter.location.ReloadTo != MainCharacter.location )
{
Sea_ReloadStartSea_Reload();
}
}

Log_SetEternalString( sti( worldMap.playerShipX ) + ", " + sti( worldMap.playerShipZ ) + " " + 

MainCharacter.location );
PostEvent( "DirectSailUpdate", 1000 );

}

string ConvertIslandNameToShortName( string name )
{

if( name == "FalaiseDeFleur" ) name = "FaleDeFler"; //else
//if( name == "asdfg" ) name = "asd";

return name;

}

void DirectSailUpdateCoordinates()
{

if( MainCharacter.location == "" || MainCharacter.location == "open_sea" )
return;

string 	Island	= ConvertIslandNameToShortName( MainCharacter.location );

float 	psX			= MakeFloat( MainCharacter.Ship.Pos.x );
float 	psZ			= MakeFloat( MainCharacter.Ship.Pos.z );

float 	ix			= MakeFloat( worldMap.islands.( Island ).position.rx );
float 	iz			= MakeFloat( worldMap.islands.( Island ).position.rz );

worldMap.playerShipX	= ( psX / WDM_MAP_TO_SEA_SCALE ) + ix;
worldMap.playerShipZ	= ( psZ / WDM_MAP_TO_SEA_SCALE ) + iz;

}

void FindNearestIsland()
{

DirectSailUpdateCoordinates();

int i;
string 	island 				= "";

float 	shipX					= MakeFloat( worldMap.playerShipX );
float 	shipZ					= MakeFloat( worldMap.playerShipZ );

float 	islandX;
float 	islandZ;
float 	distanceX;
float 	distanceZ;
float 	distance;

float 	distanceCurr	= -1;
for( i = 0; i < MAX_ISLANDS; i++ )
{

island		= ConvertIslandNameToShortName( Islands[ i ].id );

if( island != "" )
{

islandX		= stf( worldMap.islands.( island ).position.rx );
islandZ		= stf( worldMap.islands.( island ).position.rz );

distanceX = islandX - shipX;
distanceZ = islandZ - shipZ;

distance	= sqrt( ( distanceX * distanceX ) + ( distanceZ * distanceZ ) );

if( distanceCurr > distance || distanceCurr == -1 )
{

MainCharacter.location.ReloadTo = Islands[ i ].id;
distanceCurr = distance;

}

} else
{

TraceLog( 1, "Invalid island id (" + island + ")" );

}

}

}

void DirectSailSea_Reload()
{

TraceLogStart( 3, "void DirectSailSea_Reload()" );

// Same as Sea_Reload() but initializes Login with coordinates translated to the new island.
DelEventHandler("DirectSailSea_Reload", "DirectSailSea_Reload");

if( CheckAttribute( MainCharacter, "location.ReloadTo" ) )
{

string	island		= MainCharacter.location.ReloadTo;
if( island == "" || island == MainCharacter.location )
{
TraceLogEnd();
return;
}

TraceLog( 1, "Loading island: " + MainCharacter.location.ReloadTo );
// Convert worldmap coordinates to island coordinates
float psX = MakeFloat( worldMap.playerShipX );
float psZ = MakeFloat( worldMap.playerShipZ );
float ix	= MakeFloat( worldMap.islands.( island ).position.rx );
float iz	= MakeFloat( worldMap.islands.( island ).position.rz );

object Login;
Login.PlayerGroup.ay	= stf( MainCharacter.Ship.Ang.y );
Login.PlayerGroup.x		= ( psX - ix ) * WDM_MAP_TO_SEA_SCALE;
Login.PlayerGroup.y		= 0.0;
Login.PlayerGroup.z		= ( psZ - iz ) * WDM_MAP_TO_SEA_SCALE;
Login.Island					= island;
DeleteAttribute( MainCharacter, "location.ReloadTo" );

SeaLogin( &Login );

}

TraceLogEnd();

}

void Sea_ReloadStartSea_Reload()
{

TraceLogStart( 3, "void Sea_ReloadStartSea_Reload()" );
// Same as Sea_ReloadStart() but calls DirectSailSea_Reload() instead of Sea_Reload().
if( !bSeaActive )
return;

DeleteSeaEnvironment();
SetEventHandler( "DirectSailSea_Reload", "DirectSailSea_Reload", 0 );
PostEvent( "DirectSailSea_Reload", 1 );

TraceLogEnd();

}

Busy with the deck loading part and encounters on sea.

:drunk
Two Eyed
 
Forgat to tell that I made MainCharacter a global ref. So you might want to change that too.

For the stable part, with me, it has never crashed. As it is just using the stock function SeaLogin. So, all is done in the way it was coded, with and without Akella's errors wich worked.

Second advantage I could think of is the for scoop in void FindNearestIsland(); It is no longer needed to update the DirectSail when added/changing islands.

The implementation of encounters and weahter would have their own event, timed at a random number.

Wishlist thing:
Only a few parts of the weather needs a reload (at least I think, :mm didn't look at that yet) so it can be updated more frequent, changing the direction and speed just slightly. Making it more accurate and brings in the realism to plot your course over and over again :whipa


cy
Two Eyed,
 
Second advantage I could think of is the for scoop in void FindNearestIsland(); It is no longer needed to update the DirectSail when added/changing islands.

When an island is added, the file DirectSail.c needs to be updated with the new island or it won't be noticed thus directed to it.


The implementation of encounters and weahter would have their own event, timed at a random number.

Encounters (and weather) are generated while doing directsail stuff every hour.
My aim will be to create an event for an encounter outside the directsail.

Code:
void initbattleinterface()
SetEventHandler("EncounterUpdate","EncounterUpdate",0); (and delevent)

void EncounterUpdate()
{
// ...
float next = Frand( 1800000 ) + 1800000; // next encouner between 30 to 60 minutes
PostEvent( "EncounterUpdate", next );
}


Only a few parts of the weather needs a reload (at least I think, :mm didn't look at that yet) so it can be updated more frequent, changing the direction and speed just slightly. Making it more accurate and brings in the realism to plot your course over and over again :whipa

the weather needs a reload of the seaenvironment to change scenery but the direction is just a number. That number can be changed without reloading the entire scene.

The realism would be if you steer towards an island and the wind direction changes after 10 minutes or so with a degree of 90 it could be that the wind isn't sideways but comming from the island. Needing a course change and so the DirectSai would be less dul.

cy
Two Eyed,

again here :b:
 
Is this based on the original Build 13 version or the Build 14 Beta 1 code?
The latter is really quite different and I think it no longer requires islands to be defined in the DirectSail.c file.

One issue that we DO still have is the time scale difference.
While a worldmap voyage takes several game days, DirectSail takes several hours.
To counter that, we added one day to the calender for every hour at sea,
but that is rather arbitrary, weird and confusing.
If you can, that'd be a wonderful thing to have sorted. :yes
 
well here is a fast reply, hehe

The code is based upon stock POTC, as I think it wouldn't matter. Haven't looked Build 14 thou.

The reason why I used stock is the number of bugs and this way I am more able to find the structure Akella used.
 
Well, that is (have installed stock _and_ Build13 together) that I have looked at CCC's part. So credits still to him and Akella.


One issue that we DO still have is the time scale difference.
...
If you can, that'd be a wonderful thing to have sorted. :yes

Will have a look at this, is there a change between 13 and 14 on this matter? So consider it as done.

TwoEyed
 
The Build 14 code still works on the same concept, but there's been a lot of updates made to it.
 
Back
Top