Page 1 of 1

How to call ACS_EXECUTE from a class instance in ZSCRIPT

Posted: Fri May 13, 2022 6:04 am
by peewee_RotA
Is there a version of ACS_EXECUTE in zscript that is called by a specific actor so they can be the activator?

A lot of ACS Script functions rely on identifying the activator. The ones that do not imply an activator will require a TID. In my case I need to call teleport on a player from Zscript to a teleport destination determined by another ACS script. It has to be a specific player, not all players in coop, and the player doesn't have a tid. I have a pointer to the player actor in zscript, but the related event I am calling it from is on a monster (and its projectile). In this case, a DoSpecialDamage.

What I'd like to do is just call a specific script number set by the args1 property (this is readable as args[0] in zscript) when the monster causes damage. I let the script number be set like this, instead of hardcoded, so the feature is more flexible. This way I can have 2 or more of the same monster that call different scripts on these events.

I know that I can call ACS_EXECUTE from zscript with other monsters I've tested. I also know that the script number in the argument is working. This is the first case where I am using the action Teleport which requires that the activator be the thing that teleports.

So far I've found that ACS_ScriptCall is a function on an actor that properly sets the activator. The problem is that this uses a named function. That means I can't set the script number like normal, requiring it to be hardcoded to a specific string. I'm also unclear if named scripts in ACS have the same limitations as named functions in ACS. Either way, it would be very helpful if I could call scripts in this way by number.

Here's the ZSCRIPT code I have using the ACS_ScriptCall functionality

Code: Select all

const HARDCODED_SCRIPT_NAME = "NamedScriptName";
class TeleMonster : MyBaseMonster
{
    void DoScriptCall(Actor targetActor)
    {
        targetActor.ACS_ScriptCall(HARDCODED_SCRIPT_NAME);
    }

    override int DoSpecialDamage(Actor target, int damage, name damagetype) //Call script from melee damage
    {
        A_PrintBold("Damaged! 111");
        let playerObj = PlayerPawn(target);
        if (damage > 0 && playerObj && playerObj.health > 0)
        {
            A_PrintBold("Damaged!");
            DoScriptCall(playerObj);
        }

        return damage;
    }
}

class TeleProjectile : MyBaseProjectile
{
    Default
    {
        Radius 13;
        Height 8;
        Speed 15;
        Damage 2;
    }

    void DoScriptCall(Actor targetActor)
    {
        targetActor.ACS_ScriptCall(HARDCODED_SCRIPT_NAME);
    }

    override int DoSpecialDamage(Actor target, int damage, name damagetype) // Call script from projectile damage
    {
        let playerObj = PlayerPawn(target);
        if (damage > 0 && playerObj && playerObj.health > 0)
        {
            DoScriptCall(playerObj);
        }

        return damage;
    }
}

Re: How to call ACS_EXECUTE from a class instance in ZSCRIPT

Posted: Fri May 13, 2022 6:08 am
by peewee_RotA
Here's the ZSCRIPT code I use to call ACS_EXCECUTE from monsters when the activator doesn't matter. In this case it activates when the monster is hit.

Code: Select all

const SCRIPT_NUM_DRAGON = 212;
class ScriptDragon : Dragon
{
    Default
    {
        +NOTELEOTHER
    }
    override int TakeSpecialDamage(Actor inflictor, Actor source, int damage, Name damagetype)
    {
        let playerObj = PlayerPawn(source);
        if (damage > 0 && playerObj && playerObj.health > 0)
        {
            int scriptNum = Args[0];
            if (scriptNum == 0)
                scriptNum = SCRIPT_NUM_DRAGON;
           
            ACS_Execute(scriptNum);
        }

        return damage;
    }
}