Initial upload. PRC8 has been added. Module compiles, PRC's default AI & treasure scripts have been integrated. Started work on top hak for SLA / Ability / Scripting modifications.
426 lines
13 KiB
Plaintext
426 lines
13 KiB
Plaintext
//::///////////////////////////////////////////////
|
|
//:: jw_smith_copy
|
|
//:: Palmer - straight copy of the smith script from HotU
|
|
//:: Copyright (c) 2001 Bioware Corp.
|
|
//:://////////////////////////////////////////////
|
|
/*
|
|
Main include file for the weapon upgrade smith.
|
|
|
|
* Nov 5th 2003 (BK)
|
|
- Unlimited ammo property is now +5 not +3
|
|
*/
|
|
//:://////////////////////////////////////////////
|
|
//:: Created By:
|
|
//:: Created On:
|
|
//:://////////////////////////////////////////////
|
|
|
|
//****************************************************
|
|
// * Constants
|
|
//****************************************************
|
|
#include "prc_x2_itemprop"
|
|
|
|
// Tokens
|
|
const int WeaponToken = 9809;
|
|
const int CostOfAcid = 9711; // All elemental damages use this.
|
|
const int CostOfHaste = 9712;
|
|
const int CostOfKeen = 9713;
|
|
const int CostOfTrueSeeing = 9714;
|
|
const int CostOfSpellResistance = 9715;
|
|
const int CostOfRegeneration2 = 9716;
|
|
const int CostOfEnhancement = 9717;
|
|
|
|
// * Ranged
|
|
const int CostOfAttackBonus = 9611;
|
|
const int CostOfMighty5 = 9612;
|
|
const int CostOfMighty10 = 9613;
|
|
const int CostOfUnlimited3 = 9614;
|
|
|
|
// Prices
|
|
const int WS_COST_ACID_PROPERTY = 75000; // All elemental damages use this.
|
|
const int WS_COST_ATTACK_BONUS = 30000;
|
|
const int WS_COST_ENHANCEMENT_BONUS = 50000;
|
|
const int WS_COST_HASTE = 150000;
|
|
const int WS_COST_KEEN = 50000;
|
|
const int WS_COST_TRUESEEING = 30000;
|
|
const int WS_COST_SPELLRESISTANCE = 75000;
|
|
const int WS_COST_REGENERATION2 = 75000;
|
|
const int WS_COST_MIGHTY_5 = 50000;
|
|
const int WS_COST_MIGHTY_10 = 100000;
|
|
const int WS_COST_UNLIMITED_3 = 100000;
|
|
|
|
// * Other Constants -- needed to make "fake" constants for some item property
|
|
const int IP_CONST_WS_ATTACK_BONUS = 19000;
|
|
const int IP_CONST_WS_ENHANCEMENT_BONUS = 19001;
|
|
const int IP_CONST_WS_HASTE = 19002;
|
|
const int IP_CONST_WS_KEEN = 19003;
|
|
const int IP_CONST_WS_TRUESEEING = 19005;
|
|
const int IP_CONST_WS_SPELLRESISTANCE = 19006;
|
|
const int IP_CONST_WS_REGENERATION = 19007;
|
|
const int IP_CONST_WS_MIGHTY_5 = 19008;
|
|
const int IP_CONST_WS_MIGHTY_10 = 19009;
|
|
const int IP_CONST_WS_UNLIMITED_3 = 19010;
|
|
|
|
const int MAX_ENHANCEMENT_BONUS = 10;
|
|
const int MAX_ATTACK_BONUS = 10;
|
|
|
|
//****************************************************
|
|
// * Declaration
|
|
//****************************************************
|
|
void SetWeaponToken(object oPC);
|
|
// * Function checks against WS_ properties to
|
|
// * see if its okay to add this item property
|
|
int IsOkToAdd(object oPC, int nPropertyCode);
|
|
object GetRightHandWeapon(object oPC);
|
|
// * sets all custom tokens for the prices of services
|
|
void wsSetupPrices();
|
|
// * A variable has been set earlier to indicate
|
|
// * which item property you want to add
|
|
// * now it tests to see if you have enough
|
|
// * gold for that item property
|
|
int wsHaveEnoughGoldForCurrentItemProperty(object oPC);
|
|
// * MAJOR
|
|
// * Actual function to add the enhancement to the item
|
|
void wsEnhanceItem(object oWielder, object oPC);
|
|
// * Returns the correct item proeprty based upon nType
|
|
// * oItem is passed in to find specific information about the
|
|
// * current item
|
|
itemproperty ReturnItemPropertyToUse(int nType, object oItem);
|
|
// * Returns total attack bonus for the item
|
|
int ReturnAttackBonus(object oItem);
|
|
// * Returns total enhancement bonus for the item
|
|
int ReturnEnhancementBonus(object oItem);
|
|
// * Returns total AC bonus for the item
|
|
int ReturnACBonus(object oItem);
|
|
// Returns TRUE if the item has this property - only checks base properties
|
|
int GetHasItemProperty(object oItem, int nProperty);
|
|
|
|
//****************************************************
|
|
// * Implementation
|
|
//****************************************************
|
|
|
|
void SetWeaponToken(object oPC)
|
|
{
|
|
// * Get Name of weapon
|
|
// * Assumption -- a weapon is being held
|
|
// * in the main hand
|
|
object oItem = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC);
|
|
string sWeaponName = "";
|
|
if (GetIsObjectValid(oItem) == TRUE)
|
|
{
|
|
sWeaponName = GetName(oItem);
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
SetCustomToken(WeaponToken, sWeaponName);
|
|
}
|
|
object GetRightHandWeapon(object oPC)
|
|
{
|
|
return GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC);
|
|
}
|
|
// * Function checks against WS_ properties to
|
|
// * see if its okay to add this item property
|
|
int IsOkToAdd(object oPC, int nPropertyCode)
|
|
{
|
|
object oItem = GetRightHandWeapon(oPC);
|
|
|
|
// * Always okay to add attack or enhancement bonuses, up to +10
|
|
if (nPropertyCode == IP_CONST_WS_ATTACK_BONUS)
|
|
{
|
|
if (ReturnAttackBonus(oItem) < MAX_ATTACK_BONUS)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
else
|
|
if (nPropertyCode == IP_CONST_WS_ENHANCEMENT_BONUS)
|
|
{
|
|
if (ReturnEnhancementBonus(oItem) < MAX_ENHANCEMENT_BONUS)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
itemproperty ip = ReturnItemPropertyToUse(nPropertyCode, oItem);
|
|
int nMatchSubType = TRUE;
|
|
|
|
|
|
// * Its okay to add these item properties as long as the subtype does not match
|
|
nMatchSubType = FALSE;
|
|
|
|
int bOkToAdd = IPGetItemHasProperty(oItem,ip, -1, TRUE);
|
|
if (bOkToAdd == FALSE)
|
|
{
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
// * this function added to balance out cost of very high magical item
|
|
// * modification (so its not super cheat to get a +10 weapon)
|
|
int InflateCost(int nGoldNeed)
|
|
{
|
|
// * Modifier (November 5 2003 -- Up the price if this item already
|
|
// * has numerous other enchancement bonuses
|
|
object oItem = GetRightHandWeapon(GetPCSpeaker());
|
|
int nBonus = ReturnEnhancementBonus(oItem);
|
|
if (nBonus > 4)
|
|
{
|
|
int nDiff = nBonus - 4;
|
|
nDiff = 20000 * nDiff; // * this is extra cost to add
|
|
nGoldNeed = nGoldNeed + nDiff;
|
|
}
|
|
return nGoldNeed;
|
|
}
|
|
|
|
|
|
// * sets all custom tokens for the prices of services
|
|
void wsSetupPrices()
|
|
{
|
|
SetCustomToken(CostOfAcid, IntToString(WS_COST_ACID_PROPERTY)); // * All elemental damages use this
|
|
SetCustomToken(CostOfAttackBonus, IntToString(WS_COST_ATTACK_BONUS));
|
|
SetCustomToken(CostOfEnhancement, IntToString(InflateCost(WS_COST_ENHANCEMENT_BONUS)));
|
|
|
|
SetCustomToken(CostOfHaste, IntToString(WS_COST_HASTE));
|
|
SetCustomToken(CostOfKeen, IntToString(WS_COST_KEEN));
|
|
SetCustomToken(CostOfTrueSeeing, IntToString(WS_COST_TRUESEEING));
|
|
SetCustomToken(CostOfSpellResistance, IntToString(WS_COST_SPELLRESISTANCE));
|
|
SetCustomToken(CostOfRegeneration2, IntToString(WS_COST_REGENERATION2));
|
|
|
|
SetCustomToken(CostOfMighty5, IntToString(WS_COST_MIGHTY_5));
|
|
SetCustomToken(CostOfMighty10, IntToString(WS_COST_MIGHTY_10));
|
|
SetCustomToken(CostOfUnlimited3, IntToString(WS_COST_UNLIMITED_3));
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
int GetGoldValueForService(int nService)
|
|
{
|
|
int nGoldNeed = 0;
|
|
switch (nService)
|
|
{
|
|
case IP_CONST_DAMAGETYPE_ACID:
|
|
case IP_CONST_DAMAGETYPE_FIRE:
|
|
case IP_CONST_DAMAGETYPE_COLD:
|
|
case IP_CONST_DAMAGETYPE_ELECTRICAL:
|
|
nGoldNeed = WS_COST_ACID_PROPERTY; break;
|
|
|
|
case IP_CONST_WS_ATTACK_BONUS: nGoldNeed = WS_COST_ATTACK_BONUS; break;
|
|
case IP_CONST_WS_ENHANCEMENT_BONUS:
|
|
{
|
|
nGoldNeed = WS_COST_ENHANCEMENT_BONUS;
|
|
nGoldNeed = InflateCost(nGoldNeed);
|
|
break;
|
|
}
|
|
case IP_CONST_WS_HASTE: nGoldNeed = WS_COST_HASTE; break;
|
|
case IP_CONST_WS_KEEN: nGoldNeed = WS_COST_KEEN;break;
|
|
case IP_CONST_WS_TRUESEEING: nGoldNeed = WS_COST_TRUESEEING;break;
|
|
case IP_CONST_WS_SPELLRESISTANCE: nGoldNeed = WS_COST_SPELLRESISTANCE; break;
|
|
case IP_CONST_WS_REGENERATION: nGoldNeed = WS_COST_REGENERATION2; break;
|
|
case IP_CONST_WS_MIGHTY_5: nGoldNeed = WS_COST_MIGHTY_5; break;
|
|
case IP_CONST_WS_MIGHTY_10: nGoldNeed = WS_COST_MIGHTY_10; break;
|
|
case IP_CONST_WS_UNLIMITED_3: nGoldNeed = WS_COST_UNLIMITED_3; break;
|
|
|
|
|
|
|
|
}
|
|
return nGoldNeed;
|
|
}
|
|
// * A variable has been set earlier to indicate
|
|
// * which item property you want to add
|
|
// * now it tests to see if you have enough
|
|
// * gold for that item property
|
|
int wsHaveEnoughGoldForCurrentItemProperty(object oPC)
|
|
{
|
|
int nGoldHave = GetGold(oPC);
|
|
int nCurrentItemProperty = GetLocalInt(OBJECT_SELF, "X2_LAST_PROPERTY");
|
|
int nGoldNeed = GetGoldValueForService(nCurrentItemProperty);
|
|
if (nGoldHave >= nGoldNeed)
|
|
{
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
// * Returns total attack bonus for the item
|
|
int ReturnAttackBonus(object oItem)
|
|
{
|
|
itemproperty ipFirst = GetFirstItemProperty(oItem);
|
|
int nBonus = 0;
|
|
while (GetIsItemPropertyValid(ipFirst) == TRUE)
|
|
{
|
|
if (GetItemPropertyType(ipFirst) == ITEM_PROPERTY_ATTACK_BONUS)
|
|
{
|
|
int nSubType = GetItemPropertyCostTableValue(ipFirst);
|
|
//SpeakString("Found an attack bonus! SubType = " + IntToString(nSubType));
|
|
nBonus = nBonus + (nSubType);
|
|
return nBonus; // * Quick exit. Got what I need
|
|
}
|
|
ipFirst = GetNextItemProperty(oItem);
|
|
}
|
|
//SpeakString("Attack Bonus = " + IntToString(nBonus));
|
|
return nBonus;
|
|
}
|
|
// * Returns total enhancement bonus for the item
|
|
int ReturnEnhancementBonus(object oItem)
|
|
{
|
|
itemproperty ipFirst = GetFirstItemProperty(oItem);
|
|
int nBonus = 0;
|
|
while (GetIsItemPropertyValid(ipFirst) == TRUE)
|
|
{
|
|
if (GetItemPropertyType(ipFirst) == ITEM_PROPERTY_ENHANCEMENT_BONUS)
|
|
{
|
|
int nSubType = GetItemPropertyCostTableValue(ipFirst);
|
|
//SpeakString("Found an attack bonus! SubType = " + IntToString(nSubType));
|
|
nBonus = nBonus + (nSubType);
|
|
return nBonus; // * Quick exit. Got what I need
|
|
}
|
|
ipFirst = GetNextItemProperty(oItem);
|
|
}
|
|
//SpeakString("Attack Bonus = " + IntToString(nBonus));
|
|
return nBonus;
|
|
}
|
|
|
|
// * Returns the correct item proeprty based upon nType
|
|
// * oItem is passed in to find specific information about the
|
|
// * current item
|
|
itemproperty ReturnItemPropertyToUse(int nType, object oItem)
|
|
{
|
|
itemproperty ip;
|
|
switch(nType)
|
|
{
|
|
case IP_CONST_DAMAGETYPE_ACID:
|
|
case IP_CONST_DAMAGETYPE_FIRE:
|
|
case IP_CONST_DAMAGETYPE_COLD:
|
|
case IP_CONST_DAMAGETYPE_ELECTRICAL:
|
|
{
|
|
ip =ItemPropertyDamageBonus(nType, IP_CONST_DAMAGEBONUS_2d6);
|
|
break;
|
|
}
|
|
case IP_CONST_WS_ATTACK_BONUS:
|
|
{
|
|
int nNewBonus = ReturnAttackBonus(oItem) + 1;
|
|
|
|
ip = ItemPropertyAttackBonus(nNewBonus);
|
|
break;
|
|
}
|
|
case IP_CONST_WS_ENHANCEMENT_BONUS:
|
|
{
|
|
|
|
int nNewBonus = ReturnEnhancementBonus(oItem) + 1;
|
|
|
|
ip = ItemPropertyEnhancementBonus(nNewBonus);
|
|
break;
|
|
}
|
|
case IP_CONST_WS_HASTE:
|
|
{
|
|
ip = ItemPropertyHaste();
|
|
break;
|
|
}
|
|
case IP_CONST_WS_KEEN:
|
|
{
|
|
ip = ItemPropertyKeen();
|
|
break;
|
|
}
|
|
case IP_CONST_WS_TRUESEEING:
|
|
{
|
|
ip = ItemPropertyTrueSeeing();
|
|
break;
|
|
}
|
|
case IP_CONST_WS_SPELLRESISTANCE:
|
|
{
|
|
ip = ItemPropertyBonusSpellResistance(IP_CONST_SPELLRESISTANCEBONUS_20);
|
|
break;
|
|
}
|
|
case IP_CONST_WS_REGENERATION:
|
|
{
|
|
ip = ItemPropertyRegeneration(2);
|
|
break;
|
|
}
|
|
case IP_CONST_WS_MIGHTY_5:
|
|
{
|
|
ip = ItemPropertyMaxRangeStrengthMod(5);
|
|
break;
|
|
}
|
|
case IP_CONST_WS_MIGHTY_10:
|
|
{
|
|
ip = ItemPropertyMaxRangeStrengthMod(10);
|
|
break;
|
|
}
|
|
case IP_CONST_WS_UNLIMITED_3:
|
|
{
|
|
ip = ItemPropertyUnlimitedAmmo(IP_CONST_UNLIMITEDAMMO_PLUS5);
|
|
break;
|
|
}
|
|
|
|
}
|
|
return ip;
|
|
|
|
}
|
|
// * MAJOR
|
|
// * Actual function to add the enhancement to the item
|
|
// * Also takes the gold
|
|
void wsEnhanceItem(object oWielder, object oPC)
|
|
{
|
|
object oItem = GetRightHandWeapon(oWielder);
|
|
int nCurrentItemProperty = GetLocalInt(OBJECT_SELF, "X2_LAST_PROPERTY");
|
|
int nGoldToTake = GetGoldValueForService(nCurrentItemProperty);
|
|
// SpeakString("Enhance " + GetName(oItem));
|
|
|
|
// * if player tries to cheat just abort the item creation. (You can only have
|
|
// * this happen by moving your gold out of your inventory as you are talking).
|
|
if (GetGold(oPC) < nGoldToTake)
|
|
{
|
|
return;
|
|
}
|
|
TakeGoldFromCreature(nGoldToTake, oPC, FALSE);
|
|
// * GZ: Remove all temporary item properties from oItem to counter bug #35259
|
|
IPRemoveAllItemProperties(oItem,DURATION_TYPE_TEMPORARY);
|
|
itemproperty ip = ReturnItemPropertyToUse(nCurrentItemProperty, oItem);
|
|
IPSafeAddItemProperty(oItem, ip, 0.0f, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
|
|
|
|
|
|
}
|
|
|
|
|
|
// * Returns total AC bonus for the item
|
|
int ReturnACBonus(object oItem)
|
|
{
|
|
itemproperty ipFirst = GetFirstItemProperty(oItem);
|
|
int nBonus = 0;
|
|
while (GetIsItemPropertyValid(ipFirst) == TRUE)
|
|
{
|
|
if (GetItemPropertyType(ipFirst) == ITEM_PROPERTY_AC_BONUS)
|
|
{
|
|
int nSubType = GetItemPropertyCostTableValue(ipFirst);
|
|
//SpeakString("Found an attack bonus! SubType = " + IntToString(nSubType));
|
|
nBonus = nBonus + (nSubType);
|
|
return nBonus; // * Quick exit. Got what I need
|
|
}
|
|
ipFirst = GetNextItemProperty(oItem);
|
|
}
|
|
//SpeakString("Attack Bonus = " + IntToString(nBonus));
|
|
return nBonus;
|
|
}
|
|
|
|
int GetHasItemProperty(object oItem, int nProperty)
|
|
{
|
|
itemproperty ip = GetFirstItemProperty(oItem);
|
|
|
|
// valid ip?
|
|
while (GetIsItemPropertyValid(ip))
|
|
{
|
|
// same property type?
|
|
if ((GetItemPropertyType(ip) == nProperty))
|
|
{
|
|
return TRUE;
|
|
}
|
|
ip = GetNextItemProperty(oItem);
|
|
}
|
|
return FALSE;
|
|
}
|