Updated AMS marker feats. Removed arcane & divine marker feats. Updated Dread Necromancer for epic progression. Updated weapon baseitem models. Updated new weapons for crafting & npc equip. Updated prefix. Updated release archive.
216 lines
8.2 KiB
Plaintext
216 lines
8.2 KiB
Plaintext
//::///////////////////////////////////////////////
|
|
//:: Ability Damage special effects include
|
|
//:: inc_abil_damage
|
|
//:://////////////////////////////////////////////
|
|
/** @file
|
|
Implements the special effects of an ability
|
|
score falling down to 0 as according to PnP.
|
|
|
|
Strength: Lies helpless on ground (knockdown)
|
|
Dexterity: Paralyzed
|
|
Constitution: Death
|
|
Intelligence: Coma (knockdown)
|
|
Wisdom: Coma (knockdown)
|
|
Charisma: Coma (knockdown)
|
|
|
|
|
|
This can be turned off with a switch in
|
|
prc_inc_switches : PRC_NO_PNP_ABILITY_DAMAGE
|
|
|
|
|
|
NOTE: Due to BioOptimization (tm), Dex reaching
|
|
0 from above 3 when any other stat is already
|
|
at 0 will result in Dex being considered
|
|
restored at the same time the other stat is.
|
|
|
|
This might be workable around, but not
|
|
efficiently.
|
|
*/
|
|
//:://////////////////////////////////////////////
|
|
//:: Created By: Ornedan
|
|
//:: Created On: 09.04.2005
|
|
//:: Modified On: 25.06.2005
|
|
//:://////////////////////////////////////////////
|
|
|
|
/*
|
|
[00:55] <Stratovarius> yup
|
|
[00:56] <Stratovarius> well, something to add
|
|
[00:56] <Stratovarius> if KTTS reduces target to 0 (or would, i know NWN goes to 3)
|
|
[00:56] <Stratovarius> drop a cutscene paralyze on em
|
|
[00:56] <Stratovarius> and a long duration knockdown
|
|
[01:00] <Ornedan> 'k. And spawn a pseudo-hb on them to do recovery if they ever regain the mental stat
|
|
[01:01] <Ornedan> Also, test result: You lose spellcasting if your casting stat drops below the required, even if the reduction is a magical penalty
|
|
[01:03] <Stratovarius> you do? cool
|
|
*/
|
|
|
|
//////////////////////////////////////////////////
|
|
/* Function prototypes */
|
|
//////////////////////////////////////////////////
|
|
|
|
// Internal function. Called by a threadscript. Handles checking if any ability that has reached 0 has been restored
|
|
void AbilityDamageMonitor();
|
|
|
|
// Dex needs special handling due to the way CutsceneParalyze works (sets Dex to 3)
|
|
void DoDexCheck(object oCreature, int bFirstPart = TRUE);
|
|
|
|
//////////////////////////////////////////////////
|
|
/* Includes */
|
|
//////////////////////////////////////////////////
|
|
|
|
//#include "prc_inc_spells"
|
|
#include "prc_inc_damage" //functions to apply damage
|
|
|
|
//////////////////////////////////////////////////
|
|
/* Function defintions */
|
|
//////////////////////////////////////////////////
|
|
|
|
void AbilityDamageMonitor()
|
|
{
|
|
object oCreature = OBJECT_SELF;
|
|
int nMonitoredAbilities = GetLocalInt(oCreature, ABILITY_DAMAGE_MONITOR);
|
|
int nEffects = GetLocalInt(oCreature, ABILITY_DAMAGE_SPECIALS);
|
|
|
|
if (DEBUG) DoDebug("AbilityDamageMonitor running");
|
|
|
|
// Check each of the monitored abilities
|
|
if(nMonitoredAbilities & (1 << ABILITY_STRENGTH))
|
|
{
|
|
if(GetAbilityScore(oCreature, ABILITY_STRENGTH) > 3)
|
|
{
|
|
DeleteLocalInt(oCreature, VIRTUAL_ABILITY_SCORE + IntToString(ABILITY_STRENGTH));
|
|
SetLocalInt(oCreature, ABILITY_DAMAGE_MONITOR, GetLocalInt(oCreature, ABILITY_DAMAGE_MONITOR) ^ (1 << ABILITY_STRENGTH));
|
|
if (DEBUG) DoDebug("AbilityDamageMonitor Strength healed");
|
|
}
|
|
}
|
|
/*if(nMonitoredAbilities & (1 << ABILITY_DEXTERITY))
|
|
{
|
|
if(GetAbilityScore(oCreature, ABILITY_DEXTERITY) > 3)
|
|
{
|
|
DeleteLocalInt(oCreature, VIRTUAL_ABILITY_SCORE + IntToString(ABILITY_DEXTERITY));
|
|
SetLocalInt(oCreature, ABILITY_DAMAGE_MONITOR, GetLocalInt(oCreature, ABILITY_DAMAGE_MONITOR) ^ (1 << ABILITY_DEXTERITY));
|
|
}
|
|
}*/
|
|
if(nMonitoredAbilities & (1 << ABILITY_INTELLIGENCE))
|
|
{
|
|
if(GetAbilityScore(oCreature, ABILITY_INTELLIGENCE) > 3)
|
|
{
|
|
DeleteLocalInt(oCreature, VIRTUAL_ABILITY_SCORE + IntToString(ABILITY_INTELLIGENCE));
|
|
SetLocalInt(oCreature, ABILITY_DAMAGE_MONITOR, GetLocalInt(oCreature, ABILITY_DAMAGE_MONITOR) ^ (1 << ABILITY_INTELLIGENCE));
|
|
if (DEBUG) DoDebug("AbilityDamageMonitor Int healed");
|
|
}
|
|
}
|
|
if(nMonitoredAbilities & (1 << ABILITY_WISDOM))
|
|
{
|
|
if(GetAbilityScore(oCreature, ABILITY_WISDOM) > 3)
|
|
{
|
|
DeleteLocalInt(oCreature, VIRTUAL_ABILITY_SCORE + IntToString(ABILITY_WISDOM));
|
|
SetLocalInt(oCreature, ABILITY_DAMAGE_MONITOR, GetLocalInt(oCreature, ABILITY_DAMAGE_MONITOR) ^ (1 << ABILITY_WISDOM));
|
|
if (DEBUG) DoDebug("AbilityDamageMonitor Wis healed");
|
|
}
|
|
}
|
|
if(nMonitoredAbilities & (1 << ABILITY_CHARISMA))
|
|
{
|
|
if(GetAbilityScore(oCreature, ABILITY_CHARISMA) > 3)
|
|
{
|
|
DeleteLocalInt(oCreature, VIRTUAL_ABILITY_SCORE + IntToString(ABILITY_CHARISMA));
|
|
SetLocalInt(oCreature, ABILITY_DAMAGE_MONITOR, GetLocalInt(oCreature, ABILITY_DAMAGE_MONITOR) ^ (1 << ABILITY_CHARISMA));
|
|
if (DEBUG) DoDebug("AbilityDamageMonitor Cha healed");
|
|
}
|
|
}
|
|
|
|
// Check which effects, if any, need to be removed
|
|
int bRemovePara, bRemoveKnock;
|
|
nMonitoredAbilities = GetLocalInt(oCreature, ABILITY_DAMAGE_MONITOR);
|
|
if(!(nMonitoredAbilities & (1 << ABILITY_STRENGTH) ||
|
|
nMonitoredAbilities & (1 << ABILITY_INTELLIGENCE) ||
|
|
nMonitoredAbilities & (1 << ABILITY_WISDOM) ||
|
|
nMonitoredAbilities & (1 << ABILITY_CHARISMA)
|
|
) )
|
|
{
|
|
// Only remove effects if they are present
|
|
if(nEffects & ABILITY_DAMAGE_EFFECT_KNOCKDOWN)
|
|
{
|
|
bRemoveKnock = TRUE;
|
|
nEffects ^= ABILITY_DAMAGE_EFFECT_KNOCKDOWN;
|
|
}
|
|
if(!(nMonitoredAbilities & (1 << ABILITY_DEXTERITY)))
|
|
{
|
|
if(nEffects & ABILITY_DAMAGE_EFFECT_PARALYZE)
|
|
{
|
|
bRemovePara = TRUE;
|
|
nEffects ^= ABILITY_DAMAGE_EFFECT_KNOCKDOWN;
|
|
}
|
|
}
|
|
// Dex is the only remaining stat keeping CutscenePara on, so run the dexcheck
|
|
else
|
|
DelayCommand(0.1f, DoDexCheck(oCreature, TRUE));
|
|
|
|
SetLocalInt(oCreature, ABILITY_DAMAGE_SPECIALS, nEffects);
|
|
}
|
|
|
|
if (DEBUG) DoDebug("AbilityDamageMonitor bRemovePara:" + IntToString(bRemovePara));
|
|
if (DEBUG) DoDebug("AbilityDamageMonitor bRemoveKnock:" + IntToString(bRemoveKnock));
|
|
|
|
// Do effect removal
|
|
if(bRemovePara || bRemoveKnock)
|
|
{
|
|
effect eCheck = GetFirstEffect(oCreature);
|
|
while(GetIsEffectValid(eCheck))
|
|
{
|
|
if(bRemovePara && GetEffectType(eCheck) == EFFECT_TYPE_CUTSCENE_PARALYZE){
|
|
if (DEBUG) DoDebug("AbilityDamageMonitor Removed para");
|
|
RemoveEffect(oCreature, eCheck);
|
|
}
|
|
else if(bRemoveKnock && GetEffectType(eCheck) == 0){
|
|
RemoveEffect(oCreature, eCheck);
|
|
if (DEBUG) DoDebug("AbilityDamageMonitor Removed knock");
|
|
}
|
|
eCheck = GetNextEffect(oCreature);
|
|
}
|
|
}
|
|
if (DEBUG) DoDebug("AbilityDamageMonitor Monitored abilities:" + IntToString(nMonitoredAbilities));
|
|
|
|
// Stop the thread if there is nothing to monitor anymore
|
|
if(!nMonitoredAbilities)
|
|
TerminateCurrentThread();
|
|
}
|
|
|
|
void DoDexCheck(object oCreature, int bFirstPart = TRUE)
|
|
{
|
|
// Remove CutscenePara
|
|
if(bFirstPart)
|
|
{
|
|
effect eCheck = GetFirstEffect(oCreature);
|
|
while(GetIsEffectValid(eCheck))
|
|
{
|
|
if(GetEffectType(eCheck) == EFFECT_TYPE_CUTSCENE_PARALYZE)
|
|
RemoveEffect(oCreature, eCheck);
|
|
eCheck = GetNextEffect(oCreature);
|
|
}
|
|
|
|
DelayCommand(0.1f, DoDexCheck(oCreature, FALSE));
|
|
if (DEBUG) DoDebug("First part ran");
|
|
}
|
|
// Check if Dex is over 3 when it's gone
|
|
else
|
|
{
|
|
// It is, so remove Dex from the monitored list
|
|
if(GetAbilityScore(oCreature, ABILITY_DEXTERITY) > 3)
|
|
{
|
|
DeleteLocalInt(oCreature, VIRTUAL_ABILITY_SCORE + IntToString(ABILITY_DEXTERITY));
|
|
SetLocalInt(oCreature, ABILITY_DAMAGE_MONITOR, GetLocalInt(oCreature, ABILITY_DAMAGE_MONITOR) ^ (1 << ABILITY_DEXTERITY));
|
|
if (DEBUG) DoDebug("Dex check +");
|
|
}
|
|
/*else
|
|
SendMessageToPC(GetFirstPC(), "Dex check -");*/
|
|
|
|
// Apply CutscenePara back in either case. Next monitor call will remove it if it's supposed to be gone
|
|
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectCutsceneParalyze(), oCreature);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Test main
|
|
//void main(){}
|