private static int GetWeaponPrice(CLRScriptBase script, uint target) { #region Initialize commonly-used variables int value = BaseItemValues[script.GetBaseItemType(target)]; int itemType = script.GetBaseItemType(target); int enchantmentPenalty = 0; bool masterworkCounted = false; int specialMat = script.GetItemBaseMaterialType(target); #endregion #region Load item properties into the price calculation collection List<PricedItemProperty> itProps = new List<PricedItemProperty>(); foreach(NWItemProperty prop in script.GetItemPropertiesOnItem(target)) { if (script.GetItemPropertyDurationType(prop) == DURATION_TYPE_PERMANENT) { itProps.Add(new PricedItemProperty() { Property = prop, Price = 0 }); } } #endregion #region Check for Mundane Items if (itProps.Count == 0 && (specialMat == GMATERIAL_METAL_IRON || specialMat == GMATERIAL_NONSPECIFIC)) { // No item properties. This is just worth the base item. if (GetIsAmmunition(itemType)) { value /= 100; } return value; } #endregion #region Clear out Properties that Come from Special Materials; Set Base Price By Special Materials if (specialMat != GMATERIAL_METAL_IRON && specialMat != GMATERIAL_NONSPECIFIC) { #region Adamantine if (specialMat == GMATERIAL_METAL_ADAMANTINE) { if (GetIsAmmunition(itemType)) { value += 1500; } else if (GetIsLightWeapon(itemType)) { value += 800; } else if (GetIsHeavyWeapon(itemType)) { value += 2000; } else { value += 1400; } if (!GetIsMasterwork(script, itProps)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyAttackBonus(1), target, 0.0f); } masterworkCounted = true; } #endregion #region Silver and Alchemical Silver else if (specialMat == GMATERIAL_METAL_ALCHEMICAL_SILVER) { if (GetIsAlchemicalSilver(script, itProps)) { if (GetIsAmmunition(itemType)) { value += 200; } else if (GetIsLightWeapon(itemType)) { value += 20; } else if (GetIsHeavyWeapon(itemType)) { value += 180; } else { value += 90; } } else { if (GetIsAmmunition(itemType)) { value += 1500; } else if (GetIsLightWeapon(itemType)) { value += 1500; } else if (GetIsHeavyWeapon(itemType)) { value += 3500; } else { value += 2500; } if (!GetIsMasterwork(script, itProps)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyAttackBonus(1), target, 0.0f); } masterworkCounted = true; } } #endregion #region Arandur else if (specialMat == GMATERIAL_ARANDUR) { if (GetIsAmmunition(itemType)) { value += 1000; if (!GetHasElementalWeaponBonus(script, itProps, IP_CONST_DAMAGETYPE_SONIC, IP_CONST_DAMAGEBONUS_1)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_SONIC, IP_CONST_DAMAGEBONUS_1), target, 0.0f); } } else if (GetIsLightWeapon(itemType)) { value += 2000; if (!GetHasElementalWeaponBonus(script, itProps, IP_CONST_DAMAGETYPE_SONIC, IP_CONST_DAMAGEBONUS_1)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_SONIC, IP_CONST_DAMAGEBONUS_1), target, 0.0f); } } else if (GetIsHeavyWeapon(itemType)) { value += 4000; if (!GetHasElementalWeaponBonus(script, itProps, IP_CONST_DAMAGETYPE_SONIC, IP_CONST_DAMAGEBONUS_1d3)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_SONIC, IP_CONST_DAMAGEBONUS_1d3), target, 0.0f); } } else { value += 3000; if (!GetHasElementalWeaponBonus(script, itProps, IP_CONST_DAMAGETYPE_SONIC, IP_CONST_DAMAGEBONUS_1d2)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_SONIC, IP_CONST_DAMAGEBONUS_1d2), target, 0.0f); } } } #endregion #region Bluewood else if (specialMat == GMATERIAL_BLUEWOOD) { if (GetIsAmmunition(itemType)) { value += 400; } else if (GetIsLightWeapon(itemType)) { value += 400; } else if (GetIsHeavyWeapon(itemType)) { value += 900; } else { value += 600; } if(!GetIsHalfWeight(script, itProps)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyWeightReduction(IP_CONST_REDUCEDWEIGHT_50_PERCENT), target, 0.0f); } if (!GetIsMasterwork(script, itProps)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyAttackBonus(1), target, 0.0f); } masterworkCounted = true; } #endregion #region Cold Iron else if (specialMat == GMATERIAL_METAL_COLD_IRON) { value += BaseItemValues[script.GetBaseItemType(target)]; enchantmentPenalty = 2000; } #endregion #region Copper // Copper weapons have no special properties or pricing. #endregion #region Darksteel else if (specialMat == GMATERIAL_METAL_DARKSTEEL) { if (GetIsAmmunition(itemType)) { value += 1000; if (!GetHasElementalWeaponBonus(script, itProps, IP_CONST_DAMAGETYPE_ELECTRICAL, IP_CONST_DAMAGEBONUS_1)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_ELECTRICAL, IP_CONST_DAMAGEBONUS_1), target, 0.0f); } } else if (GetIsLightWeapon(itemType)) { value += 2000; if (!GetHasElementalWeaponBonus(script, itProps, IP_CONST_DAMAGETYPE_ELECTRICAL, IP_CONST_DAMAGEBONUS_1)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_ELECTRICAL, IP_CONST_DAMAGEBONUS_1), target, 0.0f); } } else if (GetIsHeavyWeapon(itemType)) { value += 4000; if (!GetHasElementalWeaponBonus(script, itProps, IP_CONST_DAMAGETYPE_ELECTRICAL, IP_CONST_DAMAGEBONUS_1d3)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_ELECTRICAL, IP_CONST_DAMAGEBONUS_1d3), target, 0.0f); } } else { value += 3000; if (!GetHasElementalWeaponBonus(script, itProps, IP_CONST_DAMAGETYPE_ELECTRICAL, IP_CONST_DAMAGEBONUS_1d2)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_ELECTRICAL, IP_CONST_DAMAGEBONUS_1d2), target, 0.0f); } } if (!GetIsMasterwork(script, itProps)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyAttackBonus(1), target, 0.0f); } masterworkCounted = true; } #endregion #region Dlarun else if (specialMat == GMATERIAL_DLARUN) { if (GetIsAmmunition(itemType)) { value += 1000; if (!GetHasElementalWeaponBonus(script, itProps, IP_CONST_DAMAGETYPE_COLD, IP_CONST_DAMAGEBONUS_1)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_COLD, IP_CONST_DAMAGEBONUS_1), target, 0.0f); } } else if (GetIsLightWeapon(itemType)) { value += 2000; if (!GetHasElementalWeaponBonus(script, itProps, IP_CONST_DAMAGETYPE_COLD, IP_CONST_DAMAGEBONUS_1)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_COLD, IP_CONST_DAMAGEBONUS_1), target, 0.0f); } } else if (GetIsHeavyWeapon(itemType)) { value += 4000; if (!GetHasElementalWeaponBonus(script, itProps, IP_CONST_DAMAGETYPE_COLD, IP_CONST_DAMAGEBONUS_1d3)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_COLD, IP_CONST_DAMAGEBONUS_1d3), target, 0.0f); } } else { value += 3000; if (!GetHasElementalWeaponBonus(script, itProps, IP_CONST_DAMAGETYPE_COLD, IP_CONST_DAMAGEBONUS_1d2)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_COLD, IP_CONST_DAMAGEBONUS_1d2), target, 0.0f); } } if (!GetIsMasterwork(script, itProps)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyAttackBonus(1), target, 0.0f); } masterworkCounted = true; } #endregion #region Black, Green, or Copper Dragon else if (specialMat == GMATERIAL_CREATURE_BLACK_DRAGON || specialMat == GMATERIAL_CREATURE_GREEN_DRAGON || specialMat == GMATERIAL_CREATURE_COPPER_DRAGON) { value += 2000; if (!GetHasElementalWeaponBonus(script, itProps, IP_CONST_DAMAGETYPE_ACID, IP_CONST_DAMAGEBONUS_1)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_ACID, IP_CONST_DAMAGEBONUS_1), target, 0.0f); } if (!GetIsMasterwork(script, itProps)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyAttackBonus(1), target, 0.0f); } masterworkCounted = true; } #endregion #region Blue or Brass Dragon else if (specialMat == GMATERIAL_CREATURE_BLUE_DRAGON || specialMat == GMATERIAL_CREATURE_BRONZE_DRAGON) { value += 2000; if (!GetHasElementalWeaponBonus(script, itProps, IP_CONST_DAMAGETYPE_ELECTRICAL, IP_CONST_DAMAGEBONUS_1)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_ELECTRICAL, IP_CONST_DAMAGEBONUS_1), target, 0.0f); } if (!GetIsMasterwork(script, itProps)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyAttackBonus(1), target, 0.0f); } masterworkCounted = true; } #endregion #region Red, Brass, or Gold Dragon else if (specialMat == GMATERIAL_CREATURE_RED_DRAGON || specialMat == GMATERIAL_CREATURE_BRASS_DRAGON || specialMat == GMATERIAL_CREATURE_GOLD_DRAGON) { value += 2000; if (!GetHasElementalWeaponBonus(script, itProps, IP_CONST_DAMAGETYPE_FIRE, IP_CONST_DAMAGEBONUS_1)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE, IP_CONST_DAMAGEBONUS_1), target, 0.0f); } if (!GetIsMasterwork(script, itProps)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyAttackBonus(1), target, 0.0f); } masterworkCounted = true; } #endregion #region White or Silver Dragon else if (specialMat == GMATERIAL_CREATURE_WHITE_DRAGON || specialMat == GMATERIAL_CREATURE_SILVER_DRAGON) { value += 2000; if (!GetHasElementalWeaponBonus(script, itProps, IP_CONST_DAMAGETYPE_COLD, IP_CONST_DAMAGEBONUS_1)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_COLD, IP_CONST_DAMAGEBONUS_1), target, 0.0f); } if (!GetIsMasterwork(script, itProps)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyAttackBonus(1), target, 0.0f); } masterworkCounted = true; } #endregion #region Duskwood else if (specialMat == GMATERIAL_WOOD_DUSKWOOD) { value += 1000; if (!GetIsMasterwork(script, itProps)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyAttackBonus(1), target, 0.0f); } masterworkCounted = true; } #endregion #region Fever Iron else if (specialMat == GMATERIAL_FEVER_IRON) { if (GetIsAmmunition(itemType)) { value += 1000; if (!GetHasElementalWeaponBonus(script, itProps, IP_CONST_DAMAGETYPE_FIRE, IP_CONST_DAMAGEBONUS_1)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE, IP_CONST_DAMAGEBONUS_1), target, 0.0f); } } else if (GetIsLightWeapon(itemType)) { value += 2000; if (!GetHasElementalWeaponBonus(script, itProps, IP_CONST_DAMAGETYPE_FIRE, IP_CONST_DAMAGEBONUS_1)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE, IP_CONST_DAMAGEBONUS_1), target, 0.0f); } } else if (GetIsHeavyWeapon(itemType)) { value += 4000; if (!GetHasElementalWeaponBonus(script, itProps, IP_CONST_DAMAGETYPE_FIRE, IP_CONST_DAMAGEBONUS_1d3)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE, IP_CONST_DAMAGEBONUS_1d3), target, 0.0f); } } else { value += 3000; if (!GetHasElementalWeaponBonus(script, itProps, IP_CONST_DAMAGETYPE_FIRE, IP_CONST_DAMAGEBONUS_1d2)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE, IP_CONST_DAMAGEBONUS_1d2), target, 0.0f); } } if (!GetIsMasterwork(script, itProps)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyAttackBonus(1), target, 0.0f); } masterworkCounted = true; } #endregion #region Fiend Bone else if (specialMat == GMATERIAL_FIENDBONE) { if (GetIsAmmunition(itemType)) { value += 1500; } else if (GetIsLightWeapon(itemType)) { value += 1500; } else if (GetIsHeavyWeapon(itemType)) { value += 3500; } else { value += 2500; } if(!GetHasVersusAlignmentBonus(script, itProps, IP_CONST_ALIGNMENTGROUP_GOOD, IP_CONST_DAMAGEBONUS_1)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonusVsAlign(IP_CONST_ALIGNMENTGROUP_GOOD, IP_CONST_DAMAGETYPE_MAGICAL, IP_CONST_DAMAGEBONUS_1), target, 0.0f); } if (!GetIsMasterwork(script, itProps)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyAttackBonus(1), target, 0.0f); } masterworkCounted = true; } #endregion #region Frystalline else if (specialMat == GMATERIAL_FRYSTALLINE) { if (GetIsAmmunition(itemType)) { value += 1500; } else if (GetIsLightWeapon(itemType)) { value += 1500; } else if (GetIsHeavyWeapon(itemType)) { value += 3500; } else { value += 2500; } if (!GetHasVersusAlignmentBonus(script, itProps, IP_CONST_ALIGNMENTGROUP_EVIL, IP_CONST_DAMAGEBONUS_1)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonusVsAlign(IP_CONST_ALIGNMENTGROUP_EVIL, IP_CONST_DAMAGETYPE_MAGICAL, IP_CONST_DAMAGEBONUS_1), target, 0.0f); } if (!GetIsMasterwork(script, itProps)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyAttackBonus(1), target, 0.0f); } masterworkCounted = true; } #endregion #region Gold else if (specialMat == GMATERIAL_GOLD) { if (GetIsAmmunition(itemType)) { value += 1500; } else if (GetIsLightWeapon(itemType)) { value += 1500; } else if (GetIsHeavyWeapon(itemType)) { value += 2500; } else { value += 3500; } if (!GetIsMasterwork(script, itProps)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyAttackBonus(1), target, 0.0f); } masterworkCounted = true; } #endregion #region Hizagkuur else if (specialMat == GMATERIAL_FEVER_IRON) { if (GetIsAmmunition(itemType)) { value += 1000; if (!GetHasElementalWeaponBonus(script, itProps, IP_CONST_DAMAGETYPE_FIRE, IP_CONST_DAMAGEBONUS_1)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE, IP_CONST_DAMAGEBONUS_1), target, 0.0f); } } else if (GetIsLightWeapon(itemType)) { value += 2000; if (!GetHasElementalWeaponBonus(script, itProps, IP_CONST_DAMAGETYPE_FIRE, IP_CONST_DAMAGEBONUS_1)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE, IP_CONST_DAMAGEBONUS_1), target, 0.0f); } } else if (GetIsHeavyWeapon(itemType)) { value += 4000; if (!GetHasElementalWeaponBonus(script, itProps, IP_CONST_DAMAGETYPE_FIRE, IP_CONST_DAMAGEBONUS_1d3)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE, IP_CONST_DAMAGEBONUS_1d3), target, 0.0f); } } else { value += 3000; if (!GetHasElementalWeaponBonus(script, itProps, IP_CONST_DAMAGETYPE_FIRE, IP_CONST_DAMAGEBONUS_1d2)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE, IP_CONST_DAMAGEBONUS_1d2), target, 0.0f); } } if (!GetIsMasterwork(script, itProps)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyAttackBonus(1), target, 0.0f); } masterworkCounted = true; } #endregion #region Living Metal else if (specialMat == GMATERIAL_LIVING_METAL) { value += 1000; if (!GetIsMasterwork(script, itProps)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyAttackBonus(1), target, 0.0f); } masterworkCounted = true; } #endregion #region Mithral else if (specialMat == GMATERIAL_METAL_MITHRAL) { if (GetIsAmmunition(itemType)) { value += 1000; } else if (GetIsLightWeapon(itemType)) { value += 1000; } else if (GetIsHeavyWeapon(itemType)) { value += 12000; } else { value += 6000; } if (!GetIsHalfWeight(script, itProps)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyWeightReduction(IP_CONST_REDUCEDWEIGHT_50_PERCENT), target, 0.0f); } if (!GetIsMasterwork(script, itProps)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyAttackBonus(1), target, 0.0f); } masterworkCounted = true; } #endregion #region Platinum // Platinum has no special properties as a weapon. #endregion #region Sondarr else if (specialMat == GMATERIAL_LIVING_METAL) { value += 1000; } #endregion #region Zalantar else if (specialMat == GMATERIAL_WOOD_DARKWOOD) { if (GetIsAmmunition(itemType)) { value += 300; } else if (GetIsLightWeapon(itemType)) { value += 300; } else if (GetIsHeavyWeapon(itemType)) { value += 300; } else { value += 300; } int addedVal = 0; if (int.TryParse(script.Get2DAString("baseitems", "TenthLBS", itemType), out addedVal)) { value += addedVal; } if (!GetIsHalfWeight(script, itProps)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyWeightReduction(IP_CONST_REDUCEDWEIGHT_50_PERCENT), target, 0.0f); } if (!GetIsMasterwork(script, itProps)) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyAttackBonus(1), target, 0.0f); } masterworkCounted = true; } #endregion } #endregion #region Check for masterwork and mighty bonuses if (!masterworkCounted) { if (GetIsAmmunition(itemType)) { if (GetIsMasterworkAmmunition(script, itProps)) { value += 300; } } else if (GetIsMasterwork(script, itProps)) { value += 300; } } foreach (PricedItemProperty prop in itProps) { if (script.GetItemPropertyType(prop.Property) == ITEM_PROPERTY_MIGHTY) { if (itemType == BASE_ITEM_LONGBOW || itemType == BASE_ITEM_HEAVYCROSSBOW) { value += (100 * script.GetItemPropertyCostTableValue(prop.Property)); } else { value += (75 * script.GetItemPropertyCostTableValue(prop.Property)); } } } #endregion #region Check for early return, if the item is only masterwork or special material if (itProps.Count == 0) { if (GetIsAmmunition(itemType)) { value /= 100; } return value; } #endregion #region Check for Use Restriction bool IsClassRestricted = GetIsUseRestrictedByClass(script, itProps); #endregion #region Calculate Magical Bonuses float effectivePlus = 0.0f; int ACvsEveryone = 0; int attackVsEveryone = 0; int enhancementVsEveryone = 0; #region Properties that are Indiscriminate foreach (PricedItemProperty prop in itProps) { int propType = script.GetItemPropertyType(prop.Property); switch (propType) { #region Ability Score Bonus case ITEM_PROPERTY_ABILITY_BONUS: { prop.Price = (script.GetItemPropertyCostTableValue(prop.Property) * script.GetItemPropertyCostTableValue(prop.Property) * 1000); break; } #endregion #region Bonus Armor Class case ITEM_PROPERTY_AC_BONUS: { if (script.GetItemPropertyCostTableValue(prop.Property) > ACvsEveryone) { ACvsEveryone = script.GetItemPropertyCostTableValue(prop.Property); } prop.Price = (ACvsEveryone * ACvsEveryone * 2000); break; } #endregion #region Magical Attack Bonus case ITEM_PROPERTY_ATTACK_BONUS: { attackVsEveryone = script.GetItemPropertyCostTableValue(prop.Property); effectivePlus += attackVsEveryone; break; } #endregion #region Base Item Weight Reduction case ITEM_PROPERTY_BASE_ITEM_WEIGHT_REDUCTION: { // Question: do we call this item illegal? break; } #endregion #region Bonus Feat (disarm only) case ITEM_PROPERTY_BONUS_FEAT: { if (script.GetItemPropertySubType(prop.Property) == IP_CONST_FEAT_DISARM) { effectivePlus += 0.5f; } else { if(debug) script.SendMessageToAllDMs("Illegal weapon because it provides an unsupported feat"); return -1; } break; } #endregion #region Bonus Spell Slot case ITEM_PROPERTY_BONUS_SPELL_SLOT_OF_LEVEL_N: { int level = script.GetItemPropertyCostTableValue(prop.Property); if (level == 0) { prop.Price = 500; } else { prop.Price = level * level * 1000; } break; } #endregion #region Cast Spell case ITEM_PROPERTY_CAST_SPELL: { int spell = script.GetItemPropertySubType(prop.Property); if (spell == IP_CONST_CASTSPELL_ACTIVATE_ITEM || spell == IP_CONST_CASTSPELL_UNIQUE_POWER || spell == IP_CONST_CASTSPELL_UNIQUE_POWER_SELF_ONLY) { // We can't price these, as their powers are custom scripted. return -2; } float spellLevel = 0.0f; float casterLevel = 0.0f; float.TryParse(script.Get2DAString("iprp_spells", "InnateLvl", spell), out spellLevel); float.TryParse(script.Get2DAString("iprp_spells", "CasterLvl", spell), out casterLevel); if (spellLevel < 0.5f) { spellLevel = 0.5f; } if (casterLevel < 1.0f) { casterLevel = 1.0f; } float multiplier = spellLevel * casterLevel; switch (script.GetItemPropertyCostTableValue(prop.Property)) { case IP_CONST_CASTSPELL_NUMUSES_0_CHARGES_PER_USE: { if (debug) script.SendMessageToAllDMs("Illegal weapon because it provides infinite spellcasting"); return -1; } case IP_CONST_CASTSPELL_NUMUSES_1_CHARGE_PER_USE: { prop.ChargedPrice = (int)(multiplier * 36); break; } case IP_CONST_CASTSPELL_NUMUSES_1_USE_PER_DAY: { prop.Price = (int)(multiplier * 360); break; } case IP_CONST_CASTSPELL_NUMUSES_2_CHARGES_PER_USE: { prop.ChargedPrice = (int)(multiplier * 18); break; } case IP_CONST_CASTSPELL_NUMUSES_2_USES_PER_DAY: { prop.Price = (int)(multiplier * 720); break; } case IP_CONST_CASTSPELL_NUMUSES_3_CHARGES_PER_USE: { prop.ChargedPrice = (int)(multiplier * 12); break; } case IP_CONST_CASTSPELL_NUMUSES_3_USES_PER_DAY: { prop.Price = (int)(multiplier * 1080); break; } case IP_CONST_CASTSPELL_NUMUSES_4_CHARGES_PER_USE: { prop.ChargedPrice = (int)(multiplier * 9); break; } case IP_CONST_CASTSPELL_NUMUSES_4_USES_PER_DAY: { prop.Price = (int)(multiplier * 1440); break; } case IP_CONST_CASTSPELL_NUMUSES_5_CHARGES_PER_USE: { prop.ChargedPrice = (int)(multiplier * 7); break; } case IP_CONST_CASTSPELL_NUMUSES_5_USES_PER_DAY: { prop.Price = (int)(multiplier * 1800); break; } case IP_CONST_CASTSPELL_NUMUSES_SINGLE_USE: { if (script.GetItemCharges(target) > 0) { if (IsClassRestricted) { prop.ChargedPrice = (int)((multiplier * 25) / script.GetItemCharges(target)); } else { prop.ChargedPrice = (int)((multiplier * 50) / script.GetItemCharges(target)); } } else { if (IsClassRestricted) { prop.Price = (int)(multiplier * 25); } else { prop.Price = (int)(multiplier * 50); } } break; } case IP_CONST_CASTSPELL_NUMUSES_UNLIMITED_USE: { if (debug) script.SendMessageToAllDMs("Illegal weapon because it provides infinite spellcasting"); return -1; } } break; } #endregion #region Damage Bonus case ITEM_PROPERTY_DAMAGE_BONUS: { switch (script.GetItemPropertySubType(prop.Property)) { case IP_CONST_DAMAGETYPE_ACID: case IP_CONST_DAMAGETYPE_BLUDGEONING: case IP_CONST_DAMAGETYPE_COLD: case IP_CONST_DAMAGETYPE_ELECTRICAL: case IP_CONST_DAMAGETYPE_FIRE: case IP_CONST_DAMAGETYPE_PHYSICAL: case IP_CONST_DAMAGETYPE_PIERCING: case IP_CONST_DAMAGETYPE_SLASHING: case IP_CONST_DAMAGETYPE_SONIC: case IP_CONST_DAMAGETYPE_SUBDUAL: { switch (script.GetItemPropertyCostTableValue(prop.Property)) { case IP_CONST_DAMAGEBONUS_1d4: { effectivePlus += 1.0f; break; } case IP_CONST_DAMAGEBONUS_1d6: { effectivePlus += 1.5f; break; } case IP_CONST_DAMAGEBONUS_1d8: { effectivePlus += 2.2f; break; } case IP_CONST_DAMAGEBONUS_1: { effectivePlus += 0.4f; break; } case IP_CONST_DAMAGEBONUS_2: { effectivePlus += 0.8f; break; } case IP_CONST_DAMAGEBONUS_3: { effectivePlus += 1.2f; break; } case IP_CONST_DAMAGEBONUS_4: { effectivePlus += 1.6f; break; } case IP_CONST_DAMAGEBONUS_5: { effectivePlus += 2.0f; break; } default: { if (debug) script.SendMessageToAllDMs("Illegal weapon because it provides an unsupported damage bonus"); return -1; } } break; } case IP_CONST_DAMAGETYPE_NEGATIVE: { switch (script.GetItemPropertyCostTableValue(prop.Property)) { case IP_CONST_DAMAGEBONUS_1d4: { effectivePlus += 1.1f; break; } case IP_CONST_DAMAGEBONUS_1d6: { effectivePlus += 1.7f; break; } case IP_CONST_DAMAGEBONUS_1d8: { effectivePlus += 2.4f; break; } case IP_CONST_DAMAGEBONUS_1: { effectivePlus += 0.5f; break; } case IP_CONST_DAMAGEBONUS_2: { effectivePlus += 0.9f; break; } case IP_CONST_DAMAGEBONUS_3: { effectivePlus += 1.3f; break; } case IP_CONST_DAMAGEBONUS_4: { effectivePlus += 1.8f; break; } case IP_CONST_DAMAGEBONUS_5: { effectivePlus += 2.2f; break; } default: { if (debug) script.SendMessageToAllDMs("Illegal weapon because it provides an unsupported damage bonus"); return -1; } } break; } case IP_CONST_DAMAGETYPE_DIVINE: case IP_CONST_DAMAGETYPE_MAGICAL: case IP_CONST_DAMAGETYPE_POSITIVE: { switch (script.GetItemPropertyCostTableValue(prop.Property)) { case IP_CONST_DAMAGEBONUS_1d4: { effectivePlus += 1.3f; break; } case IP_CONST_DAMAGEBONUS_1d6: { effectivePlus += 2.0f; break; } case IP_CONST_DAMAGEBONUS_1d8: { effectivePlus += 2.7f; break; } case IP_CONST_DAMAGEBONUS_1: { effectivePlus += 0.7f; break; } case IP_CONST_DAMAGEBONUS_2: { effectivePlus += 1.1f; break; } case IP_CONST_DAMAGEBONUS_3: { effectivePlus += 1.5f; break; } case IP_CONST_DAMAGEBONUS_4: { effectivePlus += 2.1f; break; } case IP_CONST_DAMAGEBONUS_5: { effectivePlus += 2.5f; break; } default: { if (debug) script.SendMessageToAllDMs("Illegal weapon because it provides an unsupported damage bonus"); return -1; } } break; } } break; } #endregion #region Damage Resistance case ITEM_PROPERTY_DAMAGE_RESISTANCE: { switch (script.GetItemPropertySubType(prop.Property)) { case IP_CONST_DAMAGETYPE_ACID: case IP_CONST_DAMAGETYPE_COLD: case IP_CONST_DAMAGETYPE_ELECTRICAL: case IP_CONST_DAMAGETYPE_FIRE: case IP_CONST_DAMAGETYPE_SONIC: { switch (script.GetItemPropertyCostTableValue(prop.Property)) { case IP_CONST_DAMAGERESIST_5: { prop.Price = 4000; break; } case IP_CONST_DAMAGERESIST_10: { prop.Price = 12000; break; } case IP_CONST_DAMAGERESIST_15: { prop.Price = 20000; break; } case IP_CONST_DAMAGERESIST_20: { prop.Price = 28000; break; } case IP_CONST_DAMAGERESIST_25: { prop.Price = 36000; break; } case IP_CONST_DAMAGERESIST_30: { prop.Price = 44000; break; } default: { if (debug) script.SendMessageToAllDMs("Illegal weapon because it provides an unsupported damage resistance"); return -1; } } break; } case IP_CONST_DAMAGETYPE_NEGATIVE: { switch (script.GetItemPropertyCostTableValue(prop.Property)) { case IP_CONST_DAMAGERESIST_5: { prop.Price = 6000; break; } case IP_CONST_DAMAGERESIST_10: { prop.Price = 18000; break; } case IP_CONST_DAMAGERESIST_15: { prop.Price = 30000; break; } case IP_CONST_DAMAGERESIST_20: { prop.Price = 42000; break; } case IP_CONST_DAMAGERESIST_25: { prop.Price = 54000; break; } case IP_CONST_DAMAGERESIST_30: { prop.Price = 66000; break; } default: { if (debug) script.SendMessageToAllDMs("Illegal weapon because it provides an unsupported damage resistance"); return -1; } } break; } default: { if (debug) script.SendMessageToAllDMs("Illegal weapon because it provides an illegal type of damage resistance"); return -1; } } break; } #endregion #region Freedom of Movement case ITEM_PROPERTY_FREEDOM_OF_MOVEMENT: { prop.Price = 40000; break; } #endregion #region Enhancement Bonus case ITEM_PROPERTY_ENHANCEMENT_BONUS: { enhancementVsEveryone = script.GetItemPropertyCostTableValue(prop.Property); effectivePlus += enhancementVsEveryone; break; } #endregion #region Immunities case ITEM_PROPERTY_IMMUNITY_MISCELLANEOUS: { switch (script.GetItemPropertySubType(prop.Property)) { case IP_CONST_IMMUNITYMISC_DEATH_MAGIC: { prop.Price = 80000; break; } case IP_CONST_IMMUNITYMISC_DISEASE: { prop.Price = 7500; break; } case IP_CONST_IMMUNITYMISC_FEAR: { prop.Price = 10000; break; } case IP_CONST_IMMUNITYMISC_KNOCKDOWN: { prop.Price = 22500; break; } case IP_CONST_IMMUNITYMISC_LEVEL_ABIL_DRAIN: { prop.Price = 40000; break; } case IP_CONST_IMMUNITYMISC_PARALYSIS: { prop.Price = 15000; break; } case IP_CONST_IMMUNITYMISC_POISON: { prop.Price = 25000; break; } default: { if (debug) script.SendMessageToAllDMs("Illegal weapon because it provides a disallowed immunity"); return -1; } } break; } #endregion #region Immunity to Specific Spell case ITEM_PROPERTY_IMMUNITY_SPECIFIC_SPELL: { float spellLevel = 0.0f; float.TryParse(script.Get2DAString("spells", "Innate", script.GetItemPropertyCostTableValue(prop.Property)), out spellLevel); if (spellLevel < 0.5f) { spellLevel = 0.5f; } prop.Price = (int)(((spellLevel * spellLevel) + 1) * 1000); break; } #endregion #region Keen case ITEM_PROPERTY_KEEN: { effectivePlus += 1.0f; break; } #endregion #region Light case ITEM_PROPERTY_LIGHT: { prop.Price = script.GetItemPropertyCostTableValue(prop.Property) * 100; break; } #endregion #region Massive Criticals case ITEM_PROPERTY_MASSIVE_CRITICALS: { switch (script.GetItemPropertyCostTableValue(prop.Property)) { case IP_CONST_DAMAGEBONUS_1d4: { effectivePlus += 0.3f; break; } case IP_CONST_DAMAGEBONUS_1d6: { effectivePlus += 0.4f; break; } case IP_CONST_DAMAGEBONUS_1d8: { effectivePlus += 0.6f; break; } case IP_CONST_DAMAGEBONUS_1d10: { effectivePlus += 0.8f; break; } case IP_CONST_DAMAGEBONUS_1d12: { effectivePlus += 1.0f; break; } case IP_CONST_DAMAGEBONUS_2d4: { effectivePlus += 0.7f; break; } case IP_CONST_DAMAGEBONUS_2d6: { effectivePlus += 1.1f; break; } case IP_CONST_DAMAGEBONUS_1: { effectivePlus += 0.1f; break; } case IP_CONST_DAMAGEBONUS_2: { effectivePlus += 0.2f; break; } case IP_CONST_DAMAGEBONUS_3: { effectivePlus += 0.3f; break; } case IP_CONST_DAMAGEBONUS_4: { effectivePlus += 0.4f; break; } case IP_CONST_DAMAGEBONUS_5: { effectivePlus += 0.6f; break; } case IP_CONST_DAMAGEBONUS_6: { effectivePlus += 0.8f; break; } } break; } #endregion #region Regeneration: Vampiric case ITEM_PROPERTY_REGENERATION_VAMPIRIC: { int val = script.GetItemPropertyCostTableValue(prop.Property); if (val > 2) { if (debug) script.SendMessageToAllDMs("Illegal weapon because it provides more than 2 points of vampiric regeneration"); return -1; } effectivePlus = val * 0.5f; break; } #endregion #region Bonus to Saving Throw Subtypes case ITEM_PROPERTY_SAVING_THROW_BONUS: { int val = script.GetItemPropertyCostTableValue(prop.Property); if (val > 5) { if (debug) script.SendMessageToAllDMs("Illegal weapon because it provides a bonus to saving throws greater than five"); return -1; } if (script.GetItemPropertySubType(prop.Property) == IP_CONST_SAVEVS_UNIVERSAL) { prop.Price = (val * val) * 1000; } else if (script.GetItemPropertyCostTableValue(prop.Property) == IP_CONST_SAVEVS_MINDAFFECTING) { prop.Price = (val * val) * 500; } else { prop.Price = (val * val) * 250; } break; } #endregion #region Bonus to Saving Throw Types case ITEM_PROPERTY_SAVING_THROW_BONUS_SPECIFIC: { int val = script.GetItemPropertyCostTableValue(prop.Property); if (val > 5) { if (debug) script.SendMessageToAllDMs("Illegal weapon because it provides a saving throw bonus greater than five."); return -1; } prop.Price = (val * val) * 250; break; } #endregion #region Skill Bonus case ITEM_PROPERTY_SKILL_BONUS: { int val = script.GetItemPropertyCostTableValue(prop.Property); prop.Price = (val * val) * 100; break; } #endregion #region Spell Resistance case ITEM_PROPERTY_SPELL_RESISTANCE: { switch (script.GetItemPropertyCostTableValue(prop.Property)) { case IP_CONST_SPELLRESISTANCEBONUS_10: { prop.Price = 6000; break; } case IP_CONST_SPELLRESISTANCEBONUS_12: { prop.Price = 10000; break; } case IP_CONST_SPELLRESISTANCEBONUS_14: { prop.Price = 20000; break; } case IP_CONST_SPELLRESISTANCEBONUS_16: { prop.Price = 40000; break; } case IP_CONST_SPELLRESISTANCEBONUS_18: { prop.Price = 60000; break; } case IP_CONST_SPELLRESISTANCEBONUS_20: { prop.Price = 80000; break; } case IP_CONST_SPELLRESISTANCEBONUS_22: { prop.Price = 100000; break; } case IP_CONST_SPELLRESISTANCEBONUS_24: { prop.Price = 120000; break; } case IP_CONST_SPELLRESISTANCEBONUS_26: { prop.Price = 140000; break; } default: { if (debug) script.SendMessageToAllDMs("Illegal weapon because it provides a spell resistance bonus greater than 26."); return -1; } } break; } #endregion #region Unlimited Ammunition case ITEM_PROPERTY_UNLIMITED_AMMUNITION: { effectivePlus += 0.5f; switch (script.GetItemPropertyCostTableValue(prop.Property)) { // Basic unlimited ammo just has the 0.5 above. case IP_CONST_UNLIMITEDAMMO_BASIC: { break; } // These are bonus elemental damage. Price as such. case IP_CONST_UNLIMITEDAMMO_1D6COLD: case IP_CONST_UNLIMITEDAMMO_1D6FIRE: case IP_CONST_UNLIMITEDAMMO_1D6LIGHT: { effectivePlus += 1.5f; break; } // These are actually only bonus physical damage. Price as such. case IP_CONST_UNLIMITEDAMMO_PLUS1: { effectivePlus += +0.4f; break; } case IP_CONST_UNLIMITEDAMMO_PLUS2: { effectivePlus += 0.8f; break; } case IP_CONST_UNLIMITEDAMMO_PLUS3: { effectivePlus += 1.2f; break; } case IP_CONST_UNLIMITEDAMMO_PLUS4: { effectivePlus += 1.6f; break; } case IP_CONST_UNLIMITEDAMMO_PLUS5: { effectivePlus += 2.0f; break; } default: { if (debug) script.SendMessageToAllDMs("Illegal weapon because it provides a variety of unlimited ammunition which is illegal."); return -1; } } break; } #endregion #region Banned Properties case ITEM_PROPERTY_BONUS_HITPOINTS: case ITEM_PROPERTY_DAMAGE_REDUCTION: case ITEM_PROPERTY_DARKVISION: case ITEM_PROPERTY_ENHANCED_CONTAINER_REDUCED_WEIGHT: case ITEM_PROPERTY_EXTRA_MELEE_DAMAGE_TYPE: case ITEM_PROPERTY_EXTRA_RANGED_DAMAGE_TYPE: case ITEM_PROPERTY_HASTE: case ITEM_PROPERTY_HEALERS_KIT: case ITEM_PROPERTY_HOLY_AVENGER: case ITEM_PROPERTY_IMMUNITY_DAMAGE_TYPE: case ITEM_PROPERTY_IMMUNITY_SPELL_SCHOOL: case ITEM_PROPERTY_IMMUNITY_SPELLS_BY_LEVEL: case ITEM_PROPERTY_IMPROVED_EVASION: case ITEM_PROPERTY_MIND_BLANK: case ITEM_PROPERTY_MONSTER_DAMAGE: case ITEM_PROPERTY_ON_HIT_PROPERTIES: case ITEM_PROPERTY_ON_MONSTER_HIT: case ITEM_PROPERTY_ONHITCASTSPELL: case ITEM_PROPERTY_POISON: case ITEM_PROPERTY_REGENERATION: case ITEM_PROPERTY_SPECIAL_WALK: case ITEM_PROPERTY_THIEVES_TOOLS: case ITEM_PROPERTY_TRAP: case ITEM_PROPERTY_TRUE_SEEING: case ITEM_PROPERTY_TURN_RESISTANCE: { if (debug) script.SendMessageToAllDMs("Illegal weapon because it provides an illegal property base type."); return -1; } #endregion #region Penalties and Non-Price-Affecting Properties case ITEM_PROPERTY_DAMAGE_REDUCTION_DEPRECATED: case ITEM_PROPERTY_DAMAGE_VULNERABILITY: case ITEM_PROPERTY_DECREASED_ABILITY_SCORE: case ITEM_PROPERTY_DECREASED_AC: case ITEM_PROPERTY_DECREASED_ATTACK_MODIFIER: case ITEM_PROPERTY_DECREASED_DAMAGE: case ITEM_PROPERTY_DECREASED_ENHANCEMENT_MODIFIER: case ITEM_PROPERTY_DECREASED_SAVING_THROWS: case ITEM_PROPERTY_DECREASED_SAVING_THROWS_SPECIFIC: case ITEM_PROPERTY_DECREASED_SKILL_MODIFIER: case ITEM_PROPERTY_NO_DAMAGE: case ITEM_PROPERTY_USE_LIMITATION_ALIGNMENT_GROUP: case ITEM_PROPERTY_USE_LIMITATION_CLASS: case ITEM_PROPERTY_USE_LIMITATION_RACIAL_TYPE: case ITEM_PROPERTY_USE_LIMITATION_SPECIFIC_ALIGNMENT: case ITEM_PROPERTY_VISUALEFFECT: case ITEM_PROPERTY_WEIGHT_INCREASE: { // these props don't affect the price. break. break; } #endregion } } #endregion #region Properties that are vs. Specifics foreach (PricedItemProperty prop in itProps) { if (prop.Price > 0) { continue; } int propType = script.GetItemPropertyType(prop.Property); switch (propType) { #region AC Bonus vs. Alignement Group case ITEM_PROPERTY_AC_BONUS_VS_ALIGNMENT_GROUP: { int ACvsGroup = script.GetItemPropertyCostTableValue(prop.Property); if (ACvsGroup > ACvsEveryone) { float multiplier = 0.40f; if (script.GetItemPropertySubType(prop.Property) == IP_CONST_ALIGNMENTGROUP_NEUTRAL) { multiplier = 2.0f / 3.0f; } if (script.GetItemPropertySubType(prop.Property) == IP_CONST_ALIGNMENTGROUP_EVIL) { multiplier = 0.50f; } float effectiveBonus = ((ACvsGroup - ACvsEveryone) * multiplier) + ACvsEveryone; prop.Price = (int)((effectiveBonus * effectiveBonus * 2000) - (ACvsEveryone * ACvsEveryone * 2000)); } break; } #endregion #region AC Bonus vs. Damage Type case ITEM_PROPERTY_AC_BONUS_VS_DAMAGE_TYPE: { int ACvsGroup = script.GetItemPropertyCostTableValue(prop.Property); if (ACvsGroup > ACvsEveryone) { float multiplier = 1.0f / 3.0f; float effectiveBonus = ((ACvsGroup - ACvsEveryone) * multiplier) + ACvsEveryone; prop.Price = (int)((effectiveBonus * effectiveBonus * 2000) - (ACvsEveryone * ACvsEveryone * 2000)); } break; } #endregion #region AC Bonus vs. Racial Type case ITEM_PROPERTY_AC_BONUS_VS_RACIAL_GROUP: { int ACvsGroup = script.GetItemPropertyCostTableValue(prop.Property); if (ACvsGroup > ACvsEveryone) { float multiplier = 1.0f / 3.0f; float effectiveBonus = ((ACvsGroup - ACvsEveryone) * multiplier) + ACvsEveryone; prop.Price = (int)((effectiveBonus * effectiveBonus * 2000) - (ACvsEveryone * ACvsEveryone * 2000)); } break; } #endregion #region AC Bonus vs. Specific Alignment case ITEM_PROPERTY_AC_BONUS_VS_SPECIFIC_ALIGNMENT: { int ACvsGroup = script.GetItemPropertyCostTableValue(prop.Property); if (ACvsGroup > ACvsEveryone) { float multiplier = 1.0f / 6.0f; float effectiveBonus = ((ACvsGroup - ACvsEveryone) * multiplier) + ACvsEveryone; prop.Price = (int)((effectiveBonus * effectiveBonus * 2000) - (ACvsEveryone * ACvsEveryone * 2000)); } break; } #endregion #region Attack Bonus vs. Alignment Group case ITEM_PROPERTY_ATTACK_BONUS_VS_ALIGNMENT_GROUP: { int attackVsGroup = script.GetItemPropertyCostTableValue(prop.Property); if (attackVsGroup > attackVsEveryone) { float multiplier = 0.40f; if (script.GetItemPropertySubType(prop.Property) == IP_CONST_ALIGNMENTGROUP_NEUTRAL) { multiplier = 2.0f / 3.0f; } if (script.GetItemPropertySubType(prop.Property) == IP_CONST_ALIGNMENTGROUP_EVIL) { multiplier = 0.50f; } effectivePlus += ((attackVsGroup - attackVsEveryone) * multiplier); } break; } #endregion #region Attack Bonus vs. Racial Group case ITEM_PROPERTY_ATTACK_BONUS_VS_RACIAL_GROUP: { int attackVsGroup = script.GetItemPropertyCostTableValue(prop.Property); if (attackVsGroup > attackVsEveryone) { float multiplier = 1.0f / 3.0f; effectivePlus += ((attackVsGroup - attackVsEveryone) * multiplier); } break; } #endregion #region Attack Bonus vs. Specific Alignment case ITEM_PROPERTY_ATTACK_BONUS_VS_SPECIFIC_ALIGNMENT: { int attackVsGroup = script.GetItemPropertyCostTableValue(prop.Property); if (attackVsGroup > attackVsEveryone) { float multiplier = 1.0f/6.0f; effectivePlus += ((attackVsGroup - attackVsEveryone) * multiplier); } break; } #endregion #region Damage Bonus vs. Alignment Group case ITEM_PROPERTY_DAMAGE_BONUS_VS_ALIGNMENT_GROUP: { float multiplier = 0.40f; if (script.GetItemPropertySubType(prop.Property) == IP_CONST_ALIGNMENTGROUP_NEUTRAL) { multiplier = 2.0f / 3.0f; } if (script.GetItemPropertySubType(prop.Property) == IP_CONST_ALIGNMENTGROUP_EVIL) { multiplier = 0.50f; } switch (script.GetItemPropertyCostTableValue(prop.Property)) { case IP_CONST_DAMAGEBONUS_1d4: { effectivePlus += (1.3f * multiplier); break; } case IP_CONST_DAMAGEBONUS_1d6: { effectivePlus += (2.0f * multiplier); break; } case IP_CONST_DAMAGEBONUS_1d8: { effectivePlus += (2.7f * multiplier); break; } case IP_CONST_DAMAGEBONUS_2d4: { effectivePlus += (3.0f * multiplier); break; } case IP_CONST_DAMAGEBONUS_1: { effectivePlus += (0.7f * multiplier); break; } case IP_CONST_DAMAGEBONUS_2: { effectivePlus += (1.1f * multiplier); break; } case IP_CONST_DAMAGEBONUS_3: { effectivePlus += (1.5f * multiplier); break; } case IP_CONST_DAMAGEBONUS_4: { effectivePlus += (2.1f * multiplier); break; } case IP_CONST_DAMAGEBONUS_5: { effectivePlus += (2.5f * multiplier); break; } default: { if (debug) script.SendMessageToAllDMs("Illegal weapon because it provides an unsupported damage type vs. alignment groups."); return -1; } } break; } #endregion #region Damage Bonus vs. Racial Group case ITEM_PROPERTY_DAMAGE_BONUS_VS_RACIAL_GROUP: { float multiplier = 1.0f / 3.0f; switch (script.GetItemPropertyCostTableValue(prop.Property)) { case IP_CONST_DAMAGEBONUS_1d4: { effectivePlus += (1.3f * multiplier); break; } case IP_CONST_DAMAGEBONUS_1d6: { effectivePlus += (2.0f * multiplier); break; } case IP_CONST_DAMAGEBONUS_1d8: { effectivePlus += (2.7f * multiplier); break; } case IP_CONST_DAMAGEBONUS_2d4: { effectivePlus += (3.0f * multiplier); break; } case IP_CONST_DAMAGEBONUS_1: { effectivePlus += (0.7f * multiplier); break; } case IP_CONST_DAMAGEBONUS_2: { effectivePlus += (1.1f * multiplier); break; } case IP_CONST_DAMAGEBONUS_3: { effectivePlus += (1.5f * multiplier); break; } case IP_CONST_DAMAGEBONUS_4: { effectivePlus += (2.1f * multiplier); break; } case IP_CONST_DAMAGEBONUS_5: { effectivePlus += (2.5f * multiplier); break; } default: { if (debug) script.SendMessageToAllDMs("Illegal weapon because it provides an unsupported damage type vs. racial groups."); return -1; } } break; } #endregion #region Damage Bonus vs. Specific Alignment case ITEM_PROPERTY_DAMAGE_BONUS_VS_SPECIFIC_ALIGNMENT: { float multiplier = 1.0f / 6.0f; switch (script.GetItemPropertyCostTableValue(prop.Property)) { case IP_CONST_DAMAGEBONUS_1d4: { effectivePlus += (1.3f * multiplier); break; } case IP_CONST_DAMAGEBONUS_1d6: { effectivePlus += (2.0f * multiplier); break; } case IP_CONST_DAMAGEBONUS_1d8: { effectivePlus += (2.7f * multiplier); break; } case IP_CONST_DAMAGEBONUS_2d4: { effectivePlus += (3.0f * multiplier); break; } case IP_CONST_DAMAGEBONUS_1: { effectivePlus += (0.7f * multiplier); break; } case IP_CONST_DAMAGEBONUS_2: { effectivePlus += (1.1f * multiplier); break; } case IP_CONST_DAMAGEBONUS_3: { effectivePlus += (1.5f * multiplier); break; } case IP_CONST_DAMAGEBONUS_4: { effectivePlus += (2.1f * multiplier); break; } case IP_CONST_DAMAGEBONUS_5: { effectivePlus += (2.5f * multiplier); break; } default: { if (debug) script.SendMessageToAllDMs("Illegal weapon because it provides an unsupported damage type vs. specific alignments."); return -1; } } break; } #endregion #region Enhancement Bonus vs. Alignment Group case ITEM_PROPERTY_ENHANCEMENT_BONUS_VS_ALIGNMENT_GROUP: { int enhancementVsGroup = script.GetItemPropertyCostTableValue(prop.Property); if (enhancementVsGroup > enhancementVsEveryone) { float multiplier = 0.40f; if (script.GetItemPropertySubType(prop.Property) == IP_CONST_ALIGNMENTGROUP_NEUTRAL) { multiplier = 2.0f / 3.0f; } if (script.GetItemPropertySubType(prop.Property) == IP_CONST_ALIGNMENTGROUP_EVIL) { multiplier = 0.50f; } effectivePlus += ((enhancementVsGroup - enhancementVsEveryone) * multiplier); } break; } #endregion #region Enhancement Bonus vs. Racial Group case ITEM_PROPERTY_ENHANCEMENT_BONUS_VS_RACIAL_GROUP: { int enhancementVsGroup = script.GetItemPropertyCostTableValue(prop.Property); if (enhancementVsGroup > enhancementVsEveryone) { float multiplier = 1.0f / 3.0f; effectivePlus += ((enhancementVsGroup - enhancementVsEveryone) * multiplier); } break; } #endregion #region Enhancement Bonus vs. Specific Alignment case ITEM_PROPERTY_ENHANCEMENT_BONUS_VS_SPECIFIC_ALIGNEMENT: { int enhancementVsGroup = script.GetItemPropertyCostTableValue(prop.Property); if (enhancementVsGroup > enhancementVsEveryone) { float multiplier = 1.0f / 6.0f; effectivePlus += ((enhancementVsGroup - enhancementVsEveryone) * multiplier); } break; } #endregion } } #endregion #endregion #region Sum Calculated Values #region Permanent Properties value += enchantmentPenalty; bool allSecondary = false; if (effectivePlus >= 0.05f) { allSecondary = true; if (effectivePlus >= 1.0f) { if (enhancementVsEveryone < 0.99 && !GetIsAmmunition(itemType)) { script.SendMessageToAllDMs("Illegal weapon because total enhancement is 1 or greater, but no baseline enhancement bonus is established."); return -1; } value += (int)((effectivePlus * effectivePlus) * 2000); } else { value += (int)(effectivePlus * 2000); } } int costliestProp = 0; int propsPrice = 0; PricedItemProperty costliestCharge = null; PricedItemProperty secondCostliestCharge = null; foreach (PricedItemProperty prop in itProps) { value += prop.Price; propsPrice += prop.Price; if (costliestProp < prop.Price) { costliestProp = prop.Price; } if (prop.ChargedPrice > 0) { if (costliestCharge == null) { costliestCharge = prop; } else if (prop.ChargedPrice > costliestCharge.ChargedPrice) { secondCostliestCharge = costliestCharge; costliestCharge = prop; } else if(secondCostliestCharge == null) { secondCostliestCharge = prop; } else if (prop.ChargedPrice > secondCostliestCharge.ChargedPrice) { secondCostliestCharge = prop; } } } if (allSecondary) { value += (propsPrice / 2); } else { // If the costliest prop is the only prop, 0/2 = 0. // otherwise, all secondary props cost 50% more. value += ((propsPrice - costliestProp) / 2); } #endregion #region Charge-Consuming Properties int chargesCost = 0; if (costliestCharge != null) { if (secondCostliestCharge == null) { chargesCost += costliestCharge.ChargedPrice * script.GetItemCharges(target); value += costliestCharge.ChargedPrice * script.GetItemCharges(target); } else { foreach (PricedItemProperty prop in itProps) { if (costliestCharge == prop) { chargesCost += prop.ChargedPrice * script.GetItemCharges(target); value += prop.ChargedPrice * script.GetItemCharges(target); } else if (secondCostliestCharge == prop) { chargesCost += (prop.ChargedPrice * script.GetItemCharges(target) * 3) / 4; value += (prop.ChargedPrice * script.GetItemCharges(target) * 3) / 4; } else { chargesCost += (prop.ChargedPrice * script.GetItemCharges(target)) / 2; value += (prop.ChargedPrice * script.GetItemCharges(target)) / 2; } } } } if (IsClassRestricted) { value -= (chargesCost - ((chargesCost * 750) / 1800)); } #endregion #endregion #region Correct for Ammunition if (GetIsAmmunition(itemType)) { value /= 100; } #endregion return value; }
public static int NewWeapon(CLRScriptBase script, int maxValue) { int itemType = SelectWeaponType(ref maxValue); int weaponValue = Pricing.BaseItemValues[itemType]; maxValue -= weaponValue; generateId++; uint weapon = script.CreateItemOnObject(WeaponResrefs[itemType], script.OBJECT_SELF, 1, WeaponResrefs[itemType]+generateId.ToString(), FALSE); #region About +1.4 weapons if (maxValue > 4220) { if (Generation.rand.Next(10) > 0) { if (Pricing.GetIsAmmunition(itemType)) { if (itemType == BASE_ITEM_BULLET) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_BLUDGEONING, 1), weapon, 0.0f); } else { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_PIERCING, 1), weapon, 0.0f); } } else { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyEnhancementBonus(1), weapon, 0.0f); } switch (Generation.rand.Next(7)) { case 0: script.SetFirstName(weapon, "Flametouched " + script.GetName(weapon) + " +1"); script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE, 1), weapon, 0.0f); if (Pricing.GetIsAmmunition(itemType)) { weaponValue += 1600; } else { weaponValue += 4220; } break; case 1: script.SetFirstName(weapon, "Frosttouched " + script.GetName(weapon) + " +1"); script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_COLD, 1), weapon, 0.0f); if (Pricing.GetIsAmmunition(itemType)) { weaponValue += 1600; } else { weaponValue += 4220; } break; case 3: script.SetFirstName(weapon, "Acidtouched " + script.GetName(weapon) + " +1"); script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_ACID, 1), weapon, 0.0f); if (Pricing.GetIsAmmunition(itemType)) { weaponValue += 1600; } else { weaponValue += 4220; } break; case 4: script.SetFirstName(weapon, "Sparktouched " + script.GetName(weapon) + " +1"); script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_ELECTRICAL, 1), weapon, 0.0f); if (Pricing.GetIsAmmunition(itemType)) { weaponValue += 1600; } else { weaponValue += 4220; } break; case 5: script.SetFirstName(weapon, "Humming " + script.GetName(weapon) + " +1"); script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_SONIC, 1), weapon, 0.0f); if (Pricing.GetIsAmmunition(itemType)) { weaponValue += 1600; } else { weaponValue += 4220; } break; case 6: script.SetFirstName(weapon, "Blessed " + script.GetName(weapon) + " +1"); script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonusVsAlign(IP_CONST_ALIGNMENTGROUP_EVIL, IP_CONST_DAMAGETYPE_MAGICAL, 1), weapon, 0.0f); if (Pricing.GetIsAmmunition(itemType)) { weaponValue += 1500; } else { weaponValue += 3945; } break; } } else { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyEnhancementBonus(1), weapon, 0.0f); script.SetFirstName(weapon, script.GetName(weapon) + " +1"); weaponValue += 2300; } } #endregion #region Simple Enchantment, +1 else if (maxValue > 2300) { if (Generation.rand.Next(10) > 0) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyEnhancementBonus(1), weapon, 0.0f); script.SetFirstName(weapon, script.GetName(weapon) + " +1"); weaponValue += 2300; } else { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyAttackBonus(1), weapon, 0.0f); script.SetFirstName(weapon, "Masterwork " + script.GetName(weapon)); weaponValue += 300; } } #endregion #region Simple Bonus Damage, < +1 equiv else if (maxValue > 1100) { if (Generation.rand.Next(10) > 0) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyAttackBonus(1), weapon, 0.0f); switch (Generation.rand.Next(7)) { case 0: script.SetFirstName(weapon, "Flametouched " + script.GetName(weapon)); script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE, 1), weapon, 0.0f); weaponValue += 1100; break; case 1: script.SetFirstName(weapon, "Frosttouched " + script.GetName(weapon)); script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_COLD, 1), weapon, 0.0f); weaponValue += 1100; break; case 3: script.SetFirstName(weapon, "Acidtouched " + script.GetName(weapon)); script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_ACID, 1), weapon, 0.0f); weaponValue += 1100; break; case 4: script.SetFirstName(weapon, "Sparktouched " + script.GetName(weapon)); script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_ELECTRICAL, 1), weapon, 0.0f); weaponValue += 1100; break; case 5: script.SetFirstName(weapon, "Humming " + script.GetName(weapon)); script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_SONIC, 1), weapon, 0.0f); weaponValue += 1100; break; case 6: script.SetFirstName(weapon, "Blessed " + script.GetName(weapon)); script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyDamageBonusVsAlign(IP_CONST_ALIGNMENTGROUP_EVIL, IP_CONST_DAMAGETYPE_MAGICAL, 1), weapon, 0.0f); weaponValue += 1000; break; } } else { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyAttackBonus(1), weapon, 0.0f); script.SetFirstName(weapon, "Masterwork " + script.GetName(weapon)); weaponValue += 300; } } #endregion #region Masterwork Only else if (maxValue > 300) { if (Generation.rand.Next(10) > 0) { script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyAttackBonus(1), weapon, 0.0f); script.SetFirstName(weapon, "Masterwork " + script.GetName(weapon)); weaponValue += 300; } } #endregion if (Pricing.GetIsAmmunition(itemType)) { script.SetItemStackSize(weapon, 50, FALSE); weaponValue /= 2; } Pricing.CalculatePrice(script, weapon); return weaponValue; }