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.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			216 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
////////////////////////////////////////////////////////////////////
 | 
						|
// Acidic Fire
 | 
						|
// sp_acidfire.nss
 | 
						|
///////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
/*
 | 
						|
Acidic Fire: The alchemical concoction combines alchemical fire with a strong acid.
 | 
						|
A direct hit with acidic fire deals 1d4 points of acid damage and 1d8 points of fire damage.
 | 
						|
Every creature within 5 feet of the point where the acidic fire hits takes 1 point of acid
 | 
						|
damage and 1 point of fire damage from the splash.
 | 
						|
 | 
						|
Taken from x0_s3_alchem
 | 
						|
*/
 | 
						|
 | 
						|
 | 
						|
 | 
						|
#include "prc_inc_sp_tch"
 | 
						|
 | 
						|
//::///////////////////////////////////////////////
 | 
						|
//:: PRCDoGrenade
 | 
						|
//:: Copyright (c) 2001 Bioware Corp.
 | 
						|
//:://////////////////////////////////////////////
 | 
						|
/*
 | 
						|
    Does a damage type grenade (direct or splash on miss)
 | 
						|
*/
 | 
						|
//:://////////////////////////////////////////////
 | 
						|
//:: Created By:
 | 
						|
//:: Created On:
 | 
						|
//:://////////////////////////////////////////////
 | 
						|
void PRCDoGrenade(int nDirectDamage, int nSplashDamage, int vSmallHit, int vRingHit, int nDamageType, float fExplosionRadius , int nObjectFilter, int nRacialType=RACIAL_TYPE_ALL)
 | 
						|
{
 | 
						|
    //Declare major variables  ( fDist / (3.0f * log( fDist ) + 2.0f) )
 | 
						|
    object oTarget = PRCGetSpellTargetObject();
 | 
						|
    int nCasterLvl = PRCGetCasterLevel(OBJECT_SELF);
 | 
						|
    int nDamage = 0;
 | 
						|
    int nMetaMagic = PRCGetMetaMagicFeat();
 | 
						|
    int nCnt;
 | 
						|
    effect eMissile;
 | 
						|
    effect eVis = EffectVisualEffect(vSmallHit);
 | 
						|
    location lTarget = PRCGetSpellTargetLocation();
 | 
						|
 | 
						|
 | 
						|
    float fDist = GetDistanceBetween(OBJECT_SELF, oTarget);
 | 
						|
    int nTouch;
 | 
						|
 | 
						|
 | 
						|
    if (GetIsObjectValid(oTarget) == TRUE)
 | 
						|
    {
 | 
						|
/*        // * BK September 27 2002
 | 
						|
        // * if the object is 'far' from the original impact it
 | 
						|
        // * will be an automatic miss too
 | 
						|
        location lObject = GetLocation(oTarget);
 | 
						|
        float fDistance = GetDistanceBetweenLocations(lTarget, lObject);
 | 
						|
//        SpawnScriptDebugger();
 | 
						|
        if (fDistance > 1.0)
 | 
						|
        {
 | 
						|
            nTouch = -1;
 | 
						|
        }
 | 
						|
        else
 | 
						|
        This did not work. The location and object location are the same.
 | 
						|
        For now we'll have to live with the possiblity of the 'explosion'
 | 
						|
        happening away from where the grenade hits.
 | 
						|
        We could convert everything to splash...
 | 
						|
        */
 | 
						|
            nTouch = PRCDoRangedTouchAttack(oTarget);
 | 
						|
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        nTouch = -1; // * this means that target was the ground, so the user
 | 
						|
                    // * intended to splash
 | 
						|
    }
 | 
						|
    if (nTouch >= 1)
 | 
						|
    {
 | 
						|
        //Roll damage
 | 
						|
        int nDam = nDirectDamage;
 | 
						|
 | 
						|
        if(nTouch == 2)
 | 
						|
        {
 | 
						|
            nDam *= 2;
 | 
						|
        }
 | 
						|
 | 
						|
        //Set damage effect
 | 
						|
        effect eDam = EffectDamage(nDam, nDamageType);
 | 
						|
        //Apply the MIRV and damage effect
 | 
						|
 | 
						|
        // * only damage enemies
 | 
						|
        if(spellsIsTarget(oTarget,SPELL_TARGET_STANDARDHOSTILE,OBJECT_SELF) )
 | 
						|
        {
 | 
						|
        // * must be the correct racial type (only used with Holy Water)
 | 
						|
            if ((nRacialType != RACIAL_TYPE_ALL) && (nRacialType == MyPRCGetRacialType(oTarget)))
 | 
						|
            {
 | 
						|
                ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget);
 | 
						|
                SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, PRCGetSpellId()));
 | 
						|
                //ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eVis, oTarget); VISUALS outrace the grenade, looks bad
 | 
						|
            }
 | 
						|
            else
 | 
						|
            if ((nRacialType == RACIAL_TYPE_ALL) )
 | 
						|
            {
 | 
						|
                ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget);
 | 
						|
                SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, PRCGetSpellId()));
 | 
						|
                //ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eVis, oTarget); VISUALS outrace the grenade, looks bad
 | 
						|
            }
 | 
						|
 | 
						|
        }
 | 
						|
 | 
						|
    //    ApplyEffectToObject(DURATION_TYPE_INSTANT, eMissile, oTarget);
 | 
						|
    }
 | 
						|
 | 
						|
// *
 | 
						|
// * Splash damage always happens as well now
 | 
						|
// *
 | 
						|
    {
 | 
						|
        effect eExplode = EffectVisualEffect(vRingHit);
 | 
						|
       //Apply the fireball explosion at the location captured above.
 | 
						|
 | 
						|
/*       float fFace = GetFacingFromLocation(lTarget);
 | 
						|
       vector vPos = GetPositionFromLocation(lTarget);
 | 
						|
       object oArea = GetAreaFromLocation(lTarget);
 | 
						|
       vPos.x = vPos.x - 1.0;
 | 
						|
       vPos.y = vPos.y - 1.0;
 | 
						|
       lTarget = Location(oArea, vPos, fFace);
 | 
						|
       missing code looks bad because it does not jive with visual
 | 
						|
*/
 | 
						|
       ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eExplode, lTarget);
 | 
						|
    object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, fExplosionRadius, lTarget, TRUE, nObjectFilter);
 | 
						|
    //Cycle through the targets within the spell shape until an invalid object is captured.
 | 
						|
    while (GetIsObjectValid(oTarget))
 | 
						|
    {
 | 
						|
        if(spellsIsTarget(oTarget,SPELL_TARGET_STANDARDHOSTILE,OBJECT_SELF) )
 | 
						|
        {
 | 
						|
            float fDelay = GetDistanceBetweenLocations(lTarget, GetLocation(oTarget))/20;
 | 
						|
            //Roll damage for each target
 | 
						|
            nDamage = nSplashDamage;
 | 
						|
 | 
						|
            //Set the damage effect
 | 
						|
            effect eDam = EffectDamage(nDamage, nDamageType);
 | 
						|
            if(nDamage > 0)
 | 
						|
            {
 | 
						|
        // * must be the correct racial type (only used with Holy Water)
 | 
						|
                if ((nRacialType != RACIAL_TYPE_ALL) && (nRacialType == MyPRCGetRacialType(oTarget)))
 | 
						|
                {
 | 
						|
                    // Apply effects to the currently selected target.
 | 
						|
                    SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, PRCGetSpellId()));
 | 
						|
                    DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
 | 
						|
                    //This visual effect is applied to the target object not the location as above.  This visual effect
 | 
						|
                    //represents the flame that erupts on the target not on the ground.
 | 
						|
                    DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
 | 
						|
                }
 | 
						|
                else
 | 
						|
                if ((nRacialType == RACIAL_TYPE_ALL) )
 | 
						|
                {
 | 
						|
                    SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, PRCGetSpellId()));
 | 
						|
                    DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
 | 
						|
                    DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
 | 
						|
                }
 | 
						|
 | 
						|
            }
 | 
						|
        }
 | 
						|
       //Select the next target within the spell shape.
 | 
						|
       oTarget = GetNextObjectInShape(SHAPE_SPHERE, fExplosionRadius, lTarget, TRUE, nObjectFilter);
 | 
						|
       }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void AddFlamingEffectToWeapon(object oTarget, float fDuration)
 | 
						|
{
 | 
						|
   // If the spell is cast again, any previous itemproperties matching are removed.
 | 
						|
   IPSafeAddItemProperty(oTarget, ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE, IP_CONST_DAMAGEBONUS_1d4), fDuration, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
 | 
						|
   IPSafeAddItemProperty(oTarget, ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_ACID, IP_CONST_DAMAGEBONUS_1d4), fDuration, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
 | 
						|
   IPSafeAddItemProperty(oTarget, ItemPropertyVisualEffect(ITEM_VISUAL_FIRE), fDuration,X2_IP_ADDPROP_POLICY_REPLACE_EXISTING,FALSE,TRUE);
 | 
						|
   return;
 | 
						|
}
 | 
						|
 | 
						|
void main()
 | 
						|
{
 | 
						|
    effect eVis = EffectVisualEffect(VFX_IMP_PULSE_FIRE);
 | 
						|
    effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
 | 
						|
    object oTarget = PRCGetSpellTargetObject();
 | 
						|
    object oMyWeapon;
 | 
						|
    int nTarget = GetObjectType(oTarget);
 | 
						|
    int nDuration = 4;
 | 
						|
    int nCasterLvl = 1;
 | 
						|
 | 
						|
    if(nTarget == OBJECT_TYPE_ITEM)
 | 
						|
    {
 | 
						|
        oMyWeapon = oTarget;
 | 
						|
        int nItem = IPGetIsMeleeWeapon(oMyWeapon);
 | 
						|
        if(nItem == TRUE)
 | 
						|
        {
 | 
						|
            if(GetIsObjectValid(oMyWeapon))
 | 
						|
            {
 | 
						|
                SignalEvent(OBJECT_SELF, EventSpellCastAt(OBJECT_SELF, GetSpellId(), FALSE));
 | 
						|
 | 
						|
                if (nDuration > 0)
 | 
						|
                {
 | 
						|
                    // haaaack: store caster level on item for the on hit spell to work properly
 | 
						|
                    SetLocalInt(oMyWeapon,"X2_SPELL_CLEVEL_FLAMING_WEAPON",nCasterLvl);
 | 
						|
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, GetItemPossessor(oMyWeapon));
 | 
						|
                    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDur, GetItemPossessor(oMyWeapon), RoundsToSeconds(nDuration));
 | 
						|
                    AddFlamingEffectToWeapon(oMyWeapon, RoundsToSeconds(nDuration));
 | 
						|
                }
 | 
						|
                    return;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            FloatingTextStrRefOnCreature(100944,OBJECT_SELF);
 | 
						|
        }
 | 
						|
    }
 | 
						|
    else if(nTarget == OBJECT_TYPE_CREATURE || OBJECT_TYPE_DOOR || OBJECT_TYPE_PLACEABLE)
 | 
						|
    {
 | 
						|
        PRCDoGrenade(d8(1),1, VFX_IMP_FLAME_M, VFX_FNF_FIREBALL,DAMAGE_TYPE_FIRE,RADIUS_SIZE_HUGE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
 | 
						|
        PRCDoGrenade(d4(1),1, VFX_IMP_ACID_L, VFX_FNF_GAS_EXPLOSION_ACID, DAMAGE_TYPE_ACID, RADIUS_SIZE_HUGE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
 | 
						|
    }
 | 
						|
} |