2024-06-20 15:47:42 -04:00

613 lines
29 KiB
Plaintext

//::///////////////////////////////////////////////
//:: [Item Property Function]
//:: [inc_item_props.nss]
//:://////////////////////////////////////////////
//:: This file defines several functions used to
//:: simulate melee combat through scripting.
//:: This is useful for creating spells or feats
//:: which work in combat, such as the Smite Feats.
//:: The only problem at the moment is that the functions
//:: cannot determine bonuses derieved from Magical
//:: effects on creatures. Other than that, these
//:: will behave exactly like normal combat.
//::
//:: Example: Creating a Smite Neutral feat
//:: In the spell script attached to the feat, check
//:: the alignment of the target, and run DoMeleeAttack
//:: entering the appropriate Smite bonus into iMod
//:: On a hit, call GetMeleeWeaponDamage and add the
//:: bonus damage from the feat.
//::
//:: Finally, simulate the rest of the combat round
//:: by calling DoMeleeAttack/GetMeleeWeaponDamage
//:: once for each remaining attack that the player
//:: should get. Adding a -5 to iMod for each consecutive
//:: attack.
//:://////////////////////////////////////////////
//:: Created By: Aaon Graywolf
//:: Created On: Dec 19, 2003
//:://////////////////////////////////////////////
//:: Update: Jan 4 2002
//:: - Extended Composite bonus function to handle pretty much
//:: every property that can possibly be composited.
// * Returns an integer amount of damage from a constant
// * iDamageConst = DAMAGE_BONUS_* or IP_CONST_DAMAGEBONUS_*
int GetDamageByConstant(int iDamageConst, int iItemProp);
// * Returns the appropriate weapon feat given a weapon type
// * iType = BASE_ITEM_*
// * sFeat = "Focus", "Specialization", EpicFocus", "EpicSpecialization", "ImprovedCrit"
int GetFeatByWeaponType(int iType, string sFeat);
// * Returns the low end of oWeap's critical threat range
// * Accounts for Keen and Improved Critical bonuses
int GetMeleeWeaponCriticalRange(object oPC, object oWeap);
// * Performs a melee attack roll by oPC against oTarget.
// * Begins with BAB; to simulate multiple attacks in one round,
// * use iMod to add a -5 modifier for each consecutive attack.
// * If bShowFeedback is TRUE, display the attack roll in oPC's
// * message window after a delay of fDelay seconds.
// * Caveat: Cannot account for ATTACK_BONUS effects on oPC
int DoMeleeAttack(object oPC, object oWeap, object oTarget, int iMod = 0, int bShowFeedback = TRUE, float fDelay = 0.0);
// * Returns an integer amount of damage done by oPC with oWeap
// * Caveat: Cannot account for DAMAGE_BONUS effects on oPC
int GetMeleeWeaponDamage(object oPC, object oWeap, int bCrit = FALSE,int iDamage = 0);
// * Returns the Enhancement Bonus of oWeap as DAMAGE_POWER_*
int GetWeaponEnhancement(object oWeap);
// * Oddly enough, Damage Types by weapon don't seem to appear in baseitems.2da
// * This funciton runs a switch that returns the appropriate damage type.
int GetWeaponDamageType(object oWeap);
int GetDamageByConstant(int iDamageConst, int iItemProp)
{
if(iItemProp)
{
switch(iDamageConst)
{
case IP_CONST_DAMAGEBONUS_1:
return 1;
case IP_CONST_DAMAGEBONUS_2:
return 2;
case IP_CONST_DAMAGEBONUS_3:
return 3;
case IP_CONST_DAMAGEBONUS_4:
return 4;
case IP_CONST_DAMAGEBONUS_5:
return 5;
case IP_CONST_DAMAGEBONUS_6:
return 6;
case IP_CONST_DAMAGEBONUS_7:
return 7;
case IP_CONST_DAMAGEBONUS_8:
return 8;
case IP_CONST_DAMAGEBONUS_9:
return 9;
case IP_CONST_DAMAGEBONUS_10:
return 10;
case IP_CONST_DAMAGEBONUS_1d4:
return d4(1);
case IP_CONST_DAMAGEBONUS_1d6:
return d6(1);
case IP_CONST_DAMAGEBONUS_1d8:
return d8(1);
case IP_CONST_DAMAGEBONUS_1d10:
return d10(1);
case IP_CONST_DAMAGEBONUS_1d12:
return d12(1);
case IP_CONST_DAMAGEBONUS_2d4:
return d4(2);
case IP_CONST_DAMAGEBONUS_2d6:
return d6(2);
case IP_CONST_DAMAGEBONUS_2d8:
return d8(2);
case IP_CONST_DAMAGEBONUS_2d10:
return d10(2);
case IP_CONST_DAMAGEBONUS_2d12:
return d12(2);
}
}
else
{
switch(iDamageConst)
{
case DAMAGE_BONUS_1:
return 1;
case DAMAGE_BONUS_2:
return 2;
case DAMAGE_BONUS_3:
return 3;
case DAMAGE_BONUS_4:
return 4;
case DAMAGE_BONUS_5:
return 5;
case DAMAGE_BONUS_6:
return 6;
case DAMAGE_BONUS_7:
return 7;
case DAMAGE_BONUS_8:
return 8;
case DAMAGE_BONUS_9:
return 9;
case DAMAGE_BONUS_10:
return 10;
case DAMAGE_BONUS_11:
return 10;
case DAMAGE_BONUS_12:
return 10;
case DAMAGE_BONUS_13:
return 10;
case DAMAGE_BONUS_14:
return 10;
case DAMAGE_BONUS_15:
return 10;
case DAMAGE_BONUS_16:
return 10;
case DAMAGE_BONUS_17:
return 10;
case DAMAGE_BONUS_18:
return 10;
case DAMAGE_BONUS_19:
return 10;
case DAMAGE_BONUS_20:
return 10;
case DAMAGE_BONUS_1d4:
return d4(1);
case DAMAGE_BONUS_1d6:
return d6(1);
case DAMAGE_BONUS_1d8:
return d8(1);
case DAMAGE_BONUS_1d10:
return d10(1);
case DAMAGE_BONUS_1d12:
return d12(1);
case DAMAGE_BONUS_2d4:
return d4(2);
case DAMAGE_BONUS_2d6:
return d6(2);
case DAMAGE_BONUS_2d8:
return d8(2);
case DAMAGE_BONUS_2d10:
return d10(2);
case DAMAGE_BONUS_2d12:
return d12(2);
}
}
return 0;
}
int GetFeatByWeaponType(int iType, string sFeat)
{
if(sFeat == "Focus")
switch(iType)
{
case BASE_ITEM_BASTARDSWORD: return FEAT_WEAPON_FOCUS_BASTARD_SWORD;
case BASE_ITEM_BATTLEAXE: return FEAT_WEAPON_FOCUS_BATTLE_AXE;
case BASE_ITEM_CLUB: return FEAT_WEAPON_FOCUS_CLUB;
case BASE_ITEM_DAGGER: return FEAT_WEAPON_FOCUS_DAGGER;
case BASE_ITEM_DART: return FEAT_WEAPON_FOCUS_DART;
case BASE_ITEM_DIREMACE: return FEAT_WEAPON_FOCUS_DIRE_MACE;
case BASE_ITEM_DOUBLEAXE: return FEAT_WEAPON_FOCUS_DOUBLE_AXE;
case BASE_ITEM_DWARVENWARAXE: return FEAT_WEAPON_FOCUS_DWAXE;
case BASE_ITEM_GREATAXE: return FEAT_WEAPON_FOCUS_GREAT_AXE;
case BASE_ITEM_GREATSWORD: return FEAT_WEAPON_FOCUS_GREAT_SWORD;
case BASE_ITEM_HALBERD: return FEAT_WEAPON_FOCUS_HALBERD;
case BASE_ITEM_HANDAXE: return FEAT_WEAPON_FOCUS_HAND_AXE;
case BASE_ITEM_HEAVYCROSSBOW: return FEAT_WEAPON_FOCUS_HEAVY_CROSSBOW;
case BASE_ITEM_HEAVYFLAIL: return FEAT_WEAPON_FOCUS_HEAVY_FLAIL;
case BASE_ITEM_KAMA: return FEAT_WEAPON_FOCUS_KAMA;
case BASE_ITEM_KATANA: return FEAT_WEAPON_FOCUS_KATANA;
case BASE_ITEM_KUKRI: return FEAT_WEAPON_FOCUS_KUKRI;
case BASE_ITEM_LIGHTCROSSBOW: return FEAT_WEAPON_FOCUS_LIGHT_CROSSBOW;
case BASE_ITEM_LIGHTFLAIL: return FEAT_WEAPON_FOCUS_LIGHT_FLAIL;
case BASE_ITEM_LIGHTHAMMER: return FEAT_WEAPON_FOCUS_LIGHT_HAMMER;
case BASE_ITEM_LIGHTMACE: return FEAT_WEAPON_FOCUS_LIGHT_MACE;
case BASE_ITEM_LONGBOW: return FEAT_WEAPON_FOCUS_LONG_SWORD;
case BASE_ITEM_LONGSWORD: return FEAT_WEAPON_FOCUS_LONGBOW;
case BASE_ITEM_MORNINGSTAR: return FEAT_WEAPON_FOCUS_MORNING_STAR;
case BASE_ITEM_QUARTERSTAFF: return FEAT_WEAPON_FOCUS_STAFF;
case BASE_ITEM_RAPIER: return FEAT_WEAPON_FOCUS_RAPIER;
case BASE_ITEM_SCIMITAR: return FEAT_WEAPON_FOCUS_SCIMITAR;
case BASE_ITEM_SCYTHE: return FEAT_WEAPON_FOCUS_SCYTHE;
case BASE_ITEM_SHORTBOW: return FEAT_WEAPON_FOCUS_SHORTBOW;
case BASE_ITEM_SHORTSPEAR: return FEAT_WEAPON_FOCUS_SPEAR;
case BASE_ITEM_SHORTSWORD: return FEAT_WEAPON_FOCUS_SHORT_SWORD;
case BASE_ITEM_SHURIKEN: return FEAT_WEAPON_FOCUS_SHURIKEN;
case BASE_ITEM_SICKLE: return FEAT_WEAPON_FOCUS_SICKLE;
case BASE_ITEM_SLING: return FEAT_WEAPON_FOCUS_SLING;
case BASE_ITEM_THROWINGAXE: return FEAT_WEAPON_FOCUS_THROWING_AXE;
case BASE_ITEM_TWOBLADEDSWORD: return FEAT_WEAPON_FOCUS_TWO_BLADED_SWORD;
case BASE_ITEM_WARHAMMER: return FEAT_WEAPON_FOCUS_WAR_HAMMER;
case BASE_ITEM_WHIP: return -1; //No constant (?)
}
else if(sFeat == "Specialization")
switch(iType)
{
case BASE_ITEM_BASTARDSWORD: return FEAT_WEAPON_SPECIALIZATION_BASTARD_SWORD;
case BASE_ITEM_BATTLEAXE: return FEAT_WEAPON_SPECIALIZATION_BATTLE_AXE;
case BASE_ITEM_CLUB: return FEAT_WEAPON_SPECIALIZATION_CLUB;
case BASE_ITEM_DAGGER: return FEAT_WEAPON_SPECIALIZATION_DAGGER;
case BASE_ITEM_DART: return FEAT_WEAPON_SPECIALIZATION_DART;
case BASE_ITEM_DIREMACE: return FEAT_WEAPON_SPECIALIZATION_DIRE_MACE;
case BASE_ITEM_DOUBLEAXE: return FEAT_WEAPON_SPECIALIZATION_DOUBLE_AXE;
case BASE_ITEM_DWARVENWARAXE: return FEAT_WEAPON_SPECIALIZATION_DWAXE ;
case BASE_ITEM_GREATAXE: return FEAT_WEAPON_SPECIALIZATION_GREAT_AXE;
case BASE_ITEM_GREATSWORD: return FEAT_WEAPON_SPECIALIZATION_GREAT_SWORD;
case BASE_ITEM_HALBERD: return FEAT_WEAPON_SPECIALIZATION_HALBERD;
case BASE_ITEM_HANDAXE: return FEAT_WEAPON_SPECIALIZATION_HAND_AXE;
case BASE_ITEM_HEAVYCROSSBOW: return FEAT_WEAPON_SPECIALIZATION_HEAVY_CROSSBOW;
case BASE_ITEM_HEAVYFLAIL: return FEAT_WEAPON_SPECIALIZATION_HEAVY_FLAIL;
case BASE_ITEM_KAMA: return FEAT_WEAPON_SPECIALIZATION_KAMA;
case BASE_ITEM_KATANA: return FEAT_WEAPON_SPECIALIZATION_KATANA;
case BASE_ITEM_KUKRI: return FEAT_WEAPON_SPECIALIZATION_KUKRI;
case BASE_ITEM_LIGHTCROSSBOW: return FEAT_WEAPON_SPECIALIZATION_LIGHT_CROSSBOW;
case BASE_ITEM_LIGHTFLAIL: return FEAT_WEAPON_SPECIALIZATION_LIGHT_FLAIL;
case BASE_ITEM_LIGHTHAMMER: return FEAT_WEAPON_SPECIALIZATION_LIGHT_HAMMER;
case BASE_ITEM_LIGHTMACE: return FEAT_WEAPON_SPECIALIZATION_LIGHT_MACE;
case BASE_ITEM_LONGBOW: return FEAT_WEAPON_SPECIALIZATION_LONG_SWORD;
case BASE_ITEM_LONGSWORD: return FEAT_WEAPON_SPECIALIZATION_LONGBOW;
case BASE_ITEM_MORNINGSTAR: return FEAT_WEAPON_SPECIALIZATION_MORNING_STAR;
case BASE_ITEM_QUARTERSTAFF: return FEAT_WEAPON_SPECIALIZATION_STAFF;
case BASE_ITEM_RAPIER: return FEAT_WEAPON_SPECIALIZATION_RAPIER;
case BASE_ITEM_SCIMITAR: return FEAT_WEAPON_SPECIALIZATION_SCIMITAR;
case BASE_ITEM_SCYTHE: return FEAT_WEAPON_SPECIALIZATION_SCYTHE;
case BASE_ITEM_SHORTBOW: return FEAT_WEAPON_SPECIALIZATION_SHORTBOW;
case BASE_ITEM_SHORTSPEAR: return FEAT_WEAPON_SPECIALIZATION_SPEAR;
case BASE_ITEM_SHORTSWORD: return FEAT_WEAPON_SPECIALIZATION_SHORT_SWORD;
case BASE_ITEM_SHURIKEN: return FEAT_WEAPON_SPECIALIZATION_SHURIKEN;
case BASE_ITEM_SICKLE: return FEAT_WEAPON_SPECIALIZATION_SICKLE;
case BASE_ITEM_SLING: return FEAT_WEAPON_SPECIALIZATION_SLING;
case BASE_ITEM_THROWINGAXE: return FEAT_WEAPON_SPECIALIZATION_THROWING_AXE;
case BASE_ITEM_TWOBLADEDSWORD: return FEAT_WEAPON_SPECIALIZATION_TWO_BLADED_SWORD;
case BASE_ITEM_WARHAMMER: return FEAT_WEAPON_SPECIALIZATION_WAR_HAMMER;
}
else if(sFeat == "EpicFocus")
switch(iType)
{
case BASE_ITEM_BASTARDSWORD: return FEAT_EPIC_WEAPON_FOCUS_BASTARDSWORD;
case BASE_ITEM_BATTLEAXE: return FEAT_EPIC_WEAPON_FOCUS_BATTLEAXE;
case BASE_ITEM_CLUB: return FEAT_EPIC_WEAPON_FOCUS_CLUB;
case BASE_ITEM_DAGGER: return FEAT_EPIC_WEAPON_FOCUS_DAGGER;
case BASE_ITEM_DART: return FEAT_EPIC_WEAPON_FOCUS_DART;
case BASE_ITEM_DIREMACE: return FEAT_EPIC_WEAPON_FOCUS_DIREMACE;
case BASE_ITEM_DOUBLEAXE: return FEAT_EPIC_WEAPON_FOCUS_DOUBLEAXE;
case BASE_ITEM_DWARVENWARAXE: return FEAT_EPIC_WEAPON_FOCUS_DWAXE;
case BASE_ITEM_GREATAXE: return FEAT_EPIC_WEAPON_FOCUS_GREATAXE;
case BASE_ITEM_GREATSWORD: return FEAT_EPIC_WEAPON_FOCUS_GREATSWORD;
case BASE_ITEM_HALBERD: return FEAT_EPIC_WEAPON_FOCUS_HALBERD;
case BASE_ITEM_HANDAXE: return FEAT_EPIC_WEAPON_FOCUS_HANDAXE;
case BASE_ITEM_HEAVYCROSSBOW: return FEAT_EPIC_WEAPON_FOCUS_HEAVYCROSSBOW;
case BASE_ITEM_HEAVYFLAIL: return FEAT_EPIC_WEAPON_FOCUS_HEAVYFLAIL;
case BASE_ITEM_KAMA: return FEAT_EPIC_WEAPON_FOCUS_KAMA;
case BASE_ITEM_KATANA: return FEAT_EPIC_WEAPON_FOCUS_KATANA;
case BASE_ITEM_KUKRI: return FEAT_EPIC_WEAPON_FOCUS_KUKRI;
case BASE_ITEM_LIGHTCROSSBOW: return FEAT_EPIC_WEAPON_FOCUS_LIGHTCROSSBOW;
case BASE_ITEM_LIGHTFLAIL: return FEAT_EPIC_WEAPON_FOCUS_LIGHTFLAIL;
case BASE_ITEM_LIGHTHAMMER: return FEAT_EPIC_WEAPON_FOCUS_LIGHTHAMMER;
case BASE_ITEM_LIGHTMACE: return FEAT_EPIC_WEAPON_FOCUS_LIGHTMACE;
case BASE_ITEM_LONGBOW: return FEAT_EPIC_WEAPON_FOCUS_LONGSWORD;
case BASE_ITEM_LONGSWORD: return FEAT_EPIC_WEAPON_FOCUS_LONGBOW;
case BASE_ITEM_MORNINGSTAR: return FEAT_EPIC_WEAPON_FOCUS_MORNINGSTAR;
case BASE_ITEM_QUARTERSTAFF: return FEAT_EPIC_WEAPON_FOCUS_QUARTERSTAFF;
case BASE_ITEM_RAPIER: return FEAT_EPIC_WEAPON_FOCUS_RAPIER;
case BASE_ITEM_SCIMITAR: return FEAT_EPIC_WEAPON_FOCUS_SCIMITAR;
case BASE_ITEM_SCYTHE: return FEAT_EPIC_WEAPON_FOCUS_SCYTHE;
case BASE_ITEM_SHORTBOW: return FEAT_EPIC_WEAPON_FOCUS_SHORTBOW;
case BASE_ITEM_SHORTSPEAR: return FEAT_EPIC_WEAPON_FOCUS_SHORTSPEAR;
case BASE_ITEM_SHORTSWORD: return FEAT_EPIC_WEAPON_FOCUS_SHORTSWORD;
case BASE_ITEM_SHURIKEN: return FEAT_EPIC_WEAPON_FOCUS_SHURIKEN;
case BASE_ITEM_SICKLE: return FEAT_EPIC_WEAPON_FOCUS_SICKLE;
case BASE_ITEM_SLING: return FEAT_EPIC_WEAPON_FOCUS_SLING;
case BASE_ITEM_THROWINGAXE: return FEAT_EPIC_WEAPON_FOCUS_THROWINGAXE;
case BASE_ITEM_TWOBLADEDSWORD: return FEAT_EPIC_WEAPON_FOCUS_TWOBLADEDSWORD;
case BASE_ITEM_WARHAMMER: return FEAT_EPIC_WEAPON_FOCUS_WARHAMMER;
case BASE_ITEM_WHIP: return -1; //No constant (?)
}
else if(sFeat == "EpicSpecialization")
switch(iType)
{
case BASE_ITEM_BASTARDSWORD: return FEAT_EPIC_WEAPON_SPECIALIZATION_BASTARDSWORD;
case BASE_ITEM_BATTLEAXE: return FEAT_EPIC_WEAPON_SPECIALIZATION_BATTLEAXE;
case BASE_ITEM_CLUB: return FEAT_EPIC_WEAPON_SPECIALIZATION_CLUB;
case BASE_ITEM_DAGGER: return FEAT_EPIC_WEAPON_SPECIALIZATION_DAGGER;
case BASE_ITEM_DART: return FEAT_EPIC_WEAPON_SPECIALIZATION_DART;
case BASE_ITEM_DIREMACE: return FEAT_EPIC_WEAPON_SPECIALIZATION_DIREMACE;
case BASE_ITEM_DOUBLEAXE: return FEAT_EPIC_WEAPON_SPECIALIZATION_DOUBLEAXE;
case BASE_ITEM_DWARVENWARAXE: return FEAT_EPIC_WEAPON_SPECIALIZATION_DWAXE;
case BASE_ITEM_GREATAXE: return FEAT_EPIC_WEAPON_SPECIALIZATION_GREATAXE;
case BASE_ITEM_GREATSWORD: return FEAT_EPIC_WEAPON_SPECIALIZATION_GREATSWORD;
case BASE_ITEM_HALBERD: return FEAT_EPIC_WEAPON_SPECIALIZATION_HALBERD;
case BASE_ITEM_HANDAXE: return FEAT_EPIC_WEAPON_SPECIALIZATION_HANDAXE;
case BASE_ITEM_HEAVYCROSSBOW: return FEAT_EPIC_WEAPON_SPECIALIZATION_HEAVYCROSSBOW;
case BASE_ITEM_HEAVYFLAIL: return FEAT_EPIC_WEAPON_SPECIALIZATION_HEAVYFLAIL;
case BASE_ITEM_KAMA: return FEAT_EPIC_WEAPON_SPECIALIZATION_KAMA;
case BASE_ITEM_KATANA: return FEAT_EPIC_WEAPON_SPECIALIZATION_KATANA;
case BASE_ITEM_KUKRI: return FEAT_EPIC_WEAPON_SPECIALIZATION_KUKRI;
case BASE_ITEM_LIGHTCROSSBOW: return FEAT_EPIC_WEAPON_SPECIALIZATION_LIGHTCROSSBOW;
case BASE_ITEM_LIGHTFLAIL: return FEAT_EPIC_WEAPON_SPECIALIZATION_LIGHTFLAIL;
case BASE_ITEM_LIGHTHAMMER: return FEAT_EPIC_WEAPON_SPECIALIZATION_LIGHTHAMMER;
case BASE_ITEM_LIGHTMACE: return FEAT_EPIC_WEAPON_SPECIALIZATION_LIGHTMACE;
case BASE_ITEM_LONGBOW: return FEAT_EPIC_WEAPON_SPECIALIZATION_LONGSWORD;
case BASE_ITEM_LONGSWORD: return FEAT_EPIC_WEAPON_SPECIALIZATION_LONGBOW;
case BASE_ITEM_MORNINGSTAR: return FEAT_EPIC_WEAPON_SPECIALIZATION_MORNINGSTAR;
case BASE_ITEM_QUARTERSTAFF: return FEAT_EPIC_WEAPON_SPECIALIZATION_QUARTERSTAFF;
case BASE_ITEM_RAPIER: return FEAT_EPIC_WEAPON_SPECIALIZATION_RAPIER;
case BASE_ITEM_SCIMITAR: return FEAT_EPIC_WEAPON_SPECIALIZATION_SCIMITAR;
case BASE_ITEM_SCYTHE: return FEAT_EPIC_WEAPON_SPECIALIZATION_SCYTHE;
case BASE_ITEM_SHORTBOW: return FEAT_EPIC_WEAPON_SPECIALIZATION_SHORTBOW;
case BASE_ITEM_SHORTSPEAR: return FEAT_EPIC_WEAPON_SPECIALIZATION_SHORTSPEAR;
case BASE_ITEM_SHORTSWORD: return FEAT_EPIC_WEAPON_SPECIALIZATION_SHORTSWORD;
case BASE_ITEM_SHURIKEN: return FEAT_EPIC_WEAPON_SPECIALIZATION_SHURIKEN;
case BASE_ITEM_SICKLE: return FEAT_EPIC_WEAPON_SPECIALIZATION_SICKLE;
case BASE_ITEM_SLING: return FEAT_EPIC_WEAPON_SPECIALIZATION_SLING;
case BASE_ITEM_THROWINGAXE: return FEAT_EPIC_WEAPON_SPECIALIZATION_THROWINGAXE;
case BASE_ITEM_TWOBLADEDSWORD: return FEAT_EPIC_WEAPON_SPECIALIZATION_TWOBLADEDSWORD;
case BASE_ITEM_WARHAMMER: return FEAT_EPIC_WEAPON_SPECIALIZATION_WARHAMMER;
case BASE_ITEM_WHIP: return -1; //No constant (?)
}
else if(sFeat == "ImprovedCrit")
switch(iType)
{
case BASE_ITEM_BASTARDSWORD: return FEAT_IMPROVED_CRITICAL_BASTARD_SWORD;
case BASE_ITEM_BATTLEAXE: return FEAT_IMPROVED_CRITICAL_BATTLE_AXE;
case BASE_ITEM_CLUB: return FEAT_IMPROVED_CRITICAL_CLUB;
case BASE_ITEM_DAGGER: return FEAT_IMPROVED_CRITICAL_DAGGER;
case BASE_ITEM_DART: return FEAT_IMPROVED_CRITICAL_DART;
case BASE_ITEM_DIREMACE: return FEAT_IMPROVED_CRITICAL_DIRE_MACE;
case BASE_ITEM_DOUBLEAXE: return FEAT_IMPROVED_CRITICAL_DOUBLE_AXE;
case BASE_ITEM_DWARVENWARAXE: return FEAT_IMPROVED_CRITICAL_DWAXE ;
case BASE_ITEM_GREATAXE: return FEAT_IMPROVED_CRITICAL_GREAT_AXE;
case BASE_ITEM_GREATSWORD: return FEAT_IMPROVED_CRITICAL_GREAT_SWORD;
case BASE_ITEM_HALBERD: return FEAT_IMPROVED_CRITICAL_HALBERD;
case BASE_ITEM_HANDAXE: return FEAT_IMPROVED_CRITICAL_HAND_AXE;
case BASE_ITEM_HEAVYCROSSBOW: return FEAT_IMPROVED_CRITICAL_HEAVY_CROSSBOW;
case BASE_ITEM_HEAVYFLAIL: return FEAT_IMPROVED_CRITICAL_HEAVY_FLAIL;
case BASE_ITEM_KAMA: return FEAT_IMPROVED_CRITICAL_KAMA;
case BASE_ITEM_KATANA: return FEAT_IMPROVED_CRITICAL_KATANA;
case BASE_ITEM_KUKRI: return FEAT_IMPROVED_CRITICAL_KUKRI;
case BASE_ITEM_LIGHTCROSSBOW: return FEAT_IMPROVED_CRITICAL_LIGHT_CROSSBOW;
case BASE_ITEM_LIGHTFLAIL: return FEAT_IMPROVED_CRITICAL_LIGHT_FLAIL;
case BASE_ITEM_LIGHTHAMMER: return FEAT_IMPROVED_CRITICAL_LIGHT_HAMMER;
case BASE_ITEM_LIGHTMACE: return FEAT_IMPROVED_CRITICAL_LIGHT_MACE;
case BASE_ITEM_LONGBOW: return FEAT_IMPROVED_CRITICAL_LONG_SWORD;
case BASE_ITEM_LONGSWORD: return FEAT_IMPROVED_CRITICAL_LONGBOW;
case BASE_ITEM_MORNINGSTAR: return FEAT_IMPROVED_CRITICAL_MORNING_STAR;
case BASE_ITEM_QUARTERSTAFF: return FEAT_IMPROVED_CRITICAL_STAFF;
case BASE_ITEM_RAPIER: return FEAT_IMPROVED_CRITICAL_RAPIER;
case BASE_ITEM_SCIMITAR: return FEAT_IMPROVED_CRITICAL_SCIMITAR;
case BASE_ITEM_SCYTHE: return FEAT_IMPROVED_CRITICAL_SCYTHE;
case BASE_ITEM_SHORTBOW: return FEAT_IMPROVED_CRITICAL_SHORTBOW;
case BASE_ITEM_SHORTSPEAR: return FEAT_IMPROVED_CRITICAL_SPEAR;
case BASE_ITEM_SHORTSWORD: return FEAT_IMPROVED_CRITICAL_SHORT_SWORD;
case BASE_ITEM_SHURIKEN: return FEAT_IMPROVED_CRITICAL_SHURIKEN;
case BASE_ITEM_SICKLE: return FEAT_IMPROVED_CRITICAL_SICKLE;
case BASE_ITEM_SLING: return FEAT_IMPROVED_CRITICAL_SLING;
case BASE_ITEM_THROWINGAXE: return FEAT_IMPROVED_CRITICAL_THROWING_AXE;
case BASE_ITEM_TWOBLADEDSWORD: return FEAT_IMPROVED_CRITICAL_TWO_BLADED_SWORD;
case BASE_ITEM_WARHAMMER: return FEAT_IMPROVED_CRITICAL_WAR_HAMMER;
}
return -1;
}
int GetMeleeWeaponCriticalRange(object oPC, object oWeap)
{
int iType = GetBaseItemType(oWeap);
int nThreat = StringToInt(Get2DAString("baseitems", "CritThreat", iType));
int bKeen = GetItemHasItemProperty(oWeap, ITEM_PROPERTY_KEEN);
int bImpCrit = GetHasFeat(GetFeatByWeaponType(iType, "ImprovedCrit"), oPC);
nThreat *= bKeen ? 2 : 1;
nThreat *= bImpCrit ? 2 : 1;
return 21 - nThreat;
}
int DoMeleeAttack(object oPC, object oWeap, object oTarget, int iMod = 0, int bShowFeedback = TRUE, float fDelay = 0.0)
{
//Declare in instantiate major variables
int iDiceRoll = d20();
int iBAB = GetBaseAttackBonus(oPC);
int iAC = GetAC(oTarget);
int iType = GetBaseItemType(oWeap);
int iCritThreat = GetMeleeWeaponCriticalRange(oPC, oWeap);
int bFinesse = GetHasFeat(FEAT_WEAPON_FINESSE, oPC);
int bLight = StringToInt(Get2DAString("baseitems", "WeaponSize", iType)) <= 2 || iType == BASE_ITEM_RAPIER;
int iEnhancement = GetWeaponEnhancement(oWeap);
iEnhancement = iEnhancement < 0 ? 0 : iEnhancement;
int bFocus = GetHasFeat(GetFeatByWeaponType(iType, "Focus"), oPC);
int bEFocus = GetHasFeat(GetFeatByWeaponType(iType, "EpicFocus"), oPC);
int bProwess = GetHasFeat(FEAT_EPIC_PROWESS, oPC);
int iStr = GetAbilityModifier(ABILITY_STRENGTH, oPC);
iStr = iStr < 0 ? 0 : iStr;
int iDex = GetAbilityModifier(ABILITY_DEXTERITY, oPC);
iDex = iStr < 0 ? 0 : iDex;
string sFeedback = GetName(oPC) + " attacks " + GetName(oTarget) + ": ";
int iReturn = 0;
//Add up total attack bonus
int iAttackBonus = iBAB;
iAttackBonus += bFinesse && bLight ? iDex : iStr;
iAttackBonus += bFocus ? 1 : 0;
iAttackBonus += bEFocus ? 2 : 0;
iAttackBonus += bProwess ? 1 : 0;
iAttackBonus += iEnhancement;
iAttackBonus += iMod;
//Include ATTACK_BONUS properties from the weapon
itemproperty ip = GetFirstItemProperty(oWeap);
while(GetIsItemPropertyValid(ip))
{
if(GetItemPropertyType(ip) == ITEM_PROPERTY_ATTACK_BONUS)
iAttackBonus += GetItemPropertyCostTableValue(ip);
ip = GetNextItemProperty(oWeap);
}
//Check for a critical threat
if(iDiceRoll >= iCritThreat && iDiceRoll + iAttackBonus > iAC)
{
sFeedback += "*critical hit*: (" + IntToString(iDiceRoll) + " + " + IntToString(iAttackBonus) + " = " + IntToString(iDiceRoll + iAttackBonus) + "): ";
//Roll again to see if we scored a critical hit
iDiceRoll = d20();
sFeedback += "*threat roll*: (" + IntToString(iDiceRoll) + " + " + IntToString(iAttackBonus) + " = " + IntToString(iDiceRoll + iAttackBonus) + ")";
if(iDiceRoll + iAttackBonus > iAC)
iReturn = 2;
else
iReturn = 1;
}
//Just a regular hit
else if(iDiceRoll + iAttackBonus > iAC)
{
sFeedback += "*hit*: (" + IntToString(iDiceRoll) + " + " + IntToString(iAttackBonus) + " = " + IntToString(iDiceRoll + iAttackBonus) + ")";
iReturn = 1;
}
//Missed
else
{
sFeedback += "*miss*: (" + IntToString(iDiceRoll) + " + " + IntToString(iAttackBonus) + " = " + IntToString(iDiceRoll + iAttackBonus) + ")";
iReturn = 0;
}
if(bShowFeedback) DelayCommand(fDelay, SendMessageToPC(oPC, sFeedback));
return iReturn;
}
int GetMeleeWeaponDamage(object oPC, object oWeap, int bCrit = FALSE,int iDamage = 0)
{
//Declare in instantiate major variables
int iType = GetBaseItemType(oWeap);
int nSides = StringToInt(Get2DAString("baseitems", "DieToRoll", iType));
int nDice = StringToInt(Get2DAString("baseitems", "NumDice", iType));
int nCritMult = StringToInt(Get2DAString("baseitems", "CritHitMult", iType));
int nMassiveCrit;
int iStr = GetAbilityModifier(ABILITY_STRENGTH, oPC);
iStr = iStr < 0 ? 0 : iStr;
int bSpec = GetHasFeat(GetFeatByWeaponType(iType, "Specialization"), oPC);
int bESpec = GetHasFeat(GetFeatByWeaponType(iType, "EpicSpecialization"), oPC);
// int iDamage = 0;
int iBonus = 0;
int iEnhancement = GetWeaponEnhancement(oWeap);
iEnhancement = iEnhancement < 0 ? 0 : iEnhancement;
//Get Damage Bonus and Massive Critical Properties from oWeap
itemproperty ip = GetFirstItemProperty(oWeap);
while(GetIsItemPropertyValid(ip))
{
int tempConst = -1;
int iCostVal = GetItemPropertyCostTableValue(ip);
if(GetItemPropertyType(ip) == ITEM_PROPERTY_MASSIVE_CRITICALS){
if(iCostVal > tempConst){
nMassiveCrit = GetDamageByConstant(iCostVal, TRUE);
tempConst = iCostVal;
}
}
if(GetItemPropertyType(ip) == ITEM_PROPERTY_DAMAGE_BONUS){
iBonus += GetDamageByConstant(iCostVal, TRUE);
}
ip = GetNextItemProperty(oWeap);
}
//Roll the base damage dice.
if(nSides == 2) iDamage += d2(nDice);
if(nSides == 4) iDamage += d4(nDice);
if(nSides == 6) iDamage += d6(nDice);
if(nSides == 8) iDamage += d8(nDice);
if(nSides == 10) iDamage += d10(nDice);
if(nSides == 12) iDamage += d12(nDice);
//Add any applicable bonuses
if(bSpec) iDamage += 2;
if(bESpec) iDamage += 4;
iDamage += iStr;
iDamage += iEnhancement;
iDamage += iBonus;
//Add critical bonuses
if(bCrit){
iDamage *= nCritMult;
iDamage += nMassiveCrit;
}
return iDamage;
}
int GetWeaponEnhancement(object oWeap)
{
int iBonus = -1;
int iTemp;
itemproperty ip = GetFirstItemProperty(oWeap);
while(GetIsItemPropertyValid(ip))
{
if(GetItemPropertyType(ip) == ITEM_PROPERTY_ENHANCEMENT_BONUS)
iTemp += GetDamageByConstant(GetItemPropertyCostTableValue(ip), TRUE);
iBonus = iTemp > iBonus ? iBonus : iTemp;
ip = GetNextItemProperty(oWeap);
}
return iBonus;
}
int GetWeaponDamageType(object oWeap)
{
int iType = GetBaseItemType(oWeap);
switch(iType)
{
case BASE_ITEM_BASTARDSWORD:
case BASE_ITEM_BATTLEAXE:
case BASE_ITEM_DOUBLEAXE:
case BASE_ITEM_DWARVENWARAXE:
case BASE_ITEM_GREATAXE:
case BASE_ITEM_GREATSWORD:
case BASE_ITEM_HALBERD:
case BASE_ITEM_HANDAXE:
case BASE_ITEM_KAMA:
case BASE_ITEM_KATANA:
case BASE_ITEM_KUKRI:
case BASE_ITEM_LONGSWORD:
case BASE_ITEM_SCIMITAR:
case BASE_ITEM_SHORTSWORD:
case BASE_ITEM_SHURIKEN:
case BASE_ITEM_SICKLE:
case BASE_ITEM_THROWINGAXE:
case BASE_ITEM_TWOBLADEDSWORD:
case BASE_ITEM_WHIP:
return DAMAGE_TYPE_SLASHING;
case BASE_ITEM_DAGGER:
case BASE_ITEM_DART:
case BASE_ITEM_SHORTSPEAR:
case BASE_ITEM_RAPIER:
case BASE_ITEM_LONGBOW:
case BASE_ITEM_SHORTBOW:
case BASE_ITEM_LIGHTCROSSBOW:
case BASE_ITEM_HEAVYCROSSBOW:
return DAMAGE_TYPE_PIERCING;
case BASE_ITEM_WARHAMMER:
case BASE_ITEM_MORNINGSTAR:
case BASE_ITEM_QUARTERSTAFF:
case BASE_ITEM_LIGHTFLAIL:
case BASE_ITEM_LIGHTHAMMER:
case BASE_ITEM_LIGHTMACE:
case BASE_ITEM_HEAVYFLAIL:
case BASE_ITEM_DIREMACE:
return DAMAGE_TYPE_BLUDGEONING;
}
return -1;
}