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.
I feel like a noob asking this, but... how to determine the damage type of a spell
Débuté par
Darin
, mai 26 2013 08:45
#1
Posté 26 mai 2013 - 08:45
#2
Posté 26 mai 2013 - 09:43
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.
perhaps one the experienced scripters knows another work around.
#3
Posté 26 mai 2013 - 10:42
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:
Another possibility is to manually list out the spells that do fire damage and check for those. ( or as Semp says, filter them )
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
Posté 26 mai 2013 - 11:31
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
Posté 26 mai 2013 - 11:58
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
Posté 27 mai 2013 - 12:23
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.
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
Posté 27 mai 2013 - 03:10
// '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
Posté 27 mai 2013 - 03:59
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)
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
Posté 27 mai 2013 - 04:06
okay, noticed that the thing needs to be zero...that and MetaMagic Any also failed...
#10
Posté 27 mai 2013 - 04:30
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
Posté 27 mai 2013 - 04:39
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
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
Posté 27 mai 2013 - 11:32
...many spells cannot target doors, hence the work I did on Disintigrate was useless
#13
Posté 27 mai 2013 - 11:36
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
Posté 27 mai 2013 - 12:45
So, the only thing not working id the actual spellcasting on the part of the door....
#15
Posté 27 mai 2013 - 06:29
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
Posté 27 mai 2013 - 06:48
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
Posté 27 mai 2013 - 06:57
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
Posté 27 mai 2013 - 07:20
well that's a bummer, doors won't cast spells back but placeables do
#19
Posté 27 mai 2013 - 07:39
looks like it, so, spawn an ipoint, delay a destroy, have it cast...okay
#20
Posté 27 mai 2013 - 07:52
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).
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
Posté 27 mai 2013 - 08:33
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
Posté 27 mai 2013 - 08:42
so i don't have to think about it for any other door I apply this to.
#23
Posté 27 mai 2013 - 08:47
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 ....
----
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
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





Retour en haut






