Aller au contenu

Photo

I feel like a noob asking this, but... how to determine the damage type of a spell


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

#1
Darin

Darin
  • Members
  • 282 messages
 Wondering if there is a function in the variuous #include files that would allow me to determine if a spell has a specific damage type, in my case fire.  I know I could use the "ondamage" script, but I want to use the onspellcastat if I can to use only 1 script, hence wondering if it's on an include or anything of the sort.

What I really want to do is set a door to cast all fire-based spells (and disintigrate) back at the caster... ironically I don't expect this script to see use, but I converting Haunted Halls and Ed Greenwood liked to do that sort of thing, so here I am.

#2
-Semper-

-Semper-
  • Members
  • 2 256 messages
first thing would be hooking into spell casting which is described in detail here. it's for nwn1 but works also for nwn2. dunno if you can get the damage type before the spell fires but you could filter out all the fire based spells. i guess the easiest way to read the damage is the ondamage event as you noticed yourself.

perhaps one the experienced scripters knows another work around.

#3
kevL

kevL
  • Members
  • 4 056 messages
spellhooking is very powerful

The problem i see with the onSpellCastAt event is that, say a Fireball might blow the door apart before it gets to retaliate. If the door is made invulerable somehow, say with high hitpoints, you could probably use the onSCA event to ID the spell and cheat-cast the same spell back at the caster.

with a spellhook you can rewrite the spellscript if you want. If a Fireball is targetted on a particular door, it can blow up in the caster's face, or to get fancy you'd simulate the Fireball going one way then right back again and do damage as befits


to the question:

// Get the amount of damage of type nDamageType that has been dealt to the caller.
// - nDamageType: DAMAGE_TYPE_*
int GetDamageDealtByType(int nDamageType);


int DAMAGE_TYPE_FIRE = 256;


Another possibility is to manually list out the spells that do fire damage and check for those. ( or as Semp says, filter them )

Modifié par kevL, 26 mai 2013 - 10:55 .


#4
Eguintir Eligard

Eguintir Eligard
  • Members
  • 1 832 messages
Hm... is it really necessary to spellhook? Sounds like its the actual damage type that is required only. You can detect the damage done by type. That way you don't have to input every fire type spell to check for... just check for fire on the hit taken.

#5
Darin

Darin
  • Members
  • 282 messages
Yeah, I was more hoping that there was some function in an include that acted like GetLastSpell but only looked for damage type. Oh well, I'll have to find some other way to cheat it... maybe give the door resistance to fire? I dunno.

#6
Dann-J

Dann-J
  • Members
  • 3 161 messages
There is a column in spells.2da (ImmunityType) indicating the type of immunity that protects from that spell's damage. I don't know how thoroughly populated it is though. If it's fairly reliable, then the following line in the OnSpellCastAt script should work.

string sDmgType = Get2DAString("spells", "ImmunityType", GetLastSpellCast());

It would return string values such as "acid", "fire", etc.

Modifié par DannJ, 27 mai 2013 - 12:24 .


#7
kevL

kevL
  • Members
  • 4 056 messages
// 'kl_od_returnfire'
// onDamaged event

void main()
{
  object oDebug = GetFirstPC(FALSE);
  SendMessageToPC(oDebug, "run ( kl_od_returnfire )");

  int iSpellID = GetLastSpell();
  object oCaster = GetLastSpellCaster();

  SendMessageToPC(oDebug, ". Spell ID = " + IntToString(iSpellID));
  SendMessageToPC(oDebug, ". Caster = " + GetName(oCaster));

  int iFire = GetDamageDealtByType(DAMAGE_TYPE_FIRE);
  if (iFire)
  {
    SendMessageToPC(oDebug, ". . Fire = " + IntToString(iFire));

    ActionCastSpellAtObject(iSpellID, oCaster, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
  }
}


This actually tested with a semblance of what ye described. Personally i'd replace ActionCast w/ FakeCast and apply the same damage taken after a short delay. oh, and heal the door ( or start a game of pong to see which object lasts longer ;)

#8
Darin

Darin
  • Members
  • 282 messages
So, FakeSpell, I get why you'd use it, but the issue is spells like Fireball...it'd take a lot of scripting I don't need to do in order to get that to work right,,,

But, I have this on the "on damage" script, and it fails worse than the kid that slept through class all year... not sure why, but I'm sure it's bound to be something dumb.

void main()
{
//variables...
object oAttacker = GetLastDamager(OBJECT_SELF);
int nFire = GetDamageDealtByType(DAMAGE_TYPE_FIRE);

//ImmuneFire/ReflectSpell
//Variable:
// nFireReflectSpell == 1
if((GetLocalInt(OBJECT_SELF,"nFireReflectSpell")==1)&&!(nFire==1))
{
//check if a spell caused the damaged
if(GetTag(GetLastSpellCaster())==GetTag(oAttacker))
{
int nSpell = GetLastSpell();
ActionCastSpellAtObject(nSpell,oAttacker,METAMAGIC_QUICKEN,TRUE,0,PROJECTILE_PATH_TYPE_DEFAULT,TRUE);
}
//prevent damage
effect eHeal = EffectHeal(nFire);
ApplyEffectToObject(DURATION_TYPE_INSTANT,eHeal,OBJECT_SELF);
}
}

testes with Burning Hands (leveled up a bard to a level 1 wizard as part of the "runmodule" test). and yeah, it fails (well, nothing happens)

#9
Darin

Darin
  • Members
  • 282 messages
okay, noticed that the thing needs to be zero...that and MetaMagic Any also failed...

#10
kevL

kevL
  • Members
  • 4 056 messages
void main()

{

  if (!GetLocalInt(OBJECT_SELF, "nFireReflectSpell")) return;





  int iFire = GetDamageDealtByType(DAMAGE_TYPE_FIRE);

  if (iFire > 0)

  {

    object oCaster = GetLastSpellCaster();

    if (GetLastDamager() == oCaster)

    {

      effect eHeal = EffectHeal(iFire);

      ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, OBJECT_SELF);



      int iSpellID = GetLastSpell();

      ActionCastSpellAtObject(iSpellID, oCaster, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);

    }

  }

}

Modifié par kevL, 27 mai 2013 - 04:53 .


#11
kevL

kevL
  • Members
  • 4 056 messages
but i notice a problem : its reflecting everything back, acid, cold, electricity ...


Edit, ok GetDamageDealtByType() returns "-1" if it's not fire (corrected above)

I also notice that Firebrand doesn't affect placeables... or doors, only Creatures

Scorching Ray has issues too

Modifié par kevL, 27 mai 2013 - 05:12 .


#12
Darin

Darin
  • Members
  • 282 messages
...many spells cannot target doors, hence the work I did on Disintigrate was useless

#13
Darin

Darin
  • Members
  • 282 messages
but by that script, wouldn't the last spell cast at the door be reflected as soon as the door takes fire damage? meaning If I hit the door with an Acid Splash, then hit it with alchemist fire, it would acid splash whoever splashed it?

#14
Darin

Darin
  • Members
  • 282 messages
So, the only thing not working id the actual spellcasting on the part of the door....

#15
Tchos

Tchos
  • Members
  • 5 042 messages
If you need help making a spell target a door, M. Rieder modified some spells to work on non-creature objects for the Wizard's Apprentice modules -- possibly including doors. Maybe you could check to see if he did it with those spells you need.

#16
Darin

Darin
  • Members
  • 282 messages
I'm more concerned with getting the door to cast the spell back if it hits it, but thank you (n o one will disintegrate a door if they normally can't and the reward is getting hit with the same spell)

#17
-Semper-

-Semper-
  • Members
  • 2 256 messages

EpicFetus wrote...

I'm more concerned with getting the door to cast the spell back if it hits it


couldn't you just set a ipoint in front of the door which casts the spell (ActionCastSpellAtObject)? Dunno if placeables can cast spells but afaik ipoints are able to do so. if all fails you could always script a fire effect with the same damage as the spell on the caster instead.

Modifié par -Semper-, 27 mai 2013 - 06:59 .


#18
kevL

kevL
  • Members
  • 4 056 messages
well that's a bummer, doors won't cast spells back but placeables do

#19
Darin

Darin
  • Members
  • 282 messages
looks like it, so, spawn an ipoint, delay a destroy, have it cast...okay

#20
MasterChanger

MasterChanger
  • Members
  • 686 messages
IIRC, Pain set up a very sophisticated spell type/descriptor system as part of the Community Script Library. This included stuff like whether a spell was of the "Fire" type.

There's so much in the CSL that really could make life easier for project authors if they knew what was in there. Unfortunately I don't know if there's a current directory or easy way to get at it (this was always my pet peeve with it) but perhaps there's some way for it to be rolled into the NeverLauncher (http://social.biowar.../index/15594660).

#21
-Semper-

-Semper-
  • Members
  • 2 256 messages

EpicFetus wrote...

looks like it, so, spawn an ipoint, delay a destroy, have it cast...okay


why fiddle around with the spawn? just drop an ipoint in the area right in front of the door. even if it never casts a spell it won't cause any issues sitting there.

Modifié par -Semper-, 27 mai 2013 - 08:35 .


#22
Darin

Darin
  • Members
  • 282 messages
so i don't have to think about it for any other door I apply this to.

#23
kevL

kevL
  • Members
  • 4 056 messages
re CSL. I've got a copy and should doxygenize it ...

but i think we'd still be getting many of the problems faced here.


This is what I've got. Had to use onSCAt also, in an attempt to prevent the AcidSplash->FlameDagger->retaliate stuff. Check to make sure door isn't hit by its own retaliation ( thermonuclear no longer possible w/ AoE fireballs ). IPoint stuff is in. FakeCast is in but spells like FlameArrow won't use it, probably because the vFx are done in scripting not Spells.2da (option: just use generic Fireball vFx for retaliations). Using delays which could/should be tweaked. also, I'm tweaking my personal .2da & spellscripts in an ongoing effort to achieve consistency.


spells unable to target doors/placeables is usually either def'ns like this in their spellscripts:

GetFirst/NextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, lTarget, TRUE, OBJECT_TYPE_CREATURE)

- and/or the TargetType column in Spells.2da preventing direct targetting of doors/placeables ....


----
// onSpellCastAt

void main()
{
  SetLocalInt(OBJECT_SELF, "fire_bReady", TRUE);
  DelayCommand(5.5f, DeleteLocalInt(OBJECT_SELF, "fire_bReady"));
}


--
// onDamaged

void ReturnFire(object oCaster, int iFire, int iSpellID, location lSelf)
{
  ActionCastFakeSpellAtObject(iSpellID, oCaster);


  location lLoc = GetLocation(oCaster);
  float fDelay = GetDistanceBetweenLocations(lLoc, lSelf) / 20;

  effect eVis = EffectVisualEffect(VFX_HIT_SPELL_FIRE);
  effect eFire = EffectDamage(iFire, DAMAGE_TYPE_FIRE);
  eFire = EffectLinkEffects(eVis, eFire);
  DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eFire, oCaster));

  DestroyObject(OBJECT_SELF, fDelay + 3.f);
}


void main()
{
  if (!GetLocalInt(OBJECT_SELF, "nFireReflectSpell")
      || !GetLocalInt(OBJECT_SELF, "fire_bReady")) return;


  int iFire = GetDamageDealtByType(DAMAGE_TYPE_FIRE);
  if (iFire > 0)
  {
    object oCaster = GetLastSpellCaster();
    if (GetLastDamager() == oCaster)
    {
      effect eHeal = EffectHeal(iFire);
      ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, OBJECT_SELF);

      if (OBJECT_SELF != oCaster)
      {
        int iSpellID = GetLastSpell();

        location lSelf = GetLocation(OBJECT_SELF);
        object oIPoint = CreateObject(OBJECT_TYPE_PLACEABLE, "plc_ipoint ", lSelf);
        DelayCommand(0.13f, AssignCommand(oIPoint, ReturnFire(oCaster, iFire, iSpellID, lSelf)));
      }
    }
  }
}



i hope I didn't make any mistakes transposing it. Feel free to compare notes and use stuff ..... I moved the heal code up so it heals itself if caught in its own AoE ( like fireball ), then the next check prevents loops.

Note: haven't tried multi-damage spells like Flame Strike

#24
Tchos

Tchos
  • Members
  • 5 042 messages
EpicFetus, if you want to check out the CSL that was mentioned here (Community Script Library), you can download it, along with a partial guide, here.