/* 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) + PRCMax((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)); } }