I was about to use Tchos’ Visual Effects for Characters https://neverwintervault.org/project/nwn2/other/visual-effect/tchos-visual-effects-characters in an area. I wanted musical notes above an NPC. So, I made a script on OnClientEnter of the area which I thought would work. However, I got an error when trying to compile that has to do with “case” and “break”, and with my current scripting knowledge I don’t quite understand what’s wrong. I’m sure it’s something simple. It says “Skipping declaration via “case” statement dissalowed” and it seems that it’s something wrong in the function written by Tchos as far as I can understand. Here’s my script with Tchos function written out above my script:
void TchosFX(int iFX, object oPC=OBJECT_SELF);
// At the time of this writing, there are only two effects to choose from. Choose which one with the int "iFX".
// 0 = Remove sleeping and/or music effects from character, if they are applied.
// 1 = Sleeping effect. Floating Zs over the character's head. Use together with prone custom animation.
// 2 = Musical notes rise above character's head. Use for singing characters or musicians.
// Default target is self. Specify another character if desired.
void TchosFX(int iFX, object oPC=OBJECT_SELF)
{
effect eFX;
switch (iFX)
{
case 0:
RemoveSEFFromObject(oPC, "musical.sef");
RemoveSEFFromObject(oPC, "zzz.sef");
break;
case 1:
effect eFX = EffectNWN2SpecialEffectFile("zzz.sef");
ApplyEffectToObject( DURATION_TYPE_PERMANENT, eFX, oPC);
break;
case 2:
effect eFX = EffectNWN2SpecialEffectFile("musical.sef");
ApplyEffectToObject( DURATION_TYPE_PERMANENT, eFX, oPC);
break;
}
}
void main()
{
object oPC = GetEnteringObject();
if(!GetIsPC(oPC)) return;
object oKrostnost = GetNearestObjectByTag("krostnost",oPC);
object oArea = GetObjectByTag("esvr");
if(GetArea(oKrostnost) == oArea)
{
TchosFX(2, oKroknost);
}
}
There are two issues that do not allow it to compile:
the first one is that effect eFX is being recalled inside the switch case of the first function, to fix this you simply have to remove effect before the two eFX inside the switch.
The second one is that at the very end, you use “oKroknost” instead of “oKrostnost”.
With these two fixes the script compiles, here how it should look like:
// At the time of this writing, there are only two effects to choose from. Choose which one with the int "iFX".
// 0 = Remove sleeping and/or music effects from character, if they are applied.
// 1 = Sleeping effect. Floating Zs over the character's head. Use together with prone custom animation.
// 2 = Musical notes rise above character's head. Use for singing characters or musicians.
// Default target is self. Specify another character if desired.
void TchosFX(int iFX, object oPC=OBJECT_SELF)
{
effect eFX;
switch (iFX)
{
case 0:
RemoveSEFFromObject(oPC, "musical.sef");
RemoveSEFFromObject(oPC, "zzz.sef");
break;
case 1:
eFX = EffectNWN2SpecialEffectFile("zzz.sef");
ApplyEffectToObject( DURATION_TYPE_PERMANENT, eFX, oPC);
break;
case 2:
eFX = EffectNWN2SpecialEffectFile("musical.sef");
ApplyEffectToObject( DURATION_TYPE_PERMANENT, eFX, oPC);
break;
}
}
void main()
{
object oPC = GetEnteringObject();
if(!GetIsPC(oPC)) return;
object oKrostnost = GetNearestObjectByTag("krostnost",oPC);
object oArea = GetObjectByTag("esvr");
if(GetArea(oKrostnost) == oArea)
{
TchosFX(2, oKrostnost);
}
}
Thanks. Maybe one should point this out to Tchos on the page for the download of his effects. Ah, I thought I had copied that oKrostnost, but instead I wrote it, and I wrote it wrong.
the case/break blocks are not scoped w/ { /*code*/ } braces
so compilers get chuffed when a variable is re-declared – effect eFX
There are two ways to deal with it. First is do what Clangeddin does above and declare effect eFX before the switch/case begins. The second is to use braces to properly scope the declarations.
If you are putting this on an area’s OnClientEnter, then the GetArea check is unnecessary. Additionally, if you are only using the music effect, then the case/switch code is also unnecessary. All you need is the musical.sef file. Try this:
Thanks travus! You are right of course. The reason I used GetArea is that at one point in the module (I think, I’ve not come that far yet) the oKrostnost won’t be there anymore. But maybe then the script just won’t fire if it doesn’t find the object…but…well, I thought just in case…