Introducing ... ExecuteScriptEnhanced()

what a superb little advanced function !

how to use it (eg.)

AddScriptParameterObject(oTarget);
ExecuteScriptEnhanced(sScript, oCaster, TRUE);

Basically a function signature can be concocted on-the-fly by adding script parameters [ function here meaning main() or StartingConditional() ]

that can execute a script that has this signature:

void main(object oTarget)

or this

int StartingConditional(object oTarget)

In the latter case ExecuteScriptEnhanced() should return TRUE/FALSE (or likely any integer that you want the executed script to return).

But with the much simpler ExecuteScript() we had to set oTarget as a local object on say the module and then get it back in the executed script – with an enhanced script call oTarget gets passed in automagically as a parameter.

 
I don’t advise using it willy-nilly. If all you need is a function call then write the function w/ parameters and call it. But if for example you’re writing a substantial subsystem and have chosen to keep things organized by writing a bunch of separate scripts … and they need various parameters passed to them … this could be the ticket

4 Likes

Hi KevL,

Yes, I finally understood this one a short while back. It was the AddScriptParameter I did not realise was part of the setup, which, as you say, makes it rather cool compared to having to store it on the module.

Whether I will ever get to use it or not, only time will tell. I think I used it once to get a returned value, but did not know about the AddScriptParameter when I did it.

Cheers, Lance.

imagine this, Lance …

i maintain the MetaPrepa add-on, it recasts party spellbuffs (aka a spell-sequencer)

But spells that are on a submenu won’t cast via ActionCastSpellAtObject() …

Because caster doesn’t memorize the subspell only the master spell (even though GetHasSpell(subspell) returns true)

So the released version of MetaPrepa uses bCheat to cast those subspells. But, the bCheat parameter forces the spell to cast at L10.

so am testing a workaround

// parsed down to only the relevant stuff

void DoAllPreparations(object oBook, int bInstant)
{
    struct preparation pPrep = GetFirstPreparation(oBook);
    while (GetIsPreparationValid(pPrep))
    {
        EncapsulateSpell(pPrep, bInstant, iIteration, oPossessor, oItem);
        pPrep = GetNextPreparation(oBook);
    }
}

void EncapsulateSpell(struct preparation pSpell, int bInstant, int iIteration = 0, object oPossessor = OBJECT_INVALID, object oItem = OBJECT_INVALID)
{
    if (pSpell.iSpellId == iMasterId) // if spell is its own Master
    {
        ActionCastSpellAtObject(pSpell.iSpellId, oTarget, pSpell.iMeta, pSpell.bCheat, 0, PROJECTILE_PATH_TYPE_DEFAULT, FALSE);
    }
    else // fake the spell and execute a forced script ->
    {
        ActionCastFakeSpellAtObject(pSpell.iSpellId, oTarget, PROJECTILE_PATH_TYPE_DEFAULT);

        ActionDoCommand(AddScriptParameterObject(oTarget));

        string sScript = "radial_" + IntToString(pSpell.iSpellId);
        ActionDoCommand(ExecuteScriptEnhancedVoid(sScript, oCaster, TRUE));
    }
}

where the “radial” scripts are modified spellscripts (which ofc don’t have legitimate access to all the functions that a regular spellscript has)

 
The code for fastcast is more tenuous …

else // do NOT fake the spell and only execute a forced script ->
{
    DelayCommand(_fFastDelay, ActionDoCommand(AddScriptParameterObject(oTarget)));

    string sScript = "radial_" + IntToString(pSpell.iSpellId);
    DelayCommand(_fFastDelay + 0.0005f, ActionDoCommand(ExecuteScriptEnhancedVoid(sScript, oCaster, TRUE)));
}

 
the point: Trying to set oTarget(s) on the module (iteratively) would be a nightmare … because that’s actually what i did with the cast-on-item code before clueing into ExecuteScriptEnhanced(). First it creates a long string that then needs to be parsed back down into objects, spellids, etc. It seems to work but it’s not quite as robust as I believe the technique above (which, uh, i’m still testing…) would be

ps. Sorry if that’s all bleh. Am just saying that this could be an even huger benefit when parameterized “commands” need to be iterated/sequenced. yet it remains to be tested whether the parameters stick properly to their respective ExecuteScriptEnhanced() calls …

2 Likes

Hi KevL,

I’m not sure I grasped all that, as I don’t recognise the context (even with the code), so am probably missing the key point. (I thought I had used Sequencer somewhere in my second mod, but maybe not in the way you mention.)

Maybe I need to take a closer look at the MetaPrepa add-on to grasp in what context this is. :slight_smile:

It sounds quite complex. However, I am still interested in how this pans out. :slight_smile: Even if not for now, maybe in the future.

Cheers, Lance.

1 Like

summary:

  1. Put a bunch of items (that represent spells) in a container.
  2. Cast them all at the say-so of the player.
    2a. do it without invoking the bCheat parameter of ActionCastSpellAtObject() …

Note that child spells like Protection from Evil won’t auto-cast like that w/out bCheat.

 
will let you know but am not in a rush. In my playtesting right now, I only have Prot.Evil prepared … to get a reliable result will need a few other child-like spells active …

3 Likes