Files
dsrc/sku.0/sys.server/compiled/game/script/library/player_structure.scriptlib
T
2014-04-01 01:57:32 -07:00

10345 lines
328 KiB
Plaintext

/**********************************************************************
* 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<city_ids.length; i++ )
{
location city_loc = cityGetLocation( city_ids[i] );
if ( city_loc.area.equals(planet_name) )
cities_on_planet++;
}
int max_cities = 0;
string[] planets = dataTableGetStringColumn( "datatables/city/city_limits.iff", "SCENE" );
for ( int i=0; i<planets.length; i++ )
{
if ( planets[i].equals(planet_name) )
{
max_cities = dataTableGetInt( "datatables/city/city_limits.iff", i, "MAX_CITIES" );
break;
}
}
int godLevel = getGodLevel(player);
if(godLevel < 9)
{
if ( cities_on_planet >= 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<contents.length; j++)
{
if(hasCondition(contents[j], CONDITION_VENDOR))
{
obj_id owner = getObjIdObjVar(contents[j], "vendor_owner");
if (!isIdValid(owner))
owner = getOwner( contents[j] );
vendor_lib.finalizePackUp(owner, contents[j], player, isAbandoned);
}
if(isIdValid(contents[j]))
{
messageTo(contents[j], "OnPack", null, 1.0f, false);
}
}
}
}
}
// Get the structure name
string structName = getStructureName(structure);
if (structName == null || structName.length() < 1)
{
structName = "Building";
}
// destroy waypoint if it exists
if(hasObjVar(structure, VAR_WAYPOINT_STRUCTURE))
{
obj_id waypoint = getObjIdObjVar(structure, VAR_WAYPOINT_STRUCTURE);
if(isIdValid(waypoint))
{
destroyWaypointInDatapad(waypoint, structure_owner);
removeObjVar(structure, VAR_WAYPOINT_STRUCTURE);
}
}
// Destroy house sign and name the control device whatever the building name was
destroyStructureSign(structure);
setName(scd, structName);
// Remove the structure as the player's residence
if ( hasBeenDeclaredResidence( structure ) )
{
obj_id resident = getResidentPlayer(structure);
setHouseId( resident, obj_id.NULL_ID );
removeObjVar( structure, VAR_RESIDENCE_BUILDING );
// Also remove the player from his current city.
int cityId = getCitizenOfCityId(resident);
if(cityId != 0)
{
cityRemoveCitizen( cityId, resident );
}
}
//we need removed even if we aren't a citizen.
city.removeStructureFromCity(structure);
// set the template objvar, this is required by the re-placement code
string template = getTemplateName(structure);
setDeedTemplate(scd, template);
// add the scene restrictions
if(hasObjVar(structure, VAR_DEED_SCENE))
{
setObjVar(scd, VAR_DEED_SCENE, getDeedScene(structure));
}
location where = getLocation(structure);
// if the structure is a "lot over limit structure", set objvar to indicate it has been moved to the datapad
if (isIdValid(structure_owner) && exists(structure_owner))
{
obj_id lotOverlimitStructure = getObjIdObjVar(structure_owner, "lotOverlimit.structure_id");
if (isIdValid(lotOverlimitStructure) && (lotOverlimitStructure == structure))
{
setObjVar(structure_owner, "lotOverlimit.structure_location", "Datapad");
}
}
// put the house into the structure control device
putIn(structure, scd);
if ( !structure_owner.isLoaded() )
{
const int maxDepth = isFactory(structure) ? 101 : 1;
moveToOfflinePlayerDatapadAndUnload(scd, structure_owner, maxDepth + 1); // add one for the scd
fixLoadWith(structure, structure_owner, maxDepth);
}
CustomerServiceLog("housepackup", "Player/Owner " + getPlayerName(player) +
" (" + player + ") packed structure (" + structure + ",abandoned="
+ isAbandoned + "," + where.toString()
+ " into device (" + scd + ")");
//if structure is in a city, we need to mail the mayor
if(city.isInCity(structure))
{
int city_id = getCityAtLocation( getLocation( structure ), 0 );
obj_id mayor = cityGetLeader( city_id );
string mayor_name = cityGetCitizenName( city_id, mayor );
string structure_name = localize( getNameStringId( structure ));
string ownerName = player_structure.getStructureOwner(structure);
prose_package pp = new prose_package();
prose.setStringId(pp, SELF_PACKUP_EMAIL_BODY);
prose.setTT(pp, ownerName);
prose.setTU(pp, structure_name);
utils.sendMail(SELF_PACKUP_EMAIL_TITLE, pp, mayor, "Galactic Housing Authority");
}
return;
}
/*
Pack up abandoned house as non-owner
*/
void finalizeAbandonedStructurePackUp(obj_id player, obj_id structure)
{
blog("player_structure.finalizeAbandonedStructurePackUp init.");
const boolean isAbandoned = isAbandoned(structure);
if(!isAbandoned)
{
//ADD LOGGING
return;
}
obj_id structure_owner = getOwner(structure);
CustomerServiceLog("housepackup", "Player " + getPlayerName(player) +
" (" + player + ") is attempting to pack structure (" + structure + ",abandoned=" + isAbandoned + ") owned by player " +
getPlayerName(structure_owner) + " (" + structure_owner + ")");
if (!structure.isLoaded() || !structure.isAuthoritative())
{
blog("player_structure.finalizeAbandonedStructurePackUp structure NOT LOADED or NOT AUTHORITATIVE.");
CustomerServiceLog("housepackup", "Structure (" + structure + ") could not be packed by player ("
+ getPlayerName(player) + ") structure -"
+ " isLoaded = " + structure.isLoaded()
+ " isAuthoritative = " + structure.isAuthoritative()
);
return;
}
// get data pad
obj_id datapad = utils.getPlayerDatapad(player);
if (!isIdValid(datapad))
{
blog("player_structure.finalizeAbandonedStructurePackUp datapad not valid.");
CustomerServiceLog("housepackup", "Structure (" + structure + ") could not be packed by player ("
+ getPlayerName(player) + ") - datapad was not valid"
);
return;
}
// Create a new structure control device in the datapad
if (structure_owner.isLoaded() && structure_owner.isAuthoritative())
{
blog("player_structure.finalizeAbandonedStructurePackUp The owner is loaded in game.");
obj_id owner_datapad = utils.getPlayerDatapad(structure_owner);
if(isIdValid(owner_datapad))
{
datapad = owner_datapad;
}
}
else if (!player.isLoaded() || !player.isAuthoritative())
{
blog("player_structure.finalizeAbandonedStructurePackUp The owner is NOT loaded in game and the player packing is not loaded or not authoritative.");
CustomerServiceLog("housepackup", "Structure (" + structure + ") could not be packed by player ("
+ getPlayerName(player) + ") player -"
+ " isLoaded = " + player.isLoaded()
+ " isAuthoritative = " + player.isAuthoritative()
);
return;
}
location where = getLocation(structure);
//play animation for abandoned structure
dictionary params = new dictionary();
params.put("structure", structure);
params.put("structure_owner", structure_owner);
blog("player_structure.finalizePackUp STRUCTURE WAS ABANDONED. Sending message back to player to send animation, tally success.");
messageTo( player, "callAirStrikePackAbandonedStructure", params, 0, false );
CustomerServiceLog("housepackup", "Player " + getPlayerName(player) +
" (" + player + ") is ABOUT to pack abandoned structure (" + structure + ",abandoned=" + isAbandoned + "," + where.toString() + ") owned by player " +
getPlayerName(structure_owner) + " (" + structure_owner + ")");
//if structure is in a city, we need to mail the mayor
if(city.isInCity(structure))
{
int city_id = getCityAtLocation( getLocation( structure ), 0 );
obj_id mayor = cityGetLeader( city_id );
string mayor_name = cityGetCitizenName( city_id, mayor );
string structure_name = localize( getNameStringId( structure ));
string ownerName = player_structure.getStructureOwner(structure);
prose_package pp = new prose_package();
prose.setStringId(pp, PACKUP_EMAIL_BODY);
prose.setTT(pp, ownerName);
prose.setTU(pp, structure_name);
utils.sendMail(PACKUP_EMAIL_TITLE, pp, mayor, "Galactic Vacant Building Demolishing Movement");
}
return;
}
//City House Packup System - Called when a player attempts to City Pack a structure that has
//a Zoning Violation - This re-checks to ensure the player is still in violation before continuing.
void confirmCityAbandonedAndPack(obj_id structure, obj_id player)
{
if(!isIdValid(player))
{
if(hasObjVar(player, "qa.city_packup"))
sendSystemMessageTestingOnly(player, "Packup Failed to confirm due to player(you) Obj_ID being invalid");
LOG("sissynoid", "City Pack Up System - Player ("+ player +")"+ getPlayerFullName(player) +" attempted to pack a structure("+ structure +"), but the Player ID is invalid");
CustomerServiceLog("city_house_packup", "City Pack Up System - Player ("+ player +")"+ getPlayerFullName(player) +" attempted to pack a structure("+ structure +"), but the Player ID is invalid");
return;
}
if(!isIdValid(structure))
{
if(hasObjVar(player, "qa.city_packup"))
sendSystemMessageTestingOnly(player, "Packup Failed to confirm due to structure Obj_ID being invalid");
LOG("sissynoid", "City Pack Up System - Player ("+ player +")"+ getPlayerFullName(player) +" attempted to pack a structure("+ structure +"), but the house ID is invalid");
CustomerServiceLog("city_house_packup", "City Pack Up System - Player ("+ player +")"+ getPlayerFullName(player) +" attempted to pack a structure("+ structure +"), but the house ID is invalid");
sendSystemMessage(player, SID_GENERIC_CITY_PACKUP_ERROR);
return;
}
//Check to make sure the player is still in violation of the 90+ Day Inactivity Ruleset.
obj_id owner = getOwner(structure);
if(!isPlayer(owner))
{
if(hasObjVar(player, "qa.city_packup"))
sendSystemMessageTestingOnly(player, "Packup Failed to confirm due to owner Obj_ID not existing - he has likely been deleted.");
LOG("sissynoid", "City Pack Up System - Player ("+ player +")"+ getPlayerFullName(player) +" attempted to pack structure("+ structure +") but the owner("+ getOwner(structure) +") Obj ID is not a player - Character has been deleted.");
CustomerServiceLog("city_house_packup", "City Pack Up System - Player ("+ player +")"+ getPlayerFullName(player) +" attempted to pack structure("+ structure +") but the owner("+ getOwner(structure) +") Obj ID is not a player - Character has been deleted.");
sendSystemMessage(player, SID_GENERIC_CITY_PACKUP_ERROR);
return;
}
if(!isIdValid(owner))
{
if(hasObjVar(player, "qa.city_packup"))
sendSystemMessageTestingOnly(player, "Packup Failed to confirm due to invalid owner Obj_ID");
LOG("sissynoid", "City Pack Up System - Player ("+ player +")"+ getPlayerFullName(player) +" attempted to pack structure("+ structure +") owned by Player("+ getOwner(structure) +") - but owner ID of the structure is invalid.");
CustomerServiceLog("city_house_packup", "City Pack Up System - Player ("+ player +")"+ getPlayerFullName(player) +" attempted to pack structure("+ structure +") owned by Player("+ getOwner(structure) +") - but owner ID of the structure is invalid.");
sendSystemMessage(player, SID_GENERIC_CITY_PACKUP_ERROR);
return;
}
//ensure the Owner has not logged in
int loginTime = getPlayerLastLoginTime(owner);
int curTime = getCalendarTime();
//Server Config: cityCitizenshipInactivePackupInactiveTimeSeconds=7776000 //90 days inactive
if((curTime - loginTime) < cityGetInactivePackupInactiveTimeSeconds())
{
if(hasObjVar(player, "qa.city_packup"))
sendSystemMessageTestingOnly(player, "Packup Failed to confirm due to the owner not being in violation (has not been logged out long enough)");
//we should not be abandoned!
LOG("sissynoid", "City Pack Up System - Player ("+ player +")"+ getPlayerFullName(player) +" attempted to pack structure("+ structure +") owned by Player("+ getOwner(structure) +") - but owner has not been offline for 90 days - Removing City Abandoned Flag.");
CustomerServiceLog("city_house_packup", "City Pack Up System - Player ("+ player +")"+ getPlayerFullName(player) +" attempted to pack structure("+ structure +") owned by Player("+ getOwner(structure) +") - but owner has not been offline for 90 days - Removing City Abandoned Flag.");
player_structure.removeCityAbandoned(structure);
sendSystemMessage(player, SID_NOT_CITY_ABANDONED);
return;
}
int city_id = getCityAtLocation(getLocation(structure), 0);
if(!cityExists(city_id))
{
if(hasObjVar(player, "qa.city_packup"))
sendSystemMessageTestingOnly(player, "Packup Failed to confirm due to the offending structure no longer residing inside of a player city.");
//A city no longer exists - remove the flag...
LOG("sissynoid", "City Pack Up System - Player ("+ player +")"+ getPlayerFullName(player) +" attempted to pack structure("+ structure +") owned by Player("+ getOwner(structure) +") but the structure is no longer in a valid Player City. Removing City Abandoned Tag.");
CustomerServiceLog("city_house_packup", "City Pack Up System - Player ("+ player +")"+ getPlayerFullName(player) +" attempted to pack structure("+ structure +") owned by Player("+ getOwner(structure) +") but the structure is no longer in a valid Player City. Removing City Abandoned Tag.");
player_structure.removeCityAbandoned(structure);
sendSystemMessage(player, SID_NO_CITY);
return;
}
if(city.hasMayorProtectionFlag(owner, city_id))
{
if(hasObjVar(player, "qa.city_packup"))
sendSystemMessageTestingOnly(player, "Packup Failed to confirm due to the Mayor protecting this Player's House.");
LOG("sissynoid", "City Pack Up System - Player ("+ player +")"+ getPlayerFullName(player) +" attempted to pack structure("+ structure +") owned by Player("+ getOwner(structure) +") - but owner is protected by the Mayor("+cityGetLeader(city_id)+") of City("+ city_id +")");
CustomerServiceLog("city_house_packup", "City Pack Up System - Player ("+ player +")"+ getPlayerFullName(player) +" attempted to pack structure("+ structure +") owned by Player("+ getOwner(structure) +") - but owner is protected by the Mayor("+cityGetLeader(city_id)+") of City("+ city_id +")");
sendSystemMessage(player, SID_MAYOR_PROTECTED);
return;
}
if(player_structure.isOwner(structure, player))
{
if(hasObjVar(player, "qa.city_packup"))
sendSystemMessageTestingOnly(player, "Packup Failed to confirm due to YOU being the OWNER! (God Mode makes you the owner of everything - '/setGod 0' please)");
//OMG! he's online! remove the abandoned tag!
LOG("sissynoid", "City Pack Up System - Player ("+ player +")"+ getPlayerFullName(player) +" attempted to pack his own structure - Removing City Abandoned Tag.");
CustomerServiceLog("city_house_packup", "City Pack Up System - Player ("+ player +")"+ getPlayerFullName(player) +" attempted to pack his own structure - Removing City Abandoned Tag.");
player_structure.removeCityAbandoned(structure);
return;
}
if(!player_structure.isCityAbandoned(structure))
{
if(hasObjVar(player, "qa.city_packup"))
sendSystemMessageTestingOnly(player, "Packup Failed to confirm due to Structure no longer being CityAbandoned");
LOG("sissynoid", "City Pack Up System - Player ("+ player +")"+ getPlayerFullName(player) +" attempted to pack this structure("+ structure +") - but it is not abandoned - bail");
CustomerServiceLog("city_house_packup", "City Pack Up System - Player ("+ player +")"+ getPlayerFullName(player) +" attempted to pack this structure("+ structure +") - but it is not abandoned - bail");
sendSystemMessage(player, SID_NOT_CITY_ABANDONED);
return;
}
if(!player_structure.isCityPackupAuthoritative(player, structure))
{
if(hasObjVar(player, "qa.city_packup"))
sendSystemMessageTestingOnly(player, "Packup Failed to confirm due to Player and House being on different game servers.");
//they are not authoritative
LOG("sissynoid", "City Pack Up System - Player ("+ player +")"+ getPlayerFullName(player) +" attempted to pack this structure - but the structure("+ structure +") is on a different server than the player.");
CustomerServiceLog("city_house_packup", "City Pack Up System - Player ("+ player +")"+ getPlayerFullName(player) +" attempted to pack this structure - but the structure("+ structure +") is on a different server than the player.");
sendSystemMessage(player, SID_GENERIC_CITY_PACKUP_ERROR);
return;
}
//otherwise - pack this house!
if(!player_structure.canPackStructureWithVendors(player, structure))
{
if(hasObjVar(player, "qa.city_packup"))
sendSystemMessageTestingOnly(player, "Packup Failed to confirm due to Server Vendor Config preventing Vendor Packups.");
LOG("sissynoid", "City Pack Up System - Player ("+ player +")"+ getPlayerFullName(player) +" attempted to pack structure - but the structure("+ structure +") can't be packed due to Vendors Config");
CustomerServiceLog("city_house_packup", "City Pack Up System - Player ("+ player +")"+ getPlayerFullName(player) +" attempted to pack structure - but the structure("+ structure +") can't be packed due to Vendors Config");
sendSystemMessage(player, SID_GENERIC_CITY_PACKUP_ERROR);
return;
}
LOG("sissynoid", "CHECKING NULL: SIGN CALL: HOUSE("+ structure +"), PLAYER(PACKER)("+ player +")");
dictionary params = new dictionary();
params.put("house", structure);
params.put("player", player);
messageTo(player, "packUpCityAbandonedStructure", params, 1.0f, false);
}
void finalizeCityPackUp(obj_id player, obj_id structure)
{
LOG("sissynoid", "Entered: finalizeCityPackUp");
if(!isIdValid(player))
{
LOG("sissynoid", "finalizeCityPackUp - Player is Invalid");
return;
}
if(!isIdValid(structure))
{
LOG("sissynoid", "finalizeCityPackUp - Structure is Invalid");
return;
}
if(!isCityAbandoned(structure))
{
LOG("sissynoid", "finalizeCityPackUp - Is NOT CITY ABANDONED!");
CustomerServiceLog("city_house_packup", "City House Packup was called on Structure("+ structure +
") by player("+ player +") but house was not City Abandoned!");
return;
}
//let's make sure we're still inside of a City.
int city_id = getCityAtLocation(getLocation(structure), 0);
if(!cityExists(city_id))
{
LOG("sissynoid", "finalizeCityPackUp: No Longer inside of a City - Remove isCityAbandoned!");
//we are no longer inside a City Limit - Remove the Abandoned Tag.
CustomerServiceLog("city_house_packup", "City House Packup was called on Structure("+ structure +
") by player("+ player +") but house is no longer in a City - Removing isCityAbandoned Flag.");
removeCityAbandoned(structure);
return;
}
obj_id structure_owner = getOwner(structure);
CustomerServiceLog("city_house_packup", "Player "+ getPlayerName(player) +" (" + player +
") is attempting to pack structure (" + structure + ", City Abandoned = " + isCityAbandoned(structure) +
") owned by player " + getPlayerName(structure_owner) + " (" + structure_owner + ")");
//get data pad
obj_id datapad = utils.getPlayerDatapad(player);
if(!isIdValid(datapad))
{
LOG("sissynoid", "finalizeCityPackUp: Datapad ID is Invalid");
CustomerServiceLog("city_house_packup", "Structure (" + structure + ") could not be packed by player ("+
getPlayerName(player) + ") - datapad was not valid");
return;
}
if(!player_structure.isCityPackupAuthoritative(player, structure)) //tests both player and structure
{
LOG("sissynoid", "finalizeCityPackUp: Player(Packer) is not Loaded or Authoritative");
CustomerServiceLog("city_house_packup",
"'finalizeCityPackUp' - Structure (" + structure +
") could not be packed by player ("
+ getPlayerName(player) + ") player -" +
" isLoaded(Player) = " + player.isLoaded() +
" isAuthoritative(Player) = " + player.isAuthoritative() +
" isLoaded(Structure) = " + structure.isLoaded() +
" isAuthoritative(Structure) = " + structure.isAuthoritative());
return;
}
location where = getLocation(structure);
CustomerServiceLog("city_house_packup", "Player " + getPlayerName(player) +" (" + player +
") is ABOUT to pack abandoned structure (" + structure + ",abandoned=" + isCityAbandoned(structure) +
"," + where.toString() + ") owned by player " + getPlayerName(structure_owner) + " (" + structure_owner + ")");
//if structure is in a city, we need to mail the mayor
if(cityExists(city_id))
{
LOG("sissynoid", "Mailing Mayor");
obj_id mayor = cityGetLeader(city_id);
string mayor_name = cityGetCitizenName(city_id, mayor);
string structure_name = localize(getNameStringId(structure));
string ownerName = player_structure.getStructureOwner(structure);
LOG("sissynoid", "CHECKING MAIL FOR NULL: MAYOR("+ mayor +"), MAYOR_NAME("+ mayor_name +"), STRUCTURE_NAME("+ structure_name +"), STRUCTURE_OWNER("+ ownerName +")");
prose_package pp = new prose_package();
prose.setStringId(pp, PACKUP_EMAIL_BODY);
prose.setTT(pp, ownerName);
prose.setTU(pp, structure_name);
utils.sendMail(PACKUP_EMAIL_TITLE, pp, mayor, "Galactic Housing Authority");
}
LOG("sissynoid", "checking for Null Value: PLAYER("+ player +"), STRUCTURE("+ structure +"), STRUCTURE_OWNER("+ structure_owner +")");
//Finally getting to the final step
dictionary params = new dictionary();
params.put("player", player);
params.put("structure", structure);
params.put("structure_owner", structure_owner);
messageTo (structure, "cityMoveStructureToSCD", params, 1.0f, false);
LOG("sissynoid", "Calling cityMoveStructureToSCD - Finally starting the packup procedure.");
return;
}
// House packing decrease point
int getPlayerPackUpMeritPoints(obj_id player)
{
int noMerit = 0;
if(!isValidId(player) || !exists(player))
return noMerit;
if(!hasObjVar(player, HOUSE_PACKUP_ARRAY_OBJVAR))
return noMerit;
int[] housePackingTally = getIntArrayObjVar(player, HOUSE_PACKUP_ARRAY_OBJVAR);
if(housePackingTally == null || housePackingTally.length != ARRAY_LENGTH_FOR_HOUSE_PACKUP)
return noMerit;
int currentAmountAvailable = housePackingTally[0];
if(currentAmountAvailable <= 0)
return noMerit;
return currentAmountAvailable;
}
// House packing decrease point
boolean housePackingPointDecrease(obj_id player)
{
return housePackingPointDecrease(player, 1);
}
// House packing decrease one or more point
boolean housePackingPointDecrease(obj_id player, int changeAmount)
{
if(!isValidId(player) || !exists(player))
return false;
if(changeAmount == 0)
return false;
if(changeAmount < 0)
changeAmount = Math.abs(changeAmount);
//If the player is being sent here and they dont have
//the array to decrement then it is an error!
if(!hasObjVar(player, HOUSE_PACKUP_ARRAY_OBJVAR))
return false;
int[] housePackingTally = getIntArrayObjVar(player, HOUSE_PACKUP_ARRAY_OBJVAR);
if(housePackingTally == null || housePackingTally.length != ARRAY_LENGTH_FOR_HOUSE_PACKUP)
return false;
int currentAmountAvailable = housePackingTally[0];
if(currentAmountAvailable <= 0)
return false;
if(currentAmountAvailable < changeAmount)
changeAmount = currentAmountAvailable;
//Decrement only the first element in the array
//the second element tallies the amount of career
//packups for the player so they can get a badge.
for(int i = 0; i < changeAmount; i++)
housePackingTally[0]--;
setObjVar (player, HOUSE_PACKUP_ARRAY_OBJVAR, housePackingTally);
return true;
}
// House packing reward point
boolean housePackingPointIncrease(obj_id player)
{
return housePackingPointIncrease(player, 1);
}
// House packing reward one or more points
boolean housePackingPointIncrease(obj_id player, int changeAmount)
{
blog("player_structure.housePackingPointIncrease init - changeAmount: "+changeAmount);
if(!isValidId(player) || !exists(player))
return false;
if(changeAmount <= 0)
return false;
//Do once when first house demolished
if(!hasObjVar(player, HOUSE_PACKUP_ARRAY_OBJVAR))
{
blog("player_structure.housePackingPointIncrease HOUSE_PACKUP_ARRAY_OBJVAR first time today packing house");
int[] newPackUpTrackingArray = new int[ARRAY_LENGTH_FOR_HOUSE_PACKUP];
//for the sake of readability we make sure each element is
//initialized to 0
for(int i = 0; i < ARRAY_LENGTH_FOR_HOUSE_PACKUP; i++)
newPackUpTrackingArray[i] = 0;
setObjVar(player, HOUSE_PACKUP_ARRAY_OBJVAR, newPackUpTrackingArray);
}
//Get the array objvar regardless of it just being created or existing
//previously
int[] housePackUpTrackingArray = getIntArrayObjVar(player, HOUSE_PACKUP_ARRAY_OBJVAR);
if(housePackUpTrackingArray.length != ARRAY_LENGTH_FOR_HOUSE_PACKUP)
return false;
for(int s = 0; s < ARRAY_LENGTH_FOR_HOUSE_PACKUP; s++)
{
blog("player_structure.housePackingPointIncrease changing housePackUpTrackingArray["+ s +"] from: "+housePackUpTrackingArray[s]);
housePackUpTrackingArray[s] += changeAmount;
blog("to: "+housePackUpTrackingArray[s]);
}
setObjVar(player, HOUSE_PACKUP_ARRAY_OBJVAR, housePackUpTrackingArray);
//Update objvar to make sure that a player can only pack
//up X number of houses a day
if(!hasObjVar(player, HOUSE_PACKUP_DAILY_TALLY_OBJVAR))
{
//If this is their first house today
setObjVar(player, HOUSE_PACKUP_DAILY_TALLY_OBJVAR, 1);
int resetTime = getGameTime() + player_structure.TIME_TO_NEXT_PACKUP; // 24 hours
blog("housePackingPointIncrease - resetting time to next packup: "+resetTime);
setObjVar(player, HOUSE_PACKUP_DAILY_TIMER_OBJVAR, resetTime);
}
else
{
//If this is an additional house for an existing tally
int tally = getIntObjVar(player, HOUSE_PACKUP_DAILY_TALLY_OBJVAR);
tally += changeAmount;
setObjVar(player, HOUSE_PACKUP_DAILY_TALLY_OBJVAR, tally);
}
if(!badge.hasBadge(player, "house_packup_badge"))
{
if(housePackUpTrackingArray[1] >= 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<contents.length; j++)
{
if(hasCondition(contents[j], CONDITION_VENDOR))
{
return true;
}
}
}
}
}
return false;
}
/***********************************************************************
* @brief Checks to see if the object is a building
*
* @param obj_id object
*
* @return boolean
***********************************************************************/
boolean isBuilding(obj_id object)
{
int got = getGameObjectType(object);
if ( isGameObjectTypeOf(got, GOT_building) )
{
//LOG("//LOG_CHANNEL", "player_structure::isInstallation called -- true");
return true;
}
/*
string template = getTemplateName(object);
if ((template.indexOf("building")) != -1)
{
////LOG("//LOG_CHANNEL", "player_structure::isBuilding called -- true");
return true;
}
else
{
////LOG("//LOG_CHANNEL", "player_structure::isBuilding called -- false");
return false;
}*/
return false;
}
/***********************************************************************
* @brief Checks to see if the object template name starts with object/building
*
* @param string objectTemplateName
*
* @return boolean
***********************************************************************/
boolean isBuildingName (string objectTemplateName)
{
return objectTemplateName.indexOf ("building") != -1;
}
/***********************************************************************
* @brief Checks to see if the object is an installation
*
* @param obj_id object
*
* @return boolean
***********************************************************************/
boolean isInstallation(obj_id object)
{
if (object == null || object == obj_id.NULL_ID)
{
return false;
}
int got = getGameObjectType(object);
if ( isGameObjectTypeOf(got, GOT_installation) )
{
//LOG("//LOG_CHANNEL", "player_structure::isInstallation called -- true");
return true;
}
/*
string template = getTemplateName(object);
if ((template.indexOf("installation")) != -1)
{
//LOG("//LOG_CHANNEL", "player_structure::isInstallation called -- true");
return true;
}
else
{
//LOG("//LOG_CHANNEL", "player_structure::isInstallation called -- false");
return false;
}*/
return false;
}
/***********************************************************************
* @brief Checks to see if the object is a guild hall.
*
* @param obj_id object
*
* @return boolean
***********************************************************************/
boolean isGuildHall(obj_id object)
{
if (!isIdValid(object))
return false;
if (!isBuilding(object))
return false;
if (hasObjVar(object, VAR_IS_GUILD_HALL))
return true;
else
{
String templateName = getTemplateName(object);
if(templateName.indexOf("guildhall") > 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<structures.length; i++ )
{
if ( structures[i] == template )
{
int civic = dataTableGetInt( PLAYER_STRUCTURE_DATATABLE, i, "CIVIC" );
if ( civic == 1 )
return true;
else
return false;
}
}
return false;
}
boolean isShuttleportTemplate( string template )
{
string[] structures = dataTableGetStringColumn( PLAYER_STRUCTURE_DATATABLE, "STRUCTURE" );
for ( int i=0; i<structures.length; i++ )
{
if ( structures[i] == template )
{
int shuttleport = dataTableGetInt( PLAYER_STRUCTURE_DATATABLE, i, "SHUTTLEPORT" );
if ( shuttleport == 1 )
return true;
else
return false;
}
}
return false;
}
boolean isCloneTemplate( string template )
{
string[] structures = dataTableGetStringColumn( PLAYER_STRUCTURE_DATATABLE, "STRUCTURE" );
for ( int i=0; i<structures.length; i++ )
{
if ( structures[i] == template )
{
int clone = dataTableGetInt( PLAYER_STRUCTURE_DATATABLE, i, "CLONE_FACILITY" );
if ( clone == 1 )
return true;
else
return false;
}
}
return false;
}
boolean isGarageTemplate(string template)
{
string[] structures = dataTableGetStringColumn(PLAYER_STRUCTURE_DATATABLE, "GARAGE");
for (int i=0; i<structures.length; i++)
{
if (structures[i] == template)
{
int garage = dataTableGetInt( PLAYER_STRUCTURE_DATATABLE, i, "GARAGE");
if (garage == 1)
return true;
else
return false;
}
}
return false;
}
/***********************************************************************
* @brief Checks to see if the object is a factory
*
* @param obj_id object
*
* @return boolean
***********************************************************************/
boolean isFactory(obj_id object)
{
if (object == null || object == obj_id.NULL_ID)
return false;
if (getGameObjectType(object) == GOT_installation_factory)
return true;
else
return false;
}
/***********************************************************************
* @brief Checks to see if the object is a harvester
*
* @param obj_id object
*
* @return boolean
***********************************************************************/
boolean isHarvester(obj_id object)
{
if (object == null || object == obj_id.NULL_ID)
return false;
if (getGameObjectType(object) == GOT_installation_harvester)
return true;
else
return false;
}
/***********************************************************************
* @brief Checks to see if the object is a generator
*
* @param obj_id object
*
* @return boolean
***********************************************************************/
boolean isGenerator(obj_id object)
{
if (object == null || object == obj_id.NULL_ID)
return false;
if (getGameObjectType(object) == GOT_installation_generator)
return true;
else
return false;
}
/***********************************************************************
* @brief Determines if the specified player has permission to admin
* the specified structure
*
* @param obj_id structure
* @param string player_or_guild_name (guild names must be prefixed with "guild:")
*
* @return boolean
***********************************************************************/
boolean isAdmin(obj_id structure, string player_or_guild_name)
{
if (!isIdValid(structure))
return false;
string[] admin_list = getAdminListRaw(structure);
if (admin_list != null)
{
// See if the player name or guild name is on the admin list
if ( isNameOnRawList( admin_list, player_or_guild_name ) )
{
return true;
}
else
{
// If admin lists ever properly support guilds, the
// following code will likely need to be enabled
/*
// Check to see if we have a player name by looking at the prefix
if ( player_or_guild_name.toLowerCase().indexOf("guild:") == -1 )
{
obj_id playerObjId = getPlayerIdFromFirstName( player_or_guild_name.trim().toLowerCase() );
if ( isIdValid( playerObjId ) )
{
// See if the player's guild is on the admin list
if ( isGuildIdOnRawList( admin_list, getGuildId( playerObjId ) ) )
{
return true;
}
}
}
*/
}
}
return false;
}
/***********************************************************************
* @brief Overload for isAdmin
*
* @param obj_id structure
* @param obj_id player_name
*
* @return boolean
***********************************************************************/
boolean isAdmin(obj_id structure, obj_id player)
{
if (!isIdValid(structure))
return false;
if (!isIdValid(player))
return false;
if (isGod(player))
return true;
string player_name = getPlayerName(player);
boolean admin = isAdmin(structure, player_name);
if (!admin)
{
// Check to see if the player is the owner, but somehow is not on the admin list (probably due to a name change)
if (isOwner(structure, player))
{
// Reset the structure owner name.
setObjVar(structure, VAR_OWNER, player_name);
// Re-add the player to the admin list.
modifyList(structure, player_name, null, VAR_ADMIN_LIST, false);
return true;
}
}
return admin;
}
/***********************************************************************
* @brief Determines if the specified player has permission to place
* vendors at the specified structure
*
* @param obj_id structure
* @param string player_name
*
* @return boolean
***********************************************************************/
boolean isVendor(obj_id structure, string player_name)
{
if (structure == null || structure == obj_id.NULL_ID)
return false;
string[] vendor_list = getVendorList(structure);
if (vendor_list != null)
{
string playerNameUpperCase = player_name.toUpperCase();
for (int i = 0; i < vendor_list.length; i++)
{
if (playerNameUpperCase.equals(vendor_list[i].toUpperCase()))
{
return true;
}
}
}
return false;
}
/***********************************************************************
* @brief Overload for canVendor
*
* @param obj_id structure
* @param obj_id player_name
*
* @return boolean
***********************************************************************/
boolean isVendor(obj_id structure, obj_id player)
{
if (isIdValid(player))
return isVendor(structure, getPlayerName(player));
else
return false;
}
/***********************************************************************
* @brief Determines if the specified player can enter the
* specified structure
*
* @param obj_id structure
* @param string player_or_guild_name
*
* @return boolean
***********************************************************************/
boolean canEnter(obj_id structure, string player_or_guild_name)
{
if (!isIdValid(structure))
return false;
string[] entry_list = getCompleteEntryList(structure);
if (entry_list != null)
{
if ( isNameOnPermissionList( entry_list, player_or_guild_name ) )
{
return true;
}
else
{
// DANGER WILL ROBINSON!!!!
//
// This method has never checked the guild of the player
// to see if the guild is on the list. If the following
// code is enabled, then some things may break
/*
// Check to see if we have a player name by looking at the prefix
if ( player_or_guild_name.toLowerCase().indexOf("guild:") == -1 )
{
obj_id playerObjId = getPlayerIdFromFirstName( player_or_guild_name.trim().toLowerCase() );
if ( isIdValid( playerObjId ) )
{
// See if the player's guild is on the admin list
int guildId = getGuildId( playerObjId );
if ( guildId != 0 )
{
string guildName = "guild:" + guildGetName( guildId );
// Look for the guild name in the list
if ( isNameOnPermissionList( entry_list, guildName ) )
{
return true;
}
}
}
}
*/
}
}
return false;
}
/***********************************************************************
* @brief Overload for canEnter
*
* @param obj_id structure
* @param obj_id player_name
*
* @return boolean
***********************************************************************/
boolean canEnter(obj_id structure, obj_id player)
{
if (isIdValid(player))
return canEnter(structure, getPlayerName(player));
else
return false;
}
/***********************************************************************
* @brief Overload for canHopper
*
* @param obj_id structure
* @param obj_id player_or_guild_name (guild names must be prefixed with "guild:")
*
* @return boolean
***********************************************************************/
boolean canHopper(obj_id structure, string player_or_guild_name)
{
if (!isIdValid(structure))
return false;
string[] hopper_list = getHopperListRaw(structure);
if (hopper_list != null)
{
// See if the player name or guild name is on the hopper list
if ( isNameOnRawList( hopper_list, player_or_guild_name ) )
{
return true;
}
else
{
// If hopper lists ever properly support guilds, the
// following code will likely need to be enabled
/*
// Check to see if we have a player name by looking at the prefix
if ( player_or_guild_name.toLowerCase().indexOf("guild:") == -1 )
{
obj_id playerObjId = getPlayerIdFromFirstName( player_or_guild_name.trim().toLowerCase() );
if ( isIdValid( playerObjId ) )
{
// See if the player's guild is on the hopper list
if ( isGuildIdOnRawList( hopper_list, getGuildId( playerObjId ) ) )
{
return true;
}
}
}
*/
}
}
return false;
}
/***********************************************************************
* @brief Determines if the specified player can use the
* hopper of the installation
*
* @param obj_id structure
* @param obj_id player
*
* @return boolean
***********************************************************************/
boolean canHopper(obj_id structure, obj_id player)
{
if (isIdValid(player))
return canHopper(structure, getPlayerName(player));
else
return false;
}
/***********************************************************************
* @brief Determines if the specified player is banned from the
* specified structure
*
* @param obj_id structure
* @param string player_or_guild_name
*
* @return boolean
***********************************************************************/
boolean isBanned(obj_id structure, string player_or_guild_name)
{
if (!isIdValid(structure))
return false;
string[] ban_list = getBanList(structure);
if (ban_list != null)
{
if ( isNameOnPermissionList( ban_list, player_or_guild_name ) )
{
return true;
}
else
{
// DANGER WILL ROBINSON!!!!
//
// This method has never checked the guild of the player
// to see if the guild is on the list. If the following
// code is enabled, then some things may break
/*
// Check to see if we have a player name by looking at the prefix
if ( player_or_guild_name.toLowerCase().indexOf("guild:") == -1 )
{
obj_id playerObjId = getPlayerIdFromFirstName( player_or_guild_name.trim().toLowerCase() );
if ( isIdValid( playerObjId ) )
{
// See if the player's guild is on the admin list
int guildId = getGuildId( playerObjId );
if ( guildId != 0 )
{
string guildName = "guild:" + guildGetName( guildId );
// Look for the guild name in the list
if ( isNameOnPermissionList( ban_list, guildName ) )
{
return true;
}
}
}
}
*/
}
}
return false;
}
/***********************************************************************
* @brief Overload for isBanned
*
* @param obj_id structure
* @param obj_id player_name
*
* @return boolean
***********************************************************************/
boolean isBanned(obj_id structure, obj_id player)
{
if (isIdValid(player))
return isBanned(structure, getPlayerName(player));
else
return false;
}
/***********************************************************************
* @brief Determines if the specified player is the owner of the
* specified structure
*
* @param obj_id structure
* @param string player_name
*
* @return boolean
***********************************************************************/
boolean isOwner(obj_id structure, string player_name)
{
if (structure == null || structure == obj_id.NULL_ID)
return false;
string owner_name = getStructureOwner(structure);
if (owner_name.toUpperCase().equals(player_name.toUpperCase())) return true;
else return false;
}
/***********************************************************************
* @brief Overload for isOwner
*
* @param obj_id structure
* @param obj_id player_name
*
* @return boolean
***********************************************************************/
boolean isOwner(obj_id structure, obj_id player)
{
if (player == null || player == obj_id.NULL_ID)
return false;
if (isGod(player))
return true;
//string player_name = getFirstName(player);
obj_id owner = getOwner(structure);
if (owner == player)
return true;
else
return false;
}
/***********************************************************************
* @brief Determines if the specified player has declared residence
* in the specified structure
*
* @param obj_id structure
* @param string player_name
*
* @return boolean
***********************************************************************/
boolean isResidence(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;
obj_id residence = getResidence(player);
if (residence == structure)
return true;
else
return false;
}
/***********************************************************************
* @brief applies the owner's management mods to the structure
*
* @param obj_id structure
* @param dictionary mods a dictionary of all mods to apply
*
* @return boolean
***********************************************************************/
boolean applyManagementMods(obj_id structure, dictionary mods)
{
if (structure == null || structure == obj_id.NULL_ID)
return false;
// Maintenance modifer reduces the cost per maintenance loop.
int mm = 0;
if (mods.containsKey("maintenance_mod"))
mm = mm + mods.getInt("maintenance_mod");
if (isFactory(structure))
{
if (mods.containsKey("factory_mod"))
mm = mm + mods.getInt("factory_mod");
}
string template = getTemplateName(structure);
int idx = getStructureTableIndex(template);
int maint_rate = dataTableGetInt(PLAYER_STRUCTURE_DATATABLE, idx, DATATABLE_COL_MAINT_RATE);
maint_rate = maint_rate * 100 / (100 + mm);
// Store the total management mod for updates.
if (mm > 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<contents.length; j++)
{
if(hasCondition(contents[j], CONDITION_VENDOR))
{
obj_id vendorOwner = getObjIdObjVar(contents[j], "vendor_owner");
if (!isIdValid(vendorOwner))
vendorOwner = getOwner( contents[j] );
vendor_lib.finalizePackUp(vendorOwner, contents[j], self, false);
}
}
}
}
}
}
// Now destroy the structure.
destroyObject(structure);
return bGetSelfPowered ? DESTROY_RESULT_SUCCESS_SELFPOWERED : DESTROY_RESULT_SUCCESS;
}
/***********************************************************************
* @brief Destroys a structure and provides necessary cleanup. Assumes "self" is a player trying to destroy the structure.
*
* @param obj_id structure structure to destroy
* @param boolean reclaim whether or not to reconstruct the deed
*
* @return boolean true on success
***********************************************************************/
boolean destroyStructure(obj_id structure, boolean reclaim)
{
return destroyStructure(structure, reclaim, false);
}
boolean destroyStructure(obj_id structure, boolean reclaim, boolean overrideOwner)
{
obj_id owner = overrideOwner ? getSelf() : getStructureOwnerObjId(structure);
if (!isIdValid(owner))
return false;
obj_id self = getSelf(); //this should be the person that used the /destroyStructure command
if ( isPlayer(self) && !isGod(self) && self != owner )
{
sendSystemMessage(self, new string_id(STF_FILE, "destroy_must_be_owner")); // You must be the owner to destroy a structure.
return false;
}
obj_id inv = utils.getInventoryContainer(self);
int resultCode = destroyStructure(structure, inv, reclaim, false);
switch(resultCode)
{
case DESTROY_RESULT_FAIL_COULD_NOT_CREATE_DEED:
sendSystemMessage(self, new string_id(STF_FILE, "repack_design_error"));
return false;
case DESTROY_RESULT_FAIL_COULD_NOT_DETERMINE_DEED_FOR_STRUCTURE:
sendSystemMessage(self, new string_id(STF_FILE, "contact_cs"));
return false;
case DESTROY_RESULT_FAIL_TARGET_CONTAINER_FULL:
sendSystemMessage(self, new string_id(STF_FILE, "inventory_full"));
return false;
case DESTROY_RESULT_FAIL_TARGET_CONTAINER_FULL_SELFPOWERED:
sendSystemMessage(self, new string_id(STF_FILE, "inventory_full_selfpowered"));
return false;
case DESTROY_RESULT_SUCCESS_SELFPOWERED :
sendSystemMessage(self, new string_id(STF_FILE, "selfpowered"));
break;
case DESTROY_RESULT_INVALID_STATIC_ITEM :
sendSystemMessage(self, new string_id(STF_FILE, "invalid_static_item"));
return false;
case DESTROY_RESULT_INVALID_CONTAINER :
sendSystemMessage(self, new string_id(STF_FILE, "inventory_invalid"));
return false;
}
return true;
}
/***********************************************************************
* @brief Overload for destroy structure
*
* @param obj_id structure structure to destroy
*
* @return boolean true on success
***********************************************************************/
boolean destroyStructure(obj_id structure)
{
return destroyStructure(structure, false);
}
/***********************************************************************
* @brief Destroys all objects created when the building was intialized
*
* @param obj_id structure structure whose pool to reduce
*
* @return boolean true on success
***********************************************************************/
boolean destroyBaseObjects(obj_id structure)
{
if (structure == null || structure == obj_id.NULL_ID)
return false;
obj_id[] base_objects = getObjIdArrayObjVar(structure, VAR_BASE_OBJECT);
if (base_objects == null)
{
//LOG("//LOG_CHANNEL", structure + " has a null base object list.");
return false;
}
for (int i = 0; i < base_objects.length; i++)
{
if (isIdValid(base_objects[i]))
destroyObject(base_objects[i]);
}
return true;
}
/***********************************************************************
* @brief Determines whether or not the obj_ids of base objects
* are valid. If they are not, it recreates them.
*
* @param obj_id structure structure whose pool to reduce
*
* @return boolean true on success
***********************************************************************/
boolean validateBaseObjects(obj_id structure)
{
if (!isIdValid(structure))
return false;
boolean create_objects = false;
obj_id[] base_objects = getStructureBaseObjects(structure);
if (base_objects != null)
{
for (int i = 0; i < base_objects.length; i++)
{
if (!isIdValid(base_objects[i]) || !base_objects[i].isLoaded())
create_objects = true;
else
{
obj_id container = getTopMostContainer(base_objects[i]);
if (container == null || structure != container)
create_objects = true;
}
}
}
// Recreate all base objects if any of them are invalid.
if (create_objects)
{
destroyBaseObjects(structure);
float yaw = getYaw(structure);
if (yaw < 0.0f)
yaw = yaw + 360.0f;
int rotation = (int)(yaw + 1) / 90;
createStructureObjects(structure, rotation);
}
return true;
}
/***********************************************************************
* @brief Converts time from seconds into days, hours, etc.
*
* @param int time
*
* @return int[] {days, hours, minutes, seconds}
***********************************************************************/
int[] convertSecondsTime(int time)
{
if (time < 1)
return null;
if ( time == Integer.MAX_VALUE )
{
int[] ret = {Integer.MAX_VALUE};
return ret;
}
int mod_day = time % 86400;
int mod_hour = mod_day % 3600;
int days = time / 86400;
int hours = mod_day / 3600;
int minutes = mod_hour / 60;
int seconds = mod_hour % 60;
int[] converted_time = {days, hours, minutes, seconds};
return converted_time;
}
/***********************************************************************
* @brief Assembles time into a string.
*
* @param int days
* @param int hours
* @param int minutes
* @param int seconds
*
* @return string converted time.
***********************************************************************/
string assembleTimeRemaining(int[] time_values)
{
if ( time_values == null || time_values.length == 0 || time_values.length > 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:<guild name>"
*
* @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 <<<<NEWNEWNEW RCT. (This whole block is new)
{
if ( template.indexOf( "_large_style_" ) != -1 )
{
setObjVar(structure, "newBuilding", true );
setObjVar(structure, "newBuildPartTwo", true );
}
}
}
//this is to convert the lot costs of OLD guildhalls and OLD factories so
// that re-deeding them gives you back the same number of lots they
// cost to place them:
// added 10-22-4, delete this in a month or two
int convertLotCosts( obj_id structure, string template, int struct_lots )
{
if ( !hasObjVar(structure, "newBuilding" ) || !hasObjVar(structure, "newBuildPartTwo" ))
{
//if this is an OLD guildhall, it cost 9 lots, except for tatooine halls
if ( template.indexOf( "_guildhall_" ) != -1 )
{
//tat style halls only ever cost 7, so leave the lot cost at 7
if ( template.indexOf("_guildhall_tatooine_") == -1 )
{
// this must have cost 9 to place, so get 9 back for picking it up
struct_lots = 9;
}
else // if it IS a tat guild hall, it was originally 7 lots, not 9. <<<<NEWNEWNEW RCT - This whole block
{
// this must have cost 7 to place, so get 7 back for picking it up
struct_lots = 7;
}
}
else if ( template.indexOf( "structure_factory" ) != -1 )
{
//this building cost 2 lots to place,
// so get two back for plucking it up
struct_lots = 2;
}
else if ( template.indexOf( "player_house_" ) != -1 ) //If it's a large house, credit them with the original number of lots for it <<<<NEWNEWNEW RCT. (This whole block is new)
{
if ( template.indexOf( "_large_style_" ) != -1 )
{
//this building cost 6 lots to place,
// so get six back for plucking it up
struct_lots = 6;
}
}
}
return struct_lots;
}
// added 10-22-4, delete this in a month or two
void doOldToNewLotConversion( obj_id player, obj_id structure )
{
if (!isOwner(structure, player))
return;//fuck that!
//if it has this objvar, it's already been converted!
if ( !hasObjVar(structure, "newBuilding" ))
{
string template = getTemplateName(structure);
//convert guild lot costs and structure factory costs:
if ( template.indexOf( "_guildhall_" ) != -1 )
{
//tatooine guildhalls don't get converted!
if ( template.indexOf("_guildhall_tatooine_") == -1 )
{
//We Owe you 2 lots!
adjustLotCount(getPlayerObject(player), -4); //modified to add 4 lots instead of 2, for part 2 lot changes
setObjVar(structure, "newBuilding", true );
setObjVar(structure, "newBuildPartTwo", true );
}
else //(if it IS a tatooine guildhall) <<<<NEWNEWNEW RCT (this whole ELSE block is new. Used to ignore tat guildhalls)
{
//We Owe you 2 lots!
adjustLotCount(getPlayerObject(player), -2);
setObjVar(structure, "newBuilding", true );
setObjVar(structure, "newBuildPartTwo", true );
}
}
else if ( template.indexOf( "structure_factory" ) != -1 )
{
//we owe you one lot
adjustLotCount(getPlayerObject(player), -1);
setObjVar(structure, "newBuilding", true );
}
else if ( template.indexOf( "player_house_" ) != -1 ) //If it's a large house, change their lots also <<<<NEWNEWNEW RCT. (This whole block is new)
{
if ( template.indexOf( "_large_style_" ) != -1 )
{
//we owe you one lot
adjustLotCount(getPlayerObject(player), -1);
setObjVar(structure, "newBuilding", true );
setObjVar(structure, "newBuildPartTwo", true );
}
}
}
else if ( !hasObjVar(structure, "newBuildPartTwo" ) ) // NEW NEW NEW - RCT - If the building has already been updated by JeffF's lot updater, let's set just the latest round of changes
{
string template = getTemplateName(structure);
//convert guild lot costs and large house costs
if ( template.indexOf( "_guildhall_" ) != -1 )
{
//We Owe you 2 lots!
adjustLotCount(getPlayerObject(player), -2);
setObjVar(structure, "newBuildPartTwo", true );
}
else if ( template.indexOf( "player_house_" ) != -1 ) //If it's a large house, change their lots also <<<<NEWNEWNEW RCT. (This whole block is new)
{
if ( template.indexOf( "_large_style_" ) != -1 )
{
//we owe you one lot
adjustLotCount(getPlayerObject(player), -1);
setObjVar(structure, "newBuildPartTwo", true );
}
}
}
}
// added 10-22-4, delete this in a month or two
void adjustLotsForOfflinePlayer( obj_id owner, obj_id structure )
{
dictionary params = new dictionary();
//if it has this objvar, it's already been converted!
if ( !hasObjVar(structure, "newBuilding" ) )
{
string template = getTemplateName(structure);
//convert guild lot costs and structure factory costs:
if ( template.indexOf( "_guildhall_" ) != -1 )
{
//tatooine guildhalls don't get converted!
if ( template.indexOf("_guildhall_tatooine_") == -1 )
{
//We Owe you 2 lots!
//params.put( "lotAdjust", -2 ); //commented out, as we're going to give you 4 lots back (going from 9 to 5 lots) <<<<NEWNEWNEW RCT
params.put( "lotAdjust", -4 );
setObjVar(structure, "newBuilding", true );
setObjVar(structure, "newBuildPartTwo", true );
messageTo( owner, "handleAdjustLotCount", params, 0, true );
}
else //(if it IS a tatooine guildhall) <<<<NEWNEWNEW RCT (this whole ELSE block is new. Used to ignore tat guildhalls)
{
//We Owe you 2 lots!
params.put( "lotAdjust", -2 );
setObjVar(structure, "newBuilding", true );
setObjVar(structure, "newBuildPartTwo", true );
messageTo( owner, "handleAdjustLotCount", params, 0, true );
}
}
else if ( template.indexOf( "structure_factory" ) != -1 )
{
//we owe you one lot
params.put( "lotAdjust", -1 );
setObjVar(structure, "newBuilding", true );
setObjVar(structure, "newBuildPartTwo", true );
messageTo( owner, "handleAdjustLotCount", params, 0, true );
}
else if ( template.indexOf( "player_house_" ) != -1 ) //If it's a large house, change their lots also <<<<NEWNEWNEW RCT. (This whole block is new)
{
if ( template.indexOf( "_large_style_" ) != -1 )
{
//we owe you one lot
params.put( "lotAdjust", -1 );
setObjVar(structure, "newBuilding", true );
setObjVar(structure, "newBuildPartTwo", true );
messageTo( owner, "handleAdjustLotCount", params, 0, true );
}
}
}
else if ( !hasObjVar(structure, "newBuildPartTwo" ) ) // NEW NEW NEW - RCT - If the building has already been updated by JeffF's lot updater, let's set just the latest round of changes
{
string template = getTemplateName(structure);
//convert guild lot costs and large house costs
if ( template.indexOf( "_guildhall_" ) != -1 )
{
//We Owe you 2 lots!
params.put( "lotAdjust", -2 );
setObjVar(structure, "newBuildPartTwo", true );
messageTo( owner, "handleAdjustLotCount", params, 0, true );
}
else if ( template.indexOf( "player_house_" ) != -1 ) //If it's a large house, change their lots also <<<<NEWNEWNEW RCT. (This whole block is new)
{
if ( template.indexOf( "_large_style_" ) != -1 )
{
//we owe you one lot
params.put( "lotAdjust", -1 );
setObjVar(structure, "newBuildPartTwo", true );
messageTo( owner, "handleAdjustLotCount", params, 0, true );
}
}
}
}
void doCondemnedSui(obj_id objStructure, obj_id objItem)
{
// branching suis
// 1. ARe you owner
obj_id objOwner = getStructureOwnerObjId(objStructure);
LOG("test", "objOwner is "+objOwner+" and item is "+objItem);
if(isPlayer(objItem))
{
if(objOwner==objItem || player_structure.isAdmin(objStructure, objItem))
{
int intRepairCost =getStructureRepairCost(objStructure);
int intBankCredits = getBankBalance(objItem);
if(intRepairCost<=intBankCredits)
{
/// SUI
string strTitle = "@player_structure:fix_condemned_title";
string_id strPrompt = new string_id(STF_FILE, "structure_condemned_owner_has_credits");
string strConfirm= "@player_structure:confirm_pay";
prose_package pp = new prose_package();
prose.setStringId(pp, strPrompt);
prose.setDI(pp, intRepairCost);
// something magical goes here.
int pid = sui.msgbox(objStructure, objItem, pp, sui.OK_CANCEL, strTitle, "payCondemnedFees");
if(pid > -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);
}