mirror of
https://github.com/SWG-Source/dsrc.git
synced 2026-07-14 23:07:51 -04:00
10345 lines
328 KiB
Plaintext
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);
|
|
}
|