Further file organization
Further file organization
This commit is contained in:
257
nwn/nwnprc/trunk/scripts/prc_duelist.nss
Normal file
257
nwn/nwnprc/trunk/scripts/prc_duelist.nss
Normal file
@@ -0,0 +1,257 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: [Duelist Feats]
|
||||
//:: [prc_duelist.nss]
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Check to see which Duelist feats a creature
|
||||
//:: has and apply the appropriate bonuses.
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Aaon Graywolf
|
||||
//:: Created On: Dec 20, 2003
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Fixed By: Stratovarius
|
||||
//:: Fixed On: Sep 05, 2018
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
#include "prc_inc_combat"
|
||||
#include "x0_i0_modes"
|
||||
|
||||
// * Applies the Duelist's AC bonuses as CompositeBonuses on the object's skin.
|
||||
// * AC bonus is determined by object's int bonus
|
||||
// * iOnOff = TRUE/FALSE
|
||||
void DuelistCannyDefense(object oPC, object oSkin, int iOnOff)
|
||||
{
|
||||
int iIntBonus = GetAbilityModifier(ABILITY_INTELLIGENCE, oPC);
|
||||
|
||||
// limits bonus to class level as per 3.5e rules.
|
||||
int iDuelistLevel = GetLevelByClass(CLASS_TYPE_DUELIST,oPC);
|
||||
if(iIntBonus > iDuelistLevel) iIntBonus = iDuelistLevel;
|
||||
|
||||
if(iOnOff){
|
||||
SetCompositeBonus(oSkin, "CannyDefenseBonus", iIntBonus, ITEM_PROPERTY_AC_BONUS);
|
||||
if(GetLocalInt(oPC, "CannyDefense") != TRUE)
|
||||
SetLocalInt(oPC, "CannyDefense", TRUE);
|
||||
}
|
||||
else {
|
||||
SetCompositeBonus(oSkin, "CannyDefenseBonus", 0, ITEM_PROPERTY_AC_BONUS);
|
||||
if(GetLocalInt(oPC, "CannyDefense") != FALSE)
|
||||
SetLocalInt(oPC, "CannyDefense", FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
// * Applies the Duelist's reflex bonuses as CompositeBonuses on the object's skin.
|
||||
// Bonus is always 2
|
||||
void DuelistGrace(object oPC, object oSkin)
|
||||
{
|
||||
if(!GetLocalInt(oPC, "Grace"))
|
||||
{
|
||||
SetCompositeBonus(oSkin, "GraceBonus", 2, ITEM_PROPERTY_SAVING_THROW_BONUS_SPECIFIC, IP_CONST_SAVEBASETYPE_REFLEX);
|
||||
if(GetLocalInt(oPC, "Grace") != TRUE)
|
||||
SetLocalInt(oPC, "Grace", TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCompositeBonus(oSkin, "GraceBonus", 0, ITEM_PROPERTY_SAVING_THROW_BONUS_SPECIFIC, IP_CONST_SAVEBASETYPE_REFLEX);
|
||||
if(GetLocalInt(oPC, "Grace") != FALSE)
|
||||
SetLocalInt(oPC, "Grace", FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Incorrect, archived
|
||||
/*
|
||||
void RemoveDuelistPreciseStrike(object oWeap)
|
||||
{
|
||||
int iSlashBonus = GetLocalInt(oWeap,"DuelistPreciseSlash");
|
||||
if (iSlashBonus) RemoveSpecificProperty(oWeap, ITEM_PROPERTY_DAMAGE_BONUS, IP_CONST_DAMAGETYPE_SLASHING, iSlashBonus, 1, "DuelistPreciseSlash", -1, DURATION_TYPE_TEMPORARY);
|
||||
}
|
||||
|
||||
void DuelistPreciseStrike(object oPC, object oWeap)
|
||||
{
|
||||
int iSlashBonus = 0;
|
||||
int iDuelistLevel = GetLevelByClass(CLASS_TYPE_DUELIST,oPC);
|
||||
|
||||
RemoveDuelistPreciseStrike(oWeap);
|
||||
|
||||
// since new duelist gains it every 5 levels
|
||||
iDuelistLevel /= 5;
|
||||
|
||||
switch(iDuelistLevel)
|
||||
{
|
||||
case 1:
|
||||
iSlashBonus = IP_CONST_DAMAGEBONUS_1d4;
|
||||
break;
|
||||
case 2:
|
||||
iSlashBonus = IP_CONST_DAMAGEBONUS_2d4;
|
||||
break;
|
||||
case 3:
|
||||
iSlashBonus = IP_CONST_DAMAGEBONUS_3d4;
|
||||
break;
|
||||
case 4:
|
||||
iSlashBonus = IP_CONST_DAMAGEBONUS_4d4;
|
||||
break;
|
||||
case 5:
|
||||
iSlashBonus = IP_CONST_DAMAGEBONUS_5d4;
|
||||
break;
|
||||
case 6:
|
||||
iSlashBonus = IP_CONST_DAMAGEBONUS_6d4;
|
||||
break;
|
||||
}
|
||||
|
||||
int nDamageType = GetWeaponDamageType(oWeap);
|
||||
if(iSlashBonus)
|
||||
{
|
||||
SetLocalInt(oWeap,"DuelistPreciseSlash",iSlashBonus); // misnomer for simplicity's sake
|
||||
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyDamageBonus(nDamageType, iSlashBonus), oWeap, 99999.9);
|
||||
}
|
||||
}
|
||||
|
||||
if(bPStrk > 0 &&
|
||||
GetBaseItemType(oLefthand) != BASE_ITEM_SMALLSHIELD &&
|
||||
GetBaseItemType(oLefthand) != BASE_ITEM_LARGESHIELD &&
|
||||
GetBaseItemType(oLefthand) != BASE_ITEM_TOWERSHIELD &&
|
||||
(GetBaseItemType(oWeapon) == BASE_ITEM_RAPIER ||
|
||||
GetBaseItemType(oWeapon) == BASE_ITEM_DAGGER ||
|
||||
GetBaseItemType(oWeapon) == BASE_ITEM_SHORTSWORD))
|
||||
DuelistPreciseStrike(oPC, oWeapon);
|
||||
|
||||
if(GetLocalInt(oPC,"ONEQUIP") == 1)
|
||||
RemoveDuelistPreciseStrike(GetItemLastUnequipped());
|
||||
|
||||
if(GetBaseAC(oArmor) != 0 ||
|
||||
GetBaseItemType(oLefthand) == BASE_ITEM_SMALLSHIELD ||
|
||||
GetBaseItemType(oLefthand) == BASE_ITEM_LARGESHIELD ||
|
||||
GetBaseItemType(oLefthand) == BASE_ITEM_TOWERSHIELD)
|
||||
RemoveDuelistPreciseStrike(oWeapon);
|
||||
*/
|
||||
|
||||
void main()
|
||||
{
|
||||
int nEvent = GetRunningEvent();
|
||||
object oPC;
|
||||
switch(nEvent)
|
||||
{
|
||||
case EVENT_ITEM_ONHIT: oPC = OBJECT_SELF; break;
|
||||
case EVENT_ONPLAYEREQUIPITEM: oPC = GetItemLastEquippedBy(); break;
|
||||
case EVENT_ONPLAYERUNEQUIPITEM: oPC = GetItemLastUnequippedBy(); break;
|
||||
case EVENT_ONHEARTBEAT: oPC = OBJECT_SELF; break;
|
||||
|
||||
default:
|
||||
oPC = OBJECT_SELF;
|
||||
}
|
||||
int nDuel = GetLevelByClass(CLASS_TYPE_DUELIST, oPC);
|
||||
object oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC);
|
||||
object oLefthand = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oPC);
|
||||
object oSkin = GetPCSkin(oPC);
|
||||
object oArmor = GetItemInSlot(INVENTORY_SLOT_CHEST, oPC);
|
||||
|
||||
if(nEvent == FALSE)
|
||||
{
|
||||
//Determine which duelist feats the character has
|
||||
int bCanDef = GetHasFeat(FEAT_CANNY_DEFENSE, oPC);
|
||||
int bGrace = GetHasFeat(FEAT_GRACE, oPC);
|
||||
int iLefthand = GetBaseItemType(oLefthand);
|
||||
|
||||
//Apply bonuses accordingly
|
||||
if(bCanDef > 0 && GetBaseAC(oArmor) == 0 &&
|
||||
GetBaseItemType(oLefthand) != BASE_ITEM_SMALLSHIELD &&
|
||||
GetBaseItemType(oLefthand) != BASE_ITEM_LARGESHIELD &&
|
||||
GetBaseItemType(oLefthand) != BASE_ITEM_TOWERSHIELD)
|
||||
DuelistCannyDefense(oPC, oSkin, TRUE);
|
||||
else
|
||||
DuelistCannyDefense(oPC, oSkin, FALSE);
|
||||
|
||||
if(bGrace > 0 && GetBaseAC(oArmor) == 0 &&
|
||||
GetBaseItemType(oLefthand) != BASE_ITEM_SMALLSHIELD &&
|
||||
GetBaseItemType(oLefthand) != BASE_ITEM_LARGESHIELD &&
|
||||
GetBaseItemType(oLefthand) != BASE_ITEM_TOWERSHIELD)
|
||||
DuelistGrace(oPC, oSkin);
|
||||
else
|
||||
DuelistGrace(oPC, oSkin);
|
||||
|
||||
//Defensive Strike
|
||||
/*if(nDuel >= 7 && GetHasFeat(FEAT_EXPERTISE, oPC))
|
||||
{
|
||||
if(DEBUG) DoDebug("prc_duelist: Adding eventhooks");
|
||||
AddEventScript(oPC, EVENT_ONHEARTBEAT, "prc_duelist", TRUE, FALSE);
|
||||
}*/
|
||||
AddEventScript(oPC, EVENT_ONPLAYEREQUIPITEM, "prc_duelist", TRUE, FALSE);
|
||||
AddEventScript(oPC, EVENT_ONPLAYERUNEQUIPITEM, "prc_duelist", TRUE, FALSE);
|
||||
}
|
||||
// We're being called from the OnHeartbeat eventhook, so check or skip
|
||||
/*if(nEvent == EVENT_ONHEARTBEAT)
|
||||
{
|
||||
// Only applies when using expertise
|
||||
if(GetModeActive(ACTION_MODE_EXPERTISE) || GetActionMode(oPC, ACTION_MODE_EXPERTISE) || GetLastAttackMode(oPC) == COMBAT_MODE_EXPERTISE ||
|
||||
GetModeActive(ACTION_MODE_IMPROVED_EXPERTISE) || GetActionMode(oPC, ACTION_MODE_IMPROVED_EXPERTISE) || GetLastAttackMode(oPC) == COMBAT_MODE_IMPROVED_EXPERTISE)
|
||||
{
|
||||
effect eAC = EffectACIncrease(nDuel, AC_DODGE_BONUS);
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eAC, oPC, 6.0);
|
||||
}
|
||||
}// end if - Running OnHeart event*/
|
||||
else if(nEvent == EVENT_ITEM_ONHIT && !GetIsObjectValid(oLefthand) && nDuel >= 5) // Left hand must be empty, Duelist must be at least level 5
|
||||
{
|
||||
oWeapon = GetSpellCastItem();
|
||||
object oTarget = PRCGetSpellTargetObject();
|
||||
if(DEBUG) DoDebug("prc_duelist: OnHit:\n"
|
||||
+ "oPC = " + DebugObject2Str(oPC) + "\n"
|
||||
+ "oWeapon = " + DebugObject2Str(oWeapon) + "\n"
|
||||
+ "oTarget = " + DebugObject2Str(oTarget) + "\n"
|
||||
);
|
||||
|
||||
// Only applies to weapons, target must not be immune to criticals/sneak attacks
|
||||
if(IPGetIsMeleeWeapon(oWeapon) && !GetIsImmune(oTarget, IMMUNITY_TYPE_CRITICAL_HIT) && !GetIsImmune(oTarget, IMMUNITY_TYPE_SNEAK_ATTACK))
|
||||
{
|
||||
// Calculate Precise Strike damage and apply
|
||||
int nDam = d6(nDuel/5);
|
||||
effect eDam = EffectDamage(nDam, DAMAGE_TYPE_MAGICAL); //Using this because any DR has already taken piercing damage
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget);
|
||||
FloatingTextStringOnCreature("Precise Strike Damage: "+IntToString(nDam), oPC, FALSE);
|
||||
}// end if - Item is a melee weapon
|
||||
}// end if - Running OnHit event
|
||||
else if(nEvent == EVENT_ONPLAYEREQUIPITEM && nDuel >= 5) //Duelist has to be at least level 5
|
||||
{
|
||||
oPC = GetItemLastEquippedBy();
|
||||
oWeapon = GetItemLastEquipped();
|
||||
if(DEBUG) DoDebug("prc_duelist - OnEquip\n"
|
||||
+ "oPC = " + DebugObject2Str(oPC) + "\n"
|
||||
+ "oWeapon = " + DebugObject2Str(oWeapon) + "\n"
|
||||
);
|
||||
|
||||
// Only applies to one handed piercing weapons
|
||||
if(GetBaseItemType(oLefthand) != BASE_ITEM_SMALLSHIELD &&
|
||||
GetBaseItemType(oLefthand) != BASE_ITEM_LARGESHIELD &&
|
||||
GetBaseItemType(oLefthand) != BASE_ITEM_TOWERSHIELD &&
|
||||
(GetBaseItemType(oWeapon) == BASE_ITEM_RAPIER ||
|
||||
GetBaseItemType(oWeapon) == BASE_ITEM_DAGGER ||
|
||||
GetBaseItemType(oWeapon) == BASE_ITEM_SHORTSWORD))
|
||||
{
|
||||
|
||||
// Add eventhook to the item
|
||||
AddEventScript(oWeapon, EVENT_ITEM_ONHIT, "prc_duelist", TRUE, FALSE);
|
||||
|
||||
// Add the OnHitCastSpell: Unique needed to trigger the event
|
||||
IPSafeAddItemProperty(oWeapon, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1), 99999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
||||
}
|
||||
}
|
||||
// We are called from the OnPlayerUnEquipItem eventhook. Remove OnHitCast: Unique Power from oPC's weapon
|
||||
else if(nEvent == EVENT_ONPLAYERUNEQUIPITEM && nDuel >= 5) //Duelist has to be at least level 5
|
||||
{
|
||||
oPC = GetItemLastUnequippedBy();
|
||||
oWeapon = GetItemLastUnequipped();
|
||||
if(DEBUG) DoDebug("prc_duelist - OnUnEquip\n"
|
||||
+ "oPC = " + DebugObject2Str(oPC) + "\n"
|
||||
+ "oWeapon = " + DebugObject2Str(oWeapon) + "\n"
|
||||
);
|
||||
|
||||
// Only applies to weapons
|
||||
if(IPGetIsMeleeWeapon(oWeapon))
|
||||
{
|
||||
// Add eventhook to the item
|
||||
RemoveEventScript(oWeapon, EVENT_ITEM_ONHIT, "prc_duelist", TRUE, FALSE);
|
||||
|
||||
// Remove the temporary OnHitCastSpell: Unique
|
||||
// Makes sure to get ammo if its a ranged weapon
|
||||
RemoveSpecificProperty(oWeapon, ITEM_PROPERTY_ONHITCASTSPELL, IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 0, 1, "", -1, DURATION_TYPE_TEMPORARY);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user