/********************************************************************** * Copyright (c)2000-2002 Sony Online Entertainment Inc. * All Rights Reserved * * Title: player_structure.scriptlib * Description: player structure script library * @author $Author:$ * @version $Revision:$ **********************************************************************/ //------------------------------------------------ // Includes //------------------------------------------------ include java.lang.Math; include library.city; include library.prose; include library.regions; include library.static_item; include library.sui; include library.target_dummy; include library.trace; include library.trial; include library.utils; include library.vendor_lib; //------------------------------------------------ // Constants //------------------------------------------------ //LOGGING const boolean LOGGING_ON = false; const string LOGGING_CATEGORY = "special_sign"; // Scripts const string SCRIPT_TERMINAL_STRUCTURE = "terminal.terminal_structure"; const string SCRIPT_PERMANENT_STRUCTURE = "structure.permanent_structure"; // Datatables const string PLAYER_STRUCTURE_DATATABLE = "datatables/structure/player_structure.iff"; const string PLAYER_STRUCTURE_VALIDATION_DATATABLE = "datatables/structure/player_structure_validation.iff"; const string TBL_SIGN = "datatables/structure/player_structure_sign.iff"; const string TBL_SPECIAL_SIGNS = "datatables/structure/special_sign.iff"; const string SIGN_ADJUST_SIGN_BY_TEMPLATE = "datatables/structure/sign_adjust_by_template.iff"; // Datatable Columns const string DATATABLE_COL_STRUCTURE = "STRUCTURE"; const string DATATABLE_COL_TEMP_STRUCTURE = "TEMP_STRUCTURE"; const string DATATABLE_COL_FOOTPRINT = "FOOTPRINT_TEMPLATE"; const string DATATABLE_COL_EJECT_RANGE = "EJECT_RANGE"; 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_OBJECT = "OBJECT"; const string DATATABLE_COL_CIVIC = "CIVIC"; const string DATATABLE_COL_CITY_RANK = "CITY_RANK"; const string DATATABLE_COL_CITY_COST = "CITY_COST"; const string DATATABLE_COL_MAINT_RATE = "MAINT_RATE"; const string DATATABLE_COL_DECAY_RATE = "DECAY_RATE"; const string DATATABLE_COL_REDEED_COST = "REDEED_COST"; const string DATATABLE_COL_CONDITION = "CONDITION"; const string DATATABLE_COL_SKILL_MOD = "SKILLMOD"; const string DATATABLE_COL_SKILL_MOD_VALUE = "SKILLMODVALUE"; const string DATATABLE_COL_SKILL_MOD_MESSAGE = "SKILLMOD_MESSAGE"; const string DATATABLE_COL_VERSION = "VERSION"; const string DATATABLE_COL_NO_LOT_REQ = "NO_LOT_REQUIREMENT"; const string DATATABLE_COL_LOT_REDUCTION = "LOT_REDUCTION"; const string DATATABLE_COL_HAS_SIGN = "HAS_SIGN"; const string DATATABLE_COL_POWER_RATE = "POWER_RATE"; const string WORLD_DELTA = "WORLD_DELTA"; // Harvester Validation Columns const string DATATABLE_COL_TEMPLATE = "TEMPLATE"; const string DATATABLE_COL_HOPPER_MIN = "HOPPER_MIN"; const string DATATABLE_COL_HOPPER_MAX = "HOPPER_MAX"; // Object variable constants... // root const string VAR_PLAYER_STRUCTURE = "player_structure"; // for terminals const string VAR_TERMINAL_HEADING = "player_structure.intendedHeading"; const string OBJVAR_STORED_HANGAR_LITE = "hangar_lite.storedInHangarLite"; // for structures const string VAR_OWNER = "player_structure.owner"; const string VAR_OWNER_FACTION = "player_structure.faction"; const string VAR_ENTER_LIST = "player_structure.enter.enterList"; const string VAR_BAN_LIST = "player_structure.ban.banList"; const string VAR_ADMIN_LIST = "player_structure.admin.adminList"; const string VAR_VENDOR_LIST = "player_structure.vendor.vendorList"; const string VAR_HOPPER_LIST = "player_structure.hopper.hopperList"; const string VAR_CIVIC = "player_structure.civic"; const string VAR_CITY_RANK = "player_structure.city_rank"; const string VAR_CITY_COST = "player_structure.city_cost"; const string VAR_MAINTENANCE_MOD = "player_structure.maintanence.mod"; const string VAR_DECAY_RATE = "player_structure.maintanence.decay"; const string VAR_LAST_MAINTANENCE = "player_structure.last_maintanence"; const string VAR_CONDITION = "player_structure.condition"; const string VAR_MAX_CONDITION = "player_structure.max_condition"; const string VAR_BASE_OBJECT = "player_structure.base_objects"; const string VAR_MAX_EXTRACTION = "player_structure.maxExtraction"; const string VAR_CURRENT_EXTRACTION = "player_structure.currentExtraction"; const string VAR_MAX_HOPPER = "player_structure.maxHopper"; const string VAR_VERSION = "player_structure.version"; const string VAR_IS_GUILD_HALL = "player_structure.is_guild_hall"; const string VAR_LAST_MESSAGE = "player_structure.last_message"; const string VAR_PERMISSIONS_CONVERTED = "player_structure.permissions_converted"; const string VAR_ABANDONED = "player_structure.abandoned"; const string OBJVAR_HANGAR_CREATED = "hangar.created"; // for maint mods const string VAR_MAINTENANCE_MODIFIERS = "player_structure.maintanence.modifiers"; const string VAR_MAINTENANCE_MOD_FACTORY = VAR_MAINTENANCE_MODIFIERS + ".factory"; const string VAR_MAINTENANCE_MOD_HARVESTER = VAR_MAINTENANCE_MODIFIERS + ".harvester"; const string VAR_MAINTENANCE_MOD_MERCHANT = VAR_MAINTENANCE_MODIFIERS + ".merchant"; const string VAR_MAINTENANCE_MOD_TAX = VAR_MAINTENANCE_MODIFIERS + ".tax"; const string VAR_POWER_MOD_FACTORY = "player_structure.power.modifiers.factory"; const string VAR_POWER_MOD_HARVESTER = "player_structure.power.modifiers.harvester"; // for signs const string VAR_SIGN_BASE = "player_structure.sign"; const string VAR_SIGN_ID = VAR_SIGN_BASE + ".id"; const string VAR_SIGN_NAME = VAR_SIGN_BASE + ".name"; const string VAR_SIGN_TYPE = VAR_SIGN_BASE + ".type"; // for deeds const string SCRIPT_TEMPORARY_STRUCTURE = "structure.temporary_structure"; const string VAR_DEED_TEMPLATE = "player_structure.deed.template"; const string VAR_DEED_TEMPLATE_CRC = "player_structure.deed.template_crc"; const string VAR_DEED_BUILDTIME = "player_structure.deed.buildtime"; const string VAR_DEED_SCENE = "player_structure.deed.scene"; const string VAR_DEED_TIMESTAMP = "player_structure.deed.timestamp"; const string VAR_DEED_MAX_EXTRACTION = "player_structure.deed.maxExtractionRate"; const string VAR_DEED_CURRENT_EXTRACTION = "player_structure.deed.currentExtractionRate"; const string VAR_DEED_MAX_HOPPER = "player_structure.deed.maxHopperSize"; // for surplus tracking const string VAR_DEED_SURPLUS_BASE = "player_structure.deed.surplus"; const string VAR_DEED_SURPLUS_POWER = "player_structure.deed.surplus.power"; const string VAR_DEED_SURPLUS_MAINTENANCE = "player_structure.deed.surplus.maintenance"; // for temporary structures const string VAR_TEMP_TEMPLATE = "player_structure.construction.template"; const string VAR_TEMP_OWNER = "player_structure.construction.owner"; const string VAR_TEMP_OWNER_NAME = "player_structure.construction.ownerName"; const string VAR_TEMP_OWNER_FACTION = "player_structure.construction.ownerFaction"; const string VAR_TEMP_ROTATION = "player_structure.construction.rotation"; const string VAR_TEMP_PLACEMENT_HEIGHT = "player_structure.construction.placementHeight"; // for players const string VAR_LOTS_USED = "player_structure.lotsUsed"; const string VAR_RESIDENCE_BUILDING = "player_structure.residence.building"; const string VAR_RESIDENCE_CAN_DECLARE = "player_structure.residence.canDeclare"; const string VAR_CONFIRM_DESTROY = "player_structure.confirmDestroy"; // for base objects const string VAR_IS_PLACED_OBJECT = "player_structure.is_placed_object"; // for waypoints const string VAR_WAYPOINT_STRUCTURE = "player_structure.waypoint"; // Misc const float INSTALLATION_RANGE = 30.0f; const float CIVIC_INSTALLATION_RANGE = 30.0f; const float RATE_POWER_MIN = 1f; const float MERCHANT_SALES_MODIFIER = -0.2f; const int MIN_RESIDENCE_DURATION = 86400; const int MAX_LOTS = 10; const int MAX_LIST_SIZE = 50; const int MAIL_WARNING_INTERVAL = 86400; const int TIME_TO_NEXT_PACKUP = 86400; const float HOUSE_PACKUP_FAILURE_TIMER = 0.f; const float HOUSE_PACKUP_LOCKOUT_TIMER = 300.0f; const int ARRAY_LENGTH_FOR_HOUSE_PACKUP = 2; const string SCRIPTVAR_HOUSE_PACKUP_TREE_PREFIX = "packup_structure"; const string SCRIPTVAR_HOUSE_PACKUP_LOCKOUT_TIME = SCRIPTVAR_HOUSE_PACKUP_TREE_PREFIX + ".time_started"; //DO NOT CHANGE THE FOLLOWING CONST. YOU WILL BREAK THE HOUSE PACKUP SYSTEM const string HOUSE_PACKUP_ARRAY_OBJVAR = "housePackup"; const string HOUSE_PACKUP_DAILY_TALLY_OBJVAR = "dailyHousePackup"; const string HOUSE_PACKUP_DAILY_TIMER_OBJVAR = "maxHousePackupTimer"; const string_id SID_LOCKOUT_MESSAGE = new string_id("player_structure", "house_lockout_remaining"); //HOUSE PACKUP CONST END //The following 2 constant arrays are now in the special_sign table (datatables/structure/special_sign.iff) const string[] SIGN_TYPE = { "object/tangible/sign/player/house_address.iff", "object/tangible/sign/player/shop_sign_s01.iff", "object/tangible/sign/player/shop_sign_s02.iff", "object/tangible/sign/player/shop_sign_s03.iff", "object/tangible/sign/player/shop_sign_s04.iff", "object/tangible/sign/player/house_address_naboo.iff", "object/tangible/sign/player/house_address_corellia.iff", "object/tangible/sign/player/house_address_tatooine.iff", }; const string_id[] SIGN_NAMES = { new string_id("player_structure","house_address"), new string_id("player_structure","shop_sign1"), new string_id("player_structure","shop_sign2"), new string_id("player_structure","shop_sign3"), new string_id("player_structure","shop_sign4") }; //Template name for custom house sign const string MODIFIED_HOUSE_SIGN = "structure.modifiedSign"; //Static Item name for custom house sign const string MODIFIED_HOUSE_SIGN_MODEL = "structure.modifiedSignModel"; const string SPECIAL_SIGN = "structure.special_sign.hasSpecialSign"; const string SPECIAL_SIGN_TEMPLATE = "structure.special_sign.specialSignTemplate"; const string SPECIAL_SIGN_SKILLMOD = "structure.special_sign.specialSignSkillMod"; const string SPECIAL_SIGN_DECREMENT_MOD = "structure.special_sign.specialSignDecrementSkillMod"; const string SPECIAL_SIGN_OWNER_ONLY = "structure.special_sign.specialSignOwnerOnly"; const string VAR_SPECIAL_SIGN_TREE = "special_sign"; //player vars const string VAR_SPECIAL_SIGN_LIST = VAR_SPECIAL_SIGN_TREE+".sign_list"; const string VAR_SPECIAL_SIGN_NAMES = VAR_SPECIAL_SIGN_TREE+".sign_name"; const string VAR_SPECIAL_SIGN_MENU = VAR_SPECIAL_SIGN_TREE+".sign_menu"; const string VAR_SPECIAL_SIGN_MENU_PID = VAR_SPECIAL_SIGN_TREE+".sign_menu_pid"; // Strings const string_id SID_MAIL_STRUCTURE_DAMAGE_CONDEMN = new string_id("player_structure", "mail_structure_damage_condemn"); const string_id SID_MAIL_STRUCTURE_DAMAGE_SUB = new string_id("player_structure", "mail_structure_damage_sub"); const string_id SID_MAIL_STRUCTURE_DAMAGE = new string_id("player_structure", "mail_structure_damage"); const string_id SID_BUILD_NO_CITY = new string_id("city/city", "build_no_city"); const string_id SID_RANK_REQ = new string_id("city/city", "rank_req"); const string_id SID_NO_RIGHTS = new string_id("player_structure", "no_rights"); const string_id SID_CIVIC_COUNT = new string_id("city/city", "civic_count"); const string_id CANNOT_PLACE_MINEFIELD = new string_id("player_structure", "cannot_place_minefield"); const string_id CANNOT_PLACE_TURRET = new string_id("player_structure", "cannot_place_turret"); const string_id SID_CANNOT_BUILD_GARAGE_TOO_CLOSE = new string_id("player_structure", "cannot_build_garage_too_close"); const string_id SID_SUI_CONFIRM_PLACEMENT_TITLE = new string_id("player_structure", "sui_confirm_placement_title"); const string_id SID_SUI_CONFIRM_PLACEMENT_PROMPT = new string_id("player_structure", "sui_confirm_placement_prompt"); const string_id SID_NO_FREE_TRIAL = new string_id("player_structure", "no_free_trial"); const string_id PACKUP_EMAIL_TITLE = new string_id("spam", "packup_email_title"); const string_id PACKUP_EMAIL_BODY = new string_id("spam", "packup_email_body"); const string_id SELF_PACKUP_EMAIL_TITLE = new string_id("spam", "packup_email_title_self"); const string_id SELF_PACKUP_EMAIL_BODY = new string_id("spam", "packup_email_body_self"); const string_id CANT_APPLY_SKILLMOD = new string_id("base_player", "cant_use_item"); const string_id SID_SPECIAL_SIGN_FAILED = new string_id("base_player", "special_sign_failed"); const string_id SID_SPECIAL_SIGN_SUCCESS = new string_id("base_player", "special_sign_success"); const string_id SID_SPECIAL_SIGN_REVERT_SUCCESS = new string_id("base_player", "special_sign_revert_success"); const string_id SID_SPECIAL_SIGN_REMOVED = new string_id("base_player", "special_sign_removed"); const string_id SID_SPECIAL_SIGN_UI_TITLE = new string_id("base_player", "special_sign_ui_title"); const string_id SID_SPECIAL_SIGN_UI_PROMPT = new string_id("base_player", "special_sign_ui_prompt"); const string_id SID_REMOVE_SPCIAL_SIGN_TO_DESTROY = new string_id("player_structure", "remove_sign_before_structure_destroy"); const string_id SID_SPECIAL_SIGN_NO_TRANSFER = new string_id("player_structure", "remove_sign_before_structure_transfer"); const string_id SID_HALLOWEEN_SIGN_UPDATED = new string_id("player_structure", "halloween_sign_updated"); const string_id SID_ONLY_OWNER_CAN_REMOVE = new string_id("player_structure", "only_owner_can_remove_sign"); const string STF_FILE = "player_structure"; const string SELFPOWERED_DEED = "object/tangible/veteran_reward/harvester.iff"; const string SELFPOWERED_DEED_ELITE = "object/tangible/veteran_reward/harvester_elite.iff"; const int MAX_BASE_COUNT = 3; const int HARVESTER_MAX_EXTRACTION_RATE = 70; const int HARVESTER_MAX_HOPPER_SIZE = 600000; // Result codes used by destroyStructure() const int DESTROY_RESULT_SUCCESS = 0; const int DESTROY_RESULT_SUCCESS_SELFPOWERED = 1; const int DESTROY_RESULT_FAIL_COULD_NOT_CREATE_DEED = 2; const int DESTROY_RESULT_FAIL_COULD_NOT_DETERMINE_DEED_FOR_STRUCTURE = 3; const int DESTROY_RESULT_FAIL_TARGET_CONTAINER_FULL = 4; const int DESTROY_RESULT_FAIL_TARGET_CONTAINER_FULL_SELFPOWERED = 5; const int DESTROY_RESULT_INVALID_STRUCTURE = 6; const int DESTROY_RESULT_INVALID_STATIC_ITEM = 7; const int DESTROY_RESULT_INVALID_CONTAINER = 8; // Constants for use in abandoned structures, values used in objvar player_structure.abandoned const int PLAYER_STRUCTURE_PRE_ABANDONED = 2; const int PLAYER_STRUCTURE_ABANDONED = 1; const int MAX_PACKUP_PER_DAY = 5; const int NUM_NEEDED_PACKUP_FIRST_BADGE = 10; const int NUM_NEEDED_PACKUP_SECOND_BADGE = 50; const int NUM_NEEDED_PACKUP_THIRD_BADGE = 100; const string ABANDONED_TEXT = "\\#ff0000 (Abandoned)\\#."; const string CITY_ABANDONED_TEXT = "\\#ff0000 (Zoning Violation)\\#."; const string_id MSG_STORAGE_OVER_CAP = new string_id(STF_FILE, "msg_over_cap"); const string OBJVAR_STRUCTURE_STORAGE_INCREASE = "structureChange.storageIncrease"; const string OBJVAR_STORAGE_AMOUNT = "increaseAmount"; const int STORAGE_AMOUNT_CAP = 5000; const int STORAGE_AMOUNT_DECREASE_UNIT = 100; const string NON_GENERIC_STORAGE_ITEM_OBJVAR = "nonGenericStorageType"; const string TCG_STATIC_ITEM_DEED_OBJVAR = "tcg.static_item_deed"; //City Packup Constants const string VAR_CITY_ABANDONED = "player_structure.city_abandoned"; const int PLAYER_STRUCTURE_CITY_ABANDONED = 1; const int HOUSE_ITEMS_SEARCH_LOCKOUT = 5*60; // 5 minutes. const string_id SID_NOT_CITY_ABANDONED = new string_id("city/city", "not_city_abandoned"); const string_id SID_NO_CITY = new string_id("city/city", "no_city_during_packup"); const string_id SID_GENERIC_CITY_PACKUP_ERROR = new string_id("city/city", "city_packup_generic_fail"); const string_id SID_MAYOR_PROTECTED = new string_id("city/city", "city_packup_mayor_protected"); /*********************************************************************** * @brief creates the player structure * * @param string building template * @param obj_id owner player who used the deed * @param location loc the location where the structure is to be created * @param int rotation the rotation in placement tool units. * @param string deed_template the template to use to recreate a deed on structure destroy * * @return obj_id; null if failed ***********************************************************************/ obj_id createPlayerStructure(string template, obj_id owner, location loc, int rotation, dictionary deed_info) { //LOG("//LOG_CHANNEL", "template ->" + template + " owner ->" + owner); if (template == null) { //LOG("//LOG_CHANNEL", "player_structure::createPlayerStructure-- template is invalid"); return null; } if (!isIdValid(owner)) { //LOG("//LOG_CHANNEL", "player_structure::createPlayerStructure-- owner is invalid"); return null; } if (loc == null) { //LOG("//LOG_CHANNEL", "player_structure::createPlayerStructure-- loc is invalid"); return null; } debugSpeakMsg(owner, "I am making my house at " + loc); if(!canPlaceGarage(loc, 120f, template)) { sendSystemMessage(owner, new string_id(STF_FILE, "proximity_build_failed")); // Build failed, too close to another garage. return null; } obj_id structure = createObject(template, loc); if (structure == null || structure == obj_id.NULL_ID) { //LOG("//LOG_CHANNEL", "player_structure::createPlayerStructure -- unable to create object."); return null; } // set orientation float rot_float = (float)(90 * rotation); setYaw(structure, rot_float); persistObject(structure); //initialize structure objvars initializeStructure(structure, owner, deed_info); /* createStructureObjects(structure, rotation); if ( isBuilding(structure) ) createStructureSign(structure, rot_float); else { */ dictionary outparams = new dictionary(); outparams.put( "rotation", rotation ); messageTo( structure, "createStructureObjects", outparams, 10.f, false ); if ( !isBuilding( structure ) ) { // !!! This should eventually go into the templates !!! if ( !isCivic( structure ) ) attachScript( structure, SCRIPT_TERMINAL_STRUCTURE ); } // Send a message to the player letting him know its done. dictionary params = new dictionary(); params.put("structure_name", getNameStringId(structure)); messageTo(owner, "OnConstructionComplete", params, 30.0f, true); CustomerServiceLog("playerStructure","Structure " + structure + "(" + getName(structure) + ") placed by " + owner + " at location " + loc); //LOG("//LOG_CHANNEL", "player_structure::createPlayerStructure-- created building " + structure); //debugSpeakMsg(structure, "Hi! I'm " + structure); float ejectRange = dataTableGetFloat(PLAYER_STRUCTURE_DATATABLE, template, DATATABLE_COL_EJECT_RANGE); if ( ejectRange > 0f ) { dictionary ejectmsg = new dictionary(); ejectmsg.put("sender", structure); messageToRange(ejectRange, "handleEjection", ejectmsg, 1); } return structure; } /*********************************************************************** * @brief creates a temporary player structure * * @param obj_id deed the deed that creates the building * @param obj_id owner player who used the deed * @param location loc the location where the structure is to be created * * @return obj_id; null if failed ***********************************************************************/ obj_id createTemporaryStructure(obj_id deed, obj_id owner, location loc, int rot, float placementHeight) { //LOG("//LOG_CHANNEL", "player_structure::createTemporaryStructure"); if(!isIdValid(deed)) { return null; } if(!isIdValid(owner)) { return null; } if(loc == null) return null; // Get deed data before its deletion. string cityName = getStringObjVar( deed, "cityName" ); string template = getDeedTemplate(deed); string deed_template = getTemplateName(deed); int build_time = getDeedBuildTime(deed); int time_stamp = getGameTime(); string owner_name = getPlayerName(owner); string scene = getDeedScene(deed); int max_extraction = -1; int current_extraction = -1; int max_hopper = -1; if(hasObjVar(deed, VAR_DEED_MAX_EXTRACTION)) { max_extraction = getIntObjVar(deed, VAR_DEED_MAX_EXTRACTION); } if(hasObjVar(deed, VAR_DEED_CURRENT_EXTRACTION)) { current_extraction = getIntObjVar(deed, VAR_DEED_CURRENT_EXTRACTION); } if(hasObjVar(deed, VAR_DEED_MAX_HOPPER)) { max_hopper = getIntObjVar(deed, VAR_DEED_MAX_HOPPER); } int storageIncrease = 0; // Check for Vet Reward storage increase and add it to the structure if(hasObjVar(deed, "structureChange.storageIncrease")) { storageIncrease = getIntObjVar(deed, "structureChange.storageIncrease"); } float surplusPower = getFloatObjVar(deed, VAR_DEED_SURPLUS_POWER); int maintPool = getIntObjVar(deed, VAR_DEED_SURPLUS_MAINTENANCE); if(maintPool > 0) { CustomerServiceLog("playerStructure", "Deed " + deed + " with suplus maintenance used. Amount: " + maintPool + ". Owner is %TU.", owner, null); } if(template == null) { //LOG("//LOG_CHANNEL", "player_structure::OnPlaceStructure -- Unable to find template on deed."); return null; } if(build_time == -1) { //LOG("//LOG_CHANNEL", "player_structure::OnPlaceStructure -- Unable to find buildtime on deed."); return null; } if(!destroyObject(deed)) { //LOG("//LOG_CHANNEL", "player_structure::OnPlaceStructure -- Unable to destroy deed."); //removeStructure(structure, template, owner, owner_name, true, true); //destroyObject(structure); return null; } // Get the temporary structure to create int idx = getStructureTableIndex(template); if(idx == -1) { return null; } string temp_template = dataTableGetString(PLAYER_STRUCTURE_DATATABLE, idx, DATATABLE_COL_TEMP_STRUCTURE); //LOG("//LOG_CHANNEL", "temp_template ->" + temp_template); loc.y = getHeightAtLocation(loc.x, loc.z); obj_id structure = createObject(temp_template, loc); if(!isIdValid(structure)) { //LOG("//LOG_CHANNEL", "Unable to find a temporary structure. Using default."); // If couldn't find the temp_template, use the default. structure = createObject("object/building/player/construction_structure.iff", loc); if(!isIdValid(structure)) { return null; } } // Persist it persistObject(structure); // Rotate it float rot_fl = (float)(rot * 90); setYaw(structure, rot_fl); // Set up temporary structure setObjVar(structure, VAR_DEED_BUILDTIME, build_time); setObjVar(structure, VAR_DEED_TIMESTAMP, time_stamp); //attachScript(structure, SCRIPT_TEMPORARY_STRUCTURE); // Add the structure to the player's ownership list. string structure_name = localize(getNameStringId(structure)); addStructure(structure, template, structure_name, loc, owner, owner_name, true, true); // Store player's maintenance skill mods int maintenance_mod = getSkillStatMod(owner, "structure_maintenance_mod"); int factory_mod = getSkillStatMod(owner, "factory_efficiency"); // Store deed information for reclamation purposes. // Store any management modifiers dictionary deed_info = new dictionary(); deed_info.put("template", deed_template); deed_info.put("build_time", build_time); deed_info.put("owner_name", owner_name); // Pass the storage increase objvar to the structure if(storageIncrease > 0) { deed_info.put("structure_storage", storageIncrease); } if(surplusPower > 0) { deed_info.put("power", surplusPower); } if(maintPool > 0) { deed_info.put("maintenance_pool", maintPool); } // Write out data on construction site (this is for the recovery of a lost construction complete message) setObjVar(structure, VAR_TEMP_TEMPLATE, template); setObjVar(structure, VAR_TEMP_OWNER, owner); setObjVar(structure, VAR_TEMP_OWNER_NAME, owner_name); setObjVar(structure, VAR_TEMP_ROTATION, rot); setObjVar(structure, VAR_TEMP_PLACEMENT_HEIGHT, placementHeight); //setObjVar(structure, VAR_DEED_TEMPLATE, deed_template); setDeedTemplate(structure, deed_template); setObjVar(structure, VAR_DEED_BUILDTIME, build_time); setObjVar(structure, VAR_DEED_SCENE, scene); if(cityName != null && cityName != "") // Pass on the city name. { setObjVar( structure, "cityName", cityName ); deed_info.put( "cityName", cityName ); } string owner_faction = factions.getFaction(owner); if(owner_faction != null && !owner_faction.equals("")) { deed_info.put("owner_faction", owner_faction); setObjVar(structure, VAR_TEMP_OWNER_FACTION, owner_faction); } if(scene != null) { deed_info.put("scene", scene); } if(max_extraction != -1) { deed_info.put("max_extraction", max_extraction); setObjVar(structure, VAR_DEED_MAX_EXTRACTION, max_extraction); } if(current_extraction != -1) { deed_info.put("current_extraction", current_extraction); setObjVar(structure, VAR_DEED_CURRENT_EXTRACTION, current_extraction); } if(max_hopper != -1) { deed_info.put("max_hopper", max_hopper); setObjVar(structure, VAR_DEED_MAX_HOPPER, max_hopper); } if(maintenance_mod > 0) { deed_info.put("maintenance_mod", maintenance_mod); } if(factory_mod > 0) { deed_info.put("factory_mod", factory_mod); } if(hasCommand(owner, "place_merchant_tent")) { deed_info.put("merchant_mod", MERCHANT_SALES_MODIFIER); } // Set up message dictionary dictionary params = new dictionary(); params.put("template", template); params.put("owner", owner); params.put("deed_info", deed_info); params.put("buildTime", build_time); params.put("rotation", rot); params.put("timestamp", time_stamp); params.put("placementHeight", placementHeight); messageTo(structure, "OnBuildingComplete", params, 5.0f, true); return structure; } /*********************************************************************** * @brief Creates objects within the structure as specified by the datatable * * @param obj_id structure structure in which to put the terminal * @param string datatable datatable where the terminal structure information is held * * @return boolean; false on unable to add ***********************************************************************/ boolean createStructureObjects(obj_id structure, int rotation) { if (structure == obj_id.NULL_ID) { //LOG("//LOG_CHANNEL", "player_structure::createTerminal-- structure is invalid"); return false; } string sceneName = getCurrentSceneName(); string structureTemplate = getTemplateName(structure); int numItems = 0; if ( dataTableOpen(PLAYER_STRUCTURE_DATATABLE) ) { numItems = dataTableGetNumRows(PLAYER_STRUCTURE_DATATABLE); } else { //LOG("//LOG_CHANNEL", "player_structure::createTerminal-- cannot query datatable"); return false; } if ( numItems == 0 ) { //LOG("//LOG_CHANNEL", "player_structure::createTerminal-- datatable is empty"); return false; } boolean object_set = false; boolean object_mode = false; obj_id object = obj_id.NULL_ID; resizeable obj_id[] base_object_list = new obj_id[0]; for ( int i = 0; i < numItems; i++ ) { string buildingTemplate = dataTableGetString(PLAYER_STRUCTURE_DATATABLE, i, DATATABLE_COL_STRUCTURE); //LOG("//LOG_CHANNEL", "buildingTemplate -> [" + i + "]" + buildingTemplate); // Once we find the correct template, we're ready to look for objects in the indices immediately // after it. if ( buildingTemplate.equals(structureTemplate) ) { object_mode = true; continue; } // We're at a row that specifies objects for our structure if (object_mode) { // If we hit the next row with a building template, we are done finding objects for our structure. if (buildingTemplate.length() != 0) break; // Get objects to create. They start with the row underneath the structure template dictionary item = dataTableGetRow(PLAYER_STRUCTURE_DATATABLE, i); string TEMPLATE = item.getString(DATATABLE_COL_OBJECT); float X = item.getFloat(DATATABLE_COL_X); float Y = item.getFloat(DATATABLE_COL_Y); float Z = item.getFloat(DATATABLE_COL_Z); float HEADING = item.getFloat(DATATABLE_COL_HEADING); string CELL_NAME = item.getString(DATATABLE_COL_CELL); //LOG("//LOG_CHANNEL", "TEMPLATE ->" + TEMPLATE + " CELL_NAME ->" + CELL_NAME); obj_id CELL_ID = obj_id.NULL_ID; location s_loc = getLocation(structure); if ( CELL_NAME.equals(WORLD_DELTA) ) { // Place an object outside of the structure's coordinate system. if (rotation != 0) { // We have to rotate the position of the object with respect to the building // since it is not in the buildings coordinate system. ////LOG("//LOG_CHANNEL", "X/Z ->" + X + "/" + Z); float[] delta_trans = transformDeltaWorldCoord(X, Z, rotation); X = delta_trans[0]; Z = delta_trans[1]; ////LOG("//LOG_CHANNEL", "X/Z ->" + X + "/" + Z); // Now transform the heading of the object. HEADING = HEADING + (float)(rotation * 90); if (HEADING > 360) HEADING = HEADING - 360; } location obj_loc = new location(s_loc.x - X, s_loc.y - Y, s_loc.z - Z, sceneName, obj_id.NULL_ID); object = createObject(TEMPLATE, obj_loc); if ( isCivic( structure ) ) setOwner( object, structure ); //LOG("//LOG_CHANNEL", "Creating delta_world object ->" + object); } else { CELL_ID = getCellId(structure, CELL_NAME); if ( CELL_ID == null || CELL_ID == obj_id.NULL_ID ) { //LOG("//LOG_CHANNEL", "player_structure::createTerminal-- datatable " + PLAYER_STRUCTURE_DATATABLE + " has a bad cell name"); continue; } else { location spot = new location(X, Y, Z, sceneName, CELL_ID); object = createObjectInCell(TEMPLATE, structure, CELL_NAME, spot); //LOG("//LOG_CHANNEL", "player_structure::createObjects-- creating object " + object); } } if ( (object != null) && (object != obj_id.NULL_ID) ) { //rotate it! setYaw(object, HEADING); //Add it to the structure's base object list base_object_list = utils.addElement(base_object_list, object); //Mark the object as a base object //setObjVar(object, VAR_IS_BASE_OBJECT, 1); //persistObject(object); object_set = true; //Clear object for the next one object = obj_id.NULL_ID; } } } if (!object_set) { //LOG("//LOG_CHANNEL", "player_structure::createStructureObjects-- did not create any objects."); return false; } else { // keep track of the base objects on the structure if(base_object_list.length > 0) { // Zero length array check setObjVar(structure, VAR_BASE_OBJECT, base_object_list); return true; } else { return false; } } } /*********************************************************************** * @brief Initializes player structure objvars * * @param obj_id structure structure to initialize * @param obj_id owner owner of the structure * * @return boolean; false on unable to initialize ***********************************************************************/ boolean initializeStructure(obj_id structure, obj_id owner, dictionary deed_info) { if(structure == obj_id.NULL_ID) { return false; } if(owner == obj_id.NULL_ID) { return false; } LOG("player_structure","deed_info = " + deed_info.toString()); string template = getTemplateName(structure); // Owner may not be loaded. Get name from stored temp structure data. //string owner_name = deed_info.getString("owner_name"); string owner_name = getPlayerName(owner); if(owner_name == null) { //LOG("//LOG_CHANNEL", "player_structure::initializeStructure -- owner_name is null for " + structure); return false; } string[] adminList = new string[1]; adminList[0] = owner.toString(); // store objId as a string since this list will also hold guild names // Get base values int decay_rate = 10; int condition = 1000; int civic = 0; int city_rank = 0; int city_cost = 0; float power_value = 0f; float power_rate = getBasePowerRate(structure); int items_stored = 0; int idx = getStructureTableIndex(template); if (idx == -1) { //LOG("//LOG_CHANNEL", "player structure::initializeStructure -- unable to find template in datatable."); } else { decay_rate = dataTableGetInt(PLAYER_STRUCTURE_DATATABLE, idx, DATATABLE_COL_DECAY_RATE); condition = dataTableGetInt(PLAYER_STRUCTURE_DATATABLE, idx, DATATABLE_COL_CONDITION); civic = dataTableGetInt(PLAYER_STRUCTURE_DATATABLE, idx, DATATABLE_COL_CIVIC); city_rank = dataTableGetInt(PLAYER_STRUCTURE_DATATABLE, idx, DATATABLE_COL_CITY_RANK); city_cost = dataTableGetInt(PLAYER_STRUCTURE_DATATABLE, idx, DATATABLE_COL_CITY_COST); } // Get the structure version int version = dataTableGetInt(PLAYER_STRUCTURE_DATATABLE, idx, DATATABLE_COL_VERSION); int got = getGameObjectType(structure); // These are for all player structures. setOwner(structure, owner); setObjVar(structure, VAR_OWNER, owner_name); string owner_faction = deed_info.getString("owner_faction"); if(owner_faction != null && !owner_faction.equals("")) { factions.setFaction(structure, owner_faction); } // Check for a city name. string cityName = deed_info.getString("cityName"); if(cityName != null && cityName != "") { setObjVar( structure, "cityName", cityName ); // This objvar is later removed when the city is set up. } // A civic structure doesn't pay maintenance. setObjVar(structure, VAR_CIVIC, civic); if(city_rank > 0) { setObjVar(structure, VAR_CITY_RANK, city_rank); } if(city_cost > 0) { setObjVar(structure, VAR_CITY_COST, city_cost); } setObjVar(structure, VAR_ADMIN_LIST, adminList); permissionsAddAllowed(structure, owner_name); // The entry list setObjVar(structure, VAR_DECAY_RATE, decay_rate); if(condition > 0) { setMaxHitpoints(structure, condition); setInvulnerableHitpoints(structure, condition); } setObjVar(structure, VAR_VERSION, version); // These are only for buildings if(isBuilding(structure)) { // Allow the house to act as a hospital and cantina. setObjVar(structure, "healing.canhealwound", 1); setObjVar(structure, "healing.canhealshock", 1); setObjVar(structure, "safeLogout", 1); } // These are only for installations if(isInstallation(structure) && got != GOT_installation_turret) { string[] hopperList = new string[1]; hopperList[0] = owner.toString(); // store objId as a string since this list will also hold guild names setObjVar(structure, VAR_HOPPER_LIST, hopperList); if(got == GOT_installation_factory || got == GOT_installation_harvester) { if(deed_info.containsKey("power")) { setPowerValue(structure, deed_info.getFloat("power")); } else { setPowerValue(structure, 0.0f); } power_rate = expertiseModifyPowerRate(structure, owner, power_rate); if(power_rate < 0) { power_rate = 0; } setPowerRate(structure, power_rate); } } // Store deed data for deed reclamation and set deed override objvars //setObjVar(structure, VAR_DEED_TEMPLATE, deed_info.getString("template")); setDeedTemplate(structure, deed_info.getString("template")); setObjVar(structure, VAR_DEED_BUILDTIME, deed_info.getInt("build_time")); setObjVar(structure, VAR_DEED_SCENE, deed_info.getString("scene")); if(deed_info.containsKey("current_extraction") && (isHarvester(structure) || isGenerator(structure))) { int expertiseExtractionIncrease = (int)getSkillStatisticModifier(owner, "expertise_harvester_collection_increase"); int currentExtraction = deed_info.getInt("current_extraction"); int maxExtraction = deed_info.getInt("max_extraction"); // These objvars are used for re-deeding the harvester. setObjVar(structure, "current_extraction", currentExtraction); setObjVar(structure, "max_extraction", maxExtraction); if(expertiseExtractionIncrease > 0) { currentExtraction += (int)(currentExtraction * (float)(expertiseExtractionIncrease / 100.0f)); maxExtraction += (int)(maxExtraction * (float)(expertiseExtractionIncrease / 100.0f)); } if(currentExtraction > HARVESTER_MAX_EXTRACTION_RATE) { currentExtraction = HARVESTER_MAX_EXTRACTION_RATE; } if(maxExtraction > HARVESTER_MAX_EXTRACTION_RATE) { maxExtraction = HARVESTER_MAX_EXTRACTION_RATE; } setCurrentExtractionRate(structure, currentExtraction); setMaxExtractionRate(structure, maxExtraction); } if(deed_info.containsKey("max_hopper")) { int max_hopper = deed_info.getInt("max_hopper"); // This objvar is used for re-deeding. setObjVar(structure, VAR_DEED_MAX_HOPPER, max_hopper); if(isHarvester(structure) || isGenerator(structure)) { int expertiseHopperIncrease = (int)getSkillStatisticModifier(owner, "expertise_havester_storage_increase"); if(expertiseHopperIncrease > 0) { max_hopper += (int)(max_hopper * (float)(expertiseHopperIncrease / 100.0f)); } } if(max_hopper > HARVESTER_MAX_HOPPER_SIZE) { max_hopper = HARVESTER_MAX_HOPPER_SIZE; } setMaxHopperAmount(structure, max_hopper); } if(deed_info.containsKey("maintenance_pool")) { int maintPool = deed_info.getInt("maintenance_pool"); transferBankCreditsFromNamedAccount(money.ACCT_STRUCTURE_DESTROYED, structure, maintPool, "noHandler", "noHandler", new dictionary()); CustomerServiceLog("playerStructure", "Structure " + structure + " was created with surplus maintenance. Amount: " + maintPool + ". Owner is %TU.", owner, null); } if(deed_info.containsKey("merchant_mod") && got != GOT_building_factional) { setObjVar(structure, VAR_MAINTENANCE_MOD_MERCHANT, deed_info.getFloat("merchant_mod")); } if(deed_info.containsKey("structure_storage")) { setObjVar(structure, "structureChange.storageIncrease", deed_info.getInt("structure_storage")); } // Make the structure private if(civic == 1 || hasObjVar(structure, "force_public")) { permissionsMakePublic(structure); } else if(got != GOT_building_factional) { permissionsMakePrivate(structure); } attachScript(structure, SCRIPT_PERMANENT_STRUCTURE); // Send message to player to update his ownership list. dictionary new_params = new dictionary(); new_params.put("structure", structure); new_params.put("structure_name", localize(getNameStringId(structure))); new_params.put("structure_loc", getLocation(structure)); new_params.put("template", template); messageTo(owner, "OnAddStructure", new_params, 0, true); // Start the maintenance loop dictionary params = new dictionary(); int time_stamp = getGameTime(); setObjVar(structure, VAR_LAST_MAINTANENCE, time_stamp); if(civic == 0) { params.put("timestamp", time_stamp); LOG("LOG_CHANNEL", "Messaging "+structure+" to run maintenance loop"); messageTo(structure, "OnMaintenanceLoop", params, 30, false); } return true; } float getBasePowerRate(obj_id structure) { string template = getTemplateName(structure); int idx = getStructureTableIndex(template); float power_rate = dataTableGetFloat(PLAYER_STRUCTURE_DATATABLE, idx, DATATABLE_COL_POWER_RATE); if(power_rate < 0f) { power_rate = 0; } if(hasObjVar(structure, "selfpowered")) { power_rate = 0f; } return power_rate; } float expertiseModifyPowerRate(obj_id structure, obj_id owner, float power_rate) { if(!isIdValid(structure)) { return power_rate; } if(power_rate <= 0) { return 0; } int got = getGameObjectType(structure); int expertisePowerReduction = 0; // If the owner is not online, try to get the values off the harvester if(!isIdValid(owner) || !exists(owner)) { if(got == GOT_installation_factory && hasObjVar(structure, VAR_POWER_MOD_FACTORY)) { expertisePowerReduction = getIntObjVar(structure, VAR_POWER_MOD_FACTORY); } if(got == GOT_installation_harvester && hasObjVar(structure, VAR_POWER_MOD_HARVESTER)) { expertisePowerReduction = getIntObjVar(structure, VAR_POWER_MOD_HARVESTER); } } else // If the owner is online, try to get the values off the owner { if(got == GOT_installation_factory) { expertisePowerReduction = (int)getSkillStatisticModifier(owner, "expertise_factory_energy_decrease"); setObjVar(structure, VAR_POWER_MOD_FACTORY, expertisePowerReduction); } if(got == GOT_installation_harvester) { expertisePowerReduction = (int)getSkillStatisticModifier(owner, "expertise_harvester_energy_decrease"); setObjVar(structure, VAR_POWER_MOD_HARVESTER, expertisePowerReduction); } } if(expertisePowerReduction > 0) { power_rate -= (int)(power_rate * (float)(expertisePowerReduction / 100.0f)); } return power_rate; } /*********************************************************************** * @brief Adds a structure to the player's ownership list. * * @param obj_id structure structure to add * @param string template template to use for lot calculation * @param obj_id player player to own the structure * @param string player_name player name to use * @param boolean struct_loaded true if the structure is guaranteed * to be loaded into memory * @param boolean player_loaded true if the player is guaranteed to * be loaded into memory * @return boolean ***********************************************************************/ boolean addStructure( obj_id structure, string template, string structure_name, location structure_location, obj_id player, string player_name, boolean struct_loaded, boolean player_loaded ) { if ( structure == null || structure == obj_id.NULL_ID ) return false; if ( player == null || player == obj_id.NULL_ID ) return false; string fp_template = getFootprintTemplate( template ); if ( fp_template == null || fp_template.equals("") ) return false; if ( player_loaded ) { // Get our datatable entry index. int idx = getStructureTableIndex( template ); if ( idx == -1 ) return false; int ignore_lots = dataTableGetInt( PLAYER_STRUCTURE_DATATABLE, idx, DATATABLE_COL_NO_LOT_REQ ); if ( ignore_lots != 1 ) { int struct_lots = (getNumberOfLots(fp_template) / 4) - dataTableGetInt( PLAYER_STRUCTURE_DATATABLE, idx, DATATABLE_COL_LOT_REDUCTION ); if (struct_lots < 1) struct_lots = 1; //conversion from 9-lot halls to 7, 2-lot factories to 1 // added 10-22-4, delete this in a month or two flagConverted( template, structure ); // check/flag/enforce possible lot overlimit condition if ((getAccountNumLots(getPlayerObject(player)) + struct_lots) > MAX_LOTS) { string realStructureTemplate = template; if (exists(structure)) realStructureTemplate = getTemplateName(structure); if ((realStructureTemplate != null) && (realStructureTemplate.length() > 0) && (realStructureTemplate.indexOf("object/building/player/player_house_") == 0)) { setObjVar(player, "lotOverlimit.structure_id", structure); if ((structure_name != null) && (structure_name.length() > 0)) setObjVar(player, "lotOverlimit.structure_name", structure_name); if (structure_location != null) setObjVar(player, "lotOverlimit.structure_location", localize(new string_id("planet_n", structure_location.area)) + " (" + (int)structure_location.x + ", " + (int)structure_location.z + ")"); setObjVar(player, "lotOverlimit.violation_time", getCalendarTime()); } } adjustLotCount( getPlayerObject(player), struct_lots ); } } if ( struct_loaded ) { // Make player the owner and admin of the structure setObjVar(structure, VAR_OWNER, getPlayerName(player)); setOwner(structure, player); if (!isAdmin(structure, getPlayerName(player))) modifyList(structure, getPlayerName(player), null, VAR_ADMIN_LIST, false); } if ( player_loaded && struct_loaded ) { // Add a waypoint to the structure //string_id name_id = getNameStringId(structure); //obj_id waypoint = addStructureWaypoint(player, getLocation(structure), localize(name_id), structure); //if (isIdValid(waypoint)) // setObjVar(structure, VAR_WAYPOINT_STRUCTURE, waypoint); } // Add this structure to a city. city.addStructureToCity( structure ); return true; } /*********************************************************************** * @brief Overload for addStructure when player and structure * are loaded into memory. * * @param obj_id structure structure to add * @param obj_id player player to own the structure * * @return boolean ***********************************************************************/ boolean addStructure(obj_id structure, obj_id player) { string template = getTemplateName(structure); string structure_name = localize(getNameStringId(structure)); location structure_location = getWorldLocation(structure); string player_name = getPlayerName(player); // Add the player's management mods to the structure // applyManagementMods(structure, player); return addStructure(structure, template, structure_name, structure_location, player, player_name, true, true); } /*********************************************************************** * @brief Removes a structure from the player's ownership list. This function * should be used in conjunction with addStructure unless the structure * is to be destroyed. * * @param obj_id structure structure to add * @param string template template to use for lot size * @param obj_id player owner of the structure * @param string player_name player name to use * @param boolean struct_loaded true if the structure is guaranteed * to be loaded into memory * @param boolean player_loaded true if the player is guaranteed to * be loaded into memory * * @return boolean ***********************************************************************/ boolean removeStructure( obj_id structure, string template, obj_id player, string player_name, boolean struct_loaded, boolean player_loaded ) { if ( structure == null || structure == obj_id.NULL_ID ) return false; if ( player == null || player == obj_id.NULL_ID ) return false; string fp_template = getFootprintTemplate( template ); if ( fp_template == null || fp_template.equals("") ) return false; if ( player_loaded ) { // Get our datatable entry index. int idx = getStructureTableIndex( template ); if ( idx == -1 ) return false; int ignore_lots = dataTableGetInt( PLAYER_STRUCTURE_DATATABLE, idx, DATATABLE_COL_NO_LOT_REQ ); if ( ignore_lots != 1 ) { // Get the player's structure information int struct_lots = (getNumberOfLots(fp_template) / 4) - dataTableGetInt( PLAYER_STRUCTURE_DATATABLE, idx, DATATABLE_COL_LOT_REDUCTION ); if ( struct_lots < 1 ) struct_lots = 1; // Remove the lots CustomerServiceLog("playerStructure","Structure " + template + " "+ structure + "(" + ") REMOVED by " + player + " at location " + getLocation(player)); adjustLotCount(getPlayerObject(player), -struct_lots); // Reality check on lots. Reset it if it's messed up. int current_lots = getAccountNumLots( getPlayerObject(player) ); if ( current_lots < 0 ) adjustLotCount( getPlayerObject(player), -current_lots ); } // Remove the structure as the player's residence if ( isResidence( structure, player ) ) { setHouseId( player, obj_id.NULL_ID ); removeObjVar( structure, VAR_RESIDENCE_BUILDING ); // Also remove the player from his current city. city.removeCitizen( player, structure ); } } // Clear out the owner and admin settings on the structure. if ( struct_loaded ) { removeObjVar( structure, VAR_OWNER ); // Although the player object is passed, setting verbose to false insures that it won't be queried. if (isAdmin(structure, getPlayerName(player))) modifyList( structure, getPlayerName(player), null, VAR_ADMIN_LIST, false ); } return true; } /*********************************************************************** * @brief Overload for removeStructure when player and structure * are loaded into memory. * * @param obj_id structure structure to remove * @param obj_id player owner of the structure * * @return boolean ***********************************************************************/ boolean removeStructure(obj_id structure, obj_id player) { string template = getTemplateName(structure); string player_name = getPlayerName(player); // Remove management mods from the structure. // removeManagementMods(structure); return removeStructure( structure, template, player, player_name, true, true ); } /*********************************************************************** * @brief Checks to see if the structure is of the current version. * Updates the structure if not. * * @param obj_id structure structure to remove * @param obj_id player owner of the structure * * @return boolean returns true if an update was made. ***********************************************************************/ boolean updateStructureVersion(obj_id structure) { //LOG("//LOG_CHANNEL", "player_structure::updateStructureVersion"); if (!isIdValid(structure)) { //LOG("//LOG_CHANNEL", "player_structure::updateStructureDatatableValues -- structure is null!"); return false; } string template = getTemplateName(structure); //LOG("//LOG_CHANNEL", "template ->" + template); if (template == null) return false; int idx = getStructureTableIndex(template); if (idx == -1) { //LOG("//LOG_CHANNEL", "player_structure::checkStructureVersion -- unable to find template."); return false; } //int version = dataTableGetInt(PLAYER_STRUCTURE_DATATABLE, idx, DATATABLE_COL_VERSION); //int struct_version = getStructureVersion(structure); // Get the yaw into placement tool units float yaw = getYaw(structure); if (yaw < 0.0f) yaw = yaw + 360.0f; int rotation = (int)(yaw + 1) / 90; // Update datatable data updateStructureData(structure); // Remove the base objects and recreate them. // destroyBaseObjects(structure); createStructureObjects(structure, rotation); createStructureSign(structure); // Set the updated version //setObjVar(structure, VAR_VERSION, version); return true; } /*********************************************************************** * @brief Updates structure datatable values * * @param obj_id structure * * @return boolean returns true if an update was made. ***********************************************************************/ boolean updateStructureData(obj_id structure) { //LOG("//LOG_CHANNEL", "player_structure::updateStructureData"); if (!isIdValid(structure)) { //LOG("//LOG_CHANNEL", "player_structure::updateStructureDatatableValues -- structure is null!"); return false; } string template = getTemplateName(structure); if (template == null) return false; // //LOG("//LOG_CHANNEL", "template ->" + template); int idx = getStructureTableIndex(template); if (idx == -1) { //LOG("//LOG_CHANNEL", "player_structure::updateStructureDatatableValues -- unable to find template."); return false; } dictionary row = dataTableGetRow(PLAYER_STRUCTURE_DATATABLE, idx); int decay_rate = row.getInt(DATATABLE_COL_DECAY_RATE); int condition = row.getInt(DATATABLE_COL_CONDITION); // Apply management mods if applicable //if (hasObjVar(structure, VAR_MAINTENANCE_MOD)) //{ // int mm = getIntObjVar(structure, VAR_MAINTENANCE_MOD); // applyManagementMods(structure, mm); //} setObjVar(structure, VAR_DECAY_RATE, decay_rate); float power_rate = 0.0f; if(!hasObjVar(structure, "selfpowered")) { power_rate = row.getFloat(DATATABLE_COL_POWER_RATE); power_rate = expertiseModifyPowerRate(structure, null, power_rate); } setPowerRate(structure, power_rate); if(condition > 0) { int current_hp = getHitpoints(structure); int max_hp = getMaxHitpoints(structure); setMaxHitpoints(structure, condition); // We only adjust current hitpoints if the structure is at 100% if (current_hp == max_hp) setInvulnerableHitpoints(structure, condition); } //LOG("//LOG_CHANNEL", "player_structure::updateStructureData -- complete"); return true; } /*********************************************************************** * @brief Determines if the player may place a structure * * @param obj_id player player placing the structure * @param obj_id template template of the structure being placed * @param location loc the place where the structure will be * * @return boolean ***********************************************************************/ boolean canPlaceStructure(obj_id player, string template, location loc, obj_id deed) { if(isFreeTrialAccount(player)) { sendSystemMessage(player, new string_id(STF_FILE, "no_trial_accounts")); // Trial accounts are not authorized to place those structures return false; } // Check for the template on the player_structure datatable. int template_idx = getStructureTableIndex(template); LOG("LOG_CHANNEL", "player_structure::canPlaceStructure -- template_idx ->" + template_idx); if (template_idx == -1) { LOG("LOG_CHANNEL", "player_structure::OnObjectMenuSelect -- Unable to find template on datatable."); return false; } // PREVENT PLAYERS FROM BUILDING NON-INSTALLATION STRUCTURES ON ENDOR, DATHOMIR AND YAVIN4 string strPlanet = loc.area; if(strPlanet==null) { // what the hell is wrong with you? return false; } if((strPlanet=="yavin4")||(strPlanet=="dathomir")||(strPlanet=="endor")) { int intIndex = template.indexOf("installation"); if(intIndex<0) { sendSystemMessage(player, new string_id(STF_FILE, "cannot_use_deed_here")); // That deed cannot be used on this planet. return false; } } // Check to see if the structure is valid for the scene. if ( isIdValid(deed) ) { if ( hasObjVar( deed, VAR_DEED_SCENE ) ) { string scene = getCurrentSceneName(); string deed_scene = getDeedScene(deed); boolean match = false; java.util.StringTokenizer st = new java.util.StringTokenizer( deed_scene, "," ); while ( st.hasMoreTokens() ) { string curScene = st.nextToken(); if ( scene.equals(curScene) ) { match = true; break; } } if ( !match ) { if ( !isGod(player) ) { sendSystemMessage(player, new string_id(STF_FILE, "cannot_use_deed_here")); // That deed cannot be used on this planet. return false; } else { sendSystemMessageTestingOnly(player, "God-Mode Placement Override: Structure is not native to this planet!"); } } } } if(hasScript(deed, "faction_perk.minefield.field_deed")) { sendSystemMessage(player, CANNOT_PLACE_MINEFIELD); return false; } if(hasScript(deed, "faction_perk.turret.turret_deed")) { sendSystemMessage(player, CANNOT_PLACE_TURRET); return false; } if (loc.cell != null && loc.cell != obj_id.NULL_ID) { //LOG("//LOG_CHANNEL", "You can not place a structure while you are inside a building."); sendSystemMessage(player, new string_id(STF_FILE, "not_inside")); // You can not place a structure while you are inside a building. return false; } // Check to see if the player is in a buildable region. region[] rgnTest = getRegionsWithBuildableAtPoint( loc, regions.BUILD_FALSE ); if ( rgnTest != null ) { sendSystemMessage(player, new string_id(STF_FILE, "not_permitted")); // Building is not permitted here. return false; } // If the deed is not for a House Control Device if (!isGameObjectTypeOf (getGameObjectType(deed), GOT_data_house_control_device)) { // Check to see if the player is eligable to own the building. if ( !canOwnStructure(template, player, true) ) return false; } // For a city, check the city object to make sure placement here is legal. if ( template.indexOf( "cityhall" ) != -1 ) { // Enforce planetary limits. int cities_on_planet = 0; string planet_name = getCurrentSceneName(); int[] city_ids = getAllCityIds(); for ( int i=0; i= max_cities ) { sendSystemMessage(player, new string_id(STF_FILE, "max_cities")); // This planet has already reached its max allowed number of player cities. return false; } } // Check our location against other cities max radius. int blocking_city = city.canBuildCityHere( player, loc ); if ( blocking_city > -1 ) { string block_name = cityGetName( blocking_city ); location block_loc = cityGetLocation( blocking_city ); sendSystemMessageProse(player, prose.getPackage(new string_id (STF_FILE, "city_too_close"), block_name)); return false; } } // Check to see if we have a city rank requirement to meet. int city_rank_req = dataTableGetInt( PLAYER_STRUCTURE_DATATABLE, template_idx, DATATABLE_COL_CITY_RANK ); int civic = dataTableGetInt( PLAYER_STRUCTURE_DATATABLE, template_idx, DATATABLE_COL_CIVIC ); if ( city_rank_req > 0 ) { int city_id = getCityAtLocation( loc, 0 ); if ( !cityExists( city_id ) ) { sendSystemMessage( player, SID_BUILD_NO_CITY ); return false; } int city_rank = city.getCityRank( city_id ); if ( city_rank < city_rank_req ) { // Can't build it. prose_package pp = prose.getPackage( SID_RANK_REQ, new string_id( "city/city", "rank"+city_rank_req ), city_rank_req ); sendSystemMessageProse( player, pp ); return false; } } // Check to see if we need zoning rights. int city_id = getCityAtLocation( loc, 0 ); obj_id mayor = cityGetLeader( city_id ); if ( cityExists( city_id ) && city.isCityZoned( city_id ) && isIdValid(player) ) { if(!city.hasZoningRights(player, city_id)) { sendSystemMessage( player, SID_NO_RIGHTS ); return false; } } // Check to see if we have hit our civic structure cap. if ( civic == 1 ) { int civic_count = city.getCivicCount( city_id ); int max_civic = city.getMaxCivicCount( city_id ); if ( civic_count >= max_civic ) { prose_package pp = prose.getPackage( SID_CIVIC_COUNT, max_civic ); sendSystemMessageProse( player, pp ); return false; } } return true; } /*********************************************************************** * @brief Overload for canPlaceStructure * * @param obj_id player player placing the structure * @param obj_id template template of the structure being placed * * @return boolean ***********************************************************************/ boolean canPlaceStructure(obj_id player, string template) { location loc = getLocation(player); return canPlaceStructure(player, template, loc, null); } /*********************************************************************** * @brief Determines if a player is eligable to own a specified structure * * @param obj_id player player to own the structure * @param obj_id template template of the structure * @param boolean allowOverLotLimitIfPlayerHouse see comment below * * @return boolean ***********************************************************************/ boolean canOwnStructure( string template, obj_id player, boolean allowOverLotLimitIfPlayerHouse ) { if ( player == null || player == obj_id.NULL_ID ) return false; // Get our datatable entry index. int idx = getStructureTableIndex( template ); if ( idx == -1 ) return false; int ignore_lots = dataTableGetInt( PLAYER_STRUCTURE_DATATABLE, idx, DATATABLE_COL_NO_LOT_REQ ); if ( ignore_lots != 1 ) { // Check to see if the player has enough available lots int lots = getAccountNumLots( getPlayerObject(player) ); int lots_needed = (getNumberOfLots(template) / 4) - dataTableGetInt( PLAYER_STRUCTURE_DATATABLE, idx, DATATABLE_COL_LOT_REDUCTION ); if ( lots_needed < 1 ) lots_needed = 1; if (lots > MAX_LOTS) { sendSystemMessageProse(player, prose.getPackage(new string_id (STF_FILE, "not_enough_lots"), lots_needed)); // This structure requires %DI lots. return false; } // if allowOverLotLimitIfPlayerHouse is specified and the structure is a // player house, *ALWAYS* allow the structure if the player is currently // at or below the lot limit, even if doing so would cause the lot limit // to be exceeded; we will enforce certain restrictions to coerce the // player to get back to lot limit compliance if ((lots + lots_needed) > MAX_LOTS) { if (allowOverLotLimitIfPlayerHouse && (template.indexOf("object/building/player/player_house_") == 0)) { // allow lot limit to be exceeded } else { sendSystemMessageProse(player, prose.getPackage(new string_id (STF_FILE, "not_enough_lots"), lots_needed)); // This structure requires %DI lots. return false; } } } else if (isFactionPerkBase(template)) { if ( hasObjVar(player,"factionBaseCount" )) { int factionBaseCount = getIntObjVar(player,"factionBaseCount"); if ( factionBaseCount > MAX_BASE_COUNT-1 ) { string_id strSpam = new string_id("faction_perk", "not_enough_base_units"); sendSystemMessage(player, strSpam); getClusterWideData("gcw_player_base", "base_cwdata_manager*", true, player); return false; } } } // If the template has no skill mod, then it doesn't require a skill mod to own. string skill_mod = dataTableGetString( PLAYER_STRUCTURE_DATATABLE, idx, DATATABLE_COL_SKILL_MOD ); if ( skill_mod.length() > 0 ) { int skill_mod_value = dataTableGetInt( PLAYER_STRUCTURE_DATATABLE, idx, DATATABLE_COL_SKILL_MOD_VALUE ); int player_skill = getSkillStatMod( player, skill_mod ); if ( player_skill < skill_mod_value ) { string msg = dataTableGetString( PLAYER_STRUCTURE_DATATABLE, idx, DATATABLE_COL_SKILL_MOD_MESSAGE ); if ( (msg == null) || (msg == "") ) { sendSystemMessage(player, new string_id(STF_FILE, "no_skill")); // You do not have sufficient skill to place the structure. } else { string_id msgsid = new string_id( STF_FILE, msg ); sendSystemMessage( player, msgsid ); } return false; } } return true; } /*********************************************************************** * @brief Overload for canOwnStructure * * @param obj_id player player to own the structure * @param obj_id structure * * @return boolean ***********************************************************************/ boolean canOwnStructure(obj_id structure, obj_id player) { if (structure == null || structure == obj_id.NULL_ID) return false; string template = getTemplateName(structure); return canOwnStructure(template, player, false); } /*********************************************************************** * @brief * * @param string template * * @return string ***********************************************************************/ string getFootprintTemplate(string template) { if ( template == null || template.equals("") ) return null; string fp_template = dataTableGetString(PLAYER_STRUCTURE_DATATABLE, template, DATATABLE_COL_FOOTPRINT); LOG("LOG_CHANNEL","retrieved fp_template = " + fp_template); if ( fp_template == null || fp_template.equals("") ) return template; return fp_template; } /*********************************************************************** * @brief Determines if the player may place an object * within a given structure. * * @param obj_id structure * @param obj_id player player to own the structure * * @return boolean ***********************************************************************/ boolean canPlaceObject(obj_id structure, obj_id player) { if (structure == null || structure == obj_id.NULL_ID) return false; if (player == null || player == obj_id.NULL_ID) return false; if (!isAdmin(structure, player)) { //LOG("//LOG_CHANNEL", player + "-> You must be an admin to place an item here."); sendSystemMessage(player, new string_id(STF_FILE, "admin_only")); // You must be an admin to place an item here. return false; } return true; } /*********************************************************************** * @brief Determines if the player is in range to admin a structure * * @param obj_id structure * @param obj_id player player to own the structure * * @return boolean ***********************************************************************/ boolean isInAdminRange(obj_id structure, obj_id player) { if (structure == null || structure == obj_id.NULL_ID) return false; if (player == null || player == obj_id.NULL_ID) return false; // if the structure is contained by the player (house packup) // then it is always within range if (pclib.isContainedByPlayer(player, structure)) return true; location loc_structure = getLocation(structure); location loc_player = getLocation(player); obj_id building = getTopMostContainer(loc_player.cell); // If the player is in the building, he's always within range. if (building == structure) return true; float distance = loc_structure.distance(loc_player); if (distance < getInstallationRange(structure)) return true; else { //LOG("//LOG_CHANNEL", player + " ->You are too far away to do that."); sendSystemMessage(player, new string_id(STF_FILE, "too_far")); // You are too far away to do that. return false; } } float getInstallationRange( obj_id structure ) { if ( isCivic( structure ) ) return CIVIC_INSTALLATION_RANGE; else return INSTALLATION_RANGE; } /*********************************************************************** * @brief Gets the template of the structure a deed/temporary * structure creates * * @param obj_id deed a deed or structure with deed info * * @return string -1 if the object has no deed info ***********************************************************************/ string getDeedTemplate(obj_id deed) { if (!hasObjVar(deed, VAR_DEED_TEMPLATE)) { if ( hasObjVar(deed, VAR_DEED_TEMPLATE_CRC) ) return getObjectTemplateName(getDeedTemplateCrc(deed)); return null; } return getStringObjVar(deed, VAR_DEED_TEMPLATE); } /*********************************************************************** * @brief Gets the template of the structure a deed/temporary * structure creates * * @param obj_id deed a deed or structure with deed info * * @return string -1 if the object has no deed info ***********************************************************************/ int getDeedTemplateCrc(obj_id deed) { return getIntObjVar(deed, VAR_DEED_TEMPLATE_CRC); } /*********************************************************************** * @brief Gets the template of the structure a deed/temporary * structure creates * * @param obj_id deed a deed or structure with deed info * * @return string -1 if the object has no deed info ***********************************************************************/ boolean setDeedTemplate(obj_id deed, string template) { if ( !isIdValid(deed) || template == null || template.equals("") ) return false; removeObjVar(deed, VAR_DEED_TEMPLATE); return setObjVar(deed, VAR_DEED_TEMPLATE_CRC, getObjectTemplateCrc(template)); } /*********************************************************************** * @brief Gets the build time of the structure a deed/temporary * structure creates * * @param obj_id deed a deed or structure with deed info * * @return int -1 if the object has no a deed info ***********************************************************************/ int getDeedBuildTime(obj_id deed) { if (!hasObjVar(deed, VAR_DEED_BUILDTIME)) return -1; return getIntObjVar(deed, VAR_DEED_BUILDTIME); } /*********************************************************************** * @brief Gets the area/planet where the structure must be built. * * @param obj_id deed a deed or structure with deed info * * @return string null on failure ***********************************************************************/ string getDeedScene(obj_id deed) { if (!hasObjVar(deed, VAR_DEED_SCENE)) return null; return getStringObjVar(deed, VAR_DEED_SCENE); } /*********************************************************************** * @brief Gets the max extraction rate value of a deed. * * @param obj_id deed a deed or structure with deed info * * @return int -1 if the object has no a deed info ***********************************************************************/ int getDeedMaxExtraction(obj_id deed) { if (!hasObjVar(deed, VAR_DEED_MAX_EXTRACTION)) return -1; return getIntObjVar(deed, VAR_DEED_MAX_EXTRACTION); } /*********************************************************************** * @brief Gets the max extraction rate value of a deed. * * @param obj_id deed a deed or structure with deed info * * @return int -1 if the object has no a deed info ***********************************************************************/ int getDeedCurrentExtraction(obj_id deed) { if (!hasObjVar(deed, VAR_DEED_CURRENT_EXTRACTION)) return -1; return getIntObjVar(deed, VAR_DEED_CURRENT_EXTRACTION); } /*********************************************************************** * @brief Gets the max hopper size value of a deed. * * @param obj_id deed a deed or structure with deed info * * @return int -1 if the object has no a deed info ***********************************************************************/ int getDeedMaxHopper(obj_id deed) { if (!hasObjVar(deed, VAR_DEED_MAX_HOPPER)) return -1; return getIntObjVar(deed, VAR_DEED_MAX_HOPPER); } /*********************************************************************** * @brief Returns a structure's owner name * * @param obj_id structure * * @return string owner ***********************************************************************/ string getStructureOwner(obj_id structure) { //obj_id owner = getOwner(structure); return getPlayerName(getOwner(structure)); } /*********************************************************************** * @brief Returns a structure's owner obj_id * * @param obj_id structure * * @return obj_id ownerObjId ***********************************************************************/ obj_id getStructureOwnerObjId(obj_id structure) { return getOwner(structure); } /*********************************************************************** * @brief Returns a structure's maintenance rate * * @param obj_id structure * * @return int ***********************************************************************/ int getMaintenanceRate(obj_id structure) { int civic = getIntObjVar( structure, VAR_CIVIC ); if ( civic == 1 ) return 0; else { // Get base maintenance. int maint = getBaseMaintenanceRate(structure); float merchant_mod = getMaintenanceMerchantMod(structure); if ( merchant_mod != 0f ) { maint = Math.round(maint * (1f+merchant_mod)); } float factory_mod = getMaintenanceFactoryMod(structure); if ( factory_mod != 0f ) { maint -= Math.round(maint * (factory_mod / 100.0f)); } float harvester_mod = getMaintenanceHarvesterMod(structure); if ( harvester_mod != 0f ) { maint -= Math.round(maint * (harvester_mod / 100.0f)); } // Add in property tax. int tax = getMaintenancePropertyTax(structure); if ( tax > 0 ) maint += tax; return maint; } } int getBaseMaintenanceRate(obj_id structure) { int idx = getStructureTableIndex( getTemplateName( structure ) ); return dataTableGetInt( PLAYER_STRUCTURE_DATATABLE, idx, DATATABLE_COL_MAINT_RATE ); } int getRedeedCost(obj_id structure) { int idx = getStructureTableIndex( getTemplateName( structure ) ); return dataTableGetInt( PLAYER_STRUCTURE_DATATABLE, idx, DATATABLE_COL_REDEED_COST ); } float getMaintenanceMerchantMod(obj_id structure) { if ( !isIdValid(structure) ) return 0f; return getFloatObjVar(structure, VAR_MAINTENANCE_MOD_MERCHANT); } float getMaintenanceFactoryMod(obj_id structure) { if ( !isIdValid(structure) ) return 0f; return getFloatObjVar(structure, VAR_MAINTENANCE_MOD_FACTORY); } float getMaintenanceHarvesterMod(obj_id structure) { if ( !isIdValid(structure) ) return 0f; return getFloatObjVar(structure, VAR_MAINTENANCE_MOD_HARVESTER); } int getMaintenancePropertyTax(obj_id structure) { if ( !isIdValid(structure) ) return -1; int maint = getBaseMaintenanceRate( structure ); if ( maint > 0 ) return Math.round(maint * city.getPropertyTax(structure)/100.f); return 0; } /*********************************************************************** * @brief Returns a structure's maintenance pool * * @param obj_id structure * * @return int ***********************************************************************/ int getMaintenancePool(obj_id structure) { return getBankBalance(structure); } /*********************************************************************** * @brief Returns a structure's decay rate * * @param obj_id structure * * @return int ***********************************************************************/ int getDecayRate(obj_id structure) { return getIntObjVar(structure, VAR_DECAY_RATE); } /*********************************************************************** * @brief Returns a structure's condition * * @param obj_id structure * * @return int ***********************************************************************/ int getStructureCondition(obj_id structure) { //return getIntObjVar(structure, VAR_CONDITION); return getHitpoints(structure); } /*********************************************************************** * @brief Returns a structure's maximum condition * * @param obj_id structure * * @return int ***********************************************************************/ int getMaxCondition(obj_id structure) { //return getIntObjVar(structure, VAR_MAX_CONDITION); return getMaxHitpoints(structure); } /*********************************************************************** * @brief Gets the max extraction rate value of a strcture. * * @param obj_id structure * * @return int -1 if the object doesn't have the value ***********************************************************************/ int getMaxExtraction(obj_id structure) { if (!hasObjVar(structure, VAR_MAX_EXTRACTION)) return -1; return getIntObjVar(structure, VAR_MAX_EXTRACTION); } /*********************************************************************** * @brief Gets the max extraction rate value of a deed. * * @param obj_id structure * * @return int -1 if the object doesn't have the value ***********************************************************************/ int getCurrentExtraction(obj_id structure) { if (!hasObjVar(structure, VAR_CURRENT_EXTRACTION)) return -1; return getIntObjVar(structure, VAR_CURRENT_EXTRACTION); } /*********************************************************************** * @brief Gets the max hopper size value of a deed. * * @param obj_id structure * * @return int -1 if the object doesn't have the value ***********************************************************************/ int getMaxHopper(obj_id structure) { if (!hasObjVar(structure, VAR_MAX_HOPPER)) return -1; return getIntObjVar(structure, VAR_MAX_HOPPER); } /*********************************************************************** * @brief Returns a structure's version * * @param obj_id structure * * @return int version number ***********************************************************************/ int getStructureVersion(obj_id structure) { return getIntObjVar(structure, VAR_VERSION); } /*********************************************************************** * @brief Returns a player's residence * * @param obj_id player * * @return obj_id ***********************************************************************/ obj_id getResidence(obj_id player) { if (player == null || player == obj_id.NULL_ID) return null; return getHouseId( player ); } /*********************************************************************** * @brief Returns the number of player placed items within a structure * * @param obj_id player * * @return obj_id ***********************************************************************/ int getStructureNumItems(obj_id structure) { if (structure == null || structure == obj_id.NULL_ID) return -1; return getIntObjVar(structure, "itemLimit"); } /*********************************************************************** * @brief Returns a building's base objects * * @param obj_id player * * @return obj_id ***********************************************************************/ obj_id[] getStructureBaseObjects(obj_id structure) { if (structure == null || structure == obj_id.NULL_ID) return null; return getObjIdArrayObjVar(structure, VAR_BASE_OBJECT); } /*********************************************************************** * @brief Returns a structure's entry list, but removes any obj_ids * from the list. Those obj_id would be any NPCs added via a scripted * system rather than added manually by a player. Such as a Target Dummy. * * @param obj_id structure * * @return string[] entry list ***********************************************************************/ string[] getEntryList(obj_id structure) { if ( !isIdValid( structure ) ) return null; string[] fullEntryList = permissionsGetAllowed(structure); // We're going to block any entries in the list that are npc obj_ids // from being shown in the player's list. resizeable string[] filteredEntryList = new string[0]; for ( int i = 0; i < fullEntryList.length; i++ ) { string entryItemString = fullEntryList[i]; obj_id entryItemId = utils.stringToObjId(entryItemString); if ( isIdValid(entryItemId) ) { } else { if ( entryItemString.toLowerCase().indexOf("guild:") > -1 ) { int guild_id = findGuild(entryItemString.substring(6).toLowerCase().trim()); if (guild_id > 0) { utils.addElement(filteredEntryList, entryItemString); } else { // remove bad guild name from entry list } } else { utils.addElement(filteredEntryList, entryItemString); } } } string[] returnList = filteredEntryList; return returnList; } /*********************************************************************** * @brief Returns a structure's entry list. This is the complete list * without excluding any obj_id entries from the list. Intended for those in god mode. * * @param obj_id structure * * @return string[] entry list ***********************************************************************/ string[] getCompleteEntryList(obj_id structure) { if ( !isIdValid( structure ) ) return null; return permissionsGetAllowed(structure); } /*********************************************************************** * @brief Returns whether a name is on structure's ban list * * @param obj_id structure * @param string player_or_guild_name * * @return boolean true if the name was found on the list ***********************************************************************/ boolean isNameOnEntryList(obj_id structure, string player_or_guild_name) { string[] entry_list = getCompleteEntryList(structure); if (entry_list != null) { if ( isNameOnPermissionList( entry_list, player_or_guild_name ) ) { return true; } } return false; } /*********************************************************************** * @brief Returns a structure's ban list * * @param obj_id structure * * @return string[] ban list ***********************************************************************/ string[] getBanList(obj_id structure) { if ( !isIdValid( structure ) ) return null; return permissionsGetBanned(structure); } /*********************************************************************** * @brief Returns whether a name is on structure's ban list * * @param obj_id structure * @param string player_or_guild_name * * @return boolean true if the name was found on the list ***********************************************************************/ boolean isNameOnBanList(obj_id structure, string player_or_guild_name) { string[] ban_list = getBanList(structure); if (ban_list != null) { if ( isNameOnPermissionList( ban_list, player_or_guild_name ) ) { return true; } } return false; } /*********************************************************************** * @brief Returns a structure's admin list in the raw format * 1) All player names are object IDs represented as strings * 2) All guild names are guild IDs represented as strings * and prefixed by "guild:" * * @param obj_id structure * * @return string[] admin list ***********************************************************************/ string[] getAdminListRaw(obj_id structure) { if ( !isIdValid( structure ) ) return null; return getStringArrayObjVar(structure, VAR_ADMIN_LIST); } /*********************************************************************** * @brief Returns a structure's admin list as a list of names * * @param obj_id structure * * @return string[] admin list ***********************************************************************/ string[] getAdminListNames(obj_id structure) { return convertRawListToNames( getAdminListRaw(structure) ); } /*********************************************************************** * @brief Returns whether a name is on structure's admin list * * @param obj_id structure * @param string player_or_guild_name * * @return boolean true if the name was found on the list ***********************************************************************/ boolean isNameOnAdminList(obj_id structure, string player_or_guild_name) { string[] admin_list = getAdminListRaw(structure); if (admin_list != null) { if ( isNameOnRawList( admin_list, player_or_guild_name ) ) { return true; } } return false; } /*********************************************************************** * @brief Add a name to the admin list. * * @param obj_id structure * @param string the name of the player or guild to be added * * @return boolean true if the name was successfully added ***********************************************************************/ boolean adminListAddName(obj_id structure, string nameToAdd ) { if ( isIdValid( structure ) ) { resizeable string[] adminList = getResizeableStringArrayObjVar(structure, VAR_ADMIN_LIST); // If the objvar list does not exist, create a new list if ( adminList == null ) { adminList = new Vector(); } if ( addNameToRawList( adminList, nameToAdd ) ) { if ( adminList.length > 0 ) { setObjVar( structure, VAR_ADMIN_LIST, adminList ); return true; } } } return false; } /*********************************************************************** * @brief Remove a name from the admin list. * * @param obj_id structure * string the name of the player or guild to be removed * * @return boolean true if the name was successfully removed ***********************************************************************/ boolean adminListRemoveName(obj_id structure, string nameToRemove ) { if ( isIdValid( structure ) ) { resizeable string[] adminList = getResizeableStringArrayObjVar(structure, VAR_ADMIN_LIST); if ( removeNameFromRawList( adminList, nameToRemove ) ) { if ( adminList.length == 0 ) { removeObjVar( structure, VAR_ADMIN_LIST ); } else { setObjVar( structure, VAR_ADMIN_LIST, adminList ); } return true; } } return false; } /*********************************************************************** * @brief Returns a structure's vendor list * !!!Method deprecated!!! * * @param obj_id structure * * @return string[] vendor list ***********************************************************************/ string[] getVendorList(obj_id structure) { if ( !isIdValid( structure ) ) return null; //return getStringArrayObjVar(structure, VAR_VENDOR_LIST); string[] vendor_list = new string[0]; return vendor_list; } /*********************************************************************** * @brief Returns a structure's hopper list in the raw format * 1) All player names are object IDs represented as strings * 2) All guild names are guild IDs represented as strings * and prefixed by "guild:" * * @param obj_id structure * * @return string[] admin list ***********************************************************************/ string[] getHopperListRaw(obj_id structure) { if ( !isIdValid( structure ) ) return null; return getStringArrayObjVar(structure, VAR_HOPPER_LIST); } /*********************************************************************** * @brief Returns a structure's hopper list as a list of names * * @param obj_id structure * * @return string[] admin list ***********************************************************************/ string[] getHopperListNames(obj_id structure) { return convertRawListToNames( getHopperListRaw(structure) ); } /*********************************************************************** * @brief Returns whether a name is on structure's hopper list * * @param obj_id structure * @param string player_or_guild_name * * @return boolean true if the name was found on the list ***********************************************************************/ boolean isNameOnHopperList(obj_id structure, string player_or_guild_name) { string[] hopper_list = getHopperListRaw(structure); if (hopper_list != null) { if ( isNameOnRawList( hopper_list, player_or_guild_name ) ) { return true; } } return false; } /*********************************************************************** * @brief Add a name to the hopper list. * * @param obj_id structure * string the name of the player or guild to be added * * @return boolean true if the name was successfully added ***********************************************************************/ boolean hopperListAddName(obj_id structure, string nameToAdd ) { if ( isIdValid( structure ) ) { resizeable string[] hopperList = getResizeableStringArrayObjVar(structure, VAR_HOPPER_LIST); // If the objvar list does not exist, create a new list if ( hopperList == null ) { hopperList = new Vector(); } if ( addNameToRawList( hopperList, nameToAdd ) ) { if ( hopperList.length > 0 ) { setObjVar( structure, VAR_HOPPER_LIST, hopperList ); return true; } } } return false; } /*********************************************************************** * @brief Remove a name from the hopper list. * * @param obj_id structure * string the name of the player or guild to be removed * * @return boolean true if the name was successfully removed ***********************************************************************/ boolean hopperListRemoveName(obj_id structure, string nameToRemove ) { if ( isIdValid( structure ) ) { resizeable string[] hopperList = getResizeableStringArrayObjVar(structure, VAR_HOPPER_LIST); if ( removeNameFromRawList( hopperList, nameToRemove ) ) { if ( hopperList.length == 0 ) { removeObjVar( structure, VAR_HOPPER_LIST ); } else { setObjVar( structure, VAR_HOPPER_LIST, hopperList ); } return true; } } return false; } /*********************************************************************** * @brief Returns an object's parent structure or a structure * in the player's lookat or a structure that is near him * that he owns. * * @param obj_id object * * @return obj_id structure id ***********************************************************************/ obj_id getStructure(obj_id object) { location loc = getLocation(object); obj_id structure = getContainedBy(loc.cell); if ((structure == null)||(structure == obj_id.NULL_ID)) { // Check the owner. obj_id obj_owner = getOwner( object ); if ( isInstallation( obj_owner ) && isCivic ( obj_owner ) ) return obj_owner; //If structure is null, check to see if the player has an installation in his lookat if (isPlayer(object)) { structure = getLookAtTarget(object); // Make sure the structure is an installation if (!isInstallation(structure)) { obj_id target = structure; structure = obj_id.NULL_ID; // Get everything near the player and start looking for an installation obj_id[] items = getObjectsInRange(loc, INSTALLATION_RANGE); if (items == null) return null; for (int i = 0; i < items.length; i++) { // Look for an installation if (isInstallation(items[i])) { // See if the player is an admin. if (isAdmin(items[i], object)) { // NOTE: When destroying a player city garden, this point in the script will be reached. // If these gardens are placed very close to other civic structures that the player has // admin rights to, there is a chance that the script will destroy the wrong structure. // // We put this part in to see if the terminal that the player is using to destroy the // structure (which should be the object that the player has targetted) is one of the // structure's base objects. If the look-at target matches one of the base objects, then // we go ahead and return that structure as the correct one. // // If the player does not have a look at target, or the structure does not have any // base objects, then the script should function exactly as it did before. obj_id[] base_objects = getObjIdArrayObjVar(items[i], "player_structure.base_objects"); if(base_objects != null && base_objects.length > 0) { for(int j = 0; j < base_objects.length; j++) { if(base_objects[j] == target) { return items[i]; } } } // Found something! // Check to see if it is closest strucutre if ( (!isIdValid(structure)) || (getLocation(items[i]).distance(loc) < getLocation(structure).distance(loc)) ) structure = items[i]; } } } } } } return structure; } /*********************************************************************** * @brief Returns an array of object id's that are in the structure. * Returns an empty array if there are no objects. Returns * null on an error. * * @param obj_id structure * * @return obj_id[] ***********************************************************************/ obj_id[] getObjectsInBuilding(obj_id structure) { if (structure == null || structure == obj_id.NULL_ID) return null; if (!isBuilding(structure)) return null; obj_id[] cells = getCellIds(structure); resizeable obj_id[] objects = new obj_id[0]; if (cells != null) { for (int i = 0; i < cells.length; i++) { if ( isIdValid(cells[i]) ) { obj_id[] cell_contents = getContents(cells[i]); if (cell_contents.length > 0) objects = utils.concatArrays(objects, cell_contents); } } } return objects; } /*********************************************************************** * @brief Returns an array of player id's that are in the structure. * Returns an empty array if there are no objects. Returns * null on an error. * * @param obj_id structure * * @return obj_id[] ***********************************************************************/ obj_id[] getPlayersInBuilding(obj_id structure) { if (structure == null || structure == obj_id.NULL_ID) return null; if (!isBuilding(structure)) return null; resizeable obj_id[] players = new obj_id[0]; obj_id[] objects = getObjectsInBuilding(structure); if (objects != null && objects.length > 0) { for (int i = 0; i < objects.length; i++) { if (isIdValid(objects[i]) && isPlayer(objects[i])) players = utils.addElement(players, objects[i]); } } return players; } /*********************************************************************** * @brief Returns an array of player id's that are near the installation. * Returns an empty array if there are no objects. Returns * null on an error. * * @param obj_id structure * * @return obj_id[] ***********************************************************************/ obj_id[] getPlayersNearInstallation(obj_id structure) { if (structure == null || structure == obj_id.NULL_ID) return null; location loc = getLocation(structure); resizeable obj_id[] players = new obj_id[0]; obj_id[] items = getObjectsInRange(loc, getInstallationRange(structure)); if (items == null) return players; for (int i = 0; i < items.length; i++) { if (isPlayer(items[i])) players = utils.addElement(players, items[i]); } return players; } void confirmNoReclaimPlacement(obj_id deedOrScd, obj_id player, string template) { if ( utils.hasScriptVar(deedOrScd, "noreclaim.pid") ) { int oldpid = utils.getIntScriptVar(deedOrScd, "noreclaim.pid"); obj_id oldplayer = utils.getObjIdScriptVar(deedOrScd, "noreclaim.player"); utils.removeScriptVarTree(deedOrScd, "noreclaim"); if ( isIdValid(oldplayer) ) sui.closeSUI(oldplayer, oldpid); } string title = utils.packStringId(SID_SUI_CONFIRM_PLACEMENT_TITLE); string prompt = utils.packStringId(SID_SUI_CONFIRM_PLACEMENT_PROMPT); int pid = sui.msgbox(deedOrScd, player, prompt, sui.YES_NO, title, "handleNoReclaimConfirm"); if ( pid > - 1 ) { utils.setScriptVar(deedOrScd, "noreclaim.pid", pid); utils.setScriptVar(deedOrScd, "noreclaim.player", player); utils.setScriptVar(deedOrScd, "noreclaim.deedOrScd", deedOrScd); } } boolean tryQueueStructurePlacement(obj_id deedOrScd, obj_id player) { string template = player_structure.getDeedTemplate(deedOrScd); if(!player_structure.canReclaimDeed(template) ) { if(!player_structure.isFactionPerkBase(template)) { confirmNoReclaimPlacement(deedOrScd, player, template); return false; } } location loc = getLocation(player); float range = 200f; if(!player_structure.canPlaceGarage(loc, range, template)) { sendSystemMessage(player, SID_CANNOT_BUILD_GARAGE_TOO_CLOSE); return false; } if(!player_structure.canPlaceFactionPerkDeed(deedOrScd, player)) { return false; } queueCommand(player, ##"placeStructureMode", deedOrScd, "", COMMAND_PRIORITY_DEFAULT); return true; } boolean tryEnterPlacementMode(obj_id deedOrScd, obj_id player) { obj_id target = deedOrScd; if(!isIdValid(target)) { return false; } if (!isGameObjectTypeOf (getGameObjectType(target), GOT_deed) && !isGameObjectTypeOf (getGameObjectType(target), GOT_data_house_control_device)) { sendSystemMessage(player, new string_id("player_structure", "not_a_deed")); // This is not a deed. return false; } string template = player_structure.getDeedTemplate(target); if (template == null) { return false; } location here = getLocation(player); if(!player_structure.canPlaceStructure(player, template, here, target)) { return false; } // check the footprint template string fp_template = player_structure.getFootprintTemplate(template); if (!fp_template.equals(template)) { if ( !player_structure.canPlaceStructure(player, fp_template, here, null) ) { return false; } } enterClientStructurePlacementMode(player, target, fp_template); return true; } // Ensures the player should be able to packup the structure boolean canPackBuilding(obj_id player, obj_id structure) { return !utils.isFreeTrial(player) && !isCivic(structure) && !isHarvester(structure) && !isGenerator(structure) && isOwner(structure, player); } // // Packs the @structure into a structure control device and adds the control device to the @player's datapad // ::canPackBuilding should be called before this function is called as this function won't make any // permission checks // void packBuilding(obj_id player, obj_id structure) { utils.setScriptVar(player, "packup.structure", structure); if(utils.hasScriptVar(player, "packup.suiconfirm")) { sui.closeSUI(player, utils.getIntScriptVar(player, "packup.suiconfirm")); } string stringId = vendor_lib.isVendorPackUpEnabled() ? "confirm_packup" : "confirm_packup_no_vendors"; if ( isInstallation( structure ) ) { stringId += "_factory"; } if ( !isOwner(structure, player) ) { stringId += "_abandoned"; } utils.setScriptVar(player, "packup.suiconfirm", sui.msgbox(player, player, utils.packStringId(new string_id("sui", stringId)), sui.YES_NO, "msgConfirmHousePackup")); return; } // // Actually performs the packup // void finalizePackUp(obj_id player, obj_id structure) { blog("player_structure.finalizePackUp init."); const boolean isAbandoned = isAbandoned(structure); blog("player_structure.finalizePackUp isAbandoned: "+isAbandoned); obj_id structure_owner = getOwner(structure); if(structure_owner != player && isAbandoned) { CustomerServiceLog("housepackup", "Structure (" + structure + ") was abandoned and was not being packed by Owner (" + getPlayerName(structure_owner) + ") " + structure_owner + ". A player ( " + getPlayerName(player) + " is packing this structure. Sending job to the Abandoned Structure Pack Up function." ); finalizeAbandonedStructurePackUp(player, structure); return; } blog("player_structure.finalizePackUp PLAYER IS THE OWNER."); if(!structure_owner.isLoaded() || !structure_owner.isAuthoritative()) { //correct logging here CustomerServiceLog("housepackup", "Structure (" + structure + ") could not be packed by player/owner (" + getPlayerName(player) + ") OID (" +player+ ") The cause: Player/owner -" + " isLoaded = " + player.isLoaded() + " isAuthoritative = " + player.isAuthoritative() ); return; } CustomerServiceLog("housepackup", "Player/Owner " + getPlayerName(player) + " OID (" + player + ") is attempting to pack structure (" + structure + ",abandoned=" + isAbandoned + ") Structure is loaded and is Authoritative." ); if (!structure.isLoaded() || !structure.isAuthoritative()) { blog("player_structure.finalizePackUp structure NOT LOADED or NOT AUTHORITATIVE."); CustomerServiceLog("housepackup", "Structure (" + structure + ") could not be packed by player/owner (" + getPlayerName(player) + ") OID (" + player + ") because structure -" + " isLoaded = " + structure.isLoaded() + " isAuthoritative = " + structure.isAuthoritative() ); return; } blog("player_structure.finalizePackUp getting datapad"); // get data pad obj_id datapad = utils.getPlayerDatapad(player); if(!isIdValid(datapad)) { blog("player_structure.finalizePackUp datapad not valid."); CustomerServiceLog("housepackup", "Structure (" + structure + ") could not be packed by player/owner (" + getPlayerName(player) + ") - datapad was not valid" ); return; } blog("player_structure.finalizePackUp creating SCD"); // Create a new structure control device in the datapad obj_id scd = createObjectOverloaded("object/intangible/house/generic_house_control_device.iff", datapad); if(!isIdValid(scd)) { CustomerServiceLog("housepackup", "Structure (" + structure + ") could not be packed by player/owner (" + getPlayerName(player) + ") - scd was not valid" ); return; } attachScript(scd, "structure.house_control_device"); //If the structure is a factory, turn it off if(player_structure.isFactory(structure) && isHarvesterActive(structure)) { CustomerServiceLog("housepackup", "Structure (" + structure + ") was a factory that was active. Turning off factory for player/owner (" + getPlayerName(player) + ") OID (" + player + ")" ); deactivate(structure); } // eject all players from house obj_id[] players = getPlayersInBuilding(structure); if (players != null) { blog("player_structure.finalizePackUp Players are in the building that is about to be packed."); for (int i = 0; i < players.length; i++) { expelFromBuilding(players[i]); } } // Destroy vendors inside this structure. string[] cells = getCellNames(structure); if( cells != null) { for(int i = 0; i < cells.length; i++) { obj_id cellid = getCellId(structure, cells[i]); obj_id contents[] = getContents(cellid); if(contents != null) { for(int j=0; j= player_structure.NUM_NEEDED_PACKUP_FIRST_BADGE) badge.grantBadge (player, "house_packup_badge"); return true; } if(!badge.hasBadge(player, "house_packup_badge_master")) { if(housePackUpTrackingArray[1] >= player_structure.NUM_NEEDED_PACKUP_SECOND_BADGE) badge.grantBadge (player, "house_packup_badge_master"); return true; } if(!badge.hasBadge(player, "house_packup_badge_mogul")) { if(housePackUpTrackingArray[1] >= player_structure.NUM_NEEDED_PACKUP_THIRD_BADGE) badge.grantBadge (player, "house_packup_badge_mogul"); return true; } //Has all the badges return true; } boolean hasBeenDeclaredResidence(obj_id structure) { return hasObjVar(structure, VAR_RESIDENCE_BUILDING); } obj_id getResidentPlayer(obj_id structure) { if(!hasBeenDeclaredResidence(structure)) return null; obj_id resident = getObjIdObjVar(structure, VAR_RESIDENCE_BUILDING); return resident; } boolean replacePackedStructure(obj_id scd, obj_id owner, location loc, int rot, float placementHeight) { obj_id[] contents = getContents(scd); if(contents.length != 1) { // danger! danger! trace.log("housepackup", "%TU attempted to unpack a house, but the SCD did not contain one.", owner, trace.TL_CS_LOG | trace.TL_ERROR_LOG); return false; } obj_id house = contents[0]; if (isIdValid(house)) { string houseTemplateName = getTemplateName(house); if ((houseTemplateName != null) && player_structure.isBuildingName(houseTemplateName)) loc.y = placementHeight; } if(!setLocation(house, loc)) { return false; } // if the structure is a "lot over limit structure", set objvar to indicate it has been moved to the world if (isIdValid(owner) && exists(owner)) { obj_id lotOverlimitStructure = getObjIdObjVar(owner, "lotOverlimit.structure_id"); if (isIdValid(lotOverlimitStructure) && (lotOverlimitStructure == house)) { setObjVar(owner, "lotOverlimit.structure_location", localize(new string_id("planet_n", loc.area)) + " (" + (int)loc.x + ", " + (int)loc.z + ")"); } } // remove the fix_scene_ids objvar. When the house is unpacked, // we want it to validate the scene ids for contained objects // the next time that they are loaded. if (hasObjVar(house, "packed_house.fix_contained_scene_ids")) { removeObjVar(house, "packed_house.fix_contained_scene_ids"); } // Remove abandoned flag if ( player_structure.isAbandoned( house ) ) { removeObjVar( house, "player_structure.abandoned" ); if ( hasObjVar( house, "player_structure.name.original" ) ) { obj_var originalName = getObjVar( house, "player_structure.name.original" ); setName( house, originalName.getStringData() ); } } if(player_structure.isCityAbandoned(house)) { removeObjVar(house, "player_structure.city_abandoned"); if(hasObjVar(house, "player_structure.name.original")) { obj_var originalName = getObjVar(house, "player_structure.name.original"); setName(house, originalName.getStringData()); } } float rot_float = (float)(90 * rot); setYaw(house, rot_float); persistObject(house); createStructureSign(house, rot_float); addStructureWaypoint(owner, loc, getStructureName(house), house); //Add the Structure to the City city.addStructureToCity(house); trace.log("housepackup", "%TU unpacked their house (" + house + ") from structure control device ( " + scd + ") to new location " + loc.toString(), owner, trace.TL_CS_LOG); obj_id[] houseContents = trial.getAllObjectsInDungeon(house); for(int i = 0, j = houseContents.length; i < j; i++) { messageTo(houseContents[i], "OnUnpack", null, 1.0f, false); } return true; } boolean hasVendors(obj_id structure) { // Check for vendors inside this structure. string[] cells = getCellNames(structure); if( cells != null) { for(int i = 0; i < cells.length; i++) { obj_id cellid = getCellId(structure, cells[i]); obj_id contents[] = getContents(cellid); if(contents != null) { for(int j=0; j 0 || templateName.indexOf("player_mustafar_house_lg") > 0 || templateName.indexOf("player_house_mustafar_lg") > 0 ) { return true; } else return false; } } /*********************************************************************** * @brief Checks to see if the object is a civic structure * * @param obj_id object * * @return boolean ***********************************************************************/ boolean isCivic( obj_id object ) { if ( !isIdValid(object) ) return false; if ( exists(object) && getIntObjVar(object, VAR_CIVIC) == 1 ) return true; else return false; } /*********************************************************************** * @brief Checks to see if the object is an abandoned structure * * @param obj_id object * * @return boolean ***********************************************************************/ boolean isAbandoned( obj_id object ) { if ( !isIdValid(object) ) return false; return ( getIntObjVar(object, VAR_ABANDONED) == PLAYER_STRUCTURE_ABANDONED ); } void setAbandoned(obj_id object) { setObjVar(object, VAR_ABANDONED, PLAYER_STRUCTURE_ABANDONED); } /*********************************************************************** * @brief Checks to see if the object is a pre-abandoned structure. * * @param obj_id object * * @return boolean ***********************************************************************/ boolean isPreAbandoned( obj_id object ) { if ( !isIdValid(object) ) return false; return ( getIntObjVar(object, VAR_ABANDONED) == PLAYER_STRUCTURE_PRE_ABANDONED ); } void setPreAbandoned(obj_id object) { setObjVar(object, VAR_ABANDONED, PLAYER_STRUCTURE_PRE_ABANDONED); } void setStructureAsNotAbandoned(obj_id object) { removeObjVar(object, VAR_ABANDONED); } /*********************************************************************** ************************************************************************ ************************************************************************ ****City Demolition Crew - Allowing Packup If Structure is in a City**** ************************************************************************ ************************************************************************ ***********************************************************************/ boolean isCityAbandoned(obj_id object) { if(!isIdValid(object)) return false; if(hasObjVar(object, VAR_CITY_ABANDONED)) { return true; } return false; } void setCityAbandoned(obj_id object) { if(!isIdValid(object)) return; setObjVar(object, VAR_CITY_ABANDONED, PLAYER_STRUCTURE_CITY_ABANDONED); } void removeCityAbandoned(obj_id object) { if(!isIdValid(object)) return; //removes the abandoned text(Zoning Violation) from the house sign since it's no longer abandoned. removeCityAbandonedTagFromHouse(object); if(hasObjVar(object, VAR_CITY_ABANDONED)) removeObjVar(object, VAR_CITY_ABANDONED); } boolean isCityPackupAuthoritative(obj_id player, obj_id structure) { if (!player.isLoaded() || !player.isAuthoritative()) return false; if (!structure.isLoaded() || !structure.isAuthoritative()) return false; return true; } //If someone accesses the House Sign and 'City Abandoned' is no longer valid - //This will remove the 'Zoning Violation' tag from the house immediately, instead //of waiting for the server to bounce. void removeCityAbandonedTagFromHouse(obj_id structure) { LOG("sissynoid", "Removing Zoning Violation Text."); if(!isIdValid(structure)) return; //Factory Names Go This Way if(player_structure.isFactory(structure)) { //updateCityAbandonedFactoryName(structure); if(hasObjVar(structure, "player_structure.name.original")) { string signOriginal = getStringObjVar(structure, "player_structure.name.original"); setName(structure, signOriginal); } return; } else { if(!hasObjVar(structure, "player_structure.sign.id")) { LOG("sissynoid", "Structure("+ structure +") does not have a House Sign ObjVar"); return; } obj_id signId = getObjIdObjVar(structure, "player_structure.sign.id"); string signText = getName(signId); int indexOfAbandonedText = signText.indexOf(player_structure.CITY_ABANDONED_TEXT); if(indexOfAbandonedText > -1) { //we are no longer abandoned signText = signText.substring(0, indexOfAbandonedText); setName(signId, signText); LOG("sissynoid", "Removed Zoning Violation - New Text: " + signText); } } } //This adds the 'Zoning Violation' to Factories void updateCityAbandonedFactoryName(obj_id factory) { if (player_structure.isFactory(factory)) { LOG("sissynoid", "Factory - Updating Sign"); string assignedName = getAssignedName(factory); if (!hasObjVar(factory, "player_structure.name.original")) setObjVar(factory, "player_structure.name.original", assignedName == null ? "" : assignedName); else { // if we have an original name and our current name has abandoned text if (assignedName != null && assignedName.indexOf(player_structure.CITY_ABANDONED_TEXT) != -1) // restore the original name assignedName = getStringObjVar(factory, "player_structure.name.original"); else // otherwise, the player renamed it and removed abandoned text so update the original name setObjVar(factory, "player_structure.name.original", assignedName == null ? "" : assignedName); } if (assignedName == null || assignedName.length () == 0) { string templateName = getTemplateName(factory); if (templateName.equals("object/installation/manufacture/food_factory.iff")) assignedName = "Food and Chemical Factory"; else if (templateName.equals("object/installation/manufacture/clothing_factory.iff")) assignedName = "Wearables Factory"; else if (templateName.equals("object/installation/manufacture/weapon_factory.iff")) assignedName = "Equipment Factory"; else if (templateName.equals("object/installation/manufacture/structure_factory.iff")) assignedName = "Structure Factory"; else assignedName = "Factory"; } setName(factory, assignedName + player_structure.CITY_ABANDONED_TEXT); } } /*********************************************************************** *********************END CITY DEMOLITION CREW*************************** ***********************************************************************/ boolean isCommercial( obj_id object ) { if ( !isIdValid(object) ) return false; // Commercial structures are not civic, but have a rank req. if ( !isCivic(object) && getStructureCityRank(object)>0 ) return true; return false; } int getStructureCityRank( obj_id object ) { if ( !isIdValid(object) ) return 0; return getIntObjVar( object, VAR_CITY_RANK ); } int getStructureCityCost( obj_id object ) { if ( !isIdValid(object) ) return 0; return getIntObjVar( object, VAR_CITY_COST ); } boolean isCivicTemplate( string template ) { string[] structures = dataTableGetStringColumn( PLAYER_STRUCTURE_DATATABLE, "STRUCTURE" ); for ( int i=0; i 0) setObjVar(structure, VAR_MAINTENANCE_MOD, mm); return true; } /*********************************************************************** * @brief overload for applyManagementMods * * @param obj_id structure * @param obj_id player player whose mods to use * * @return boolean ***********************************************************************/ boolean applyManagementMods(obj_id structure, obj_id player) { if (player == null || player == obj_id.NULL_ID) return false; dictionary mods = new dictionary(); int maintenance_mod = getSkillStatMod(player, "structure_maintenance_mod"); if (maintenance_mod > 0) mods.put("maintenance_mod", maintenance_mod); int factory_mod = getSkillStatMod(player, "factory_efficiency"); if(isFactory(structure)) maintenance_mod += (int)getSkillStatisticModifier(player, "expertise_factory_maintenance_decrease"); if(isHarvester(structure)) maintenance_mod += (int)getSkillStatisticModifier(player, "expertise_harvester_maintenance_decrease"); if (factory_mod > 0) mods.put("factory_mod", maintenance_mod); return applyManagementMods(structure, mods); } /*********************************************************************** * @brief overload for applyManagementMods * * @param obj_id structure * @param int mods total management mod to apply * * @return boolean ***********************************************************************/ boolean applyManagementMods(obj_id structure, int mods) { if (!isIdValid(structure)) return false; if (mods < 1) return false; dictionary mods_dict = new dictionary(); mods_dict.put("maintenance_mod", mods); return applyManagementMods(structure, mods_dict); } /*********************************************************************** * @brief removes all management mods from the structure * * @param obj_id structure * * @return boolean ***********************************************************************/ boolean removeManagementMods(obj_id structure) { /* if (structure == null || structure == obj_id.NULL_ID) return false; // remove maintenance modifier int idx = getStructureTableIndex(getTemplateName(structure)); int base_maint_rate = dataTableGetInt(PLAYER_STRUCTURE_DATATABLE, idx, DATATABLE_COL_MAINT_RATE); setObjVar(structure, VAR_MAINTENANCE_RATE, base_maint_rate); // remove the storage of the owner's management mod. if (hasObjVar(structure, VAR_MAINTENANCE_MOD)) removeObjVar(structure, VAR_MAINTENANCE_MOD); */ return true; } /*********************************************************************** * @brief Determine if a guild ID is on a raw list (i.e. an admin or hopper list) * * @param string[] nameList the raw list * @param int guildId the guild ID we are looking for * * @return boolean true if guild ID is on the list ***********************************************************************/ boolean isGuildIdOnRawList(string[] nameList, int guildId) { if ((nameList != null) && (guildId != 0)) { // Convert the guild ID to a string string guildIdAsString = "guild:" + guildId; // Try to find the string return ( utils.getElementPositionInArray( nameList, guildIdAsString ) != -1 ); } return false; } /*********************************************************************** * @brief Determine if a guild name is on a raw list (i.e. an admin or hopper list) * * @param string[] nameList the raw list * @param string guildNameToFind the guild name (with no "guild:" prefix) * * @return boolean true if the guild name is on the list ***********************************************************************/ boolean isGuildNameOnRawList(string[] nameList, string guildNameToFind) { if ( guildNameToFind != null ) { return isGuildIdOnRawList( nameList, findGuild( guildNameToFind.trim().toLowerCase() ) ); } return false; } /*********************************************************************** * @brief Determine if a player object ID is on a raw list (i.e. an admin or hopper list) * * @param string[] nameList the raw list * @param int playerObjId the player object ID we are looking for * * @return boolean true if player object ID is on the list ***********************************************************************/ boolean isPlayerObjIdOnRawList(string[] nameList, obj_id playerObjId) { if ((nameList != null) && isIdValid(playerObjId)) { // Convert the object ID to a string string playerObjIdAsString = playerObjId.toString(); // Try to find the string return ( utils.getElementPositionInArray( nameList, playerObjIdAsString ) != -1 ); } return false; } /*********************************************************************** * @brief Determine if a player name is on a raw list (i.e. an admin or hopper list) * * @param string[] nameList the raw list * @param string playerNameToFind the player name * * @return boolean true if the player name is on the list ***********************************************************************/ boolean isPlayerNameOnRawList(string[] nameList, string playerNameToFind) { if ( playerNameToFind != null ) { return isPlayerObjIdOnRawList( nameList, getPlayerIdFromFirstName( playerNameToFind.trim().toLowerCase() ) ); } return false; } /*********************************************************************** * @brief Determine if the name is on a raw list (i.e. an admin or hopper list) * * @param string[] nameList the raw list * @param string nameToFind the player or guild name (guild names must be prefixed with "guild:") * * @return boolean true if the name is on the list ***********************************************************************/ boolean isNameOnRawList(string[] nameList, string nameToFind) { if ( nameToFind != null ) { // Determine whether it is a guild name or player name by looking at the prefix if ( nameToFind.toLowerCase().indexOf("guild:") > -1 ) { // Extract the guild name return isGuildNameOnRawList( nameList, nameToFind.substring(6).toLowerCase().trim() ); } else { // Look for the player name return isPlayerNameOnRawList( nameList, nameToFind ); } } return false; } /*********************************************************************** * @brief Determine if the name is on an "entry" or "ban" list * * @param string[] nameList the entry or ban list * @param string nameToFind the player or guild name (guild names must be prefixed with "guild:") * * @return boolean true if the name is on the list ***********************************************************************/ boolean isNameOnPermissionList(string[] permissionList, string nameToFind) { if ( (permissionList != null) && (nameToFind != null) ) { // Determine whether it is a guild name or player name by looking at the prefix if ( nameToFind.toLowerCase().indexOf("guild:") > -1 ) { // Extract the guild name string guildName = nameToFind.substring(6).toLowerCase().trim(); // Try to convert the guild name to a guild ID int guildId = findGuild( guildName ); // Now loop through the list and try to find a match for ( int i = 0; i < permissionList.length; i++ ) { // See if the entry is a guild entry if ( permissionList[i].toLowerCase().indexOf("guild:") > -1 ) { string permissionListGuildName = permissionList[i].substring(6).toLowerCase().trim(); // If the name we are trying to find couldn't be matched to a guild, // do a straight string comparison if ( guildId == 0 ) { if ( guildName == permissionListGuildName ) { return true; } } else { // Try to convert the guild name on the list to a guild ID // so that guild abbreviations will match full guild names // and vice versa int permissionListGuildId = findGuild( permissionListGuildName ); if ( guildId== permissionListGuildId ) { return true; } } } } } else { string playerName = nameToFind.toLowerCase().trim(); // Loop through the list and try to find a match for ( int i = 0; i < permissionList.length; i++ ) { if ( permissionList[i].toLowerCase().trim().equals( playerName ) ) { return true; } } } } return false; } /*********************************************************************** * @brief Add the guild ID to a raw list (i.e. an admin or hopper list) * * @param string[] nameList the raw list * @param int guildId the guild ID we are adding * * @return boolean true if guild ID was added to the list ***********************************************************************/ boolean addGuildIdToRawList(resizeable string[] nameList, int guildId) { if (guildId != 0) { // We do not have a list to update if ( nameList == null ) return false; // Convert the guild ID to a string string guildIdAsString = "guild:" + guildId; // Add the guild ID if ( utils.getElementPositionInArray( nameList, guildIdAsString ) == -1 ) { nameList.add( guildIdAsString ); return true; } return true; } return false; } /*********************************************************************** * @brief Add a guild name to a raw list (i.e. an admin or hopper list) * * @param string[] nameList the raw list * @param string guildNameToAdd the guild name to add (with no "guild:" prefix) * * @return boolean true if the guild name was added to the list ***********************************************************************/ boolean addGuildNameToRawList(resizeable string[] nameList, string guildNameToAdd) { if ( guildNameToAdd != null ) { return addGuildIdToRawList( nameList, findGuild( guildNameToAdd.trim().toLowerCase() ) ); } return false; } /*********************************************************************** * @brief Add a player object ID to a raw list (i.e. an admin or hopper list) * * @param string[] nameList the raw list * @param int playerObjId the player object ID we are adding * * @return boolean true if player object ID was added to the list ***********************************************************************/ boolean addPlayerObjIdToRawList(resizeable string[] nameList, obj_id playerObjId) { if ( isIdValid(playerObjId) ) { // We do not have a list to update if ( nameList == null ) return false; // Convert the object ID to a string string playerObjIdAsString = playerObjId.toString(); // Add the object ID if ( utils.getElementPositionInArray( nameList, playerObjIdAsString ) == -1 ) { nameList.add( playerObjIdAsString ); return true; } } return false; } /*********************************************************************** * @brief Add a player name to a raw list (i.e. an admin or hopper list) * * @param string[] nameList the raw list * @param string playerNameToAdd the player name * * @return boolean true if the player name was added to the list ***********************************************************************/ boolean addPlayerNameToRawList(resizeable string[] nameList, string playerNameToAdd) { if ( playerNameToAdd != null ) { return addPlayerObjIdToRawList( nameList, getPlayerIdFromFirstName( playerNameToAdd.trim().toLowerCase() ) ); } return false; } /*********************************************************************** * @brief Add the name to a raw list (i.e. an admin or hopper list) * * @param string[] nameList the raw list * @param string nameToAdd the player or guild name (guild names must be prefixed with "guild:") * * @return boolean true if the name was added to the list ***********************************************************************/ boolean addNameToRawList(resizeable string[] nameList, string nameToAdd) { if ( nameToAdd != null ) { // Determine whether it is a guild name or player name by looking at the prefix if ( nameToAdd.toLowerCase().indexOf("guild:") > -1 ) { // Extract the guild name and then try to add it return addGuildNameToRawList( nameList, nameToAdd.substring(6).toLowerCase().trim() ); } else { // Try to add the player name return addPlayerNameToRawList( nameList, nameToAdd ); } } return false; } /*********************************************************************** * @brief Remove the guild ID from a raw list (i.e. an admin or hopper list) * * @param string[] nameList the raw list * @param int guildId the guild ID we are removing * * @return boolean true if guild ID was removed from the list ***********************************************************************/ boolean removeGuildIdFromRawList(resizeable string[] nameList, int guildId) { if ((nameList != null) && (guildId != 0)) { // Convert the guild ID to a string string guildIdAsString = "guild:" + guildId; // Try to find the string int deleteIndex = utils.getElementPositionInArray( nameList, guildIdAsString ); if ( deleteIndex != -1 ) { // Remove the guild ID nameList.remove( deleteIndex ); return true; } } return false; } /*********************************************************************** * @brief Remove a guild name from a raw list (i.e. an admin or hopper list) * * @param string[] nameList the raw list * @param string guildNameToRemove the guild name to removed (with no "guild:" prefix) * * @return boolean true if the guild name was removed from the list ***********************************************************************/ boolean removeGuildNameFromRawList(resizeable string[] nameList, string guildNameToRemove) { if ( guildNameToRemove != null ) { return removeGuildIdFromRawList( nameList, findGuild( guildNameToRemove.trim().toLowerCase() ) ); } return false; } /*********************************************************************** * @brief Remove a player object ID from a raw list (i.e. an admin or hopper list) * * @param string[] nameList the raw list * @param int playerObjId the player object ID we are removing * * @return boolean true if player object ID was removed from the list ***********************************************************************/ boolean removePlayerObjIdFromRawList(resizeable string[] nameList, obj_id playerObjId) { if ((nameList != null) && isIdValid(playerObjId)) { // Convert the object ID to a string string playerObjIdAsString = playerObjId.toString(); // Try to find the string int deleteIndex = utils.getElementPositionInArray( nameList, playerObjIdAsString ); if ( deleteIndex != -1 ) { // Remove the guild ID nameList.remove( deleteIndex ); return true; } } return false; } /*********************************************************************** * @brief Remove a player name to a raw list (i.e. an admin or hopper list) * * @param string[] nameList the raw list * @param string playerNameToRemove the player name * * @return boolean true if the player name was removed from from the list ***********************************************************************/ boolean removePlayerNameFromRawList(resizeable string[] nameList, string playerNameToRemove) { if ( playerNameToRemove != null ) { return removePlayerObjIdFromRawList( nameList, getPlayerIdFromFirstName( playerNameToRemove.trim().toLowerCase() ) ); } return false; } /*********************************************************************** * @brief Remove the name from a raw list (i.e. an admin or hopper list) * * @param string[] nameList the raw list * @param string nameToRemove the player or guild name (guild names must be prefixed with "guild:") * * @return boolean true if the name was removed from the list ***********************************************************************/ boolean removeNameFromRawList(resizeable string[] nameList, string nameToRemove) { if ( nameToRemove != null ) { // Determine whether it is a guild name or player name by looking at the prefix if ( nameToRemove.toLowerCase().indexOf("guild:") > -1 ) { // Extract the guild name and then try to remove it return removeGuildNameFromRawList( nameList, nameToRemove.substring(6).toLowerCase().trim() ); } else { // Try to remove the player name return removePlayerNameFromRawList( nameList, nameToRemove ); } } return false; } /*********************************************************************** * @brief Convert a raw list (i.e. an admin or hopper list) to a list of names * * * @param string[] nameList the raw list * @param string nameToRemove the player or guild name (guild names must be prefixed with "guild:") * * @return boolean true if the name was removed from the list ***********************************************************************/ string[] convertRawListToNames(string[] nameListToConvert) { resizeable string[] converted_list = new string[0]; if (nameListToConvert != null) { for (int i = 0; i < nameListToConvert.length; i++) { // Maybe we have a guild name if ( nameListToConvert[i].toLowerCase().indexOf("guild:") > -1 ) { string guildIdString = nameListToConvert[i].substring(6).toLowerCase().trim(); // Try to convert the string to a proper ID int guildId = utils.stringToInt( guildIdString ); if ( guildId > 0 ) { string guildAbbrev = guildGetAbbrev( guildId ); if ( (guildAbbrev != null) && (guildAbbrev != "") ) { converted_list.add( "Guild:" + guildAbbrev ); } } } else { // The raw admin list entry must be an object ID represented as a string obj_id player = utils.stringToObjId(nameListToConvert[i]); if ( isIdValid(player) ) { // Get the full name so that capitalization is correct string player_full_name = getPlayerFullName( player ); if ( player_full_name != null ) { java.util.StringTokenizer st = new java.util.StringTokenizer(player_full_name); if (st.hasMoreTokens()) { string player_first_name = st.nextToken(); converted_list.add( player_first_name ); } } } } } } return converted_list; } /*********************************************************************** * @brief Base function for adding and removing players/guilds from a * permission list. * * @param obj_id structure the structure whose list to modify * @param string player_or_guild_name player/guild name to add/remove (guild names must be prefixed with "guild:") * @param obj_id admin the admin making the change * @param string objvar the list's objvar name * @param boolean verbose whether or not to show messaging to admin * * @return boolean true if successful ***********************************************************************/ boolean modifyList(obj_id structure, string player_or_guild_name, obj_id admin, string objvar, boolean verbose) { //LOG("//LOG_CHANNEL", "structure ->" + structure + " player ->" + player + " player_name ->" + getPlayerName(player) + " admin ->" + admin + " objvar ->" + objvar); if ( !isIdValid(structure) ) return false; if ( !isIdValid(admin) && verbose ) return false; if ( isIdValid(admin) ) { if ( !isAdmin(structure, admin) ) { //LOG("//LOG_CHANNEL", "You must be an admin to modify permissions lists."); if ( verbose ) { sendSystemMessage(admin, new string_id(STF_FILE, "must_be_admin")); // You must be an admin to modify permissions lists. } return false; } } if ( player_or_guild_name == null ) return false; // Determine whether the player or guild is on the list in question boolean is_name_on_list = false; if ( objvar.equals(VAR_ENTER_LIST) ) { is_name_on_list = isNameOnEntryList(structure, player_or_guild_name); } else if ( objvar.equals(VAR_BAN_LIST) ) { is_name_on_list = isNameOnBanList(structure, player_or_guild_name); } else if ( objvar.equals(VAR_ADMIN_LIST) ) { is_name_on_list = isNameOnAdminList(structure, player_or_guild_name); } else if ( objvar.equals(VAR_HOPPER_LIST) ) { is_name_on_list = isNameOnHopperList(structure, player_or_guild_name); } else { return false; } // If the name isn't on the list, we will add them if ( !is_name_on_list ) { //LOG("//LOG_CHANNEL", "player_name ->" + player_or_guild_name + " admin ->" + admin); // The name is not on the list, so see if there is room to add a new name { string[] listOfNames = new string[0]; if ( objvar.equals(VAR_ENTER_LIST) ) { listOfNames = getEntryList(structure); } else if ( objvar.equals(VAR_BAN_LIST) ) { listOfNames = getBanList(structure); } else if ( objvar.equals(VAR_ADMIN_LIST) ) { listOfNames = getAdminListRaw(structure); } else if ( objvar.equals(VAR_HOPPER_LIST) ) { listOfNames = getHopperListRaw(structure); } if ( listOfNames != null ) { if (listOfNames.length >= MAX_LIST_SIZE) { if ( verbose && isIdValid(admin) ) { //LOG("//LOG_CHANNEL", "You have too many entries on that list. You must remove some before adding more."); sendSystemMessage(admin, new string_id(STF_FILE, "too_many_entries")); // You have too many entries on that list. You must remove some before adding more. } return false; } } } // Check that the name is a valid player name or guild name if (player_or_guild_name.toLowerCase().indexOf("guild:") > -1) { // For now, don't allow guild names on admin lists or hopper lists. if ( objvar.equals(VAR_ADMIN_LIST) || objvar.equals(VAR_HOPPER_LIST) ) { // DANGER WILL ROBINSON!!!! // // If guild names are ever allowed on these lists, then all logic // related to isAdmin(), canHopper(), etc.. must be scrutinized. // It would be a major undertaking to verify nothing will break. if ( verbose && isIdValid(admin) ) { sendSystemMessageProse(admin, prose.getPackage(new string_id (STF_FILE, "modify_list_invalid_player"), player_or_guild_name)); // %NO is an invalid player name. } return false; } // See if the guild name is valid int guild_id = findGuild(player_or_guild_name.substring(6).toLowerCase().trim()); if (guild_id == 0) { if ( verbose && isIdValid(admin) ) { sendSystemMessageProse(admin, prose.getPackage(new string_id (STF_FILE, "modify_list_invalid_guild"), player_or_guild_name.substring(6).trim())); // %NO is an invalid guild name. } return false; } } else { if ( !isIdValid(utils.stringToObjId(player_or_guild_name)) ) { // Assume we have a player name, in which case we need to convert it to an object ID obj_id player_objId = getPlayerIdFromFirstName(player_or_guild_name.toLowerCase().trim()); if( !isIdValid(player_objId) ) { if ( verbose && isIdValid(admin) ) { sendSystemMessageProse(admin, prose.getPackage(new string_id (STF_FILE, "modify_list_invalid_player"), player_or_guild_name)); // %NO is an invalid player name. } return false; } } } if ( objvar.equals(VAR_ENTER_LIST) ) { permissionsAddAllowed(structure, player_or_guild_name); } else if ( objvar.equals(VAR_BAN_LIST) ) { permissionsAddBanned(structure, player_or_guild_name); } else if ( objvar.equals(VAR_ADMIN_LIST) ) { adminListAddName(structure, player_or_guild_name); } else if ( objvar.equals(VAR_HOPPER_LIST) ) { hopperListAddName(structure, player_or_guild_name); } //LOG("//LOG_CHANNEL", "Adding " + player_name + " to " + objvar); if ( verbose && isIdValid(admin) ) { sendSystemMessageProse(admin, prose.getPackage(new string_id (STF_FILE, "player_added"), player_or_guild_name)); // %NO added to the list. } if ( objvar.equals(VAR_ADMIN_LIST) ) { //The admin has permissions for everything. We want to //add him to everything. if ( isBuilding(structure) ) { if ( !isNameOnEntryList(structure, player_or_guild_name) ) { modifyList(structure, player_or_guild_name, admin, VAR_ENTER_LIST, false); } } if ( isInstallation(structure) ) { if ( !isNameOnHopperList(structure, player_or_guild_name) ) { modifyList(structure, player_or_guild_name, admin, VAR_HOPPER_LIST, false); } } } if ( objvar.equals(VAR_BAN_LIST) ) { //If the player is being added to ban, we want to remove him from //the other lists. if ( isBuilding(structure) ) { if ( isNameOnEntryList(structure, player_or_guild_name) ) { modifyList(structure, player_or_guild_name, admin, VAR_ENTER_LIST, false); } } if ( isInstallation(structure) ) { if ( isNameOnHopperList(structure, player_or_guild_name) ) { modifyList(structure, player_or_guild_name, admin, VAR_HOPPER_LIST, false); } } } } else { if ( objvar.equals(VAR_ENTER_LIST) ) { permissionsRemoveAllowed(structure, player_or_guild_name); } else if ( objvar.equals(VAR_BAN_LIST) ) { permissionsRemoveBanned(structure, player_or_guild_name); } else if ( objvar.equals(VAR_ADMIN_LIST) ) { adminListRemoveName(structure, player_or_guild_name); } else if ( objvar.equals(VAR_HOPPER_LIST) ) { hopperListRemoveName(structure, player_or_guild_name); } //LOG("//LOG_CHANNEL", "Removing " + player_name + " from " + objvar); if ( verbose && isIdValid(admin) ) { sendSystemMessageProse(admin, prose.getPackage(new string_id (STF_FILE, "player_removed"), player_or_guild_name)); // %NO added to the list. } } return true; } /*********************************************************************** * @brief Adds or removes a specified player from the entry list * * @param obj_id structure the structure whose list to modify * @param obj_id player player to add/remove * @param obj_id admin player initiating the modification * * @return boolean true if successful ***********************************************************************/ boolean modifyEntryList(obj_id structure, obj_id player, obj_id admin) { if ( isIdValid(player) ) { return modifyEntryList( structure, getPlayerName( player ), admin ); } else { //LOG("//LOG_CHANNEL", "player_structure.modifyEntryList -- invalid obj_id " + player); return false; } } /*********************************************************************** * @brief Adds or removes a specified player or guild from the entry list * * @param obj_id structure the structure whose list to modify * @param string player_or_guild_name name of player or guild to add/remove * @param obj_id admin player initiating the modification * * @return boolean ***********************************************************************/ boolean modifyEntryList(obj_id structure, string player_or_guild_name, obj_id admin) { if (!isBuilding(structure)) { //LOG("//LOG_CHANNEL", "Only buildings have entry lists."); sendSystemMessage(admin, new string_id(STF_FILE, "no_entry_list")); // Only buildings have entry lists. return false; } if (canEnter(structure, player_or_guild_name)) { // The player/guild is already on the entry list, so we must be trying to remove them... // You cannot remove an admin from the entry list. if (isAdmin(structure, player_or_guild_name)) { //LOG("//LOG_CHANNEL", "You cannot remove an admin from the entry list."); sendSystemMessage(admin, new string_id(STF_FILE, "no_remove_admin")); return false; } } else { // We must be trying to add the player/guild to the entry list... // You cannot add a banned player to the entry list. if (isBanned(structure, player_or_guild_name)) { //LOG("//LOG_CHANNEL", "You cannot add a banned player to the entry list."); sendSystemMessage(admin, new string_id(STF_FILE, "no_banned")); return false; } } return modifyList(structure, player_or_guild_name, admin, VAR_ENTER_LIST, true); } /*********************************************************************** * @brief Adds or removes a specified player or guild from the ban list * * @param obj_id structure the structure whose list to modify * @param string player_or_guild_name name of player or guild to add/remove * @param obj_id admin player initiating the modification * * @return boolean true if successful ***********************************************************************/ boolean modifyBanList(obj_id structure, string player_or_guild_name, obj_id admin) { // Must check for everything here since this method will eject the player. if (!isBuilding(structure)) { //LOG("//LOG_CHANNEL", "Only buildings have banned lists."); sendSystemMessage(admin, new string_id(STF_FILE, "no_banned")); // You cannot add a banned player to the entry list. return false; } if (!isAdmin(structure, admin)) { //LOG("//LOG_CHANNEL", "You must be an admin to modify permissions lists."); sendSystemMessage(admin, new string_id(STF_FILE, "admin_only_modify")); // You must be an admin to modify permissions lists. return false; } if (isAdmin(structure, player_or_guild_name)) { //LOG("//LOG_CHANNEL", "You can not ban an admin."); sendSystemMessage(admin, new string_id(STF_FILE, "cannot_ban_admin")); // You can not ban an admin. return false; } //Now that's he's been expelled, go ahead and add him to the ban list. return modifyList(structure, player_or_guild_name, admin, VAR_BAN_LIST, true); } /*********************************************************************** * @brief Overload for modifyBanList. Also expels the player from * the building if he's in there. * * @param obj_id structure * @param obj_id player * @param obj_id admin * * @return boolean ***********************************************************************/ boolean modifyBanList(obj_id structure, obj_id player, obj_id admin) { if (isIdValid(player)) { boolean result = modifyBanList( structure, getPlayerName( player ), admin ); if ( result ) { //Since we have an obj_id, we'll go ahead and expel the player from //the house if he's in there. if ( player.isLoaded() && player.isAuthoritative() ) { obj_id ban_structure = getStructure(player); // The banned player is in the admin's structure if ( ban_structure.equals( structure ) ) { expelFromBuilding(player); } } } return result; } else { //LOG("//LOG_CHANNEL", "player_structure.modifyBanList -- unable to find obj_id for " + player_name); return false; } } /*********************************************************************** * @brief Adds or removes a specified player from the admin list * * @param obj_id structure the structure whose list to modify * @param obj_id player player to add/remove * @param obj_id admin player initiating the modification * * @return boolean true if successful ***********************************************************************/ boolean modifyAdminList(obj_id structure, obj_id player, obj_id admin) { return modifyAdminList( structure, getPlayerName( player ), admin ); } /*********************************************************************** * @brief Overload for modifyAdminList * * @param obj_id structure * @param string player_or_guild_name * @param obj_id admin * * @return boolean ***********************************************************************/ boolean modifyAdminList(obj_id structure, string player_or_guild_name, obj_id admin) { if (player_or_guild_name.equals(getPlayerName(admin))) { //LOG("//LOG_CHANNEL", "You cannot remove yourself from the admin list."); sendSystemMessage(admin, new string_id(STF_FILE, "cannot_remove_self")); // You cannot remove yourself from the admin list. return false; } if (isOwner(structure, player_or_guild_name)) { //LOG("//LOG_CHANNEL", "You cannot remove the owner from the admin list."); sendSystemMessage(admin, new string_id(STF_FILE, "cannot_remove_owner")); // You cannot remove the owner from the admin list. return false; } if (isBanned(structure, player_or_guild_name)) { //LOG("//LOG_CHANNEL", player_name + " must first be removed from the banned list."); sendSystemMessageProse(admin, prose.getPackage(new string_id (STF_FILE, "cannot_add_banned"), player_or_guild_name)); // %NO must first be removed from the banned list. return false; } return modifyList(structure, player_or_guild_name, admin, VAR_ADMIN_LIST, true); } /*********************************************************************** * @brief Adds or removes a specified player from the vendor list * !! Deprecated !! * * @param obj_id structure the structure whose list to modify * @param string player name of player to add/remove * @param obj_id admin player initiating the modification * * @return boolean true if successful ***********************************************************************/ boolean modifyVendorList(obj_id structure, string player_name, obj_id admin) { return false; } /*********************************************************************** * @brief Overload for modifyVendorList * * @param obj_id structure * @param obj_id player_name * @param obj_id admin * * @return boolean ***********************************************************************/ boolean modifyVendorList(obj_id structure, obj_id player, obj_id admin) { string player_name = getPlayerName(player); return modifyVendorList(structure, player_name, admin); } /*********************************************************************** * @brief Adds or removes a specified player from the hopper list * * @param obj_id structure the structure whose list to modify * @param obj_id player name of player to add/remove * @param obj_id admin player initiating the modification * * @return boolean true if successful ***********************************************************************/ boolean modifyHopperList(obj_id structure, obj_id player, obj_id admin) { return modifyHopperList( structure, getPlayerName( player ), admin ); } /*********************************************************************** * @brief Overload for modifyHopperList * * @param obj_id structure * @param string player_or_guild_name * @param obj_id admin * * @return boolean ***********************************************************************/ boolean modifyHopperList(obj_id structure, string player_or_guild_name, obj_id admin) { if (!isInstallation(structure)) { //LOG("//LOG_CHANNEL", "Only installations have hopper permissions lists."); sendSystemMessage(admin, new string_id(STF_FILE, "only_installations")); // Only installations have hopper permissions lists. return false; } if (canHopper(structure, player_or_guild_name)) { // The player is already on the hopper list so we must be trying to remove them... // You cannot remove an admin from the hopper list. if (isAdmin(structure, player_or_guild_name)) { //LOG("//LOG_CHANNEL", "You cannot remove an admin from the hopper list."); sendSystemMessage(admin, new string_id(STF_FILE, "hopper_cannot_remove_admin")); return false; } } else { // We must be trying to add the player... // You cannot add a banned player to the vendor list. if (isBanned(structure, player_or_guild_name)) { //LOG("//LOG_CHANNEL", "You cannot add a banned player to the vendor list."); sendSystemMessage(admin, new string_id(STF_FILE, "no_banned_vendors")); return false; } } return modifyList(structure, player_or_guild_name, admin, VAR_HOPPER_LIST, true); } /*********************************************************************** * @brief Returns a template's position in the datatable * * @param string template * * @return int row number or -1 if no match was made. ***********************************************************************/ int getStructureTableIndex(string template) { if ( template == null || template.equals("") ) return -1; int idx = dataTableSearchColumnForString(template, DATATABLE_COL_STRUCTURE, PLAYER_STRUCTURE_DATATABLE); if ( idx == -1 ) { idx = dataTableSearchColumnForString(template, DATATABLE_COL_FOOTPRINT, PLAYER_STRUCTURE_DATATABLE); } return idx; } /*********************************************************************** * @brief Adds a battlefield waypoint to the player for a given structure * * @param obj_id player player to give the waypoint * @param location loc location to place the waypoint * @param string name of the waypoint * @param structure structure obj_id * * @return boolean ***********************************************************************/ obj_id addStructureWaypoint(obj_id player, location loc, string name, obj_id structure) { LOG("LOG_CHANNEL", "player_structure.addStructureWaypoint -- " + name); if (!isIdValid(player)) return null; if (loc == null) return null; if (name == null) return null; obj_id waypoint = createWaypointInDatapad(player, loc); if (!isIdValid(waypoint)) return null; setWaypointVisible(waypoint, true); setWaypointActive(waypoint, true); setWaypointName(waypoint, name); if (structure.isLoaded()) setObjVar(structure, VAR_WAYPOINT_STRUCTURE, waypoint); else { dictionary params = new dictionary(); params.put("waypoint", waypoint); messageTo(structure, "msgAddWaypointData", params, 0.0f, true); } return waypoint; } /*********************************************************************** * @brief Adds money to a structure's maintenance pool. Pulls money * from the player's cash and then bank. * * @param obj_id player player to pay * @param obj_id structure structure to pay into * @param int amt the amount to add * * @return boolean true if success ***********************************************************************/ boolean payMaintenance(obj_id player, obj_id structure, int amt) { ////LOG("//LOG_CHANNEL", "player_structure::payMaintanence -- player ->" + player + " structure ->" + structure + " amt ->" + amt); if (!isIdValid(player) || !isIdValid(structure)) return false; if (amt < 1 || amt > 100000) return false; //added 10/22/4, feel free to delete it in a month or two! if ( isOwner(structure, player) ) doOldToNewLotConversion( player, structure ); return money.pay(player, structure, amt, "handlePayment", null); } /*********************************************************************** * @brief Removes money from the structure's maintenance pool and * places it in the player's account. * * @param obj_id player player to receive money * @param obj_id structure structure to remove money * @param int amt the amount to remove * * @return boolean true if success ***********************************************************************/ boolean withdrawMaintenance(obj_id player, obj_id structure, int amt) { if (!isIdValid(player) || !isIdValid(structure)) return false; if (amt < 1) return false; dictionary d = new dictionary(); d.put("player", player); d.put("structure", structure); d.put("amount", amt); CustomerServiceLog("playerStructure", "%TU has initiated a withdraw of " + amt + " from structure " + structure + ".", player, null); return transferBankCreditsTo(structure, player, amt, "msgPAWithdrawSuccess", "msgPAWithdrawFail", d); } /*********************************************************************** * @brief Reduces the structure's maintenance pool * * @param obj_id structure structure whose pool to reduce * @param int amt amount to reduce * * @return int the amount left in the pool. -1 if failed * -2 if insufficient funds. ***********************************************************************/ int decrementMaintenancePool(obj_id structure, int amt) { if ( getConfigSetting("GameServer", "disableStructureFees") != null ) return 1; //LOG("//LOG_CHANNEL", "structure ->" + structure + " amt ->" + amt); if (!isIdValid(structure)) return -1; if (amt < 1) return -1; int pool = getBankBalance(structure); if (amt > pool) return -2; int property_tax = city.getPropertyTax(structure); int pretax_amt = 0, tax_amt = 0; int base_amt = amt; if ( property_tax > 0 ) { pretax_amt = Math.round(amt / (1+(property_tax/100.f))); tax_amt = base_amt - pretax_amt; if ( money.bankTo(structure, money.ACCT_STRUCTURE_MAINTENANCE, pretax_amt) ) { pool -= pretax_amt; if ( (tax_amt > 0) && money.bankTo( structure, city.getCityHall(structure), tax_amt ) ) pool -= tax_amt; return pool; } } else { if (money.bankTo(structure, money.ACCT_STRUCTURE_MAINTENANCE, amt)) { pool -= amt; return pool; } } return -1; } /*********************************************************************** * @brief Damages a structure. Destroyes it if its condition goes * to zero. * * @param obj_id structure structure whose pool to reduce * @param int amt amount to damage * * @return int structure's condition after the damage. * 0 if the structure was destroy, -1 if fail. ***********************************************************************/ int damageStructure(obj_id structure, int amt, boolean boolCondemn) { if (structure == null || structure == obj_id.NULL_ID) return -1; if (amt < 1) return -1; int condition = getStructureCondition(structure); condition = condition - amt; if (condition < 1) { condition = 0; if ( hasCondition( structure, CONDITION_VENDOR ) ) destroyObject( structure ); else { //see if we are a house or a Factory if(isBuilding(structure) || isFactory(structure)) { if( boolCondemn) { setInvulnerableHitpoints(structure, 1); return 0; } } CustomerServiceLog("playerStructure","Structure " + structure + " destroyed for lack of maintenance."); destroyStructure(structure); } } else { //setObjVar(structure, VAR_CONDITION, condition); setInvulnerableHitpoints(structure, condition); } return condition; } int damageStructure(obj_id structure, int amt) { return damageStructure(structure, amt, false); } /*********************************************************************** * @brief Repairs a structure. * * @param obj_id structure structure whose pool to reduce * @param int amt amount to repair * * @return int structure's condition after the repair ***********************************************************************/ int repairStructure(obj_id structure, int amt) { if (structure == null || structure == obj_id.NULL_ID) { LOG("building", "Returning 1"); return -1; } if (amt < 1) { LOG("building", "Returning 12"); return -1; } int condition = getStructureCondition(structure); //LOG("building", "Old condition is "+condition); int max_condition = getMaxCondition(structure); //LOG("building", "max condition is "+max_condition); condition = condition + amt; LOG("building", "new condition is "+condition); if (condition > max_condition) condition = max_condition; //LOG("building", "new condition 3 is "+condition); //setObjVar(structure, VAR_CONDITION, condition); setInvulnerableHitpoints(structure, condition); //LOG("building", "HP is "+getHitpoints(structure)); //LOG("building", "HP is "+getHitpoints(structure)); if(isStructureCondemned(structure)) { removeObjVar(structure, "player_structure.condemned"); } //LOG("building", "Returning "+condition); return condition; } /*********************************************************************** * @brief Performs a repair check and spends maintenance pool * credits to initiate repairs if necessary. * * @param obj_id structure structure whose pool to reduce * @param int amt amount to repair * * @return int structure's condition after the repair ***********************************************************************/ boolean initiateRepairCheck(obj_id structure) { if (!isIdValid(structure)) return false; int condition = getStructureCondition(structure); int max_condition = getMaxCondition(structure); if (condition != max_condition) { int damage = max_condition - condition; int maint_pool = getBankBalance(structure); // repairs cost the maintenance rate per 3 points. float per_point_cost = getBaseMaintenanceRate( structure ) / 3.0f; // Check for owner skill mods //if ( hasSkill( getStructureOwnerObjId(structure), "crafting_merchant_sales_04" ) ) // per_point_cost *= 0.8f; //if (per_point_cost < 1) // per_point_cost = 1; int repair_cost = (int)(damage * per_point_cost); int amt_paid = 0; int amt_repaired = 0; if (maint_pool >= per_point_cost) { LOG("LOG_CHANNEL", "permanent_structure::OnMaintenanceLoop -- initiating repairs."); LOG("LOG_CHANNEL", "cond ->" + condition); if (maint_pool < repair_cost) { // Use the whole pool for repairs amt_repaired = (int)(maint_pool / per_point_cost); amt_paid = maint_pool; } else { // Repair all of the damage amt_paid = (int)(damage * per_point_cost); amt_repaired = damage; } int result = decrementMaintenancePool(structure, amt_paid); if (result > -1) { LOG("LOG_CHANNEL", "amt_paid ->" + amt_paid + " amt_repaired ->" + amt_repaired); condition = repairStructure(structure, amt_repaired); LOG("LOG_CHANNEL", "2cond ->" + condition); } else LOG("LOG_CHANNEL", "permanent_structure::OnMaintenanceLoop -- unable to pay repair costs."); } } return true; } /*********************************************************************** * @brief Sends mail when a structure is damaged. * * @param obj_id structure structure whose pool to reduce * * @return boolean ***********************************************************************/ boolean sendMaintenanceMail(obj_id structure) { if (!isIdValid(structure)) return false; int last_message = 0; if (hasObjVar(structure, VAR_LAST_MESSAGE)) last_message = getIntObjVar(structure, VAR_LAST_MESSAGE); if (last_message <= getGameTime() && !isStructureCondemned(structure) ) { int condition = player_structure.getStructureCondition(structure); int max_condition = player_structure.getMaxCondition(structure); int perc_condition = (condition * 100) / max_condition; if (perc_condition <= 90) { // send a warning obj_id owner = getStructureOwnerObjId(structure); if (isIdValid(owner)) { location loc = getLocation(structure); string area = loc.area; if (area != null) area = area.substring(0,1).toUpperCase() + area.substring(1); string loc_str = "(" + loc.x + ", " + loc.z + " " + loc.area + ")"; string_id strSpam = player_structure.SID_MAIL_STRUCTURE_DAMAGE; prose_package pp = prose.getPackage(strSpam, null, structure, loc_str, perc_condition); utils.sendMail(player_structure.SID_MAIL_STRUCTURE_DAMAGE_SUB, pp, getPlayerName(owner), "@player_structure:management"); utils.setObjVar(structure, VAR_LAST_MESSAGE, getGameTime() + MAIL_WARNING_INTERVAL); return true; } } else if (hasObjVar(structure, VAR_LAST_MESSAGE)) removeObjVar(structure, VAR_LAST_MESSAGE); } return false; } /*********************************************************************** * @brief Destroys a structure and provides necessary cleanup. Makes no assumptions about what "self" is. * * @param obj_id structure structure to destroy * @param obj_id containerForDeed container in which to place the structure's deed (and self-powered kit if appropriate) * @param boolean reclaim whether or not to reconstruct the deed (self-powered kit is always reconstructed) * @param boolean overloaded whether or not to ignore container limits when creating the deed(s) * * @return int result code (DESTROY_RESULT_...) ***********************************************************************/ int destroyStructure(obj_id structure, obj_id containerForDeed, boolean reclaim, boolean overloaded) { if(!isValidId(structure) || !exists(structure)) return DESTROY_RESULT_INVALID_STRUCTURE; string template = getTemplateName(structure); obj_id owner = getStructureOwnerObjId(structure); obj_id self = getSelf(); //this could be any object. Used in log messages only // Log the destruction string sname = getStructureName( structure ); CustomerServiceLog("playerStructure","Initiating destroy for structure " + structure + " (Template: " + template + " Name: " + sname + "). Owner is " + getStructureOwner(structure) + " (" + owner + ") Location: " + getLocation(structure) + " Reclaim: " + reclaim); boolean bGetSelfPowered = false; // reconstruct the deed if( hasObjVar(structure, "selfpowered") ) bGetSelfPowered = true; if(reclaim) { //if this is a TCG Static Item Deed, do this and igone the rest obj_id deed = null; boolean isStaticItemDeed = false; string deed_template = getDeedTemplate(structure); if(deed_template == null || deed_template.equals("")) { CustomerServiceLog("playerStructure","Attempting to reclaim deed, but can't find deed information for " + structure + ". Owner is " + getStructureOwner(structure) + "(" + owner + ") Location: " + getLocation(structure)); return DESTROY_RESULT_FAIL_COULD_NOT_DETERMINE_DEED_FOR_STRUCTURE; // Error in attempting to reclaim deed. Destroy structure denied. Please contact Customer Service. } if(!overloaded && getVolumeFree(containerForDeed) < 1) return DESTROY_RESULT_FAIL_TARGET_CONTAINER_FULL; // Your inventory is full. Please make space for the deed that will be created. if(!overloaded && getVolumeFree(containerForDeed) < 2 && bGetSelfPowered) return DESTROY_RESULT_FAIL_TARGET_CONTAINER_FULL_SELFPOWERED; if(hasObjVar(structure, TCG_STATIC_ITEM_DEED_OBJVAR)) { CustomerServiceLog("playerStructure", "DestroyStructure -- Player has TCG STRUCTURE: " + structure + ". Owner is %TU. destroyStructure initiated by %TT", owner, self); string staticItemDeed = getStringObjVar(structure, TCG_STATIC_ITEM_DEED_OBJVAR); if(staticItemDeed == null || staticItemDeed.equals("")) return DESTROY_RESULT_INVALID_STATIC_ITEM; if(!static_item.isStaticItem(staticItemDeed)) return DESTROY_RESULT_INVALID_STATIC_ITEM; deed = static_item.createNewItemFunction(staticItemDeed, containerForDeed); isStaticItemDeed = true; CustomerServiceLog("playerStructure", "DestroyStructure -- Owner has TCG STRUCTURE: " + structure + " and has the correct static item: "+staticItemDeed+". Owner is %TU. destroyStructure initiated by %TT", owner, self); } else { deed = overloaded ? createObjectOverloaded(deed_template, containerForDeed) : createObject(deed_template, containerForDeed, ""); } if(!isValidId(deed) || !exists(deed)) { CustomerServiceLog("playerStructure","structure("+structure+")|owner("+owner+") was unable to create the deed for caller("+self+") and is dumping out without destroying the structure"); return DESTROY_RESULT_FAIL_COULD_NOT_CREATE_DEED; } if(!isStaticItemDeed) { setDeedTemplate(deed, template); setObjVar(deed, VAR_DEED_BUILDTIME, getDeedBuildTime(structure)); string deed_scene = getDeedScene( structure ); // Update old pre-patch deed scenes. 12/09/03 if ( deed_scene != null ) { if ( deed_scene.equals( "tatooine" ) ) deed_scene = "tatooine,lok,dantooine"; else if ( deed_scene.equals( "naboo" ) ) deed_scene = "naboo,rori,dantooine"; else if ( deed_scene.equals( "corellia" ) ) deed_scene = "corellia,talus"; } setObjVar( deed, VAR_DEED_SCENE, deed_scene ); } // Check for Vet Reward Storage increase - if the house contains set the deed to notrade and put the objvar on it // so when the player rebuilds the house it contains extra storage - PMW if (hasObjVar(structure, "structureChange.storageIncrease")) { int storageIncrease = getIntObjVar(structure, "structureChange.storageIncrease"); setObjVar( deed, "structureChange.storageIncrease", storageIncrease); setObjVar( deed, "noTrade", 1); attachScript( deed, "item.special.nomove"); } int maxExtractionRate = getIntObjVar(structure, "max_extraction"); if(maxExtractionRate != -1 && isHarvester(structure) || isGenerator(structure)) { setObjVar(deed, VAR_DEED_MAX_EXTRACTION, maxExtractionRate); } int currentExtractionRate = getIntObjVar(structure, "current_extraction"); if(currentExtractionRate != -1 && isHarvester(structure) || isGenerator(structure)) { setObjVar(deed, VAR_DEED_CURRENT_EXTRACTION, currentExtractionRate); } int maxHopperAmount = getIntObjVar(structure, VAR_DEED_MAX_HOPPER); if (maxHopperAmount > 0) setObjVar(deed, VAR_DEED_MAX_HOPPER, maxHopperAmount); int maintPool = getBankBalance(structure); int reclaimCost = getRedeedCost(structure); transferBankCreditsToNamedAccount(structure, money.ACCT_DEED_RECLAIM, reclaimCost, "noHandler", "noHandler", new dictionary()); int surplus = maintPool - reclaimCost; if ( surplus > 0 ) { setObjVar(deed, VAR_DEED_SURPLUS_MAINTENANCE, surplus); transferBankCreditsToNamedAccount(structure, money.ACCT_STRUCTURE_DESTROYED, surplus, "noHandler", "noHandler", new dictionary()); CustomerServiceLog("playerStructure", "DestroyStructure -- transferring maintenance to deed " + deed + " from structure " + structure + " Amount: " + surplus + ". Owner is %TU. destroyStructure initiated by %TT", owner, self); } float power = getPowerValue(structure); if(power > 0f && (isFactory(structure) || isHarvester(structure) || isGenerator(structure))) { setObjVar(deed, VAR_DEED_SURPLUS_POWER, power); } } else { if(isIdValid(containerForDeed) && getVolumeFree(containerForDeed)<1 && bGetSelfPowered) return DESTROY_RESULT_FAIL_TARGET_CONTAINER_FULL_SELFPOWERED; // Your inventory is full. Please make space for the deed that will be created. transferBankCreditsToNamedAccount(structure, money.ACCT_STRUCTURE_DESTROYED, getBankBalance(structure), "noHandler", "noHandler", new dictionary()); } // player gets a Self Powered Harvester Kit back. if( bGetSelfPowered ) { string veteranRewardDeedToReturn = null; if(isEliteHarvester(structure)) veteranRewardDeedToReturn = SELFPOWERED_DEED_ELITE; else veteranRewardDeedToReturn = SELFPOWERED_DEED; if (overloaded) createObjectOverloaded( veteranRewardDeedToReturn, containerForDeed); else createObject( veteranRewardDeedToReturn, containerForDeed, ""); } // Remove this structure from a city. city.removeStructureFromCity( structure ); // remove all players from the building before destroying it. if (isBuilding(structure)) { obj_id[] players = getPlayersInBuilding(structure); if (players != null) { for (int i = 0; i < players.length; i++) { //LOG("//LOG_CHANNEL", "Ejecting " + players[i]); expelFromBuilding(players[i]); } } } destroyBaseObjects(structure); destroyStructureSign(structure); // send a message to the player to remove structure from his ownership list. dictionary params = new dictionary(); params.put("structure", structure); params.put("template", template); if (hasObjVar(structure, VAR_WAYPOINT_STRUCTURE)) params.put("waypoint", getObjIdObjVar(structure, VAR_WAYPOINT_STRUCTURE)); adjustLotsForOfflinePlayer( self, structure ); messageTo(owner, "OnRemoveStructure", params, 0.1f, true); if (vendor_lib.isVendorPackUpEnabled()) { // Destroy vendors inside this structure. string[] cells = getCellNames(structure); if( cells != null) { for(int i = 0; i < cells.length; i++) { obj_id cellid = getCellId(structure, cells[i]); obj_id contents[] = getContents(cellid); if(contents != null) { for(int j=0; j 4 ) return "error"; if ( time_values.length == 1 && time_values[0] == Integer.MAX_VALUE ) return "3550+ weeks"; //Determine the number of non-zero time values string [] time_strings = {"day", "hour", "minute", "second"}; int num_times = 0; for (int i = 0; i < time_values.length; i++) { if (time_values[i] != 0) num_times++; } int num_left = num_times; StringBuffer sb = new StringBuffer(); for (int i = 0; i < time_values.length; i++) { if (time_values[i] > 0) { sb.append(time_values[i] + " " + time_strings[i]); if (time_values[i] > 1) sb.append("s"); if (num_left == 1) sb.append("."); else if (num_left == 2) { if (num_times > 2) sb.append(", and "); else sb.append(" and "); } else sb.append(", "); num_left--; } } return sb.toString(); } /*********************************************************************** * @brief Converts permission lists over to obj_id's if needed. * * @param obj_id structure * * @return boolean ***********************************************************************/ boolean convertPermissionsLists(obj_id structure) { if (!isIdValid(structure)) { LOG("player_structure", "player_structure.convertPermissionsLists -- structure is invalid."); return false; } // Determine if we have already been converted if (!hasObjVar(structure, VAR_PERMISSIONS_CONVERTED)) { obj_id[] admin_list_as_objIds = getObjIdArrayObjVar(structure, VAR_ADMIN_LIST); if (admin_list_as_objIds!= null) { // If we got back a string array, it's using the old stuff. string[] new_admin_list = convertObjIdPermissionList(admin_list_as_objIds); if (new_admin_list != null) { if (new_admin_list.length > 0) setObjVar(structure, VAR_ADMIN_LIST, new_admin_list); else removeObjVar(structure, VAR_ADMIN_LIST); } } else { string[] admin_list_as_strings = getStringArrayObjVar(structure, VAR_ADMIN_LIST); if (admin_list_as_strings != null) { // If we got back a string array, it's using the old stuff. string[] new_admin_list = convertStringPermissionList(admin_list_as_strings); if (new_admin_list != null) { if (new_admin_list.length > 0) setObjVar(structure, VAR_ADMIN_LIST, new_admin_list); else removeObjVar(structure, VAR_ADMIN_LIST); } } } obj_id[] hopper_list_as_objIds = getObjIdArrayObjVar(structure, VAR_HOPPER_LIST); if (hopper_list_as_objIds != null) { // If we got back a string array, it's using the old stuff. string[] new_hopper_list = convertObjIdPermissionList(hopper_list_as_objIds); if (new_hopper_list != null) { if (new_hopper_list.length > 0) setObjVar(structure, VAR_HOPPER_LIST, new_hopper_list); else removeObjVar(structure, VAR_HOPPER_LIST); } } else { string[] hopper_list_as_strings = getStringArrayObjVar(structure, VAR_HOPPER_LIST); if (hopper_list_as_strings != null) { // If we got back a string array, it's using the old stuff. string[] new_hopper_list = convertStringPermissionList(hopper_list_as_strings); if (new_hopper_list != null) { if (new_hopper_list.length > 0) setObjVar(structure, VAR_HOPPER_LIST, new_hopper_list); else removeObjVar(structure, VAR_HOPPER_LIST); } } } // We have converted the permissions so set the flag... setObjVar(structure, VAR_PERMISSIONS_CONVERTED, 1); } else { // TODO: At some point we need to strip out invalid IDs // (for example, characters may have been purged) } return true; } /*********************************************************************** * @brief Transforms a list of object IDs into a list with following format: * 1) All object IDs have been converted to object ID strings * * @param obj_id[] object ID list * * @return string[] list of strings, null on error ***********************************************************************/ string[] convertObjIdPermissionList(obj_id[] objId_list) { if (objId_list == null || objId_list.length < 1) { LOG("player_structure", "player_structure.objIdListToNameList -- obj_id_list is null or empty."); return null; } resizeable string[] new_name_list = new string[0]; for (int i = 0; i < objId_list.length; i++) { if ( !addPlayerObjIdToRawList( new_name_list, objId_list[i] ) ) { LOG("player_structure", "player_structure.convertObjIdPermissionList -- invalid object ID " + objId_list[i].toString()); } } if (new_name_list.length > 0) return new_name_list; else return null; } /*********************************************************************** * @brief Transforms a list of names into a list with following format: * 1) All player names have been converted to object ID strings * 2) All guild entries keep the format "guild:" * * @param string[] name_list * * @return string[] list of strings, null on error ***********************************************************************/ string[] convertStringPermissionList(string[] name_list) { if (name_list == null || name_list.length < 1) { LOG("player_structure", "player_structure.objIdListToNameList -- obj_id_list is null or empty."); return null; } resizeable string[] new_name_list = new string[0]; for (int i = 0; i < name_list.length; i++) { if ( !addNameToRawList( new_name_list, name_list[i] ) ) { LOG("player_structure", "player_structure.convertStringPermissionList -- couldn't convert the name " + name_list[i]); } } if (new_name_list.length > 0) return new_name_list; else return null; } /*********************************************************************** * @brief Provides rotation transformation of delta_world coordinates * * @param float X X delta_world coordinate * @param float Z Z delta_world coordinate * to rotate. * @param rotation rotation of the structure in place structure * tool units (0 = 0, 1 = 90, 2 = 180, etc.) * * @return float[] transformed delta_world coords {X, Z} ***********************************************************************/ float[] transformDeltaWorldCoord(float X, float Z, int rotation) { //LOG("player_structure","transformDeltaWorldCoord entered..."); //LOG("player_structure","transformDeltaWorldCoord: rotation = " + rotation); float x = X; float z = Z; switch(rotation) { case 0: break; case 1: X = z; Z = -x; break; case 2: Z = -z; X = -x; break; case 3: X = -z; Z = x; break; } float[] delta_world = {X, Z}; return delta_world; } location transformDeltaWorldCoord(location here, float dx, float dz, float yaw) { yaw = yaw % 360f; if ( yaw < 0 ) yaw += 360f; int rotation = java.lang.Math.round(yaw/90f); float[] xz = transformDeltaWorldCoord(dx, dz, rotation); if ( xz != null & xz.length == 2 ) { location there = here; there.x += xz[0]; there.z += xz[1]; return there; } return null; } boolean hasSign(obj_id structure) { if ( !isIdValid(structure) ) return false; return hasObjVar(structure, VAR_SIGN_ID); } boolean isPackedUp(obj_id structure) { obj_id container = getContainedBy(structure); if(!isIdValid(container)) { return false; } string template = getTemplateName(container); return template.equals("object/intangible/house/generic_house_control_device.iff"); } obj_id createStructureSign(obj_id structure, float sYaw) { //LOG("structureSign","createStructureSign: entered... structure = " + structure); if ( !isIdValid(structure) ) return null; if(isPackedUp(structure)) { // don't want a structure that is packed up inside of a container to recreate its sign return null; } string structureTemplate = getTemplateName(structure); //LOG("structureSign","createStructureSign: structure template = " + structureTemplate); int needSign = dataTableGetInt(PLAYER_STRUCTURE_DATATABLE, structureTemplate, DATATABLE_COL_HAS_SIGN); //LOG("structureSign","createStructureSign: needSign = " + needSign); if ( needSign == 1 ) { destroyStructureSign(structure); location here = getLocation(structure); for ( int x = 0; x < SIGN_TYPE.length; x++ ) { obj_id[] nc = getAllObjectsWithTemplate(here, 64f, SIGN_TYPE[x]); if ( nc != null && nc.length > 0 ) { for ( int i = 0; i < nc.length; i++ ) { if ( isObjectPersisted(nc[i]) && !utils.hasScriptVar(nc[i],"player_structure.parent") ) { CustomerServiceLog("sign_destruction", "destroying sign " + nc[i] + " whose name is '" + getName(nc[i]) + "'"); destroyObject(nc[i]); } } } } dictionary params = dataTableGetRow(TBL_SIGN, structureTemplate); if ( (params != null) && (!params.isEmpty()) ) { int signType = 0; float x = params.getFloat("X"); float y = params.getFloat("Y"); float z = params.getFloat("Z"); float heading = params.getFloat("HEADING"); string signTemplate = params.getString("DEFAULT_SIGN"); string signName = "Unnamed Structure"; if ( isCivic( structure ) ) { signName = utils.getStringName( structure ); } else { string[] admins = getAdminListNames(structure); if ( (admins != null) && (admins.length != 0) ) { string admin_name = admins[0]; if (admin_name != null) { if(structureTemplate.indexOf("guild") > -1 ) signName = admin_name + "'s Guildhall"; else if ( structureTemplate.indexOf("barn") > -1 ) signName = admin_name + "'s Barn"; else if ( structureTemplate.indexOf("diner") > -1 ) signName = admin_name + "'s Diner"; else if ( structureTemplate.indexOf("cantina") > -1 ) signName = admin_name + "'s Cantina"; else if ( structureTemplate.indexOf("hospital") > -1 ) signName = admin_name + "'s Medical Center"; else if ( structureTemplate.indexOf("pgc_merchant_tent") > -1 ) signName = admin_name + "'s Chronicles Tent"; else if ( structureTemplate.indexOf("merchant_tent") > -1 ) signName = admin_name + "'s Merchant Tent"; else if(structureTemplate.indexOf("theater") > -1 ) signName = admin_name + "'s Theater"; else if(structureTemplate.indexOf("garage") > -1 ) signName = admin_name + "'s Garage"; else signName = admin_name + "'s House"; } else { if(structureTemplate.indexOf("guild") > -1 ) signName = "Guildhall"; else if ( structureTemplate.indexOf("barn") > -1 ) signName = admin_name + "Barn"; else if ( structureTemplate.indexOf("diner") > -1 ) signName = admin_name + "Diner"; else if ( structureTemplate.indexOf("cantina") > -1 ) signName = admin_name + "Cantina"; else if ( structureTemplate.indexOf("hospital") > -1 ) signName = admin_name + "Medical Center"; else if ( structureTemplate.indexOf("pgc_merchant_tent") > -1 ) signName = admin_name + "'s Chronicles Tent"; else if ( structureTemplate.indexOf("merchant_tent") > -1 ) signName = admin_name + "Merchant Tent"; else if(structureTemplate.indexOf("theater") > -1 ) signName = "Theater"; else if(structureTemplate.indexOf("garage") > -1 ) signName = "Garage"; else signName = "House"; } } } //does it have previous leftover info? if ( hasObjVar(structure, VAR_SIGN_BASE) ) { if ( hasObjVar(structure, VAR_SIGN_NAME) ) { string storedName = getStringObjVar(structure, VAR_SIGN_NAME); if ( storedName != null && !storedName.equals("") ) { signName = storedName; } } if ( hasObjVar(structure, VAR_SIGN_TYPE) ) { signType = getIntObjVar(structure, VAR_SIGN_TYPE); if(structureTemplate.equals("object/building/player/player_house_mustafar_lg.iff") && hasObjVar(structure, VAR_ABANDONED)) { signType = 0; } if ( signType > 0) { signTemplate = SIGN_TYPE[signType]; x = params.getFloat("ALT_X"); y = params.getFloat("ALT_Y"); z = params.getFloat("ALT_Z"); heading = params.getFloat("ALT_HEADING"); } } } location there = new location(here.x + x, here.y + y, here.z + z, here.area, here.cell); //LOG("structureSign","createStructureSign: there = " + there.toString()); /* ****************************************************************************** ****************************************************************************** ****************************************************************************** ****************************************************************************** ****************************************************************************** ****************************************************************************** ****************************************************************************** ****************************************************************************** ****************************************************************************** ****************************************************************************** ****************************************************************************** ****************************************************************************** ****************************************************************************** ****************************************************************************** ****************************************************************************** ****************************************************************************** ****************************************************************************** ****************************************************************************** ****************************************************************************** ****************************************************************************** ****************************************************************************** */ //House has received a different house sign. if (hasObjVar(structure, MODIFIED_HOUSE_SIGN)) { signTemplate = getStringObjVar(structure, MODIFIED_HOUSE_SIGN); //A custom house sign on the mustafar bunker needs to be repositioned. if (structureTemplate.equals("object/building/player/player_house_mustafar_lg.iff") && signTemplate.startsWith("object/tangible/sign/player/house_address") && !signTemplate.startsWith("object/tangible/sign/player/house_address_corellia")) { //modify there.x/y/z values directly there.z -= 0.4f; //we need to modify the 'z' from the datatable for the transform. z -= 0.4f; } //A custom STANDING house sign on the Generic Large House needs to be repositioned. if (structureTemplate.equals("object/building/player/player_house_generic_large_style_01.iff")) { if(signTemplate.startsWith("object/tangible/sign/player/shop_sign_") && !signTemplate.startsWith("object/tangible/sign/player/shop_sign_s0")) { //modify there.x/y/z values directly there.z += 0.8f; //we need to modify the 'z' from the datatable for the transform. z += 0.8f; } } //If using a custom HANGING sign on a naboo cantina, we have to modify the yaw. if (structureTemplate.startsWith("object/building/player/city/cantina_naboo") && signTemplate.startsWith("object/tangible/sign/player/house_address") && !signTemplate.startsWith("object/tangible/sign/municipal/municipal_sign_hanging_cantina")) { //modify there.x/y/z values directly there.z += 0.3f; //we need to modify the 'z' from the datatable for the transform. z += 0.3f; } //If using a custom HANGING sign on a naboo cantina, we have to modify the yaw. if (structureTemplate.startsWith("object/building/player/city/cantina_corellia") && signTemplate.startsWith("object/tangible/sign/player/house_address") && !signTemplate.startsWith("object/tangible/sign/municipal/municipal_sign_hanging_cantina")) { //modify there.x/y/z values directly there.z += 0.1f; //we need to modify the 'z' from the datatable for the transform. z += 0.1f; } } else if(hasObjVar(structure, SPECIAL_SIGN)) { signTemplate = getStringObjVar(structure, player_structure.SPECIAL_SIGN_TEMPLATE); //If the sign is the TCG set 5 hanging sign, raise it if (signTemplate.startsWith("object/tangible/tcg/series5/house_sign_tcg_hanging")) { there.y += 1.5f; y += 1.5f; } if(signTemplate.startsWith("object/tangible/sign/player/pgc_sign_hanging.iff")) { //modify there.x/y/z values directly there.x -= 0.45f; //there.z -= 0.4f; //we need to modify the 'x' and 'z' from the datatable for the transform. x -= 0.45f; //z -= 0.4f; } //MERCHANT TENT SPECIAL-CASED SIGN LOCATIONS if(structureTemplate.startsWith("object/building/player/player_merchant_tent")) { //TCG_S01 (HANGING) if(!signTemplate.startsWith("object/tangible/tcg/series3/house_sign_tcg_s02") && signTemplate.startsWith("object/tangible/tcg/")) { //modify there.x/y/z values directly there.x -= 0.4f; there.z -= 0.4f; //we need to modify the 'x' and 'z' from the datatable for the transform. x -= 0.4f; z -= 0.4f; } //TCG_S02 (STANDING) if(signTemplate.startsWith("object/tangible/tcg/series3/house_sign_tcg_s02")) { //modify there.x/y/z values directly there.x += 0.6f; there.z += 0.1f; //we need to modify the 'x' and 'z' from the datatable for the transform. x += 0.6f; z += 0.1f; } //HALLOWEEN 2008 if(signTemplate.startsWith("object/tangible/sign/player/house_address_halloween")) { //modify there.x/y/z values directly there.x -= 0.2f; there.z -= 0.2f; //we need to modify the 'x' and 'z' from the datatable for the transform. x -= 0.2f; z -= 0.2f; } //EMPIRE DAY 2009 (HANGING) if(signTemplate.startsWith("object/tangible/sign/player/imperial_empire_day_2009_sign_hanging") || signTemplate.startsWith("object/tangible/sign/player/rebel_remembrance_day_2009_sign_hanging")) { //modify there.x/y/z values directly there.x -= 0.37f; there.z -= 0.37f; //we need to modify the 'x' and 'z' from the datatable for the transform. x -= 0.37f; z -= 0.37f; } //EMPIRE DAY 2009 (STANDING) if(signTemplate.startsWith("object/tangible/sign/player/imperial_empire_day_2009_sign_standing") || signTemplate.startsWith("object/tangible/sign/player/rebel_remembrance_day_2009_sign_standing")) { //modify there.x/y/z values directly there.x += 0.6f; there.z += 0.1f; //we need to modify the 'x' and 'z' from the datatable for the transform. x += 0.6f; z += 0.1f; } } //MUSTAFAR BUNKER SPECIAL-CASED SIGN LOCATIONS if(structureTemplate.startsWith("object/building/player/player_house_mustafar_lg")) { //TCG S01 (HANGING) if(signTemplate.startsWith("object/tangible/tcg/series3/house_sign_tcg_s01")) { //modify there.x/y/z values directly there.z -= 0.4f; //we need to modify the 'z' from the datatable for the transform. z -= 0.4f; } //EMPIRE DAY 2009 (HANGING) if(signTemplate.startsWith("object/tangible/sign/player/imperial_empire_day_2009_sign_hanging") || signTemplate.startsWith("object/tangible/sign/player/rebel_remembrance_day_2009_sign_hanging")) { //modify there.x/y/z values directly there.z -= 0.4f; //we need to modify the 'z' from the datatable for the transform. z -= 0.4f; } //TCG Series 5 Sign if(signTemplate.startsWith("object/tangible/tcg/series5/house_sign_tcg_hanging")) { //move the sign back against the house. there.z -= 0.4f; //we need to modify the 'z' from the datatable for the transform. z -= 0.4f; } } //Corellian Theaters if(structureTemplate.startsWith("object/building/player/city/theater_corellia")) { //TCG Set 5 Sign - Hanging if(signTemplate.startsWith("object/tangible/tcg/series5/house_sign_tcg_hanging")) { there.x -= 0.4f; x -= 0.4f; } } //Corellian Guild Hall if(structureTemplate.startsWith("object/building/player/player_guildhall_corellia")) { //TCG Set 5 Sign - Hanging if(signTemplate.startsWith("object/tangible/tcg/series5/house_sign_tcg_hanging")) { there.z -= 0.4f; there.y -= 0.1f; z -= 0.4f; y -= 0.1f; } //Remembrance Day Sign 2009 if(signTemplate.startsWith("object/tangible/sign/player/rebel_remembrance_day_2009_sign_hanging") || signTemplate.startsWith("object/tangible/sign/player/imperial_empire_day_2009_sign_hanging")) { heading += 90f; there.z -= 0.4f; z -= 0.4f; } } //Tatooine Theaters if(structureTemplate.startsWith("object/building/player/city/theater_tatooine")) { //Empire Day Sign 2009 if(signTemplate.startsWith("object/tangible/sign/player/imperial_empire_day_2009_sign_hanging")) { there.x -= 0.4f; x -= 0.4f; } //Remembrance Day Sign 2009 if(signTemplate.startsWith("object/tangible/sign/player/rebel_remembrance_day_2009_sign_hanging")) { there.x -= 0.4f; x -= 0.4f; } } //Tatppome Guild Hall if(structureTemplate.startsWith("object/building/player/player_guildhall_tatooine")) { //Remembrance Day Sign 2009 if(signTemplate.startsWith("object/tangible/sign/player/rebel_remembrance_day_2009_sign_hanging") || signTemplate.startsWith("object/tangible/sign/player/imperial_empire_day_2009_sign_hanging")) { there.z -= 0.1f; z -= 0.1f; } } //A custom STANDING house sign on the Generic Large House needs to be repositioned. if (structureTemplate.equals("object/building/player/player_house_generic_large_style_01.iff") || structureTemplate.equals("object/building/player/player_house_corellia_large_style_01.iff")) { //TCG Series 5 if (signTemplate.startsWith("object/tangible/tcg/series5/house_sign_tcg_standing")) { there.z += 1.2f; z += 1.2f; } //Empire/Remembrance Day Signs 2009 if (signTemplate.startsWith("object/tangible/sign/player/rebel_remembrance_day_2009_sign_standing.iff") || signTemplate.startsWith("object/tangible/sign/player/imperial_empire_day_2009_sign_standing.iff")) { there.z += 0.6f; z += 0.6f; } //Empire/Remembrance Day Signs 2009 - hanging if (signTemplate.startsWith("object/tangible/sign/player/rebel_remembrance_day_2009_sign_hanging.iff") || signTemplate.startsWith("object/tangible/sign/player/imperial_empire_day_2009_sign_hanging.iff")) { there.z -= 0.3f; z -= 0.3f; } } //Generic House Medium - Windowed House if(structureTemplate.startsWith("object/building/player/player_house_generic_medium_windowed_s02.iff")) { //TCG Series 5 if (signTemplate.startsWith("object/tangible/tcg/series5/house_sign_tcg_hanging.iff")) { there.z -= 0.25f; z -= 0.25f; } //Empire/Remembrance Day Signs 2009 if (signTemplate.startsWith("object/tangible/sign/player/rebel_remembrance_day_2009_sign_hanging.iff") || signTemplate.startsWith("object/tangible/sign/player/imperial_empire_day_2009_sign_hanging.iff")) { there.z -= 0.25f; z -= 0.25f; } } //Custom Hanging PGC Sign if (signTemplate.startsWith("object/tangible/sign/player/pgc_sign_hanging.iff")) { if(structureTemplate.startsWith("object/building/player/player_house_naboo_small_style_02.iff")) { there.x += 0.5f; x += 0.5f; } if(structureTemplate.startsWith("object/building/player/player_house_corellia_large_style_01.iff")) { heading += 90; there.z -= 0.5f; z -= 0.5f; } if(structureTemplate.startsWith("object/building/player/player_house_corellia_large_style_02.iff") || structureTemplate.startsWith("object/building/player/player_house_corellia_small_style_02.iff") || structureTemplate.startsWith("object/building/player/player_house_corellia_small_style_02_floorplan_02.iff")) { heading += 90; there.z -= 0.1f; z -= 0.1f; } if(structureTemplate.startsWith("object/building/player/player_house_corellia_medium_style_01.iff")) { heading += 90; } if(structureTemplate.startsWith("object/building/player/player_house_corellia_small_style_01.iff") || structureTemplate.startsWith("object/building/player/player_house_corellia_small_style_01_floorplan_02.iff")) { heading += 90; there.x += 0.5f; x += 0.5f; } if(structureTemplate.startsWith("object/building/player/player_merchant_tent_style_01.iff") || structureTemplate.startsWith("object/building/player/player_merchant_tent_style_02.iff") || structureTemplate.startsWith("object/building/player/player_merchant_tent_style_03.iff")) { heading += 10; there.x += 0.3f; there.z -= 0.1f; x += 0.3f; z -= 0.1f; } if(structureTemplate.startsWith("object/building/player/player_house_tatooine_large_style_01.iff")) { there.z -= 0.1f; z -= 0.1f; } if(structureTemplate.startsWith("object/building/player/player_house_mustafar_lg.iff")) { heading += 180; there.x -= 0.3f; x -= 0.3f; } if(structureTemplate.startsWith("object/building/player/player_house_generic_large_style_01.iff") || structureTemplate.startsWith("object/building/player/player_house_generic_large_style_02.iff") || structureTemplate.startsWith("object/building/player/player_house_generic_medium_style_02.iff") || structureTemplate.startsWith("object/building/player/player_house_generic_small_style_02.iff")) { there.z += 0.2f; z += 0.2f; } if(structureTemplate.startsWith("object/building/player/player_house_generic_medium_windowed_s02.iff")) { there.z -= 0.2f; z -= 0.2f; } if(structureTemplate.startsWith("object/building/player/player_house_generic_small_style_01.iff")) { there.z += 0.2f; there.x += 0.7f; z += 0.2f; x += 0.7f; } if(structureTemplate.startsWith("object/building/player/player_house_naboo_small_style_01.iff")) { heading -= 10; there.x += 0.4f; x += 0.4f; } if(structureTemplate.startsWith("object/building/player/player_house_generic_small_windowed.iff")) { there.x += 0.5f; x += 0.5f; } if(structureTemplate.startsWith("object/building/player/player_house_generic_small_window_style_03.iff")) { there.x += 1; there.z -= 0.2f; x += 1; z -= 0.2f; } if(structureTemplate.startsWith("object/building/player/player_house_naboo_small_window_style_01.iff")) { heading -= 12; there.x += 0.6f; x += 0.6f; } } //more fucked up houses because of the Empire/Remembrance Day Signs. if(structureTemplate.startsWith("object/building/player/player_house_corellia_small_style_02_floorplan_02.iff") || structureTemplate.startsWith("object/building/player/player_house_corellia_small_style_02.iff") || structureTemplate.startsWith("object/building/player/player_house_tatooine_small_style_02.iff") || structureTemplate.startsWith("object/building/player/player_house_tatooine_large_style_01.iff")) { //Empire/Remembrance Day Signs 2009 if (signTemplate.startsWith("object/tangible/sign/player/rebel_remembrance_day_2009_sign_hanging.iff") || signTemplate.startsWith("object/tangible/sign/player/imperial_empire_day_2009_sign_hanging.iff")) { there.z -= 0.2f; z -= 0.2f; } } //Large Naboo House if (structureTemplate.startsWith("object/building/player/player_house_naboo_large_style_01.iff")) { if (signTemplate.startsWith("object/tangible/sign/player/rebel_remembrance_day_2009_sign_hanging.iff") || signTemplate.startsWith("object/tangible/sign/player/imperial_empire_day_2009_sign_hanging.iff")) { there.z += 0.1f; z += 0.1f; } } // TCG Structure - Vehicle Garage if ( structureTemplate.startsWith("object/building/player/player_house_tcg_vehicle_garage.iff") ) { if ( signTemplate.startsWith("object/tangible/tcg/series3/house_sign_tcg_s01.iff") || signTemplate.startsWith("object/tangible/sign/player/house_address_halloween_sign.iff") || signTemplate.startsWith("object/tangible/sign/player/imperial_empire_day_2009_sign_hanging.iff") || signTemplate.startsWith("object/tangible/sign/player/rebel_remembrance_day_2009_sign_hanging.iff") || signTemplate.startsWith("object/tangible/tcg/series5/house_sign_tcg_hanging.iff") || signTemplate.startsWith("object/tangible/sign/player/pgc_sign_hanging.iff")) { heading += 90; there.z -= 0.3f; z -= 0.3f; } } // TCG Structure - V.I.P. Bunker if ( structureTemplate.startsWith("object/building/player/player_house_tcg_vip_bunker.iff") ) { if ( signTemplate.startsWith("object/tangible/tcg/series3/house_sign_tcg_s01.iff") || signTemplate.startsWith("object/tangible/sign/player/house_address_halloween_sign.iff") || signTemplate.startsWith("object/tangible/sign/player/imperial_empire_day_2009_sign_hanging.iff") || signTemplate.startsWith("object/tangible/sign/player/rebel_remembrance_day_2009_sign_hanging.iff") || signTemplate.startsWith("object/tangible/tcg/series5/house_sign_tcg_hanging.iff") || signTemplate.startsWith("object/tangible/sign/player/pgc_sign_hanging.iff")) { heading += 90; there.z += 0.3f; z += 0.3f; } } // TCG Structure - Commando Bunker if ( structureTemplate.startsWith("object/building/player/player_house_tcg_commando_bunker.iff") ) { if ( signTemplate.startsWith("object/tangible/tcg/series3/house_sign_tcg_s01.iff") || signTemplate.startsWith("object/tangible/sign/player/house_address_halloween_sign.iff") || signTemplate.startsWith("object/tangible/sign/player/imperial_empire_day_2009_sign_hanging.iff") || signTemplate.startsWith("object/tangible/sign/player/rebel_remembrance_day_2009_sign_hanging.iff") || signTemplate.startsWith("object/tangible/tcg/series5/house_sign_tcg_hanging.iff") || signTemplate.startsWith("object/tangible/sign/player/pgc_sign_hanging.iff")) { heading += 90; there.z -= 0.6f; z -= 0.6f; } } } location spawn = there; if ( sYaw != 0f ) { location newspawn = transformDeltaWorldCoord(here, x, z, sYaw); newspawn.y = there.y; spawn = newspawn; //LOG("structureSign","createStructureSign: spawn = " + spawn.toString()); } if ( (signTemplate != null) && (!signTemplate.equals("")) ) { //LOG("structureSign","createStructureSign: sign template = " + signTemplate); obj_id sign = createObject(signTemplate, spawn); if ( isIdValid(sign) ) { string preSignName = ""; string postSignName = ""; string viewSignName = signName; if ( isAbandoned( structure ) || isPreAbandoned( structure ) ) { int indexOfAbandonedText = signName.indexOf(ABANDONED_TEXT); string filteredSignName = ""; boolean foundAbandonedText = false; while (indexOfAbandonedText != -1) { filteredSignName += signName.substring(0, indexOfAbandonedText); signName = signName.substring(indexOfAbandonedText + ABANDONED_TEXT.length()); indexOfAbandonedText = signName.indexOf(ABANDONED_TEXT); foundAbandonedText = true; } if (foundAbandonedText) { signName = filteredSignName + signName; viewSignName = signName; } postSignName = ABANDONED_TEXT; if ( viewSignName.length() > 100 ) { viewSignName = viewSignName.substring(0, 99); } } //Player City - Inactive Structure Rules if(isCityAbandoned(structure) && cityIsInactivePackupActive()) { int indexOfAbandonedText = signName.indexOf(CITY_ABANDONED_TEXT); string filteredSignName = ""; boolean foundAbandonedText = false; while (indexOfAbandonedText != -1) { filteredSignName += signName.substring(0, indexOfAbandonedText); signName = signName.substring(indexOfAbandonedText + CITY_ABANDONED_TEXT.length()); indexOfAbandonedText = signName.indexOf(CITY_ABANDONED_TEXT); foundAbandonedText = true; } if (foundAbandonedText) { signName = filteredSignName + signName; viewSignName = signName; } postSignName = CITY_ABANDONED_TEXT; if ( viewSignName.length() > 100 ) { viewSignName = viewSignName.substring(0, 99); } } //LOG("structureSign","createStructureSign: setting sign name to '" + signName + "'"); setName(sign, preSignName + viewSignName + postSignName); //LOG("structureSign","createStructureSign: setting objvars"); setObjVar(structure, VAR_SIGN_ID, sign); setObjVar(structure, VAR_SIGN_NAME, signName); setObjVar(structure, VAR_SIGN_TYPE, signType); /* This entire section is dedicated to Yaw */ float tYaw = sYaw + heading; if ( tYaw != 0f ) { //LOG("structureSign","createStructureSign: rotating sign..."); setYaw(sign, tYaw); } string[] allStructures = dataTableGetStringColumn(SIGN_ADJUST_SIGN_BY_TEMPLATE, "structure_template"); if(allStructures != null && allStructures.length > 0) { resizeable string[] thisStructure = new string[0]; for(int i = 0; i < allStructures.length; i++) { if(structureTemplate.equals(allStructures[i])) { thisStructure = utils.addElement(thisStructure, allStructures[i]); } } } /* string templateName = getTemplateName(sign); //If using a custom HANGING sign on a mustafar bunker, we have to modify the yaw. if (structureTemplate.startsWith("object/building/player/player_house_mustafar_lg") && templateName.startsWith("object/tangible/sign/player/house_address") && !templateName.startsWith("object/tangible/sign/player/house_address_corellia")) { setYaw(sign, tYaw + 90.0f); } //HANGING TCG Signs, Empire Day 2009 Signs, Remembrance Day 2009 Signs. if((structureTemplate.startsWith("object/building/player/player_house_mustafar_lg") && templateName.startsWith("object/tangible/tcg/series3/house_sign_tcg_s01")) || (structureTemplate.startsWith("object/building/player/player_house_mustafar_lg") && templateName.startsWith("object/tangible/sign/player/imperial_empire_day_2009_sign_hanging")) || (structureTemplate.startsWith("object/building/player/player_house_mustafar_lg") && templateName.startsWith("object/tangible/sign/player/rebel_remembrance_day_2009_sign_hanging")) || (structureTemplate.startsWith("object/building/player/player_house_mustafar_lg") && templateName.startsWith("object/tangible/tcg/series5/house_sign_tcg_hanging"))) { setYaw(sign, tYaw + 90.0f); } //If using a custom HANGING sign on a corellia building, we have to modify the yaw. if ((structureTemplate.startsWith("object/building/player/player_house_corellia") && templateName.startsWith("object/tangible/sign/player/house_address") && !templateName.startsWith("object/tangible/sign/player/house_address_corellia")) || (structureTemplate.startsWith("object/building/player/player_house_corellia") && templateName.startsWith("object/tangible/tcg/series5/house_sign_tcg_hanging")) || (structureTemplate.startsWith("object/building/player/player_house_corellia") && templateName.startsWith("object/tangible/sign/player/rebel_remembrance_day_2009_sign_hanging")) || (structureTemplate.startsWith("object/building/player/player_house_corellia") && templateName.startsWith("object/tangible/sign/player/imperial_empire_day_2009_sign_hanging"))) { setYaw(sign, tYaw + 90.0f); } //If using a custom STANDING sign on a merchant tent, we have to modify the yaw. if (structureTemplate.startsWith("object/building/player/player_merchant_tent") && templateName.startsWith("object/tangible/sign/player/shop_sign") && !templateName.startsWith("object/tangible/sign/player/shop_sign_s0")) { setYaw(sign, tYaw + 180.0f); } //If using a custom HANGING sign on a merchant tent, we have to modify the yaw. if (structureTemplate.startsWith("object/building/player/player_merchant_tent") && !templateName.startsWith("object/tangible/sign/player/house_address_corellia") && !signTemplate.startsWith("object/tangible/tcg/series3/house_sign_tcg_s02") && !templateName.startsWith("object/tangible/sign/player/shop_sign")) { setYaw(sign, tYaw + 90.0f); } //If using a custom HANGING sign on a corellian guild hall, we have to modify the yaw. if ((structureTemplate.startsWith("object/building/player/player_guildhall_corellia") && templateName.startsWith("object/tangible/sign/player/house_address") && !templateName.startsWith("object/tangible/sign/player/house_address_corellia")) || (structureTemplate.startsWith("object/building/player/player_guildhall_corellia") && templateName.startsWith("object/tangible/tcg/series5/house_sign_tcg_hanging"))) { setYaw(sign, tYaw + 90.0f); } //If using a custom STANDING sign on a tatooine guild hall, we have to modify the yaw. if (structureTemplate.startsWith("object/building/player/player_guildhall_tatooine") && templateName.startsWith("object/tangible/sign/player/shop_sign_") && !templateName.startsWith("object/tangible/sign/player/shop_sign_s0")) { setYaw(sign, tYaw + 180.0f); } //If using a custom STANDING sign on a generic large house, we have to modify the yaw. if (structureTemplate.startsWith("object/building/player/player_house_generic_large_style_01") && templateName.startsWith("object/tangible/sign/player/shop_sign_") && !templateName.startsWith("object/tangible/sign/player/shop_sign_s0")) { setYaw(sign, tYaw + 180.0f); } //TCG Set 5 Hanging Sign with Corellia Theaters if (structureTemplate.startsWith("object/building/player/city/theater_corellia") && templateName.startsWith("object/tangible/tcg/series5/house_sign_tcg_hanging")) { setYaw(sign, tYaw + 90.0f); } */ //LOG("structureSign","createStructureSign: return sign id = " + sign); utils.setScriptVar(sign, "player_structure.parent", structure); return sign; } } else { //LOG("structureSign","createStructureSign: bad sign template!!"); } } else { //LOG("structureSign","createStructureSign: row = empty!"); } } else { //LOG("structureSign","createStructureSign: no sign required..."); } return null; } obj_id createStructureSign(obj_id structure) { if (!isIdValid(structure) ) return null; float sYaw = getYaw(structure); sYaw = (float)(Math.round(sYaw)); return createStructureSign(structure, sYaw); } void destroyStructureSign(obj_id structure) { if ( !isIdValid(structure) ) return; obj_id sign = getObjIdObjVar(structure, VAR_SIGN_ID); if ( isIdValid(sign) && exists(sign) ) destroyObject(sign); removeObjVar(structure, VAR_SIGN_ID); } /*********************************************************************** * @brief sets/adds to the remaining power of the specified building, if possible * * @param obj_id bldg * @param obj_id energon * * @return int - amt of power remaining; -1 on error ***********************************************************************/ float powerInstallation(obj_id bldg, obj_id energon) { //LOG("energon","****** player_structure.powerInstallation: now = " + getGameTime() + " ***********"); if ( !isIdValid(bldg) || !isIdValid(energon) ) { //LOG("energon","invalid params! returning -1"); return -1f; } //LOG("energon","params: bldg = " + bldg + " energon = " + energon); int energonGOT = getGameObjectType(energon); if ( isGameObjectTypeOf(energonGOT, GOT_resource_container) ) { //LOG("energon","energon is not a resource container! returning -1"); return -1f; } int bldgGOT = getGameObjectType(bldg); if ( !isGameObjectTypeOf(bldgGOT, GOT_installation) ) { //LOG("energon","bldg is not of GOT type GOT_installation! returning -1"); return -1f; } obj_id rId = getResourceContainerResourceType(energon); if ( !isIdValid(rId) ) { //LOG("energon","invalid resource type obj_id! returning -1"); return -1f; } if ( !isResourceDerivedFrom(rId, "energy") || !isResourceDerivedFrom(rId, "radioactive") ) { //LOG("energon","resource type is not derived from resource class ENERGY! returning -1"); return -1f; } int amt = resource.getPotentialEnergyValue(energon); if ( amt > 0f ) { //LOG("energon","attempting to increment power value: amt = " + amt); return powerInstallation(bldg, amt); } //LOG("energon","default powerInstallation fall-thru..."); return -1f; } float powerInstallation(obj_id bldg, int amt) { if ( !isIdValid(bldg) || (amt <= 0f) ) return -1f; incrementPowerValue(bldg, amt); return getPowerValue(bldg); } void validateHarvestedResources(obj_id structure) { if ( !isIdValid(structure) ) return; if ( utils.hasScriptVar(structure, "validatedResources") ) return; if ( !isHarvester(structure) && !isGenerator(structure) ) return; string listPath = "resource"; if ( hasObjVar(structure, listPath) ) { obj_var_list ovl = getObjVarList(structure, listPath); if ( ovl != null ) { int numItems = ovl.getNumItems(); for ( int i = 0; i < numItems; i++ ) { obj_var ov = ovl.getObjVar(i); if ( ov != null ) { string ovName = ov.getName(); obj_id rId = utils.stringToObjId(ovName); if ( !isValidResourceId(rId) ) { //replace fubar resource! float amt = ov.getFloatData(); //get master resource type for harvester string mType = getHarvesterMasterResource(structure); if ( mType != null && !mType.equals("") ) { obj_id newId = pickRandomNonDepeletedResource(mType); if ( isIdValid(newId) ) { setObjVar(structure, "resource." + newId, amt); } else { CustomerServiceLog("trade","bad resouce found in installation #" + structure + " and the system was unable to find a suitable replacement!"); CustomerServiceLog("trade","installation #" + structure + " report: bad resource id = " + ovName + " amt = " + Math.round(amt)); } } else { CustomerServiceLog("trade","bad resouce found in installation #" + structure + " and the system was unable to determine a suitable resource type for replacement!"); CustomerServiceLog("trade","installation #" + structure + " report: bad resource id = " + ovName + " amt = " + Math.round(amt)); } //remove bad objvar removeObjVar(structure, listPath + "." + ovName); } } } } } utils.setScriptVar(structure, "validatedResources", true); } string getHarvesterMasterResource(obj_id structure) { if ( !isIdValid(structure) ) return null; if ( !isHarvester(structure) && !isGenerator(structure) ) return null; string template = getTemplateName(structure); if ( template == null || template.equals("") ) return null; if ( isHarvester(structure) ) { if ( template.indexOf("mining_ore") > -1 ) return "mineral"; if ( template.indexOf("mining_gas") > -1 ) return "gas"; if ( template.indexOf("mining_liquid") > -1 ) { if ( template.indexOf("moisture") > -1 ) return "water"; return "chemical"; } if ( template.indexOf("mining_organic") > -1 ) { if ( template.indexOf("creature") > -1 ) return "creature_resources"; return "flora_resources"; } } else if ( isGenerator(structure) ) { if ( template.indexOf("fusion") > -1 ) return "radioactive"; if ( template.indexOf("solar") > -1 ) return "energy_renewable_unlimited_solar"; if ( template.indexOf("wind") > -1 ) return "energy_renewable_unlimited_wind"; } return null; } boolean canReclaimDeed(obj_id structure) { if ( !isIdValid(structure) ) return false; string template = getTemplateName(structure); return canReclaimDeed(template); } boolean canReclaimDeed(string structureTemplate) { if ( structureTemplate == null || structureTemplate.equals("") ) return false; return dataTableGetInt(PLAYER_STRUCTURE_DATATABLE, structureTemplate, "CAN_RECLAIM") == 1; } void showChangeSignSui(obj_id structure, obj_id player) { if ( !isIdValid(structure) || !isIdValid(player) ) return; int skillmod = getSkillStatMod(player, "shop_sign"); if ( skillmod < 1 ) return; resizeable string[] entries = new string[0]; for ( int i = 0; i <= skillmod; i++ ) { if (i < SIGN_NAMES.length) entries = utils.addElement(entries, utils.packStringId(SIGN_NAMES[i])); else break; } if ( entries != null && entries.length > 0 ) { string prompt = "@player_structure:changesign_prompt"; string title = "@player_structure:changesign_title"; sui.listbox(structure, player, prompt, sui.OK_CANCEL, title, entries, "handleChangeSignSui"); } } string getStructureName(obj_id structure) { if ( !isIdValid(structure) ) return null; if ( isBuilding(structure) && hasObjVar(structure, VAR_SIGN_NAME) ) { string signName = getStringObjVar(structure, VAR_SIGN_NAME); if ( signName != null && !signName.equals("") ) return signName; } return utils.getStringName(structure); } boolean canPlaceGarage(location loc, float range, string template) { if (1 == dataTableGetInt(player_structure.PLAYER_STRUCTURE_DATATABLE, template, "GARAGE")) { obj_id check = getFirstObjectWithTemplate(loc, range, template); if (check != null) return false; } return true; }//end canPlaceGarage boolean hasMaintenanceDroid(obj_id player) { obj_id[] datapad = getContents(utils.getPlayerDatapad(player)); for (int i = 0; i < datapad.length; i++) { if (hasObjVar(datapad[i], "module_data.struct_maint")) return true; } return false; } obj_id[] getMaintenanceDroids(obj_id player) { resizeable obj_id[] droids = new obj_id[0]; obj_id[] datapad = getContents(utils.getPlayerDatapad(player)); for (int i = 0; i < datapad.length; i++) { if (hasObjVar(datapad[i], "module_data.struct_maint")) droids = utils.addElement(droids, datapad[i]); } return droids; } //this is to flag the NEW buildings, so we know not to convert their lost costs // when they are re-deeded: // added 10-22-4, delete this in a month or two void flagConverted( string template, obj_id structure ) { //if this is an OLD guildhall, it cost 9 lots, except for tatooine halls which cost 7 if ( template.indexOf( "_guildhall_" ) != -1 ) { //newly placed halls need this objvar, so you don't get 9 or 7 lots for re-deeding them: setObjVar(structure, "newBuilding", true ); setObjVar(structure, "newBuildPartTwo", true ); } else if ( template.indexOf( "structure_factory" ) != -1 ) { //slap these with the same objvar so that when re-deeded, the player only gets back one lot: setObjVar(structure, "newBuilding", true ); setObjVar(structure, "newBuildPartTwo", true ); } else if ( template.indexOf( "player_house_" ) != -1 ) //If it's a large house, credit them with the original number of lots for it <<< -1) { // Rename some buttons and show the sui //setSUIProperty(pid, sui.MSGBOX_BTN_OK, sui.PROP_TEXT, strConfirm); showSUIPage(pid); } return; } else { string_id strSpam = new string_id(STF_FILE, "structure_condemned_owner_no_credits"); prose_package pp = new prose_package(); prose.setStringId(pp, strSpam); prose.setDI(pp, intRepairCost); sendSystemMessageProse(objItem, pp); return; } } else { string_id strSpam = new string_id(STF_FILE, "structure_condemned_not_owner"); sendSystemMessage(objItem, strSpam); return; } } // 2 do you have enough money to pay maintenance fees } int getStructureRepairCost(obj_id structure) { int condition = getStructureCondition(structure); int max_condition = getMaxCondition(structure); int damage = max_condition - condition; int maint_pool = getBankBalance(structure); // repairs cost the maintenance rate per 3 points. float per_point_cost = getBaseMaintenanceRate( structure ) / 3.0f; int repair_cost = (int)(damage * per_point_cost); return repair_cost; } boolean isStructureCondemned(obj_id objStructure) { return hasObjVar(objStructure, "player_structure.condemned"); } void sendCondemnedMail(obj_id objStructure) { obj_id objOwner = getOwner(objStructure); string strName = getPlayerName(objOwner); string_id strSubject = new string_id(STF_FILE, "structure_condemned_subject"); string_id strBody = new string_id(STF_FILE, "structure_condemned_body"); int intRepairCost = getStructureRepairCost(objStructure); location loc = getLocation(objStructure); string area = loc.area; if (area != null) area = area.substring(0,1).toUpperCase() + area.substring(1); string loc_str = "(" + loc.x + ", " + loc.z + " " + loc.area + ")"; prose_package pp = new prose_package(); prose.setStringId(pp, strBody); prose.setTO(pp, loc_str); prose.setTT(pp, objStructure); prose.setDI(pp, intRepairCost); utils.sendMail(strSubject, pp, strName , "@player_structure:management"); return; } int getMaintenanceHeartbeat() { const int MAINTENANCE_HEARTBEAT = 1800; string strConfigSetting = getConfigSetting("GameServer", "maintenanceHeartbeat"); if((strConfigSetting!=null)&&(strConfigSetting!="")) { int intHeartBeat = utils.stringToInt(strConfigSetting); if(intHeartBeat>0) { return intHeartBeat; } } return MAINTENANCE_HEARTBEAT; } void sendOutOfMaintenanceMail(obj_id objStructure) { //LOG("test", "Sending email"); obj_id objOwner = getOwner(objStructure); string strName = getPlayerName(objOwner); string_id strSubject = new string_id(STF_FILE, "structure_maintenance_empty_subject"); string_id strBody = new string_id(STF_FILE, "structure_maintenance_empty_body"); location loc = getLocation(objStructure); string area = loc.area; if (area != null) area = area.substring(0,1).toUpperCase() + area.substring(1); string loc_str = "(" + loc.x + ", " + loc.z + " " + loc.area + ")"; //LOG("test", "sending email "+strSubject+" with body "+strBody+" and loc_str "+loc_str); prose_package pp = new prose_package(); prose.setStringId(pp, strBody); prose.setTO(pp, loc_str); prose.setTT(pp, objStructure); //prose.setDI(pp, intRepairCost); //LOG("test", "sending mail to "+strName); string strTest = getString(strSubject); //LOG("test", "strTest1 is "+strTest); strTest = getString(strBody); //LOG("test", "strTest2 is "+strTest); utils.sendMail(strSubject, pp, strName , "@player_structure:management"); return; } /*********************************************************************** * @brief Checks to see if the object template name starts with object/building * * @param string objectTemplateName * * @return boolean ***********************************************************************/ boolean isFactionPerkBase (string objectTemplateName) { return objectTemplateName.indexOf ("object/building/faction_perk/hq/") != -1; } /*********************************************************************** * @brief Checks to see if the object template name starts with object/building * * @param string objectTemplateName * * @return boolean ***********************************************************************/ boolean isFactionPerkBaseDeed(obj_id objDeed) { return isFactionPerkBaseDeed(getTemplateName(objDeed)); } boolean isFactionPerkBaseDeed (string deedObjectTemplateName) { return deedObjectTemplateName.indexOf ("object/tangible/deed/faction_perk/hq/") != -1; } boolean canPlaceFactionPerkDeed(obj_id objDeed, obj_id objPlayer) { const float CHECK_RANGE = 600f; const int BASES_ALLOWED = 3; if(player_structure.isFactionPerkBaseDeed(objDeed)) { location locTest = getLocation(objPlayer); obj_id[] objBases = getAllObjectsWithScript(locTest, CHECK_RANGE, "faction_perk.hq.loader"); if((objBases!=null)&&(objBases.length>=BASES_ALLOWED)) { string_id strSpam = new string_id("gcw", "too_many_bases"); sendSystemMessage(objPlayer, strSpam); return false; } } return true; } // PLAYER_STRUCTURE_VALIDATION_DATATABLE contains hopper validation values int validateHopperSize(obj_id structureObject) { int objvar_hopper = 0; if(!isIdValid(structureObject)) { return 0; } string templateName = getTemplateName(structureObject); if(templateName == null || templateName.length() <= 0) { return 0; } dictionary dict = utils.dataTableGetRow(PLAYER_STRUCTURE_VALIDATION_DATATABLE, templateName); if(dict == null) { return -1; } int minHopper = dataTableGetInt(PLAYER_STRUCTURE_VALIDATION_DATATABLE, templateName, DATATABLE_COL_HOPPER_MIN); int maxHopper = dataTableGetInt(PLAYER_STRUCTURE_VALIDATION_DATATABLE, templateName, DATATABLE_COL_HOPPER_MAX); if(minHopper <= 0 || maxHopper <= 0) { return 0; } if(hasObjVar(structureObject, VAR_DEED_MAX_HOPPER)) { objvar_hopper = getIntObjVar(structureObject, VAR_DEED_MAX_HOPPER); } else // Missing objvar. Set the objvar on the object to an average value. { objvar_hopper = (minHopper + maxHopper) / 2; // Average hopper size. return objvar_hopper; } // Something is wrong with this hopper size. The hopper needs to be resized to an average between min and max. // It is not possible to get a minimum hopper size, unless the structure had a problem with the deed/placement/redeed phases. if(objvar_hopper <= minHopper) { objvar_hopper = (minHopper + maxHopper) / 2; // Average hopper size. } // Make sure the object's max hopper size is not insane. if(objvar_hopper > HARVESTER_MAX_HOPPER_SIZE) { objvar_hopper = HARVESTER_MAX_HOPPER_SIZE; } return objvar_hopper; } //This is the primary function used to evaluate any structure for //packup ability. If this returns a true, the structure can be //packed by a player when the structure has been abandoned or packed //by the owner via radial option boolean doesUnmarkedStructureQualifyForHousePackup(obj_id structure) { if (!isBuilding(structure) && !isInstallation(structure)) return false; if (isInstallation(structure) && !isFactory(structure)) return false; if (isCivic(structure)) return false; string templateName = getTemplateName(structure); if (templateName == null || isFactionPerkBase(templateName)) return false; return true; } boolean needsPreAbandonCheck(obj_id structure) { if (!isIdValid(structure)) return false; if (!utils.checkConfigFlag("GameServer", "enableHousePackup")) return false; if (isAbandoned(structure) || isPreAbandoned(structure)) return true; if (!doesUnmarkedStructureQualifyForHousePackup(structure)) return false; return true; } boolean needsAbandonCheck(obj_id structure) { if (!isIdValid(structure)) return false; if (!utils.checkConfigFlag("GameServer", "enableAbandonedHousePackup")) return false; if (isPreAbandoned(structure) || isAbandoned(structure)) return true; if (!doesUnmarkedStructureQualifyForHousePackup(structure)) return false; return true; } boolean needsCityAbandonCheck(obj_id structure) { if (!isIdValid(structure)) { LOG("sissynoid", "Failed 'needsCityAbandonedCheck - Invalid STructure"); return false; } if(!cityIsInactivePackupActive()) //server config: cityCitizenshipInactivePackupStartTimeEpoch=1241161260 (May 1, 2009) { LOG("sissynoid", "Failed 'needsCityAbandonedCheck - cityIsInactivePackupActive Config Inactive"); return false; } if (!doesUnmarkedStructureQualifyForHousePackup(structure)) { LOG("sissynoid", "Failed 'needsCityAbandonedCheck - Structure is unpackable"); return false; } location loc = getLocation(structure); int city_id = getCityAtLocation(loc, 0); if(!cityExists(city_id)) { LOG("sissynoid", "Failed 'needsCityAbandonedCheck - No City Exists at this Location"); return false; } return true; } string getStructureInfo(obj_id structure) { const string yes = "Y|"; const string no = "N|"; const string blank = "|"; const string templateName = getTemplateName(structure); const obj_id ownerId = getOwner(structure); string result = "|" + structure + "|" + ownerId + "|" + templateName + "|"; result += needsPreAbandonCheck(structure) ? yes : no; result += needsAbandonCheck(structure) ? yes : no; result += doesUnmarkedStructureQualifyForHousePackup(structure) ? yes : no; result += isIdValid(structure) ? yes : no; result += isAccountQualifiedForHousePackup(ownerId) ? yes : no; result += isBuilding(structure) ? yes : no; result += isInstallation(structure) ? yes : no; result += isFactory(structure) ? yes : no; result += isFactionPerkBase(templateName) ? yes : no; result += isCivic(structure) ? yes : no; result += isInWorld(structure) ? yes : no; result += isInWorldCell(structure) ? yes : no; if (hasObjVar(structure, VAR_CIVIC)) result += getIntObjVar(structure, VAR_CIVIC) + "|"; else result += blank; if (hasObjVar(structure, VAR_ABANDONED)) result += getIntObjVar(structure, VAR_ABANDONED); else result += blank; if (hasObjVar(structure, VAR_LAST_MAINTANENCE)) result += getIntObjVar(structure, VAR_LAST_MAINTANENCE) + "|"; else result += blank; return result; } //checks to see if we are an elite harvester boolean isEliteHarvester(obj_id structure) { if(isIdValid(structure)) { string templateName = getTemplateName(structure); if(templateName.endsWith("_style_4.iff") || templateName.endsWith("_elite.iff")) return true; } return false; } // this option is only available if the structure is abandoned and the player // attempting to pack it is not in the free trial boolean canShowPackOption(obj_id player, obj_id structure) { if (!isIdValid(structure) || !isIdValid(player)) return false; if (!utils.checkConfigFlag("GameServer", "allowPlayersToPackAbandonedStructures")) return false; if (!player_structure.isAbandoned(structure)) return false; if (utils.isFreeTrial(player)) return false; if (!isCommoditiesServerAvailable()) return false; return true; } boolean canPlayerPackAbandonedStructure(obj_id player, obj_id structure) { if (!canShowPackOption(player, structure)) return false; if (isAtPendingLoadRequestLimit()) return false; if (!player.isLoaded() || !player.isAuthoritative()) return false; if (!structure.isLoaded() || !structure.isAuthoritative()) return false; return true; } // Check if a structure has vendors and return if players are // allowed to pack boolean canPackStructureWithVendors(obj_id player, obj_id structure) { const boolean hasVendors = hasVendors(structure); if (hasVendors && !vendor_lib.isVendorPackUpEnabled()) { sendSystemMessage(player, new string_id("sui", "cant_pack_vendors")); return false; } if (hasVendors && !isCommoditiesServerAvailable()) { sendSystemMessage(player, new string_id("sui", "cannot_pack_now")); return false; } return true; } //The main function for packing up abandoned houses void packAbandonedBuilding(obj_id player, obj_id structure, dictionary params) { // if the 24hr abandoned house packup timer has expired, // reset the 24hr abandoned house packup timer and tally // and start the packup process, thus starting a new // 24hr abandoned house packup timer and tally if (hasObjVar(player, HOUSE_PACKUP_DAILY_TIMER_OBJVAR)) { int resetTime = getIntObjVar(player, HOUSE_PACKUP_DAILY_TIMER_OBJVAR); if (getGameTime() >= resetTime) { removeObjVar(player, HOUSE_PACKUP_DAILY_TIMER_OBJVAR); removeObjVar(player, HOUSE_PACKUP_DAILY_TALLY_OBJVAR); params.put("structure", structure); messageTo(player, "msgFinalizePackup", params, 0, false); return; } } //if this is the player's first pack up of the day. if(!hasObjVar(player, HOUSE_PACKUP_DAILY_TALLY_OBJVAR)) { params.put("structure", structure); messageTo(player, "msgFinalizePackup", params, 0, false); return; } int dailyHousePacking = getIntObjVar (player, HOUSE_PACKUP_DAILY_TALLY_OBJVAR); if(dailyHousePacking < 0) dailyHousePacking = 0; if(dailyHousePacking > MAX_PACKUP_PER_DAY) dailyHousePacking = MAX_PACKUP_PER_DAY; if (dailyHousePacking < MAX_PACKUP_PER_DAY) { //need to clean up any player that doesnt have a timer if(!hasObjVar (player, HOUSE_PACKUP_DAILY_TIMER_OBJVAR)) removeObjVar (player, HOUSE_PACKUP_DAILY_TALLY_OBJVAR); params.put("structure", structure); messageTo(player, "msgFinalizePackup", params, 0, false); return; } //this canPackMoreToday function is an almost exact duplicate of //the code above. else if(!canPackMoreToday(player)) { //This is where the Comm is sent to the player saying they //have reached the daily quota. if(!hasObjVar (player, HOUSE_PACKUP_DAILY_TIMER_OBJVAR)) { int resetTime = getGameTime() + TIME_TO_NEXT_PACKUP; // 24 hours blog("packAbandonedBuilding - resetting time to next packup: "+resetTime); setObjVar (player, HOUSE_PACKUP_DAILY_TIMER_OBJVAR, resetTime); } int timeLeft = getIntObjVar (player, HOUSE_PACKUP_DAILY_TIMER_OBJVAR); timeLeft -= getGameTime(); string displayTime = utils.assembleTimeRemainToUse(timeLeft, false); string_id stringId = new string_id("spam", "wait_twenty_four"); prose_package p = new prose_package(); prose.setStringId(p, stringId); prose.setDI(p, MAX_PACKUP_PER_DAY); prose.setTT(p, displayTime); commPlayers(player, "object/mobile/dressed_hiddendagger_pilot_m_01.iff", "sound/sys_comm_other.snd", 5f, player, p); messageTo(player, "handleFailedStructurePackup", null, 0, false); //this appears to be a call to TT's test script //remove the delay message so that it doesn't confuse the player into //thinking they can pack more houses later messageTo(player, "handlePlayerStructurePackupLockoutRemoval", null, 0, false); } //Calls back to the structure so it can send a messageto right back here again. else { blog("player_structure.packAbandonedBuilding I HAVER FALLEN THROUGH THE NORMAL CONDITIONS!!!!"); removeObjVar (player, HOUSE_PACKUP_DAILY_TIMER_OBJVAR); removeObjVar (player, HOUSE_PACKUP_DAILY_TALLY_OBJVAR); messageTo (structure, "packAbandonedBuilding", params, 4, false); } } /* This function needs to check if the player's DAILY TIMER objvar has expired. This function should also check for the existance of a daily tally, if none exists the player can pack the structure. If the tally exists and is les than daily max, then the player can pack the structure. If the player has packed houses and reached or exceeded the max, return false. */ boolean canPackMoreToday(obj_id player) { blog("canPackMoreToday - Init."); if(!isIdValid(player)) return false; if(!hasObjVar(player, HOUSE_PACKUP_DAILY_TALLY_OBJVAR)) { blog("canPackMoreToday - Player has no tally at all and can pack more."); return true; } blog("canPackMoreToday - Player has pack up DAILY TALLY objvar"); //If the player does not have the TIMER objvar, the day has expired if(!hasObjVar (player, HOUSE_PACKUP_DAILY_TIMER_OBJVAR)) { blog("canPackMoreToday - The Player CAN PACK MORE"); return true; } blog("canPackMoreToday - Player has pack up DAILY TIMER objvar"); int dailyHousePacking = getIntObjVar (player, HOUSE_PACKUP_DAILY_TALLY_OBJVAR); if(dailyHousePacking < 0) { CustomerServiceLog("playerStructure","House Pack Up - Player " + player + "(" + getName(player) + ") had an INVALID pack up tally amount of less than zero. We are correcting by setting to ZERO"); dailyHousePacking = 0; } blog("canPackMoreToday - Player has dailyHousePacking: "+dailyHousePacking); if(dailyHousePacking > MAX_PACKUP_PER_DAY) dailyHousePacking = MAX_PACKUP_PER_DAY; blog("canPackMoreToday - Player has dailyHousePacking: "+MAX_PACKUP_PER_DAY); if (dailyHousePacking < MAX_PACKUP_PER_DAY) { blog("canPackMoreToday - The Player CAN PACK MORE"); return true; } blog("canPackMoreToday - the player has met or exceeded the MAX_PACKUP_PER_DAY but we need to check to make sure that wasn't yesterday's timer."); int resetTime = getIntObjVar (player, HOUSE_PACKUP_DAILY_TIMER_OBJVAR); blog("canPackMoreToday - timer resetTime: "+resetTime); blog("canPackMoreToday - timer resetTime - gameTime: "+(resetTime - getGameTime())); if (resetTime - getGameTime() <= 0) { blog("canPackMoreToday - timer has expired."); return true; } blog("canPackMoreToday - timer has not expired."); return false; } /* HOUSE PACK UP isPlayerGatedFromHousePackUp() Check to see the players current status regarding packing up. 1. If the player can pack more and has no lock out timer, the player is NOT GATED (retrun false) 2. If the player is locked out adn can pack more, send them a system message saying how long before they can pack more. 3. If the player cannot pack any more today, (immediately) send them a communication saying so. */ boolean isPlayerGatedFromHousePackUp(obj_id player) { blog("player_structure.isPlayerGatedFromHousePackUp init"); if(!isValidId(player) || !exists(player)) return true; blog("player_structure.isPlayerGatedFromHousePackUp is calling canPackMoreToday(player)"); boolean canPackMore = canPackMoreToday(player); boolean playerLockedOut = isPlayerLockedOutOfHousePackup(player); if(canPackMore && !playerLockedOut) { blog("player_structure.isPlayerGatedFromHousePackUp - canPackMoreToday(player) && !utils.hasScriptVar(player, SCRIPTVAR_HOUSE_PACKUP_LOCKOUT_TIME)"); //Player hasn't reached quota for the day. //The player has no script var and is not locked out. return false; } else if(playerLockedOut && canPackMore) { blog("player_structure.isPlayerLockedOutOfHousePackup PLAYER HAS BEEN LOCKED OUT"); int timeNeeded = utils.getIntScriptVar(player, SCRIPTVAR_HOUSE_PACKUP_LOCKOUT_TIME) + (int)HOUSE_PACKUP_LOCKOUT_TIMER; int timeNow = getGameTime(); blog("player_structure.isPlayerLockedOutOfHousePackup timeNeeded: "+timeNeeded); blog("player_structure.isPlayerLockedOutOfHousePackup timeNow: "+timeNow); blog("player_structure.isPlayerLockedOutOfHousePackup timeNow - timeNeeded: "+(timeNow - timeNeeded)); int timeDiff = timeNeeded - timeNow; if(timeDiff <= 0) { blog("player_structure.isPlayerLockedOutOfHousePackup THE LOCK OUT TIME EXPIRED ALREADY"); //remove immediately! messageTo(player, "handlePlayerStructurePackupLockoutRemoval", null, 0, false); return false; } string timeMessage = utils.formatTimeVerbose(timeDiff); prose_package pp = new prose_package(); pp = prose.setStringId(pp, SID_LOCKOUT_MESSAGE); pp = prose.setTO(pp, timeMessage); sendSystemMessageProse(player, pp); } else if(!canPackMore) { blog("player_structure.isPlayerGatedFromHousePackUp - !canPackMoreToday(player)"); //This is where the Comm is sent to the player saying they //have reached the daily quota. if(!hasObjVar (player, HOUSE_PACKUP_DAILY_TIMER_OBJVAR)) { int resetTime = getGameTime() + TIME_TO_NEXT_PACKUP; // 24 hours blog("isPlayerGatedFromHousePackUp - resetting time to next packup: "+resetTime); setObjVar (player, HOUSE_PACKUP_DAILY_TIMER_OBJVAR, resetTime); } int timeLeft = getIntObjVar (player, HOUSE_PACKUP_DAILY_TIMER_OBJVAR); timeLeft -= getGameTime(); string displayTime = utils.assembleTimeRemainToUse(timeLeft, false); string_id stringId = new string_id("spam", "wait_twenty_four"); prose_package p = new prose_package(); prose.setStringId(p, stringId); prose.setDI(p, MAX_PACKUP_PER_DAY); prose.setTT(p, displayTime); commPlayers(player, "object/mobile/dressed_hiddendagger_pilot_m_01.iff", "sound/sys_comm_other.snd", 5f, player, p); messageTo(player, "handleFailedStructurePackup", null, 0, false); //this appears to be a call to TT's test script //remove the delay message so that it doesn't confuse the player into //thinking they can pack more houses later messageTo(player, "handlePlayerStructurePackupLockoutRemoval", null, 0, false); } return true; } //HOUSE PACK UP isPlayerLockedOutOfHousePackup() //Check to see if a scriptvar is on player preventing //the player from paking up more structures. boolean isPlayerLockedOutOfHousePackup(obj_id player) { blog("player_structure.isPlayerLockedOutOfHousePackup init"); if(!isValidId(player) || !exists(player)) return true; if(utils.hasScriptVar(player, SCRIPTVAR_HOUSE_PACKUP_LOCKOUT_TIME)) return true; blog("player_structure.isPlayerLockedOutOfHousePackup FALSE........FALSE on LOCKOUT"); return false; } //gets the total added to a structure int getTotalIncreasedStorageAmountStructure(obj_id structure) { if(isIdValid(structure)) { if (hasObjVar(structure, OBJVAR_STRUCTURE_STORAGE_INCREASE)) return getIntObjVar(structure, OBJVAR_STRUCTURE_STORAGE_INCREASE); } return 0; } //make sure its okay to remove boolean validSafeStorageRemoval(obj_id structure, int decreaseAmount) { int numItems = player_structure.getStructureNumItems(structure); int baseItemLimit = getPobBaseItemLimit(structure); int storageIncreased = getTotalIncreasedStorageAmountStructure(structure); int projectedAmount = baseItemLimit + (storageIncreased - decreaseAmount); // 150 > 150 + (300 - 100) //LOG("STORAGE", "Items in house is " +numItems); //LOG("STORAGE", "Projected Amount is " +projectedAmount); //make sure the house isn't going to become overloaded and we aren't going below house min if( (numItems > projectedAmount) || (projectedAmount < baseItemLimit) ) return false; return true; } //add an amount of increased storage to the house boolean incrementStorageAmount(obj_id player, obj_id structure, obj_id deed, int increaseAmount) { if(isIdValid(structure) && increaseAmount > 0) { //get the current amount on the house int baseStorageIncrease = getTotalIncreasedStorageAmountStructure(structure); //LOG("STORAGE", "Base Storage is " +baseStorageIncrease); //LOG("STORAGE", "Increase Amount is " +increaseAmount); //math int newStrucStorage = baseStorageIncrease + increaseAmount; //LOG("STORAGE", "Increased Storage is " +newStrucStorage); //check to make sure we are not over cap if(newStrucStorage > STORAGE_AMOUNT_CAP) { sendSystemMessage (player, MSG_STORAGE_OVER_CAP); return false; } //lets make sure we are actually adding something if(newStrucStorage > baseStorageIncrease) { setObjVar(structure, OBJVAR_STRUCTURE_STORAGE_INCREASE, newStrucStorage); if ( isNonGenericLootItem(deed) ) { setNonGenericStorageIncreaseOfTypeObjVar(structure, deed, increaseAmount); } return true; } } return false; } //remove a chunk of increased storage from the house boolean decrementStorageAmount(obj_id player, obj_id structure, obj_id terminal, int selectedRedeedTypeIndex) { if( isIdValid(structure) && isIdValid(terminal) ) { string crate = "item_storage_increase_05_03"; if ( utils.hasScriptVar(terminal, "storageTypeNamesRef") ) { string[] storageTypeNamesArrayRef = utils.getStringBatchScriptVar(terminal, "storageTypeNamesRef"); crate = storageTypeNamesArrayRef[selectedRedeedTypeIndex]; } int decreaseAmount = STORAGE_AMOUNT_DECREASE_UNIT; string nonGenericStorageTypeObjVar = NON_GENERIC_STORAGE_ITEM_OBJVAR+"."+crate; if ( hasObjVar(structure, nonGenericStorageTypeObjVar) ) { decreaseAmount = getIntObjVar(structure, nonGenericStorageTypeObjVar); } //get the current amount on the house int baseStorageIncrease = getTotalIncreasedStorageAmountStructure(structure); //LOG("STORAGE", "Base Storage is " +baseStorageIncrease); //LOG("STORAGE", "Decrease Amount is " +decreaseAmount); int newStrucStorage = baseStorageIncrease - decreaseAmount; //LOG("STORAGE", "Decreased Storage is " +newStrucStorage); if( newStrucStorage >= 0 && validSafeStorageRemoval(structure, decreaseAmount) ) { obj_id pInv = utils.getInventoryContainer(player); if (!isIdValid(pInv)) return false; static_item.createNewItemFunction(crate, pInv); removeNonGenericStorageIncreaseOfTypeObjVar(structure, crate); if(newStrucStorage == 0) { //LOG("STORAGE", "Decreased Storage hit zero remove Objvar"); removeObjVar(structure, OBJVAR_STRUCTURE_STORAGE_INCREASE); return true; } //LOG("STORAGE", "Setting new objvar " +newStrucStorage); setObjVar(structure, OBJVAR_STRUCTURE_STORAGE_INCREASE, newStrucStorage); return true; } else { sendSystemMessage(player, new string_id("player_structure", "storage_item_cannot_remove")); player_structure.displayAvailableNonGenericStorageTypes(player, terminal, structure); } } return false; } boolean isNonGenericLootItem(obj_id deed) { return hasObjVar(deed, "nonGenericStorageItem"); } boolean alreadyHasNonGenericStorageIncreaseOfType(obj_id structure, obj_id deed) { string deedType = getStaticItemName(deed); string nonGenericStorageTypeObjVar = NON_GENERIC_STORAGE_ITEM_OBJVAR+"."+deedType; return hasObjVar(structure, nonGenericStorageTypeObjVar); } void setNonGenericStorageIncreaseOfTypeObjVar(obj_id structure, obj_id deed, int increaseAmount) { string deedType = getStaticItemName(deed); string nonGenericStorageTypeObjVar = NON_GENERIC_STORAGE_ITEM_OBJVAR+"."+deedType; setObjVar(structure, nonGenericStorageTypeObjVar, increaseAmount); return; } void removeNonGenericStorageIncreaseOfTypeObjVar(obj_id structure, string type) { string nonGenericStorageTypeObjVar = NON_GENERIC_STORAGE_ITEM_OBJVAR+"."+type; if ( hasObjVar(structure, nonGenericStorageTypeObjVar) ) { removeObjVar(structure, nonGenericStorageTypeObjVar); } return; } void displayAvailableNonGenericStorageTypes(obj_id player, obj_id terminal, obj_id structure) { if ( utils.hasScriptVar(player, "structureStorageRedeedPid") ) { int oldSui = utils.getIntScriptVar(player, "structureStorageRedeedPid"); forceCloseSUIPage(oldSui); } string[] storageTypeNamesArrayRef = getStorageTypeNamesArray(structure); if ( !hasObjVar(structure, NON_GENERIC_STORAGE_ITEM_OBJVAR) ) { if ( validSafeStorageRemoval(structure, STORAGE_AMOUNT_DECREASE_UNIT) ) { handleStorageReclaimConfirmation(player, terminal); } else { sendSystemMessage(player, new string_id("sui", "storage_item_count_over_base")); } } else { string title = utils.packStringId(new string_id("player_structure", "sui_storage_nongeneric_redeed_title")); string prompt = utils.packStringId(new string_id("player_structure","sui_storage_nongeneric_redeed_prompt")); string[] storageTypeNamesArrayStrings = new string[storageTypeNamesArrayRef.length]; for ( int i = 0; i < storageTypeNamesArrayRef.length; i++ ) { string nonGenericStorateType = storageTypeNamesArrayRef[i]; int decreaseAmount = STORAGE_AMOUNT_DECREASE_UNIT; string nonGenericStorageTypeObjVar = NON_GENERIC_STORAGE_ITEM_OBJVAR+"."+nonGenericStorateType; if ( hasObjVar(structure, nonGenericStorageTypeObjVar) ) { decreaseAmount = getIntObjVar(structure, nonGenericStorageTypeObjVar); } if ( validSafeStorageRemoval(structure, decreaseAmount) ) { storageTypeNamesArrayStrings[i] = utils.packStringId(new string_id("static_item_n", nonGenericStorateType)); } else { // if removing a storage type would put the current limit below the number of items in the house, grey it out. string greyedOut = utils.packStringId(new string_id("static_item_n", nonGenericStorateType)); string_id contrastText_sid = new string_id("faction_recruiter","rank_list_empty"); prose_package pp = prose.getPackage(contrastText_sid); prose.setTO(pp, greyedOut); storageTypeNamesArrayStrings[i] = "\0" + packOutOfBandProsePackage(null, pp); } } int newSui = sui.listbox(terminal, player, prompt, sui.OK_CANCEL, title, storageTypeNamesArrayStrings, "handleStorageRedeedChoice"); utils.setScriptVar(player, "structureStorageRedeedPid", newSui); } utils.setBatchScriptVar(terminal, "storageTypeNamesRef", storageTypeNamesArrayRef); return; } string[] getStorageTypeNamesArray(obj_id structure) { resizeable string[] storageIncreaseTypes = new string[0]; int totalNonGenericStorageIncrease = 0; if ( hasObjVar(structure, NON_GENERIC_STORAGE_ITEM_OBJVAR) ) { obj_var_list nonGenericStorageObjvarList = getObjVarList(structure, NON_GENERIC_STORAGE_ITEM_OBJVAR); if ( nonGenericStorageObjvarList != null ) { int numItem = nonGenericStorageObjvarList.getNumItems(); for ( int i = 0; i < numItem; i++ ) { obj_var nonGenericStorageObjvar = nonGenericStorageObjvarList.getObjVar(i); string nonGenericStorageObjvarName = nonGenericStorageObjvar.getName(); totalNonGenericStorageIncrease = totalNonGenericStorageIncrease + nonGenericStorageObjvar.getIntData(); if ( nonGenericStorageObjvarName != null && nonGenericStorageObjvarName.length() > 0 ) { storageIncreaseTypes = utils.addElement(storageIncreaseTypes, nonGenericStorageObjvarName); } } } } if ( getTotalIncreasedStorageAmountStructure(structure) > totalNonGenericStorageIncrease ) { storageIncreaseTypes = utils.addElement(storageIncreaseTypes, "item_storage_increase_05_03"); } return storageIncreaseTypes; } boolean handleStorageReclaimConfirmation(obj_id player, obj_id terminal) { string title = utils.packStringId(new string_id("player_structure", "sui_storage_redeed_title")); string prompt = utils.packStringId(new string_id("player_structure", "sui_storage_redeed_prompt")); sui.msgbox(terminal, player, prompt, sui.YES_NO, title, "handleStorageRedeedChoice"); return false; } //can player rotate furniture in the pitch and roll axes boolean canRotateFurnitureInPitchRollAxes(obj_id player) { if (!isIdValid(player)) return false; return hasCompletedCollection(player, "force_shui_tier_02"); } boolean isPlayerStructure(obj_id target) { if(!isValidId(target) || !exists(target)) return false; if(!isBuilding(target)) return false; if(!hasObjVar(target, "player_structure")) return false; string template = getTemplateName(target); if(template == null || template.equals("")) return false; if(!template.startsWith("object/building/player/")) return false; if(!isGameObjectTypeOf(target, GOT_building_player)) return false; return true; } /*********************************************************************** * @brief Checks to see if a player has any special sign skillmods. * Returns true if one is found. * * @param obj_id player * * @return boolean ***********************************************************************/ boolean hasSpecialSignSkillMod(obj_id player, obj_id structure) { blog("player_structure.hasSpecialSignSkillMod: init"); if(!isValidId(player) || !exists(player)) return false; boolean owner = isOwner(structure, player); //Get a list of all possible sign skill mods blog("player_structure.hasSpecialSignSkillMod: initial validation passes"); string[] specialSignSkillMods = dataTableGetStringColumn(TBL_SPECIAL_SIGNS, "skillmod_name"); int[] adminSpecialSign = dataTableGetIntColumn(TBL_SPECIAL_SIGNS, "admin_placement"); if(specialSignSkillMods == null || specialSignSkillMods.length <= 0) return false; blog("player_structure.hasSpecialSignSkillMod: about to test each of the special signs to see if I have the necessary skill mods."); for(int i = 0; i < specialSignSkillMods.length; i++) { if(getSkillStatMod(player, specialSignSkillMods[i]) <= 0) continue; if(!owner && adminSpecialSign[i] == 0) continue; blog("player_structure.hasSpecialSignSkillMod: Found a skill mod I have: "+specialSignSkillMods[i]); return true; } return false; } /*********************************************************************** * @brief Checks to see if a player has any special sign skillmods, * if so it returns a list of signs available to the player * * @param obj_id player * * @return string[] ***********************************************************************/ boolean getSpecialSignList(obj_id player, obj_id structure) { blog("player_structure.getSpecialSignList: init"); if(!isValidId(player) || !exists(player)) return false; boolean owner = isOwner(structure, player); //Get a list of all possible sign skill mods blog("player_structure.getSpecialSignList: initial validation passes"); string[] specialSignSkillMods = dataTableGetStringColumn(TBL_SPECIAL_SIGNS, "skillmod_name"); string[] specialSignTemplates = dataTableGetStringColumn(TBL_SPECIAL_SIGNS, "sign_template"); string[] specialSignNames = dataTableGetStringColumn(TBL_SPECIAL_SIGNS, "string_mapping"); int[] adminSpecialSign = dataTableGetIntColumn(TBL_SPECIAL_SIGNS, "admin_placement"); if(specialSignSkillMods == null || specialSignSkillMods.length <= 0) return false; else if(specialSignTemplates == null || specialSignTemplates.length <= 0) return false; else if(specialSignSkillMods.length != specialSignTemplates.length) return false; resizeable string[] allSignTemplates = new string[0]; resizeable string[] allSignStrings = new string[0]; blog("player_structure.getSpecialSignList: about to test each of the special signs to see if I have the necessary skill mods."); for(int i = 0; i < specialSignSkillMods.length; i++) { if(getSkillStatMod(player, specialSignSkillMods[i]) <= 0) continue; if(!owner && adminSpecialSign[i] <= 0) continue; blog("player_structure.getSpecialSignList: Found a skill mod I have: "+specialSignSkillMods[i]); utils.addElement(allSignTemplates, specialSignTemplates[i]); //adding the special sign template, not the skill mod utils.addElement(allSignStrings, "@"+specialSignNames[i]); //special sign template string } if(allSignTemplates.size() <= 0) return false; if(allSignStrings.size() <= 0) return false; string[] signList = new string[allSignTemplates.size()]; allSignTemplates.toArray(signList); string[] signName = new string[allSignStrings.size()]; allSignStrings.toArray(signName); utils.setScriptVar(player, VAR_SPECIAL_SIGN_LIST, signList); utils.setScriptVar(player, VAR_SPECIAL_SIGN_NAMES, signName); return true; } boolean removeSpecialSign(obj_id player, obj_id structure, boolean revertMessage) { blog("player_structure.removeSpecialSign - init"); if(!isValidId(player) || !isValidId(structure)) return false; //If the building has a custom sign, we remove that before changing signs. if(hasObjVar(structure, MODIFIED_HOUSE_SIGN_MODEL)) { revertCustomSign(player, structure); return true; } boolean owner = isOwner(structure, player); if(hasObjVar(structure, SPECIAL_SIGN_OWNER_ONLY)) { boolean needsOwnerToRemove = getBooleanObjVar(structure, SPECIAL_SIGN_OWNER_ONLY); if(!owner && needsOwnerToRemove) { sendSystemMessage(player, SID_ONLY_OWNER_CAN_REMOVE); return false; } } string skillmod = getStringObjVar(structure, SPECIAL_SIGN_SKILLMOD); if(skillmod == null || skillmod.length() <= 0) return false; blog("player_structure.removeSpecialSign - validation completed"); string skillmodRecovery = getStringObjVar(structure, SPECIAL_SIGN_SKILLMOD); boolean ownerOnlyRecovery = false; if(hasObjVar(structure, SPECIAL_SIGN_OWNER_ONLY) && getBooleanObjVar(structure, SPECIAL_SIGN_OWNER_ONLY)) ownerOnlyRecovery = true; string signTemplateRecovery = getStringObjVar(structure, SPECIAL_SIGN_TEMPLATE); int signTypeRecovery = 0; if(hasObjVar(structure, VAR_SIGN_TYPE)) { signTypeRecovery = getIntObjVar(structure, VAR_SIGN_TYPE); //standing sign will overwrite 0 } if(signTemplateRecovery == null || signTemplateRecovery.length() <= 0 || signTypeRecovery <= -1) { blog("player_structure.removeSpecialSign - signTemplateRecovery failed"); sendSystemMessage(player, SID_SPECIAL_SIGN_FAILED); CustomerServiceLog("playerStructure","Special Sign could not be removed and replaced with default sign on structure " + structure + ". The player: "+player+". Reason: signTemplateRecovery failed."); return false; } removeObjVar(structure, SPECIAL_SIGN); removeObjVar(structure, SPECIAL_SIGN_TEMPLATE); removeObjVar(structure, VAR_SIGN_TYPE); removeObjVar(structure, SPECIAL_SIGN_SKILLMOD); removeObjVar(structure, SPECIAL_SIGN_OWNER_ONLY); if(!isValidId(player_structure.createStructureSign(structure))) { setObjVar(structure, SPECIAL_SIGN, true); setObjVar(structure, SPECIAL_SIGN_TEMPLATE, signTemplateRecovery); setObjVar(structure, VAR_SIGN_TYPE, signTypeRecovery); setObjVar(structure, VAR_SIGN_TYPE, skillmodRecovery); setObjVar(structure, SPECIAL_SIGN_OWNER_ONLY, ownerOnlyRecovery); blog("player_structure.removeSpecialSign - Default Sign Creation failed!!!!!!!!!!!!!!!!!"); sendSystemMessage(player, SID_SPECIAL_SIGN_FAILED); CustomerServiceLog("playerStructure","Special Sign could not be removed and replaced with default sign on structure " + structure + ". The player: "+player+". Reason: createStructureSign failed."); return false; } if(hasObjVar(structure, SPECIAL_SIGN_DECREMENT_MOD)) { if(!applySkillStatisticModifier(player, skillmod, 1)) { blog("player_structure.removeSpecialSign - Applying skillmod failed!!!!!!!!!!!!!!!!!"); CustomerServiceLog("playerStructure","Player: "+player+" attempted to remove special sign from structure: " + structure + ". During the destroy process the skillmod: " + skillmod + " failed to be reimbursed so the process was aborted."); sendSystemMessage(player, SID_SPECIAL_SIGN_FAILED); return false; } removeObjVar(structure, player_structure.SPECIAL_SIGN_DECREMENT_MOD); } blog("player_structure.removeSpecialSign - skillmod reimbursed and default sign created"); if(revertMessage) sendSystemMessage(player, SID_SPECIAL_SIGN_REVERT_SUCCESS); CustomerServiceLog("playerStructure","Player: "+player+" removed special sign from structure: " + structure + ". During the destroy process the skillmod: " + skillmod + " was reimbursed."); return true; } boolean blog(string msg) { if(LOGGING_ON && msg != null && !msg.equals("")) LOG(LOGGING_CATEGORY, msg); return true; } //This now gives new object that converts the sign to the special sign system void revertCustomSign(obj_id player, obj_id structure) { blog("revertCustomSign - revertCustomSign init"); player_structure.destroyStructureSign(structure); removeObjVar(structure, player_structure.MODIFIED_HOUSE_SIGN); string customSign = getStringObjVar(structure, player_structure.MODIFIED_HOUSE_SIGN_MODEL); string newSign = ""; blog("revertCustomSign - customSign: "+customSign); if(customSign.equals("item_event_halloween_house_sign")) { blog("revertCustomSign - customSign: item_event_halloween_house_sign "+customSign); newSign = "item_special_sign_halloween_hanging_sign"; } else if(customSign.equals("item_event_halloween_house_sign_standing")) { blog("revertCustomSign - customSign: item_event_halloween_house_sign_standing "+customSign); newSign = "item_special_sign_halloween_standing_sign"; } if(newSign == null || newSign.length() <= 0) { blog("revertCustomSign - customSign: FAIL!!!!!!!!!!!"); //Something wrong happened, give them the old sign version if possible. obj_id sign = static_item.createNewItemFunction(customSign, player); if(isValidId(sign)) CustomerServiceLog("playerStructure","Player: "+player+" attempted to remove their old Galactic Moon Festival Sign: "+customSign+" from structure: "+structure+" but it failed to update to the new special sign system. The player was reimbursed with the old sign object: "+sign+"."); else CustomerServiceLog("playerStructure","Player: "+player+" attempted to remove their old Galactic Moon Festival Sign: "+customSign+" from structure: "+structure+" but it failed to update to the new special sign system. The player was reimbursed with the old sign object: "+sign+"."); } else { blog("revertCustomSign - customSign: SUCCESS: "+newSign); //The new sign was delivered. obj_id sign = static_item.createNewItemFunction(newSign, player); if(isValidId(sign)) { blog("revertCustomSign - customSign: Object ID: "+sign); CustomerServiceLog("playerStructure","Player: "+player+" remove their old Galactic Moon Festival Sign: "+customSign+" from structure: "+structure+" and received a new skillmod sign object: "+sign+"."); sendSystemMessage(player, SID_HALLOWEEN_SIGN_UPDATED); } else { blog("revertCustomSign - customSign: Object COULD NOT BE CREATED"); CustomerServiceLog("playerStructure","Player: "+player+" attempted to remove their old Galactic Moon Festival Sign: "+customSign+" from structure: "+structure+" but it failed to update to the new special sign system. The player was reimbursed with the old sign object: "+sign+"."); } } removeObjVar(structure, player_structure.MODIFIED_HOUSE_SIGN_MODEL); player_structure.createStructureSign(structure); } // ****** FIND ITEM IN HOUSE FUNCTIONS ******************************** void initializeFindAllItemsInHouse(obj_id self, obj_id player) { cleanupFindItemScriptVars(player); cleanupFindItemScriptVars(self); showFindItemsListboxPage(self, player, 0); return; } void initializeItemSearchInHouse(obj_id self, obj_id player) { string title = utils.packStringId(new string_id("player_structure", "find_items_search_keyword_title")); string prompt = getString(new string_id("player_structure","find_items_search_keyword_prompt")); int pid = sui.inputbox(self, player, prompt, sui.OK_CANCEL, title, sui.INPUT_NORMAL, null, "handlePlayerStructureSearchItemsGetKeyword"); if ( pid > -1 ) { sui.showSUIPage(pid); utils.setScriptVar(player, "findItems.pid", pid); } return; } void showFindItemsListboxPage(obj_id self, obj_id player, int startingIndex) { //PROFILER_START("player_structure.showFindItemsListboxPage"); cleanupFindItemScriptVars(player); cleanupFindItemScriptVars(self); resizeable obj_id[] myItemsInBuilding = getMyItemsInBuilding(player); if ( myItemsInBuilding != null && myItemsInBuilding.length > 0 ) { int totalNumItems = myItemsInBuilding.length; if ( totalNumItems <= 49 ) { startingIndex = 0; } int endingIndex = startingIndex + 49; if ( endingIndex >= totalNumItems ) { endingIndex = totalNumItems - 1; } string[] itemsPageNamesList = new string[(endingIndex + 1) - startingIndex]; obj_id[] itemsPageList = new obj_id[(endingIndex + 1) - startingIndex]; int j = 0; for ( int i = startingIndex; i <= endingIndex; i++ ) { obj_id item = myItemsInBuilding[i]; string itemName = getEncodedName(item); itemsPageNamesList[j] = itemName; itemsPageList[j] = item; ++j; } showFindItemsListboxSui(self, player, startingIndex, totalNumItems, itemsPageList, itemsPageNamesList); } else { sendSystemMessage(player, new string_id("player_structure", "find_items_no_items_found")); cleanupFindItemScriptVars(player); cleanupFindItemScriptVars(self); } //PROFILER_STOP("player_structure.showFindItemsListboxPage"); return; } void repeatFindItemsListboxPage(obj_id self, obj_id player, int startingIndex, int totalNumItems, obj_id[] itemsPageList) { cleanupFindItemScriptVars(player); cleanupFindItemScriptVars(self); string[] itemsPageNamesList = new string[itemsPageList.length]; for ( int i = 0; i < itemsPageList.length; i++ ) { obj_id item = itemsPageList[i]; string itemName = getEncodedName(item); itemsPageNamesList[i] = itemName; } showFindItemsListboxSui(self, player, startingIndex, totalNumItems, itemsPageList, itemsPageNamesList); return; } void showFindItemsListboxSui(obj_id self, obj_id player, int startingIndex, int totalNumItems, obj_id[] itemsPageList, string[] itemsPageNamesList) { string title = utils.packStringId(new string_id("player_structure", "find_items_title")); string prompt = utils.packStringId(new string_id("player_structure", "find_items_prompt")); prompt += target_dummy.addLineBreaks(2); prompt += target_dummy.ORANGE + "Number of Items Found: " + target_dummy.WHITE + totalNumItems; //if ( totalNumItems > 50 ) //{ int endingIndex = startingIndex + 49; if ( endingIndex >= totalNumItems ) { endingIndex = totalNumItems - 1; } prompt += target_dummy.addLineBreaks(1); prompt += target_dummy.ORANGE + "Displaying Items: " + target_dummy.WHITE + (startingIndex+1) + " through " + (endingIndex+1); //} int pid = sui.listbox(self, player, prompt, sui.OK_CANCEL_REFRESH, title, itemsPageNamesList, "handlePlayerStructureFindItemsListResponse"); if ( pid > -1 ) { if ( totalNumItems > 50 ) { sui.listboxUseOtherButton(pid, "Change Page"); } else { sui.listboxUseOtherButton(pid, "Refresh Page"); } sui.setSUIProperty(pid, sui.LISTBOX_BTN_OK, sui.PROP_TEXT,"Retrieve Object"); sui.showSUIPage(pid); utils.setScriptVar(player, "findItems.pid", pid); utils.setScriptVar(player, "findItems.startingIndex", startingIndex); utils.setScriptVar(player, "findItems.totalNumItems", totalNumItems); utils.setScriptVar(self, "findItems.itemsPageList", itemsPageList); } return; } resizeable obj_id[] getMyItemsInBuilding(obj_id player) { resizeable obj_id[] myItemsInBuilding = new obj_id[0]; location here = getLocation(player); obj_id myCell = here.cell; if ( isIdValid(myCell) ) { obj_id building = getContainedBy(myCell); if ( isIdValid(building) ) { obj_id buildingOwner = getOwner(building); if ( (isIdValid(buildingOwner) && player == buildingOwner) || isGod(player) ) { obj_id[] cellList = getContents(building); if ( cellList != null && cellList.length > 0 ) { for ( int i = 0; i < cellList.length; i++ ) { obj_id buildingCell = cellList[i]; if ( getTemplateName(buildingCell).equals(structure.TEMPLATE_CELL) ) { addPlayerItemsFromContainerToList(buildingCell, player, myItemsInBuilding); } } } } else { sendSystemMessage(player, new string_id("player_structure", "find_items_not_building_owner")); } } else { sendSystemMessage(player, new string_id("player_structure", "find_items_not_in_a_cell")); } } else { sendSystemMessage(player, new string_id("player_structure", "find_items_not_in_a_building")); } if ( myItemsInBuilding.length > 0 ) { return myItemsInBuilding; } return null; } void addPlayerItemsFromContainerToList(obj_id container, obj_id player, resizeable obj_id[] myItemsInBuilding) { obj_id[] contents = getContents(container); if ( contents != null && contents.length > 0 ) { for ( int j = 0; j < contents.length; j++ ) { obj_id thing = contents[j]; if ( isIdValid(thing) ) { boolean isValidPlayerOwnedObject = true; // If the item is owned by the player or if the player is in god mode, // then it can be added to the list obj_id thingOwner = getOwner(thing); if ( player != thingOwner && !isGod(player) ) isValidPlayerOwnedObject = false; // if the object is not persisted, then the player did not place it if ( !isObjectPersisted(thing) ) isValidPlayerOwnedObject = false; // Do not add players to the list if ( isPlayer(thing) ) isValidPlayerOwnedObject = false; // Do not add mobs to the list if ( isMob(thing) ) isValidPlayerOwnedObject = false; // Do not add ship loot boxes to the list obj_id ship = space_transition.getContainingShip(thing); if ( isIdValid(ship) ) { obj_id lootBox = obj_id.NULL_ID; if ( hasObjVar(ship, "objLootBox") ) lootBox = getObjIdObjVar(ship, "objLootBox"); if ( isIdValid(lootBox) && lootBox == thing ) isValidPlayerOwnedObject = false; } // Do not add vendors to the list if ( hasCondition(thing, CONDITION_VENDOR) ) isValidPlayerOwnedObject = false; if ( isValidPlayerOwnedObject ) { if ( getContainerType(thing) != 0 && getGameObjectType(thing) != GOT_misc_factory_crate ) { addPlayerItemsFromContainerToList(thing, player, myItemsInBuilding); } utils.addElement(myItemsInBuilding, thing); } } } } } boolean moveItemInBuildingToPlayer(obj_id player, obj_id selectedItem) { location here = getLocation(player); obj_id myCell = here.cell; if ( isIdValid(myCell) ) { obj_id building = getContainedBy(myCell); if ( isIdValid(building) ) { obj_id buildingOwner = getOwner(building); if ( (isIdValid(buildingOwner) && player == buildingOwner) || isGod(player) ) { if ( exists(selectedItem) ) { if ( !utils.isNestedWithinAPlayer(selectedItem) ) { obj_id itemTopMost = getTopMostContainer(selectedItem); obj_id myTopMost = getTopMostContainer(player); if ( itemTopMost == myTopMost ) { obj_id topNonCellContainer = getTopNonCellContainer(selectedItem); string itemName = getEncodedName(selectedItem); string containerName = getEncodedName(topNonCellContainer); string_id message = new string_id("player_structure", "find_items_item_moved"); if ( topNonCellContainer != selectedItem ) { message = new string_id("player_structure", "find_items_item_container_moved"); } prose_package pp = prose.getPackage(message); prose.setTO(pp, itemName); prose.setTT(pp, containerName); sendQuestSystemMessage(player, pp); setLocation(topNonCellContainer, here); return true; } else { sendSystemMessage(player, new string_id("player_structure", "find_items_failed_not_in_same_building")); } } else { if ( utils.isNestedWithin(selectedItem, player) ) { sendSystemMessage(player, new string_id("player_structure", "find_items_failed_nested_within_you")); } else { sendSystemMessage(player, new string_id("player_structure", "find_items_failed_nested_within_other_player")); } } } else { sendSystemMessage(player, new string_id("player_structure", "find_items_failed_no_longer_exists")); } } else { sendSystemMessage(player, new string_id("player_structure", "find_items_failed_not_owner")); } } else { sendSystemMessage(player, new string_id("player_structure", "find_items_failed_uncontained_cell")); } } else { sendSystemMessage(player, new string_id("player_structure", "find_items_failed_not_outside")); } return false; } // If nothing is containing the item, then the item itself will be returned. // If the item is directly contained by the cell of a building, then the item itself will be returned. // If anythingf else is containing the item, then this will iterate until it find the top container that is not a cell. obj_id getTopNonCellContainer(obj_id item) { obj_id container = getContainedBy(item); if ( !isIdValid(container) ) { // not contained by anything, return the item itself return item; } else if ( getTemplateName(container).equals(structure.TEMPLATE_CELL) ) { // contained by the cell of a building, return the item itself return item; } else { // contained by something...find out if that container is contained by anything return getTopNonCellContainer(container); } } void cleanupFindItemScriptVars(obj_id target) { utils.removeScriptVarTree(target, "findItems"); return; } void handleFindItemsListResponse(obj_id self, dictionary params) { if ( params == null || params.isEmpty() ) { return; } obj_id player = sui.getPlayerId(params); if ( !isIdValid(player) ) { return; } int button = sui.getIntButtonPressed(params); if ( button == sui.BP_CANCEL ) { sendSystemMessage(player, new string_id("player_structure", "find_items_search_cancelled")); cleanupFindItemScriptVars(player); cleanupFindItemScriptVars(self); return; } int startingIndex = utils.getIntScriptVar(player, "findItems.startingIndex"); int totalNumItems = utils.getIntScriptVar(player, "findItems.totalNumItems"); obj_id[] itemsPageList = utils.getObjIdArrayScriptVar(self, "findItems.itemsPageList"); if ( itemsPageList == null || itemsPageList.length < 1 ) { sendSystemMessage(player, new string_id("player_structure", "find_items_no_items_found")); cleanupFindItemScriptVars(player); cleanupFindItemScriptVars(self); return; } if ( button == sui.BP_REVERT ) { if ( totalNumItems > 50 ) { // Go forward or backward in the list string title = utils.packStringId(new string_id("player_structure", "find_items_page_title")); string prompt = ""; int pid = sui.createSUIPage(sui.SUI_MSGBOX, self, player, "handlePlayerStructureFindItemsPageResponse"); if ( startingIndex == 0 ) { if ( pid > -1 ) { setSUIProperty(pid, sui.MSGBOX_TITLE, sui.PROP_TEXT, title); prompt = utils.packStringId(new string_id("player_structure", "find_items_page_next_prompt")); setSUIProperty(pid, sui.MSGBOX_PROMPT, sui.PROP_TEXT, prompt); sui.msgboxButtonSetup(pid, sui.YES_NO); setSUIProperty(pid, sui.MSGBOX_BTN_OK, sui.PROP_TEXT, "Next Page"); setSUIProperty(pid, sui.MSGBOX_BTN_CANCEL, sui.PROP_TEXT, "Cancel"); sui.showSUIPage(pid); } } else if ( startingIndex + 50 >= totalNumItems ) { if ( pid > -1 ) { setSUIProperty(pid, sui.MSGBOX_TITLE, sui.PROP_TEXT, title); prompt = utils.packStringId(new string_id("player_structure", "find_items_page_previous_prompt")); setSUIProperty(pid, sui.MSGBOX_PROMPT, sui.PROP_TEXT, prompt); sui.msgboxButtonSetup(pid, sui.YES_NO); setSUIProperty(pid, sui.MSGBOX_BTN_OK, sui.PROP_TEXT, "Previous Page"); setSUIProperty(pid, sui.MSGBOX_BTN_CANCEL, sui.PROP_TEXT, "Cancel"); utils.setScriptVar(player, "findItems.lastPage", 1); sui.showSUIPage(pid); } } else { if ( pid > -1 ) { setSUIProperty(pid, sui.MSGBOX_TITLE, sui.PROP_TEXT, title); prompt = utils.packStringId(new string_id("player_structure", "find_items_page_next_previous_prompt")); setSUIProperty(pid, sui.MSGBOX_PROMPT, sui.PROP_TEXT, prompt); sui.msgboxButtonSetup(pid, sui.YES_NO_CANCEL); setSUIProperty(pid, sui.MSGBOX_BTN_REVERT, sui.PROP_TEXT, "Previous Page"); setSUIProperty(pid, sui.MSGBOX_BTN_OK, sui.PROP_TEXT, "Next Page"); setSUIProperty(pid, sui.MSGBOX_BTN_CANCEL, sui.PROP_TEXT, "Cancel"); setSUIProperty(pid, sui.MSGBOX_BTN_REVERT, "OnPress", "RevertWasPressed=1\r\nparent.btnOk.press=t"); subscribeToSUIProperty(pid, sui.MSGBOX_BTN_REVERT, "RevertWasPressed"); sui.showSUIPage(pid); } } } else { repeatFindItemsListboxPage(self, player, startingIndex, totalNumItems, itemsPageList); } return; } int item_selected = sui.getListboxSelectedRow(params); if ( item_selected < 0 ) { sendSystemMessage(player, new string_id("player_structure", "find_items_no_selection")); cleanupFindItemScriptVars(player); cleanupFindItemScriptVars(self); return; } obj_id selectedItem = itemsPageList[item_selected]; if ( isIdValid(selectedItem) ) { moveItemInBuildingToPlayer(player, selectedItem); repeatFindItemsListboxPage(self, player, startingIndex, totalNumItems, itemsPageList); return; } cleanupFindItemScriptVars(player); cleanupFindItemScriptVars(self); return; } void handleFindItemsChangePageResponse(obj_id self, dictionary params) { if ( params == null || params.isEmpty() ) { return; } obj_id player = sui.getPlayerId(params); if ( !isIdValid(player) ) { return; } // Determine which button was pressed. string revert = params.getString(sui.MSGBOX_BTN_REVERT+".RevertWasPressed"); int button = sui.getIntButtonPressed( params ); if(button == sui.BP_CANCEL) { sendSystemMessage(player, new string_id("player_structure", "find_items_search_cancelled")); cleanupFindItemScriptVars(player); cleanupFindItemScriptVars(self); return; } int startingIndex = utils.getIntScriptVar(player, "findItems.startingIndex"); if ( revert != null && !revert.equals("") ) { // Previous page startingIndex = startingIndex - 50; } else if ( utils.hasScriptVar(player, "findItems.lastPage") ) { // Hack for OK button on last page to offer Previous Page // instead of Next Page startingIndex = startingIndex - 50; } else { // Next Page startingIndex = startingIndex + 50; } if ( startingIndex < 0 ) { startingIndex = 0; } cleanupFindItemScriptVars(player); cleanupFindItemScriptVars(self); showFindItemsListboxPage(self, player, startingIndex); return; } void handleSearchItemsGetKeyword(obj_id self, dictionary params) { if ( params == null || params.isEmpty() ) { return; } obj_id player = sui.getPlayerId(params); if ( !isIdValid(player) ) { return; } int btn = sui.getIntButtonPressed(params); if ( btn == sui.BP_CANCEL ) { sendSystemMessage(player, new string_id("player_structure", "find_items_search_cancelled")); return; } string keyword = toLower(sui.getInputBoxText(params)); if ( keyword == null || keyword.length() < 1 ) { sendSystemMessage(player, new string_id("player_structure", "find_items_search_no_keyword")); return; } //PROFILER_START("player_structure.handleSearchItemsGetKeyword"); resizeable obj_id[] myItemsInBuilding = player_structure.getMyItemsInBuilding(player); resizeable obj_id[] keywordMatchedIds = new obj_id[0]; resizeable string[] keywordMatchedNames = new string[0]; int numMatches = 0; string prompt = utils.packStringId(new string_id("player_structure", "find_items_search_list_prompt")); for ( int i = 0; i < myItemsInBuilding.length; i++ ) { obj_id thing = myItemsInBuilding[i]; string name = getAssignedName(thing); if ( name == null || name.length () < 1 ) { string_id sidName = getNameStringId(thing); if ( sidName != null && !sidName.isEmpty() ) { sidName = utils.unpackString("@" + sidName.toString()); name = getString(sidName); if ( name.startsWith("@") ) { CustomerServiceLog("findItemInStructure", "Server localization for this item failed: "+getTemplateName(thing)+" ("+thing+")."); } } } string lowerCaseName = toLower(name); int stringCheck = lowerCaseName.indexOf(keyword); if ( stringCheck > -1 ) { utils.addElement(keywordMatchedIds, thing); utils.addElement(keywordMatchedNames, name); ++numMatches; } if ( numMatches >= 50 ) { prompt = utils.packStringId(new string_id("player_structure", "find_items_search_list_too_long_prompt")); break; } } if ( keywordMatchedIds == null || keywordMatchedIds.length < 1 ) { sendSystemMessage(player, new string_id("player_structure", "find_items_search_not_found")); return; } if ( keywordMatchedNames == null || keywordMatchedNames.length < 1 || keywordMatchedIds.length != keywordMatchedNames.length ) { // something strange happened...why don't some of those objects have names? return; } string[] matchingItemsNameList = utils.toStaticStringArray(keywordMatchedNames); obj_id[] matchingItemsList = utils.toStaticObjIdArray(keywordMatchedIds); showSearchItemsListboxSui(self, player, matchingItemsList, matchingItemsNameList, prompt); //PROFILER_STOP("player_structure.handleSearchItemsGetKeyword"); return; } void repeatSearchItemsKeywordList(obj_id self, obj_id player, obj_id[] matchingItemsList) { cleanupFindItemScriptVars(player); cleanupFindItemScriptVars(self); string[] matchingItemsNamesList = new string[matchingItemsList.length]; for ( int i = 0; i < matchingItemsList.length; i++ ) { obj_id item = matchingItemsList[i]; string itemName = getEncodedName(item); matchingItemsNamesList[i] = itemName; } string prompt = utils.packStringId(new string_id("player_structure", "find_items_search_list_prompt")); if ( matchingItemsList.length >= 50 ) { prompt = utils.packStringId(new string_id("player_structure", "find_items_search_list_too_long_prompt")); } showSearchItemsListboxSui(self, player, matchingItemsList, matchingItemsNamesList, prompt); return; } void showSearchItemsListboxSui(obj_id self, obj_id player, obj_id[] matchingItemsList, string[] matchingItemsNamesList, string prompt) { string title = utils.packStringId(new string_id("player_structure", "find_items_search_list_title")); int pid = sui.listbox(self, player, prompt, sui.OK_CANCEL, title, matchingItemsNamesList, "handlePlayerStructureSearchItemsSelectedResponse"); if ( pid > -1 ) { sui.setSUIProperty(pid, sui.LISTBOX_BTN_OK, sui.PROP_TEXT,"Retrieve Object"); sui.showSUIPage(pid); utils.setScriptVar(player, "findItems.pid", pid); utils.setScriptVar(self, "findItems.searchList", matchingItemsList); } return; } void handleSearchItemsSelectedResponse(obj_id self, dictionary params) { if ( params == null || params.isEmpty() ) { return; } obj_id player = sui.getPlayerId(params); if ( !isIdValid(player) ) { return; } int button = sui.getIntButtonPressed(params); if ( button == sui.BP_CANCEL ) { sendSystemMessage(player, new string_id("player_structure", "find_items_search_cancelled")); cleanupFindItemScriptVars(player); cleanupFindItemScriptVars(self); return; } obj_id[] searchList = utils.getObjIdArrayScriptVar(self, "findItems.searchList"); if ( searchList == null || searchList.length < 1 ) { cleanupFindItemScriptVars(player); cleanupFindItemScriptVars(self); return; } int item_selected = sui.getListboxSelectedRow(params); if ( item_selected < 0 ) { sendSystemMessage(player, new string_id("player_structure", "find_items_no_selection")); cleanupFindItemScriptVars(player); cleanupFindItemScriptVars(self); return; } obj_id selectedItem = searchList[item_selected]; if ( isIdValid(selectedItem) ) { moveItemInBuildingToPlayer(player, selectedItem); repeatSearchItemsKeywordList(self, player, searchList); return; } cleanupFindItemScriptVars(player); cleanupFindItemScriptVars(self); return; } // ******************************************************************** // Remove structure maintenance off the droid and the player control device based on its index. void removeStructureFromMaintenance(obj_id droid, obj_id pcd, int indexOfStructure) { if(!isIdValid(pcd)) { return; } // remove selected structure from list. obj_id[] struct_list = getObjIdArrayObjVar(pcd, "module_data.maint_list.ids"); if(struct_list == null || struct_list.length <= 0) { return; } // Make sure the index is in a valid range of the structure list. if(indexOfStructure < 0 || indexOfStructure >= struct_list.length) { return; } obj_id[] new_struct_list = new obj_id[struct_list.length - 1]; int currentIndex = 0; for(int i = 0; i < struct_list.length; i++) { if(i == indexOfStructure) { if(isIdValid(droid)) { removeObjVar(droid, "module_data.maint_list.loc_" + i); } removeObjVar(pcd, "module_data.maint_list.loc_" + i); continue; } if(i < indexOfStructure) { new_struct_list[i] = struct_list[i]; } else { new_struct_list[i - 1] = struct_list[i]; if(hasObjVar(pcd, "module_data.maint_list.loc_" + i)) { if(isIdValid(droid)) { setObjVar(droid, "module_data.maint_list.loc_" + (i - 1), getLocationObjVar(droid, "module_data.maint_list.loc_" + i)); } setObjVar(pcd, "module_data.maint_list.loc_" + (i - 1), getLocationObjVar(pcd, "module_data.maint_list.loc_" + i)); } else { if(isIdValid(droid)) { removeObjVar(droid, "module_data.maint_list.loc_" + (i - 1)); } removeObjVar(pcd, "module_data.maint_list.loc_" + (i - 1)); } } } if(isIdValid(droid)) { setObjVar(droid, "module_data.maint_list.ids", new_struct_list); } setObjVar(pcd, "module_data.maint_list.ids", new_struct_list); }