PDA

View Full Version : FP - how to script immunity for *specific* enemy


darthrevanrlz
07-11-2006, 03:17 PM
Heya.

So here's the story.

After having finished with the buffs this morning (muchas gracias Stoffe!!), I got to work on an expanded Force Kill tree. Will be home in an hour or two and would like to dive right back into it... :D

I won't go in detail on the new FP stats/effects, but, my question is:

is it possible to make sure that certain *HUMAN* characters will ALWAYS save against that power and only suffer the *lower* damage???

I'm thinking the three Sith Lords and Atris, btw. I KNOW their fortitude saves are plain sick. But just pump your WIZ via cheating and there ya go, a Sith Lord minus 50% health not to mention neutralizd for 6 seconds.

So, is there any way to put a restriction in the FP's script?

EDIT: I know you can easily put restrictions for *RACIAL* types, but 4 specific characters seem somewhat more complicated... :D

stoffe
07-11-2006, 03:27 PM
is it possible to make sure that certain *HUMAN* characters will ALWAYS save against that power and only suffer the *lower* damage???


Maybe something like this may work as part of the spell script:


string sName = GetName(oTarget);
if (!GetIsPC(oTarget)
&& ((sName == "Darth Sion")
|| (sName == "Atris")
|| (sName == "Darth Nihilus")
|| (sName == "Darth Traya")))
{
// Do "saved" effects...
}
else {
// Proceed as normal...
}


It's a bit more generic than checking for tags, since those may differ for the NPCs in different modules, but they are usually named the same every time they appear.

If you want to do it a bit more generic you could add a condition that makes the power always have a lesser effect against characters who are higher in level than the force user (since the Bosses usually are higher level than the player).

darthrevanrlz
07-11-2006, 06:59 PM
Mmm...

What I had in mind was that these bosses would get half regular damage when SUCCEEDING a save and a quarter when failing it.

It's... it's just not working out.

EDIT: A question: for the sName... what exactly am I supposed to go for? Tag? First name? Went for the TAG and that may be the problem... :(
But then again, when I used the "darth Sion" proposed, I'd get eDam AND eDam2... (see script below)

I even tried to go overboard by punching in both "sName !=" and "sName ==" but I just can't get it right.

At first, bosses would get the dmg for eDam1 & eDam2. I got it down to eDam1 only but it's still not what I'm trying to achieve.

This is what the script looks like. Ugly, I know, but it's not as if there was ANY reference out there... Hell, there are two versions which managed to not work just the same...

I tried to NOT separate it in two big blocks (punching in IF everywhere), but I then just couldn't get it to be compiled...

*sigh*

#include "k_inc_force"

//TeleK I

void main()
{

object oTarget = GetSpellTargetObject();
SWFP_HARMFUL = TRUE;
SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_FORT;

SWFP_DAMAGE = ((GetCurrentHitPoints(oTarget))/2);
SWFP_DAMAGE_TYPE = DAMAGE_TYPE_BLUDGEONING;

effect eDrop = EffectForcePushed();
effect eCrush = EffectCrush();
effect eDeath = EffectDeath();
effect eDam = EffectDamage(SWFP_DAMAGE, SWFP_DAMAGE_TYPE);
effect eDam2 = EffectDamage(SWFP_DAMAGE/2, SWFP_DAMAGE_TYPE);
effect eDam3 = EffectDamage(SWFP_DAMAGE/4, SWFP_DAMAGE_TYPE);
int nSpellID = GetSpellId();

int nResist = Sp_BlockingChecks(oTarget, eCrush, eDam, eDeath);
int nSaves = Sp_MySavingThrows(oTarget);


string sName = GetName(oTarget);

SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));

if (!GetIsPC(oTarget)
&& ((sName == "DarthSion")
|| (sName == "Atris")
|| (sName == "DarthNihilus")
|| (sName == "KreiaEvil")
|| (sName == "kavar")
|| (sName == "npc_vrook")
|| (sName == "Zezkaiel"))) {

if(nResist == 0)
{

if(nSaves != 0)
{
DelayCommand( 1.64, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam3, oTarget) );
}

else
{
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eCrush, oTarget, 2.0);
DelayCommand( 2.0, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDrop, oTarget) );
DelayCommand( 1.64, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam2, oTarget) );
}
}

else {
eDam = EffectDamage(0, DAMAGE_TYPE_BLUDGEONING);
}
}

if(!GetIsPC(oTarget)
&& ((sName != "DarthSion")
|| (sName != "Atris")
|| (sName != "DarthNihilus")
|| (sName != "KreiaEvil")
|| (sName != "kavar")
|| (sName != "npc_vrook")
|| (sName != "Zezkaiel"))) {

if(nResist == 0)
{

if(nSaves != 0)
{
DelayCommand( 1.64, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam2, oTarget) );
}

else
{
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eCrush, oTarget, 2.0);
DelayCommand( 2.0, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDrop, oTarget) );
DelayCommand( 1.64, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget) );
}
}

else {
eDam = EffectDamage(0, DAMAGE_TYPE_BLUDGEONING);
}

}

if(nResist > 0)
{
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
}
}


I'll admit I'm not even sure if eDeath is necessary, but that's not the problem right now... :D

1 - What the hell went wrong with the character restrictions???

2 - This one should be real short, lol. Assuming I'd want to go for an area effect on this one (3.33 - 5.0 range, I guess)... How would I put a number of targets restrictions? Let's say I want to put a cap of 3 "crushed" opponents within that range...

P.S. Damnit, I KNOW putting such character restrictions isn't *necessary*, but it's just to prevent the highly unlikely case of a "boss" not succeeding in a FP save throw... I mean, Kill or similar spells should never ever work on bosses. Even THEORETICALLY speaking. :D

stoffe
07-12-2006, 12:13 PM
A question: for the sName... what exactly am I supposed to go for? Tag? First name? Went for the TAG and that may be the problem... :(


The name of the NPC, as shown when selected in-game. You could use GetTag(oTarget) instead of GetName(oTarget) if you want to check for their tags instead of character name if you feel that's more reliable. Just make sure to check the tags in all modules they appear, since they are not necessarily the same everywhere.


This is what the script looks like. Ugly, I know, but it's not as if there was ANY reference out there... Hell, there are two versions which managed to not work just the same...


That script had lots of rendundant code and some rather peculiar formatting. :) If I interpreted it correctly, this somewhat cleaned up variant should probably work:


#include "k_inc_force"

int IsBossNPC(object oTarget);

void main() {
SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_FORT;

object oTarget = GetSpellTargetObject();
int nDamage = GetCurrentHitPoints(oTarget) / 2;
effect eDrop = EffectForcePushed();
effect eCrush = EffectCrush();
effect eDeath = EffectDeath();
effect eDam;

// ST: Run OnSpellCastAt event on the target.
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), TRUE));

// ST: Check for immunity and magic resistance.
if (!Sp_BlockingChecks(oTarget, eCrush, eDam, eDeath)) {
int bBoss = IsBossNPC(oTarget);

if (!Sp_MySavingThrows(oTarget)) {
// ST: "Boss" NPCs only take half damage
eDam = EffectDamage((bBoss ? nDamage / 2 : nDamage), DAMAGE_TYPE_BLUDGEONING);
DelayCommand(1.64, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));

// ST: "Boss" type NPCs won't be debilitated.
if (!bBoss) {
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eCrush, oTarget, 2.0);
DelayCommand(2.0, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDrop, oTarget));
}
}
else {
// "Boss" type NPCs only take one quarter damage on successful save.
eDam = EffectDamage((bBoss ? nDamage/4 : nDamage/2), DAMAGE_TYPE_BLUDGEONING);
DelayCommand( 1.64, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
}
}
else {
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
}
}

int IsBossNPC(object oTarget) {
string sName = GetName(oTarget);
return !IsObjectPartyMember(oTarget)
&& ( (sName == "Darth Sion")
|| (sName == "Atris")
|| (sName == "Darth Nihilus")
|| (sName == "Kreia")
|| (sName == "Master Kavar")
|| (sName == "Master Vrook")
|| (sName == "Zez-Kai Ell")
|| (sName == "Master Zez-Kai Ell")
);
}



I'll admit I'm not even sure if eDeath is necessary, but that's not the problem right now... :D


In that script it is used to make any creature with immunity to Death effects completely invulnerable to the force power. Even though the power itself doesn't apply any death effect.


2 - This one should be real short, lol. Assuming I'd want to go for an area effect on this one (3.33 - 5.0 range, I guess)... How would I put a number of targets restrictions? Let's say I want to put a cap of 3 "crushed" opponents within that range...


Add a counter to the loop and add a stop condition to the loop when that counter exceeds the desired number. Like:

int iCnt = 0;
location lLoc = GetLocation(GetSpellTargetObject());
object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, 5.0, lLoc);
while (GetIsObjectValid(oTarget) && (iCnt < 3)) {
// ... Do whatever the power is supposed to do here ...

iCnt++;
oTarget = GetNextObjectInShape(SHAPE_SPHERE, 5.0, lLoc);
}

darthrevanrlz
07-12-2006, 02:15 PM
That script had lots of rendundant code and some rather peculiar formatting. :) If I interpreted it correctly, this somewhat cleaned up variant should probably work:

Yeah, well, the first version looked a LOT cleaner, lol. :D

Let's just say I stopped caring altogether about formatting after the third try... :D

Nice script, btw. Lot less of a headache than my previous attempt, lol.

And what exactly IS eDeath? Saw it for Kill and since the spell more or less does the same, I just put it in there in case it would be needed...

stoffe
07-12-2006, 02:25 PM
And what exactly IS eDeath? Saw it for Kill and since the spell more or less does the same, I just put it in there in case it would be needed...

EffectDeath() produces an instant death effect that kills the target without dealing damage to them. In this case it's not used to make the force power kill the target outright, but for immunity checking. I.e. if the target is immune to instant death effects, the force power will fizzle if used against them.