Case Statement to run script?

Looking for help with this script, I’m trying to call a random script from a list via case statement. Tips, nudges, any help is always appreciated!

I think I’m going down the wrong path with this. Likely a easier way to do this… I pulled/modified this from a ‘get random weapon damage’ script. I still need the bits of code around this that actually use the variable iScript:

int RandomScript()
{
    //pick a random script
    int iScript;
    int iSwitch = Random(6);
    if (iSwitch == 0) iScript = arena_0001
    if (iSwitch == 1) iScript = arena_0002
    if (iSwitch == 2) iScript = arena_0003
    if (iSwitch == 3) iScript = arena_0004
    if (iSwitch == 4) iScript = arena_0005
    if (iSwitch == 5) iScript = arena_0006
    return iScript;
}

The script names are strings, not integers.

You need double quotes “arena_0001” etc. and semi-colons after each.

string  RandomScript()
{
    //pick a random script
    string sScript;
    int iSwitch = Random(6);
    if (iSwitch == 0) sScript = "arena_0001";
    if (iSwitch == 1) sScript = "arena_0002";
    if (iSwitch == 2) sScript = "arena_0003";
    if (iSwitch == 3) sScript = "arena_0004";
    if (iSwitch == 4) sScript = "arena_0005";
    if (iSwitch == 5) sScript = "arena_0006";
    return sScript;
}

There is a switch syntax which is marginally more efficient, but not much more elegant, if you add a break; to every line.

You could build a table then select an element, but that’s more work in a simple case like this.

If the script names will always end in a consecutive number less than 10, you can replace all those if statements with

return "arena_000" + IntToString(iSwitch + 1));

though that is fragile and harder to understand.

If the scripts are all very similar, consider making one script, then pass a random parameter to it.

1 Like

Thank you! As you can see the script fundamentals elude my brain.

So in order to trigger the script, I need:

ExecuteScript ("sScript", object oArea);

How do I use sScript there as the variable string we pull form the case?

Here you don’t need to use the quotation marks as you defined the string with the “scriptname” earlier:

ExecuteScript(sScript, oArea);

Sorry struggling with this one. I’ve thrown a void main() and wrapped the contents. But I keep running into compile issues. And this alone won’t compile the ExecuteScript line. I tried finding something similar and also the examples on lexicon, even tried doing sometihng similar with LS script tool, ust to get an idea of what I need to get this working as is so I can understand it.

string  RandomScript()
{
    //pick a random script
    string sScript;
    int iSwitch = Random(6);
    if (iSwitch == 0) sScript = "arena_0001";
    if (iSwitch == 1) sScript = "arena_0002";
    if (iSwitch == 2) sScript = "arena_0003";
    if (iSwitch == 3) sScript = "arena_0004";
    if (iSwitch == 4) sScript = "arena_0005";
    if (iSwitch == 5) sScript = "arena_0006";
    return sScript;
ExecuteScript (sRandomScript, object oArea);
}

You don’t need the “object” part before oArea in ExecuteScript.
Anyway, when the compiler reaches the return sScript; line, the script will end (and ExecuteScript will not run).

The compiler will throw errors with that anyway because you haven’t declared the string variable sRandomScript. Try this -

string  RandomScript()
{
    //pick a random script
    
    string sScript;
    int iSwitch = d6();

    switch(iSwitch)
    {
        case 1 :
                sScript = "arena_0001";
                break;
        case 2 :
                sScript = "arena_0002";
                break;
        case 3 :
                sScript = "arena_0003";
                break;
        case 4 :
                sScript = "arena_0004";
                break;
        case 5 :
                sScript = "arena_0005";
                break;
        case 6 :
                sScript = "arena_0006";
    }
    return sScript;
}

// Then when you want to use your random script elsewhere in your code you would use -

    ExecuteScript(RandomScript(), oArea);

To get the hang of scripting see this pinned thread (and bookmark it for future reference) -

The Starting Point - module building tutorials for beginners - and where to find them

At the very least grab the offline Lexicon - NwN Lexicon 1.69

TR

2 Likes

Huh? Why fragile?

In this special case, a one-liner could do the trick:

return "arena_000" + IntToString(d6());

Well, professionals might fairly point out that the code breaks when the number of scripts exceeds 9 (which can be fixed with a function that returns the number in the form NNNN) and when one of the scripts needs to be named differently for some essential reason (which can’t).

Maybe not so important in a hobby environment.

Ah, I see. Writing such code always requires a solid estimation, which range of numbers is to expect.

So the code is indeed somewhat fragile, but the original code from the op would be even more fragile … Well let’s add an error-response if the number exceeds the expected value :slight_smile:

1 Like

I didn’t go that route since I plan on having many scripts for this arena spawner. So the TR’s case statement works better for me.

I got the code working by just adding a include for the case statement script in a super basic script that just executes the random script. :slight_smile: works great.

I kept trying to cram the ExecuteScript() into the case statement above - thinking that was the best way, just one script. I assume it’s entirely doable but having a separate script to just call the randomscript is also simple.

I attempted to add more scripts to this case and figured I just need to up the d# for int iSwitch = d6(); for he number of cases I have but just adding one script and changing it to d7 fails to compile with error: phrasing variable list.

Never seen a seven sided die before… I don’t think there is a d7() function.

And you won’t see. After all to be a die, the polyhedron must have a near-uniform probability distribution, which only the 5 platonic solids qualify for.

@Beleghost, use int iSwitch = Random(7) like you had before to “roll” a 7-sided die (or any-sided die, up to 32768). The d6() etc functions are its +1 shortcuts provided for convenience.

1 Like

Yes. I suppose I should have put a winky face on that post… :slight_smile:

1 Like

You just beat me to it! I was just testing this out :slight_smile: Thanks you!

Dilbert: What you are asking for defies the Laws of Physics
Sales Rep: Can we have it by Thursday?

2 Likes

Use d8() in a loop like -

string  RandomScript()
{
    //pick a random script
    
    string sScript;
    int iSwitch;
    
    do
    {
        iSwitch = d8();
    }
    while(iSwitch == 8)
        
    switch(iSwitch)
    {
        case 1 :
                sScript = "arena_0001";
                break;
        case 2 :
                sScript = "arena_0002";
                break;
        case 3 :
                sScript = "arena_0003";
                break;
        case 4 :
                sScript = "arena_0004";
                break;
        case 5 :
                sScript = "arena_0005";
                break;
        case 6 :
                sScript = "arena_0006";
                break;
        case 7 :
                sScript = "arena_0007";
    }
    
    return sScript;
}

// Then when you want to use your random script elsewhere in your code you would use -

    ExecuteScript(RandomScript(), oArea);

Most times the code will pass through the do/loop just the once. If it gets an 8, it will reroll until it is not an 8.

Just an alternative to using random().

TR

1 Like

Yep, definitely should have put that winky-face…

1 Like

Ah yes, sophisticated maths! I love it! How do you make a d3? (which is a available function)