Re: ZScript-only "How do I..." thread

Fri Jan 27, 2017 11:03 pm

Courtesy quote:

ZZYZX wrote:
Vaecrius wrote:Thanks!
(I assume "&&(players[i].mo)" would do the trick? Or do I need to add a !=null after the mo?)

Objects implicitly cast to bool like in C, yes.

Vaecrius wrote:What's the difference between the AddInventory and GiveInventory (and GiveAmmo) functions? Does Add bypass pickup states? Do the first two ignore skill-based ammo doubling?

AddInventory takes an Inventory object (possibly created using Spawn()).
GiveInventory takes a class name.


////////////////////////////////////////////////

ZZYZX wrote:Ok, minus two scripted calls and minus four native calls http://pastebin.com/pmfTPmAq, because 30x slower function call here means noticeably smaller FPS with large usage counts.


And here's ZZYZX's optimized version, tweaked to be blood-splat-friendly. For educational purposes and for anyone else reading this!

[ EDIT: Latest version is here -> viewtopic.php?f=3&t=55073&p=973732#p973732 ]

////////////////////////////////////////////////

NOW! I have an actual, new question.

I'm trying to make SetToSlope() a generic function that any actor can use, so that I don't have to copy/paste that code ten billion times. And no, I can't make a base class because not everything that will use SetToSlope is the same kind of thing - some of them are vehicles, some of them are blood splats/floor grunge, some of them are even monsters. They're all different kinds of things with a lot of different base classes.

I tried this:

Code:

class SetToSlope
{
    static void SetToSlope(void)
    {
        // code
    }
}

// trying it on a monster...
class Z_TestMonster : Z_MonsterBase
{
    override void Tick(void)
    {
        Super.Tick();
        SetToSlope.SetToSlope();
    }
}

// trying it on a blood splat...
class Z_BloodSplat : Z_BloodBase
{
    override void Tick(void)
    {
        Super.Tick();
        SetToSlope.SetToSlope();
    }
}
 


but it doesn't work!!!
Last edited by Nash on Sat Jan 28, 2017 12:06 am, edited 1 time in total.

Re: ZScript-only "How do I..." thread

Fri Jan 27, 2017 11:41 pm

How exactly it doesn't work?
You will have to provide a self pointer, like such:
Code:
class Lib
{
  static void SetToSlope(Actor self) { ... }
}

Oh, and replace CurSector with self.CurSector.

And then call it like
Code:
Lib.SetToSlope(self);
in the actor.
Although if you make this a unified function, I'd give it arguments dAng and pitchOffset externally. And call pitchOffset dPitch for readability. 'd' by itself meant diff, while 'f' means floor.

Re: ZScript-only "How do I..." thread

Fri Jan 27, 2017 11:53 pm

ZZYZX wrote:Solution


Works perfectly now, thanks! And I took your advice about the name of the variable, and also parameterizing them. Thanks a bunch!!!

Code:
//===========================================================================
//
// GENERIC PHYSICS CLASS
//
//===========================================================================

class Physics
{
    static void AlignToSlope(Actor self, double dAng, double dPitch)
    {
        vector3 fNormal = self.CurSector.FloorPlane.Normal;
        vector2 fNormalP1 = (fNormal.!= 0 || fNormal.!= 0) ? (fNormal.X, fNormal.Y).Unit() : (0, 0);
        vector2 fNormalP2 = ((fNormal.X, fNormal.Y).Length(), fNormal.Z);
        double fAng = atan2(fNormalP1.Y, fNormalP1.X); // floor angle (not pitch!)
        double fPitch = -atan2(fNormalP2.X, fNormalP2.Y); // floor pitch
        double dDiff1 = sin(fAng - (dAng + dPitch));
        double dDiff2 = cos(fAng - dAng);
        self.Pitch = fPitch * dDiff2 + dPitch;
        self.Roll = fPitch * dDiff1;
        self.Angle = dAng;
    }
}

class Z_BloodSpot : Z_BloodBase
{
    bool bSloped;

    override void Tick()
    {
        if (!bSloped)
        {
            Physics.AlignToSlope(self, self.Angle, 0.f);
            bSloped = true;
        }
        Super.Tick();
    }
}

 
Last edited by Nash on Sat Jan 28, 2017 12:07 am, edited 2 times in total.

Re: ZScript-only "How do I..." thread

Fri Jan 27, 2017 11:57 pm

So how do you... do that? I still don't understand what goes where and why and what "static" means and what can or cannot go into a thing that's "static".

Like, can you post a full example?

Re: ZScript-only "How do I..." thread

Fri Jan 27, 2017 11:59 pm

A static function is a function without a hidden "self" argument, that's pretty much it, in simple terms.
As a result, if you want a static function to perform actions on the caller, you must explicitly pass the caller to the function.

Re: ZScript-only "How do I..." thread

Sat Jan 28, 2017 12:04 am

So why doesn't this work?
Code:
class Lib{
   static void ShootMissile(actor self,class<Actor> ms="DoomImpBall",double ht=-1){
      if(ht<0) ht=self.height-12; //the real default
      actor prj=Spawn(ms,(pos.x,pos.y,pos.z+ht),ALLOW_REPLACE);
      prj.vel=vel;prj.angle=angle;prj.pitch=pitch;
      prj.target=self;prj.master=self;
      prj.vel+=(prj.speed*cos(pitch)*cos(angle),prj.speed*cos(pitch)*sin(angle),
         prj.speed*sin(-pitch));
   }
}
It gives "Call to unknown function 'Spawn'" and then an error message for all subsequent references to "prj".

Re: ZScript-only "How do I..." thread

Sat Jan 28, 2017 12:15 am

Spawn is a function of the Actor class. Your class, Lib, is not a descendant of Actor, so it has no direct access to Spawn. However, since Spawn is Static, you may call it as Actor.Spawn()

Re: ZScript-only "How do I..." thread

Sat Jan 28, 2017 1:59 am

Got it working, thanks!

EDIT: So like half the stuff I'm trying gets me "Cannot call non-static function Actor::_____ from here". How do I know whether a function is static?

Re: ZScript-only "How do I..." thread

Sat Jan 28, 2017 5:53 am

Generally you can check the contents of gzdoom.pk3/zscript/actor.txt and see if the function you're trying to use has the 'static' modifier.

Re: ZScript-only "How do I..." thread

Sat Jan 28, 2017 6:46 am

Very specific question: How do I make a bullet puff of a hitscan's weapon do something different depending on whether it hit a wall, or a ceiling/floor? Is there any mechanics built-in that can detect these situations?

Re: ZScript-only "How do I..." thread

Sat Jan 28, 2017 6:51 am

Nash wrote:Very specific question: How do I make a bullet puff of a hitscan's weapon do something different depending on whether it hit a wall, or a ceiling/floor? Is there any mechanics built-in that can detect these situations?

There's probably better ways to do it, but I'd use GetZAt or A_CheckSolidFooting on puff spawn to check if it's on the floor or ceiling.

Re: ZScript-only "How do I..." thread

Sat Jan 28, 2017 7:05 am

The Zombie Killer wrote:There's probably better ways to do it, but I'd use GetZAt or A_CheckSolidFooting on puff spawn to check if it's on the floor or ceiling.


Okay, this solves the condition filtering... now is there any way to get any information about the LINEDEF that the bullet attack hit? I'm hoping to retrieve the angle of the wall that the bullet just hit.

Re: ZScript-only "How do I..." thread

Sun Jan 29, 2017 1:51 am

Is it possible to use "target=" to set an actor's target? If not, what should I be using?

I'm trying to get this to work:
Code:
movetarget=spawn("idledummy",pos);

...[in between the movetarget is placed in a position flanking the target]...

//call A_Chase using the movetarget
targbak=target; target=movetarget;
A_Chase(null,null,CHF_NODIRECTIONTURN);
target=targbak;

Re: ZScript-only "How do I..." thread

Sun Jan 29, 2017 3:20 am

Post more code. That fragment does not tell us enough. A_Chase has some delay counters so doing this just once won't produce much of a result.

Re: ZScript-only "How do I..." thread

Sun Jan 29, 2017 3:54 am

Nash wrote:Okay, this solves the condition filtering... now is there any way to get any information about the LINEDEF that the bullet attack hit? I'm hoping to retrieve the angle of the wall that the bullet just hit.

Not yet AFAIK.
I guess you could fire a few hitscans in a "+" pattern from right behind the puff (with super tiny offsets) and calculate the angle between those to account for both slopes and wall angles.

Can't wait for it to be possible though, especially the possibility of retrieving the texture of the wall. I'll go into a frenzy of making F.E.A.R style particle effects if/when that becomes possible.