Just a minor update for AL, a couple bugs fixed and a few more checks implemented.
- permanent -5 damage after a server crash bug fixed (won't affect existing bugged weapons, they'll need to be replaced)
Code: Select all
Mostly minor changes to the following functions:
-ACR_ToggleNLDMode()
-ACR_NLD_OnWeaponSwitch()
-_NLDamageReductionCheck()
-_ApplyNLDFist()
void ACR_ToggleNLDMode(object oUser = OBJECT_SELF)
{
object oWeapR = GetItemInSlot(4, oUser);
object oWeapL = GetItemInSlot(5, oUser);
object oCweap = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oUser);
if(_GetNLDMode(oUser))
{
if(GetIsObjectValid(oWeapR) && GetWeaponType(oWeapR) != WEAPON_TYPE_NONE
&& GetWeaponRanged(oWeapR) != TRUE)
ACR_NLD_OnWeaponSwitch(oUser, oWeapR, FALSE);
if(GetIsObjectValid(oWeapL) && GetWeaponType(oWeapL) != WEAPON_TYPE_NONE)
ACR_NLD_OnWeaponSwitch(oUser, oWeapL, FALSE);
if(GetIsObjectValid(oCweap) && GetTag(oCweap) == "acr_nld_fist")
{
DestroyObject(oCweap, 0.2, FALSE);
}
_RestoreNLDSneakAttackFeats(oUser);
FeatRemove(oUser, FEAT_WEAPON_PROFICIENCY_CREATURE);
if(GetHasFeat(FEAT_WEAPON_FOCUS_CREATURE, oUser))
FeatRemove(oUser, FEAT_WEAPON_FOCUS_CREATURE);
DelayCommand(0.1,_SetNLDMode(oUser, FALSE));
}
else
{
_SetNLDMode(oUser, TRUE);
if(GetIsObjectValid(oWeapR) && GetWeaponType(oWeapR) != WEAPON_TYPE_NONE
&& GetWeaponRanged(oWeapR) != TRUE)
DelayCommand(0.1,ACR_NLD_OnWeaponSwitch(oUser, oWeapR, TRUE));
if(GetIsObjectValid(oWeapL) && GetWeaponType(oWeapL) != WEAPON_TYPE_NONE)
DelayCommand(0.1,ACR_NLD_OnWeaponSwitch(oUser, oWeapL, TRUE));
_HandleNLDSneakAttacks(oUser);
DelayCommand(0.1, _GiveNLDFist(oUser));
}
}
void ACR_NLD_OnWeaponSwitch(object oUser, object oWeapon, int bEquipped = TRUE)
{
if(!_GetNLDMode(oUser))
return;
object oWeapR = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oUser);
object oWeapL = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oUser);
object oCweap = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oUser);
// handle offhand/2handed str modifiers for currently equipped weapons
if(GetIsObjectValid(oWeapR) && GetWeaponRanged(oWeapR) != TRUE
&& GetWeaponType(oWeapR) != WEAPON_TYPE_NONE)
{
SetLocalInt(oWeapR,ACR_NLD_WOFFHAND,FALSE);
// item in the offhand?
if(GetIsObjectValid(oWeapL) && oWeapL != oWeapR)
{
SetLocalInt(oWeapR,ACR_NLD_W2HANDED,FALSE);
if(GetWeaponType(oWeapL) != WEAPON_TYPE_NONE)
SetLocalInt(oWeapL,ACR_NLD_WOFFHAND,TRUE);
}
else
{
//check weapon size vs creature size to determine if it's wielded 2 handed
int nSize = StringToInt(Get2DAString("baseitems","WeaponSize",GetBaseItemType(oWeapR)));
// Debug
// SendMessageToPC(oUser, "Weapon size is: "+IntToString(nSize));
if((GetCreatureSize(oUser) == CREATURE_SIZE_HUGE && nSize >= 4)
|| (GetCreatureSize(oUser) == CREATURE_SIZE_LARGE && nSize >= 4)
|| (GetCreatureSize(oUser) == CREATURE_SIZE_MEDIUM && nSize >= 3)
|| (GetCreatureSize(oUser) == CREATURE_SIZE_SMALL && nSize >= 2)
|| (GetCreatureSize(oUser) == CREATURE_SIZE_TINY && nSize >= 1))
SetLocalInt(oWeapR,ACR_NLD_W2HANDED,TRUE);
else
SetLocalInt(oWeapR,ACR_NLD_W2HANDED,FALSE);
}
}
else if(!GetIsObjectValid(oWeapR))
{
// need to work on barehanded subdual.
if(!GetIsObjectValid(oCweap))
{
_GiveNLDFist(oUser);
}
}
// now look at the weapon that was just equipped
if(GetTag(oWeapon) == "acr_nld_fist")
return;
if(GetIsObjectValid(oWeapon) && GetWeaponRanged(oWeapon) != TRUE
&& GetWeaponType(oWeapon) != WEAPON_TYPE_NONE)
{
itemproperty iProp;
itemproperty iHit = ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER,1);
itemproperty iNoDam = ItemPropertyNoDamage();
itemproperty iNoStr = ItemPropertyDamagePenalty(5);
int nDiceDam, nDiceNum, nBaseItem, nSADice, nDamPenalty;
// weapon was just unequipped: remove NLD properties, zero damage/sneak vars
if(bEquipped == FALSE)
{
iProp = GetFirstItemProperty(oWeapon);
while(GetIsItemPropertyValid(iProp))
{
if(GetItemPropertyType(iProp) == ITEM_PROPERTY_ONHITCASTSPELL
|| GetItemPropertyType(iProp) == ITEM_PROPERTY_NO_DAMAGE
|| GetItemPropertyType(iProp) == ITEM_PROPERTY_DECREASED_DAMAGE)
DelayCommand(0.5,AssignCommand(oUser,RemoveItemProperty(oWeapon,iProp)));
iProp = GetNextItemProperty(oWeapon);
}
SetLocalInt(oWeapon,ACR_NLD_WOFFHAND,FALSE);
SetLocalInt(oWeapon,ACR_NLD_W2HANDED,FALSE);
SetLocalInt(oWeapon,ACR_NLD_SA_DICE,0);
nDamPenalty = GetLocalInt(oWeapon, ACR_NLD_DAMAGE_PENALTY);
if(nDamPenalty >= 1 && nDamPenalty < 255)
AssignCommand(oUser,AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamagePenalty(nDamPenalty),oWeapon));
}
// weapon was just equipped: add NLD properties, set damage/sneak vars
else
{
iProp = GetFirstItemProperty(oWeapon);
while(GetIsItemPropertyValid(iProp))
{
if(GetItemPropertyType(iProp) == ITEM_PROPERTY_DECREASED_DAMAGE)
{
nDamPenalty = GetItemPropertyCostTableValue(iProp);
SetLocalInt(oWeapon, ACR_NLD_DAMAGE_PENALTY, nDamPenalty);
}
iProp = GetNextItemProperty(oWeapon);
}
if(nDamPenalty < 1)
SetLocalInt(oWeapon, ACR_NLD_DAMAGE_PENALTY, 255);
nBaseItem = GetBaseItemType(oWeapon);
nDiceDam = StringToInt(Get2DAString("baseitems","DieToRoll",nBaseItem));
nDiceNum = StringToInt(Get2DAString("baseitems","NumDice",nBaseItem));
nSADice = _GetNLDSneakAttackDice(oUser);
SetLocalInt(oWeapon,ACR_NLD_DICE_DAMAGE,nDiceDam);
SetLocalInt(oWeapon,ACR_NLD_DICE_NUMBER,nDiceNum);
SetLocalInt(oWeapon,ACR_NLD_SA_DICE,nSADice);
AssignCommand(oUser,AddItemProperty(DURATION_TYPE_PERMANENT,iHit,oWeapon));
AssignCommand(oUser,AddItemProperty(DURATION_TYPE_PERMANENT,iNoDam,oWeapon));
AssignCommand(oUser,AddItemProperty(DURATION_TYPE_PERMANENT,iNoStr,oWeapon));
}
}
}
string _NLDamageReductionCheck(object oTarget, object oWeapon, int nNLDamage, int nHeal)
{
string sReturn = "";
int nDam = 0;
int nHigh;
string sHeal;
string sWeapon = GetTag(oWeapon);
object oSkin = GetItemInSlot(INVENTORY_SLOT_CARMOUR, oTarget);
int nSDancer = GetLevelByClass(CLASS_TYPE_SHADOWDANCER, oTarget);
// Determine if oTarget has DR bypassable by adamantine weapons (spells only)
int nAdm = (GetHasSpellEffect(SPELL_PREMONITION, oTarget) == TRUE
|| GetHasSpellEffect(SPELL_SHADES_TARGET_CASTER, oTarget) == TRUE) ? 30 :
(GetHasSpellEffect(SPELL_GREATER_STONESKIN, oTarget) == TRUE
|| GetHasSpellEffect(SPELL_ETHEREAL_VISAGE, oTarget) == TRUE) ? 20 :
(GetHasSpellEffect(SPELL_STONESKIN, oTarget) == TRUE
|| GetHasSpellEffect(SPELL_SHADES_STONESKIN, oTarget) == TRUE
|| GetHasSpellEffect(SPELL_SHADOW_SHIELD, oTarget) == TRUE
|| (GetHasSpellEffect(SPELL_SHADOW_EVADE, oTarget) && nSDancer >= 10)) ? 10 :
(GetHasSpellEffect(SPELLABILITY_MERGE_WITH_STONE, oTarget) == TRUE) ? 5 : FALSE;
if(nAdm != FALSE)
{
// Check the attackers weapon - is it adamantine?
if(TestStringAgainstPattern("**"+ACR_NLD_MAT_ADAMANTINE+"**", sWeapon))
nAdm = FALSE;
}
// Determine if oTarget has DR bypassable by magic weapons
int nMgc = (GetLevelByClass(CLASS_TYPE_MONK, oTarget) >= 20) ? 10 :
(GetHasSpellEffect(SPELL_GHOSTLY_VISAGE, oTarget) == TRUE
|| GetHasSpellEffect(SPELLABILITY_AS_GHOSTLY_VISAGE, oTarget) == TRUE
|| (GetHasSpellEffect(351, oTarget) == TRUE) || (nSDancer <= 5
&& GetHasSpellEffect(SPELL_SHADOW_EVADE, oTarget))) ? 5 : FALSE;
if(nMgc != FALSE)
{
// Check the attackers weapon - is it magical?
if(GetItemHasItemProperty(oWeapon, ITEM_PROPERTY_ENHANCEMENT_BONUS))
nMgc = FALSE;
}
// Determine if oTarget has DR bypassable by cold iron weapons
int nWlk = GetLevelByClass(CLASS_TYPE_WARLOCK, oTarget);
int nCld= (nWlk >= 3 && nWlk < 7) ? 1 : (nWlk >= 7 && nWlk < 11) ? 2 :
(nWlk >= 11 && nWlk < 15) ? 3 : (nWlk >= 15 && nWlk < 19) ? 4 :
(nWlk >= 19 || GetLevelByClass(CLASS_TYPE_SPIRIT_SHAMAN, oTarget) >= 20) ? 5 :
(GetHasFeat(2087, oTarget)) ? 10 : FALSE;
int nFey = GetHasFeat(2184, oTarget, TRUE);
int nCnt;
if(nFey)
{
for(nCnt=2181;nCnt<=2184;nCnt++)
{
if(GetHasFeat(nFey, oTarget, TRUE))
nFey += 1;
}
nCld += nFey;
}
if(nCld != FALSE)
{
// Check the attackers weapon - is it cold iron?
if(TestStringAgainstPattern("**"+ACR_NLD_MAT_COLDIRON+"**", sWeapon))
nCld = FALSE;
}
// Determine if oTarget has DR bypassable by silver weapons
int nSlv = (GetHasSpellEffect(SPELL_I_DARK_FORESIGHT, oTarget) == TRUE || GetHasFeat(2088, oTarget)
|| (GetHasSpellEffect(SPELL_SHADOW_EVADE, oTarget) && (nSDancer == 8 || nSDancer == 9))
|| GetRacialType(oTarget) == RACIAL_TYPE_SHAPECHANGER) ? 10 :
(GetHasSpellEffect(SPELL_SHADOW_EVADE, oTarget) && (nSDancer == 6 || nSDancer == 7)) ? 5 : FALSE;
if(nSlv != FALSE)
{
// Check the attackers weapon - is it alchemical silver?
if(TestStringAgainstPattern("**"+ACR_NLD_MAT_ALCSILVER+"**", sWeapon))
nSlv = FALSE;
}
if(nAdm != FALSE || nMgc != FALSE || nSlv != FALSE || nCld != FALSE)
{
nHigh = (nAdm >= nMgc && nAdm >= nSlv && nAdm >= nCld) ? nAdm :
(nSlv >= nMgc && nSlv >= nCld) ? nSlv :
(nCld >= nMgc) ? nCld : nMgc;
}
else
nHigh = FALSE;
if(nHigh != FALSE)
{
effect eDam;
if(nHigh >= nNLDamage)
{
nDam = (nNLDamage > nHeal) ? nNLDamage - nHeal : 0;
sReturn = "ND_00";
}
else
{
sReturn = IntToString(nNLDamage - nHigh);
if(GetStringLength(sReturn) == 1)
sReturn = "0"+sReturn;
if(nHigh >= nHeal)
{
nDam = nHigh - nHeal;
sReturn = "ND_"+sReturn;
}
else
{
nDam = 0;
sHeal = IntToString(nHeal - nHigh) + "_";
if(GetStringLength(sHeal) == 2)
sHeal = "0"+sHeal;
sReturn = sHeal+sReturn;
}
}
if(nDam > 0)
{
eDam = EffectDamage(nDam, DAMAGE_TYPE_BLUDGEONING);
AssignCommand(GetItemPossessor(oWeapon),
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
}
}
else
{
// Determine if oTarget has DR not bypassable by anything
// (barb DR or adamantine armor/shield only)
int nBarb = GetLevelByClass(CLASS_TYPE_BARBARIAN, oTarget);
int nDDef = GetLevelByClass(CLASS_TYPE_DWARVENDEFENDER, oTarget);
int nNoPass = (nBarb >= 7 && nBarb < 10) ? 1 : (nBarb >= 10 && nBarb < 13) ? 2 :
((nBarb >= 13 && nBarb < 16) || (nDDef >= 6 && nDDef < 10)) ? 3 :
(nBarb >= 16 && nBarb < 19) ? 4 : (nBarb >= 19) ? 5 : (nDDef >= 10) ? 6 : FALSE;
if(nNoPass != FALSE)
{
// Check for the Greater Resiliency feat (barb only)
nNoPass = (GetHasFeat(FEAT_GREATER_RESILIENCY, oTarget) == TRUE) ?
nNoPass+1 : nNoPass;
}
int nArm = 0;
int nRank;
object oArm = GetItemInSlot(INVENTORY_SLOT_CHEST, oTarget);
if(GetIsObjectValid(oArm))
{
string sArm = GetTag(oArm);
if(TestStringAgainstPattern("**"+ACR_NLD_MAT_ADAMANTINE+"**", sArm))
{
nRank = GetArmorRank(oArm);
nArm = (nRank == ARMOR_RANK_HEAVY) ? 3 : (nRank == ARMOR_RANK_MEDIUM) ? 2 :
(nRank == ARMOR_RANK_LIGHT) ? 1 : 0;
}
}
object oShd = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oTarget);
if(GetIsObjectValid(oShd))
{
string sShd = GetTag(oShd);
if(TestStringAgainstPattern("**"+ACR_NLD_MAT_ADAMANTINE+"**", sShd))
{
int nType = GetBaseItemType(oShd);
nArm = (nType == BASE_ITEM_TOWERSHIELD && nArm < 3) ? 3 :
(nType == BASE_ITEM_LARGESHIELD && nArm < 2) ? 2 :
(nType == BASE_ITEM_SMALLSHIELD && nArm < 1) ? 1 : nArm;
}
}
nNoPass = (nNoPass >= nArm) ? nNoPass : nArm;
if(nNoPass >= 1)
{
if(nNoPass < nNLDamage)
{
sReturn = IntToString(nNLDamage - nNoPass);
if(GetStringLength(sReturn) == 1)
sReturn == "0"+sReturn;
if(nNoPass >= nHeal)
sReturn = "ND_"+sReturn;
else
{
sHeal = IntToString(nHeal - nNoPass) + "_";
if(GetStringLength(sHeal) == 2)
sHeal = "0"+sHeal;
sReturn = sHeal + sReturn;
}
}
else
sReturn = "ND_00";
}
else
{
sReturn = IntToString(nNLDamage);
if(GetStringLength(sReturn) == 1)
sReturn = "0"+sReturn;
sHeal = IntToString(nHeal) + "_";
if(GetStringLength(sHeal) == 2)
sHeal = "0"+sHeal;
sReturn = sHeal + sReturn;
}
}
return sReturn;
}
void _ApplyNLDFist(object oUser)
{
object oFist = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oUser);
if(!GetIsObjectValid(oFist))
{
return;
}
int nDiceDam, nDiceNum, nSADice, nSlot, nSize, nMonk;
nSize = GetCreatureSize(oUser);
nDiceNum = 1;
nDiceDam = (nSize == CREATURE_SIZE_SMALL) ? 2 : 3;
nMonk = GetLevelByClass(CLASS_TYPE_MONK, oUser)
+ GetLevelByClass(CLASS_TYPE_SACREDFIST, oUser);
if(nMonk >= 1)
{
if(nMonk <= 3)
nDiceDam = (nSize == CREATURE_SIZE_SMALL) ? 4 : 6;
else if(nMonk <= 7)
nDiceDam = (nSize == CREATURE_SIZE_SMALL) ? 6 : 8;
else if(nMonk <= 11)
nDiceDam = (nSize == CREATURE_SIZE_SMALL) ? 8 : 10;
else if(nMonk <= 15)
{
nDiceDam = (nSize == CREATURE_SIZE_SMALL) ? 10 : 6;
nDiceNum = (nSize == CREATURE_SIZE_SMALL) ? 1 : 2;
}
else if(nMonk <= 19)
{
nDiceDam = (nSize == CREATURE_SIZE_SMALL) ? 6 : 8;
nDiceNum = 2;
}
else
{
nDiceDam = (nSize == CREATURE_SIZE_SMALL) ? 8 : 10;
nDiceNum = 2;
}
}
nSADice = _GetNLDSneakAttackDice(oUser);
SetLocalInt(oFist, ACR_NLD_DICE_DAMAGE, nDiceDam);
SetLocalInt(oFist, ACR_NLD_DICE_NUMBER, nDiceNum);
SetLocalInt(oFist, ACR_NLD_SA_DICE, nSADice);
SetLocalInt(oFist, ACR_NLD_WOFFHAND, FALSE);
SetLocalInt(oFist, ACR_NLD_W2HANDED, FALSE);
if(GetHasFeat(FEAT_WEAPON_FOCUS_UNARMED_STRIKE, oUser))
FeatAdd(oUser, FEAT_WEAPON_FOCUS_CREATURE, FALSE);
}