A while ago, someone wanted a way to save the location of a player to be recalled later. This is useful for a portalling system where the player casts a portal on the ground in the dungeon, then uses the portal to return to town and after doing some business in the town, uses a portal in town to return to where they were in the dungeon.
I have written some scripts which should handle this. The method used is to save the player's location as a string in an object's description.
The player must be carrying an object (preferably undroppable) which their location can be saved to. One possible way of doing this is to give the player an undroppable item when they first enter the game. If you wish, the item could also double as the portal-casting wand.
Every area in your module needs to have a unique tag. Having more than one area with the same tag can cause the GetLocationFromObject function to return the wrong location.
These functions can only be used with an item (preferably) or placeable as the target since they are the only objects with descriptions.
Save the following code as script inc_savelocation in your module. In any script where you need to set or get the location, place the include command at the start of the script and you can then use any of the functions in the include file.
#include "inc_savelocation"
*** Begin Code ***
/* inc_savelocation
Saves and retrieves a location to the description of an object. */
// Saves location lWhere at the end of the description of oObject and
// precedes the location information with sKey so it can be found by the
// GetLocationFromObject function. Returns TRUE on success or FALSE otherwise.
int SetLocationOnObject(object oObject,location lWhere,string sKey="xYz");
// Searches the description of oObject for string sKey and attempts to
// create a new location from the information following that key.
// Returns the location of oObject or oObject's container on failure.
location GetLocationFromObject(object oObject,string sKey="xYz");
// Finds the key string sKey and deletes any stored location including
// the key. Returns TRUE on success, FALSE on any failure.
int DeleteLocationFromObject(object oObject,string sKey="xYz");
int SetLocationOnObject(object oObject,location lWhere,string sKey="xYz")
{
// We need to find if there's already a location stored on this object
// using the key string. If it exists, we need to delete and replace it.
DeleteLocationFromObject(oObject,sKey);
// Find the current description on the object.
string sDescript=GetDescription(oObject);
// Convert the location components to a string so they can be saved later.
// The string begins with sKey followed by the tag of the area, then the x,
// y and z values of the vector and the facing value. These are delimited by
// colons ":" to make separating them later easier.
object oArea=GetAreaFromLocation(lWhere);
if(!GetIsObjectValid(oArea)) return FALSE;
string sWhere=":"+sKey+":"+GetTag(oArea);
vector vWhere=GetPositionFromLocation(lWhere);
sWhere=sWhere+":"+FloatToString(vWhere.x)+":"+
FloatToString(vWhere.y)+":"+FloatToString(vWhere.z);
float fWhere=GetFacingFromLocation(lWhere);
sWhere=sWhere+":"+FloatToString(fWhere)+":";
// Add the location info to the description.
sDescript=sDescript+sWhere;
// Set the new description.
SetDescription(oObject,sDescript);
return TRUE;
}
location GetLocationFromObject(object oObject,string sKey="xYz")
{
// Get the description from the object.
string sDescript=GetDescription(oObject);
//*** Find the area.
// Try to find the key string in the description.
int iKey=FindSubString(sDescript,sKey);
// If the key string does not exist, return failure.
if(iKey<0) return GetLocation(oObject);
// Adjust iKey to point to the first character of the area tag.
iKey=iKey+GetStringLength(sKey)+1;
// Find the next delimiter so we know where the area tag ends.
int iKey2=FindSubString(sDescript,":",iKey);
// If there is no next delimiter, return failure.
if(iKey2<0) return GetLocation(oObject);
// Extract the area tag from the description.
string sArea=GetSubString(sDescript,iKey,iKey2-iKey);
// Find the area.
object oArea=GetObjectByTag(sArea);
// If the area is invalid, return failure.
if(!GetIsObjectValid(oArea)) return GetLocation(oObject);
//*** Extract the x value
// Point to the x value for the vector.
iKey=iKey2+1;
// Find the next delimiter so we know where the x value ends.
iKey2=FindSubString(sDescript,":",iKey);
// If there is no next delimiter, return failure.
if(iKey2<0) return GetLocation(oObject);
// Extract the x value for the vector.
float fX=StringToFloat(GetSubString(sDescript,iKey,iKey2-iKey));
//*** Extract the y value
// Point to the y value for the vector.
iKey=iKey2+1;
// Find the next delimiter so we know where the y value ends.
iKey2=FindSubString(sDescript,":",iKey);
// If there is no next delimiter, return failure.
if(iKey2<0) return GetLocation(oObject);
// Extract the y value for the vector.
float fY=StringToFloat(GetSubString(sDescript,iKey,iKey2-iKey));
//*** Extract the z value
// Point to the z value for the vector.
iKey=iKey2+1;
// Find the next delimiter so we know where the z value ends.
iKey2=FindSubString(sDescript,":",iKey);
// If there is no next delimiter, return failure.
if(iKey2<0) return GetLocation(oObject);
// Extract the z value for the vector.
float fZ=StringToFloat(GetSubString(sDescript,iKey,iKey2-iKey));
// Build the new vector from the x, y & z values.
vector vWhere=Vector(fX,fY,fZ);
//*** Find the facing value.
// Point to the facing value.
iKey=iKey2+1;
// Find the next delimiter so we know where the facing value ends.
iKey2=FindSubString(sDescript,":",iKey);
// If there is no next delimiter, return failure.
if(iKey2<0) return GetLocation(oObject);
// Extract the facing value for the vector.
float fWhere=StringToFloat(GetSubString(sDescript,iKey,iKey2-iKey));
//*** Create a new location from the extracted information.
location lWhere=Location(oArea,vWhere,fWhere);
// Return the location to the caller of this function.
return lWhere;
}
int DeleteLocationFromObject(object oObject,string sKey="xYz")
{
string sDescript=GetDescription(oObject);
// Try to find the key string.
int iKey=FindSubString(sDescript,sKey);
// If the key string does not exist, return failure.
if(iKey<0) return FALSE;
//** Find the end of the location information so we know how much to delete.
// Find the end of the area tag.
int iKey2=FindSubString(sDescript,":",iKey+1);
// If it doesn't exist, return failure.
if(iKey2<0) return FALSE;
// Find the end of the x vector.
iKey2=FindSubString(sDescript,":",iKey2+1);
// If it doesn't exist, return failure.
if(iKey2<0) return FALSE;
// Find the end of the y vector.
iKey2=FindSubString(sDescript,":",iKey2+1);
// If it doesn't exist, return failure.
if(iKey2<0) return FALSE;
// Find the end of the z vector.
iKey2=FindSubString(sDescript,":",iKey2+1);
// If it doesn't exist, return failure.
if(iKey2<0) return FALSE;
// Find the end of the facing value.
iKey2=FindSubString(sDescript,":",iKey2+1);
// If it doesn't exist, return failure.
if(iKey2<0) return FALSE;
// Construct a new description without the location information.
sDescript=GetStringLeft(sDescript,iKey-1)+
GetSubString(sDescript,iKey2+1,GetStringLength(sDescript));
// Set the new object description.
SetDescription(oObject,sDescript);
// Return success.
return TRUE;
}
//void main(){}// Uncomment for compilation testing. Comment out otherwise.
*** End Code ***
You can save more than one location to the same object, so long as you use a different "key" string for each location you want to save. Make sure that the key string does not appear anywhere else in the object's description, or the functions will not work correctly.
I've done some basic testing but haven't had time to check everything so let me know if it fails for you and if so, what went wrong.
Modifié par Melkior_King, 31 octobre 2010 - 01:46 .