mirror of
https://github.com/SWG-Source/dsrc.git
synced 2026-07-31 00:15:54 -04:00
You can now rename your beast as much as you would like. Police officers will no longer harass corpses. Static NPC's conversing will now successfully converse with one another. When a player dies, the pet will go invulnerable and be immediately packed up. When respecing professions, your weapon will now be unequiped. Fixed the chat system for some NPC's. You can now only mount your vehicle from less than 5 meters. Quest items that can be clicked on cannot be used from less than 5 meters. Added a message to the QaSetup script, notifying the QA that they have received their items.
15885 lines
488 KiB
Plaintext
15885 lines
488 KiB
Plaintext
/**
|
|
* Title: base_player.script
|
|
* Description: required script functionality for all player objects
|
|
*/
|
|
|
|
/***** INCLUDES ********************************************************/
|
|
|
|
include ai.ai_combat;
|
|
include java.lang.Math;
|
|
include java.util.Iterator;
|
|
include java.util.Set;
|
|
include library.ai_lib;
|
|
include library.anims;
|
|
include library.armor;
|
|
include library.badge;
|
|
include library.beast_lib;
|
|
include library.bio_engineer;
|
|
include library.bounty_hunter;
|
|
include library.buff;
|
|
include library.callable;
|
|
include library.chat;
|
|
include library.city;
|
|
include library.cloninglib;
|
|
include library.colors;
|
|
include library.colors_hex;
|
|
include library.collection;
|
|
include library.combat;
|
|
include library.consumable;
|
|
include library.corpse;
|
|
include library.cts;
|
|
include library.dot;
|
|
include library.dump;
|
|
include library.expertise;
|
|
include library.event_perk;
|
|
include library.factions;
|
|
include library.features;
|
|
include library.food;
|
|
include library.force_rank;
|
|
include library.force_rank;
|
|
include library.fs_quests;
|
|
include library.gm;
|
|
include library.gmlib;
|
|
include library.groundquests;
|
|
include library.group;
|
|
include library.gcw; // not alphabetical // thx nfo
|
|
include library.guild;
|
|
include library.healing;
|
|
include library.hq;
|
|
include library.hue;
|
|
include library.instance;
|
|
include library.jedi;
|
|
include library.jedi_trials;
|
|
include library.list;
|
|
include library.locations;
|
|
include library.loot;
|
|
include library.luck;
|
|
include library.meditation;
|
|
include library.metrics;
|
|
include library.money;
|
|
include library.movement;
|
|
include library.npe;
|
|
include library.pclib;
|
|
include library.performance;
|
|
include library.permissions;
|
|
include library.pet_lib;
|
|
include library.pgc_quests;
|
|
include library.player_stomach;
|
|
include library.player_structure;
|
|
include library.proc;
|
|
include library.prose;
|
|
include library.pvp;
|
|
include library.regions;
|
|
include library.resource;
|
|
include library.respec;
|
|
include library.scout;
|
|
include library.skill;
|
|
include library.skill_template;
|
|
include library.slicing;
|
|
include library.smuggler;
|
|
include library.space_combat;
|
|
include library.space_crafting;
|
|
include library.space_dungeon;
|
|
include library.space_dungeon_data;
|
|
include library.space_flags;
|
|
include library.space_quest;
|
|
include library.space_skill;
|
|
include library.space_transition;
|
|
include library.space_utils;
|
|
include library.squad_leader;
|
|
include library.static_item;
|
|
include library.stealth;
|
|
include library.storyteller;
|
|
include library.structure;
|
|
include library.sui;
|
|
include library.temp_schematic;
|
|
include library.township;
|
|
include library.trace;
|
|
include library.travel;
|
|
include library.trial;
|
|
include library.utils;
|
|
include library.vehicle;
|
|
include library.vendor_lib;
|
|
include library.veteran_deprecated;
|
|
include library.weapons;
|
|
include library.xp;
|
|
include library.restuss_event;
|
|
include library.session;
|
|
include library.incubator;
|
|
include library.missions;
|
|
include library.reverse_engineering;
|
|
|
|
include java.util.Arrays;
|
|
include java.util.Vector;
|
|
include java.util.Enumeration; // <-- only need this for some debug shits
|
|
|
|
/***** CONSTANTS *******************************************************/
|
|
|
|
const int TIME_DEATH = 5;
|
|
//const int MAX_JEDI_DEATHS = 5;
|
|
|
|
const float RANGE_COUP_DE_GRACE = 3.0f;
|
|
|
|
const string JEDI_CLOAK_TEMPLATE = "object/tangible/wearable/robe/robe_s05.iff";
|
|
|
|
const string MSG_REVIVE_TITLE = "@base_player:revive_title";
|
|
const string MSG_REVIVE_MSG = "@base_player:revive_msg";
|
|
|
|
const string MSG_REVIVE_CLOSEST_INSURED = "@base_player:revive_closest_insured";
|
|
const string MSG_REVIVE_CLOSEST_UNINSURED = "@base_player:revive_closest_uninsured";
|
|
const string MSG_REVIVE_BIND_INSURED = "@base_player:revive_bind_insured";
|
|
const string MSG_REVIVE_BIND_UNINSURED = "@base_player:revive_bind_uninsured";
|
|
|
|
const string MSG_REVIVE_CLOSEST = "@base_player:revive_closest";
|
|
const string MSG_REVIVE_BIND = "@base_player:revive_bind";
|
|
|
|
const string_id SID_VICTIM_INCAPACITATED = new string_id("base_player", "victim_incapacitated");
|
|
const string_id SID_KILLER_TARGET_INCAPACITATED = new string_id("base_player", "killer_target_incapacitated");
|
|
|
|
const string_id PROSE_VICTIM_INCAP = new string_id("base_player", "prose_victim_incap");
|
|
const string_id PROSE_TARGET_INCAP = new string_id("base_player", "prose_target_incap");
|
|
|
|
const string_id SID_COUP_DE_GRACE = new string_id("base_player", "death_blow");
|
|
const string_id SID_REVIVE = new string_id("base_player", "revive_player");
|
|
const string_id SID_RESUSCITATE = new string_id("base_player", "resuscitate_player");
|
|
|
|
const string_id SID_TARGET_OUT_OF_RANGE = new string_id("error_message","target_out_of_range");
|
|
const string_id SID_TARGET_NOT_ATTACKABLE = new string_id("error_message","target_not_attackable");
|
|
|
|
const string_id SID_SYNTAX_UNCONSENT = new string_id("error_message","syntax_unconsent");
|
|
|
|
const string_id SID_CONSENT_TO_EMPTY = new string_id("error_message","consent_to_empty");
|
|
const string_id SID_CONSENT_FROM_EMPTY = new string_id("error_message","consent_from_empty");
|
|
|
|
const string_id SID_HAVE_CONSENT_TRUE = new string_id("base_player","haveconsent_true");
|
|
const string_id SID_HAVE_CONSENT_FALSE = new string_id("base_player","haveconsent_false");
|
|
|
|
const string_id SID_CONSENT_SUCCESSFUL = new string_id("base_player","consent_successful");
|
|
const string_id SID_UNCONSENT_SUCCESSFUL = new string_id("base_player","unconsent_successful");
|
|
|
|
const string_id SID_CONSENT_TO_LISTBOX_PROMPT = new string_id("base_player","consent_to_listbox_prompt");
|
|
const string_id SID_CONSENT_TO_LISTBOX_TITLE = new string_id("base_player","consent_to_listbox_title");
|
|
|
|
const string_id SID_CONSENT_FROM_LISTBOX_PROMPT = new string_id("base_player","consent_from_listbox_prompt");
|
|
const string_id SID_CONSENT_FROM_LISTBOX_TITLE = new string_id("base_player","consent_from_listbox_title");
|
|
|
|
const string_id SID_UNCONSENT_LISTBOX_PROMPT = new string_id("base_player","unconsent_listbox_prompt");
|
|
const string_id SID_UNCONSENT_LISTBOX_TITLE = new string_id("base_player","unconsent_listbox_title");
|
|
|
|
const string_id PROSE_GOT_CONSENT = new string_id("base_player","prose_got_consent");
|
|
const string_id PROSE_LOST_CONSENT = new string_id("base_player","prose_lost_consent");
|
|
|
|
const string_id SID_CORPSE_EXPIRED = new string_id("base_player","corpse_expired");
|
|
|
|
const string_id SID_PERM_NO_MOVE = new string_id("error_message","perm_no_move");
|
|
|
|
const string_id SID_CMD_OPEN_FAIL = new string_id("error_message","prose_open_fail");
|
|
|
|
const string_id SID_CMD_NO_EFFECT = new string_id("error_message","cmd_no_effect");
|
|
const string_id SID_CMD_NO_EFFECT_ON_TARGET = new string_id("error_message","cmd_no_effect_on_target");
|
|
|
|
const string_id SID_NO_UNINSURED_INSURABLES = new string_id("error_message","no_uninsured_insurables");
|
|
const string_id SID_BAD_INSURE_REQUEST = new string_id("error_message","bad_insure_request");
|
|
|
|
const string_id SID_INSURE_FAIL = new string_id("error_message","insure_fail");
|
|
const string_id PROSE_INSURE_FAIL = new string_id("error_message","prose_insure_fail");
|
|
|
|
const string_id SID_CLONE_FAIL = new string_id("error_message","clone_fail");
|
|
const string_id SID_CLONE_FAIL_SELECTION = new string_id("base_player", "clone_fail_no_selection");
|
|
|
|
const string_id SID_TARGET_MUST_BE_PLAYER = new string_id("error_message","target_must_be_player");
|
|
|
|
const string_id SID_ERROR_INVITE_RANGE = new string_id("error_message","error_invite_range");
|
|
const string_id PROSE_INVITE_RANGE = new string_id("error_message","prose_invite_range");
|
|
|
|
const string_id SID_INSTANCE_REVIVE = new string_id("base_player", "instance_revive");
|
|
const string_id SID_INSTANCE_REVIVE_TITLE = new string_id("base_player", "instance_revive_title");
|
|
|
|
const string HANDLER_PLAYER_REVIVE = "handlePlayerRevive";
|
|
|
|
const string HANDLER_UNCONSENT_MENU = "handleUnconsentMenu";
|
|
|
|
const string HANDLER_CASH_LOOTED = "handleCashLooted";
|
|
|
|
const string_id PROSE_COIN_LOOT = new string_id("base_player","prose_coin_loot");
|
|
const string_id PROSE_COIN_LOOT_NO_TARGET = new string_id("base_player","prose_coin_loot_no_target");
|
|
const string_id PROSE_COIN_LOOT_FAILED = new string_id("error_message","prose_coin_loot_fail");
|
|
const int LOGOUT_TIME = 30;
|
|
const int LOGOUT_COUNT_INTERVAL = 5;
|
|
|
|
|
|
|
|
// Scent Masking
|
|
const string_id SID_SYS_SCENTMASK_NOSKILL = new string_id("skl_use","sys_scentmask_noskill");
|
|
const string_id SID_SYS_SCENTMASK_START = new string_id("skl_use","sys_scentmask_start");
|
|
const string_id SID_SYS_SCENTMASK_STOP = new string_id("skl_use","sys_scentmask_stop");
|
|
const string_id SID_SYS_SCENTMASK_FAIL = new string_id("skl_use","sys_scentmask_fail");
|
|
const string_id SID_SYS_SCENTMASK_ALREADY = new string_id("skl_use","sys_scentmask_already");
|
|
const string_id SID_SYS_SCENTMASK_DELAY = new string_id("skl_use","sys_scentmask_delay");
|
|
const string_id SID_SYS_SCENTMASK_CONCEALED = new string_id("skl_use","sys_scentmask_concealed");
|
|
|
|
// Conceal
|
|
const string_id SID_SYS_CONCEAL_NOSKILL = new string_id("skl_use","sys_conceal_noskill");
|
|
const string_id SID_SYS_CONCEAL_START = new string_id("skl_use","sys_conceal_start");
|
|
const string_id SID_SYS_CONCEAL_STOP = new string_id("skl_use","sys_conceal_stop");
|
|
const string_id SID_SYS_CONCEAL_FAIL = new string_id("skl_use","sys_conceal_fail");
|
|
const string_id SID_SYS_CONCEAL_CANT = new string_id("skl_use","sys_conceal_cant");
|
|
const string_id SID_SYS_CONCEAL_NOTPLAYER = new string_id("skl_use","sys_conceal_notplayer");
|
|
const string_id SID_SYS_TARGET_CONCEALED = new string_id("skl_use","sys_target_concealed");
|
|
const string_id SID_SYS_CONCEAL_REMOVE = new string_id("skl_use","sys_conceal_remove");
|
|
const string_id SID_SYS_CONCEAL_NOKIT = new string_id("skl_use","sys_conceal_nokit");
|
|
const string_id SID_SYS_CONCEAL_SCENTMASKED = new string_id("skl_use","sys_conceal_scentmasked");
|
|
const string_id SID_SYS_CONCEAL_APPLY = new string_id("skl_use","sys_conceal_apply");
|
|
const string_id SID_SYS_CONCEAL_DELAY = new string_id("skl_use","sys_conceal_delay");
|
|
|
|
// Area Scan
|
|
const string_id SID_SYS_SCAN_NOTHING = new string_id("skl_use","sys_scan_nothing");
|
|
const string_id SID_SYS_SCAN_BEGIN = new string_id("skl_use","sys_scan_begin");
|
|
const string_id SID_SYS_SCAN_ALREADY = new string_id("skl_use","sys_scan_already");
|
|
const string_id SID_SYS_SCAN_INSIDE = new string_id("skl_use","sys_scan_inside");
|
|
const string_id SID_SYS_SCAN_MOVED = new string_id("skl_use","sys_scan_moved");
|
|
const string_id SID_SYS_SCAN_COMBAT = new string_id("skl_use","sys_scan_combat");
|
|
|
|
// Survey
|
|
const string_id SID_SURVEY_WAYPOINT_NAME = new string_id("skl_use", "survey_waypoint_name");
|
|
const string_id SID_SURVEY_WAYPOINT = new string_id("survey", "survey_waypoint");
|
|
const string_id SID_SAMPLE_CANCEL = new string_id("survey", "sample_cancel");
|
|
const string_id SID_SAMPLE_CANCEL_ATTACK = new string_id("survey", "sample_cancel_attack");
|
|
const string_id SID_NODE_WAYPOINT = new string_id("survey", "node_waypoint");
|
|
const string_id SID_GAMBLE_NO_ACTION = new string_id("survey", "gamble_no_action");
|
|
|
|
// Ranger Traps
|
|
const string_id SID_TRAP_CANCEL = new string_id("trap/trap", "sys_traplay_cancel");
|
|
const string_id SID_TRAP_CANCEL_ATTACK = new string_id("trap/trap", "sys_traplay_cancel_attack");
|
|
const string_id SID_TRAP_COUNT = new string_id("trap/trap", "sys_traplay_count");
|
|
|
|
// Eject
|
|
const string_id SID_SYS_EJECT_REQUEST = new string_id("error_message", "sys_eject_request");
|
|
const string_id SID_SYS_EJECT_FAIL_MOVE = new string_id("error_message", "sys_eject_fail_move");
|
|
const string_id SID_SYS_EJECT_FAIL_CONTAINED= new string_id("error_message", "sys_eject_fail_contained");
|
|
const string_id SID_SYS_EJECT_FAIL_PROXIMITY= new string_id("error_message", "sys_eject_fail_proximity");
|
|
const string_id SID_SYS_EJECT_FAIL_GROUND = new string_id("error_message", "sys_eject_fail_ground");
|
|
const string_id SID_SYS_EJECT_SUCCESS = new string_id("error_message", "sys_eject_success");
|
|
const string_id SID_SYS_EJECT_DUNGEON = new string_id("error_messaage", "sys_eject_dungeon_pp");
|
|
|
|
// City Militia
|
|
const string_id SID_NOT_MILITIA = new string_id("city/city", "not_militia");
|
|
const string_id SID_CITY_WARNED = new string_id("city/city", "city_warned");
|
|
const string_id SID_CITY_WARN_DONE = new string_id("city/city", "city_warn_done");
|
|
const string_id SID_ALREADY_WARNED = new string_id("city/city", "already_warned");
|
|
const string_id SID_CITY_BANNED = new string_id("city/city", "city_banned");
|
|
const string_id SID_CITY_BAN_DONE = new string_id("city/city", "city_ban_done");
|
|
const string_id SID_CITY_PARDONED = new string_id("city/city", "city_pardoned");
|
|
const string_id SID_CITY_PARDON_DONE = new string_id("city/city", "city_pardon_done");
|
|
const string_id SID_LEAVE_CITY = new string_id("city/city", "city_leave_city");
|
|
const string_id SID_ENTER_CITY = new string_id("city/city", "city_enter_city");
|
|
const string_id SID_CITY_WARNING = new string_id("city/city", "city_warning");
|
|
const string_id SID_CITY_WARNING_TARGET = new string_id("city/city", "city_warning_target");
|
|
const string_id SID_NOT_CITIZEN_BAN = new string_id("city/city", "not_citizen_ban");
|
|
const string_id SID_NOT_CSR_BAN = new string_id("city/city", "not_csr_ban");
|
|
const string_id SID_CSR_BAN_ATTEMPT_MSG = new string_id("city/city", "csr_ban_attempt_msg");
|
|
|
|
// Other City
|
|
const string_id SID_RIGHTS_GRANTED = new string_id("city/city", "rights_granted");
|
|
const string_id SID_GRANT_RIGHTS_FAIL = new string_id("city/city", "grant_rights_fail");
|
|
const string_id SID_RIGHTS_GRANTED_SELF = new string_id("city/city", "rights_granted_self");
|
|
const string CITY_MISSION_TERMINALS = "datatables/city/mission_terminals.iff";
|
|
const string_id SID_NO_MORE_MT = new string_id("city/city", "no_more_mt");
|
|
const string CITY_SKILL_TRAINERS = "datatables/city/skill_trainers.iff";
|
|
const string_id SID_NO_MORE_TRAINERS = new string_id("city/city", "no_more_trainers");
|
|
const string_id SID_CITY_NO_MONEY = new string_id("city/city", "action_no_money");
|
|
const string_id SID_NO_FACTIONAL = new string_id("city/city", "no_factional");
|
|
const string_id SID_RIGHTS_REVOKED = new string_id("city/city", "rights_revoked");
|
|
const string_id SID_RIGHTS_REVOKED_OTHER = new string_id("city/city", "rights_revoked_other");
|
|
const string_id SID_CIVIC_ONLY = new string_id("city/city", "civic_only");
|
|
|
|
//zoning rights update 8
|
|
const string[] ZONING_RIGHTS_ARRAY = new string[] {"@city/city:full_zoning_rights",
|
|
"@city/city:st_zoning_rights",};
|
|
const string_id SID_ST_RIGHTS_GRANTED = new string_id("city/city", "st_rights_granted");
|
|
const string_id SID_ST_GRANT_RIGHTS_FAIL = new string_id("city/city", "st_grant_rights_fail");
|
|
const string_id SID_ST_RIGHTS_GRANTED_SELF = new string_id("city/city", "st_rights_granted_self");
|
|
const string_id SID_ST_RIGHTS_REVOKED = new string_id("city/city", "st_rights_revoked");
|
|
const string_id SID_ST_RIGHTS_REVOKED_OTHER = new string_id("city/city", "st_rights_revoked_other");
|
|
const string_id SID_NOT_IN_CITY_LIMITS = new string_id("city/city", "not_in_city_limits");
|
|
|
|
// New Player Profession Novice Skills
|
|
const string NOVICE_MARKSMAN = "combat_marksman_novice";
|
|
const string NOVICE_BRAWLER = "combat_brawler_novice";
|
|
const string NOVICE_MEDIC = "science_medic_novice";
|
|
const string NOVICE_ARTISAN = "crafting_artisan_novice";
|
|
const string NOVICE_ENTERTAINER = "social_entertainer_novice";
|
|
const string NOVICE_SCOUT = "outdoors_scout_novice";
|
|
|
|
const string_id SID_INVITE_TO_RIDE = new string_id("base_player", "invite_to_ride");
|
|
const string_id SID_CANNOT_OFFER_RIDE_TO = new string_id("base_player", "cannot_offer_ride_to");
|
|
const string_id SID_OFFER_RIDE_TO = new string_id("base_player", "offer_ride_to");
|
|
const string_id SID_UNABLE_TO_ACCEPT_RIDE = new string_id("base_player", "unable_to_accept_ride");
|
|
const string_id SID_ACCEPTED_RIDE = new string_id("base_player", "accepted_ride");
|
|
const string_id SID_DECLINED_RIDE = new string_id("base_player", "declined_ride");
|
|
const string_id SID_NO_ROOM_FOR_PASSENGER = new string_id("base_player", "no_room_for_passenger");
|
|
|
|
const string_id SID_SPICE_DOWNER_DURATION_REDUCED = new string_id("base_player", "spice_downer_duration_reduced");
|
|
const string_id SID_SPICE_DOWNER_DURATION_NEGATED = new string_id("base_player", "spice_downer_duration_negated");
|
|
const string_id SID_INCAPACITATION_DURATION_REDUCED = new string_id("base_player", "incapacitation_duration_reduced");
|
|
|
|
const string NEW_PLAYER_QUESTS_SCRIPT = "theme_park.new_player.new_player";
|
|
|
|
// Space constants
|
|
//const string SPACE_CERTIFICATION = "cert_space"; // This should have been originally put in with a 'private_' in front, to keep it from appearing in the player's UI
|
|
const string SPACE_CERTIFICATION = "private_cert_space";
|
|
|
|
const string_id SID_CAN_PLACE_ONE_BASE = new string_id("faction_perk", "faction_base_refunded_one");
|
|
const string COUPE_DE_GRACE_TARGET = "coupeDeGraceTarget";
|
|
const string[] ATTRIBUTES =
|
|
{
|
|
"HEALTH",
|
|
"CONSTITUTION",
|
|
"ACTION",
|
|
"STAMINA",
|
|
"MIND",
|
|
"WILLPOWER"
|
|
};
|
|
|
|
const int TRANSFER_SHIPS = 1;
|
|
const int TRANSFER_DROIDS = 1;
|
|
|
|
const string_id SID_CANT_MILK_MOUNTED = new string_id("skl_use","milk_mounted");
|
|
const string_id SID_CANT_MILK = new string_id("skl_use","milk_cant");
|
|
const string_id SID_CANT_MILK_COMBAT = new string_id("skl_use", "milk_combat");
|
|
const string_id SID_NO_MILK = new string_id("skl_use", "milk_none");
|
|
const string_id SID_NO_ALLOW_MILK = new string_id("skl_use", "milk_unmilkeable");
|
|
const string_id MILK_TOO_FAR_START = new string_id("skl_use", "milk_too_far_start");
|
|
const string_id MILK_NO_TARGET = new string_id("skl_use", "milk_no_target");
|
|
|
|
const string CTS_LOT_COUNT = "cts.lotcount";
|
|
|
|
//PvP Rank Skills
|
|
|
|
const string PVP_SKILL_1 = "retaliation_ability";
|
|
const string PVP_SKILL_2 = "adrenaline_ability";
|
|
const string PVP_SKILL_3 = "unstoppable_ability";
|
|
const string PVP_SKILL_4 = "last_man_ability";
|
|
const string PVP_SKILL_5 = "aura_buff_self";
|
|
const string PVP_SKILL_6 = "airstrike_ability";
|
|
|
|
const string_id COVERCHARGE_DANCER_MESSAGE = new string_id("base_player", "covercharge_dancer_message");
|
|
|
|
//lair constants
|
|
const string_id SID_FOUND_NOTHING = new string_id("lair_n", "found_nothing");
|
|
const string_id TOO_FAR_FROM_LAIR = new string_id("lair_n", "too_far_from_lair");
|
|
const string_id LAIR_NOT_TARGETED = new string_id("lair_n", "lair_not_targeted");
|
|
|
|
//Shapechange buff when entering combat
|
|
const string_id SHAPECHANGE = new string_id("spam", "shapechange_combat");
|
|
|
|
//ground planet name that can be specified with /waypoint (to create a waypoint on a different planet
|
|
//than the current planet/zone)
|
|
|
|
// this is the name the player enters with the /waypoint command
|
|
// WAYPOINT_GROUND_PLANETS_EXTERNAL and WAYPOINT_GROUND_PLANETS_INTERNAL
|
|
// and WAYPOINT_GROUND_PLANETS_BUILDOUT_COORDS must be kept in sync
|
|
|
|
// this list ***MUST*** be kept in sync with planetOrZoneNames in ClientCommandQueue.cpp
|
|
const string[] WAYPOINT_GROUND_PLANETS_EXTERNAL =
|
|
{
|
|
"tatooine", // tatooine
|
|
"naboo", // naboo
|
|
"corellia", // corellia
|
|
"rori", // rori
|
|
"talus", // talus
|
|
"yavin4", // yavin4
|
|
"endor", // endor
|
|
"lok", // lok
|
|
"dantooine", // dantooine
|
|
"dathomir", // dathomir
|
|
"kachirho", // kashyyyk_main
|
|
"etyyy", // kashyyyk_hunting
|
|
"khowir", // kashyyyk_dead_forest
|
|
"mustafar", // mustafar
|
|
};
|
|
|
|
// this is the internal scene/planet/zone name that needs to be set for the waypoint
|
|
// WAYPOINT_GROUND_PLANETS_EXTERNAL and WAYPOINT_GROUND_PLANETS_INTERNAL
|
|
// and WAYPOINT_GROUND_PLANETS_BUILDOUT_COORDS must be kept in sync
|
|
const string[] WAYPOINT_GROUND_PLANETS_INTERNAL =
|
|
{
|
|
"tatooine", // tatooine
|
|
"naboo", // naboo
|
|
"corellia", // corellia
|
|
"rori", // rori
|
|
"talus", // talus
|
|
"yavin4", // yavin4
|
|
"endor", // endor
|
|
"lok", // lok
|
|
"dantooine", // dantooine
|
|
"dathomir", // dathomir
|
|
"kashyyyk_main", // kashyyyk_main
|
|
"kashyyyk_hunting", // kashyyyk_hunting
|
|
"kashyyyk_dead_forest", // kashyyyk_dead_forest
|
|
"mustafar", // mustafar
|
|
};
|
|
|
|
// when creating a waypoint on a ground planet other than the current planet/zone,
|
|
// use the following (x,z) coords to get the corresponding buildout area as the
|
|
// buildout area from which to calculate the final waypoint coords, if necessary
|
|
// WAYPOINT_GROUND_PLANETS_EXTERNAL and WAYPOINT_GROUND_PLANETS_INTERNAL
|
|
// and WAYPOINT_GROUND_PLANETS_BUILDOUT_COORDS must be kept in sync
|
|
const vector[] WAYPOINT_GROUND_PLANETS_BUILDOUT_COORDS =
|
|
{
|
|
null, // tatooine
|
|
null, // naboo
|
|
null, // corellia
|
|
null, // rori
|
|
null, // talus
|
|
null, // yavin4
|
|
null, // endor
|
|
null, // lok
|
|
null, // dantooine
|
|
null, // dathomir
|
|
new vector(0.0f, 0.0f, 0.0f), // kashyyyk_main
|
|
new vector(0.0f, 0.0f, 0.0f), // kashyyyk_hunting
|
|
new vector(0.0f, 0.0f, 0.0f), // kashyyyk_dead_forest
|
|
new vector(-2304.0f, 0.0f, 2848.0f), // mustafar
|
|
};
|
|
|
|
//space zone name that can be specified with /waypoint (to create a waypoint on a different zone
|
|
//than the current planet/zone)
|
|
|
|
// this is the name the player enters with the /waypoint command
|
|
// WAYPOINT_SPACE_ZONES_EXTERNAL and WAYPOINT_SPACE_ZONES_INTERNAL
|
|
// must be kept in sync
|
|
|
|
// this list ***MUST*** be kept in sync with planetOrZoneNames in ClientCommandQueue.cpp
|
|
const string[] WAYPOINT_SPACE_ZONES_EXTERNAL =
|
|
{
|
|
"space_tatooine", // space_tatooine
|
|
"space_naboo", // space_naboo
|
|
"space_corellia", // space_corellia
|
|
"space_deep", // space_heavy1
|
|
"space_kessel", // space_light1
|
|
"space_yavin4", // space_yavin4
|
|
"space_endor", // space_endor
|
|
"space_lok", // space_lok
|
|
"space_dantooine", // space_dantooine
|
|
"space_dathomir", // space_dathomir
|
|
"space_kashyyyk", // space_kashyyyk
|
|
"space_nova_orion", // space_nova_orion
|
|
};
|
|
|
|
// this is the internal scene/planet/zone name that needs to be set for the waypoint
|
|
// WAYPOINT_SPACE_ZONES_EXTERNAL and WAYPOINT_SPACE_ZONES_INTERNAL
|
|
// must be kept in sync
|
|
const string[] WAYPOINT_SPACE_ZONES_INTERNAL =
|
|
{
|
|
"space_tatooine", // space_tatooine
|
|
"space_naboo", // space_naboo
|
|
"space_corellia", // space_corellia
|
|
"space_heavy1", // space_heavy1
|
|
"space_light1", // space_light1
|
|
"space_yavin4", // space_yavin4
|
|
"space_endor", // space_endor
|
|
"space_lok", // space_lok
|
|
"space_dantooine", // space_dantooine
|
|
"space_dathomir", // space_dathomir
|
|
"space_kashyyyk", // space_kashyyyk
|
|
"space_nova_orion", // space_nova_orion
|
|
};
|
|
|
|
const boolean LOGGING_ON = true;
|
|
const string LOGNAME = "junk_log";
|
|
|
|
|
|
/***** TRIGGERS ********************************************************/
|
|
// ----OnCustomizeFinished for the Crafted Armor Cutomization Kit: script/item/tool/crafted_armor_customization_kit.script
|
|
trigger OnCustomizeFinished(obj_id object, string params)
|
|
{
|
|
if(utils.hasScriptVar(self, "armor_colorize.tool_oid") || utils.hasScriptVar(self, "structure_colorize.tool_oid"))
|
|
{
|
|
obj_id tool = obj_id.NULL_ID;
|
|
if(utils.hasScriptVar(self, "armor_colorize.tool_oid"))
|
|
{
|
|
tool = utils.getObjIdScriptVar(self, "armor_colorize.tool_oid");
|
|
}
|
|
else if(utils.hasScriptVar(self, "structure_colorize.tool_oid"))
|
|
{
|
|
tool = utils.getObjIdScriptVar(self, "structure_colorize.tool_oid");
|
|
}
|
|
|
|
if(!isValidId(tool) || !exists(tool))
|
|
return SCRIPT_CONTINUE;
|
|
|
|
colorizeObject(self, object, tool, params);
|
|
|
|
}
|
|
if(utils.hasScriptVar(self, vendor_lib.GREETER_PLAYTERCOLOR_SCRVAR))
|
|
vendor_lib.colorizeGreeterFromWidget(self, object, params);
|
|
|
|
|
|
//vet reward script colorize_item section
|
|
if(utils.hasScriptVar(self, "veteranRewardItemColor.color_setting"))
|
|
utils.colorizeItemFromWidget(self, object, params);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//If a player is shapechanged, we remove it when they enter combat.
|
|
trigger OnEnteredCombat()
|
|
{
|
|
int shapechange = buff.getBuffOnTargetFromGroup(self, "shapechange");
|
|
|
|
if(shapechange != 0)
|
|
{
|
|
buff.removeBuff(self, shapechange);
|
|
sendSystemMessage(self, SHAPECHANGE);
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
/***** STANDARD TRIGGERS ********************************************************/
|
|
trigger OnAttach()
|
|
{
|
|
const string[] NEWBIE_PROFICIENCIES = {"knife_stone","knife_survival","lance_staff_wood_s1","axe_heavy","rifle_cdef","pistol_cdef","carbine_cdef"};
|
|
setObjVar(self, pclib.VAR_NEWBIE_DEATH, 1);
|
|
|
|
skill.setPlayerStatsForLevel(self, 1);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnSkillAboutToBeRevoked(string skill)
|
|
{
|
|
|
|
if(toLower(skill).startsWith("pilot"))
|
|
{
|
|
|
|
int godLevel = -1;
|
|
|
|
if(isGod(self))
|
|
godLevel = getGodLevel(self);
|
|
|
|
if(!utils.hasScriptVar(self, "revokePilotSkill") && (godLevel < 50))
|
|
{
|
|
space_skill.retireWarning(self, skill);
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnCombatLevelChanged(int oldCombatLevel, int newCombatLevel)
|
|
{
|
|
if ( newCombatLevel <= 1 || oldCombatLevel >= newCombatLevel )
|
|
return SCRIPT_CONTINUE;//don't do anything for level 1 or when level is decreasing/not really changing
|
|
|
|
if (!utils.hasScriptVar(self, "respec.conceal"))
|
|
{
|
|
skill.doPlayerLeveling(self, oldCombatLevel, newCombatLevel);
|
|
}
|
|
else
|
|
{
|
|
skill.setPlayerStatsForLevel(self, newCombatLevel);
|
|
utils.removeScriptVar(self, "respec.conceal");
|
|
}
|
|
|
|
//lets make sure all 4 trader professions have a base trader skill box we can look for
|
|
if( (utils.isProfession(self, utils.TRADER )) &&(!hasSkill(self, "class_trader")) )
|
|
{
|
|
grantSkill(self, "class_trader");
|
|
}
|
|
|
|
//expertise: if a player levels to or past 10 during a session, assign them the 'expertise' skill
|
|
if ((!hasSkill(self, "expertise"))&&(newCombatLevel == 10))
|
|
expertise.autoAllocateExpertiseByLevel(self, true);
|
|
|
|
// For expertise and The Future!
|
|
recomputeCommandSeries(self);
|
|
|
|
// Spam players with info about their level up stat gains.
|
|
skill.sendlevelUpStatChangeSystemMessages(self, oldCombatLevel, newCombatLevel);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
|
|
/*
|
|
trigger OnExitedCombat()
|
|
{
|
|
|
|
int myPosture = getPosture(self);
|
|
if ( myPosture == POSTURE_UPRIGHT )
|
|
{
|
|
obj_id weapon = getCurrentWeapon( self );
|
|
if (isIdValid(weapon))
|
|
{
|
|
int weaponType = getWeaponType(weapon);
|
|
if ( weaponType == WEAPON_TYPE_PISTOL || weaponType == WEAPON_TYPE_RIFLE || weaponType == WEAPON_TYPE_LIGHT_RIFLE )
|
|
{
|
|
doAnimationAction( self, "reload" );
|
|
playClientEffectObj(self, "clienteffect/weapon_reload.cef", self, null);
|
|
}
|
|
}
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
*/
|
|
|
|
|
|
messageHandler updateGCWStanding()
|
|
{
|
|
int intScore = params.getInt("intScore");
|
|
|
|
gcw.checkAndUpdateGCWStanding(self, intScore);
|
|
return SCRIPT_CONTINUE;
|
|
|
|
|
|
}
|
|
|
|
trigger OnSkillRevoked(string strSkill)
|
|
{
|
|
// 2/2006 mhalash: No more armor hindrance
|
|
// armor.calculateArmorHinderances( self );
|
|
//cleanup assorted spacequest things if the player is surrendering their novice pilot skill:
|
|
if ( strSkill.equals( "pilot_rebel_navy_novice" ) || strSkill.equals( "pilot_imperial_navy_novice" ) || strSkill.equals( "pilot_neutral_novice" ) )
|
|
{
|
|
space_flags.clearSpaceTrack( self );
|
|
space_skill.revokeExperienceForRetire(self, strSkill);
|
|
if ( space_quest.hasQuest( self ) )
|
|
{
|
|
obj_id datapad = utils.getPlayerDatapad( self );
|
|
if ( isIdValid( datapad ) )
|
|
{
|
|
obj_id[] dpobjs = getContents( datapad );
|
|
for ( int i=0; i<dpobjs.length; i++ )
|
|
{
|
|
if ( hasObjVar( dpobjs[i], space_quest.QUEST_TYPE ) )
|
|
space_quest.setQuestAborted( self, dpobjs[i] );
|
|
}
|
|
}
|
|
}
|
|
|
|
//remove some special case "series"flags
|
|
removeObjVar(self, "space_quest.series");
|
|
|
|
//This checks all the space progression objvars and removes all pilot progression objvars but leaves quest content space missions alone
|
|
//get the objvar
|
|
obj_var_list questList = getObjVarList(self, space_quest.QUEST_STATUS);
|
|
LOG("revoke","QUESTLIST: QuestList " +questList);
|
|
if(questList != null)
|
|
|
|
{
|
|
//break it up
|
|
int spaceQuests = questList.getNumItems();
|
|
//LOG("revoke","SPACEQUEST: SpaceQuest " +spaceQuests);
|
|
for (int i = 0; i < spaceQuests; ++i)
|
|
{
|
|
obj_var spaceFields = questList.getObjVar(i);
|
|
string questType = spaceFields.getName();
|
|
|
|
//LOG("revoke","QUESTTYPE: QuestType " + questType);
|
|
obj_var_list typeList = questList.getObjVarList(questType);
|
|
int questCount = typeList.getNumItems();
|
|
|
|
for (int j = 0; j < questCount; j++)
|
|
{
|
|
obj_var quest = typeList.getObjVar(j);
|
|
string questName = quest.getName();
|
|
|
|
//LOG("revoke","QUESTNAME: QuestName " + questName);
|
|
|
|
//construct a string based on /datatables/spacequest key 2 + key 3 + .iff
|
|
//LOG("revoke","DATATABLE STRING: /datatables/spacequest/" + questType + "/" + questName + ".iff" );
|
|
string spaceTable = "/datatables/spacequest/" + questType + "/" + questName + ".iff" ;
|
|
string questSeries = dataTableGetString( spaceTable, 0, "questSeries" );
|
|
if(questSeries == null)
|
|
{
|
|
LOG("revoke_space_quest","QUESTSERIES IS NULL IN DATATABLE: " + spaceTable);
|
|
continue;
|
|
}
|
|
//remove the quest if it has pilot profession
|
|
if(questSeries != "" && questSeries == "pilot_profession")
|
|
{
|
|
space_quest.clearQuestFlags( self, questType, questName );
|
|
//LOG("revoke","QUESTSERIES: Revoked! " +questName);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
// unequip any uncerted weapons and armor - notifies the player of unequip
|
|
utils.unequipAndNotifyUncerted(self);
|
|
if (strSkill.equals("outdoors_ranger_movement_03"))
|
|
{
|
|
if (hasSchematic(self, "object/draft_schematic/scout/item_camokit_kashyyyk.iff"))
|
|
revokeSchematic(self, "object/draft_schematic/scout/item_camokit_kashyyyk.iff");
|
|
}
|
|
|
|
if (strSkill.startsWith("expertise_"))
|
|
{
|
|
expertise.cacheExpertiseProcReacList(self);
|
|
armor.recalculateArmorForPlayer(self);
|
|
obj_id tempWeapon = getObjectInSlot(self, "hold_r");
|
|
|
|
if(isIdValid(tempWeapon))
|
|
{
|
|
weapons.adjustWeaponRangeForExpertise(self, tempWeapon, true);
|
|
}
|
|
|
|
skill.recalcPlayerPools(self, false);
|
|
}
|
|
|
|
trial.bumpSession(self, "displayDefensiveMods");
|
|
messageTo(self, "setDisplayOnlyDefensiveMods", trial.getSessionDict(self, "displayDefensiveMods") , 5, false);
|
|
|
|
// For expertise and The Future!
|
|
recomputeCommandSeries(self);
|
|
|
|
// Update our beast stats if applicable.
|
|
beast_lib.verifyAndUpdateCalledBeastStats(self);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnInitialize()
|
|
{
|
|
//lets make sure all 4 trader professions have a base trader skill box we can look for
|
|
if( (utils.isProfession(self, utils.TRADER )) &&(!hasSkill(self, "class_trader")) )
|
|
{
|
|
grantSkill(self, "class_trader");
|
|
}
|
|
|
|
//expertise auto-allocation check
|
|
if (!hasSkill(self, "expertise"))
|
|
expertise.autoAllocateExpertiseByLevel(self, false);
|
|
// Let the city system update us.
|
|
city.initCitizen( self );
|
|
|
|
respecNewEntertainerSkills(self);
|
|
respecNewCrafterSkills(self);
|
|
|
|
boolean setting = utils.checkConfigFlag("TestCenterPlayer", "ApplyTCMark");
|
|
if ( setting)
|
|
{
|
|
setObjVar(self, "tcTester", 1);
|
|
}
|
|
|
|
if ( getForcePower(self) > 0)
|
|
{
|
|
// make sure our Jedi state has been initialized
|
|
if ( getJediState(self) == JEDI_STATE_NONE )
|
|
{
|
|
setJediState(self, JEDI_STATE_FORCE_SENSITIVE);
|
|
}
|
|
}
|
|
|
|
|
|
// Run Jedi conversion stuff to new system
|
|
if (hasSkill(self, "jedi_padawan_novice"))
|
|
{
|
|
setSkillTemplate(self, "a");
|
|
attachScript(self, "player.player_jedi_conversion");
|
|
}
|
|
|
|
// Set up jedi skills.
|
|
if (!isJedi(self))
|
|
{
|
|
if (hasObjVar(self, "jedi.postponeGrant"))
|
|
{
|
|
if (!jedi.postponeGrantJedi())
|
|
{
|
|
// you get to be a jedi.
|
|
LOG("jedi", "MAKING " + self + " A JEDI FROM ON_INITIALIZE");
|
|
messageTo(self, "makeJedi", null, 0.1f, false);
|
|
}
|
|
}
|
|
else if (hasObjVar(self, "jedi.timeStamp"))
|
|
{
|
|
// you get to be a jedi.
|
|
LOG("jedi", "MAKING " + self + " A JEDI FROM ON_INITIALIZE");
|
|
messageTo(self, "makeJedi", null, 0.1f, false);
|
|
}
|
|
}
|
|
|
|
skill.fixTerrainNegotiationMods(self);
|
|
|
|
// if you have a declared residence or are a mayor, make sure you have politician skill
|
|
if(isIdValid(getHouseId(self)))
|
|
{
|
|
skill.grantAllPoliticianSkills(self);
|
|
}
|
|
else
|
|
{
|
|
int currentCity = getCitizenOfCityId(self);
|
|
obj_id currentCityMayor = cityGetLeader(currentCity);
|
|
if (self == currentCityMayor)
|
|
skill.grantAllPoliticianSkills(self);
|
|
}
|
|
|
|
//make sure they dont have any vehicle buffs on login
|
|
int vehicleBuff = buff.getBuffOnTargetFromGroup(self, "vehicle");
|
|
if(vehicleBuff !=0)
|
|
buff.removeBuff(self, vehicleBuff);
|
|
|
|
|
|
// Remove force Run on Login due to horrid exploits
|
|
if (buff.hasBuff(self, "forceRun"))
|
|
buff.removeBuff(self, "forceRun");
|
|
if (buff.hasBuff(self, "forceRun_1"))
|
|
buff.removeBuff(self, "forceRun_1");
|
|
if (buff.hasBuff(self, "forceRun_2"))
|
|
buff.removeBuff(self, "forceRun_2");
|
|
|
|
jedi.jediSaberPearlRestore(self);
|
|
|
|
if (!hasSkill(self, "social_language_wookiee_comprehend"))
|
|
grantSkill(self, "social_language_wookiee_comprehend");
|
|
|
|
// Cleanup SL group buffs
|
|
if (!group.isGrouped(self))
|
|
{
|
|
int[] buffList = buff.getGroupBuffEffects(self);
|
|
if (buffList != null && buffList.length > 0)
|
|
buff.removeGroupBuffEffect(self, buffList);
|
|
}
|
|
|
|
// Set up space ceritification
|
|
if (features.isSpaceEdition(self))
|
|
{
|
|
grantCommand(self, SPACE_CERTIFICATION);
|
|
}
|
|
else
|
|
{
|
|
revokeCommand(self, SPACE_CERTIFICATION);
|
|
}
|
|
|
|
// Remove safe logout objvar is not already cleaned up.
|
|
removeObjVar( self, pclib.VAR_SAFE_LOGOUT );
|
|
recalculateLevel( self );
|
|
|
|
removeObjVar(self, "clickRespec");
|
|
removeObjVar(self, "npcRespec");
|
|
|
|
// 2/2006 mhalash: No more armor hindrance
|
|
// armor.calculateArmorHinderances(self);
|
|
|
|
// Calculate speed mods for weapon type
|
|
|
|
// Remove group member script if not already cleaned up!
|
|
detachScript( self, group.SCRIPT_GROUP_MEMBER );
|
|
|
|
// Clean up any stray dot states if the player doesn't have the dot script.
|
|
if ( !hasScript(self, dot.SCRIPT_PLAYER_DOT) )
|
|
{
|
|
setState( self, STATE_BLEEDING, false );
|
|
setState( self, STATE_POISONED, false );
|
|
setState( self, STATE_DISEASED, false );
|
|
setState( self, STATE_ON_FIRE, false );
|
|
}
|
|
|
|
if(buff.hasBuff(self, "healOverTime"))
|
|
buff.removeBuff(self, "healOverTime");
|
|
|
|
chat.resetTempAnimationMood( self );
|
|
|
|
// Update bind location data to new cloning system
|
|
if (hasObjVar(self, cloninglib.VAR_BIND_FACILITY_TEMPLATE))
|
|
{
|
|
obj_id facilityId = getObjIdObjVar(self, cloninglib.VAR_BIND_FACILITY);
|
|
dictionary data = new dictionary();
|
|
data.put("requester", self);
|
|
messageTo(facilityId, "requestCloningData", data, 0, false);
|
|
}
|
|
|
|
// Clean up coa objvars
|
|
if (hasObjVar(self, "coa3"))
|
|
{
|
|
removeObjVar(self, "coa3");
|
|
}
|
|
|
|
// Check for valid hairstyles
|
|
utils.validatePlayerHairStyle(self);
|
|
|
|
// Checks to see if players have completed Imperial, Rebel, or Jabba Theme Parks but have not received badges
|
|
// If not, the appropriate badges are granted
|
|
badge.grantThemeParkBadges(self);
|
|
|
|
// Razor knuckler fix. Remove this when the correct Razor knucklers have been added to the game
|
|
if (hasSchematic(self, getObjectTemplateCrc("object/draft_schematic/weapon/razor_knuckler.iff")))
|
|
{
|
|
temp_schematic.revoke(self, "object/draft_schematic/weapon/razor_knuckler.iff");
|
|
}
|
|
|
|
if(bounty_hunter.hasMaxBountyMissionsOnTarget(self))
|
|
messageTo(self, "handleBountyMissionTimeout", null, 30.0f, true);
|
|
|
|
// Customer service logging for extraordinary wealth and profit
|
|
int totalMoney = getTotalMoney(self);
|
|
utils.setScriptVar(self, "profit", totalMoney);
|
|
|
|
string balanceThreshold = getConfigSetting("GameServer", "wealthLoggingThreshold");
|
|
if(balanceThreshold == null || balanceThreshold == "") {
|
|
|
|
balanceThreshold = "10000000";
|
|
}
|
|
if(utils.stringToInt(balanceThreshold) > -1) {
|
|
|
|
if(totalMoney > utils.stringToInt(balanceThreshold)) {
|
|
|
|
CustomerServiceLog("Wealth", "Extraordinary Wealth: " + getName(self) + " (" + self + ") logged in with " + totalMoney + " credits");
|
|
}
|
|
}
|
|
|
|
// unequip any uncerted weapons and armor - notifies the player of unequip
|
|
utils.unequipAndNotifyUncerted(self);
|
|
utils.checkInventoryForSnowflakeItemSwaps(self);
|
|
if(hasObjVar(self, "item_reimbursement_list"))
|
|
{
|
|
string[] strReimbursementList = getStringArrayObjVar(self, "item_reimbursement_list");
|
|
removeObjVar(self,"item_reimbursement_list");
|
|
for(int intI = 0; intI < strReimbursementList.length; intI++)
|
|
{
|
|
obj_id objTest = createObjectInInventoryAllowOverload(strReimbursementList[intI], self);
|
|
if(isIdValid(objTest))
|
|
{
|
|
// Apparently we can never escape special case code...
|
|
if (armor.isArmorComponent(objTest))
|
|
{
|
|
if (!isGameObjectTypeOf(objTest, GOT_armor_foot) && !isGameObjectTypeOf(objTest, GOT_armor_hand))
|
|
{
|
|
// The armor pieces need to have properties set on them
|
|
const string[] ARMOR_SET = {
|
|
// ARMOR_SET_IMPERIAL
|
|
"object/tangible/wearables/armor/clone_trooper/armor_clone_trooper_imperial_s01_leggings.iff",
|
|
"object/tangible/wearables/armor/clone_trooper/armor_clone_trooper_imperial_s01_helmet.iff",
|
|
"object/tangible/wearables/armor/clone_trooper/armor_clone_trooper_imperial_s01_gloves.iff",
|
|
"object/tangible/wearables/armor/clone_trooper/armor_clone_trooper_imperial_s01_chest_plate.iff",
|
|
"object/tangible/wearables/armor/clone_trooper/armor_clone_trooper_imperial_s01_bracer_r.iff",
|
|
"object/tangible/wearables/armor/clone_trooper/armor_clone_trooper_imperial_s01_bracer_l.iff",
|
|
"object/tangible/wearables/armor/clone_trooper/armor_clone_trooper_imperial_s01_boots.iff",
|
|
"object/tangible/wearables/armor/clone_trooper/armor_clone_trooper_imperial_s01_bicep_r.iff",
|
|
"object/tangible/wearables/armor/clone_trooper/armor_clone_trooper_imperial_s01_bicep_l.iff",
|
|
"object/tangible/wearables/armor/clone_trooper/armor_clone_trooper_imperial_s01_belt.iff",
|
|
|
|
// ARMOR_SET_REBEL
|
|
"object/tangible/wearables/armor/clone_trooper/armor_clone_trooper_rebel_s01_leggings.iff",
|
|
"object/tangible/wearables/armor/clone_trooper/armor_clone_trooper_rebel_s01_helmet.iff",
|
|
"object/tangible/wearables/armor/clone_trooper/armor_clone_trooper_rebel_s01_gloves.iff",
|
|
"object/tangible/wearables/armor/clone_trooper/armor_clone_trooper_rebel_s01_chest_plate.iff",
|
|
"object/tangible/wearables/armor/clone_trooper/armor_clone_trooper_rebel_s01_bracer_r.iff",
|
|
"object/tangible/wearables/armor/clone_trooper/armor_clone_trooper_rebel_s01_bracer_l.iff",
|
|
"object/tangible/wearables/armor/clone_trooper/armor_clone_trooper_rebel_s01_boots.iff",
|
|
"object/tangible/wearables/armor/clone_trooper/armor_clone_trooper_rebel_s01_bicep_r.iff",
|
|
"object/tangible/wearables/armor/clone_trooper/armor_clone_trooper_rebel_s01_bicep_l.iff",
|
|
"object/tangible/wearables/armor/clone_trooper/armor_clone_trooper_rebel_s01_belt.iff",
|
|
|
|
// ARMOR_SET_NEUTRAL
|
|
"object/tangible/wearables/armor/clone_trooper/armor_clone_trooper_neutral_s01_leggings.iff",
|
|
"object/tangible/wearables/armor/clone_trooper/armor_clone_trooper_neutral_s01_helmet.iff",
|
|
"object/tangible/wearables/armor/clone_trooper/armor_clone_trooper_neutral_s01_gloves.iff",
|
|
"object/tangible/wearables/armor/clone_trooper/armor_clone_trooper_neutral_s01_chest_plate.iff",
|
|
"object/tangible/wearables/armor/clone_trooper/armor_clone_trooper_neutral_s01_bracer_r.iff",
|
|
"object/tangible/wearables/armor/clone_trooper/armor_clone_trooper_neutral_s01_bracer_l.iff",
|
|
"object/tangible/wearables/armor/clone_trooper/armor_clone_trooper_neutral_s01_boots.iff",
|
|
"object/tangible/wearables/armor/clone_trooper/armor_clone_trooper_neutral_s01_bicep_r.iff",
|
|
"object/tangible/wearables/armor/clone_trooper/armor_clone_trooper_neutral_s01_bicep_l.iff",
|
|
"object/tangible/wearables/armor/clone_trooper/armor_clone_trooper_neutral_s01_belt.iff"
|
|
};
|
|
|
|
for (int intJ = 0; intJ < ARMOR_SET.length; intJ++)
|
|
{
|
|
if (strReimbursementList[intI] == ARMOR_SET[intJ])
|
|
{
|
|
armor.setArmorDataPercent(objTest, 2, 1, 0.94f, 0.95f);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
CustomerServiceLog("item_reimbursement", "Created item of type "+strReimbursementList[intI]+" and Id of "+objTest+ " in the inventory of %TU", self);
|
|
}
|
|
else
|
|
{
|
|
CustomerServiceLog("item_reimbursement", "Failed to reimburse item of type "+strReimbursementList[intI]+" in the inventory of %TU", self);
|
|
}
|
|
}
|
|
}
|
|
|
|
// GET RID OF ANY LINGERING BATTLE FATIGUE
|
|
int fatigue = getShockWound(self);
|
|
if(fatigue > 0)
|
|
setShockWound(self, 0);
|
|
|
|
//This function cleans off objvars from the clickitem system
|
|
obj_var_list buffList = getObjVarList(self, "clickItem");
|
|
if ( buffList != null )
|
|
{
|
|
int count = buffList.getNumItems();
|
|
int curTime = getGameTime();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
obj_var item = buffList.getObjVar(i);
|
|
int reuseTime = item.getIntData();
|
|
|
|
if (reuseTime < curTime)
|
|
{
|
|
string cooldownGroup = item.getName();
|
|
removeObjVar(self, "clickItem."+cooldownGroup);
|
|
}
|
|
}
|
|
}
|
|
|
|
//this is where to put on-the-fly live conversion type issues:
|
|
if ( !hasScript( self, "player.live_conversions" ) )
|
|
attachScript( self, "player.live_conversions" );
|
|
|
|
if(!hasScript(self, "systems.skills.stealth.player_stealth"))
|
|
{
|
|
attachScript( self, "systems.skills.stealth.player_stealth" );
|
|
}
|
|
|
|
skill_template.validateWorkingSkill(self);
|
|
skill.setPlayerStatsForLevel(self, getLevel(self));
|
|
|
|
LOG("base_player - OnInitialize", "calling armor.recalculateArmorForPlayer(self); with a 'self' of: "+self);
|
|
armor.recalculateArmorForPlayer(self);
|
|
|
|
// check their unarmed WEapon
|
|
|
|
obj_id objWeapon = getDefaultWeapon(self);
|
|
string strTemplate = getTemplateName(objWeapon);
|
|
if(isIdValid(objWeapon) && strTemplate.equals("object/weapon/melee/unarmed/unarmed_default_player.iff"))
|
|
{
|
|
if (!hasScript(objWeapon, "systems.combat.combat_weapon"))
|
|
{
|
|
attachScript(objWeapon, "systems.combat.combat_weapon");
|
|
messageTo(objWeapon, "weaponConversion", null, 2, false);
|
|
}
|
|
|
|
float fltWeaponSpeed = getWeaponAttackSpeed(objWeapon);
|
|
if(fltWeaponSpeed != .50f)
|
|
{
|
|
setWeaponAttackSpeed(objWeapon, .50f);
|
|
}
|
|
}
|
|
|
|
expertise.cacheExpertiseProcReacList(self);
|
|
proc.buildCurrentProcList(self);
|
|
proc.buildCurrentReacList(self);
|
|
|
|
givePublishGift(self);
|
|
|
|
sendSmugglerSystemBootstrap(self);
|
|
|
|
// For expertise and The Future!
|
|
recomputeCommandSeries(self);
|
|
|
|
// Display only skill mods for new combat defenses.
|
|
trial.bumpSession(self, "displayDefensiveMods");
|
|
messageTo(self, "setDisplayOnlyDefensiveMods", trial.getSessionDict(self, "displayDefensiveMods") , 5, false);
|
|
|
|
missions.initializeDailyOnLogin(self);
|
|
|
|
// Bounty Decay
|
|
|
|
// A weekly decay based on a login time.
|
|
// Bounty threshhold is 10000 credits.
|
|
// Bounty Decay is for players that rarely PvP, so they do not get ganked by bounty hunters due to the auto-bounty system.
|
|
|
|
int lastDecayTime = getIntObjVar(self, "bounty.decayTime");
|
|
int currentTime = getCalendarTime();
|
|
|
|
if(lastDecayTime == 0) // First time to decay? Go ahead and set the time.
|
|
{
|
|
setObjVar(self, "bounty.decayTime", currentTime);
|
|
}
|
|
else
|
|
{
|
|
int bounty = getIntObjVar(self, "bounty.amount");
|
|
|
|
if(currentTime - lastDecayTime > 604800) // 1 Week or more
|
|
{
|
|
setObjVar(self, "bounty.decayTime", currentTime);
|
|
|
|
// Bounty threshhold is 10000 credits.
|
|
// This is for players that rarely PvP, so they do not get ganked by bounty hunters due to the auto-bounty system.
|
|
if(bounty < 10000)
|
|
{
|
|
removeObjVar(self, "bounty.amount"); // Clear the bounty amount for the week.
|
|
}
|
|
}
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleRetireWarning() {
|
|
|
|
int btn = sui.getIntButtonPressed(params);
|
|
|
|
if(btn == sui.BP_CANCEL) {
|
|
|
|
location loc = utils.getLocationScriptVar(self, "revokePilotSkillWarningLoc");
|
|
string wp_name = utils.getStringScriptVar(self, "revokePilotSkillWarningWpName");
|
|
|
|
if(loc == null)
|
|
return SCRIPT_CONTINUE;
|
|
|
|
obj_id wp = createWaypointInDatapad(self, loc);
|
|
setWaypointName(wp, wp_name);
|
|
setWaypointColor(wp, "blue");
|
|
setWaypointActive(wp, true);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Grant badges and new abilities as players gain PvP ranks
|
|
|
|
trigger OnPvpRankingChanged(int oldRank, int newRank)
|
|
{
|
|
string faction = "";
|
|
boolean isImperial = false;
|
|
|
|
if(factions.isImperial(self))
|
|
{
|
|
faction = "pvp_imperial_";
|
|
isImperial = true;
|
|
}
|
|
|
|
if(factions.isRebel(self))
|
|
{
|
|
faction = "pvp_rebel_";
|
|
}
|
|
|
|
if(faction == "")
|
|
{
|
|
factions.removeAllPvpSkills (self);
|
|
CustomerServiceLog("pvp_rank_error", "Player %TU somehow changed PvP rank without being Rebel or Imperial, removing all PvP skills.", self);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
if(oldRank <= 6 && newRank > 6)
|
|
{
|
|
skill.grantSkill(self, faction + PVP_SKILL_1);
|
|
|
|
if(isImperial)
|
|
{
|
|
badge.grantBadge(self, "pvp_imperial_lieutenant");
|
|
}
|
|
else
|
|
{
|
|
badge.grantBadge(self, "pvp_rebel_lieutenant");
|
|
}
|
|
}
|
|
|
|
if(oldRank <= 7 && newRank > 7)
|
|
{
|
|
skill.grantSkill(self, faction + PVP_SKILL_2);
|
|
|
|
if(isImperial)
|
|
{
|
|
badge.grantBadge(self, "pvp_imperial_captain");
|
|
}
|
|
else
|
|
{
|
|
badge.grantBadge(self, "pvp_rebel_captain");
|
|
}
|
|
}
|
|
|
|
if(oldRank <= 8 && newRank > 8)
|
|
{
|
|
skill.grantSkill(self, faction + PVP_SKILL_3);
|
|
|
|
if(isImperial)
|
|
{
|
|
badge.grantBadge(self, "pvp_imperial_major");
|
|
}
|
|
else
|
|
{
|
|
badge.grantBadge(self, "pvp_rebel_major");
|
|
}
|
|
}
|
|
|
|
if(oldRank <= 9 && newRank > 9)
|
|
{
|
|
skill.grantSkill(self, faction + PVP_SKILL_4);
|
|
|
|
if(isImperial)
|
|
{
|
|
badge.grantBadge(self, "pvp_imperial_lt_colonel");
|
|
}
|
|
else
|
|
{
|
|
badge.grantBadge(self, "pvp_rebel_commander");
|
|
}
|
|
}
|
|
|
|
if(oldRank <= 10 && newRank > 10)
|
|
{
|
|
skill.grantSkill(self, faction + PVP_SKILL_5);
|
|
|
|
if(isImperial)
|
|
{
|
|
badge.grantBadge(self, "pvp_imperial_colonel");
|
|
}
|
|
else
|
|
{
|
|
badge.grantBadge(self, "pvp_rebel_colonel");
|
|
}
|
|
}
|
|
|
|
if(oldRank <= 11 && newRank > 11)
|
|
{
|
|
skill.grantSkill(self, faction + PVP_SKILL_6);
|
|
|
|
if(isImperial)
|
|
{
|
|
badge.grantBadge(self, "pvp_imperial_general");
|
|
}
|
|
else
|
|
{
|
|
badge.grantBadge(self, "pvp_rebel_general");
|
|
}
|
|
}
|
|
|
|
if(oldRank == 12 && newRank <= 11)
|
|
{
|
|
skill.revokeSkill(self, faction + PVP_SKILL_6);
|
|
|
|
if (newRank == 10)
|
|
{
|
|
skill.revokeSkill(self, faction + PVP_SKILL_5);
|
|
}
|
|
if (newRank == 9)
|
|
{
|
|
skill.revokeSkill(self, faction + PVP_SKILL_4);
|
|
skill.revokeSkill(self, faction + PVP_SKILL_5);
|
|
}
|
|
if (newRank == 8)
|
|
{
|
|
skill.revokeSkill(self, faction + PVP_SKILL_3);
|
|
skill.revokeSkill(self, faction + PVP_SKILL_4);
|
|
skill.revokeSkill(self, faction + PVP_SKILL_5);
|
|
}
|
|
if (newRank == 7)
|
|
{
|
|
skill.revokeSkill(self, faction + PVP_SKILL_2);
|
|
skill.revokeSkill(self, faction + PVP_SKILL_3);
|
|
skill.revokeSkill(self, faction + PVP_SKILL_4);
|
|
skill.revokeSkill(self, faction + PVP_SKILL_5);
|
|
}
|
|
if (newRank < 7)
|
|
{
|
|
skill.revokeSkill(self, faction + PVP_SKILL_1);
|
|
skill.revokeSkill(self, faction + PVP_SKILL_2);
|
|
skill.revokeSkill(self, faction + PVP_SKILL_3);
|
|
skill.revokeSkill(self, faction + PVP_SKILL_4);
|
|
skill.revokeSkill(self, faction + PVP_SKILL_5);
|
|
}
|
|
}
|
|
|
|
if(oldRank == 11 && newRank <= 10)
|
|
{
|
|
skill.revokeSkill(self, faction + PVP_SKILL_5);
|
|
|
|
if (newRank == 9)
|
|
{
|
|
skill.revokeSkill(self, faction + PVP_SKILL_4);
|
|
}
|
|
if (newRank == 8)
|
|
{
|
|
skill.revokeSkill(self, faction + PVP_SKILL_3);
|
|
skill.revokeSkill(self, faction + PVP_SKILL_4);
|
|
}
|
|
if (newRank == 7)
|
|
{
|
|
skill.revokeSkill(self, faction + PVP_SKILL_2);
|
|
skill.revokeSkill(self, faction + PVP_SKILL_3);
|
|
skill.revokeSkill(self, faction + PVP_SKILL_4);
|
|
}
|
|
if (newRank < 7)
|
|
{
|
|
skill.revokeSkill(self, faction + PVP_SKILL_1);
|
|
skill.revokeSkill(self, faction + PVP_SKILL_2);
|
|
skill.revokeSkill(self, faction + PVP_SKILL_3);
|
|
skill.revokeSkill(self, faction + PVP_SKILL_4);
|
|
}
|
|
}
|
|
|
|
if(oldRank == 10 && newRank <= 9)
|
|
{
|
|
skill.revokeSkill(self, faction + PVP_SKILL_4);
|
|
|
|
if (newRank == 8)
|
|
{
|
|
skill.revokeSkill(self, faction + PVP_SKILL_3);
|
|
}
|
|
if (newRank == 7)
|
|
{
|
|
skill.revokeSkill(self, faction + PVP_SKILL_2);
|
|
skill.revokeSkill(self, faction + PVP_SKILL_3);
|
|
}
|
|
if (newRank < 7)
|
|
{
|
|
skill.revokeSkill(self, faction + PVP_SKILL_1);
|
|
skill.revokeSkill(self, faction + PVP_SKILL_2);
|
|
skill.revokeSkill(self, faction + PVP_SKILL_3);
|
|
}
|
|
}
|
|
|
|
if(oldRank == 9 && newRank <= 8)
|
|
{
|
|
skill.revokeSkill(self, faction + PVP_SKILL_3);
|
|
|
|
if (newRank == 7)
|
|
{
|
|
skill.revokeSkill(self, faction + PVP_SKILL_2);
|
|
}
|
|
if (newRank < 7)
|
|
{
|
|
skill.revokeSkill(self, faction + PVP_SKILL_1);
|
|
skill.revokeSkill(self, faction + PVP_SKILL_2);
|
|
}
|
|
}
|
|
|
|
if(oldRank == 8 && newRank <= 7)
|
|
{
|
|
skill.revokeSkill(self, faction + PVP_SKILL_2);
|
|
|
|
if (newRank < 7)
|
|
{
|
|
skill.revokeSkill(self, faction + PVP_SKILL_1);
|
|
}
|
|
}
|
|
|
|
if(oldRank == 7 && newRank < 7)
|
|
{
|
|
skill.revokeSkill(self, faction + PVP_SKILL_1);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
//**************** DEATH TRIGGERS ******************************
|
|
|
|
trigger OnEnvironmentalDeath()
|
|
{
|
|
// setup player so he falls though handleplayerdeath OK
|
|
if ( !hasObjVar(self, pclib.VAR_BEEN_COUPDEGRACED) )
|
|
{
|
|
setObjVar(self, pclib.VAR_DEATHBLOW_KILLER, self);
|
|
setObjVar(self, pclib.VAR_DEATHBLOW_STAMP, getGameTime());
|
|
}
|
|
|
|
messageTo(self, pclib.HANDLER_PLAYER_DEATH, null, 0, false);
|
|
//utils.setScriptVar(self, "waitingOnCloneRespawn", 1);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnAboutToBeIncapacitated(obj_id killer)
|
|
{
|
|
if (performCriticalHeal(self))
|
|
return SCRIPT_OVERRIDE;
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnIncapacitated(obj_id killer)
|
|
{
|
|
|
|
utils.setScriptVar(self, "lastKiller", killer);
|
|
|
|
if (hasScript(killer, "ai.smuggler_spawn_enemy"))
|
|
{
|
|
int exceptionSmuggler = 0;
|
|
if (hasObjVar(self, "quest.owner"))
|
|
{
|
|
obj_id smuggler = (getObjIdObjVar(self, "quest.owner"));
|
|
if (self != smuggler)
|
|
{
|
|
exceptionSmuggler = 1;
|
|
}
|
|
}
|
|
|
|
if (exceptionSmuggler == 0)
|
|
{
|
|
|
|
groundquests.sendSignal(self, "smugglerEnemyIncap");
|
|
messageTo(killer, "smugglerKilled", null, 1f, false);
|
|
}
|
|
}
|
|
|
|
if(callable.hasAnyCallable(self))
|
|
{
|
|
obj_id objCallable = callable.getCallable(self, callable.CALLABLE_TYPE_RIDEABLE);
|
|
if(exists(objCallable) && isIdValid(objCallable))
|
|
{
|
|
callable.storeCallable(self, objCallable);
|
|
}
|
|
}
|
|
|
|
//make sure they dont have any vehicle buffs after incap
|
|
int vehicleBuff = buff.getBuffOnTargetFromGroup(self, "vehicle");
|
|
if(vehicleBuff !=0)
|
|
buff.removeBuff(self, vehicleBuff);
|
|
|
|
if (buff.hasBuff(self, "incapWeaken"))
|
|
{
|
|
pclib.killPlayer(self, killer, true);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
else
|
|
{
|
|
buff.applyBuff(self, "incapWeaken");
|
|
}
|
|
|
|
int recapacitateTimer = 10;
|
|
|
|
float recapacitateModified = ((float)getEnhancedSkillStatisticModifierUncapped(self, "resistance_incapacitation"));
|
|
if(recapacitateModified > 0)
|
|
{
|
|
recapacitateTimer -= recapacitateModified;
|
|
if(recapacitateTimer <= 2)
|
|
{
|
|
recapacitateTimer = 2;
|
|
}
|
|
sendSystemMessage(self, SID_INCAPACITATION_DURATION_REDUCED);
|
|
}
|
|
|
|
CustomerServiceLog("player_death", "Player %TU is incapacitated by %TT", self, killer);
|
|
|
|
if ( !isIdValid(killer) )
|
|
killer = self;
|
|
|
|
if ( killer == self )
|
|
{
|
|
sendSystemMessage(self, SID_VICTIM_INCAPACITATED);
|
|
}
|
|
else
|
|
{
|
|
prose_package ppToVictim = prose.getPackage(PROSE_VICTIM_INCAP, killer);
|
|
sendSystemMessageProse(self, ppToVictim);
|
|
}
|
|
|
|
if ( killer != self )
|
|
{
|
|
prose_package ppToKiller = prose.getPackage(PROSE_TARGET_INCAP, self);
|
|
sendSystemMessageProse(killer, ppToKiller);
|
|
}
|
|
|
|
// prevent me from doing a death blow
|
|
utils.removeScriptVar(self, COUPE_DE_GRACE_TARGET);
|
|
|
|
// Set regen to 0 and send a message at the fixed recap timer
|
|
utils.setScriptVar(self, "incap.timeStamp", (getGameTime() + recapacitateTimer));
|
|
setCount(self, recapacitateTimer);
|
|
|
|
//incap you
|
|
setHealth( self, 0);
|
|
combat.doCombatDebuffs(self);
|
|
messageTo(self, "recapacitationDelay", null, recapacitateTimer, false);
|
|
|
|
//clear TEF's from AI toward this player and vice versa:
|
|
clearAllAiEnemyFlags( self );
|
|
dot.removeAllDots(self);
|
|
|
|
if (stealth.hasInvisibleBuff(self))
|
|
{
|
|
stealth.checkForAndMakeVisible(self);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
void clearAllAiEnemyFlags( obj_id self )
|
|
{
|
|
obj_id allEnemies[] = pvpGetPersonalEnemyIds(self);
|
|
if ( allEnemies == null )
|
|
return;
|
|
|
|
for ( int i = 0; i < allEnemies.length; ++i )
|
|
{
|
|
if ( isIdValid(allEnemies[i]) && allEnemies[i].isLoaded() && (!isPlayer(allEnemies[i])) )
|
|
{
|
|
pvpRemoveTempEnemyFlags(self, allEnemies[i]);
|
|
pvpRemoveTempEnemyFlags(allEnemies[i], self);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
messageHandler recapacitationDelay()
|
|
{
|
|
if(getPosture(self) != POSTURE_INCAPACITATED)
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
if(!combat.clearCombatDebuffs(self))
|
|
{
|
|
//we need to check again, so we dont get perma incapped
|
|
messageTo(self, "recapacitationDelay", null, 1, false);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
setHealth( self, 1);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler requestMissionLocations()
|
|
{
|
|
// group_object sent a requestMissionLocations
|
|
// message.
|
|
obj_id groupObject = getGroupObject(self);
|
|
if((isIdValid(groupObject)) && (params != null) && (params.containsKey("requestMissionLocationsNumber")))
|
|
{
|
|
// get a list of all of the missions currently
|
|
// held by the group member
|
|
obj_id[] missions = getMissionObjects(self);
|
|
resizeable location[] missionLocation = new location[0];
|
|
|
|
if((missions != null) && (missions.length > 0))
|
|
{
|
|
// iterate through each mission, extracting its
|
|
// location and sending it to the group object
|
|
int missionIndex = 0;
|
|
|
|
for(missionIndex = 0; missionIndex < missions.length; ++missionIndex)
|
|
{
|
|
if(isIdValid(missions[missionIndex]))
|
|
{
|
|
// verify the mission is active and available
|
|
if(getMissionStatus(missions[missionIndex]) > 0)
|
|
{
|
|
// retrieve the start location
|
|
utils.addElement(missionLocation, getMissionStartLocation(missions[missionIndex]));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// setup the messageTo parameters dictionary
|
|
dictionary response = new dictionary();
|
|
response.put("requestMissionLocationsNumber", params.getInt("requestMissionLocationsNumber"));
|
|
response.put("sender", self);
|
|
response.put("senderLocation", getLocation(self));
|
|
|
|
// even if this group member doesn't have any missions to send;
|
|
// it still needs to reply with the group member's current
|
|
// location because that gets used in calculating the nearest
|
|
// group mission waypoint
|
|
if(missionLocation.length > 0)
|
|
response.put("missionLocation", missionLocation);
|
|
|
|
// tell the group object about the missions and the
|
|
// group member's location
|
|
messageTo(groupObject, "missionLocationResponse", response, 0, false);
|
|
}
|
|
|
|
// this message is received in response to the group object
|
|
// attempting to calculate the nearest group mission waypoint.
|
|
// The waypoint will be set once the group object has finished
|
|
// making it's calculations.
|
|
group.destroyGroupWaypoint(self);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//************** GROUPING TRIGGERS ******************************
|
|
trigger OnAddedToGroup(obj_id groupId)
|
|
{
|
|
if ( !hasScript(self, group.SCRIPT_GROUP_MEMBER) )
|
|
attachScript(self, group.SCRIPT_GROUP_MEMBER);
|
|
|
|
if (beast_lib.getBeastOnPlayer(self) != null)
|
|
{
|
|
obj_id beast = beast_lib.getBeastOnPlayer(self);
|
|
obj_id beastBCD = beast_lib.getBeastBCD(beast);
|
|
messageTo (beastBCD, "ownerGrouped", null, 1, false);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnRemovedFromGroup(obj_id groupId)
|
|
{
|
|
if (utils.hasScriptVar(self, "currentHolo"))
|
|
{
|
|
performance.holographicCleanup(self);
|
|
}
|
|
|
|
squad_leader.clearRallyPoint(self);
|
|
|
|
detachScript(self, group.SCRIPT_GROUP_MEMBER);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnGroupLeaderChanged(obj_id groupId, obj_id newLeader, obj_id oldLeader)
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnGroupDisbanded(obj_id group)
|
|
{
|
|
squad_leader.clearRallyPoint(self);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
/*
|
|
trigger OnGroupFormed(obj_id group)
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
*/
|
|
|
|
//************** MENUING TRIGGERS ******************************
|
|
trigger OnObjectMenuRequest(obj_id player, menu_info mi)
|
|
{
|
|
removeObjVar( self, "noTrade" );
|
|
|
|
menu_info_data mid = mi.getMenuItemByType(menu_info_types.COMBAT_DEATH_BLOW);
|
|
if ( mid == null )
|
|
{
|
|
int myPosture = getPosture(self);
|
|
if ( myPosture == POSTURE_INCAPACITATED )
|
|
{
|
|
if ( pvpCanAttack(player, self) )
|
|
{
|
|
mi.addRootMenu (menu_info_types.COMBAT_DEATH_BLOW, new string_id("",""));
|
|
}
|
|
}
|
|
else if ( myPosture == POSTURE_DEAD )
|
|
{
|
|
if((group.inSameGroup(self, player) || pclib.hasConsent(player, self)))
|
|
{
|
|
if(hasCommand(player, "revivePlayer"))
|
|
{
|
|
int reviveRoot = mi.addRootMenu(menu_info_types.SERVER_MENU1, SID_REVIVE);
|
|
|
|
if(hasCommand(player, "resuscitatePlayer"))
|
|
{
|
|
mi.addSubMenu(reviveRoot, menu_info_types.SERVER_MENU9, SID_RESUSCITATE);
|
|
}
|
|
}
|
|
else if(hasCommand(player, "resuscitatePlayer"))
|
|
{
|
|
mi.addRootMenu(menu_info_types.SERVER_MENU9, SID_RESUSCITATE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
mid.setServerNotify(true);
|
|
}
|
|
|
|
// performance observation commands
|
|
{
|
|
// stop listening command if we have a listen target that is in the same group with the menu target
|
|
obj_id listenTarget = getPerformanceListenTarget(player);
|
|
if (isIdValid(listenTarget) && group.inSameGroup(listenTarget, self))
|
|
mi.addRootMenu(menu_info_types.SERVER_PERFORMANCE_LISTEN_STOP, performance.SID_RADIAL_PERFORMANCE_LISTEN_STOP);
|
|
// listen command if the menu target is a performing musician, and the menu target is not in the same group
|
|
// as our current listen target
|
|
if (hasScript(self, performance.MUSIC_HEARTBEAT_SCRIPT) && (!isIdValid(listenTarget) || !group.inSameGroup(self, listenTarget)))
|
|
mi.addRootMenu(menu_info_types.SERVER_PERFORMANCE_LISTEN, performance.SID_RADIAL_PERFORMANCE_LISTEN);
|
|
|
|
obj_id watchTarget = getPerformanceWatchTarget(player);
|
|
// stop watching command if we are watching the menu target
|
|
if (watchTarget == self)
|
|
mi.addRootMenu(menu_info_types.SERVER_PERFORMANCE_WATCH_STOP, performance.SID_RADIAL_PERFORMANCE_WATCH_STOP);
|
|
else
|
|
{
|
|
// watch command if we are not dancing, not already watching the menu target, and the menu target is a performing dancer
|
|
if (hasScript(self, performance.DANCE_HEARTBEAT_SCRIPT))
|
|
mi.addRootMenu(menu_info_types.SERVER_PERFORMANCE_WATCH, performance.SID_RADIAL_PERFORMANCE_WATCH);
|
|
}
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnObjectMenuSelect(obj_id player, int item)
|
|
{
|
|
if ( item == menu_info_types.COMBAT_DEATH_BLOW)
|
|
{
|
|
//client queues command
|
|
}
|
|
else if ( item == menu_info_types.SERVER_MENU9 )
|
|
{
|
|
queueCommand(player, ##"resuscitatePlayer", self, "", COMMAND_PRIORITY_DEFAULT);
|
|
}
|
|
else if ( item == menu_info_types.SERVER_MENU1 )
|
|
{
|
|
queueCommand(player, ##"revivePlayer", self, "", COMMAND_PRIORITY_DEFAULT);
|
|
}
|
|
else if ( item == menu_info_types.SERVER_PERFORMANCE_LISTEN )
|
|
{
|
|
// Can no longer call the performance watch/listen function directly from a radial menu as the context is incorrect
|
|
// the functions need to be called by the watch/listening player so now we send a message to them to handle it.
|
|
|
|
//performance.listen(player, self);
|
|
|
|
dictionary params = new dictionary();
|
|
params.put("target", self);
|
|
messageTo(player, "handleListenRadialCmd", params, 0, false);
|
|
|
|
sendDirtyObjectMenuNotification(self);
|
|
}
|
|
else if ( item == menu_info_types.SERVER_PERFORMANCE_WATCH )
|
|
{
|
|
// Can no longer call the performance watch/listen function directly from a radial menu as the context is incorrect
|
|
// the functions need to be called by the watch/listening player so now we send a message to them to handle it.
|
|
|
|
//performance.watch(player, self);
|
|
|
|
dictionary params = new dictionary();
|
|
params.put("target", self);
|
|
messageTo(player, "handleWatchRadialCmd", params, 0, false);
|
|
|
|
sendDirtyObjectMenuNotification(self);
|
|
}
|
|
else if ( item == menu_info_types.SERVER_PERFORMANCE_LISTEN_STOP )
|
|
{
|
|
// Can no longer call the performance watch/listen function directly from a radial menu as the context is incorrect
|
|
// the functions need to be called by the watch/listening player so now we send a message to them to handle it.
|
|
|
|
dictionary params = new dictionary();
|
|
messageTo(player, "handleListenRadialCmd", params, 0, false);
|
|
|
|
sendDirtyObjectMenuNotification(self);
|
|
}
|
|
else if ( item == menu_info_types.SERVER_PERFORMANCE_WATCH_STOP )
|
|
{
|
|
// Can no longer call the performance watch/listen function directly from a radial menu as the context is incorrect
|
|
// the functions need to be called by the watch/listening player so now we send a message to them to handle it.
|
|
|
|
dictionary params = new dictionary();
|
|
messageTo(player, "handleWatchRadialCmd", params, 0, false);
|
|
|
|
sendDirtyObjectMenuNotification(self);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnMadeAuthoritative()
|
|
{
|
|
// Hack a fix in for the pirate tutorial for combat upgrade
|
|
string flag = getConfigSetting("GameServer", "skipTutorial");
|
|
if (flag != null && (flag == "true" || flag == "1"))
|
|
{
|
|
setObjVar(self, "skipTutorial", 1);
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnLogin()
|
|
{
|
|
// don't allow log in if the character is in the middle of a CTS
|
|
boolean ctsDisconnectRequested = false;
|
|
if (hasObjVar(self, "disableLoginCtsInProgress"))
|
|
{
|
|
int timeOut = getIntObjVar(self, "disableLoginCtsInProgress");
|
|
if (timeOut > getGameTime())
|
|
{
|
|
ctsDisconnectRequested = true;
|
|
messageTo(self, "disconnectPlayerCtsCompletedOrInProgress", null, 0.1f, false);
|
|
CustomerServiceLog("Login", "dropping character (" + self + ": " + getName(self) + ") because of CTS completed or in progress");
|
|
}
|
|
else
|
|
{
|
|
removeObjVar(self, "disableLoginCtsInProgress");
|
|
}
|
|
}
|
|
|
|
// don't allow log in if the character has already transferred
|
|
if (!ctsDisconnectRequested && hasObjVar(self, "disableLoginCtsCompleted") && !isUsingAdminLogin(self))
|
|
{
|
|
ctsDisconnectRequested = true;
|
|
messageTo(self, "disconnectPlayerCtsCompletedOrInProgress", null, 0.1f, false);
|
|
CustomerServiceLog("Login", "dropping character (" + self + ": " + getName(self) + ") because of CTS completed or in progress");
|
|
}
|
|
|
|
if (!utils.hasScriptVar(self, "galaxyMessage.showmessage"))
|
|
{
|
|
obj_id planetId = getPlanetByName("tatooine");
|
|
if (!isIdNull(planetId))
|
|
{
|
|
utils.setScriptVar(self, "galaxyMessage.showmessage", true);
|
|
if (hasObjVar(planetId, "galaxyMessage"))
|
|
{
|
|
string strGalaxyMessage = "\\#FF0000"+utils.getStringObjVar(planetId, "galaxyMessage")+"\\#FFFFFF";
|
|
sendConsoleMessage(self, strGalaxyMessage);
|
|
}
|
|
else
|
|
{
|
|
string strGalaxyMessage = "\\#FF0000"+"Welcome to Star Wars Galaxies"+"\\#FFFFFF";
|
|
sendConsoleMessage(self, strGalaxyMessage);
|
|
}
|
|
|
|
boolean warden = isWarden(self);
|
|
if (warden || (getGodLevel(self) >= 10))
|
|
{
|
|
string strGalaxyMessage = "\\#FF0000";
|
|
if (!warden)
|
|
{
|
|
strGalaxyMessage += "Displaying warden MOTD to you even though you are not a warden, because you are of the appropriate god level:\n";
|
|
}
|
|
|
|
if (hasObjVar(planetId, "galaxyWardenMessage"))
|
|
{
|
|
strGalaxyMessage += utils.getStringObjVar(planetId, "galaxyWardenMessage");
|
|
}
|
|
else
|
|
{
|
|
strGalaxyMessage += "Welcome warden";
|
|
}
|
|
|
|
strGalaxyMessage += "\\#FFFFFF";
|
|
sendConsoleMessage(self, strGalaxyMessage);
|
|
}
|
|
}
|
|
}
|
|
|
|
removeObjVar( self, "noTrade");
|
|
|
|
if (hasObjVar (self, "comingFromTutorial"))
|
|
{
|
|
removeObjVar (self, "comingFromTutorial");
|
|
attachScript (self, "theme_park.newbie_tutorial.new_player_ribbon");
|
|
}
|
|
|
|
//if combatLevel is stored in the wrong place, put it in the right place:
|
|
if ( !hasObjVar( self, "combatLevel") && hasObjVar( self, "clickRespec.combatLevel") )
|
|
{
|
|
setObjVar(self, "combatLevel", getIntObjVar(self,"clickRespec.combatLevel"));
|
|
removeObjVar(self,"clickRespec.combatLevel");
|
|
}
|
|
|
|
//attach cureward script for wonked servers.
|
|
if ( getConfigSetting("GameServer", "combatUpgradeReward") != null )
|
|
{
|
|
if ( !hasScript( self, "cureward.cureward" ))
|
|
{
|
|
attachScript( self, "cureward.cureward" );
|
|
}
|
|
}
|
|
|
|
//Handle building notification:
|
|
obj_id bldg = getTopMostContainer( self );
|
|
if ( isIdValid(bldg) )
|
|
{
|
|
dictionary parms = new dictionary();
|
|
parms.put( "player", self );
|
|
messageTo( bldg, "handlePlayerLogin", parms, 0, false );
|
|
|
|
string bldgName = getTemplateName (bldg);
|
|
string setting = getConfigSetting("Dungeon", "Death_Watch");
|
|
|
|
if (bldgName == "object/building/general/bunker_allum_mine.iff")
|
|
{
|
|
if ( setting == null || setting == "false" || setting == "0")
|
|
{
|
|
CustomerServiceLog("DUNGEON_DeathWatchBunker", "*Death Watch Unauthorized Entry: %TU entered the death watch bunker while it was turned off.", self);
|
|
}
|
|
}
|
|
|
|
if(hasObjVar(bldg, "player_structure.condemned"))
|
|
{
|
|
player_structure.doCondemnedSui(bldg, self);
|
|
expelFromBuilding(self);
|
|
}
|
|
|
|
}
|
|
|
|
// subscribe the player to system chat rooms
|
|
|
|
// System Messages for EVERY Star Wars Galaxy
|
|
chatEnterRoom("SWG.system");
|
|
//chatEnterRoom("SWG.Universe");
|
|
|
|
// System messages for THIS Galaxy
|
|
chatEnterRoom("SWG." + getGalaxyName() + ".system");
|
|
//chatEnterRoom("SWG." + getGalaxyName() + ".Galaxy");
|
|
|
|
// system messages for THIS planet
|
|
chatEnterRoom("SWG." + getGalaxyName() + "." + getCurrentSceneName() + ".system");
|
|
//chatEnterRoom("SWG." + getGalaxyName() + "." + getCurrentSceneName() + ".Planet");
|
|
|
|
/*******************************************/
|
|
|
|
// clamp the player scale if it is out of range
|
|
float curScale = getScale(self);
|
|
int gender = getGender(self);
|
|
int intSpecies= getSpecies(self);
|
|
string species = utils.getPlayerSpeciesName(intSpecies);
|
|
|
|
float min = 1.0f;
|
|
float max = 1.0f;
|
|
|
|
if ( gender == GENDER_MALE )
|
|
{
|
|
min = dataTableGetFloat("datatables/player/racial_scale.iff", species, "MALE_MIN");
|
|
max = dataTableGetFloat("datatables/player/racial_scale.iff", species, "MALE_MAX");
|
|
}
|
|
else
|
|
{
|
|
min = dataTableGetFloat("datatables/player/racial_scale.iff", species, "FEMALE_MIN");
|
|
max = dataTableGetFloat("datatables/player/racial_scale.iff", species, "FEMALE_MAX");
|
|
}
|
|
|
|
if ( min > 0 && max > 0 )
|
|
{
|
|
if ( curScale < min )
|
|
setScale(self, min);
|
|
else if ( curScale > max )
|
|
setScale(self, max);
|
|
}
|
|
|
|
if (getState(self, STATE_MASK_SCENT) == 1)
|
|
{
|
|
if ( utils.hasScriptVar( self, "scentmask.camokit" ) )
|
|
{
|
|
string kitPlanet = utils.getStringScriptVar(self, "scentmask.camokit");
|
|
string planetName = getCurrentSceneName();
|
|
if (planetName.startsWith("kashyyyk"))
|
|
{
|
|
planetName = "kashyyyk";
|
|
}
|
|
if (!kitPlanet.equals(planetName))
|
|
messageTo(self, "removeScentMaskNoNotify", null, 0, false);
|
|
|
|
}
|
|
else
|
|
{
|
|
messageTo(self, "removeScentMaskNoNotify", null, 0, false);
|
|
}
|
|
}
|
|
if ( hasSkill(self, "demo_combat") )
|
|
revokeSkill(self, "demo_combat");
|
|
|
|
boolean needsPrerequisites = true;
|
|
int attempts = 0;
|
|
while(needsPrerequisites && attempts < 100)
|
|
{
|
|
++attempts;
|
|
needsPrerequisites = false;
|
|
String[] skillList = getSkillListingForPlayer(self);
|
|
if(skillList != null)
|
|
{
|
|
int i = 0;
|
|
for(i = 0; i < skillList.length; ++i)
|
|
{
|
|
String[] prereqs = getSkillPrerequisiteSkills(skillList[i]);
|
|
if(prereqs != null)
|
|
{
|
|
int j = 0;
|
|
for(j = 0; j < prereqs.length; ++j)
|
|
{
|
|
if(! hasSkill(self, prereqs[j]))
|
|
{
|
|
grantSkill(self, prereqs[j]);
|
|
needsPrerequisites = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* COMMENTED OUT AS PART OF NPE/CLICKY-COMBAT CHANGES -- RcT -- 10/11/05
|
|
// Force Sensitive Kick off
|
|
if (!isJediState(self, JEDI_STATE_FORCE_SENSITIVE) && !isJedi(self))
|
|
{
|
|
if (!hasScript(self, "quest.force_sensitive.fs_kickoff"))
|
|
{
|
|
|
|
if (fs_quests.forceSensitiveQualified(self))
|
|
{
|
|
CustomerServiceLog("fs_quests", "%TU has qualified for the intro quest. Initializing intro quest start.", self, null);
|
|
attachScript(self, "quest.force_sensitive.fs_kickoff");
|
|
setObjVar(self, "fs_kickoff_stage", 0);
|
|
fs_quests.setDelay(self, 0);
|
|
}
|
|
//else
|
|
//{
|
|
// fs_quests.badgeLeadin(self);
|
|
//}
|
|
//
|
|
}
|
|
}
|
|
*/
|
|
// Check to see if they have an old residence obj var and convert it.
|
|
if ( hasObjVar( self, player_structure.VAR_RESIDENCE_BUILDING ) )
|
|
{
|
|
setHouseId( self, getObjIdObjVar( self, player_structure.VAR_RESIDENCE_BUILDING ) );
|
|
removeObjVar( self, player_structure.VAR_RESIDENCE_BUILDING );
|
|
}
|
|
|
|
// Remove slicing script vars, if any.
|
|
slicing.clearSlicing( self );
|
|
|
|
hq.ejectEnemyFactionOnLogin( self );
|
|
|
|
//structure.checkForDeathWatch(self);
|
|
|
|
if (!isIdValid(getGroupObject(self)))
|
|
{
|
|
obj_id groupWaypoint = getObjIdObjVar(self, "groupWaypoint");
|
|
if (isIdValid(groupWaypoint))
|
|
{
|
|
destroyWaypointInDatapad(groupWaypoint, self);
|
|
removeObjVar(self, "groupWaypoint");
|
|
}
|
|
}
|
|
|
|
veteran_deprecated.updateVeteranTime(self);
|
|
|
|
// Check to see if the player was renamed.
|
|
if (hasObjVar(self, "renamePerformed"))
|
|
{
|
|
string old_name = getStringObjVar(self, "renamePerformed");
|
|
removeObjVar(self, "renamePerformed");
|
|
if (old_name != null)
|
|
{
|
|
if (force_rank.isForceRanked(self))
|
|
{
|
|
// Intiate a rename on the enclave data.
|
|
force_rank.renameRankMember(self, old_name);
|
|
}
|
|
}
|
|
}
|
|
|
|
meditation.endMeditation(self, false);
|
|
|
|
//Reattach group member script if still in the group
|
|
if (isIdValid(getGroupObject(self)) && (!hasScript(self, group.SCRIPT_GROUP_MEMBER)))
|
|
attachScript(self, group.SCRIPT_GROUP_MEMBER);
|
|
|
|
// clear out coupe de grace target (should already be cleared, but just in case)
|
|
utils.removeScriptVar(self, COUPE_DE_GRACE_TARGET);
|
|
|
|
if(!isInTutorialArea(self))
|
|
{
|
|
space_dungeon.verifyPlayerSession(self);
|
|
space_dungeon.validateInstanceControllerId(self);
|
|
}
|
|
|
|
//temp code to convert camp xp to scout xp:
|
|
int campXp = getExperiencePoints(self, "camp");
|
|
if ( campXp > 0 )
|
|
{
|
|
grantExperiencePoints(self, "scout", campXp );
|
|
grantExperiencePoints(self, "camp", 0-campXp );
|
|
}
|
|
|
|
// "perma bounty" check/cleanup
|
|
if (!utils.hasScriptVar(self,"bountyConsistencyCheck"))
|
|
{
|
|
// get the list of player ids that this
|
|
// player has player bounty missions for
|
|
resizeable obj_id[] playerBountyMissionTargetId = new obj_id[0];
|
|
|
|
obj_id[] objMissions = getMissionObjects(self);
|
|
if (objMissions != null)
|
|
{
|
|
for (int i = 0; i < objMissions.length; ++i)
|
|
{
|
|
string missionType = getMissionType(objMissions[i]);
|
|
if (missionType == "bounty")
|
|
{
|
|
if (hasObjVar(objMissions[i], "objTarget"))
|
|
playerBountyMissionTargetId = utils.addElement(playerBountyMissionTargetId, getObjIdObjVar(objMissions[i], "objTarget"));
|
|
}
|
|
}
|
|
}
|
|
|
|
// get the list of player ids that
|
|
// this player has bounties for
|
|
obj_id[] bounties = getBountyHunterBounties(self);
|
|
if (bounties == null)
|
|
bounties = new obj_id[0];
|
|
|
|
// check for player bounty missions that the player
|
|
// has but there is not a corresponding bounty
|
|
boolean foundMatch = false;
|
|
for (int i = 0; i < playerBountyMissionTargetId.length; ++i)
|
|
{
|
|
foundMatch = false;
|
|
|
|
for (int j = 0; j < bounties.length; ++j)
|
|
{
|
|
if (playerBountyMissionTargetId[i] == bounties[j])
|
|
{
|
|
foundMatch = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!foundMatch)
|
|
{
|
|
CustomerServiceLog("bounty_inconsistency", self + " (" + getName(self) + ") has a bounty mission for " + playerBountyMissionTargetId[i] + " (" + getPlayerName(playerBountyMissionTargetId[i]) + ") but doesn't have a corresponding bounty");
|
|
|
|
// destroy the dangling bounty mission
|
|
dictionary d = new dictionary();
|
|
d.put("target", playerBountyMissionTargetId[i]);
|
|
messageTo(self, "handleBountyMissionIncomplete", d, 10.0f, false);
|
|
}
|
|
}
|
|
|
|
// check for bounties that the player has but
|
|
// there is not a corresponding bounty mission
|
|
for (int k = 0; k < bounties.length; ++k)
|
|
{
|
|
foundMatch = false;
|
|
|
|
for (int l = 0; l < playerBountyMissionTargetId.length; ++l)
|
|
{
|
|
if (playerBountyMissionTargetId[l] == bounties[k])
|
|
{
|
|
foundMatch = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!foundMatch)
|
|
{
|
|
CustomerServiceLog("bounty_inconsistency", self + " (" + getName(self) + ") has a bounty for " + bounties[k] + " (" + getPlayerName(bounties[k]) + ") but doesn't have a corresponding bounty misssion");
|
|
|
|
// remove the "dangling" bounty
|
|
removeJediBounty(bounties[k], self);
|
|
}
|
|
}
|
|
|
|
utils.setScriptVar(self,"bountyConsistencyCheck",1);
|
|
}
|
|
|
|
// rebalance shield on all of player's ship to prevent exploit (DT 19001);
|
|
// this is normally done when the ship is packed during landing; but if
|
|
// you are in space when the cluster is shutdown, the ship doesn't get
|
|
// packed so the shield is left unbalanced; so, whenever the player is
|
|
// loaded from the database, we'll do a rebalance on all the player's ships
|
|
if (!utils.hasScriptVar(self,"shipShieldOneTimeRebalance"))
|
|
{
|
|
obj_id[] objPcds = space_transition.findShipControlDevicesForPlayer(self);
|
|
if (objPcds != null && objPcds.length > 0)
|
|
{
|
|
for (int i = 0; i < objPcds.length; ++i)
|
|
{
|
|
obj_id objShip = space_transition.getShipFromShipControlDevice(objPcds[i]);
|
|
if(isIdValid(objShip))
|
|
{
|
|
space_combat.simpleShieldRatioRebalance(objShip);
|
|
}
|
|
}
|
|
}
|
|
|
|
utils.setScriptVar(self,"shipShieldOneTimeRebalance",1);
|
|
}
|
|
|
|
// count number of worn armor items
|
|
armor.calculateWornArmor(self);
|
|
|
|
// Clean up orphaned rally point
|
|
squad_leader.validateRallyPoint(self);
|
|
|
|
//sendSystemMessageTestingOnly(self, "OnLogin: checking waitingOnCloneRespawn");
|
|
if ( !utils.hasScriptVar(self, "waitingOnCloneRespawn") )
|
|
{
|
|
int posture = getPosture(self);
|
|
if ( posture == POSTURE_DEAD )
|
|
{
|
|
if ( !hasObjVar(self, pclib.VAR_BEEN_COUPDEGRACED) )
|
|
{
|
|
setObjVar(self, pclib.VAR_DEATHBLOW_KILLER, self);
|
|
setObjVar(self, pclib.VAR_DEATHBLOW_STAMP, getGameTime());
|
|
}
|
|
|
|
messageTo(self, pclib.HANDLER_PLAYER_DEATH, null, 5, false);
|
|
}
|
|
else
|
|
{
|
|
if ( hasObjVar(self, pclib.VAR_BEEN_COUPDEGRACED) )
|
|
removeObjVar(self, pclib.VAR_BEEN_COUPDEGRACED);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
messageTo(self, "handleCloneRespawn", null, 1f, false);
|
|
}
|
|
|
|
if (groundquests.hasCompletedQuest(self, "ep3_avatar_self_destruct"))
|
|
badge.grantBadge(self, "bdg_kash_avatar_zssik");
|
|
|
|
if(!utils.hasScriptVar(self, "performance.buildabuff.buffComponentKeys") && buff.hasBuff(self, "buildabuff_inspiration") )
|
|
buff.removeBuff(self, "buildabuff_inspiration");
|
|
|
|
|
|
// If you are ever uncontained on dungeon1, then something has gone wrong.
|
|
if (getLocation(self).area == "dungeon1")
|
|
{
|
|
if (trial.getTop(self) == self)
|
|
{
|
|
warpPlayer( self, "tatooine", 0, 0, 0, null, 0, 0, 0, null, false );
|
|
}
|
|
}
|
|
|
|
if (utils.isProfession(self, utils.FORCE_SENSITIVE) && getLevel(self) > 3)
|
|
{
|
|
if(!buff.isInStance(self) && !buff.isInFocus(self))
|
|
messageTo(self, "applyJediStance", null, 1.0f, false);
|
|
}
|
|
|
|
if(utils.isProfession(self, utils.SMUGGLER))
|
|
{
|
|
messageTo(self, "applySmugglingBonuses", null, 1.0f, false);
|
|
}
|
|
|
|
//Update 8 - City Citizen Messages
|
|
int cityId = getCitizenOfCityId(self);
|
|
if(cityId > 0 && !utils.hasScriptVar(self, "recieved_city_motd"))
|
|
{
|
|
obj_id cityHall = cityGetCityHall(cityId);
|
|
dictionary outparams = new dictionary();
|
|
outparams.put("player", self);
|
|
messageTo(cityHall, "msgCheckMyCityMotd", outparams, 0, false);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler disconnectPlayerCtsCompletedOrInProgress()
|
|
{
|
|
setObjVar(self, "safeLogout", 1);
|
|
disconnectPlayer(self);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler ctsCompletedForCharacter()
|
|
{
|
|
// destroy item used for CTS, if any
|
|
if (utils.hasScriptVar(self, cts.SCRIPTVAR_CTS_ITEM_ID))
|
|
{
|
|
const obj_id ctsItem = utils.getObjIdScriptVar(self, cts.SCRIPTVAR_CTS_ITEM_ID);
|
|
if (isIdValid(ctsItem))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "destroying item " + ctsItem + " used for ingame CTS by character " + self);
|
|
destroyObject(ctsItem);
|
|
}
|
|
}
|
|
|
|
setObjVar(self, "disableLoginCtsCompleted", getCalendarTime());
|
|
messageTo(self, "disconnectPlayerCtsCompletedOrInProgress", null, 0.1f, false);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler applyJediStance()
|
|
{
|
|
if (hasSkill(self, "expertise_fs_path_cautious_nature_1"))
|
|
buff.applyBuff(self, self, jedi.JEDI_STANCE);
|
|
else
|
|
buff.applyBuff(self, self, jedi.JEDI_FOCUS);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler applySmugglingBonuses()
|
|
{
|
|
removeSmugglingBuffs(self);
|
|
|
|
messageTo(self, "addSmugglingBuffs", null, 1.0f, false);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
|
|
messageHandler addSmugglingBuffs()
|
|
{
|
|
int smUnderworld = (int)getSkillStatisticModifier(self, "expertise_underworld_boss_bonus");
|
|
int rangeBonus = (int)getSkillStatisticModifier(self, "expertise_sm_rank_range_buff");
|
|
int damageBonus = (int)getSkillStatisticModifier(self, "expertise_sm_rank_damage_buff");
|
|
|
|
float underworldFaction = factions.getFactionStanding(self, "underworld");
|
|
|
|
int smugglerTier = smuggler.getSmugglerRank(underworldFaction);
|
|
|
|
switch(smugglerTier)
|
|
{
|
|
case 1:
|
|
if(smUnderworld > 0)
|
|
{
|
|
buff.applyBuff(self, "sm_underworld_boss_1");
|
|
}
|
|
if(rangeBonus > 0)
|
|
{
|
|
buff.applyBuff(self, "sm_underworld_range_1");
|
|
}
|
|
if(damageBonus > 0)
|
|
{
|
|
buff.applyBuff(self, "sm_underworld_damage_1");
|
|
}
|
|
break;
|
|
case 2:
|
|
if(smUnderworld > 0)
|
|
{
|
|
buff.applyBuff(self, "sm_underworld_boss_2");
|
|
}
|
|
if(rangeBonus > 0)
|
|
{
|
|
buff.applyBuff(self, "sm_underworld_range_2");
|
|
}
|
|
if(damageBonus > 0)
|
|
{
|
|
buff.applyBuff(self, "sm_underworld_damage_2");
|
|
}
|
|
break;
|
|
case 3:
|
|
if(smUnderworld > 0)
|
|
{
|
|
buff.applyBuff(self, "sm_underworld_boss_3");
|
|
}
|
|
if(rangeBonus > 0)
|
|
{
|
|
buff.applyBuff(self, "sm_underworld_range_3");
|
|
}
|
|
if(damageBonus > 0)
|
|
{
|
|
buff.applyBuff(self, "sm_underworld_damage_3");
|
|
}
|
|
break;
|
|
default: break;
|
|
}
|
|
|
|
messageTo(self, "recalcArmor", null, 1, false);
|
|
messageTo(self, "recalcWeaponRange", null, 1, false);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler recalcWeaponRange()
|
|
{
|
|
obj_id tempWeapon = getObjectInSlot(self, "hold_r");
|
|
|
|
if(isIdValid(tempWeapon))
|
|
{
|
|
weapons.adjustWeaponRangeForExpertise(self, tempWeapon, true);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
void removeSmugglingBuffs(obj_id who)
|
|
{
|
|
buff.removeBuff(who, "sm_underworld_boss_1");
|
|
buff.removeBuff(who, "sm_underworld_boss_2");
|
|
buff.removeBuff(who, "sm_underworld_boss_3");
|
|
buff.removeBuff(who, "sm_underworld_range_1");
|
|
buff.removeBuff(who, "sm_underworld_range_2");
|
|
buff.removeBuff(who, "sm_underworld_range_3");
|
|
buff.removeBuff(who, "sm_underworld_damage_1");
|
|
buff.removeBuff(who, "sm_underworld_damage_2");
|
|
buff.removeBuff(who, "sm_underworld_damage_3");
|
|
|
|
messageTo(who, "recalcArmor", null, 1, false);
|
|
messageTo(who, "recalcWeaponRange", null, 1, false);
|
|
}
|
|
|
|
messageHandler removeSmugglingBonuses()
|
|
{
|
|
removeSmugglingBuffs(self);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handlerRemoveGroupBuffEffect()
|
|
{
|
|
if(params == null || params.isEmpty())
|
|
return SCRIPT_CONTINUE;
|
|
|
|
int[] buffList = params.getIntArray("buffList");
|
|
|
|
if(buffList == null || buffList.length <= 0)
|
|
return SCRIPT_CONTINUE;
|
|
|
|
buff.removeGroupBuffEffect(self, buffList);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
|
|
trigger OnNewbieTutorialResponse(string action)
|
|
{
|
|
if (action.equals("clientReady"))
|
|
{
|
|
//Making sure that the player isn't stuck with a costume.
|
|
int playerState = getState(self, STATE_DISGUISE);
|
|
|
|
if (playerState > 0)
|
|
{
|
|
int shapechange = buff.getBuffOnTargetFromGroup(self, "shapechange");
|
|
|
|
if(shapechange == 0)
|
|
revertObjectAppearance(self);
|
|
}
|
|
|
|
location myLoc = getLocation(self);
|
|
|
|
if(hasTriggerVolume(self, "group_buff_breach"))
|
|
{
|
|
obj_id groupId = getGroupObject(self);
|
|
|
|
if(isIdValid(groupId))
|
|
{
|
|
|
|
obj_id[] groupMembers = getGroupMemberIds(groupId);
|
|
|
|
if(groupMembers != null && groupMembers.length > 0)
|
|
{
|
|
|
|
int[] buffList = buff.getOwnedGroupBuffs(self);
|
|
dictionary dict = new dictionary();
|
|
dict.put("buffList", buffList);
|
|
|
|
for(int i = 0; i < groupMembers.length; ++i)
|
|
{
|
|
|
|
location playerLoc = getLocation(groupMembers[i]);
|
|
|
|
if(playerLoc == null)
|
|
{
|
|
messageTo(groupMembers[i], "handlerRemoveGroupBuffEffect", dict, 1, false);
|
|
continue;
|
|
}
|
|
|
|
if(!myLoc.area.equals(playerLoc.area))
|
|
{
|
|
messageTo(groupMembers[i], "handlerRemoveGroupBuffEffect", dict, 1, false);
|
|
continue;
|
|
}
|
|
|
|
float distance = getDistance(myLoc, playerLoc);
|
|
|
|
if(distance > 110.0f)
|
|
{
|
|
messageTo(groupMembers[i], "handlerRemoveGroupBuffEffect", dict, 1, false);
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//need to check for aura buffs that need to be cleared
|
|
int[] allBuffs = buff.getAllBuffs(self);
|
|
|
|
if(allBuffs != null && allBuffs.length > 0)
|
|
{
|
|
for(int i = 0; i < allBuffs.length; ++i)
|
|
{
|
|
if(buff.isAuraBuff(allBuffs[i]))
|
|
{
|
|
obj_id caster = buff.getBuffCaster(self, allBuffs[i]);
|
|
|
|
if(!isIdValid(caster) || !exists(caster))
|
|
{
|
|
buff.removeBuff(self, allBuffs[i]);
|
|
continue;
|
|
}
|
|
|
|
location casterLoc = getLocation(caster);
|
|
|
|
if(!myLoc.area.equals(casterLoc.area))
|
|
{
|
|
buff.removeBuff(self, allBuffs[i]);
|
|
continue;
|
|
}
|
|
|
|
float distance = getDistance(myLoc, casterLoc);
|
|
|
|
//has to be at least 5m from last time
|
|
if(distance > 110.0f)
|
|
{
|
|
buff.removeBuff(self, allBuffs[i]);
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//Halloween cleanup code.
|
|
string halloweenRunning = getConfigSetting("GameServer", "halloween");
|
|
|
|
if (halloweenRunning == null)
|
|
{
|
|
if (hasObjVar(self, event_perk.COUNTER_TIMESTAMP))
|
|
removeObjVar(self, event_perk.COUNTER_TIMESTAMP);
|
|
|
|
if (hasObjVar(self, event_perk.COUNTER))
|
|
removeObjVar(self, event_perk.COUNTER);
|
|
|
|
if (hasObjVar(self, event_perk.COUNTER_RESTARTTIME))
|
|
removeObjVar(self, event_perk.COUNTER_RESTARTTIME);
|
|
}
|
|
|
|
//Life day cleanup code.
|
|
string lifedayRunning = getConfigSetting("GameServer", "lifeday");
|
|
|
|
if (lifedayRunning == null)
|
|
{
|
|
if (hasObjVar(self, "lifeday"))
|
|
removeObjVar(self, "lifeday");
|
|
}
|
|
if (lifedayRunning != null)
|
|
{
|
|
if (lifeDayNewDay(self))
|
|
{
|
|
if (hasObjVar(self, "lifeday"))
|
|
removeObjVar(self, "lifeday");
|
|
|
|
//If player has old buffs, we remove them.
|
|
if (buff.hasBuff(self, "event_lifeday_imperial_competitive"))
|
|
buff.removeBuff(self, "event_lifeday_imperial_competitive");
|
|
if (buff.hasBuff(self, "event_lifeday_rebel_competitive"))
|
|
buff.removeBuff(self, "event_lifeday_rebel_competitive");
|
|
if (buff.hasBuff(self, "event_lifeday_imperial_present_counter"))
|
|
buff.removeBuff(self, "event_lifeday_imperial_present_counter");
|
|
if (buff.hasBuff(self, "event_lifeday_rebel_tree_counter"))
|
|
buff.removeBuff(self, "event_lifeday_rebel_tree_counter");
|
|
}
|
|
}
|
|
|
|
if (hasScript(self, "systems.respec.click_combat_respec"))
|
|
detachScript(self, "systems.respec.click_combat_respec");
|
|
|
|
// use this for Xmas gift granting if you want to drop into players inventory
|
|
//utils.grantGift(self);
|
|
|
|
// Clicky-combat Respec
|
|
string skillTemplate = getSkillTemplate(self);
|
|
string workingSkill = getWorkingSkill(self);
|
|
if (skillTemplate == null || skillTemplate == "" || skillTemplate == "a")
|
|
{
|
|
int combatLevel = respec.getOldCombatLevel(self);
|
|
obj_id respecDevice = utils.getStaticItemInBankOrInventory(self, "item_respec_token_01_01");
|
|
|
|
// Check to see if we already calculated the combat level
|
|
if (hasObjVar(self, "combatLevel"))
|
|
{
|
|
combatLevel = getIntObjVar(self, "combatLevel");
|
|
}
|
|
// Check to see if there is already a respec device
|
|
else
|
|
{
|
|
if (isIdValid(respecDevice))
|
|
{
|
|
combatLevel = getIntObjVar(respecDevice, "combatLevel");
|
|
}
|
|
}
|
|
|
|
//cap it at 80 in case this is a wonked character:
|
|
if ( combatLevel > 80 )
|
|
combatLevel = 80;
|
|
|
|
//store the combat level on the player in case something breaks:
|
|
setObjVar( self, "combatLevel", combatLevel);
|
|
|
|
//And temp. store it here for the respec:
|
|
setObjVar( self, "clickRespec.combatLevel", combatLevel);
|
|
setObjVar( self, "clickRespec.npeRespec", 1);
|
|
|
|
if (!isIdValid(respecDevice))
|
|
{
|
|
respecDevice = static_item.createNewItemFunction("item_respec_token_01_01", self);
|
|
if (isIdValid(respecDevice))
|
|
{
|
|
setObjVar(respecDevice, "combatLevel", combatLevel);
|
|
setObjVar(respecDevice, "highestLevel", true );
|
|
}
|
|
}
|
|
|
|
attachScript(self, "systems.respec.click_combat_respec");
|
|
|
|
messageTo(self, "delayRespecInstructions", null, 1, false);
|
|
}
|
|
|
|
if ( hasObjVar(self, "npe.skippingTutorial"))
|
|
{
|
|
location origin = getLocation (self);
|
|
location fighting = new location (3521f, 0.0f, -4821f, origin.area);
|
|
location crafty = new location (3309.0f, 6.0f, -4785.0f, origin.area);
|
|
string profession = getSkillTemplate (self);
|
|
|
|
obj_id objInv = utils.getInventoryContainer(self);
|
|
|
|
//define quests
|
|
string questNewbieStart = "quest/speeder_quest";
|
|
string questNewbieStartBH = "quest/speeder_quest";
|
|
string questCrafterEntertainer = "quest/tatooine_eisley_noncombat";
|
|
|
|
|
|
int crafter = profession.indexOf ("trader");
|
|
int entertainer = profession.indexOf ("entertainer");
|
|
int bountyhunter = profession.indexOf ("bounty_hunter");
|
|
if (crafter > -1 || entertainer > -1)
|
|
{
|
|
if (!groundquests.isQuestActiveOrComplete(self, questCrafterEntertainer))
|
|
{
|
|
//createClientPath( self, origin, crafty );
|
|
groundquests.grantQuest(self, questCrafterEntertainer);
|
|
}
|
|
}
|
|
else if (bountyhunter > -1)
|
|
{
|
|
if (groundquests.hasCompletedQuest (self, questNewbieStartBH) || groundquests.isQuestActive (self, questNewbieStartBH))
|
|
{
|
|
detachScript (self, "npe.handoff_to_tatooine");
|
|
}
|
|
else
|
|
{
|
|
groundquests.requestGrantQuest (self, questNewbieStartBH);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
if (groundquests.hasCompletedQuest (self, questNewbieStart) || groundquests.isQuestActive (self, questNewbieStart))
|
|
{
|
|
detachScript (self, "npe.handoff_to_tatooine");
|
|
}
|
|
else
|
|
{
|
|
groundquests.requestGrantQuest (self, questNewbieStart);
|
|
}
|
|
|
|
}
|
|
|
|
if (crafter > -1)
|
|
{
|
|
messageTo(self, "handleSurveyToolbarSetup", null, 5, false);
|
|
}
|
|
|
|
//Give everyone the uniform crate
|
|
static_item.createNewItemFunction("item_npe_uniform_crate_01_01", objInv);
|
|
|
|
//11/9: wwallace: changed this to use the library function
|
|
npe.giveProfessionWeapon(self);
|
|
|
|
|
|
removeObjVar(self, "npe.skippingTutorial");
|
|
|
|
//make combat level 5
|
|
int combatLevel = getLevel( self );
|
|
if ( combatLevel < 5 )
|
|
respec.autoLevelPlayer(self, 5, false);
|
|
}
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnCSCreateItem(obj_id container, string staticItemName)
|
|
{
|
|
gmlib.generateStaticItem( container, staticItemName );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler delayRespecInstructions()
|
|
{
|
|
int pid = createSUIPage( sui.SUI_MSGBOX, self, self, "noHandler" );
|
|
setSUIProperty(pid, "this", "Size", "475,575");
|
|
setSUIProperty(pid, "this", "Location", "100,100");
|
|
setSUIProperty(pid, sui.MSGBOX_TITLE, sui.PROP_TEXT, "@click_respec:respec_title");
|
|
setSUIProperty(pid, sui.MSGBOX_PROMPT, sui.PROP_TEXT, "@click_respec:respec_message");
|
|
sui.msgboxButtonSetup(pid, sui.OK_ONLY);
|
|
showSUIPage(pid);
|
|
flushSUIPage(pid);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//clean-up code for old-style conversation objvars:
|
|
trigger OnRemovingFromWorld()
|
|
{
|
|
removeObjVar( self, "conversation" );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
|
|
messageHandler handleLoginLocResolved()
|
|
{
|
|
CustomerServiceLog("LOGIN_LOC", "("+self+":"+getPlayerObject(self)+") "+getName(self)+": warp callback entered @ loc="+getLocation(self).toString()+" world_loc="+getWorldLocation(self).toString());
|
|
|
|
string prompt = "Due to a system error involving invalid login coordinates, an attempt has been made to warp you to a local starport.";
|
|
prompt += " We apologize for the inconvenience.";
|
|
|
|
sui.msgbox(self, prompt);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleStatProfileSUI()
|
|
{
|
|
if ( !utils.hasScriptVar(self, "screwedStats.opt") )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
string[] opt = utils.getStringArrayScriptVar(self, "screwedStats.opt");
|
|
utils.removeScriptVar(self, "screwedStats.opt");
|
|
|
|
int idx = sui.getListboxSelectedRow(params);
|
|
if ( idx == -1 || idx == 0 )
|
|
{
|
|
sendSystemMessageTestingOnly(self, "You will be asked the previous question on each log-in until the problem is rectified.");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
if ( opt == null || opt.length == 0 )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
if ( idx < 1 || idx >= opt.length )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
dictionary racial_mods = null;
|
|
string template = utils.getTemplateFilenameNoPath(self);
|
|
if ( template != null && !template.equals("") )
|
|
{
|
|
if ( template.endsWith(".iff") )
|
|
template = template.substring(0, template.length() - 4);
|
|
|
|
string racial_tbl = "datatables/creation/racial_mods.iff";
|
|
int templateRow = 0;
|
|
if ( getGender(self) == GENDER_MALE )
|
|
{
|
|
templateRow = dataTableSearchColumnForString(template, 0, racial_tbl);
|
|
}
|
|
else
|
|
{
|
|
templateRow = dataTableSearchColumnForString(template, 1, racial_tbl);
|
|
}
|
|
|
|
racial_mods = dataTableGetRow(racial_tbl, templateRow);
|
|
}
|
|
|
|
if ( racial_mods == null || racial_mods.isEmpty() )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
string profile = opt[idx];
|
|
if ( profile == null || profile.equals("") || profile.equals("none") )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
dictionary prof_mods = dataTableGetRow("datatables/creation/profession_mods.iff", profile);
|
|
for ( int x = 0; x < NUM_ATTRIBUTES; x++ )
|
|
{
|
|
string aname = "";
|
|
switch ( x )
|
|
{
|
|
case 0:
|
|
aname = "health";
|
|
break;
|
|
case 1:
|
|
aname = "constitution";
|
|
break;
|
|
case 2:
|
|
aname = "action";
|
|
break;
|
|
case 3:
|
|
aname = "stamina";
|
|
break;
|
|
case 4:
|
|
aname = "mind";
|
|
break;
|
|
case 5:
|
|
aname = "willpower";
|
|
break;
|
|
}
|
|
|
|
int newval = racial_mods.getInt(aname) + prof_mods.getInt(aname);
|
|
setMaxAttrib(self, x, newval);
|
|
}
|
|
|
|
healing.fullHeal(self);
|
|
|
|
string prompt = " We apologize for any inconveniences this may cause.";
|
|
|
|
sui.msgbox(self, prompt);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnLogout()
|
|
{
|
|
if ( hasObjVar(self, pclib.VAR_CONSENT_FROM_ID) )
|
|
{
|
|
pclib.relinquishConsents(self);
|
|
}
|
|
|
|
self.getScriptVars().remove(veteran_deprecated.SCRIPTVAR_VETERAN_LOGGED_IN);
|
|
|
|
obj_id objBuilding = getTopMostContainer(self);
|
|
if(isIdValid(objBuilding) && objBuilding != self )
|
|
{
|
|
if(hasScript(objBuilding, "planet_map.active_registered"))
|
|
{
|
|
dictionary dctParams = new dictionary();
|
|
dctParams.put("objItem", self);
|
|
messageTo(objBuilding, "removeRegistrant", dctParams, 0, false);
|
|
}
|
|
|
|
location buildingEjectionPoint = getBuildingEjectLocation(objBuilding);
|
|
if (buildingEjectionPoint != null)
|
|
setObjVar(self, "building_ejection_point", buildingEjectionPoint);
|
|
}
|
|
else
|
|
{
|
|
removeObjVar(self, "building_ejection_point");
|
|
}
|
|
|
|
if(utils.hasScriptVar(self, "battlefield.queue"))
|
|
{
|
|
string battlefieldName = utils.getStringScriptVar(self, "battlefield.queue");
|
|
obj_id controller = null;
|
|
|
|
if(battlefieldName != null || battlefieldName.length() > 0)
|
|
{
|
|
controller = utils.getObjIdScriptVar(self, "battlefield." + battlefieldName);
|
|
}
|
|
|
|
if(isIdValid(controller))
|
|
{
|
|
dictionary params = new dictionary();
|
|
|
|
params.put("player", self);
|
|
|
|
if(factions.isRebel(self))
|
|
{
|
|
params.put("faction", factions.FACTION_FLAG_REBEL);
|
|
}
|
|
else if(factions.isImperial(self))
|
|
{
|
|
params.put("faction", factions.FACTION_FLAG_IMPERIAL);
|
|
}
|
|
|
|
messageTo(controller, "removePlayerFromQueue", params, 1.0f, false);
|
|
}
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnUnloadedFromMemory()
|
|
{
|
|
chatExitRoom("SWG.system");
|
|
//chatExitRoom("SWG.Universe");
|
|
|
|
// System messages for THIS Galaxy
|
|
chatExitRoom("SWG." + getGalaxyName() + ".system");
|
|
//chatExitRoom("SWG." + getGalaxyName() + ".Galaxy");
|
|
|
|
// system messages for THIS planet
|
|
chatExitRoom("SWG." + getGalaxyName() + "." + getCurrentSceneName() + ".system");
|
|
//chatExitRoom("SWG." + getGalaxyName() + "." + getCurrentSceneName() + ".Planet");
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
|
|
trigger OnImmediateLogout()
|
|
{
|
|
self.getScriptVars().remove(veteran_deprecated.SCRIPTVAR_VETERAN_LOGGED_IN);
|
|
|
|
// Customer service logging for extraordinary profit
|
|
if(utils.hasScriptVar(self, "profit")) {
|
|
|
|
int startMoney = utils.getIntScriptVar(self, "profit");
|
|
int endMoney = getTotalMoney(self);
|
|
|
|
utils.removeScriptVar(self, "profit");
|
|
|
|
string profitThreshold = getConfigSetting("GameServer", "profitLoggingThreshold");
|
|
if(profitThreshold == null || profitThreshold == "") {
|
|
|
|
profitThreshold = "500000";
|
|
}
|
|
if(utils.stringToInt(profitThreshold) > -1) {
|
|
|
|
if((endMoney - startMoney) > utils.stringToInt(profitThreshold)) {
|
|
|
|
// float percent = ((endMoney-startMoney)/startMoney)*100;
|
|
CustomerServiceLog("Wealth", "Extraordinary Profit: " + getName(self) + " (" + self + ") logged in with " + startMoney + " credits and logged out with " + endMoney + " credits, for a profit of " + (endMoney - startMoney) + " credits");
|
|
}
|
|
}
|
|
}
|
|
|
|
if(guild.hasWindowPid(self))
|
|
guild.removeWindowPid(self);
|
|
|
|
//make sure they dont bypass removing vehicle buffs by just going to char select and logging back in
|
|
int vehicleBuff = buff.getBuffOnTargetFromGroup(self, "vehicle");
|
|
if(vehicleBuff !=0)
|
|
buff.removeBuff(self, vehicleBuff);
|
|
|
|
if(callable.hasAnyCallable(self))
|
|
{
|
|
callable.storeCallables(self);
|
|
}
|
|
|
|
//somehow the player got stuck with a bad sampling ObjVar on them
|
|
removeObjVar(self, "surveying.sampleLocation");
|
|
|
|
// immediate logout allowed if we have 'safeLogout=1' on us
|
|
if (hasObjVar(self, "safeLogout"))
|
|
if (getIntObjVar(self, "safeLogout") == 1)
|
|
return SCRIPT_CONTINUE;
|
|
|
|
// immediate logout allowed in buildings with 'safeLogout=1' on them
|
|
obj_id building = getTopMostContainer(self);
|
|
|
|
if(isIdValid(building))
|
|
{
|
|
if(hasObjVar(building, "safeLogout") && getIntObjVar(building, "safeLogout") == 1)
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
if(hasScript(building, force_rank.SCRIPT_ENCLAVE_CONTROLLER))
|
|
{
|
|
if(!force_rank.isPlayersEnclave(building, self))
|
|
{
|
|
expelFromBuilding(self);
|
|
}
|
|
}
|
|
}
|
|
|
|
// don't allow immediate logout
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
/***** UTILITY TRIGGERS **************************************************/
|
|
trigger OnAboutToReceiveItem(obj_id srcContainer, obj_id transferer, obj_id item)
|
|
{
|
|
int got = getGameObjectType(item);
|
|
//are we equipping a container object?
|
|
if(isGameObjectTypeOf(got, GOT_misc_container_wearable))
|
|
{
|
|
obj_id belt = getObjectInSlot(self, "utility_belt");
|
|
if(isIdValid(belt) && isGameObjectTypeOf(belt, GOT_misc_container_wearable))
|
|
{
|
|
//we are a belt slot item and a container, kick item off
|
|
obj_id inv = utils.getInventoryContainer(self);
|
|
putInOverloaded(belt, inv);
|
|
}
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnReceivedItem(obj_id srcContainer, obj_id transferer, obj_id item)
|
|
{
|
|
int got = getGameObjectType(item);
|
|
if (isGameObjectTypeOf(got, GOT_armor) && !isGameObjectTypeOf(got, GOT_armor_psg))
|
|
armor.calculateWornArmor(self);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnLostItem(obj_id destContainer, obj_id transferer, obj_id item)
|
|
{
|
|
int got = getGameObjectType(item);
|
|
if (isGameObjectTypeOf(got, GOT_armor) && !isGameObjectTypeOf(got, GOT_armor_psg))
|
|
armor.calculateWornArmor(self);
|
|
|
|
if (isGameObjectTypeOf(got, GOT_weapon))
|
|
combat.cacheCombatData(self);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnTransferred(obj_id src, obj_id dest, obj_id transferer)
|
|
{
|
|
if((pet_lib.isMount(src)) || (pet_lib.isMount(dest)) || (vehicle.isVehicle(src)) || (vehicle.isVehicle(dest)))
|
|
{
|
|
movement.refresh(self);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleEjection()
|
|
{
|
|
obj_id sender = null;
|
|
if ( params == null || params.isEmpty() )
|
|
{
|
|
sender = getTopMostContainer(self);
|
|
}
|
|
else
|
|
{
|
|
sender = params.getObjId("sender");
|
|
}
|
|
|
|
if ( !isIdValid(sender) )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
location there = getBuildingEjectLocation(sender);
|
|
if ( there == null )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
//setLocation(self, there);
|
|
pclib.sendToAnyLocation(self, there, null);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
commandHandler cmdEject()
|
|
{
|
|
// Dispatch the message.
|
|
dictionary outparams = new dictionary();
|
|
outparams.put( "loc", getLocation( self ) );
|
|
messageTo( self, "handleDelayedEjection", outparams, 10.f, false );
|
|
|
|
sendSystemMessage( self, SID_SYS_EJECT_REQUEST );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleDelayedEjection()
|
|
{
|
|
if ( params == null )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
if ( getLocation(self).area == "tutorial" )
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
location loc = params.getLocation( "loc" );
|
|
location curloc = getLocation( self );
|
|
if ( getDistance( loc, curloc ) > 1f )
|
|
{
|
|
// Failed due to player move.
|
|
sendSystemMessage( self, SID_SYS_EJECT_FAIL_MOVE );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
obj_id instanceController = instance.getAreaInstanceController(self);
|
|
|
|
if (isIdValid(instanceController))
|
|
{
|
|
string instanceName = instance.getInstanceName(instanceController);
|
|
instance.requestExitPlayer(instanceName, self);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
|
|
// determine if we are in a space dungeon
|
|
{
|
|
obj_id dungeon_id = space_dungeon.getDungeonIdForPlayer(self);
|
|
if (isValidId(dungeon_id) && exists(dungeon_id))
|
|
{
|
|
return SCRIPT_CONTINUE;//Request Denied
|
|
/**
|
|
if (space_dungeon.ejectPlayerFromDungeon(self))
|
|
{
|
|
LOG("space_dungeon", "player.base.base_player.handleDelayedEjection -- handleDelayedEjection ejected player ["
|
|
+ self + "] from dungeon [" + dungeon_id + "," + space_dungeon.getDungeonName(dungeon_id) + "]");
|
|
|
|
prose_package pp = new prose_package();
|
|
pp.stringId = SID_SYS_EJECT_DUNGEON;
|
|
pp.other.set(space_dungeon.getDungeonName(dungeon_id));
|
|
sendSystemMessageProse(self, pp);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
**/
|
|
}
|
|
}
|
|
|
|
// Determine if we are in a structure.
|
|
obj_id container = getTopMostContainer( self );
|
|
obj_id building = null;
|
|
if ( isIdValid(container) )
|
|
{
|
|
if ( isGameObjectTypeOf( container, GOT_building ) && hasScript( container, "structure.permanent_structure" ) )
|
|
ejectPlayerFromBuilding(self, container);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Couldnt find containing building! Find a nearby structure.
|
|
obj_id[] near = getNonCreaturesInRange( getWorldLocation(self), 128f );
|
|
|
|
location here = getWorldLocation(self);
|
|
|
|
obj_id closest = null;
|
|
float maxdist = 9999.f;
|
|
for ( int i=0; i<near.length; i++ )
|
|
{
|
|
// Make sure one of these is a building.
|
|
if ( isGameObjectTypeOf( near[i], GOT_building ) || isGameObjectTypeOf(near[i], GOT_installation) )
|
|
{
|
|
// Store the closest one.
|
|
float dist = getDistance( here, getWorldLocation( near[i] ) );
|
|
if ( dist < maxdist )
|
|
{
|
|
maxdist = dist;
|
|
closest = near[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( isIdValid(closest) )
|
|
{
|
|
if ( isGameObjectTypeOf(closest, GOT_building) )
|
|
ejectPlayerFromBuilding(self, closest);
|
|
else if ( isGameObjectTypeOf(closest, GOT_installation) )
|
|
{
|
|
float yaw = getYaw(closest);
|
|
location there = getWorldLocation(closest);
|
|
location loc1 = utils.rotatePointXZ(there, 8f, yaw+90f);
|
|
location loc2 = utils.rotatePointXZ(there, 8f, yaw-90f);
|
|
|
|
float d1 = getDistance(here, loc1);
|
|
float d2 = getDistance(here, loc2);
|
|
|
|
if ( d1 < d2 )
|
|
{
|
|
pclib.sendToAnyLocation( self, loc1, null );
|
|
}
|
|
else
|
|
{
|
|
pclib.sendToAnyLocation( self, loc2, null );
|
|
}
|
|
|
|
sendSystemMessage( self, SID_SYS_EJECT_SUCCESS );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Failed because no building nearby.
|
|
sendSystemMessage( self, SID_SYS_EJECT_FAIL_PROXIMITY );
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
void ejectPlayerFromBuilding(obj_id player, obj_id building)
|
|
{
|
|
// Send the player there.
|
|
location there = getBuildingEjectLocation( building );
|
|
if ( there == null )
|
|
return;
|
|
|
|
pclib.sendToAnyLocation( player, there, null );
|
|
sendSystemMessage( player, SID_SYS_EJECT_SUCCESS );
|
|
}
|
|
|
|
messageHandler handleWatchRadialCmd()
|
|
{
|
|
obj_id target = params.getObjId("target");
|
|
|
|
if (isIdValid(target))
|
|
performance.watch(self, target);
|
|
else
|
|
performance.stopWatch(self);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleListenRadialCmd()
|
|
{
|
|
obj_id target = params.getObjId("target");
|
|
|
|
if (isIdValid(target))
|
|
performance.listen(self, target);
|
|
else
|
|
performance.stopListen(self);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
/***** SKILL HANDLERS *************************************************/
|
|
messageHandler handleSkillPurchase()
|
|
{
|
|
string boxTitle = params.getString(sui.LISTBOX_TITLE + "." + sui.PROP_TEXT);
|
|
string skillName = boxTitle.substring(boxTitle.indexOf(":") + 1);
|
|
|
|
//debugSpeakMsg(self, "skillName = " + skillName);
|
|
|
|
if ( !skill.purchaseSkill(self, skillName) )
|
|
{
|
|
//debugSpeakMsg(self, "something went weird purchasing the skill!");
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
/***** LOOT HANDLERS *************************************************/
|
|
messageHandler handleRequestCoinLoot()
|
|
{
|
|
if ( params == null || params.isEmpty() )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
obj_id corpseId = params.getObjId(corpse.DICT_CORPSE_ID);
|
|
if ( !isIdValid(corpseId) )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
int cash = params.getInt(corpse.DICT_COINS);
|
|
//int cash = getCashBalance(corpseId);
|
|
int safeCash = group.getSafeDifference(self, cash);
|
|
if (safeCash < cash)
|
|
{
|
|
cash = safeCash;
|
|
params.put(corpse.DICT_COINS, cash);
|
|
}
|
|
|
|
//LOG("corpseLoot","passed cash = " + cash + " retrieved cash = " + cash);
|
|
if ( cash > 0 )
|
|
{
|
|
if (transferBankCreditsFromNamedAccount(money.ACCT_NPC_LOOT, self, cash, null, null, null))
|
|
{
|
|
utils.moneyInMetric(corpseId, money.ACCT_NPC_LOOT, cash);
|
|
|
|
withdrawCashFromBank(self, cash, corpse.HANDLER_COINS_LOOTED, corpse.HANDLER_COINLOOT_FAILED, params);
|
|
}
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
/***** CONSENT HANDLERS *************************************************/
|
|
messageHandler handleUnconsentMenu()
|
|
{
|
|
int btnPressed = sui.getIntButtonPressed(params);
|
|
switch(btnPressed)
|
|
{
|
|
case sui.BP_CANCEL:
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
int idx = sui.getListboxSelectedRow(params);
|
|
if ( idx < 0 )
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
if ( hasObjVar(self, pclib.VAR_CONSENT_TO_ID) )
|
|
{
|
|
obj_id[] consentTo = getObjIdArrayObjVar(self, pclib.VAR_CONSENT_TO_ID);
|
|
if ( (consentTo == null) || (consentTo.length == 0) )
|
|
{
|
|
//this must have been an expired UI
|
|
}
|
|
else
|
|
{
|
|
obj_id target = consentTo[idx];
|
|
queueCommand(self, ##"unconsent", null, getPlayerFullName(target), COMMAND_PRIORITY_DEFAULT);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
}
|
|
|
|
sendSystemMessage(self, SID_CONSENT_TO_EMPTY);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleConsentToLogout()
|
|
{
|
|
if ( params == null )
|
|
{
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
obj_id consented = params.getObjId(corpse.DICT_PLAYER_ID);
|
|
obj_id[] corpses = getObjIdArrayObjVar(self, pclib.VAR_CORPSE_ID);
|
|
if ( corpses != null )
|
|
{
|
|
corpse.revokeCorpseConsent(corpses, consented);
|
|
}
|
|
|
|
resizeable obj_id[] consentToList = getResizeableObjIdArrayObjVar(self, pclib.VAR_CONSENT_TO_ID);
|
|
if ( consentToList != null )
|
|
{
|
|
consentToList = utils.removeElement(consentToList, consented);
|
|
if ( (consentToList == null) || (consentToList.length == 0) )
|
|
{
|
|
removeObjVar(self, pclib.VAR_CONSENT_TO_ID);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
setObjVar(self, pclib.VAR_CONSENT_TO_ID, consentToList);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleReceivedConsent()
|
|
{
|
|
obj_id consenter = params.getObjId(pclib.DICT_CONSENTER_ID);
|
|
|
|
resizeable obj_id[] consentFrom = getResizeableObjIdArrayObjVar(self, pclib.VAR_CONSENT_FROM_ID);
|
|
if (consentFrom == null)
|
|
{
|
|
resizeable obj_id[] newConsentFrom = new obj_id[0];
|
|
consentFrom = newConsentFrom;
|
|
}
|
|
else
|
|
{
|
|
if(utils.getElementPositionInArray(consentFrom, consenter) > -1)
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
}
|
|
|
|
consentFrom = utils.addElement(consentFrom, consenter);
|
|
|
|
setObjVar(self, pclib.VAR_CONSENT_FROM_ID, consentFrom);
|
|
|
|
prose_package pp = prose.getPackage(PROSE_GOT_CONSENT, getPlayerFullName(consenter));
|
|
sendSystemMessageProse(self, pp);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleReceivedUnconsent()
|
|
{
|
|
obj_id consenter = params.getObjId(pclib.DICT_CONSENTER_ID);
|
|
|
|
resizeable obj_id[] consentFrom = getResizeableObjIdArrayObjVar(self, pclib.VAR_CONSENT_FROM_ID);
|
|
if ( consentFrom != null )
|
|
{
|
|
int idx = utils.getElementPositionInArray(consentFrom, consenter);
|
|
if ( idx > -1 )
|
|
{
|
|
consentFrom = utils.removeElementAt(consentFrom, idx);
|
|
|
|
if ((consentFrom == null) || (consentFrom.length == 0))
|
|
{
|
|
removeObjVar(self, pclib.VAR_CONSENT_FROM_BASE);
|
|
}
|
|
else
|
|
{
|
|
setObjVar(self, pclib.VAR_CONSENT_FROM_ID, consentFrom);
|
|
}
|
|
|
|
prose_package pp = prose.getPackage(PROSE_LOST_CONSENT, getPlayerFullName(consenter));
|
|
sendSystemMessageProse(self, pp);
|
|
}
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
/***** CORPSE HANDLERS *************************************************/
|
|
messageHandler handleCorpseCoinLoot()
|
|
{
|
|
if ( params == null || params.isEmpty() )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
obj_id corpseId = params.getObjId(corpse.DICT_CORPSE_ID);
|
|
int cash = params.getInt(corpse.DICT_COINS);
|
|
|
|
//sendSystemMessageTestingOnly(self, "You looted " + cash + " credits from " + getName(corpseId));
|
|
|
|
if (isIdValid(corpseId))
|
|
{
|
|
obj_id nullId = null;
|
|
queueCommand(self, ##"splitCreditsWithGroup", null, Integer.toString(cash), COMMAND_PRIORITY_DEFAULT);
|
|
|
|
obj_id gid = getGroupObject(self);
|
|
if (isIdValid(gid))
|
|
{
|
|
group.notifyCoinLoot(gid, self, corpseId, cash);
|
|
}
|
|
else
|
|
{
|
|
prose_package pp = prose.getPackage(PROSE_COIN_LOOT_NO_TARGET, null, nullId, cash);
|
|
sendSystemMessageProse(self, pp);
|
|
}
|
|
CustomerServiceLog("Loot", "(" + self + ") " + getName(self) + " looted " + cash + " credits from (" + corpseId + ") " + getName(corpseId));
|
|
|
|
//DO NOT PREMATURELY EXPIRE CORPSE IF IT HAS LOOT
|
|
obj_id cInv = utils.getInventoryContainer(corpseId);
|
|
if(isIdValid(cInv))
|
|
{
|
|
obj_id[] corpseContents = corpse.getValidLootContents(getContents(cInv));
|
|
if(corpseContents == null || corpseContents.length <= 0)
|
|
{
|
|
messageTo(corpseId, "handleCorpseExpire", null, 2, true);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
else
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
}
|
|
|
|
//lets catch any weird cases that the corpse doesnt clean itself up by sending an expire callback
|
|
messageTo(corpseId, "handleCorpseExpire", null, 2, true);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleCorpseCoinLootFailed()
|
|
{
|
|
if ( params == null )
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
obj_id corpseId = params.getObjId(corpse.DICT_CORPSE_ID);
|
|
int cash = params.getInt(corpse.DICT_COINS);
|
|
|
|
//sendSystemMessageTestingOnly(self, "You FAILED to loot " + cash + " credits from " + getName(corpseId) + ". Notify a GM of the error.");
|
|
|
|
prose_package pp = prose.getPackage(PROSE_COIN_LOOT_FAILED, null, corpseId, cash);
|
|
sendSystemMessageProse(self, pp);
|
|
|
|
int got = getGameObjectType(corpseId);
|
|
if ( got == GOT_corpse )
|
|
{
|
|
CustomerServiceLog("Death", "(" + self + ") " + getName(self) + " FAILED to loot " + cash + " credits from (" + corpseId + ") " + getName(corpseId));
|
|
}
|
|
else
|
|
{
|
|
CustomerServiceLog("Loot", "(" + self + ") " + getName(self) + " FAILED to loot " + cash + " credits from (" + corpseId + ") " + getName(corpseId));
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleCorpseExpire()
|
|
{
|
|
if ( params == null )
|
|
{
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
obj_id corpseId = params.getObjId(corpse.DICT_CORPSE_ID);
|
|
if (isIdValid(corpseId))
|
|
{
|
|
obj_id[] corpses = getObjIdArrayObjVar(self, pclib.VAR_CORPSE_ID);
|
|
if ( utils.getElementPositionInArray(corpses, corpseId) > -1 )
|
|
{
|
|
sendSystemMessage(self, SID_CORPSE_EXPIRED);
|
|
}
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleCorpseWaypointUpdate()
|
|
{
|
|
if ( params == null )
|
|
{
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
obj_id waypoint = params.getObjId(corpse.DICT_CORPSE_WAYPOINT);
|
|
location loc = params.getLocation(corpse.DICT_CORPSE_LOC);
|
|
|
|
setWaypointLocation(waypoint, loc);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleCorpseCleanup()
|
|
{
|
|
if ( params == null )
|
|
{
|
|
//debugSpeakMsg(self, "base_player::handleCorpseCleanup: received null params... you betta ask somebody");
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
obj_id corpseId = params.getObjId(corpse.DICT_CORPSE_ID);
|
|
obj_id waypoint = params.getObjId(corpse.DICT_CORPSE_WAYPOINT);
|
|
|
|
destroyWaypointInDatapad(waypoint, self);
|
|
|
|
resizeable obj_id[] corpses = utils.getResizeableObjIdBatchObjVar(self, pclib.VAR_CORPSE_ID);
|
|
resizeable obj_id[] killers = utils.getResizeableObjIdBatchObjVar(self, pclib.VAR_CORPSE_KILLER);
|
|
resizeable int[] stamps = utils.getResizeableIntBatchObjVar(self, pclib.VAR_CORPSE_STAMP);
|
|
|
|
if ( (corpses == null) || (killers == null) )
|
|
{
|
|
//something very bad happened
|
|
//debugSpeakMsg(self, "corpse.id or corpse.killer array is outta whack!");
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
int idx = utils.getElementPositionInArray(corpses, corpseId);
|
|
if ( idx > -1 )
|
|
{
|
|
corpses = utils.removeElementAt(corpses, idx);
|
|
killers = utils.removeElementAt(killers, idx);
|
|
stamps = utils.removeElementAt(stamps, idx);
|
|
if ( (corpses == null) || (corpses.length == 0) )
|
|
{
|
|
removeObjVar(self, pclib.VAR_CORPSE_BASE);
|
|
}
|
|
else
|
|
{
|
|
utils.setResizeableBatchObjVar(self, pclib.VAR_CORPSE_ID, corpses);
|
|
utils.setResizeableBatchObjVar(self, pclib.VAR_CORPSE_KILLER, killers);
|
|
utils.setResizeableBatchObjVar(self, pclib.VAR_CORPSE_STAMP, stamps);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//how did I get this corpse id??
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//********* DEATH MESSAGEHANDLERS ****************************************
|
|
messageHandler handleIncapCounterDeath()
|
|
{
|
|
int posture = getPosture(self);
|
|
obj_id objKiller = params.getObjId("objKiller");
|
|
if ( posture == POSTURE_INCAPACITATED && !hasObjVar(self, pclib.VAR_BEEN_COUPDEGRACED) )
|
|
pclib.coupDeGrace(self, objKiller, false);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
commandHandler reportJediDeathCount()
|
|
{
|
|
//messageTo(self, "handleJediDeathCount", null, 0, false);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleJediDeathCount()
|
|
{
|
|
if (isJedi(self))
|
|
{
|
|
int jediDeaths = getIntObjVar(self, jedi.VAR_JEDI_DEATHS);
|
|
|
|
string_id msg = new string_id("jedi_spam", "jedi_death");
|
|
prose_package proseMsg = prose.getPackage(msg, jediDeaths);
|
|
|
|
sendSystemMessageProse(self, proseMsg);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler decayJediDeath()
|
|
{
|
|
|
|
int jediDeaths = getIntObjVar(self, jedi.VAR_JEDI_DEATHS);
|
|
jediDeaths--;
|
|
if (jediDeaths < 0) jediDeaths = 0;
|
|
|
|
setObjVar(self, jedi.VAR_JEDI_DEATHS, jediDeaths);
|
|
|
|
if (isGod(self))
|
|
{
|
|
string_id msg = new string_id("jedi_spam", "jedi_death_decay");
|
|
prose_package proseMsg = prose.getPackage(msg, jediDeaths);
|
|
sendSystemMessageProse(self, proseMsg);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleHealOverTimeTick()
|
|
{
|
|
float duration = params.getFloat("duration");
|
|
float tick = params.getFloat("tick");
|
|
int heal = params.getInt("heal");
|
|
int hot_id = params.getInt("id");
|
|
int isCombat = params.getInt("combat");
|
|
obj_id medic = params.getObjId("medic");
|
|
|
|
if(isDead(self))
|
|
{
|
|
if(buff.hasBuff(self, "healOverTime"))
|
|
buff.removeBuff(self, "healOverTime");
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
if(!utils.hasScriptVar(self, healing.VAR_PLAYER_HOT_ID))
|
|
{
|
|
if(buff.hasBuff(self, "healOverTime"))
|
|
buff.removeBuff(self, "healOverTime");
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
int player_id = utils.getIntScriptVar(self, healing.VAR_PLAYER_HOT_ID);
|
|
|
|
if(hot_id != player_id)
|
|
return SCRIPT_CONTINUE;
|
|
|
|
if(!isIncapacitated(self))
|
|
{
|
|
int delta = healing.healDamage(medic, self, HEALTH, heal);
|
|
|
|
if(isCombat == 1 && isIdValid(medic))
|
|
{
|
|
prose_package pp = new prose_package();
|
|
pp = prose.setStringId(pp, new string_id("healing", "heal_fly"));
|
|
pp = prose.setDI(pp, delta);
|
|
pp = prose.setTO(pp, ATTRIBUTES[HEALTH]);
|
|
showFlyTextPrivateProseWithFlags(self, self, pp, 2.0f, colors.SEAGREEN, FLY_TEXT_FLAG_IS_HEAL);
|
|
|
|
if(medic != self)
|
|
showFlyTextPrivateProseWithFlags(self, medic, pp, 2.0f, colors.SEAGREEN, FLY_TEXT_FLAG_IS_HEAL);
|
|
|
|
pp = prose.setStringId(pp, healing.SID_PERFORM_HEAL_DAMAGE_SUCCESS);
|
|
pp = prose.setTT(pp, medic);
|
|
pp = prose.setTO(pp, self);
|
|
pp = prose.setDI(pp, delta);
|
|
healing.sendMedicalSpam(medic, self, pp, true, true, true, COMBAT_RESULT_MEDICAL);
|
|
|
|
delta = (int)(delta*healing.HEAL_OVER_TIME_AGGRO_REDUCER);
|
|
healing._addMedicalHate(medic, self, delta);
|
|
}
|
|
}
|
|
|
|
duration -= tick;
|
|
if(duration <= 0.0f)
|
|
{
|
|
if(buff.hasBuff(self, "healOverTime"))
|
|
buff.removeBuff(self, "healOverTime");
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
dictionary d = new dictionary();
|
|
d.put("duration", duration);
|
|
d.put("tick", tick);
|
|
d.put("heal", heal);
|
|
d.put("id", hot_id);
|
|
d.put("combat", isCombat);
|
|
d.put("medic", medic);
|
|
|
|
if(tick >= 0)
|
|
messageTo(self, healing.MSG_HEAL_OVER_TIME, d, tick, false);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handlePlayerDeath()
|
|
{
|
|
// If they are doing any smuggler mission this will fail it
|
|
groundquests.sendSignal(self, "smugglerEnemyIncap");
|
|
|
|
if ( utils.hasScriptVar(self, pclib.VAR_SUI_CLONE) )
|
|
{
|
|
int oldpid = utils.getIntScriptVar(self, pclib.VAR_SUI_CLONE);
|
|
forceCloseSUIPage(oldpid);
|
|
|
|
utils.removeScriptVar(self, pclib.VAR_SUI_CLONE);
|
|
}
|
|
|
|
if ( !isDead(self) )
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
pvpRemoveAllTempEnemyFlags(self);
|
|
|
|
clearBuffIcon(self, "food");
|
|
|
|
if(isPvpRelatedDeath(self))
|
|
{
|
|
utils.setScriptVar(self, "buffDecay", 1);
|
|
buff.decayAllBuffsFromPvpDeath(self);
|
|
}
|
|
else
|
|
buff.removeAllBuffs(self, true);
|
|
|
|
// Clear invisibility
|
|
//stealth.testInvisNonCombatAction(self, null);
|
|
|
|
if ( !hasObjVar(self, pclib.VAR_BEEN_COUPDEGRACED) )
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
resizeable string[] options = new string[0];
|
|
resizeable location[] cloneLocs = new location[0];
|
|
resizeable location[] spawnLocs = new location[0];
|
|
resizeable int[] damage = new int[0];
|
|
|
|
//if (space_dungeon.isCloningInstance(self))
|
|
//{
|
|
// messageTo(self, "handleInstanceClonePause", null, 1, false);
|
|
// return SCRIPT_CONTINUE;
|
|
//}
|
|
|
|
boolean isNewbieDeath = false;
|
|
|
|
location deathLoc = pclib.getEffectiveDeathLocation(self);
|
|
string planetName = deathLoc.area;
|
|
obj_id planet = getPlanetByName(planetName);
|
|
|
|
location worldLoc = getWorldLocation(self);
|
|
string areaName = getBuildoutAreaName(worldLoc.x, worldLoc.z);
|
|
|
|
obj_id bound = getObjIdObjVar(self, cloninglib.VAR_BIND_FACILITY);
|
|
boolean isBindListed = false;
|
|
|
|
obj_id controller = utils.getObjIdScriptVar(self, "battlefield.active");
|
|
|
|
if(isIdValid(controller) && exists(controller))
|
|
{
|
|
location cloneLoc = null;
|
|
string cloneName = "Clone Center";
|
|
string battlefieldName = utils.getStringObjVar(controller, "battlefieldName");
|
|
|
|
if(factions.isRebel(self))
|
|
{
|
|
cloneLoc = utils.getLocationScriptVar(controller, "battlefieldRebelSpawn");
|
|
cloneName = "Rebel Cloning Center - " + localize(new string_id("spam", battlefieldName));
|
|
}
|
|
else if(factions.isImperial(self))
|
|
{
|
|
cloneLoc = utils.getLocationScriptVar(controller, "battlefieldImperialSpawn");
|
|
cloneName = "Imperial Cloning Center - " + localize(new string_id("spam", battlefieldName));
|
|
}
|
|
|
|
options = utils.addElement(options, cloneName);
|
|
cloneLocs = utils.addElement(cloneLocs, cloneLoc);
|
|
spawnLocs = utils.addElement(spawnLocs, cloneLoc);
|
|
}
|
|
else
|
|
{
|
|
if(cloninglib.canUseBindFacility(planetName, areaName))
|
|
{
|
|
string bindName = "@base_player:clone_location_registered_select_begin ";
|
|
|
|
if(hasObjVar(self, cloninglib.VAR_BIND_BASE))
|
|
{
|
|
string cloneName = getStringObjVar(self, cloninglib.VAR_BIND_CITY_NAME);
|
|
location bindLoc = getLocationObjVar(self, cloninglib.VAR_BIND_LOCATION);
|
|
location spawnLoc = getLocationObjVar(self, cloninglib.VAR_BIND_SPAWN_LOC);
|
|
|
|
if(bindLoc != null)
|
|
{
|
|
if(isIdValid(bound))
|
|
{
|
|
if(city.isCityBanned(self, bound))
|
|
{
|
|
bindName += " @base_player:clone_location_city_banned";
|
|
bindLoc = null;
|
|
spawnLoc = null;
|
|
}
|
|
else
|
|
{
|
|
bindName += cloneName;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bindName += "@base_player:clone_location_unknown";
|
|
bindLoc = null;
|
|
spawnLoc = null;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bindName += "@base_player:clone_location_none";
|
|
bindLoc = null;
|
|
spawnLoc = null;
|
|
}
|
|
|
|
bindName += " @base_player:clone_location_registered_select_end";
|
|
options = utils.addElement(options, bindName);
|
|
cloneLocs = utils.addElement(cloneLocs, bindLoc);
|
|
spawnLocs = utils.addElement(spawnLocs, spawnLoc);
|
|
|
|
if(pvp.isPvpDeath(self) || isNewbieDeath)
|
|
damage = utils.addElement(damage, 0);
|
|
else
|
|
damage = utils.addElement(damage, cloninglib.CLONE_DAMAGE_LOW);
|
|
isBindListed = true;
|
|
}
|
|
}
|
|
|
|
if(isIdValid(planet))
|
|
{
|
|
if(utils.hasScriptVar(planet, cloninglib.VAR_PLANET_CLONE_LOC))
|
|
{
|
|
Vector cloneList = cloninglib.getAvailableCloningFacilities(self);
|
|
int playerFaction = factions.getFactionFlag(self);
|
|
obj_id tatooinePlanet = getPlanetByName("tatooine");
|
|
|
|
for(int i = 0; i < cloneList.size(); i++)
|
|
{
|
|
dictionary cloneData = (dictionary)(cloneList.get(i));
|
|
|
|
obj_id facility = cloneData.getObjId("faciltyId");
|
|
string cloneName = cloneData.getString("cloneName");
|
|
location cloneLoc = cloneData.getLocation("facilityLoc");
|
|
location spawnLoc = cloneData.getLocation("spawnLoc");
|
|
|
|
if (facility == bound && !isBindListed)
|
|
{
|
|
cloneName = "@base_player:clone_location_registered_select_begin "+
|
|
getStringObjVar(self, cloninglib.VAR_BIND_CITY_NAME)+
|
|
" @base_player:clone_location_registered_select_end";
|
|
|
|
//if (pvp.isPvpDeath(self) || isNewbieDeath)
|
|
// damage = utils.addElement(damage, 0);
|
|
//else
|
|
// damage = utils.addElement(damage, cloninglib.CLONE_DAMAGE_LOW);
|
|
|
|
isBindListed = true;
|
|
}
|
|
//else
|
|
//{
|
|
// if (isNewbieDeath)
|
|
// damage = utils.addElement(damage, 0);
|
|
// else if (pvp.isPvpDeath(self))
|
|
// damage = utils.addElement(damage, cloninglib.CLONE_DAMAGE_LOW);
|
|
// else
|
|
// damage = utils.addElement(damage, cloninglib.CLONE_DAMAGE_HIGH);
|
|
//}
|
|
|
|
// This hackery differentiates the two different theed cloning facilities.
|
|
if(cloneName.equals("@naboo_region_names:theed") && cloneLoc.z > 4100)
|
|
cloneName+= "_north";
|
|
|
|
if(playerFaction == factions.FACTION_FLAG_IMPERIAL || playerFaction == factions.FACTION_FLAG_REBEL)
|
|
{
|
|
if(cloneName.equals("@tatooine_region_names:bestine") && utils.hasScriptVar(tatooinePlanet, "gcw.invasionRunning.bestine"))
|
|
{
|
|
int factionDefending = utils.getIntScriptVar(tatooinePlanet, "gcw.factionDefending.bestine");
|
|
|
|
if( (factionDefending == factions.FACTION_FLAG_IMPERIAL ||
|
|
factionDefending == factions.FACTION_FLAG_REBEL) &&
|
|
playerFaction != factionDefending)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if(cloneName.equals("@talus_region_names:dearic") && utils.hasScriptVar(tatooinePlanet, "gcw.invasionRunning.dearic"))
|
|
{
|
|
int factionDefending = utils.getIntScriptVar(tatooinePlanet, "gcw.factionDefending.dearic");
|
|
|
|
if( (factionDefending == factions.FACTION_FLAG_IMPERIAL ||
|
|
factionDefending == factions.FACTION_FLAG_REBEL) &&
|
|
playerFaction != factionDefending)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if(cloneName.equals("@naboo_region_names:keren") && utils.hasScriptVar(tatooinePlanet, "gcw.invasionRunning.keren"))
|
|
{
|
|
int factionDefending = utils.getIntScriptVar(tatooinePlanet, "gcw.factionDefending.keren");
|
|
|
|
if( (factionDefending == factions.FACTION_FLAG_IMPERIAL ||
|
|
factionDefending == factions.FACTION_FLAG_REBEL) &&
|
|
playerFaction != factionDefending)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
options = utils.addElement(options, cloneName);
|
|
cloneLocs = utils.addElement(cloneLocs, cloneLoc);
|
|
spawnLocs = utils.addElement(spawnLocs, spawnLoc);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// If there are no options to revive yourself, then you are probably in a bad location/bugged planet.
|
|
if(options == null || options.length < 1)
|
|
{
|
|
// pclib.playerRevive(self);
|
|
// return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
int suiClone = createCloningSui(self, options);
|
|
|
|
if(suiClone == -1)
|
|
{
|
|
debugServerConsoleMsg(self, "PLAYER DEATH ERROR: unable to create sui for player = " + self);
|
|
debugServerConsoleMsg(self, "* reviving player at cuttent location...");
|
|
// if ( !pclib.playerRevive(self) )
|
|
// {
|
|
//messageTo(self, pclib.HANDLER_CLONE_RESPAWN, null, 1, true);
|
|
// }
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
utils.setScriptVar(self, pclib.VAR_SUI_CLONE, suiClone);
|
|
utils.setScriptVar(self, pclib.VAR_REVIVE_OPTIONS, options);
|
|
utils.setScriptVar(self, pclib.VAR_REVIVE_CLONE, cloneLocs);
|
|
utils.setScriptVar(self, pclib.VAR_REVIVE_SPAWN, spawnLocs);
|
|
//utils.setScriptVar(self, pclib.VAR_REVIVE_DAMAGE, damage);
|
|
|
|
dictionary hrem = new dictionary();
|
|
hrem.put("time", healing.REVIVE_TIMER);
|
|
hrem.put("sui", suiClone);
|
|
utils.setScriptVar(self, combat.DIED_RECENTLY, true);
|
|
messageTo(self, "clearRecentDeathScriptVar", null, combat.RECENT_DEATH_EXPIRATION, false);
|
|
messageTo(self, "handleReviveExpirationMessage", hrem, 0.0f, false);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
int createCloningSui(obj_id player, resizeable string[] list)
|
|
{
|
|
string title = MSG_REVIVE_TITLE;
|
|
string prompt = buildCloningPrompt(player, -1);
|
|
|
|
int pid = createSUIPage(sui.SUI_LISTBOX, player, player, HANDLER_PLAYER_REVIVE);
|
|
|
|
setSUIProperty(pid, sui.LISTBOX_TITLE, sui.PROP_TEXT, title);
|
|
setSUIProperty(pid, sui.LISTBOX_PROMPT, sui.PROP_TEXT, prompt);
|
|
|
|
// Add buttons.
|
|
sui.listboxButtonSetup(pid, sui.OK_ONLY);
|
|
|
|
clearSUIDataSource(pid, sui.LISTBOX_DATASOURCE);
|
|
|
|
for (int i = 0; i < list.length; i++)
|
|
{
|
|
addSUIDataItem(pid, sui.LISTBOX_DATASOURCE, "" + i);
|
|
setSUIProperty(pid, sui.LISTBOX_DATASOURCE + "." + i, sui.PROP_TEXT, list[i]);
|
|
}
|
|
|
|
subscribeToSUIEvent(pid, sui_event_type.SET_onGenericSelection, sui.LISTBOX_LIST, "handleCloneSuiUpdate");
|
|
subscribeToSUIPropertyForEvent(pid, sui_event_type.SET_onGenericSelection, sui.LISTBOX_LIST, sui.LISTBOX_LIST, sui.PROP_SELECTEDROW);
|
|
|
|
subscribeToSUIProperty(pid, sui.LISTBOX_LIST, sui.PROP_SELECTEDROW);
|
|
subscribeToSUIProperty(pid, sui.LISTBOX_TITLE, sui.PROP_TEXT);
|
|
|
|
showSUIPage(pid);
|
|
flushSUIPage(pid);
|
|
|
|
return pid;
|
|
}
|
|
|
|
messageHandler handleCloneSuiUpdate()
|
|
{
|
|
if ( (params == null) || (params.isEmpty()) )
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
int pid = utils.getIntScriptVar(self, pclib.VAR_SUI_CLONE);
|
|
int idx = sui.getListboxSelectedRow(params);
|
|
|
|
string prompt = buildCloningPrompt(self, idx);
|
|
|
|
setSUIProperty(pid, sui.LISTBOX_PROMPT, sui.PROP_TEXT, prompt);
|
|
flushSUIPage(pid);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
string buildCloningPrompt(obj_id player, int index)
|
|
{
|
|
string[] options = utils.getStringArrayScriptVar(player, pclib.VAR_REVIVE_OPTIONS);
|
|
location[] cloneLocs = utils.getLocationArrayScriptVar(player, pclib.VAR_REVIVE_CLONE);
|
|
//int[] damageList = utils.getIntArrayScriptVar(player, pclib.VAR_REVIVE_DAMAGE);
|
|
|
|
string prompt = "@base_player:clone_prompt_header ";
|
|
|
|
if (index > -1)
|
|
{
|
|
prompt += "\n\n @base_player:clone_prompt_data ";
|
|
prompt += "\n @base_player:clone_prompt_location "+options[index];
|
|
prompt += "\n @base_player:clone_prompt_distance "+distanceToString(getDistance(player, cloneLocs[index]));
|
|
}
|
|
|
|
return prompt;
|
|
}
|
|
|
|
string distanceToString(float dist)
|
|
{
|
|
string text;
|
|
|
|
//dist = dist / 100f;
|
|
|
|
if (dist < 0)
|
|
{
|
|
text = "@base_player:clone_location_unknown";
|
|
}
|
|
else if (dist < 1000)
|
|
{
|
|
text = ""+(int)dist+"m";
|
|
}
|
|
else
|
|
{
|
|
text = ""+(int)(dist/1000f)+"km";
|
|
}
|
|
|
|
return text;
|
|
}
|
|
|
|
messageHandler handleCloningDataUpdate()
|
|
{
|
|
obj_id facilityId = params.getObjId("faciltyId");
|
|
location facilityLoc = params.getLocation("facilityLoc");
|
|
location spawnLoc = params.getLocation("spawnLoc");
|
|
string cloneName = params.getString("cloneName");
|
|
|
|
setObjVar(self, cloninglib.VAR_BIND_FACILITY, facilityId);
|
|
setObjVar(self, cloninglib.VAR_BIND_LOCATION, facilityLoc);
|
|
setObjVar(self, cloninglib.VAR_BIND_SPAWN_LOC, spawnLoc);
|
|
setObjVar(self, cloninglib.VAR_BIND_CITY_NAME, cloneName);
|
|
|
|
removeObjVar(self, cloninglib.VAR_BIND_FACILITY_TEMPLATE);
|
|
removeObjVar(self, cloninglib.VAR_BIND_FACILITY_CELL);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler clearRecentDeathScriptVar()
|
|
{
|
|
if(utils.hasScriptVar(self, combat.DIED_RECENTLY))
|
|
utils.removeScriptVar(self, combat.DIED_RECENTLY);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleReviveExpirationMessage()
|
|
{
|
|
if(!utils.hasScriptVar(self, pclib.VAR_SUI_CLONE))
|
|
return SCRIPT_CONTINUE;
|
|
|
|
int remaining_time = params.getInt("time");
|
|
int sui_id = params.getInt("sui");
|
|
int next_msg_time = 600;
|
|
|
|
int sui_var = utils.getIntScriptVar(self, pclib.VAR_SUI_CLONE);
|
|
if(sui_id != sui_var)
|
|
return SCRIPT_CONTINUE;
|
|
|
|
prose_package pp = new prose_package();
|
|
pp = prose.setStringId(pp, new string_id("base_player", "revive_exp_msg"));
|
|
|
|
if(remaining_time <= 0)
|
|
{
|
|
sendSystemMessage(self, new string_id("base_player", "revive_expired"));
|
|
forceCloseSUIPage(sui_id);
|
|
|
|
if (space_dungeon.isCloningInstance(self))
|
|
{
|
|
space_dungeon.handleInstanceClone(self);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
location[] cloneLocs = utils.getLocationArrayScriptVar(self, pclib.VAR_REVIVE_CLONE);
|
|
location[] spawnLocs = utils.getLocationArrayScriptVar(self, pclib.VAR_REVIVE_SPAWN);
|
|
|
|
location clone = cloneLocs[0];
|
|
location spawn = spawnLocs[0];
|
|
|
|
if(!pclib.playerRevive(self, clone, spawn, 0))
|
|
{
|
|
messageTo(self, pclib.HANDLER_CLONE_RESPAWN, null, 1, true);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
else if(remaining_time <= 60)
|
|
{
|
|
pp = prose.setStringId(pp, new string_id("base_player", "revive_exp_msg_last"));
|
|
next_msg_time = remaining_time;
|
|
}
|
|
else if(remaining_time <= 300)
|
|
{
|
|
next_msg_time = 120;
|
|
}
|
|
else if(remaining_time <= 600)
|
|
{
|
|
next_msg_time = 300;
|
|
}
|
|
|
|
pp = prose.setTT(pp, player_structure.assembleTimeRemaining(player_structure.convertSecondsTime(remaining_time)));
|
|
sendSystemMessageProse(self, pp);
|
|
|
|
remaining_time -= next_msg_time;
|
|
|
|
dictionary d = new dictionary();
|
|
d.put("time", remaining_time);
|
|
d.put("sui", sui_id);
|
|
|
|
messageTo(self, "handleReviveExpirationMessage", d, (float)next_msg_time, false);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleInstanceClonePause()
|
|
{
|
|
string prompt = "@"+SID_INSTANCE_REVIVE;
|
|
string title = "@"+SID_INSTANCE_REVIVE_TITLE;
|
|
int pid = sui.msgbox(self, self, prompt, sui.OK_ONLY, title, "handleInstanceCloneSelection");
|
|
showSUIPage(pid);
|
|
|
|
utils.setScriptVar(self, pclib.VAR_SUI_CLONE, pid);
|
|
dictionary hrem = new dictionary();
|
|
hrem.put("time", healing.REVIVE_TIMER);
|
|
hrem.put("sui", pid);
|
|
messageTo(self, "handleReviveExpirationMessage", hrem, 0.0f, false);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleInstanceCloneSelection()
|
|
{
|
|
int posture = getPosture(self);
|
|
if ( posture != POSTURE_DEAD )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
//I don't care what button you pushed. You will clone.
|
|
space_dungeon.handleInstanceClone(self);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler showReviveSUI()
|
|
{
|
|
if(utils.hasScriptVar(self, "reviveSUI.pid") )
|
|
{
|
|
int oldpid = utils.getIntScriptVar(self, "reviveSUI.pid");
|
|
sui.closeSUI(self, oldpid);
|
|
utils.removeScriptVar(self, "reviveSUI.pid");
|
|
}
|
|
|
|
|
|
obj_id medic = params.getObjId("medic");
|
|
int weak = params.getInt("weak");
|
|
|
|
string_id reviveSUITitleSID = new string_id("spam", "revive_sui_title");
|
|
prose_package ppPrompt = new prose_package();
|
|
ppPrompt = prose.setStringId(ppPrompt, new string_id("spam", "revive_sui_prompt"));
|
|
ppPrompt = prose.setTT(ppPrompt, medic);
|
|
|
|
if(weak == 0)
|
|
{
|
|
reviveSUITitleSID = new string_id("spam", "revive_sui_title_weak");
|
|
ppPrompt = prose.setStringId(ppPrompt, new string_id("spam", "revive_sui_prompt_weak"));
|
|
}
|
|
|
|
string title = "@" + reviveSUITitleSID;
|
|
|
|
utils.setScriptVar(self, "reviveSUI.medic", medic);
|
|
utils.setScriptVar(self, "reviveSUI.weak", weak);
|
|
|
|
int pid = sui.msgbox(self, self, ppPrompt, sui.YES_NO, title, "handleReviveSUI");
|
|
utils.setScriptVar(self, "reviveSUI.pid", pid);
|
|
|
|
showSUIPage(pid);
|
|
|
|
params.put("pid", pid);
|
|
messageTo(self, "handleReviveSUITimeout", params, 120, false); // Put at 120
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleReviveSUITimeout()
|
|
{
|
|
int pidThisMessageRefersToo = params.getInt("pid");
|
|
|
|
if(utils.hasScriptVar(self, "reviveSUI.pid") )
|
|
{
|
|
int storedPid = utils.getIntScriptVar(self, "reviveSUI.pid");
|
|
|
|
if(storedPid == pidThisMessageRefersToo)
|
|
{
|
|
sui.closeSUI(self, storedPid);
|
|
utils.removeScriptVar(self, "reviveSUI.pid");
|
|
}
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleReviveSUI()
|
|
{
|
|
int bp = sui.getIntButtonPressed(params);
|
|
obj_id medic = utils.getObjIdScriptVar(self, "reviveSUI.medic");
|
|
int weak = utils.getIntScriptVar(self, "reviveSUI.weak");
|
|
|
|
if(bp == sui.BP_OK)
|
|
{
|
|
pclib.clearEffectsForDeath(self);
|
|
int maxHealth = getWoundedMaxAttrib(self, HEALTH);
|
|
int maxAction = getWoundedMaxAttrib(self, ACTION);
|
|
|
|
int actionVal = weak * (maxAction/2);
|
|
int toHeal = (maxHealth / 3) + 1;
|
|
|
|
if(weak == 0)
|
|
toHeal = (maxHealth / 10) + 1;
|
|
|
|
setAttrib(self, HEALTH, toHeal);
|
|
setAttrib(self, ACTION, actionVal);
|
|
setAttrib(self, MIND, 0);
|
|
|
|
utils.removeScriptVar(self, "reviveSUI.weak");
|
|
utils.removeScriptVar(self, "reviveSUI.pid");
|
|
messageTo(self, "handlePlayerResuscitated", null, 0, true);
|
|
}
|
|
else
|
|
{
|
|
prose_package pp = new prose_package();
|
|
pp = prose.setStringId(pp, new string_id("spam", "revive_attempt_denied") );
|
|
pp = prose.setTO(pp, self);
|
|
sendSystemMessageProse(medic, pp);
|
|
|
|
utils.removeScriptVar(self, "reviveSUI.weak");
|
|
utils.removeScriptVar(self, "reviveSUI.medic");
|
|
utils.removeScriptVar(self, "reviveSUI.pid");
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handlePlayerRevive()
|
|
{
|
|
if ( !utils.hasScriptVar(self, pclib.VAR_SUI_CLONE) )
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
utils.removeScriptVar(self, pclib.VAR_SUI_CLONE);
|
|
|
|
location clone = null;
|
|
location spawn = null;
|
|
int damage = cloninglib.CLONE_DAMAGE_HIGH;
|
|
int idx = -1;
|
|
|
|
int delayedClone = 0;
|
|
|
|
if ( params != null )
|
|
{
|
|
idx = sui.getListboxSelectedRow(params);
|
|
|
|
if (idx > -1) //no row selected
|
|
{
|
|
location[] cloneLocs = utils.getLocationArrayScriptVar(self, pclib.VAR_REVIVE_CLONE);
|
|
location[] spawnLocs = utils.getLocationArrayScriptVar(self, pclib.VAR_REVIVE_SPAWN);
|
|
//int[] damageList = utils.getIntArrayScriptVar(self, pclib.VAR_REVIVE_DAMAGE);
|
|
|
|
clone = cloneLocs[idx];
|
|
spawn = spawnLocs[idx];
|
|
//damage = damageList[idx];
|
|
|
|
location deathLoc = getLocation(self);
|
|
|
|
region[] respawnRegions = getRegionsWithPvPAtPoint(deathLoc, regions.PVP_REGION_TYPE_ADVANCED);
|
|
|
|
if((respawnRegions != null && respawnRegions.length > 0) || utils.hasScriptVar(self, "battlefield.active"))
|
|
{
|
|
delayedClone = 15;
|
|
utils.setScriptVar(self, "no_cloning_sickness", 1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sendSystemMessage(self, SID_CLONE_FAIL_SELECTION);
|
|
}
|
|
}
|
|
|
|
if (clone != null && clone.compareTo(new location()) != 0 &&
|
|
spawn != null && spawn.compareTo(new location()) != 0)
|
|
{
|
|
if(delayedClone > 0)
|
|
{
|
|
int gameTime = getGameTime();
|
|
int timeRemaining = delayedClone - (gameTime % delayedClone);
|
|
|
|
int pid = sui.countdownTimerSUI(self, self, "waitingToClone", new string_id("gcw", "static_base_waiting_to_clone"), (delayedClone - timeRemaining), delayedClone, "handleDelayedCloneCancel");
|
|
|
|
if(pid > -1)
|
|
{
|
|
dictionary d = new dictionary();
|
|
d.put("clone", clone);
|
|
d.put("spawn", spawn);
|
|
d.put("damage", damage);
|
|
d.put("id", pid);
|
|
|
|
messageTo(self, "handleDelayedClone", d, timeRemaining, true);
|
|
|
|
utils.setScriptVar(self, "waiting_to_clone", pid);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
}
|
|
else if(pclib.playerRevive(self, clone, spawn, 0))
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
}
|
|
|
|
// Something bad happened try handling the death again
|
|
messageTo(self, pclib.HANDLER_PLAYER_DEATH, null, 0, false);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleDelayedClone()
|
|
{
|
|
if(!utils.hasScriptVar(self, "waiting_to_clone"))
|
|
return SCRIPT_CONTINUE;
|
|
|
|
int pid = utils.getIntScriptVar(self, "waiting_to_clone");
|
|
|
|
int id = params.getInt("id");
|
|
if(pid != id)
|
|
return SCRIPT_CONTINUE;
|
|
|
|
forceCloseSUIPage(pid);
|
|
|
|
location clone = params.getLocation("clone");
|
|
location spawn = params.getLocation("spawn");
|
|
int damage = params.getInt("damage");
|
|
|
|
if (clone != null && clone.compareTo(new location()) != 0 &&
|
|
spawn != null && spawn.compareTo(new location()) != 0)
|
|
{
|
|
pclib.playerRevive(self, clone, spawn, damage);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleDelayedCloneCancel()
|
|
{
|
|
if(!utils.hasScriptVar(self, "waiting_to_clone"))
|
|
return SCRIPT_CONTINUE;
|
|
|
|
utils.removeScriptVar(self, "waiting_to_clone");
|
|
|
|
messageTo(self, pclib.HANDLER_PLAYER_DEATH, null, 0.0f, true);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleCloneRespawn()
|
|
{
|
|
//sendSystemMessageTestingOnly(self, "handleCloneRespawn: entered...");
|
|
|
|
utils.removeScriptVar(self, pclib.VAR_SUI_CLONE);
|
|
utils.removeScriptVar(self, pclib.VAR_REVIVE_OPTIONS);
|
|
utils.removeScriptVar(self, pclib.VAR_REVIVE_CLONE);
|
|
utils.removeScriptVar(self, pclib.VAR_REVIVE_SPAWN);
|
|
//utils.removeScriptVar(self, pclib.VAR_REVIVE_DAMAGE);
|
|
|
|
utils.removeScriptVar(self, "waitingOnCloneRespawn");
|
|
|
|
removeObjVar(self, pclib.VAR_BEEN_COUPDEGRACED);
|
|
|
|
pvpRemoveAllTempEnemyFlags(self);
|
|
|
|
// if the player is in a guild currently involved in guild war,
|
|
// set the player to be in the guild war "cool down" period
|
|
// so he can't participate in guild war pvp for a period of time;
|
|
// this *MUST* be done after the above pvpRemoveAllTempEnemyFlags()
|
|
// call since the guild war "cool down" period is implemented as a
|
|
// temporary enemy flag
|
|
int intGuildId = getGuildId(self);
|
|
if (intGuildId != 0)
|
|
{
|
|
int[] enemies_A_to_B = guildGetEnemies(intGuildId); // guilds I have declared war against
|
|
if (enemies_A_to_B != null && enemies_A_to_B.length > 0)
|
|
{
|
|
int[] enemies_B_to_A = getGuildsAtWarWith(intGuildId); // guilds that have declared war against me
|
|
if (enemies_B_to_A != null && enemies_B_to_A.length > 0)
|
|
{
|
|
for (int i = 0; i < enemies_A_to_B.length; ++i)
|
|
{
|
|
if (guild.findIntTableOffset(enemies_B_to_A, enemies_A_to_B[i]) != -1)
|
|
{
|
|
pvpSetGuildWarCoolDownPeriodEnemyFlag(self);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pclib.checkCovertRespawn(self);
|
|
|
|
pclib.clearEffectsForDeath(self);
|
|
|
|
// Turned off Jedi PvE death penalties (penalty should still exist for Bounty Deaths)
|
|
//if (isJedi(self))
|
|
// if (!(force_rank.isForceRanked(self) && utils.hasScriptVar(self, "jedi.rankedDeath")))
|
|
// jedi.jediDeathExperienceLoss(self);
|
|
|
|
utils.removeScriptVar(self, "jedi.rankedDeath");
|
|
|
|
if ( hasObjVar(self, "fullHealClone") )
|
|
{
|
|
removeObjVar(self, "fullHealClone");
|
|
healing.healClone(self, false);
|
|
}
|
|
else
|
|
{
|
|
healing.healClone(self, true);
|
|
}
|
|
|
|
setPosture(self, POSTURE_UPRIGHT);
|
|
utils.removeScriptVar(self, "pvp_death");
|
|
// send a command to stand so the client will know that we are standing
|
|
queueCommand(self, ##"stand", self, "", COMMAND_PRIORITY_IMMEDIATE);
|
|
|
|
// debugServerConsoleMsg(null, "Playing clone fx now");
|
|
playClientEffectObj(self, "clienteffect/player_clone_compile.cef", self, null);
|
|
|
|
// cloning sickness
|
|
if( !utils.hasScriptVar(self, "no_cloning_sickness") && !instance.isInInstanceArea(self) )
|
|
buff.applyBuff(self, "cloning_sickness");
|
|
else if ( utils.hasScriptVar(self, "no_cloning_sickness") )
|
|
utils.removeScriptVar(self, "no_cloning_sickness");
|
|
|
|
// if declared factional helper, set status to covert factional helper
|
|
if (0 == pvpGetAlignedFaction(self))
|
|
{
|
|
int currentMercenaryFaction = pvpNeutralGetMercenaryFaction(self);
|
|
if ((0 != currentMercenaryFaction) && pvpNeutralIsMercenaryDeclared(self))
|
|
{
|
|
pvpNeutralSetMercenaryFaction(self, currentMercenaryFaction, false);
|
|
}
|
|
}
|
|
|
|
CustomerServiceLog("Death", "(" + self + ") " + getName(self) + " has clone respawned at " + getLocation(self).toString());
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handlePlayerResuscitated()
|
|
{
|
|
int suiClone = utils.getIntScriptVar(self, pclib.VAR_SUI_CLONE);
|
|
LOG("resuscitate","self = " + self + ": clone sui = " + suiClone);
|
|
if ( suiClone > -1 )
|
|
{
|
|
LOG("resuscitate","attempting to force closure of clone sui: sui #" + suiClone);
|
|
forceCloseSUIPage(suiClone);
|
|
}
|
|
|
|
utils.removeScriptVar(self, pclib.VAR_SUI_CLONE);
|
|
utils.removeScriptVar(self, pclib.VAR_REVIVE_OPTIONS);
|
|
pvpRemoveAllTempEnemyFlags(self);
|
|
|
|
removeObjVar(self, pclib.VAR_BEEN_COUPDEGRACED);
|
|
|
|
obj_id medic = utils.getObjIdScriptVar(self, "reviveSUI.medic");
|
|
utils.removeScriptVar(self, "reviveSUI.medic");
|
|
|
|
if(isIdValid(medic))
|
|
{
|
|
prose_package pp = new prose_package();
|
|
pp = prose.setStringId(pp, healing.SID_PERFORM_REVIVE_SUCCESS);
|
|
pp = prose.setTT(pp, medic);
|
|
pp = prose.setTO(pp, self);
|
|
sendSystemMessageProse(medic, pp);
|
|
sendSystemMessageProse(self, pp);
|
|
}
|
|
else
|
|
{
|
|
sendSystemMessage(self, new string_id("healing", "perform_revive_success_self_only"));
|
|
}
|
|
|
|
//This was added to avoid players using vehicles inside the
|
|
//quarantine zone when revived.
|
|
if(hasObjVar(self, "outbreak.usedGate"))
|
|
{
|
|
buff.applyBuff(self, "death_troopers_no_vehicle");
|
|
}
|
|
|
|
setPosture(self, POSTURE_UPRIGHT);
|
|
utils.removeScriptVar(self, "pvp_death");
|
|
|
|
CustomerServiceLog("Death", "(" + self + ") " + getName(self) + " has been resuscitated at " + getLocation(self).toString());
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleReviveStand()
|
|
{
|
|
setPosture(self, POSTURE_UPRIGHT);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleInstanceRessurect()
|
|
{
|
|
pclib.resurrectPlayer(self, true);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
messageHandler handleDecayReport()
|
|
{
|
|
utils.removeScriptVarTree(self, "decayReport");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleRepairItems()
|
|
{
|
|
obj_id[] repairList = params.getObjIdArray("items");
|
|
cloninglib.repairItems(self, repairList);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
|
|
//************* INSURANCE MESSAGEHANDLERS ***********************/
|
|
|
|
// DEPRECATED - No more insurance
|
|
/*
|
|
messageHandler handleFinalizeBatchInsure()
|
|
{
|
|
if ( (params == null) || (params.isEmpty()) )
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
int retVal = money.getReturnCode(params);
|
|
|
|
int now = params.getInt(money.DICT_OTHER);
|
|
string basepath = pclib.VAR_TO_INSURE + "." + now;
|
|
|
|
if ( retVal == money.RET_SUCCESS )
|
|
{
|
|
// if ( !hasObjVar(self, basepath) )
|
|
// return SCRIPT_CONTINUE;
|
|
|
|
if ( !utils.hasScriptVar(self, basepath) )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
// resizeable obj_id[] allErrors = new obj_id[0];
|
|
//
|
|
// obj_var_list ovl = getObjVarList(self, basepath);
|
|
// int numItems = ovl.getNumItems();
|
|
//
|
|
// for ( int i = 0; i < numItems; i++ )
|
|
// {
|
|
// string path = basepath + "." + i;
|
|
// obj_id[] items = getObjIdArrayObjVar(self, path);
|
|
// if ( (items == null) || (items.length == 0) )
|
|
// {
|
|
//
|
|
// }
|
|
// else
|
|
// {
|
|
// obj_id[] errors = pclib.insureItem(self, items);
|
|
// if ( (errors != null) && (errors.length > 0) )
|
|
// {
|
|
// allErrors = utils.concatArrays(allErrors, errors);
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
obj_id[] allErrors = new obj_id[0];
|
|
obj_id[] items = utils.getObjIdBatchScriptVar(self, basepath);
|
|
if ( items != null && items.length > 0 )
|
|
{
|
|
allErrors = pclib.insureItem(self, items);
|
|
}
|
|
|
|
|
|
if ( (allErrors == null) || (allErrors.length == 0) )
|
|
{
|
|
sendSystemMessage(self, pclib.SID_INSURE_SUCCESS);
|
|
}
|
|
else
|
|
{
|
|
string title = utils.packStringId(pclib.SID_BULK_INSURE_ERRORS_TITLE);
|
|
string prompt = utils.packStringId(pclib.SID_BULK_INSURE_ERRORS_PROMPT);
|
|
|
|
string[] dsrc = utils.makeNameList(allErrors);
|
|
|
|
sui.listbox(self, prompt, title, dsrc);
|
|
}
|
|
}
|
|
|
|
removeObjVar(self, basepath);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
*/
|
|
|
|
//********* PERSISTANT MESSAGE MESSAGEHANDLERS ****************************
|
|
messageHandler handleChatPersistentMessage()
|
|
{
|
|
if(params == null)
|
|
return SCRIPT_OVERRIDE;
|
|
|
|
String from = params.getString("from");
|
|
if(from == null)
|
|
return SCRIPT_OVERRIDE;
|
|
|
|
String subject = params.getString("subject");
|
|
if(subject == null)
|
|
return SCRIPT_OVERRIDE;
|
|
|
|
String message = params.getString("message");
|
|
if(message == null)
|
|
return SCRIPT_OVERRIDE;
|
|
|
|
String outOfBand = params.getString("outofband"); // This is allowed to be null
|
|
|
|
String avatarName = getChatName(self);
|
|
if(avatarName == null)
|
|
return SCRIPT_OVERRIDE;
|
|
|
|
chatSendPersistentMessage(from, avatarName, subject, message, outOfBand);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
/***** COMMANDHANDLERS *************************************************/
|
|
/***** MISC CMDS *************************************************/
|
|
commandHandler gmRevive()
|
|
{
|
|
target = self;
|
|
params = toLower(params);
|
|
if ( params.equals("-target") )
|
|
{
|
|
target = getLookAtTarget(self);
|
|
}
|
|
|
|
if (isIdValid(target))
|
|
{
|
|
obj_id targetCreature = null;
|
|
obj_id targetShip = null;
|
|
int got = getGameObjectType(target);
|
|
if (isGameObjectTypeOf(got, GOT_ship))
|
|
{
|
|
targetShip = target;
|
|
targetCreature = getShipPilot(target);
|
|
}
|
|
else if (isGameObjectTypeOf(got, GOT_creature))
|
|
{
|
|
targetShip = getPilotedShip(target);
|
|
targetCreature = target;
|
|
}
|
|
|
|
if (!isIdValid(targetShip) && !isIdValid(targetCreature))
|
|
{
|
|
sendSystemMessageTestingOnly(self, "The /gmRevive command may only be used on creature or ship type objects");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
if (isIdValid(targetShip))
|
|
{
|
|
// repair to full with no decay
|
|
space_crafting.repairDamage(targetCreature, targetShip, 1.f, 0.f);
|
|
|
|
if(isShipSlotInstalled(targetShip, ship_chassis_slot_type.SCST_shield_0))
|
|
{
|
|
setShipShieldHitpointsFrontCurrent(targetShip, getShipShieldHitpointsFrontMaximum(targetShip));
|
|
setShipShieldHitpointsBackCurrent(targetShip, getShipShieldHitpointsBackMaximum(targetShip));
|
|
}
|
|
|
|
if (isIdValid(targetCreature))
|
|
sendSystemMessageTestingOnly(targetCreature, "Ship Repaired.");
|
|
|
|
CustomerServiceLog("Death", "(" + targetShip + ") " + getName(targetShip) + " has been /gmRevive'd at " + getLocation(self).toString() + " by (" + self + ") " + getName(self));
|
|
}
|
|
|
|
if (isIdValid(targetCreature))
|
|
{
|
|
// Handle a mounted rider: auto-dismount. Parts of /gmRevive set state that breaks mounts.
|
|
// @todo: fix up the parts of this call chain that break mounts and allow a rider to be /gmrevived.
|
|
obj_id mountId = getMountId(targetCreature);
|
|
if (isIdValid(mountId))
|
|
utils.dismountRiderJetpackCheck(targetCreature);
|
|
|
|
if (isJedi(targetCreature))
|
|
{
|
|
setForcePower(targetCreature, getMaxForcePower(targetCreature));
|
|
sendSystemMessageTestingOnly(targetCreature, "Force Power Maxed");
|
|
}
|
|
if (pclib.resurrectPlayer(targetCreature))
|
|
{
|
|
sendSystemMessageTestingOnly(targetCreature, "You have been restored...");
|
|
|
|
if (isPlayer(targetCreature))
|
|
{
|
|
pclib.clearCombatData(targetCreature);
|
|
buff.removeAllBuffs(targetCreature, true);
|
|
|
|
removeObjVar(targetCreature, "combat.intIncapacitationCount");
|
|
|
|
setPosture(targetCreature, POSTURE_UPRIGHT);
|
|
queueCommand(targetCreature, ##"stand", targetCreature, "", COMMAND_PRIORITY_IMMEDIATE);
|
|
queueCommand(targetCreature, ##"stopCraftingSession", targetCreature, "", COMMAND_PRIORITY_IMMEDIATE);
|
|
utils.removeScriptVar(targetCreature, "pvp_death");
|
|
|
|
sendSystemMessageTestingOnly(self, "You have /gmRevived "+getName(targetCreature));
|
|
}
|
|
}
|
|
}
|
|
|
|
CustomerServiceLog("Death", "(" + targetCreature + ") " + getName(targetCreature) + " has been /gmRevive'd at " + getLocation(self).toString() + " by (" + self + ") " + getName(self));
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
commandHandler cmdEat()
|
|
{
|
|
if ( !isIdValid(target) && exists(target) )
|
|
{
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
consumable.consumeItem(self, target);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
commandHandler cmdUseSkillBuff()
|
|
{
|
|
LOG("skillBuff", "cmdUseSkillBuff");
|
|
if ( !isIdValid(target) && exists(target) )
|
|
{
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
dictionary childparams = new dictionary();
|
|
childparams.put("player", self);
|
|
messageTo( target, "handleUseSkillBuff", childparams, 1f, true );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Tip handler.
|
|
commandHandler cmdTip()
|
|
{
|
|
// Display the command syntax.
|
|
if ( (params == null) || (params.equals("")) )
|
|
{
|
|
showTipSyntax(self);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Disallow tipping in the tutorial level.
|
|
location here = getLocation(self);
|
|
if ( (here.area).equals("tutorial") )
|
|
{
|
|
sendSystemMessageTestingOnly( self, "You cannot use this command from within the tutorial." );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
CustomerServiceLog( "Trade", "Tip Invoked -- Self: " + self + " Target: " + target + " Params: " + params );
|
|
|
|
// Clean up tip UI.
|
|
if ( params.equals("clear") )
|
|
{
|
|
CustomerServiceLog( "Trade", " Tip -- Self: " + self + " " + getName(self) + " -- User requested tip data clear." );
|
|
sendSystemMessage( self, pclib.SID_TIP_CLEAR );
|
|
pclib.cleanupTipSui( self );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Close previous tip attempt.
|
|
if ( utils.hasScriptVar(self, pclib.VAR_TIP_SUI) )
|
|
{
|
|
int suiConfirm = utils.getIntScriptVar( self, pclib.VAR_TIP_SUI );
|
|
forceCloseSUIPage( suiConfirm );
|
|
|
|
obj_id oldTarget = utils.getObjIdScriptVar( self, pclib.VAR_TIP_TARGET );
|
|
if ( isIdValid(oldTarget) && exists(oldTarget) && oldTarget.isLoaded() )
|
|
{
|
|
prose_package tipAbort = prose.getPackage( pclib.PROSE_TIP_ABORT, oldTarget );
|
|
sendSystemMessageProse( self, tipAbort );
|
|
}
|
|
else
|
|
{
|
|
sendSystemMessage( self, pclib.SID_TIP_ABORT );
|
|
}
|
|
|
|
CustomerServiceLog( "Trade", " Tip -- Self: " + self + " " + getName(self) + " -- Cancelled prior tip due to new tip attempt." );
|
|
pclib.cleanupTipSui( self );
|
|
}
|
|
|
|
// We can't target ourselves.
|
|
if ( target == self )
|
|
{
|
|
CustomerServiceLog( "Trade", " Tip -- Self: " + self + " " + getName(self) + " -- Tip aborted: (target == self)" );
|
|
sendSystemMessageTestingOnly( self, "You can't use yourself as a target for /tip!" );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Check to see if we should tip from the bank.
|
|
boolean useCash = true;
|
|
if ( params.indexOf("bank") > -1 )
|
|
{
|
|
params = gm.removeKeyword( params, "bank" );
|
|
useCash = false;
|
|
}
|
|
|
|
// Parse params.
|
|
java.util.StringTokenizer st = new java.util.StringTokenizer(params);
|
|
int amt = 0;
|
|
string name = null;
|
|
int cnt = st.countTokens();
|
|
switch ( cnt )
|
|
{
|
|
case 1:
|
|
if ( !isIdValid(target) )
|
|
{
|
|
showTipSyntax(self);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
name = st.nextToken();
|
|
break;
|
|
|
|
default:
|
|
showTipSyntax(self);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
boolean areMoreTokens = st.hasMoreTokens();
|
|
if ( areMoreTokens )
|
|
{
|
|
string sAmt = st.nextToken();
|
|
amt = utils.stringToInt(sAmt);
|
|
if ( amt < 1 )
|
|
{
|
|
prose_package invalidParam = prose.getPackage( pclib.PROSE_INVALID_TIP_PARAM, sAmt );
|
|
sendSystemMessageProse( self, invalidParam );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
if ( (name == null) || (name.equals("")) )
|
|
pclib.giveTip( self, target, getName(target), amt, useCash );
|
|
else
|
|
{
|
|
obj_id playerId = getPlayerIdFromFirstName( name );
|
|
if ( isIdValid(playerId) )
|
|
pclib.giveTip( self, playerId, name, amt, useCash );
|
|
}
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
commandHandler cmdTipFail()
|
|
{
|
|
sendSystemMessageTestingOnly(self, "/TIP command failed in command table...");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
commandHandler cmdCheckForceStatus()
|
|
{
|
|
/* COMMENTED OUT
|
|
//LOG("quest", "base_player.checkForceStatus");
|
|
int progress_level = 0;
|
|
if (fs_quests.fsBadgeCheck(self))
|
|
progress_level = 5;
|
|
else
|
|
{
|
|
string config = getConfigSetting("GameServer", "fsQuestJediPrereqs");
|
|
int min_prereqs = utils.stringToInt(config);
|
|
//LOG("quest", "min_prereq ->" + min_prereqs);
|
|
int skills_complete = 8;
|
|
if (min_prereqs > 0)
|
|
{
|
|
if (hasObjVar(self, pclib.OBJVAR_JEDI_SKILL_REQUIREMENTS))
|
|
{
|
|
skills_complete = 8 - getStringArrayObjVar(self, pclib.OBJVAR_JEDI_SKILL_REQUIREMENTS).length;
|
|
int diff = min_prereqs - skills_complete;
|
|
|
|
if (diff == 1)
|
|
progress_level = 4;
|
|
else if (diff == 2)
|
|
progress_level = 3;
|
|
else if (diff == 3)
|
|
progress_level = 2;
|
|
else if (diff == 4)
|
|
progress_level = 1;
|
|
}
|
|
}
|
|
|
|
if (progress_level == 0 || skills_complete < 3)
|
|
{
|
|
progress_level = 0;
|
|
if (utils.getIntScriptVar(self, "jediBadges") >= 3)
|
|
progress_level++;
|
|
if (utils.getIntScriptVar(self, "explorerBadges") >= 5)
|
|
progress_level++;
|
|
if (utils.getIntScriptVar(self, "contentBadges") >= 5)
|
|
progress_level++;
|
|
if (utils.getIntScriptVar(self, "totalBadges") >= 5)
|
|
progress_level++;
|
|
}
|
|
|
|
if (isJedi(self))
|
|
progress_level = 5;
|
|
}
|
|
|
|
sendSystemMessage(self, new string_id("jedi_spam", "fs_progress_" + progress_level));
|
|
*/
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Handler for the "You will be charged 5% for bank-to-bank" dialog.
|
|
messageHandler handleWireConfirm()
|
|
{
|
|
// See if the player canceled.
|
|
int bp = sui.getIntButtonPressed(params);
|
|
if ( bp == sui.BP_CANCEL )
|
|
{
|
|
CustomerServiceLog( "Trade", " Tip -- Player: " + self + " " + getName(self) + " -- Tip aborted: Bank-to-Bank transfer canceled by player's request." );
|
|
pclib.cleanupTipSui( self );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Make sure our target is still valid.
|
|
obj_id target = utils.getObjIdScriptVar( self, pclib.VAR_TIP_TARGET );
|
|
if ( !isIdValid(target) )
|
|
{
|
|
sendSystemMessage( self, pclib.SID_TIP_ERROR );
|
|
CustomerServiceLog( "Trade", " Tip -- Player: " + self + " " + getName(self) + " Target: " + target + " -- Tip aborted: Target was invalid after tip fee dialog was accepted." );
|
|
pclib.cleanupTipSui( self );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Calculate how much to send, including fee.
|
|
int amt = utils.getIntScriptVar( self, pclib.VAR_TIP_AMT );
|
|
int fee = (int)(amt * pclib.TIP_WIRE_SURCHARGE);
|
|
if ( fee < 1 )
|
|
fee = 1;
|
|
int total = amt + fee;
|
|
|
|
string targetName = utils.getStringScriptVar( self, pclib.VAR_TIP_TARGET_NAME );
|
|
if ( getBankBalance(self) < total )
|
|
{
|
|
// The player couldn't afford the tip fee.
|
|
CustomerServiceLog( "Trade", " Tip -- Player: " + self + " " + getName(self) + " Target: " + target + " -- Tip aborted: Player couldn't afford the wire fee." );
|
|
|
|
prose_package nsfWire = prose.getPackage( pclib.PROSE_TIP_NSF_WIRE, self, getName(self), null, target, targetName, null, null, null, null, total, 0f );
|
|
sendSystemMessageProse( self, nsfWire );
|
|
}
|
|
else
|
|
{
|
|
dictionary d = new dictionary();
|
|
d.put("target", target);
|
|
d.put("amt", amt);
|
|
d.put("useCash", false);
|
|
d.put("targetName", targetName);
|
|
|
|
// Transfer the amount to escrow acct.
|
|
CustomerServiceLog( "Trade", " Tip -- Player: " + self + " " + getName(self) + " Target: " + target + " -- Transferring wire bank money to escrow account! Amt: " + amt );
|
|
transferBankCreditsToNamedAccount( self, money.ACCT_TIP_ESCROW, amt, "handleTipSuccess", "handleTipFail", d );
|
|
|
|
if (utils.isFreeTrial(self, target))
|
|
pclib.doTipLogging(self, target, amt);
|
|
|
|
// Transfer the fee to surcharge acct.
|
|
CustomerServiceLog( "Trade", " Tip -- Player: " + self + " " + getName(self) + " Target: " + target + " -- Transferring wire bank fee to surcharge account! Amt: " + fee );
|
|
transferBankCreditsToNamedAccount( self, money.ACCT_TIP_SURCHARGE, fee, "noHandler", "noHandler", d );
|
|
|
|
// Track the fee money leaving the system.
|
|
utils.moneyOutMetric( self, money.ACCT_TIP_SURCHARGE, fee );
|
|
}
|
|
|
|
// Clean up.
|
|
pclib.cleanupTipSui( self );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Handler for tip native money transfer function calls.
|
|
messageHandler handleTipSuccess()
|
|
{
|
|
string myName = getName(self);
|
|
obj_id po = getPlayerObject(self);
|
|
|
|
CustomerServiceLog( "Trade", " Tip -- Player: " + self + " " + getName(self) + " -- Handling a successful transfer." );
|
|
|
|
// Make sure the target is still valid.
|
|
obj_id target = params.getObjId("target");
|
|
if ( params == null || params.isEmpty() || !isIdValid(target) )
|
|
{
|
|
CustomerServiceLog( "Trade", " Tip -- Player: " + self + " " + getName(self) + " -- Error! Can't handle successful tip transfer! The target data is invalid." );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Peel off our params.
|
|
int amt = params.getInt("amt");
|
|
boolean useCash = params.getBoolean("useCash");
|
|
string targetName = params.getString("targetName");
|
|
params.put( "actor", self );
|
|
params.put( "actorName", myName );
|
|
obj_id tpo = getPlayerObject( target );
|
|
|
|
if ( useCash )
|
|
{
|
|
// Notify the player and target of a successful cash transfer.
|
|
prose_package toSelf = prose.getPackage( pclib.PROSE_TIP_PASS_SELF, target, amt );
|
|
sendSystemMessageProse( self, toSelf );
|
|
prose_package toTarget = prose.getPackage( pclib.PROSE_TIP_PASS_TARGET, self, amt );
|
|
sendSystemMessageProse( target, toTarget );
|
|
|
|
CustomerServiceLog( "Trade", " Tip -- Player: " + self + " " + getName(self) + " Target: " + target + " " + getName(target) + " -- Cash tip transfer successfully completed. Amt: " + amt );
|
|
}
|
|
else
|
|
{
|
|
CustomerServiceLog( "Trade", " Tip -- Player: " + self + " " + getName(self) + " Target: " + target + " " + getName(target) + " -- Bank->Escrow wire transfer complete. Telling target to request escrow funds. Amt: " + amt );
|
|
messageTo( target, "handleTipEscrowRequest", params, 1f, true );
|
|
prose_package bankToEscrow = prose.getPackage( new string_id( "base_player", "bank_to_escrow" ), targetName, amt );
|
|
sendSystemMessageProse( self, bankToEscrow );
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Called on the target, to get the money out of the escrow account.
|
|
messageHandler handleTipEscrowRequest()
|
|
{
|
|
int amt = params.getInt("amt");
|
|
obj_id player = params.getObjId("actor");
|
|
string playerName = params.getString("actorName");
|
|
CustomerServiceLog( "Trade", " Tip -- Player: " + player + " " + playerName + " Target: " + self + " " + getName(self) + " -- Target is now requesting funds from the escrow account. Amt: " + amt );
|
|
|
|
if ( amt >= 1 && amt <= 1000000 )
|
|
{
|
|
boolean success = transferBankCreditsFromNamedAccount( money.ACCT_TIP_ESCROW, self, amt, "handleTipEscrowPass", "handleTipEscrowFail", params );
|
|
if ( !success )
|
|
{
|
|
// We failed for some reason.
|
|
CustomerServiceLog( "Trade", " Tip -- Player: " + player + " " + playerName + " Target: " + self + " -- Tip aborted: Unable to transfer money from bank to escrow. Amt: " + amt );
|
|
|
|
// Attempt to refund the money.
|
|
refundEscrow( player, playerName, self, getName(self), amt );
|
|
}
|
|
}
|
|
else
|
|
CustomerServiceLog( "Trade", " Tip -- Player: " + player + " " + playerName + " Target: " + self + " " + getName(self) + " -- Target was unable to request tip funds from escrow because the amount is invalid! Amt: " + amt );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Called if we successfully pulled the money out of escrow.
|
|
messageHandler handleTipEscrowPass()
|
|
{
|
|
obj_id actor = params.getObjId("actor");
|
|
string actorName = params.getString("actorName");
|
|
|
|
obj_id target = params.getObjId("target");
|
|
string targetName = params.getString("targetName");
|
|
|
|
if ( !isIdValid(actor) || !isIdValid(target) || targetName == null || actorName == null )
|
|
{
|
|
CustomerServiceLog( "Trade", " Tip -- Player: " + actor + " " + actorName + " Target: " + target + " " + getName(target) + " -- Unable to handle successful transfer Escrow->Bank because of bad parameters." );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
int amt = params.getInt("amt");
|
|
boolean useCash = params.getBoolean("useCash");
|
|
|
|
CustomerServiceLog( "Trade", " Tip -- Player: " + actor + " " + actorName + " Target: " + target + " " + getName(target) + " -- Target successfully withdrew the money from escrow. Wire transfer complete. Amt: " + amt );
|
|
|
|
// Send emails to the players involved that the bank transfer was a success.
|
|
prose_package bodyToTarget = prose.getPackage( pclib.PROSE_WIRE_MAIL_TARGET, actorName, amt );
|
|
utils.sendMail( pclib.SID_WIRE_MAIL_SUBJECT, bodyToTarget, targetName, "@money/acct_n:bank" );
|
|
prose_package bodyToSelf = prose.getPackage( pclib.PROSE_WIRE_MAIL_SELF, targetName, amt );
|
|
utils.sendMail( pclib.SID_WIRE_MAIL_SUBJECT, bodyToSelf, actorName, targetName );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Called if we fail to pull the money out of escrow.
|
|
messageHandler handleTipEscrowFail()
|
|
{
|
|
obj_id actor = params.getObjId("actor");
|
|
string actorName = params.getString("actorName");
|
|
|
|
obj_id target = params.getObjId("target");
|
|
string targetName = params.getString("targetName");
|
|
|
|
if ( !isIdValid(actor) || !isIdValid(target) || targetName == null || actorName == null )
|
|
{
|
|
CustomerServiceLog( "Trade", " Tip -- Player: " + actor + " " + actorName + " Target: " + target + " " + getName(target) + " -- Unable to handle FAILED transfer Escrow->Bank because of bad parameters." );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
int amt = params.getInt("amt");
|
|
boolean useCash = params.getBoolean("useCash");
|
|
|
|
CustomerServiceLog( "Trade", " Tip -- Player: " + actor + " " + actorName + " Target: " + target + " " + getName(target) + " -- Target failed to withdraw the money from escrow! Wire transfer FAILED! Attempting to refund. Amt: " + amt );
|
|
|
|
prose_package escrowFailed = prose.getPackage( new string_id("base_player", "escrow_withdraw_failed"), actorName, amt );
|
|
utils.sendMail( pclib.SID_WIRE_MAIL_SUBJECT, escrowFailed, targetName, actorName );
|
|
|
|
// Attempt to refund the money.
|
|
refundEscrow( actor, actorName, target, targetName, amt );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Spawn an escrow refund request. This is sent from the tip target.
|
|
void refundEscrow( obj_id player, string playerName, obj_id target, string targetName, int amt )
|
|
{
|
|
// Send a message back to the sending player that they can get a refund.
|
|
dictionary params = new dictionary();
|
|
params.put( "player", player );
|
|
params.put( "playerName", playerName );
|
|
params.put( "target", target );
|
|
params.put( "targetName", targetName );
|
|
params.put( "amt", amt );
|
|
messageTo( player, "handleTipRefundRequest", params, 1f, true );
|
|
}
|
|
|
|
// Handled on the person who sent the tip. Tries to get a refund from escrow.
|
|
messageHandler handleTipRefundRequest()
|
|
{
|
|
obj_id player = params.getObjId( "player" );
|
|
string playerName = params.getString( "playerName" );
|
|
obj_id target = params.getObjId( "target" );
|
|
string targetName = params.getString( "targetName" );
|
|
int amt = params.getInt( "amt" );
|
|
|
|
if ( amt < 1 || amt > 1000000 )
|
|
{
|
|
CustomerServiceLog( "Trade", " Tip -- Player: " + player + " " + playerName + " Target: " + target + " " + targetName + " -- Unable to refund escrow because the amount is invalid! Amt:" + amt );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// The target failed to receive the money from escrow. Try to refund the money.
|
|
boolean success = transferBankCreditsFromNamedAccount( money.ACCT_TIP_ESCROW, player, amt, "handleTipRefundPass", "handleTipRefundFail", params );
|
|
CustomerServiceLog( "Trade", " Tip -- Player: " + player + " " + playerName + " Target: " + target + " " + targetName + " -- Calling transferBankCreditsFromNamedAccount to transfer refund from escrow. Amt:" + amt );
|
|
if ( !success )
|
|
{
|
|
// We couldn't refund the money!
|
|
CustomerServiceLog( "Trade", " Tip -- Player: " + player + " " + playerName + " Target: " + target + " " + targetName + " -- transferBankCreditsFromNamedAccount failed immediately while attempting to refund escrow! Amt:" + amt );
|
|
notifyFailedRefund( player, playerName, target, targetName, amt );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Called on the person who sent the tip, if the money didn't arrive and they got a refund.
|
|
messageHandler handleTipRefundPass()
|
|
{
|
|
obj_id player = params.getObjId( "player" );
|
|
string playerName = params.getString( "playerName" );
|
|
obj_id target = params.getObjId( "target" );
|
|
string targetName = params.getString( "targetName" );
|
|
int amt = params.getInt( "amt" );
|
|
|
|
// Email the player that they got a refund.
|
|
prose_package refundToSelf = prose.getPackage( new string_id("base_player","received_escrow_refund"), targetName, amt );
|
|
utils.sendMail( pclib.SID_WIRE_MAIL_SUBJECT, refundToSelf, playerName, targetName );
|
|
CustomerServiceLog( "Trade", " Tip -- Player: " + player + " " + playerName + " Target: " + target + " " + targetName + " -- Refund successfully delivered. Amt:" + amt );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Called on the person who sent the tip, if the refund didn't make it!
|
|
messageHandler handleTipRefundFail()
|
|
{
|
|
obj_id player = params.getObjId( "player" );
|
|
string playerName = params.getString( "playerName" );
|
|
obj_id target = params.getObjId( "target" );
|
|
string targetName = params.getString( "targetName" );
|
|
int amt = params.getInt( "amt" );
|
|
|
|
notifyFailedRefund( player, playerName, target, targetName, amt );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Called to send the email that the refund failed.
|
|
void notifyFailedRefund( obj_id player, string playerName, obj_id target, string targetName, int amt )
|
|
{
|
|
CustomerServiceLog( "Trade", " Tip -- Player: " + player + " " + playerName + " Target: " + target + " " + targetName + " -- Failed to refund player from escrow account! Amt:" + amt );
|
|
prose_package refundToSelf = prose.getPackage( new string_id("base_player","failed_escrow_refund"), targetName, amt );
|
|
utils.sendMail( pclib.SID_WIRE_MAIL_SUBJECT, refundToSelf, playerName, targetName );
|
|
}
|
|
|
|
// Called if we fail to transfer cash or money to escrow.
|
|
messageHandler handleTipFail()
|
|
{
|
|
CustomerServiceLog( "Trade", " Tip -- Player: " + self + " " + getName(self) + " -- Tip cash transfer or bank wire escrow transfer failed!" );
|
|
|
|
utils.removeScriptVar( self, pclib.VAR_TIP_SUI );
|
|
utils.removeScriptVar( self, pclib.VAR_TIP_TARGET );
|
|
utils.removeScriptVar( self, pclib.VAR_TIP_AMT );
|
|
|
|
obj_id target = params.getObjId("target");
|
|
if ( !isIdValid(target) )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
if ( !exists(target) || !target.isLoaded() )
|
|
{
|
|
sendSystemMessage( self, pclib.SID_TIP_ERROR );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
int amt = params.getInt("amt");
|
|
boolean useCash = params.getBoolean("useCash");
|
|
if ( useCash )
|
|
{
|
|
CustomerServiceLog( "Trade", " Tip -- Player: " + self + " " + getName(self) + " Target: " + target + " " + getName(target) + " -- Cash transfer failed in transferCashTo! Amt: " + amt );
|
|
prose_package nsfCash = prose.getPackage( pclib.PROSE_TIP_NSF_CASH, target, amt );
|
|
sendSystemMessageProse( self, nsfCash );
|
|
}
|
|
else
|
|
{
|
|
CustomerServiceLog( "Trade", " Tip -- Player: " + self + " " + getName(self) + " Target: " + target + " " + getName(target) + " -- Bank->Escrow transfer failed in transferBankCreditsToNamedAccount! Amt: " + amt );
|
|
prose_package nsfBank = prose.getPackage( pclib.PROSE_TIP_NSF_BANK, target, amt );
|
|
sendSystemMessageProse( self, nsfBank );
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
void showTipSyntax(obj_id self)
|
|
{
|
|
sendSystemMessage(self, pclib.SID_TIP_SYNTAX);
|
|
}
|
|
|
|
/***** CONTAINER & LOOTING CMDS ***********************************/
|
|
commandHandler cmdOpenFail()
|
|
{
|
|
if (!isIdValid(target))
|
|
{
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
prose_package pp = prose.getPackage(SID_CMD_OPEN_FAIL, target);
|
|
sendSystemMessageProse(self, pp);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
commandHandler cmdLoot()
|
|
{
|
|
obj_id player = self;
|
|
|
|
if ( !isIdValid(target) )
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
if ( !isMob(target) )
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
if ( !isIncapacitated(target) )
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
if ( isIncapacitated(self))
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
if ( pet_lib.isPet (target))
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
int got = getGameObjectType(target);
|
|
if ( got == GOT_corpse )
|
|
{
|
|
queueCommand(self, ##"lootPlayerCorpse", target, "", COMMAND_PRIORITY_DEFAULT);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
|
|
if ( isMob(target) && !isPlayer (target))
|
|
{
|
|
if (group.isGrouped(self))
|
|
{
|
|
obj_id team = getGroupObject (self);
|
|
int lootRule = getGroupLootRule(team);
|
|
|
|
if (lootRule == 3)
|
|
{
|
|
if (hasObjVar (target, "autoLootComplete" ))
|
|
{
|
|
obj_id corpseInv = utils.getInventoryContainer(target);
|
|
queueCommand(player, ##"openContainer", corpseInv, "", COMMAND_PRIORITY_DEFAULT);
|
|
}
|
|
|
|
obj_id[] objMembersWhoExist = utils.getLocalGroupMemberIds(team);
|
|
int teamNumber = objMembersWhoExist.length;
|
|
|
|
if (teamNumber > 0)
|
|
{
|
|
int which = rand(0, teamNumber-1);
|
|
player = objMembersWhoExist[which];
|
|
}
|
|
}
|
|
|
|
if (loot.doGroupLootAllCheck(self, target))
|
|
{
|
|
loot.lootAiCorpse(player, target);
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
loot.lootAiCorpse(self, target);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
commandHandler cmdLootPlayer()
|
|
{
|
|
if ( !isIdValid(target) )
|
|
return SCRIPT_OVERRIDE;
|
|
|
|
if ( !utils.isOwner(target, self) && !isGod(self) )
|
|
return SCRIPT_OVERRIDE;
|
|
|
|
int got = getGameObjectType(target);
|
|
if ( got != GOT_corpse )
|
|
return SCRIPT_OVERRIDE;
|
|
|
|
corpse.lootPlayerCorpse(self, target);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
|
|
/***** DEATH CMDS *************************************************/
|
|
commandHandler cmdActivateClone()
|
|
{
|
|
if ( params.equals("now") )
|
|
{
|
|
// Making this a godlevel debug only command. Players should not be able to force cloning in place.
|
|
if (isGod(self))
|
|
{
|
|
if ( utils.hasScriptVar(self, pclib.VAR_SUI_CLONE) )
|
|
{
|
|
int cloneSui = utils.getIntScriptVar(self, pclib.VAR_SUI_CLONE);
|
|
utils.removeScriptVar(self, pclib.VAR_SUI_CLONE);
|
|
forceCloseSUIPage(cloneSui);
|
|
}
|
|
|
|
if ( !pclib.playerRevive(self) )
|
|
{
|
|
// This should not be sent on fail. Why force an additional respawn if pclib.playerRevive fails? (ie, player not dead.)
|
|
//messageTo(self, pclib.HANDLER_CLONE_RESPAWN, null, 1, true);
|
|
sendSystemMessageTestingOnly(self, "You may only use this command to force a clone spawn if you are dead.");
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
}
|
|
|
|
if ( utils.hasScriptVar(self, pclib.VAR_SUI_CLONE) )
|
|
{
|
|
sendSystemMessageTestingOnly(self, "You already have a cloning options menu open!");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
if ( !isDead(self) )
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageTo(self, pclib.HANDLER_PLAYER_DEATH, null, 0, false);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
commandHandler cmdActivateCloneFail()
|
|
{
|
|
sendSystemMessageTestingOnly(self, "You may only use this command to activate the cloning options menu if you are dead.");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
commandHandler cmdSetBind()
|
|
{
|
|
//SYNTAX /clone
|
|
if (!isIdValid(target))
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
int got = getGameObjectType(target);
|
|
if ( got != GOT_terminal_cloning )
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
cloninglib.requestBind(self, target);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
|
|
boolean canDeathBlow(obj_id killer, obj_id victim)
|
|
{
|
|
|
|
if ( (!isIdValid(victim)) || (!isPlayer(victim)) )
|
|
{
|
|
debugServerConsoleMsg(killer, "cmdCoupDeGrace: (" + victim + ")target is not player or is not incapacitated!!");
|
|
combat.sendCombatSpamMessage(killer, new string_id("cbt_spam", "invalid_target"));
|
|
showFlyTextPrivate(killer, killer, new string_id("combat_effects", "target_invalid_fly"), 1.5f, colors.WHITE);
|
|
return false;
|
|
}
|
|
|
|
|
|
if ( !pvpCanAttack(killer, victim) )
|
|
{
|
|
showFlyTextPrivate(killer, killer, new string_id("combat_effects", "target_invalid_fly"), 1.5f, colors.WHITE);
|
|
combat.sendCombatSpamMessage(killer, new string_id("cbt_spam", "invalid_pvp_target"));
|
|
return false;
|
|
}
|
|
|
|
|
|
if (isIncapacitated(victim))
|
|
{
|
|
if ( hasObjVar(victim, pclib.VAR_BEEN_COUPDEGRACED) )
|
|
{
|
|
combat.sendCombatSpamMessage(killer, new string_id("cbt_spam", "invalid_target"));
|
|
showFlyTextPrivate(killer, killer, new string_id("combat_effects", "target_invalid_fly"), 1.5f, colors.WHITE);
|
|
return false;
|
|
}
|
|
location myPos = getLocation(killer);
|
|
location targetPos = getLocation(victim);
|
|
if ( myPos != null && targetPos != null)
|
|
{
|
|
float distance = myPos.distance(targetPos);
|
|
float maxDistance = getCommandMaxRange(##"coupDeGrace");
|
|
debugServerConsoleMsg(null, "Deathblow distance to target ");
|
|
if (distance < maxDistance)
|
|
{
|
|
//if you try to deathblow, you get the uncovered
|
|
stealth.checkForAndMakeVisibleNoRecourse(killer);
|
|
//HERE ARE CHECKS TO ENSURE THE KILLER IS STILL ABLE TO DO THIS:
|
|
if ( isIncapacitated(killer) || isDead(killer) )
|
|
return false;//you died or got incapped, so you are done.
|
|
|
|
if (getState(killer, STATE_FEIGN_DEATH) == 1)
|
|
return false;//you're busy doing that now.
|
|
|
|
|
|
int killerPosture = getPosture( killer );
|
|
if ( killerPosture == POSTURE_KNOCKED_DOWN )
|
|
return false;//Oh! Knocked down!
|
|
|
|
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
showFlyTextPrivate(killer, killer, new string_id("combat_effects", "range_too_far"), 1.5f, colors.MEDIUMTURQUOISE);
|
|
combat.sendCombatSpamMessage(killer, new string_id("cbt_spam", "out_of_range_far"), COMBAT_RESULT_OUT_OF_RANGE);
|
|
|
|
CustomerServiceLog("Pvp", "Player %TU received deathblow message for target %TT, but has moved too "+
|
|
"far away (" + distance + ")", killer, victim);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
combat.sendCombatSpamMessage(killer, new string_id("cbt_spam", "invalid_target"));
|
|
|
|
showFlyTextPrivate(killer, killer, new string_id("combat_effects", "target_invalid_fly"), 1.5f, colors.WHITE);
|
|
CustomerServiceLog("Pvp", "Player %TU received deathblow message for target %TT, but we could "+
|
|
"not get the player's positions", killer, victim);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
combat.sendCombatSpamMessage(killer, new string_id("cbt_spam", "invalid_target"));
|
|
showFlyTextPrivate(killer, killer, new string_id("combat_effects", "target_invalid_fly"), 1.5f, colors.WHITE);
|
|
}
|
|
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
commandHandler cmdCoupDeGrace()
|
|
{
|
|
if (canDeathBlow(self, target))
|
|
{
|
|
pclib.coupDeGrace(target, self);
|
|
}
|
|
else
|
|
{
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleCoupDeGrace()
|
|
{
|
|
if (utils.hasScriptVar(self, COUPE_DE_GRACE_TARGET))
|
|
{
|
|
obj_id target = utils.getObjIdScriptVar(self, COUPE_DE_GRACE_TARGET);
|
|
utils.removeScriptVar(self, COUPE_DE_GRACE_TARGET);
|
|
debugServerConsoleMsg(null, "Performing deathblow on " + target);
|
|
if ( isIdValid(target) )
|
|
{
|
|
// make sure the target is still incapped
|
|
if (isIncapacitated(target))
|
|
{
|
|
// make sure the player is still close to the target
|
|
// WARNING!! There are two delathblow commands: coupDeGrace and deathBlow. We are assuming their data is the same.
|
|
location myPos = getLocation(self);
|
|
location targetPos = getLocation(target);
|
|
if ( myPos != null && targetPos != null)
|
|
{
|
|
float distance = myPos.distance(targetPos);
|
|
float maxDistance = getCommandMaxRange(##"coupDeGrace");
|
|
debugServerConsoleMsg(null, "Deathblow distance to target ");
|
|
if (distance < maxDistance)
|
|
{
|
|
CustomerServiceLog("Pvp", "Player %TU received deathblow message for target %TT, and is performing the blow");
|
|
pclib.coupDeGrace(target, self);
|
|
}
|
|
else
|
|
{
|
|
// @todo: send the player a message that he is too far away
|
|
CustomerServiceLog("Pvp", "Player %TU received deathblow message for target %TT, but has moved too "+
|
|
"far away (" + distance + ")", self, target);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CustomerServiceLog("Pvp", "Player %TU received deathblow message for target %TT, but we could "+
|
|
"not get the player's positions", self, target);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CustomerServiceLog("Pvp", "Player %TU received deathblow message, but target %TT is no longer incapped ", self, target);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CustomerServiceLog("Pvp", "Player %TU received deathblow message, but has invalid deathblow scriptvar " + target, self);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CustomerServiceLog("Pvp", "Player %TU received deathblow message, but has no deathblow scriptvar ", self);
|
|
}
|
|
if (!isIncapacitated(self))
|
|
setCount(self, 0);
|
|
setState(self, STATE_PERFORM_DEATHBLOW, false);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
commandHandler cmdCorpse()
|
|
{
|
|
queueCommand(self, ##"dragPlayer", target, "", COMMAND_PRIORITY_DEFAULT);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
|
|
/*
|
|
// JEFF DOESN'T KNOW WHAT THE FUCK
|
|
debugConsoleMsg( self, "*********************** CORPSE\n" );
|
|
|
|
resizeable obj_id[] movedCorpses = new obj_id[0];
|
|
|
|
target = getLookAtTarget(self);
|
|
|
|
if ( !isIdValid(target) || (target == self) )
|
|
{
|
|
if ( hasObjVar(self, pclib.VAR_CORPSE_ID) )
|
|
{
|
|
obj_id[] corpses = utils.getObjIdBatchObjVar(self, pclib.VAR_CORPSE_ID);
|
|
if ( (corpses != null) && (corpses.length != 0) )
|
|
{
|
|
obj_id[] draggedCorpses = corpse.dragPlayerCorpse(self, corpses);
|
|
movedCorpses = draggedCorpses;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//check permissions and drag if possible
|
|
int got = getGameObjectType(target);
|
|
if ( got == GOT_corpse )
|
|
{
|
|
if ( corpse.dragPlayerCorpse(self, target) )
|
|
{
|
|
movedCorpses = utils.addElement(movedCorpses, target);
|
|
}
|
|
else
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
}
|
|
else if ( isPlayer(target) )
|
|
{
|
|
if ( hasObjVar(target, pclib.VAR_CORPSE_ID) )
|
|
{
|
|
obj_id[] corpses = utils.getObjIdBatchObjVar(target, pclib.VAR_CORPSE_ID);
|
|
if ( (corpses != null) && (corpses.length > 0) )
|
|
{
|
|
obj_id[] draggedCorpses = corpse.dragPlayerCorpse(self, corpses);
|
|
movedCorpses = draggedCorpses;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
boolean badTarget = false;
|
|
if ( !isPlayer(target) || (getContainerType(target) == 0) )
|
|
{
|
|
badTarget = true;
|
|
}
|
|
else
|
|
{
|
|
obj_id[] targetContents = utils.getContents(target, true); //recursive getContents search
|
|
if ( ((targetContents == null) || (targetContents.length == 0)) && (getCashBalance(target) == 0) )
|
|
{
|
|
badTarget = true;
|
|
}
|
|
else
|
|
{
|
|
for ( int i = 0; i < targetContents.length; i++ )
|
|
{
|
|
int targetGot = getGameObjectType(targetContents[i]);
|
|
if ( targetGot == GOT_corpse )
|
|
{
|
|
if ( corpse.dragPlayerCorpse(self, target) )
|
|
{
|
|
movedCorpses = utils.addElement(movedCorpses, target);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( badTarget )
|
|
{
|
|
sendSystemMessage(self, pclib.SID_CMD_BAD_TARGET);
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( (movedCorpses == null) || (movedCorpses.length == 0) )
|
|
{
|
|
if ( !isIdValid(target) )
|
|
{
|
|
sendSystemMessage(self, SID_CMD_NO_EFFECT);
|
|
}
|
|
else
|
|
{
|
|
sendSystemMessage(self, SID_CMD_NO_EFFECT_ON_TARGET);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//corpses got moved!
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
*/
|
|
}
|
|
|
|
/***** CONSENT CMDS *************************************************/
|
|
commandHandler cmdConsent()
|
|
{
|
|
//SYNTAX: /consent <player name>, <player name>, <player name>, ...
|
|
//note: no params = show consentTo List
|
|
|
|
if ( params.equals("") )
|
|
{
|
|
target = getLookAtTarget(self);
|
|
|
|
// If the player has a target, assume they want to add the target
|
|
if ( isIdValid(target) && isPlayer(target) )
|
|
{
|
|
pclib.consent(self, target);
|
|
}
|
|
else //no target and no params
|
|
{
|
|
if ( hasObjVar(self, pclib.VAR_CONSENT_TO_ID) )
|
|
{
|
|
obj_id[] consentTo = getObjIdArrayObjVar(self, pclib.VAR_CONSENT_TO_ID);
|
|
if ( (consentTo == null) || (consentTo.length == 0) )
|
|
{
|
|
sendSystemMessage(self, SID_CONSENT_TO_EMPTY);
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
// Convert the object ID values into a list of names for the user
|
|
resizeable string[] consentToName = new string[0];
|
|
for ( int i = 0; i < consentTo.length; ++i )
|
|
{
|
|
consentToName = utils.addElement(consentToName, getPlayerFullName(consentTo[i]));
|
|
}
|
|
|
|
sui.listbox(self, "@" + SID_CONSENT_TO_LISTBOX_PROMPT, "@" + SID_CONSENT_TO_LISTBOX_TITLE, consentToName);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
sendSystemMessage(self, SID_CONSENT_TO_EMPTY);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
}
|
|
else //params != null
|
|
{
|
|
//try to parse params into something meaningful
|
|
if ( params.startsWith(">") )
|
|
{
|
|
java.util.StringTokenizer st = new java.util.StringTokenizer(params);
|
|
params = params.substring(1);
|
|
}
|
|
|
|
if ( params.indexOf(",") > 0 )
|
|
{
|
|
//attempting multiple consents?
|
|
java.util.StringTokenizer st = new java.util.StringTokenizer(params);
|
|
do
|
|
{
|
|
string arg = st.nextToken();
|
|
if ( arg.startsWith(">") )
|
|
{
|
|
arg = arg.substring(1);
|
|
}
|
|
|
|
obj_id playerId = getPlayerIdFromFirstName(arg);
|
|
if (isIdValid(playerId))
|
|
pclib.consent(self, playerId);
|
|
|
|
} while (st.hasMoreTokens());
|
|
}
|
|
else
|
|
{
|
|
obj_id playerId = getPlayerIdFromFirstName(params);
|
|
if (isIdValid(playerId))
|
|
pclib.consent(self, playerId);
|
|
}
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
commandHandler cmdUnconsent()
|
|
{
|
|
//SYNTAX: /unconsent <player name>, <player name>, <player name>, ...
|
|
//note: no params = provide menu to remove one
|
|
|
|
if ( params.equals("") )
|
|
{
|
|
target = getLookAtTarget(self);
|
|
|
|
// If the player has a target, assume they want to add the target
|
|
if ( isIdValid(target) && isPlayer(target) )
|
|
{
|
|
pclib.unconsent(self, target);
|
|
}
|
|
else
|
|
{
|
|
if ( hasObjVar(self, pclib.VAR_CONSENT_TO_ID) )
|
|
{
|
|
obj_id[] consentTo = getObjIdArrayObjVar(self, pclib.VAR_CONSENT_TO_ID);
|
|
if ( (consentTo == null) || (consentTo.length == 0) )
|
|
{
|
|
sendSystemMessage(self, SID_CONSENT_TO_EMPTY);
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
// Convert the object ID values into a list of names for the user
|
|
resizeable string[] consentToName = new string[0];
|
|
for ( int i = 0; i < consentTo.length; ++i )
|
|
{
|
|
consentToName = utils.addElement(consentToName, getPlayerFullName(consentTo[i]));
|
|
}
|
|
|
|
sui.listbox(self, self, "@" + SID_UNCONSENT_LISTBOX_PROMPT, sui.OK_CANCEL, "@" + SID_UNCONSENT_LISTBOX_TITLE, consentToName, HANDLER_UNCONSENT_MENU);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
sendSystemMessage(self, SID_CONSENT_TO_EMPTY);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
}
|
|
else //params != null
|
|
{
|
|
//try to parse params into something meaningful
|
|
if ( params.startsWith(">") )
|
|
{
|
|
params = params.substring(1);
|
|
}
|
|
|
|
if ( params.indexOf(",") > 0 )
|
|
{
|
|
//attempting multiple consents?
|
|
java.util.StringTokenizer st = new java.util.StringTokenizer(params);
|
|
do
|
|
{
|
|
string arg = st.nextToken();
|
|
if ( arg.startsWith(">") )
|
|
{
|
|
arg = arg.substring(1);
|
|
}
|
|
|
|
obj_id playerId = getPlayerIdFromFirstName(arg);
|
|
if (isIdValid(playerId))
|
|
pclib.unconsent(self, playerId);
|
|
|
|
} while (st.hasMoreTokens());
|
|
}
|
|
else
|
|
{
|
|
obj_id playerId = getPlayerIdFromFirstName(params);
|
|
if (isIdValid(playerId))
|
|
pclib.unconsent(self, playerId);
|
|
}
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
commandHandler cmdHaveConsent()
|
|
{
|
|
//SYNTAX: /haveconsent {optional: <player name>}
|
|
//note: no params = show consentFrom list
|
|
|
|
if ( params.equals("") )
|
|
{
|
|
target = getLookAtTarget(self);
|
|
|
|
// If the player has a target, assume they want to add the target
|
|
if ( isIdValid(target) && isPlayer(target) )
|
|
{
|
|
pclib.hasConsent(self, target, true);
|
|
}
|
|
else
|
|
{
|
|
if ( hasObjVar(self, pclib.VAR_CONSENT_FROM_ID) )
|
|
{
|
|
obj_id[] consentFrom = getObjIdArrayObjVar(self, pclib.VAR_CONSENT_FROM_ID);
|
|
if ( (consentFrom == null) || (consentFrom.length == 0) )
|
|
{
|
|
sendSystemMessage(self, SID_CONSENT_TO_EMPTY);
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
// Convert the object ID values into a list of names for the user
|
|
resizeable string[] consentFromName = new string[0];
|
|
for ( int i = 0; i < consentFrom.length; ++i )
|
|
{
|
|
consentFromName = utils.addElement(consentFromName, getPlayerFullName(consentFrom[i]));
|
|
}
|
|
|
|
sui.listbox(self, "@" + SID_CONSENT_FROM_LISTBOX_PROMPT, "@" + SID_CONSENT_FROM_LISTBOX_TITLE, consentFromName);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
sendSystemMessage(self, SID_CONSENT_FROM_EMPTY);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
}
|
|
else //params != null
|
|
{
|
|
//try to parse params into something meaningful
|
|
if ( params.startsWith(">") )
|
|
{
|
|
java.util.StringTokenizer st = new java.util.StringTokenizer(params);
|
|
params = params.substring(1);
|
|
}
|
|
|
|
if ( params.indexOf(",") > 0 )
|
|
{
|
|
//attempting multiple consents?
|
|
java.util.StringTokenizer st = new java.util.StringTokenizer(params);
|
|
do
|
|
{
|
|
string arg = st.nextToken();
|
|
if ( arg.startsWith(">") )
|
|
{
|
|
arg = arg.substring(1);
|
|
}
|
|
|
|
obj_id playerId = getPlayerIdFromFirstName(arg);
|
|
if (isIdValid(playerId))
|
|
pclib.hasConsent(self, playerId, true);
|
|
|
|
} while (st.hasMoreTokens());
|
|
}
|
|
else
|
|
{
|
|
//consider this a single consent attempt
|
|
obj_id playerId = getPlayerIdFromFirstName(params);
|
|
if (isIdValid(playerId))
|
|
pclib.hasConsent(self, playerId, true);
|
|
}
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
/***** INSURANCE CMDS *************************************************/
|
|
|
|
// DEPRECATED - No more insurance
|
|
/*
|
|
commandHandler cmdInsureItem()
|
|
{
|
|
//SYNTAX: /insure all|<obj_id>
|
|
//note: no params = show insurance ui
|
|
|
|
if ( (target == null) || (target == obj_id.NULL_ID) )
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
|
|
// int got = getGameObjectType(target);
|
|
// if ( got != GOT_terminal_insurance )
|
|
// {
|
|
// return SCRIPT_CONTINUE;
|
|
// }
|
|
|
|
if ( hasObjVar(self, pclib.VAR_NEWBIE_BASE) )
|
|
{
|
|
|
|
if ( !hasObjVar(self, pclib.VAR_NEWBIE_CONFIRM_INSURE) )
|
|
{
|
|
if ( utils.hasScriptVar(self, "sui.newbieInsureConfirm") )
|
|
{
|
|
int pid = utils.getIntScriptVar(self, "sui.newbieInsureConfirm");
|
|
forceCloseSUIPage(pid);
|
|
}
|
|
|
|
string title = "@base_player:noob_confirm_insure_title";
|
|
string prompt = "@base_player:noob_confirm_insure_prompt";
|
|
|
|
if ( params != null && !params.equals("") )
|
|
utils.setScriptVar(target, "newbieConfirm." + self, params);
|
|
|
|
int pid = sui.msgbox(target, self, prompt, sui.YES_NO, title, "handleNewbieInsureConfirm");
|
|
if ( pid > -1 )
|
|
{
|
|
utils.setScriptVar(self, "sui.newbieInsureConfirm", pid);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
}
|
|
|
|
if ( utils.hasScriptVar(self, "sui.insurance") )
|
|
{
|
|
int pid = utils.getIntScriptVar(self, "sui.insurance");
|
|
forceCloseSUIPage(pid);
|
|
}
|
|
|
|
if ( toLower(params).equals("") )
|
|
{
|
|
pclib.showInsuranceUI(target, self);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
else if ( toLower(params).equals("all") )
|
|
{
|
|
obj_id[] uninsured = pclib.getValidUninsuredItems(self);
|
|
if ( uninsured == null )
|
|
{
|
|
sendSystemMessage(self, SID_BAD_INSURE_REQUEST);
|
|
}
|
|
else if ( uninsured.length == 0 )
|
|
{
|
|
sendSystemMessage(self, SID_NO_UNINSURED_INSURABLES );
|
|
}
|
|
else
|
|
{
|
|
pclib.purchaseItemInsurance(self, target, uninsured);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
}
|
|
else if ( toLower(params).equals("insured") )
|
|
{
|
|
obj_id[] items = pclib.getValidInsuredItems(self);
|
|
if ( items == null )
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
else if ( items.length == 0 )
|
|
{
|
|
sui.msgbox(self, "You have no insured items!");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
string[] names = new string[items.length];
|
|
for ( int i = 0; i < items.length; i++ )
|
|
{
|
|
names[i] = "(" + items[i] + ") " + getName(items[i]);
|
|
}
|
|
sui.listbox(self, "The following are your insured items", names);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
else if ( toLower(params).equals("uninsured") )
|
|
{
|
|
obj_id[] items = pclib.getValidUninsuredItems(self);
|
|
if ( items == null )
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
else if ( items.length == 0 )
|
|
{
|
|
sui.msgbox(self, "You have no uninsured items!");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
string[] names = new string[items.length];
|
|
for ( int i = 0; i < items.length; i++ )
|
|
{
|
|
names[i] = "(" + items[i] + ") " + getName(items[i]);
|
|
}
|
|
sui.listbox(self, "The following are your uninsured items:", names);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
else
|
|
{
|
|
java.util.StringTokenizer st = new java.util.StringTokenizer(toLower(params));
|
|
if ( st.countTokens() == 1 )
|
|
{
|
|
obj_id item = utils.stringToObjId(st.nextToken());
|
|
if ( (item == null) || (item == obj_id.NULL_ID) )
|
|
{
|
|
sendSystemMessage(self, SID_BAD_INSURE_REQUEST);
|
|
}
|
|
else
|
|
{
|
|
pclib.purchaseItemInsurance(self, target, item);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
}
|
|
else if ( st.countTokens() > 1 )
|
|
{
|
|
resizeable string[] errorItems = new string[0];
|
|
resizeable obj_id[] toInsure = new obj_id[0];
|
|
do
|
|
{
|
|
string arg = st.nextToken();
|
|
obj_id item = utils.stringToObjId(arg);
|
|
if ( !isIdValid(item) )
|
|
{
|
|
errorItems = utils.addElement(errorItems, "(" + arg + ") Unable to parse object id");
|
|
}
|
|
else
|
|
{
|
|
toInsure = utils.addElement(toInsure, item);
|
|
}
|
|
} while (st.hasMoreTokens());
|
|
|
|
if ( errorItems.length > 0 )
|
|
{
|
|
sui.listbox(self, "Transaction Error! Errors occurred with the following items:", errorItems);
|
|
}
|
|
else if ( errorItems.length == 0 )
|
|
{
|
|
pclib.purchaseItemInsurance(self, target, toInsure);
|
|
}
|
|
}
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
*/
|
|
|
|
/***** TRACE LOG CMDS *************************************************/
|
|
commandHandler startTraceLogging()
|
|
{
|
|
|
|
enableTraceLogging();
|
|
return SCRIPT_CONTINUE;
|
|
|
|
}
|
|
|
|
commandHandler stopTraceLogging()
|
|
{
|
|
|
|
disableTraceLogging();
|
|
return SCRIPT_CONTINUE;
|
|
|
|
}
|
|
|
|
// spawning commands
|
|
commandHandler createCreature()
|
|
{
|
|
string strCreatureType = params;
|
|
location locSpawnLocation = getLocation(self);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
commandHandler createNPC()
|
|
{
|
|
string strNPCType = params;
|
|
location locSpawnLocation = getLocation(self);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
commandHandler cmdStartLogout()
|
|
{
|
|
if (!hasScript(self, "player.player_logout"))
|
|
{
|
|
attachScript(self, "player.player_logout");
|
|
dictionary d = new dictionary();
|
|
if (isGod(self))
|
|
d.put("timeLeft", 1);
|
|
else
|
|
d.put("timeLeft", LOGOUT_TIME);
|
|
d.put("countInterval", LOGOUT_COUNT_INTERVAL);
|
|
messageTo(self, "OnLogoutPulse", d, 0.1f, false);
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
|
|
/***** SCOUT COMMANDS **************************************************/
|
|
|
|
//------------------------------------------------------------------------------------------------
|
|
// SCENT MASKING
|
|
//------------------------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------
|
|
// maskscent
|
|
//
|
|
// /maskscent command handler.
|
|
//------------------------------------------------
|
|
|
|
commandHandler maskscent()
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
/*
|
|
// Check to see if there is a remask delay (from a break).
|
|
if ( utils.hasScriptVar( self, "remaskDelay" ) )
|
|
{
|
|
int delay = utils.getIntScriptVar( self, "remaskDelay" );
|
|
int timeDiff = getGameTime() - delay;
|
|
if ( timeDiff >= 0 )
|
|
{
|
|
// The delay has passed.
|
|
utils.removeScriptVar( self, "remaskDelay" );
|
|
}
|
|
else
|
|
{
|
|
// The delay hasn't passed yet. (You must wait XX seconds to mask your scent again.)
|
|
prose_package pp = prose.getPackage( SID_SYS_SCENTMASK_DELAY, -timeDiff );
|
|
sendSystemMessageProse( self, pp );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
}
|
|
|
|
// Check to see if we are already scent masked.
|
|
int scentMasked = getState( self, STATE_MASK_SCENT );
|
|
int count = utils.getIntScriptVar( self, "scentmask.count" );
|
|
if ( scentMasked == 1 )
|
|
{
|
|
dictionary outparams = new dictionary();
|
|
outparams.put( "count", count );
|
|
if ( utils.hasScriptVar( self, "scentmask.camokit" ) )
|
|
sendSystemMessage( self, SID_SYS_SCENTMASK_CONCEALED );
|
|
else
|
|
messageTo( self, "removeScentMask", outparams, 0, false );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// We are able to sneak versus creatures.
|
|
int skillMod = getSkillStatisticModifier( self, "mask_scent" ) / 2;
|
|
if ( skillMod < 1 )
|
|
{
|
|
// Lack the skill.
|
|
sendSystemMessage( self, SID_SYS_SCENTMASK_NOSKILL );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Mask Time = 12 Seconds * Skill Mod (camouflage)
|
|
int maskTime = 12 * skillMod;
|
|
|
|
// Set masked scent state.
|
|
setState( self, STATE_MASK_SCENT, true );
|
|
buff.applyBuff(self, "mask_scent");
|
|
count++;
|
|
utils.setScriptVar( self, "scentmask.count", count );
|
|
|
|
// Remove scent mask delay vars.
|
|
utils.removeScriptVar( self, "scentmask.time" );
|
|
utils.removeScriptVar( self, "scentmask.level" );
|
|
|
|
// Set callback to remove scent.
|
|
dictionary outparams = new dictionary();
|
|
outparams.put( "count", count );
|
|
messageTo( self, "removeScentMask", outparams, maskTime, false );
|
|
|
|
// Notify the player.
|
|
sendSystemMessage( self, SID_SYS_SCENTMASK_START );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
*/
|
|
}
|
|
|
|
//------------------------------------------------
|
|
// failMaskscent
|
|
//------------------------------------------------
|
|
|
|
commandHandler failMaskscent()
|
|
{
|
|
// The player can't creature sneak. Probably because of his position.
|
|
//sendSystemMessage( self, SID_SYS_SCENTMASK_FAIL );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
commandHandler milkCreature()
|
|
{
|
|
obj_id playerCurrentMount = getMountId(self);
|
|
|
|
//get player targets -- intended & lookAt
|
|
obj_id intendedTarget = getIntendedTarget(self);
|
|
obj_id lookAtTarget = getLookAtTarget(self);
|
|
//can either target be milked?
|
|
string milkType_lookAt = ai_lib.getMilkType(lookAtTarget);
|
|
string milkType_intended = ai_lib.getMilkType(intendedTarget);
|
|
if(milkType_lookAt != null && milkType_lookAt != "none")
|
|
{
|
|
target = lookAtTarget;
|
|
}
|
|
else if(milkType_intended != null && milkType_intended != "none")
|
|
{
|
|
target = intendedTarget;
|
|
}
|
|
//nothing targeted
|
|
else if(!isIdValid(lookAtTarget) && !isIdValid(intendedTarget))
|
|
{
|
|
sendSystemMessage(self, MILK_NO_TARGET);
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
else
|
|
{
|
|
sendSystemMessage(self, SID_NO_ALLOW_MILK);
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
if(vehicle.isVehicle(target) || (ai_lib.aiGetNiche(target) == NICHE_DROID) || (ai_lib.aiGetNiche(target) == NICHE_ANDROID))
|
|
{
|
|
sendSystemMessage(self, SID_NO_ALLOW_MILK);
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
if(isIdValid(playerCurrentMount))
|
|
{
|
|
sendSystemMessage(self, SID_CANT_MILK_MOUNTED);
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
if(pet_lib.isPet(target))
|
|
{
|
|
sendSystemMessage(self, SID_CANT_MILK);
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
//make sure you are close enough to start milking.
|
|
float distStart = utils.getDistance2D(self, target);
|
|
if((distStart < -3) || (distStart > 3))
|
|
{
|
|
sendSystemMessage(self, MILK_TOO_FAR_START);
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
if (!ai_lib.isAiDead(target) && !hasScript(target, "ai.pet_advance") && !ai_lib.isInCombat(target))
|
|
{
|
|
dictionary dict = new dictionary();
|
|
dict.put("player", self);
|
|
messageTo(target, "attemptMilkHandler", dict, 0, false);
|
|
}
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
commandHandler searchLair()
|
|
{
|
|
//get player targets
|
|
obj_id intendedTarget = getIntendedTarget(self);
|
|
obj_id lookAtTarget = getLookAtTarget(self);
|
|
//find which target is a lair - set it to target
|
|
int GOT_type_intended = getGameObjectType(intendedTarget);
|
|
int GOT_type_look = getGameObjectType(lookAtTarget);
|
|
if(GOT_type_intended == GOT_lair)
|
|
{
|
|
target = intendedTarget;
|
|
}
|
|
else if(GOT_type_look == GOT_lair)
|
|
{
|
|
target = lookAtTarget;
|
|
}
|
|
else
|
|
{
|
|
sendSystemMessage(self, LAIR_NOT_TARGETED);
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
float maxDistance = 10f;
|
|
float distanceToLair = utils.getDistance2D(self, target);
|
|
|
|
if (hasScript(target, "theme_park.dungeon.mustafar_trials.valley_battleground.battlefield_destructable"))
|
|
return SCRIPT_OVERRIDE;
|
|
|
|
if(distanceToLair > maxDistance)
|
|
{
|
|
sendSystemMessage(self, TOO_FAR_FROM_LAIR );
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
else
|
|
{
|
|
if (!utils.hasScriptVar( target, "lair.searched" ) && !isIncapacitated( self ) )
|
|
{
|
|
//Collection Milk
|
|
collection.collectionResource(self, "egg");
|
|
|
|
dictionary dict = new dictionary();
|
|
dict.put("player", self);
|
|
messageTo(target, "searchLair", dict, 0, false);
|
|
}
|
|
else
|
|
{
|
|
sendSystemMessage(self, SID_FOUND_NOTHING );
|
|
}
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//------------------------------------------------
|
|
// removeScentMask
|
|
//------------------------------------------------
|
|
|
|
messageHandler removeScentMask()
|
|
{
|
|
// Ignore this message if we are not scent masked.
|
|
int scentMasked = getState( self, STATE_MASK_SCENT );
|
|
if ( scentMasked == 0 )
|
|
{
|
|
buff.removeBuff(self, "mask_scent");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
// Check the count stamp.
|
|
int scount = params.getInt( "count" );
|
|
int count = utils.getIntScriptVar( self, "scentmask.count" );
|
|
if ( count != scount )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
// No longer masking scent.
|
|
setState( self, STATE_MASK_SCENT, false );
|
|
buff.removeBuff(self, "mask_scent");
|
|
sendSystemMessage( self, SID_SYS_SCENTMASK_STOP );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//------------------------------------------------
|
|
// removeScentMaskNoNotify
|
|
//
|
|
// Also removes conceal camo.
|
|
//------------------------------------------------
|
|
|
|
messageHandler removeScentMaskNoNotify()
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
/*
|
|
// No longer masking scent.
|
|
setState( self, STATE_MASK_SCENT, false );
|
|
buff.removeBuff(self, "mask_scent");
|
|
buff.removeBuff(self, "conceal");
|
|
|
|
utils.removeScriptVar( self, "scentmask.camokit" );
|
|
utils.removeScriptVar( self, "scentmask.camoquality" );
|
|
utils.removeScriptVar( self, "scentmask.camoapply" );
|
|
|
|
if ( params != null )
|
|
{
|
|
int remaskDelay = params.getInt( "remaskDelay" );
|
|
utils.setScriptVar( self, "remaskDelay", getGameTime() + remaskDelay );
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
*/
|
|
}
|
|
|
|
|
|
//------------------------------------------------
|
|
// concealEnable
|
|
//------------------------------------------------
|
|
|
|
messageHandler concealEnable()
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
/*
|
|
if ( params == null )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
int count = utils.getIntScriptVar( self, "scentmask.count" );
|
|
string planetName = params.getString( "planetName" );
|
|
int maskTime = params.getInt( "maskTime" );
|
|
int skillMod = params.getInt( "skillMod" );
|
|
obj_id player = params.getObjId( "player" );
|
|
|
|
// Set masked scent state.
|
|
setState( self, STATE_MASK_SCENT, true );
|
|
count++;
|
|
buff.applyBuff(self, "conceal");
|
|
utils.setScriptVar( self, "scentmask.count", count );
|
|
utils.setScriptVar( self, "scentmask.camokit", planetName );
|
|
utils.setScriptVar( self, "scentmask.camoquality", skillMod );
|
|
utils.setScriptVar( self, "scentmask.camoapply", player );
|
|
|
|
// Remove scent mask delay vars.
|
|
utils.removeScriptVar( self, "scentmask.time" );
|
|
utils.removeScriptVar( self, "scentmask.level" );
|
|
|
|
// Set callback to remove scent.
|
|
dictionary outparams = new dictionary();
|
|
outparams.put( "count", count );
|
|
messageTo( self, "removeScentMask", outparams, maskTime, false );
|
|
|
|
// Notify the player.
|
|
sendSystemMessage( self, SID_SYS_CONCEAL_START );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
*/
|
|
}
|
|
|
|
//------------------------------------------------
|
|
// failConceal
|
|
//
|
|
// Handles inability to conceal.
|
|
//------------------------------------------------
|
|
|
|
commandHandler failConceal()
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//------------------------------------------------
|
|
// removeConceal
|
|
//------------------------------------------------
|
|
|
|
messageHandler removeConceal()
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
/*
|
|
// Ignore this message if we are not scent masked / concealed.
|
|
int scentMasked = getState( self, STATE_MASK_SCENT );
|
|
if ( scentMasked == 0 )
|
|
{
|
|
buff.removeBuff(self, "conceal");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
// Check the count stamp.
|
|
int scount = params.getInt( "count" );
|
|
int count = utils.getIntScriptVar( self, "scentmask.count" );
|
|
if ( count != scount )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
// No longer masking scent.
|
|
utils.removeScriptVar( self, "scentmask.camokit" );
|
|
utils.removeScriptVar( self, "scentmask.camoquality" );
|
|
utils.removeScriptVar( self, "scentmask.camoapply" );
|
|
|
|
setState( self, STATE_MASK_SCENT, false );
|
|
buff.removeBuff(self, "conceal");
|
|
sendSystemMessage( self, SID_SYS_CONCEAL_STOP );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
*/
|
|
}
|
|
|
|
//------------------------------------------------
|
|
// itemIsRare
|
|
//------------------------------------------------
|
|
|
|
boolean itemIsRare( obj_id self, int skillMod )
|
|
{
|
|
// Check for rare success.
|
|
boolean rare = false;
|
|
if ( skillMod >= 65 )
|
|
{
|
|
int difficultyCheck = (skillMod-50) + 30;
|
|
int dieRoll = rand( 1, 100 );
|
|
if ( dieRoll > difficultyCheck )
|
|
{
|
|
// Skill check passed. Now do general rarity enforcing random test.
|
|
dieRoll = rand( 1, 4 );
|
|
if ( dieRoll == 1 )
|
|
rare = true;
|
|
}
|
|
}
|
|
return rare;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------------------------
|
|
// SYSGROUP - Squad Leader
|
|
//------------------------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------
|
|
// sysgroup
|
|
//
|
|
// Squad leader group message handler.
|
|
//------------------------------------------------
|
|
|
|
commandHandler sysGroup()
|
|
{
|
|
if ( hasSkill( self, "class_officer_phase1_master" ) )
|
|
{
|
|
squad_leader.sendSquadLeaderCommand( self, params );
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//group waypoints from officer
|
|
commandHandler groupWaypoint()
|
|
{
|
|
if ( hasSkill( self, "class_officer_phase1_master" ) )
|
|
{
|
|
//a and c are sent by the client to tell server what targeting mode we are in
|
|
if(params.equals("a") || params.equals("c"))
|
|
{
|
|
squad_leader.sendSquadWaypoint(self, getLocation(self));
|
|
}
|
|
else
|
|
{
|
|
// ground target. Location is passed in the params
|
|
location wayLoc = combat.getCommandGroundTargetLocation(params);
|
|
squad_leader.sendSquadWaypoint(self, wayLoc);
|
|
}
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler createOfficerGroupWaypoint()
|
|
{
|
|
if(params == null || params.isEmpty())
|
|
return SCRIPT_CONTINUE;
|
|
|
|
location wayLoc = params.getLocation("wayLoc");
|
|
|
|
obj_id groupWaypoint = createWaypointInDatapad(self, wayLoc);
|
|
setWaypointColor(groupWaypoint, "green");
|
|
setWaypointName(groupWaypoint, "Group Waypoint");
|
|
setWaypointActive(groupWaypoint, true);
|
|
|
|
dictionary dict = new dictionary();
|
|
dict.put("groupWaypoint", groupWaypoint);
|
|
|
|
messageTo(self, "removeOfficerGroupWaypoint", dict, 600, false);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
|
|
}
|
|
|
|
|
|
messageHandler removeOfficerGroupWaypoint()
|
|
{
|
|
if(params == null || params.isEmpty())
|
|
return SCRIPT_CONTINUE;
|
|
|
|
obj_id groupWaypoint = params.getObjId("groupWaypoint");
|
|
|
|
if(!isIdValid(groupWaypoint) || !exists(groupWaypoint))
|
|
return SCRIPT_CONTINUE;
|
|
|
|
destroyWaypointInDatapad(groupWaypoint, self);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------------------------
|
|
// Survey Results Handler
|
|
//------------------------------------------------------------------------------------------------
|
|
|
|
trigger OnSurveyDataReceived( float[] xVals, float[] zVals, float[] efficiencies )
|
|
{
|
|
if ( efficiencies == null )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
int highest = -1;
|
|
float highVal = 0.f;
|
|
for ( int i=0; i<efficiencies.length; i++ )
|
|
{
|
|
if ( efficiencies[i] > highVal )
|
|
{
|
|
highest = i;
|
|
highVal = efficiencies[i];
|
|
}
|
|
}
|
|
|
|
if ( (highest > -1) && (highVal > 0.1) )
|
|
{
|
|
|
|
// Set location.
|
|
location point = new location();
|
|
point.x = xVals[highest];
|
|
point.y = 0;
|
|
point.z = zVals[highest];
|
|
|
|
// Create a waypoint to this location.
|
|
obj_id waypoint = getSurveyWaypoint( self );
|
|
boolean newWpCreated = false;
|
|
if (!isIdValid(waypoint))
|
|
{
|
|
waypoint = createWaypointInDatapad( self, point );
|
|
newWpCreated = true;
|
|
}
|
|
|
|
if (isIdValid(waypoint))
|
|
{
|
|
setWaypointVisible( waypoint, true );
|
|
setWaypointActive( waypoint, true );
|
|
setWaypointLocation( waypoint, point );
|
|
setWaypointName( waypoint, "Resource Survey" );
|
|
|
|
// survey waypoint is orange by default
|
|
if (newWpCreated)
|
|
setWaypointColor( waypoint, "orange" );
|
|
|
|
setObjVar( self, "survey_waypoint", waypoint );
|
|
}
|
|
|
|
sendSystemMessage( self, SID_SURVEY_WAYPOINT );
|
|
}
|
|
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
obj_id getSurveyWaypoint( obj_id self )
|
|
{
|
|
// Check to see if any waypoints are already to that location.
|
|
obj_id[] data = getWaypointsInDatapad( self );
|
|
if ( data != null )
|
|
{
|
|
for ( int i=0; i<data.length; i++ )
|
|
{
|
|
if (!isIdValid(data[i]))
|
|
continue;
|
|
string waypointName = getWaypointName( data[i] );
|
|
if ( (waypointName != null) && waypointName.equals( "Resource Survey" ) )
|
|
{
|
|
// Matching waypoint.
|
|
return data[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
// Handle posture change while sampling.
|
|
trigger OnChangedPosture( int before, int after )
|
|
{
|
|
//meditate cleanup
|
|
if(meditation.isMeditating(self))
|
|
meditation.endMeditation(self);
|
|
|
|
//sampling cleanup
|
|
if ( before == POSTURE_CROUCHED )
|
|
{
|
|
if ( utils.hasScriptVar( self, "surveying.takingSamples" ) )
|
|
{
|
|
obj_id tool = utils.getObjIdScriptVar( self, "surveying.tool" );
|
|
resource.cleanupTool(self, tool);
|
|
sendSystemMessage( self, SID_SAMPLE_CANCEL );
|
|
|
|
}
|
|
else if ( utils.hasScriptVar( self, "trapdrop.settrap" ) )
|
|
{
|
|
obj_id trap = utils.getObjIdScriptVar( self, "trapdrop.settrap" );
|
|
messageTo( trap, "stopDeploy", null, 0.f, false );
|
|
sendSystemMessage( self, SID_TRAP_CANCEL );
|
|
utils.removeScriptVar( self, "trapdrop.settrap" );
|
|
}
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Stop sampling / trap deployment
|
|
trigger OnCreatureDamaged( obj_id attacker, obj_id weapon, int[] damage )
|
|
{
|
|
//meditate cleanup
|
|
if(meditation.isMeditating(self))
|
|
meditation.endMeditation(self);
|
|
|
|
if ( utils.hasScriptVar( self, "surveying.takingSamples" ) )
|
|
{
|
|
obj_id tool = utils.getObjIdScriptVar( self, "surveying.tool" );
|
|
resource.cleanupTool(self, tool);
|
|
sendSystemMessage( self, SID_SAMPLE_CANCEL_ATTACK );
|
|
}
|
|
else if ( utils.hasScriptVar( self, "trapdrop.settrap" ) )
|
|
{
|
|
obj_id trap = utils.getObjIdScriptVar( self, "trapdrop.settrap" );
|
|
messageTo( trap, "stopDeploy", null, 0.f, false );
|
|
sendSystemMessage( self, SID_TRAP_CANCEL_ATTACK );
|
|
utils.removeScriptVar( self, "trapdrop.settrap" );
|
|
}
|
|
|
|
metrics.logArmorStatus(self);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Stop sampling if attacked.
|
|
trigger OnTargeted( obj_id attacker )
|
|
{
|
|
if ( utils.hasScriptVar( self, "surveying.takingSamples" ) )
|
|
{
|
|
obj_id tool = utils.getObjIdScriptVar( self, "surveying.tool" );
|
|
resource.cleanupTool(self, tool);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------------------------
|
|
// Survey Special Events
|
|
//------------------------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------
|
|
// handleSurveyNodeChoice
|
|
//------------------------------------------------
|
|
|
|
messageHandler handleSurveyNodeChoice()
|
|
{
|
|
if(!sui.hasPid(self, resource.PID_NAME))
|
|
return SCRIPT_CONTINUE;
|
|
|
|
sui.removePid(self, resource.PID_NAME);
|
|
|
|
// Confirm that the player is still in a proper sampling mode.
|
|
// The player may have aborted surveying before picking an option from the UI.
|
|
// Or he might have changed which tool he is using.
|
|
if ( !utils.hasScriptVar( self, "surveying.takingSamples" ) )
|
|
return SCRIPT_CONTINUE;
|
|
obj_id curtool = utils.getObjIdScriptVar( self, "surveying.tool" );
|
|
obj_id tool = utils.getObjIdScriptVar( self, "survey_event.tool" );
|
|
if ( tool != curtool )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
// Grab params.
|
|
int idx = sui.getListboxSelectedRow( params );
|
|
if ( idx < 0 ) idx = 0;
|
|
obj_id player = sui.getPlayerId( params );
|
|
int btn = sui.getIntButtonPressed( params );
|
|
if ( (btn == sui.BP_CANCEL) || (idx == 0) )
|
|
{
|
|
// Player chose to ignore the node.
|
|
dictionary outparams = new dictionary();
|
|
outparams.put( "player", self );
|
|
messageTo( tool, "continueSampleLoop", outparams, 0.f, false );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
else if(idx == 2)
|
|
{
|
|
if(!hasCompletedCollection(player, "sampling_pet_collection"))
|
|
{
|
|
modifyCollectionSlotValue(player, "col_pet_resource_sampling", 1);
|
|
}
|
|
|
|
int dieRoll = rand( 1, 100 );
|
|
if ( dieRoll < 75 )
|
|
{
|
|
// Success!
|
|
utils.setScriptVar( player, "survey_event.gamble", 3 );
|
|
}
|
|
else
|
|
{
|
|
// Fail!
|
|
utils.setScriptVar( player, "survey_event.gamble", 4 );
|
|
}
|
|
|
|
dictionary outparams = new dictionary();
|
|
outparams.put( "player", self );
|
|
messageTo( tool, "continueSampleLoop", outparams, 0.f, false );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Tell the player to stop sampling.
|
|
dictionary outparams = new dictionary();
|
|
outparams.put( "player", self );
|
|
messageTo( tool, "stopSampleEvent", outparams, 0.f, false );
|
|
|
|
// Stop surveying and lock on to a nearby point.
|
|
location point = locations.getGoodLocationAroundLocation( getLocation(self), 10, 10, 50, 50, true, false );
|
|
|
|
if (point == null)
|
|
return SCRIPT_CONTINUE;
|
|
|
|
// Update the waypoint.
|
|
obj_id waypoint = getSurveyWaypoint( self );
|
|
if ( !isIdValid(waypoint) )
|
|
waypoint = createWaypointInDatapad( self, point );
|
|
if ( isIdValid(waypoint) )
|
|
{
|
|
setWaypointVisible( waypoint, true );
|
|
setWaypointActive( waypoint, true );
|
|
setWaypointLocation( waypoint, point );
|
|
setWaypointName( waypoint, "Resource Survey" );
|
|
setWaypointColor( waypoint, "blue" );
|
|
}
|
|
|
|
// Notify the player of the node location.
|
|
sendSystemMessage( self, SID_NODE_WAYPOINT );
|
|
|
|
// Store the event information.
|
|
utils.setScriptVar( self, "survey_event.location", point );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//------------------------------------------------
|
|
// handleSurveyGambleChoice
|
|
//------------------------------------------------
|
|
|
|
messageHandler handleSurveyGambleChoice()
|
|
{
|
|
if(!sui.hasPid(self, resource.PID_NAME))
|
|
return SCRIPT_CONTINUE;
|
|
|
|
sui.removePid(self, resource.PID_NAME);
|
|
|
|
// Confirm that the player is still in a proper sampling mode.
|
|
// The player may have aborted surveying before picking an option from the UI.
|
|
// Or he might have changed which tool he is using.
|
|
if ( !utils.hasScriptVar( self, "surveying.takingSamples" ) )
|
|
return SCRIPT_CONTINUE;
|
|
obj_id curtool = utils.getObjIdScriptVar( self, "surveying.tool" );
|
|
obj_id tool = utils.getObjIdScriptVar( self, "survey_event.tool" );
|
|
if ( tool != curtool )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
// Grab params.
|
|
int idx = sui.getListboxSelectedRow( params );
|
|
if ( idx < 0 ) idx = 0;
|
|
obj_id player = sui.getPlayerId( params );
|
|
int btn = sui.getIntButtonPressed( params );
|
|
if ( (btn == sui.BP_CANCEL) || (idx == 0) )
|
|
{
|
|
// Player chose to ignore the node.
|
|
dictionary outparams = new dictionary();
|
|
outparams.put( "player", self );
|
|
messageTo( tool, "continueSampleLoop", outparams, 0.f, false );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Check to see if the player has enough pool and drain it.
|
|
int action = getAttrib( player, ACTION );
|
|
int actioncost = 2000;
|
|
if ( !drainAttributes( player, actioncost, 0 ) )
|
|
{
|
|
// We don't have the pool to do this.
|
|
sendSystemMessage( player, SID_GAMBLE_NO_ACTION );
|
|
dictionary outparams = new dictionary();
|
|
outparams.put( "player", self );
|
|
messageTo( tool, "continueSampleLoop", outparams, 0.f, false );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
if(idx == 2)
|
|
{
|
|
string resource_class = getStringObjVar(tool, resource.VAR_SURVEY_CLASS);
|
|
string collectionName = "col_resource_" + resource_class + "_01";
|
|
modifyCollectionSlotValue(player, collectionName, 1);
|
|
utils.setScriptVar( player, "survey_event.gamble", 5 );
|
|
|
|
dictionary outparams = new dictionary();
|
|
outparams.put( "player", self );
|
|
messageTo( tool, "continueSampleLoop", outparams, 0.f, false );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Roll the die.
|
|
int dieRoll = rand( 1, 100 );
|
|
if ( dieRoll < 75 )
|
|
{
|
|
// Success!
|
|
utils.setScriptVar( player, "survey_event.gamble", 1 );
|
|
}
|
|
else
|
|
{
|
|
// Fail!
|
|
utils.setScriptVar( player, "survey_event.gamble", 2 );
|
|
}
|
|
|
|
// Continue sampling.
|
|
dictionary outparams = new dictionary();
|
|
outparams.put( "player", self );
|
|
messageTo( tool, "continueSampleLoop", outparams, 0.f, false );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------------------------
|
|
// DNA Harvesting - Bio-Engineer
|
|
//------------------------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------
|
|
// cmdHarvestDNA
|
|
//
|
|
// Bio-Engineer DNA harvest message handler.
|
|
//------------------------------------------------
|
|
|
|
commandHandler cmdHarvestDNA()
|
|
{
|
|
if (!isIdValid(target))
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//debugSpeakMsg(self, "attempting to harvest...");
|
|
bio_engineer.harvestCreatureDNA (self, target);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//------------------------------------------------
|
|
// cmdHarvestDNA
|
|
//
|
|
// Bio-Engineer DNA harvest fail message handler.
|
|
//------------------------------------------------
|
|
|
|
commandHandler cmdHarvestDNAFail()
|
|
{
|
|
if (!isIdValid(target))
|
|
{
|
|
sendSystemMessage(self, bio_engineer.SID_HARVEST_DNA_FAILED);
|
|
}
|
|
else
|
|
{
|
|
prose_package pp = prose.getPackage (bio_engineer.PROSE_HARVEST_DNA_FAILED, target);
|
|
sendSystemMessageProse (self, pp);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//------------------------------------------------
|
|
// cmdHarvestDNA
|
|
//
|
|
// Bio-Engineer DNA harvest cempletion message handler.
|
|
//------------------------------------------------
|
|
|
|
messageHandler completeHarvestDNA()
|
|
{
|
|
//debugSpeakMsg(self, "harvesting complete");
|
|
bio_engineer.completeHarvest (self);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
commandHandler cmdWaypoint()
|
|
{
|
|
string wpColor = null;
|
|
float displayCoordX = 0.0f;
|
|
float displayCoordZ = 0.0f;
|
|
boolean wpDifferentPlanet = false;
|
|
obj_id lookAtTarget = null;
|
|
obj_id intendedTarget = null;
|
|
|
|
// parse params; if a valid waypoint color is specified in the params,
|
|
// save off the waypoint color, and remove it from the params list
|
|
int parsedIndex = 0;
|
|
resizeable string[] parsedParams = new string[0];
|
|
if (params != null && !params.equals(""))
|
|
{
|
|
java.util.StringTokenizer st = new java.util.StringTokenizer(params);
|
|
while (st.hasMoreTokens())
|
|
{
|
|
string token = st.nextToken();
|
|
if (wpColor == null)
|
|
{
|
|
for (int i = 0; i < utils.WAYPOINT_COLORS.length; ++i)
|
|
{
|
|
if (token.toLowerCase().equals(utils.WAYPOINT_COLORS[i]))
|
|
{
|
|
wpColor = utils.WAYPOINT_COLORS[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (wpColor == null)
|
|
{
|
|
utils.addElement(parsedParams, token);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
utils.addElement(parsedParams, token);
|
|
}
|
|
}
|
|
}
|
|
|
|
location spot = null;
|
|
if (parsedParams == null || (parsedParams.length <= 0))
|
|
{
|
|
spot = getWorldLocation(self);
|
|
|
|
// calculate display coords from world coords
|
|
if (spot != null)
|
|
{
|
|
displayCoordX = spot.x;
|
|
displayCoordZ = spot.z;
|
|
float[] baInfo = getBuildoutAreaSizeAndCenter(spot.x, spot.z, spot.area, true, true);
|
|
if ((baInfo != null) && (baInfo.length == 4))
|
|
{
|
|
displayCoordX -= baInfo[2];
|
|
displayCoordZ -= baInfo[3];
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
string wpGroundPlanet = null;
|
|
vector wpGroundPLanetBuildoutCoords = null;
|
|
string wpSpaceZone = null;
|
|
float wpCoord1 = Float.NEGATIVE_INFINITY;
|
|
float wpCoord2 = Float.NEGATIVE_INFINITY;
|
|
float wpCoord3 = Float.NEGATIVE_INFINITY;
|
|
boolean useTarget = false;
|
|
|
|
wpCoord1 = utils.stringToFloat(parsedParams[parsedIndex]); // is first parameter a float?
|
|
if (wpCoord1 == Float.NEGATIVE_INFINITY)
|
|
{
|
|
// first parameter is not a float, see if it's a ground planet name or a space zone name
|
|
string planet = parsedParams[parsedIndex].toLowerCase();
|
|
|
|
// see it it's "-target"
|
|
if (planet.equals("-target"))
|
|
{
|
|
useTarget = true;
|
|
++parsedIndex;
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < WAYPOINT_GROUND_PLANETS_EXTERNAL.length; ++i)
|
|
{
|
|
if ((planet.equals(WAYPOINT_GROUND_PLANETS_EXTERNAL[i])) && (i < WAYPOINT_GROUND_PLANETS_INTERNAL.length))
|
|
{
|
|
wpGroundPlanet = WAYPOINT_GROUND_PLANETS_INTERNAL[i];
|
|
|
|
if (i < WAYPOINT_GROUND_PLANETS_BUILDOUT_COORDS.length)
|
|
wpGroundPLanetBuildoutCoords = WAYPOINT_GROUND_PLANETS_BUILDOUT_COORDS[i];
|
|
|
|
++parsedIndex;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (wpGroundPlanet == null)
|
|
{
|
|
for (int i = 0; i < WAYPOINT_SPACE_ZONES_EXTERNAL.length; ++i)
|
|
{
|
|
if ((planet.equals(WAYPOINT_SPACE_ZONES_EXTERNAL[i])) && (i < WAYPOINT_SPACE_ZONES_INTERNAL.length))
|
|
{
|
|
wpSpaceZone = WAYPOINT_SPACE_ZONES_INTERNAL[i];
|
|
|
|
++parsedIndex;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (((wpGroundPlanet != null) || (wpSpaceZone != null)) && (parsedIndex < parsedParams.length))
|
|
{
|
|
wpCoord1 = utils.stringToFloat(parsedParams[parsedIndex]); // is next parameter a float?
|
|
}
|
|
}
|
|
|
|
if (wpCoord1 != Float.NEGATIVE_INFINITY) // first waypoint coord specified?
|
|
{
|
|
++parsedIndex;
|
|
if (parsedIndex < parsedParams.length)
|
|
{
|
|
wpCoord2 = utils.stringToFloat(parsedParams[parsedIndex]); // is next parameter a float?
|
|
if (wpCoord2 != Float.NEGATIVE_INFINITY) // next waypoint coord specified?
|
|
{
|
|
++parsedIndex;
|
|
if (parsedIndex < parsedParams.length)
|
|
{
|
|
wpCoord3 = utils.stringToFloat(parsedParams[parsedIndex]); // is next parameter a float?
|
|
if (wpCoord3 != Float.NEGATIVE_INFINITY) // next waypoint coord specified?
|
|
{
|
|
++parsedIndex;
|
|
}
|
|
else if (wpSpaceZone != null) // space zone requires 3 coords
|
|
{
|
|
wpCoord1 = Float.NEGATIVE_INFINITY;
|
|
wpCoord2 = Float.NEGATIVE_INFINITY;
|
|
--parsedIndex;
|
|
--parsedIndex;
|
|
}
|
|
}
|
|
else if (wpSpaceZone != null) // space zone requires 3 coords
|
|
{
|
|
wpCoord1 = Float.NEGATIVE_INFINITY;
|
|
wpCoord2 = Float.NEGATIVE_INFINITY;
|
|
--parsedIndex;
|
|
--parsedIndex;
|
|
}
|
|
}
|
|
else // only 1 coord specified, don't treat it as a coord
|
|
{
|
|
wpCoord1 = Float.NEGATIVE_INFINITY;
|
|
--parsedIndex;
|
|
}
|
|
}
|
|
else // only 1 coord specified, don't treat it as a coord
|
|
{
|
|
wpCoord1 = Float.NEGATIVE_INFINITY;
|
|
--parsedIndex;
|
|
}
|
|
}
|
|
|
|
// validate coords
|
|
if ((wpGroundPlanet != null) && ((wpCoord1 == Float.NEGATIVE_INFINITY) || (wpCoord2 == Float.NEGATIVE_INFINITY)))
|
|
{
|
|
// did not specify valid coords for the specified planet, don't treat it as a coord or a specified planet name
|
|
wpGroundPlanet = null;
|
|
wpCoord1 = Float.NEGATIVE_INFINITY;
|
|
wpCoord2 = Float.NEGATIVE_INFINITY;
|
|
wpCoord3 = Float.NEGATIVE_INFINITY;
|
|
parsedIndex = 0;
|
|
}
|
|
|
|
if ((wpSpaceZone != null) && ((wpCoord1 == Float.NEGATIVE_INFINITY) || (wpCoord2 == Float.NEGATIVE_INFINITY) || (wpCoord3 == Float.NEGATIVE_INFINITY)))
|
|
{
|
|
// did not specify valid coords for the specified space zone, don't treat it as a coord or a specified space zone name
|
|
wpSpaceZone = null;
|
|
wpCoord1 = Float.NEGATIVE_INFINITY;
|
|
wpCoord2 = Float.NEGATIVE_INFINITY;
|
|
wpCoord3 = Float.NEGATIVE_INFINITY;
|
|
parsedIndex = 0;
|
|
}
|
|
|
|
// construct location for waypoint
|
|
if (wpCoord1 == Float.NEGATIVE_INFINITY)
|
|
{
|
|
if (useTarget)
|
|
{
|
|
intendedTarget = getIntendedTarget(self);
|
|
if (isIdValid(intendedTarget))
|
|
{
|
|
spot = getWorldLocation(intendedTarget);
|
|
}
|
|
|
|
if (spot == null)
|
|
{
|
|
intendedTarget = null;
|
|
lookAtTarget = getLookAtTarget(self);
|
|
if (isIdValid(lookAtTarget))
|
|
{
|
|
spot = getWorldLocation(lookAtTarget);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (spot == null)
|
|
{
|
|
intendedTarget = null;
|
|
lookAtTarget = null;
|
|
spot = getWorldLocation(self);
|
|
}
|
|
|
|
// calculate display coords from world coords
|
|
if (spot != null)
|
|
{
|
|
displayCoordX = spot.x;
|
|
displayCoordZ = spot.z;
|
|
float[] baInfo = getBuildoutAreaSizeAndCenter(spot.x, spot.z, spot.area, true, true);
|
|
if ((baInfo != null) && (baInfo.length == 4))
|
|
{
|
|
displayCoordX -= baInfo[2];
|
|
displayCoordZ -= baInfo[3];
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (wpCoord3 == Float.NEGATIVE_INFINITY)
|
|
spot = new location(wpCoord1, 0.0f, wpCoord2);
|
|
else
|
|
spot = new location(wpCoord1, wpCoord2, wpCoord3);
|
|
|
|
// coords that are specified on the command line are display coords, convert them to world coords
|
|
if (spot != null)
|
|
{
|
|
displayCoordX = spot.x;
|
|
displayCoordZ = spot.z;
|
|
|
|
float[] baInfo = null;
|
|
|
|
// was a different planet specified?
|
|
if ((wpGroundPlanet != null) && (!wpGroundPlanet.equals(spot.area)))
|
|
{
|
|
if (wpGroundPLanetBuildoutCoords != null)
|
|
{
|
|
baInfo = getBuildoutAreaSizeAndCenter(wpGroundPLanetBuildoutCoords.x, wpGroundPLanetBuildoutCoords.z, wpGroundPlanet, true, true);
|
|
}
|
|
|
|
wpDifferentPlanet = true;
|
|
spot.area = wpGroundPlanet;
|
|
}
|
|
else if ((wpSpaceZone != null) && (!wpSpaceZone.equals(spot.area)))
|
|
{
|
|
wpDifferentPlanet = true;
|
|
spot.area = wpSpaceZone;
|
|
}
|
|
else
|
|
{
|
|
location currentLoc = getWorldLocation(self);
|
|
if (currentLoc != null)
|
|
{
|
|
baInfo = getBuildoutAreaSizeAndCenter(currentLoc.x, currentLoc.z, currentLoc.area, true, true);
|
|
}
|
|
}
|
|
|
|
if ((baInfo != null) && (baInfo.length == 4))
|
|
{
|
|
const float halfWidth = baInfo[0]/2;
|
|
if (displayCoordX > halfWidth)
|
|
displayCoordX = halfWidth;
|
|
else if (displayCoordX < -halfWidth)
|
|
displayCoordX = -halfWidth;
|
|
|
|
const float halfHeight = baInfo[1]/2;
|
|
if (displayCoordZ > halfHeight)
|
|
displayCoordZ = halfHeight;
|
|
else if (displayCoordZ < -halfHeight)
|
|
displayCoordZ = -halfHeight;
|
|
|
|
spot.x = displayCoordX + baInfo[2];
|
|
spot.z = displayCoordZ + baInfo[3];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( spot == null )
|
|
{
|
|
sendSystemMessageTestingOnly(self, "Waypoint: The system was unable to parse a valid waypoint location.");
|
|
}
|
|
else
|
|
{
|
|
obj_id wp = createWaypointInDatapadWithLimits(self, spot);
|
|
if ( isIdValid(wp) )
|
|
{
|
|
if (!wpDifferentPlanet)
|
|
{
|
|
setWaypointActive(wp, true);
|
|
}
|
|
|
|
setWaypointVisible(wp, true);
|
|
|
|
// construct waypoint name
|
|
string wpName = null;
|
|
for (int i = parsedIndex; i < parsedParams.length; ++i)
|
|
{
|
|
if (wpName == null)
|
|
{
|
|
wpName = parsedParams[i];
|
|
}
|
|
else
|
|
{
|
|
wpName += " ";
|
|
wpName += parsedParams[i];
|
|
}
|
|
}
|
|
|
|
if (wpName == null)
|
|
{
|
|
wpName = "Waypoint";
|
|
}
|
|
|
|
setWaypointName(wp, wpName);
|
|
|
|
if ( wpColor != null && !wpColor.equals("") )
|
|
setWaypointColor(wp, wpColor);
|
|
|
|
if (!wpDifferentPlanet)
|
|
{
|
|
if (isIdValid(intendedTarget))
|
|
sendSystemMessageTestingOnly(self, "Waypoint: New waypoint \"" + wpName + "\" created for intended target location (" + (int)displayCoordX + ", " + (int)spot.y + ", " + (int)displayCoordZ + ")");
|
|
else if (isIdValid(lookAtTarget))
|
|
sendSystemMessageTestingOnly(self, "Waypoint: New waypoint \"" + wpName + "\" created for look at target location (" + (int)displayCoordX + ", " + (int)spot.y + ", " + (int)displayCoordZ + ")");
|
|
else
|
|
sendSystemMessageTestingOnly(self, "Waypoint: New waypoint \"" + wpName + "\" created for location (" + (int)displayCoordX + ", " + (int)spot.y + ", " + (int)displayCoordZ + ")");
|
|
}
|
|
else
|
|
{
|
|
const string localizedPlanetName = localize(new string_id("planet_n", spot.area));
|
|
sendSystemMessageTestingOnly(self, "Waypoint: New waypoint \"" + wpName + "\" created for location " + localizedPlanetName + " (" + (int)displayCoordX + ", " + (int)spot.y + ", " + (int)displayCoordZ + ")");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
string_id errorMessage = new string_id("base_player", "too_many_waypoints");
|
|
sendSystemMessage(self, errorMessage);
|
|
}
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
commandHandler cmdSpaceWaypoint()
|
|
{
|
|
string wpColor = null;
|
|
float displayCoordX = 0.0f;
|
|
float displayCoordZ = 0.0f;
|
|
boolean wpDifferentPlanet = false;
|
|
|
|
// parse params; if a valid waypoint color is specified in the params,
|
|
// save off the waypoint color, and remove it from the params list
|
|
int parsedIndex = 0;
|
|
resizeable string[] parsedParams = new string[0];
|
|
if (params != null && !params.equals(""))
|
|
{
|
|
java.util.StringTokenizer st = new java.util.StringTokenizer(params);
|
|
while (st.hasMoreTokens())
|
|
{
|
|
string token = st.nextToken();
|
|
if (wpColor == null)
|
|
{
|
|
for (int i = 0; i < utils.WAYPOINT_COLORS.length; ++i)
|
|
{
|
|
if (token.toLowerCase().equals(utils.WAYPOINT_COLORS[i]))
|
|
{
|
|
wpColor = utils.WAYPOINT_COLORS[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (wpColor == null)
|
|
{
|
|
utils.addElement(parsedParams, token);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
utils.addElement(parsedParams, token);
|
|
}
|
|
}
|
|
}
|
|
|
|
location spot = null;
|
|
if (parsedParams == null || (parsedParams.length <= 0))
|
|
{
|
|
if ( !isIdValid(target) )
|
|
{
|
|
target = space_transition.getContainingShip(self);
|
|
}
|
|
else
|
|
{
|
|
obj_id objContainer = getTopMostContainer(target);
|
|
if(isIdValid(objContainer))
|
|
{
|
|
target = objContainer;// feh
|
|
}
|
|
}
|
|
|
|
spot = getWorldLocation(target);
|
|
|
|
if (spot != null)
|
|
{
|
|
displayCoordX = spot.x;
|
|
displayCoordZ = spot.z;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
string wpGroundPlanet = null;
|
|
vector wpGroundPLanetBuildoutCoords = null;
|
|
string wpSpaceZone = null;
|
|
float wpCoord1 = Float.NEGATIVE_INFINITY;
|
|
float wpCoord2 = Float.NEGATIVE_INFINITY;
|
|
float wpCoord3 = Float.NEGATIVE_INFINITY;
|
|
|
|
wpCoord1 = utils.stringToFloat(parsedParams[parsedIndex]); // is first parameter a float?
|
|
if (wpCoord1 == Float.NEGATIVE_INFINITY)
|
|
{
|
|
// first parameter is not a float, see if it's a ground planet name or a space zone name
|
|
string planet = parsedParams[parsedIndex].toLowerCase();
|
|
for (int i = 0; i < WAYPOINT_GROUND_PLANETS_EXTERNAL.length; ++i)
|
|
{
|
|
if ((planet.equals(WAYPOINT_GROUND_PLANETS_EXTERNAL[i])) && (i < WAYPOINT_GROUND_PLANETS_INTERNAL.length))
|
|
{
|
|
wpGroundPlanet = WAYPOINT_GROUND_PLANETS_INTERNAL[i];
|
|
|
|
if (i < WAYPOINT_GROUND_PLANETS_BUILDOUT_COORDS.length)
|
|
wpGroundPLanetBuildoutCoords = WAYPOINT_GROUND_PLANETS_BUILDOUT_COORDS[i];
|
|
|
|
++parsedIndex;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (wpGroundPlanet == null)
|
|
{
|
|
for (int i = 0; i < WAYPOINT_SPACE_ZONES_EXTERNAL.length; ++i)
|
|
{
|
|
if ((planet.equals(WAYPOINT_SPACE_ZONES_EXTERNAL[i])) && (i < WAYPOINT_SPACE_ZONES_INTERNAL.length))
|
|
{
|
|
wpSpaceZone = WAYPOINT_SPACE_ZONES_INTERNAL[i];
|
|
|
|
++parsedIndex;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (((wpGroundPlanet != null) || (wpSpaceZone != null)) && (parsedIndex < parsedParams.length))
|
|
{
|
|
wpCoord1 = utils.stringToFloat(parsedParams[parsedIndex]); // is next parameter a float?
|
|
}
|
|
}
|
|
|
|
if (wpCoord1 != Float.NEGATIVE_INFINITY) // first waypoint coord specified?
|
|
{
|
|
++parsedIndex;
|
|
if (parsedIndex < parsedParams.length)
|
|
{
|
|
wpCoord2 = utils.stringToFloat(parsedParams[parsedIndex]); // is next parameter a float?
|
|
if (wpCoord2 != Float.NEGATIVE_INFINITY) // next waypoint coord specified?
|
|
{
|
|
++parsedIndex;
|
|
if (parsedIndex < parsedParams.length)
|
|
{
|
|
wpCoord3 = utils.stringToFloat(parsedParams[parsedIndex]); // is next parameter a float?
|
|
if (wpCoord3 != Float.NEGATIVE_INFINITY) // next waypoint coord specified?
|
|
{
|
|
++parsedIndex;
|
|
}
|
|
else if (wpGroundPlanet == null) // only 2 coords specified, don't treat it as a coord, unless we're creating a waypoint for a ground planet
|
|
{
|
|
wpCoord1 = Float.NEGATIVE_INFINITY;
|
|
wpCoord2 = Float.NEGATIVE_INFINITY;
|
|
--parsedIndex;
|
|
--parsedIndex;
|
|
}
|
|
}
|
|
else if (wpGroundPlanet == null) // only 2 coords specified, don't treat it as a coord, unless we're creating a waypoint for a ground planet
|
|
{
|
|
wpCoord1 = Float.NEGATIVE_INFINITY;
|
|
wpCoord2 = Float.NEGATIVE_INFINITY;
|
|
--parsedIndex;
|
|
--parsedIndex;
|
|
}
|
|
}
|
|
else // only 1 coord specified, don't treat it as a coord
|
|
{
|
|
wpCoord1 = Float.NEGATIVE_INFINITY;
|
|
--parsedIndex;
|
|
}
|
|
}
|
|
else // only 1 coord specified, don't treat it as a coord
|
|
{
|
|
wpCoord1 = Float.NEGATIVE_INFINITY;
|
|
--parsedIndex;
|
|
}
|
|
}
|
|
|
|
// validate coords
|
|
if ((wpGroundPlanet != null) && ((wpCoord1 == Float.NEGATIVE_INFINITY) || (wpCoord2 == Float.NEGATIVE_INFINITY)))
|
|
{
|
|
// did not specify valid coords for the specified planet, don't treat it as a coord or a specified planet name
|
|
wpGroundPlanet = null;
|
|
wpCoord1 = Float.NEGATIVE_INFINITY;
|
|
wpCoord2 = Float.NEGATIVE_INFINITY;
|
|
wpCoord3 = Float.NEGATIVE_INFINITY;
|
|
parsedIndex = 0;
|
|
}
|
|
|
|
if ((wpSpaceZone != null) && ((wpCoord1 == Float.NEGATIVE_INFINITY) || (wpCoord2 == Float.NEGATIVE_INFINITY) || (wpCoord3 == Float.NEGATIVE_INFINITY)))
|
|
{
|
|
// did not specify valid coords for the specified space zone, don't treat it as a coord or a specified space zone name
|
|
wpSpaceZone = null;
|
|
wpCoord1 = Float.NEGATIVE_INFINITY;
|
|
wpCoord2 = Float.NEGATIVE_INFINITY;
|
|
wpCoord3 = Float.NEGATIVE_INFINITY;
|
|
parsedIndex = 0;
|
|
}
|
|
|
|
// construct location for waypoint
|
|
if (wpCoord1 == Float.NEGATIVE_INFINITY)
|
|
{
|
|
if ( !isIdValid(target) )
|
|
{
|
|
target = space_transition.getContainingShip(self);
|
|
}
|
|
else
|
|
{
|
|
obj_id objContainer = getTopMostContainer(target);
|
|
if(isIdValid(objContainer))
|
|
{
|
|
target = objContainer;// feh
|
|
}
|
|
}
|
|
|
|
spot = getWorldLocation(target);
|
|
|
|
if (spot != null)
|
|
{
|
|
displayCoordX = spot.x;
|
|
displayCoordZ = spot.z;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (wpCoord3 == Float.NEGATIVE_INFINITY)
|
|
spot = new location(wpCoord1, 0.0f, wpCoord2);
|
|
else
|
|
spot = new location(wpCoord1, wpCoord2, wpCoord3);
|
|
|
|
if (spot != null)
|
|
{
|
|
displayCoordX = spot.x;
|
|
displayCoordZ = spot.z;
|
|
|
|
// if creating waypoint on a ground planet, then coords that are specified
|
|
// on the command line are display coords, convert them to world coords
|
|
// was a different planet specified?
|
|
if ((wpGroundPlanet != null) && (!wpGroundPlanet.equals(spot.area)))
|
|
{
|
|
if (wpGroundPLanetBuildoutCoords != null)
|
|
{
|
|
float[] baInfo = getBuildoutAreaSizeAndCenter(wpGroundPLanetBuildoutCoords.x, wpGroundPLanetBuildoutCoords.z, wpGroundPlanet, true, true);
|
|
|
|
if ((baInfo != null) && (baInfo.length == 4))
|
|
{
|
|
const float halfWidth = baInfo[0]/2;
|
|
if (displayCoordX > halfWidth)
|
|
displayCoordX = halfWidth;
|
|
else if (displayCoordX < -halfWidth)
|
|
displayCoordX = -halfWidth;
|
|
|
|
const float halfHeight = baInfo[1]/2;
|
|
if (displayCoordZ > halfHeight)
|
|
displayCoordZ = halfHeight;
|
|
else if (displayCoordZ < -halfHeight)
|
|
displayCoordZ = -halfHeight;
|
|
|
|
spot.x = displayCoordX + baInfo[2];
|
|
spot.z = displayCoordZ + baInfo[3];
|
|
}
|
|
}
|
|
|
|
wpDifferentPlanet = true;
|
|
spot.area = wpGroundPlanet;
|
|
}
|
|
else if ((wpSpaceZone != null) && (!wpSpaceZone.equals(spot.area)))
|
|
{
|
|
wpDifferentPlanet = true;
|
|
spot.area = wpSpaceZone;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( spot == null )
|
|
{
|
|
sendSystemMessageTestingOnly(self, "Waypoint: The system was unable to parse a valid waypoint location.");
|
|
}
|
|
else
|
|
{
|
|
obj_id wp = createWaypointInDatapadWithLimits(self, spot);
|
|
if ( isIdValid(wp) )
|
|
{
|
|
if (!wpDifferentPlanet)
|
|
{
|
|
setWaypointActive(wp, true);
|
|
}
|
|
|
|
setWaypointVisible(wp, true);
|
|
|
|
// construct waypoint name
|
|
string wpName = null;
|
|
for (int i = parsedIndex; i < parsedParams.length; ++i)
|
|
{
|
|
if (wpName == null)
|
|
{
|
|
wpName = parsedParams[i];
|
|
}
|
|
else
|
|
{
|
|
wpName += " ";
|
|
wpName += parsedParams[i];
|
|
}
|
|
}
|
|
|
|
if (wpName == null)
|
|
{
|
|
wpName = "Waypoint";
|
|
}
|
|
|
|
setWaypointName(wp, wpName);
|
|
|
|
// default space waypoint color
|
|
if ((wpColor == null) && !wpDifferentPlanet)
|
|
{
|
|
wpColor = "space";
|
|
}
|
|
|
|
if ( wpColor != null && !wpColor.equals("") )
|
|
setWaypointColor(wp, wpColor);
|
|
|
|
if (!wpDifferentPlanet)
|
|
{
|
|
sendSystemMessageTestingOnly(self, "Waypoint: New waypoint \"" + wpName + "\" created for location (" + (int)displayCoordX + ", " + (int)spot.y + ", " + (int)displayCoordZ + ")");
|
|
}
|
|
else
|
|
{
|
|
const string localizedPlanetName = localize(new string_id("planet_n", spot.area));
|
|
sendSystemMessageTestingOnly(self, "Waypoint: New waypoint \"" + wpName + "\" created for location " + localizedPlanetName + " (" + (int)displayCoordX + ", " + (int)spot.y + ", " + (int)displayCoordZ + ")");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
string_id errorMessage = new string_id("base_player", "too_many_waypoints");
|
|
sendSystemMessage(self, errorMessage);
|
|
}
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
commandHandler cmdClearQueue()
|
|
{
|
|
queueClear(self);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
/**
|
|
* This handler allows a player indirect access to a crafting tool's prototype slot.
|
|
* It will attept to put the prototype in the player's inventory (or possibly in the world
|
|
* for very large items)
|
|
*/
|
|
commandHandler getPrototype()
|
|
{
|
|
if ( !isIdValid(target) )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
// make sure the target is a crafting tool
|
|
if (!hasObjVar(target, "crafting.tool"))
|
|
return SCRIPT_CONTINUE;
|
|
|
|
// ask the tool for the prototype
|
|
messageTo(target, "getPrototype", null, 0, false);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------------------------
|
|
// CITY MILITIA
|
|
//------------------------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------
|
|
// cmdCityban
|
|
//
|
|
// /cityban command handler
|
|
//------------------------------------------------
|
|
|
|
commandHandler cmdCityban()
|
|
{
|
|
if ( target == self )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
if ( !isPlayer( target ) )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
// Check to see if we are in a city.
|
|
int city_id = city.checkCity( self, true );
|
|
if ( city_id == 0 )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
// Check to see if we are a militaperson.
|
|
obj_id mayor = cityGetLeader( city_id );
|
|
if ( !city.isMilitiaOfCity( self, city_id ) && (self != mayor) )
|
|
{
|
|
sendSystemMessage( self, SID_NOT_MILITIA );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
if(isGod(target) || hasObjVar(target, "gm")) {
|
|
|
|
sendSystemMessage(self, SID_NOT_CSR_BAN);
|
|
|
|
prose_package pp = prose.getPackage(SID_CSR_BAN_ATTEMPT_MSG, getFirstName(self), cityGetName(city_id));
|
|
sendSystemMessageProse(target, pp);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Don't allow the militia to ban the mayor.
|
|
if ( target == mayor )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
// Don't allow a citizen to be banned.
|
|
if ( city.isCitizenOfCity( target, city_id ) )
|
|
{
|
|
sendSystemMessage( self, SID_NOT_CITIZEN_BAN );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// This person is BANNED.
|
|
sendSystemMessage( target, SID_CITY_BANNED );
|
|
int[] banCities = getIntArrayObjVar( target, "city.banlist" );
|
|
if ( banCities == null )
|
|
{
|
|
int[] newBanCities = new int[1];
|
|
newBanCities[0] = city_id;
|
|
|
|
setObjVar( target, "city.banlist", newBanCities );
|
|
}
|
|
else
|
|
{
|
|
// Don't allow dupe entries.
|
|
for ( int i=0; i<banCities.length; i++ )
|
|
{
|
|
if ( banCities[i] == city_id )
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
int[] newBanCities = new int[banCities.length+1];
|
|
for ( int i=0; i<banCities.length; i++ )
|
|
{
|
|
newBanCities[i+1] = banCities[i];
|
|
}
|
|
newBanCities[0] = city_id;
|
|
|
|
setObjVar( target, "city.banlist", newBanCities );
|
|
}
|
|
|
|
prose_package pp = prose.getPackage( SID_CITY_BAN_DONE, target );
|
|
sendSystemMessageProse( self, pp );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//------------------------------------------------
|
|
// cmdCitypardon
|
|
//
|
|
// /citypardon command handler
|
|
//------------------------------------------------
|
|
|
|
commandHandler cmdCitypardon()
|
|
{
|
|
if ( target == self )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
if ( !isPlayer( target ) )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
// Check to see if we are in a city.
|
|
int city_id = city.checkCity( self, true );
|
|
if ( city_id == 0 )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
// Check to see if we are a militaperson.
|
|
obj_id mayor = cityGetLeader( city_id );
|
|
if ( !city.isMilitiaOfCity( self, city_id ) && (self != mayor) )
|
|
{
|
|
sendSystemMessage( self, SID_NOT_MILITIA );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Don't allow the militia to pardon the mayor.
|
|
if ( target == mayor )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
// This person is PARDONED.
|
|
int[] banCities = getIntArrayObjVar( target, "city.banlist" );
|
|
if ( banCities != null )
|
|
{
|
|
int found = 0;
|
|
for ( int i=0; i<banCities.length; i++ )
|
|
{
|
|
if ( banCities[i] == city_id )
|
|
{
|
|
found = 1;
|
|
break;
|
|
}
|
|
}
|
|
if ( found == 0 )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
if ( banCities.length == 1 )
|
|
{
|
|
removeObjVar( target, "city.banlist" );
|
|
}
|
|
else
|
|
{
|
|
int j = 0;
|
|
int[] newBanCities = new int[banCities.length-1];
|
|
for ( int i=0; i<banCities.length; i++ )
|
|
{
|
|
if ( banCities[i] != city_id )
|
|
{
|
|
newBanCities[j] = banCities[i];
|
|
j++;
|
|
}
|
|
}
|
|
setObjVar( target, "city.banlist", newBanCities );
|
|
}
|
|
}
|
|
sendSystemMessage( target, SID_CITY_PARDONED );
|
|
|
|
prose_package pp = prose.getPackage( SID_CITY_PARDON_DONE, target );
|
|
sendSystemMessageProse( self, pp );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------------------------
|
|
// CITY MISC
|
|
//------------------------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------
|
|
// OnCityChanged
|
|
//------------------------------------------------
|
|
|
|
trigger OnCityChanged( int oldCityId, int newCityId )
|
|
{
|
|
if ( (oldCityId != 0) && cityExists(oldCityId) )
|
|
{
|
|
string city_name = cityGetName( oldCityId );
|
|
prose_package pp = prose.getPackage( SID_LEAVE_CITY, city_name );
|
|
sendSystemMessageProse( self, pp );
|
|
}
|
|
|
|
if ( (newCityId != 0) && cityExists(newCityId) )
|
|
{
|
|
int city_rank = city.getCityRank( newCityId );
|
|
string_id rank_name = new string_id( "city/city", "rank"+city_rank );
|
|
string city_name = cityGetName( newCityId );
|
|
string spec = city.cityGetSpecString( newCityId );
|
|
prose_package pp = new prose_package();
|
|
pp.stringId = SID_ENTER_CITY;
|
|
pp.target.set( city_name );
|
|
string specpart = localize(rank_name);
|
|
if ( spec != null && !spec.equals("null") )
|
|
{
|
|
specpart = specpart + ", " + localize( new string_id( "city/city", spec ) );
|
|
}
|
|
|
|
/*
|
|
obj_id mayor = cityGetLeader( newCityId );
|
|
if (isIdValid(mayor))
|
|
{
|
|
string mayorName = cityGetCitizenName( newCityId, mayor );
|
|
if ((mayorName != null) && (mayorName.length() > 0))
|
|
{
|
|
specpart = specpart + ", " + localize( new string_id( "city/city", "mayor_prompt" ) ) + mayorName;
|
|
}
|
|
}
|
|
*/
|
|
|
|
int factionId = cityGetFaction(newCityId);
|
|
if (##"imperial" == factionId)
|
|
specpart = specpart + ", Imperial aligned";
|
|
else if (##"rebel" == factionId)
|
|
specpart = specpart + ", Rebel aligned";
|
|
|
|
pp.other.set( specpart );
|
|
sendSystemMessageProse( self, pp );
|
|
|
|
//Update 8: Adding City Visitor Message
|
|
obj_id cityHallId = cityGetCityHall(newCityId);
|
|
string cityName = cityGetName(newCityId);
|
|
if(hasObjVar(cityHallId, "city_visitor_message"))
|
|
{
|
|
string cityVisitorMessage = getStringObjVar(cityHallId, "city_visitor_message");
|
|
sendConsoleMessage(self, "City(" + cityName + ") Message: " + cityVisitorMessage + "\\#DFDFDF");
|
|
}
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//------------------------------------------------
|
|
// /grantZoningRights
|
|
//------------------------------------------------
|
|
|
|
commandHandler cmdGrantZoningRights()
|
|
{
|
|
if ( target == self )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
if(!isPlayer(target))
|
|
return SCRIPT_CONTINUE;
|
|
|
|
//set the scriptVar on 'self' of your target for use later.
|
|
utils.setScriptVar(self, "zoning_rights_target", target);
|
|
//give the player the SUI
|
|
sui.listbox(self, self, "@city/city:zoning_rights_p", sui.OK_CANCEL, "@city/city:zoning_rights_t", ZONING_RIGHTS_ARRAY, "handleZoningRightsSelect", true);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
|
|
}
|
|
|
|
messageHandler handleZoningRightsSelect()
|
|
{
|
|
obj_id player = sui.getPlayerId(params);
|
|
|
|
int btn = sui.getIntButtonPressed(params);
|
|
if(btn == sui.BP_CANCEL)
|
|
{
|
|
utils.removeScriptVar(player, "zoning_rights_target");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
if(!utils.hasScriptVar(player, "zoning_rights_target"))
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
obj_id target = utils.getObjIdScriptVar(player, "zoning_rights_target");
|
|
utils.removeScriptVar(player, "zoning_rights_target");
|
|
|
|
obj_id top = getTopMostContainer(player);
|
|
int city_id = getCityAtLocation(getLocation(top), 0);
|
|
|
|
//if you are not in a city's boundary - bail.
|
|
if(city_id <= 0)
|
|
{
|
|
sendSystemMessage(player, SID_NOT_IN_CITY_LIMITS);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
int idx = sui.getListboxSelectedRow(params);
|
|
|
|
if(idx < 0)
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
switch (idx)
|
|
{
|
|
case 0:
|
|
handleCmdGrantZoningRights(player, target, city_id);
|
|
break;
|
|
case 1:
|
|
handleStorytellerZoningRights(player, target, city_id);
|
|
break;
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
void handleCmdGrantZoningRights(obj_id player, obj_id target, int city_id)
|
|
{
|
|
if(!isIdValid(player) || !isIdValid(target))
|
|
return;
|
|
if(target == player)
|
|
return;
|
|
if(!isPlayer(target))
|
|
return;
|
|
|
|
obj_id mayor = cityGetLeader(city_id);
|
|
|
|
if((mayor != player) && !city.isMilitiaOfCity(player, city_id))
|
|
{
|
|
sendSystemMessage(player, SID_GRANT_RIGHTS_FAIL);
|
|
return;
|
|
}
|
|
|
|
if(hasObjVar(target, "city.zoning_rights"))
|
|
{
|
|
int other_city_id = getIntObjVar(target, "city.zoning_rights");
|
|
if(other_city_id == city_id)
|
|
{
|
|
int curt = getGameTime();
|
|
int rights_time = getIntObjVar(target, "city.zoning_rights_time");
|
|
if(curt - rights_time < 24*60*60)
|
|
{
|
|
removeObjVar(target, "city.zoning_rights");
|
|
removeObjVar(target, "city.zoning_rights_time");
|
|
sendSystemMessage(player, SID_RIGHTS_REVOKED);
|
|
sendSystemMessage(target, SID_RIGHTS_REVOKED_OTHER);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Grant them zoning rights.
|
|
setObjVar(target, "city.zoning_rights", city_id);
|
|
setObjVar(target, "city.zoning_rights_time", getGameTime());
|
|
prose_package pp = prose.getPackage(SID_RIGHTS_GRANTED, cityGetName(city_id));
|
|
sendSystemMessageProse(target, pp);
|
|
pp = prose.getPackage(SID_RIGHTS_GRANTED_SELF, getName(target));
|
|
sendSystemMessageProse(player, pp);
|
|
|
|
return;
|
|
}
|
|
|
|
void handleStorytellerZoningRights(obj_id player, obj_id target, int city_id)
|
|
{
|
|
//LOG("sissynoid", "ENTERED: handleStorytellerZoningRights");
|
|
if(!isIdValid(player) || !isIdValid(target))
|
|
return;
|
|
if(target == player)
|
|
return;
|
|
if(!isPlayer(target))
|
|
return;
|
|
|
|
obj_id mayor = cityGetLeader(city_id);
|
|
|
|
if((mayor != player) && !city.isMilitiaOfCity(player, city_id))
|
|
{
|
|
sendSystemMessage(player, SID_ST_GRANT_RIGHTS_FAIL);
|
|
return;
|
|
}
|
|
|
|
if(hasObjVar(target, "city.st_zoning_rights"))
|
|
{
|
|
//LOG("sissynoid", "HAS OBJVAR: city.st_zoning_rights - retrieving info");
|
|
//he has st zoning rights. we need to clean up/add to array
|
|
int[] city_id_array = getIntArrayObjVar(target, "city.st_zoning_rights");
|
|
int[] zoning_time_array = getIntArrayObjVar(target, "city.st_zoning_rights_time");
|
|
resizeable int[] ids = city_id_array;
|
|
resizeable int[] times = zoning_time_array;
|
|
// resizeable obj_id[] loadedStructuresFinal = new obj_id[0];
|
|
for(int i = 0; i < city_id_array.length; i++)
|
|
{
|
|
if(city_id_array[i] == city_id)
|
|
{
|
|
//LOG("sissynoid", "City ID MATCH: Player has this ID in his ObjVar array.");
|
|
int curt = getGameTime();
|
|
if(curt - zoning_time_array[i] < 24*60*60)
|
|
{
|
|
//LOG("sissynoid", "REVOKING RIGHTS - less than 24 Hours has passed.");
|
|
//we are revoking - send messages and remove.
|
|
ids.removeElementAt(i);
|
|
times.removeElementAt(i);
|
|
sendSystemMessage(player, SID_ST_RIGHTS_REVOKED);
|
|
sendSystemMessage(target, SID_ST_RIGHTS_REVOKED_OTHER);
|
|
|
|
int[] stampIdsArray = ids;
|
|
int[] stampTimesArray = times;
|
|
setObjVar(target, "city.st_zoning_rights", stampIdsArray);
|
|
setObjVar(target, "city.st_zoning_rights_time", stampTimesArray);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
//LOG("sissynoid", "REMOVING RIGHTS - More than 24 Hours has passed.");
|
|
//it has expired - just remove.
|
|
ids.removeElementAt(i);
|
|
times.removeElementAt(i);
|
|
|
|
int[] stampIdsArray = ids;
|
|
int[] stampTimesArray = times;
|
|
setObjVar(target, "city.st_zoning_rights", stampIdsArray);
|
|
setObjVar(target, "city.st_zoning_rights_time", stampTimesArray);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
//LOG("sissynoid", "NO MATCHES - Granting ST Zoning Rights to Player");
|
|
prose_package pp = prose.getPackage(SID_ST_RIGHTS_GRANTED, cityGetName(city_id));
|
|
sendSystemMessageProse(target, pp);
|
|
pp = prose.getPackage(SID_ST_RIGHTS_GRANTED_SELF, getName(target));
|
|
sendSystemMessageProse(player, pp);
|
|
//no matches occurred - let's grant them privileges
|
|
utils.addElement(ids, city_id);
|
|
utils.addElement(times, getGameTime());
|
|
//they now have privileges, stamp back on the character.
|
|
int[] stampIdsArray = ids;
|
|
int[] stampTimesArray = times;
|
|
setObjVar(target, "city.st_zoning_rights", stampIdsArray);
|
|
setObjVar(target, "city.st_zoning_rights_time", stampTimesArray);
|
|
|
|
}
|
|
//has no objvar - newbies need rights too!
|
|
else
|
|
{
|
|
//LOG("sissynoid", "NEWBIE - no objvars - granting access for first time.");
|
|
int[] id_array = new int[] {city_id};
|
|
int[] time_array = new int[] {getGameTime()};
|
|
setObjVar(target, "city.st_zoning_rights", id_array);
|
|
setObjVar(target, "city.st_zoning_rights_time", time_array);
|
|
prose_package pp = prose.getPackage(SID_ST_RIGHTS_GRANTED, cityGetName(city_id));
|
|
sendSystemMessageProse(target, pp);
|
|
pp = prose.getPackage(SID_ST_RIGHTS_GRANTED_SELF, getName(target));
|
|
sendSystemMessageProse(player, pp);
|
|
}
|
|
return;
|
|
}
|
|
|
|
commandHandler cmdGrantStorytellerZoningRights()
|
|
{
|
|
//call ST zoning code
|
|
if(!isIdValid(self) || !isIdValid(target))
|
|
return SCRIPT_CONTINUE;
|
|
obj_id player = self;
|
|
obj_id top = getTopMostContainer(player);
|
|
int city_id = getCityAtLocation(getLocation(top), 0);
|
|
|
|
if(city_id <= 0)
|
|
{
|
|
sendSystemMessage(player, SID_NOT_IN_CITY_LIMITS);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
handleStorytellerZoningRights(player, target, city_id);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//------------------------------------------------
|
|
// /installMissionTerminal
|
|
//------------------------------------------------
|
|
|
|
commandHandler cmdInstallMissionTerminal()
|
|
{
|
|
// Make sure we are mayor of this city.
|
|
int city_id = city.checkMayorCity( self, true );
|
|
if ( city_id == 0 )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
// Pop up the mission terminal dialog.
|
|
string[] rawTerminalTypes = dataTableGetStringColumn( CITY_MISSION_TERMINALS, "STRING" );
|
|
string[] terminalTypes = new string[rawTerminalTypes.length+1];
|
|
terminalTypes[0] = "@city/city:current_mt " + city.getMTCount( city_id ) + "/" + city.getMaxMTCount( city_id );
|
|
for ( int i=0; i<rawTerminalTypes.length; i++ )
|
|
{
|
|
terminalTypes[i+1] = rawTerminalTypes[i];
|
|
}
|
|
sui.listbox( self, self, "@city/city:job_d", sui.OK_CANCEL, "@city/city:job_n", terminalTypes, "handleInstallMissionTerminal" );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//------------------------------------------------
|
|
// handleInstallMissionTerminal
|
|
//------------------------------------------------
|
|
|
|
messageHandler handleInstallMissionTerminal()
|
|
{
|
|
int idx = sui.getListboxSelectedRow( params );
|
|
if ( idx < 0 ) idx = 0;
|
|
int btn = sui.getIntButtonPressed( params );
|
|
if ( btn == sui.BP_CANCEL )
|
|
return SCRIPT_CONTINUE;
|
|
if ( idx == 0 )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
int city_id = city.checkMayorCity( self, true );
|
|
if ( city_id == 0 )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
// The mayor wants to drop a mission terminal here.
|
|
int maxmt = city.getMaxMTCount( city_id );
|
|
int curmt = city.getMTCount( city_id );
|
|
if ( curmt+1 > maxmt )
|
|
{
|
|
sendSystemMessage( self, SID_NO_MORE_MT );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Determine if factional.
|
|
int factional = dataTableGetInt( CITY_MISSION_TERMINALS, idx-1, "FACTION" );
|
|
if ( (factional == 1) && !hasSkill( self, "social_politician_martial_04" ) )
|
|
{
|
|
sendSystemMessage( self, SID_NO_FACTIONAL );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
obj_id structure = getTopMostContainer( self );
|
|
if ( isIdValid(structure) && (structure != self) )
|
|
{
|
|
// Make sure this structure is civic.
|
|
if ( !player_structure.isCivic( structure ) )
|
|
{
|
|
sendSystemMessage( self, SID_CIVIC_ONLY );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
}
|
|
|
|
// Charge the placement fee.
|
|
int cost = 1000;
|
|
|
|
dictionary payparams = new dictionary();
|
|
payparams.put( "city_id", city_id );
|
|
payparams.put( "cost", cost );
|
|
payparams.put( "idx", idx );
|
|
transferBankCreditsToNamedAccount( cityGetCityHall( city_id ), money.ACCT_CITY, cost, "handleMTFeeSuccess", "handleMTFeeFail", payparams );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//------------------------------------------------
|
|
// handleMTFeeSuccess
|
|
//------------------------------------------------
|
|
|
|
messageHandler handleMTFeeSuccess()
|
|
{
|
|
int city_id = params.getInt( "city_id" );
|
|
int idx = params.getInt( "idx" );
|
|
string[] terminalTemplates = dataTableGetStringColumn( CITY_MISSION_TERMINALS, "TEMPLATE" );
|
|
city.addMissionTerminal( city_id, self, terminalTemplates[idx-1] );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//------------------------------------------------
|
|
// handleMTFeeFail
|
|
//------------------------------------------------
|
|
|
|
messageHandler handleMTFeeFail()
|
|
{
|
|
int cost = params.getInt( "cost" );
|
|
prose_package pp = prose.getPackage( SID_CITY_NO_MONEY, cost );
|
|
sendSystemMessageProse( self, pp );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//------------------------------------------------
|
|
// handleSTFeeSuccess
|
|
//------------------------------------------------
|
|
|
|
messageHandler handleSTFeeSuccess()
|
|
{
|
|
int city_id = params.getInt( "city_id" );
|
|
int idx = params.getInt( "idx" );
|
|
string[] trainerTemplates = dataTableGetStringColumn( CITY_SKILL_TRAINERS, "TEMPLATE" );
|
|
city.addSkillTrainer( city_id, self, trainerTemplates[idx-1] );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//------------------------------------------------
|
|
// handleSTFeeFail
|
|
//------------------------------------------------
|
|
|
|
messageHandler handleSTFeeFail()
|
|
{
|
|
int cost = params.getInt( "cost" );
|
|
prose_package pp = prose.getPackage( SID_CITY_NO_MONEY, cost );
|
|
sendSystemMessageProse( self, pp );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//------------------------------------------------
|
|
// /cityInfo
|
|
// LIVE CSR command to get city info.
|
|
// UNLOCALIZED CSR COMMAND
|
|
//------------------------------------------------
|
|
|
|
commandHandler cmdCityInfo()
|
|
{
|
|
// Get a list of all the cities.
|
|
int[] cities = getAllCityIds();
|
|
if ( (cities == null) || (cities.length == 0) )
|
|
{
|
|
sendSystemMessage( self, new string_id( "city/city", "csr_no_cities" ) );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
string[] planets = { "corellia", "dantooine", "lok", "naboo", "rori", "talus", "tatooine" };
|
|
java.util.Map counts = new java.util.HashMap();
|
|
|
|
string[] cityPlanet = new string[cities.length];
|
|
string[] cityName = new string[cities.length];
|
|
for ( int i=0; i<cities.length; i++ )
|
|
{
|
|
// Build a list of cities by planet.
|
|
location cityLoc = cityGetLocation( cities[i] );
|
|
cityPlanet[i] = cityLoc.area;
|
|
cityName[i] = cityGetName( cities[i] );
|
|
|
|
int count = 0;
|
|
Integer icount = (Integer) counts.get( cityPlanet[i] );
|
|
if ( icount != null )
|
|
count = icount.intValue();
|
|
count++;
|
|
counts.put( cityPlanet[i], new Integer( count ) );
|
|
}
|
|
|
|
string[] planetList = new string[planets.length];
|
|
for ( int i=0; i<planets.length; i++ )
|
|
{
|
|
Integer count = (Integer) counts.get( planets[i] );
|
|
if ( count == null )
|
|
planetList[i] = "\\#888888 " + planets[i] + " (0)";
|
|
else
|
|
planetList[i] = "\\#00FF00 " + planets[i] + "\\#FFFFFF (" + count + ")";
|
|
}
|
|
|
|
utils.setScriptVar( self, "planetList", planetList );
|
|
sui.listbox( self, self, "@city/city:cityplanets_d", sui.OK_CANCEL, "@city/city:cityinfo_n", planetList, "handleSelectPlanet" );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleSelectPlanet()
|
|
{
|
|
int idx = sui.getListboxSelectedRow( params );
|
|
if ( idx < 0 ) idx = 0;
|
|
int btn = sui.getIntButtonPressed( params );
|
|
if ( btn == sui.BP_CANCEL )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
string[] planets = { "corellia", "dantooine", "lok", "naboo", "rori", "talus", "tatooine" };
|
|
string planet = planets[idx];
|
|
int[] cities = getAllCityIds();
|
|
|
|
// Get the names of these cities.
|
|
int count = 0;
|
|
int[] planetCities = new int[cities.length];
|
|
for ( int i=0; i<cities.length; i++ )
|
|
{
|
|
location cityLoc = cityGetLocation( cities[i] );
|
|
if ( cityLoc.area.equals( planet ) )
|
|
{
|
|
planetCities[i] = 1;
|
|
count++;
|
|
}
|
|
else
|
|
planetCities[i] = 0;
|
|
}
|
|
|
|
string[] cityList = new string[count];
|
|
int[] planetCityIds = new int[count];
|
|
|
|
int j = 0;
|
|
for ( int i=0; i<planetCities.length; i++ )
|
|
{
|
|
if ( planetCities[i] == 1 )
|
|
{
|
|
int cityRank = city.getCityRank( cities[i] );
|
|
string cityName = cityGetName( cities[i] );
|
|
planetCityIds[j] = cities[i];
|
|
cityList[j++] = "\\#00FF00 " + cityName + "\\#FFFFFF (" + cities[i] + ")" + "\\#BBBBBB Rank " + cityRank;
|
|
}
|
|
}
|
|
|
|
utils.setScriptVar( self, "cities", planetCityIds );
|
|
utils.setScriptVar( self, "cityList", cityList );
|
|
sui.listbox( self, self, "@city/city:cityinfo_d", sui.OK_CANCEL, "@city/city:cityinfo_n", cityList, "handleSelectCity", true, false );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleSelectCity()
|
|
{
|
|
int idx = sui.getListboxSelectedRow( params );
|
|
if ( idx < 0 ) idx = 0;
|
|
int btn = sui.getIntButtonPressed( params );
|
|
if ( btn == sui.BP_CANCEL )
|
|
{
|
|
string[] planetList = utils.getStringArrayScriptVar( self, "planetList" );
|
|
sui.listbox( self, self, "@city/city:cityplanets_d", sui.OK_CANCEL, "@city/city:cityinfo_n", planetList, "handleSelectPlanet" );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
int[] cities = utils.getIntArrayScriptVar( self, "cities" );
|
|
int city_id = cities[idx];
|
|
|
|
// Get info on this city for display.
|
|
string cityName = cityGetName( city_id );
|
|
obj_id cityHall = cityGetCityHall( city_id );
|
|
location cityLoc = cityGetLocation( city_id );
|
|
obj_id mayor = cityGetLeader( city_id );
|
|
string mayorName = cityGetCitizenName( city_id, mayor );
|
|
obj_id[] citizens = cityGetCitizenIds( city_id );
|
|
obj_id[] structures = cityGetStructureIds( city_id );
|
|
int cityRank = city.getCityRank( city_id );
|
|
int numCitizens = citizens.length;
|
|
int numStructures = structures.length;
|
|
|
|
int incomeTax = cityGetIncomeTax( city_id );
|
|
int propertyTax = cityGetPropertyTax( city_id );
|
|
int salesTax = cityGetSalesTax( city_id );
|
|
|
|
string[] cityInfo = new string[9];
|
|
|
|
cityInfo[0] = "\\#00FF00 Name: \\#FFFFFF " + cityName;
|
|
cityInfo[1] = "\\#00FF00 Hall ID: \\#FFFFFF " + cityHall;
|
|
cityInfo[2] = "\\#00FF00 Location: \\#FFFFFF " + cityLoc;
|
|
cityInfo[3] = "\\#00FF00 Mayor: \\#FFFFFF " + mayorName + " (" + mayor + ")";
|
|
cityInfo[4] = "\\#00FF00 Rank: \\#FFFFFF " + cityRank;
|
|
cityInfo[5] = "\\#00FF00 # Citizens: \\#FFFFFF " + numCitizens;
|
|
cityInfo[6] = "\\#00FF00 # Structures: \\#FFFFFF " + numStructures;
|
|
cityInfo[7] = "\\#00FF00 Taxes (Income/Property/Sales): \\#FFFFFF " + incomeTax + "/" + propertyTax + "/" + salesTax;
|
|
cityInfo[8] = "\\#00FF00 Voting Information";
|
|
|
|
utils.setScriptVar( self, "cityinfo", city_id );
|
|
utils.setScriptVar( self, "cityloc", cityLoc );
|
|
|
|
utils.setScriptVar( self, "cityInfo", cityInfo );
|
|
sui.listbox( self, self, "@city/city:cityinfos_d", sui.OK_CANCEL, "@city/city:cityinfos_n", cityInfo, "handleSelectCityInfo" );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleSelectCityInfo()
|
|
{
|
|
int idx = sui.getListboxSelectedRow( params );
|
|
if ( idx < 0 ) idx = 0;
|
|
int btn = sui.getIntButtonPressed( params );
|
|
if ( btn == sui.BP_CANCEL )
|
|
{
|
|
string[] cityList = utils.getStringArrayScriptVar( self, "cityList" );
|
|
sui.listbox( self, self, "@city/city:cityinfo_d", sui.OK_CANCEL, "@city/city:cityinfo_n", cityList, "handleSelectCity", true, false );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
int city_id = utils.getIntScriptVar( self, "cityinfo" );
|
|
|
|
if ( idx == 2 )
|
|
{
|
|
// Travel to that location.
|
|
location loc = utils.getLocationScriptVar( self, "cityloc" );
|
|
warpPlayer( self, loc.area, loc.x, loc.y, loc.z, loc.cell, 0, 0, 0, null, false );
|
|
}
|
|
else if ( idx == 5 )
|
|
{
|
|
// Display a list of citizens.
|
|
obj_id[] citizens = cityGetCitizenIds( city_id );
|
|
string[] civInfo = new string[citizens.length];
|
|
|
|
for ( int i=0; i<citizens.length; i++ )
|
|
{
|
|
string militia = "";
|
|
if ( city.hasMilitiaFlag( citizens[i], city_id ) )
|
|
{
|
|
militia = "\\#FF0000 Militia";
|
|
}
|
|
|
|
string citName = cityGetCitizenName( city_id, citizens[i] );
|
|
civInfo[i] = "\\#00FF00 " + citName + "\\#FFFFFF (" + citizens[i] + ")" + militia;
|
|
}
|
|
|
|
sui.listbox( self, self, "@city/city:civinfo_d", sui.OK_CANCEL, "@city/city:cityinfo_n", civInfo, "handleNothing", true, false );
|
|
}
|
|
else if ( idx == 6 )
|
|
{
|
|
// Display a list of structures.
|
|
obj_id[] structures = cityGetStructureIds( city_id );
|
|
string[] strInfo = new string[structures.length];
|
|
|
|
for ( int i=0; i<structures.length; i++ )
|
|
{
|
|
int typeflags = cityGetStructureType( city_id, structures[i] );
|
|
string typestring = "";
|
|
if ( 0 != (typeflags & city.SF_MISSION_TERMINAL) )
|
|
typestring = "\\#AAAAAA (Mission Terminal)";
|
|
else if ( 0 != (typeflags & city.SF_SKILL_TRAINER) )
|
|
typestring = "\\#AAAAAA (Skill Trainer)";
|
|
else if ( 0 != (typeflags & city.SF_DECORATION) )
|
|
typestring = "\\#AAAAAA (Decoration)";
|
|
else if ( 0 != (typeflags & city.SF_COST_CITY_HALL) )
|
|
typestring = "\\#AAAAAA (City Hall)";
|
|
|
|
strInfo[i] = "\\#00FF00 " + getTemplateName( structures[i] ) + "\\#FFFFFF (" + structures[i] + ")" + typestring;
|
|
}
|
|
|
|
sui.listbox( self, self, "@city/city:strinfo_d", sui.OK_CANCEL, "@city/city:cityinfo_n", strInfo, "handleNothing", true, false );
|
|
}
|
|
else if ( idx == 8 )
|
|
{
|
|
// We want voting info.
|
|
resizeable string[] vote_names = new string[0];
|
|
resizeable obj_id[] vote_ids = new obj_id[0];
|
|
resizeable int[] vote_counts = new int[0];
|
|
obj_id[] citizens = cityGetCitizenIds( city_id );
|
|
for ( int i=0; i<citizens.length; i++ )
|
|
{
|
|
if ( !isIdValid( citizens[i] ) )
|
|
continue;
|
|
|
|
boolean found = false;
|
|
|
|
obj_id vote = cityGetCitizenAllegiance( city_id, citizens[i] );
|
|
if ( isIdValid(vote) )
|
|
{
|
|
for ( int j=0; (j<vote_ids.length); j++ )
|
|
{
|
|
// Increment vote count for a person who has been voted for.
|
|
if ( vote_ids[j] == vote )
|
|
{
|
|
vote_counts[j] = vote_counts[j] + 1;
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( !found )
|
|
{
|
|
// Person has not been voted for yet.
|
|
utils.addElement( vote_ids, vote );
|
|
utils.addElement( vote_counts, 1 );
|
|
utils.addElement( vote_names, cityGetCitizenName( city_id, citizens[i] ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
utils.setScriptVar( self, "votes_ids", vote_ids );
|
|
|
|
obj_id mayor = cityGetLeader( city_id );
|
|
string[] voteInfo = new string[vote_names.length];
|
|
for ( int i=0; i<voteInfo.length; i++ )
|
|
{
|
|
if ( vote_ids[i] == mayor )
|
|
voteInfo[i] = "\\#00FF00 "+ vote_names[i] + "\\#AAAAFF Votes: " + vote_counts[i] + "\\#FFFFFF (" + vote_ids[i] + ") " + "\\#AAAAAA (Incumbent)";
|
|
else
|
|
voteInfo[i] = "\\#00FF00 "+ vote_names[i] + "\\#AAAAFF Votes: " + vote_counts[i] + "\\#FFFFFF (" + vote_ids[i] + ")";
|
|
}
|
|
|
|
sui.listbox( self, self, "@city/city:voteinfo_d", sui.OK_CANCEL, "@city/city:cityinfo_n", voteInfo, "handleSelectRunner", true, false );
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleSelectRunner()
|
|
{
|
|
int idx = sui.getListboxSelectedRow( params );
|
|
if ( idx < 0 ) idx = 0;
|
|
int btn = sui.getIntButtonPressed( params );
|
|
if ( btn == sui.BP_CANCEL )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
int city_id = utils.getIntScriptVar( self, "cityinfo" );
|
|
obj_id[] runners = utils.getObjIdArrayScriptVar( self, "votes_ids" );
|
|
obj_id runner = runners[idx];
|
|
|
|
resizeable string[] vote_names = new string[0];
|
|
resizeable obj_id[] vote_ids = new obj_id[0];
|
|
obj_id[] citizens = cityGetCitizenIds( city_id );
|
|
for ( int i=0; i<citizens.length; i++ )
|
|
{
|
|
if ( !isIdValid( citizens[i] ) )
|
|
continue;
|
|
boolean found = false;
|
|
obj_id vote = cityGetCitizenAllegiance( city_id, citizens[i] );
|
|
if ( vote == runner )
|
|
{
|
|
utils.addElement( vote_ids, citizens[i] );
|
|
utils.addElement( vote_names, cityGetCitizenName( city_id, citizens[i] ) );
|
|
}
|
|
}
|
|
|
|
string[] voteInfo = new string[vote_names.length];
|
|
for ( int i=0; i<voteInfo.length; i++ )
|
|
{
|
|
voteInfo[i] = "\\#00FF00 "+ vote_names[i] + "\\#FFFFFF ("+ vote_ids[i] +")";
|
|
}
|
|
|
|
sui.listbox( self, self, "@city/city:voterinfo_d", sui.OK_CANCEL, "@city/city:cityinfo_n", voteInfo, "handleNothing", true, false );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//------------------------------------------------
|
|
// END: /cityInfo
|
|
//------------------------------------------------
|
|
|
|
|
|
|
|
|
|
trigger OnSkillGranted(string skillName)
|
|
{
|
|
if (!hasObjVar(self, "clickRespec.granting") && !hasObjVar(self, "npcRespec.inProgress"))
|
|
{
|
|
if ( getLevel( self ) <= 1 )
|
|
{
|
|
playClientEffectObj(self, "clienteffect/skill_granted.cef", self, null);
|
|
showFlyText(self, new string_id("cbt_spam", "skill_up"), 2.5f, colors.YELLOWGREEN);
|
|
}
|
|
}
|
|
|
|
//this does all the appropriate checks, such as "Is this a master skill?"
|
|
// and "does the player already have it?"
|
|
badge.grantMasterSkillBadge( self, skillName );
|
|
|
|
// 2/2006 mhalash: No more armor hindrance
|
|
// armor.calculateArmorHinderances(self);
|
|
|
|
//check for worn item effects we may now qualify for
|
|
static_item.validateWornEffects(self);
|
|
|
|
// check to give new player helper droid if starting profession novice skill.
|
|
if ( skillName.endsWith("_novice") )
|
|
{
|
|
//this is where default flags are set and PVPTYPE_NEUTRAL is handled and so on:
|
|
if (!setupNovicePilotSkill( self, skillName ))
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
/*
|
|
if ( skillName.startsWith("force_discipline") )
|
|
{
|
|
if ( jedi_trials.isEligibleForJediKnightTrials(self) )
|
|
{
|
|
messageTo(self, "handleStartJediKnightTrials", null, 15, false);
|
|
}
|
|
}
|
|
*/
|
|
|
|
if ( !allowedBySpaceExpansion( self, skillName ) )
|
|
return SCRIPT_OVERRIDE;
|
|
|
|
if (skillName.startsWith("expertise_"))
|
|
{
|
|
expertise.cacheExpertiseProcReacList(self);
|
|
armor.recalculateArmorForPlayer(self);
|
|
|
|
if(utils.isProfession(self, utils.SMUGGLER))
|
|
{
|
|
messageTo(self, "applySmugglingBonuses", null, 1.0f, false);
|
|
}
|
|
|
|
if(utils.isProfession(self, utils.FORCE_SENSITIVE))
|
|
{
|
|
if(buff.isInStance(self))
|
|
{
|
|
buff.removeBuff(self, jedi.JEDI_STANCE);
|
|
buff.applyBuff(self, jedi.JEDI_STANCE);
|
|
}
|
|
|
|
if(buff.isInFocus(self))
|
|
{
|
|
buff.removeBuff(self, jedi.JEDI_FOCUS);
|
|
buff.applyBuff(self, jedi.JEDI_FOCUS);
|
|
}
|
|
}
|
|
|
|
// verify that the player can have this ability
|
|
if(!expertise.isProfAllowedSkill(self, skillName))
|
|
{
|
|
//if you cant, then revoke it.
|
|
revokeSkillSilent(self, skillName);
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
obj_id tempWeapon = getObjectInSlot(self, "hold_r");
|
|
|
|
if(isIdValid(tempWeapon))
|
|
{
|
|
weapons.adjustWeaponRangeForExpertise(self, tempWeapon, true);
|
|
}
|
|
|
|
skill.recalcPlayerPools(self, false);
|
|
}
|
|
|
|
// For expertise and The Future!
|
|
recomputeCommandSeries(self);
|
|
|
|
// Update our beast stats if applicable.
|
|
beast_lib.verifyAndUpdateCalledBeastStats(self);
|
|
|
|
trial.bumpSession(self, "displayDefensiveMods");
|
|
messageTo(self, "setDisplayOnlyDefensiveMods", trial.getSessionDict(self, "displayDefensiveMods") , 5, false);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleStartJediKnightTrials()
|
|
{
|
|
if ( !hasScript(self, jedi_trials.KNIGHT_TRIALS_SCRIPT) )
|
|
{
|
|
attachScript(self, jedi_trials.KNIGHT_TRIALS_SCRIPT);
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnStartCharacterUpload(byte[] results, modifiable_int resultSize, boolean w, boolean ao)
|
|
{
|
|
Boolean withItems = new Boolean(w);
|
|
dictionary params = new dictionary();
|
|
params.put("withItems", w);
|
|
params.put("allowOverride", ao);
|
|
Object[] triggerParams = new Object[2];
|
|
triggerParams[0] = self;
|
|
triggerParams[1] = params;
|
|
|
|
CustomerServiceLog("CharacterTransfer", "OnStartCharacterUpload(withItems=" + withItems + ", allowOverride=" + ao + ")");
|
|
|
|
resultSize.set(0);
|
|
string result = null;
|
|
try
|
|
{
|
|
int err = script_entry.runScripts("OnUploadCharacter", triggerParams);
|
|
if(err == SCRIPT_CONTINUE)
|
|
{
|
|
byte[] tmp = params.pack();
|
|
if(tmp.length < results.length)
|
|
{
|
|
int i;
|
|
for(i = 0; i < tmp.length; ++i)
|
|
{
|
|
results[i] = tmp[i];
|
|
}
|
|
resultSize.set(tmp.length);
|
|
}
|
|
else
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnStartCharacterUpload(withItems=" + withItems + ") tmp.length=" + tmp.length + " is >= results.length=" + results.length + ", not enough buffer space to pack the dictionary! character transfer will FAIL");
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnStartCharacterUpload(withItems=" + withItems + ") runScripts(\"OnUploadCharacter\") returned SCRIPT_OVERRIDE, character transfer will FAIL");
|
|
const string_id mailTransferFailedScriptError = new string_id("character_transfer", "failed_internal_script_error");
|
|
const string_id mailTransferFailedSubject = new string_id("character_transfer", "failed_subject");
|
|
utils.sendMail(mailTransferFailedScriptError, mailTransferFailedScriptError, self, "System");
|
|
|
|
resultSize.set(0);
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
}
|
|
catch(Throwable t)
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnStartCharacterUpload(withItems=" + withItems + ") : an exception was thrown, character transfer will FAIL : " + t);
|
|
const string_id mailTransferFailedScriptError = new string_id("character_transfer", "failed_internal_script_error");
|
|
const string_id mailTransferFailedSubject = new string_id("character_transfer", "failed_subject");
|
|
utils.sendMail(mailTransferFailedScriptError, mailTransferFailedScriptError, self, "System");
|
|
|
|
result = null;
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
boolean ctsCheckAndLogUniqueStaticItemAlreadyExists(obj_id container, dictionary itemDictionary)
|
|
{
|
|
if (isIdNull(container) || (itemDictionary == null))
|
|
return false;
|
|
|
|
if (itemDictionary.containsKey("staticItemName"))
|
|
{
|
|
String staticItemName = itemDictionary.getString("staticItemName");
|
|
if (staticItemName == null)
|
|
return false;
|
|
|
|
if (!static_item.isUniqueStaticItem(staticItemName))
|
|
return false;
|
|
|
|
obj_id containerOwnerId = getOwner(container);
|
|
if (isIdNull(containerOwnerId))
|
|
return false;
|
|
|
|
if (!isPlayer(containerOwnerId))
|
|
return false;
|
|
|
|
if (utils.playerHasStaticItemInBankOrInventory(containerOwnerId, staticItemName))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "unique static item " + staticItemName + " already exists");
|
|
return true;
|
|
}
|
|
|
|
if (utils.playerHasStaticItemInAppearanceInventory(containerOwnerId, staticItemName))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "unique static item " + staticItemName + " already exists");
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
boolean ctsHasExceededResourceTransferLimit(int crateCountLimit, int currentCrateCount, long unitCountLimit, long currentUnitCount)
|
|
{
|
|
if ((crateCountLimit > 0) && (currentCrateCount >= crateCountLimit))
|
|
return true;
|
|
|
|
if ((unitCountLimit > 0L) && (currentUnitCount >= unitCountLimit))
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
obj_id unpackItem(obj_id container, dictionary itemDictionary)
|
|
{
|
|
obj_id newItem = null;
|
|
|
|
try
|
|
{
|
|
obj_id self = getSelf();
|
|
if(!isIdValid(self))
|
|
return null;
|
|
|
|
LIVE_LOG("CharacterTransfer", "unpackItem(" + container + ", " + itemDictionary + ")");
|
|
|
|
if(! itemDictionary.containsKey("objectTemplateCrc"))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "unpackItem() : could not retrieve object template crc from item dictionary. TRANSFER FAILED");
|
|
return null;
|
|
}
|
|
int objectTemplateCrc = itemDictionary.getInt("objectTemplateCrc");
|
|
|
|
String objectTemplateName = "UNKNOWN ITEM";
|
|
if(itemDictionary.containsKey("objectTemplateName"))
|
|
{
|
|
objectTemplateName = itemDictionary.getString("objectTemplateName");
|
|
}
|
|
|
|
boolean isEquipped = false;
|
|
if(itemDictionary.containsKey("isEquipped"))
|
|
{
|
|
isEquipped = itemDictionary.getBoolean("isEquipped");
|
|
}
|
|
|
|
boolean isAppearanceEquipped = false;
|
|
if(itemDictionary.containsKey("isAppearanceEquipped"))
|
|
{
|
|
isAppearanceEquipped = itemDictionary.getBoolean("isAppearanceEquipped");
|
|
}
|
|
|
|
if (itemDictionary.containsKey("staticItemName"))
|
|
{
|
|
String staticItemName = itemDictionary.getString("staticItemName");
|
|
newItem = static_item.createNewItemFunction(staticItemName, container);
|
|
CustomerServiceLog("CharacterTransfer", "unpackItem() : createNewItemFunction(" + staticItemName + ", " + container + ") = " + newItem);
|
|
}
|
|
else if (itemDictionary.containsKey("msoDraftSchematicCrc"))
|
|
{
|
|
int schematicCrc = itemDictionary.getInt("msoDraftSchematicCrc");
|
|
newItem = createSchematic(schematicCrc, container);
|
|
CustomerServiceLog("CharacterTransfer", "unpackItem() : createSchematic(" + schematicCrc + ", " + container + ") = " + newItem);
|
|
}
|
|
else if (itemDictionary.containsKey("schematicTemplateCrc"))
|
|
{
|
|
// these are currently not packed, or unpacked. Attempting to run the normal
|
|
// item creation/unpack code on them will cause a crash.
|
|
return null;
|
|
}
|
|
else
|
|
{
|
|
if(isEquipped || isAppearanceEquipped)
|
|
{
|
|
// Create object in inventory for now, so that objvars etc are set first,
|
|
// since they might impact whether the item can be equipped.
|
|
newItem = createObjectInInventoryAllowOverload(objectTemplateCrc, self);
|
|
CustomerServiceLog("CharacterTransfer", "unpackItem() : createObjectInInventoryAllowOverload(" + objectTemplateCrc + "=" + objectTemplateName + ", " + self + ") = " + newItem);
|
|
}
|
|
else if(itemDictionary.containsKey("bypassVolumeCheck"))
|
|
{
|
|
newItem = createObjectInInventoryAllowOverload(objectTemplateCrc, self);
|
|
}
|
|
else
|
|
{
|
|
int containerType = getContainerType(container);
|
|
if (containerType == 2)
|
|
{
|
|
newItem = createObjectOverloaded(objectTemplateCrc, container);
|
|
}
|
|
else
|
|
{
|
|
newItem = createObject(objectTemplateCrc, container, "");
|
|
}
|
|
CustomerServiceLog("CharacterTransfer", "unpackItem() : createObjectOverloaded(" + objectTemplateCrc + "=" + objectTemplateName + ", " + container + ") = " + newItem);
|
|
}
|
|
}
|
|
|
|
if(!isIdValid(newItem))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "unpackItem() : FAILED to create object in container " + container + ": " + itemDictionary);
|
|
return null;
|
|
}
|
|
else
|
|
{
|
|
setOwner(newItem, self);
|
|
|
|
// set this flag so the object can do any special unpack handling
|
|
utils.setLocalVar(newItem, "ctsBeingUnpacked", true);
|
|
}
|
|
|
|
// objvars
|
|
if(! itemDictionary.containsKey("packedObjvars"))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "unpackItem() : FAILED to retrieve packedObjvars from item dictionary: " + itemDictionary);
|
|
return null;
|
|
}
|
|
|
|
String packedObjvars = itemDictionary.getString("packedObjvars");
|
|
if(packedObjvars == null)
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "unpackItem() : FAILED to get a non-null packedObjvars value from item dictionary: " + itemDictionary);
|
|
return null;
|
|
}
|
|
|
|
setPackedObjvars(newItem, packedObjvars);
|
|
|
|
int objectType = getGameObjectType(newItem);
|
|
if (!static_item.isStaticItem(newItem))
|
|
{
|
|
// attributes
|
|
if(itemDictionary.containsKey("attribute_types") && itemDictionary.containsKey("attribute_values"))
|
|
{
|
|
int[] itemAttribTypes = itemDictionary.getIntArray("attribute_types");
|
|
int[] itemAttribValues = itemDictionary.getIntArray("attribute_values");
|
|
if(itemAttribTypes != null && itemAttribValues != null)
|
|
{
|
|
attribute[] itemAttribs = new attribute[itemAttribTypes.length];
|
|
int itemAttribsIter;
|
|
for(itemAttribsIter = 0; itemAttribsIter < itemAttribTypes.length; ++itemAttribsIter)
|
|
{
|
|
itemAttribs[itemAttribsIter] = new attribute(itemAttribTypes[itemAttribsIter], itemAttribValues[itemAttribsIter]);
|
|
}
|
|
if (!setMaxAttribs(newItem, itemAttribs))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "setMaxAttribs( " + newItem + ", ...) FAILED");
|
|
}
|
|
if (!setAttribs(newItem, itemAttribs))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "setAttribs( " + newItem + ", ...) FAILED");
|
|
}
|
|
}
|
|
}
|
|
|
|
// Max Hitpoints
|
|
if(itemDictionary.containsKey("maxHitpoints"))
|
|
{
|
|
int maxHitpoints = itemDictionary.getInt("maxHitpoints");
|
|
if (!setMaxHitpoints(newItem, maxHitpoints))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "setMaxHitpoints( " + newItem + ", " + maxHitpoints + ") FAILED");
|
|
}
|
|
}
|
|
|
|
// Current Hitpoints
|
|
if(itemDictionary.containsKey("hitpoints"))
|
|
{
|
|
int hitpoints = itemDictionary.getInt("hitpoints");
|
|
if (!setInvulnerableHitpoints(newItem, hitpoints))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "setInvulnerableHitpoints( " + newItem + ", " + hitpoints + ") FAILED");
|
|
}
|
|
}
|
|
|
|
// Condition Flags
|
|
if(itemDictionary.containsKey("conditionFlags"))
|
|
{
|
|
int conditionFlags = itemDictionary.getInt("conditionFlags");
|
|
if (!setCondition(newItem, conditionFlags))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "setCondition( " + newItem + ", " + conditionFlags + ") FAILED");
|
|
}
|
|
}
|
|
|
|
// scripts, it's ok if this isn't available
|
|
if(itemDictionary.containsKey("scripts"))
|
|
{
|
|
String[] itemScripts = itemDictionary.getStringArray("scripts");
|
|
if(itemScripts != null && itemScripts.length > 0)
|
|
{
|
|
int scriptIter;
|
|
for(scriptIter = 0; scriptIter < itemScripts.length; ++scriptIter)
|
|
{
|
|
if (!hasScript(newItem, itemScripts[scriptIter]))
|
|
{
|
|
attachScript(newItem, itemScripts[scriptIter]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(itemDictionary.containsKey("objectName"))
|
|
{
|
|
String objectName = itemDictionary.getString("objectName");
|
|
setName(newItem, objectName);
|
|
}
|
|
|
|
// is it a weapon?
|
|
if(itemDictionary.containsKey("isWeaponItem"))
|
|
{
|
|
boolean isWeaponItem = itemDictionary.getBoolean("isWeaponItem");
|
|
if(isWeaponItem)
|
|
{
|
|
// get weapon stats
|
|
if(itemDictionary.containsKey("currentVersion"))
|
|
{
|
|
|
|
int currentVersion = itemDictionary.getInt("currentVersion");
|
|
setConversionId(newItem, currentVersion);
|
|
}
|
|
|
|
int minDamage = itemDictionary.getInt("minDamage");
|
|
if (!setWeaponMinDamage(newItem, minDamage))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "setWeaponMinDamage( " + newItem + ", " + minDamage + ") FAILED");
|
|
}
|
|
|
|
int maxDamage = itemDictionary.getInt("maxDamage");
|
|
if (!setWeaponMaxDamage(newItem, maxDamage))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "setWeaponMaxDamage( " + newItem + ", " + maxDamage + ") FAILED");
|
|
}
|
|
|
|
float attackSpeed = itemDictionary.getFloat("attackSpeed");
|
|
if (!setWeaponAttackSpeed(newItem, attackSpeed))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "setWeaponAttackSpeed( " + newItem + ", " + attackSpeed + ") FAILED");
|
|
}
|
|
|
|
range_info rangeInfo = new range_info();
|
|
rangeInfo.minRange = itemDictionary.getFloat("rangeInfoMinRange");
|
|
rangeInfo.maxRange = itemDictionary.getFloat("rangeInfoMaxRange");
|
|
if (!setWeaponRangeInfo(newItem, rangeInfo))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "setWeaponRangeInfo( " + newItem + ", " + rangeInfo + ") FAILED");
|
|
}
|
|
|
|
float woundChance = itemDictionary.getFloat("woundChance");
|
|
if (!setWeaponWoundChance(newItem, woundChance))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "setWeaponWoundChance( " + newItem + ", " + woundChance + ") FAILED");
|
|
}
|
|
|
|
float damageRadius = itemDictionary.getFloat("damageRadius");
|
|
if (!setWeaponDamageRadius(newItem, damageRadius))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "setWeaponDamageRadius( " + newItem + ", " + damageRadius + ") FAILED");
|
|
}
|
|
|
|
int accuracy = itemDictionary.getInt("accuracy");
|
|
if (!setWeaponAccuracy(newItem, accuracy))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "setWeaponAccuracy( " + newItem + ", " + accuracy + ") FAILED");
|
|
}
|
|
|
|
int elementalType = itemDictionary.getInt("elementalType");
|
|
if (!setWeaponElementalType(newItem, elementalType))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "setWeaponElemetalType( " + newItem + ", " + elementalType + ") FAILED");
|
|
}
|
|
|
|
int elementalValue = itemDictionary.getInt("elementalValue");
|
|
if (!setWeaponElementalValue(newItem, elementalValue))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "setWeaponElemetalValue( " + newItem + ", " + elementalValue + ") FAILED");
|
|
}
|
|
|
|
int damageType = itemDictionary.getInt("damageType");
|
|
if (!setWeaponDamageType(newItem, damageType))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "setWeaponDamageType( " + newItem + ", " + damageType + ") FAILED");
|
|
}
|
|
|
|
int attackCost = itemDictionary.getInt("attackCost");
|
|
if (!setWeaponAttackCost(newItem, attackCost))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "setWeaponAttackCost( " + newItem + ", " + attackCost + ") FAILED");
|
|
}
|
|
|
|
weapons.setWeaponData(newItem);
|
|
}
|
|
}
|
|
|
|
// color data
|
|
if(itemDictionary.containsKey("colorData"))
|
|
{
|
|
dictionary colorData = itemDictionary.getDictionary("colorData");
|
|
hue.setPalcolorData(newItem, colorData);
|
|
}
|
|
|
|
if(itemDictionary.containsKey("customAppearance"))
|
|
{
|
|
byte[] customAppearance = itemDictionary.getByteArray("customAppearance");
|
|
setAutoVariableFromByteStream(newItem, "customAppearance", customAppearance);
|
|
}
|
|
|
|
if(itemDictionary.containsKey("appearanceData"))
|
|
{
|
|
byte[] appearanceData = itemDictionary.getByteArray("appearanceData");
|
|
setAutoVariableFromByteStream(newItem, "appearanceData", appearanceData);
|
|
}
|
|
}
|
|
|
|
if(hasCondition(newItem, CONDITION_LOCKED))
|
|
{
|
|
clearUserAccessList(newItem);
|
|
clearGuildAccessList(newItem);
|
|
addUserToAccessList(newItem, self);
|
|
|
|
if(hasObjVar(newItem, "lock_owner"))
|
|
setObjVar(newItem, "lock_owner", self);
|
|
if(hasObjVar(newItem, "lock_owner_name"))
|
|
setObjVar(newItem, "lock_owner_name", getName(self));
|
|
}
|
|
|
|
// Number of Uses
|
|
if(itemDictionary.containsKey("count"))
|
|
{
|
|
int count = itemDictionary.getInt("count");
|
|
if (!setCount(newItem, count))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "setCount( " + newItem + ", " + count + ") FAILED");
|
|
}
|
|
}
|
|
|
|
// Bank balance (this will handle maintenance pool on various object types)
|
|
if(itemDictionary.containsKey("bankBalance"))
|
|
{
|
|
byte[] bankBalance = itemDictionary.getByteArray("bankBalance");
|
|
setAutoVariableFromByteStream(newItem, "bankBalance", bankBalance);
|
|
}
|
|
|
|
// recreate ship and components components.
|
|
if (isGameObjectTypeOf(objectType, GOT_ship))
|
|
{
|
|
// remove all the default components of the ship so that we can install the
|
|
// real components that came from the source ship, except for the Sorosuub, which
|
|
// is not a customizable ship, so we need to leave its default components alone
|
|
if ((objectTemplateName != null) && (objectTemplateName.endsWith("player_sorosuub_space_yacht.iff")))
|
|
{
|
|
// Sorosuub is not a customizable ship, so we need to leave its default components alone
|
|
}
|
|
else
|
|
{
|
|
// destroy the existing components - they're garbage.
|
|
space_crafting.uninstallAll(newItem);
|
|
}
|
|
|
|
float mass = itemDictionary.getFloat("ship_mass");
|
|
float maxHp = itemDictionary.getFloat("ship_hp");
|
|
float currentHp = itemDictionary.getFloat("ship_current_hp");
|
|
|
|
setChassisComponentMassMaximum(newItem, mass);
|
|
setShipMaximumChassisHitPoints(newItem, maxHp);
|
|
setShipCurrentChassisHitPoints(newItem, currentHp);
|
|
|
|
// if the ship has an installed droid control device, store
|
|
// the oid of the ***SOURCE*** droid control device temporarily
|
|
// as a localvar on the ship; after all the datapad items have
|
|
// been unpacked, we'll go through all the ships that have
|
|
// installed droid control device and find out the oid
|
|
// that the droid ***SOURCE*** droid control device got assigned
|
|
// to when it got unpacked, and then "relink" the ship
|
|
// to the correct droid control device
|
|
if (itemDictionary.containsKey("droid_control_device"))
|
|
{
|
|
obj_id objDroidControlDevice = itemDictionary.getObjId("droid_control_device");
|
|
if (isIdValid(objDroidControlDevice))
|
|
{
|
|
utils.setLocalVar(newItem, "droid_control_device", objDroidControlDevice);
|
|
}
|
|
}
|
|
|
|
if(itemDictionary.containsKey("shipComponents"))
|
|
{
|
|
// find our player owner. Since this is a ship, we should be being created
|
|
// in a ship control device, which should be contained by a datapad which
|
|
// is then contained by a player.
|
|
obj_id datapad = getContainedBy(container);
|
|
obj_id player = getOwner(datapad);
|
|
|
|
if(isIdValid(player))
|
|
{
|
|
dictionary componentsDictionary = itemDictionary.getDictionary("shipComponents");
|
|
if(componentsDictionary != null)
|
|
{
|
|
Set keySet = componentsDictionary.keySet();
|
|
Integer[] slots = new Integer[keySet.size()];
|
|
keySet.toArray(slots);
|
|
for(int i = 0; i < slots.length; ++i)
|
|
{
|
|
// ship slot.
|
|
Integer slot = slots[i];
|
|
|
|
// unpack the component into the player. we'll remove it in
|
|
// a second.
|
|
dictionary componentDictionary = componentsDictionary.getDictionary(slot);
|
|
if (ctsCheckAndLogUniqueStaticItemAlreadyExists(player, componentDictionary))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
componentDictionary.put("bypassVolumeCheck", 1);
|
|
obj_id newComponent = unpackItem(player, componentsDictionary.getDictionary(slot));
|
|
|
|
// install it.
|
|
if(isIdValid(newComponent))
|
|
{
|
|
shipInstallComponent(player, newItem, slot.intValue(), newComponent);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// update lightsaber crystal owner
|
|
if(itemDictionary.containsKey("isCrystalOwner") )
|
|
{
|
|
// special handling to preserve the existing crystal owner name value
|
|
if (hasObjVar(self, "preserve_existing_lightsaber_crystal_owner_objvar"))
|
|
{
|
|
string namePrefix = getStringObjVar(self, "preserve_existing_lightsaber_crystal_owner_objvar");
|
|
if ((namePrefix != null) && (namePrefix.length() > 0) && !namePrefix.equals("none"))
|
|
{
|
|
string existingName = getStringObjVar(newItem, jedi.VAR_CRYSTAL_OWNER_NAME);
|
|
if ((existingName != null) && (existingName.length() > 0))
|
|
{
|
|
setObjVar(newItem, jedi.VAR_CRYSTAL_OWNER_NAME, namePrefix + existingName);
|
|
}
|
|
}
|
|
|
|
setObjVar(newItem, jedi.VAR_CRYSTAL_OWNER_ID, 0);
|
|
}
|
|
else
|
|
{
|
|
if( itemDictionary.getBoolean("isCrystalOwner") )
|
|
{
|
|
setObjVar(newItem, jedi.VAR_CRYSTAL_OWNER_ID, self);
|
|
setObjVar(newItem, jedi.VAR_CRYSTAL_OWNER_NAME, getName(self));
|
|
}
|
|
else
|
|
{
|
|
setObjVar(newItem, jedi.VAR_CRYSTAL_OWNER_ID, 0);
|
|
setObjVar(newItem, jedi.VAR_CRYSTAL_OWNER_NAME, "None");
|
|
}
|
|
}
|
|
|
|
// THIS SHOULD BE FIXED.
|
|
// This code is a cut and paste of the exact same code in the
|
|
// tuneCrystal method of systems.jedi.jedi_saber_component.
|
|
|
|
string name = getEncodedName(newItem);
|
|
if (name.startsWith("@"))
|
|
name = localize(getNameStringId(newItem));
|
|
name = "\\"+colors_hex.GREEN+""+name + " (tuned)\\#.";
|
|
setName(newItem, name);
|
|
}
|
|
|
|
if (itemDictionary.containsKey("biolink"))
|
|
{
|
|
obj_id biolink = itemDictionary.getObjId("biolink");
|
|
if (itemDictionary.getBoolean("isBiolinkOwner"))
|
|
{
|
|
biolink = self;
|
|
}
|
|
if (!setBioLink(newItem, biolink))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "setBioLink( " + newItem + ", " + biolink + ") FAILED");
|
|
}
|
|
}
|
|
|
|
// RESOURCE CONTAINER
|
|
if (isGameObjectTypeOf(objectType, GOT_resource_container))
|
|
{
|
|
// GOT_resource_container_pseudo are not real resource container (i.e. they contain no resource information
|
|
// like quantity and resource type), so don't use the resource container packing logic on them
|
|
if (objectType != GOT_resource_container_pseudo)
|
|
{
|
|
if (itemDictionary.containsKey("resourceQuantity") && itemDictionary.containsKey("resourceData"))
|
|
{
|
|
int quantity = itemDictionary.getInt("resourceQuantity");
|
|
string resourceData = itemDictionary.getString("resourceData");
|
|
|
|
CustomerServiceLog("CharacterTransfer", "unpackItem() : created resource container " + newItem + ": resourceQuantity=" + quantity + ", resourceData=" + resourceData);
|
|
|
|
setResourceCtsData(newItem, quantity, resourceData);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "unpackItem() : created pseudo resource container " + newItem);
|
|
}
|
|
}
|
|
|
|
// factory crate
|
|
if (objectType == GOT_misc_factory_crate)
|
|
{
|
|
recomputeCrateAttributes(newItem);
|
|
}
|
|
|
|
// MANUFACTURING SCHEMATIC
|
|
if ((objectType == GOT_data_manufacturing_schematic) && itemDictionary.containsKey("msoCtsPackUnpack"))
|
|
{
|
|
byte[] data = itemDictionary.getByteArray("msoCtsPackUnpack");
|
|
setAutoVariableFromByteStream(newItem, "msoCtsPackUnpack", data);
|
|
|
|
if (itemDictionary.containsKey("msoConversionId"))
|
|
setConversionId(newItem, itemDictionary.getInt("msoConversionId"));
|
|
}
|
|
|
|
// MISSION
|
|
if (objectType == GOT_data_mission_object)
|
|
{
|
|
if (itemDictionary.containsKey("moCtsPackUnpack"))
|
|
{
|
|
byte[] data = itemDictionary.getByteArray("moCtsPackUnpack");
|
|
setAutoVariableFromByteStream(newItem, "moCtsPackUnpack", data);
|
|
}
|
|
|
|
if (itemDictionary.containsKey("missionAge"))
|
|
{
|
|
int timeCreated = (getGameTime() - itemDictionary.getInt("missionAge"));
|
|
if (timeCreated <= 0)
|
|
timeCreated = 1;
|
|
|
|
setObjVar(newItem, "time_created", timeCreated);
|
|
}
|
|
}
|
|
|
|
// Player Generated Content
|
|
if (objectType == GOT_chronicles_quest_holocron || objectType == GOT_chronicles_quest_holocron_recipe)
|
|
{
|
|
if (itemDictionary.containsKey("PGCPacked"))
|
|
{
|
|
byte[] data = itemDictionary.getByteArray("PGCPacked");
|
|
setAutoVariableFromByteStream(newItem, "PGCPacked", data);
|
|
}
|
|
|
|
if (objectType == GOT_chronicles_quest_holocron_recipe)
|
|
{
|
|
// Reset Recipe ownership
|
|
setPlayerQuestCreator(newItem, self);
|
|
setObjVar(newItem, pgc_quests.PCG_QUEST_CREATOR_ID_OBJVAR, self);
|
|
setObjVar(newItem, pgc_quests.PCG_QUEST_CREATOR_STATIONID_OBJVAR, getPlayerStationId(self));
|
|
setObjVar(newItem, pgc_quests.PCG_QUEST_CREATOR_NAME_OBJVAR, getName(self));
|
|
}
|
|
}
|
|
|
|
// INCUBATOR WITH INSTALLED RESOURCE
|
|
if ((objectTemplateCrc == ##"object/tangible/crafting/station/incubator_station.iff") && (hasObjVar(newItem, incubator.RESOURCE_POWER_NAME)))
|
|
{
|
|
if (itemDictionary.containsKey("incubatorResourceData"))
|
|
{
|
|
byte[] data = itemDictionary.getByteArray("incubatorResourceData");
|
|
setAutoVariableFromByteStream(newItem, "incubatorResourceData", data);
|
|
}
|
|
}
|
|
|
|
// factory
|
|
if (objectType == GOT_installation_factory)
|
|
{
|
|
// owner
|
|
setObjVar(newItem, player_structure.VAR_OWNER, getPlayerName(self));
|
|
|
|
// set the admin list to just ourselves.
|
|
string[] admin_list = new string[1];
|
|
admin_list[0] = self.toString();
|
|
setObjVar(newItem, player_structure.VAR_ADMIN_LIST, admin_list);
|
|
|
|
// set the hopper list to just ourselves.
|
|
setObjVar(newItem, player_structure.VAR_HOPPER_LIST, admin_list);
|
|
|
|
// remove the entrance and ban lists.
|
|
removeObjVar(newItem, player_structure.VAR_ENTER_LIST);
|
|
removeObjVar(newItem, player_structure.VAR_BAN_LIST);
|
|
|
|
// we shouldn't have any vendors, but we'll make sure.
|
|
removeObjVar(newItem, player_structure.VAR_VENDOR_LIST);
|
|
|
|
// and we aren't part of a city any more
|
|
removeObjVar(newItem, "city_id");
|
|
|
|
// and we aren't a guild hall.
|
|
removeObjVar(newItem, player_structure.VAR_IS_GUILD_HALL);
|
|
|
|
// factory power pool
|
|
if(itemDictionary.containsKey("powerValue"))
|
|
{
|
|
byte[] powerValue = itemDictionary.getByteArray("powerValue");
|
|
setAutoVariableFromByteStream(newItem, "powerValue", powerValue);
|
|
}
|
|
|
|
if(itemDictionary.containsKey("powerRate"))
|
|
{
|
|
byte[] powerRate = itemDictionary.getByteArray("powerRate");
|
|
setAutoVariableFromByteStream(newItem, "powerRate", powerRate);
|
|
}
|
|
|
|
// manufacturing schematic
|
|
if(itemDictionary.containsKey("manf_schematic"))
|
|
{
|
|
dictionary dictManfSchematic = itemDictionary.getDictionary("manf_schematic");
|
|
if (dictManfSchematic != null)
|
|
{
|
|
// create the manufacturing schematic in the datapad first, and then move it into the slot on the factory that holds the manufacturing schematic
|
|
obj_id manfSchematic = unpackItem(utils.getPlayerDatapad(self), dictManfSchematic);
|
|
if (isIdValid(manfSchematic))
|
|
{
|
|
transferManufactureSchematicToStation(manfSchematic, newItem);
|
|
}
|
|
}
|
|
}
|
|
|
|
// ingredient hopper contents
|
|
if(itemDictionary.containsKey("ingr_hopper_contents"))
|
|
{
|
|
dictionary dictIngrHopperContents = itemDictionary.getDictionary("ingr_hopper_contents");
|
|
if (dictIngrHopperContents != null)
|
|
{
|
|
obj_id ingrHopper = getObjectInSlot(newItem, "ingredient_hopper");
|
|
if (isIdValid(ingrHopper))
|
|
{
|
|
Set keySet = dictIngrHopperContents.keySet();
|
|
Iterator contentsIterator = keySet.iterator();
|
|
while (contentsIterator.hasNext())
|
|
{
|
|
obj_id key = (obj_id)contentsIterator.next();
|
|
|
|
dictionary containedItemDict = dictIngrHopperContents.getDictionary(key);
|
|
if (containedItemDict == null)
|
|
continue;
|
|
|
|
if (ctsCheckAndLogUniqueStaticItemAlreadyExists(ingrHopper, containedItemDict))
|
|
continue;
|
|
|
|
unpackItem(ingrHopper, containedItemDict);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// output hopper contents
|
|
if(itemDictionary.containsKey("output_hopper_contents"))
|
|
{
|
|
dictionary dictOutputHopperContents = itemDictionary.getDictionary("output_hopper_contents");
|
|
if (dictOutputHopperContents != null)
|
|
{
|
|
obj_id outputHopper = getObjectInSlot(newItem, "output_hopper");
|
|
if (isIdValid(outputHopper))
|
|
{
|
|
Set keySet = dictOutputHopperContents.keySet();
|
|
Iterator contentsIterator = keySet.iterator();
|
|
while (contentsIterator.hasNext())
|
|
{
|
|
obj_id key = (obj_id)contentsIterator.next();
|
|
|
|
dictionary containedItemDict = dictOutputHopperContents.getDictionary(key);
|
|
if (containedItemDict == null)
|
|
continue;
|
|
|
|
if (ctsCheckAndLogUniqueStaticItemAlreadyExists(outputHopper, containedItemDict))
|
|
continue;
|
|
|
|
unpackItem(outputHopper, containedItemDict);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// crafting station
|
|
if (objectType == GOT_misc_crafting_station)
|
|
{
|
|
// input hopper contents
|
|
if(itemDictionary.containsKey("input_hopper_contents"))
|
|
{
|
|
dictionary dictInputHopperContents = itemDictionary.getDictionary("input_hopper_contents");
|
|
if (dictInputHopperContents != null)
|
|
{
|
|
obj_id inputHopper = getObjectInSlot(newItem, "ingredient_hopper");
|
|
if (isIdValid(inputHopper))
|
|
{
|
|
Set keySet = dictInputHopperContents.keySet();
|
|
Iterator contentsIterator = keySet.iterator();
|
|
while (contentsIterator.hasNext())
|
|
{
|
|
obj_id key = (obj_id)contentsIterator.next();
|
|
|
|
dictionary containedItemDict = dictInputHopperContents.getDictionary(key);
|
|
if (containedItemDict == null)
|
|
continue;
|
|
|
|
if (ctsCheckAndLogUniqueStaticItemAlreadyExists(inputHopper, containedItemDict))
|
|
continue;
|
|
|
|
unpackItem(inputHopper, containedItemDict);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (itemDictionary.containsKey("isBlueprintDesigner"))
|
|
{
|
|
if ( itemDictionary.getBoolean("isBlueprintDesigner") )
|
|
{
|
|
setObjVar(newItem, storyteller.BLUEPRINT_AUTHOR_OBJVAR, self);
|
|
}
|
|
else
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "Player is not blueprint's designer: player = " + self + "; blueprint = " + newItem);
|
|
}
|
|
}
|
|
|
|
// if the structure was a "lot over limit structure", need to
|
|
// flag the target structure as the "lot over limit structure"
|
|
if (isGameObjectTypeOf(objectType, GOT_building))
|
|
{
|
|
// if the structure was a "lot over limit structure", need to
|
|
// flag the target structure as the "lot over limit structure"
|
|
if (itemDictionary.containsKey("lotOverlimitStructureId"))
|
|
{
|
|
obj_id lotOverlimitStructureOnCharacter = getObjIdObjVar(self, "lotOverlimit.structure_id");
|
|
if (isIdValid(lotOverlimitStructureOnCharacter))
|
|
{
|
|
obj_id lotOverlimitStructure = itemDictionary.getObjId("lotOverlimitStructureId");
|
|
if (isIdValid(lotOverlimitStructure) && (lotOverlimitStructure == lotOverlimitStructureOnCharacter))
|
|
{
|
|
setObjVar(self, "lotOverlimit.structure_id", newItem);
|
|
setObjVar(self, "lotOverlimit.structure_location", "Datapad");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// house stuff
|
|
if (itemDictionary.containsKey("house_contents"))
|
|
{
|
|
// if we have house contents, we're a house. Set the owner id appropriately.
|
|
setObjVar(newItem, player_structure.VAR_OWNER, getPlayerName(self));
|
|
|
|
// set the admin list to just ourselves.
|
|
string[] admin_list = new string[1];
|
|
admin_list[0] = self.toString();
|
|
setObjVar(newItem, player_structure.VAR_ADMIN_LIST, admin_list);
|
|
|
|
// remove the entrance and ban lists.
|
|
|
|
removeObjVar(newItem, player_structure.VAR_ENTER_LIST);
|
|
removeObjVar(newItem, player_structure.VAR_BAN_LIST);
|
|
|
|
// we shouldn't have any vendors or hopper items, but we'll make sure.
|
|
removeObjVar(newItem, player_structure.VAR_VENDOR_LIST);
|
|
|
|
removeObjVar(newItem, player_structure.VAR_HOPPER_LIST);
|
|
|
|
// and we aren't a guild hall.
|
|
removeObjVar(newItem, player_structure.VAR_IS_GUILD_HALL);
|
|
|
|
dictionary contentsDict = itemDictionary.getDictionary("house_contents");
|
|
Set keySet = contentsDict.keySet();
|
|
Iterator contentsIterator = keySet.iterator();
|
|
while(contentsIterator.hasNext())
|
|
{
|
|
obj_id key = (obj_id)contentsIterator.next();
|
|
if(isIdNull(key))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "unpackItem() FAILED: key " + key + " not valid in house contents dictionary: " + contentsDict);
|
|
return null;
|
|
}
|
|
dictionary containedItemDict = contentsDict.getDictionary(key);
|
|
if (containedItemDict == null)
|
|
continue;
|
|
|
|
// temporarily place in inventory.
|
|
if (ctsCheckAndLogUniqueStaticItemAlreadyExists(utils.getInventoryContainer(self), containedItemDict))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
containedItemDict.put("bypassVolumeCheck", 1);
|
|
obj_id house_item = unpackItem(utils.getInventoryContainer(self), containedItemDict);
|
|
if (isIdValid(house_item))
|
|
{
|
|
location loc = containedItemDict.getLocation("house_cell_loc");
|
|
// fix up the cell id.
|
|
string cell_name = containedItemDict.getString("house_cell");
|
|
obj_id cellid = getCellId(newItem, cell_name);
|
|
if (isIdValid(cellid))
|
|
{
|
|
loc.cell = cellid;
|
|
setLocation(house_item, loc);
|
|
}
|
|
|
|
float[] quaternion = containedItemDict.getFloatArray("quaternion");
|
|
if ((quaternion != null) && (quaternion.length == 4))
|
|
setQuaternion(house_item, quaternion[0], quaternion[1], quaternion[2], quaternion[3]);
|
|
|
|
// creating an item inside a POB that is inside the datapad
|
|
// requires a "force" update of the item's position to the
|
|
// DB so that the item's location/orientation inside the cell
|
|
// can be persisted
|
|
requestSendPositionUpdate(house_item);
|
|
}
|
|
}
|
|
|
|
// call loadBuildingContents() (even though this is a new building and won't
|
|
// have anything in the DB to load) to mark the building as "demand loaded";
|
|
// if the new building doesn't have any contents, then it'll get marked
|
|
// "demand loaded" later on when it get unpacked and someone enters it for the
|
|
// first time, causing it to load its contents;
|
|
if (isGameObjectTypeOf(objectType, GOT_building))
|
|
{
|
|
loadBuildingContents(self, newItem);
|
|
}
|
|
}
|
|
|
|
// reset maintenance time for factory and house
|
|
if ((objectType == GOT_installation_factory) || isGameObjectTypeOf(objectType, GOT_building))
|
|
{
|
|
if (hasObjVar(newItem, player_structure.VAR_LAST_MAINTANENCE))
|
|
setObjVar(newItem, player_structure.VAR_LAST_MAINTANENCE, getGameTime());
|
|
}
|
|
|
|
// containers
|
|
int containerType = itemDictionary.getInt("containerType");
|
|
|
|
// check the type
|
|
if(containerType > 0 || jedi.isLightsaber(newItem) || isGameObjectTypeOf(objectType, GOT_data_ship_control_device))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "unpackItem() : unpacking contents of container " + newItem + "(type " + containerType + ")");
|
|
// it is a volume container, retrieve the contents dictionary
|
|
if(itemDictionary.containsKey("contents"))
|
|
{
|
|
// for the 6 navi computers, the datapad is automatically created when
|
|
// the item is created, so we need to destroy the auto-created datapad
|
|
// in order to unpack the original datapad (and the datapad's contents)
|
|
if (objectTemplateName.equals("object/intangible/ship/navicomputer_1.iff") ||
|
|
objectTemplateName.equals("object/intangible/ship/navicomputer_2.iff") ||
|
|
objectTemplateName.equals("object/intangible/ship/navicomputer_3.iff") ||
|
|
objectTemplateName.equals("object/intangible/ship/navicomputer_4.iff") ||
|
|
objectTemplateName.equals("object/intangible/ship/navicomputer_5.iff") ||
|
|
objectTemplateName.equals("object/intangible/ship/navicomputer_6.iff"))
|
|
{
|
|
obj_id datapad = utils.getDatapad(newItem);
|
|
if (isIdValid(datapad))
|
|
{
|
|
destroyObject(datapad);
|
|
}
|
|
}
|
|
|
|
dictionary contentsDict = itemDictionary.getDictionary("contents");
|
|
Set keySet = contentsDict.keySet();
|
|
Iterator contentsIterator = keySet.iterator();
|
|
while(contentsIterator.hasNext())
|
|
{
|
|
obj_id key = (obj_id)contentsIterator.next();
|
|
if(isIdNull(key))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "unpackItem() FAILED: key " + key + " not valid in container contents dictionary: " + contentsDict);
|
|
return null;
|
|
}
|
|
|
|
dictionary containedItemDict = contentsDict.getDictionary(key);
|
|
|
|
obj_id unpackedItem = null;
|
|
obj_id saberInv = null;
|
|
|
|
// lightsaber crystals inside of lightsabers must be recreated in 3 steps due to tuning requirement:
|
|
// 1) recreate untuned crystal in parent container
|
|
// 2) retune crystal
|
|
// 3) move tuned crystal into the lightsaber
|
|
if (jedi.isLightsaber(newItem))
|
|
{
|
|
if (ctsCheckAndLogUniqueStaticItemAlreadyExists(container, containedItemDict))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
saberInv = getObjectInSlot(newItem, "saber_inv");
|
|
unpackedItem = unpackItem(container, containedItemDict); // container == PARENT container
|
|
}
|
|
else
|
|
{
|
|
if (ctsCheckAndLogUniqueStaticItemAlreadyExists(newItem, containedItemDict))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
unpackedItem = unpackItem(newItem, containedItemDict); // newItem == CURRENT container
|
|
}
|
|
|
|
if(!isIdValid(unpackedItem))
|
|
{
|
|
if (isIdNull(unpackedItem))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "unpackItem() : unpackItem() returned NULL id for item: " + containedItemDict);
|
|
return null;
|
|
}
|
|
else
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "unpackItem() : unpackItem() returned invalid id " + unpackedItem + " for item: " + containedItemDict);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (isIdValid(saberInv))
|
|
{
|
|
if (jedi.hasColorCrystal(newItem) && jedi.isColorCrystal(unpackedItem))
|
|
{
|
|
removeObjVar(newItem, jedi.VAR_SABER_BASE + "." + jedi.VAR_COLOR);
|
|
}
|
|
if (!putIn(unpackedItem, saberInv))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "unpackItem() : FAILED to move lightsaber crystal " + unpackedItem + " into saber " + saberInv);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// if the factory crate's creator is transferring the crate, then on the
|
|
// destination galaxy, preserve the crate's creator information by setting
|
|
// the destination crate's creator to the destination character; otherwise,
|
|
// set the destination crate's creator to some non-zero oid that cannot
|
|
// possibly be a player on the target galaxy (like 1), to make it look like
|
|
// the crate's creator is no longer on the galaxy, like the crate's
|
|
// creator has been deleted and removed from the DB
|
|
if (objectType == GOT_misc_factory_crate)
|
|
{
|
|
boolean factoryCrateHasCreator = false;
|
|
if (itemDictionary.containsKey("factoryCrateHasCreator"))
|
|
factoryCrateHasCreator = itemDictionary.getBoolean("factoryCrateHasCreator");
|
|
|
|
boolean factoryCrateCreatorIsSelf = false;
|
|
if (itemDictionary.containsKey("factoryCrateCreatorIsSelf"))
|
|
factoryCrateCreatorIsSelf = itemDictionary.getBoolean("factoryCrateCreatorIsSelf");
|
|
|
|
obj_id factoryCrateCreator = (factoryCrateCreatorIsSelf ? self : obj_id.getObjId(10000000)); // 10,000,000 is max gold oid
|
|
|
|
if (factoryCrateHasCreator)
|
|
setCrafter(newItem, factoryCrateCreator);
|
|
|
|
obj_id[] factoryCrateContents = getContents(newItem);
|
|
if ((factoryCrateContents != null) && (factoryCrateContents.length > 0))
|
|
{
|
|
for (int i = 0; i < factoryCrateContents.length; ++i)
|
|
setCrafter(factoryCrateContents[i], factoryCrateCreator);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(isEquipped)
|
|
{
|
|
if (equip(newItem, self))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "unpackItem() : equipped item (" + newItem + ")");
|
|
}
|
|
else
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "unpackItem() : FAILED to equip item (" + newItem + ")");
|
|
}
|
|
}
|
|
if(isAppearanceEquipped)
|
|
{
|
|
obj_id appearanceInventory = getAppearanceInventory(self);
|
|
if(!isIdValid(appearanceInventory))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "unpackItem() : Failed to equip appearance item (" + newItem +"). Character has no valid appearance inventory.");
|
|
return null;
|
|
}
|
|
|
|
if(putIn(newItem, appearanceInventory))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "unpackItem() : equipped appearance item (" + newItem + ")");
|
|
}
|
|
else
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "unpackItem() : FAILED to equip appearance item (" + newItem + ")");
|
|
}
|
|
|
|
}
|
|
if(isGameObjectTypeOf(objectType, GOT_data_ship_control_device))
|
|
{
|
|
// update objvars with the correct ids
|
|
obj_id ship = space_transition.getShipFromShipControlDevice(newItem);
|
|
setObjVar(newItem, "ship", ship);
|
|
setObjVar(ship, "shipControlDevice", newItem);
|
|
if(!isIdValid(ship))
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
}
|
|
catch(Throwable t)
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "unpackItem() FAILED : container=" + container + ", itemDictionary=" + itemDictionary + " EXCEPTION: " + t);
|
|
return null;
|
|
}
|
|
|
|
utils.removeLocalVar(newItem, "ctsBeingUnpacked");
|
|
return newItem;
|
|
}
|
|
|
|
obj_id unpackWaypoint(dictionary waypointDictionary)
|
|
{
|
|
obj_id self = getSelf();
|
|
|
|
if(!isIdValid(self))
|
|
{
|
|
return null;
|
|
}
|
|
obj_id newWaypoint = null;
|
|
location loc = waypointDictionary.getLocation("location");
|
|
// create a new waypoint based on the area that the old one is in.
|
|
// do not use the cell, as that will be invalid.
|
|
|
|
if(!isIdNull(loc.cell))
|
|
{
|
|
// don't transfer waypoints not in the world
|
|
return null;
|
|
}
|
|
|
|
location newloc = new location(loc.x, loc.y, loc.z, loc.area);
|
|
string name = waypointDictionary.getString("name");
|
|
newWaypoint = createWaypointInDatapad(self, newloc);
|
|
setWaypointName(newWaypoint, name);
|
|
return newWaypoint;
|
|
}
|
|
|
|
boolean itemIsAllowedToTransfer(obj_id item, obj_id player)
|
|
{
|
|
if (!isValidId(item) || !isValidId(player))
|
|
return false;
|
|
|
|
// item that is used to perform CTS should not get transferred
|
|
if (utils.hasScriptVar(player, cts.SCRIPTVAR_CTS_ITEM_ID))
|
|
{
|
|
const obj_id ctsItem = utils.getObjIdScriptVar(player, cts.SCRIPTVAR_CTS_ITEM_ID);
|
|
if (isValidId(ctsItem) && (ctsItem == item))
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
dictionary packWaypoint(obj_id waypoint)
|
|
{
|
|
obj_id self = getSelf();
|
|
dictionary waypointDictionary = null;
|
|
try
|
|
{
|
|
waypointDictionary = new dictionary();
|
|
if(!isValidId(waypoint))
|
|
{
|
|
return null;
|
|
}
|
|
// location
|
|
location loc = getWaypointLocation(waypoint);
|
|
waypointDictionary.put("location", loc);
|
|
|
|
// name
|
|
string name = getWaypointName(waypoint);
|
|
waypointDictionary.put("name", name);
|
|
|
|
}
|
|
catch(Throwable t)
|
|
{
|
|
return null;
|
|
}
|
|
return waypointDictionary;
|
|
}
|
|
|
|
void doItemPrepack(obj_id item)
|
|
{
|
|
if(!isValidId(item))
|
|
return;
|
|
// let any scripts do whatever cleanup they feel is necessary.
|
|
{
|
|
dictionary d = new dictionary();
|
|
int result = script_entry.callMessageHandlers("OnPack", item, d);
|
|
if(result != SCRIPT_CONTINUE)
|
|
{
|
|
utils.setScriptVar(item, "do_not_pack", 1);
|
|
return;
|
|
}
|
|
}
|
|
obj_id[] contents = null;
|
|
|
|
contents = getContents(item);
|
|
if(contents != null)
|
|
{
|
|
for( int i = 0; i < contents.length; ++i )
|
|
{
|
|
doItemPrepack( contents[i] );
|
|
}
|
|
}
|
|
}
|
|
|
|
dictionary packItem(obj_id item, int objectType, boolean allowOverride, int resourceCrateCountLimit, int[] resourceCurrentCrateCount, long resourceUnitCountLimit, long[] resourceCurrentUnitCount)
|
|
{
|
|
// itemDictionary will be returned from packItem()
|
|
dictionary itemDictionary = null;
|
|
|
|
try
|
|
{
|
|
const obj_id self = getSelf();
|
|
|
|
if(getName(item).equalsIgnoreCase( "object/cell/cell.iff"))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (hasCondition(item, CONDITION_VENDOR))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if(utils.hasScriptVar(item, "do_not_pack"))
|
|
{
|
|
return null; // some script doesn't want us to get packed.
|
|
}
|
|
|
|
// get data useful for identifying the item and for logging
|
|
String name = getName(item);
|
|
String objectTypeName = getGameObjectTypeName(objectType);
|
|
String objectTemplateName = getTemplateName(item);
|
|
int objectTemplateCrc = getObjectTemplateCrc(objectTemplateName);
|
|
|
|
// make sure factory crate is good (i.e. has an item in it and count is > 0)
|
|
if (objectType == GOT_misc_factory_crate)
|
|
{
|
|
int factoryCrateCount = getCount(item);
|
|
if (factoryCrateCount <= 0)
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "packItem(" + item + ") skipping factory crate because it has a count of " + factoryCrateCount);
|
|
return null;
|
|
}
|
|
|
|
obj_id[] factoryCrateContents = getContents(item);
|
|
if ((factoryCrateContents == null) || (factoryCrateContents.length <= 0))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "packItem(" + item + ") skipping factory crate because it is empty");
|
|
return null;
|
|
}
|
|
|
|
string crateItemTemplateName = getTemplateName(factoryCrateContents[0]);
|
|
|
|
if(crateItemTemplateName == null || crateItemTemplateName.length() <= 0)
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "packItem(" + item + ") skipping factory crate because its contents returned a null string as a template name.");
|
|
return null;
|
|
}
|
|
|
|
if (crateItemTemplateName.equals("object/tangible/food/crafted/dessert_felbar.iff") ||
|
|
crateItemTemplateName.equals("object/tangible/food/crafted/dessert_blap_biscuit.iff") ||
|
|
crateItemTemplateName.equals("object/tangible/food/crafted/dessert_pastebread.iff") ||
|
|
crateItemTemplateName.equals("object/tangible/food/crafted/dessert_sweesonberry_rolls.iff"))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "packItem(" + item + ") skipping factory crate because it contained old pet food("+crateItemTemplateName+"), that is supposed to be deleted.");
|
|
return null;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
// ok, start packing the object into the dictionary
|
|
itemDictionary = new dictionary();
|
|
itemDictionary.put("objectTemplateCrc", objectTemplateCrc);
|
|
itemDictionary.put("objectTemplateName", objectTemplateName);
|
|
|
|
// OBJVARS
|
|
String packedObjvars = getPackedObjvars(item);
|
|
itemDictionary.put("packedObjvars", packedObjvars);
|
|
|
|
String staticItemName = getStaticItemName(item);
|
|
if (static_item.isStaticItem(item) && staticItemName != "item_respec_token_01_01")
|
|
{
|
|
itemDictionary.put("staticItemName", staticItemName);
|
|
CustomerServiceLog("CharacterTransfer", "packItem(" + item + ", " + allowOverride + ") staticItemName=" + staticItemName);
|
|
}
|
|
else
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "packItem(" + item + ", " + allowOverride + ") objectTemplateName=" + objectTemplateName + ", name=" + name);
|
|
|
|
// SCRIPTS
|
|
String[] itemScripts = getScriptList(item);
|
|
if(itemScripts != null && itemScripts.length > 0)
|
|
{
|
|
// remove the 'script.' prefix from each script name
|
|
for (int i = 0; i < itemScripts.length; ++i)
|
|
if (itemScripts[i].startsWith("script."))
|
|
itemScripts[i] = itemScripts[i].substring(7);
|
|
|
|
itemDictionary.put("scripts", itemScripts);
|
|
}
|
|
|
|
// NAME
|
|
String objectName = getAssignedName(item);
|
|
|
|
if(objectName == null || objectName.equals(""))
|
|
{
|
|
objectName = utils.packStringId(getNameStringId(item));
|
|
}
|
|
if(objectName == null)
|
|
{
|
|
objectName = "";
|
|
}
|
|
|
|
|
|
itemDictionary.put("objectName", objectName);
|
|
|
|
// COLOR / APPEARANCE
|
|
dictionary colorData = hue.getPalcolorData(item);
|
|
if(colorData != null)
|
|
{
|
|
itemDictionary.put("colorData", colorData);
|
|
}
|
|
|
|
|
|
if (isTangible(item))
|
|
{
|
|
byte[] customAppearance = getByteStreamFromAutoVariable(item, "customAppearance");
|
|
if(customAppearance != null && customAppearance.length > 0)
|
|
{
|
|
itemDictionary.put("customAppearance", customAppearance);
|
|
}
|
|
|
|
byte[] appearanceData = getByteStreamFromAutoVariable(item, "appearanceData");
|
|
if(appearanceData != null && appearanceData.length > 0)
|
|
{
|
|
itemDictionary.put("appearanceData", appearanceData);
|
|
}
|
|
|
|
// CREATURE ATTRIBUTES
|
|
if (isMob(item))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "packItem() : getAttribs(" + item + ") on a creature object");
|
|
|
|
attribute[] itemAttribs = getAttribs(item);
|
|
if (itemAttribs != null)
|
|
{
|
|
// attributes are stored as a vector of a pair of ints (type, value)
|
|
int[] itemAttribTypes = new int[itemAttribs.length];
|
|
int[] itemAttribValues = new int[itemAttribs.length];
|
|
|
|
// iterate through all attributes and retrieve values
|
|
int itemAttribsIter;
|
|
CustomerServiceLog("CharacterTransfer", "packItem() : retrieving " + itemAttribs.length + " attributes");
|
|
for(itemAttribsIter = 0; itemAttribsIter < itemAttribs.length; ++itemAttribsIter)
|
|
{
|
|
itemAttribTypes[itemAttribsIter] = itemAttribs[itemAttribsIter].getType();
|
|
itemAttribValues[itemAttribsIter] = getUnmodifiedMaxAttrib(item, itemAttribsIter);
|
|
CustomerServiceLog("CharacterTransfer", "packItem() : itemAttribTypes[" + itemAttribsIter + "] = " + itemAttribTypes[itemAttribsIter] + ", itemAttribsValues[" + itemAttribsIter + "] = " + itemAttribValues[itemAttribsIter]);
|
|
}
|
|
|
|
// store the arrays in the item dictionary
|
|
itemDictionary.put("attribute_types", itemAttribTypes);
|
|
itemDictionary.put("attribute_values", itemAttribValues);
|
|
}
|
|
else
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "packItem() FAILED: getAttribs(" + item + ") = null.");
|
|
return null;
|
|
}
|
|
}
|
|
// NON-CREATURE ATTRIBUTES
|
|
else
|
|
{
|
|
// Max Hitpoints
|
|
int maxHitpoints = getMaxHitpoints(item);
|
|
if (maxHitpoints != ATTRIB_ERROR)
|
|
{
|
|
itemDictionary.put("maxHitpoints", maxHitpoints);
|
|
}
|
|
else
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "packItem() FAILED: getMaxHitpoints(" + item + ") failed!");
|
|
return null;
|
|
}
|
|
|
|
// Current Hitpoints
|
|
int hitpoints = getHitpoints(item);
|
|
if (hitpoints != ATTRIB_ERROR)
|
|
{
|
|
itemDictionary.put("hitpoints", hitpoints);
|
|
}
|
|
else
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "packItem() FAILED: getHitpoints(" + item + ") failed!");
|
|
return null;
|
|
}
|
|
|
|
// Condition Flags
|
|
itemDictionary.put("conditionFlags", getCondition(item));
|
|
|
|
// is it a weapon?
|
|
boolean isWeaponItem = isWeapon(item);
|
|
itemDictionary.put("isWeaponItem", isWeaponItem);
|
|
if(isWeaponItem)
|
|
{
|
|
// get weapon stats
|
|
int currentVersion = getConversionId(item);
|
|
if(currentVersion > 0)
|
|
|
|
itemDictionary.put("currentVersion", currentVersion);
|
|
int minDamage = getWeaponMinDamage(item);
|
|
itemDictionary.put("minDamage", minDamage);
|
|
|
|
int maxDamage = getWeaponMaxDamage(item);
|
|
itemDictionary.put("maxDamage", maxDamage);
|
|
|
|
float attackSpeed = getWeaponAttackSpeed(item);
|
|
itemDictionary.put("attackSpeed", attackSpeed);
|
|
|
|
range_info rangeInfo = getWeaponRangeInfo(item);
|
|
itemDictionary.put("rangeInfoMinRange", rangeInfo.minRange);
|
|
itemDictionary.put("rangeInfoMaxRange", rangeInfo.maxRange);
|
|
|
|
float woundChance = getWeaponWoundChance(item);
|
|
itemDictionary.put("woundChance", woundChance);
|
|
|
|
float damageRadius = getWeaponDamageRadius(item);
|
|
itemDictionary.put("damageRadius", damageRadius);
|
|
|
|
int accuracy = getWeaponAccuracy(item);
|
|
itemDictionary.put("accuracy", accuracy);
|
|
|
|
int elementalType = getWeaponElementalType(item);
|
|
itemDictionary.put("elementalType", elementalType);
|
|
|
|
int elementalValue = getWeaponElementalValue(item);
|
|
itemDictionary.put("elementalValue", elementalValue);
|
|
|
|
int damageType = getWeaponDamageType(item);
|
|
itemDictionary.put("damageType", damageType);
|
|
|
|
int attackCost = getWeaponAttackCost(item);
|
|
itemDictionary.put("attackCost", attackCost);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// COUNT (number of uses or stack size)
|
|
int count = getCount(item);
|
|
if (count > 0)
|
|
{
|
|
itemDictionary.put("count", count);
|
|
}
|
|
|
|
// Bank balance (this will handle maintenance pool on various object types)
|
|
if (getBankBalance(item) > 0)
|
|
{
|
|
byte[] bankBalance = getByteStreamFromAutoVariable(item, "bankBalance");
|
|
if (bankBalance != null && bankBalance.length > 0)
|
|
{
|
|
itemDictionary.put("bankBalance", bankBalance);
|
|
}
|
|
}
|
|
|
|
// LIGHTSABER CRYSTAL OWNERSHIP
|
|
if (hasScript(item, "systems.jedi.jedi_saber_component"))
|
|
{
|
|
if( jedi.isCrystalTuned(item) )
|
|
{
|
|
if( jedi.isCrystalOwner(self,item))
|
|
{
|
|
itemDictionary.put("isCrystalOwner", true);
|
|
}
|
|
else
|
|
{
|
|
itemDictionary.put("isCrystalOwner", false);
|
|
}
|
|
}
|
|
}
|
|
|
|
// BIOLINK
|
|
obj_id biolink = getBioLink(item);
|
|
if (isIdValid(biolink))
|
|
{
|
|
itemDictionary.put("biolink", biolink);
|
|
if (biolink == self)
|
|
{
|
|
itemDictionary.put("isBiolinkOwner", true);
|
|
}
|
|
else
|
|
{
|
|
itemDictionary.put("isBiolinkOwner", false);
|
|
}
|
|
}
|
|
|
|
// Storyteller Blueprint
|
|
if ( hasObjVar(item, storyteller.BLUEPRINT_AUTHOR_OBJVAR) )
|
|
{
|
|
obj_id blueprintDesigner = getObjIdObjVar(item, storyteller.BLUEPRINT_AUTHOR_OBJVAR);
|
|
if ( isIdValid(blueprintDesigner) )
|
|
{
|
|
if ( blueprintDesigner == self )
|
|
{
|
|
itemDictionary.put("isBlueprintDesigner", true);
|
|
}
|
|
else
|
|
{
|
|
itemDictionary.put("isBlueprintDesigner", false);
|
|
}
|
|
}
|
|
}
|
|
|
|
// EQUIPPED?
|
|
if(getContainedBy(item) == self)
|
|
{
|
|
itemDictionary.put("isEquipped", true);
|
|
}
|
|
else
|
|
{
|
|
itemDictionary.put("isEquipped", false);
|
|
}
|
|
|
|
// APPEARANCE EQUIPPED?
|
|
obj_id appearanceInventory = getAppearanceInventory(self);
|
|
if(isIdValid(appearanceInventory) && getContainedBy(item) == appearanceInventory)
|
|
{
|
|
itemDictionary.put("isAppearanceEquipped", true);
|
|
}
|
|
else
|
|
{
|
|
itemDictionary.put("isAppearanceEquipped", false);
|
|
}
|
|
|
|
// RESOURCE CONTAINER
|
|
if (isGameObjectTypeOf(objectType, GOT_resource_container))
|
|
{
|
|
// GOT_resource_container_pseudo are not real resource container (i.e. they contain no resource information
|
|
// like quantity and resource type), so don't use the resource container packing logic on them
|
|
if (objectType != GOT_resource_container_pseudo)
|
|
{
|
|
int quantity = getResourceContainerQuantity(item);
|
|
if (quantity <= 0)
|
|
return null;
|
|
|
|
string resourceData = getResourceCtsData(item);
|
|
if ((resourceData == null) || (resourceData.length() <= 0))
|
|
return null;
|
|
|
|
// reduce quantity if it would exceed the allowable cts resource unit count limit
|
|
if ((resourceUnitCountLimit > 0L) && ((resourceCurrentUnitCount[0] + quantity) > resourceUnitCountLimit))
|
|
{
|
|
quantity = (int)(resourceUnitCountLimit - resourceCurrentUnitCount[0]);
|
|
|
|
if (quantity <= 0)
|
|
return null;
|
|
}
|
|
|
|
// for resource transfer limit, update running total of resource crate and resource count that will be transferred
|
|
resourceCurrentCrateCount[0] = resourceCurrentCrateCount[0] + 1;
|
|
resourceCurrentUnitCount[0] = resourceCurrentUnitCount[0] + quantity;
|
|
|
|
CustomerServiceLog("CharacterTransfer", "packItem(" + item + ") packed resource container (" + resourceCurrentCrateCount[0] + "/" + resourceCrateCountLimit + ") (" + resourceCurrentUnitCount[0] + "/" + resourceUnitCountLimit + "): resourceQuantity=" + quantity + ", resourceData=" + resourceData);
|
|
|
|
itemDictionary.put("resourceQuantity", quantity);
|
|
itemDictionary.put("resourceData", resourceData);
|
|
}
|
|
else
|
|
{
|
|
// for resource transfer limit, update running total of resource crate and resource count that will be transferred
|
|
resourceCurrentCrateCount[0] = resourceCurrentCrateCount[0] + 1;
|
|
|
|
CustomerServiceLog("CharacterTransfer", "packItem(" + item + ") packed pseudo resource container (" + resourceCurrentCrateCount[0] + "/" + resourceCrateCountLimit + ") (" + resourceCurrentUnitCount[0] + "/" + resourceUnitCountLimit + ")");
|
|
}
|
|
}
|
|
|
|
// if the factory crate's creator is transferring the crate, then on the
|
|
// destination galaxy, preserve the crate's creator information by setting
|
|
// the destination crate's creator to the destination character; otherwise,
|
|
// set the destination crate's creator to some non-zero oid that cannot
|
|
// possibly be a player on the target galaxy (like 1), to make it look like
|
|
// the crate's creator is no longer on the galaxy, like the crate's
|
|
// creator has been deleted and removed from the DB
|
|
if (objectType == GOT_misc_factory_crate)
|
|
{
|
|
obj_id factoryCrateCreator = getCrafter(item);
|
|
if (isIdValid(factoryCrateCreator))
|
|
{
|
|
itemDictionary.put("factoryCrateHasCreator", true);
|
|
|
|
if (factoryCrateCreator == self)
|
|
itemDictionary.put("factoryCrateCreatorIsSelf", true);
|
|
else
|
|
itemDictionary.put("factoryCrateCreatorIsSelf", false);
|
|
}
|
|
else
|
|
{
|
|
itemDictionary.put("factoryCrateHasCreator", false);
|
|
}
|
|
}
|
|
|
|
// MANUFACTURING SCHEMATIC
|
|
if (objectType == GOT_data_manufacturing_schematic)
|
|
{
|
|
byte[] data = getByteStreamFromAutoVariable(item, "msoCtsPackUnpack");
|
|
if (data != null && data.length > 0)
|
|
{
|
|
itemDictionary.put("msoCtsPackUnpack", data);
|
|
}
|
|
|
|
itemDictionary.put("msoDraftSchematicCrc", getDraftSchematicCrc(item));
|
|
|
|
int conversionId = getConversionId(item);
|
|
if (conversionId > 0)
|
|
itemDictionary.put("msoConversionId", conversionId);
|
|
}
|
|
|
|
// MISSION
|
|
if (objectType == GOT_data_mission_object)
|
|
{
|
|
byte[] data = getByteStreamFromAutoVariable(item, "moCtsPackUnpack");
|
|
if (data != null && data.length > 0)
|
|
{
|
|
itemDictionary.put("moCtsPackUnpack", data);
|
|
}
|
|
|
|
if (hasObjVar(item, "time_created"))
|
|
{
|
|
int secondsSinceCreated = (getGameTime() - getIntObjVar(item, "time_created"));
|
|
if (secondsSinceCreated < 0)
|
|
secondsSinceCreated = 0;
|
|
|
|
itemDictionary.put("missionAge", secondsSinceCreated);
|
|
}
|
|
}
|
|
|
|
// Player Generated Content
|
|
if (objectType == GOT_chronicles_quest_holocron || objectType == GOT_chronicles_quest_holocron_recipe)
|
|
{
|
|
byte[] data = getByteStreamFromAutoVariable(item, "PGCPacked");
|
|
if (data != null && data.length > 0)
|
|
{
|
|
itemDictionary.put("PGCPacked", data);
|
|
}
|
|
|
|
}
|
|
|
|
// INCUBATOR WITH INSTALLED RESOURCE
|
|
if ((objectTemplateCrc == ##"object/tangible/crafting/station/incubator_station.iff") && (hasObjVar(item, incubator.RESOURCE_POWER_NAME)))
|
|
{
|
|
byte[] data = getByteStreamFromAutoVariable(item, "incubatorResourceData");
|
|
if (data != null && data.length > 0)
|
|
{
|
|
itemDictionary.put("incubatorResourceData", data);
|
|
}
|
|
}
|
|
|
|
// SHIP
|
|
if (isGameObjectTypeOf(objectType, GOT_ship))
|
|
{
|
|
float mass = getChassisComponentMassMaximum(item);
|
|
float hp = getShipMaximumChassisHitPoints(item);
|
|
float currentHp = getShipCurrentChassisHitPoints(item);
|
|
|
|
itemDictionary.put("ship_mass", mass);
|
|
itemDictionary.put("ship_hp", hp);
|
|
itemDictionary.put("ship_current_hp", currentHp);
|
|
|
|
// if the ship has an installed droid control device, save the oid
|
|
// of the ***SOURCE*** droid control device; on the destination
|
|
// galaxy, we'll figure the oid of the destination droid control device
|
|
// and "relink" the destination ship to the correct droid control device
|
|
obj_id objDroidControlDevice = getDroidControlDeviceForShip(item);
|
|
if (isIdValid(objDroidControlDevice))
|
|
{
|
|
itemDictionary.put("droid_control_device", objDroidControlDevice);
|
|
}
|
|
|
|
// Sorosuub is not a customizable ship, so don't need to transfer its ship components
|
|
if ((objectTemplateName != null) && (objectTemplateName.endsWith("player_sorosuub_space_yacht.iff")))
|
|
{
|
|
// Sorosuub is not a customizable ship, so don't need to transfer its ship components
|
|
}
|
|
else
|
|
{
|
|
dictionary shipDict = new dictionary();
|
|
// get list of slots.
|
|
int[] shipSlots = getShipChassisSlots(item);
|
|
|
|
// uninstall slots.
|
|
for(int i = 0; i < shipSlots.length; ++i)
|
|
{
|
|
if(isShipSlotInstalled(item, shipSlots[i]))
|
|
{
|
|
// put uninstalled item in dictionary by slot.
|
|
obj_id component = shipUninstallComponentAllowOverload(getOwner(item), item, shipSlots[i], utils.getInventoryContainer(self));
|
|
|
|
// pack component.
|
|
if(isIdValid(component))
|
|
{
|
|
int ot = getGameObjectType(component);
|
|
if (itemIsAllowedToTransfer(component, self) && (!isGameObjectTypeOf(ot, GOT_resource_container) || !ctsHasExceededResourceTransferLimit(resourceCrateCountLimit, resourceCurrentCrateCount[0], resourceUnitCountLimit, resourceCurrentUnitCount[0])))
|
|
{
|
|
dictionary component_dict = packItem(component, ot, true, resourceCrateCountLimit, resourceCurrentCrateCount, resourceUnitCountLimit, resourceCurrentUnitCount);
|
|
if (component_dict != null)
|
|
shipDict.put(new Integer(shipSlots[i]), component_dict);
|
|
}
|
|
}
|
|
|
|
// reinstall the component.
|
|
shipInstallComponent(getOwner(item), item, shipSlots[i], component);
|
|
}
|
|
}
|
|
itemDictionary.put("shipComponents", shipDict);
|
|
}
|
|
}
|
|
|
|
// factory
|
|
if (objectType == GOT_installation_factory)
|
|
{
|
|
// factory power pool
|
|
byte[] powerValue = getByteStreamFromAutoVariable(item, "powerValue");
|
|
if (powerValue != null && powerValue.length > 0)
|
|
{
|
|
itemDictionary.put("powerValue", powerValue);
|
|
}
|
|
|
|
byte[] powerRate = getByteStreamFromAutoVariable(item, "powerRate");
|
|
if (powerRate != null && powerRate.length > 0)
|
|
{
|
|
itemDictionary.put("powerRate", powerRate);
|
|
}
|
|
|
|
// manufacturing schematic
|
|
obj_id manfSchematic = getObjectInSlot(item, "manf_schematic");
|
|
if (isIdValid(manfSchematic))
|
|
{
|
|
int ot = getGameObjectType(manfSchematic);
|
|
if (itemIsAllowedToTransfer(manfSchematic, self) && (!isGameObjectTypeOf(ot, GOT_resource_container) || !ctsHasExceededResourceTransferLimit(resourceCrateCountLimit, resourceCurrentCrateCount[0], resourceUnitCountLimit, resourceCurrentUnitCount[0])))
|
|
{
|
|
dictionary dictManfSchematic = packItem(manfSchematic, ot, true, resourceCrateCountLimit, resourceCurrentCrateCount, resourceUnitCountLimit, resourceCurrentUnitCount);
|
|
if (dictManfSchematic != null)
|
|
{
|
|
itemDictionary.put("manf_schematic", dictManfSchematic);
|
|
}
|
|
}
|
|
}
|
|
|
|
// ingredient hopper contents
|
|
obj_id ingrHopper = getObjectInSlot(item, "ingredient_hopper");
|
|
if (isIdValid(ingrHopper))
|
|
{
|
|
obj_id ingrHopperContents[] = getContents(ingrHopper);
|
|
if (ingrHopperContents != null && ingrHopperContents.length > 0)
|
|
{
|
|
dictionary dictIngrHopperContents = new dictionary();
|
|
|
|
for (int i = 0; i < ingrHopperContents.length; ++i)
|
|
{
|
|
obj_id ingrHopperContent = ingrHopperContents[i];
|
|
|
|
if (!isObjectPersisted(ingrHopperContent))
|
|
continue;
|
|
|
|
int ot = getGameObjectType(ingrHopperContent);
|
|
if (itemIsAllowedToTransfer(ingrHopperContent, self) && (!isGameObjectTypeOf(ot, GOT_resource_container) || !ctsHasExceededResourceTransferLimit(resourceCrateCountLimit, resourceCurrentCrateCount[0], resourceUnitCountLimit, resourceCurrentUnitCount[0])))
|
|
{
|
|
dictionary dictIngrHopperContent = packItem(ingrHopperContent, ot, true, resourceCrateCountLimit, resourceCurrentCrateCount, resourceUnitCountLimit, resourceCurrentUnitCount);
|
|
if (dictIngrHopperContent != null)
|
|
{
|
|
dictIngrHopperContents.put(ingrHopperContent, dictIngrHopperContent);
|
|
}
|
|
}
|
|
}
|
|
|
|
itemDictionary.put("ingr_hopper_contents", dictIngrHopperContents);
|
|
}
|
|
}
|
|
|
|
// output hopper contents
|
|
obj_id outputHopper = getObjectInSlot(item, "output_hopper");
|
|
if (isIdValid(outputHopper))
|
|
{
|
|
obj_id outputHopperContents[] = getContents(outputHopper);
|
|
if (outputHopperContents != null && outputHopperContents.length > 0)
|
|
{
|
|
dictionary dictOutputHopperContents = new dictionary();
|
|
|
|
for (int i = 0; i < outputHopperContents.length; ++i)
|
|
{
|
|
obj_id outputHopperContent = outputHopperContents[i];
|
|
|
|
if (!isObjectPersisted(outputHopperContent))
|
|
continue;
|
|
|
|
int ot = getGameObjectType(outputHopperContent);
|
|
if (itemIsAllowedToTransfer(outputHopperContent, self) && (!isGameObjectTypeOf(ot, GOT_resource_container) || !ctsHasExceededResourceTransferLimit(resourceCrateCountLimit, resourceCurrentCrateCount[0], resourceUnitCountLimit, resourceCurrentUnitCount[0])))
|
|
{
|
|
dictionary dictOutputHopperContent = packItem(outputHopperContent, ot, true, resourceCrateCountLimit, resourceCurrentCrateCount, resourceUnitCountLimit, resourceCurrentUnitCount);
|
|
if (dictOutputHopperContent != null)
|
|
{
|
|
dictOutputHopperContents.put(outputHopperContent, dictOutputHopperContent);
|
|
}
|
|
}
|
|
}
|
|
|
|
itemDictionary.put("output_hopper_contents", dictOutputHopperContents);
|
|
}
|
|
}
|
|
}
|
|
|
|
// crafting station
|
|
if (objectType == GOT_misc_crafting_station)
|
|
{
|
|
// input hopper contents
|
|
obj_id inputHopper = getObjectInSlot(item, "ingredient_hopper");
|
|
if (isIdValid(inputHopper))
|
|
{
|
|
obj_id inputHopperContents[] = getContents(inputHopper);
|
|
if (inputHopperContents != null && inputHopperContents.length > 0)
|
|
{
|
|
dictionary dictInputHopperContents = new dictionary();
|
|
|
|
for (int i = 0; i < inputHopperContents.length; ++i)
|
|
{
|
|
obj_id inputHopperContent = inputHopperContents[i];
|
|
|
|
if (!isObjectPersisted(inputHopperContent))
|
|
continue;
|
|
|
|
int ot = getGameObjectType(inputHopperContent);
|
|
if (itemIsAllowedToTransfer(inputHopperContent, self) && (!isGameObjectTypeOf(ot, GOT_resource_container) || !ctsHasExceededResourceTransferLimit(resourceCrateCountLimit, resourceCurrentCrateCount[0], resourceUnitCountLimit, resourceCurrentUnitCount[0])))
|
|
{
|
|
dictionary dictInputHopperContent = packItem(inputHopperContent, ot, true, resourceCrateCountLimit, resourceCurrentCrateCount, resourceUnitCountLimit, resourceCurrentUnitCount);
|
|
if (dictInputHopperContent != null)
|
|
{
|
|
dictInputHopperContents.put(inputHopperContent, dictInputHopperContent);
|
|
}
|
|
}
|
|
}
|
|
|
|
itemDictionary.put("input_hopper_contents", dictInputHopperContents);
|
|
}
|
|
}
|
|
}
|
|
|
|
// HOUSE CONTENTS
|
|
{
|
|
if (isGameObjectTypeOf(objectType, GOT_building) || space_utils.isPobType(objectTemplateName))
|
|
{
|
|
if (isGameObjectTypeOf(objectType, GOT_building))
|
|
{
|
|
// if the structure is a "lot over limit structure", need to
|
|
// flag it so that on the destination galaxy, the corresponding
|
|
// target structure can be flagged as the "lot over limit structure"
|
|
obj_id lotOverlimitStructure = getObjIdObjVar(self, "lotOverlimit.structure_id");
|
|
if (isIdValid(lotOverlimitStructure) && (lotOverlimitStructure == item))
|
|
{
|
|
itemDictionary.put("lotOverlimitStructureId", item);
|
|
}
|
|
}
|
|
|
|
string[] cells = getCellNames(item);
|
|
if( cells != null)
|
|
{
|
|
dictionary house_contents = new dictionary();
|
|
for(int i = 0; i < cells.length; i++)
|
|
{
|
|
obj_id cellid = getCellId(item, cells[i]);
|
|
obj_id contents[] = getContents(cellid);
|
|
if(contents != null && contents.length > 0)
|
|
{
|
|
for(int j=0; j<contents.length; j++)
|
|
{
|
|
obj_id house_item = contents[j];
|
|
|
|
if (!isObjectPersisted(house_item))
|
|
continue;
|
|
|
|
int ot = getGameObjectType(house_item);
|
|
if (itemIsAllowedToTransfer(house_item, self) && (!isGameObjectTypeOf(ot, GOT_resource_container) || !ctsHasExceededResourceTransferLimit(resourceCrateCountLimit, resourceCurrentCrateCount[0], resourceUnitCountLimit, resourceCurrentUnitCount[0])))
|
|
{
|
|
dictionary house_item_dict = packItem(house_item, ot, true, resourceCrateCountLimit, resourceCurrentCrateCount, resourceUnitCountLimit, resourceCurrentUnitCount);
|
|
if (house_item_dict != null)
|
|
{
|
|
// add the cell id
|
|
house_item_dict.put("house_cell", cells[i]);
|
|
// and the location. We'll handle the cell fixup on the other side.
|
|
house_item_dict.put("house_cell_loc", getLocation(house_item));
|
|
|
|
float[] quaternion = getQuaternion(house_item);
|
|
if ((quaternion != null) && (quaternion.length == 4))
|
|
house_item_dict.put("quaternion", quaternion);
|
|
|
|
house_contents.put(house_item, house_item_dict);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
itemDictionary.put("house_contents", house_contents);
|
|
}
|
|
}
|
|
}
|
|
|
|
// CONTAINER
|
|
int containerType = getContainerType(item);
|
|
itemDictionary.put("containerType", containerType);
|
|
|
|
// lastly, if the item is a volume container or lightsaber, get the contents
|
|
obj_id[] contents = null;
|
|
obj_id saberInv = null;
|
|
boolean b_is_ship = false;
|
|
|
|
if(containerType == 2 && !isGameObjectTypeOf(objectType, GOT_building))
|
|
{
|
|
contents = getContents(item);
|
|
}
|
|
else if (jedi.isLightsaber(item))
|
|
{
|
|
saberInv = getObjectInSlot(item, "saber_inv");
|
|
if (isIdValid(saberInv))
|
|
{
|
|
contents = getContents(saberInv);
|
|
}
|
|
}
|
|
else if ( isGameObjectTypeOf( objectType, GOT_data_ship_control_device ) )
|
|
{
|
|
contents = getContents(item);
|
|
}
|
|
else if (isGameObjectTypeOf(objectType, GOT_ship))
|
|
{
|
|
contents = getContents(item);
|
|
}
|
|
else if ( isGameObjectTypeOf( objectType, GOT_data_droid_control_device ) )
|
|
{
|
|
contents = getContents(item);
|
|
}
|
|
else if (isGameObjectTypeOf(objectType, GOT_data_house_control_device))
|
|
{
|
|
contents = getContents(item);
|
|
}
|
|
|
|
// recurse into packItem()
|
|
if(contents != null && contents.length > 0)
|
|
{
|
|
dictionary container = new dictionary();
|
|
|
|
int i = 0;
|
|
for(i = 0; i < contents.length; ++i)
|
|
{
|
|
if (guild.STR_GUILD_REMOTE_DEVICE.equals(getTemplateName(contents[i])))
|
|
continue;
|
|
|
|
int ot = getGameObjectType(contents[i]);
|
|
if (itemIsAllowedToTransfer(contents[i], self) && (!isGameObjectTypeOf(ot, GOT_resource_container) || !ctsHasExceededResourceTransferLimit(resourceCrateCountLimit, resourceCurrentCrateCount[0], resourceUnitCountLimit, resourceCurrentUnitCount[0])))
|
|
{
|
|
dictionary containedItem = packItem(contents[i], ot, allowOverride, resourceCrateCountLimit, resourceCurrentCrateCount, resourceUnitCountLimit, resourceCurrentUnitCount);
|
|
if(containedItem != null)
|
|
{
|
|
container.put(contents[i], containedItem);
|
|
|
|
// resource crate only contains 1 item; so after
|
|
// successfully packing the first item, ignore
|
|
// any other item that may be incorrectly in the crate
|
|
if (objectType == GOT_misc_factory_crate)
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if(! allowOverride)
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
itemDictionary.put("contents", container);
|
|
}
|
|
}
|
|
catch(Throwable t)
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "packItem() FAILED: item=" + item + ", allowOverride=" + allowOverride + ", itemDictionary= " + itemDictionary + " EXCEPTION: " + t);
|
|
return null;
|
|
}
|
|
|
|
return itemDictionary;
|
|
}
|
|
|
|
trigger OnUploadCharacter(dictionary characterData)
|
|
{
|
|
int resourceCrateCountLimit = 0;
|
|
string config = getConfigSetting("GameServer", "ctsResourceCrateCountLimit");
|
|
if (config != null)
|
|
resourceCrateCountLimit = utils.stringToInt(config);
|
|
|
|
int[] resourceCurrentCrateCount = new int[1];
|
|
resourceCurrentCrateCount[0] = 0;
|
|
|
|
long resourceUnitCountLimit = 0L;
|
|
config = getConfigSetting("GameServer", "ctsResourceUnitCountLimit");
|
|
if (config != null)
|
|
resourceUnitCountLimit = utils.stringToLong(config);
|
|
|
|
long[] resourceCurrentUnitCount = new long[1];
|
|
resourceCurrentUnitCount[0] = 0L;
|
|
|
|
try
|
|
{
|
|
const boolean withItems = characterData.getBoolean("withItems");
|
|
const boolean allowOverride = characterData.getBoolean("allowOverride");
|
|
CustomerServiceLog("CharacterTransfer", "OnUploadCharacter(withItems=" + withItems + ", allowOverride=" + allowOverride + ") begin");
|
|
|
|
// don't allow transfer if the character is in the middle of a CTS
|
|
if (hasObjVar(self, "disableLoginCtsInProgress"))
|
|
{
|
|
int timeOut = getIntObjVar(self, "disableLoginCtsInProgress");
|
|
if (timeOut > getGameTime())
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnUploadCharacter() : FAILED because of CTS completed or in progress for character");
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
else
|
|
{
|
|
removeObjVar(self, "disableLoginCtsInProgress");
|
|
}
|
|
}
|
|
|
|
// don't allow transfer if the character has already transferred
|
|
if (hasObjVar(self, "disableLoginCtsCompleted"))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnUploadCharacter() : FAILED because of CTS completed or in progress for character");
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
// PROFESSION
|
|
string skillTemplate = getSkillTemplate(self);
|
|
if (skillTemplate == null || skillTemplate == "" || skillTemplate == "a")
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnUploadCharacter() : skillTemplate not set! (pre-NGE source characters must choose profession prior to transfer) TRANSFER FAILED");
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
characterData.put("skillTemplate", skillTemplate);
|
|
|
|
// LEVEL
|
|
int combatLevel = getLevel(self);
|
|
characterData.put("combatLevel", combatLevel);
|
|
|
|
// workingSkill is the de facto "level" for non level-based professions
|
|
string workingSkill = getWorkingSkill(self);
|
|
if (workingSkill == null || workingSkill == "")
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnUploadCharacter() : workingSkill not set! (pre-NGE source characters must choose profession prior to transfer) TRANSFER FAILED");
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
characterData.put("workingSkill", workingSkill);
|
|
|
|
CustomerServiceLog("CharacterTransfer", "OnUploadCharacter() : skillTemplate == " + skillTemplate + ", workingSkill == " + workingSkill + ", combatLevel == " + combatLevel);
|
|
|
|
// COMMANDS and SKILLS (non-roadmap)
|
|
characterData.put("commands", getCommandListingForPlayer(self));
|
|
characterData.put("skills", getSkillListingForPlayer(self));
|
|
|
|
// OBJVARS
|
|
const string[] strObjVarLists=
|
|
{
|
|
"badge",
|
|
factions.FACTION,
|
|
groundquests.questBaseObjVar,
|
|
"live_conversions",
|
|
space_flags.IMPERIAL_CORELLIA,
|
|
space_flags.IMPERIAL_NABOO,
|
|
space_flags.IMPERIAL_TATOOINE,
|
|
space_flags.PRIVATEER_CORELLIA,
|
|
space_flags.PRIVATEER_NABOO,
|
|
space_flags.PRIVATEER_TATOOINE,
|
|
space_flags.REBEL_CORELLIA,
|
|
space_flags.REBEL_NABOO,
|
|
space_flags.REBEL_TATOOINE,
|
|
space_quest.QUEST_STATUS,
|
|
township.OBJVAR_NOVA_ORION_FACTION,
|
|
pgc_quests.PGC_GRANTED_ROADMAP_REWARDS_OBJVAR,
|
|
"spaceTrackFlagListName",
|
|
"veteran_rewards",
|
|
"_notskill.schematics",
|
|
"_notskill.mods",
|
|
"respec_voucher",
|
|
"mand.acknowledge",
|
|
respec.EXPERTISE_VERSION_OBJVAR,
|
|
"publish_gift",
|
|
"legacy",
|
|
temp_schematic.VAR_TEMP_SCHEMATIC_BASE,
|
|
"cts",
|
|
"ctsHistory",
|
|
utils.CTS_OBJVAR_HISTORY,
|
|
"hoth.flawless_reward",
|
|
"instance_player_protected_data",
|
|
"bornOnGalaxyTitleSet",
|
|
"beast_master",
|
|
"playerRespec",
|
|
"respecsBought",
|
|
player_structure.HOUSE_PACKUP_ARRAY_OBJVAR,
|
|
"space.dantooine_landing_permission",
|
|
"lotOverlimit",
|
|
"renameCharacterRequest.requestTime",
|
|
"galactic_reserve",
|
|
"preserve_existing_lightsaber_crystal_owner_objvar",
|
|
"testing_only_force_cts_failure_testing_only", // setting this objvar on a character will cause CTS to fail once the destination character receives this objvar - this is for testing CTS failure handling
|
|
};
|
|
|
|
// EXPERIENCE POINTS
|
|
dictionary experiencePoints = getExperiencePoints(self);
|
|
if(experiencePoints != null)
|
|
{
|
|
characterData.put("experience_points", experiencePoints);
|
|
}
|
|
|
|
// FACTION
|
|
characterData.put("pvp_type", pvpGetType(self));
|
|
characterData.put("pvp_aligned_faction", pvpGetAlignedFaction(self));
|
|
|
|
// GCW
|
|
characterData.put("gcw_current_point", pvpGetCurrentGcwPoints(self));
|
|
characterData.put("gcw_current_rating", pvpGetCurrentGcwRating(self));
|
|
characterData.put("gcw_current_pvp_kill", pvpGetCurrentPvpKills(self));
|
|
characterData.put("gcw_lifetime_point", pvpGetLifetimeGcwPoints(self));
|
|
characterData.put("gcw_max_imperial_rating", pvpGetMaxGcwImperialRating(self));
|
|
characterData.put("gcw_max_rebel_rating", pvpGetMaxGcwRebelRating(self));
|
|
characterData.put("gcw_lifetime_pvp_kill", pvpGetLifetimePvpKills(self));
|
|
characterData.put("gcw_next_rating_calc_time", pvpGetNextGcwRatingCalcTime(self));
|
|
|
|
// CTS tracking information
|
|
characterData.put("source_character_oid", self);
|
|
characterData.put("source_character_name", getName(self));
|
|
characterData.put("source_cluster", getClusterName());
|
|
|
|
if (hasObjVar(self, "freeCtsTransactionRuleName"))
|
|
characterData.put("freeCtsTransactionRuleName", getStringObjVar(self, "freeCtsTransactionRuleName"));
|
|
|
|
// QUESTS and other PlayerObject data
|
|
obj_id playerObject = getPlayerObject(self);
|
|
if(isIdValid(playerObject))
|
|
{
|
|
byte[] quests = getByteStreamFromAutoVariable(playerObject, "quests");
|
|
if(quests != null && quests.length > 0)
|
|
{
|
|
characterData.put("quests", quests);
|
|
}
|
|
|
|
byte[] activeQuests = getByteStreamFromAutoVariable(playerObject, "activeQuests");
|
|
if(activeQuests != null && activeQuests.length > 0)
|
|
{
|
|
characterData.put("activeQuests", activeQuests);
|
|
}
|
|
|
|
byte[] completedQuests = getByteStreamFromAutoVariable(playerObject, "completedQuests");
|
|
if(completedQuests != null && completedQuests.length > 0)
|
|
{
|
|
characterData.put("completedQuests", completedQuests);
|
|
}
|
|
|
|
byte[] currentQuest = getByteStreamFromAutoVariable(playerObject, "currentQuest");
|
|
if(currentQuest != null && currentQuest.length > 0)
|
|
{
|
|
characterData.put("currentQuest", currentQuest);
|
|
}
|
|
|
|
|
|
byte[] bornDate = getByteStreamFromAutoVariable(playerObject, "bornDate");
|
|
if(bornDate != null && bornDate.length > 0)
|
|
{
|
|
characterData.put("bornDate", bornDate);
|
|
}
|
|
|
|
byte[] playedTime = getByteStreamFromAutoVariable(playerObject, "playedTime");
|
|
if(playedTime != null && playedTime.length > 0)
|
|
{
|
|
characterData.put("playedTime", playedTime);
|
|
}
|
|
|
|
byte[] food = getByteStreamFromAutoVariable(playerObject, "food");
|
|
if(food != null && food.length > 0)
|
|
{
|
|
characterData.put("food", food);
|
|
}
|
|
|
|
byte[] maxFood = getByteStreamFromAutoVariable(playerObject, "maxFood");
|
|
if(maxFood != null && maxFood.length > 0)
|
|
{
|
|
characterData.put("maxFood", maxFood);
|
|
}
|
|
|
|
byte[] drink = getByteStreamFromAutoVariable(playerObject, "drink");
|
|
if(drink != null && drink.length > 0)
|
|
{
|
|
characterData.put("drink", drink);
|
|
}
|
|
|
|
byte[] maxDrink = getByteStreamFromAutoVariable(playerObject, "maxDrink");
|
|
if(maxDrink != null && maxDrink.length > 0)
|
|
{
|
|
characterData.put("maxDrink", maxDrink);
|
|
}
|
|
|
|
byte[] meds = getByteStreamFromAutoVariable(playerObject, "meds");
|
|
if(meds != null && meds.length > 0)
|
|
{
|
|
characterData.put("meds", meds);
|
|
}
|
|
|
|
byte[] maxMeds = getByteStreamFromAutoVariable(playerObject, "maxMeds");
|
|
if(maxMeds != null && maxMeds.length > 0)
|
|
{
|
|
characterData.put("maxMeds", maxMeds);
|
|
}
|
|
|
|
byte[] matchMakingPersonalProfileId = getByteStreamFromAutoVariable(playerObject, "matchMakingPersonalProfileId");
|
|
if(matchMakingPersonalProfileId != null && matchMakingPersonalProfileId.length > 0)
|
|
{
|
|
characterData.put("matchMakingPersonalProfileId", matchMakingPersonalProfileId);
|
|
}
|
|
|
|
byte[] matchMakingCharacterProfileId = getByteStreamFromAutoVariable(playerObject, "matchMakingCharacterProfileId");
|
|
if(matchMakingCharacterProfileId != null && matchMakingCharacterProfileId.length > 0)
|
|
{
|
|
characterData.put("matchMakingCharacterProfileId", matchMakingCharacterProfileId);
|
|
}
|
|
|
|
byte[] playerObjectWorkingSkill = getByteStreamFromAutoVariable(playerObject, "workingSkill");
|
|
if(playerObjectWorkingSkill != null && playerObjectWorkingSkill.length > 0)
|
|
{
|
|
characterData.put("workingSkill", playerObjectWorkingSkill);
|
|
}
|
|
|
|
byte[] playerObjectSkillTemplate = getByteStreamFromAutoVariable(playerObject, "skillTemplate");
|
|
if(playerObjectSkillTemplate != null && playerObjectSkillTemplate.length > 0)
|
|
{
|
|
characterData.put("skillTemplate", playerObjectSkillTemplate);
|
|
}
|
|
|
|
byte[] collections = getByteStreamFromAutoVariable(playerObject, "collections");
|
|
if(collections != null && collections.length > 0)
|
|
{
|
|
characterData.put("collections", collections);
|
|
}
|
|
|
|
byte[] collections2 = getByteStreamFromAutoVariable(playerObject, "collections2");
|
|
if(collections2 != null && collections2.length > 0)
|
|
{
|
|
characterData.put("collections2", collections2);
|
|
}
|
|
}
|
|
|
|
// WAYPOINTS
|
|
|
|
// first, make a list of quest waypoints so we don't transfer them - they'll be recreated on the destination
|
|
|
|
int[] quests = questGetAllActiveQuestIds(self);
|
|
dictionary questWaypoints = new dictionary();
|
|
for(int i = 0; i < quests.length; ++i)
|
|
{
|
|
int questCrc = quests[i];
|
|
for(int taskId = 0; taskId < 16; ++taskId)
|
|
{
|
|
obj_id waypoint = groundquests.getObjIdForWaypoint(questCrc, taskId, self);
|
|
obj_id entryWaypoint = groundquests.getObjIdForEntranceWaypoint(questCrc, taskId, self);
|
|
if(isIdValid(waypoint))
|
|
questWaypoints.put(waypoint, 1);
|
|
if(isIdValid(entryWaypoint))
|
|
questWaypoints.put(entryWaypoint, 1);
|
|
}
|
|
|
|
}
|
|
|
|
// make a list of "static quest" waypoints so we don't transfer them because
|
|
// we don't transfer "static quest"; "static quests" are those you get from
|
|
// a particular NPC that always give out the same quest (like the 'Dagonel
|
|
// "Digger" Dimms' quest you get from Tekil Barje at Tatooine, -5269 -6567);
|
|
// "static quests" don't have a corresponding mission object and don't have
|
|
// an entry in the quest journal; they just have a waypoint that contains
|
|
// the quest description
|
|
dictionary staticQuestWaypoints = new dictionary();
|
|
string[] questIDs = dataTableGetStringColumnNoDefaults("datatables/npc/static_quest/all_quest_names.iff", "quest_ids");
|
|
if ((questIDs != null) && (questIDs.length > 0))
|
|
{
|
|
for (int i = 0; i < questIDs.length; ++i)
|
|
{
|
|
if (hasObjVar(self, questIDs[i] + ".waypoint"))
|
|
{
|
|
obj_id waypoint = getObjIdObjVar(self, questIDs[i] + ".waypoint");
|
|
if (isIdValid(waypoint))
|
|
{
|
|
staticQuestWaypoints.put(waypoint, 1);
|
|
}
|
|
}
|
|
|
|
if (hasObjVar(self, questIDs[i] + ".waypointhome"))
|
|
{
|
|
obj_id waypoint = getObjIdObjVar(self, questIDs[i] + ".waypointhome");
|
|
if (isIdValid(waypoint))
|
|
{
|
|
staticQuestWaypoints.put(waypoint, 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
obj_id[] waypoints = getWaypointsInDatapad(self);
|
|
if(waypoints != null && waypoints.length > 0)
|
|
{
|
|
dictionary waypointDictionaries = new dictionary();
|
|
for(int i = 0; i < waypoints.length; ++i)
|
|
{
|
|
if (questWaypoints.containsKey(waypoints[i]))
|
|
continue;
|
|
|
|
if (staticQuestWaypoints.containsKey(waypoints[i]))
|
|
continue;
|
|
|
|
waypointDictionaries.put(waypoints[i], packWaypoint(waypoints[i]));
|
|
}
|
|
characterData.put("waypoints", waypointDictionaries);
|
|
}
|
|
|
|
if(withItems == true)
|
|
{
|
|
// cash credits
|
|
int moneyFromCash = getCashBalance(self);
|
|
CustomerServiceLog("CharacterTransfer", "OnUploadCharacter : packing " + moneyFromCash + " credits from cash");
|
|
characterData.put("moneyFromCash", moneyFromCash);
|
|
|
|
// bank credits
|
|
int moneyFromBank = getBankBalance(self);
|
|
CustomerServiceLog("CharacterTransfer", "OnUploadCharacter : packing " + moneyFromBank + " credits from bank");
|
|
characterData.put("moneyFromBank", moneyFromBank);
|
|
|
|
// inventory items
|
|
CustomerServiceLog("CharacterTransfer", "OnUploadCharacter() : packing inventory items");
|
|
dictionary inventoryDictionary = new dictionary();
|
|
obj_id[] inventoryItems = getInventoryAndEquipment(self);
|
|
obj_id playerInventory = getObjectInSlot(self, "inventory");
|
|
if(inventoryItems != null && inventoryItems.length > 0)
|
|
{
|
|
int inventoryIter = 0;
|
|
for(inventoryIter = 0; inventoryIter < inventoryItems.length; ++inventoryIter)
|
|
{
|
|
doItemPrepack(inventoryItems[inventoryIter]);
|
|
}
|
|
for(inventoryIter = 0; inventoryIter < inventoryItems.length; ++inventoryIter)
|
|
{
|
|
if(!isValidId(inventoryItems[inventoryIter]))
|
|
continue;
|
|
|
|
if(hasScript(inventoryItems[inventoryIter], "event.housepackup.cts_greeter"))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnUploadCharacter() : SKIPPING pack of inventory item " + inventoryItems[inventoryIter] + ". This item was a unique object for Free CTS and cannot be transfered to another server.");
|
|
continue;
|
|
}
|
|
|
|
if (getContainedBy(inventoryItems[inventoryIter]) != self && getContainedBy(inventoryItems[inventoryIter]) != playerInventory)
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnUploadCharacter() : SKIPPING pack of inventory item " + inventoryItems[inventoryIter] + " due to incorrect containment");
|
|
continue;
|
|
}
|
|
if (hasCondition(inventoryItems[inventoryIter], CONDITION_VENDOR))
|
|
continue;
|
|
|
|
int ot = getGameObjectType(inventoryItems[inventoryIter]);
|
|
if (itemIsAllowedToTransfer(inventoryItems[inventoryIter], self) && (!isGameObjectTypeOf(ot, GOT_resource_container) || !ctsHasExceededResourceTransferLimit(resourceCrateCountLimit, resourceCurrentCrateCount[0], resourceUnitCountLimit, resourceCurrentUnitCount[0])))
|
|
{
|
|
dictionary itemDictionary = packItem(inventoryItems[inventoryIter], ot, allowOverride, resourceCrateCountLimit, resourceCurrentCrateCount, resourceUnitCountLimit, resourceCurrentUnitCount);
|
|
if(itemDictionary != null)
|
|
{
|
|
inventoryDictionary.put(inventoryItems[inventoryIter], itemDictionary);
|
|
}
|
|
else
|
|
{
|
|
if(! allowOverride)
|
|
{
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
characterData.put("inventoryDictionary", inventoryDictionary);
|
|
LIVE_LOG("CharacterTransfer", "OnUploadCharacter() : inventory items packed (" + inventoryDictionary.toString() + ")");
|
|
|
|
// bank items
|
|
CustomerServiceLog("CharacterTransfer", "OnUploadCharacter() : packing bank items");
|
|
dictionary bankDictionary = new dictionary();
|
|
obj_id playerBank = utils.getPlayerBank(self);
|
|
if (isIdValid(playerBank))
|
|
{
|
|
obj_id[] bankItems = getContents(playerBank);
|
|
if(bankItems != null && bankItems.length > 0)
|
|
{
|
|
int bankIter = 0;
|
|
for(bankIter = 0; bankIter < bankItems.length; ++bankIter)
|
|
{
|
|
doItemPrepack(bankItems[bankIter]);
|
|
}
|
|
for(bankIter = 0; bankIter < bankItems.length; ++bankIter)
|
|
{
|
|
if(!isValidId(bankItems[bankIter]))
|
|
continue;
|
|
if (getContainedBy(bankItems[bankIter]) != self && getContainedBy(bankItems[bankIter]) != playerBank)
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnUploadCharacter() : SKIPPING pack of bank item " + bankItems[bankIter] + " due to incorrect containment");
|
|
continue;
|
|
}
|
|
if (hasCondition(bankItems[bankIter], CONDITION_VENDOR))
|
|
continue;
|
|
|
|
int ot = getGameObjectType(bankItems[bankIter]);
|
|
if (itemIsAllowedToTransfer(bankItems[bankIter], self) && (!isGameObjectTypeOf(ot, GOT_resource_container) || !ctsHasExceededResourceTransferLimit(resourceCrateCountLimit, resourceCurrentCrateCount[0], resourceUnitCountLimit, resourceCurrentUnitCount[0])))
|
|
{
|
|
dictionary itemDictionary = packItem(bankItems[bankIter], ot, allowOverride, resourceCrateCountLimit, resourceCurrentCrateCount, resourceUnitCountLimit, resourceCurrentUnitCount);
|
|
if(itemDictionary != null)
|
|
{
|
|
bankDictionary.put(bankItems[bankIter], itemDictionary);
|
|
}
|
|
else
|
|
{
|
|
if(! allowOverride)
|
|
{
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
characterData.put("bankDictionary", bankDictionary);
|
|
LIVE_LOG("CharacterTransfer", "OnUploadCharacter() : bank items packed (" + bankDictionary.toString() + ")");
|
|
}
|
|
else
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnUploadCharacter() : FAILED to pack bank items. bank object is not valid. TRANSFER FAILED");
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
// datapad transfer
|
|
CustomerServiceLog("CharacterTransfer", "OnUploadCharacter() : packing datapad items");
|
|
dictionary datapadDictionary = new dictionary();
|
|
obj_id playerDatapad = utils.getPlayerDatapad(self);
|
|
if (isIdValid(playerDatapad))
|
|
{
|
|
obj_id[] datapadItems = getContents(playerDatapad);
|
|
if(datapadItems != null && datapadItems.length > 0)
|
|
{
|
|
int datapadIter = 0;
|
|
for(datapadIter = 0; datapadIter < datapadItems.length; ++datapadIter)
|
|
{
|
|
doItemPrepack(datapadItems[datapadIter]);
|
|
}
|
|
for(datapadIter = 0; datapadIter < datapadItems.length; ++datapadIter)
|
|
{
|
|
if(!isValidId(datapadItems[datapadIter]))
|
|
continue;
|
|
if (getContainedBy(datapadItems[datapadIter]) != self && getContainedBy(datapadItems[datapadIter]) != playerDatapad)
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnUploadCharacter() : SKIPPING pack of datapad item " + datapadItems[datapadIter] + " due to incorrect containment");
|
|
continue;
|
|
}
|
|
if (guild.STR_GUILD_REMOTE_DEVICE.equals(getTemplateName(datapadItems[datapadIter])))
|
|
{
|
|
continue;
|
|
}
|
|
if (hasCondition(datapadItems[datapadIter], CONDITION_VENDOR))
|
|
continue;
|
|
|
|
int objtype = getGameObjectType(datapadItems[datapadIter]);
|
|
|
|
if (isGameObjectTypeOf(objtype, GOT_data_house_control_device))
|
|
{
|
|
//continue;
|
|
}
|
|
if (isGameObjectTypeOf(objtype, GOT_data_ship_control_device) && (TRANSFER_SHIPS == 0))
|
|
{
|
|
continue;
|
|
}
|
|
if (isGameObjectTypeOf(objtype, GOT_data_droid_control_device) && (TRANSFER_DROIDS == 0))
|
|
{
|
|
continue;
|
|
}
|
|
if (isGameObjectTypeOf(objtype, GOT_data_manufacturing_schematic))
|
|
{
|
|
//continue;
|
|
}
|
|
if (isGameObjectTypeOf(objtype, GOT_data_vendor_control_device))
|
|
{
|
|
continue;
|
|
}
|
|
if (objtype == GOT_data_mission_object)
|
|
{
|
|
// don't transfer bounty mission
|
|
string missionType = getMissionType(datapadItems[datapadIter]);
|
|
if ((missionType != null) && missionType.equals("bounty"))
|
|
continue;
|
|
}
|
|
|
|
if (itemIsAllowedToTransfer(datapadItems[datapadIter], self) && (!isGameObjectTypeOf(objtype, GOT_resource_container) || !ctsHasExceededResourceTransferLimit(resourceCrateCountLimit, resourceCurrentCrateCount[0], resourceUnitCountLimit, resourceCurrentUnitCount[0])))
|
|
{
|
|
dictionary itemDictionary = packItem(datapadItems[datapadIter], objtype, allowOverride, resourceCrateCountLimit, resourceCurrentCrateCount, resourceUnitCountLimit, resourceCurrentUnitCount);
|
|
if(itemDictionary != null)
|
|
{
|
|
datapadDictionary.put(datapadItems[datapadIter], itemDictionary);
|
|
}
|
|
else
|
|
{
|
|
if(! allowOverride)
|
|
{
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
characterData.put("datapadDictionary", datapadDictionary);
|
|
LIVE_LOG("CharacterTransfer", "OnUploadCharacter() : datapad items packed (" + datapadDictionary.toString() + ")");
|
|
|
|
}
|
|
else
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnUploadCharacter() : FAILED to pack datapad items. datapad object is not valid. TRANSFER FAILED");
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
/*
|
|
******************************************
|
|
******************************************
|
|
******************************************
|
|
BUY BACK CONTAINER
|
|
******************************************
|
|
******************************************
|
|
******************************************
|
|
*/
|
|
CustomerServiceLog("CharacterTransfer", "OnUploadCharacter() : packing appearance buy back items");
|
|
dictionary buyBackDictionary = new dictionary();
|
|
obj_id buyBackContainer = getObjIdObjVar(self, smuggler.BUYBACK_CONTAINER_VAR);
|
|
if(!isIdValid(buyBackContainer))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnUploadCharacter() : FAILED to find a buy back container object.");
|
|
}
|
|
else
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnUploadCharacter() : SUCCESS finding a buy back container object.");
|
|
obj_id[] buyBackItems = getContents(buyBackContainer);
|
|
if(buyBackItems != null && buyBackItems.length > 0)
|
|
{
|
|
int buyBackIter = 0;
|
|
for(buyBackIter = 0; buyBackIter < buyBackItems.length; ++buyBackIter)
|
|
{
|
|
doItemPrepack(buyBackItems[buyBackIter]);
|
|
}
|
|
for(buyBackIter = 0; buyBackIter < buyBackItems.length; ++buyBackIter)
|
|
{
|
|
if(!isValidId(buyBackItems[buyBackIter]))
|
|
continue;
|
|
if (getContainedBy(buyBackItems[buyBackIter]) != self && getContainedBy(buyBackItems[buyBackIter]) != buyBackContainer)
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnUploadCharacter() : SKIPPING pack of buy back item " + buyBackItems[buyBackIter] + " due to incorrect containment");
|
|
continue;
|
|
}
|
|
int objtype = getGameObjectType(buyBackItems[buyBackIter]);
|
|
|
|
if (isGameObjectTypeOf(objtype, GOT_data_ship_control_device) && (TRANSFER_SHIPS == 0))
|
|
{
|
|
continue;
|
|
}
|
|
if (itemIsAllowedToTransfer(buyBackItems[buyBackIter], self) && (!isGameObjectTypeOf(objtype, GOT_resource_container) || !ctsHasExceededResourceTransferLimit(resourceCrateCountLimit, resourceCurrentCrateCount[0], resourceUnitCountLimit, resourceCurrentUnitCount[0])))
|
|
{
|
|
dictionary itemDictionary = packItem(buyBackItems[buyBackIter], objtype, allowOverride, resourceCrateCountLimit, resourceCurrentCrateCount, resourceUnitCountLimit, resourceCurrentUnitCount);
|
|
if(itemDictionary != null)
|
|
{
|
|
buyBackDictionary.put(buyBackItems[buyBackIter], itemDictionary);
|
|
}
|
|
else
|
|
{
|
|
if(! allowOverride)
|
|
{
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
characterData.put("buyBackDictionary", buyBackDictionary);
|
|
LIVE_LOG("CharacterTransfer", "OnUploadCharacter() : buy back items packed (" + buyBackDictionary.toString() + ")");
|
|
}
|
|
|
|
// hangar transfer
|
|
CustomerServiceLog("CharacterTransfer", "OnUploadCharacter() : packing hangar items");
|
|
dictionary hangarDictionary = new dictionary();
|
|
obj_id playerHangar = utils.getPlayerHangar(self);
|
|
if (isIdValid(playerHangar))
|
|
{
|
|
obj_id[] hangarItems = getContents(playerHangar);
|
|
if(hangarItems != null && hangarItems.length > 0)
|
|
{
|
|
int hangarIter = 0;
|
|
for(hangarIter = 0; hangarIter < hangarItems.length; ++hangarIter)
|
|
{
|
|
doItemPrepack(hangarItems[hangarIter]);
|
|
}
|
|
for(hangarIter = 0; hangarIter < hangarItems.length; ++hangarIter)
|
|
{
|
|
if(!isValidId(hangarItems[hangarIter]))
|
|
continue;
|
|
if (getContainedBy(hangarItems[hangarIter]) != self && getContainedBy(hangarItems[hangarIter]) != playerHangar)
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnUploadCharacter() : SKIPPING pack of hangar item " + hangarItems[hangarIter] + " due to incorrect containment");
|
|
continue;
|
|
}
|
|
int objtype = getGameObjectType(hangarItems[hangarIter]);
|
|
|
|
if (isGameObjectTypeOf(objtype, GOT_data_ship_control_device) && (TRANSFER_SHIPS == 0))
|
|
{
|
|
continue;
|
|
}
|
|
if (itemIsAllowedToTransfer(hangarItems[hangarIter], self) && (!isGameObjectTypeOf(objtype, GOT_resource_container) || !ctsHasExceededResourceTransferLimit(resourceCrateCountLimit, resourceCurrentCrateCount[0], resourceUnitCountLimit, resourceCurrentUnitCount[0])))
|
|
{
|
|
dictionary itemDictionary = packItem(hangarItems[hangarIter], objtype, allowOverride, resourceCrateCountLimit, resourceCurrentCrateCount, resourceUnitCountLimit, resourceCurrentUnitCount);
|
|
if(itemDictionary != null)
|
|
{
|
|
hangarDictionary.put(hangarItems[hangarIter], itemDictionary);
|
|
}
|
|
else
|
|
{
|
|
if(! allowOverride)
|
|
{
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
characterData.put("hangarDictionary", hangarDictionary);
|
|
LIVE_LOG("CharacterTransfer", "OnUploadCharacter() : hangar items packed (" + hangarDictionary.toString() + ")");
|
|
|
|
}
|
|
else
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnUploadCharacter() : FAILED to pack hangar items. hangar object is not valid. The player doesnt have a hangar object, transfer continuing.");
|
|
}
|
|
|
|
|
|
// Appearance Inventory
|
|
CustomerServiceLog("CharacterTransfer", "OnUploadCharacter() : packing appearance inventory items");
|
|
dictionary appearanceDictionary = new dictionary();
|
|
obj_id playerAppearance = getAppearanceInventory(self);
|
|
if (isIdValid(playerAppearance))
|
|
{
|
|
obj_id[] appearanceItems = getContents(playerAppearance);
|
|
if(appearanceItems != null && appearanceItems.length > 0)
|
|
{
|
|
int appearanceIter = 0;
|
|
for(appearanceIter = 0; appearanceIter < appearanceItems.length; ++appearanceIter)
|
|
{
|
|
doItemPrepack(appearanceItems[appearanceIter]);
|
|
}
|
|
for(appearanceIter = 0; appearanceIter < appearanceItems.length; ++appearanceIter)
|
|
{
|
|
if(!isValidId(appearanceItems[appearanceIter]))
|
|
continue;
|
|
|
|
int objtype = getGameObjectType(appearanceItems[appearanceIter]);
|
|
|
|
if (itemIsAllowedToTransfer(appearanceItems[appearanceIter], self) && (!isGameObjectTypeOf(objtype, GOT_resource_container) || !ctsHasExceededResourceTransferLimit(resourceCrateCountLimit, resourceCurrentCrateCount[0], resourceUnitCountLimit, resourceCurrentUnitCount[0])))
|
|
{
|
|
dictionary itemDictionary = packItem(appearanceItems[appearanceIter], objtype, allowOverride, resourceCrateCountLimit, resourceCurrentCrateCount, resourceUnitCountLimit, resourceCurrentUnitCount);
|
|
if(itemDictionary != null)
|
|
{
|
|
appearanceDictionary.put(appearanceItems[appearanceIter], itemDictionary);
|
|
}
|
|
else
|
|
{
|
|
if(! allowOverride)
|
|
{
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
characterData.put("appearanceDictionary", appearanceDictionary);
|
|
LIVE_LOG("CharacterTransfer", "OnUploadCharacter() : appearance inventory items packed (" + appearanceDictionary.toString() + ")");
|
|
|
|
}
|
|
else
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnUploadCharacter() : FAILED to pack appearance inventory items. appearance inventory object is not valid. TRANSFER FAILED");
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
}
|
|
|
|
// Need to flag whether to attach player space quest script
|
|
if (hasScript(self, "space.quest_logic.player_spacequest"))
|
|
characterData.put("attachSpacequestScript", true);
|
|
|
|
// collect and write objvars. Do it this late, because the packup process may have modified something.
|
|
string[] strObjVars = new string[strObjVarLists.length];
|
|
for(int intI = 0; intI < strObjVarLists.length; intI++)
|
|
{
|
|
string strObjVar = getPackedObjvars(self, strObjVarLists[intI]);
|
|
strObjVars[intI] = strObjVar;
|
|
}
|
|
characterData.put("strObjVars", strObjVars);
|
|
}
|
|
catch(Throwable t)
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnUploadCharacter() : an exception was thrown! characterData(" + characterData + ") TRANSFER FAILED : " + t);
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
removeObjVar(self, "cts");
|
|
CustomerServiceLog("CharacterTransfer", "OnUploadCharacter() complete");
|
|
|
|
// to prevent any sort of exploit by trying to log in the character while
|
|
// the transfer is happening or when the transfer has completed but the
|
|
// character hasn't been disabled yet, set this objvar to prevent the
|
|
// character from log in for the next 10 minutes; if the transfer succeeds,
|
|
// we'll set a permanent objvar to prevent any future login on the character;
|
|
// if the transfer fails, then it will be 10 minutes before the character
|
|
// can log in again (we'll just have to live with that annoying possibility
|
|
// in order to prevent an exploit)
|
|
setObjVar(self, "disableLoginCtsInProgress", (getGameTime() + 600));
|
|
messageTo(self, "disconnectPlayerCtsCompletedOrInProgress", null, 0.1f, false);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
const string[][] STARTING_CLOTHES =
|
|
{
|
|
// human_male
|
|
// zabrak_male
|
|
// bothan_male
|
|
// moncal_male
|
|
// rodian_male
|
|
// twilek_male
|
|
{ "object/tangible/wearables/shirt/shirt_s14.iff",
|
|
"object/tangible/wearables/jacket/jacket_s16.iff",
|
|
"object/tangible/wearables/pants/pants_s14.iff",
|
|
"object/tangible/wearables/boots/boots_s05.iff" },
|
|
|
|
// human_female
|
|
// zabrak_female
|
|
// bothan_female
|
|
// rodian_female
|
|
// twilek_female
|
|
{ "object/tangible/wearables/shirt/shirt_s27.iff",
|
|
"object/tangible/wearables/pants/pants_s07.iff",
|
|
"object/tangible/wearables/boots/boots_s05.iff",
|
|
"object/tangible/wearables/gloves/gloves_s03.iff" },
|
|
|
|
// moncal_female
|
|
{ "object/tangible/wearables/shirt/shirt_s27.iff",
|
|
"object/tangible/wearables/pants/pants_s07.iff",
|
|
"object/tangible/wearables/boots/boots_s05.iff",
|
|
"object/tangible/wearables/gloves/gloves_s02.iff" },
|
|
// trandoshan_male
|
|
{ "object/tangible/wearables/shirt/shirt_s14.iff",
|
|
"object/tangible/wearables/jacket/jacket_s16.iff",
|
|
"object/tangible/wearables/pants/pants_s14.iff" },
|
|
|
|
// trandoshan_female
|
|
{ "object/tangible/wearables/shirt/shirt_s27.iff",
|
|
"object/tangible/wearables/pants/pants_s07.iff",
|
|
"object/tangible/wearables/gloves/gloves_s03.iff", }};
|
|
|
|
|
|
void createStartingEquipment(obj_id objPlayer)
|
|
{
|
|
obj_id playerInv = utils.getInventoryContainer(objPlayer);
|
|
|
|
// Starting clothes
|
|
int gender = getGender(objPlayer);
|
|
int species = getSpecies(objPlayer);
|
|
int idx = -1;
|
|
if (gender == GENDER_MALE)
|
|
{
|
|
if (species == SPECIES_HUMAN || species == SPECIES_ZABRAK || species == SPECIES_BOTHAN ||
|
|
species == SPECIES_MON_CALAMARI || species == SPECIES_RODIAN || species == SPECIES_TWILEK)
|
|
{
|
|
idx = 0;
|
|
}
|
|
|
|
if (species == SPECIES_TRANDOSHAN)
|
|
{
|
|
idx = 3;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (species == SPECIES_HUMAN || species == SPECIES_ZABRAK || species == SPECIES_BOTHAN ||
|
|
species == SPECIES_RODIAN || species == SPECIES_TWILEK)
|
|
{
|
|
idx = 1;
|
|
}
|
|
|
|
if (species == SPECIES_MON_CALAMARI)
|
|
{
|
|
idx = 2;
|
|
}
|
|
|
|
if (species == SPECIES_TRANDOSHAN)
|
|
{
|
|
idx = 4;
|
|
}
|
|
}
|
|
if ( idx >= 0 )
|
|
{
|
|
for ( int i = 0; i < STARTING_CLOTHES[idx].length; i++ )
|
|
{
|
|
obj_id newItem = createObject( STARTING_CLOTHES[idx][i], playerInv, "" );
|
|
if ( isIdValid( newItem) )
|
|
{
|
|
equip(newItem, playerInv);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
trigger OnDownloadCharacter(byte[] packedData)
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnDownloadCharacter() begin");
|
|
try
|
|
{
|
|
if(hasObjVar(self, "hasTransferred"))
|
|
return SCRIPT_OVERRIDE;
|
|
|
|
// set this flag so the object can do any special unpack handling
|
|
utils.setLocalVar(self, "ctsBeingUnpacked", true);
|
|
|
|
setObjVar(self, "hasTransferred", 1);
|
|
|
|
dictionary characterData = dictionary.unpack(packedData);
|
|
|
|
if(characterData != null)
|
|
{
|
|
String skillTemplate = characterData.getString("skillTemplate");
|
|
String workingSkill = characterData.getString("workingSkill");
|
|
int combatLevel = characterData.getInt("combatLevel");
|
|
|
|
// PROFESSION and LEVEL
|
|
// Use the same mechanism as the respec system to set character profession and level.
|
|
// Pass "false" so that roadmap items are not granted, since they will transfer explicitly.
|
|
CustomerServiceLog("CharacterTransfer", "setSkillTemplate(" + self + ", " + skillTemplate + ") (combatLevel == " + combatLevel + ", workingSkill == " + workingSkill + ")");
|
|
setObjVar(self, "clickRespec.combatLevel", combatLevel);
|
|
setObjVar(self, "clickRespec.workingSkill", workingSkill);
|
|
setObjVar(self, "clickRespec.cts", true);
|
|
setSkillTemplate(self, skillTemplate); // see OnSkillTemplateChanged()
|
|
|
|
// SKILLS
|
|
// Explicitly re-grant skills that might not have been implicitly re-granted by setSkillTemplate().
|
|
String[] skills = characterData.getStringArray("skills");
|
|
for(int i = 0; i < skills.length; ++i)
|
|
{
|
|
if (!hasSkill(self, skills[i]))
|
|
{
|
|
if (grantSkill(self, skills[i]))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "grantSkill(" + self + ", " + skills[i] + ")");
|
|
}
|
|
else
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "grantSkill(" + self + ", " + skills[i] + ") FAILED");
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
}
|
|
}
|
|
|
|
// COMMANDS
|
|
// Explicitly re-grant commands that might not have been implicitly re-granted by setSkillTemplate().
|
|
String[] commands = characterData.getStringArray("commands");
|
|
for(int i = 0; i < commands.length; ++i)
|
|
{
|
|
if (!hasCommand(self, commands[i]))
|
|
{
|
|
if (grantCommand(self, commands[i]))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "grantCommand(" + self + ", " + commands[i] + ")");
|
|
}
|
|
else
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "grantCommand(" + self + ", " + commands[i] + ") FAILED");
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
}
|
|
}
|
|
|
|
// EXPERIENCE POINTS
|
|
// Explicitly re-grant experience point types that might not have been implicitly re-granted by setSkillTemplate().
|
|
dictionary experiencePoints = characterData.getDictionary("experience_points");
|
|
if(experiencePoints != null)
|
|
{
|
|
Set keySet = experiencePoints.keySet();
|
|
Iterator expIterator = keySet.iterator();
|
|
while(expIterator.hasNext())
|
|
{
|
|
String expType = (String)expIterator.next();
|
|
if(expType != null)
|
|
{
|
|
int expValue = experiencePoints.getInt(expType);
|
|
if (getExperiencePoints(self, expType) != expValue)
|
|
{
|
|
int result = grantExperiencePoints(self, expType, expValue);
|
|
if (result == XP_ERROR)
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "grantExperiencePoints(" + self + ", " + expType + ", " + expValue + ") FAILED");
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
else
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "grantExperiencePoints(" + self + ", " + expType + ", " + expValue + ") (non-roadmap exp)");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// OBJVARS
|
|
string[] strObjVars = characterData.getStringArray("strObjVars");
|
|
for(int intI = 0; intI < strObjVars.length; intI++)
|
|
{
|
|
setPackedObjvars(self, strObjVars[intI]);
|
|
}
|
|
|
|
// remove the galactic_reserve_cooldown objvar which may have gotten
|
|
// transferred along with the galactic_reserve objvar, which isn't
|
|
// applicable on the destination galaxy
|
|
removeObjVar(self, "galactic_reserve_cooldown");
|
|
|
|
// LOT COUNT
|
|
// note - this is transferred as an objvar so that it's easier to keep track of
|
|
// as we trawl the player inventory.
|
|
|
|
if(hasObjVar(self, CTS_LOT_COUNT))
|
|
{
|
|
int lot_count = getIntObjVar(self, CTS_LOT_COUNT);
|
|
CustomerServiceLog("CharacterTransfer", "adjusting lot count(" + self + ", " + lot_count + ")" );
|
|
player_structure.adjustLotCount(getPlayerObject(self), lot_count);
|
|
}
|
|
|
|
// FACTION
|
|
int sourceCharacterAlignedFaction = characterData.getInt("pvp_aligned_faction");
|
|
int sourceCharacterPvpType = characterData.getInt("pvp_type");
|
|
switch (sourceCharacterPvpType)
|
|
{
|
|
case PVPTYPE_NEUTRAL:
|
|
// don't call pvpMakeNeutral if the character is factioned;
|
|
// factioned character with PVPTYPE_NEUTRAL means the
|
|
// character is on leave, so we must use pvpMakeOnLeave() below
|
|
if (sourceCharacterAlignedFaction == 0)
|
|
pvpMakeNeutral(self);
|
|
break;
|
|
case PVPTYPE_COVERT:
|
|
pvpMakeCovert(self);
|
|
break;
|
|
case PVPTYPE_DECLARED:
|
|
pvpMakeDeclared(self);
|
|
break;
|
|
}
|
|
|
|
pvpSetAlignedFaction(self, sourceCharacterAlignedFaction);
|
|
|
|
if ((sourceCharacterAlignedFaction != 0) && (sourceCharacterPvpType == PVPTYPE_NEUTRAL))
|
|
pvpMakeOnLeave(self);
|
|
|
|
// GCW
|
|
ctsUseOnlySetGcwInfo(self, characterData.getInt("gcw_current_point"), characterData.getInt("gcw_current_rating"), characterData.getInt("gcw_current_pvp_kill"), characterData.getLong("gcw_lifetime_point"), characterData.getInt("gcw_max_imperial_rating"), characterData.getInt("gcw_max_rebel_rating"), characterData.getInt("gcw_lifetime_pvp_kill"), characterData.getInt("gcw_next_rating_calc_time"));
|
|
|
|
// WAYPOINTS
|
|
|
|
// destroy any existing waypoints;
|
|
obj_id[] old_waypoints = getWaypointsInDatapad(self);
|
|
if(old_waypoints != null && old_waypoints.length > 0)
|
|
{
|
|
for (int i = 0; i < old_waypoints.length; ++i)
|
|
{
|
|
destroyWaypointInDatapad(old_waypoints[i], self);
|
|
}
|
|
}
|
|
dictionary waypoints = characterData.getDictionary("waypoints");
|
|
if(waypoints != null)
|
|
{
|
|
Set keySet = waypoints.keySet();
|
|
Iterator waypointIterator = keySet.iterator();
|
|
while(waypointIterator.hasNext())
|
|
{
|
|
obj_id key = (obj_id)waypointIterator.next();
|
|
dictionary waypointDict = waypoints.getDictionary(key);
|
|
unpackWaypoint(waypointDict);
|
|
}
|
|
}
|
|
// QUESTS and other PlayerObject data
|
|
obj_id playerObject = getPlayerObject(self);
|
|
if(isIdValid(playerObject))
|
|
{
|
|
if(characterData.containsKey("quests"))
|
|
{
|
|
byte[] quests = characterData.getByteArray("quests");
|
|
setAutoVariableFromByteStream(playerObject, "quests", quests);
|
|
}
|
|
|
|
if(characterData.containsKey("activeQuests"))
|
|
{
|
|
byte[] activeQuests = characterData.getByteArray("activeQuests");
|
|
setAutoVariableFromByteStream(playerObject, "activeQuests", activeQuests);
|
|
}
|
|
|
|
if(characterData.containsKey("completedQuests"))
|
|
{
|
|
byte[] completedQuests = characterData.getByteArray("completedQuests");
|
|
setAutoVariableFromByteStream(playerObject, "completedQuests", completedQuests);
|
|
}
|
|
|
|
if(characterData.containsKey("currentQuest"))
|
|
{
|
|
byte[] currentQuest = characterData.getByteArray("currentQuest");
|
|
setAutoVariableFromByteStream(playerObject, "currentQuest", currentQuest);
|
|
}
|
|
|
|
// at this point we need to make sure that any scripts for the quests
|
|
// are attached.
|
|
groundquests.reattachQuestScripts(self);
|
|
|
|
if(characterData.containsKey("bornDate"))
|
|
{
|
|
byte[] bornDate = characterData.getByteArray("bornDate");
|
|
setAutoVariableFromByteStream(playerObject, "bornDate", bornDate);
|
|
}
|
|
|
|
if(characterData.containsKey("playedTime"))
|
|
{
|
|
byte[] playedTime = characterData.getByteArray("playedTime");
|
|
setAutoVariableFromByteStream(playerObject, "playedTime", playedTime);
|
|
}
|
|
|
|
if(characterData.containsKey("food"))
|
|
{
|
|
byte[] food = characterData.getByteArray("food");
|
|
setAutoVariableFromByteStream(playerObject, "food", food);
|
|
}
|
|
|
|
if(characterData.containsKey("maxFood"))
|
|
{
|
|
byte[] maxFood = characterData.getByteArray("maxFood");
|
|
setAutoVariableFromByteStream(playerObject, "maxFood", maxFood);
|
|
}
|
|
|
|
if(characterData.containsKey("drink"))
|
|
{
|
|
byte[] drink = characterData.getByteArray("drink");
|
|
setAutoVariableFromByteStream(playerObject, "drink", drink);
|
|
}
|
|
|
|
if(characterData.containsKey("maxDrink"))
|
|
{
|
|
byte[] maxDrink = characterData.getByteArray("maxDrink");
|
|
setAutoVariableFromByteStream(playerObject, "maxDrink", maxDrink);
|
|
}
|
|
|
|
if(characterData.containsKey("meds"))
|
|
{
|
|
byte[] meds = characterData.getByteArray("meds");
|
|
setAutoVariableFromByteStream(playerObject, "meds", meds);
|
|
}
|
|
|
|
if(characterData.containsKey("maxMeds"))
|
|
{
|
|
byte[] maxMeds = characterData.getByteArray("maxMeds");
|
|
setAutoVariableFromByteStream(playerObject, "maxMeds", maxMeds);
|
|
}
|
|
|
|
if(characterData.containsKey("matchMakingPersonalProfileId"))
|
|
{
|
|
byte[] matchMakingPersonalProfileId = characterData.getByteArray("matchMakingPersonalProfileId");
|
|
setAutoVariableFromByteStream(playerObject, "matchMakingPersonalProfileId", matchMakingPersonalProfileId);
|
|
}
|
|
|
|
if(characterData.containsKey("matchMakingCharacterProfileId"))
|
|
{
|
|
byte[] matchMakingCharacterProfileId = characterData.getByteArray("matchMakingCharacterProfileId");
|
|
setAutoVariableFromByteStream(playerObject, "matchMakingCharacterProfileId", matchMakingCharacterProfileId);
|
|
}
|
|
|
|
if(characterData.containsKey("workingSkill"))
|
|
{
|
|
byte[] playerObjectWorkingSkill = characterData.getByteArray("workingSkill");
|
|
setAutoVariableFromByteStream(playerObject, "workingSkill", playerObjectWorkingSkill);
|
|
}
|
|
|
|
if(characterData.containsKey("skillTemplate"))
|
|
{
|
|
byte[] playerObjectSkillTemplate = characterData.getByteArray("skillTemplate");
|
|
setAutoVariableFromByteStream(playerObject, "skillTemplate", playerObjectSkillTemplate);
|
|
}
|
|
|
|
if(characterData.containsKey("collections"))
|
|
{
|
|
byte[] collections = characterData.getByteArray("collections");
|
|
setAutoVariableFromByteStream(playerObject, "collections", collections);
|
|
}
|
|
|
|
if(characterData.containsKey("collections2"))
|
|
{
|
|
byte[] collections2 = characterData.getByteArray("collections2");
|
|
setAutoVariableFromByteStream(playerObject, "collections2", collections2);
|
|
}
|
|
|
|
// CTS tracking information - this will update the collections information, so it must be
|
|
// done after collections unpacking, or else it will be overwritten by collections unpacking
|
|
if (characterData.containsKey("source_cluster"))
|
|
{
|
|
// "append" the CTS information to the historical CTS tracking information for the character
|
|
String sourceCluster = characterData.getString("source_cluster");
|
|
|
|
if (characterData.containsKey("source_character_oid") && characterData.containsKey("source_character_name"))
|
|
{
|
|
int ctsHistoryIndex = 1;
|
|
while (true)
|
|
{
|
|
if (!hasObjVar(self, "ctsHistory." + ctsHistoryIndex))
|
|
{
|
|
setObjVar(self, "ctsHistory." + ctsHistoryIndex, "" + getCalendarTime() + " " + sourceCluster + " " + characterData.getObjId("source_character_oid") + " " + characterData.getString("source_character_name"));
|
|
break;
|
|
}
|
|
|
|
++ctsHistoryIndex;
|
|
}
|
|
}
|
|
|
|
// only grant CTS title if it is a transfer to a different cluster
|
|
String currentCluster = getClusterName();
|
|
boolean grantCtsTitle = !sourceCluster.equals(currentCluster);
|
|
|
|
// lower case source cluster name and replace - with _
|
|
// for use to grant CTS title and/or free CTS marking
|
|
sourceCluster = toLower(sourceCluster);
|
|
sourceCluster = sourceCluster.replace('-', '_');
|
|
|
|
// grant CTS title collection slot, if qualified/necessary
|
|
if (grantCtsTitle)
|
|
modifyCollectionSlotValue(self, "cts_from_" + sourceCluster, 1L);
|
|
|
|
// if the transfer is free, set objvar on the destination character indicating so
|
|
if (characterData.containsKey("freeCtsTransactionRuleName"))
|
|
setObjVar(self, characterData.getString("freeCtsTransactionRuleName") + "." + sourceCluster, currentCluster);
|
|
}
|
|
|
|
// rebuild quests and waypoints (resets object ids by removing and readding them)
|
|
int[] quests = questGetAllActiveQuestIds(self);
|
|
for(int i = 0; i < quests.length; ++i)
|
|
{
|
|
int questId = quests[i];
|
|
|
|
for(int taskId = 0; taskId < 16; ++taskId)
|
|
{
|
|
if (questIsTaskActive(questId, taskId, self))
|
|
groundquests.refreshQuestWaypoints(questId, taskId, true, self);
|
|
}
|
|
}
|
|
}
|
|
|
|
boolean withItems = characterData.getBoolean("withItems");
|
|
if(withItems == true)
|
|
{
|
|
// nuke everything the player has
|
|
obj_id[] existingItems = getInventoryAndEquipment(self);
|
|
obj_id inv = utils.getInventoryContainer(self);
|
|
|
|
if (existingItems != null)
|
|
{
|
|
int existingIter;
|
|
for(existingIter = 0; existingIter < existingItems.length; ++existingIter)
|
|
{
|
|
if(existingItems[existingIter] != self && existingItems[existingIter] != inv)
|
|
{
|
|
LIVE_LOG("CharacterTransfer", "OnDownloadCharacter() : destroying unwanted pre-existing destination item : " + getTemplateName(existingItems[existingIter]));
|
|
destroyObject(existingItems[existingIter]);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Determine the max amount of money that can be transferred at one time
|
|
int maxMoneyTransferAmount = 100000000;
|
|
{
|
|
int tempMaxMoneyTransferAmount = utils.stringToInt( getConfigSetting("GameServer", "maxMoneyTransfer") );
|
|
if(tempMaxMoneyTransferAmount > 0)
|
|
{
|
|
maxMoneyTransferAmount = tempMaxMoneyTransferAmount;
|
|
}
|
|
}
|
|
|
|
// Restore the cash for the player
|
|
if(characterData.containsKey("moneyFromCash"))
|
|
{
|
|
int moneyFromCash = characterData.getInt("moneyFromCash");
|
|
CustomerServiceLog("CharacterTransfer", "OnDownloadCharacter : unpacking " + moneyFromCash + " credits to cash");
|
|
|
|
while (moneyFromCash > 0)
|
|
{
|
|
int transferAmount = utils.clipRange(moneyFromCash, 0, maxMoneyTransferAmount);
|
|
|
|
// We use transferBankCreditsFromNamedAccount() because the other bank transfer methods appear
|
|
// to check a source (such as the cash on hand) before allowing the transfer
|
|
if (!transferBankCreditsFromNamedAccount("characterTransfer", self, transferAmount, null, null, null))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "transferBankCreditsFromNamedAccount(characterTransfer, " + self + ", " + transferAmount + ", null, null, null) FAILED");
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
// Convert the bank credits to cash
|
|
if (!withdrawCashFromBank(self, transferAmount, null, null, null))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "withdrawCashFromBank(characterTransfer, " + self + ", " + transferAmount + ", null, null, null) FAILED");
|
|
break;
|
|
}
|
|
|
|
CustomerServiceLog("CharacterTransfer", "OnDownloadCharacter : +" + transferAmount + " credits to cash");
|
|
}
|
|
|
|
moneyFromCash -= maxMoneyTransferAmount;
|
|
}
|
|
}
|
|
|
|
// Restore the bank credits for the player
|
|
if(characterData.containsKey("moneyFromBank"))
|
|
{
|
|
int moneyFromBank = characterData.getInt("moneyFromBank");
|
|
CustomerServiceLog("CharacterTransfer", "OnDownloadCharacter : unpacking " + moneyFromBank + " credits to bank");
|
|
|
|
while (moneyFromBank > 0)
|
|
{
|
|
int transferAmount = utils.clipRange(moneyFromBank, 0, maxMoneyTransferAmount);
|
|
|
|
// We use transferBankCreditsFromNamedAccount() because the other bank transfer methods appear
|
|
// to check a source (such as the cash on hand) before allowing the transfer
|
|
if (!transferBankCreditsFromNamedAccount("characterTransfer", self, transferAmount, null, null, null))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "transferBankCreditsFromNamedAccount(characterTransfer, " + self + ", " + transferAmount + ", null, null, null) FAILED");
|
|
break;
|
|
}
|
|
|
|
CustomerServiceLog("CharacterTransfer", "OnDownloadCharacter : +" + transferAmount + " credits to bank");
|
|
|
|
moneyFromBank -= maxMoneyTransferAmount;
|
|
}
|
|
}
|
|
|
|
// ITEMS
|
|
|
|
obj_id playerInventory = utils.getInventoryContainer(self);
|
|
obj_id playerBank = utils.getPlayerBank(self);
|
|
|
|
// Prevent autostack items from attempting to restack.
|
|
utils.setScriptVar(self, "autostack.ignoreitems", true);
|
|
|
|
// Restore the inventory items for the player
|
|
CustomerServiceLog("CharacterTransfer", "OnDownloadCharacter : unpacking inventory items");
|
|
dictionary inventoryDictionary = characterData.getDictionary("inventoryDictionary");
|
|
if(inventoryDictionary == null)
|
|
{
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
else
|
|
{
|
|
Set keySet = inventoryDictionary.keySet();
|
|
Iterator inventoryIterator = keySet.iterator();
|
|
while(inventoryIterator.hasNext())
|
|
{
|
|
obj_id key = (obj_id)inventoryIterator.next();
|
|
if(isIdNull(key))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnDownloadCharacter() : could not retrieve a key from the inventory dictionary iterator. TRANSFER FAILED");
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
dictionary itemDictionary = inventoryDictionary.getDictionary(key);
|
|
|
|
if (ctsCheckAndLogUniqueStaticItemAlreadyExists(playerInventory, itemDictionary))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
obj_id unpackedItem = unpackItem(playerInventory, itemDictionary);
|
|
if(!isIdValid(unpackedItem))
|
|
{
|
|
if (isIdNull(unpackedItem))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnDownloadCharacter() : unpackItem() returned NULL id for item: " + itemDictionary);
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
else
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnDownloadCharacter() : unpackItem() returned invalid id " + unpackedItem + " for item: " + itemDictionary);
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Restore the bank items for the player
|
|
CustomerServiceLog("CharacterTransfer", "OnDownloadCharacter : unpacking bank items");
|
|
dictionary bankDictionary = characterData.getDictionary("bankDictionary");
|
|
if(bankDictionary == null)
|
|
{
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
else
|
|
{
|
|
Set keySet = bankDictionary.keySet();
|
|
Iterator bankIterator = keySet.iterator();
|
|
while(bankIterator.hasNext())
|
|
{
|
|
obj_id key = (obj_id)bankIterator.next();
|
|
if(isIdNull(key))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnDownloadCharacter() : could not retrieve a key from the bank dictionary iterator. TRANSFER FAILED");
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
dictionary itemDictionary = bankDictionary.getDictionary(key);
|
|
|
|
if (ctsCheckAndLogUniqueStaticItemAlreadyExists(playerInventory, itemDictionary))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// Unpack into inventory first to take advantage of overloading.
|
|
obj_id unpackedItem = unpackItem(playerInventory, itemDictionary);
|
|
if(!isIdValid(unpackedItem))
|
|
{
|
|
if (isIdNull(unpackedItem))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnDownloadCharacter() : unpackItem() returned NULL id for item: " + itemDictionary);
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
else
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnDownloadCharacter() : unpackItem() returned invalid id " + unpackedItem + " for item: " + itemDictionary);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// Move into bank.
|
|
if (putIn(unpackedItem, playerBank))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "unpackItem() : moved item " + unpackedItem + " into bank " + playerBank);
|
|
}
|
|
else
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "unpackItem() : FAILED to move item " + unpackedItem + " into bank " + playerBank);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Restore the datapad items for the player
|
|
obj_id playerDatapad = utils.getPlayerDatapad(self);
|
|
obj_id datapadObjects[] = getContents(playerDatapad);
|
|
for (int oldDatapad = 0; oldDatapad < datapadObjects.length; ++oldDatapad)
|
|
{
|
|
destroyObject(datapadObjects[oldDatapad]);
|
|
}
|
|
CustomerServiceLog("CharacterTransfer", "OnDownloadCharacter : unpacking datapad items");
|
|
dictionary datapadDictionary = characterData.getDictionary("datapadDictionary");
|
|
if(datapadDictionary == null)
|
|
{
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
else
|
|
{
|
|
// keep track of what new oid is assigned to each original datapad item
|
|
dictionary datapadItemOidTranslation = new dictionary();
|
|
|
|
// keep track of ships that need to be "relinked" back to its proper droid control device
|
|
resizeable obj_id[] shipsWithDroidControlDevice = new obj_id[0];
|
|
|
|
Set keySet = datapadDictionary.keySet();
|
|
Iterator datapadIterator = keySet.iterator();
|
|
while(datapadIterator.hasNext())
|
|
{
|
|
obj_id key = (obj_id)datapadIterator.next();
|
|
if(isIdNull(key))
|
|
{
|
|
|
|
CustomerServiceLog("CharacterTransfer", "OnDownloadCharacter() : could not retrieve a key from the datapad dictionary iterator. TRANSFER FAILED");
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
dictionary itemDictionary = datapadDictionary.getDictionary(key);
|
|
|
|
if (ctsCheckAndLogUniqueStaticItemAlreadyExists(playerDatapad, itemDictionary))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
obj_id unpackedItem = unpackItem(playerDatapad, itemDictionary);
|
|
if(!isIdValid(unpackedItem))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "unpackItem() : FAILED to unpack datapad item (original oid " + key + ") into datapad " + playerDatapad);
|
|
}
|
|
else
|
|
{
|
|
// keep track of what new oid is assigned to each original datapad item
|
|
datapadItemOidTranslation.put(key, unpackedItem);
|
|
|
|
// keep track of ships that need to be "relinked" back to its proper droid control device
|
|
if (utils.hasScript(unpackedItem, "space.ship_control_device.ship_control_device"))
|
|
{
|
|
obj_id ship = space_transition.getShipFromShipControlDevice(unpackedItem);
|
|
if (isIdValid(ship) && utils.hasLocalVar(ship, "droid_control_device"))
|
|
{
|
|
utils.addElement(shipsWithDroidControlDevice, ship);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// now that all datapad items have been unpacked, we need to go
|
|
// back through them and "relink" each ship back to its correct
|
|
// droid control device, if necessary
|
|
for (int i = 0; i < shipsWithDroidControlDevice.length; ++i)
|
|
{
|
|
obj_id originalDroidControlDevice = utils.getObjIdLocalVar(shipsWithDroidControlDevice[i], "droid_control_device");
|
|
if (isIdValid(originalDroidControlDevice) && datapadItemOidTranslation.containsKey(originalDroidControlDevice))
|
|
{
|
|
obj_id newDroidControlDevice = datapadItemOidTranslation.getObjId(originalDroidControlDevice);
|
|
if (isIdValid(newDroidControlDevice))
|
|
{
|
|
associateDroidControlDeviceWithShip(shipsWithDroidControlDevice[i], newDroidControlDevice);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
******************************************
|
|
******************************************
|
|
******************************************
|
|
BUY BACK CONTAINER UNPACK
|
|
******************************************
|
|
******************************************
|
|
******************************************
|
|
*/
|
|
// Restore the buy back items for the player
|
|
obj_id buyBackContainer = getObjIdObjVar(self, smuggler.BUYBACK_CONTAINER_VAR);
|
|
if(isIdValid(buyBackContainer))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnDownloadCharacter : source character had an existing buy back container: "+buyBackContainer);
|
|
|
|
obj_id buyBackObjects[] = getContents(buyBackContainer);
|
|
if(buyBackObjects != null && buyBackObjects.length > 0)
|
|
{
|
|
for (int oldContainer = 0; oldContainer < buyBackObjects.length; ++oldContainer)
|
|
{
|
|
destroyObject(buyBackObjects[oldContainer]);
|
|
}
|
|
}
|
|
}
|
|
|
|
CustomerServiceLog("CharacterTransfer", "OnDownloadCharacter : unpacking buy back items");
|
|
dictionary buyBackDictionary = characterData.getDictionary("buyBackDictionary");
|
|
if(buyBackDictionary == null || buyBackDictionary.isEmpty())
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnDownloadCharacter : source character did not have a buy back dictionary data!!");
|
|
}
|
|
else
|
|
{
|
|
//we need to create the hangar on the player
|
|
if(!isIdValid(buyBackContainer))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnDownloadCharacter : source character did not have a valid buy back container.");
|
|
buyBackContainer = smuggler.getBuyBackContainerObjVar(self);
|
|
}
|
|
//if we still dont have one, we need to bail on the transfer
|
|
if(!isIdValid(buyBackContainer))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnDownloadCharacter : source character could not create buy back container. TRANSFER FAILED");
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
Set keySet = buyBackDictionary.keySet();
|
|
Iterator buyBackIterator = keySet.iterator();
|
|
while(buyBackIterator.hasNext())
|
|
{
|
|
obj_id key = (obj_id)buyBackIterator.next();
|
|
if(isIdNull(key))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnDownloadCharacter() : could not retrieve a key from the buy back dictionary iterator. TRANSFER FAILED");
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
dictionary itemDictionary = buyBackDictionary.getDictionary(key);
|
|
obj_id unpackedItem = unpackItem(buyBackContainer, itemDictionary);
|
|
if(!isIdValid(unpackedItem))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "unpackItem() : FAILED to unpack buy back item (original oid " + key + ") into buy back container " + buyBackContainer);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
// Restore the hangar items for the player
|
|
obj_id playerHangar = utils.getPlayerHangar(self);
|
|
|
|
if(isIdValid(playerHangar))
|
|
{
|
|
obj_id hangarObjects[] = getContents(playerHangar);
|
|
for (int oldHangar = 0; oldHangar < hangarObjects.length; ++oldHangar)
|
|
{
|
|
destroyObject(hangarObjects[oldHangar]);
|
|
}
|
|
}
|
|
CustomerServiceLog("CharacterTransfer", "OnDownloadCharacter : unpacking hangar items");
|
|
dictionary hangarDictionary = characterData.getDictionary("hangarDictionary");
|
|
if( hangarDictionary == null || hangarDictionary.isEmpty() )
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnDownloadCharacter : source character did not have a hangar object.");
|
|
}
|
|
else
|
|
{
|
|
//we need to create the hangar on the player
|
|
if(!isIdValid(playerHangar))
|
|
{
|
|
playerHangar = createObject("object/tangible/datapad/character_hangar_datapad.iff", self, "hangar");
|
|
}
|
|
//if we still dont have one, we need to bail on the transfer
|
|
if(!isIdValid(playerHangar))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "OnDownloadCharacter : source character could not create hangar. TRANSFER FAILED");
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
setObjVar(self, player_structure.OBJVAR_HANGAR_CREATED, playerHangar);
|
|
|
|
//we need to persist this object
|
|
persistObject(playerHangar);
|
|
|
|
// keep track of what new oid is assigned to each original datapad item
|
|
dictionary hangarItemOidTranslation = new dictionary();
|
|
|
|
// keep track of ships that need to be "relinked" back to its proper droid control device
|
|
resizeable obj_id[] shipsWithDroidControlDevice = new obj_id[0];
|
|
|
|
Set keySet = hangarDictionary.keySet();
|
|
Iterator hangarIterator = keySet.iterator();
|
|
while(hangarIterator.hasNext())
|
|
{
|
|
obj_id key = (obj_id)hangarIterator.next();
|
|
if(isIdNull(key))
|
|
{
|
|
|
|
CustomerServiceLog("CharacterTransfer", "OnDownloadCharacter() : could not retrieve a key from the hangar dictionary iterator. TRANSFER FAILED");
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
dictionary itemDictionary = hangarDictionary.getDictionary(key);
|
|
|
|
if (ctsCheckAndLogUniqueStaticItemAlreadyExists(playerDatapad, itemDictionary))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
obj_id unpackedItem = unpackItem(playerHangar, itemDictionary);
|
|
if(!isIdValid(unpackedItem))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "unpackItem() : FAILED to unpack hangar item (original oid " + key + ") into hangar " + playerHangar);
|
|
}
|
|
else
|
|
{
|
|
// keep track of what new oid is assigned to each original hanagar item
|
|
hangarItemOidTranslation.put(key, unpackedItem);
|
|
|
|
// keep track of ships that need to be "relinked" back to its proper droid control device
|
|
if (utils.hasScript(unpackedItem, "space.ship_control_device.ship_control_device"))
|
|
{
|
|
obj_id ship = space_transition.getShipFromShipControlDevice(unpackedItem);
|
|
if (isIdValid(ship) && utils.hasLocalVar(ship, "droid_control_device"))
|
|
{
|
|
utils.addElement(shipsWithDroidControlDevice, ship);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// now that all hangar items have been unpacked, we need to go
|
|
// back through them and "relink" each ship back to its correct
|
|
// droid control device, if necessary
|
|
for (int i = 0; i < shipsWithDroidControlDevice.length; ++i)
|
|
{
|
|
obj_id originalDroidControlDevice = utils.getObjIdLocalVar(shipsWithDroidControlDevice[i], "droid_control_device");
|
|
if (isIdValid(originalDroidControlDevice) && hangarItemOidTranslation.containsKey(originalDroidControlDevice))
|
|
{
|
|
obj_id newDroidControlDevice = hangarItemOidTranslation.getObjId(originalDroidControlDevice);
|
|
if (isIdValid(newDroidControlDevice))
|
|
{
|
|
associateDroidControlDeviceWithShip(shipsWithDroidControlDevice[i], newDroidControlDevice);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Restore the appearance inventory items for the player
|
|
obj_id playerAppearance = getAppearanceInventory(self);
|
|
obj_id appearanceObjects[] = getContents(playerAppearance);
|
|
for (int oldAppearance = 0; oldAppearance < appearanceObjects.length; ++oldAppearance)
|
|
{
|
|
destroyObject(appearanceObjects[oldAppearance]);
|
|
}
|
|
CustomerServiceLog("CharacterTransfer", "OnDownloadCharacter : unpacking appearance inventory items");
|
|
dictionary appearanceDictionary = characterData.getDictionary("appearanceDictionary");
|
|
if(appearanceDictionary == null)
|
|
{
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
else
|
|
{
|
|
Set keySet = appearanceDictionary.keySet();
|
|
Iterator appearanceIterator = keySet.iterator();
|
|
while(appearanceIterator.hasNext())
|
|
{
|
|
obj_id key = (obj_id)appearanceIterator.next();
|
|
if(isIdNull(key))
|
|
{
|
|
|
|
CustomerServiceLog("CharacterTransfer", "OnDownloadCharacter() : could not retrieve a key from the appearance dictionary iterator. TRANSFER FAILED");
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
dictionary itemDictionary = appearanceDictionary.getDictionary(key);
|
|
|
|
if (ctsCheckAndLogUniqueStaticItemAlreadyExists(playerAppearance, itemDictionary))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
obj_id unpackedItem = unpackItem(playerInventory, itemDictionary);
|
|
if(!isIdValid(unpackedItem))
|
|
{
|
|
CustomerServiceLog("CharacterTransfer", "unpackItem() : FAILED to unpack appearance inventory item (original oid " + key + ") into appearance inventory " + playerAppearance);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Turn off temporary autostack prevention.
|
|
utils.removeScriptVar(self, "autostack.ignoreitems");
|
|
|
|
}
|
|
else
|
|
{
|
|
// give the player a newbie load-out
|
|
obj_id inventory = getObjectInSlot( self, "inventory" );
|
|
if(isIdValid(inventory))
|
|
{
|
|
weapons.createWeapon("object/weapon/ranged/pistol/pistol_cdef.iff", inventory, 0.90f);
|
|
createObject("object/tangible/survey_tool/survey_tool_mineral.iff", inventory, "");
|
|
weapons.createWeapon("object/weapon/melee/knife/knife_survival.iff", inventory, 0.90f);
|
|
createObject("object/tangible/crafting/station/generic_tool.iff", inventory, "");
|
|
if(utils.isProfession(self, utils.ENTERTAINER))
|
|
{
|
|
createObject("object/tangible/instrument/slitherhorn.iff", inventory, "");
|
|
}
|
|
createStartingEquipment(self);
|
|
}
|
|
}
|
|
|
|
// Need to check for whether to attach player space quest script
|
|
if (characterData.containsKey("attachSpacequestScript") && characterData.getBoolean("attachSpacequestScript"))
|
|
{
|
|
attachScript(self, "space.quest_logic.player_spacequest");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
}
|
|
catch(Throwable t)
|
|
{
|
|
removeObjVar(self, "cts");
|
|
utils.removeLocalVar(self, "ctsBeingUnpacked");
|
|
CustomerServiceLog("CharacterTransfer", "OnDownloadCharacter() : an exception was thrown! TRANSFER FAILED : " + t);
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
CustomerServiceLog("CharacterTransfer", "OnDownloadCharacter() complete");
|
|
|
|
removeObjVar(self, "cts");
|
|
removeObjVar(self, "preserve_existing_lightsaber_crystal_owner_objvar");
|
|
utils.removeLocalVar(self, "ctsBeingUnpacked");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Handle temporary skill mod expiration.
|
|
// Callback from addSkillModModifier
|
|
trigger OnSkillModDone( string modName, boolean isDead )
|
|
{
|
|
if ( modName == null )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
// Is this a food mod? (has food_ prefix)
|
|
if ( modName.indexOf( "food_" ) == 0 )
|
|
{
|
|
// Remove tracking script var.
|
|
utils.removeScriptVar( self, modName );
|
|
|
|
// Notify the player that we expired?
|
|
}
|
|
|
|
trial.bumpSession(self, "displayDefensiveMods");
|
|
messageTo(self, "setDisplayOnlyDefensiveMods", trial.getSessionDict(self, "displayDefensiveMods") , 5, false);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler removeDelayedFoodEffect()
|
|
{
|
|
if ( params == null )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
string type = params.getString( "type" );
|
|
if ( !utils.hasScriptVar( self, "food."+type+".dur" ) )
|
|
return SCRIPT_CONTINUE;
|
|
int time = utils.getIntScriptVar( self, "food."+type+".time" );
|
|
if ( getGameTime() - time < 1799 )
|
|
return SCRIPT_CONTINUE; // Old message. Ignore.
|
|
|
|
// Remove this delayed effect.
|
|
utils.removeScriptVarTree( self, "food."+type );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler removeDurationFoodEffect()
|
|
{
|
|
if ( params == null )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
string type = params.getString( "type" );
|
|
if ( !utils.hasScriptVar( self, "food."+type+".dur" ) )
|
|
return SCRIPT_CONTINUE;
|
|
int time = utils.getIntScriptVar( self, "food."+type+".time" );
|
|
if ( getGameTime() - time < 1799 )
|
|
return SCRIPT_CONTINUE; // Old message. Ignore.
|
|
|
|
// Remove this delayed effect.
|
|
utils.removeScriptVarTree( self, "food."+type );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleSpiceDownerEffect()
|
|
{
|
|
if(buff.hasBuff(self, "spice_downer"))
|
|
buff.removeBuff(self, "spice_downer");
|
|
|
|
float duration = buff.getDuration("spice_downer");
|
|
|
|
float downerModified = ((float)getEnhancedSkillStatisticModifierUncapped(self, "resistance_spice_downer"));
|
|
if(downerModified > 0)
|
|
{
|
|
duration -= downerModified;
|
|
if(duration <= 0)
|
|
{
|
|
sendSystemMessage(self, SID_SPICE_DOWNER_DURATION_NEGATED);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
sendSystemMessage(self, SID_SPICE_DOWNER_DURATION_REDUCED);
|
|
}
|
|
|
|
|
|
if(buff.applyBuff(self, "spice_downer", duration))
|
|
doAnimationAction(self, anims.PLAYER_HEAVY_COUGH_VOMIT);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//more generic a handler. Buff doesn't mention spice.
|
|
messageHandler handleGenericDownerEffect()
|
|
{
|
|
if(buff.hasBuff(self, "generic_downer"))
|
|
buff.removeBuff(self, "generic_downer");
|
|
|
|
float duration = buff.getDuration("generic_downer");
|
|
|
|
if(buff.applyBuff(self, "generic_downer", duration))
|
|
doAnimationAction(self, anims.PLAYER_HEAVY_COUGH_VOMIT);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnStomachUpdate()
|
|
{
|
|
player_stomach.getStomach( self, 0 );
|
|
player_stomach.getStomach( self, 1 );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler grantUnmodifiedExperienceOnSelf()
|
|
{
|
|
//capping players on the tutorial to level 10
|
|
if(npe.hasReachedMaxTutorialLevel(self))
|
|
{
|
|
int hadNotif = utils.getIntScriptVar(self, "npe.level_capped");
|
|
if(hadNotif == 0)
|
|
{
|
|
string_id chat = new string_id("npe", "pop_level_cap");
|
|
obj_id building = getTopMostContainer(self);
|
|
obj_id droid = utils.getObjIdScriptVar(building, "objDroidInvis");
|
|
npe.commTutorialPlayer(droid, self, 10, chat, "sound/dro_r2_3_danger.snd", "object/mobile/r2.iff");
|
|
utils.setScriptVar(self, "npe.level_capped", 1);
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
int playerLevel = getLevel(self);
|
|
if(isFreeTrialAccount(self))
|
|
{
|
|
if(playerLevel >= xp.TRIAL_LEVEL_CAP)
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
}
|
|
|
|
|
|
string xp_type = params.getString("xp_type");
|
|
int amt = params.getInt("amt");
|
|
String fromCallback = params.getString("fromCallback");
|
|
dictionary fromCallbackData = params.getDictionary("fromCallbackData");
|
|
obj_id fromId = params.getObjId("fromId");
|
|
|
|
if(luck.isLucky(self, 0.001f))
|
|
{
|
|
float bonus = amt * 0.1f;
|
|
if(bonus < 1.0f)
|
|
bonus = 1.0f;
|
|
|
|
amt += bonus;
|
|
}
|
|
|
|
xp._grantUnmodifiedExperience(self, xp_type, amt, fromCallback, fromCallbackData, fromId);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler grantSquadLeaderXpResult()
|
|
{
|
|
int granted = params.getInt(xp.GRANT_XP_RESULT_VALUE);
|
|
dictionary data = params.getDictionary(xp.GRANT_XP_RETURN_DATA);
|
|
obj_id player = data.getObjId("player");
|
|
int amt = data.getInt("amt");
|
|
xp.grantSquadLeaderXpResult(player, granted, amt);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler cmdSetExperienceResult()
|
|
{
|
|
if ( isGod(self) )
|
|
{
|
|
int granted = params.getInt(xp.GRANT_XP_RESULT_VALUE);
|
|
dictionary data = params.getDictionary(xp.GRANT_XP_RETURN_DATA);
|
|
obj_id target = data.getObjId("target");
|
|
string xp_type = data.getString("xp_type");
|
|
sendSystemMessageTestingOnly(self, "/setExperience: granted (" + target + ")" + utils.getStringName(target) + " " + granted + "pts of " + getString(new string_id("exp_n",xp_type)) + " (" + xp_type + ") experience");
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------------------------
|
|
// VETERAN REWARDS
|
|
//------------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Checks if the emote being performed is in the veteran rewards emote list,
|
|
* and prevents the player from performing the emote unless they have the
|
|
* appropriate reward.
|
|
*/
|
|
trigger OnPerformEmote(string emote)
|
|
{
|
|
int[] emotes = dataTableGetIntColumn(veteran_deprecated.EMOTES_DATATABLE, veteran_deprecated.EMOTES_COLUMN_EMOTE);
|
|
if ( emotes == null)
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// see if the emote matches a veteran emote
|
|
int emoteCrc = getStringCrc(emote);
|
|
for ( int i = 0; i < emotes.length; ++i )
|
|
{
|
|
if ( emoteCrc == emotes[i] )
|
|
{
|
|
// see if the player has the emote group that the veteran emote belongs to
|
|
int[] playerEmotes = getIntArrayObjVar(self, veteran_deprecated.OBJVAR_VETERAN_EMOTES);
|
|
if ( playerEmotes != null)
|
|
{
|
|
int emoteGroup = dataTableGetInt(veteran_deprecated.EMOTES_DATATABLE, i, veteran_deprecated.EMOTES_COLUMN_GROUP);
|
|
for ( int j = 0; j < playerEmotes.length; ++j )
|
|
{
|
|
if ( emoteGroup == playerEmotes[j])
|
|
{
|
|
// yes, the player can do the emote
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
}
|
|
}
|
|
// no, the player can't do the emote
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
/**
|
|
* Lets a player see how much veteran time they have, or lets a gm see the veteran time of any player.
|
|
*/
|
|
commandHandler cmdGetVeteranRewardTime()
|
|
{
|
|
if (!"true".equals(getConfigSetting("GameServer", "enableVeteranRewards")))
|
|
return SCRIPT_CONTINUE;
|
|
|
|
if ( isGod(self) )
|
|
{
|
|
if ( !isIdValid(target) )
|
|
target = self;
|
|
if ( veteran_deprecated.checkVeteranTarget(target) )
|
|
{
|
|
int veteranTime = getIntObjVar(target, veteran_deprecated.OBJVAR_TIME_ACTIVE);
|
|
prose_package pp = new prose_package();
|
|
pp.stringId = veteran_deprecated.SID_VETERAN_TIME_ACTIVE;
|
|
pp.target.id = target;
|
|
pp.digitInteger = veteranTime;
|
|
sendSystemMessageProse(self, pp);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( hasObjVar(self, veteran_deprecated.OBJVAR_TIME_ACTIVE) )
|
|
{
|
|
int veteranTime = getIntObjVar(self, veteran_deprecated.OBJVAR_TIME_ACTIVE);
|
|
prose_package pp = new prose_package();
|
|
pp.stringId = veteran_deprecated.SID_VETERAN_SELF_TIME_ACTIVE;
|
|
pp.digitInteger = veteranTime;
|
|
sendSystemMessageProse(self, pp);
|
|
}
|
|
else
|
|
sendSystemMessage(self, veteran_deprecated.SID_SYSTEM_INACTIVE);
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
/**
|
|
* Shows the player a list of all the veteran rewards.
|
|
* @todo: this could be done entirely on the client
|
|
*/
|
|
commandHandler cmdListVeteranRewards()
|
|
{
|
|
if (!"true".equals(getConfigSetting("GameServer", "enableVeteranRewards")))
|
|
return SCRIPT_CONTINUE;
|
|
|
|
if ( !isGod(self) && !hasObjVar(self, veteran_deprecated.OBJVAR_TIME_ACTIVE) )
|
|
{
|
|
// don't let normal players see the list until we activate the system
|
|
sendSystemMessage(self, veteran_deprecated.SID_SYSTEM_INACTIVE);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
int[] templateCrcs = dataTableGetIntColumn(veteran_deprecated.REWARDS_DATATABLE, veteran_deprecated.REWARDS_COLUMN_TEMPLATE);
|
|
if ( templateCrcs == null)
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
int[] milestones = dataTableGetIntColumn(veteran_deprecated.REWARDS_DATATABLE, veteran_deprecated.REWARDS_COLUMN_MILESTONE);
|
|
if ( milestones == null)
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
string_id[] nameIds = getNamesFromTemplates(templateCrcs);
|
|
if ( nameIds == null)
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
if ( milestones.length != nameIds.length )
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
string[] milestonesText = new string[nameIds.length];
|
|
string daysText = getString(veteran_deprecated.SID_DAYS);
|
|
for ( int i = 0; i < nameIds.length; ++i )
|
|
{
|
|
if ( nameIds[i] != null )
|
|
milestonesText[i] = "@" + nameIds[i] + " :\\>200" + (milestones[i] * veteran_deprecated.DAYS_PER_MILESTONE) + daysText;
|
|
else
|
|
milestonesText[i] = "<error>";
|
|
}
|
|
|
|
int pid = sui.listbox(self, "", milestonesText);
|
|
if ( pid < 0 )
|
|
{
|
|
CustomerServiceLog("veteran", "Could not create sui reward list, error = " + pid);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
/**
|
|
* Callback when a player has selected which milestone they want to get a reward for.
|
|
*/
|
|
messageHandler handleVeteranMilestoneSelected()
|
|
{
|
|
if ( (params == null) || (params.isEmpty()) )
|
|
{
|
|
veteran_deprecated.cleanupPlayerData(self);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
int bp = sui.getIntButtonPressed(params);
|
|
if ( bp == sui.BP_CANCEL )
|
|
{
|
|
veteran_deprecated.cleanupPlayerData(self);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
int rowSelected = sui.getListboxSelectedRow(params);
|
|
int[] milestones = self.getScriptVars().getIntArray(veteran_deprecated.SCRIPTVAR_AVAILABLE_MILESTONES);
|
|
if ( milestones == null || milestones.length < 1 || rowSelected < 0 )
|
|
{
|
|
veteran_deprecated.cleanupPlayerData(self);
|
|
sendSystemMessage(self, veteran_deprecated.SID_BAD_MILESTONE);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// for now, the only milestone that can be selected is the 180 days milestone
|
|
rowSelected = 1;
|
|
|
|
for ( int i = 0; i < milestones.length; ++i )
|
|
{
|
|
if ( (rowSelected + 1) == milestones[i] )
|
|
{
|
|
veteran_deprecated.requestVeteranRewards(self, milestones[i]);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
}
|
|
|
|
veteran_deprecated.cleanupPlayerData(self);
|
|
sendSystemMessage(self, veteran_deprecated.SID_BAD_MILESTONE);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
/**
|
|
* Callback when a player has selected which veteran reward they would like.
|
|
*/
|
|
messageHandler handleVeteranRewardSelected()
|
|
{
|
|
if ( (params == null) || (params.isEmpty()) )
|
|
{
|
|
veteran_deprecated.cleanupPlayerData(self);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
int bp = sui.getIntButtonPressed(params);
|
|
if ( bp == sui.BP_CANCEL )
|
|
{
|
|
veteran_deprecated.cleanupPlayerData(self);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
int rowSelected = sui.getListboxSelectedRow(params);
|
|
if ( rowSelected < 0 )
|
|
{
|
|
veteran_deprecated.cleanupPlayerData(self);
|
|
sendSystemMessage(self, veteran_deprecated.SID_BAD_REWARD);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
int result = veteran_deprecated.givePlayerReward(self, rowSelected, true);
|
|
if (result == veteran_deprecated.GIVE_PLAYER_REWARD_SUCCESS)
|
|
{
|
|
veteran_deprecated.cleanupPlayerData(self);
|
|
sendSystemMessage(self, veteran_deprecated.SID_REWARD_GIVEN);
|
|
}
|
|
else if (result == veteran_deprecated.GIVE_PLAYER_REWARD_FAILED)
|
|
{
|
|
veteran_deprecated.cleanupPlayerData(self);
|
|
sendSystemMessage(self, veteran_deprecated.SID_REWARD_ERROR);
|
|
}
|
|
else
|
|
{
|
|
// don't need to do anything here; it means there's
|
|
// more processing required; the code to do more
|
|
// processing will finish everything up
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
/**
|
|
* Callback when a player responds to the cofirmation window when
|
|
* the milestone of the selected reward doesn not match the milestone
|
|
* that the player is claiming
|
|
*/
|
|
messageHandler handleVeteranRewardConfirmed()
|
|
{
|
|
if ( (params == null) || (params.isEmpty()) )
|
|
{
|
|
veteran_deprecated.cleanupPlayerData(self);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
int bp = sui.getIntButtonPressed(params);
|
|
if ( bp == sui.BP_CANCEL )
|
|
{
|
|
// display the select rewards window
|
|
if ( !self.getScriptVars().hasKey(veteran_deprecated.SCRIPTVAR_SELECTED_MILESTONE) )
|
|
{
|
|
veteran_deprecated.cleanupPlayerData(self);
|
|
}
|
|
else
|
|
{
|
|
self.getScriptVars().remove(veteran_deprecated.SCRIPTVAR_SELECTED_REWARD);
|
|
int milestone = self.getScriptVars().getInt(veteran_deprecated.SCRIPTVAR_SELECTED_MILESTONE);
|
|
veteran_deprecated.requestVeteranRewards(self, milestone);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// get the index of the selected reward
|
|
if ( !self.getScriptVars().hasKey(veteran_deprecated.SCRIPTVAR_SELECTED_REWARD) )
|
|
{
|
|
CustomerServiceLog("veteran", "handleVeteranRewardConfirmed could not find SCRIPTVAR_SELECTED_REWARD for player %TU", self);
|
|
veteran_deprecated.cleanupPlayerData(self);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
int rewardIndex = self.getScriptVars().getInt(veteran_deprecated.SCRIPTVAR_SELECTED_REWARD);
|
|
int result = veteran_deprecated.givePlayerReward(self, rewardIndex, false);
|
|
if (result == veteran_deprecated.GIVE_PLAYER_REWARD_SUCCESS)
|
|
{
|
|
veteran_deprecated.cleanupPlayerData(self);
|
|
sendSystemMessage(self, veteran_deprecated.SID_REWARD_GIVEN);
|
|
}
|
|
else
|
|
{
|
|
veteran_deprecated.cleanupPlayerData(self);
|
|
sendSystemMessage(self, veteran_deprecated.SID_REWARD_ERROR);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Allows a player to receive another Flash Speeder.
|
|
commandHandler cmdFlashSpeeder()
|
|
{
|
|
string config = getConfigSetting("GameServer", "flashSpeederReward");
|
|
if (config == null || !config.equals("true"))
|
|
return SCRIPT_CONTINUE;
|
|
|
|
int sub_bits = getGameFeatureBits(self);
|
|
if (hasObjVar(self, "flash_speeder.eligible"))
|
|
sub_bits = getIntObjVar(self, "flash_speeder.eligible");
|
|
|
|
if (features.isSpaceEdition(self) && utils.checkBit(sub_bits, 3) || features.isJPCollectorEdition(self)) // 3 is the JtL pre-order bit.
|
|
{
|
|
if (!hasObjVar(self, "flash_speeder.granted"))
|
|
{
|
|
obj_id inv = getObjectInSlot(self, "inventory");
|
|
int free_space = getVolumeFree(inv);
|
|
if (free_space < 1)
|
|
{
|
|
sendSystemMessage(self, new string_id(veteran_deprecated.VETERAN_STRING_TABLE, "flash_speeder_no_inv_space"));
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
// The player hasn't received a speeder yet, so make that call.
|
|
if (veteran_deprecated.checkFlashSpeederReward(self))
|
|
sendSystemMessage(self, new string_id(veteran_deprecated.VETERAN_STRING_TABLE, "flash_speeder_granted"));
|
|
else
|
|
sendSystemMessage(self, new string_id(veteran_deprecated.VETERAN_STRING_TABLE, "flash_speeder_grant_failed"));
|
|
}
|
|
else
|
|
{
|
|
// The player has already received a free speeder. Now he must pay for extras.
|
|
sui.msgbox(self, self, "@" + veteran_deprecated.VETERAN_STRING_TABLE + ":flash_speeder_replace_prompt", sui.YES_NO, "msgFlashSpeederConfirmed");
|
|
}
|
|
}
|
|
else
|
|
sendSystemMessage(self, new string_id(veteran_deprecated.VETERAN_STRING_TABLE, "flash_speeder_not_eligible"));
|
|
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler msgFlashSpeederConfirmed()
|
|
{
|
|
string button = params.getString("buttonPressed");
|
|
if (button.equals("Cancel"))
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
if (getTotalMoney(self) < veteran_deprecated.FLASH_SPEEDER_COST)
|
|
{
|
|
sendSystemMessage(self, new string_id(veteran_deprecated.VETERAN_STRING_TABLE, "flash_speeder_no_credits"));
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
obj_id inv = getObjectInSlot(self, "inventory");
|
|
int free_space = getVolumeFree(inv);
|
|
if (free_space < 1)
|
|
{
|
|
sendSystemMessage(self, new string_id(veteran_deprecated.VETERAN_STRING_TABLE, "flash_speeder_no_inv_space"));
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
money.pay(self, money.ACCT_VEHICLE_REPAIRS, veteran_deprecated.FLASH_SPEEDER_COST, "msgFlashSpeederPaid", null);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler msgFlashSpeederPaid()
|
|
{
|
|
int result = money.getReturnCode(params);
|
|
if (result == money.RET_SUCCESS)
|
|
{
|
|
createObjectInInventoryAllowOverload("object/tangible/deed/vehicle_deed/speederbike_flash_deed.iff", self);
|
|
CustomerServiceLog("flash_speeder", "%TU has purchased a new JtL pre-order Flash Speeder.", self);
|
|
sendSystemMessage(self, new string_id(veteran_deprecated.VETERAN_STRING_TABLE, "flash_speeder_granted"));
|
|
}
|
|
else
|
|
sendSystemMessage(self, new string_id(veteran_deprecated.VETERAN_STRING_TABLE, "flash_speeder_grant_failed"));
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler playDelayedClientEffect()
|
|
{
|
|
string clientEffect = params.getString("effect");
|
|
obj_id target = params.getObjId("target");
|
|
|
|
playClientEffectObj(target, clientEffect, target, "");
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler clearScriptVar()
|
|
{
|
|
string scriptVarName = params.getString("name");
|
|
|
|
utils.removeScriptVar(self, scriptVarName);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnEnterRegion(string planetName, string regionName)
|
|
{
|
|
obj_id pvpRegionController = gcw.getPvpRegionControllerIdByName(self, regionName);
|
|
|
|
if(isIdValid(pvpRegionController) && exists(pvpRegionController))
|
|
gcw.notifyPvpRegionControllerOfPlayerEnter(pvpRegionController, self);
|
|
|
|
if(regionName.equals(restuss_event.PVP_REGION_NAME))
|
|
{
|
|
//This is to eject players from the restuss pvp region that would otherwise be stuck inside
|
|
if ((!factions.isImperial(self) && !factions.isRebel(self)) || !factions.isCovert(self) || getLevel(self) < 75)
|
|
{
|
|
if(getLevel(self) < 75)
|
|
{
|
|
sendSystemMessage(self, new string_id("gcw", "pvp_advanced_region_level_low"));
|
|
}
|
|
else
|
|
{
|
|
sendSystemMessage(self, new string_id("gcw", "pvp_advanced_region_not_allowed"));
|
|
}
|
|
|
|
int attempts = 0;
|
|
string enterAttempt = "enterRestussAttempt";
|
|
|
|
if (utils.hasScriptVar(self, enterAttempt))
|
|
attempts = utils.getIntScriptVar(self, enterAttempt);
|
|
|
|
if (attempts > 5)
|
|
{
|
|
utils.removeScriptVar(self, enterAttempt);
|
|
warpPlayer(self, "rori", 5305, 80, 6188, null, 0, 0, 0);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
attempts++;
|
|
|
|
utils.setScriptVar(self, enterAttempt, attempts);
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
sendSystemMessage(self, new string_id("gcw", "pvp_advanced_region_entered"));
|
|
|
|
pvpMakeDeclared(self);
|
|
utils.setScriptVar(self, factions.IN_ADHOC_PVP_AREA, true);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
else if(regionName.startsWith(gcw.PVP_BATTLEFIELD_REGION))
|
|
{
|
|
//try to make sure the player has the scriptvar allowing them to clone here
|
|
obj_id controllerOnPlayer = utils.getObjIdScriptVar(self, "battlefield.active");
|
|
|
|
//missing scriptvar
|
|
if(!isIdValid(controllerOnPlayer))
|
|
{
|
|
//lets make sure they belong here
|
|
if(utils.hasObjIdBatchScriptVar(pvpRegionController, "battlefield.active_players"))
|
|
{
|
|
//get all the players the BF thinks are supposed to be here
|
|
obj_id[] allPlayers = utils.getObjIdBatchScriptVar(pvpRegionController, "battlefield.active_players");
|
|
if(allPlayers != null && allPlayers.length > 0)
|
|
{
|
|
boolean found = false;
|
|
//go through them all
|
|
for(int i = 0; i < allPlayers.length; ++i)
|
|
{
|
|
//if this is me, then I need to get that scriptvar placed
|
|
if(allPlayers[i] == self)
|
|
{
|
|
utils.setScriptVar(self, "battlefield.active", pvpRegionController);
|
|
found = true;
|
|
pvp.bfLog(pvpRegionController, "Player " + getName(self) + "("+self+") Entered the Battlefield and was missing the 'battlefield.active_players' scriptvar. Player was just found and the scriptvar was added.");
|
|
break;
|
|
}
|
|
}
|
|
|
|
//if I wasnt on the list, I prolly shouldnt be here.
|
|
if(!found)
|
|
{
|
|
pvp.bfLog(pvpRegionController, "Player " + getName(self) + "("+self+") Entered the Battlefield and was missing the 'battlefield.active_players' scriptvar. After reviewing the list of players allowed, they were not found. They need to be removed from the Battlefield");
|
|
/*
|
|
dictionary params = new dictionary();
|
|
params.put("player", self);
|
|
messageTo(pvpRegionController, "validateTeamPlayer", params, 1.0f, false);
|
|
*/
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
sendSystemMessage(self, new string_id("gcw", "pvp_advanced_region_entered"));
|
|
|
|
pvpMakeDeclared(self);
|
|
utils.setScriptVar(self, factions.IN_ADHOC_PVP_AREA, true);
|
|
|
|
buff.applyBuff(self, "battlefield_radar_invisibility");
|
|
}
|
|
else if(regionName.startsWith(gcw.PVP_PUSHBACK_REGION))
|
|
{
|
|
|
|
if(((!factions.isImperial(self) && !factions.isRebel(self)) || getLevel(self) < 75) && !isGod(self))
|
|
{
|
|
if(getLevel(self) < 75)
|
|
{
|
|
sendSystemMessage(self, new string_id("gcw", "pvp_advanced_region_level_low"));
|
|
}
|
|
else
|
|
{
|
|
sendSystemMessage(self, new string_id("gcw", "pvp_advanced_region_not_allowed"));
|
|
}
|
|
|
|
string enterAttempt = "enterBattlefieldAttempt";
|
|
int attempts = utils.getIntScriptVar(self, enterAttempt);
|
|
|
|
if(attempts > 5)
|
|
{
|
|
utils.removeScriptVar(self, enterAttempt);
|
|
}
|
|
else
|
|
{
|
|
attempts++;
|
|
|
|
utils.setScriptVar(self, enterAttempt, attempts);
|
|
|
|
playMusic(self, "sound/wall_of_mist_barrier_os.snd");
|
|
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
}
|
|
|
|
obj_id controller = gcw.getPushbackControllerByPlayer(self);
|
|
|
|
if(isIdValid(controller))
|
|
{
|
|
dictionary params = new dictionary();
|
|
|
|
params.put("player", self);
|
|
|
|
messageTo(controller, "validateTeamPlayer", params, 1.0f, false);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
// Aurilia Township "Wall of Fog"
|
|
else if(regionName == "dathomir_fs_village_unpassable")
|
|
{
|
|
string config = getConfigSetting("GameServer", "fsWallOfMistEnabled");
|
|
if (config != null)
|
|
{
|
|
if (config.equals("false"))
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
if( !township.isTownshipEligible(self) || ai_lib.isInCombat( self ))
|
|
{
|
|
boolean playEffect = false;
|
|
int gameTime = getGameTime();
|
|
|
|
if( utils.hasScriptVar(self, "lastTownshipUnpassable") )
|
|
{
|
|
int lastNotice = utils.getIntScriptVar(self, "lastTownshipUnpassable");
|
|
if( gameTime - 30 > lastNotice )
|
|
{
|
|
playEffect = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
playEffect = true;
|
|
}
|
|
|
|
if( playEffect )
|
|
{
|
|
playMusic(self, "sound/wall_of_mist_barrier_os.snd");
|
|
|
|
string_id sid = null;
|
|
if(! fs_quests.isVillageEligible(self))
|
|
{
|
|
sid = new string_id("base_player", "fs_village_unavailable");
|
|
}
|
|
else if(ai_lib.isInCombat(self))
|
|
{
|
|
sid = new string_id("base_player", "fs_village_no_combat");
|
|
}
|
|
|
|
if(sid != null)
|
|
{
|
|
sendSystemMessage(self, sid);
|
|
}
|
|
|
|
utils.setScriptVar(self, "lastFsUnpassable", gameTime);
|
|
}
|
|
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
}
|
|
else if(regionName.equals("@dathomir_region_names:black_mesa") && hasObjVar(self, "outbreak.usedGate"))
|
|
{
|
|
buff.applyBuff(self, "death_troopers_no_vehicle");
|
|
}
|
|
else if ( regionName.equals("outbreak_infected_area_01") || regionName.equals("outbreak_infected_area_02") ||
|
|
regionName.equals("outbreak_infected_area_03") || regionName.equals("outbreak_infected_area_04") )
|
|
{
|
|
if ( !isGod(self) )
|
|
{
|
|
if ( needsBlackwingLightInfection(self) )
|
|
{
|
|
//This is what is setting the debuff on players that have the anti-virus
|
|
//buff.applyBuff(self, "death_troopers_infection_1");
|
|
messageTo(self, "death_troopers_apply_virus", null, 3.0f, false);
|
|
}
|
|
|
|
if ( !buff.hasBuff(self, "death_troopers_no_vehicle") )
|
|
{
|
|
buff.applyBuff(self, "death_troopers_no_vehicle");
|
|
}
|
|
|
|
// Pull the player off their mount.
|
|
obj_id currentMount = getMountId(self);
|
|
if ( isIdValid(currentMount) )
|
|
{
|
|
sendSystemMessage(self, new string_id("base_player", "dismounting"));
|
|
utils.dismountRiderJetpackCheck(self);
|
|
if ( exists(currentMount) )
|
|
{
|
|
obj_id petControlDevice = callable.getCallableCD(currentMount);
|
|
vehicle.storeVehicle(petControlDevice, self);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
region enteredRegion = getRegion(planetName, regionName);
|
|
|
|
if(enteredRegion != null && enteredRegion.getPvPType() == regions.PVP_REGION_TYPE_ADVANCED)
|
|
{
|
|
if ((!factions.isImperial(self) && !factions.isRebel(self)) || !factions.isCovert(self))
|
|
{
|
|
sendSystemMessage(self, new string_id("gcw", "pvp_advanced_region_not_allowed"));
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
sendSystemMessage(self, new string_id("gcw", "pvp_advanced_region_entered"));
|
|
|
|
if(hasObjVar(self, "intChangingFactionStatus"))
|
|
{
|
|
sendSystemMessage(self, new string_id("gcw", "pvp_advanced_region_faction_type_change_cancel"));
|
|
}
|
|
|
|
|
|
pvpMakeDeclared(self);
|
|
utils.setScriptVar(self, factions.IN_ADHOC_PVP_AREA, true);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
|
|
trigger OnExitRegion(string planetName, string regionName)
|
|
{
|
|
|
|
//message to the player that they are leaving the battlefield
|
|
if(regionName.startsWith(gcw.PVP_BATTLEFIELD_REGION) && !utils.hasScriptVar(self, "battlefield.kicked_out"))
|
|
{
|
|
sendSystemMessage(self, new string_id("gcw", "pvp_advanced_region_leaving_battlefield"));
|
|
|
|
if(buff.hasBuff(self, "battlefield_communication_run"))
|
|
{
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
}
|
|
|
|
if(regionName.startsWith(gcw.PVP_BATTLEFIELD_REGION))
|
|
{
|
|
buff.removeBuff(self, "battlefield_radar_invisibility");
|
|
utils.removeScriptVar(self, factions.IN_ADHOC_PVP_AREA);
|
|
}
|
|
|
|
//message to the player that they are REALLY exiting the battlefield
|
|
if(regionName.startsWith(gcw.PVP_PUSHBACK_REGION))
|
|
{
|
|
sendSystemMessage(self, new string_id("gcw", "pvp_advanced_region_leaving_pushback"));
|
|
}
|
|
//this scriptvar is placed when they are removed during BF cleanup. We can safely remove it now
|
|
//it was used to stop the messages above from firing.
|
|
if(utils.hasScriptVar(self, "battlefield.kicked_out"))
|
|
utils.removeScriptVar(self, "battlefield.kicked_out");
|
|
|
|
if (regionName.equals(restuss_event.PVP_REGION_NAME))
|
|
{
|
|
sendSystemMessage(self, restuss_event.SID_PVP_EXIT_MESSAGE);
|
|
if (utils.hasScriptVar(self, factions.IN_ADHOC_PVP_AREA))
|
|
utils.removeScriptVar(self, factions.IN_ADHOC_PVP_AREA);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
else if( regionName.equals("@dathomir_region_names:black_mesa") )
|
|
{
|
|
if ( isGod(self) )
|
|
sendSystemMessage(self, "[GodMode] Now Leaving the Infected Zone. We hope you enjoyed your visit.", "");
|
|
|
|
obj_id building = getTopMostContainer(self);
|
|
if ( isIdValid(building) && getTemplateName(building).equals("object/building/dathomir/imperial_blackwing_facility.iff") )
|
|
{
|
|
// do nothing...they are still inside of the quarantined research facility even though the pob area
|
|
// extends beyond the region.
|
|
if ( isGod(self) )
|
|
sendSystemMessage(self, "[GodMode] Please disregard that previous message as you are clearly still within the Blackwing facility. Be sure to enjoy your infection while you are here.", "");
|
|
}
|
|
else
|
|
{
|
|
buff.removeBuff(self, "death_troopers_infection_1");
|
|
buff.removeBuff(self, "death_troopers_infection_2");
|
|
buff.removeBuff(self, "death_troopers_infection_3");
|
|
buff.removeBuff(self, "death_troopers_no_vehicle");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
region exitedRegion = getRegion(planetName, regionName);
|
|
if(exitedRegion != null && exitedRegion.getPvPType() == regions.PVP_REGION_TYPE_ADVANCED)
|
|
{
|
|
// sendSystemMessageTestingOnly(self, "Exiting PVP region...");
|
|
sendSystemMessage(self, new string_id("gcw", "pvp_advanced_region_exited"));
|
|
|
|
if (utils.hasScriptVar(self, factions.IN_ADHOC_PVP_AREA))
|
|
utils.removeScriptVar(self, factions.IN_ADHOC_PVP_AREA);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
boolean setupNovicePilotSkill( obj_id self, string skillName )
|
|
{
|
|
//whatever is granting the novice pilot skill SHOULD be
|
|
// also setting the content flags for the profession.
|
|
// This is just in case it doesn't:
|
|
if (!skillName.startsWith("pilot_") )
|
|
return true;
|
|
|
|
|
|
|
|
if ( skillName.equals("pilot_imperial_navy_novice" ) )
|
|
{
|
|
int intAlignedFaction = pvpGetAlignedFaction(self);
|
|
if(intAlignedFaction==##"rebel")
|
|
{
|
|
sendSystemMessage( self, new string_id( "faction_recruiter", "no_rebel_imp_pilots" ));
|
|
if ( !isGod(self) )
|
|
return false;
|
|
else
|
|
sendSystemMessageTestingOnly( self, "GODMODE MSG: You can only acquire this skill BECAUSE you are in god mode" );
|
|
}
|
|
else
|
|
{
|
|
pvpSetAlignedFaction(self, ##"imperial" );
|
|
if ( pvpGetType( self ) == PVPTYPE_NEUTRAL )
|
|
{
|
|
if(!factions.isOnLeave(self))
|
|
{
|
|
pvpMakeCovert(self);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// u r imperial already
|
|
}
|
|
}
|
|
}
|
|
else if ( skillName.equals("pilot_rebel_navy_novice" ) )
|
|
{
|
|
int intAlignedFaction = pvpGetAlignedFaction(self);
|
|
if(intAlignedFaction==##"imperial")
|
|
{
|
|
sendSystemMessage( self, new string_id( "faction_recruiter", "no_imp_rebel_pilots" ));
|
|
if ( !isGod(self) )
|
|
return false;
|
|
else
|
|
sendSystemMessageTestingOnly( self, "GODMODE MSG: You can only acquire this skill BECAUSE you are in god mode" );
|
|
}
|
|
else
|
|
{
|
|
pvpSetAlignedFaction(self, ##"rebel" );
|
|
if ( pvpGetType( self ) == PVPTYPE_NEUTRAL )
|
|
{
|
|
if(!factions.isOnLeave(self))
|
|
{
|
|
pvpMakeCovert(self);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// u r rebelalready
|
|
}
|
|
}
|
|
}
|
|
if ( !hasObjVar( self, space_flags.SPACE_TRACK_FLAG ) )
|
|
{
|
|
//either it hasn't been set, or hasn't been set yet:
|
|
if ( skillName == "pilot_imperial_navy_novice" )
|
|
space_flags.setSpaceTrack( self, space_flags.IMPERIAL_TATOOINE );
|
|
else if ( skillName == "pilot_rebel_navy_novice" )
|
|
space_flags.setSpaceTrack( self, space_flags.REBEL_TATOOINE );
|
|
else
|
|
space_flags.setSpaceTrack( self, space_flags.PRIVATEER_TATOOINE );
|
|
}
|
|
return true;
|
|
}
|
|
|
|
boolean allowedBySpaceExpansion( obj_id self, string skillName )
|
|
{
|
|
if ( skillName.startsWith("pilot_") || skillName.startsWith("crafting_shipwright_" ) )
|
|
{
|
|
if ( !features.isSpaceEdition( self ))
|
|
{
|
|
//You cannot have one of these skills without the space expansion!
|
|
sendSystemMessage( self, new string_id( "skl_use", "need_space_expansion" ) );
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
commandHandler gmForceCommand()
|
|
{
|
|
if((params==null)||(params.equals("")))
|
|
{
|
|
sendSystemMessageTestingOnly(self, "Incorrect syntax. Syntax is /gmForceCommand <command> <target_object_id> <command parameters>. You can use 0 instead of a valid object_id if needed. Params are optionsl");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
if(!isIdValid(target))
|
|
{
|
|
target = getLookAtTarget(self);
|
|
}
|
|
|
|
if(!isIdValid(target))
|
|
{
|
|
sendSystemMessageTestingOnly(self, "You must target the player you wish to call this command on");
|
|
return SCRIPT_CONTINUE;
|
|
|
|
}
|
|
string[] strText = split(params, ',');
|
|
if(strText.length<2)
|
|
{
|
|
sendSystemMessageTestingOnly(self, "Incorrect syntax. Syntax is /gmForceCommand <command> <target_object_id> <command parameters>. You can use 0 instead of a valid object_id if needed. Params are optionsl");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
string strCommand = strText[0];
|
|
if(strCommand.equals("gmForceCommand"))
|
|
{
|
|
sendSystemMessageTestingOnly(self, "You are not permitted to use this command to force this command. Don't do that");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
string strCommandTarget = strText[1];
|
|
string strParams = "";
|
|
|
|
if(strText.length==3)
|
|
{
|
|
strParams = strText[2];
|
|
}
|
|
|
|
|
|
Long lngId;
|
|
try
|
|
{
|
|
lngId = new Long(strCommandTarget); // convert the string to a long so we can make an obj_id
|
|
} // try with error handling
|
|
catch (NumberFormatException err)
|
|
{
|
|
sendSystemMessageTestingOnly(self, strCommandTarget+" is not a valid number to use. Please retry.");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
obj_id objCommandTarget = obj_id.getObjId(lngId.longValue());
|
|
if(isIdValid(objCommandTarget)&&(!exists(objCommandTarget)))
|
|
{
|
|
sendSystemMessageTestingOnly(self, "That command target does not exist and it is not 0. Object id was "+objCommandTarget);
|
|
return SCRIPT_CONTINUE;
|
|
|
|
}
|
|
|
|
dictionary dctParams = new dictionary();
|
|
dctParams.put("objTarget", objCommandTarget);
|
|
int intCommand = getStringCrc(strCommand);
|
|
dctParams.put("intCommand", intCommand);
|
|
dctParams.put("strParams", strParams);
|
|
messageTo(target, "doForcedGmCommand", dctParams, 0, false);
|
|
sendSystemMessageTestingOnly(self, "Forcing "+target+" to do command "+ strCommand+" to target "+objCommandTarget+" with Parameters "+strParams);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler doForcedGmCommand()
|
|
{
|
|
int intCommand = params.getInt("intCommand");
|
|
obj_id objTarget = params.getObjId("objTarget");
|
|
string strParams = params.getString("strParams");
|
|
queueCommand(self, intCommand, objTarget, strParams, COMMAND_PRIORITY_DEFAULT);
|
|
sendSystemMessageTestingOnly(self, "A GM Forced you to do a command");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
|
|
messageHandler factionBaseLotRefund()
|
|
{
|
|
int baseLotRefund = params.getInt( "baseLotRefund" );
|
|
obj_id playerObject = getPlayerObject(self);
|
|
//int lots = getAccountNumLots(playerObject);
|
|
//LOG("hq", "player.base.base_player ////--\\\\ factionBaseLotRefund: message received. player account num lots BEFORE adjust is = : "+lots);
|
|
|
|
adjustLotCount( playerObject, (baseLotRefund * -1) );
|
|
//LOG("hq", "player.base.base_player ////--\\\\ factionBaseLotRefund: message received. Refunding passed-in lot value to player. Number of lots to be refunded = : "+baseLotRefund);
|
|
|
|
//lots = getAccountNumLots(playerObject);
|
|
//LOG("hq", "player.base.base_player ////--\\\\ factionBaseLotRefund: message received. player account num lots AFTER adjust is = : "+lots);
|
|
|
|
float baseFactionRefund = params.getFloat("baseFactionRefund");
|
|
int baseFaction = params.getInt("baseFaction");
|
|
factions.addFactionStanding( self, baseFaction, baseFactionRefund );
|
|
|
|
// NEED TO TELL PLAYER WHAT WE'VE DONE.
|
|
if ( (int)(baseFactionRefund) > 0)
|
|
{
|
|
int intBaseFactionRefund = (int)(baseFactionRefund);
|
|
sendSystemMessageProse(self, prose.getPackage(new string_id ("faction_perk", "old_fbase_refunded"), baseLotRefund, intBaseFactionRefund));
|
|
}
|
|
else
|
|
sendSystemMessageProse(self, prose.getPackage(new string_id ("faction_perk", "new_old_fbase_refunded"), baseLotRefund));
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Some other object has sent the player a message, telling the player to deduct some money.
|
|
*/
|
|
messageHandler transferMoneyToNamedAccount()
|
|
{
|
|
transferBankCreditsToNamedAccount(self, params.getString("account"), params.getInt("amount"), "transferMoneyToNamedAccount_successCallback", "transferMoneyToNamedAccount_failCallback", params);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler transferMoneyToNamedAccount_successCallback()
|
|
{
|
|
messageTo(params.getObjId("replyTo"), params.getString("successCallback"), params, 0, false);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler transferMoneyToNamedAccount_failCallback()
|
|
{
|
|
messageTo(params.getObjId("replyTo"), params.getString("failCallback"), params, 0, false);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler sendSystemMessageProseAuthoritative()
|
|
{
|
|
if ((params == null) || (params.isEmpty()))
|
|
{
|
|
debugSpeakMsg (self, "sendSystemMessageProseAuthoritative called with no params");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
string stf = params.getString("stf");
|
|
string message = params.getString("message");
|
|
obj_id TO = params.getObjId("TO");
|
|
obj_id TT = params.getObjId("TT");
|
|
|
|
prose_package pp = new prose_package();
|
|
string_id msg = new string_id (stf, message);
|
|
pp = prose.setStringId(pp, msg);
|
|
pp = prose.setTO(pp, TO);
|
|
pp = prose.setTT(pp, TT);
|
|
|
|
sendSystemMessageProse(self, pp);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnRecapacitated()
|
|
{
|
|
dictionary params = new dictionary();
|
|
params.put("player", self);
|
|
broadcastMessage("handleSawRecapacitation", params);
|
|
|
|
const int aggroImmuneDuration = 12;
|
|
setAggroImmuneDuration(self, aggroImmuneDuration);
|
|
debugSpeakMsgc(aiLoggingEnabled(self), self, "AggroImmune(" + aggroImmuneDuration + "s)");
|
|
utils.removeScriptVar(self, "incap.timeStamp");
|
|
combat.clearCombatDebuffs(self);
|
|
|
|
//iterate through all players equipped items and see if they have worn buff effects and re-apply them
|
|
static_item.validateWornEffects(self);
|
|
|
|
//iterate through all players equipped chest,weapon,shirt slots and re-apply power up effects if there
|
|
reverse_engineering.checkPowerUpReApply(self);
|
|
|
|
messageTo(self, "setDisplayOnlyDefensiveMods", trial.getSessionDict(self, "displayDefensiveMods") , 5, false);
|
|
|
|
if(utils.isProfession(self, utils.SMUGGLER))
|
|
{
|
|
messageTo(self, "applySmugglingBonuses", null, 1.0f, false);
|
|
}
|
|
|
|
if ( utils.isProfession(self, utils.FORCE_SENSITIVE) && getLevel(self) > 3 )
|
|
{
|
|
if( !buff.isInStance(self) && !buff.isInFocus(self) )
|
|
{
|
|
messageTo(self, "applyJediStance", null, 1.0f, false);
|
|
}
|
|
}
|
|
|
|
if (factions.isInAdhocPvpArea(self))
|
|
pvpMakeDeclared(self);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleInstanceTimeRemainingMessage()
|
|
{
|
|
string message = params.getString("message");
|
|
sendSystemMessageTestingOnly(self, message);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler setRespecVersion()
|
|
{
|
|
respec.setRespecVersion(self);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
|
|
messageHandler receiveCreditForKill()
|
|
{
|
|
string creatureName = params.getString("creatureName");
|
|
if( creatureName != null && creatureName != "" )
|
|
{
|
|
location creatureLoc = params.getLocation("location");
|
|
location playerLoc = getLocation(self);
|
|
|
|
if(!playerLoc.area.equals(creatureLoc.area))
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//faction collections -
|
|
string col_faction = params.getString("col_faction");
|
|
int col_difficulty = params.getInt("difficultyClass");
|
|
if(col_faction != null && !col_faction.equals(""))
|
|
{
|
|
//Emperor's Hand gets counted for both factions.
|
|
string[] col_factionArray = split(col_faction, ',');
|
|
for(int i = 0; i < col_factionArray.length; i++)
|
|
{
|
|
if(col_faction.equals("rebel"))
|
|
{
|
|
if(col_difficulty == 0)
|
|
{
|
|
modifyCollectionSlotValue(self, "kill_rebel_01", 1);
|
|
}
|
|
else
|
|
{
|
|
modifyCollectionSlotValue(self, "kill_rebel_boss_01", 1);
|
|
}
|
|
|
|
}
|
|
if(col_faction.equals("imperial"))
|
|
{
|
|
if(col_difficulty == 0)
|
|
{
|
|
modifyCollectionSlotValue(self, "kill_imperial_01", 1);
|
|
}
|
|
else
|
|
{
|
|
modifyCollectionSlotValue(self, "kill_imperial_boss_01", 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( getDistance( getLocation(self), creatureLoc ) <= xp.MAX_DISTANCE )
|
|
{
|
|
badge.checkForCombatTargetBadge(self, creatureName);
|
|
//check to see if this updates a collection
|
|
string[] slotNames = getAllCollectionSlotsInCategory("kill_" + creatureName);
|
|
|
|
if(slotNames == null || slotNames.length <= 0)
|
|
return SCRIPT_CONTINUE;
|
|
|
|
for(int i = 0; i < slotNames.length; ++i)
|
|
{
|
|
if(!hasCompletedCollectionSlot(self, slotNames[i]))
|
|
{
|
|
modifyCollectionSlotValue(self, slotNames[i], 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
obj_id target = params.getObjId("target");
|
|
|
|
//Check for GCW Specific Credit
|
|
if(isValidId(target))
|
|
{
|
|
if(hasObjVar(target, gcw.GCW_PARTICIPATION_FLAG))
|
|
{
|
|
obj_id parent = trial.getParent(target);
|
|
if(isIdValid(parent))
|
|
{
|
|
trial.addNonInstanceFactionParticipant(self, parent);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(utils.hasScriptVar(self,"currentBounty") && utils.hasScriptVar(self,"currentBountyValue"))
|
|
{
|
|
obj_id target = params.getObjId("target");
|
|
obj_id storedTarget = utils.getObjIdScriptVar(self,"currentBounty");
|
|
|
|
if(storedTarget == target)
|
|
{
|
|
int amount = utils.getIntScriptVar(self, "currentBountyValue");
|
|
bounty_hunter.awardBounty(self, creatureName,amount);
|
|
}
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler HandleSetCoverCharge()
|
|
{
|
|
int bp = sui.getIntButtonPressed(params);
|
|
|
|
if(bp == sui.BP_CANCEL)
|
|
return SCRIPT_CONTINUE;
|
|
|
|
string strAmount = sui.getInputBoxText(params);
|
|
int amount = utils.stringToInt(strAmount);
|
|
|
|
if(amount > 0)
|
|
performance.covercharge(self, amount);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler HandleCoverCharge()
|
|
{
|
|
int bp = sui.getIntButtonPressed(params);
|
|
obj_id audience = sui.getPlayerId(params);
|
|
int charge = utils.getIntScriptVar(audience, performance.VAR_PERFORM_PAY_WAIT);
|
|
if (bp == 0)
|
|
{
|
|
if (money.hasFunds(audience, money.MT_TOTAL, charge))
|
|
{
|
|
utils.removeScriptVar(audience, performance.VAR_PERFORM_PAY_WAIT);
|
|
utils.setScriptVar(audience, performance.VAR_PERFORM_PAY_AGREE, charge);
|
|
money.pay(audience, money.ACCT_PERFORM_ESCROW, charge, "handlePayment", null);
|
|
// system message for the dancer
|
|
if(utils.hasScriptVar(audience, "dancerID"))
|
|
{
|
|
obj_id targetDancer = utils.getObjIdScriptVar(audience, "dancerID");
|
|
|
|
string audienceName = getFirstName(audience); //get audience member first name (returns with capitalization.)
|
|
if((audienceName == null) || (audienceName == ""))
|
|
{
|
|
audienceName = getPlayerName(audience);
|
|
}
|
|
prose_package dancerProse = new prose_package();
|
|
prose.setTU(dancerProse, audienceName); // name
|
|
prose.setDI(dancerProse, charge); // charge amount
|
|
prose.setStringId(dancerProse, COVERCHARGE_DANCER_MESSAGE);
|
|
sendSystemMessageProse(targetDancer, dancerProse);
|
|
//remove scriptvar from audience.
|
|
utils.removeScriptVar(audience, "dancerID");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sendSystemMessage(audience, performance.SID_CC_NO_FUNDS);
|
|
utils.removeScriptVar(audience, performance.VAR_PERFORM_PAY_WAIT);
|
|
performance.stopListen(audience);
|
|
performance.stopWatch(audience);
|
|
//remove scriptvar from watcher - dancerID for system message
|
|
if(utils.hasScriptVar(audience, "dancerID"))
|
|
{
|
|
utils.removeScriptVar(audience, "dancerID");
|
|
}
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
utils.removeScriptVar(audience, performance.VAR_PERFORM_PAY_WAIT);
|
|
utils.setScriptVar(audience, performance.VAR_PERFORM_PAY_DISAGREE, charge);
|
|
performance.stopListen(audience);
|
|
performance.stopWatch(audience);
|
|
//remove scriptvar from watcher - dancerID for system message
|
|
if(utils.hasScriptVar(audience, "dancerID"))
|
|
{
|
|
utils.removeScriptVar(audience, "dancerID");
|
|
}
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
/**
|
|
* Message handler for updating mission critical objects across servers.
|
|
* Set "addObjects" and/or "removeObjects" object id arrays in the input
|
|
* parameter dictionary to add/remove as appropriate.
|
|
*/
|
|
messageHandler messageUpdateMissionCriticalObjects()
|
|
{
|
|
obj_id[] addObjects = params.getObjIdArray("addObjects");
|
|
obj_id[] removeObjects = params.getObjIdArray("removeObjects");
|
|
|
|
if (addObjects != null && addObjects.length > 0)
|
|
{
|
|
for (int i=0; i<addObjects.length; ++i)
|
|
{
|
|
addMissionCriticalObject(self, addObjects[i]);
|
|
}
|
|
}
|
|
|
|
if (removeObjects != null && removeObjects.length > 0)
|
|
{
|
|
for (int i=0; i<removeObjects.length; ++i)
|
|
{
|
|
removeMissionCriticalObject(self, removeObjects[i]);
|
|
}
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
/**
|
|
* Send a quest system message. Works across scene/servers.
|
|
*/
|
|
messageHandler messageSendQuestSystemMessage()
|
|
{
|
|
string_id sid = params.getStringId("sid");
|
|
string_id to = params.getStringId("to");
|
|
|
|
prose_package pp = prose.getPackage(sid, to);
|
|
|
|
sendQuestSystemMessage(self, pp);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
commandHandler cmdShowLockout()
|
|
{
|
|
space_dungeon.displayAllDungeonLockoutTimers(self);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
trigger OnPvpTypeChanged(int oldType, int newType)
|
|
{
|
|
if (oldType == PVPTYPE_DECLARED)
|
|
{
|
|
if ((newType == PVPTYPE_COVERT) || (newType == PVPTYPE_NEUTRAL))
|
|
{
|
|
obj_id playerCurrentMount = getMountId (self);
|
|
if ( isIdValid( playerCurrentMount ))
|
|
{
|
|
if (group.isGrouped(self))
|
|
{
|
|
obj_id gid = getGroupObject(self);
|
|
obj_id[] members = getGroupMemberIds(gid);
|
|
for ( int i = 0; i < members.length; i++ )
|
|
{
|
|
obj_id member = members[i];
|
|
if ( isIdValid(member) && member.isLoaded() && isPlayer(member) )
|
|
{
|
|
obj_id groupMemberCurrentMount = getMountId (member);
|
|
if ( isIdValid( groupMemberCurrentMount ))
|
|
{
|
|
if (groupMemberCurrentMount == playerCurrentMount)
|
|
{
|
|
if (factions.isDeclared(member))
|
|
{
|
|
//utils.dismountRiderJetpackCheck(member);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnQuestActivated(int questCrc)
|
|
{
|
|
if(groundquests.isQuestVisible(questCrc))
|
|
{
|
|
string questCategory = groundquests.getQuestStringDataEntry(questCrc, groundquests.datatableColumnCategory);
|
|
string questTitle = groundquests.getQuestStringDataEntry(questCrc, groundquests.datatableColumnjournalEntryTitle);
|
|
|
|
prose_package pp = prose.getPackage(groundquests.SID_QUEST_RECEIVED);
|
|
prose.setTT(pp, questCategory);
|
|
prose.setTO(pp, questTitle);
|
|
sendQuestSystemMessage(self, pp);
|
|
|
|
play2dNonLoopingSound(self, groundquests.MUSIC_QUEST_ACTIVATED);
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnQuestReceivedReward(int questCrc, String exclusiveItemChoice)
|
|
{
|
|
//gather data for this task
|
|
int questLevel = groundquests.getQuestIntDataEntry (questCrc, groundquests.dataTableColumnLevel);
|
|
int questTier = groundquests.getQuestIntDataEntry (questCrc, groundquests.dataTableColumnTier);
|
|
String experienceType = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardExperienceType);
|
|
int experienceAmount = groundquests.getQuestIntDataEntry (questCrc, groundquests.dataTableColumnQuestRewardExperienceAmount);
|
|
String factionName = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardFactionName);
|
|
int factionAmount = groundquests.getQuestIntDataEntry (questCrc, groundquests.dataTableColumnQuestRewardFactionAmount);
|
|
boolean grantGcwReward = groundquests.getQuestBoolDataEntry (questCrc, groundquests.dataTableColumnGcwGrant, false);
|
|
int grantGcwOverwriteAmt = groundquests.getQuestIntDataEntry (questCrc, groundquests.dataTableColumnGcwOverwriteAmt);
|
|
int grantGcwSFModifier = groundquests.getQuestIntDataEntry (questCrc, groundquests.dataTableColumnGcwOvrwrtSFMod);
|
|
string grantGcwRebReward = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnGcwRebReward);
|
|
int grantGcwRebRewardCount = groundquests.getQuestIntDataEntry (questCrc, groundquests.dataTableColumnGcwRebRewardCnt);
|
|
string grantGcwImpReward = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnGcwImpReward);
|
|
int grantGcwImpRewardCount = groundquests.getQuestIntDataEntry (questCrc, groundquests.dataTableColumnGcwImpRewardCnt);
|
|
int grantGcwSFRewardMultip = groundquests.getQuestIntDataEntry (questCrc, groundquests.dataTableColumnGcwRewardMultip);
|
|
int bankCredits = groundquests.getQuestIntDataEntry (questCrc, groundquests.dataTableColumnQuestRewardBankCredits);
|
|
String item = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardItem);
|
|
int itemCount = groundquests.getQuestIntDataEntry (questCrc, groundquests.dataTableColumnQuestRewardCount);
|
|
String weapon = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardWeapon);
|
|
int weaponCount = groundquests.getQuestIntDataEntry (questCrc, groundquests.dataTableColumnQuestRewardCountWeapon);
|
|
float weaponSpeed = utils.stringToFloat(groundquests.getQuestStringDataEntry (questCrc, groundquests.dataTableColumnQuestRewardSpeed));
|
|
float weaponDamage = utils.stringToFloat(groundquests.getQuestStringDataEntry (questCrc, groundquests.dataTableColumnQuestRewardDamage));
|
|
float weaponEfficiency = utils.stringToFloat(groundquests.getQuestStringDataEntry (questCrc, groundquests.dataTableColumnQuestRewardEfficiency));
|
|
float weaponElementalValue = utils.stringToFloat(groundquests.getQuestStringDataEntry (questCrc, groundquests.dataTableColumnQuestRewardElementalValue));
|
|
String armor = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardArmor);
|
|
int armorCount = groundquests.getQuestIntDataEntry (questCrc, groundquests.dataTableColumnQuestRewardCountArmor);
|
|
int armorQuality = groundquests.getQuestIntDataEntry (questCrc, groundquests.dataTableColumnQuestRewardQuality);
|
|
|
|
|
|
String[] inclusiveLootNames = new String[3];
|
|
int[] inclusiveLootCounts = new int[3];
|
|
inclusiveLootNames[0] = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardLootName);
|
|
inclusiveLootCounts[0] = groundquests.getQuestIntDataEntry (questCrc, groundquests.dataTableColumnQuestRewardLootCount);
|
|
inclusiveLootNames[1] = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardLootName2);
|
|
inclusiveLootCounts[1] = groundquests.getQuestIntDataEntry (questCrc, groundquests.dataTableColumnQuestRewardLootCount2);
|
|
inclusiveLootNames[2] = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardLootName3);
|
|
inclusiveLootCounts[2] = groundquests.getQuestIntDataEntry (questCrc, groundquests.dataTableColumnQuestRewardLootCount3);
|
|
|
|
String[] exclusiveLootNames = new String[10];
|
|
int[] exclusiveLootCounts = new int[10];
|
|
exclusiveLootNames[0] = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardExclusiveLootName);
|
|
exclusiveLootCounts[0] = groundquests.getQuestIntDataEntry (questCrc, groundquests.dataTableColumnQuestRewardExclusiveLootCount);
|
|
exclusiveLootNames[1] = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardExclusiveLootName2);
|
|
exclusiveLootCounts[1] = groundquests.getQuestIntDataEntry (questCrc, groundquests.dataTableColumnQuestRewardExclusiveLootCount2);
|
|
exclusiveLootNames[2] = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardExclusiveLootName3);
|
|
exclusiveLootCounts[2] = groundquests.getQuestIntDataEntry (questCrc, groundquests.dataTableColumnQuestRewardExclusiveLootCount3);
|
|
exclusiveLootNames[3] = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardExclusiveLootName4);
|
|
exclusiveLootCounts[3] = groundquests.getQuestIntDataEntry (questCrc, groundquests.dataTableColumnQuestRewardExclusiveLootCount4);
|
|
exclusiveLootNames[4] = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardExclusiveLootName5);
|
|
exclusiveLootCounts[4] = groundquests.getQuestIntDataEntry (questCrc, groundquests.dataTableColumnQuestRewardExclusiveLootCount5);
|
|
exclusiveLootNames[5] = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardExclusiveLootName6);
|
|
exclusiveLootCounts[5] = groundquests.getQuestIntDataEntry (questCrc, groundquests.dataTableColumnQuestRewardExclusiveLootCount6);
|
|
exclusiveLootNames[6] = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardExclusiveLootName7);
|
|
exclusiveLootCounts[6] = groundquests.getQuestIntDataEntry (questCrc, groundquests.dataTableColumnQuestRewardExclusiveLootCount7);
|
|
exclusiveLootNames[7] = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardExclusiveLootName8);
|
|
exclusiveLootCounts[7] = groundquests.getQuestIntDataEntry (questCrc, groundquests.dataTableColumnQuestRewardExclusiveLootCount8);
|
|
exclusiveLootNames[8] = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardExclusiveLootName9);
|
|
exclusiveLootCounts[8] = groundquests.getQuestIntDataEntry (questCrc, groundquests.dataTableColumnQuestRewardExclusiveLootCount9);
|
|
exclusiveLootNames[9] = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardExclusiveLootName10);
|
|
exclusiveLootCounts[9] = groundquests.getQuestIntDataEntry (questCrc, groundquests.dataTableColumnQuestRewardExclusiveLootCount10);
|
|
|
|
string badge = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnBadge);
|
|
|
|
//TODO read in this value
|
|
int exclusiveLootCountChoice = 1;
|
|
|
|
groundquests.grantQuestReward(self, questCrc, questLevel, questTier, experienceType, experienceAmount, factionName, factionAmount, grantGcwReward, bankCredits, item, itemCount, weapon, weaponCount, weaponSpeed, weaponDamage, weaponEfficiency, weaponElementalValue, armor, armorCount, armorQuality, inclusiveLootNames, inclusiveLootCounts, exclusiveItemChoice, exclusiveLootCountChoice, badge, (questIsQuestForceAccept(questCrc) || !questDoesUseAcceptanceUI(questCrc)), grantGcwOverwriteAmt, grantGcwSFModifier, grantGcwRebReward, grantGcwRebRewardCount, grantGcwImpReward, grantGcwImpRewardCount, grantGcwSFRewardMultip);
|
|
|
|
// Caculate final xp amount for logs
|
|
experienceAmount = groundquests.getQuestExperienceReward(self, questLevel, questTier, experienceAmount);
|
|
metrics.doQuestMetrics(self, questCrc, questLevel, questTier, experienceType, experienceAmount);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
trigger OnQuestCompleted(int questCrc)
|
|
{
|
|
//handle conditional quest granting
|
|
String conditionalQuestToGrant = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnConditionQuestGrantQuest);
|
|
String listOfQuestsThatMustBeCompleted = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnConditionQuestGrantListOfCompletedQuests);
|
|
|
|
if(conditionalQuestToGrant != null && conditionalQuestToGrant.length() > 0 && listOfQuestsThatMustBeCompleted != null && listOfQuestsThatMustBeCompleted.length() > 0)
|
|
{
|
|
//parse the text
|
|
string[] completedQuestList = split(listOfQuestsThatMustBeCompleted, ',');
|
|
|
|
//there must be at least one conditional quest to test
|
|
boolean grantQuest = completedQuestList.length > 0;
|
|
|
|
//validate each quest as a valid quest and completed by the player
|
|
for(int i = 0; i < completedQuestList.length && grantQuest; ++i)
|
|
{
|
|
string quest = completedQuestList[i];
|
|
if(!groundquests.isValidQuestName(quest) || !groundquests.hasCompletedQuest(self, quest))
|
|
{
|
|
grantQuest = false;
|
|
}
|
|
}
|
|
|
|
//grant the quest if it's valid and they've completed the requirements
|
|
if(groundquests.isValidQuestName(conditionalQuestToGrant) && grantQuest)
|
|
{
|
|
groundquests.requestGrantQuest(self, conditionalQuestToGrant);
|
|
}
|
|
}
|
|
|
|
if(groundquests.isQuestVisible(questCrc))
|
|
{
|
|
play2dNonLoopingSound(self, groundquests.MUSIC_QUEST_COMPLETED);
|
|
}
|
|
|
|
//Checks to see if the completed quest is tied to a collection based on on the table at collection.QUEST__COMPLETED_COLLECTIONS.
|
|
//If so, call collection.grantQuestBasedCollections
|
|
string questString = questGetQuestName(questCrc);
|
|
int tableRow = dataTableSearchColumnForString(questString, "questName", collection.QUEST__COMPLETED_COLLECTIONS);
|
|
|
|
if(tableRow > -1)
|
|
{
|
|
collection.grantQuestBasedCollections(questString, self);
|
|
}
|
|
|
|
smuggler.removeFromBountyTerminal(self, questCrc, false);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
trigger OnQuestCleared(int questCrc)
|
|
{
|
|
String factionName = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestPenaltyFactionName);
|
|
int factionAmount = groundquests.getQuestIntDataEntry(questCrc, groundquests.dataTableColumnQuestPenaltyFactionAmount);
|
|
|
|
LOG("QUEST", "Quest " + questCrc + " cleared!");
|
|
|
|
groundquests.applyQuestPenalty(self, factionName, factionAmount);
|
|
smuggler.removeFromBountyTerminal(self, questCrc, true);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
trigger OnRequestStaticItemData(string itemName)
|
|
{
|
|
dictionary itemData = static_item.getMergedItemDictionary(itemName);
|
|
|
|
if (itemData != null)
|
|
{
|
|
String[] keysStringVector = itemData.keysStringVector();
|
|
String[] valuesStringVector = itemData.valuesStringVector();
|
|
sendStaticItemDataToPlayer(self, keysStringVector, valuesStringVector);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
commandHandler handleClientLogin()
|
|
{
|
|
int[] quests = questGetAllActiveQuestIds(self);
|
|
for(int i = 0; i < quests.length; ++i)
|
|
{
|
|
int questCrc = quests[i];
|
|
|
|
resizeable String[] objectsToTellClientAbout = new String[0];
|
|
String item = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardLootName);
|
|
if(item != null)
|
|
utils.addElement(objectsToTellClientAbout, item);
|
|
item = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardLootName2);
|
|
if(item != null)
|
|
utils.addElement(objectsToTellClientAbout, item);
|
|
item = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardLootName3);
|
|
if(item != null)
|
|
utils.addElement(objectsToTellClientAbout, item);
|
|
item = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardExclusiveLootName);
|
|
if(item != null)
|
|
utils.addElement(objectsToTellClientAbout, item);
|
|
item = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardExclusiveLootName2);
|
|
if(item != null)
|
|
utils.addElement(objectsToTellClientAbout, item);
|
|
item = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardExclusiveLootName3);
|
|
if(item != null)
|
|
utils.addElement(objectsToTellClientAbout, item);
|
|
item = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardExclusiveLootName4);
|
|
if(item != null)
|
|
utils.addElement(objectsToTellClientAbout, item);
|
|
item = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardExclusiveLootName5);
|
|
if(item != null)
|
|
utils.addElement(objectsToTellClientAbout, item);
|
|
item = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardExclusiveLootName6);
|
|
if(item != null)
|
|
utils.addElement(objectsToTellClientAbout, item);
|
|
item = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardExclusiveLootName7);
|
|
if(item != null)
|
|
utils.addElement(objectsToTellClientAbout, item);
|
|
item = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardExclusiveLootName8);
|
|
if(item != null)
|
|
utils.addElement(objectsToTellClientAbout, item);
|
|
item = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardExclusiveLootName9);
|
|
if(item != null)
|
|
utils.addElement(objectsToTellClientAbout, item);
|
|
item = groundquests.getQuestStringDataEntry(questCrc, groundquests.dataTableColumnQuestRewardExclusiveLootName10);
|
|
if(item != null)
|
|
utils.addElement(objectsToTellClientAbout, item);
|
|
|
|
for(int j = 0; j < objectsToTellClientAbout.length; ++j)
|
|
{
|
|
String itemName = objectsToTellClientAbout[j];
|
|
if(itemName != null && itemName != "")
|
|
{
|
|
dictionary itemData = static_item.getMergedItemDictionary(itemName);
|
|
if(itemData != null)
|
|
{
|
|
String[] keysStringVector = itemData.keysStringVector();
|
|
String[] valuesStringVector = itemData.valuesStringVector();
|
|
sendStaticItemDataToPlayer(self, keysStringVector, valuesStringVector);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// if they login and are in the blackwing facility, check to see if they need to start the infection chain
|
|
obj_id building = getTopMostContainer(self);
|
|
if ( isIdValid(building) && getTemplateName(building).equals("object/building/dathomir/imperial_blackwing_facility.iff") )
|
|
{
|
|
if ( needsBlackwingLightInfection(self) )
|
|
{
|
|
buff.applyBuff(self, "death_troopers_infection_1");
|
|
}
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
trigger OnGetStaticItemsAttributes(string staticItemName, string[] names, string[] attribs)
|
|
{
|
|
if ((names == null) || (attribs == null) || (names.length != attribs.length))
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
static_item.getAttributes(self, staticItemName, names, attribs);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
commandHandler handleSmugglerFenceAbility()
|
|
{
|
|
smuggler.showSellJunkSui(self, self, true, true);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleSellJunkSui()
|
|
{
|
|
obj_id player = sui.getPlayerId(params);
|
|
|
|
if(!isIdValid(player))
|
|
return SCRIPT_CONTINUE;
|
|
// Get the row of the list box that was highlighted, and get the button that was pushed
|
|
int idx = sui.getListboxSelectedRow(params);
|
|
int bp = sui.getIntButtonPressed(params);
|
|
|
|
// Get the list of items off of the player
|
|
obj_id[] junk = utils.getObjIdBatchScriptVar(player, smuggler.SCRIPTVAR_JUNK_IDS);
|
|
|
|
//do not repop up the SUI if we have have no more items to sell
|
|
boolean reshowSui = true;
|
|
if (junk.length < 1)
|
|
reshowSui = false;
|
|
|
|
boolean fence = utils.getBooleanScriptVar(self, "fence");
|
|
|
|
// Clean the script vars off of the player
|
|
smuggler.cleanupSellJunkSui(player);
|
|
|
|
if(bp == sui.BP_CANCEL)
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
else if(bp == sui.BP_REVERT)
|
|
{
|
|
if(idx >= 0 && idx <= junk.length - 1)
|
|
{
|
|
if((junk != null) || (junk.length > 0))
|
|
{
|
|
openExamineWindow(player, junk[idx]);
|
|
}
|
|
}
|
|
|
|
if(fence)
|
|
{
|
|
smuggler.showSellJunkSui(player, self, true, false);
|
|
}
|
|
else
|
|
{
|
|
smuggler.showSellJunkSui(player, self, false, false);
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
else
|
|
{
|
|
// If no row was selected, quit out
|
|
if(idx < 0)
|
|
{
|
|
if(reshowSui)
|
|
{
|
|
smuggler.showSellJunkSui(self, self, true, true);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
if((junk == null) || (junk.length == 0))
|
|
return SCRIPT_CONTINUE;
|
|
|
|
// If our arithmetic is off, quit out
|
|
if(idx > junk.length - 1)
|
|
{
|
|
if(reshowSui)
|
|
{
|
|
smuggler.showSellJunkSui(self, self, true, true);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Go through the sell item procedure
|
|
smuggler.sellJunkItem(player, junk[idx], fence, reshowSui);
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleSoldJunk()
|
|
{
|
|
blog("base_player.handleSoldJunk() - init");
|
|
// If the parameters we've passed don't exist, quit out
|
|
if(params == null || params.isEmpty())
|
|
return SCRIPT_CONTINUE;
|
|
|
|
// Get the obj id of the player we paid. If they don't exist, quit out
|
|
obj_id player = params.getObjId(money.DICT_TARGET_ID);
|
|
if(!isIdValid(player))
|
|
{
|
|
CustomerServiceLog("Junk_Dealer: ", "junk_dealer.handleSoldJunk() - Player: "+self+" cannot sell an item because the junk dealer failed to send a valid obj_id.");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Get the obj id of the item sold. If it doesn't exist, quit out
|
|
obj_id item = params.getObjId("item");
|
|
if(!isIdValid(item))
|
|
{
|
|
CustomerServiceLog("Junk_Dealer: ", "junk_dealer.handleSoldJunk() - Player: "+self+" cannot sell an item because the item was found to be invalid.");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
boolean fence = params.getBoolean("fence");
|
|
blog("base_player.handleSoldJunk() - fence: "+fence);
|
|
|
|
// Get the return code of the money transaction
|
|
int retCode = params.getInt(money.DICT_CODE);
|
|
|
|
// If the transaction failed
|
|
if(retCode == money.RET_FAIL)
|
|
{
|
|
prose_package ppNoSale = prose.getPackage(smuggler.PROSE_NO_SALE, self, item);
|
|
if(fence)
|
|
{
|
|
ppNoSale = prose.getPackage(smuggler.PROSE_NO_SALE_FENCE, self, item);
|
|
}
|
|
sendSystemMessageProse(player, ppNoSale);
|
|
|
|
// Un-mark the item as in process of being sold. The player can try to sell this item again
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Get the price we paid for the item
|
|
int price = params.getInt("price");
|
|
|
|
// Let the player know exactly what he or she just did
|
|
prose_package ppSoldJunk = prose.getPackage(smuggler.PROSE_SOLD_JUNK, item, price);
|
|
if(fence)
|
|
{
|
|
ppSoldJunk = prose.getPackage(smuggler.PROSE_SOLD_JUNK_FENCE, item, price);
|
|
}
|
|
sendSystemMessageProse(player, ppSoldJunk);
|
|
|
|
// Mark the item as in the process of being sold
|
|
setObjVar(item, smuggler.BUYBACK_OBJ_SOLD, getGameTime());
|
|
smuggler.moveBuyBackObjectIntoContainer(player, item, price);
|
|
|
|
CustomerServiceLog("Junk_Dealer: ", "junk_dealer.handleSoldJunk() - Player: "+self+" has sold item: "+item+" and the item has been marked sold. The item is about to be moved to the buy back container.");
|
|
|
|
// Get whether or not we decided to reshow the sui
|
|
boolean reshowSui = params.getBoolean("reshowSui");
|
|
|
|
// If we want to reshow the sui, show it again with an updated list of items
|
|
if(reshowSui && fence)
|
|
{
|
|
smuggler.showSellJunkSui(player, self, true, false);
|
|
}
|
|
else if(reshowSui && !fence)
|
|
{
|
|
smuggler.showSellJunkSui(player, self, false, false);
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnSkillModsChanged(string[] modNames, int[] modValues)
|
|
{
|
|
// Display only skill mods for new combat defenses.
|
|
trial.bumpSession(self, "displayDefensiveMods");
|
|
messageTo(self, "setDisplayOnlyDefensiveMods", trial.getSessionDict(self, "displayDefensiveMods") , 5, false);
|
|
|
|
for(int intI = 0; intI < modNames.length; intI++)
|
|
{
|
|
if((modNames[intI].startsWith("constitution"))||(modNames[intI].startsWith("stamina")))
|
|
{
|
|
skill.recalcPlayerPools(self, false);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
if(modNames[intI].startsWith("movement_resist"))
|
|
{
|
|
messageTo(self, "check_movement_immunity", null, 0.1f, false);
|
|
}
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
/***** BOUNTY HUNTER COMMANDS **************************************************/
|
|
|
|
//------------------------------------------------------------------------------------------------
|
|
// BOUNTY COMMANDS
|
|
//------------------------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------
|
|
// checkbounty
|
|
//
|
|
// /checkbounty command handler.
|
|
//------------------------------------------------
|
|
|
|
messageHandler handlePlayerBountyEngagement()
|
|
{
|
|
obj_id target = params.getObjId("target");
|
|
|
|
pvpSetPermanentPersonalEnemyFlag(self, target);
|
|
|
|
messageTo(self, "handlePlayerBountyTimeout", params, bounty_hunter.BOUNTY_COLLECT_TIME_LIMIT, true);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handlePlayerBountyTimeout()
|
|
{
|
|
obj_id target = params.getObjId("target");
|
|
int id = params.getInt("id");
|
|
|
|
if(utils.hasScriptVar(self, "bounty.id"))
|
|
{
|
|
int bounty_id = utils.getIntScriptVar(self, "bounty.id");
|
|
|
|
if(bounty_id != id)
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
if(pvpHasPersonalEnemyFlag(self, target))
|
|
{
|
|
pvpRemovePersonalEnemyFlags(self, target);
|
|
sendSystemMessage(self, new string_id("bounty_hunter", "time_expired"));
|
|
}
|
|
|
|
utils.removeScriptVarTree(self, "bounty");
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
|
|
messageHandler handleAwardedBountyCheck()
|
|
{
|
|
|
|
// Clean up the bounty scriptvars
|
|
if(utils.hasScriptVar(self,"currentBounty"))
|
|
utils.removeScriptVar(self,"currentBounty");
|
|
if(utils.hasScriptVar(self,"currentBountyValue"))
|
|
utils.removeScriptVar(self,"currentBountyValue");
|
|
|
|
// If the parameters we've passed don't exist, quit out
|
|
if(params == null || params.isEmpty())
|
|
return SCRIPT_CONTINUE;
|
|
|
|
// Get the obj id of the player we paid. If they don't exist, quit out
|
|
obj_id player = params.getObjId(money.DICT_TARGET_ID);
|
|
if(!isIdValid(player))
|
|
return SCRIPT_CONTINUE;
|
|
|
|
// Get the return code of the money transaction
|
|
int retCode = params.getInt(money.DICT_CODE);
|
|
|
|
// If the transaction failed
|
|
if(retCode == money.RET_FAIL)
|
|
{
|
|
// Let the player know
|
|
prose_package pp = new prose_package ();
|
|
pp.stringId = new string_id ("bounty_hunter", "no_reward_possible");
|
|
sendSystemMessageProse( player, pp );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Get the price we paid for the item
|
|
int amount = params.getInt("amount");
|
|
string creatureName = params.getString("creatureName");
|
|
|
|
// Let the player know exactly what he or she just did
|
|
prose_package pp = new prose_package ();
|
|
pp.stringId = new string_id ("bounty_hunter", "reward");
|
|
pp.digitInteger = amount;
|
|
pp.other.set (creatureName);
|
|
sendSystemMessageProse( player, pp );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleAwardedPlayerBounty()
|
|
{
|
|
obj_id target = params.getObjId("target");
|
|
int amount = params.getInt("bounty");
|
|
|
|
int retCode = params.getInt(money.DICT_CODE);
|
|
if(retCode == money.RET_FAIL)
|
|
{
|
|
sendSystemMessage(self, new string_id("bounty_hunter", "player_bounty_reward_fail"));
|
|
CustomerServiceLog("bounty", "%TU has defeated %TT but an error occured during the bounty (" + amount + " credits) payout!", self, target);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
CustomerServiceLog("bounty", "%TU has defeated %TT and collected a bounty worth " + amount + " credits", self, target);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleSurveyToolbarSetup()
|
|
{
|
|
obj_id objInv = utils.getInventoryContainer(self);
|
|
createObject("object/tangible/survey_tool/survey_tool_mineral.iff", objInv, "");
|
|
newbieTutorialSetToolbarElement(self, 10, "/survey");
|
|
|
|
return SCRIPT_CONTINUE;
|
|
|
|
}
|
|
|
|
messageHandler factionBaseUnitRefund() //This is a refund for when a base operating under the new GCW lotless system is destroyed somehow - 2/8/05
|
|
{
|
|
//LOG("hq", "+++ base_player:factionBaseUnitRefund messagehandler ///////////////////////// Just entered function.");
|
|
|
|
debugServerConsoleMsg( null, "+++ base_player.factionBaseUnitRefund +++ entered message handler");
|
|
|
|
if ( hasObjVar(self,"factionBaseCount" ))
|
|
{
|
|
//LOG("hq", "+++ base_player.factionBaseUnitRefund +++ has objvar 'factionBaseCount'");
|
|
|
|
int factionBaseCount = getIntObjVar(self,"factionBaseCount");
|
|
int updatedFactionBaseCount = factionBaseCount-1;
|
|
//LOG("hq", "+++ base_player.factionBaseUnitRefund +++ has objvar 'factionBaseCount'= "+factionBaseCount+" updatedFactionBaseCount= "+updatedFactionBaseCount);
|
|
|
|
if ( updatedFactionBaseCount > 0 )
|
|
setObjVar(self,"factionBaseCount",updatedFactionBaseCount);
|
|
else
|
|
removeObjVar(self,"factionBaseCount");
|
|
|
|
if ( updatedFactionBaseCount == player_structure.MAX_BASE_COUNT -1 )
|
|
sendSystemMessage(self, SID_CAN_PLACE_ONE_BASE);
|
|
else
|
|
sendSystemMessageProse(self, prose.getPackage(new string_id ("faction_perk", "faction_base_unit_refunded"), (player_structure.MAX_BASE_COUNT-updatedFactionBaseCount)));
|
|
|
|
//LOG("hq", "player.base.base_player -- factionBaseUnitRefund: message received. Refunding a single base unit value to player.");
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//this fucking trigger fires every time a player logs in
|
|
trigger OnSkillTemplateChanged(string skillTemplateName, boolean clientSelected)
|
|
{
|
|
if (skillTemplateName == null || skillTemplateName == "" || skillTemplateName == "a")
|
|
{
|
|
if(hasObjVar(self, "clickRespec.tokenId"))
|
|
{
|
|
removeObjVar(self, "clickRespec.tokenId");
|
|
}
|
|
|
|
if(hasObjVar(self, "npcRespec.inProgress"))
|
|
{
|
|
removeObjVar(self, "npcRespec.inProgress");
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//since the player might not actually be changing their template, and this
|
|
//trigger is just firing because it SUCKS, we have to ignore template
|
|
//changes that were NOT spawned by a respec token. WHICH IS BAD!!!
|
|
if (!hasObjVar( self, "clickRespec") && !hasObjVar(self, "npcRespec.inProgress"))
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
if(hasObjVar(self, "npcRespec.inProgress"))
|
|
{
|
|
respec.handleNpcRespec(self, skillTemplateName);
|
|
//set respec version
|
|
respec.setRespecVersion(self);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
else if(hasObjVar(self, "clickRespec.tokenId"))
|
|
{
|
|
obj_id token = getObjIdObjVar(self, "clickRespec.tokenId");
|
|
|
|
if ( hasObjVar(self,"clickRespec.oldTemplate") )
|
|
{
|
|
string oldTemplate = getStringObjVar(self, "clickRespec.oldTemplate");
|
|
|
|
// Quit out if the template has not changed
|
|
if (oldTemplate.equals(getSkillTemplate(self)))
|
|
{
|
|
removeObjVar( self, "clickRespec");
|
|
detachScript(self, "systems.respec.click_combat_respec");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
static_item.decrementStaticItem(token);
|
|
|
|
//ensure we only consume one charge here:
|
|
removeObjVar( self, "clickRespec.tokenId");
|
|
}
|
|
|
|
}
|
|
|
|
boolean withItems = true;
|
|
if (hasObjVar(self, "clickRespec.cts"))
|
|
{
|
|
withItems = false;
|
|
}
|
|
|
|
respec.earnProfessionSkills(self, skillTemplateName, withItems);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
void givePublishGift(obj_id self)
|
|
{
|
|
const string OBJVAR_PUBLISH_GIFT = "publish_gift";
|
|
const string GIFT_DATATABLE = "datatables/veteran_rewards/publish_gift.iff";
|
|
|
|
int currentBD = getCurrentBirthDate();
|
|
int playerBD = getPlayerBirthDate(self);
|
|
|
|
if(playerBD < 0)
|
|
return;
|
|
|
|
if((currentBD - playerBD) < 10)
|
|
return;
|
|
|
|
if(isInTutorialArea(self))
|
|
return;
|
|
|
|
int old_publish = -1;
|
|
if(hasObjVar(self, OBJVAR_PUBLISH_GIFT))
|
|
old_publish = getIntObjVar(self, OBJVAR_PUBLISH_GIFT);
|
|
|
|
int[] publish_numbers = dataTableGetIntColumn(GIFT_DATATABLE, "PUBLISH");
|
|
if(publish_numbers == null || publish_numbers.length == 0)
|
|
return;
|
|
|
|
int last_publish = -1;
|
|
Vector gifts = new Vector();
|
|
|
|
for(int i=0; i < publish_numbers.length; i++)
|
|
{
|
|
if(publish_numbers[i] > last_publish)
|
|
{
|
|
last_publish = publish_numbers[i];
|
|
|
|
gifts = new Vector();
|
|
gifts.addElement(dataTableGetString(GIFT_DATATABLE, i, "ITEM"));
|
|
}
|
|
else if(publish_numbers[i] == last_publish)
|
|
{
|
|
gifts.addElement(dataTableGetString(GIFT_DATATABLE, i, "ITEM"));
|
|
}
|
|
}
|
|
|
|
if(gifts == null || gifts.size() == 0)
|
|
return;
|
|
|
|
if(old_publish >= last_publish)
|
|
return;
|
|
|
|
obj_id inv = utils.getInventoryContainer(self);
|
|
Vector objects = new Vector();
|
|
|
|
boolean noGift = false;
|
|
|
|
for(int i=0; i < gifts.size(); i++)
|
|
{
|
|
string item = (String)gifts.get(i);
|
|
|
|
if(item.equals("none"))
|
|
{
|
|
noGift = true;
|
|
continue;
|
|
}
|
|
|
|
obj_id new_gift = static_item.createNewItemFunction(item, inv);
|
|
|
|
if(isIdValid(new_gift))
|
|
{
|
|
objects.addElement(new_gift);
|
|
CustomerServiceLog("grantGift", "%TU has received the gift(s) for Publish " + last_publish + ". Item given was " + item + ". Item OID was " + new_gift, self);
|
|
}
|
|
}
|
|
|
|
obj_id[] object_array = utils.toStaticObjIdArray(objects);
|
|
|
|
if((object_array == null || object_array.length == 0))
|
|
{
|
|
if(noGift)
|
|
setObjVar(self, OBJVAR_PUBLISH_GIFT, last_publish);
|
|
|
|
return;
|
|
}
|
|
|
|
sendSystemMessage(self, new string_id("base_player", "received_gift"));
|
|
|
|
setObjVar(self, OBJVAR_PUBLISH_GIFT, last_publish);
|
|
|
|
showLootBox(self, object_array);
|
|
|
|
}
|
|
|
|
void respecNewEntertainerSkills(obj_id self)
|
|
{
|
|
string template = getSkillTemplate(self);
|
|
|
|
if(template == null)
|
|
return;
|
|
|
|
if(!template.equals("entertainer_2a"))
|
|
return;
|
|
|
|
string oldSkills = dataTableGetString(skill_template.TEMPLATE_TABLE, "entertainer_2a", "template");
|
|
string[] oldSkillList = split(oldSkills, ',');
|
|
|
|
if(oldSkillList == null || oldSkillList.length == 0)
|
|
return;
|
|
|
|
int oldSkillCount = 0;
|
|
float oldSkillPct = 0.0f;
|
|
|
|
for(int i = 0; i < oldSkillList.length; i++)
|
|
{
|
|
if(hasSkill(self, oldSkillList[i]))
|
|
oldSkillCount++;
|
|
}
|
|
|
|
oldSkillPct = (float)oldSkillCount / (float)oldSkillList.length;
|
|
|
|
skill.revokeAllProfessionSkills(self);
|
|
|
|
dictionary d = new dictionary();
|
|
d.put("oldSkillPct", oldSkillPct);
|
|
|
|
messageTo(self, "finishEntertainerRespec", d, 1.0f, true);
|
|
}
|
|
|
|
|
|
void respecNewCrafterSkills(obj_id self)
|
|
{
|
|
string template = getSkillTemplate(self);
|
|
|
|
if (template == null)
|
|
return;
|
|
|
|
if (!template.startsWith("trader_1"))
|
|
return;
|
|
|
|
float pctDone = respec.getPercentageCompletion(self, template);
|
|
|
|
string newTemplate = getCorrectTraderTemplate(template);
|
|
|
|
skill.revokeAllProfessionSkills(self);
|
|
|
|
setSkillTemplate(self, newTemplate);
|
|
respec.setPercentageCompletion(self, newTemplate, pctDone, true);
|
|
|
|
skill.recalcPlayerPools(self, true);
|
|
trial.bumpSession(self, "displayDefensiveMods");
|
|
messageTo(self, "setDisplayOnlyDefensiveMods", trial.getSessionDict(self, "displayDefensiveMods") , 5, false);
|
|
}
|
|
|
|
string getCorrectTraderTemplate(string template)
|
|
{
|
|
if (template.endsWith("1a"))
|
|
return "trader_0a";
|
|
|
|
if (template.endsWith("1b"))
|
|
return "trader_0b";
|
|
|
|
if (template.endsWith("1c"))
|
|
return "trader_0c";
|
|
|
|
if (template.endsWith("1d"))
|
|
return "trader_0d";
|
|
|
|
return "trader_0a";
|
|
}
|
|
messageHandler finishEntertainerRespec()
|
|
{
|
|
float oldSkillPct = params.getFloat("oldSkillPct");
|
|
|
|
string newSkills = dataTableGetString(skill_template.TEMPLATE_TABLE, "entertainer_1a", "template");
|
|
string[] newSkillList = split(newSkills, ',');
|
|
|
|
int newSkillCount = (int)Math.ceil(oldSkillPct * (float)newSkillList.length);
|
|
|
|
setSkillTemplate(self, "entertainer_1a");
|
|
|
|
for(int i = 0; i < newSkillCount; i++)
|
|
skill.grantSkillToPlayer(self, newSkillList[i]);
|
|
|
|
if(newSkillCount < newSkillList.length)
|
|
setWorkingSkill(self, newSkillList[newSkillCount]);
|
|
|
|
skill.recalcPlayerPools(self, true);
|
|
trial.bumpSession(self, "displayDefensiveMods");
|
|
messageTo(self, "setDisplayOnlyDefensiveMods", trial.getSessionDict(self, "displayDefensiveMods") , 5, false);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleSetBounty()
|
|
{
|
|
int bp = sui.getIntButtonPressed(params);
|
|
|
|
if(bp == sui.BP_CANCEL)
|
|
return SCRIPT_CONTINUE;
|
|
|
|
if(!utils.hasScriptVar(self, "setbounty.killer"))
|
|
return SCRIPT_CONTINUE;
|
|
|
|
obj_id killer = utils.getObjIdScriptVar(self, "setbounty.killer");
|
|
utils.removeScriptVar(self, "setbounty.killer");
|
|
|
|
int amount = utils.stringToInt(sui.getInputBoxText(params));
|
|
|
|
if(amount < 0)
|
|
{
|
|
sendSystemMessage(self, new string_id("bounty_hunter", "setbounty_invalid_number"));
|
|
bounty_hunter.showSetBountySUI(self, killer);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
if(amount > bounty_hunter.MAX_BOUNTY_SET)
|
|
{
|
|
sendSystemMessage(self, new string_id("bounty_hunter", "setbounty_cap"));
|
|
amount = bounty_hunter.MAX_BOUNTY_SET;
|
|
}
|
|
|
|
if(amount < bounty_hunter.MIN_BOUNTY_SET)
|
|
{
|
|
sendSystemMessage(self, new string_id("bounty_hunter", "setbounty_too_little"));
|
|
bounty_hunter.showSetBountySUI(self, killer);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
if(hasObjVar(killer, "bounty.amount"))
|
|
{
|
|
int bounty = getIntObjVar(killer, "bounty.amount");
|
|
if(bounty >= bounty_hunter.MAX_BOUNTY)
|
|
{
|
|
sendSystemMessage(self, new string_id("bounty_hunter", "max_bounty"));
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
else if((bounty + amount) > bounty_hunter.MAX_BOUNTY)
|
|
{
|
|
amount = (bounty + amount) - bounty_hunter.MAX_BOUNTY;
|
|
}
|
|
}
|
|
|
|
int total = getTotalMoney(self);
|
|
|
|
if(amount > total)
|
|
{
|
|
sendSystemMessage(self, new string_id("bounty_hunter", "setbounty_too_much"));
|
|
bounty_hunter.showSetBountySUI(self, killer);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
dictionary d = new dictionary();
|
|
d.put("killer", killer);
|
|
d.put("amt", amount);
|
|
|
|
money.pay(self, money.ACCT_BOUNTY, amount, "handleSetBountyTransaction", d, true);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleSetBountyTransaction()
|
|
{
|
|
int code = money.getReturnCode(params);
|
|
|
|
if(code == money.RET_FAIL)
|
|
return SCRIPT_CONTINUE;
|
|
|
|
obj_id killer = params.getObjId("killer");
|
|
int amount = params.getInt("amt");
|
|
|
|
int bounty = 0;
|
|
|
|
if(hasObjVar(killer, "bounty.amount"))
|
|
bounty = getIntObjVar(killer, "bounty.amount");
|
|
|
|
bounty += amount;
|
|
|
|
if(bounty >= 10000)
|
|
{
|
|
setJediBountyValue(killer, bounty);
|
|
}
|
|
|
|
setObjVar(killer, "bounty.amount", bounty);
|
|
|
|
// int visibility = (pvp.VISIBILITY_THRESHOLD + 1);
|
|
// changeJediVisibility(killer, visibility);
|
|
|
|
CustomerServiceLog("bounty", "%TU has taken a bounty of " + amount + " credits out on %TT", self, killer);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleBountyMissionIncomplete()
|
|
{
|
|
obj_id target = params.getObjId("target");
|
|
|
|
removeJediBounty(target, self);
|
|
|
|
obj_id mission = bounty_hunter.getBountyMission(self, target);
|
|
|
|
if(isIdValid(mission))
|
|
{
|
|
sendSystemMessage(self, new string_id("bounty_hunter", "bounty_incomplete"));
|
|
endMission(mission);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleUpdateBountyMissionTime()
|
|
{
|
|
int gameTime = params.getInt("gameTime");
|
|
int lastMission = 0;
|
|
|
|
if(hasObjVar(self, "bounty.lastMissionTime"))
|
|
lastMission = getIntObjVar(self, "bounty.lastMissionTime");
|
|
|
|
if(lastMission < gameTime)
|
|
setObjVar(self, "bounty.lastMissionTime", gameTime);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleBountyMissionTimeout()
|
|
{
|
|
int gameTime = getGameTime();
|
|
int lastMission = 0;
|
|
|
|
if(hasObjVar(self, "bounty.lastMissionTime"))
|
|
lastMission = getIntObjVar(self, "bounty.lastMissionTime");
|
|
|
|
if((gameTime - lastMission) > bounty_hunter.BOUNTY_MISSION_TIME_LIMIT)
|
|
{
|
|
obj_id[] hunters = getJediBounties(self);
|
|
|
|
if(hunters != null && hunters.length > 0)
|
|
{
|
|
for(int i = 0; i < hunters.length; i++)
|
|
{
|
|
dictionary d = new dictionary();
|
|
d.put("target", self);
|
|
|
|
messageTo(hunters[i], "handleBountyMissionIncomplete", d, 0.0f, true);
|
|
}
|
|
}
|
|
|
|
removeAllJediBounties(self);
|
|
removeObjVar(self, "bounty.lastMissionTime");
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
boolean performCriticalHeal(obj_id self)
|
|
{
|
|
int [] buffs = buff.getAllBuffs(self);
|
|
|
|
if (buffs == null || buffs.length == 0)
|
|
return false;
|
|
|
|
for (int i = 0;i<buffs.length;i++)
|
|
{
|
|
string type = buff.getEffectParam(buffs[i], 1);
|
|
if (type.equals("avoid_incap_heal"))
|
|
{
|
|
string subType = dataTableGetString("datatables/buff/effect_mapping.iff", "avoid_incap_heal", "SUBTYPE");
|
|
float value = utils.getFloatScriptVar(self, "buff_handler."+subType);
|
|
// sendSystemMessageTestingOnly(self, "Checking buff_handler."+subType+" to pull value to heal is: "+value);
|
|
healing.healDamage(self, self, HEALTH, (int)value);
|
|
buff.removeBuff(self, buff.getBuffNameFromCrc(buffs[i]));
|
|
buff.applyBuff(self, "gcw_base_critical_heal_recourse");
|
|
string_id SID_INCAP_HEAL = new string_id("cbt_spam", "incap_heal");
|
|
prose_package pp = new prose_package();
|
|
pp = prose.setStringId(pp, SID_INCAP_HEAL);
|
|
pp = prose.setDF(pp, value);
|
|
pp = prose.setTU(pp, self);
|
|
sendCombatSpamMessageProse(self, self, pp, true, true, true, COMBAT_RESULT_MEDICAL);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void sendSmugglerSystemBootstrap(obj_id self)
|
|
{
|
|
if(utils.isProfession(self, utils.SMUGGLER))
|
|
{
|
|
if(isInTutorialArea(self))
|
|
return;
|
|
|
|
if(hasObjVar(self, "smuggler_bootstrap"))
|
|
return;
|
|
|
|
messageTo(self, "handleSendSmugglerBootstrapRequest", null, 120f, false);
|
|
}
|
|
}
|
|
|
|
messageHandler handleSendSmugglerBootstrapRequest()
|
|
{
|
|
string_id subject = new string_id("smuggler/messages", "bootstrap_subject");
|
|
string_id body = new string_id("smuggler/messages", "bootstrap_body");
|
|
|
|
string body_oob = chatMakePersistentMessageOutOfBandBody(null, body);
|
|
body_oob = chatAppendPersistentMessageWaypointData(body_oob, "tatooine", -1049f, -3538f, new string_id("mob/creature_names", "smuggler_broker_barak"), null);
|
|
string subject_str = "@" + subject.toString ();
|
|
|
|
chatSendPersistentMessage("Barak", self, subject_str, null, body_oob);
|
|
|
|
setObjVar(self, "smuggler_bootstrap", 1);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleSmugglerMissionFailureSignal()
|
|
{
|
|
groundquests.sendSignal(self, "smugglerEnemyIncap");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnClusterWideDataResponse(string manage_name, string data_name, int request_id, string[] element_name_list, dictionary[] dungeon_data, int lock_key)
|
|
{
|
|
if (dungeon_data == null || dungeon_data.length == 0)
|
|
return SCRIPT_CONTINUE;
|
|
|
|
//If a player attempts to place a factional base and is at the cap a call to all registered bases will be made.
|
|
//If a player has less registered bases than what their objvar says they will be refunded those bases.
|
|
if (data_name.startsWith("base_cwdata_manager"))
|
|
{
|
|
int myBases = 0;
|
|
|
|
for (int i=0;i<dungeon_data.length;i++)
|
|
{
|
|
if (dungeon_data[i].getObjId("ownerId") == self)
|
|
myBases++;
|
|
}
|
|
|
|
int recordedBases = getIntObjVar(self, "factionBaseCount");
|
|
|
|
if (recordedBases != myBases)
|
|
{
|
|
int correction = recordedBases - myBases;
|
|
|
|
prose_package pp = new prose_package();
|
|
pp = prose.setStringId(pp, new string_id("gcw", "faction_base_correction"));
|
|
pp = prose.setDI(pp, correction);
|
|
pp = prose.setTO(pp, ""+myBases);
|
|
|
|
sendSystemMessageProse(self, pp);
|
|
setObjVar(self, "factionBaseCount", myBases);
|
|
}
|
|
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler removeIncubatorFromUser()
|
|
{
|
|
obj_id station = params.getObjId("station");
|
|
incubator.forceRemoveIncubatorFromUser(station, self);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
// Storyteller assistant
|
|
messageHandler handleStoryTellerAssistantRequest()
|
|
{
|
|
obj_id storytellerPlayer = params.getObjId("storytellerPlayer");
|
|
string storytellerName = params.getString("storytellerName");
|
|
|
|
if ( isIdValid(storytellerPlayer) )
|
|
{
|
|
if( storyteller.doIAutoDeclineStorytellerInvites(self) )
|
|
{
|
|
dictionary webster = new dictionary();
|
|
webster.put("targetName", getName(self));
|
|
messageTo(storytellerPlayer, "handleStorytellerAssistantDeclined", webster, 0, false);
|
|
}
|
|
else
|
|
{
|
|
if ( !utils.hasScriptVar(self, "storytellerAssistant") )
|
|
{
|
|
storyteller.storyAssistantSui(storytellerPlayer, storytellerName, self);
|
|
}
|
|
else
|
|
{
|
|
boolean alreadyAStorytellersAssistant = false;
|
|
|
|
obj_id storytellerId = utils.getObjIdScriptVar(self, "storytellerAssistant");
|
|
if( storytellerId == storytellerPlayer )
|
|
{
|
|
alreadyAStorytellersAssistant = true;
|
|
}
|
|
|
|
dictionary webster = new dictionary();
|
|
webster.put("alreadyAStorytellersAssistant", alreadyAStorytellersAssistant);
|
|
webster.put("targetName", getName(self));
|
|
messageTo(storytellerPlayer, "handleStorytellerAlreadyAnAssistant", webster, 0, false);
|
|
}
|
|
}
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleTellStorytellerIDeclinedAssistant()
|
|
{
|
|
obj_id storytellerPlayer = params.getObjId("storytellerPlayer");
|
|
if ( isIdValid(storytellerPlayer) )
|
|
{
|
|
dictionary webster = new dictionary();
|
|
webster.put("targetName", getName(self));
|
|
messageTo(storytellerPlayer, "handleStorytellerAssistantDeclined", webster, 0, false);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
|
|
messageHandler handleStoryTellerAssistantAccepted()
|
|
{
|
|
obj_id storytellerPlayer = params.getObjId("storytellerPlayer");
|
|
string storytellerName = params.getString("storytellerName");
|
|
|
|
if ( isIdValid(storytellerPlayer) )
|
|
{
|
|
storyteller.storyAssistantAcepted(storytellerPlayer, storytellerName, self);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleStoryTellerRemoveAssistant()
|
|
{
|
|
obj_id storytellerPlayer = params.getObjId("storytellerPlayer");
|
|
string storytellerName = params.getString("storytellerName");
|
|
|
|
if ( isIdValid(storytellerPlayer) )
|
|
{
|
|
dictionary webster = new dictionary();
|
|
webster.put("removedPlayerName", getName(self));
|
|
|
|
if ( utils.hasScriptVar(self, "storytellerAssistant") )
|
|
{
|
|
obj_id targetStorytellerId = utils.getObjIdScriptVar(self, "storytellerAssistant");
|
|
if ( targetStorytellerId == storytellerPlayer )
|
|
{
|
|
storyteller.storyPlayerRemoveAssistant(storytellerPlayer, storytellerName, self);
|
|
}
|
|
else
|
|
{
|
|
messageTo(storytellerPlayer, "handleStorytellerRemovePlayerNotAssistant", webster, 0, false);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
messageTo(storytellerPlayer, "handleStorytellerRemovePlayerNotAssistant", webster, 0, false);
|
|
}
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Storyteller invites, removal, etc.
|
|
messageHandler handleStoryTellerInviteRequest()
|
|
{
|
|
obj_id storytellerPlayer = params.getObjId("storytellerPlayer");
|
|
string storytellerName = params.getString("storytellerName");
|
|
obj_id storytellerAssistant = params.getObjId("storytellerAssistant");
|
|
|
|
if ( isIdValid(storytellerPlayer) )
|
|
{
|
|
if ( storyteller.doIAutoDeclineStorytellerInvites(self) )
|
|
{
|
|
dictionary webster = new dictionary();
|
|
webster.put("targetName", getName(self));
|
|
messageTo(storytellerPlayer, "handleStorytellerInviteDeclined", webster, 0, false);
|
|
}
|
|
else
|
|
{
|
|
if ( !utils.hasScriptVar(self, "storytellerid") )
|
|
{
|
|
if ( isIdValid(storytellerAssistant) )
|
|
{
|
|
storyteller.storyInviteSui(storytellerAssistant, storytellerName, self);
|
|
}
|
|
else
|
|
{
|
|
storyteller.storyInviteSui(storytellerPlayer, storytellerName, self);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
boolean alreadyInStorytellersStory = false;
|
|
|
|
obj_id storytellerId = utils.getObjIdScriptVar(self, "storytellerid");
|
|
if( storytellerId == storytellerPlayer )
|
|
{
|
|
alreadyInStorytellersStory = true;
|
|
}
|
|
|
|
dictionary webster = new dictionary();
|
|
webster.put("alreadyInStorytellersStory", alreadyInStorytellersStory);
|
|
webster.put("targetName", getName(self));
|
|
webster.put("storytellerName", storytellerName);
|
|
|
|
if ( isIdValid(storytellerAssistant) )
|
|
{
|
|
messageTo(storytellerAssistant, "handleStorytellerInviteAlreadyInAStory", webster, 0, false);
|
|
}
|
|
else
|
|
{
|
|
messageTo(storytellerPlayer, "handleStorytellerInviteAlreadyInAStory", webster, 0, false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleTellStorytellerIDeclinedInvite()
|
|
{
|
|
obj_id storytellerPlayer = params.getObjId("storytellerPlayer");
|
|
if ( isIdValid(storytellerPlayer) )
|
|
{
|
|
dictionary webster = new dictionary();
|
|
webster.put("targetName", getName(self));
|
|
messageTo(storytellerPlayer, "handleStorytellerInviteDeclined", webster, 0, false);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleStoryTellerInviteAccepted()
|
|
{
|
|
obj_id storytellerPlayer = params.getObjId("storytellerPlayer");
|
|
string storytellerName = params.getString("storytellerName");
|
|
obj_id storytellerAssistant = params.getObjId("storytellerAssistant");
|
|
|
|
if ( isIdValid(storytellerPlayer) )
|
|
{
|
|
storyteller.storyInviteAcepted(storytellerPlayer, storytellerName, self, storytellerAssistant);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleStoryTellerRemovedFromStory()
|
|
{
|
|
obj_id storytellerPlayer = params.getObjId("storytellerPlayer");
|
|
string storytellerName = params.getString("storytellerName");
|
|
|
|
if ( isIdValid(storytellerPlayer) )
|
|
{
|
|
|
|
dictionary webster = new dictionary();
|
|
webster.put("removedPlayerName", getName(self));
|
|
|
|
if ( utils.hasScriptVar(self, "storytellerid") )
|
|
{
|
|
obj_id targetStorytellerId = utils.getObjIdScriptVar(self, "storytellerid");
|
|
if ( targetStorytellerId == storytellerPlayer )
|
|
{
|
|
storyteller.storyPlayerRemovedFromStory(storytellerPlayer, storytellerName, self);
|
|
}
|
|
else
|
|
{
|
|
messageTo(storytellerPlayer, "handleStorytellerRemovePlayerNotInStory", null, 0, false);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
messageTo(storytellerPlayer, "handleStorytellerRemovePlayerNotInStory", null, 0, false);
|
|
}
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler setDisplayOnlyDefensiveMods()
|
|
{
|
|
if(!trial.verifySession(self, params, "displayDefensiveMods"))
|
|
return SCRIPT_CONTINUE;
|
|
|
|
string[] variousMods = { "display_only_glancing_blow",
|
|
"display_only_dodge",
|
|
"display_only_parry",
|
|
"display_only_block",
|
|
"display_only_tohit",
|
|
"display_only_evasion",
|
|
"display_only_strikethrough",
|
|
"display_only_crit_resistance",
|
|
"display_only_critical",
|
|
// "display_only_crit_resistance",
|
|
"display_only_parry_reduction",
|
|
"display_only_opp_block_reduction",
|
|
"display_only_opp_dodge_reduction",
|
|
"display_only_expertise_critical_hit_reduction",
|
|
"display_only_expertise_critical_hit_pvp_reduction"
|
|
};
|
|
|
|
float glancingBlowChance = combat.getDefenderGlancingBlowChance(self) * 100;
|
|
float dodgeChance = combat.getDefenderDodgeChance(self) * 100;
|
|
float parryChance = combat.getDefenderParryChance(self) * 100;
|
|
float blockChance = combat.getDefenderBlockChance(self) * 100;
|
|
float evasionChance = combat.getDefenderEvasionChance(self) * 100;
|
|
float strikeThroughChance = combat.getAttackerStrikethroughChance(self) * 100;
|
|
float toHitBonus = combat.getToHitBonus(self) * 100;
|
|
float criticalChance = (combat.getAttackerCritMod(self)) * 100;
|
|
// float criticalVulnerability = combat.getDefenderCriticalChance(self) * 100;
|
|
float parryRedcution = combat.getAttackerParryReduction(self) * 100;
|
|
float dodgeReduction = combat.getAttackerDodgeReduction(self) * 100;
|
|
float blockReduction = combat.getAttackerBlockReduction(self) * 100;
|
|
float hitReduction = combat.getDefenderCriticalChance(self) * 100;
|
|
float hitPvPReduction = (combat.getDefenderCriticalChance(self) + combat.getPvPHitReductionChance(self)) * 100;
|
|
|
|
for(int i = 0; i < variousMods.length; i++)
|
|
{
|
|
removeAttribOrSkillModModifier(self, variousMods[i]);
|
|
}
|
|
|
|
addSkillModModifier(self, "display_only_glancing_blow", "display_only_glancing_blow", (int)glancingBlowChance, -1, false, false);
|
|
addSkillModModifier(self, "display_only_dodge", "display_only_dodge", (int)dodgeChance, -1, false, false);
|
|
addSkillModModifier(self, "display_only_parry", "display_only_parry", (int)parryChance, -1, false, false);
|
|
addSkillModModifier(self, "display_only_block", "display_only_block", (int)blockChance, -1, false, false);
|
|
addSkillModModifier(self, "display_only_tohit", "display_only_tohit", (int)toHitBonus, -1, false, false);
|
|
addSkillModModifier(self, "display_only_evasion", "display_only_evasion", (int)evasionChance, -1, false, false);
|
|
addSkillModModifier(self, "display_only_strikethrough", "display_only_strikethrough", (int)strikeThroughChance, -1, false, false);
|
|
addSkillModModifier(self, "display_only_critical", "display_only_critical", (int)criticalChance, -1, false, false);
|
|
// addSkillModModifier(self, "display_only_crit_resistance", "display_only_crit_resistance", (int)criticalVulnerability, -1, false, false);
|
|
addSkillModModifier(self, "display_only_parry_reduction", "display_only_parry_reduction", (int)parryRedcution, -1, false, false);
|
|
addSkillModModifier(self, "display_only_opp_dodge_reduction", "display_only_opp_dodge_reduction", (int)dodgeReduction, -1, false, false);
|
|
addSkillModModifier(self, "display_only_opp_block_reduction", "display_only_opp_block_reduction", (int)blockReduction, -1, false, false);
|
|
addSkillModModifier(self, "display_only_expertise_critical_hit_reduction", "display_only_expertise_critical_hit_reduction", (int)hitReduction, -1, false, false);
|
|
addSkillModModifier(self, "display_only_expertise_critical_hit_pvp_reduction", "display_only_expertise_critical_hit_pvp_reduction", (int)hitPvPReduction, -1, false, false);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
trigger OnGetAttributes(obj_id player, string[] names, string[] attribs)
|
|
{
|
|
int idx = utils.getValidAttributeIndex(names);
|
|
if (idx == -1)
|
|
return SCRIPT_CONTINUE;
|
|
|
|
if( utils.hasScriptVar(self, "storytellerName") )
|
|
{
|
|
string storytellerName = utils.getStringScriptVar(self, "storytellerName");
|
|
names[idx] = "storyteller_name";
|
|
attribs[idx] = storytellerName;
|
|
idx++;
|
|
if (idx >= names.length)
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
if( utils.hasScriptVar(self, "storytellerAssistantName") )
|
|
{
|
|
string storytellerAssistantName = utils.getStringScriptVar(self, "storytellerAssistantName");
|
|
names[idx] = "storyteller_assistant_name";
|
|
attribs[idx] = storytellerAssistantName;
|
|
idx++;
|
|
if (idx >= names.length)
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
|
|
}
|
|
|
|
|
|
commandHandler cmdGetGalaxyMessage()
|
|
{
|
|
obj_id planetId = getPlanetByName("tatooine");
|
|
if (!isIdNull(planetId))
|
|
{
|
|
if (hasObjVar(planetId, "galaxyMessage"))
|
|
{
|
|
string strGalaxyMessage = "\\#FF0000"+utils.getStringObjVar(planetId, "galaxyMessage")+"\\#FFFFFF";
|
|
sendConsoleMessage(self, strGalaxyMessage);
|
|
}
|
|
else
|
|
{
|
|
string strGalaxyMessage = "\\#FF0000"+"Welcome to Star Wars Galaxies"+"\\#FFFFFF";
|
|
sendConsoleMessage(self, strGalaxyMessage);
|
|
}
|
|
|
|
boolean warden = isWarden(self);
|
|
if (warden || (getGodLevel(self) >= 10))
|
|
{
|
|
string strGalaxyMessage = "\\#FF0000";
|
|
if (!warden)
|
|
{
|
|
strGalaxyMessage += "Displaying warden MOTD to you even though you are not a warden, because you are of the appropriate god level:\n";
|
|
}
|
|
|
|
if (hasObjVar(planetId, "galaxyWardenMessage"))
|
|
{
|
|
strGalaxyMessage += utils.getStringObjVar(planetId, "galaxyWardenMessage");
|
|
}
|
|
else
|
|
{
|
|
strGalaxyMessage += "Welcome warden";
|
|
}
|
|
|
|
strGalaxyMessage += "\\#FFFFFF";
|
|
sendConsoleMessage(self, strGalaxyMessage);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sendConsoleMessage(self, "Welcome to Star Wars Galaxies");
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler myCityMotdResponse()
|
|
{
|
|
string city_motd = params.getString("city_motd");
|
|
if(city_motd != null && city_motd.length() > 0)
|
|
sendConsoleMessage(self, city_motd + "\\#DFDFDF");
|
|
|
|
//set scriptvar so we don't spam them when they travel.
|
|
utils.setScriptVar(self, "recieved_city_motd", 1);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler stampDungeonArea()
|
|
{
|
|
string dungeon_area = params.getString("buildout_area");
|
|
if (dungeon_area == "invalid")
|
|
return SCRIPT_CONTINUE;
|
|
|
|
int buildout_row = params.getInt("buildout_row");
|
|
if (buildout_row == -1)
|
|
return SCRIPT_CONTINUE;
|
|
|
|
setObjVar(self, space_dungeon.VAR_BUILDOUT_AREA, dungeon_area);
|
|
setObjVar(self, space_dungeon.VAR_BUILDOUT_ROW, buildout_row);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler removeDungeonArea()
|
|
{
|
|
string dungeon_area = params.getString("buildout_area");
|
|
if (dungeon_area == "invalid")
|
|
return SCRIPT_CONTINUE;
|
|
|
|
int buildout_row = params.getInt("buildout_row");
|
|
if (buildout_row == -1)
|
|
return SCRIPT_CONTINUE;
|
|
|
|
if (!hasObjVar(self, space_dungeon.VAR_BUILDOUT_AREA) || getStringObjVar(self, space_dungeon.VAR_BUILDOUT_AREA) != dungeon_area)
|
|
return SCRIPT_CONTINUE;
|
|
|
|
removeObjVar(self, space_dungeon.VAR_BUILDOUT_AREA);
|
|
removeObjVar(self, space_dungeon.VAR_BUILDOUT_ROW);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleStopDanceMessage()
|
|
{
|
|
utils.removeScriptVar(self, "stopDanceMessage");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler onGuildCreateTerminalDataObject()
|
|
{
|
|
|
|
boolean hasTerminal = utils.playerHasItemByTemplateInDataPad(self, guild.STR_GUILD_REMOTE_DEVICE);
|
|
|
|
if(!hasTerminal)
|
|
{
|
|
obj_id pDataPad = utils.getPlayerDatapad(self);
|
|
createObjectOverloaded(guild.STR_GUILD_REMOTE_DEVICE, utils.getPlayerDatapad(self));
|
|
|
|
string_id stringMessage = new string_id("guild", "datapad_terminal_created");
|
|
|
|
sendSystemMessage(self, stringMessage);
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//handler to apply mount buff, if player has somehow gotton off vehicle buff will not fire
|
|
messageHandler applyMountBuff()
|
|
{
|
|
obj_id playerCurrentMount = getMountId(self);
|
|
if(isIdValid(playerCurrentMount))
|
|
vehicle.applyVehicleBuffs(self, playerCurrentMount);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
//call mission lib to clear all daily objvars
|
|
messageHandler handleDailyMissionReset()
|
|
{
|
|
missions.clearDailyObjVars(self);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
/***** MEDITATION ********************************************************/
|
|
commandHandler cmdMeditate()
|
|
{
|
|
//need to check if they are not sitting since command table won't do it if a toolbar button command.
|
|
if (getPosture(self) != POSTURE_SITTING)
|
|
{
|
|
sendSystemMessage(self, new string_id("jedi_spam", "meditate_not_sitting"));
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
//if the are invis pop them out
|
|
stealth.checkForAndMakeVisibleNoRecourse(self);
|
|
|
|
//check to see if player is force meditating, if so do not let them meditate
|
|
if (getState(self, STATE_MEDITATE) == 1)
|
|
{
|
|
sendSystemMessage(self, new string_id("jedi_spam", "already_in_meditative_state"));
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
//debugSpeakMsg(self, "cmdMeditate: entered...");
|
|
|
|
meditation.startMeditation(self);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
commandHandler cmdMeditateFail()
|
|
{
|
|
sendSystemMessage(self, meditation.SID_MED_FAIL);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//IMMA CHARGIN MAH LASZERS
|
|
messageHandler handleMeditationTick()
|
|
{
|
|
if ( !meditation.isMeditating(self) )
|
|
{
|
|
meditation.endMeditation(self, false);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
if(!trial.verifySession(self, params, meditation.HANDLER_MEDITATION_TICK))
|
|
return SCRIPT_CONTINUE;
|
|
|
|
//only Jedi get the Benefit of Buffs from meditation
|
|
if(utils.isProfession(self, utils.FORCE_SENSITIVE))
|
|
{
|
|
|
|
//first time through we don't have scriptVar and value is 0
|
|
int value = 0;
|
|
|
|
if(utils.hasScriptVar(self, meditation.VAR_MEDITATION_BASE))
|
|
{
|
|
value = utils.getIntScriptVar(self, meditation.VAR_MEDITATION_BASE);
|
|
value++;
|
|
|
|
//sendSystemMessageTestingOnly(self, "IMMA CHARGIN MAH LASZERS " +value);
|
|
if(value >= 3)
|
|
{
|
|
//if the are invis pop them out
|
|
stealth.checkForAndMakeVisibleNoRecourse(self);
|
|
//random buff is applied
|
|
string meditateBuff= meditation.MEDITATE_BUFFS[rand(0, meditation.MEDITATE_BUFFS.length-1)];
|
|
//sendSystemMessageTestingOnly(self, "LASZERS CHARGED!!!");
|
|
buff.applyBuff(self, meditateBuff);
|
|
value = 0;
|
|
}
|
|
|
|
}
|
|
//sendSystemMessageTestingOnly(self, "ScriptVarValue " +value);
|
|
utils.setScriptVar(self, meditation.VAR_MEDITATION_BASE, value);
|
|
}
|
|
|
|
messageTo(self, meditation.HANDLER_MEDITATION_TICK, trial.getSessionDict(self, meditation.HANDLER_MEDITATION_TICK), 10f, false);
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//message handler that will recall coupdegrace
|
|
//only called if the victim and killer are not both authoritative
|
|
messageHandler msgCoupDeGraceAuthoritativeCheck()
|
|
{
|
|
if (!utils.hasScriptVar(self, "death.beingCoupDeGraced"))
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//validate params
|
|
if(params == null || params.isEmpty())
|
|
{
|
|
utils.removeScriptVar(self, "death.beingCoupDeGraced");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//this variable checks how many times we have attempted to make both players authoritative
|
|
int numberOfTries = params.getInt("numberOfTries");
|
|
//Get all data needed to call pclib.coupDeGrace
|
|
obj_id victim = params.getObjId("victim");
|
|
obj_id killer = params.getObjId("killer");
|
|
boolean playAnim = params.getBoolean("playAnim");
|
|
boolean usePVPRules = params.getBoolean("usePVPRules");
|
|
|
|
//we are all authoritative now, so lets kill them correctly
|
|
if(victim.isAuthoritative() && killer.isAuthoritative())
|
|
{
|
|
utils.removeScriptVar(self, "death.beingCoupDeGraced");
|
|
pclib.coupDeGrace(victim, killer, playAnim, usePVPRules);
|
|
}
|
|
else /* wait! */
|
|
{
|
|
//if we have attempted this 5 or more times, we need to give up, and send a CS message.
|
|
if(numberOfTries >= 5)
|
|
{
|
|
CustomerServiceLog("player_death", "coupDeGrace:Player %TU was Death Blowed by %TT, " + numberOfTries + " attempts have been made to force them onto the same process, and has failed. %TU may be perma-incapped", victim, killer);
|
|
utils.removeScriptVar(self, "death.beingCoupDeGraced");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//lets try again in 2 seconds.
|
|
params.put("numberOfTries", ++numberOfTries);
|
|
messageTo(victim, "msgCoupDeGraceAuthoritativeCheck", params, 2, false);
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
//Checking if it's a new day for life day and the player should be reset..
|
|
boolean lifeDayNewDay(obj_id player)
|
|
{
|
|
if (hasObjVar(player, "lifeday.time_stamp"))
|
|
{
|
|
int now = getCalendarTime();
|
|
int then = getIntObjVar(player, "lifeday.time_stamp");
|
|
|
|
if (now > then)
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
boolean colorizeObject(obj_id self, obj_id object, obj_id tool, string params)
|
|
{
|
|
if(!isValidId(self) || !exists(self))
|
|
return false;
|
|
if(!isValidId(object) || !exists(object))
|
|
return false;
|
|
if(!isValidId(tool) || !exists(tool))
|
|
return false;
|
|
if(params == null || params.equals(""))
|
|
return false;
|
|
|
|
//if the params are blank, the player hit cancel.
|
|
if(params == null || params.equals(""))
|
|
{
|
|
messageTo(tool, "cancelTool", null, 0, false);
|
|
return false;
|
|
}
|
|
|
|
string[] colorArray = split(params, ' ');
|
|
if(colorArray == null || colorArray.length <= 0)
|
|
return false;
|
|
|
|
for(int i = 0; i < colorArray.length; i+=2)
|
|
{
|
|
if(colorArray[i] == null || colorArray[i].equals(""))
|
|
break;//if a blank entry is found bail out.
|
|
hue.setColor(object, colorArray[i], utils.stringToInt(colorArray[i+1]));
|
|
}
|
|
|
|
messageTo(tool, "decrementTool", null, 0, false);
|
|
return true;
|
|
}
|
|
|
|
boolean isPvpRelatedDeath(obj_id player)
|
|
{
|
|
if(!utils.hasScriptVar(player, "lastKiller"))
|
|
return false;
|
|
|
|
obj_id lastKillerOID = utils.getObjIdScriptVar(player, "lastKiller");
|
|
|
|
utils.removeScriptVar(player, "lastKiller");
|
|
|
|
if(!isIdValid(lastKillerOID))
|
|
return false;
|
|
|
|
if(isPlayer(lastKillerOID))
|
|
return true;
|
|
|
|
if(pet_lib.isPet(lastKillerOID) || pet_lib.isDroidPet(lastKillerOID) || pet_lib.isNpcPet(lastKillerOID) || pet_lib.isCombatDroid(lastKillerOID)
|
|
|| beast_lib.isBeast(lastKillerOID))
|
|
{
|
|
obj_id master = getMaster(lastKillerOID);
|
|
if ( isIdValid(master) && isPlayer(master))
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
boolean needsBlackwingLightInfection(obj_id self)
|
|
{
|
|
if ( !buff.hasBuff(self, "death_troopers_infection_1") && !buff.hasBuff(self, "death_troopers_infection_2") &&
|
|
!buff.hasBuff(self, "death_troopers_infection_3") && !buff.hasBuff(self, "death_troopers_inoculation") )
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
messageHandler death_troopers_apply_virus()
|
|
{
|
|
if( needsBlackwingLightInfection(self) && locations.isInRegion(self, "@dathomir_region_names:black_mesa") )
|
|
{
|
|
buff.applyBuff(self, "death_troopers_infection_1");
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleBuyBackSui()
|
|
{
|
|
if(params == null || params.equals(""))
|
|
{
|
|
CustomerServiceLog("Junk_Dealer: ", "base_player.handleBuyBackSui() - Player: "+self+" attempted to get a list of buy back items but the message handler received not data.");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Get the obj id of the player that hit a button
|
|
obj_id junkDealer = params.getObjId("dealer");
|
|
|
|
// If the player is not valid, quit out
|
|
if(!isIdValid(junkDealer))
|
|
return SCRIPT_CONTINUE;
|
|
//range check
|
|
if (utils.outOfRange(junkDealer, self, 10.0f, true))
|
|
{
|
|
CustomerServiceLog("Junk_Dealer: ", "base_player.handleBuyBackSui() - Player: "+self+" attempted to get a list of buy back items but the action failed. The player was too far away from the TERMINAL.");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Get the row of the list box that was highlighted, and get the button that was pushed
|
|
int idx = sui.getListboxSelectedRow(params);
|
|
int bp = sui.getIntButtonPressed(params);
|
|
|
|
// Get the list of relics off of the player
|
|
obj_id[] junk = utils.getObjIdBatchScriptVar(self, smuggler.SCRIPTVAR_JUNK_IDS);
|
|
|
|
// Clean the script vars off of the player
|
|
smuggler.cleanupSellJunkSui(self);
|
|
|
|
// If the button pressed was "CANCEL"
|
|
if(bp == sui.BP_CANCEL)
|
|
{
|
|
// Go ahead and quit out
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
else if(bp == sui.BP_REVERT)
|
|
{
|
|
if(idx >= 0 && idx <= junk.length - 1)
|
|
{
|
|
if((junk != null) || (junk.length > 0))
|
|
{
|
|
openExamineWindow(self, junk[idx]);
|
|
}
|
|
}
|
|
|
|
obj_id[] buyBackItems = smuggler.getBuyBackItemsInContainer(self);
|
|
if(buyBackItems != null && buyBackItems.length > 0)
|
|
{
|
|
smuggler.showBuyBackSui(self, junkDealer);
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// The only other button left is "OK" or our 'sell' button
|
|
else
|
|
{
|
|
// If no row was selected, quit out
|
|
if(idx < 0)
|
|
return SCRIPT_CONTINUE;
|
|
|
|
// If the list of relics is empty, quit out
|
|
if((junk == null) || (junk.length == 0))
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// If our arithmetic is off, quit out
|
|
if(idx > junk.length - 1)
|
|
return SCRIPT_CONTINUE;
|
|
|
|
// Go through the sell item procedure
|
|
smuggler.buyBackJunkItem(self, junkDealer, junk[idx], true);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleTheBuyBack()
|
|
{
|
|
if(params == null || params.equals(""))
|
|
{
|
|
CustomerServiceLog("Junk_Dealer: ", "base_player.handleBuyBackSui() - Player: "+self+" attempted to get a list of buy back items but the message handler received not data.");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Get the obj id of the player that hit a button
|
|
obj_id junkDealer = params.getObjId("dealer");
|
|
|
|
// If the player is not valid, quit out
|
|
if(!isIdValid(junkDealer))
|
|
return SCRIPT_CONTINUE;
|
|
//range check
|
|
if (utils.outOfRange(junkDealer, self, 10.0f, true))
|
|
{
|
|
CustomerServiceLog("Junk_Dealer: ", "base_player.handleBuyBackSui() - Player: "+self+" attempted to get a list of buy back items but the action failed. The player was too far away from the TERMINAL.");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Get the obj id of the item sold. If it doesn't exist, quit out
|
|
obj_id item = params.getObjId("item");
|
|
if(!isIdValid(item))
|
|
{
|
|
CustomerServiceLog("Junk_Dealer: ", "base_player.handleTheBuyBack() - Player (OID: " + self + ") could not sell item because the item parameter was invalid.");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
int price = params.getInt("price");
|
|
if(price <= 0)
|
|
{
|
|
CustomerServiceLog("Junk_Dealer: ", "base_player.handleTheBuyBack() - Player (OID: " + self + ") could not sell item because the price on the item was invalid.");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Get the return code of the money transaction
|
|
int retCode = params.getInt(money.DICT_CODE);
|
|
|
|
// If the transaction failed
|
|
if(retCode == money.RET_FAIL)
|
|
{
|
|
// Let the player know
|
|
prose_package ppNoSale = prose.getPackage(smuggler.PROSE_NO_BUY_BACK, item);
|
|
sendSystemMessageProse(self, ppNoSale);
|
|
CustomerServiceLog("Junk_Dealer: ", "base_player.handleTheBuyBack() - Player (OID: " + self + ") could not sell item (" + item + ") for (" + price + ") because the player did not have the credits.");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Let the player know exactly what he or she just did
|
|
prose_package ppSoldJunk = prose.getPackage(smuggler.PROSE_PURCHASED_JUNK, item, price);
|
|
sendSystemMessageProse(self, ppSoldJunk);;
|
|
CustomerServiceLog("Junk_Dealer: ", "base_player.handleTheBuyBack() - Player (OID: " + self + ") has paid: "+price+" for a buy back item and is about to retrieve that item: "+item+" from their buy back container.");
|
|
|
|
smuggler.moveBuyBackObjectIntoInventory(self, item);
|
|
|
|
obj_id[] buyBackItems = smuggler.getBuyBackItemsInContainer(self);
|
|
if(buyBackItems != null && buyBackItems.length > 0)
|
|
{
|
|
smuggler.showBuyBackSui(self, junkDealer);
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
|
|
messageHandler handleFlagJunkSui()
|
|
{
|
|
if(params == null || params.equals(""))
|
|
{
|
|
CustomerServiceLog("Junk_Dealer: ", "base_player.handleBuyBackSui() - Player: "+self+" attempted to get a list of buy back items but the message handler received not data.");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// Get the obj id of the player that hit a button
|
|
obj_id junkDealer = params.getObjId("dealer");
|
|
|
|
// If the player is not valid, quit out
|
|
if(!isIdValid(junkDealer))
|
|
return SCRIPT_CONTINUE;
|
|
//range check
|
|
if (utils.outOfRange(junkDealer, self, 10.0f, true))
|
|
{
|
|
CustomerServiceLog("Junk_Dealer: ", "base_player.handleBuyBackSui() - Player: "+self+" attempted to get a list of buy back items but the action failed. The player was too far away from the TERMINAL.");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
// Get the row of the list box that was highlighted, and get the button that was pushed
|
|
int idx = sui.getListboxSelectedRow(params);
|
|
int bp = sui.getIntButtonPressed(params);
|
|
|
|
// Get the list of items off of the player
|
|
obj_id[] junk = utils.getObjIdBatchScriptVar(self, smuggler.SCRIPTVAR_JUNK_IDS);
|
|
|
|
//do not repop up the SUI if we have have no more items to sell
|
|
boolean reshowSui = true;
|
|
if (junk.length < 1)
|
|
reshowSui = false;
|
|
|
|
// Clean the script vars off of the player
|
|
smuggler.cleanupSellJunkSui(self);
|
|
|
|
if(bp == sui.BP_CANCEL)
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
else if(bp == sui.BP_REVERT)
|
|
{
|
|
if(idx >= 0 && idx <= junk.length - 1)
|
|
{
|
|
if((junk != null) || (junk.length > 0))
|
|
{
|
|
openExamineWindow(self, junk[idx]);
|
|
smuggler.flagJunkSaleSui(self, junkDealer);
|
|
}
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
else
|
|
{
|
|
// If no row was selected, quit out
|
|
if(idx < 0)
|
|
{
|
|
if(junk != null && junk.length > 0)
|
|
{
|
|
smuggler.flagJunkSaleSui(self, junkDealer);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
|
|
// If our arithmetic is off, quit out
|
|
if(idx > junk.length - 1)
|
|
{
|
|
if(junk != null && junk.length > 0)
|
|
{
|
|
smuggler.flagJunkSaleSui(self, junkDealer);
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
if(hasObjVar(junk[idx], smuggler.JUNK_DEALKER_NO_SALE_FLAG))
|
|
{
|
|
removeObjVar(junk[idx], smuggler.JUNK_DEALKER_NO_SALE_FLAG);
|
|
}
|
|
else
|
|
{
|
|
setObjVar(junk[idx], smuggler.JUNK_DEALKER_NO_SALE_FLAG, getGameTime());
|
|
}
|
|
smuggler.flagJunkSaleSui(self, junkDealer);
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
|
|
boolean blog(string txt)
|
|
{
|
|
if(LOGGING_ON)
|
|
{
|
|
LOG(LOGNAME, txt);
|
|
}
|
|
return true;
|
|
}
|
|
|