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

1276 lines
35 KiB
Plaintext

/**********************************************************************
* Copyright (c)2000-2002 Sony Online Entertainment Inc.
* All Rights Reserved
*
* Title: structure.scriptlib
* Description: player structure script library
* @author $Author:$
* @version $Revision:$
**********************************************************************/
/***** INCLUDES ********************************************************/
include library.skill;
include library.utils;
include library.list;
include library.datatable;
/***** CONSTANTS *******************************************************/
//generic templates
const string TEMPLATE_DEED = "object/intangible/deed/deed.iff";
const string TEMPLATE_CELL = "object/cell/cell.iff";
//slot string defs
const string SLOT_GENERAL_INVENTORY = "";
//CELL DEFINITIONS
const string CELLNAME_FOYER = "foyer";
const string CELLNAME_SPAWN = "spawn";
//objvar defs
const string VAR_DEED_SCRIPTS = "script_names";
const string VAR_PLAYER_HOME = "home";
//SCRIPT DEFINES
const string SCRIPT_DEED = "structure.deed.deed";
const string SCRIPT_BASE_STRUCTURE = "structure.base.base_structure";
const string SCRIPT_TURNSTILE = "structure.base.turnstile";
//STRING ID
const string_id SID_CLONING_FACILITY = new string_id("building_name","cloning_facility");
//DATATABLES
const string WORLD_DELTA = "WORLD_DELTA";
const string DATATABLE_STRUCTURE_VERSION = "datatables/structure/structure_version.iff";
const string DATATABLE_COL_STRUCTURE = "STRUCTURE";
const string DATATABLE_COL_SCRIPT = "SCRIPT";
const string DATATABLE_COL_VERSION_TERMINAL = "VERSION_TERMINAL";
const string DATATABLE_COL_VERSION_SPAWN = "VERSION_SPAWN";
const string DATATABLE_COL_TUBES = "TUBES";
//CONSTANTS FOR FACILITY TERMINALS DATATABLE
//const string DATATABLE_COL_STRUCTURE = "STRUCTURE"; //commented out due to dupe
const string DATATABLE_COL_X = "X";
const string DATATABLE_COL_Y = "Y";
const string DATATABLE_COL_Z = "Z";
const string DATATABLE_COL_CELL = "CELL";
const string DATATABLE_COL_HEADING = "HEADING";
const string DATATABLE_COL_TERMINAL = "TERMINAL";
//STRUCTURE OBJVAR CONSTANTS
const string VAR_FACTION = "faction";
const string VAR_STRUCTURE_BASE = "structure";
const string VAR_STRUCTURE_TERMINALS = "structure.terminals";
const string VAR_STRUCTURE_VERSION_SPAWN = "structure.version.spawn";
const string VAR_STRUCTURE_VERSION_TERMINAL = "structure.version.terminal";
const string VAR_STRUCTURE_LEVEL_CURRENT = "structure.level.current";
const string VAR_STRUCTURE_LEVEL_DESIRE = "structure.level.desired";
//const string VAR_TURNSTILE_STATE = "structure.turnstile.state";
//CONSTANTS FOR STRUCTURE INTERIOR SPAWNING
const int DEFAULT_THRESHOLD = 10;
const string VAR_SPAWN_BASE = "structure.spawn";
//binary switches for spawns
const int SWITCHLIST_STATIC = 0; //starting bit for static spawn switches
const int SWITCHLIST_AMBIENT = 16; //starting bit for ambient spawn switches
const string VAR_SPAWN_SWITCHES_BASE = "structure.spawn.switches";
const string VAR_SPAWN_SWITCHES_CURRENT = "structure.spawn.switches.current"; //int
const string VAR_SPAWN_SWITCHES_DESIRED = "structure.spawn.switches.desired"; //int
//spawn queue data
const string VAR_SPAWN_QUEUE_BASE = "structure.spawn.queue";
const string VAR_SPAWN_QUEUE_LOAD_BASE = "structure.spawn.queue.load";
const string VAR_SPAWN_QUEUE_LOAD_HI = "structure.spawn.queue.load.hi";
const string VAR_SPAWN_QUEUE_LOAD_LOW = "structure.spawn.queue.load.low";
const string VAR_SPAWN_QUEUE_BOXED = "structure.spawn.queue.boxed";
const string VAR_SPAWN_QUEUE_UNLOAD = "structure.spawn.queue.unload";
//lists of current AI spawns
const string VAR_SPAWN_CURRENT_BASE = "structure.spawn.current";
const string VAR_SPAWN_CURRENT_STATIC = "structure.spawn.current.static"; //these act just like terminals
const string VAR_SPAWN_CURRENT_AMBIENT = "structure.spawn.current.ambient"; //these act like exterior spawns
//population counts
const string VAR_SPAWN_POPULATION_BASE = "structure.spawn.population";
const string VAR_SPAWN_POPULATION_PLAYER = "structure.spawn.population.player"; //number of players in building
const string VAR_SPAWN_POPULATION_THRESHOLD = "structure.spawn.population.threshold"; //total number of objects for building
//CONSTANTS FOR FACILITY INTERIOR SPAWN DATATABLE
//const string DATATABLE_COL_STRUCTURE = "STRUCTURE"; //commented out due to dupe
//const string DATATABLE_COL_X = "X"; //destination X
//const string DATATABLE_COL_Y = "Y"; //destination Y
//const string DATATABLE_COL_Z = "Z"; //destination Z
//const string DATATABLE_COL_CELL = "CELL"; //destination CELL
//const string DATATABLE_COL_HEADING = "HEADING"; //destination HEADING
const string DATATABLE_COL_SPAWN = "SPAWN"; //creature template to spawn - null = random template selection
const string DATATABLE_COL_SKILL_TEMPLATES = "SKILL_TEMPLATES"; //comma-delimited skill templates - see skill.scriptlib
const string DATATABLE_COL_SCRIPTS = "SCRIPTS"; //comma-delimited scripts to be applied to object
//SPAWN DATATABLES
const string DATATABLE_CLONING_FACILITY_SPAWN = "datatables/structure/municipal/cloning_facility_spawn.iff";
//OTHER DATATABLES
const string DATATABLE_CLONING_FACILITY_RESPAWN = "datatables/structure/municipal/cloning_facility_respawn.iff";
//COLUMN NAMES: STRUCTURE X Y Z CELL HEADING
//TERMINAL CONSTANTS
const string VAR_TERMINAL_HEADING = "intendedHeading";
//MESSAGEHANDLERs
const string HANDLER_REGISTER_CLONING_FACILITY = "handleRegisterCloningFacility";
//SPAWN BIT DEFINES
//FILLER BUILDING CITY SPAWN DEFINES
const string DATATABLE_FILLER_BASE = "datatables/spawning/filler/";
const string DATATABLE_FILLER_SPAWN_ENDING = "_filler_spawn.iff";
const string DATATABLE_FILLER_EGG_ENDING = "_filler_egg.iff";
const string DATATABLE_COL_TEMPLATE = "TEMPLATE";
const string DATATABLE_COL_IDX = "IDX";
const string DICT_TEMPLATE = "template";
const string DICT_IDX = "idx";
const string DICT_LOC = "loc";
const string VAR_FILLER_SPAWN_BASE = "fillerSpawn";
const string VAR_FILLER_SPAWN_CURRENT_BASE = "fillerSpawn.current";
const string VAR_FILLER_SPAWN_CURRENT_EGG = "fillerSpawn.current.egg";
const string VAR_FILLER_SPAWN_CURRENT_LOC = "fillerSpawn.current.loc";
const string HANDLER_CLEANUP_SELF = "handleCleanupSelf";
/***** FUNCTIONS *******************************************************/
/***** GENERAL FUNCTIONS *******************************************************/
/*****************************************************************
* @brief gets the building obj_id for the designated object
*
* @param obj_id target
*
* @return obj_id; null on error or no container
******************************************************************/
obj_id getContainingBuilding(obj_id target)
{
if ( target == null )
return null;
obj_id topMost = getTopMostContainer(target);
if ( (topMost == target) || (topMost == null) )
return null;
return topMost;
}
/*****************************************************************
* @brief determines if target object is inside something...
*
* @param obj_id target
*
* @return boolean
******************************************************************/
boolean isInside(obj_id target)
{
if ( target == null )
return false;
obj_id topMost = getTopMostContainer(target);
if ( (topMost == target) || (topMost == null) )
return false;
return true;
}
/*****************************************************************
* @brief returns the name of a randomly selected cell inside the
* specified structure
*
* @param obj_id structure
*
* @return obj_id; null on error
******************************************************************/
string getRandomCell(obj_id structure)
{
if ( (structure == null) || (structure == obj_id.NULL_ID) )
{
return "";
}
string[] cellNames = getCellNames(structure);
if ( (cellNames == null) || (cellNames.length == 0) )
{
return "";
}
else
{
int idx = rand(0, cellNames.length - 1);
string cellName = cellNames[idx];
if ( !cellName.equals("") )
{
return cellName;
}
}
return "";
}
/*****************************************************************
* @brief returns the obj_id of a randomly selected cell inside the
* specified structure
*
* @param obj_id structure
*
* @return obj_id; null on error
******************************************************************/
obj_id getRandomCellId(obj_id structure)
{
if ( (structure == null) || (structure == obj_id.NULL_ID) )
{
return null;
}
string[] cellNames = getCellNames(structure);
if ( (cellNames == null) || (cellNames.length == 0) )
{
return null;
}
else
{
int idx = rand(0, cellNames.length - 1);
string cellName = cellNames[idx];
if ( !cellName.equals("") )
{
obj_id cellId = getCellId(structure, cellName);
if ( (cellId == null) || (cellId == obj_id.NULL_ID) )
{
}
else
{
return cellId;
}
}
}
return null;
}
/*****************************************************************
* @brief returns the obj_id of a randomly selected cell inside the
* specified structure
*
* @param obj_id structure
*
* @return obj_id; null on error
******************************************************************/
location getRandomLocationInStructure(obj_id structure)
{
if ( (structure == null) || (structure == obj_id.NULL_ID) )
{
return null;
}
string cellName = getRandomCell(structure);
if ( !cellName.equals("") )
{
return getGoodLocation(structure, cellName);
}
return null;
}
/*****************************************************************
* @brief gets the facilities version data and returns the latest rev
*
* @param obj_id facility
*
* @return int; -1 on error
******************************************************************/
int getFacilityVersion(obj_id facility, string scriptName, string columnName)
{
if ( (facility == null) || (scriptName.equals("")) || (columnName.equals("")) )
return -1;
string facilityTemplate = getTemplateName(facility);
string[] tpfs = dataTableGetStringColumn(DATATABLE_STRUCTURE_VERSION, DATATABLE_COL_STRUCTURE);
if ( (tpfs != null) && (tpfs.length > 0) )
{
for ( int i = 0; i < tpfs.length; i++ )
{
if ( tpfs[i].equals(facilityTemplate) )
{
string dataScript = dataTableGetString(DATATABLE_STRUCTURE_VERSION, i, DATATABLE_COL_SCRIPT);
if ( dataScript.equals(scriptName) )
{
return dataTableGetInt(DATATABLE_STRUCTURE_VERSION, i, columnName);
}
}
}
}
LOG("structure", "WARNING: getFacilityVersion error: unable to locate entry for passed params");
LOG("structure", "facility = " + facility + " template = " + facilityTemplate);
LOG("structure", "script = " + scriptName + " col = " + columnName);
return -1;
}
/*****************************************************************
* @brief gets the facilities TERMINAL version data and returns the latest rev
*
* @param obj_id facility
*
* @return int; -1 on error
******************************************************************/
int getFacilityTerminalVersion(obj_id facility, string scriptName)
{
if ( (facility == null) || (scriptName.equals("")) )
return -1;
return getFacilityVersion(facility, scriptName, DATATABLE_COL_VERSION_TERMINAL);
}
/*****************************************************************
* @brief gets the facilities SPAWN version data and returns the latest rev
*
* @param obj_id facility
*
* @return int; -1 on error
******************************************************************/
int getFacilitySpawnVersion(obj_id facility, string scriptName)
{
if ( (facility == null) || (scriptName.equals("")) )
return -1;
return getFacilityVersion(facility, scriptName, DATATABLE_COL_VERSION_SPAWN);
}
/*****************************************************************
* @brief gets the facilities TERMINAL version data and returns the latest rev
*
* @param obj_id facility
*
* @return int; -1 on error
******************************************************************/
boolean isCurrentTerminalVersion(obj_id facility, string scriptName)
{
if ( (facility == null) || (scriptName.equals("")) )
return false;
int current = getIntObjVar(facility, VAR_STRUCTURE_VERSION_TERMINAL);
int latest = getFacilityTerminalVersion(facility, scriptName);
if ( current >= latest )
{
return true;
}
return false;
}
/*****************************************************************
* @brief gets the facilities SPAWN version data and returns the latest rev
*
* @param obj_id facility
*
* @return int; -1 on error
******************************************************************/
boolean isCurrentSpawnVersion(obj_id facility, string scriptName)
{
if ( (facility == null) || (scriptName.equals("")) )
return false;
int current = getIntObjVar(facility, VAR_STRUCTURE_VERSION_SPAWN);
int latest = getFacilitySpawnVersion(facility, scriptName);
if ( current >= latest )
{
return true;
}
return false;
}
/*****************************************************************
* @brief gets an obj_id list of players in a specified structure
*
* @param obj_id facility
*
* @return obj_id[]; null on error
******************************************************************/
obj_id[] getPlayersInStructure(obj_id facility)
{
if ( facility == null )
{
return null;
}
resizeable obj_id[] cells = new obj_id[0];
switch (getContainerType(facility))
{
case 0: //CT_none
break;
case 1: //CT_slotted
obj_id[] contents = getContents(facility);
if ( (contents == null) || (contents.length == 0) )
{
return null;
}
for ( int i = 0; i < contents.length; i++ )
{
if ( getTemplateName(contents[i]).equals(TEMPLATE_CELL) )
{
cells = utils.addElement(cells, contents[i]);
}
}
break;
case 2: //CT_volume //This kind of container can hold tangible objects
case 3: //CT_volumeIntangible //This kind of container can hold intangible objects
case 4: //CT_volumeGeneric //This kind of container can hold any object tangible or not.
default:
break;
}
if ( (cells == null) || (cells.length == 0) )
{
return null;
}
obj_id[] cellsArray = cells;
resizeable obj_id[] players = new obj_id[0];
for ( int i = 0; i < cellsArray.length; i++ )
{
obj_id[] cellContents = getContents(cellsArray[i]);
if ( (cellContents == null) || (cellContents.length == 0) )
{
//skip this
}
else
{
for ( int n = 0; n < cellContents.length; n++ )
{
if ( isPlayer(cellContents[n]) )
{
players = utils.addElement(players, cellContents[n]);
}
}
}
}
if ( (players == null) || (players.length == 0) )
{
return null;
}
else
{
return players;
}
}
/***** OWNERSHIP FUNCTIONS *******************************************************/
/*****************************************************************
* @brief adds a coowner to a structure's coowner list
*
* @param obj_id structure
* @param obj_id owner
* @param obj_id player
*
* @return boolean; false on error
******************************************************************/
boolean addStructureCoOwner(obj_id structure, obj_id owner, obj_id player)
{
if ( (structure == null) || (owner == null) || (player == null) )
return false;
//validate permissions here
boolean isHouse = false;
//if structure = player house
// * set isHouse = true
if ( hasObjVar(structure, utils.VAR_COOWNERS) )
{
resizeable obj_id[] coowners = getResizeableObjIdArrayObjVar(structure, utils.VAR_COOWNERS);
if ( (coowners == null) || (coowners.length == 0) )
{
removeObjVar(structure, utils.VAR_COOWNERS);
return addStructureCoOwner(structure, owner, player);
}
coowners = utils.addElement(coowners, player);
if ( (coowners != null) && (coowners.length > 0) )
{
setObjVar(structure, utils.VAR_COOWNERS, coowners);
if ( isHouse )
{
setObjVar(player, VAR_PLAYER_HOME, structure);
}
//mail owner about addition
//mail original residents (coowners) about addition
//mail new coowner (player) confirmation
return true;
}
}
else
{
obj_id[] newCoOwners = new obj_id[1];
newCoOwners[0] = player;
if ( (newCoOwners != null) && (newCoOwners.length > 0) )
{
setObjVar(structure, utils.VAR_COOWNERS, newCoOwners);
if ( isHouse )
{
setObjVar(player, VAR_PLAYER_HOME, structure);
}
//mail owner about addition
//mail new coowner (player) confirmation
return true;
}
}
return false;
}
/*****************************************************************
* @brief removes a coowner from the coowner list
*
* @param obj_id structure
* @param obj_id owner
* @param obj_id player
*
* @return boolean; false on error
******************************************************************/
boolean removeStructureCoOwner(obj_id structure, obj_id owner, obj_id player)
{
if ( (structure == null) || (owner == null) || (player == null) )
return false;
//validate permissions here
boolean isHouse = false;
//if structure = player house
// * set isHouse = true
if ( hasObjVar(structure, utils.VAR_COOWNERS) )
{
resizeable obj_id[] coowners = getResizeableObjIdArrayObjVar(structure, utils.VAR_COOWNERS);
if ( (coowners == null) || (coowners.length == 0) )
{
removeObjVar(structure, utils.VAR_COOWNERS);
return false;
}
if ( !utils.isElementInArray(coowners, player) )
{
return false; //trying to remove obj_id that is not in list...
}
coowners = utils.removeElement(coowners, player);
if ( (coowners == null) || (coowners.length == 0) )
{
removeObjVar(structure, utils.VAR_COOWNERS);
}
else
{
setObjVar(structure, utils.VAR_COOWNERS, coowners);
}
if ( isHouse )
{
//extract all "player" owned items from the house
//create special "ejected trunk" in front yard
//declare "player" owner of trunk
//pclib.msgRemoveObjVar(player, VAR_PLAYER_HOME);
}
//email player that they have been booted
return true;
}
return false;
}
/***** DEED FUNCTIONS *******************************************************/
/*****************************************************************
* @brief packs a structure into a deed
*
* @param obj_id owner
* @param obj_id building
*
* @return obj_id of the new deed; null on error
******************************************************************/
obj_id packStructureToDeed(obj_id owner, obj_id building)
{
if ( (owner == null) || (building == null) )
return null;
//validate that target is a building or installation
//validate that owner is target's owner
obj_id deed = createObject(TEMPLATE_DEED, owner, SLOT_GENERAL_INVENTORY);
if ( putIn(building, deed) )
{
return deed;
}
destroyObject(deed); //failed to pack the structure - nuke the deed
return null;
}
/*****************************************************************
* @brief unpacks a structure from a deed
*
* @param obj_id owner
* @param obj_id deed
*
* @return obj_id of the placed structure; null on error
******************************************************************/
obj_id unpackStructureFromDeed(obj_id owner, obj_id deed)
{
if ( (owner == null) || (deed == null) )
return null;
obj_id[] contents = getContents(deed);
if ( (contents == null) || (contents.length != 1) )
return null; //should only contain 1 object: a structure
// validate contents[0] is a building or installation
obj_id building = contents[0];
//validate that building has no owner or that "owner" is already building owner
// call structure placement UI
// START HACK!!
if ( setLocation(building, getLocation(owner)) )
{
destroyObject(deed); //no longer needed
return building;
}
//END HACK!!
return null; //unpack failed...
}
/***** TERMINAL FUNCTIONS *******************************************************/
/*****************************************************************
* @brief creates and registers terminals for the facility
*
* @param obj_id facility
*
* @return boolean; false on error
*****************************************************************/
boolean createStructureTerminals(obj_id facility, string scriptName, string datatable)
{
if ( !isIdValid(facility) || datatable == null || datatable.equals("") )
{
return false;
}
obj_id[] terminals = createStructureTerminals(facility, datatable);
if ( (terminals == null) || (terminals.length == 0) )
return false;
return true;
}
obj_id[] createStructureTerminals(obj_id facility, string datatable)
{
if ( !isIdValid(facility) || datatable == null || datatable.equals("") )
return null;
LOG("structureTerminal","******************* FACILITY = " + facility + " *****************");
string facilityTemplate = getTemplateName(facility);
float fYaw = getYaw(facility);
LOG("structureTerminal","fYaw = " + fYaw);
string sceneName = getCurrentSceneName();
int numRows = dataTableGetNumRows(datatable);
resizeable obj_id[] terminals = new obj_id[0];
for ( int i = 0; i < numRows; i++ )
{
string buildingTemplate = dataTableGetString(datatable, i, DATATABLE_COL_STRUCTURE);
if ( buildingTemplate.equals(facilityTemplate) )
{
dictionary item = dataTableGetRow(datatable, i);
string TEMPLATE = item.getString(DATATABLE_COL_TERMINAL);
if(TEMPLATE == null || TEMPLATE.equals(""))
continue;
float X = item.getFloat(DATATABLE_COL_X);
float Y = item.getFloat(DATATABLE_COL_Y);
float Z = item.getFloat(DATATABLE_COL_Z);
float relativeHeading = item.getFloat(DATATABLE_COL_HEADING);
string CELL_NAME = item.getString(DATATABLE_COL_CELL);
obj_id CELL_ID = obj_id.NULL_ID;
LOG("structureTerminal","retrieved terminal data...");
LOG("structureTerminal","loc = " + X + ", " + Y + ". " + Z + " H = " + relativeHeading + " cell = " + CELL_NAME);
if ( CELL_NAME.equals(WORLD_DELTA) )
{
//this entry wants to set the terminal in the world with a delta from building loc
//debugSpeakMsg(facility, "attempting to place a terminal using WORLD_DELTA!");
}
else
{
CELL_ID = getCellId(facility, CELL_NAME);
}
if ( CELL_ID == null )
{
LOG("structure", "datatable " + datatable + " has a bad cell name");
}
else
{
obj_id terminal_id = obj_id.NULL_ID;
location spot = new location(X, Y, Z, sceneName, CELL_ID);
float HEADING = relativeHeading;
if ( CELL_ID == obj_id.NULL_ID )
{
LOG("structureTerminal","creating terminal in world space");
location fLoc = getLocation(facility);
LOG("structureTerminal","coordinates of facility are: " + fLoc.x + " " + fLoc.y + " " + fLoc.z + ".");
spot = new location(fLoc.x + X, fLoc.y + Y, fLoc.z + Z, sceneName, CELL_ID);
LOG("structureTerminal","coordinates of spot are: " + spot.x + " " + spot.y + " " + spot.z + ".");
if ( fYaw != 0 )
{
LOG("structureTerminal","translating coordinates to rotated location");
spot = utils.rotatePointXZ(fLoc, spot, fYaw);
LOG("structureTerminal","coordinates of new spot are: " + spot.x + " " + spot.y + " " + spot.z + ".");
LOG("structureTerminal","correcting relative heading...");
/************ correct heading ***********/
HEADING -= (90 - fYaw);
}
LOG("structureTerminal","Creating new terminal at: " + spot.x + " " + spot.y + " " + spot.z + ".");
terminal_id = createObject(TEMPLATE, spot);
}
else
{
LOG("structureTerminal","creating terminal in CELL (" + CELL_ID + ") space");
terminal_id = createObjectInCell(TEMPLATE, facility, CELL_NAME, spot);
}
if ( (terminal_id != null) && (terminal_id != obj_id.NULL_ID) )
{
//rotate it!
LOG("structureTerminal","rotating terminal to heading = " + HEADING);
setYaw(terminal_id, HEADING);
terminals = utils.addElement(terminals, terminal_id);
}
}
}
}
if ( (terminals == null) || (terminals.length == 0) )
return null;
return utils.toStaticObjIdArray(terminals);
}
/*****************************************************************
* @brief destroys and unregisters terminals for the facility
*
* @param obj_id facility
*
* @return boolean; false on error
*****************************************************************/
boolean destroyStructureTerminals(obj_id facility)
{
if ( facility == null )
{
return false;
}
//remove terminals
obj_id[] terminals = getObjIdArrayObjVar(facility, VAR_STRUCTURE_TERMINALS);
if ( (terminals == null) || (terminals.length == 0) )
{
return false;
}
for ( int i = 0; i < terminals.length; i++ )
{
destroyObject(terminals[i]);
}
//unregister terminals
removeObjVar(facility, VAR_STRUCTURE_TERMINALS);
return true;
}
/***** STRUCTURE INTERIOR SPAWN FUNCTIONS ************************************************/
boolean initializeStructureInteriorSpawn(obj_id facility)
{
if ( facility == null )
{
return false;
}
if ( hasObjVar(facility, VAR_SPAWN_CURRENT_BASE) )
{
return false;
}
setObjVar(facility, VAR_SPAWN_SWITCHES_CURRENT, 0);
setObjVar(facility, VAR_SPAWN_SWITCHES_DESIRED, 0);
obj_id[] players = getPlayersInStructure(facility);
if ( (players == null) || (players.length == 0) )
{
setObjVar(facility, VAR_SPAWN_POPULATION_PLAYER, 0);
}
else
{
setObjVar(facility, VAR_SPAWN_POPULATION_PLAYER, players.length);
}
if ( !hasObjVar(facility, VAR_SPAWN_POPULATION_THRESHOLD) )
{
setObjVar(facility, VAR_SPAWN_POPULATION_THRESHOLD, DEFAULT_THRESHOLD);
}
return true;
}
/*****************************************************************
* @brief returns the switch state
*
* @param obj_id facility
*
* @return int; -1 on error
*****************************************************************/
int getSpawnSwitchState(obj_id facility, int idx)
{
if ( facility != null )
{
if ( hasObjVar(facility, VAR_SPAWN_SWITCHES_CURRENT) )
{
if ( (idx >=0) && (idx < utils.BIT_LIST_SIZE) )
{
int switches = getIntObjVar(facility, VAR_SPAWN_SWITCHES_CURRENT);
if ( utils.checkBit(switches, idx) )
{
return 1;
}
return 0;
}
}
}
return -1;
}
/*****************************************************************
* @brief attempts to set the spawn switch state
*
* @param obj_id facility
*
* @return boolean; false on error
*****************************************************************/
boolean setSpawnSwitchState(obj_id facility, int idx, boolean setActive)
{
if ( facility != null )
{
if ( hasObjVar(facility, VAR_SPAWN_SWITCHES_CURRENT) )
{
if ( (idx >=0) && (idx < utils.BIT_LIST_SIZE) )
{
int switches = getIntObjVar(facility, VAR_SPAWN_SWITCHES_CURRENT);
if ( setActive )
{
switches = utils.setBit(switches, idx);
}
else
{
switches = utils.clearBit(switches, idx);
}
return setObjVar(facility, VAR_SPAWN_SWITCHES_CURRENT, switches);
}
}
}
return false;
}
/***** FILLER BUILDING FUNCTIONS *******************************************************/
/*****************************************************************
* @brief creates filler spawns relative to the building if necessary
*
* @param obj_id building
*
* @return boolean; false on error
*****************************************************************/
boolean resetFillerSpawns(obj_id building)
{
LOG("FILLER_BUILDING", "resetFillerSpawns: entered!");
if ( building == null )
{
return false;
}
if ( hasObjVar(building, VAR_FILLER_SPAWN_CURRENT_EGG) )
{
if ( !cleanupFillerSpawns(building) )
{
LOG("FILLER_BUILDING", "resetFillerSpawns: unable to cleanup existing spawns");
return false;
}
}
boolean doContinue = true;
int count = 0;
do
{
LOG("FILLER_BUILDING", "resetFillerSpawns: attempting to spawn next template");
if ( !spawnNextFillerEggTemplate(building) )
{
LOG("FILLER_BUILDING", "resetFillerSpawns: SPAWN FAILED!");
doContinue = false;
}
else
{
count++;
}
} while (doContinue);
if ( count > 0 )
{
return true;
}
else
{
return false;
}
}
/*****************************************************************
* @brief cleans up after filler spawns if necessary
*
* @param obj_id building
*
* @return boolean; false on error
*****************************************************************/
boolean cleanupFillerSpawns(obj_id building)
{
if ( building == null )
{
return false;
}
obj_id[] eggs = getObjIdArrayObjVar(building, VAR_FILLER_SPAWN_CURRENT_EGG);
if ( (eggs == null) || (eggs.length == 0) )
{
//dont need to do anything
}
else
{
for ( int i = 0; i < eggs.length; i++ )
{
destroyObject(eggs[i]);
}
}
removeObjVar(building, VAR_FILLER_SPAWN_CURRENT_BASE);
return true;
}
/*****************************************************************
* @brief returns a dictionary with filler spawn egg info for building
*
* @param obj_id building
*
* @return dictionary; null on error
*****************************************************************/
dictionary getFillerEggTemplate(obj_id building, int spawnIdx, int eggIdx)
{
if ( (building == null) || (spawnIdx < -1) || (eggIdx < -1) )
{
return null;
}
string buildingTemplate = getTemplateName(building);
string table = DATATABLE_FILLER_BASE + getCurrentSceneName() + DATATABLE_FILLER_SPAWN_ENDING;
if ( dataTableOpen(table) )
{
string[] buildingTemplates = dataTableGetStringColumn(table, DATATABLE_COL_TEMPLATE);
for ( int i = 0; i < buildingTemplates.length; i++ )
{
if ( buildingTemplates[i].equals(buildingTemplate) )
{
dictionary d = new dictionary();
int idx = dataTableGetInt(table, i , DATATABLE_COL_IDX);
if ( (spawnIdx == -1) || (spawnIdx == idx) )
{
d.put(DICT_IDX, idx);
float dx = dataTableGetFloat(table, i, DATATABLE_COL_X);
float dy = dataTableGetFloat(table, i, DATATABLE_COL_Y);
float dz = dataTableGetFloat(table, i, DATATABLE_COL_Z);
location bLoc = getLocation(building);
location loc = new location(bLoc.x + dx, bLoc.y + dy, bLoc.z + dz, bLoc.area, bLoc.cell);
float bYaw = getYaw(building);
if ( bYaw != 0.0f )
{
float dist = utils.getDistance2D(bLoc, loc);
loc = utils.rotatePointXZ(bLoc, dist, bYaw);
}
d.put(DICT_LOC, loc);
string lookup = DATATABLE_FILLER_BASE + getCurrentSceneName() + DATATABLE_FILLER_EGG_ENDING;
if ( dataTableOpen(lookup) )
{
//to do: integrate region type here
string[] eggs = dataTableGetStringColumn(lookup, DATATABLE_COL_TEMPLATE);
switch(eggIdx)
{
case -1:
eggIdx = rand(0, eggs.length - 1);
default:
if ( eggIdx < eggs.length )
{
d.put(DICT_TEMPLATE, eggs[eggIdx]);
return d;
}
else
{
return null;
}
}
}
}
}
}
}
return null;
}
/*****************************************************************
* @brief returns a dictionary with random filler spawn egg info for building
*
* @param obj_id building
*
* @return dictionary; null on error
*****************************************************************/
dictionary getRandomFillerEggTemplate(obj_id building)
{
if ( building == null )
{
return null;
}
return getFillerEggTemplate(building, -1, -1);
}
/*****************************************************************
* @brief returns a dictionary with random filler spawn egg info for building
*
* @param obj_id building
*
* @return dictionary; null on error
*****************************************************************/
dictionary getNextFillerEggTemplate(obj_id building)
{
if ( building == null )
{
return null;
}
int spawnIdx = -1;
int eggIdx = -1;
obj_id[] eggs = getObjIdArrayObjVar(building, VAR_FILLER_SPAWN_CURRENT_EGG);
if ( (eggs == null) || (eggs.length == 0) )
{
spawnIdx = 0;
}
else
{
spawnIdx = eggs.length;
}
return getFillerEggTemplate(building, spawnIdx, eggIdx);
}
/*****************************************************************
* @brief returns a dictionary with random filler spawn egg info for building
*
* @param obj_id building
*
* @return dictionary; null on error
*****************************************************************/
boolean spawnNextFillerEggTemplate(obj_id building)
{
LOG("FILLER_BUILDING", "spawnNextFillerEggTemplate: entered!");
if ( building == null )
{
return false;
}
dictionary d = getNextFillerEggTemplate(building);
if ( d == null )
{
LOG("FILLER_BUILDING", "spawnNextFillerEggTemplate: unable to retrieve next egg template!");
return false;
}
int idx = d.getInt(DICT_IDX);
obj_id[] eggs = getObjIdArrayObjVar(building, VAR_FILLER_SPAWN_CURRENT_EGG);
if ( (eggs == null) || (eggs.length == 0) )
{
if ( idx == 0 )
{
return spawnFillerEgg(building, d);
}
}
else
{
if ( idx == eggs.length )
{
return spawnFillerEgg(building, d);
}
}
return false;
}
/*****************************************************************
* @brief returns a dictionary with random filler spawn egg info for building
*
* @param obj_id building
*
* @return dictionary; null on error
*****************************************************************/
boolean spawnFillerEgg(obj_id building, dictionary params)
{
LOG("FILLER_BUILDING", "spawnFillerEgg: entered!");
if ( (building == null) || (params == null) )
{
return false;
}
string template = params.getString(DICT_TEMPLATE);
location loc = params.getLocation(DICT_LOC);
LOG("FILLER_BUILDING", "spawnFillerEgg: template = " + template);
LOG("FILLER_BUILDING", "spawnFillerEgg: loc = " + loc);
obj_id egg = createObject(template, loc);
if ( egg == null )
{
LOG("FILLER_BUILDING", "spawnFillerEgg: unable to create spawn egg!");
return false;
}
setYaw(egg, rand(0, 360));
resizeable obj_id[] eggs = getResizeableObjIdArrayObjVar(building, VAR_FILLER_SPAWN_CURRENT_EGG);
resizeable location[] locs = getResizeableLocationArrayObjVar(building, VAR_FILLER_SPAWN_CURRENT_LOC);
eggs = utils.addElement(eggs, egg);
locs = utils.addElement(locs, loc);
if(eggs.length > 0 && locs.length > 0) {
setObjVar(building, VAR_FILLER_SPAWN_CURRENT_EGG, eggs);
setObjVar(building, VAR_FILLER_SPAWN_CURRENT_LOC, locs);
return true;
} else {
return false;
}
}
/*****************************************************************
* @brief checks to see if player is logging into Death Watch Bunker
*
* @param obj_id player
*
*
*****************************************************************/
/*void checkForDeathWatch (obj_id player)
{
obj_id structure = player_structure.getStructure(player);
if ( !isIdValid(structure) )
return;
string strBuildingName = getTemplateName(structure);
if (strBuildingName != "object/building/general/bunker_allum_mine.iff")
return;
location myLoc = getLocation(player);
obj_id myCell = myLoc.cell;
obj_id poisonCell = getCellId(structure, "medroom38");
if (myCell == poisonCell)
{
if (!hasScript(player, "theme_park.dungeon.death_watch_bunker.death_watch_poison_player"))
{
attachScript(player, "theme_park.dungeon.death_watch_bunker.death_watch_poison_player");
return;
}
}
return;
}*/