Aller au contenu

Photo

NPCs damaging objects with their spells....


  • Veuillez vous connecter pour répondre
9 réponses à ce sujet

#1
Darin

Darin
  • Members
  • 282 messages

SOLVED.

Issue was specifically with Alchemist's Fire NOT doing Splash Damage when cast as an NPC spell

Reason that this did not occur is that when Obsidean updated the Alchemist Fire Script to allow for improved versions, they instanced the Damage and Splash damage as 0, then set it based on the Alchemist Fire used.  Since NPCs are not using an Item, none of the if()'s fired, so their splash damage was set to 0.

 

Fix: add the following script (replaces the alch fire script)

//::///////////////////////////////////////////////
//:: Alchemists fire
//:: x0_s3_alchem
//:: Copyright (c) 2002 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Grenade.
    Fires at a target. If hit, the target takes
    direct damage. If missed, all enemies within
    an area of effect take splash damage.

    HOWTO:
    - If target is valid attempt a hit
       - If miss then MISS
       - If hit then direct damage
    - If target is invalid or MISS
       - have area of effect near target
       - everyone in area takes splash damage
*/
//:://////////////////////////////////////////////
//:: Created By: Brent
//:: Created On: September 10, 2002
//:://////////////////////////////////////////////
//:: GZ: Can now be used to coat a weapon with fire.
//:: RPGplayer1 03/19/2008: Damage bonus to weapons will depend from strength of alchemist fire

#include "X2_I0_SPELLS"
#include "x2_inc_itemprop"
#include "x2_inc_spellhook"

void AddFlamingEffectToWeapon(object oTarget, float fDuration)
{
    //forget the fancy on-hit spell and just go with elemental damage item property.
    int nBonus = IP_CONST_DAMAGEBONUS_1d4;
    object oItem = GetSpellCastItem();
    string sTag = GetStringLowerCase(GetTag(oItem));

    if (sTag == "n2_it_alch_2")
    {
        nBonus = IP_CONST_DAMAGEBONUS_1d6;
    }
    else if (sTag == "n2_it_alch_3")
    {
        nBonus = IP_CONST_DAMAGEBONUS_1d8;
    }
    else if (sTag == "n2_it_alch_4")
    {
        nBonus = IP_CONST_DAMAGEBONUS_1d10;
    }
    itemproperty ipFlame = ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE, nBonus);

   // If the spell is cast again, any previous itemproperties matching are removed.
   //IPSafeAddItemProperty(oTarget, ItemPropertyOnHitCastSpell(124,1), fDuration, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
   IPSafeAddItemProperty(oTarget, ipFlame, 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_COM_HIT_FIRE);
    effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
    object oTarget = GetSpellTargetObject();
    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)
    {
		object oItem = GetSpellCastItem();
		string sTag = GetStringLowerCase(GetTag(oItem));
		
		//Original OBSIDEAN script...
		/*
		int nDmg = 0;
		int nSplashDmg = 0;
		*/
		//New Version, EpicFetus
		//  ...set to the basic grenade
		int nDmg = d6(1);
		int nSplashDmg = 1;
		
		if (sTag == "x1_wmgrenade002")
		{
			nDmg = d6(1);
			nSplashDmg = 1;
		}
		else if (sTag == "n2_it_alch_2")
		{
			nDmg = d8(1);
			nSplashDmg = 2;
		}
		else if (sTag == "n2_it_alch_3")
		{
			nDmg = d10(1);
			nSplashDmg = d4(1);
		}
		else if (sTag == "n2_it_alch_4")
		{
			nDmg = d6(2);
			nSplashDmg = d4(1) + 1;
		}
        DoGrenade(nDmg,nSplashDmg,VFX_HIT_SPELL_FIRE,VFX_HIT_AOE_FIRE,DAMAGE_TYPE_FIRE,RADIUS_SIZE_HUGE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
    }
}


#2
AGhost_7

AGhost_7
  • Members
  • 62 messages

The problem is probably(I'd need the script to diagnose :P ) the script for the oil that the kobold throws. The script is most likely filtering to only apply to OBJECT_TYPE_CREATURE. If we look at the GetFirstObjectInShape signature...

 

// Get the first object in nShape
// - nShape: SHAPE_*
// - fSize:
//   -> If nShape == SHAPE_SPHERE, this is the radius of the sphere
//   -> If nShape == SHAPE_SPELLCYLINDER, this is the length of the cylinder
//   -> If nShape == SHAPE_CONE, this is the widest radius of the cone
//   -> If nShape == SHAPE_CUBE, this is half the length of one of the sides of
//      the cube
// - lTarget: This is the centre of the effect, usually GetSpellTargetPosition(),
//   or the end of a cylinder or cone.
// - bLineOfSight: This controls whether to do a line-of-sight check on the
//   object returned. Line of sight check is done from origin to target object
//   at a height 1m above the ground
//   (This can be used to ensure that spell effects do not go through walls.)
// - nObjectFilter: This allows you to filter out undesired object types, using
//   bitwise "or".
//   For example, to return only creatures and doors, the value for this
//   parameter would be OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR
// - vOrigin: This is only used for cylinders and cones, and specifies the
//   origin of the effect(normally the spell-caster's position).
// Return value on error: OBJECT_INVALID
object GetFirstObjectInShape(int nShape, float fSize, location lTarget, int bLineOfSight=FALSE, int nObjectFilter=OBJECT_TYPE_CREATURE, vector vOrigin=[0.0,0.0,0.0]);


#3
Darin

Darin
  • Members
  • 282 messages

that could be, BUT if a PC throws oil, it sets off the pitch...why would the NPC version be different?



#4
Darin

Darin
  • Members
  • 282 messages

....the oil is the standard special ability "Alchemist's Fire" under spells (since they won't use inventory)



#5
Darin

Darin
  • Members
  • 282 messages

Okay, the script has e lse if(nTarget == OBJECT_TYPE_CREATURE || OBJECT_TYPE_DOOR || OBJECT_TYPE_PLACEABLE)

    
 
DoGrenade(), which is called by the function, is set to only damage enemies...
 
// * only damage enemies
        if(spellsIsTarget(oTarget,SPELL_TARGET_STANDARDHOSTILE,OBJECT_SELF) )
        {
 
so, how do I set a placeable to enemies with Hostile?  Faction does NOT seem to be working...


#6
Darin

Darin
  • Members
  • 282 messages

huh, I think the spell only damages 1 target if it's aimed at someone....which is dumb, but there it is....



#7
Guest_Iveforgotmypassword_*

Guest_Iveforgotmypassword_*
  • Guests

Baddies manage to smash through doors so why not a placeable ?



#8
Dann-J

Dann-J
  • Members
  • 3 161 messages

The radius damage check seems to be in the DoGrenade() function, which is pulled from one of the include files (probably X2_I0_SPELLS).

 

EDIT: it's in x0_i0_spells (via an include in  x2_i0_spells). See:

http://palmergames.c....DoGrenade.html

 

Looking at the structure of the function it seems that a specific creature/object has to be the target, which gets the full amount of damage, but there's also a smaller 'splash damage' amount that is probably dealt to surrounding creatures/objects. You'd have to check the DoGrenade() function to see if it's checking for placeables as well as creatures in the splash radius, and whether or not it's broadcasting an OnSpellCastAt event to them (depending on whether your placeable is checking for fire damage, or has an OnSpellCastAt script checking for the alchemists fire spell ID).



#9
Darin

Darin
  • Members
  • 282 messages

checking for Fire damage.  it SHOULD be doing splash damage, but isn't.  Issue may be that DoGrenade uses a HOSTILE flag check on splash damage....but that seems to make it only work on one creature anyway.  This could be based on a difference in how the NPC "spell" works vs. the item itself...not really sure.



#10
Darin

Darin
  • Members
  • 282 messages

fixed it...silly obsidean.