#include "x2_inc_itemprop"
const string s2DA = "baseitems";
//Condition Handlers
//Possible Results
//0 = Light Weapon (Unarmed and Creature excluded, they count for Power Attack)
//1 = One handed weapon (including unarmed and creature weapon)
//2 = Two handed weapon
int GetWeaponWeight(object oPC, int nWEAPON)
{
int nSIZE_PC = GetCreatureSize(oPC);
int nSIZE_WEAPON = StringToInt(Get2DAString(s2DA, "WeaponSize", nWEAPON));
switch (nWEAPON)
{
case BASE_ITEM_KUKRI:
case BASE_ITEM_DAGGER:
case BASE_ITEM_SHORTSWORD:
case BASE_ITEM_HANDAXE:
case BASE_ITEM_KAMA:
case BASE_ITEM_MACE:
case BASE_ITEM_SICKLE:
case BASE_ITEM_LIGHTHAMMER:
case BASE_ITEM_RAPIER:
if (nSIZE_WEAPON < nSIZE_PC) return 0;
break;
case BASE_ITEM_INVALID:
case BASE_ITEM_GLOVES:
case BASE_ITEM_CREATUREITEM:
return 1;
}
if (GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oPC) != OBJECT_INVALID) return 1;
if (nSIZE_WEAPON >= nSIZE_PC) return 2;
return 1;
}
//Possible Results
//0 = No Feats
//1 = Favored Enemy only
//2 = Improved Favored Enemy only
//x + 10 = Above result + Favored Power Attack
int GetFavoredEnemyFeats(object oPC, object oTARGET)
{
int nFEAT;
int nPOWER;
int nIMPROVED;
int nRACE = GetRacialType(oTARGET);
switch (nRACE)
{
case RACIAL_TYPE_ABERRATION:
nFEAT = FEAT_FAVORED_ENEMY_ABERRATION;
nIMPROVED = FEAT_IMPROVED_FAVORED_ENEMY_ABERRATION;
nPOWER = FEAT_FAVORED_POWER_ATTACK_ABERRATION;
break;
case RACIAL_TYPE_ANIMAL:
nFEAT = FEAT_FAVORED_ENEMY_ANIMAL;
nIMPROVED = FEAT_IMPROVED_FAVORED_ENEMY_ANIMAL;
nPOWER = FEAT_FAVORED_POWER_ATTACK_ANIMAL;
break;
case RACIAL_TYPE_BEAST:
nFEAT = FEAT_FAVORED_ENEMY_BEAST;
nIMPROVED = FEAT_IMPROVED_FAVORED_ENEMY_BEAST;
nPOWER = FEAT_FAVORED_POWER_ATTACK_BEAST;
break;
case RACIAL_TYPE_CONSTRUCT:
nFEAT = FEAT_FAVORED_ENEMY_CONSTRUCT;
nIMPROVED = FEAT_IMPROVED_FAVORED_ENEMY_CONSTRUCT;
nPOWER = FEAT_FAVORED_POWER_ATTACK_CONSTRUCT;
break;
case RACIAL_TYPE_DRAGON:
nFEAT = FEAT_FAVORED_ENEMY_DRAGON;
nIMPROVED = FEAT_IMPROVED_FAVORED_ENEMY_DRAGON;
nPOWER = FEAT_FAVORED_POWER_ATTACK_DRAGON;
break;
case RACIAL_TYPE_DWARF:
nFEAT = FEAT_FAVORED_ENEMY_DWARF;
nIMPROVED = FEAT_IMPROVED_FAVORED_ENEMY_DWARF;
nPOWER = FEAT_FAVORED_POWER_ATTACK_DWARF;
break;
case RACIAL_TYPE_ELEMENTAL:
nFEAT = FEAT_FAVORED_ENEMY_ELEMENTAL;
nIMPROVED = FEAT_IMPROVED_FAVORED_ENEMY_ELEMENTAL;
nPOWER = FEAT_FAVORED_POWER_ATTACK_ELEMENTAL;
break;
case RACIAL_TYPE_ELF:
nFEAT = FEAT_FAVORED_ENEMY_ELF;
nIMPROVED = FEAT_IMPROVED_FAVORED_ENEMY_ELF;
nPOWER = FEAT_FAVORED_POWER_ATTACK_ELF;
break;
case RACIAL_TYPE_FEY:
nFEAT = FEAT_FAVORED_ENEMY_FEY;
nIMPROVED = FEAT_IMPROVED_FAVORED_ENEMY_FEY;
nPOWER = FEAT_FAVORED_POWER_ATTACK_FEY;
break;
case RACIAL_TYPE_GIANT:
nFEAT = FEAT_FAVORED_ENEMY_GIANT;
nIMPROVED = FEAT_IMPROVED_FAVORED_ENEMY_GIANT;
nPOWER = FEAT_FAVORED_POWER_ATTACK_GIANT;
break;
case RACIAL_TYPE_GNOME:
nFEAT = FEAT_FAVORED_ENEMY_GNOME;
nIMPROVED = FEAT_IMPROVED_FAVORED_ENEMY_GNOME;
nPOWER = FEAT_FAVORED_POWER_ATTACK_GNOME;
break;
case RACIAL_TYPE_HUMANOID_GOBLINOID:
nFEAT = FEAT_FAVORED_ENEMY_GOBLINOID;
nIMPROVED = FEAT_IMPROVED_FAVORED_ENEMY_GOBLINOID;
nPOWER = FEAT_FAVORED_POWER_ATTACK_GOBLINOID;
break;
case RACIAL_TYPE_HALFELF:
nFEAT = FEAT_FAVORED_ENEMY_HALFELF;
nIMPROVED = FEAT_IMPROVED_FAVORED_ENEMY_HALFELF;
nPOWER = FEAT_FAVORED_POWER_ATTACK_HALFELF;
break;
case RACIAL_TYPE_HALFLING:
nFEAT = FEAT_FAVORED_ENEMY_HALFLING;
nIMPROVED = FEAT_IMPROVED_FAVORED_ENEMY_HALFLING;
nPOWER = FEAT_FAVORED_POWER_ATTACK_HALFLING;
break;
case RACIAL_TYPE_HALFORC:
nFEAT = FEAT_FAVORED_ENEMY_HALFORC;
nIMPROVED = FEAT_IMPROVED_FAVORED_ENEMY_HALFORC;
nPOWER = FEAT_FAVORED_POWER_ATTACK_HALFORC;
break;
case RACIAL_TYPE_HUMAN:
nFEAT = FEAT_FAVORED_ENEMY_HUMAN;
nIMPROVED = FEAT_IMPROVED_FAVORED_ENEMY_HUMAN;
nPOWER = FEAT_FAVORED_POWER_ATTACK_HUMAN;
break;
case RACIAL_TYPE_MAGICAL_BEAST:
nFEAT = FEAT_FAVORED_ENEMY_MAGICAL_BEAST;
nIMPROVED = FEAT_IMPROVED_FAVORED_ENEMY_MAGICAL_BEAST;
nPOWER = FEAT_FAVORED_POWER_ATTACK_MAGICAL_BEAST;
break;
case RACIAL_TYPE_HUMANOID_MONSTROUS:
nFEAT = FEAT_FAVORED_ENEMY_MONSTROUS;
nIMPROVED = FEAT_IMPROVED_FAVORED_ENEMY_MONSTROUS;
nPOWER = FEAT_FAVORED_POWER_ATTACK_MONSTROUS;
break;
case RACIAL_TYPE_HUMANOID_ORC:
nFEAT = FEAT_FAVORED_ENEMY_ORC;
nIMPROVED = FEAT_IMPROVED_FAVORED_ENEMY_ORC;
nPOWER = FEAT_FAVORED_POWER_ATTACK_ORC;
break;
case RACIAL_TYPE_OUTSIDER:
nFEAT = FEAT_FAVORED_ENEMY_OUTSIDER;
nIMPROVED = FEAT_IMPROVED_FAVORED_ENEMY_OUTSIDER;
nPOWER = FEAT_FAVORED_POWER_ATTACK_OUTSIDER;
break;
case RACIAL_TYPE_HUMANOID_REPTILIAN:
nFEAT = FEAT_FAVORED_ENEMY_REPTILIAN;
nIMPROVED = FEAT_IMPROVED_FAVORED_ENEMY_REPTILIAN;
nPOWER = FEAT_FAVORED_POWER_ATTACK_REPTILIAN;
break;
case RACIAL_TYPE_SHAPECHANGER:
nFEAT = FEAT_FAVORED_ENEMY_SHAPECHANGER;
nIMPROVED = FEAT_IMPROVED_FAVORED_ENEMY_SHAPECHANGER;
nPOWER = FEAT_FAVORED_POWER_ATTACK_SHAPECHANGER;
break;
case RACIAL_TYPE_UNDEAD:
nFEAT = FEAT_FAVORED_ENEMY_UNDEAD;
nIMPROVED = FEAT_IMPROVED_FAVORED_ENEMY_UNDEAD;
nPOWER = FEAT_FAVORED_POWER_ATTACK_UNDEAD;
break;
case RACIAL_TYPE_VERMIN:
nFEAT = FEAT_FAVORED_ENEMY_VERMIN;
nIMPROVED = FEAT_IMPROVED_FAVORED_ENEMY_VERMIN;
nPOWER = FEAT_FAVORED_POWER_ATTACK_UNDEAD;
break;
default: return 0;
}
int nFAVOR = 0;
if (GetHasFeat(nIMPROVED, oPC, TRUE) == TRUE) nFAVOR = 2;
else if (GetHasFeat(nFEAT, oPC, TRUE) == TRUE) nFAVOR = 1;
if (GetHasFeat(nPOWER, oPC, TRUE) == TRUE) nFAVOR = nFAVOR + 10;
return nFAVOR;
}
//Damage Calculators
int GetDamage_PowerAttack(object oPC, int nWEAPON, int nWEIGHT, int nFAVOR)
{
if (nWEIGHT == 0) return 0; //Light weapons don't get any damage bonus from power attack
int nPOW;
int nMODE = GetLastAttackMode(oPC);
if (nMODE == COMBAT_MODE_IMPROVED_POWER_ATTACK)
{
if (GetHasFeat(FEAT_SUPREME_POWER_ATTACK, oPC, TRUE) == TRUE) nPOW = 12;
else if (GetHasFeat(FEAT_ENHANCED_POWER_ATTACK, oPC, TRUE) == TRUE) nPOW = 10;
else nPOW = 6;
}
else if (nMODE == COMBAT_MODE_POWER_ATTACK)
{
if (GetHasFeat(FEAT_SUPREME_POWER_ATTACK, oPC, TRUE) == TRUE) nPOW = 6;
else if (GetHasFeat(FEAT_ENHANCED_POWER_ATTACK, oPC, TRUE) == TRUE) nPOW = 5;
else nPOW = 3;
}
else return 0;
int nMULT = 1;
if (nWEIGHT == 2) nMULT = nMULT + 1;
if (nFAVOR >= 10) nMULT = nMULT + 1;
nPOW = nPOW * nMULT;
return nPOW;
}
int GetDamage_FavoredEnemy(object oPC, int nFAVOR)
{
if ((nFAVOR == 0) || (nFAVOR == 10)) return 0;
int nDMG = 1 + GetLevelByClass(CLASS_TYPE_RANGER, oPC) / 5;
if ((nFAVOR == 2) || (nFAVOR == 12)) nDMG = nDMG + 3;
return nDMG;
}
int GetDamage_Specialization(object oPC, int nWEAPON)
{
int nFEAT = StringToInt(Get2DAString(s2DA, "FEATEpicWpnSpec", nWEAPON));
if (GetHasFeat(nFEAT, oPC, TRUE) == TRUE) return 6;
else
{
nFEAT = StringToInt(Get2DAString(s2DA, "FEATGrtrWpnSpec", nWEAPON));
if (GetHasFeat(nFEAT, oPC, TRUE) == TRUE) return 4;
else
{
nFEAT = StringToInt(Get2DAString(s2DA, "FEATWpnSpec", nWEAPON));
if (GetHasFeat(nFEAT, oPC, TRUE) == TRUE) return 2;
}
}
return 0;
}
int GetDamage_AbilityScores(object oPC, int nWEAPON, int nWEIGHT)
{
int nSTR = GetAbilityModifier(ABILITY_STRENGTH, oPC);
if (GetHasFeat(1957, oPC, TRUE) == TRUE) //Combat Insight
{
int nINT = GetAbilityModifier(ABILITY_INTELLIGENCE, oPC);
if (nINT > nSTR) nSTR = nINT;
}
if (nWEIGHT == 2) nSTR = (nSTR * 3) / 2;
return nSTR;
}
int GetDamage_Weapon(object oWEAPON, int nWEAPON)
{
int nDICE_NUM = StringToInt(Get2DAString(s2DA, "NumDice", nWEAPON));
int nDICE_SIZE = StringToInt(Get2DAString(s2DA, "DieToRoll", nWEAPON));
int nDMG = nDICE_NUM * (1 + Random(nDICE_SIZE));
if (nDMG < 1) nDMG = 1;
nDMG = nDMG + IPGetWeaponEnhancementBonus(oWEAPON);
return nDMG;
}
// Main Event
void ApplyResistedDamage(object oPC, object oTARGET, int nDEALT)
{
object oWEAPON = GetLastWeaponUsed(oPC);
int nFAVOR = GetFavoredEnemyFeats(oPC, oTARGET);
int nCACHE = GetNum2DARows(s2DA);
int nWEAPON = GetBaseItemType(oWEAPON);
int nWEIGHT = GetWeaponWeight(oPC, nWEAPON);
int nDMG = GetDamage_Weapon(oWEAPON, nWEAPON) +
GetDamage_AbilityScores(oPC, nWEAPON, nWEIGHT) +
GetDamage_Specialization(oPC, nWEAPON) +
GetDamage_FavoredEnemy(oPC, nFAVOR) +
GetDamage_PowerAttack(oPC, nWEAPON, nWEIGHT, nFAVOR);
if (nDMG <= nDEALT) return;
effect eFX = EffectDamage(nDMG - nDEALT, DAMAGE_TYPE_NEGATIVE, DAMAGE_POWER_NORMAL, TRUE);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eFX, oTARGET);
}
void ObtainDamageDealt(object oPC, object oTARGET, int nHP)
{
int nDEALT = GetTotalDamageDealt();
if (nDEALT < 0) nDEALT = 0;
AssignCommand(oPC, ApplyResistedDamage(oPC, oTARGET, nDEALT));
}
void main()
{
object oPC = OBJECT_SELF;
object oTARGET = GetSpellTargetObject();
int nHP = GetCurrentHitPoints(oTARGET);
AssignCommand(oTARGET, ObtainDamageDealt(oPC, oTARGET, nHP));
}