/********************************************************************** * 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; }*/