Files
dsrc/sku.0/sys.server/compiled/game/script/library/jedi.scriptlib
T
2013-09-10 23:17:15 -07:00

3104 lines
90 KiB
Plaintext

include library.armor;
include library.factions;
include library.utils;
include library.skill;
include library.money;
include library.player_version;
include library.buff;
include library.combat;
include library.group;
include library.stealth;
const string JEDI_ACTIONS_FILE = "datatables/jedi/jedi_actions.iff";
const string JEDI_RANK_DATA = "datatables/jedi/jedi_rank_data.iff";
const string JEDI_CRYSTAL_COLOR_TABLE = "datatables/jedi/crystal_color_damage.iff";
const string TEMPLATE_FORCE_CRYSTAL = "object/tangible/component/weapon/lightsaber/lightsaber_module_force_crystal.iff";
const string TEMPLATE_KRAYT_DRAGON_PEARL = "object/tangible/component/weapon/lightsaber/lightsaber_module_krayt_dragon_pearl.iff";
const string JEDI_CLOAK_LIGHT_HOOD_UP = "item_jedi_robe_06_03";
const string JEDI_CLOAK_DARK_HOOD_UP = "item_jedi_robe_06_04";
const string JEDI_CLOAK_LIGHT_HOOD_DOWN = "item_jedi_robe_06_05";
const string JEDI_CLOAK_DARK_HOOD_DOWN = "item_jedi_robe_06_06";
const string JEDI_STANCE = "fs_buff_def_1_1";
const string JEDI_FOCUS = "fs_buff_ca_1";
const int JEDI_NEUTRAL = 0;
const int JEDI_LIGHT_SIDE = 1;
const int JEDI_DARK_SIDE = 2;
const int BOUNTY_VISIBILITY_THRESHHOLD = 2000; // visiblity of this value and you get bountied
const int NO_BOUNTY_VISIBLITY_THRESHOLD = 500; // drop below this and we clear your misison
const int JEDI_DEATH_DECAY_TIME = 7*24*60*60; // 1 week
const int BOUNTY_SPLOIT_INTERVAL = 60*24*3; // every 3 days
const int MAX_JEDI_DEATHS_PADAWAN = 3;
const int MAX_JEDI_DEATHS_KNIGHT = 4;
const int MAX_JEDI_DEATHS_MASTER = 5;
const int MAX_CRYSTAL_COUNT = 6;
const string VAR_JEDI_RESTART = "jedi_restart";
const string VAR_JEDI_DEATHS_OLD = "jedi.deaths";
const string VAR_JEDI_DEATHS = "jedi.deathCount";
const string VAR_JEDI_SKILL_LOSS = "jedi.skillLoss";
const string VAR_JEDI_LAST_DEATH = "jedi.lastDeath";
const string VAR_JEDI_SKILL = "jedi.skill_required";
const string VAR_SABER_BASE = "jedi.saber";
const string VAR_SABER_DEFAULT_STATS = VAR_SABER_BASE + ".base_stats";
const string VAR_CRYSTAL_BASE = "jedi.crystal";
const string VAR_CRYSTAL_STATS = VAR_CRYSTAL_BASE + ".stats";
const string VAR_CRYSTAL_OWNER = VAR_CRYSTAL_BASE + ".owner";
const string VAR_CRYSTAL_OWNER_ID = VAR_CRYSTAL_BASE + ".owner.id";
const string VAR_CRYSTAL_OWNER_NAME = VAR_CRYSTAL_BASE + ".owner.name";
const string VAR_MIN_DMG = "min_dmg";
const string VAR_MAX_DMG = "max_dmg";
const string VAR_SPEED = "speed";
const string VAR_WOUND = "wound";
const string VAR_ATTACK_COST = "attack_cost";
const string VAR_ACCURACY = "accuracy";
const string VAR_RADIUS = "damage";
const string VAR_FORCE = "force";
const string VAR_COLOR = "color";
const string VAR_LEVEL = "level";
const string VAR_HP = "hp";
const string VAR_HP_MAX = "hpMax";
const string VAR_ELEMENTAL_DAM_TYPE = "e_damage_type";
const string VAR_ELEMENTAL_DAM_AMNT = "e_damage_amount";
const string VAR_SHADER = "shader";
const string VAR_QUALITY = "quality";
const int CRYSTAL_POOR = 0;
const int CRYSTAL_FAIR = 1;
const int CRYSTAL_GOOD = 2;
const int CRYSTAL_QUALITY = 3;
const int CRYSTAL_SELECT = 4;
const int CRYSTAL_PREMIUM = 5;
const int CRYSTAL_FLAWLESS = 6;
const int MIN_CRYSTAL_TUNE_PLAYER_LEVEL = 20;
const int MIN_NON_FR_JEDI_BOUNTY = 25000;
const int PER_JEDI_SKILL_PT_COST = 1000; // every BOUNT_SPLOIT_INTERVAL the jedi is worth this much per jedi skill point spent
const int MIN_FR_JEDI_BOUNTY = 50000; // FRS Jedi of level 1+ are worth this much
const int PER_FORCE_RANK_COST = 100000; // 100k per rank in the FRS
const string_id SID_REGEN_TEMPORARILY_REDUCED = new string_id( "jedi_spam", "regen_temporarily_reduced");
const string_id SID_UNABLE_TO_RETURN_PEARLS_INVENTORY = new string_id( "jedi_spam", "unable_to_return_pearls_inventory");
const string_id SID_MAKE_SURE_INVENTORY_SPACE_AVAILABLE = new string_id( "jedi_spam", "make_sure_inventory_space_available");
const string_id SID_WILL_ATTEMPT_NEXT_TIME = new string_id( "jedi_spam", "will_attempt_next_time");
const string_id SID_ALL_PEARLS_RESTORED = new string_id( "jedi_spam", "all_pearls_restored");
const string_id SID_LOST_JEDI_XP = new string_id( "jedi_spam", "lost_jedi_xp");
// SHARED JEDI FUNCTIONS LIVE HERE
const string[] JEDI_ENEMY_FACTIONS = {factions.FACTION_IMPERIAL};
const string[] JEDI_NEUTRAL_FACTIONS = {factions.FACTION_NEUTRAL};
const float ENEMY_VISIBILITY_MULTIPLIER = 1.0f; // full value of action is registered if performed publicly;
const float NEUTRAL_VISIBILITY_MULTIPLIER = 0.5f; // partial value if performed publicly
int getJediActionVisibilityValue(obj_id objPlayer, int intActionVisibility, int intActionRange)
{
// this gets the "public" appearance value for this action
float fltActionRange = (float) intActionRange;
float fltBaseVisibility = (float)intActionVisibility;
float fltActualVisibility = 0;
obj_id[] objNPCs = getNPCsInRange(objPlayer, fltActionRange);
obj_id[] objPlayers = getPlayerCreaturesInRange(objPlayer, fltActionRange);
if((objNPCs!=null)&&(objNPCs.length>0))
{
//LOG("jedi", "npcs found was "+objNPCs.length);
for(int intI = 0; intI<objNPCs.length; intI++)
{
if(ai_lib.isNpc( objNPCs[intI])|| ai_lib.isAndroid(objNPCs[intI]))
{
string strFaction = factions.getFaction(objNPCs[intI]);
if(strFaction!=null)
{
int intIndex = utils.getElementPositionInArray(JEDI_ENEMY_FACTIONS, strFaction);
if(intIndex>-1)
{
float fltTempVisibility = fltBaseVisibility * ENEMY_VISIBILITY_MULTIPLIER;
// EEEVIL!;
if (fltTempVisibility > fltActualVisibility)
fltActualVisibility = fltTempVisibility;
}
else
{
float fltTempVisibility = fltBaseVisibility *NEUTRAL_VISIBILITY_MULTIPLIER;
// neutral
if (fltTempVisibility > fltActualVisibility)
fltActualVisibility = fltTempVisibility;
}
}
else
{
float fltTempVisibility = fltBaseVisibility * 0.25f;
if (fltTempVisibility > fltActualVisibility)
fltActualVisibility = fltTempVisibility;
}
}
}
}
else
{
//LOG("jedi", "No npc's");
}
if (objPlayers != null && objPlayers.length>0)
{
for(int intI = 0; intI<objPlayers.length; intI++)
{
if(
(!group.inSameGroup(objPlayer, objPlayers[intI])) &&
(objPlayers[intI]!=objPlayer) &&
(!isGod(objPlayers[intI]))
)
{
if(factions.pvpDoAllowedAttackCheck(objPlayer, objPlayers[intI]))
{
fltActualVisibility += (fltBaseVisibility * ENEMY_VISIBILITY_MULTIPLIER);
// EEEVIL!;
}
else if (factions.isNeutral(objPlayers[intI]))
{
fltActualVisibility += (fltBaseVisibility * NEUTRAL_VISIBILITY_MULTIPLIER);
// neutral
}
else
{
fltActualVisibility += (fltBaseVisibility * 0.25f);
}
}
}
}
else
{
//LOG("jedi", "No players");
}
int intActualVisibility = (int)fltActualVisibility;
//LOG("jedi", "returning "+intActualVisibility);
return intActualVisibility;
}
void jediActionPerformed(obj_id objPlayer, int intActionVisibility, int intActionRadius) // increments objvars, handles a bunch of other notifiactaions
{
//if (!isPlayer (objPlayer)) // UNCOMMENT THIS TO RE-ENABLE THE JEDI VISIBILITY STUFF -- RcT - 10/11/05
return;
/*
int intRealVisibility = getJediActionVisibilityValue(objPlayer, intActionVisibility, intActionRadius);
int intNewVisibility = getJediVisibility(objPlayer);
intNewVisibility = intNewVisibility + intRealVisibility;
if (hasObjVar(objPlayer, "jedi.intVisibilityTime"))
{
int intTime = getGameTime();
int intOldTime = 0;
if (!utils.checkConfigFlag("ScriptFlags","noJediVisibilityDelay"))
intOldTime = getIntObjVar(objPlayer, "jedi.intVisibilityTime");
int intDifference = intTime - intOldTime;
if (intDifference > 0)
{
// timestamp goes away
int intOldVisibility = getIntObjVar(objPlayer, "jedi.intOldVisibility");
removeObjVar(objPlayer, "jedi.intVisibilityTime");
removeObjVar(objPlayer, "jedi.intOldVisibility");
intNewVisibility += intOldVisibility;
}
else
{
int intOldVisibility = getIntObjVar(objPlayer, "jedi.intOldVisibility");
intOldVisibility = intOldVisibility + intNewVisibility;
setObjVar(objPlayer, "jedi.intOldVisibility", intOldVisibility); // we stre the visibility increase
return;
}
}
// make sure the Jedi's visibility doesn't go above the cap
String capString = getConfigSetting("GameServer", "jediVisibilityCap");
if ( capString != null )
{
int visibilityCap = Integer.parseInt(capString);
if ( visibilityCap > 0 )
{
if ( intNewVisibility > visibilityCap )
{
CustomerServiceLog("Jedi", "Capping Jedi player %TU visibility from " + intNewVisibility +
" to " + visibilityCap + " for Jedi action", objPlayer);
intNewVisibility = visibilityCap;
}
}
else
CustomerServiceLog("Jedi", "WARNING: config setting [GameServer] jediVisibilityCap <= 0");
}
else
CustomerServiceLog("Jedi", "WARNING: config setting [GameServer] jediVisibilityCap does not exist");
setJediVisibility(objPlayer, intNewVisibility);
*/
}
void setJediVisibilityTimeStamp(obj_id self)
{
const int JEDI_BOUNTY_TIMER = 60*60*24*7; // 1 week until you get misions.
int intTimeStamp = getGameTime();
intTimeStamp = intTimeStamp + JEDI_BOUNTY_TIMER;
setObjVar(self, "jedi.intVisibilityTime", intTimeStamp);
}
void checkJediPenalties(obj_id objPlayer, int intVisiblity)
{
if(intVisiblity<NO_BOUNTY_VISIBLITY_THRESHOLD)
{
// ALL MISSIONS INCOMPLETE! WOOH
clearJediBounties(objPlayer);
}
return; // nothing going on right now.
}
void doJediTEF(obj_id objPlayer)
{
string strTest = factions.getFaction(objPlayer);
if(strTest==null)
{
return;
}
string strImperial = factions.FACTION_IMPERIAL;
string strRebel = factions.FACTION_REBEL;
if(strTest==strRebel)
{
pvpSetFactionEnemyFlag(objPlayer, ##"imperial"); // imperials are full of hate now
}
else if(strTest==strImperial)
{
pvpSetFactionEnemyFlag(objPlayer, ##"rebel"); // rebels are full of hate now
}
else
{
pvpSetFactionEnemyFlag(objPlayer, ##"imperial"); // imperials are full of hate now
}
}
void clearJediBounties(obj_id objPlayer)
{
obj_id[] hunters = getJediBounties(objPlayer);
if ( hunters != null )
{
dictionary params = new dictionary();
params.put("target", objPlayer);
for (int i = 0; i < hunters.length; i++)
{
if ( isIdValid(hunters[i]) )
{
messageTo(hunters[i], "bountyIncomplete", params, 1.0f, true);
}
}
removeAllJediBounties(objPlayer);
}
}
boolean hasForcePower(obj_id objPlayer, int intForcePowerCost)
{
int intCurrentPower = getForcePower(objPlayer);
if ((intCurrentPower - intForcePowerCost > 0)||(!isPlayer(objPlayer)))
{
return true;
}
else
{
string_id strSpam = new string_id("jedi_spam", "no_force_power");
sendSystemMessage(objPlayer, strSpam);
return false;
}
}
boolean drainForcePower(obj_id objPlayer, int intForcePowerCost)
{
return drainForcePower(objPlayer, intForcePowerCost, true);
}
boolean drainForcePower(obj_id objPlayer, int intForcePowerCost, boolean verbose)
{
if(utils.checkConfigFlag("ScriptFlags","e3Demo"))
{
intForcePowerCost = 0;
}
int intCurrentPower = getForcePower(objPlayer);
if (intCurrentPower - intForcePowerCost >= 0)
{
int intActualCost = -1 * intForcePowerCost;
alterForcePower(objPlayer, intActualCost);
return true;
}
else
{
if (verbose)
{
string_id strSpam = new string_id("jedi_spam", "no_force_power");
sendSystemMessage(objPlayer, strSpam);
}
return false;
}
}
void grantJediXP(obj_id objPlayer, int intForcePowerCost)
{
location locTest =getLocation(objPlayer);
obj_id objBuilding = getTopMostContainer(objPlayer);
if(isIdValid(objBuilding))
{
if(hasScript(objBuilding, "structure.permanent_structure"))
{
return; // inside a player structure, no xp for you
}
}
// Disabled xp grants for saber and power usage. All jedi xp must now come from kills.
//xp.grant(objPlayer, xp.JEDI_GENERAL, intForcePowerCost);
}
void doJediNonCombatAnimation(obj_id objPlayer, obj_id objTarget, dictionary dctJediInfo)
{
if(objTarget!=null)
{
// targeted animation
}
else
{
// non targeted animation ??
}
}
boolean isJediTrainerForPlayer(obj_id objPlayer, obj_id objNPC)
{
if(!isJedi(objPlayer))
{
return false;
}
location locTrainerLocation = getLocationObjVar(objPlayer, "jedi.locTrainerLocation");
if(locTrainerLocation==null)
{
return false;
}
location locNPCLocation = getWorldLocation(objNPC);
locNPCLocation.y = 0;
locTrainerLocation.y = 0;
float fltDistance = getDistance(locTrainerLocation, locNPCLocation);
if (fltDistance != -1 && fltDistance < 3)
{
return true;
}
return false;
}
boolean isLightsaber(obj_id objWeapon)
{
return isLightsaber(getWeaponType(objWeapon));
}
boolean isLightsaber(int intWeaponType)
{
switch(intWeaponType)
{
case WEAPON_TYPE_WT_1HAND_LIGHTSABER: return true;
case WEAPON_TYPE_WT_2HAND_LIGHTSABER: return true;
case WEAPON_TYPE_WT_POLEARM_LIGHTSABER: return true;
}
return false;
}
int getJediAlignment(obj_id objJedi)
{
return getSkillStatisticModifier(objJedi, "private_jedi_alignment");
}
float getJediAlignmentModifier(obj_id objPlayer, dictionary dctJediInfo)
{
//////////////////////////////////////////////////////////////////////////////////////////
// Rewrite this to use new Jadi Rank System
//////////////////////////////////////////////////////////////////////////////////////////
// int intAlignment = getJediAlignment(objPlayer);
// if(intAlignment==JEDI_NEUTRAL)
// {
// return 1.0f;
// }
// if(intAlignment==JEDI_LIGHT_SIDE)
// {
// return dctJediInfo.getFloat("fltLightSide");
// }
// else if(intAlignment==JEDI_DARK_SIDE)
// {
// return dctJediInfo.getFloat("fltDarkSide");
// }
return 1.0f; // fucked up alignment.. it's not 1, it's not 0, and it's not 2. So it's something other than thsoe
}
int modifyForcePower(obj_id objPlayer, int intForcePowerToDrain, dictionary dctJediInfo)
{
//////////////////////////////////////////////////////////////////////////////////////////
// Rewrite this to use new Jadi Rank System
//////////////////////////////////////////////////////////////////////////////////////////
float fltAlignmentModifier = getJediAlignmentModifier(objPlayer, dctJediInfo);
// modify the force cost, and the damage of the move.
float fltForcePower = (float)intForcePowerToDrain;
fltForcePower = fltForcePower - (fltForcePower * (1.0f - fltAlignmentModifier));
intForcePowerToDrain = (int)fltForcePower;
return intForcePowerToDrain;
}
float getJediActionTime(obj_id player, dictionary actionData)
{
float timeDelay = actionData.getFloat("baseTimeMod");
int rankMod = getEnhancedSkillStatisticModifier(player, "dark_jedi_power");
if (rankMod > 0)
{
timeDelay += rankMod * actionData.getFloat("darkTimeBonus");
}
else
{
rankMod = getEnhancedSkillStatisticModifier(player, "light_jedi_power");
if (rankMod > 0)
timeDelay += rankMod * actionData.getFloat("lightTimeBonus");
}
return timeDelay;
}
float getJediDamageModifier(obj_id player, dictionary actionData)
{
float damageMod = actionData.getFloat("baseDamageMod");
int rankMod = getEnhancedSkillStatisticModifier(player, "dark_jedi_power");
if (rankMod > 0)
{
damageMod += rankMod * actionData.getFloat("darkDamageMod");
}
else
{
rankMod = getEnhancedSkillStatisticModifier(player, "light_jedi_power");
if (rankMod > 0)
damageMod += rankMod * actionData.getFloat("lightDamageMod");
}
return damageMod;
}
void recalculateForcePower(obj_id player)
{
int maxPower = getSkillStatisticModifier(player, "jedi_force_power_max");
//get base force regen skill
int baseRegenRate = getSkillStatisticModifier(player, "jedi_force_power_regen");
//get modified force regen skill
int modRegenRate = (getEnhancedSkillStatisticModifier(player, "jedi_force_power_regen") - baseRegenRate);
//cap skill tapes at 15 for Jedi regen, very dangerous skill mod, capping it here
if (modRegenRate > 15)
modRegenRate = 15;
baseRegenRate = baseRegenRate + modRegenRate;
float regenRate = (float)baseRegenRate;
regenRate = regenRate / 10f;
// Add Force Rank Bonus
if (hasSkill(player, "force_rank_light_novice"))
{
int force_power = getSkillStatisticModifier(player, "force_power_light");
int force_control = getSkillStatisticModifier(player, "force_control_light");
int force_manipulation = getSkillStatisticModifier(player, "force_manipulation_light");
maxPower += (force_power + force_control) * 10;
regenRate += (force_control + force_manipulation) / 100f;
}
else if (hasSkill(player, "force_rank_dark_novice"))
{
int force_power = getSkillStatisticModifier(player, "force_power_dark");
int force_control = getSkillStatisticModifier(player, "force_control_dark");
int force_manipulation = getSkillStatisticModifier(player, "force_manipulation_dark");
maxPower += (force_power + force_control) * 10;
regenRate += (force_control + force_manipulation) / 100f;
}
// Apply Force Meditate bonus
int meditateRate = 1;
if (hasObjVar(player, "jedi.meditate"))
meditateRate = getIntObjVar(player, "jedi.meditate");
regenRate *= meditateRate;
// Get regen penalty from regainConciousness
int regenPenalty = utils.getIntScriptVar(player, "jedi.regenPenalty");
if (regenPenalty < 1) regenPenalty = 1;
regenRate /= (float)regenPenalty;
// Set power & regen rate
setMaxForcePower(player, maxPower);
setForcePowerRegenRate(player, regenRate);
return;
}
boolean postponeGrantJedi()
{
string enabled = toLower(getConfigSetting("GameServer", "postponeJediGrant"));
if (enabled == null)
return false;
if (enabled.equals("true") || enabled.equals("1"))
return true;
return false;
}
/////////////////////////////////////////////////
// Jedi Non-Combat Abilities
/////////////////////////////////////////////////
boolean doNonCombatActionPrecheck(obj_id player, obj_id target, dictionary actionData)
{
int forceCost = actionData.getInt("intJediPowerCost");
float range = actionData.getFloat("fltRange");
float actionTime = actionData.getInt("fltActionTime");
if (isIdValid(player) && isIdValid(target) && exists(target))
{
if (player != target)
{
float dist = getDistance(target, player);
if (dist > range)
{
// system message
//LOG("jedi", "Distance is "+dist+" and range is "+range);
sendSystemMessage(player, new string_id("cbt_spam", "out_of_range_single"));
return false;
}
}
}
else
{
return false;
}
forceCost = jedi.getModifiedForceCost(player, forceCost, actionData.getString("actionName")); // modifies force power cost based on light/darkside
actionData.put("intJediPowerCost", forceCost);
if(!jedi.hasForcePower(player, forceCost))
{
return false;
}
return true;
}
obj_id getCorrectFriendlyTarget(obj_id player, obj_id target, dictionary actionData)
{
float range = actionData.getFloat("fltRange");
if (range < 0)
{
//LOG("jedi", "returning "+player);
return player; // -1 or more means target the player
}
obj_id newTarget = null;
if (!isIdValid(target))
{
newTarget = player;
}
else
{
if(!factions.pvpDoAllowedHelpCheck(player, target))
{
newTarget = getLookAtTarget(player);
}
else
{
newTarget = target;
}
}
// PvP enemies & dead people are not valid targets
if (!factions.pvpDoAllowedHelpCheck(player, newTarget) || isDead(newTarget))
{
sendSystemMessage(player, new string_id("jedi_spam", "no_help_target"));
return null;
}
// Cannot help a target who is in a Dark Jedi duel
if (player != newTarget && (isIdValid(newTarget) && utils.hasScriptVar(newTarget, "noBeneficialJediHelp")))
{
sendSystemMessage(player, new string_id("jedi_spam", "no_help_target"));
return null;
}
// Check LOS
if (newTarget != player && !canSee(player, newTarget))
{
showFlyTextPrivate(player, player, new string_id("combat_effects", "cant_see"), 1.5f, colors.MEDIUMTURQUOISE);
return null;
}
return newTarget;
}
void playJediActionEffect(obj_id objPlayer, obj_id objTarget, dictionary actionData)
{
playJediActionEffect(objPlayer, objTarget, actionData, false);
}
void playJediActionEffect(obj_id objPlayer, obj_id objTarget, dictionary actionData, boolean labelEffect)
{
string combatAnim = actionData.getString("combatActionAnimation");
string selfAnim = actionData.getString("selfActionAnimation");
string clientEffect = actionData.getString("clientEffectFile");
if(objTarget==objPlayer)
{
if (selfAnim != null && selfAnim != "")
doAnimationAction(objPlayer, selfAnim);
if (clientEffect != null && clientEffect != "")
{
if (labelEffect)
playClientEffectObj(objPlayer, clientEffect, objPlayer, "", null, actionData.getString("actionName"));
else
playClientEffectObj(objPlayer, clientEffect, objPlayer, "");
}
return;
}
else
{
if (combatAnim != null && combatAnim != "")
{
defender_results[] cbtDefenderResults = new defender_results[1];
cbtDefenderResults[0] = new defender_results(); // data struct newing
attacker_results cbtAttackerResults = new attacker_results();
cbtDefenderResults[0].id = objTarget;
cbtDefenderResults[0].endPosture = getPosture(objTarget);
cbtDefenderResults[0].result = COMBAT_RESULT_HIT;
cbtAttackerResults.id = objPlayer;
cbtAttackerResults.weapon = null;
doCombatResults(combatAnim, cbtAttackerResults, cbtDefenderResults);
}
if (clientEffect != null && clientEffect != "")
{
dictionary dctParams = new dictionary();
dctParams.put("strEffect", clientEffect);
dctParams.put("objTarget", objTarget);
dctParams.put("labelEffect", labelEffect);
//LOG("jedi", "sendiig message to "+objTarget);
messageTo(objTarget, "playDelayedClientEffect", dctParams, 8f, false);
}
}
return;
}
boolean performJediBuffCommand(obj_id player, obj_id target, dictionary actionData)
{
string actionName = actionData.getString("actionName");
string buffName = actionData.getString("buffName");
LOG("jedi", "performJediBuffCommand::buff name ("+buffName+")");
if (!buffName.startsWith("avoidIncap"))
{
if (actionData.getInt("toggleBuff") == 1)
{
// Check for another buff of the same group
if(buff.hasBuff(target, buffName))
{
buff.removeBuff(target, buffName);
sendSystemMessage(player, new string_id("jedi_spam", "remove_"+actionName));
return false;
}
}
if (!buff.canApplyBuff(target, buffName))
{
LOG("jedi", "1:performJediBuffCommand::buff already present - aborting");
sendSystemMessage(player, new string_id("jedi_spam", "force_buff_present"));
return false;
}
}
else // determine new buff name so player can stack avoid incap
{
const int MAX_STACK = 5;
string newBuffName = "";
for (int i = 1; i < MAX_STACK+1; i++)
{
newBuffName = buffName + "_" + i;
if (!buff.hasBuff(target, newBuffName))
{
// found empty buffName slot
buffName = newBuffName;
break;
}
else
{
if (i == MAX_STACK)
{
// Max number of buffs already on
LOG("jedi", "2:performJediBuffCommand::buff already present - aborting");
sendSystemMessage(player, new string_id("jedi_spam", "force_buff_present"));
return false;
}
}
}
}
// Check for healing buff
int minHeal = actionData.getInt("intMinHealthHeal");
int maxHeal = actionData.getInt("intMaxHealthHeal");
int duration = (int)actionData.getFloat("buffDuration");
if (minHeal > 0 && maxHeal > 0 && buff.hasBuff(target, buffName))
{
sendSystemMessage(player, new string_id("jedi_spam", "force_buff_present"));
return false;
}
// Apply the buff
if (buff.applyBuff(target, buffName))
{
if (minHeal > 0 && maxHeal > 0)
{
healing.startHealOverTime(target, duration, 4, rand(minHeal, maxHeal));
}
sendSystemMessage(player, new string_id("jedi_spam", "apply_"+actionName));
playJediActionEffect(player, target, actionData, true);
if(!buffName.equals("invis_forceCloak"))
{
stealth.testInvisNonCombatAction(player, target);
}
}
return true;
}
boolean doBuffAction(obj_id self, obj_id target, string actionName)
{
// Make sure we are not wearing armor
int armorCount = utils.getIntScriptVar(self, armor.SCRIPTVAR_ARMOR_COUNT);
if (armorCount > 0)
{
sendSystemMessage(self, new string_id("jedi_spam", "not_with_armor"));
return false;
}
//make sure we are not mezzed
if(buff.isParalyzed(self))
{
return false;
}
actionName = combat.getBestAction(self, actionName);
dictionary actionData = dataTableGetRow(JEDI_ACTIONS_FILE, actionName);
if (actionData == null)
{
LOG("DESIGNER_FATAL","Buff Action "+actionName+" has no entry in the jedi actions datatable");
return false;
}
target = getCorrectFriendlyTarget(self, target, actionData);
if (!isIdValid(target))
return false;
if (!doNonCombatActionPrecheck(self, target, actionData))
return false;
int forceCost = actionData.getInt("intJediPowerCost");
if(!jedi.hasForcePower(self, forceCost))
return false;
// Load the weapon data
weapon_data weaponData = new weapon_data();
weaponData = getWeaponData(getCurrentWeapon(self));
int[] actionCost = combat.getActionCost(self, weaponData, actionData);
if(!combat.canDrainCombatActionAttributes(self, actionCost))
return false;
// Perform buff action
if(performJediBuffCommand(self, target, actionData))
{
jedi.drainForcePower(self, forceCost);
combat.drainCombatActionAttributes(self, actionCost);
// Increment visilbility
int visValue = actionData.getInt("intVisibilityValue");
int visRange = actionData.getInt("intVisibilityRange");
jedi.jediActionPerformed(self, visValue, visRange);
// Grant Jedi XP
int xpOverride = actionData.getInt("xpOverride");
if (xpOverride < 0)
xpOverride = forceCost;
jedi.grantJediXP(self, xpOverride);
}
else
{
return false;
}
return true;
}
boolean doForceRun(obj_id self, obj_id target, string actionName)
{
// Make sure we are not wearing armor
int armorCount = utils.getIntScriptVar(self, armor.SCRIPTVAR_ARMOR_COUNT);
if (armorCount > 0)
{
sendSystemMessage(self, new string_id("jedi_spam", "not_with_armor"));
return false;
}
actionName = combat.getBestAction(self, actionName);
dictionary actionData = dataTableGetRow(JEDI_ACTIONS_FILE, actionName);
if (actionData == null)
{
LOG("DESIGNER_FATAL","Action "+actionName+" has no entry in the jedi actions datatable");
return false;
}
target = getCorrectFriendlyTarget(self, target, actionData);
if (!isIdValid(target))
return false;
if (!doNonCombatActionPrecheck(self, target, actionData))
return false;
int forceCost = actionData.getInt("intJediPowerCost");
if(!jedi.hasForcePower(self, forceCost))
return false;
// Load the weapon data
weapon_data weaponData = new weapon_data();
weaponData = getWeaponData(getCurrentWeapon(self));
int[] actionCost = combat.getActionCost(self, weaponData, actionData);
if(!combat.canDrainCombatActionAttributes(self, actionCost))
return false;
string buffName = actionData.getString("buffName");
if(!buff.canApplyBuff(self, buffName))
{
sendSystemMessage(self, new string_id("jedi_spam", "force_run_wont_stack"));
return false;
}
// Perform buff action
if(doBuffAction(self, target, actionName))
{
combat.drainCombatActionAttributes(self, actionCost);
jedi.drainForcePower(self, forceCost);
messageTo(self, "handleForceRunCost", null, 10, true);
}
else
{
return false;
}
return true;
}
boolean regainConsciousness(obj_id self, obj_id target, string actionName)
{
actionName = combat.getBestAction(self, actionName);
dictionary actionData = dataTableGetRow(JEDI_ACTIONS_FILE, actionName);
if (actionData == null)
{
LOG("DESIGNER_FATAL","Action "+actionName+" has no entry in the jedi actions datatable");
return false;
}
target = self;
if (!isIdValid(target))
return false;
if (!doNonCombatActionPrecheck(self, target, actionData))
return false;
int forceCost = actionData.getInt("intJediPowerCost");
if(!jedi.drainForcePower(self, forceCost))
return false;
pclib.clearEffectsForDeath(self);
// Heal enough to recap
setAttrib(self, HEALTH, 200);
int regenPenalty = utils.getIntScriptVar(self, "jedi.regenPenalty");
if (regenPenalty < 1) regenPenalty = 1;
regenPenalty *= 2;
utils.setScriptVar(self, "jedi.regenPenalty", regenPenalty);
recalculateForcePower(self);
messageTo(self, "clearRegenPenalty", null, 30*60, false);
messageTo(self, "handlePlayerResuscitated", null, 0, true);
sendSystemMessage(self, SID_REGEN_TEMPORARILY_REDUCED);
// Increment visilbility
int visValue = actionData.getInt("intVisibilityValue");
int visRange = actionData.getInt("intVisibilityRange");
jedi.jediActionPerformed(self, visValue, visRange);
playJediActionEffect(self, target, actionData);
// Grant Jedi XP
int xpOverride = actionData.getInt("xpOverride");
if (xpOverride < 0)
xpOverride = forceCost;
jedi.grantJediXP(self, xpOverride);
// Jedi General XP penalty pre CU
//jediDeathExperienceLoss(self, 0.25f);
return true;
}
boolean transferForce(obj_id self, obj_id target, string actionName)
{
// Make sure we are not wearing armor
int armorCount = utils.getIntScriptVar(self, armor.SCRIPTVAR_ARMOR_COUNT);
if (armorCount > 0)
{
sendSystemMessage(self, new string_id("jedi_spam", "not_with_armor"));
return false;
}
//make sure we are not mezzed
if(buff.isParalyzed(self))
{
return false;
}
actionName = combat.getBestAction(self, actionName);
dictionary actionData = dataTableGetRow(JEDI_ACTIONS_FILE, actionName);
if (actionData == null)
return false;
target = getCorrectFriendlyTarget(self, target, actionData);
if (!isIdValid(target))
{
sendSystemMessage(self, new string_id("jedi_spam", "not_this_target"));
return false;
}
if (target == self || !isPlayer(target) || !isJedi(target))
{
sendSystemMessage(self, new string_id("jedi_spam", "not_this_target"));
return false;
}
if (!doNonCombatActionPrecheck(self, target, actionData))
return false;
int forceCost = actionData.getInt("intJediPowerCost");
if(!jedi.drainForcePower(self, forceCost))
return false;
// Load the weapon data
weapon_data weaponData = new weapon_data();
weaponData = getWeaponData(getCurrentWeapon(self));
int[] actionCost = combat.getActionCost(self, weaponData, actionData);
if(!combat.canDrainCombatActionAttributes(self, actionCost))
return false;
// Transfer Force Power
//int targetPower = getForcePower(target);
int targetPower = rand(actionData.getInt("minForceHeal"), actionData.getInt("maxForceHeal"));
alterForcePower(target, targetPower);
combat.drainCombatActionAttributes(self, actionCost);
// Send combat spam
prose_package pp = new prose_package();
pp.stringId = new string_id("cbt_spam", "forcetransfer_hit");
pp.actor.set(self);
pp.target.set(target);
pp.digitInteger = targetPower;
combat.sendCombatSpamMessageProse(self, target, pp, true, true, false);
// Increment visilbility
int visValue = actionData.getInt("intVisibilityValue");
int visRange = actionData.getInt("intVisibilityRange");
jedi.jediActionPerformed(self, visValue, visRange);
// Add Hate
healing._addMedicalHate(self, target, targetPower);
playJediActionEffect(self, target, actionData);
// Grant Jedi XP
int xpOverride = actionData.getInt("xpOverride");
if (xpOverride < 0)
xpOverride = forceCost;
jedi.grantJediXP(self, xpOverride);
return true;
}
boolean channelForce(obj_id self, obj_id target, string actionName)
{
// Make sure we are not wearing armor
int armorCount = utils.getIntScriptVar(self, armor.SCRIPTVAR_ARMOR_COUNT);
if (armorCount > 0)
{
sendSystemMessage(self, new string_id("jedi_spam", "not_with_armor"));
return false;
}
//make sure we are not mezzed
if(buff.isParalyzed(self))
{
return false;
}
actionName = combat.getBestAction(self, actionName);
dictionary actionData = dataTableGetRow(JEDI_ACTIONS_FILE, actionName);
if (actionData == null)
return false;
target = getCorrectFriendlyTarget(self, target, actionData);
if (!isIdValid(target))
return false;
if (!doNonCombatActionPrecheck(self, target, actionData))
return false;
// Read HAM cost & validate
int minHealth = actionData.getInt("intMinHealthHeal");
int maxHealth = actionData.getInt("intMaxHealthHeal");
int minAction = (int)(getMaxAttrib(self, ACTION) * (actionData.getInt("intMinActionHeal") / 100f));
int maxAction = (int)(getMaxAttrib(self, ACTION) * (actionData.getInt("intMaxActionHeal") / 100f));
attribute[] curAttribs = getAttribs(self);
if (curAttribs[HEALTH].getValue() < maxHealth ||
!combat.canDrainCombatActionAttributes(self, new int[] {0, maxAction, 0}))
{
sendSystemMessage(self, new string_id("jedi_spam", "channel_ham_too_low"));
return false;
}
int forceCost = actionData.getInt("intJediPowerCost");
if(!jedi.drainForcePower(self, forceCost))
return false;
// Channel Force Power
//int newPower = getForcePower(self);
int newPower = rand(actionData.getInt("minForceHeal"), actionData.getInt("maxForceHeal"));
alterForcePower(self, newPower);
// Add HAM attrib mod
float duration = actionData.getFloat("buffDuration") * 60;
addAttribModifier(self, HEALTH, (rand(minHealth, maxHealth) * -1), 0, 0, duration);
combat.drainCombatActionAttributes(self, new int[] {0, rand(minAction, maxAction), 0});
// Increment visilbility
int visValue = actionData.getInt("intVisibilityValue");
int visRange = actionData.getInt("intVisibilityRange");
jedi.jediActionPerformed(self, visValue, visRange);
playJediActionEffect(self, target, actionData);
// Grant Jedi XP
int xpOverride = actionData.getInt("xpOverride");
if (xpOverride < 0)
xpOverride = forceCost;
jedi.grantJediXP(self, xpOverride);
return true;
}
boolean forceMeditate(obj_id self, string actionName)
{
// Make sure we are not wearing armor
int armorCount = utils.getIntScriptVar(self, armor.SCRIPTVAR_ARMOR_COUNT);
if (armorCount > 0)
{
sendSystemMessage(self, new string_id("jedi_spam", "not_with_armor"));
return false;
}
//make sure we are not mezzed
if(buff.isParalyzed(self))
{
return false;
}
actionName = combat.getBestAction(self, actionName);
dictionary actionData = dataTableGetRow(JEDI_ACTIONS_FILE, actionName);
if (actionData == null)
return false;
if (!doNonCombatActionPrecheck(self, self, actionData))
return false;
int forceCost = actionData.getInt("intJediPowerCost");
if(!jedi.drainForcePower(self, forceCost))
return false;
// Load the weapon data
weapon_data weaponData = new weapon_data();
weaponData = getWeaponData(getCurrentWeapon(self));
int[] actionCost = combat.getActionCost(self, weaponData, actionData);
if(!combat.canDrainCombatActionAttributes(self, actionCost))
return false;
//make sure we aren't in TKA Meditate
if (getState(self,STATE_MEDITATE) == 1)
{
sendSystemMessage(self, new string_id("jedi_spam", "already_in_meditative_state"));
return false;
}
// Start Force Meditate
setState(self, STATE_MEDITATE, true);
chat.setTempAnimationMood(self, "meditating");
buff.applyBuff(self, "forceMeditate");
combat.drainCombatActionAttributes(self, actionCost);
int meditateRate = actionData.getInt("maxForceHeal");
setObjVar(self, "jedi.meditate", meditateRate);
recalculateForcePower(self);
// Increment visilbility
int visValue = actionData.getInt("intVisibilityValue");
int visRange = actionData.getInt("intVisibilityRange");
jedi.jediActionPerformed(self, visValue, visRange);
playJediActionEffect(self, self, actionData);
messageTo(self, "forceMeditateEffect", null, 5, false);
// Grant Jedi XP
int xpOverride = actionData.getInt("xpOverride");
if (xpOverride < 0)
xpOverride = forceCost;
jedi.grantJediXP(self, xpOverride);
return true;
}
void stopForceMeditate(obj_id self)
{
if (getState(self, STATE_MEDITATE) == 1)
{
setState(self, STATE_MEDITATE, false);
chat.resetTempAnimationMood(self);
}
stopClientEffectObjByLabel(self, "forceMeditate");
removeObjVar(self, "jedi.meditate");
buff.removeBuff(self, "forceMeditate");
recalculateForcePower(self);
}
void applyFeedbackDamage(obj_id player, obj_id target, float damage)
{
// Apply Force Shield
damage *= 1.0f -(combat.convertProtectionToPercent(jedi.applyForceShield(target, (int)damage)));
// Apply Force Defenses
int defense = getEnhancedSkillStatisticModifier(target, "force_defense");
if (defense > 0)
damage = damage * (1f / (1f + (defense / 100f)));
if (damage < 1)
return;
addAttribModifier(target, HEALTH, (int)damage * -1, 0f, 0f, MOD_POOL);
prose_package pp = new prose_package();
pp.stringId = new string_id("cbt_spam", "forcefeedback_hit");
pp.actor.set(player);
pp.target.set(target);
pp.digitInteger = (int)damage;
combat.sendCombatSpamMessageProse(player, target, pp, true, true, true, COMBAT_RESULT_HIT);
}
int applyForceShield(obj_id defender, int damage)
{
// Make sure we are not wearing armor
int armorCount = utils.getIntScriptVar(defender, armor.SCRIPTVAR_ARMOR_COUNT);
if (armorCount > 0)
return 0;
dictionary actionData = null;
if (buff.hasBuff(defender, "forceShield"))
actionData = dataTableGetRow(JEDI_ACTIONS_FILE, "forceShield");
else if (buff.hasBuff(defender, "forceShield_1"))
actionData = dataTableGetRow(JEDI_ACTIONS_FILE, "forceShield_1");
else if (buff.hasBuff(defender, "forceProtection"))
actionData = dataTableGetRow(JEDI_ACTIONS_FILE, "forceProtection");
float forceShield = 0;
if (actionData != null)
{
forceShield = getEnhancedSkillStatisticModifier(defender, "force_shield") * 100f;
int forceCost = (int)(damage * getModifiedExtraForceCost(defender, actionData.getFloat("extraForceCost"), actionData.getString("actionName")));
if (!jedi.drainForcePower(defender, forceCost)) // not enough power
{
buff.removeBuff(defender, actionData.getString("actionName"));
}
else
{
// prose_package pp = new prose_package();
// pp.stringId = new string_id("cbt_spam", "forceshield_hit");
// pp.actor.set(defender);
//pp.digitInteger = protection;
// combat.sendCombatSpamMessageProse(defender, pp, COMBAT_RESULT_HIT);
playClientEffectObj(defender, "clienteffect/pl_force_shield_hit.cef", defender, "");
}
}
return (int)forceShield;
}
int applyForceArmor(obj_id defender, int damage)
{
// Make sure we are not wearing armor
int armorCount = utils.getIntScriptVar(defender, armor.SCRIPTVAR_ARMOR_COUNT);
if (armorCount > 0)
return 0;
dictionary actionData = null;
if (buff.hasBuff(defender, "forceArmor"))
actionData = dataTableGetRow(JEDI_ACTIONS_FILE, "forceArmor");
else if (buff.hasBuff(defender, "forceArmor_1"))
actionData = dataTableGetRow(JEDI_ACTIONS_FILE, "forceArmor_1");
else if (buff.hasBuff(defender, "forceProtection"))
actionData = dataTableGetRow(JEDI_ACTIONS_FILE, "forceProtection");
float forceArmor = 0;
if (actionData != null)
{
forceArmor = getEnhancedSkillStatisticModifier(defender, "force_armor") * 100f;
//sendSystemMessageTestingOnly(defender, "forcearmor is = " +forceArmor);
int forceCost = (int)(damage * getModifiedExtraForceCost(defender, actionData.getFloat("extraForceCost"), actionData.getString("actionName")));
if (!jedi.drainForcePower(defender, forceCost)) // not enough power
{
buff.removeBuff(defender, actionData.getString("actionName"));
}
else
{
// prose_package pp = new prose_package();
// pp.stringId = new string_id("cbt_spam", "forcearmor_hit");
// pp.actor.set(defender);
//pp.digitInteger = protection;
// combat.sendCombatSpamMessageProse(defender, pp, COMBAT_RESULT_HIT);
playClientEffectObj(defender, "clienteffect/pl_force_armor_hit.cef", defender, "");
}
}
return (int)forceArmor;
}
void performJediReactiveDefense(obj_id attacker, obj_id defender, weapon_data weaponData, hit_result hitData, dictionary actionData)
{
// Check for Force Absorb on target
if (weaponData.weaponType == combat.WEAPON_TYPE_FORCE_POWER && getEnhancedSkillStatisticModifier(defender, "force_absorb") > 0)
{
float forceAbsorb = 0f;
if (buff.hasBuff(defender, "forceAbsorb"))
{
forceAbsorb = getModifiedExtraForceCost(defender, dataTableGetFloat(JEDI_ACTIONS_FILE, "forceAbsorb", "extraForceCost"), "forceAbsorb");
}
else
{
forceAbsorb = getModifiedExtraForceCost(defender, dataTableGetFloat(JEDI_ACTIONS_FILE, "forceAbsorb_1", "extraForceCost"), "forceAbsorb_1");
}
int forceCost = combat.getForceCost(attacker, weaponData, actionData);
forceAbsorb *= forceCost;
alterForcePower(defender, (int)forceAbsorb);
prose_package pp = new prose_package();
pp.stringId = new string_id("cbt_spam", "forceabsorb_hit");
pp.actor.set(defender);
pp.digitInteger = (int)forceAbsorb;
combat.sendCombatSpamMessageProse(defender, pp, COMBAT_RESULT_HIT);
// Play anim
dictionary data = new dictionary();
data.put("effect", "clienteffect/pl_force_absorb_hit.cef");
data.put("target", defender);
messageTo(attacker, "playDelayedClientEffect", data, 1, false);
}
// Check for Force Feedback on target
if (weaponData.weaponType == combat.WEAPON_TYPE_FORCE_POWER && getEnhancedSkillStatisticModifier(defender, "force_feedback") > 0)
{
float forceFeedback = getEnhancedSkillStatisticModifier(defender, "force_feedback") / 100f;
float feedbackDamage = forceFeedback * hitData.damage;
jedi.applyFeedbackDamage(defender, attacker, feedbackDamage);
// Play anim
dictionary data = new dictionary();
data.put("effect", "clienteffect/pl_force_feedback_hit.cef");
data.put("target", attacker);
messageTo(attacker, "playDelayedClientEffect", data, 1, false);
}
}
boolean isAvoidIncap(obj_id player)
{
if (buff.hasBuff(player, "avoidIncapacitation")) return true;
if (buff.hasBuff(player, "avoidIncapacitation_1")) return true;
if (buff.hasBuff(player, "avoidIncapacitation_2")) return true;
if (buff.hasBuff(player, "avoidIncapacitation_3")) return true;
if (buff.hasBuff(player, "avoidIncapacitation_4")) return true;
if (buff.hasBuff(player, "avoidIncapacitation_5")) return true;
return false;
}
/////////////////////////////////////////////////
// Force Rank Power Modification
/////////////////////////////////////////////////
int getModifiedForceCost(obj_id self, int baseForce, string actionName)
{
int row = dataTableSearchColumnForString(actionName, 0, JEDI_RANK_DATA);
if (row != -1)
{
if (hasSkill(self, "force_rank_light_novice"))
{
int force_manipulation = getSkillStatisticModifier(self, "force_manipulation_light");
float rank_mod = dataTableGetFloat(JEDI_RANK_DATA, row, "forceModLight");
return baseForce + (int)((force_manipulation * rank_mod) + 0.5);
}
else if (hasSkill(self, "force_rank_dark_novice"))
{
int force_manipulation = getSkillStatisticModifier(self, "force_manipulation_dark");
float rank_mod = dataTableGetFloat(JEDI_RANK_DATA, row, "forceModDark");
return baseForce + (int)((force_manipulation * rank_mod) + 0.5);
}
}
return baseForce;
}
int getModifiedMinDamage(obj_id self, int baseDamage, string actionName)
{
int row = dataTableSearchColumnForString(actionName, 0, JEDI_RANK_DATA);
if (row != -1)
{
if (hasSkill(self, "force_rank_light_novice"))
{
int force_power = getSkillStatisticModifier(self, "force_power_light");
float rank_mod = dataTableGetFloat(JEDI_RANK_DATA, row, "minDmgModLight");
return baseDamage + (int)((force_power * rank_mod) + 0.5);
}
else if (hasSkill(self, "force_rank_dark_novice"))
{
int force_power = getSkillStatisticModifier(self, "force_power_dark");
float rank_mod = dataTableGetFloat(JEDI_RANK_DATA, row, "minDmgModDark");
return baseDamage + (int)((force_power * rank_mod) + 0.5);
}
}
return baseDamage;
}
int getModifiedMaxDamage(obj_id self, int baseDamage, string actionName)
{
int row = dataTableSearchColumnForString(actionName, 0, JEDI_RANK_DATA);
if (row != -1)
{
if (hasSkill(self, "force_rank_light_novice"))
{
int force_power = getSkillStatisticModifier(self, "force_power_light");
float rank_mod = dataTableGetFloat(JEDI_RANK_DATA, row, "maxDmgModLight");
return baseDamage + (int)((force_power * rank_mod) + 0.5);
}
else if (hasSkill(self, "force_rank_dark_novice"))
{
int force_power = getSkillStatisticModifier(self, "force_power_dark");
float rank_mod = dataTableGetFloat(JEDI_RANK_DATA, row, "maxDmgModDark");
return baseDamage + (int)((force_power * rank_mod) + 0.5);
}
}
return baseDamage;
}
float getModifiedActionSpeed(obj_id self, float baseSpeed, string actionName)
{
int row = dataTableSearchColumnForString(actionName, 0, JEDI_RANK_DATA);
if (row != -1)
{
if (hasSkill(self, "force_rank_light_novice"))
{
int force_control = getSkillStatisticModifier(self, "force_control_light");
float rank_mod = dataTableGetFloat(JEDI_RANK_DATA, row, "delayModLight");
return baseSpeed + (force_control * rank_mod);
}
else if (hasSkill(self, "force_rank_dark_novice"))
{
int force_control = getSkillStatisticModifier(self, "force_control_dark");
float rank_mod = dataTableGetFloat(JEDI_RANK_DATA, row, "delayModDark");
return baseSpeed + (force_control * rank_mod);
}
}
return baseSpeed;
}
float getModifiedExtraForceCost(obj_id self, float baseForce, string actionName)
{
int row = dataTableSearchColumnForString(actionName, 0, JEDI_RANK_DATA);
if (row != -1)
{
if (hasSkill(self, "force_rank_light_novice"))
{
int force_control = getSkillStatisticModifier(self, "force_control_light");
float rank_mod = dataTableGetFloat(JEDI_RANK_DATA, row, "extraForceModLight");
return baseForce + (force_control * rank_mod);
}
else if (hasSkill(self, "force_rank_dark_novice"))
{
int force_control = getSkillStatisticModifier(self, "force_control_dark");
float rank_mod = dataTableGetFloat(JEDI_RANK_DATA, row, "extraForceModDark");
return baseForce + (force_control * rank_mod);
}
}
return baseForce;
}
int getModifiedBuffAmount(obj_id self, int baseAmount, int modNum, string actionName)
{
int row = dataTableSearchColumnForString(actionName, 0, JEDI_RANK_DATA);
if (row != -1)
{
if (hasSkill(self, "force_rank_light_novice"))
{
int force_control = getSkillStatisticModifier(self, "force_control_light");
float rank_mod = dataTableGetFloat(JEDI_RANK_DATA, row, "buffModLight"+modNum);
return baseAmount + (int)((force_control * rank_mod) + 0.5);
}
else if (hasSkill(self, "force_rank_dark_novice"))
{
int force_control = getSkillStatisticModifier(self, "force_control_dark");
float rank_mod = dataTableGetFloat(JEDI_RANK_DATA, row, "buffModDark"+modNum);
return baseAmount + (int)((force_control * rank_mod) + 0.5);
}
}
return baseAmount;
}
void jediSaberPearlRestore(obj_id player)
{
// This function checks to see if there was a recorded pearl loss from saber deconstruction and restores accordingly
string serverName = toLower(getConfigSetting("CentralServer", "clusterName"));
string restoreTable = "datatables/jedi/saber_pearl_fix/"+serverName+".iff";
int row = dataTableSearchColumnForString(player.toString(), 0, restoreTable);
if (row > -1 && !hasObjVar(player, "jedi.restoredPearls"))
{
CustomerServiceLog("jedi_saber", "%TU - saber pearl restoration: Restoring lost pearls.", player);
int count = dataTableGetNumColumns(restoreTable) - 1;
int[] pearls = new int[count];
int numPearls = 0;
for (int i = 0; i < count; i++)
{
pearls[i] = dataTableGetInt(restoreTable, row, i+1);
if (pearls[i] <= 0) break;
numPearls++;
}
CustomerServiceLog("jedi_saber", "%TU - saber pearl restoration: "+numPearls+" pearls to be restored.", player);
obj_id inventory = utils.getInventoryContainer(player);
int invSpace = getVolumeFree(inventory);
if (invSpace < numPearls)
{
CustomerServiceLog("jedi_saber", "%TU - saber pearl restoration: Unable to restore pearls due to insufficient inventory space.", player);
sendSystemMessage(player, SID_UNABLE_TO_RETURN_PEARLS_INVENTORY);
prose_package ppInvAvail = prose.getPackage(SID_MAKE_SURE_INVENTORY_SPACE_AVAILABLE);
prose.setDI(ppInvAvail, numPearls);
sendSystemMessageProse(player, ppInvAvail);
sendSystemMessage(player, SID_WILL_ATTEMPT_NEXT_TIME);
return;
}
for (int i = 0; i < numPearls; i++)
{
obj_id pearl = createObject(TEMPLATE_KRAYT_DRAGON_PEARL, inventory, "");
if (pearl == null)
{
CustomerServiceLog("jedi_saber", "%TU - saber pearl restoration: ERROR: Level " + pearls[i] + " Pearl unable to be created.", player);
}
else
{
CustomerServiceLog("jedi_saber", "%TU - saber pearl restoration: Pearl Level set to " + pearls[i] + " for Pearl " + pearl + ".", player);
setObjVar(pearl, jedi.VAR_CRYSTAL_STATS + "." + jedi.VAR_LEVEL, pearls[i]);
}
}
CustomerServiceLog("jedi_saber", "%TU - saber pearl restoration:, completed restoring all pearls.", player);
setObjVar(player, "jedi.restoredPearls", 1);
sendSystemMessage(player, SID_ALL_PEARLS_RESTORED);
}
}
/////////////////////////////////////////////////
// Jedi Death System
/////////////////////////////////////////////////
int getMaxJediDeaths(obj_id objPlayer)
{
if (hasSkill(objPlayer, "jedi_light_side_master_novice") || hasSkill(objPlayer, "jedi_dark_side_master_novice"))
return MAX_JEDI_DEATHS_MASTER;
if (hasSkill(objPlayer, "jedi_light_side_journeyman_novice") || hasSkill(objPlayer, "jedi_dark_side_journeyman_novice"))
return MAX_JEDI_DEATHS_KNIGHT;
return MAX_JEDI_DEATHS_PADAWAN;
}
/////////////////////////////////
// Jedi Permadeath - Removed
/////////////////////////////////
/*
void jediRestart(obj_id player)
{
// Clear Jedi Visibility
setJediVisibility(player, 0);
// Wipe remaining Jedi ObjVars
removeObjVar(player, "jedi");
setJediVisibilityTimeStamp(player); // reset bounty timestamp
// Remove outstanding Bounties
clearJediBounties(player);
// Revoke Skills & Experince
revokeJediSkills(player);
revokeExperience(player);
// Clear Inventory
wipeInventory(player);
// Remove restart objvar
removeObjVar(player, "jedi_restart");
// Assign New Skill Trainer
messageTo(player, "findNewTrainer", null, 1, true);
}
void revokeJediSkills(obj_id objPlayer)
{
string[] skillList = getSkillListingForPlayer(objPlayer);
int count = 0;
while (skillList != null && count < 15)
{
skillList = player_version.orderSkillListForRevoke(skillList);
if ( (skillList != null) && (skillList.length > 0) )
{
//for ( int n = 0;n<skillList.length;n++)
//{
// LOG("player_version", "revokeList #"+n+" = "+skillList[n]);
//}
for ( int x = 0; x < skillList.length; x++ )
{
//LOG("playerVersion"," attempting to revoke skill: " + skillList[x]);
CustomerServiceLog("JediFinalDeath","revokeJediSkills(): ("+objPlayer+") "+getName(objPlayer)+" has revoked skill '"+skillList[x]+"'");
revokeSkill(objPlayer, skillList[x]);
}
}
skillList = getSkillListingForPlayer(objPlayer);
count++;
}
if (hasScript(objPlayer, "player.species_innate"))
{
detachScript(objPlayer, "player.species_innate");
attachScript(objPlayer, "player.species_innate");
}
grantSkill(objPlayer, "jedi_padawan_novice");
recalculateForcePower(objPlayer);
}
const string[] jediXpList =
{ "jedi_general",
"combat_meleespecialize_onehandlightsaber",
"combat_meleespecialize_twohandlightsaber",
"combat_meleespecialize_polearmlightsaber" };
void revokeExperience(obj_id objPlayer)
{
if(objPlayer == null || !isIdValid(objPlayer))
return;
string xpList[] = xp.getXpTypes(objPlayer);
if (xpList != null && xpList.length > 0)
{
for (int i = 0; i < xpList.length; i++)
{
int xpAmount = getExperiencePoints(objPlayer, xpList[i]);
if (xpAmount > 0)
grantExperiencePoints(objPlayer, xpList[i], -xpAmount);
}
}
for (int i = 0; i < jediXpList.length; i++)
{
int xpAmount = getExperiencePoints(objPlayer, jediXpList[i]);
if (xpAmount > 0)
grantExperiencePoints(objPlayer, jediXpList[i], -xpAmount);
}
}
void wipeInventory(obj_id objPlayer)
{
// Wipe Equipment and Inventory
obj_id[] invList = getInventoryAndEquipment(objPlayer);
if (invList != null && invList.length > 0)
{
for (int i = 0; i < invList.length; i++)
{
if (isIdValid(invList[i]))
{
CustomerServiceLog("JediFinalDeath","wipeInventory(): ("+objPlayer+") "+getName(objPlayer)+" has lost item ("+invList[i]+") '"+getName(invList[i])+"'");
destroyObject(invList[i]);
}
}
}
// Wipe bank
obj_id bankId = getObjectInSlot(objPlayer, utils.SLOT_BANK);
if (isIdValid(bankId))
{
obj_id[] bankList = getContents(bankId);
if ( bankList != null && bankList.length > 0)
{
for ( int i = 0; i < bankList.length; ++i )
{
if ( isIdValid(bankList[i]) )
{
CustomerServiceLog("JediFinalDeath","wipeInventory(): ("+objPlayer+") "+getName(objPlayer)+" has lost item ("+bankList[i]+") '"+getName(bankList[i])+"'");
destroyObject(bankList[i]);
}
}
}
}
// Wipe credits
money.clearTotalPlayerCredits(objPlayer, money.ACCT_JEDI_DEATH);
// Recreate starting equipment
createStartingEquipment(objPlayer);
}
const string[] COLLECTOR_EDITION_ITEMS =
{ "object/tangible/wearables/goggles/goggles_s01.iff",
"object/tangible/wearables/goggles/goggles_s02.iff",
"object/tangible/wearables/goggles/goggles_s03.iff" };
const string[][] STARTING_CLOTHES =
{
// human_male
// zabrak_male
// bothan_male
// moncal_male
// rodian_male
// twilek_male
// ithorian_male
// sullustan_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
// ithorian_female
// sullustan_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 ||
species == SPECIES_ITHORIAN || species == SPECIES_SULLUSTAN)
{
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 || species == SPECIES_ITHORIAN ||
species == SPECIES_SULLUSTAN)
{
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);
}
}
}
// Starting equipment
string[] items = dataTableGetStringColumnNoDefaults( "datatables/equipment/newbie_equipment.iff", "jedi_padawan" );
if ( items != null && items.length > 0 )
{
for ( int i = 0; i < items.length; i++ )
{
obj_id newItem = createObject( items[i], playerInv, "" );
if ( isIdValid( newItem) )
{
pclib.autoInsureItem(newItem);
}
}
}
//collector's edition:
if ( features.isCollectorEdition( objPlayer ) )
{
for ( int i = 0; i < COLLECTOR_EDITION_ITEMS.length; i++ )
{
obj_id newItem = createObject( COLLECTOR_EDITION_ITEMS[i], playerInv, "" );
if ( isIdValid( newItem ) )
{
setObjVar( newItem, "notrade", true );
}
}
}
}
*/
////////////////////////////////////////
// Jedi Death Skill Loss - Removed
////////////////////////////////////////
/*
string[] getRevokeSkills(string[] skillList)
{
resizeable string[] revokeList = new Vector();
for (int i = 0; i < skillList.length; i++)
{
revokeList.add(skillList[i]);
}
for (int i = 0; i < skillList.length; i++)
{
string[] reqList = getSkillPrerequisiteSkills(skillList[i]);
for (int j = 0; j < reqList.length; j++)
{
int idx = utils.getElementPositionInArray(revokeList, reqList[j]);
if (idx != -1)
{
revokeList = utils.removeElementAt(revokeList, idx);
}
}
}
for (int i = 0; i < revokeList.size(); i++)
{
if (!revokeList[i].startsWith("jedi_"))
{
revokeList = utils.removeElementAt(revokeList, i);
i--;
}
}
string[] retArray = new string[revokeList.size()];
revokeList.toArray(retArray);
return retArray;
}
void handleSkillLoss(obj_id self)
{
string[] skillList = getSkillListingForPlayer(self);
string[] revokeList = getRevokeSkills(skillList);
if (isGod(self))
{
for (int i = 0; i < revokeList.length; i++)
{
LOG ("jedi_death", "Possible skill to revoke - " + revokeList[i]);
}
}
if (revokeList.length == 1)
{
if (revokeList[0].equals("jedi_padawan_novice"))
{
return;
}
}
int idx = rand(0, revokeList.length - 1);
string_id msg = new string_id("jedi_spam", "jedi_death_skill_loss");
string_id skillName = new string_id("skl_n",revokeList[idx]);
prose_package proseMsg = prose.getPackage(msg, skillName);
sendSystemMessageProse(self, proseMsg);
CustomerServiceLog("jedi_death","Jedi %TU has died: Skill lost = "+revokeList[idx]+"("+localize(skillName)+")", self);
setObjVar(self, VAR_JEDI_RESTART, 1);
revokeSkill(self, revokeList[idx]);
recalculateForcePower(self);
removeObjVar(self, VAR_JEDI_RESTART);
}
int getSkillLossThreshold(int deathCount, int deathBuffer)
{
// This shouldn't happen, but just in case.
if (deathCount <= deathBuffer)
return 99999;
// Calculate number of deaths past buffer based on skill level and death count until skill loss
int threshold = 6 - deathBuffer;
int temp = deathCount - deathBuffer;
while (temp >= threshold)
{
temp -= threshold;
threshold --;
if (threshold < 1)
{
threshold = 1;
break;
}
}
return threshold;
}
void handleJediDeath(obj_id self)
{
checkDeathCount(self);
int jediDeaths = getIntObjVar(self, VAR_JEDI_DEATHS);
int deathBuffer = getMaxJediDeaths(self);
jediDeaths++;
setObjVar(self, VAR_JEDI_DEATHS, jediDeaths);
setObjVar(self, VAR_JEDI_LAST_DEATH, getGameTime());
messageTo(self, "handleJediDeathCount", null, 0, false);
// Do nothing if still within the buffer
if (jediDeaths <= deathBuffer)
{
CustomerServiceLog("jedi_death","Jedi %TU has died: DeathCount = "+jediDeaths+", DeathBuffer = "+deathBuffer+"; DeathCount within buffer, no skill loss.", self);
return;
}
else
{
CustomerServiceLog("jedi_death","Jedi %TU has died: DeathCount = "+jediDeaths+", DeathBuffer = "+deathBuffer+"; DeathCount over buffer, possible skill loss.", self);
}
// Find out how many deaths past buffer we have and how many we are allowed till skill loss
int count = getIntObjVar(self, VAR_JEDI_SKILL_LOSS);
int threshold = getSkillLossThreshold(jediDeaths, deathBuffer);
count++;
if (count >= threshold)
{
CustomerServiceLog("jedi_death","Jedi %TU has died: SkillLossCount = "+count+", SkillLossThreshold = "+threshold+"; DeathCount hit skill loss threshold, skill will be lost.", self);
count = 0;
handleSkillLoss(self);
}
else
{
CustomerServiceLog("jedi_death","Jedi %TU has died: SkillLossCount = "+count+", SkillLossThreshold = "+threshold+"; DeathCount below skill loss threshold, no skill loss.", self);
}
setObjVar(self, VAR_JEDI_SKILL_LOSS, count);
}
void checkDeathCount(obj_id self)
{
// Error check jedi death count
if (isJedi(self))
{
if (hasObjVar(self, VAR_JEDI_DEATHS_OLD))
removeObjVar(self, VAR_JEDI_DEATHS_OLD);
int lastDeath = getIntObjVar(self, jedi.VAR_JEDI_LAST_DEATH);
if (getGameTime() > lastDeath + JEDI_DEATH_DECAY_TIME)
{
removeObjVar(self, VAR_JEDI_DEATHS);
removeObjVar(self, VAR_JEDI_LAST_DEATH);
}
}
}
*/
void jediDeathExperienceLoss(obj_id player)
{
jediDeathExperienceLoss(player, 1f);
}
void jediDeathExperienceLoss(obj_id player, float modifier)
{
const int JEDI_MIN_XP_CAP = -10000000;
const float XP_LOSS_PERCENTAGE = -0.05f;
const string[] JEDI_XP_TYPES = { "jedi_general" };
for (int i = 0; i < JEDI_XP_TYPES.length; i++)
{
int xpCap = getExperienceCap(player, JEDI_XP_TYPES[i]);
int xpLoss = (int)(xpCap * XP_LOSS_PERCENTAGE * modifier);
// Cap the minimum xp amount
int curXp = getExperiencePoints(player, "jedi_general");
if (curXp + xpLoss < JEDI_MIN_XP_CAP)
xpLoss = JEDI_MIN_XP_CAP - curXp;
grantExperiencePoints(player, JEDI_XP_TYPES[i], xpLoss);
prose_package ppLostXP = prose.getPackage(SID_LOST_JEDI_XP);
prose.setDI(ppLostXP, xpLoss);
sendSystemMessageProse(player, ppLostXP);
}
}
/////////////////////////////////////////////////////////////////////////////////////////
// New Saber functions
/////////////////////////////////////////////////////////////////////////////////////////
float getSaberForceCost(obj_id saber)
{
float forceCost = 0;
if (hasObjVar(saber, VAR_SABER_BASE))
forceCost = getFloatObjVar(saber, VAR_SABER_BASE + "." + VAR_FORCE);
else
forceCost = getFloatObjVar(saber, "crafting_components.forceCost");
if (forceCost < 2) forceCost = 2;
return forceCost;
}
boolean isCrystalTuned(obj_id crystal)
{
if(!isIdValid(crystal) || !exists(crystal))
return false;
if (hasObjVar(crystal, VAR_CRYSTAL_OWNER))
return true;
return false;
//return true; // for debugging
}
boolean isCrystalOwner(obj_id player, obj_id crystal)
{
if (!isCrystalTuned(crystal))
return false;
obj_id owner = getObjIdObjVar(crystal, VAR_CRYSTAL_OWNER_ID);
if (owner == player)
return true;
return false;
//return true; // for debugging
}
boolean doesCrystalMatchSaber(obj_id saber, obj_id crystal)
{
if (!isCrystalTuned(crystal))
return false;
obj_id saberOwner = getCrafter(saber);
if (static_item.isStaticItem(saber));
saberOwner = utils.getContainingPlayer(saber);
obj_id owner = getObjIdObjVar(crystal, VAR_CRYSTAL_OWNER_ID);
if (owner == saberOwner)
return true;
return false;
//return true; // for debugging
}
void resetSaberStats(obj_id saber)
{
if (!hasObjVar(saber, VAR_SABER_DEFAULT_STATS))
return;
initSaberBaseStats(saber);
obj_id inv = getObjectInSlot(saber, "saber_inv");
obj_id[] contents = getContents(inv);
if (contents == null || contents.length == 0)
return;
for (int i = 0; i < contents.length; i++)
{
if (!isDisabled(contents[i]))
addCrystalStats(saber, contents[i]);
}
}
void initSaberBaseStats(obj_id saber)
{
int minDmg = getIntObjVar(saber, VAR_SABER_DEFAULT_STATS + "." + VAR_MIN_DMG);
int maxDmg = getIntObjVar(saber, VAR_SABER_DEFAULT_STATS + "." + VAR_MAX_DMG);
setWeaponMinDamage(saber, minDmg);
setWeaponMaxDamage(saber, maxDmg);
float speed = getFloatObjVar(saber, VAR_SABER_DEFAULT_STATS + "." + VAR_SPEED);
setWeaponAttackSpeed(saber, speed);
float wound = getFloatObjVar(saber, VAR_SABER_DEFAULT_STATS + "." + VAR_WOUND);
setWeaponWoundChance(saber, wound);
float radius = getFloatObjVar(saber, VAR_SABER_DEFAULT_STATS + "." + VAR_RADIUS);
setWeaponDamageRadius(saber, radius);
int attackCost = getIntObjVar(saber, VAR_SABER_DEFAULT_STATS + "." + VAR_ATTACK_COST);
setWeaponAttackCost(saber, attackCost);
//float force = getFloatObjVar(saber, VAR_SABER_DEFAULT_STATS + "." + VAR_FORCE);
//setObjVar(saber, VAR_SABER_BASE + "." + VAR_FORCE, force);
int eDamageType = getIntObjVar(saber, VAR_SABER_DEFAULT_STATS + "." + VAR_ELEMENTAL_DAM_TYPE);
setWeaponElementalType(saber, eDamageType);
int eDamageAmount = getIntObjVar(saber, VAR_SABER_DEFAULT_STATS + "." + VAR_ELEMENTAL_DAM_AMNT);
setWeaponElementalValue(saber, eDamageAmount);
}
void setSaberColorCrystalDamage(obj_id saber)
{
int color = getIntObjVar (saber, VAR_SABER_BASE + "." + VAR_COLOR);
int colorRow = dataTableSearchColumnForInt(color, "color", JEDI_CRYSTAL_COLOR_TABLE);
if(color == 31 || colorRow < 0)
{
setWeaponElementalType(saber, DAMAGE_NONE);
setWeaponElementalValue(saber, 0);
return;
}
int damageType = dataTableGetInt(JEDI_CRYSTAL_COLOR_TABLE, colorRow, "elemental_type");
float damageAmt = dataTableGetFloat(JEDI_CRYSTAL_COLOR_TABLE, colorRow, "damage_amount");
setWeaponElementalType(saber, damageType);
setWeaponElementalValue(saber, (int)((getWeaponMaxDamage(saber) * damageAmt) +1));
}
void setSaberColor(obj_id saber, int color, int shader)
{
string varName = "private/index_color_blade";
custom_var myVar = getCustomVarByName(saber, varName);
if (myVar != null && myVar.isPalColor())
{
palcolor_custom_var pcVar = (palcolor_custom_var)myVar;
if (pcVar != null)
{
pcVar.setValue(color);
setObjVar (saber, VAR_SABER_BASE + "." + VAR_COLOR, color);
}
}
//set the shader objvar if this value is 0 we have a standard saber shader, 1 is equal to the lava shader
string shaderName = "private/alternate_shader_blade";
custom_var shaderVar = getCustomVarByName(saber, shaderName);
if (shaderVar != null)
{
ranged_int_custom_var riVar = (ranged_int_custom_var)shaderVar;
if (riVar != null)
{
riVar.setValue(shader);
setObjVar(saber, VAR_SABER_BASE + "." + VAR_SHADER, shader);
}
}
}
void addCrystalStats(obj_id saber, obj_id crystal)
{
obj_var_list ovl = getObjVarList(crystal, VAR_CRYSTAL_STATS);
if(ovl != null)
{
int numItems = ovl.getNumItems();
for ( int i = 0; i < numItems; i++ )
{
obj_var ov = ovl.getObjVar(i);
string name = ov.getName();
LOG("saber_test", "Processing Crystal Stat: "+name);
if (name.equals(VAR_MIN_DMG))
{
int minDmg = getWeaponMinDamage(saber);
LOG ("saber_test", "Old Min Damage = " + minDmg);
minDmg += getIntObjVar(crystal, VAR_CRYSTAL_STATS + "." + VAR_MIN_DMG);
LOG ("saber_test", "New Min Damage = " + minDmg);
if (!setWeaponMinDamage(saber, minDmg))
LOG ("saber_test", "ERROR: Failed Setting Min Damage");
}
else if (name.equals(VAR_MAX_DMG))
{
int maxDmg = getWeaponMaxDamage(saber);
maxDmg += getIntObjVar(crystal, VAR_CRYSTAL_STATS + "." + VAR_MAX_DMG);
setWeaponMaxDamage(saber, maxDmg);
}
else if (name.equals(VAR_SPEED))
{
float speed = getWeaponAttackSpeed(saber);
speed += getFloatObjVar(crystal, VAR_CRYSTAL_STATS + "." + VAR_SPEED);
setWeaponAttackSpeed(saber, speed);
}
else if (name.equals(VAR_WOUND))
{
float wound = getWeaponWoundChance(saber);
wound += getFloatObjVar(crystal, VAR_CRYSTAL_STATS + "." + VAR_WOUND);
setWeaponWoundChance(saber, wound);
}
else if (name.equals(VAR_RADIUS))
{
float radius = getWeaponDamageRadius(saber);
radius += getFloatObjVar(crystal, VAR_CRYSTAL_STATS + "." + VAR_RADIUS);
setWeaponDamageRadius(saber, radius);
}
else if (name.equals(VAR_ATTACK_COST))
{
int cost = getWeaponAttackCost(saber);
cost += getIntObjVar(crystal, VAR_CRYSTAL_STATS + "." + VAR_ATTACK_COST);
setWeaponAttackCost(saber, cost);
}
else if (name.equals(VAR_FORCE))
{
float force = getFloatObjVar(saber, VAR_SABER_BASE + "." + VAR_FORCE);
force += getFloatObjVar(crystal, VAR_CRYSTAL_STATS + "." + VAR_FORCE);
setObjVar(saber, VAR_SABER_BASE + "." + VAR_FORCE, force);
}
else if (name.equals(VAR_COLOR))
{
int color = getIntObjVar(crystal, VAR_CRYSTAL_STATS + "." + VAR_COLOR);
int shader = getIntObjVar(crystal, VAR_CRYSTAL_STATS + "." + VAR_SHADER);
setSaberColor(saber, color, shader);
}
}
}
// Validate Dmg Stats
int minDmg = getWeaponMinDamage(saber);
int maxDmg = getWeaponMaxDamage(saber);
if ((minDmg - 10) >= maxDmg)
{
minDmg = maxDmg - 10;
setWeaponMinDamage(saber, minDmg);
}
// Update the elemental damage
setSaberColorCrystalDamage(saber);
//update scriptvars
weapons.setWeaponData(saber);
}
void removeCrystalStats(obj_id saber, obj_id crystal)
{
obj_var_list ovl = getObjVarList(crystal, VAR_CRYSTAL_STATS);
if(ovl != null)
{
int numItems = ovl.getNumItems();
for ( int i = 0; i < numItems; i++ )
{
obj_var ov = ovl.getObjVar(i);
string name = ov.getName();
LOG("saber_test", "Processing Crystal Stat: "+name);
if (name.equals(VAR_MIN_DMG))
{
int minDmg = getWeaponMinDamage(saber);
LOG ("saber_test", "Old Min Damage = " + minDmg);
minDmg -= getIntObjVar(crystal, VAR_CRYSTAL_STATS + "." + VAR_MIN_DMG);
LOG ("saber_test", "New Min Damage = " + minDmg);
if (!setWeaponMinDamage(saber, minDmg))
LOG ("saber_test", "ERROR: Failed Setting Min Damage");
}
else if (name.equals(VAR_MAX_DMG))
{
int maxDmg = getWeaponMaxDamage(saber);
LOG ("saber_test", "Old Max Damage = " + maxDmg);
maxDmg -= getIntObjVar(crystal, VAR_CRYSTAL_STATS + "." + VAR_MAX_DMG);
LOG ("saber_test", "New Max Damage = " + maxDmg);
if (!setWeaponMaxDamage(saber, maxDmg))
LOG ("saber_test", "ERROR: Failed Setting Max Damage");
}
else if (name.equals(VAR_SPEED))
{
float speed = getWeaponAttackSpeed(saber);
LOG ("saber_test", "Old Speed = " + speed);
speed -= getFloatObjVar(crystal, VAR_CRYSTAL_STATS + "." + VAR_SPEED);
LOG ("saber_test", "New Speed = " + speed);
if (!setWeaponAttackSpeed(saber, speed))
LOG ("saber_test", "ERROR: Failed Setting Speed");
}
else if (name.equals(VAR_WOUND))
{
float wound = getWeaponWoundChance(saber);
LOG ("saber_test", "Old Wound = " + wound);
wound -= getFloatObjVar(crystal, VAR_CRYSTAL_STATS + "." + VAR_WOUND);
LOG ("saber_test", "New Wound = " + wound);
if (!setWeaponWoundChance(saber, wound))
LOG ("saber_test", "ERROR: Failed Setting Wound");
}
else if (name.equals(VAR_RADIUS))
{
float radius = getWeaponDamageRadius(saber);
LOG ("saber_test", "Old Radius = " + radius);
radius -= getFloatObjVar(crystal, VAR_CRYSTAL_STATS + "." + VAR_RADIUS);
LOG ("saber_test", "New Radius = " + radius);
if (!setWeaponDamageRadius(saber, radius))
LOG ("saber_test", "ERROR: Failed Setting Radius");
}
else if (name.equals(VAR_ATTACK_COST))
{
int cost = getWeaponAttackCost(saber);
LOG ("saber_test", "Old Attack Cost = " + cost);
cost -= getIntObjVar(crystal, VAR_CRYSTAL_STATS + "." + VAR_ATTACK_COST);
LOG ("saber_test", "New Attack Cost = " + cost);
if (!setWeaponAttackCost(saber, cost))
LOG ("saber_test", "ERROR: Failed Setting Attack Cost");
}
else if (name.equals(VAR_FORCE))
{
float force = getFloatObjVar(saber, VAR_SABER_BASE + "." + VAR_FORCE);
force -= getFloatObjVar(crystal, VAR_CRYSTAL_STATS + "." + VAR_FORCE);
setObjVar(saber, VAR_SABER_BASE + "." + VAR_FORCE, force);
}
else if (name.equals(VAR_COLOR))
{
int color = getIntObjVar(saber, VAR_SABER_DEFAULT_STATS + "." + VAR_COLOR);
int shader = getIntObjVar(saber, VAR_SABER_DEFAULT_STATS + "." + VAR_SHADER);
setSaberColor(saber, color, shader);
removeObjVar(saber, VAR_SABER_BASE + "." + VAR_COLOR);
removeObjVar(saber, VAR_SABER_BASE + "." + VAR_SHADER);
}
}
}
// Update the elemental damage
setSaberColorCrystalDamage(saber);
//update scriptvars
weapons.setWeaponData(saber);
}
boolean isColorCrystal(obj_id crystal)
{
return (hasObjVar(crystal, VAR_CRYSTAL_STATS + "." + VAR_COLOR));
}
boolean hasColorCrystal(obj_id saber)
{
return (hasObjVar(saber, VAR_SABER_BASE + "." + VAR_COLOR));
}
boolean validateCrystalCount(obj_id saber)
{
obj_id inv = getObjectInSlot(saber, "saber_inv");
obj_id[] contents = getContents(inv);
return (contents.length <= MAX_CRYSTAL_COUNT);
}
int getCrystalQuality(int level)
{
// Poor =20-39
if (level < 40)
return CRYSTAL_POOR;
// Fair =40-69
else if (level < 70)
return CRYSTAL_FAIR;
// Good = 70-99
else if (level < 100)
return CRYSTAL_GOOD;
// Quality = 100-139
else if (level < 140)
return CRYSTAL_QUALITY;
// Select = 140-219
else if (level < 220)
return CRYSTAL_SELECT;
// Premium = 220-329
else if (level < 330)
return CRYSTAL_PREMIUM;
// Flawless =330+
else
return CRYSTAL_FLAWLESS;
}
int getStaticCrystalQuality(int level)
{
switch(level)
{
case 0:
return CRYSTAL_POOR;
case 1:
return CRYSTAL_FAIR;
case 2:
return CRYSTAL_GOOD;
case 3:
return CRYSTAL_QUALITY;
case 4:
return CRYSTAL_SELECT;
case 5:
return CRYSTAL_PREMIUM;
case 6:
return CRYSTAL_FLAWLESS;
default:
break;
}
return CRYSTAL_GOOD;
}
// !!!!! ------>>>>>> this method causes the inventory to be overloaded no matter how full it is.
// !!!!! ------>>>>>> this method is not to be used except for one time only crystal gives, like for a quest
// !!!!! ------>>>>>> where the item creation can absolutely not fail and will only occur once per player or so
boolean forceCreateColorCrystal(obj_id player, int color)
{
obj_id crystal = createObjectInInventoryAllowOverload(TEMPLATE_FORCE_CRYSTAL, player);
setAsColorCrystal(crystal, color);
return isIdValid(crystal);
}
boolean createColorCrystal(obj_id inventory, int color)
{
obj_id crystal = static_item.createNewItemFunction(mapOldColorToNewColor(color), inventory);
return isIdValid(crystal);
}
boolean createPowerCrystal(obj_id inventory, int level)
{
obj_id crystal = static_item.createNewItemFunction(mapOldPowerCrystalLevelToNew(level), inventory);
return isIdValid(crystal);
}
// used by CTS
void setAsColorCrystal(obj_id crystal, int color, int hp, int hpMax)
{
if (isIdValid(crystal))
{
setAsColorCrystal(crystal, color);
setObjVar(crystal, jedi.VAR_CRYSTAL_STATS + "." + jedi.VAR_HP, hp);
setObjVar(crystal, jedi.VAR_CRYSTAL_STATS + "." + jedi.VAR_HP_MAX, hpMax);
}
}
void setAsColorCrystal(obj_id crystal, int color)
{
if (isIdValid(crystal))
{
custom_var myVar = getCustomVarByName(crystal, "private/index_color_1");
if (myVar != null && myVar.isPalColor())
{
palcolor_custom_var pcVar = (palcolor_custom_var)myVar;
pcVar.setValue(color);
}
setObjVar(crystal, jedi.VAR_CRYSTAL_STATS + "." + jedi.VAR_COLOR, color);
setObjVar(crystal, jedi.VAR_CRYSTAL_STATS + "." + jedi.VAR_LEVEL, -1);
}
}
// used by CTS
void setAsPowerCrystal(obj_id crystal, int level, int hp, int hpMax)
{
if (isIdValid(crystal))
{
setAsPowerCrystal(crystal, level);
setObjVar(crystal, jedi.VAR_CRYSTAL_STATS + "." + jedi.VAR_HP, hp);
setObjVar(crystal, jedi.VAR_CRYSTAL_STATS + "." + jedi.VAR_HP_MAX, hpMax);
}
}
void setAsPowerCrystal(obj_id crystal, int level)
{
if (isIdValid(crystal))
{
custom_var myVar = getCustomVarByName(crystal, "private/index_color_1");
// Guard because Krayt Dragon Pearls do not have a color.
if (myVar != null && myVar.isPalColor())
{
palcolor_custom_var pcVar = (palcolor_custom_var)myVar;
pcVar.setValue(31);
setObjVar(crystal, jedi.VAR_CRYSTAL_STATS + "." + jedi.VAR_COLOR, -1);
}
setObjVar(crystal, jedi.VAR_CRYSTAL_STATS + "." + jedi.VAR_LEVEL, level);
}
}
boolean checkRobePermission (obj_id player)
{
if ( !isIdValid(player) || !isPlayer(player) )
{
LOG("jedi", "library.jedi.robeRemove -- player is invalid");
return false;
}
// Place Robe into inventory if no longer high enough to use.
obj_id[] items = getContents(player);
if (items == null)
{
LOG("jedi", "library.jedi.robeRemove -- " + player + "'s contents are null.");
return false;
}
for (int i = 0; i < items.length; i++)
{
if (hasObjVar(items[i], VAR_JEDI_SKILL))
{
string jediSkill = getStringObjVar(items[i], VAR_JEDI_SKILL);
if (!hasSkill(player, jediSkill))
{
obj_id inv = getObjectInSlot(player, "inventory");
putInOverloaded(items[i], inv);
}
}
}
return true;
}
void setupJediTrainer(obj_id self)
{
const string[] TRAINER_TYPES = { "trainer_brawler", "trainer_artisan", "trainer_scout", "trainer_marksman", "trainer_entertainer", "trainer_medic"};
location locTest = getLocation(self);
if(locTest.area.equals("tutorial"))
{
return;
}
string strPrimaryCategory = "trainer";
string strSecondaryCategory = TRAINER_TYPES[rand(0, TRAINER_TYPES.length-1)];
map_location[] rawMapLocations = getPlanetaryMapLocations(strPrimaryCategory, strSecondaryCategory);
// Filter out locations in player cities.
resizeable map_location[] mapLocations = new map_location[0];
location testloc = new location();
for ( int i=0; i<rawMapLocations.length; i++ )
{
testloc.x = rawMapLocations[i].getX();
testloc.z = rawMapLocations[i].getY();
testloc.area = getLocation(self).area;
if ( getCityAtLocation( testloc, 0 ) > 0 )
continue;
mapLocations = utils.addElement( mapLocations, rawMapLocations[i] );
}
if((mapLocations==null)||(mapLocations.length==0))
{
locTest = getLocation(self);
LOG("DESIGNER_FATAL", "JEDI : For planet "+locTest.area+", primary category : "+strPrimaryCategory+" and secondary category "+strSecondaryCategory+" No planetary map location was found");
return;
}
int intRoll = rand(0, mapLocations.length-1);
location locHome = getLocation(self);
locTest = new location();
locTest.x = mapLocations[intRoll].getX();
locTest.z = mapLocations[intRoll].getY();
locTest.area = locHome.area;
setObjVar(self, "jedi.locTrainerLocation", locTest);
return;
}
void clickyCombatPearlFix (obj_id item)
{
float damage = 0.0f;
string template = getTemplateName(item);
string itemName = "";
boolean tunedCrystal = isCrystalTuned(item);
if (hasObjVar(item, "crafting_components"))
damage = getFloatObjVar(item, "crafting_components.minDamage");
else
damage = (getIntObjVar(item, VAR_CRYSTAL_STATS + "." + VAR_MAX_DMG));
//turn old pearls into static items
if (template.endsWith("krayt_dragon_pearl.iff"))
{
//if the pearl is tuned convert it to a static item
if (tunedCrystal)
{
obj_id owner = getObjIdObjVar(item, VAR_CRYSTAL_OWNER_ID);
if (damage < 20)
itemName = "item_krayt_pearl_04_04";
else if (damage < 30 )
itemName = "item_krayt_pearl_04_05";
else if (damage < 40 )
itemName = "item_krayt_pearl_04_06";
else if (damage < 50 )
itemName = "item_krayt_pearl_04_08";
else if (damage < 60 )
itemName = "item_krayt_pearl_04_09";
else if (damage < 70 )
itemName = "item_krayt_pearl_04_11";
else if (damage < 80 )
itemName = "item_krayt_pearl_04_13";
else if (damage < 90)
itemName = "item_krayt_pearl_04_14";
else if (damage < 100)
itemName = "item_krayt_pearl_04_15";
else if (damage < 110)
itemName = "item_krayt_pearl_04_16";
else if (damage < 120)
itemName = "item_krayt_pearl_04_17";
else if (damage >= 120)
itemName = "item_krayt_pearl_04_18";
jediComponentStatSetter(owner, item, itemName);
CustomerServiceLog("jedi_saber", "Converting Old Tuned Pearl ("+item+") - Damage:"+damage+" - to a new Static Item Pearl - "+itemName);
return;
}
//if the pearl is untuned, this also covers pre pub 9 conversions if any still happen to be around
else
{
int level = getIntObjVar(item, VAR_CRYSTAL_STATS + "." + VAR_LEVEL);
if (level > 0)
{
if (level < 20)
itemName = "item_krayt_pearl_04_02";
else if (level < 40)
itemName = "item_krayt_pearl_04_04";
else if (level < 60)
itemName = "item_krayt_pearl_04_05";
else if (level < 80)
itemName = "item_krayt_pearl_04_06";
else if (level < 100)
itemName = "item_krayt_pearl_04_07";
else if (level < 120)
itemName = "item_krayt_pearl_04_10";
else if (level < 150)
itemName = "item_krayt_pearl_04_13";
else if (level < 200)
itemName = "item_krayt_pearl_04_14";
else if (level < 250)
itemName = "item_krayt_pearl_04_16";
else if (level < 330)
itemName = "item_krayt_pearl_04_17";
else if (level >= 330)
itemName = "item_krayt_pearl_04_18";
jediComponentStatSetter(null, item, itemName);
CustomerServiceLog("jedi_saber", "Converting Old Untuned Pearl ("+item+") - Level:"+level+" - to a new Static Item Pearl - "+itemName);
return;
}
else
//no level
{
itemName = "item_krayt_pearl_04_09";
jediComponentStatSetter(null, item, itemName);
CustomerServiceLog("jedi_saber", "Converting Old Untuned Pearl Missing Level ("+item+") - Level:"+level+" - to a new Static Item Pearl - "+itemName);
return;
}
}
}
//old twin force crystals, these only ever became color crystals
else if (template.endsWith("lance_module_force_crystal.iff"))
{
//turn into static color crystal
int color = getIntObjVar(item, VAR_CRYSTAL_STATS + "." + VAR_COLOR);
string colorName = mapOldColorToNewColor(item);
if (tunedCrystal)
{
obj_id owner = getObjIdObjVar(item, VAR_CRYSTAL_OWNER_ID);
jediComponentStatSetter(owner, item, colorName);
CustomerServiceLog("jedi_saber", "Converting Old Tuned Lance Color Crystal ("+item+") - OLD COLOR:"+color+" - to a new Static Item Color Crystal - "+colorName);
return;
}
else
{
jediComponentStatSetter(null, item, colorName);
CustomerServiceLog("jedi_saber", "Converting Old Untuned Lance Color Crystal ("+item+") - OLD COLOR:"+color+" - to a new Static Item Color Crystal - "+colorName);
return;
}
}
//old power or color crystal
else if (template.endsWith("lightsaber_module_force_crystal.iff"))
{
//see if we are color or power
if(hasObjVar(item, VAR_CRYSTAL_STATS + "." + VAR_COLOR))
{
int color = getIntObjVar(item, VAR_CRYSTAL_STATS + "." + VAR_COLOR);
string colorName = mapOldColorToNewColor(item);
if (tunedCrystal)
{
obj_id owner = getObjIdObjVar(item, VAR_CRYSTAL_OWNER_ID);
jediComponentStatSetter(owner, item, colorName);
CustomerServiceLog("jedi_saber", "Converting Old Tuned Color Crystal ("+item+") - OLD COLOR:"+color+" - to a new Static Item Color Crystal - "+colorName);
return;
}
else
{
jediComponentStatSetter(null, item, colorName);
CustomerServiceLog("jedi_saber", "Converting Old Untuned Color Crystal ("+item+") - OLD COLOR:"+color+" - to a new Static Item Color Crystal - "+colorName);
return;
}
}
//if we are not a color crystal we must be a power crystal
else
{
if (tunedCrystal)
{
obj_id owner = getObjIdObjVar(item, VAR_CRYSTAL_OWNER_ID);
if (damage < 20)
itemName = "item_power_crystal_04_04";
else if (damage < 30 )
itemName = "item_power_crystal_04_05";
else if (damage < 40 )
itemName = "item_power_crystal_04_06";
else if (damage < 50)
itemName = "item_power_crystal_04_08";
else if (damage < 60)
itemName = "item_power_crystal_04_09";
else if (damage < 70)
itemName = "item_power_crystal_04_11";
else if (damage < 80)
itemName = "item_power_crystal_04_13";
else if (damage < 90)
itemName = "item_power_crystal_04_14";
else if (damage < 100)
itemName = "item_power_crystal_04_15";
else if (damage < 110)
itemName = "item_power_crystal_04_16";
else if (damage < 120)
itemName = "item_power_crystal_04_17";
else if (damage >= 120)
itemName = "item_power_crystal_04_18";
jediComponentStatSetter(owner, item, itemName);
CustomerServiceLog("jedi_saber", "Converting Old Tuned Power Crystal ("+item+") - Damage:"+damage+" - to a new Static Item Power Crystal - "+itemName);
return;
}
else
{
int level = getIntObjVar(item, VAR_CRYSTAL_STATS + "." + VAR_LEVEL);
if (level > 0)
{
itemName = mapOldPowerCrystalLevelToNew(level);
jediComponentStatSetter(null, item, itemName);
CustomerServiceLog("jedi_saber", "Converting Old Untuned Power Crystal ("+item+") - Level:"+level+" - to a new Static Item Crystal - "+itemName);
return;
}
else
//no level meaning very old crystal pre pub 9ish
{
itemName = "item_power_crystal_04_09";
jediComponentStatSetter(null, item, itemName);
CustomerServiceLog("jedi_saber", "Converting Old Untuned Power Crystal Missing Level ("+item+") - Level:"+level+" - to a new Static Item Crystal - "+itemName);
return;
}
}
}
}
return;
}
//this sets the stats of an old tuned Pearl into a static item tuned to that player
void jediComponentStatSetter(obj_id owner , obj_id item, string itemName)
{
if ( itemName != null && itemName != "" )
{
removeAllObjVars(item);
//catch all in case the above does not
removeObjVar(item, jedi.VAR_CRYSTAL_STATS);
detachAllScripts(item);
setStaticItemName(item, itemName);
dictionary itemData = static_item.getMasterItemDictionary(itemName);
setStaticItemVersion(item, itemData.getInt("version"));
setObjVar(item, jedi.VAR_CRYSTAL_STATS + "." + jedi.VAR_LEVEL, -1);
attachScript(item, "item.static_item_base");
if(owner != null)
{
setObjVar(item,VAR_CRYSTAL_OWNER_ID, owner);
setObjVar(item, jedi.VAR_CRYSTAL_OWNER_NAME, getName(owner));
}
LOG("jedi_saber", "Converted old Pearl or Crystal to " +itemName);
//we need to initialize ourself now as a static item
static_item.initializeObject(item, itemData);
}
else
CustomerServiceLog("jedi_saber", "Could not convert item("+item+") Bad itemName passed in" +itemName);
return;
}
string mapOldColorToNewColor(obj_id item)
{
return mapOldColorToNewColor(getIntObjVar(item, VAR_CRYSTAL_STATS + "." + VAR_COLOR));
}
string mapOldColorToNewColor(int color)
{
string colorMap[] = {
"item_color_crystal_02_00",
"item_color_crystal_02_01",
"item_color_crystal_02_02",
"item_color_crystal_02_03",
"item_color_crystal_02_04",
"item_color_crystal_02_05",
"item_color_crystal_02_06",
"item_color_crystal_02_07",
"item_color_crystal_02_08",
"item_color_crystal_02_09",
"item_color_crystal_02_10",
"item_color_crystal_02_11",
"item_color_crystal_02_12",
"item_color_crystal_02_13",
"item_color_crystal_02_14",
"item_color_crystal_02_15",
"item_color_crystal_02_16",
"item_color_crystal_02_17",
"item_color_crystal_02_18",
"item_color_crystal_02_19",
"item_color_crystal_02_20",
"item_color_crystal_02_21",
"item_color_crystal_02_22",
"item_color_crystal_02_23",
"item_color_crystal_02_24",
"item_color_crystal_02_25",
"item_color_crystal_02_26",
"item_color_crystal_02_27",
"item_color_crystal_02_28",
"item_color_crystal_02_29",
"item_color_crystal_02_30",
"item_color_crystal_02_00"
};
return colorMap[color];
}
string mapOldPowerCrystalLevelToNew(int level)
{
if (level < 40)
return "item_power_crystal_04_03";
else if (level < 60)
return "item_power_crystal_04_04";
else if (level < 80)
return "item_power_crystal_04_06";
else if (level < 100)
return "item_power_crystal_04_07";
else if (level < 120)
return "item_power_crystal_04_08";
else if (level < 140)
return "item_power_crystal_04_09";
else if (level < 150)
return "item_power_crystal_04_11";
else if (level < 200)
return "item_power_crystal_04_15";
else if (level < 250)
return "item_power_crystal_04_16";
else if (level < 330)
return "item_power_crystal_04_17";
else if (level >= 330)
return "item_power_crystal_04_18";
else
return "item_power_crystal_04_13";
}
void initializeCrystal(obj_id crystal, int level)
{
// check if crystal has a preset level
if (hasObjVar(crystal, VAR_CRYSTAL_STATS + "." + VAR_LEVEL))
{
LOG("jedi", "level already set, initializing");
level = getIntObjVar(crystal, VAR_CRYSTAL_STATS + "." + VAR_LEVEL);
}
LOG("jedi", "Current Crystal level = "+level);
setObjVar(crystal, VAR_CRYSTAL_STATS + "." + VAR_LEVEL, level);
if (hasObjVar(crystal, VAR_CRYSTAL_STATS + "." + VAR_HP)
&& hasObjVar(crystal, VAR_CRYSTAL_STATS + "." + VAR_HP_MAX))
{
LOG("jedi", "hp already set, initializing");
int hp = getIntObjVar(crystal,VAR_CRYSTAL_STATS + "." + VAR_HP);
setInvulnerableHitpoints(crystal, hp);
removeObjVar(crystal, VAR_CRYSTAL_STATS + "." + VAR_HP);
int hpMax = getIntObjVar(crystal, VAR_CRYSTAL_STATS + "." + VAR_HP_MAX);
setMaxHitpoints(crystal, hpMax);
removeObjVar(crystal, VAR_CRYSTAL_STATS + "." + VAR_HP_MAX);
}
else
{
// Initialize hp
const int min = 650;
const int max = 1250;
int range = max - min - level;
if (range < 0) { range = 0; level = max - min; }
int hp = min + level + rand(0, range);
setMaxHitpoints(crystal, hp);
setInvulnerableHitpoints(crystal, hp);
}
string template = getTemplateName(crystal);
if (template.endsWith("module_force_crystal.iff"))
{
int color = rand(0, 11);
if (hasObjVar(crystal, VAR_CRYSTAL_STATS + "." + VAR_COLOR))
color = getIntObjVar(crystal, VAR_CRYSTAL_STATS + "." + VAR_COLOR);
boolean setColor = true;
if (color == -1)
{
setColor = false;
removeObjVar(crystal, VAR_CRYSTAL_STATS + "." + VAR_COLOR);
}
if (setColor && rand(25, 100) > level)
{
setObjVar(crystal, VAR_CRYSTAL_STATS + "." + VAR_COLOR, color);
setObjVar(crystal, VAR_CRYSTAL_STATS + "." + VAR_LEVEL, -1);
custom_var myVar = getCustomVarByName(crystal, "private/index_color_1");
if (myVar.isPalColor())
{
palcolor_custom_var pcVar = (palcolor_custom_var)myVar;
pcVar.setValue(color);
}
}
else
{
custom_var myVar = getCustomVarByName(crystal, "private/index_color_1");
if (myVar.isPalColor())
{
palcolor_custom_var pcVar = (palcolor_custom_var)myVar;
pcVar.setValue(31);
}
}
}
}
//helper function to determine if someone is Force Sensitive
boolean isForceSensitive(obj_id player)
{
string classTemplate = getSkillTemplate(player);
if ( classTemplate != null && classTemplate.startsWith("force"))
{
return true;
}
return false;
}
//helper function to determine if a Force Sensitive mets a set of level requirements passed in
boolean isForceSensitiveLevelRequired(obj_id player, int requiredLevel)
{
int playerLevel= getLevel(player);
if(isForceSensitive(player) && playerLevel >= requiredLevel)
{
return true;
}
return false;
}
//do they have any ultra cloak
boolean hasAnyUltraCloak(obj_id player)
{
if(utils.playerHasStaticItemInBankOrInventory(player, JEDI_CLOAK_LIGHT_HOOD_UP))
return true;
if(utils.playerHasStaticItemInBankOrInventory(player, JEDI_CLOAK_DARK_HOOD_UP))
return true;
if(utils.playerHasStaticItemInBankOrInventory(player, JEDI_CLOAK_LIGHT_HOOD_DOWN))
return true;
if(utils.playerHasStaticItemInBankOrInventory(player, JEDI_CLOAK_DARK_HOOD_DOWN))
return true;
// Appearance Inventory checks.
if(utils.playerHasStaticItemInAppearanceInventory(player, JEDI_CLOAK_LIGHT_HOOD_UP))
return true;
if(utils.playerHasStaticItemInAppearanceInventory(player, JEDI_CLOAK_DARK_HOOD_UP))
return true;
if(utils.playerHasStaticItemInAppearanceInventory(player, JEDI_CLOAK_LIGHT_HOOD_DOWN))
return true;
if(utils.playerHasStaticItemInAppearanceInventory(player, JEDI_CLOAK_DARK_HOOD_DOWN))
return true;
return false;
}