NWNDS/nwnds_module/area_trans.nss
Jaysyn904 de24f81734 Added NWN Dark Sun module contents
Added NWN Dark Sun module contents.
2021-07-12 21:24:46 -04:00

661 lines
26 KiB
Plaintext

//::///////////////////////////////////////////////
//:: area_trans
//:://////////////////////////////////////////////
/*
SEAMLESS AREA TRANSITIONS v1.1
Version 1:
- areas can be different sizes
- a module can have more than one grid ("Region")
Version 1.1:
- SetLocalInt(oPC, "AREATRANS_DIRECTION_BACKUP", nDir)
new local integer used in diagonal transitions
if the diagonal direction fails, the nearest cardinal direction (N, S, E, or W)
is used in its place to find a transition area
- int AREATRANS_SQUARES_PER_GRID_UNIT
new global used to correct math error in FindAreaContainingGridTag()
- string GetDirectionName(int nDir)
new function to encapsulate code for generating name from direction integer
Otherwise this script shares functionality with and is compatible with Jaga's Seamless Area Transitioner.
http://nwvault.ign.com/View.php?view=scripts.Detail&id=89
by Jaga Te'lesin (jaga-nwn@earthlink.net)
Jaga's work was the inspiration for this rewrite.
For instructions please see the Read Me.
*/
//:://////////////////////////////////////////////
//:: Created: The Magus (2013 mar 9)
//:: Modified: The Magus (2013 mar 12) v1.1
//:://////////////////////////////////////////////
// GLOBALS ---------------------------------------------------------------------
// USER CONFIGURABLE
object AREATRANS_DATA = GetModule(); // Data Object holding area tags for each grid coord
const int AREATRANS_DEBUG = FALSE; // TRUE turns debugging feedback on
const int AREATRANS_GRID_CARTESIAN = FALSE; // use FALSE If this script is replacing Jaga's AreaTrans in an existing module
// The original Area Trans Grid was NOT cartesian
// TRUE will expect Grid coordinates to be cartesian
const float AREATRANS_DIAGONAL_OFFSET = 3.5f; // Distance out from any corner to sense diagonal movement (8 to 15 recommended)
const float AREATRANS_LANDING_OFFSET = 4.0f; // Distance out from edge in destination Area that PC will land (8 to 10 recommended)
const float AREATRANS_DELAY = 0.0f; // Delay before zoning
const float AREATRANS_REFACTORY_PERIOD = 9.0f; // delay to prevent zoning on arrival in new area
const int AREATRANS_FLEXIBLE_GRID = TRUE; // TRUE - each area regardless of size occupies only one grid coordinate
// FALSE - an area depending on size, may occupy more than one grid coordinate. See below.
const float AREATRANS_GRID_UNIT = 40.0; // INFLEXIBLE GRIDS:
// default area dimension in meters for each grid.
// This becomes the smallest size you can use for a dimension of an area
// The dimensions of larger areas must be a multiple of this figure.
// FLEXIBLE GRID:
// Unused
int AREATRANS_SQUARES_PER_GRID_UNIT = FloatToInt(AREATRANS_GRID_UNIT/10.0);
// DO NOT ADJUST THESE Directional constants
const int ERROR = -1;
const int NORTH = 1; // bit 1
const int SOUTH = 2; // bit 2
const int EAST = 4; // bit 3
const int WEST = 8; // bit 4
const int NORTHEAST = 5; // north + east
const int SOUTHEAST = 6; // south + east
const int NORTHWEST = 9; // north + west
const int SOUTHWEST = 10; // south + west
// OTHER DATA ------------------------------------------------------------------
struct GRIDCOORD
{
string prefix;
string Xtag;
string Ytag;
string Ztag;
int Xpos;
int Ypos;
int Zpos;
};
// FUNCTION DECLARATIONS -------------------------------------------------------
// leftover from Jaga's Seamless Area Transitioner. To be modified someday with unique VFX. - [FILE: area_trans]
void TransportEffect( object oTarget , float fDuration );
// Converts an integer to a string for use in the grid coord tag - [FILE: area_trans]
string GetCoordString(int nCoord);
// Returns the first prefix of a tag, without the underscore - [FILE: area_trans]
string GetTagPrefix(string sTag);
// Takes a Grid Tag and breaks it down into its components - [FILE: area_trans]
struct GRIDCOORD ParseGridTag(string sGridTag);
// Returns a tag representing coordinates on grid - [FILE: area_trans]
string GetGridTagAtPositionInArea(struct GRIDCOORD GridCoord, vector vPosition);
// Returns a tag representing coordinates on grid - [FILE: area_trans]
string GetGridTagAtDirection(struct GRIDCOORD GridCoord, int nDir, int nDist=1);
// Called by GetTransitionArea. - [FILE: area_trans]
// Looks for the area origin, by crawling from one grid node to the next FROM the grid node that the PC is transitioning to
object FindAreaContainingGridTag(string sDestGridTag, int nDir, object oPC);
// Returns an integer representing the direction that the PC is transitioning from the area - [FILE: area_trans]
// returns -1 on Error
int GetTransitionDirection(vector vPCVector, float fAreaThisHeight, float fAreaThisWidth, object oPC);
// Returns the name of the direction - [FILE: area_trans]
string GetDirectionName(int nDir);
// Returns an area object in nDir direction from the grid coords sPCGridTag - [FILE: area_trans]
object GetTransitionArea(string sDestGridTag, int nDir, object oPC);
// FUNCTION IMPLEMENTATIONS ----------------------------------------------------
void TransportEffect (object oTarget, float fDuration)
{
effect eZoneEffect1 = EffectVisualEffect(VFX_DUR_INVISIBILITY);
//effect eZoneEffect2 = EffectVisualEffect(VFX_IMP_ACID_L);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eZoneEffect1,oTarget,(fDuration*2.0f));
//ApplyEffectToObject(DURATION_TYPE_INSTANT,eZoneEffect2,oTarget);
}
string GetCoordString(int nCoord)
{
string sCoord = IntToString(abs(nCoord));
if ((nCoord < 10) && (nCoord > -1)) return ("p0"+sCoord);
else if ((nCoord > 9) && (nCoord < 100)) return ("p"+sCoord);
else if ((nCoord > -10) && (nCoord < 0)) return ("n0"+sCoord);
else if ((nCoord > -100) && (nCoord < -9)) return ("n"+sCoord);
return "";
}
string GetTagPrefix(string sTag)
{
string sTagPrefix = "";
int iPos1 = FindSubString(sTag, "_");
int iPos2;
int iLastPos = GetStringLength(sTag)-1;
if (iPos1 > 0)
{
sTagPrefix = GetStringLeft(sTag, iPos1); // returns prefix without underscores
}
else if (iPos1 == 0)
{
// we have a leading underscore
iPos2 = FindSubString(sTag, "_", ++iPos1);// look for a second underscore
if (iPos2 != -1 && iPos2 != 1 && iPos2 != iLastPos) // ignore: _XXXXX , __XXXX , _XXXX_
{
sTagPrefix = GetSubString(sTag, iPos1, iPos2 - iPos1);
}
}
return sTagPrefix;
}
struct GRIDCOORD ParseGridTag(string sGridTag)
{
struct GRIDCOORD GridCoord;
GridCoord.prefix = GetStringLeft(sGridTag, (GetStringLength(sGridTag)-9) );
string sAreaTagCoord = GetStringRight(sGridTag, 9);
GridCoord.Xtag = GetStringLeft(sAreaTagCoord,3); // X-coordinate of current area (from Tag)
GridCoord.Ytag = GetSubString(sAreaTagCoord,3,3); // Y-coordinate of current area (from Tag)
GridCoord.Ztag = GetStringRight(sAreaTagCoord,3); // Z-coordinate of current area (from Tag)
GridCoord.Xpos = StringToInt(GetStringRight(GridCoord.Xtag,2));
if(!(GetStringLeft(GridCoord.Xtag,1)=="p"))
GridCoord.Xpos *= -1;
GridCoord.Ypos = StringToInt(GetStringRight(GridCoord.Ytag,2));
if(!(GetStringLeft(GridCoord.Ytag,1)=="p"))
GridCoord.Ypos *= -1;
GridCoord.Zpos = StringToInt(GetStringRight(GridCoord.Ztag,2));
if(!(GetStringLeft(GridCoord.Ztag,1)=="p"))
GridCoord.Zpos *= -1;
return GridCoord;
}
string GetGridTagAtPositionInArea(struct GRIDCOORD GridCoord, vector vPosition)
{
int nPosX = GridCoord.Xpos + FloatToInt( (vPosition.x/AREATRANS_GRID_UNIT) );
int nPosY;
// This bit of code is required to make this code compatible with the original seamless area trans grid coordinates
// the original seamless area transitions used a non-cartesian grid in which numbers increased going south and east
// On a cartesian grid numbers increase going north and east
if(!AREATRANS_GRID_CARTESIAN)
nPosY = GridCoord.Ypos - FloatToInt( (vPosition.y/AREATRANS_GRID_UNIT) );
else
nPosY = GridCoord.Ypos + FloatToInt( (vPosition.y/AREATRANS_GRID_UNIT) );
// construct grid tag in same manner as area tag
return( GridCoord.prefix + GetCoordString(nPosX) + GetCoordString(nPosY) + GridCoord.Ztag );
}
string GetGridTagAtDirection(struct GRIDCOORD GridCoord, int nDir, int nDist=1)
{
int nPosX = GridCoord.Xpos;
int nPosY = GridCoord.Ypos;
if(AREATRANS_GRID_CARTESIAN)
{
//if(nDir==NORTH || nDir==NORTHEAST || nDir==NORTHWEST)
if(nDir&NORTH)
nPosY += nDist;
//else if(nDir==SOUTH || nDir==SOUTHEAST || nDir==SOUTHWEST)
else if(nDir&SOUTH)
nPosY -= nDist;
}
else
{
//if(nDir==NORTH || nDir==NORTHEAST || nDir==NORTHWEST)
if(nDir&NORTH)
nPosY -= nDist;
//else if(nDir==SOUTH || nDir==SOUTHEAST || nDir==SOUTHWEST)
else if(nDir&SOUTH)
nPosY += nDist;
}
//if(nDir==EAST || nDir==NORTHEAST || nDir==SOUTHEAST)
if(nDir&EAST)
nPosX += nDist;
//else if(nDir==WEST || nDir==NORTHWEST || nDir==SOUTHWEST)
else if(nDir&WEST)
nPosX -= nDist;
// construct grid tag in same manner as area tag
return( GridCoord.prefix + GetCoordString(nPosX) + GetCoordString(nPosY) + GridCoord.Ztag );
}
object FindAreaContainingGridTag(string sDestGridTag, int nDir, object oPC)
{
// if nothing is found look for the valid area tag by cycling through nearby grid coordinates
string sAreaGridTag;
int nMax = FloatToInt(320.0/AREATRANS_GRID_UNIT)-1;
int nMaxSouth, nMaxWest, nDist;
int nSouth, nWest;
if(nDir!=NORTH)
nMaxSouth = nMax;
if(nDir!=EAST)
nMaxWest = nMax;
struct GRIDCOORD SearchCoord = ParseGridTag(sDestGridTag);
object oArea = OBJECT_INVALID;
while(oArea==OBJECT_INVALID)
{
if(nSouth<nMaxSouth)
{
// Search South
sAreaGridTag = GetGridTagAtDirection(SearchCoord, SOUTH, ++nSouth);
if(AREATRANS_DEBUG)
SendMessageToPC(oPC,"Searching South ("+IntToString(nSouth)+"): "+sAreaGridTag);
}
else if(nWest<nMaxWest)
{
// Reset Southward search and search West
nSouth = 0;
++nWest;
if(nDir==NORTHEAST)
nMaxSouth = 0;
sAreaGridTag = GetGridTagAtDirection(SearchCoord, WEST);
SearchCoord = ParseGridTag(sAreaGridTag);
if(AREATRANS_DEBUG)
SendMessageToPC(oPC,"Shifting West ("+IntToString(nWest)+"): "+sAreaGridTag);
}
else
{
// Out of bounds
break;
}
oArea = GetObjectByTag(sAreaGridTag);
if(oArea!=OBJECT_INVALID)
{
int nSquareHeight = GetAreaSize(AREA_HEIGHT, oArea)/AREATRANS_SQUARES_PER_GRID_UNIT;
if(!nSquareHeight) nSquareHeight=1;
int nSquareWidth = GetAreaSize(AREA_WIDTH, oArea)/AREATRANS_SQUARES_PER_GRID_UNIT;
if(!nSquareWidth) nSquareWidth=1;
if( nSquareHeight<=nSouth
|| nSquareWidth<=nWest
)
{
oArea = OBJECT_INVALID;
}
else
SetLocalString(AREATRANS_DATA, sDestGridTag, sAreaGridTag);
}
}
return oArea;
}
int GetTransitionDirection(vector vPCVector, float fAreaThisHeight, float fAreaThisWidth, object oPC)
{
int nDir = ERROR; // return value on error
int bNorth, bSouth, bEast, bWest;
bNorth = (vPCVector.y > (fAreaThisHeight-10.0));
if(!bNorth)
bSouth = (vPCVector.y <= 10.0);
bEast = (vPCVector.x > (fAreaThisWidth-10.0));
if(!bEast)
bWest = (vPCVector.x <= 10.0);
// On Northern edge tile (area)
if(bNorth)
{
// On North-Eastern corner tile
if(bEast)
{
float fNorthDist = fAreaThisHeight - vPCVector.y; // Distance from North edge
float fEastDist = fAreaThisWidth - vPCVector.x; // Distance from East edge
if(fNorthDist<=AREATRANS_DIAGONAL_OFFSET && fEastDist<=AREATRANS_DIAGONAL_OFFSET)
{
nDir = NORTHEAST;
if(fEastDist<fNorthDist)
SetLocalInt(oPC, "AREATRANS_DIRECTION_BACKUP", EAST);
else
SetLocalInt(oPC, "AREATRANS_DIRECTION_BACKUP", NORTH);
}
else if(fEastDist<fNorthDist)
nDir = EAST;
else
nDir = NORTH;
}
// On North-Western corner tile
else if(bWest)
{
float fNorthDist = fAreaThisHeight - vPCVector.y; // Distance from North edge
if(fNorthDist<=AREATRANS_DIAGONAL_OFFSET && vPCVector.x<=AREATRANS_DIAGONAL_OFFSET)
{
nDir = NORTHWEST;
if(vPCVector.x<fNorthDist)
SetLocalInt(oPC, "AREATRANS_DIRECTION_BACKUP", WEST);
else
SetLocalInt(oPC, "AREATRANS_DIRECTION_BACKUP", NORTH);
}
else if(vPCVector.x<fNorthDist)
nDir = WEST;
else
nDir = NORTH;
}
else
nDir= NORTH;
}
// On Southern edge tile (area)
else if(bSouth)
{
// On South-Eastern corner tile
if(bEast)
{
float fEastDist = fAreaThisWidth - vPCVector.x; // Distance from East edge
if(vPCVector.y<=AREATRANS_DIAGONAL_OFFSET && fEastDist<=AREATRANS_DIAGONAL_OFFSET)
{
nDir = SOUTHEAST;
if(fEastDist<vPCVector.y)
SetLocalInt(oPC, "AREATRANS_DIRECTION_BACKUP", EAST);
else
SetLocalInt(oPC, "AREATRANS_DIRECTION_BACKUP", SOUTH);
}
else if(fEastDist<vPCVector.y)
nDir = EAST;
else
nDir = SOUTH;
}
// On South-Western corner tile
else if(bWest)
{
if(vPCVector.y<=AREATRANS_DIAGONAL_OFFSET && vPCVector.x<=AREATRANS_DIAGONAL_OFFSET)
{
nDir = SOUTHWEST;
if(vPCVector.x<vPCVector.y)
SetLocalInt(oPC, "AREATRANS_DIRECTION_BACKUP", WEST);
else
SetLocalInt(oPC, "AREATRANS_DIRECTION_BACKUP", SOUTH);
}
else if(vPCVector.x<vPCVector.y)
nDir = WEST;
else
nDir = SOUTH;
}
else
nDir= SOUTH;
}
else if(bEast)
nDir = EAST;
else if(bWest)
nDir = WEST;
return nDir;
}
string GetDirectionName(int nDir)
{
string sDir;
if(nDir&NORTH)
sDir="north";
else if(nDir&SOUTH)
sDir="south";
if(nDir&EAST)
sDir+="east";
else if(nDir&WEST)
sDir+="west";
return sDir;
}
object GetTransitionArea(string sDestGridTag, int nDir, object oPC)
{
// look up the area for those coordinates
object oArea = GetObjectByTag(sDestGridTag);
if(!AREATRANS_FLEXIBLE_GRID && oArea==OBJECT_INVALID)
{
// "table" look up
oArea = GetObjectByTag(GetLocalString(AREATRANS_DATA, sDestGridTag));
if(oArea==OBJECT_INVALID)
{
// search for area
oArea = FindAreaContainingGridTag(sDestGridTag, nDir, oPC);
}
}
return oArea;
}
void main()
{
object oPC = GetClickingObject();
if(oPC==OBJECT_INVALID || GetLocalInt(oPC,"m_nZoning"))
{
if(AREATRANS_DEBUG)
SendMessageToPC(oPC,"The transition refractory period has not elapsed yet...");
SendMessageToAllDMs("AREA TRANS: "+GetName(oPC)+" was either invalid, already zoning, or had it's Don't Zone flag set.");
return;
}
else if(GetLocalInt(GetLocalObject(oPC, "SpawnedBy"),"DontZone")==1)
return;
location lLocPC = GetLocation(oPC);
vector vPCVector = GetPositionFromLocation(lLocPC); // PC's current Vector
object oAreaThis = GetArea(OBJECT_SELF);
int nAreaThisHeight = GetAreaSize(AREA_HEIGHT, oAreaThis);
int nAreaThisWidth = GetAreaSize(AREA_WIDTH, oAreaThis);
float fAreaThisHeight = nAreaThisHeight*10.0;
float fAreaThisWidth = nAreaThisWidth*10.0;
// Parse this Area's Grid Coordinates
struct GRIDCOORD AreaThis = ParseGridTag(GetTag(oAreaThis));
// Get PC's Grid Coordinates
struct GRIDCOORD PCOrig;
if( AREATRANS_FLEXIBLE_GRID
||( fAreaThisHeight==AREATRANS_GRID_UNIT
&& fAreaThisWidth==AREATRANS_GRID_UNIT
)
)
PCOrig = AreaThis;
else
PCOrig = ParseGridTag(GetGridTagAtPositionInArea(AreaThis,vPCVector));
// Get Direction of Transition
int nDir = GetTransitionDirection(vPCVector, fAreaThisHeight, fAreaThisWidth, oPC);
// Get Tag of Destination Grid Coordinates
string sDestGridTag = GetGridTagAtDirection(PCOrig, nDir);
if(AREATRANS_DEBUG)
SendMessageToPC(oPC, "AREA("+GetTag(oAreaThis)+") ORIGIN("+GetGridTagAtPositionInArea(AreaThis,vPCVector)+") DIRECTION("+GetDirectionName(nDir)+") DEST("+sDestGridTag+")");
// Get Area of Transition
object oAreaDest = GetTransitionTarget(OBJECT_SELF);
if(oAreaDest!=OBJECT_INVALID)
{
oAreaDest = GetArea(oAreaDest);
}
else
{
oAreaDest = GetTransitionArea(sDestGridTag, nDir, oPC);
}
if( oAreaDest==OBJECT_INVALID )
{
// Backup Direction to try?
int nDirBak = GetLocalInt(oPC, "AREATRANS_DIRECTION_BACKUP");
if(nDirBak)
{
nDir = nDirBak;
sDestGridTag = GetGridTagAtDirection(PCOrig, nDir);
if(AREATRANS_DEBUG)
SendMessageToPC(oPC, "SECOND TRY AREA("+GetTag(oAreaThis)+") ORIGIN("+GetGridTagAtPositionInArea(AreaThis,vPCVector)+") DIRECTION("+GetDirectionName(nDir)+") DEST("+sDestGridTag+")");
oAreaDest = GetTransitionArea(sDestGridTag, nDir, oPC);
}
}
// Garbage collection
DeleteLocalInt(oPC, "AREATRANS_DIRECTION_BACKUP");
// Get Position in Destination Area ----------------------------------------
float fX; // east-west within destination area to western edge of gridline
float fY; // north-south within destination area to southern edge of grid
// INFLEXIBLE GRID
if(!AREATRANS_FLEXIBLE_GRID)
{
struct GRIDCOORD Orig = ParseGridTag(GetTag(oAreaDest));
struct GRIDCOORD Dest = ParseGridTag(sDestGridTag);
if(nDir==NORTH)
{
fX = ((Dest.Xpos-Orig.Xpos) * AREATRANS_GRID_UNIT);
fX += (vPCVector.x - ((PCOrig.Xpos-AreaThis.Xpos) * AREATRANS_GRID_UNIT));
fY = AREATRANS_LANDING_OFFSET;
}
else if(nDir==SOUTH)
{
fX = ((Dest.Xpos-Orig.Xpos) * AREATRANS_GRID_UNIT);
fX += (vPCVector.x - ((PCOrig.Xpos-AreaThis.Xpos) * AREATRANS_GRID_UNIT));
fY = (10.0*GetAreaSize(AREA_HEIGHT, oAreaDest)) - AREATRANS_LANDING_OFFSET;
}
else if(nDir==EAST)
{
fX = AREATRANS_LANDING_OFFSET;
fY = (abs(Dest.Ypos-Orig.Ypos) * AREATRANS_GRID_UNIT);
fY += (vPCVector.y - (abs(PCOrig.Ypos-AreaThis.Ypos) * AREATRANS_GRID_UNIT));
}
else if(nDir==WEST)
{
fX = (10.0*GetAreaSize(AREA_WIDTH, oAreaDest)) - AREATRANS_LANDING_OFFSET;
fY = (abs(Dest.Ypos-Orig.Ypos) * AREATRANS_GRID_UNIT);
fY += (vPCVector.y - (abs(PCOrig.Ypos-AreaThis.Ypos) * AREATRANS_GRID_UNIT));
}
else if(nDir==NORTHEAST)
{
fX = ((Dest.Xpos-Orig.Xpos)*AREATRANS_GRID_UNIT) + AREATRANS_LANDING_OFFSET;
fY = (abs(Dest.Ypos-Orig.Ypos)*AREATRANS_GRID_UNIT) + AREATRANS_LANDING_OFFSET;
}
else if(nDir==SOUTHEAST)
{
fX = ((Dest.Xpos-Orig.Xpos)*AREATRANS_GRID_UNIT) + AREATRANS_LANDING_OFFSET;
fY = (abs(Dest.Ypos-Orig.Ypos)*AREATRANS_GRID_UNIT) + (AREATRANS_GRID_UNIT-AREATRANS_LANDING_OFFSET);
}
else if(nDir==SOUTHWEST)
{
fX = ((Dest.Xpos-Orig.Xpos)*AREATRANS_GRID_UNIT) + (AREATRANS_GRID_UNIT-AREATRANS_LANDING_OFFSET);
fY = (abs(Dest.Ypos-Orig.Ypos)*AREATRANS_GRID_UNIT) + (AREATRANS_GRID_UNIT-AREATRANS_LANDING_OFFSET);
}
else if(nDir==NORTHWEST)
{
fX = ((Dest.Xpos-Orig.Xpos)*AREATRANS_GRID_UNIT) + (AREATRANS_GRID_UNIT-AREATRANS_LANDING_OFFSET);
fY = (abs(Dest.Ypos-Orig.Ypos)*AREATRANS_GRID_UNIT) + AREATRANS_LANDING_OFFSET;
}
}
// FLEXIBLE GRID
else
{
if(nDir==NORTH)
{
int nAreaDestWidth = GetAreaSize(AREA_WIDTH, oAreaDest);
fX = vPCVector.x * (nAreaDestWidth/IntToFloat(nAreaThisWidth));
if(fX<AREATRANS_LANDING_OFFSET)
fX = AREATRANS_LANDING_OFFSET;
else if(fX>((10.0*nAreaDestWidth)-AREATRANS_LANDING_OFFSET))
fX = ((10.0*nAreaDestWidth)-AREATRANS_LANDING_OFFSET);
fY = AREATRANS_LANDING_OFFSET;
}
else if(nDir==SOUTH)
{
int nAreaDestWidth = GetAreaSize(AREA_WIDTH, oAreaDest);
fX = vPCVector.x * (nAreaDestWidth/IntToFloat(nAreaThisWidth));
if(fX<AREATRANS_LANDING_OFFSET)
fX = AREATRANS_LANDING_OFFSET;
else if(fX>((10.0*nAreaDestWidth)-AREATRANS_LANDING_OFFSET))
fX = ((10.0*nAreaDestWidth)-AREATRANS_LANDING_OFFSET);
fY = (10.0*GetAreaSize(AREA_HEIGHT, oAreaDest)) - AREATRANS_LANDING_OFFSET;
}
else if(nDir==EAST)
{
int nAreaDestHeight = GetAreaSize(AREA_HEIGHT, oAreaDest);
fX = AREATRANS_LANDING_OFFSET;
fY = vPCVector.y * (nAreaDestHeight/IntToFloat(nAreaThisHeight));
if(fY<AREATRANS_LANDING_OFFSET)
fY = AREATRANS_LANDING_OFFSET;
else if(fY>((10.0*nAreaDestHeight)-AREATRANS_LANDING_OFFSET))
fY = ((10.0*nAreaDestHeight)-AREATRANS_LANDING_OFFSET);
}
else if(nDir==WEST)
{
int nAreaDestHeight = GetAreaSize(AREA_HEIGHT, oAreaDest);
fX = (10.0*GetAreaSize(AREA_WIDTH, oAreaDest)) - AREATRANS_LANDING_OFFSET;
fY = vPCVector.y * (nAreaDestHeight/IntToFloat(nAreaThisHeight));
if(fY<AREATRANS_LANDING_OFFSET)
fY = AREATRANS_LANDING_OFFSET;
else if(fY>((10.0*nAreaDestHeight)-AREATRANS_LANDING_OFFSET))
fY = ((10.0*nAreaDestHeight)-AREATRANS_LANDING_OFFSET);
}
else if(nDir==NORTHEAST)
{
fX = AREATRANS_LANDING_OFFSET;
fY = AREATRANS_LANDING_OFFSET;
}
else if(nDir==SOUTHEAST)
{
fX = AREATRANS_LANDING_OFFSET;
fY = (10.0*GetAreaSize(AREA_HEIGHT, oAreaDest)) - AREATRANS_LANDING_OFFSET;
}
else if(nDir==SOUTHWEST)
{
fX = (10.0*GetAreaSize(AREA_WIDTH, oAreaDest)) - AREATRANS_LANDING_OFFSET;
fY = (10.0*GetAreaSize(AREA_HEIGHT, oAreaDest)) - AREATRANS_LANDING_OFFSET;
}
else if(nDir==NORTHWEST)
{
fX = (10.0*GetAreaSize(AREA_WIDTH, oAreaDest)) - AREATRANS_LANDING_OFFSET;
fY = AREATRANS_LANDING_OFFSET;
}
}
if(AREATRANS_DEBUG)
{
SendMessageToPC(oPC,"AREA FROM ("+GetTag(oAreaThis)+") TO ("+GetTag(oAreaDest)+")");
SendMessageToPC(oPC,"GRID FROM ("+GetGridTagAtPositionInArea(AreaThis,vPCVector)+") TO ("+sDestGridTag+")");
SendMessageToPC(oPC,"POSITION FROM ("+FloatToString(vPCVector.x,6)+", "+FloatToString(vPCVector.y,6)+") TO ("+FloatToString(fX,6)+", "+FloatToString(fY,6)+")");
}
if(oAreaDest!=OBJECT_INVALID)
{
//if(!GetIsPC(oPC))
// SetCommandable(TRUE, oPC);
// Enable pursuit - by providing transition to go to
//SetLocalObject(oPC, "TRANSITION_LAST", OBJECT_SELF);
//SetLocalLocation(oPC,"TRANSITION_LAST", lLocPC);
//effect eZoneEffect3 = EffectVisualEffect(VFX_IMP_ACID_L); // ZoneIn effect for end-of-transition
location lDestination = Location(oAreaDest, Vector(fX, fY), GetFacingFromLocation(lLocPC));
SetLocalInt(oPC,"m_nZoning",TRUE);
TransportEffect(oPC,AREATRANS_DELAY);
string sDir = GetDirectionName(nDir);
SendMessageToPC(oPC, "... heading "+GetStringUpperCase(GetStringLeft(sDir,1))+GetStringRight(sDir,GetStringLength(sDir)-1)+" ...");
DelayCommand( AREATRANS_DELAY,
AssignCommand(oPC, JumpToLocation(lDestination) )
);
DelayCommand( AREATRANS_DELAY+AREATRANS_REFACTORY_PERIOD,
DeleteLocalInt(oPC,"m_nZoning")
);
/*
DelayCommand( AREATRANS_DELAY,
ApplyEffectAtLocation(DURATION_TYPE_INSTANT,eZoneEffect3,lDestination)
);
*/
}
else if(AREATRANS_DEBUG)
SendMessageToPC(oPC,"Movement to an invalid area attempted. Area was not found with specified TAG.");
}