Note: LucasForums Archive Project
The content here was reconstructed by scraping the Wayback Machine in an effort to restore some of what was lost when LF went down. The LucasForums Archive Project claims no ownership over the content or assets that were archived on archive.org.

This project is meant for research purposes only.

Force Power Help

Page: 1 of 1
 Istorian
09-13-2008, 6:58 AM
#1
I'm currently working on a Force Power and I've encountered a litle problem. I want the Force Power to target multiple enemies at once, just like Force Storm or Death Field...I just don't know how to do that...I took a look at the script of these two Force Powers, but I still can't figure out how to do that...could anybody help me, please? I'm getting desperate!:(

|I|
 stoffe
09-13-2008, 8:43 AM
#2
I'm currently working on a Force Power and I've encountered a litle problem. I want the Force Power to target multiple enemies at once, just like Force Storm or Death Field...I just don't know how to do that...I took a look at the script of these two Force Powers, but I still can't figure out how to do that...could anybody help me, please? I'm getting desperate!:(


You generally do that by fetching the location of the selected target and then looping through all other creatures within a specified radius. You then check each found creature to see if they are an enemy of the caster and generally allow them a Force Resistance check and/or a Saving Throw to avoid or lessen the effect of the force power.

Here is a simple example script of this I put together, with code comments (green text) in:


// ST: Forward declaration of two custom support functions implemented below
int ST_DoSavingThrow(object oTarget, int nSaveType, int nSaveCat = SAVING_THROW_TYPE_ALL, int nDC = 0);
int ST_DoResistCheck(object oTarget);




// ST: Main function, the code for the force power impact script.
void main() {
// ST: Example power effect - an explosion dealing 100 Ion damage.
effect eBoom = EffectLinkEffects(EffectDamage(100, DAMAGE_TYPE_ION), EffectVisualEffect(VFX_FNF_GRENADE_SONIC));

// ST: Get the location of the targeted enemy
location lLoc = GetLocation(GetSpellTargetObject());

// ST: Find the first victim within a 10 meter radius from the selected target
object oVictim = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, lLoc);

while (GetIsObjectValid(oVictim)) {
// ST: It's a hostile power, so skip anyone who's not an enemy of the caster
if (GetIsEnemy(oVictim) && !GetIsDead(oVictim)) {
// ST: Check that the power wasn't resisted, and allow the victim a Reflex save to avoid it.
if (!ST_DoResistCheck(oVictim) && !ST_DoSavingThrow(oVictim, SAVING_THROW_REFLEX)) {
// ST: Trigger AI event on the victim to inform them a force power was cast on them.
SignalEvent(oVictim, EventSpellCastAt(OBJECT_SELF, GetSpellId()));

// ST: Apply the explosion to the victim
ApplyEffectToObject(DURATION_TYPE_INSTANT, eBoom, oVictim);
}
}

// ST: Find the next victim within a 10 meter radius from the selected target
oVictim = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, lLoc);
}
}






// ST: Support function - do saving throw check and display result feedback to player
int ST_DoSavingThrow(object oTarget, int nSaveType, int nSaveCat = SAVING_THROW_TYPE_ALL, int nDC = 0) {
nDC = (nDC > 0 ? nDC : GetSpellSaveDC());
int nSave;

// ST: Do the saving throw roll.
switch (nSaveType) {
case SAVING_THROW_FORT: nSave = FortitudeSave(oTarget,nDC, nSaveCat); break;
case SAVING_THROW_REFLEX: nSave = ReflexSave(oTarget, nDC, nSaveCat); break;
case SAVING_THROW_WILL: nSave = WillSave(oTarget, nDC, nSaveCat); break;
}

// ST: The target did not fail their saving throw, show the "resist" visual on them.
if (nSave > 0) {
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceResisted(OBJECT_SELF), oTarget);

// ST: Show floatie feedback text indicating that they made their save.
switch (nSave) {
case 1: DisplayFeedBackText(oTarget, 2); break; // ST: The target was immune to the power
case 2: DisplayFeedBackText(oTarget, 1); break; // ST: The target succeeded in their save
}
}
return nSave;
}




// ST: Support function - do Force Resistance check and display feedback to player
int ST_DoResistCheck(object oTarget) {
// ST: The power was resisted, show the visual effect and floatie feedback text
if (ResistForce(OBJECT_SELF, oTarget)) {
DisplayFeedBackText(oTarget, 0);
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceResisted(OBJECT_SELF), oTarget);
return TRUE;
}
return FALSE;
}


(I've got two reusable custom functions for checking for saving throws and force resistance that shows some feedback to the player to indicate the result (the "fizzle" visual effect, and the "SAVED", "RESISTED" or "IMMUNE" floatie text above the buttons of the selecte target) to separate that stuff out from the actual functionality of the power as much as possible. Normally you want to stick functions like that in an include file that you then re-use with your powers for simplicity.)
 Istorian
09-13-2008, 9:05 AM
#3
Thanks, stoffe! Will try that right away!!:D

|I|
 Istorian
09-14-2008, 6:11 AM
#4
Well, unfortunately it doesn't work...I am still open to new scripting methods on how to do that...:(

|I|
 stoffe
09-14-2008, 7:19 AM
#5
Well, unfortunately it doesn't work...I am still open to new scripting methods on how to do that...:(

|I|

What is is that doesn't work? I tried running that example script in my game before posting it and it worked just as expected. What happens when you try to run it? Nothing? You could try adding debug printouts to the script to ensure that it's being run at all.

"It doesn't work" doesn't give much to go on to figure out what the problem is. :)
 TriggerGod
09-14-2008, 11:40 AM
#6
Well, unfortunately it doesn't work...I am still open to new scripting methods on how to do that...:(

|I|

Well, I'm not going on much... but, a problem me and Ferc had while doing the Lost Force Powers Pack was that we gave the wrong script name for Lightning Crush. Make sure that you made that column the correct script name.

Now, if animations didn't work, maybe you didn't use a valid number. Check visualeffects.2da
 Istorian
09-14-2008, 11:55 AM
#7
Well, I checked both, TG, and they are all right...Now, stoffe, check your PM's, as I couldn't reveal the script for the Force Power...it is not my mod, so it will be a spoiler...The animations don't work, so even if the script is really working, and the FP targets many enemies, I can't see it...please answer to the PM...

|I|
 stoffe
09-14-2008, 7:39 PM
#8
The animations don't work, so even if the script is really working, and the FP targets many enemies, I can't see it...


Weird. Well, here's a script that should be doing what you want if I understood you correctly. Hopefully you'll get that one to work :)

Use the attached include file when you compile it.


#include "st_inc_force"

void main() {
location lLoc = GetLocation(GetSpellTargetObject());

effect eBeam = EffectBeam(VFX_BEAM_DEATH_FIELD_TENTACLE, OBJECT_SELF, BODY_NODE_HEAD);
effect eVis = EffectVisualEffect(VFX_PRO_DEATH_FIELD);
effect eCrush = EffectCrush();
effect ePushy = EffectForcePushed();

int iDice = GetHitDice(OBJECT_SELF);
int iHeal = 0;

object oVictim = GetFirstObjectInShape(SHAPE_SPHERE, 12.0, lLoc);
while (GetIsObjectValid(oVictim)) {
if (GetIsEnemy(oVictim)
&& !GetIsDead(oVictim)
&& (GetCurrentHitPoints(oVictim) > 0)
&& (GetRacialType(oVictim) != RACIAL_TYPE_DROID))
{
SignalEvent(oVictim, EventSpellCastAt(OBJECT_SELF, GetSpellId()));

ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBeam, oVictim, 1.0);

if (!ST_ResistForce(oVictim) ) {
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oVictim);

int iDmg;
if (!ST_SavingThrows(oVictim, SAVING_THROW_FORT, SAVING_THROW_TYPE_DARK_SIDE))
iDmg = ST_CalcDamage(oVictim, iDice, 10);
else
iDmg = ST_CalcDamage(oVictim, iDice, 10) / 2;

effect eDam = EffectDamage(iDmg, DAMAGE_TYPE_DARK_SIDE);
iHeal += iDmg;

AssignCommand(oVictim, ClearAllActions());
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eCrush, oVictim, 2.0);
DelayCommand(1.64, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oVictim));
DelayCommand(2.0, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ePushy, oVictim));
}
}

oVictim = GetNextObjectInShape(SHAPE_SPHERE, 12.0, lLoc);
}

if (iHeal == 0) {
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
}
else {
if (GetCurrentHitPoints(OBJECT_SELF) < GetMaxHitPoints(OBJECT_SELF)) {
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(iHeal), OBJECT_SELF);
}
}
}
 Istorian
09-15-2008, 2:45 PM
#9
I get an errror while trying to compile it...It says something like: "Cannot open included file"...What do I do? And sorry for all the mess I've put you...

|I|
 deathdisco
09-15-2008, 4:49 PM
#10
Do you still end up with an *.ncs? If so the error is normal since include files do not compile and aren't meant to. They contain additional information used in compiling the source file.
 Istorian
09-15-2008, 6:04 PM
#11
When I compile the include file, I don't get an *.ncs file, and as you said, that's normal...But when I try to compile the basic script (the one in the codebox in stoffe's post), it doesn't compile and doesn't produce an *.ncs file, because of this error message: "Error: Unable to open include file 'st_inc_force.nss' "...So, I never end up with an *.ncs...where should I put the include file so that Kotor Tool will be able to open it?

|I|
 stoffe
09-15-2008, 9:25 PM
#12
where should I put the include file so that Kotor Tool will be able to open it?

I don't use KotorTool to compile scripts, so I don't know for sure how that application works. But I'd guess you put include files either in the override folder, or in the same folder as the script you are trying to compile.
 TriggerGod
09-15-2008, 9:29 PM
#13
When I compile the include file, I don't get an *.ncs file, and as you said, that's normal...But when I try to compile the basic script (the one in the codebox in stoffe's post), it doesn't compile and doesn't produce an *.ncs file, because of this error message: "Error: Unable to open include file 'st_inc_force.nss' "...So, I never end up with an *.ncs...where should I put the include file so that Kotor Tool will be able to open it?

|I|

Hmm...
If you have nwscript in your override (as I do) just place that script into the same area as nwscript.nss. Then, compile. That should work.
 Istorian
09-20-2008, 7:10 AM
#14
Yeah, that worked, thanks TG!! Now, two problems:

1) The beam visual effect doesn't show up, and the PC just puts his hand in the air and everybody is Force Crushed...no DF beam...

2) MAJOR: After a single use of the Force Power, the round doesn't finish, so the enemies sit there, do nothing and just watch you hit them...At least this should be fixed, I think...:xp:

Anyway, stoffe, thanks for the help so far!;)

|I|
 stoffe
09-21-2008, 9:07 PM
#15
Now, two problems:
1) The beam visual effect doesn't show up,
2) MAJOR: After a single use of the Force Power, the round doesn't finish,

Hm, which game is this for, KOTOR or TSL? Try this, using the same include file as was attached in an earlier post:


#include "st_inc_force"

void main() {
location lLoc = GetLocation(GetSpellTargetObject());

effect eBeam = EffectBeam(VFX_BEAM_DEATH_FIELD_TENTACLE, OBJECT_SELF, BODY_NODE_HEAD);
effect eVis = EffectVisualEffect(VFX_PRO_DEATH_FIELD);
effect eCrush = EffectCrush();
effect ePushy = EffectForcePushed();

int iDice = GetHitDice(OBJECT_SELF);
int iHeal = 0;

object oVictim = GetFirstObjectInShape(SHAPE_SPHERE, 12.0, lLoc);
while (GetIsObjectValid(oVictim)) {
if (GetIsEnemy(oVictim)
&& !GetIsDead(oVictim)
&& (GetCurrentHitPoints(oVictim) > 0)
&& (GetRacialType(oVictim) != RACIAL_TYPE_DROID))
{
SignalEvent(oVictim, EventSpellCastAt(OBJECT_SELF, GetSpellId()));

ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBeam, oVictim, 1.0);

if (!ST_ResistForce(oVictim) ) {
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oVictim);

int iDmg;
if (!ST_SavingThrows(oVictim, SAVING_THROW_FORT, SAVING_THROW_TYPE_DARK_SIDE))
iDmg = ST_CalcDamage(oVictim, iDice, 10);
else
iDmg = ST_CalcDamage(oVictim, iDice, 10) / 2;

effect eDam = EffectDamage(iDmg, DAMAGE_TYPE_DARK_SIDE);
iHeal += iDmg;

ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eCrush, oVictim, 2.0);
DelayCommand(1.64, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oVictim));
DelayCommand(2.0, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ePushy, oVictim));
}
}

oVictim = GetNextObjectInShape(SHAPE_SPHERE, 12.0, lLoc);
}

if (iHeal == 0) {
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
}
else {
if (GetCurrentHitPoints(OBJECT_SELF) < GetMaxHitPoints(OBJECT_SELF)) {
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(iHeal), OBJECT_SELF);
}
}
}
 Istorian
09-27-2008, 7:28 AM
#16
Stoffe, perhaps I'm the 100.000th person who says it to you, but you're a scripting guru, a genius!:D Everything works ok, but there is a slight problem...the beam is shown as lightning like Force Storm and not as the Drain Life and Death Field beams (orange)...I know I'm becoming very annoying, but what should I do?

Thanks again for the tremendous help!!:D:xp:

|I|
 stoffe
09-28-2008, 6:33 AM
#17
the beam is shown as lightning like Force Storm and not as the Drain Life and Death Field beams (orange)...I know I'm becoming very annoying, but what should I do?


The script posted uses the VFX_BEAM_DEATH_FIELD_TENTACLE constant to set the beam, which is the same used by the Death Field force power. So if you haven't changed that in the script and still are getting lightning beams instead, I would guess you are either using an nwscript.nss file that has been somehow modified to compile the script, or have a visualeffects.2da file in your override folder that has been altered so the indexes no longer appear as the default. Or have some mod installed that retextures the beams. But then you'd see the wrong beam visuals when using Death Field as well.
 Istorian
09-28-2008, 8:31 AM
#18
Well, I tried to play it with an empty override folder, but no solution...I haven't changed anything in the script, nor in the nwscript.nss file...so what is happening?

|I|
 stoffe
09-28-2008, 11:05 AM
#19
Well, I tried to play it with an empty override folder, but no solution...I haven't changed anything in the script, nor in the nwscript.nss file...so what is happening?

If you use the regular Death Field force power, does it show the correct beams?

Try replacing VFX_BEAM_DEATH_FIELD_TENTACLE with 2026 in the script and recompile it and see if that makes a difference. Also doublecheck that you are actually using the recompiled script, and that there aren't any other scripts with the same name in any sub-folders within the override folder.
 Istorian
09-28-2008, 4:59 PM
#20
Yeah, Death Field's beam is ok, and yes I use the correct file...I put 2026 in the script as you said, but I had the same effect...I triple-checked the visualeffects.2da files and spells.2da files, and everything is alright...I don't know why this is happening...:(

|I|
 stoffe
09-30-2008, 8:54 AM
#21
Yeah, Death Field's beam is ok, and yes I use the correct file...I put 2026 in the script as you said, but I had the same effect...I triple-checked the visualeffects.2da files and spells.2da files, and everything is alright...I don't know why this is happening...:(


Then I have no idea what's wrong with your game, because what you describe should technically be impossible :p

If I run the script posted above in my game the correct beam is used, so it's likely an issue with your game install rather than with your mod. Perhaps a conflict with some other mod you got installed?
 Istorian
09-30-2008, 10:29 AM
#22
Okies, I will uninsyall them and I will report back...sorry for the mess I've put you...Thanks again!:D

|I|
Page: 1 of 1