need help with first Zscript weapon

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.

need help with first Zscript weapon

Postby vAethor » Thu Feb 15, 2018 7:32 pm

This was actually in a previous topic, but I must've replied too late because it seems to be dead.

Anyways, I took a look at Caligari87's tranquility.pk3 to see how he made a weapon with multiple moving parts as overlays, now I'm trying something like that. My custom weapon's a basic assault rifle with an added ammo counter like in Halo or Aliens that counts down to zero as you shoot bullets. I already made crappy placeholder graphics for the gun, the counter and the spent casings and started a new PK3, but I'm sorta at a loss as to where to go next.

Here's what I got so far:
https://drive.google.com/file/d/1tW2GYVs7NjvUCBQdlo-OLAp62A5PkuHq/view?usp=sharing

I currently have my zscript lump with the following code so far:

Code: Select allExpand view
// Crappy gun test with ammo counter (Halo-style)
// Created:  02/14/2018
// Modified: 02/14/2018

// - THE GUN -------------------------------------------------------------------
class CounterGun : pistol
{
   Default {
   Weapon.SlotNumber 2;
   }
   
   States {
   Spawn:
      CGUN A -1;
      Loop;
   }
}


Currently it doesn't do much - pressing the slot for it just causes the player pull out another instance of the regular pistol. But this is as far as I've gotten so far, as I am a complete beginner at Zscript and had trouble making sense of Caligari's code.

I wish there were more Zscript tutorials so I could learn more on my own without asking these dumb questions.
vAethor
 
Joined: 10 May 2017

Re: need help with first Zscript weapon

Postby Matt » Thu Feb 15, 2018 8:12 pm

It wasn't intended to be a general ZScript weapon tutorial, but this reloading pistol might be a start.
User avatar
Matt
Putting the XD into *xdeath since 2007
 
Joined: 04 Jan 2004
Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia

Re: need help with first Zscript weapon

Postby vAethor » Fri Feb 16, 2018 12:55 am

Matt wrote:It wasn't intended to be a general ZScript weapon tutorial, but this reloading pistol might be a start.


Hmm, I'm studying your code and doing research on the wiki along the way. I tried executing what I've got so far but I got the cryptic error "Unexpected integer constant, Expecting '-' or '+' or ';' or identifier or '}' for line 32 of my code

Code: Select allExpand view
      // More actor flags
      +weapon.ammo_optional   +weapon.alt_ammo_optional
      +weapon.ammouse1 0;      +weapon.ammouse2 0;

This was copied directly from yours. I checked all the curly brackets to make sure nothing's unclosed, everything checks out as far as I know.

What exactly am I doing wrong here? I need to fix this before I can go on. Forgive me for being such a newcomer, but again if Zscript were as widely used as DECORATE and ACS this would be a lot easier for me.

Here's my complete code if you want to see it:
Code: Select allExpand view
// Crappy gun test with ammo counter (Halo-style)
// Created:  02/14/2018
// Modified: 02/15/2018

/* Code loosely based on Matt's reloading pistol script and Caligari's multi-
   overlay gun thing. */


const GUN_MAXAMMO = 35; // The maximum number of bullets the gun can carry


// THE GUN
class CounterGun : pistol replaces pistol
{
   Default
   {
      Weapon.SlotNumber 2;
      +rollsprite +rollcenter /* NOTE TO MYSELF: Looking up these actor
                           flags on the Zdoom Wiki to see what they
                           mean (for future reference.)
                        
                           +rollsprite rotates the sprite (GL only?)
                           +rollcenter centers the point at which the
                             sprite rotates */
                        
      +weapon.noalert /* Just copying from Matt's code here...he says this
                     is for firing the gun empty, making sure it doesn't
                     alert enemies when fired with no ammo. */
                  
      // More actor flags
      +weapon.ammo_optional   +weapon.alt_ammo_optional
      +weapon.ammouse1 0;      +weapon.ammouse2 0;
      /* */
   
   }
   
   States
   {
      nope: // Generic state (no ammo, not loaded, etc.)
      ---- A 1 A_WeaponReady(WRF_NOFIRE);
      goto ready;
      
      ready:
      CGUN A 1 A_WeaponReady(WRF_ALLOWRELOAD | WRF_ALLOWZOOM);
      wait;
      
      fire:
      CGUN A 4
      {
         if (invoker.loaded < 1) {
            player.setpsprite (PSP_WEAPON, invoker.findstate("nope"));
         }
      }
   }
   
}


The answer is probably something extremely obvious, but in the meantime maybe I should dust off my old C++ book and refresh my memory on actual coding, not just scripting.
vAethor
 
Joined: 10 May 2017

Re: need help with first Zscript weapon

Postby Blue Shadow » Fri Feb 16, 2018 1:38 am

vAethor wrote:
Code: Select allExpand view
      // More actor flags
      +weapon.ammo_optional   +weapon.alt_ammo_optional
      +weapon.ammouse1 0;      +weapon.ammouse2 0;

Weapon.AmmoUse1 and Weapon.AmmoUse2 are properties, not flags, thus they shouldn't be prefixed with a '+'.
User avatar
Blue Shadow
 
Joined: 14 Nov 2010
Operating System: Windows 10/8.1/8/201x 64-bit
OS Test Version: No (Using Stable Public Version)
Graphics Processor: ATI/AMD (Modern GZDoom)

Re: need help with first Zscript weapon

Postby vAethor » Fri Feb 16, 2018 2:47 am

Blue Shadow wrote:
vAethor wrote:
Code: Select allExpand view
      // More actor flags
      +weapon.ammo_optional   +weapon.alt_ammo_optional
      +weapon.ammouse1 0;      +weapon.ammouse2 0;

Weapon.AmmoUse1 and Weapon.AmmoUse2 are properties, not flags, thus they shouldn't be prefixed with a '+'.


Thanks man, that did something.

I got a couple more errors saying certain actor properties in the code I copied from weren't valid, and I had to comment out the code for the Fire state since it didn't recognize more things, but I did get my gun to show up in the game when I test-ran and hit IDKFA:

Image

I added the following code in the fire state:

Code: Select allExpand view
---- A 1 A_PlaySound ("GunShot");
      CGUN ABCD 1;
      goto ready;


and now it shoots too! But it doesn't kill anything yet.

I'm just still reverse-engineering others' code at this point. I take it ---- is Zscript's version of TNT1?
vAethor
 
Joined: 10 May 2017

Re: need help with first Zscript weapon

Postby Blue Shadow » Fri Feb 16, 2018 10:12 am

vAethor wrote:I got a couple more errors saying certain actor properties in the code I copied from weren't valid, and I had to comment out the code for the Fire state since it didn't recognize more things

I can't see in the code anything that would be considered an unknown or invalid actor property. For the Fire state, however, it's probably the 'loaded' variable that is causing the error, and that's because it's not declared in the weapon.

I take it ---- is Zscript's version of TNT1?

Not really.
User avatar
Blue Shadow
 
Joined: 14 Nov 2010
Operating System: Windows 10/8.1/8/201x 64-bit
OS Test Version: No (Using Stable Public Version)
Graphics Processor: ATI/AMD (Modern GZDoom)

Re: need help with first Zscript weapon

Postby vAethor » Fri Feb 16, 2018 1:30 pm

Blue Shadow wrote:I can't see in the code anything that would be considered an unknown or invalid actor property.
For the Fire state, however, it's probably the 'loaded' variable that is causing the error, and that's because it's not declared in the weapon.


Oh my bad. it was weapon.alt_ammo_optional that was commented out because GZdoom thought it was an actor property. I somehow didn't have the + next to it. I put it back since I remembered it's actually a flag, not a property. Now it runs just fine.

I just added Int loaded; at the very beginning of the class definition, now it runs perfectly. Well, except the gun doesn't animate and it still looks buggy since the equipping and putting away animations revert back to the vanilla Pistol, but it does play the firing sound as I have added a placeholder A_PlaySound() function at the beginning of the Fire state. It's a placeholder since I am guessing there is a more elegant way of doing this within Zscript, but this is what I know works from my experience with DECORATE.

I take it ---- is Zscript's version of TNT1?

Not really.


Oh yeah, I just looked it up, it means "keep previous sprite." Derp.

Anyways, I noticed something odd through trial and error. Commenting out the more complicated firing code that was in Matt's source I am still studying, and instead using simpler DECORATE-style placeholder code like this:
Code: Select allExpand view
fire:
      ---- A 1 A_PlaySound ("GunShot"); /* Placeholder code for playing the
                                  firing sound, probably a more
                                  elegant way of doing this in
                                  Zscript. */
      CGUN ABCD 1;
      goto ready;
      
      //CGUN A 1
      //{
         //if (invoker.loaded < 1)
         //{
            //player.setpsprite (PSP_WEAPON, invoker.findstate("nope"));
         //} // if statement end
      //} // loop end

The gun actually animates in addition to playing the sound, albeit somewhat slowly (it's about as fast as the vanilla Chaingun I'm guessing.)

But going with the original more advanced code has different results:
Code: Select allExpand view
fire:
      ---- A 1 A_PlaySound ("GunShot"); /* Placeholder code for playing the
                                  firing sound, probably a more
                                  elegant way of doing this in
                                  Zscript. */
      //CGUN ABCD 1;
      //goto ready;
      
      CGUN A 1
      {
         if (invoker.loaded < 1)
         {
            player.setpsprite (PSP_WEAPON, invoker.findstate("nope"));
         } // if statement end
      } // loop end

The gun doesn't animate (yet, because I haven't actually put in the code for animation...I'm planning on handling that in a function instead and just calling that function here) but it does play the firing sound, and by listening to it the rate of fire is almost twice as fast. I also notice the gun is stationary when firing standing still, but jitters about randomly while bobbing if shooting while moving around.

I'm guessing it's faster now since it cycles through the loop much faster now as it doesn't pause a tic to animate each frame on the CGUN ABCD 1 line. Am I right?
vAethor
 
Joined: 10 May 2017

Re: need help with first Zscript weapon

Postby Matt » Fri Feb 16, 2018 5:50 pm

A_PlaySound is indeed what you should be using to play the sound. Remember to specify the channel, though.

(Just as a side note: don't get too caught up in trying to find "more elegant" ZScript alternatives if you aren't specifically trying to avoid a specific thing that is assumed or ignored by a known "DECORATE" action function. Generally that function, calling more native code to do what it does, will be more optimized anyway - I've been going back to a lot of my earlier ZScript "xxx=spawn... xxx.angle=... xxx.master=..." etc. codeblocks lately and replacing them with A_SpawnItemEx.)

That said...

The gun doesn't animate (yet, because I haven't actually put in the code for animation...I'm planning on handling that in a function instead and just calling that function here) but it does play the firing sound, and by listening to it the rate of fire is almost twice as fast. I also notice the gun is stationary when firing standing still, but jitters about randomly while bobbing if shooting while moving around.

I'm guessing it's faster now since it cycles through the loop much faster now as it doesn't pause a tic to animate each frame on the CGUN ABCD 1 line. Am I right?
Yes to your last question.

Here's what your first block of code does:
1. Play sound "gunshot" on the default channel
2. Run through one frame of whatever was last used, taking 1 tic
3. Run through frames CGUNA0 through CGUND0, each taking 1 tic
4. Go back to the ready state
Total time: 5 tics per shot

Here's what your second block does:
1. Play sound "gunshot" on the default channel
2. Run through one frame of whatever was last used, taking 1 tic
3. Check to see if the weapon's "loaded" variable is below 1; if it is, go to the ready state; if not, continue to 4
4. Run through frame CGUNA0, taking 1 tic
5. Continue to whatever is below that quoted section
Total time: 2 tics per shot


My example in that post does not include the Select and Deselect states. They are found on the wiki's DECORATE version of the pistol actor - just add "();" after A_Raise/A_Lower, and put in a number inside those parentheses if you want the lower/raise to be faster or slower (bigger numbers are faster and the default is 6).

(It might be worthwhile to click on some of those links on that example code as well - everything you see there will work in ZScript, it's just a matter of formatting a few optional extras.)
User avatar
Matt
Putting the XD into *xdeath since 2007
 
Joined: 04 Jan 2004
Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia

Re: need help with first Zscript weapon

Postby vAethor » Fri Feb 16, 2018 8:01 pm

Matt wrote:A_PlaySound is indeed what you should be using to play the sound. Remember to specify the channel, though.

(Just as a side note: don't get too caught up in trying to find "more elegant" ZScript alternatives if you aren't specifically trying to avoid a specific thing that is assumed or ignored by a known "DECORATE" action function. Generally that function, calling more native code to do what it does, will be more optimized anyway - I've been going back to a lot of my earlier ZScript "xxx=spawn... xxx.angle=... xxx.master=..." etc. codeblocks lately and replacing them with A_SpawnItemEx.)


Way ahead of ya :D . While I was waiting for new replies I did a little research on some of the flags, properties and functions you used as well as learning more about DECORATE ones I already know. I also was dissatisfied with my placeholder sprites so I went into Clip Studio, rendered what I have so far of my unfinished final version and added a muzzle flash, and now it looks much better:
ImageImage

Will eventually have to either switch it back to the placeholder or work on animating this version's ammo counter separately though, because the '35' is currently a completely static part of the sprite, no overlays yet.

Now I know Zdoom (GZdoom in my case) has eight channels, so I thought to assign the gunshot sound to CHAN_WEAPON.

Now I did try a little experiment that currently failed and made me have to comment out the code, but my thought was to layer in a motor sound under the automatic gun fire (because in my fictional universe this gun uses an electromechanical bolt and ejection assembly.) I added another A_PlaySound one tic before to loop the sound "cgun_motorloop") but it ended up cancelling all the sounds when I added A_StopSound to end the motor loop when it goes back to Ready.

Code: Select allExpand view
ready:
      // Now A_WeaponReady allows reload and zoom (self-explanitory I guess)
      CGN2 A 1 A_WeaponReady(WRF_ALLOWRELOAD | WRF_ALLOWZOOM);
      //---- A 1 A_StopSound (CHAN_5);
      wait;

      select:
      CGN2 A 1 A_Raise(9);
      Loop;
      
      deselect:
      CGN2 A 1 A_Lower(8);
      Loop;

      fire:
           /* Placeholder code for playing the firing sound, probably a more
               elegant way of doing this in Zscript. */
      //---- A 2 A_PlaySound ("cgun_motorloop", CHAN_5,      1, true) ;
      ---- A 1 A_PlaySound ("cgun_shoot",    CHAN_WEAPON, 1, false);
      CGN2 BDC 1;
      goto ready;
      
      //CGUN A 1
      //{
      /* 'invoker' is what we use to refer to the weapon. If we don't use
         it Zdoom assumes we're referring to the player instead. */
         //if (invoker.loaded < 1)
         //{
            // Go to the abort (nope) state if no ammo is loaded
            //player.setpsprite (PSP_WEAPON, invoker.findstate("nope"));
            /* PSP_WEAPON is the sprite layer which refers to the actual
               weapon. PSP_X refers to a set of internal layers used by the
               engine (according to the Zdoom Wiki,) and is used with
               A_OVERLAY.
               
               I need to ask someone what 'setpsprite' is and does...it's
               not showing up in any search on the wiki. */
               
         //} // if statement end
      //} // loop end
   } // states definition end


Also just for the record, I think I pretty much understand the gist of your code I currently have commented out, except for the 'setpsprite' function. I looked it up on the Wiki as it says in my comment and it turned up nothing.

And here is my PK3 so far:
You do not have the required permissions to view the files attached to this post.
vAethor
 
Joined: 10 May 2017

Re: need help with first Zscript weapon

Postby Matt » Mon Feb 19, 2018 1:51 pm

SetPSprite sets a sprite state for an overlay - in more user-friendly terms, this is like setstate for your weapon and weaponflashes instead of your actor sprite (PLAYA1, etc.).
User avatar
Matt
Putting the XD into *xdeath since 2007
 
Joined: 04 Jan 2004
Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia

Re: need help with first Zscript weapon

Postby vAethor » Mon Feb 19, 2018 5:36 pm

Matt wrote:SetPSprite sets a sprite state for an overlay - in more user-friendly terms, this is like setstate for your weapon and weaponflashes instead of your actor sprite (PLAYA1, etc.).


Hmm okay, I think I get it. I notice your code points to the "nope" state as the second argument for setpsprite(), and that PSP_WEAPON is just the base gun sprite to apply the overlays to (I think.)

Hmm, now I got an idea. Since you say it sets the sprite state, I just got an idea for my ammo counter. Would it work if I get it to point to a function I write that animates and handles the ammo countdown and checks to see if there are still bullets in the clip? Either that or a state just for the counter, but I don't think that will work since as far as I know states apply to the whole weapon actor, not just a single overlay.

Here's some pseudocode for my idea:

Code: Select allExpand view
const GUN_MAXAMMO = 35;
int bullets;

states:
{
fire:
if (ammo loaded < 1)
{
player.setpsprite (PSP_WEAPON, go back to "nope" state);
}
else if
{
play sound (gunshot);
shoot a bullet;
countBullets(); // see below for my attempt to define this function

animation stuff;
more animation stuff;

goto ready;

// counter function
void countBullets()
{

// Not super-familiar with arrays, or even if Zscript can do them, but it's the only way I can think of to dynamically animate the counter
string frames [36] = {all the frames of the counter in here};

int currentBullets = GUN_MAXAMMO - bullets; // I think I did something wrong here

For (i = 0; i < currentBullets; i++)
{
CNT1 frames[something in here, not sure] 1;
bullets = bullets - 1;
}
}



Please current my logic if you can, I think I may be way off but I hope you get my idea.
vAethor
 
Joined: 10 May 2017

Re: need help with first Zscript weapon

Postby Matt » Mon Feb 19, 2018 7:45 pm

Keep in mind that any single ZScript function has to execute everything all at once, so to spread something out over a bunch of tics you'll need to use states.
User avatar
Matt
Putting the XD into *xdeath since 2007
 
Joined: 04 Jan 2004
Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia

Re: need help with first Zscript weapon

Postby vAethor » Mon Feb 19, 2018 8:49 pm

Matt wrote:Keep in mind that any single ZScript function has to execute everything all at once, so to spread something out over a bunch of tics you'll need to use states.


Hmm, please explain. So maybe instead of using a function I create a state for the counter code instead?

Okay, what if I have the counter code execute in a state called counter, which as soon as it's done it checks to see if there are still bullets, and if there are it goes back to the firing state, but if there aren't it goes to the nope state?
vAethor
 
Joined: 10 May 2017

Re: need help with first Zscript weapon

Postby Matt » Tue Feb 20, 2018 2:12 pm

That should work.

What you had in your previous post looked like you were trying to play a couple frames within the script itself.
User avatar
Matt
Putting the XD into *xdeath since 2007
 
Joined: 04 Jan 2004
Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia

Re: need help with first Zscript weapon

Postby vAethor » Fri Feb 23, 2018 7:35 pm

Hey, I confess I don't know as much about this as I first thought. I think my logic is good but my syntax isn't. I'm also extremely busy with work and other things and aren't replying until now.

I tried writing my char (ABCD-etc.) array in C++ for practice but even then I forgot the basic syntax as I hadn't even touched genuine non-game programming for almost five years and am quite rusty.

I am discouraged, and am hoping this thread isn't dead since I haven't replied in over three days.

I think the most I can do is get the most I can out of the Zscript code I'm already studying until you reply again, and maybe try and split both things that I want to do (ammo counting and making a gun with multiple overlays) into two separate projects until I have them both down.
vAethor
 
Joined: 10 May 2017

Next

Return to Scripting

Who is online

Users browsing this forum: No registered users and 3 guests