//:://///////////////////////////////////////////// //:: qn_onhit //::////////////////////////////////////////////// /* Touch Attacks (Creature Slam) Workaround: -5 Damage +20 Attack OnHit Cast Spell: Unique Power (Level 1) TAG must be named the same as the script "qn_onhit" !!! To use create a claw/slam/bite give it whatever damage you would like then change the TAG to the name of the script. Give it the OnHit Cast Spell: Unique Power (OnHit Level 1). Assign the appropriate variable below. Example: Wraith would be SPECIAL_ATTACK int 16. I didn't use NWNs touch attack script... its too flawed. Higher level undead can Touch you more than once a round, so I made a workaround claw/slam noted at the very begning to make it more D&D based. +20 to attack may seem like alot but you have to figure that Incorporeal Undead are touching you which might I add in 90% of the cases is very easy. Of course you don't have to use this method - its optional. */ //::////////////////////////////////////////////// //:: Created By: Q-Necron //::////////////////////////////////////////////// #include "x2_inc_switches" #include "x2_inc_spellhook" #include "prc_inc_racial" //Belker void SmokeClaw(object oTarget, int nDC, int nRounds); //Burn void Burn(object oTarget, int nDamage); //Spawn Undead void SpawnUndead(object oTarget, string sRESREF, location lDeadPC); //Drain Ability: void NegativeAbility(object oTarget, int nAbility, int nDrain); //Drain Ability or Death: void NegativeOrDeath(object oTarget, int nAbility, int nDrain, string sRESREF, int bSpawn); //Living Check int GetIsLiving(object oTarget); void main() { //Make sure it fires correctly. if(GetUserDefinedItemEventNumber() == X2_ITEM_EVENT_ONHITCAST && GetLocalInt(OBJECT_SELF, "SPECIAL_ATTACK") != 0) { object oTarget = GetAttemptedAttackTarget(); int nAbility; int nAppearance = GetAppearanceType(OBJECT_SELF); int nCharisma = GetAbilityModifier(ABILITY_CHARISMA, OBJECT_SELF); int nConstitution = GetAbilityModifier(ABILITY_CONSTITUTION, OBJECT_SELF); int nDamage; int nDC; int nDrain; int nHD = GetHitDice(OBJECT_SELF); int nPower; int nTempHP; int nType; int nSpecial = GetLocalInt(OBJECT_SELF, "SPECIAL_ATTACK"); int bSave = TRUE; int bSpawn = FALSE; int bSpectre = FALSE; int bStirge = FALSE; int nStrength = GetAbilityModifier(ABILITY_STRENGTH, OBJECT_SELF); int bTempHP = FALSE; int bWight = FALSE; effect eDamage; effect eTempHP; effect eVis = EffectVisualEffect(VFX_IMP_REDUCE_ABILITY_SCORE); string sRESREF; //Determine special attack. switch(nSpecial) { //Allip case 1: nAbility = ABILITY_WISDOM; nDrain = d4(1); bSave = FALSE; bTempHP = TRUE; nTempHP = 5; break; //Cockatrice case 2: nDC = 10 + (nHD / 2) + nConstitution; if(FortitudeSave(oTarget, nDC, SAVING_THROW_TYPE_ALL, OBJECT_SELF) == 0) { //Apply effects. ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectPetrify(), oTarget, RoundsToSeconds(nHD * 2)); } return; break; //Succubus case 3: if(GetIsLiving(oTarget) == FALSE){return;} DelayCommand(0.1, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget)); DelayCommand(0.1, ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectNegativeLevel(1), oTarget)); DelayCommand(0.1, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectConfused(), oTarget, RoundsToSeconds(12))); return; break; //Rake case 4: if(GetHasFeatEffect(FEAT_KNOCKDOWN, oTarget) == TRUE || GetHasFeatEffect(FEAT_IMPROVED_KNOCKDOWN, oTarget) == TRUE) { //Determine creature appearance. switch(nAppearance) { //Dire Tiger case APPEARANCE_TYPE_CAT_CAT_DIRE: nDamage = d4(2) + 4; nType = DAMAGE_TYPE_SLASHING; nPower = DAMAGE_POWER_NORMAL; break; //Androsphinx case APPEARANCE_TYPE_SPHINX: nDamage = d4(2) + 3; nType = DAMAGE_TYPE_SLASHING; nPower = DAMAGE_POWER_NORMAL; break; //Mountain Lion case APPEARANCE_TYPE_CAT_COUGAR: nDamage = d3(1) + 1; nType = DAMAGE_TYPE_SLASHING; nPower = DAMAGE_POWER_NORMAL; break; //Lion case APPEARANCE_TYPE_CAT_LION: nDamage = d4(1) + 2; nType = DAMAGE_TYPE_SLASHING; nPower = DAMAGE_POWER_NORMAL; break; } //Set damage. eDamage = EffectDamage(nDamage, nType, nPower); //Apply effects. ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget); } return; break; //Fire Elemental case 5: nDC = 10 + (nHD / 2) + nConstitution; if(nHD <= 7){nDamage = d6(1);}//------------------ Medium else if(nHD >= 8 && nHD <= 15){nDamage = d6(2);}// Large else{nDamage = d8(2);}//-------------------------- Huge //Reflex Save if(ReflexSave(oTarget, nDC, SAVING_THROW_TYPE_FIRE, OBJECT_SELF) == 0) { //Apply burn. DelayCommand(3.0f, Burn(oTarget, nDamage)); } return; break; //Water Elemental case 6: if(GetHasSpellEffect(SPELL_DARKFIRE, oTarget) == TRUE || GetHasSpellEffect(SPELL_ELEMENTAL_SHIELD, oTarget) == TRUE || GetHasSpellEffect(SPELL_FLAME_WEAPON, oTarget) == TRUE && d20(1) + nHD > 11 + GetHitDice(oTarget))//Dispel Check { object oLeft = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oTarget); object oRight = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget); effect eVis = EffectVisualEffect(VFX_IMP_DISPEL); itemproperty ipDamage = ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE, IP_CONST_DAMAGEBONUS_1d6); itemproperty ipVis = ItemPropertyVisualEffect(ITEM_VISUAL_FIRE); //Elemental Shield effect eEffect = GetFirstEffect(oTarget); while(GetIsEffectValid(eEffect)) { if(GetHasSpellEffect(SPELL_ELEMENTAL_SHIELD, oTarget) == TRUE) { RemoveEffect(oTarget, eEffect); } eEffect = GetNextEffect(oTarget); } //Prevents stacking IPRemoveMatchingItemProperties(oLeft, GetItemPropertyType(ipDamage), DURATION_TYPE_TEMPORARY); IPRemoveMatchingItemProperties(oLeft, GetItemPropertyType(ipVis), DURATION_TYPE_TEMPORARY); IPRemoveMatchingItemProperties(oRight, GetItemPropertyType(ipDamage), DURATION_TYPE_TEMPORARY); IPRemoveMatchingItemProperties(oRight, GetItemPropertyType(ipVis), DURATION_TYPE_TEMPORARY); //Apply effects. ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget); } return; break; //Ghoul, Ghast & Mohrg Paralysis case 7: nDC = 10 + (nHD / 2) + nCharisma; if(FortitudeSave(oTarget, nDC, SAVING_THROW_TYPE_ALL, OBJECT_SELF) == 0) { //Apply effects. ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectParalyze(), oTarget, RoundsToSeconds(nHD * 2)); ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_PARALYZE_HOLD), oTarget, RoundsToSeconds(nHD * 2)); ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_PARALYZED), oTarget, RoundsToSeconds(nHD * 2)); } return; break; //Trample case 8: nDC = 10 + (nHD / 2) + nStrength; if(ReflexSave(oTarget, nDC, SAVING_THROW_TYPE_ALL, OBJECT_SELF) == 0) { //Determine creature appearance. switch(nAppearance) { case APPEARANCE_TYPE_GORGON: nDamage = d8(1) + 7; break; case APPEARANCE_TYPE_BEETLE_STAG: nDamage = d8(2) + 3; break; } //Set damage. eDamage = EffectDamage(nDamage, DAMAGE_TYPE_BLUDGEONING, DAMAGE_POWER_NORMAL); //Apply effects. ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget); //Set Local Int SetLocalInt(OBJECT_SELF, "SPECIAL_ATTACK", 0); } return; break; //Rend case 9: if(d2(1) == 1) { //Determine creature appearance. switch(nAppearance) { case APPEARANCE_TYPE_GREY_RENDER: case APPEARANCE_TYPE_TROLL: case APPEARANCE_TYPE_TROLL_CHIEFTAIN: case APPEARANCE_TYPE_TROLL_SHAMAN: nDamage = d6(2) + 9; nType = DAMAGE_TYPE_SLASHING; nPower = DAMAGE_POWER_NORMAL; break; } //Set damage. eDamage = EffectDamage(nDamage, nType, nPower); //Apply effects. ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget); } return; break; //Gelatinous Cube case 10: nDC = 10 + (nHD / 2) + nConstitution; if(FortitudeSave(oTarget, nDC, SAVING_THROW_TYPE_ALL, OBJECT_SELF) == 0) { //Apply effects. ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectParalyze(), oTarget, RoundsToSeconds(nHD * 2)); ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_PARALYZE_HOLD), oTarget, RoundsToSeconds(nHD * 2)); ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_GLOW_GREEN), oTarget, RoundsToSeconds(nHD * 2)); } return; break; //Belker Claw case 11: nDC = 10 + (nHD / 2) + nConstitution; //Smoke Claw SmokeClaw(oTarget, nDC, d3(2)); return; break; //Shadow & Greater Shadow case 12: nAbility = ABILITY_STRENGTH; nDC = 10 + (nHD / 2) + nCharisma; bSave = FALSE; bSpawn = TRUE; sRESREF = "shadow01"; //Determine creature appearance. switch(nAppearance) { //1d6 Strength Drain case APPEARANCE_TYPE_SHADOW: nDrain = d6(1); break; //1d8 Strength Drain case APPEARANCE_TYPE_SHADOW_FIEND: nDrain = d8(1); break; } break; //Spectre case 13: nDC = 10 + (nHD / 2) + nCharisma; bSpectre = TRUE; bTempHP = TRUE; nTempHP = 5; break; //Stirge case 14: nAbility = ABILITY_CONSTITUTION; nDrain = 1; bStirge = TRUE; bTempHP = TRUE; nTempHP = 1; eVis = EffectVisualEffect(VFX_IMP_HEAD_EVIL); break; //Wight case 15: nDC = 10 + (nHD / 2) + nCharisma; bWight = TRUE; bTempHP = TRUE; nTempHP = 5; break; //Wraith case 16: nAbility = ABILITY_CONSTITUTION; nDC = 10 + (nHD / 2) + nCharisma; nDrain = d6(1); bSpawn = TRUE; sRESREF = "wraith01"; bTempHP = TRUE; nTempHP = 5; break; //Dread Wraith case 17: nAbility = ABILITY_CONSTITUTION; nDC = 10 + (nHD / 2) + nCharisma; nDrain = d8(1); bSpawn = TRUE; sRESREF = "wraith01"; bTempHP = TRUE; nTempHP = 5; break; //Icegaunt case 18: nAbility = ABILITY_CONSTITUTION; nDC = 10 + (nHD / 2) + nCharisma; nDrain = d4(1); bTempHP = TRUE; nTempHP = 5; break; //Cinderspawn case 19: nAbility = ABILITY_CHARISMA; nDC = 10 + (nHD / 2) + nCharisma; nDrain = d6(1); bTempHP = TRUE; nTempHP = 5; break; //Sword Wraith case 20: nAbility = ABILITY_STRENGTH; nDrain = 1; bSave = FALSE; break; //Voidwraith case 21: nAbility = ABILITY_CONSTITUTION; nDC = 10 + (nHD / 2) + nCharisma; nDrain = d2(1); bTempHP = TRUE; nTempHP = 5; break; } //Constructs & Undead if(GetIsLiving(oTarget) == FALSE){return;} //Bone Ring if(GetTag(GetItemInSlot(INVENTORY_SLOT_LEFTRING, oTarget)) == "r_bone" || GetTag(GetItemInSlot(INVENTORY_SLOT_RIGHTRING, oTarget)) == "r_bone") { //Priceless... bSave = TRUE; } //Spectre if(bSpectre == TRUE) { nDrain = 2; //Fotitude Save! if(FortitudeSave(oTarget, nDC, SAVING_THROW_TYPE_NEGATIVE) == 1){nDrain = 1;} //Apply effects. ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectNegativeLevel(nDrain), oTarget); ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget); //Does the touch grant temporary HP? if(bTempHP == TRUE) { eTempHP = SupernaturalEffect(EffectTemporaryHitpoints(nTempHP)); //Temporary HitPoints if(GetCurrentHitPoints(OBJECT_SELF) < (GetMaxHitPoints(OBJECT_SELF) * 2)) { ApplyEffectToObject(DURATION_TYPE_PERMANENT, eTempHP, OBJECT_SELF); } } return; } //Stirge if(bStirge == TRUE) { DelayCommand(0.1, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eVis, oTarget, RoundsToSeconds(nHD))); //Does the touch grant temporary HP? if(bTempHP == TRUE) { eTempHP = SupernaturalEffect(EffectTemporaryHitpoints(nTempHP)); //Temporary HitPoints. if(GetCurrentHitPoints(OBJECT_SELF) < (GetMaxHitPoints(OBJECT_SELF) * 2)) { ApplyEffectToObject(DURATION_TYPE_PERMANENT, eTempHP, OBJECT_SELF); } } return; } //Wight if(bWight == TRUE) { //Fotitude Save! if(FortitudeSave(oTarget, nDC, SAVING_THROW_TYPE_NEGATIVE) == 0) { //Apply effects. ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectNegativeLevel(1), oTarget); ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget); //Does the touch grant temporary HP? if(bTempHP == TRUE) { eTempHP = SupernaturalEffect(EffectTemporaryHitpoints(nTempHP)); //Temporary HitPoints if(GetCurrentHitPoints(OBJECT_SELF) < (GetMaxHitPoints(OBJECT_SELF) * 2)) { ApplyEffectToObject(DURATION_TYPE_PERMANENT, eTempHP, OBJECT_SELF); } } } return; } //Aw no save... if(bSave == FALSE) { DelayCommand(0.1, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget)); DelayCommand(0.1, NegativeOrDeath(oTarget, nAbility, nDrain, sRESREF, bSpawn)); //Does the touch grant temporary HP? if(bTempHP == TRUE) { eTempHP = SupernaturalEffect(EffectTemporaryHitpoints(nTempHP)); //Temporary HitPoints. if(GetCurrentHitPoints(OBJECT_SELF) < (GetMaxHitPoints(OBJECT_SELF) * 2)) { ApplyEffectToObject(DURATION_TYPE_PERMANENT, eTempHP, OBJECT_SELF); } } } //Save. else { //Fotitude Save! if(FortitudeSave(oTarget, nDC, SAVING_THROW_TYPE_NEGATIVE) == 0) { DelayCommand(0.1, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget)); DelayCommand(0.1, NegativeOrDeath(oTarget, nAbility, nDrain, sRESREF, bSpawn)); //Does the touch grant temporary HP? if(bTempHP == TRUE) { eTempHP = SupernaturalEffect(EffectTemporaryHitpoints(nTempHP)); //Temporary HitPoints if(GetCurrentHitPoints(OBJECT_SELF) < (GetMaxHitPoints(OBJECT_SELF) * 2)) { ApplyEffectToObject(DURATION_TYPE_PERMANENT, eTempHP, OBJECT_SELF); } } } } } } //------------------------------------------------------------------------------ // Burn //------------------------------------------------------------------------------ void Burn(object oTarget, int nDamage) { effect eBurn = EffectDamage(nDamage, DAMAGE_TYPE_FIRE); effect eVis = EffectVisualEffect(VFX_IMP_FLAME_M); //Apply effects. ApplyEffectToObject(DURATION_TYPE_INSTANT, eBurn, oTarget); ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget); } //------------------------------------------------------------------------------ // Spawn Undead //------------------------------------------------------------------------------ void SpawnUndead(object oTarget, string sRESREF, location lDeadPC) { //Is the PC still dead? if(GetIsDead(oTarget) == TRUE) { //Create undead. CreateObject(OBJECT_TYPE_CREATURE, sRESREF, lDeadPC); } else { //Set Local Int SetLocalInt(OBJECT_SELF, "DO_ONCE", 0); } } //------------------------------------------------------------------------------ // Drain Ability: //------------------------------------------------------------------------------ void NegativeAbility(object oTarget, int nAbility, int nDrain) { //Ablity Drain. effect eDrain = EffectAbilityDecrease(nAbility, nDrain); //Apply effects. ApplyEffectToObject(DURATION_TYPE_PERMANENT, eDrain, oTarget); } //------------------------------------------------------------------------------ // Drain Ability or Death: //------------------------------------------------------------------------------ void NegativeOrDeath(object oTarget, int nAbility, int nDrain, string sRESREF, int bSpawn) { //Get PC's ability. int nAbilityScore = GetAbilityScore(oTarget, nAbility); //Current ability vs drain. if(nAbilityScore - nDrain <= 0 && GetIsPC(oTarget) == TRUE) { effect eDeath = EffectDeath(); location lDeadPC = GetLocation(oTarget); //Apply effects ApplyEffectToObject(DURATION_TYPE_PERMANENT, eDeath, oTarget); //Get the killers RESREF and spawn another of its type. if(bSpawn == TRUE && GetLocalInt(OBJECT_SELF, "DO_ONCE") != 1) { DelayCommand(RoundsToSeconds(d3(2)), SpawnUndead(oTarget, sRESREF, lDeadPC)); //Set Local Int SetLocalInt(OBJECT_SELF, "DO_ONCE", 1); } } else { //Ability Drain. DelayCommand(0.1, NegativeAbility(oTarget, nAbility, nDrain)); } } //------------------------------------------------------------------------------ // Living Check //------------------------------------------------------------------------------ int GetIsLiving(object oTarget) { int bAlive; //Constructs & Undead if(MyPRCGetRacialType(oTarget) == RACIAL_TYPE_CONSTRUCT || MyPRCGetRacialType(oTarget) == RACIAL_TYPE_UNDEAD) { return bAlive = FALSE; } else { return bAlive = TRUE; } } //------------------------------------------------------------------------------ // Smoke Claw //------------------------------------------------------------------------------ void SmokeClaw(object oTarget, int nDC, int nRounds) { //Fortitude Save if(FortitudeSave(oTarget, nDC, SAVING_THROW_TYPE_ALL, OBJECT_SELF) == 0) { nRounds--; effect eDamage = EffectDamage(d4(3)); effect eVis = EffectVisualEffect(VFX_IMP_SILENCE); //Apply effects. ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget); ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget); //Smoke Claw if(nRounds != 0) { SmokeClaw(oTarget, nDC, nRounds); } } }