Files
dsrc/sku.0/sys.server/compiled/game/script/systems/combat/combat_weapon.script
T
2013-09-10 23:17:15 -07:00

698 lines
19 KiB
Plaintext

include library.ai_lib;
include library.buff;
include library.combat;
include library.jedi;
include library.proc;
include library.prose;
include library.static_item;
include library.sui;
include library.trace;
include library.utils;
include library.weapons;
const java.text.NumberFormat floatFormat = new java.text.DecimalFormat("###.##");
const java.text.NumberFormat noDecimalFormat = new java.text.DecimalFormat("###");
const java.text.NumberFormat percentFormat = new java.text.DecimalFormat("###.#%");
const string PID_NAME = "wpConversion";
trigger OnObjectMenuRequest(obj_id player, menu_info item)
{
//if is not in player inventory
if(!utils.isNestedWithinAPlayer(self))
return SCRIPT_CONTINUE;
//cannot be equipped
if(utils.isEquipped(self))
return SCRIPT_CONTINUE;
//if is static item
if(static_item.isStaticItem(self) && !hasObjVar(self, "wp.canBeDisMantled"))
return SCRIPT_CONTINUE;
//if is static dynamic
if(static_item.isDynamicItem(self))
return SCRIPT_CONTINUE;
//is already a cored weapon
if(weapons.isCoredWeapon(self))
return SCRIPT_CONTINUE;
//no lightsabers
if(jedi.isLightsaber(self))
return SCRIPT_CONTINUE;
//if a profession wheel granted schem
if(weapons.isProfWheelSchemWeapon(self))
return SCRIPT_CONTINUE;
//if biolinked, we only want the owner to do the deconstuction
obj_id bioLink = getBioLink(self);
if(isIdValid(bioLink) && utils.stringToLong(bioLink.toString()) != 1)
{
if(bioLink != player)
return SCRIPT_CONTINUE;
}
int management_root = item.addRootMenu (menu_info_types.SERVER_MENU5, weapons.SID_WEAPON_TO_SCHEM);
return SCRIPT_CONTINUE;
}
trigger OnObjectMenuSelect(obj_id player, int item)
{
if (item == menu_info_types.SERVER_MENU5)
{
//if is not in player inventory
if(!utils.isNestedWithinAPlayer(self))
return SCRIPT_CONTINUE;
//cannot be equipped
if(utils.isEquipped(self))
return SCRIPT_CONTINUE;
//if is static item
if(static_item.isStaticItem(self) && !hasObjVar(self, "wp.canBeDisMantled"))
return SCRIPT_CONTINUE;
//if is static dynamic
if(static_item.isDynamicItem(self))
return SCRIPT_CONTINUE;
//is already a cored weapon
if(weapons.isCoredWeapon(self))
return SCRIPT_CONTINUE;
//no lightsabers
if(jedi.isLightsaber(self))
return SCRIPT_CONTINUE;
//if a profession wheel granted schem
if(weapons.isProfWheelSchemWeapon(self))
return SCRIPT_CONTINUE;
//if biolinked, we only want the owner to do the deconstuction
obj_id bioLink = getBioLink(self);
if(isIdValid(bioLink) && utils.stringToLong(bioLink.toString()) != 1)
{
if(bioLink != player)
return SCRIPT_CONTINUE;
}
if(sui.hasPid(player, PID_NAME))
{
int pid = sui.getPid(player, PID_NAME);
forceCloseSUIPage(pid);
}
int pid = sui.inputbox(self, player, "@" + weapons.SID_CONVERT_PROMPT, sui.OK_CANCEL, "@" + weapons.SID_CONVERT_TITLE, sui.INPUT_NORMAL, null, "handleConvertSchemSui");
sui.setPid(player, pid, PID_NAME);
}
return SCRIPT_CONTINUE;
}
void expertiseRangeModify(obj_id self)
{
if(!isIdValid(self))
{
return;
}
if(!hasObjVar(self, "weapon.original_max_range") )
{
float weaponRange = 0f;
if(!static_item.isStaticItem(self))
{
// Crafted weapon range conversion
if(!hasObjVar(self, "dynamic_item.intLevelRequired"))
{
dictionary weaponDat = weapons.getWeaponDat(self); // Gets weapon data from schematics; NOT STATIC ITEMS
if(weaponDat == null)
{
return;
}
weaponRange = (float)weapons.getMaxRangeDistance(weaponDat);
}
else // Static-dynamic weapon range conversion
{
weaponRange = static_item.getDynamicWeaponRange(self);
}
}
else
{
string staticItemName = static_item.getStaticItemName(self);
weaponRange = (float)dataTableGetInt("datatables/item/master_item/weapon_stats.iff", staticItemName, "max_range_distance");
}
if(weaponRange > 0)
{
setObjVar(self, "weapon.original_max_range", weaponRange);
}
else
{
CustomerServiceLog("weap_conversion_bad", "POSSIBLE :BROKEN WEAPON: COULD NOT GET MAX RANGE FOR " + self + " template: " + getTemplateName(self));
return;
}
}
obj_id holder = getContainedBy(self);
if(!isIdNull(holder) && isPlayer(holder) )
{
if(self == getObjectInSlot(holder, "hold_r") )
{
weapons.adjustWeaponRangeForExpertise(holder, self, true);
}
// If it is not equipped, it should not display a modified range.
else
{
weapons.adjustWeaponRangeForExpertise(holder, self, false);
}
}
// Undo any range modification.
else
{
weapons.adjustWeaponRangeForExpertise(null, self, false);
}
}
trigger OnInitialize()
{
messageTo(self, "weaponConversion", null, 5, false);
return SCRIPT_CONTINUE;
}
messageHandler weaponConversion()
{
//we do not want to convert weapon that belong to NPCs or Mobs, lets make sure we are not either and bail out if we are
obj_id owner = utils.getContainingPlayerOrCreature( self );
int niche = ai_lib.aiGetNiche(owner);
//valid niches are 0 - 10, players are 1
if( niche != 1)
{
return SCRIPT_CONTINUE;
}
//extra double check to make sure that we are not a creature weapon
if(utils.hasScriptVar(self, "isCreatureWeapon"))
{
return SCRIPT_CONTINUE;
}
//lets not convert QA's test weapons
if(hasObjVar(self, "QAWeapon"))
{
return SCRIPT_CONTINUE;
}
//do not convert static stuff
if(static_item.isStaticItem(self))
{
expertiseRangeModify(self);
return SCRIPT_CONTINUE;
}
else
{
//check the version objvars to see if we need to convert
int currentVersion = getConversionId(self);
int masterVersion = 0;
//GU5 introduced cored weapons, so we convert those differently
boolean isCoredWeapon = weapons.isCoredWeapon(self);
if(isCoredWeapon)
{
masterVersion = weapons.CORED_WEAPON_CONVERSION_VERSION;
}
else
{
masterVersion = weapons.CONVERSION_VERSION;
}
if(currentVersion != masterVersion)
{
if(static_item.isDynamicItem(self))
{
//static item conversion
weapons.staticDynamicWeaponConversion(self);
}
else if(isCoredWeapon)
{
//cored weapon conversion
weapons.coredWeaponConversion(self);
}
else
{
//click combat weapon coversion
weapons.clickCombatWeaponConversion(self);
}
}
}
//Lets double check the Damage Type
weapons.validateWeaponDamageType(self);
//Lets double check the Range
weapons.validateWeaponRange(self);
weapons.setWeaponData(self);
expertiseRangeModify(self);
if ( weapons.checkForIllegalStorytellerWeapon(owner, self) )
{
weapons.handleIllegalStorytellerWeapon(owner, self, "OnInitialize");
}
return SCRIPT_CONTINUE;
}
trigger OnAboutToBeTransferred(obj_id destContainer, obj_id transferer)
{
if (isPlayer(destContainer) && !combat.hasCertification(destContainer, self))
{
prose_package pp = new prose_package();
pp = prose.setStringId(pp, new string_id("spam", "weapon_no_cert"));
pp = prose.setTT(pp, self);
sendSystemMessageProse(destContainer, pp);
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
trigger OnTransferred(obj_id sourceContainer, obj_id destContainer, obj_id transferer)
{
expertiseRangeModify(self);
if (isPlayer(destContainer))
{
setDamageSkillMods( destContainer, self );
proc.buildCurrentProcList(destContainer);
}
else if (isPlayer(sourceContainer))
{
setDamageSkillMods( sourceContainer, null );
proc.buildCurrentProcList(sourceContainer);
}
return SCRIPT_CONTINUE;
}
void setDamageSkillMods( obj_id player, obj_id weapon )
{
int intMultiplier = combat.PLAYER_ATTACKER_DAMAGE_LEVEL_MULTIPLIER;
int intBaseDamage = combat.PLAYER_COMBAT_BASE_DAMAGE;
int weaponMinDamage = 0;
int weaponMaxDamage = 0;
if ( isIdValid(weapon) )
{
weaponMinDamage = getWeaponMinDamage(weapon);
weaponMaxDamage = getWeaponMaxDamage(weapon);
}
int playerLevel = getLevel( player );
int minDamage = weaponMinDamage + ( playerLevel * intMultiplier );
int maxDamage = intBaseDamage + weaponMaxDamage + ( playerLevel * intMultiplier );
int oldMin = getSkillStatisticModifier(player, "minDamage");
applySkillStatisticModifier(player, "minDamage", 0-oldMin);
int oldMax = getSkillStatisticModifier(player, "maxDamage");
applySkillStatisticModifier(player, "maxDamage", 0-oldMax);
applySkillStatisticModifier(player, "minDamage", minDamage);
applySkillStatisticModifier(player, "maxDamage", maxDamage);
}
/**
* Called when a player requests info about an object. The trigger should fill
* in a localization name and attribute value for each attribute it wants
* the player to know about.
*
* @param self the object being queried
* @param player the player requesting the attributes
* @param names localization name of the attributes
* @param attribs value of the attributes
*/
trigger OnGetAttributes(obj_id player, string[] names, string[] attribs)
{
//data.reserve (data.size () + 12);
String at = "@obj_attr_n:";
boolean staticItem = static_item.isStaticItem(self);
int free = getFirstFreeIndex(names);
if (free == -1)
{
return SCRIPT_CONTINUE;
}
//-- cert info
string template = getTemplateName(self);
if(template != null)
{
dictionary itemData = new dictionary();
if(staticItem)
{
itemData = static_item.getMasterItemDictionary(self);
}
// level requirement
//GU5 we changed weapon crafting, we need to make sure the data we are gathering is from the correct weapon crafting version
int levelRequired = -1;
if(hasObjVar(self, weapons.OBJVAR_WP_LEVEL))
{
levelRequired = getIntObjVar(self, weapons.OBJVAR_WP_LEVEL);
}
else
{
levelRequired = dataTableGetInt(combat.WEAPON_LEVEL_TABLE, template, "weapon_level");
if(staticItem)
levelRequired = itemData.getInt("required_level");
if(static_item.isDynamicItem(self))
{
levelRequired = getIntObjVar(self, "dynamic_item.intLevelRequired");
}
}
names[free] = "healing_combat_level_required";
attribs[free++] = "" + levelRequired;
// tooltip: level requirement
names[free] = "tooltip.healing_combat_level_required";
attribs[free++] = "" + levelRequired;
// Check class requirement
//crafted items get requirements from weapon level table
string skillRequired = dataTableGetString(combat.WEAPON_LEVEL_TABLE, template, "secondary_restriction");
//static items get requirements from master item table
if(staticItem)
skillRequired = itemData.getString("required_skill");
string skillRequiredAttribute;
if (skillRequired != null && skillRequired != "")
{
skillRequiredAttribute = "@ui_roadmap:title_" + skillRequired;
}
else
{
skillRequiredAttribute = "None";
}
//dynamic items have no skill requirements
if(static_item.isDynamicItem(self))
skillRequiredAttribute = "None";
names[free] = "skillmodmin";
attribs[free++] = skillRequiredAttribute;
// tooltip: check skill requirement
names[free] = "tooltip.skillmodmin";
attribs[free++] = skillRequiredAttribute;
// Species requirement
int speciesRequired = dataTableGetInt(combat.WEAPON_LEVEL_TABLE, template, "species_restriction");
if(speciesRequired > 0)
{
names[free] = "race_requirement";
attribs[free++] = "@weapon_detail:species_" + speciesRequired;
// tooltip: species requirement
names[free] = "tooltip.race_requirement";
attribs[free++] = "@weapon_detail:species_" + speciesRequired;
}
if (staticItem)
{
// tier
int tier = itemData.getInt("tier");
names[free] = "tier";
attribs[free++] = "" + tier;
// tooltip: tier
names[free] = "tooltip.tier";
attribs[free++] = "" + tier;
}
}
weapon_data weaponData = getWeaponData(self);
if (weaponData != null)
{
//-- damage
{
String wpn_damage_type = "cat_wpn_damage.wpn_damage_type";
String wpn_damage_min = "cat_wpn_damage.wpn_damage_min";
String wpn_damage_max = "cat_wpn_damage.wpn_damage_max";
String wpn_damage_radius = "cat_wpn_damage.wpn_damage_radius";
String wpn_damage_wound = "cat_wpn_damage.wpn_wound_chance";
String wpn_elemental_type = "cat_wpn_damage.wpn_elemental_type";
String wpn_elemental_value = "cat_wpn_damage.wpn_elemental_value";
String wpn_category = "cat_wpn_damage.wpn_category";
const int damageType = weaponData.damageType;
names[free] = wpn_damage_type;
attribs[free++] = at + "armor_eff_" + weapons.getDamageTypeString(damageType);
// Weapon category
names[free] = "cat_wpn_damage.wpn_category";
attribs[free++] = at + "wpn_category_" + weaponData.weaponType;
// tooltip: damage type
names[free] = "tooltip.wpn_damage_type";
attribs[free++] = at + "armor_eff_" + weapons.getDamageTypeString(damageType);
names[free] = "cat_wpn_damage.wpn_attack_speed";
attribs[free++] = floatFormat.format(weaponData.attackSpeed);
names[free] = "cat_wpn_damage.damage";
string weaponDamage = Integer.toString(weaponData.minDamage) + " - " + Integer.toString(weaponData.maxDamage);
attribs[free++] = weaponDamage;
// tooltip: damage
names[free] = "tooltip.damage";
attribs[free++] = weaponDamage;
const int elementalType = weaponData.elementalType;
int elementalValue = 0;
if(elementalType > 0)
{
elementalValue = weaponData.elementalValue;
if (elementalValue > 0)
{
names[free] = wpn_elemental_type;
attribs[free++] = at + weapons.getDamageTypeString(elementalType);
names[free] = wpn_elemental_value;
attribs[free++] = Integer.toString(elementalValue);
// tooltip: elemental damage type
names[free] = "tooltip.wpn_elemental_type";
attribs[free++] = at + weapons.getDamageTypeString(elementalType);
names[free] = "tooltip.wpn_elemental_value";
attribs[free++] = Integer.toString(elementalValue);
}
}
names[free] = "cat_wpn_damage.weapon_dps";
float avg = (weaponData.minDamage + weaponData.maxDamage) / 2;
//we now add in elemental damage to our dps calcs
//we have to multiply it times 2 cause we actually do double
//elemental damage.
avg += (elementalValue * 2);
attribs[free++] = "" + (int)(avg / weaponData.attackSpeed);
}
//-- range
{
names[free] = "cat_wpn_other.wpn_range";
string weaponRange = noDecimalFormat.format(weaponData.minRange) + "-" + noDecimalFormat.format(weaponData.maxRange) + "m";
attribs[free++] = weaponRange;
// tooltip: range
names[free] = "tooltip.wpn_range";
attribs[free++] = weaponRange;
}
/*
//-- attack cost
{
const int attackCost = weaponData.attackCost;
if (attackCost != 0)
{
names[free] = "cat_wpn_other.cat_wpn_attack_cost";
attribs[free++] = Integer.toString(attackCost);
// tooltip: attack cost
names[free] = "tooltip.cat_wpn_attack_cost";
attribs[free++] = Integer.toString(attackCost);
}
}
*/
}
//display proc name on a static item
if(staticItem)
{
dictionary itemData = static_item.getStaticItemWeaponDictionary(self);
string procEffect = itemData.getString("proc_effect");
if (procEffect != null && procEffect !="")
{
names[free] = utils.packStringId( new string_id ( "proc/proc", "proc_name" ));
attribs[free++] = utils.packStringId( new string_id ( "ui_buff", procEffect));
}
}
/*
//-- slicing nasty warning
if ( hasObjVar(self, "slicing.new_hacked") || hasObjVar(self, "slicing.hacked"))
{
names[free] = "cat_wpn_other.wpn_attr";
attribs[free] = "@obj_attr_n:hacked1";
free++;
}
if(staticItem)
{
names[free] = "cat_wpn_other.wpn_attr";
attribs[free] = "@obj_attr_n:can_not_alter_weap";
free++;
}
*/
return SCRIPT_CONTINUE;
}
obj_id getContainingMobile(obj_id item)
{
obj_id containedBy = getContainedBy(item);
if(!isIdValid(containedBy))
return null;
else if(isPlayer(containedBy) || isMob(containedBy))
return containedBy;
return getContainingMobile(containedBy);
}
messageHandler handleConvertSchemSui()
{
if(params == null || params.isEmpty())
return SCRIPT_CONTINUE;
obj_id player = sui.getPlayerId(params);
if(!isIdValid(player) || !exists(player))
return SCRIPT_CONTINUE;
int bp = sui.getIntButtonPressed(params);
if(bp == sui.BP_CANCEL)
{
sui.removePid(player, PID_NAME);
return SCRIPT_CONTINUE;
}
int pageId = params.getInt("pageId");
if(!sui.hasPid(player, PID_NAME))
{
forceCloseSUIPage(pageId);
CustomerServiceLog("new_weapon_conversion", "Player "+getFirstName(player)+"("+player+") has somehow gotten two conversion windows while attempting to convert their old weapon("+self+") to a new cored schematic. Bailing out now");
return SCRIPT_CONTINUE;
}
int pid = sui.getPid(player, PID_NAME);
if(pageId != pid)
{
forceCloseSUIPage(pageId);
forceCloseSUIPage(pid);
sui.removePid(player, PID_NAME);
CustomerServiceLog("new_weapon_conversion", "Player "+getFirstName(player)+"("+player+") has somehow gotten two conversion windows while attempting to convert their old weapon("+self+") to a new cored schematic. Bailing out now");
return SCRIPT_CONTINUE;
}
if(!utils.isNestedWithinAPlayer(self))
{
forceCloseSUIPage(pid);
sui.removePid(player, PID_NAME);
CustomerServiceLog("new_weapon_conversion", "Player "+getFirstName(player)+"("+player+") has moved their weapon into a container that is not a player while attempting to convert their old weapon("+self+") to a new cored schematic. Bailing out now");
return SCRIPT_CONTINUE;
}
//cannot be equipped
if(utils.isEquipped(self))
{
forceCloseSUIPage(pid);
sui.removePid(player, PID_NAME);
CustomerServiceLog("new_weapon_conversion", "Player "+getFirstName(player)+"("+player+") has equipped their old weapon("+self+") while attempting to convert it int a new cored schematic. Bailing out now");
return SCRIPT_CONTINUE;
}
obj_id playerContained = utils.getContainingPlayer(self);
if(playerContained != player)
{
forceCloseSUIPage(pid);
sui.removePid(player, PID_NAME);
CustomerServiceLog("new_weapon_conversion", "Player "+getFirstName(player)+"("+player+") traded their old weapon("+self+") to " + getFirstName(playerContained) + "("+playerContained+") while attempting to convert it int a new cored schematic. They are prolly trying to exploit, bailing out now");
return SCRIPT_CONTINUE;
}
//if biolinked, we only want the owner to do the deconstuction
obj_id bioLink = getBioLink(self);
if(isIdValid(bioLink) && utils.stringToLong(bioLink.toString()) != 1)
{
if(bioLink != player)
{
forceCloseSUIPage(pid);
sui.removePid(player, PID_NAME);
CustomerServiceLog("armor_conversion", "Player "+getFirstName(player)+"("+player+") tried to deconstruct an old weapon("+self+") that is biolinked to " + getFirstName(bioLink) + "("+bioLink+"). They are prolly trying to exploit, bailing out now");
return SCRIPT_CONTINUE;
}
}
string response = sui.getInputBoxText(params);
if(!response.toLowerCase().equals("deconstruct"))
{
forceCloseSUIPage(pid);
sui.removePid(player, PID_NAME);
sendSystemMessage(player, weapons.SID_CONVERT_INVALID_RESPONSE);
CustomerServiceLog("new_weapon_conversion", "Player "+getFirstName(player)+"("+player+") has entered '" + response + "' instead of 'deconstruct' so the weapon will not be deconstructed.");
return SCRIPT_CONTINUE;
}
if(weapons.turnWeaponIntoSchem(player, self))
{
CustomerServiceLog("new_weapon_conversion", "Player "+getFirstName(player)+"("+player+") has decided to convert their old weapon("+self+") to a new cored schematic.");
sui.removePid(player, PID_NAME);
sendSystemMessage(player, weapons.SID_CONVERT_CONVERT_SUCCESS);
destroyObject(self);
return SCRIPT_CONTINUE;
}
else
{
sendSystemMessage(player, weapons.SID_CONVERT_CONVERT_FAIL);
CustomerServiceLog("new_weapon_conversion", "Player "+getFirstName(player)+"("+player+") attempted to convert their old weapon("+self+") to a new cored schematic, and it failed.");
sui.removePid(player, PID_NAME);
return SCRIPT_CONTINUE;
}
}