Files
dsrc/sku.0/sys.server/compiled/game/script/library/planetary_map.scriptlib
T

715 lines
20 KiB
Plaintext

/**********************************************************************
* Copyright (c)2000-2002 Sony Online Entertainment Inc.
* All Rights Reserved
*
* Title: magic_item.scriptlib
* Description: magic item reference
* @author $Author:$
* @version $Revision:$
**********************************************************************/
/***** INCLUDES ********************************************************/
include library.locations;
include library.city;
include library.player_structure;
include library.structure;
include library.factions;
include library.regions;
include library.hq;
include library.instance;
include library.utils;
include library.sui;
include java.util.Arrays;
include java.util.Vector;
/***** CONSTANTS *******************************************************/
const byte NO_FLAG = 0;
const float MAX_CLUMP_DISTANCE = 32f;
const string TBL = "datatables/planet_map/map_locations.iff";
const string COL_TEMPLATE = "TEMPLATE";
const string COL_NAME = "PM_NAME";
const string COL_CATEGORY = "PM_CATEGORY";
const string COL_SUBCATEGORY = "PM_SUBCATEGORY";
const string COL_TYPE = "PM_TYPE";
const string COL_FLAGS = "PM_FLAG";
const string TEMPLATE_LOCATION_BASE = "object/tangible/planet_map_location/map_location_base.iff";
const string TEMPLATE_LOCATION_CITY = "object/tangible/planet_map_location/city.iff";
const string CITY = "city";
const string CITY_LOCATION_CATEGORY = "city";
const string VAR_PM_BASE = "planetMap";
const string VAR_PM_NAME = VAR_PM_BASE + ".name";
const string VAR_PM_CATEGORY = VAR_PM_BASE + ".category";
const string VAR_PM_SUBCATEGORY = VAR_PM_BASE + ".subcategory";
const string VAR_PM_TYPE = VAR_PM_BASE + ".type";
const string VAR_PM_FLAGS = VAR_PM_BASE + ".flags";
const string STF_NAME = "map_loc_n";
const string CAT_TRAINER = "trainer";
const string CAT_VENDOR = "vendor";
const string SUB_VENDOR_JUNK = "vendor_junk";
const string STF_MAP_LOC = "map_loc";
const string CAT_TERMINAL = "terminal";
//FIND CONSTANTS
const string SCRIPTVAR_FIND_SUI = "find.sui";
const string SCRIPTVAR_FIND_PARAMS = "find.params";
const string_id SID_NO_REGISTERED_LOCS = new string_id("find_display", "no_registered_locs");
const string_id SID_FIND_TITLE = new string_id("base_player", "find_title");
const string_id SID_FIND_PROMPT = new string_id("base_player", "find_prompt");
/***** FUNCTIONS **************************************************/
/***** GENERAL FUNCTION ************************************/
/************************************************************
* @brief attempts to register a planetary map location
*
* @param obj_id self
*
* @return boolean; false on error
************************************************************/
boolean addMapLocation(obj_id self)
{
if ( !isIdValid(self) )
return false;
if(instance.isInInstanceArea(self))
{
removePlanetaryMapLocation(self);
return false;
}
int got = getGameObjectType(self);
if ( isGameObjectTypeOf(got, GOT_creature) )
{
return addCreatureLocation(self);
}
else if ( isGameObjectTypeOf(got, GOT_terminal) )
{
return addTerminalLocation(self);
}
//LOG("planetaryMapLocation","******************** ADD LOCATION **********************");
string locType = "map";
string planet = getCurrentSceneName();
if ( (planet == null) || (planet.equals("")) )
{
LOG("planetaryMapLocation", "planet scene name = " + planet);
return false;
}
string template = getTemplateName(self);
if ( (template == null) || (template.equals("")) )
return false;
//LOG("planetaryMapLocation","*** TEMPLATE: " + template);
location here = getLocation(self);
if ( isGameObjectTypeOf(got, GOT_building) )
{
location ejection = getBuildingEjectLocation(self);
if ( ejection != null )
here = ejection;
}
if ( here == null )
return false;
string locationName = "";
string category = "";
string subCategory = "";
int type = 0;
int flags = 0;
//LOG("planetaryMapLocation","loading info from datatable...");
if ( template.equals(TEMPLATE_LOCATION_CITY) )
{
category = CITY;
//get subCategory name (from region?)
locationName = getCityRegionName(here);
locType = "CITY";
}
else
{
dictionary row = new dictionary();
row = dataTableGetRow(TBL, template);
if ( (row == null) || (row.isEmpty()) )
{
string msg = "WARNING: map_location -> obj_id " + self + " unable to locate template (" + template + ") in datatable!";
debugServerConsoleMsg(self, msg);
//return false;
}
else
{
//LOG("planetaryMapLocation","row data = " + row.toString());
locationName = row.getString(COL_NAME);
category = row.getString(COL_CATEGORY);
subCategory = row.getString(COL_SUBCATEGORY);
type = row.getInt(COL_TYPE);
flags = row.getInt(COL_FLAGS);
}
}
if ( hasObjVar(self, VAR_PM_BASE) )
{
//LOG("planetaryMapLocation","overriding info from OBJVAR...");
if ( hasObjVar(self, VAR_PM_CATEGORY) )
{
category = getStringObjVar(self, VAR_PM_CATEGORY);
}
if ( hasObjVar(self, VAR_PM_SUBCATEGORY) )
{
subCategory = getStringObjVar(self, VAR_PM_SUBCATEGORY);
}
if ( hasObjVar(self, VAR_PM_NAME) )
{
locationName = getStringObjVar(self, VAR_PM_NAME);
}
if ( hasObjVar(self, VAR_PM_TYPE) )
{
type = getIntObjVar(self, VAR_PM_TYPE);
}
if ( hasObjVar(self, VAR_PM_FLAGS) )
{
flags = getIntObjVar(self, VAR_PM_FLAGS);
}
}
if ( player_structure.isCivic( self ) )
{
// Append city name.
int city_id = getCityAtLocation( getLocation( self ), 0 );
locationName = cityGetName( city_id );
flags = MLF_INACTIVE;
}
else if ( player_structure.isCommercial( self ) )
{
if ( hasObjVar( self, player_structure.VAR_SIGN_NAME ) )
locationName = getStringObjVar( self, player_structure.VAR_SIGN_NAME );
else
{
int city_id = getCityAtLocation( getLocation( self ), 0 );
if ( city_id > 0 )
locationName = cityGetName( city_id );
}
flags = MLF_INACTIVE;
}
if(hasObjVar(self, "healing.canhealwound")||(hasObjVar(self, "healing.canhealshock")))
{
flags = MLF_INACTIVE; // these can be activated/registered with
}
if ( category == null || category.equals("") || category.equals("unknown") )
{
string myFac = factions.getFaction(self);
if ( myFac != null )
{
if ( myFac.equals(factions.FACTION_IMPERIAL) || myFac.equals(factions.FACTION_REBEL) )
category = toLower(myFac);
}
}
if ( category != null && !category.equals("") && !category.equals("unknown") )
{
/*if ( category.indexOf(":") == -1 )
{*/
category = toLower(category);
/*}*/
if ( (locationName == null) || (locationName.equals("")) )
{
locationName = getCityRegionName(here);
if ( (locationName == null) || (locationName.equals("")) )
{
locationName = getEncodedName(self);
}
}
if ( subCategory == null )
{
subCategory = "";
}
//LOG("planetaryMapLocation","attempting to add " + locType + " location for: planet = " + planet + " obj_id = " + self);
//LOG("planetaryMapLocation","locationName = " + locationName + " here = " + here.toString());
//LOG("planetaryMapLocation","category = " + category + " subCategory = " + subCategory);
//LOG("planetaryMapLocation","flags (int) = " + flags + " (byte) = " + (byte)flags );
return addPlanetaryMapLocation(self, locationName, (int)here.x, (int)here.z, category, subCategory, type, (byte)flags);
}
//LOG("planetaryMapLocation", "WARNING: unable to add self (" + self + ") as planetary map location!");
//LOG("planetaryMapLocation", "template = " + template);
//LOG("planetaryMapLocation", "here = " + here.toString());
return false;
}
/************************************************************
* @brief attempts to determine local city region name
*
* @param location here
*
* @return string; null on error
************************************************************/
string getCityRegionName(location here)
{
if ( here == null )
return null;
region[] r = getRegionsWithGeographicalAtPoint(here, regions.GEO_CITY);
if ( (r == null) || (r.length == 0) )
{
//LOG("planetaryMapLocation","ERROR: aborting add attempt due to invalid placement!");
//LOG("planetaryMapLocation","ERROR: city locations must exist within GEO_CITY regions, but none were found.");
return null;
}
if ( r.length > 1 )
{
//LOG("planetaryMapLocation","WARNING: multiple GEO_CITY regions at point - assuming first");
for ( int i = 0; i < r.length; i++ )
{
//LOG("planetaryMapLocation"," region[" + i + "] = " + r[i].getName());
}
}
region city = r[0];
//LOG("planetaryMapLocation","getCityRegionName: Primary city region = " + city.getName());
return city.getName();
}
/************************************************************
* @brief attempts to remove a map location
*
* @param obj_id self
*
* @return void
************************************************************/
void removeMapLocation(obj_id self)
{
if ( !isIdValid(self) )
return;
//LOG("planetaryMapLocation","******************** REMOVE LOCATION **********************");
//LOG("planetaryMapLocation", "attempting to remove self (" + self + ") from planetary map location list...");
string template = getTemplateName(self);
if ( template != null )
{
//LOG("planetaryMapLocation", "template = " + template);
}
location here = getLocation(self);
if ( here != null )
{
//LOG("planetaryMapLocation", "here = " + here.toString());
}
string planet = getCurrentSceneName();
removePlanetaryMapLocation(self);
}
/************************************************************
* @brief attempts to register a CREATURE as a planetary map location
*
* @param obj_id self
*
* @return boolean; false on error
************************************************************/
boolean addCreatureLocation(obj_id self)
{
if ( !isIdValid(self) )
return false;
//LOG("planetaryMapLocation","******************** ADD CREATURE LOCATION **********************");
string locType = "map";
string planet = getCurrentSceneName();
if ( (planet == null) || (planet.equals("")) )
return false;
location here = getWorldLocation(self);
if ( here == null )
return false;
int got = getGameObjectType(self);
if ( isGameObjectTypeOf(got, GOT_creature) || (got == GOT_vendor) )
{
//LOG("planetaryMapLocation","self got = " + got + " is creature type!");
if ( !isPlayer(self) )
{
const string cType = getCreatureName(self);
if ( (cType == null) || (cType.equals("")) )
{
//LOG("planetaryMapLocation","creature has unknown creatureName!");
return false;
}
if ( cType.equals("junk_dealer") )
{
string myName = getEncodedName(self);
return addPlanetaryMapLocation(self, myName, (int)here.x, (int)here.z, CAT_VENDOR, SUB_VENDOR_JUNK, MLT_STATIC, NO_FLAG);
}
else if ( cType.startsWith("trainer_") )
{
string myName = getEncodedName(self);
string subCat = cType;
//LOG("planetaryMapLocation","attempting to add " + toUpper(cType) + ": planet = " + planet + " obj_id = " + self);
//LOG("planetaryMapLocation","locationName = " + myName + " here = " + here.toString());
//LOG("planetaryMapLocation","category = trainer subCategory = " + subCat);
return addPlanetaryMapLocation(self, myName, (int)here.x, (int)here.z, CAT_TRAINER, subCat, MLT_STATIC, NO_FLAG);
}
}
}
return false;
}
/************************************************************
* @brief attempts to register a CREATURE as a planetary map location
*
* @param obj_id self
*
* @return boolean; false on error
************************************************************/
boolean addTerminalLocation(obj_id self)
{
if ( !isIdValid(self) )
return false;
//LOG("planetaryMapLocation","******************** ADD TERMINAL LOCATION **********************");
string planet = getCurrentSceneName();
if ( (planet == null) || (planet.equals("")) )
{
LOG("planetaryMapLocation","(" + self + ") has unknown scene??");
return false;
}
location here = getWorldLocation(self);
if ( here == null )
{
LOG("planetaryMapLocation","(" + self + ") has null location??");
return false;
}
obj_id topMost = getTopMostContainer(self);
if ( isIdValid(topMost) )
{
if ( isGameObjectTypeOf(getGameObjectType(topMost), GOT_building) )
{
if ( hasObjVar(topMost, hq.VAR_HQ_BASE) )
return false;
}
}
int got = getGameObjectType(self);
if ( isGameObjectTypeOf(got, GOT_terminal) )
{
//LOG("planetaryMapLocation","self is a terminal...");
string_id sid_name = getNameStringId(self);
//LOG("planetaryMapLocation","sid_name = " + sid_name.toString());
if ( sid_name != null && sid_name != "")
{
string subCat = sid_name.getAsciiId();
if ( dataTableSearchColumnForString(subCat, "name", "datatables/player/planet_map_cat.iff") < 0 )
{
LOG("planetaryMapLocation","(" + self + ") unable to locate subCat '" + subCat + "' in the planet_map_cat.iff");
return false;
}
/*
map_location closest = findClosestLocation(here, CAT_TERMINAL, subCat);
if ( closest != null )
{
//LOG("planetaryMapLocation","closest = " + closest.getLocationId() + " @ " + closest.getX() + "," + closest.getY());
location there = here;
there.x = closest.getX();
there.z = closest.getY();
if ( getDistance(here, there) <= MAX_CLUMP_DISTANCE )
{
LOG("planetaryMapLocation","(" + self + ") skipping registration due to proximity of other terminals");
return true;
}
}
*/
string cityName = getCityRegionName(here);
if ( cityName != null )
{
map_location[] mapLocs = getPlanetaryMapLocations(CITY, null);
if ( mapLocs != null && mapLocs.length > 0 )
{
for ( int i = 0; i < mapLocs.length; i++ )
{
if ( mapLocs[i].getLocationName().equals(cityName) )
{
string_id sid_cityName = utils.unpackString(cityName);
location cityLoc = new location(mapLocs[i].getX(), 0, mapLocs[i].getY());
string cardinalString = utils.getStringCardinalDirection(cityLoc, here, true);
if ( cardinalString != null && !cardinalString.equals("") )
{
string locName = getString(sid_cityName) + " (" + cardinalString + ")";
return addPlanetaryMapLocation(self, locName, (int)here.x, (int)here.z, CAT_TERMINAL, subCat, MLT_STATIC, NO_FLAG);
}
else
{
break;
}
}
}
}
}
return addPlanetaryMapLocation(self, getEncodedName(self), (int)here.x, (int)here.z, CAT_TERMINAL, subCat, MLT_STATIC, NO_FLAG);
}
//LOG("planetaryMapLocation","sid_name was null or empty");
}
LOG("planetaryMapLocation","(" + self + ") has failed to register for an unknown reason!");
return false;
}
/************************************************************
* @brief attempts to locate the closest location from the map_locs
*
* @param obj_id target
* @param map_location[] map_locs
*
* @return map_location; null on error
************************************************************/
map_location findClosestLocation(obj_id target, map_location[] map_locs)
{
if ( !isIdValid(target) || (map_locs == null) || (map_locs.length == 0) )
{
return null;
}
return findClosestLocation(getWorldLocation(target), map_locs);
}
map_location findClosestLocation(location here, map_location[] map_locs)
{
if ( (map_locs == null) || (map_locs.length == 0) )
{
return null;
}
float min = Float.POSITIVE_INFINITY;
int locIdx = -1;
float x = 0f;
float z = 0f;
location there = new location();
for ( int n = 0; n < map_locs.length; n++ )
{
x = (float)(map_locs[n].getX());
z = (float)(map_locs[n].getY());
there = new location(x, 0, z);
float dist = utils.getDistance2D(here, there);
if ( dist < min )
{
min = dist;
locIdx = n;
}
}
if ( locIdx > -1 )
{
return map_locs[locIdx];
}
return null;
}
map_location findClosestLocation(obj_id target, string category, string subcategory)
{
if ( !isIdValid(target) )
return null;
return findClosestLocation(getWorldLocation(target), category, subcategory);
}
map_location findClosestLocation(location here, string category, string subcategory)
{
if ( (category == null) || (category.equals("")) )
return null;
if ( subcategory == null )
subcategory = "";
map_location[] map_locs = getPlanetaryMapLocations(category, subcategory);
if ( (map_locs == null) || (map_locs.length == 0) )
{
return null;
}
return findClosestLocation(here, map_locs);
}
/************************************************************
* @brief attempts to show the find sui
*
* @return int; -1 on error
************************************************************/
int showFindSui()
{
obj_id self = getSelf();
if ( !isIdValid(self) )
return -1;
closeFindSui();
string[] cats = getUniquePlanetaryMapCategories(null);
if ( (cats == null) || (cats.length == 0) )
{
sendSystemMessage(self, SID_NO_REGISTERED_LOCS);
return -1;
}
resizeable string[] entries = new string[0];
resizeable string[] params = new string[0];
//LOG("find","showFindSui: category count = " + cats.length);
for ( int i = 0; i < cats.length; i++ )
{
string cat = cats[i];
string[] subs = getUniquePlanetaryMapCategories(cat);
if ( (subs != null) && (subs.length > 0) )
{
LOG("find","showFindSui: cat = " + cat + " sub count = " + subs.length);
string_id sid_cat = new string_id("map_loc_cat_n",cat);
for ( int n = 0; n < subs.length; n++ )
{
string_id sid_sub = new string_id("map_loc_cat_n",subs[n]);
entries = utils.addElement(entries, getString(sid_cat) + ": " + getString(sid_sub));
params = utils.addElement(params, subs[n]);
}
}
else
{
entries = utils.addElement(entries, "@map_loc_cat_n:" + cat);
params = utils.addElement(params, cat);
}
}
if ( (entries != null) && (entries.length > 0) )
{
/*entries = utils.alphabetizeStringArray(entries);
if ( (entries == null) || (entries.length == 0) )
return -1;*/
string title = utils.packStringId(SID_FIND_TITLE);
string prompt = utils.packStringId(SID_FIND_PROMPT);
int pid = sui.listbox(self, self, prompt, sui.OK_CANCEL, title, entries, "handleFindSui");
if ( pid > -1 )
{
//track sui and data here
utils.setScriptVar(self, SCRIPTVAR_FIND_SUI, pid);
utils.setBatchScriptVar(self, SCRIPTVAR_FIND_PARAMS, params);
return pid;
}
}
return -1;
}
void closeFindSui() //must be called by target
{
obj_id self = getSelf();
if ( utils.hasScriptVar(self, SCRIPTVAR_FIND_SUI) )
{
int pid = utils.getIntScriptVar(self, SCRIPTVAR_FIND_SUI);
forceCloseSUIPage(pid);
cleanupFindSui();
}
}
void cleanupFindSui()
{
obj_id self = getSelf();
utils.removeScriptVar(self, SCRIPTVAR_FIND_SUI);
utils.removeBatchScriptVar(self, SCRIPTVAR_FIND_PARAMS);
}
string[] getUniquePlanetaryMapCategories(string category)
{
string[] cats = getPlanetaryMapCategories(category);
if ( (cats == null) || (cats.length == 0) )
return null;
resizeable string[] unique = new string[0];
for ( int i = 0; i < cats.length; i++ )
{
if ( utils.getElementPositionInArray(unique, cats[i]) == -1 )
unique = utils.addElement(unique, cats[i]);
}
if ( (unique == null) || (unique.length == 0) )
return null;
return unique;
}
boolean updateFacilityActive(obj_id facility, boolean isActive)
{
if ( !isIdValid(facility) )
return false;
map_location maploc = getPlanetaryMapLocation(facility);
if ( maploc == null )
return false;
if ( !maploc.isActive() && !maploc.isInactive() )
return false;
if ( maploc.isActive() && maploc.isInactive() )
return false;
byte flags = maploc.getFlags();
if ( isActive )
flags = MLF_ACTIVE;
else
flags = MLF_INACTIVE;
removePlanetaryMapLocation(facility);
return addPlanetaryMapLocation(facility, maploc.getLocationName(),
(int)maploc.getX(), (int)maploc.getY(),
maploc.getCategory(), maploc.getSubCategory(),
MLT_STATIC, flags);
}