PRC8/nwn/nwnprc/trunk/spells/x2_s2_discbreath.nss
Jaysyn904 6ec137a24e Updated AMS marker feats
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.
2024-02-11 14:01:05 -05:00

250 lines
10 KiB
Plaintext

/*
This is the edited script I had made changes to before Silver reverted to
the original. It has:
Round delays for metabreath/multiple uses
Line breath (working)
Pyroclastic being 50% of each
PRCGetReflexAdjustedDamage to interact better with other systems
Range dependant on size
Less code duplication by using dedicated functions. Easier to fix/find bugs.
Moved breath VFX so when different ones for different colors are done they can be easily implemented
Moved to a new script so its not lost permanently. Feel free to refer to this if you want.
Primogenitor
//:: edited by Fox on 1/19/08
Script has been rewritten to use the new breath include. Most of the above has
been subsumed into said include where appropriate.
//::///////////////////////////////////////////////
//:: Breath Weapon for Dragon Disciple Class
//:: x2_s2_discbreath
//:: Copyright (c) 2003Bioware Corp.
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
//:: Created By: Georg Zoeller (modified by Silver)
//:: Created On: June, 17, 2003 (June, 7, 2005)
//:://////////////////////////////////////////////
*/
#include "prc_inc_spells"
#include "prc_inc_breath"
#include "prc_inc_combat"
//////////////////////////
// Constant Definitions //
//////////////////////////
int IsLineBreath()
{
object oDD = OBJECT_SELF;
if(GetHasFeat(FEAT_BLACK_DRAGON, oDD)
|| GetHasFeat(FEAT_BLUE_DRAGON, oDD)
|| GetHasFeat(FEAT_BRASS_DRAGON, oDD)
|| GetHasFeat(FEAT_BRONZE_DRAGON, oDD)
|| GetHasFeat(FEAT_COPPER_DRAGON, oDD)
|| GetHasFeat(FEAT_AMETHYST_DRAGON, oDD)
|| GetHasFeat(FEAT_BROWN_DRAGON, oDD)
|| GetHasFeat(FEAT_CHAOS_DRAGON, oDD)
|| GetHasFeat(FEAT_OCEANUS_DRAGON, oDD)
|| GetHasFeat(FEAT_RADIANT_DRAGON, oDD)
|| GetHasFeat(FEAT_RUST_DRAGON, oDD)
|| GetHasFeat(FEAT_STYX_DRAGON, oDD)
|| GetHasFeat(FEAT_TARTIAN_DRAGON, oDD)
)
return TRUE;
return FALSE;
}
//Returns range in feet for breath struct. Conversion to meters is
//handled internally in the include
float GetRangeFromSize(int nSize)
{
float fRange = 30.0;
switch(nSize)
{
case CREATURE_SIZE_FINE:
case CREATURE_SIZE_DIMINUTIVE:
case CREATURE_SIZE_TINY: fRange = 15.0; break;
case CREATURE_SIZE_SMALL: fRange = 20.0; break;
case CREATURE_SIZE_MEDIUM: fRange = 30.0; break;
case CREATURE_SIZE_LARGE: fRange = 40.0; break;
case CREATURE_SIZE_HUGE: fRange = 50.0; break;
case CREATURE_SIZE_GARGANTUAN: fRange = 60.0; break;
case CREATURE_SIZE_COLOSSAL: fRange = 70.0; break;
}
return fRange;
}
void BreathRecharge(object oPC)
{
IncrementRemainingFeatUses(oPC, FEAT_DRAGON_DIS_BREATH);
SendMessageToPC(oPC, "Your breath weapon is ready now");
}
void main()
{
//Declare main variables.
object oPC = OBJECT_SELF;
int nLevel = GetLevelByClass(CLASS_TYPE_DRAGON_DISCIPLE, oPC);
location lTarget = PRCGetSpellTargetLocation();
struct breath DiscBreath;
int bLine = IsLineBreath();
int nVis;
//range calculation
float fRange = GetRangeFromSize(PRCGetCreatureSize(oPC));
if(bLine) fRange *= 2.0;
//Li Lung dragons have a 'roar' instead of breath weapon
/*if(GetHasFeat(FEAT_LI_LUNG_DRAGON, oPC))
{
if(nUses < 3)
{
IncrementRemainingFeatUses(oPC, FEAT_DRAGON_DIS_BREATH);
nUses++;
lTarget = GetLocation(oPC);
fRange = FeetToMeters(fRange);
float fDuration = RoundsToSeconds(nLevel);
PlaySound("c_dragnold_atk1");
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_HOWL_WAR_CRY), lTarget);
object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, fRange, lTarget, FALSE, OBJECT_TYPE_CREATURE);
while(GetIsObjectValid(oTarget))
{
float fDelay = GetDistanceBetweenLocations(lTarget, GetLocation(oTarget))/20;
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectDeaf(), oTarget, fDuration));
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_SONIC), oTarget));
oTarget = GetNextObjectInShape(SHAPE_SPHERE, fRange, lTarget, FALSE, OBJECT_TYPE_CREATURE);
}
SetLocalInt(oPC, SPECIAL_BREATH_USES, nUses);
}
return;
}
else if(GetHasFeat(FEAT_FANG_DRAGON, oPC))
{
else if(nUses < 2)
{
IncrementRemainingFeatUses(oPC, FEAT_DRAGON_DIS_BREATH);
nUses++;
object oBite = GetItemInSlot(INVENTORY_SLOT_CWEAPON_B, oPC);
int AttackRoll = GetAttackRoll(oTarget, oPC, oBite);
int nDamage = d4(1) * AttackRoll;
if(nDamage)
{
ApplyAbilityDamage(oTarget, ABILITY_CONSTITUTION, nDamage, DURATION_TYPE_PERMANENT, TRUE);
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_REDUCE_ABILITY_SCORE), oTarget);
}
SetLocalInt(oPC, SPECIAL_BREATH_USES, nUses);
}
return;
}*/
//Sets the save DC for Dragon Breath attacks. This is a reflex save to halve the damage.
//Save is 10+CON+1/2 DD level. Gains +1 at level 13, and every 3 levels after.
int nSaveDCBonus = ((nLevel)/2) + max((nLevel - 10) / 3, 0);
//Sets damage levels for Dragon Breath attacks. 2d10 at level 3,
//4d10 at level 7, and then an additional 2d10 every 3 levels (10, 13, 16, ect)
int nDice;
if (nLevel >= 3) nDice += 2;
if (nLevel >= 7) nDice += 2;
if (nLevel >= 10) nDice += 2;
if (nLevel >= 13) nDice += 2;
if (nLevel >= 16) nDice += 2;
if (nLevel >= 19) nDice += 2;
if (nLevel >= 22) nDice += 2;
if (nLevel >= 25) nDice += 2;
if (nLevel >= 28) nDice += 2;
//Only Dragons with Breath Weapons will have damage caused by their breath attack.
//Any Dragon type not listed here will have a breath attack, but it will not
//cause damage or create a visual effect.
int DBREED = GetHasFeat(FEAT_RED_DRAGON, oPC) ? DAMAGE_TYPE_FIRE :
GetHasFeat(FEAT_BRASS_DRAGON, oPC) ? DAMAGE_TYPE_FIRE :
GetHasFeat(FEAT_GOLD_DRAGON, oPC) ? DAMAGE_TYPE_FIRE :
GetHasFeat(FEAT_LUNG_WANG_DRAGON, oPC) ? DAMAGE_TYPE_FIRE :
GetHasFeat(FEAT_TIEN_LUNG_DRAGON, oPC) ? DAMAGE_TYPE_FIRE :
GetHasFeat(FEAT_PYROCLASTIC_DRAGON, oPC) ? DAMAGE_TYPE_FIRE :
GetHasFeat(FEAT_BLACK_DRAGON, oPC) ? DAMAGE_TYPE_ACID :
GetHasFeat(FEAT_GREEN_DRAGON, oPC) ? DAMAGE_TYPE_ACID :
GetHasFeat(FEAT_COPPER_DRAGON, oPC) ? DAMAGE_TYPE_ACID :
GetHasFeat(FEAT_BROWN_DRAGON, oPC) ? DAMAGE_TYPE_ACID :
GetHasFeat(FEAT_DEEP_DRAGON, oPC) ? DAMAGE_TYPE_ACID :
GetHasFeat(FEAT_RUST_DRAGON, oPC) ? DAMAGE_TYPE_ACID :
GetHasFeat(FEAT_STYX_DRAGON, oPC) ? DAMAGE_TYPE_ACID :
GetHasFeat(FEAT_SILVER_DRAGON, oPC) ? DAMAGE_TYPE_COLD :
GetHasFeat(FEAT_WHITE_DRAGON, oPC) ? DAMAGE_TYPE_COLD :
GetHasFeat(FEAT_BLUE_DRAGON, oPC) ? DAMAGE_TYPE_ELECTRICAL :
GetHasFeat(FEAT_BRONZE_DRAGON, oPC) ? DAMAGE_TYPE_ELECTRICAL :
GetHasFeat(FEAT_OCEANUS_DRAGON, oPC) ? DAMAGE_TYPE_ELECTRICAL :
GetHasFeat(FEAT_SONG_DRAGON, oPC) ? DAMAGE_TYPE_ELECTRICAL :
GetHasFeat(FEAT_EMERALD_DRAGON, oPC) ? DAMAGE_TYPE_SONIC :
GetHasFeat(FEAT_SAPPHIRE_DRAGON, oPC) ? DAMAGE_TYPE_SONIC :
GetHasFeat(FEAT_BATTLE_DRAGON, oPC) ? DAMAGE_TYPE_SONIC :
GetHasFeat(FEAT_HOWLING_DRAGON, oPC) ? DAMAGE_TYPE_SONIC :
GetHasFeat(FEAT_CRYSTAL_DRAGON, oPC) ? DAMAGE_TYPE_POSITIVE :
GetHasFeat(FEAT_AMETHYST_DRAGON, oPC) ? DAMAGE_TYPE_MAGICAL :
GetHasFeat(FEAT_TOPAZ_DRAGON, oPC) ? DAMAGE_TYPE_MAGICAL :
GetHasFeat(FEAT_ETHEREAL_DRAGON, oPC) ? DAMAGE_TYPE_MAGICAL :
GetHasFeat(FEAT_RADIANT_DRAGON, oPC) ? DAMAGE_TYPE_MAGICAL :
GetHasFeat(FEAT_TARTIAN_DRAGON, oPC) ? DAMAGE_TYPE_MAGICAL :
-1;
if(GetHasFeat(FEAT_CHAOS_DRAGON, oPC))
{
//Sets the random Element factor of the Chaos Dragons Breath Weapon.
//Affects damage, saving throw, and impact visual.
switch(Random(5))
{
case 0: DBREED = DAMAGE_TYPE_COLD;
case 1: DBREED = DAMAGE_TYPE_ACID;
case 2: DBREED = DAMAGE_TYPE_FIRE;
case 3: DBREED = DAMAGE_TYPE_SONIC;
case 4: DBREED = DAMAGE_TYPE_ELECTRICAL;
}
}
DiscBreath = CreateBreath(oPC, bLine, fRange, DBREED, 10, nDice, ABILITY_CONSTITUTION, nSaveDCBonus);
//activate override for special breath weapons
DiscBreath.nOverrideSpecial = GetHasFeat(FEAT_SHADOW_DRAGON, oPC) ? BREATH_SHADOW :
GetHasFeat(FEAT_PYROCLASTIC_DRAGON, oPC) ? BREATH_PYROCLASTIC :
GetHasFeat(FEAT_TOPAZ_DRAGON, oPC) ? BREATH_TOPAZ :
0;
//vfx
switch(DBREED)
{
case DAMAGE_TYPE_FIRE: nVis = VFX_FNF_DRAGBREATHGROUND; break;
case DAMAGE_TYPE_ACID: nVis = VFX_FNF_DRAGBREATHACID; break;
case DAMAGE_TYPE_COLD: nVis = VFX_FNF_DRAGBREATHCOLD; break;
case DAMAGE_TYPE_ELECTRICAL: nVis = VFX_FNF_DRAGBREATHMIND; break;//VFX_FNF_DRAGBREATHELEC
case DAMAGE_TYPE_SONIC: nVis = VFX_FNF_DRAGBREATHSONIC; break;
case DAMAGE_TYPE_POSITIVE: nVis = VFX_FNF_DRAGBREATHHOLY; break;
default: nVis = VFX_FNF_DRAGBREATHODD; break;
}
//actual breath effect
ApplyBreath(DiscBreath, lTarget);
//breath VFX
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(nVis), lTarget);
if(GetHasFeat(FEAT_FULL_DRAGON_BREATH, oPC))
{
// Schedule opening the delay lock
float fDelay = RoundsToSeconds(DiscBreath.nRoundsUntilRecharge);
SendMessageToPC(oPC, "Your breath weapon will be ready again in " + IntToString(DiscBreath.nRoundsUntilRecharge) + " rounds.");
DelayCommand(fDelay, BreathRecharge(oPC));
}
}