damage type on a boulder
#1
Posté 01 août 2013 - 04:13
However, I find that while you can target aoe and direct spells on the object, they dont seem to do any damage.
Is there no way to inflict and then check for sonic damage coming from a spell?
I know I can check for all the possible sonic spells in a spell cast at (or I think I can) but that seems way too much work and too lame and too open to missing certain spells that should count.
#2
Posté 01 août 2013 - 04:55
One trick I've used is to place a hostile, immobile, immortal rat (scale 0.1,0.1,0.1) nearby with nothing but an OnSpellCastAt script, and a simple OnSpawn script that puts an ethereal effect on it (so companions won't try to attack it). The rat can pass the OnSpellCastAt (or OnDamage) information on to the object that wouldn't usually be affected by the spell (placeables, doors, non-hostile creatures, etc). With such a small scaling factor, it hardly registers as a single pixel even when zoomed right in on it. It only works for AOE spells though.
Modifié par DannJ, 01 août 2013 - 04:58 .
#3
Posté 01 août 2013 - 02:24
#4
Posté 01 août 2013 - 03:07
#5
Posté 01 août 2013 - 03:27
Modifié par Eguintir Eligard, 01 août 2013 - 03:27 .
#6
Posté 01 août 2013 - 03:29
#7
Posté 01 août 2013 - 03:38
According to its description it should do 1d8 no matter what, and then check for a save for the stun. This is kind of lame because I am leading the party to believe that any sonic force can shatter the rock and this is their most likely spell since the priest is guaranteed to have it in memory. I can't really bank on them having sonic orb at level 1. Any thoughts? Or do I have to spell it out to them that they have to use a direct sonic spell and pretty much ruin the immersion?
Modifié par Eguintir Eligard, 01 août 2013 - 03:39 .
#8
Posté 01 août 2013 - 10:42
The teeny tiny hostile rat approach would register the sound burst spell (since it's an AOE), but not spells with individual targets. The orb spells certainly do damage (and trigger OnSpellCastAt events) to placeables, since I use the fire orbs spells as some of the spells that can light campfires in my current module.
You could always re-write any AOE sonic spells to also check for placeables in their spell shape, instead of just creatures. There may be several sonic-based spell scripts you might have to modify though, depending on how thorough you want to be about it.
Ah, the joys of work-arounds...
#9
Posté 01 août 2013 - 10:43
Eguintir Eligard wrote...
Is that what the effect is actually called? Ethereal?
EffectEthereal()
It's like the sanctuary effect, only without the chance of a will save to ignore it.
#10
Posté 01 août 2013 - 10:45
How about an immobile creature with a boulder appearance and immunity to everything but sonic damage?
#11
Posté 02 août 2013 - 12:54
For now I've cheaped out and gone with:
[Spellcraft > 4] We could use a sonic spell on this. But it would have to be a very intense and direct concentrated blast.
[cleric npc chimes in] I have a spell with a sonic component, but I doubt it is focused enough. I'll try if you want me to.
And then I added sonic orb to the wizard companions starting spells. I would have loved for this all to work cleanly but this seems best since I could rewrite many spells I havent even thought of.
Thank you
#12
Posté 02 août 2013 - 01:29
#13
Posté 02 août 2013 - 01:42
I have a non-hostile guard in a module I'm working on who I wanted to go to sleep if you cast a sleep spell at him, so you can pick the lock on the door he's guarding. If you try to interfere with the door while he's awake, he stops you. He also has a ring that makes him immune to natural exhaustion, so he'll never go to sleep without magical help.
The sleep spell not only doesn't work on non-hostiles, but it also doesn't trigger an OnSpellCastAt event for non-hostiles either. The spell script can't be rewritten easily, since it has complex loops that check the hit dice of hostile creatures in its AOE. It only checks for creatures, so a hostile ipoint also doesn't receive the OnSpellCastAt event. I had to use the tiny ethereal rat method, and hook things off its OnSpellCastAt script. Thankfully all the sleep spells in the game appear to be AOEs.
Modifié par DannJ, 02 août 2013 - 03:04 .
#14
Posté 02 août 2013 - 01:50
kamal_ wrote...
There can't be that many sonic spells, it might be easier to just detect them in the OnSpellCastAt script.
OnSpellCastAt events are specifically triggered from the spell script. If the spell script in question isn't considering placeables as valid targets, then their OnSpellCastAt script won't be triggered. That's why an ipoint can pick up a fireball cast near it, but not a sleep spell or a missile swarm spell.
See EventSpellCastAt().
Modifié par DannJ, 02 août 2013 - 01:51 .
#15
Posté 10 août 2013 - 10:44
I have not read through all this post just yet to see if it has been answered, but you have a function called, GetDamageDealtByType, which can be checked for SONIC damage.
However, I am not sure why you are having issues with the damage (sonic or otherwise) against the object in the first place. Is it something hard-coded perhaps. ie. Placeables do not suffer from SONIC damage? EDIT: I just realised that the function ResistSpell is probably treating the placeable as an invalid target.
Lance.
EDIT: Another way to circumvent this issue may be to use Spell Hooking to check the target of the spell as the spell is used and add your own code to damage the boulder if the spell used is sonic based and the target is the boulder. You would need to check for each SONIC based spell in the Spell Hooking script, but there are only a few as far as I can see.
Spell Hooking is an almost absolute must for some great coding with respect to spells. Simply do the following:-
1) Add the following line to your On Module Load Script (Replace "alb_spellcast" with whatever script you name to do the same job):
SetLocalString(oMod, "X2_S_UD_SPELLSCRIPT", "alb_spellcast"); // SPELL SCRIPT TO FIRE ON SPELL CASTING
2) In your "alb_spellcast" (or equivalent) you can define the following (here are some of mine, with an example of spell hooking Heal and Mass Heal):-
void main()
{
// OBJECT_SELF is the PC in this script by default. (LB)
object oPC = OBJECT_SELF; //CASTER
// SendMessageToAllPCs("CASTER >> " + GetName(oPC));
object oItem = GetSpellCastItem();
object oTarget = GetSpellTargetObject();
location lLocation = GetSpellTargetLocation();
int SpellID = GetSpellId();
int iSpellLevel = GetSpellLevel(SpellID);
int nLevel = CIGetSpellInnateLevel(SpellID,TRUE);
string sTag = GetTag(oItem);
string sRes = GetResRef(oItem);
int Charges = GetItemCharges(oItem);
string sName = GetFirstName(oItem); // FOR RECOVERY
int CASTSET = GetLocalInt(oItem, "CASTLEVEL"); // FOR RECOVERY
int nCasterLvl = GetCasterLevel(OBJECT_SELF);
// HEAL (EXAMPLE)
// ALLOW HEAL TO CURE LIKE ORIGINAL PNP HEAL
if(SpellID == SPELL_HEAL || SpellID == SPELL_MASS_HEAL)
{
effect eBad = GetFirstEffect(oTarget);
//Search for negative effects
while(GetIsEffectValid(eBad))
{
if ((GetEffectType(eBad) == EFFECT_TYPE_ABILITY_DECREASE ||
GetEffectType(eBad) == EFFECT_TYPE_BLINDNESS ||
GetEffectType(eBad) == EFFECT_TYPE_DEAF ||
GetEffectType(eBad) == EFFECT_TYPE_DISEASE ||
GetEffectType(eBad) == EFFECT_TYPE_POISON ||
GetEffectType(eBad) == EFFECT_TYPE_DAZED ||
GetEffectType(eBad) == EFFECT_TYPE_CONFUSED ||
GetEffectType(eBad) == EFFECT_TYPE_STUNNED) &&
GetEffectSpellId(eBad) != SPELL_ENLARGE_PERSON &&
GetEffectSpellId(eBad) != SPELL_RIGHTEOUS_MIGHT &&
GetEffectSpellId(eBad) != SPELL_STONE_BODY &&
GetEffectSpellId(eBad) != SPELL_IRON_BODY &&
GetEffectSpellId(eBad) != 803) // NOT SURE IF 803 ACTUALLY DOES ANYTHING
{
RemoveEffect(oTarget, eBad);
eBad = GetFirstEffect(oTarget);
}
else{eBad = GetNextEffect(oTarget);}
}
}
}
Modifié par Lance Botelle, 10 août 2013 - 11:13 .
#16
Posté 11 août 2013 - 11:28
#17
Posté 12 août 2013 - 10:58
DannJ wrote...
The spellhook would have to not only check the spell target object, but also evaluate the spell target location for proximity to the placeable. Otherwise it would miss AOE spells that were fired at the ground close to the placeable.
Hi DannJ,
It's not so bad as it might first seem to be ... I think.
For instance, if this is a "special" situation for a module, which is how I read the need (i.e. Certain rock(s) needed to be prone to sonic attacks), then we need only check for the TAG of an object (the rocks in question) when each SONIC type spell is cast. So, the spellhook would be checking for every SONIC spell cast, and then each type of SONIC (be it target or AOE) can be checked individually within each spell hook SONIC sub-section.
As spell target location is already a variable we have access to (see my example script - location lLocation = GetSpellTargetLocation(); ), we need only check within the range (for each SONIC spell type that requires AOE) to see if the rock (with certain TAG) is within range and then destroy it.
It seems reasonably straight forward to me. But I have not tested it yet.
EDIT: Other SONIC spells that would need adding: Shout, Greater Shout. (What others are there?)
Lance.
EDIT: And of course, it could always be specified that the spell has to target the rock directly to work, as opposed to ambient or nearby sonic effects.
EDIT: Here is a really quick example of what I mean. I do not know all the SONIC spells available, but they should be easy enough to add here:
// SPELL HOOK EXAMPLE (UNTESTED)
void main()
{
object oPC = OBJECT_SELF; // CASTER
object oTarget = GetSpellTargetObject(); // SPELL TAGET
string sTargetTag = GetTag(oTarget); // TARGET TAG
location lLoc = GetSpellTargetLocation(); // SPELL LOCATION
int SpellID = GetSpellId(); // SPELL ID CAST
// INTERECPT ALL SONIC SPELLS
if(SpellID == SPELL_ORB_OF_SOUND || SpellID == SPELL_LESSER_ORB_OF_SOUND || SpellID == SPELL_SOUND_BURST)
{
// THESE APPEAR TO BE DIRECT TARGET SPELLS
if(SpellID == SPELL_ORB_OF_SOUND || SpellID == SPELL_LESSER_ORB_OF_SOUND)
{
// ONLY INTERESTED IN SONIC PRONE TARGETS FOR THESE SPELLS
if(sTargetTag == "alb_sonicprone")
{
// ADD VFX FOR ROCK EXPLOSIONS HERE TOO
DestroyObject(oTarget);
}
}
// AN EXAMPLE OF AREA EFFECT SONIC
if(SpellID == SPELL_SOUND_BURST)
{
oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_MEDIUM, lLoc);
while (GetIsObjectValid(oTarget))
{
// ONLY INTERESTED IN SONIC PRONE TARGETS FOR THESE SPELLS
if(sTargetTag == "alb_sonicprone")
{
// ADD VFX FOR ROCK EXPLOSIONS HERE TOO
DestroyObject(oTarget);
}
//Get the next target in the spell area
oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_MEDIUM, lLoc);
}
}
}
}
Modifié par Lance Botelle, 12 août 2013 - 11:39 .
#18
Posté 12 août 2013 - 04:16
#19
Posté 12 août 2013 - 05:21
Eguintir Eligard wrote...
I dont care about checking the area around the item. I DO care about having to list every spell that could possible effect it as that was the whole thing I was trying to avoid in this process. It's a closed case anyway as I handled it with a conversation tip to the player.
Hi E.E.
Glad you got it sorted.
Out of interest, I don't think there were many SONIC spells to list, and using spell hooking, you only need to add an "OR" spell ID for each spell you wanted to cover. i.e. That code I give does most of the work you needed. You would have just needed to add a few "OR" spell IDs.
But, you have it sorted now, so that's the main thing.
Lance.





Retour en haut






