DECORATE Weapon Questions

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.

DECORATE Weapon Questions

Postby Exosphere » Mon Dec 04, 2017 12:03 pm

Need a little help with a few weapon conundrums.

1. I have seen weapons in other mods (most notably Russian Overkill's Powercube weapon at least from what I remember) where the ammo recharges over time. However, I have been sort of lost on how to put it in code. Are there any clear examples that I look at to get a better understanding how this recharging works? Pretty much solved

2. One of the weapons for my mods I am planning on adding is a rifle that has the ability to fire three different projectiles and also being able to cycle through them. However, I would ideally like to have it so that the weapon uses three different kinds of ammo, one for each respective projectile. I am completely stumpted as how to make this a reality, both the cycling AND WHILE using three different ammo types; I do have some ideas, but I would really like to see if anyone has done this before and can clearly explain how to acheive this OR there are any clear and fairly simple examples I can look at.

Any help is appreciated.
Last edited by Exosphere on Mon Dec 11, 2017 1:22 pm, edited 2 times in total.
User avatar
Exosphere
 
Joined: 11 Jun 2017
Location: New England, US

Re: DECORATE Weapon Questions

Postby R4L » Mon Dec 04, 2017 11:21 pm

The way I picture your first question working, is a constant reload loop that gives 1 to a custom ammo type every few seconds. Your fire state would allow a shot when you have a certain amount of ammo recharged. You could even have it so you can fire weaker shots at certain recharged levels. For a weapon that acts similar to that, I'd look at wildweasel's Diaz mod (I'm always referencing this, but for obvious reasons!) for the Psionic Amp weapon. It constantly charges up while it's equipped.

For your second question, you might want to check out Lithium. The rifle has a "modal" upgrade that allows you to switch from full auto to burst, and then have a third mode that fires grenades IIRC. Also, Russian Overkill's Rasputin weapon seems to have three custom inventory items defined, each one for each different ammo mode, so there's also that...
User avatar
R4L
Ordinary Vanity
 
Joined: 03 Mar 2017
Discord: R4L#4655
Operating System: Windows 10/8.1/8 64-bit
Graphics Processor: ATI/AMD with Vulkan Support

Re: DECORATE Weapon Questions

Postby Exosphere » Tue Dec 05, 2017 3:30 am

Minor Breakthrough:

I decided to go with ACS for the mode changer instead of only DECORATE, and have been able to successfully change to the shotgun mode. However, once it is in Shotgun mode, it can't be changed to Rocket mode, and I have no idea why that is. Included is the "Cycler" ACS code as well as the switching portion of the weapon.

Code: Select allExpand view
#library "cyclr"
#include "zcommon.acs"

script "Cycler" (int mode)
{
   int init = 1;
   mode = init;
   
   if (CheckWeapon("OICW") == 1)
   {
      mode++;
      
      if(mode == init)
      {
         TakeInventory("RocketMode", 1);
         GiveInventory("RifleMode", 1);
         Log(s:"9.5x25mm Caseless Rifle Mode: ACTIVE.");
      }
      if(mode == 2)
      {
         TakeInventory("RifleMode", 1);
         GiveInventory("ShotgunMode", 1);
         Log(s:"10ga Shotgun Mode: ACTIVE.");
      }
      if(mode == 3)
      {
         TakeInventory("ShotgunMode", 1);
         GiveInventory("RocketMode", 1);
         Log(s:"20mm Smart Rocket Mode: ACTIVE.");
      }
      if(mode == 4)
      { mode = init; }
   }
}


Code: Select allExpand view
Fire:
         TNT1 A 0 A_JumpIfInventory("RifleMode", 1, "RifleFire")
         TNT1 A 0 A_JumpIfInventory("ShotgunMode", 1, "ShotgunFire")
         TNT1 A 0 A_JumpIfInventory("RocketMode", 1, "RocketFire")
         Goto Ready

AltFire:
         PLSG A 1 ACS_NamedExecute("Cycler", 0, 1, 0, 0)
         OICW A 1 A_Log("Mode Switched")
         Goto Ready


Anyone have any ideas/solutions on why this is partially working?
User avatar
Exosphere
 
Joined: 11 Jun 2017
Location: New England, US

Re: DECORATE Weapon Questions

Postby Apeirogon » Tue Dec 05, 2017 6:31 am

Exosphere wrote:Need a little help with a few weapon conundrums.

1. I have seen weapons in other mods (most notably Russian Overkill's Powercube weapon at least from what I remember) where the ammo recharges over time. However, I have been sort of lost on how to put it in code. Are there any clear examples that I look at to get a better understanding how this recharging works?

Code: Select allExpand view
actor constantlu_reloading_weapon:weapon
{
   Weapon.SelectionOrder 7980
   Weapon.KickBack 60
   Weapon.AmmoUse 1
   Scale 0.95
   Weapon.AmmoType "charging_cell"   
   Inventory.PickupMessage "What a cheater weapon I discover..."
   Obituary "%o was beat by %k's ace in the sleeve"
   +WEAPON.NOALERT
   States
   {
   Ready:
    DTRS ABCDE 1 a_weaponready
         tnt1 q 0 a_giveinventory("charging_cell",1)//give to you every tick that you hold it in hand and dont shoot one "charging_cell"
    Loop

   Deselect:
     DTEK A 1 A_Lower
   loop

   Select:
    TNT1 A 0 A_Raise
    Wait

   Fire:
     DTKF A 2 Bright A_FireCustomMissile("cheat_projectile",0,1,0,0,0,0)
    DTKF B 1 Bright A_Light2
     DTKF C 2 A_Light0
     TNT1 A 0 A_ReFire
     Goto Ready
 
   Spawn:
     DTEP A -1
     Stop
     }
}

Or look at russian overkill powercube. If you try look at it pillowbluster dont burst into your room, with madly rolling eyes and words "CLOSE SLADE, HANDS UP THAT I CAN SEE IT!!!"

Exosphere wrote:OR there are any clear and fairly simple examples I can look at.

TR_SturmmanM97 from the throoper.
Apeirogon
I have a strange sense of humour
 
Joined: 12 Jun 2017

Re: DECORATE Weapon Questions

Postby Exosphere » Tue Dec 05, 2017 9:05 pm

Thanks for the input Apeirogon. You didn't need to a full example weapon, all I really needed was this:

Code: Select allExpand view
Ready:
    DTRS ABCDE 1 a_weaponready
         tnt1 q 0 a_giveinventory("charging_cell",1)//give to you every tick that you hold it in hand and dont shoot one "charging_cell"
    Loop

But still, thank you anyway.

Apeirogon wrote:Or look at russian overkill powercube. If you try look at it pillowbluster dont burst into your room, with madly rolling eyes and words "CLOSE SLADE, HANDS UP THAT I CAN SEE IT!!!"


Don't worry, I'm not making a weapon that is identical to the PowerCube, I just needed to know how it recharged ammo.

(Still looking for any input from anyone on the issues with the ACS and DECORATE code I posted)
User avatar
Exosphere
 
Joined: 11 Jun 2017
Location: New England, US

Re: DECORATE Weapon Questions

Postby Apeirogon » Wed Dec 06, 2017 1:22 am

You ACS code can be easy implement in decorate.

Code: Select allExpand view
altfire:
sprite letter number
{
if (countinv("shotgun_mode")==1)
{
a_TakeInventory("shotgun_mode", 1);
a_GiveInventory("rocket_mode", 1);
A_Print(s:"20mm Smart Rocket Mode: ACTIVE.");
}

else if (countinv("rocket_mode")==1)
{
a_TakeInventory("rocket_mode", 1);
A_Print(s:"9.5x25mm Caseless Rifle Mode: ACTIVE.");
}

else if (countinv("shotgun_mode")==1 && countinv("rocket_mode")==1)
{
GiveInventory("ShotgunMode", 1);
A_Print(s:"10ga Shotgun Mode: ACTIVE.");
}
}
Apeirogon
I have a strange sense of humour
 
Joined: 12 Jun 2017

Re: DECORATE Weapon Questions

Postby Blitzky » Wed Dec 06, 2017 10:16 am

I'll admit my knowledge of ACS is a bit limited, but...

Your variable 'mode' only exists within your script.

Every time you call this script, it checks to see if the player is holding the correct weapon, then increments mode by 1.
However, every time the script is called, it also sets 'mode' to be equal to 'init', which is 1.

Essentially, you're calling a script that assigns mode to 1, then increments it to 2 every time, meaning it's constantly trying to switch from rifle mode to shotgun mode.
User avatar
Blitzky
Illi-Noying
 
Joined: 25 Jan 2011
Location: Chicagoland, Illinois
Discord: Blitzky#8213

Re: DECORATE Weapon Questions

Postby Exosphere » Wed Dec 06, 2017 11:56 am

Blitzky wrote:I'll admit my knowledge of ACS is a bit limited, but...

Your variable 'mode' only exists within your script.

Every time you call this script, it checks to see if the player is holding the correct weapon, then increments mode by 1.
However, every time the script is called, it also sets 'mode' to be equal to 'init', which is 1.

Essentially, you're calling a script that assigns mode to 1, then increments it to 2 every time, meaning it's constantly trying to switch from rifle mode to shotgun mode.


Interesting. I'm also not as knowledgable in ACS, but still willing to learn. Do you have any suggestions on fixes I could change to make it work?
User avatar
Exosphere
 
Joined: 11 Jun 2017
Location: New England, US

Re: DECORATE Weapon Questions

Postby Blitzky » Wed Dec 06, 2017 8:50 pm

Here's my 'analysis':
Code: Select allExpand view
DECORATE
Fire:
         TNT1 A 0 A_JumpIfInventory("RifleMode", 1, "RifleFire")
         TNT1 A 0 A_JumpIfInventory("ShotgunMode", 1, "ShotgunFire")
         TNT1 A 0 A_JumpIfInventory("RocketMode", 1, "RocketFire")
         Goto Ready

AltFire:
         PLSG A 1 ACS_NamedExecute("Cycler", 0, 1, 0, 0)  //Call 'Cycler' with a value of 1 for the first argument
         OICW A 1 A_Log("Mode Switched")
         Goto Ready
=========================================================
ACS
#library "cyclr"
#include "zcommon.acs"

script "Cycler" (int mode)   //Value of 1 is passed to 'mode' by the altfire state
{
   int init = 1;   //'init' is created and given a value of 1
   mode = init;   //'mode' is given the value of 'init'(1)
   
   if (CheckWeapon("OICW") == 1)  //Make sure the player is using the OICW
   {
      mode++;   //'mode' is incremented, now a value of 2
     
      if(mode == init)   //'mode' is 2, skip this part
      {
         TakeInventory("RocketMode", 1);
         GiveInventory("RifleMode", 1);
         Log(s:"9.5x25mm Caseless Rifle Mode: ACTIVE.");
      }
      if(mode == 2)   //'mode' is 2, execute this
      {
         TakeInventory("RifleMode", 1);
         GiveInventory("ShotgunMode", 1);
         Log(s:"10ga Shotgun Mode: ACTIVE.");
      }
      if(mode == 3)   //'mode' is 2, nothing beyond is executed
      {
         TakeInventory("ShotgunMode", 1);
         GiveInventory("RocketMode", 1);
         Log(s:"20mm Smart Rocket Mode: ACTIVE.");
      }
      if(mode == 4)
      { mode = init; }
   }
}

This is what I mentioned earlier. You defined 'mode' as an argument here, and pass it a value of 1 when altfire is used.
However, your script immediately gives it a value of 1 regardless by setting it equal to 'init'.
To remedy this without editing your script, you would need to write a few more lines in the altfire state that pass values of 1, 2, or 3, depending on which of the three dummy items the player is currently holding.
The 'init' value is redundant, as it is the same as giving mode a value of 1.

However, you can completely avoid the use of variables like this:
Code: Select allExpand view
#library "cyclr"
#include "zcommon.acs"
 
script "Cycler" (void)
{
   if (CheckWeapon("OICW") == 1) //Make sure the player is using the OICW
   {
      if(CheckInventory("RifleMode")) //Execute if the player has "RifleMode"
      {
         TakeInventory("RifleMode", 1);
         GiveInventory("ShotgunMode", 1);
         Log(s:"10ga Shotgun Mode: ACTIVE.");
      }
    
     else if(CheckInventory("ShotgunMode")) //Execute if the player has "ShotgunMode"
      {
         TakeInventory("ShotgunMode", 1);
         GiveInventory("RocketMode", 1);
         Log(s:"20mm Smart Rocket Mode: ACTIVE.");
      }
    
     else if(CheckInventory("RocketMode"))   //Execute if the player has "RocketMode"
      {
         TakeInventory("RocketMode", 1);
         GiveInventory("RifleMode", 1);
         Log(s:"9.5x25mm Caseless Rifle Mode: ACTIVE.");
      } 
   }
}
User avatar
Blitzky
Illi-Noying
 
Joined: 25 Jan 2011
Location: Chicagoland, Illinois
Discord: Blitzky#8213

Re: DECORATE Weapon Questions

Postby Exosphere » Fri Dec 08, 2017 12:29 pm

SIgnificant Update:

After some tinkering, and with a little help from Blitzky, I was able to successfully have it so that the weapon can switch between the rifle, shotgun, and rocket launcher without fail. Now with that complete, the final aspect for the weapon that I would want to have is the ability to reload at will or once the ammo from the magazine is depleated. (The gun will use infinite ammo.) However, with the method that I had implemented, it doesnt function properly, in that it doesnt reload (with all weapons) and stalls on the rocket mode after firing one rocket. (I will include the code snippets for people to look at, along with the ACS of the improved cycler.) Let me know if anything needs to be clairified.

ACS
Code: Select allExpand view
if (CheckWeapon("OICW") == 1)
   {
      if(CheckInventory("RocketMode")==1 && CheckInventory("RifleMode")==0)
      //If Rocket Mode is ACTIVE and RifleMode is INACTIVE
      {
         TakeInventory("RocketMode", 1);
         GiveInventory("RifleMode", 1);
         Print(s:"9.5x25mm Caseless Rifle Mode: ACTIVE.");
      }
      else if(CheckInventory("RifleMode")==1 && CheckInventory("ShotgunMode")==0)
      //If Rifle Mode is ACTIVE and Shotgun Mode is INACTIVE
      {
         TakeInventory("RifleMode", 1);
         GiveInventory("ShotgunMode", 1);
         Print(s:"10ga Shotgun Mode: ACTIVE.");
      }
      else if(CheckInventory("ShotgunMode")==1 && CheckInventory("RocketMode")==0)
      //If Shotgun Mode is ACTIVE and RocketMode is INACTIVE
      {
         TakeInventory("ShotgunMode", 1);
         GiveInventory("RocketMode", 1);
         Print(s:"20mm Smart Rocket Mode: ACTIVE.");
      }
   }


DECORATE
Code: Select allExpand view
ACTOR RifleMag : Ammo
{
   Inventory.MaxAmount 99
   +INVENTORY.PERSISTENTPOWER
   +INVENTORY.INVBAR
   +IGNORESKILL
}
//Magazine Example

Reload:
         TNT1 A 0 A_JumpIfInventory("RifleMag", 0, "RifleReload")
         etc
         Goto Ready
RifleReload:
         OICW A 1 A_GiveInventory("RifleMag", 99)
         Goto Ready
ShotgunReload:
         ~ (same syntax as above)
         Goto Ready
RocketReload:
         ~ (same syntax as above)
         Goto Ready
User avatar
Exosphere
 
Joined: 11 Jun 2017
Location: New England, US

Re: DECORATE Weapon Questions

Postby R4L » Fri Dec 08, 2017 3:16 pm

For reloading, you will want to do two ammo types for each mode. One type is your magazine count, the other is your reserve. In your Reload state you create a new looping state that adds 1 to your magazine and takes 1 from reserve if the weapon magazine is not full. If it is full, you go to your second reload state where you finish up the reload. Do a check in your Fire state for when there is no ammo, and jump to the Reload state.
User avatar
R4L
Ordinary Vanity
 
Joined: 03 Mar 2017
Discord: R4L#4655
Operating System: Windows 10/8.1/8 64-bit
Graphics Processor: ATI/AMD with Vulkan Support

Re: DECORATE Weapon Questions

Postby Exosphere » Sat Dec 09, 2017 2:58 pm

R4L wrote:For reloading, you will want to do two ammo types for each mode. One type is your magazine count, the other is your reserve. In your Reload state you create a new looping state that adds 1 to your magazine and takes 1 from reserve if the weapon magazine is not full. If it is full, you go to your second reload state where you finish up the reload. Do a check in your Fire state for when there is no ammo, and jump to the Reload state.


I gave it a shot, however I am pretty sure this isnt the method you are referring to. Here is the code.

Code: Select allExpand view
ACTOR RifleMagReserve : Ammo
{
   Inventory.MaxAmount 99
   +INVENTORY.PERSISTENTPOWER
   +INVENTORY.INVBAR
   +IGNORESKILL
}
ACTOR RifleMagCount : Ammo
{
   Inventory.Amount 99
   +IGNORESKILL
}

States
{
RifleFire:
         OICW A 2 A_FireCGun
         OICW A 1 A_TakeInventory("RifleMagCount", 1)
         OICW A 1 A_Refire
         OICW A 1 A_JumpIfNoAmmo("RifleReload")
         Goto Ready
RifleReload:
         OICW A 1 A_TakeInventory("RifleMagReserve", 1)
         OICW A 1 A_GiveInventory("RifleMagCount", 1)
         OICW A 1 A_JumpIfInventory("RifleMagCount", 99, "RifleReady")
         Loop
RifleReady:
         TNT1 A 0 A_PlaySound("weapons/shotgr", CHAN_AUTO, 50.0)
         OICW A 1 A_Print("Rifle Reloaded")
         Goto Ready
}


However, I am still encountering the problem of when the Rocket launcher is fired once, it can't be fired again and I cant switch to any other mode.

Anyone have any thoughts?
User avatar
Exosphere
 
Joined: 11 Jun 2017
Location: New England, US

Re: DECORATE Weapon Questions

Postby R4L » Sun Dec 10, 2017 1:50 pm

JumpIfNoAmmo should be the first thing in your fire state.

EDIT: Deleted most of my post because it was just plain incorrect. Looking at your new code for reloading, it seems that you have only defined how the rifle reloads, not the other two weapons.
User avatar
R4L
Ordinary Vanity
 
Joined: 03 Mar 2017
Discord: R4L#4655
Operating System: Windows 10/8.1/8 64-bit
Graphics Processor: ATI/AMD with Vulkan Support

Re: DECORATE Weapon Questions

Postby Exosphere » Mon Dec 11, 2017 1:20 pm

R4L wrote:JumpIfNoAmmo should be the first thing in your fire state.

EDIT: Deleted most of my post because it was just plain incorrect. Looking at your new code for reloading, it seems that you have only defined how the rifle reloads, not the other two weapons.


Its ok about deleting you post, dont worry about it. :) The other reloads are mostly the same, but I can the adding details on my own.

Anyway, another update. I was still experimenting with the decorate functions before trying out ACS again. Luckily, I was surprisingly able to make it work, to an extent. The weapon will still fires even if the ammo is empty in their corresponding magazines. The +AMMO_OPTIONAL flag isnt present in the weapon.

ACS
Code: Select allExpand view
script "Reloader" (void)
{
   if (CheckWeapon("OICW") == 1)
   {
      if(CheckInventory("RifleMode")==1)
      { GiveInventory("RifleMag", 25); Print(s:"Rifle Reloaded"); }
   }
}


DECORATE
Code: Select allExpand view
RifleFire:
         OICW A 1 A_JumpIfNoAmmo("Reload")
         OICW A 1 BRIGHT A_FireProjectile()
         OICW A 1 A_TakeInventory("RifleMag", 1)
         OICW A 1 A_Refire
         Goto Ready

Reload:
         OICW A 1 ACS_NamedExecute("Reloader", 0, 0, 0, 0)
         //play sound indicating weapon has been reloaded
         Goto Ready
Last edited by Exosphere on Mon Dec 11, 2017 4:12 pm, edited 1 time in total.
User avatar
Exosphere
 
Joined: 11 Jun 2017
Location: New England, US

Re: DECORATE Weapon Questions

Postby R4L » Mon Dec 11, 2017 3:27 pm

Wouldn't be because your script is named "reload" and your calling "reloader" in your Reload state, would it?
User avatar
R4L
Ordinary Vanity
 
Joined: 03 Mar 2017
Discord: R4L#4655
Operating System: Windows 10/8.1/8 64-bit
Graphics Processor: ATI/AMD with Vulkan Support

Next

Return to Scripting

Who is online

Users browsing this forum: No registered users and 1 guest