/** @file psi_pow_rmtview Remote Viewing Clairsentience (Scrying) Level: Seer 4 Display: Mental Manifesting Time: 1 Standard Action Range: See text Effect: Quasi-real viewpoint Duration: 1 min./level (D) Saving Throw: Will negates Power Resistance: Yes Power Points: 7 You send your mind across space and dimensions, forming it into a quasireal viewpoint from which you can see and hear some creature located at any distance from you, even if planar boundaries separate you. If the subject succeeds on a Will save, the remote viewing attempt fails. No spells or powers may be manifest while using this power. Valid targets are any monster within the same area as the caster, or any PC. */ #include "psi_inc_psifunc" #include "psi_inc_pwresist" #include "psi_spellhook" #include "inc_dynconv" void ApplyScryEffects(object oPC) { if(DEBUG) DoDebug("prc_inc_scry: ApplyScryEffects():\n" + "oPC = '" + GetName(oPC) + "'" ); // The Scryer is not supposed to be visible, nor can he move or cast // He also can't take damage from scrying effect eLink = EffectSpellImmunity(SPELL_ALL_SPELLS); // Damage immunities eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_ACID, 100)); eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_BLUDGEONING, 100)); eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_COLD, 100)); eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_DIVINE, 100)); eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_ELECTRICAL, 100)); eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_FIRE, 100)); eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_MAGICAL, 100)); eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_NEGATIVE, 100)); eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_PIERCING, 100)); eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_POSITIVE, 100)); eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_SLASHING, 100)); eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_SONIC, 100)); // Specific immunities eLink = EffectLinkEffects(eLink, EffectImmunity(IMMUNITY_TYPE_ABILITY_DECREASE)); eLink = EffectLinkEffects(eLink, EffectImmunity(IMMUNITY_TYPE_BLINDNESS)); eLink = EffectLinkEffects(eLink, EffectImmunity(IMMUNITY_TYPE_DEAFNESS)); eLink = EffectLinkEffects(eLink, EffectImmunity(IMMUNITY_TYPE_CRITICAL_HIT)); eLink = EffectLinkEffects(eLink, EffectImmunity(IMMUNITY_TYPE_DEATH)); eLink = EffectLinkEffects(eLink, EffectImmunity(IMMUNITY_TYPE_DISEASE)); eLink = EffectLinkEffects(eLink, EffectImmunity(IMMUNITY_TYPE_ENTANGLE)); eLink = EffectLinkEffects(eLink, EffectImmunity(IMMUNITY_TYPE_SLOW)); eLink = EffectLinkEffects(eLink, EffectImmunity(IMMUNITY_TYPE_KNOCKDOWN)); eLink = EffectLinkEffects(eLink, EffectImmunity(IMMUNITY_TYPE_NEGATIVE_LEVEL)); eLink = EffectLinkEffects(eLink, EffectImmunity(IMMUNITY_TYPE_PARALYSIS)); eLink = EffectLinkEffects(eLink, EffectImmunity(IMMUNITY_TYPE_SILENCE)); eLink = EffectLinkEffects(eLink, EffectImmunity(IMMUNITY_TYPE_SNEAK_ATTACK)); eLink = EffectLinkEffects(eLink, EffectImmunity(IMMUNITY_TYPE_TRAP)); eLink = EffectLinkEffects(eLink, EffectImmunity(IMMUNITY_TYPE_MIND_SPELLS)); // Random stuff eLink = EffectLinkEffects(eLink, EffectCutsceneGhost()); eLink = EffectLinkEffects(eLink, EffectCutsceneImmobilize()); eLink = EffectLinkEffects(eLink, EffectEthereal()); eLink = EffectLinkEffects(eLink, EffectAttackDecrease(50)); eLink = EffectLinkEffects(eLink, EffectVisualEffect(VFX_DUR_CUTSCENE_INVISIBILITY)); // Permanent until Scry ends ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ExtraordinaryEffect(eLink), oPC, GetLocalFloat(oPC, "ScryDuration") + 6.0); // Create array for storing a list of the nerfed weapons in array_create(oPC, "Scry_Nerfed"); object oWeapon; itemproperty ipNoDam = ItemPropertyNoDamage(); oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC); if(IPGetIsMeleeWeapon(oWeapon)){ if(!GetItemHasItemProperty(oWeapon, ITEM_PROPERTY_NO_DAMAGE)){ //SetLocalInt(oWeapon, "BaelnornProjection_NoDamage", TRUE); AddItemProperty(DURATION_TYPE_PERMANENT, ipNoDam, oWeapon); array_set_object(oPC, "Scry_Nerfed", array_get_size(oPC, "Scry_Nerfed"), oWeapon); } // Check left hand only if right hand had a weapon oWeapon = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oPC); if(IPGetIsMeleeWeapon(oWeapon)){ if(!GetItemHasItemProperty(oWeapon, ITEM_PROPERTY_NO_DAMAGE)){ //SetLocalInt(oWeapon, "BaelnornProjection_NoDamage", TRUE); AddItemProperty(DURATION_TYPE_PERMANENT, ipNoDam, oWeapon); array_set_object(oPC, "Scry_Nerfed", array_get_size(oPC, "Scry_Nerfed"), oWeapon); }} }else if(IPGetIsRangedWeapon(oWeapon)){ if(!GetItemHasItemProperty(oWeapon, ITEM_PROPERTY_NO_DAMAGE)){ //SetLocalInt(oWeapon, "BaelnornProjection_NoDamage", TRUE); AddItemProperty(DURATION_TYPE_PERMANENT, ipNoDam, oWeapon); array_set_object(oPC, "Scry_Nerfed", array_get_size(oPC, "Scry_Nerfed"), oWeapon); }} oWeapon = GetItemInSlot(INVENTORY_SLOT_CWEAPON_B, oPC); if(GetIsObjectValid(oWeapon)){ if(!GetItemHasItemProperty(oWeapon, ITEM_PROPERTY_NO_DAMAGE)){ //SetLocalInt(oWeapon, "BaelnornProjection_NoDamage", TRUE); AddItemProperty(DURATION_TYPE_PERMANENT, ipNoDam, oWeapon); array_set_object(oPC, "Scry_Nerfed", array_get_size(oPC, "Scry_Nerfed"), oWeapon); }} oWeapon = GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oPC); if(GetIsObjectValid(oWeapon)){ if(!GetItemHasItemProperty(oWeapon, ITEM_PROPERTY_NO_DAMAGE)){ //SetLocalInt(oWeapon, "BaelnornProjection_NoDamage", TRUE); AddItemProperty(DURATION_TYPE_PERMANENT, ipNoDam, oWeapon); array_set_object(oPC, "Scry_Nerfed", array_get_size(oPC, "Scry_Nerfed"), oWeapon); }} oWeapon = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oPC); if(GetIsObjectValid(oWeapon)){ if(!GetItemHasItemProperty(oWeapon, ITEM_PROPERTY_NO_DAMAGE)){ //SetLocalInt(oWeapon, "BaelnornProjection_NoDamage", TRUE); AddItemProperty(DURATION_TYPE_PERMANENT, ipNoDam, oWeapon); array_set_object(oPC, "Scry_Nerfed", array_get_size(oPC, "Scry_Nerfed"), oWeapon); }} } void main() { /* Spellcast Hook Code Added 2004-11-02 by Stratovarius If you want to make changes to all powers, check psi_spellhook to find out more */ if (!PsiPrePowerCastCode()) { // If code within the PrePowerCastHook (i.e. UMD) reports FALSE, do not run this spell return; } // End of Spell Cast Hook object oManifester = OBJECT_SELF; object oTarget = PRCGetSpellTargetObject(); struct manifestation manif = EvaluateManifestation(oManifester, oTarget, PowerAugmentationProfile(), METAPSIONIC_EXTEND ); if(manif.bCanManifest) { float fDur = 60.0 * manif.nManifesterLevel; if(manif.bExtend) fDur *= 2; SetLocalInt(oManifester, "ScryCasterLevel", manif.nManifesterLevel); SetLocalInt(oManifester, "ScrySpellId", manif.nSpellID); SetLocalInt(oManifester, "ScrySpellDC", GetManifesterDC(oManifester)); SetLocalFloat(oManifester, "ScryDuration", fDur); StartDynamicConversation("prc_scry_conv", oManifester, DYNCONV_EXIT_NOT_ALLOWED, FALSE, TRUE, oManifester); // Apply the immunity effects ApplyScryEffects(oManifester); } }