Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
  • 0
ArrivedHero

ZScript: The Elephant In The Room

Question

ZScript has proven to do absolute wonders. Currently, I am learning C# and that has helped me out so far as I have been about to create void functions, functions with parameters, virtual and a few custom actor properties. (Still trying to wrap my head around actor flags though; I assume they are like simple bools). I got data types down as well as arrays (does zscript do lists and dictionaries as well?). I started with converting my custom monsters from decorate to zscript as to clean up their codes so it they aren't a jumbled mess of frames and {} blocks. But I have attempted to convert weapons over and I keep getting an error "incompatible self pointer", which seems to be a common error people are getting for zscript weapons. What exactly is causing this and how do you do it right?

 

Below is my own sample code for a custom melee attack for the player.

 

class Knuckles : Fist Replaces Fist
{

States
{
    Fire:
    PUNG B 4;
    PUNG C 4;
    PUNG D 5 {invoker.A_PlayerPunch();} //I included the "invoker" because I read that it is

                                                            //need from another forum. However, the function will
                                                            //print but the player can't land a punch.
    PUNG C 4;
    PUNG B 5 A_ReFire;
    Goto Ready;
}

void A_PlayerPunch()
{
    A_PrintBold("Test");

    if(Owner && Owner is "MaleMarine")
    {        
        if(countinv("PowerStrength"))
        {
            A_CustomPunch(2*random(1, 10), true, 0, "MeleePuff", 0, 0, 0, "none", "player/male/fist", "skeleton/swing");
        }
        else
        {
            A_CustomPunch(4*random(1, 10), false, 0, "MeleePuff", 0, 0, 0, "none", "player/male/fist", "skeleton/swing");
        }
    }
    else
    {
        if(!countinv("PowerStrength"))
        {
            A_CustomPunch(random(1, 10), true, 0, "MeleePuff", 0, 0, 0, "none", "player/male/fist", "skeleton/swing");
        }
        else
        {
            A_CustomPunch(2*random(5, 15), false, 0, "MeleePuff", 0, 0, 0, "none", "player/male/fist", "skeleton/swing");
        }
    }
}
}

Share this post


Link to post

15 answers to this question

Recommended Posts

  • 2

don't call the action with invoker. and append "action" to the action itself. ie

action void A_PlayerPunch()

 

Then you'll have to change the Owner references to invoker.Owner, otherwise it could try to access the Owner property of the player, which doesn't exist.

 

Share this post


Link to post
  • 1
3 hours ago, ArrivedHero said:

Thank you SaladBadger! It works now! Though now I have to ask, why do I need to append "action" to the void function?

weapons are an odd beast. In the original doom, the way the codepointers are defined made it so that any typical codepointers would be called on the bearer of the gun, not on the gun itself (which in the original doom didn't even exist as a object in the world when you picked it up), and weapon codepointers instead had to use a different field, analogous to "invoker" in order to actually access the weapon-y things. ZDoom makes things a little weirder by giving all weapons a "body" in the world, usually placed at 0,0,0 and hidden away from view when you pick up the weapon. action in this context, I believe, flags to zscript that "this is an action that should be performed on the gun in your hands" and not "this is something that should be done to the weapon's ghost body in the world"

Share this post


Link to post
  • 1

eh? they should be public by default, really. Don't forget, the variable Owner is of type PlayerPawn, so you can only see what variables are available to PlayerPawn, so if you add more in your custom class, they won't be seen. You need to cast as needed, ie

let customOwner = MyCoolPlayerClass(Owner);

customOwner.coolVar = 12;

Share this post


Link to post
  • 0
1 hour ago, ArrivedHero said:

 if(Owner && Owner is "MaleMarine")

Since I make stuff for Zandronum, I don't know ZScript.  Is "is" an actual ZScript operator?  Maybe that should be == for comparison (not = for assignment).

Share this post


Link to post
  • 0

I would use zscript but so far I just haven't had any situation where decorate hasn't worked just fine. It also doesn't help that where as decorate is extremely well documented zscript has barely any proper documentation that I am aware of.

Share this post


Link to post
  • 0
3 hours ago, SaladBadger said:

don't call the action with invoker. and append "action" to the action itself. ie

 


action void A_PlayerPunch()

 

 

Then you'll have to change the Owner references to invoker.Owner, otherwise it could try to access the Owner property of the player, which doesn't exist.

 

Thank you SaladBadger! It works now! Though now I have to ask, why do I need to append "action" to the void function?

Share this post


Link to post
  • 0

To answer previous questions, Empyre asked if "is" is an operator. Yes it is, you are correct in your assumption that it is similar to the "==" operand.  Partly the reason I am using ZScript is because I feel like it is a lot neater and two is because I am currently learning a programming language and I want to push myself. In all fairness, there is some documentation for ZScript but it is not so friendly to people using it for the first time and you do need some prior knowledge to understand it.

 

Here is the new code:

(Please follow example if you need help ;)

 

class NewKnuckles : Fist
{

States
{
    Fire:
    PUNG B 4;
    PUNG C 4;
    PUNG D 5 A_PlayerPunch;
    PUNG C 4;
    PUNG B 5 A_ReFire;
    Goto Ready;
}
    
action void A_PlayerPunch()
{
    A_PrintBold("Test");

    if(invoker.Owner && invoker.Owner is "MaleMarine")
    {        
        if(countinv("PowerStrength"))
        {
            A_CustomPunch(2*random(1, 10), true, 0, "MeleePuff", 0, 0, 0, "none", "player/male/fist", "skeleton/swing");
        }
        else
        {
            A_CustomPunch(4*random(1, 10), false, 0, "MeleePuff", 0, 0, 0, "none", "player/male/fist", "skeleton/swing");
        }
    }
    else
    {
        if(!countinv("PowerStrength"))
        {
            A_CustomPunch(random(1, 10), true, 0, "MeleePuff", 0, 0, 0, "none", "player/male/fist", "skeleton/swing");
        }
        else
        {
            A_CustomPunch(2*random(5, 15), false, 0, "MeleePuff", 0, 0, 0, "none", "player/male/fist", "skeleton/swing");
        }
    }
}
}

 

Lastly, I did promise a demo for ladders, so I should get on that.

Share this post


Link to post
  • 0

Ok, so I am trying not to make too many threads and keep them under the same categories.

 

My next question is concerning class variables, I understand the difference between private and public variables but I see that they can only be private for ZScript. I was wondering if there was any way, say a weapon class was able to read a variable of its owner. Or, am I stuck with declaring global variables with Event Handlers?

Share this post


Link to post
  • 0
1 hour ago, ArrivedHero said:

Ok, is this a Java thing or just one of the many quirks of ZScript?

you'll see it in pretty much any of these OOP languages. Try this C#:

 


    public class Class1
    {
        public int var1;
    }
    public class Class2 : Class1
    {
        public int var2;
    }
    public class Class3
    {
        public void testFunc()
        {
            Class1 test = new Class2();
            test.var2 = 1;

            //^Will not compile!
        }
    }

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×