ZScript Discussion

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!

Moderator: GZDoom Developers

Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.

Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
D2JK
Posts: 543
Joined: Sat Aug 30, 2014 8:21 am

Re: ZScript Discussion

Post by D2JK »

Is it possible to retrieve the player's current maximum health, when it has been modified in ACS using SetActorProperty and APROP_SPAWNHEALTH?

I'd like to avoid creating an intermediate inventory item to keep track of it, if possible.

Edit:

I forgot to mention: SpawnHealth() and GetSpawnHealth() won't work, as they keep returning "100" (the original max health before the modifications).
Blue Shadow
Posts: 4962
Joined: Sun Nov 14, 2010 12:59 am

Re: ZScript Discussion

Post by Blue Shadow »

Didn't this help?
D2JK
Posts: 543
Joined: Sat Aug 30, 2014 8:21 am

Re: ZScript Discussion

Post by D2JK »

Ah, right... I forgot I had already asked. Well, the thing is that I don't understand casting (my intention is to call this function from a weapon, not from the player class). Can you explain how to do that?
Blue Shadow
Posts: 4962
Joined: Sun Nov 14, 2010 12:59 am

Re: ZScript Discussion

Post by Blue Shadow »

To do that, cast 'self' to 'PlayerPawn':

Code: Select all

let p = PlayerPawn(self); 
Then check for the validity of the cast by doing a null pointer check on 'p'.


Here is a working example:

Code: Select all

class RL : RocketLauncher
{
    Default
    {
        Weapon.SlotNumber 0;
    }

    States
    {
    Fire:
        MISG B 8 A_GunFlash;
        MISG B 12
        { // Fire a BFG ball if health is above max, otherwise fire a rocket.
            let p = PlayerPawn(self);

            if(p != null && health > p.GetMaxHealth())
            {
                A_FireCustomMissile("BFGBall");
            }
            else
            {
                A_FireCustomMissile("Rocket");
            }
        }
        MISG B 0 A_ReFire;
        Goto Ready;
    }
} 
D2JK
Posts: 543
Joined: Sat Aug 30, 2014 8:21 am

Re: ZScript Discussion

Post by D2JK »

Many thanks! Now I get it.

By the way, in that if - check, is it possible for p to ever equal to null, in a case like this?
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49098
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: ZScript Discussion

Post by Graf Zahl »

Currently not but you should always check anyway.
User avatar
Major Cooke
Posts: 8190
Joined: Sun Jan 28, 2007 3:55 pm
Preferred Pronouns: He/Him
Location: QZDoom Maintenance Team

Re: ZScript Discussion

Post by Major Cooke »

Can something like this be done?

Code: Select all

// "MyActor" has an int variable PL.
Actor t = Spawn("MyActor",pos);

let s = t;

if (s)
{
    s.PL = 1;
}
Because this doesn't work. PL isn't recognized.

I ask because I have an array of Class<Actor>s to determine randomly which actor to spawn, and I haven't found a working solution to auto-resolve the class fully without requiring yet another cast to be around it.

Something tells me I need the list of actors to inherit from someone with the variable...
User avatar
Nash
 
 
Posts: 17452
Joined: Mon Oct 27, 2003 12:07 am
Location: Kuala Lumpur, Malaysia

Re: ZScript Discussion

Post by Nash »

How much of ZScript will be overhauled in the short term? I just got done learning how to use the various macros used to export stuff to ZScript for my custom native fields and functions (for my standalone game) but if they're going to change soon, I think I should just hold back from working any further...
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49098
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: ZScript Discussion

Post by Graf Zahl »

Major Cooke wrote: Because this doesn't work. PL isn't recognized.
Of course not. If you need a common variable for a set of actors they need to inherit from a common base class and the variable needs to be of the base class's type. 'let s = t;' will give s the same type as t, not the type of the actual object t points to. That cannot be done at compile time.
User avatar
ZZYZX
 
 
Posts: 1384
Joined: Sun Oct 14, 2012 1:43 am
Location: Ukraine

Re: ZScript Discussion

Post by ZZYZX »

Note: question to Graf, Cooke as the 2nd best ZScript expert already said he doesn't know.

This article http://zdoom.org/wiki/ZScript_variables
Claims that single-quoted strings are something called "names".

Code: Select all

const con4 = 'A name it is.'; //name
How do I define a char then?
For example I'd want to write my own int parsing function (for whatever, this is just a theoretical example). I'd want to get integer value of char '0' and subtract it from chars provided these chars are between 0 and 9.
I also once had a random coloring function that basically appended a \c escape sequence plus Random('A', 'V') on top of it.
How do I do this in ZScript?
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49098
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: ZScript Discussion

Post by Graf Zahl »

At the moment you can't. The constant parser as it is now is too limited for that - this is still the original as Randi implemented it and it's suffering from several limitations. Eventually this will have to be redone using the compiler backend to resolve the expressions but this is going to be a bit of work.
User avatar
Nash
 
 
Posts: 17452
Joined: Mon Oct 27, 2003 12:07 am
Location: Kuala Lumpur, Malaysia

Re: ZScript Discussion

Post by Nash »

I have a problem.

I want a bunch of new variables that I've made to be accessible by EVERYTHING - monsters AND players included. "extend class Actor" is not possible.

I could probably create ie

Code: Select all

class Z_Actor : Actor
{
    int customVar;
}
And have my monsters inherit Z_Actor instead of Actor. But that will only work for monsters.

What about players? I want my PlayerPawns to have access to customVar too.

The ONLY way I see of doing this is to now make a copy:

Code: Select all

class Z_PlayerPawn : PlayerPawn
{
    int customVar;
}
... what this means is that I now have to define the variables twice, one for every generic actor, and one more for the players. This is really clumsy. And I plan to add MANY variables. It will become tedious.

My goal is to just declare (lots) of new variables that EVERY actor class could use.

It would've worked if only "extend class Actor" was supported but well, it doesn't.

Help?
ZzZombo
Posts: 315
Joined: Mon Jul 16, 2012 2:02 am

Re: ZScript Discussion

Post by ZzZombo »

Yeah, I've asked already why we can't extend/override existing definitions, but got no reply.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49098
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: ZScript Discussion

Post by Graf Zahl »

You can't extend Actor by new variables because they cannot propagate to already derived subclasses. If you wanted to add a custom variable, *ALL* subclasses of Actor would need to have it, even those which have already been created and where other variables are already occupying the same slot. And for native subclasses this is not solvable at all.

It's also highly non-trivial on the implementation side because those added variables couldn't be regular members of the object, they'd have to be stored elsewhere with very costly access methods.
ZzZombo
Posts: 315
Joined: Mon Jul 16, 2012 2:02 am

Re: ZScript Discussion

Post by ZzZombo »

But does this hold for functions? So you could override, say, AActor::Die().

Return to “Scripting”