Weapon Juggling - An Easier Way?

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!
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!)
User avatar
NeoTerraNova
Posts: 153
Joined: Tue Mar 14, 2017 5:18 pm
Location: Western North Southlandia (East Side)

Weapon Juggling - An Easier Way?

Post by NeoTerraNova »

Greetings, all, and thanks again for reading.

I'm looking to do something fairly complex, but I'm hoping I can do it in a fairly easy way. In my current project, I aim to have (eventually) three factions in the combat area (UAC private military, Marines, and a third faction), each with their own lists of weapons. To that end, I want it to be possible for the Player to swap weapons on-the-fly, while keeping them limited to a fairly small amount of arms - both to prevent them having to carry so many weapons as to be hard-to-manage, and to instill an atmosphere of survival. So, my questions are these:

-Is there an easy way, in DECORATE, to limit the number of weapons a player can carry? Either by limiting the number of weapons that can go in each slot, or limiting the inventory as a whole?
-Is there a way - easy or not - to either calculate the remaining ammo in a weapon's magazine and have it dump loose ammo on the ground (individual rounds or a partial magazine) when dropping the weapon?
-How would I go about doing these in a fairly simple manner?

I'm familiar with Wild Weasel's magop.wad, and somewhat familiar with a few others with similar concepts, but the code seems very complex, and I'm hoping there's a simpler way to go about it. Thank you, all, for your time.
User avatar
hideousdestructor
Posts: 9696
Joined: Sun Jan 04, 2004 5:37 pm
Preferred Pronouns: They/Them
Operating System Version (Optional): Debian Bullseye
Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia

Re: Weapon Juggling - An Easier Way?

Post by hideousdestructor »

in DECORATE
Does this need to run in Zandronum?
User avatar
NeoTerraNova
Posts: 153
Joined: Tue Mar 14, 2017 5:18 pm
Location: Western North Southlandia (East Side)

Re: Weapon Juggling - An Easier Way?

Post by NeoTerraNova »

No, I'm using GZDoom. I don't know very much about ACS and ZScript, though - I understand DECORATE better. If it has to be ACS or ZScript, that's fine, I can accept that, but if it can be done in DECORATE, I'd understand what I'm trying to do a bit better.
User avatar
hideousdestructor
Posts: 9696
Joined: Sun Jan 04, 2004 5:37 pm
Preferred Pronouns: They/Them
Operating System Version (Optional): Debian Bullseye
Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia

Re: Weapon Juggling - An Easier Way?

Post by hideousdestructor »

It doesn't have to be, but the DECORATE option will have a bit more spaghetti to deal with.

I'll post later tonight with an explanation of the difference.
User avatar
NeoTerraNova
Posts: 153
Joined: Tue Mar 14, 2017 5:18 pm
Location: Western North Southlandia (East Side)

Re: Weapon Juggling - An Easier Way?

Post by NeoTerraNova »

Much appreciated!
User avatar
hideousdestructor
Posts: 9696
Joined: Sun Jan 04, 2004 5:37 pm
Preferred Pronouns: They/Them
Operating System Version (Optional): Debian Bullseye
Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia

Re: Weapon Juggling - An Easier Way?

Post by hideousdestructor »

In ZScript you could create the following script that counts how many weapons the calling actor has:

Code: Select all

class LimitPickupWeapon : Weapon
{
    static int WeaponCount(actor caller)
    {
        int wepcount=0;
        for(inventory wepcheck=caller.inv; wepcheck!=null; wepcheck=wepcheck.inv)
        {
            if(wepcheck is "Weapon") wepcount++;
        }
        return wepcount;
    }
} 
Then in your weapon you can call that script when the weapon is Touch()ed so that it aborts if the player already has, say, 3 weapons:

Code: Select all

class LimitPickupWeapon : Weapon
{
    //...count function omitted...
    override void Touch(actor toucher)
    {
        if(LimitPickupWeapon.WeaponCount(toucher) < 3) super.Touch(toucher);
    }
} 
Here's a simple working example. Pick up a chaingun, then try to pick up a shotgun, fail because you've already got fist+pistol+chaingun (but if you pick up the shotgun first the chaingun's fine because it doesn't check for this):

Code: Select all

class LimitPickupShotgun : Shotgun replaces Shotgun
{
    static int WeaponCount(actor caller)
    {
        int wepcount=0;
        for(inventory wepcheck=caller.inv; wepcheck!=null; wepcheck=wepcheck.inv)
        {
            if(wepcheck is "Weapon") wepcount++;
        }
        return wepcount;
    }
    override void Touch(actor toucher)
    {
        if(LimitPickupShotgun.WeaponCount(toucher) < 3) super.Touch(toucher);
    }
} 

In DECORATE without ZScript, I won't type out all the code for it but you'll need to set up an inventory item to count the weapons and then do the following for each affected weapon:

- in the weapon's Spawn state, have it A_SpawnItemEx its CustomInventory replacement and disappear.
- in that custominventory replacement's Pickup state, use A_SetInventory to reset that counter item, then go through every possible affected weapon and subtract 1 if the player has it, then call A_JumpIfInventory to fail or give the player the corresponding weapon as appropriate.

Example:

Code: Select all

actor RoomForWeapon:Inventory{inventory.maxamount 3}
//...
    pickup:
        TNT1 A 0{
            A_SetInventory("RoomForWeapon",3);
            if(countinv("YourReplacementShotgun") > 0) A_TakeInventory("RoomForWeapon",1);
            if(countinv("YourReplacementRifle") > 0) A_TakeInventory("RoomForWeapon",1);
            ...
        }
        TNT1 A 0 A_JumpIfInventory("RoomForWeapon",1,"actualpickup")
        fail
    actualpickup:
        TNT1 A 0 A_JumpIf(countinv("YourReplacementRifle")<1,1)
        fail
        TNT1 A 0 A_GiveInventory("YourReplacementRifle")
        stop
I strongly recommend using creating a base actor that all the other weapon replacement pickups inherit from so that you only need to maintain that checklist once.

(The other option, which is a bit more self-contained but messier-looking and only useful if you are limiting to a single primary, is to set up each weapon so that it calls A_DropInventory in its select state to drop every weapon that isn't itself.)
User avatar
NeoTerraNova
Posts: 153
Joined: Tue Mar 14, 2017 5:18 pm
Location: Western North Southlandia (East Side)

Re: Weapon Juggling - An Easier Way?

Post by NeoTerraNova »

Wow, this is amazing. Thank you. When I have more time, I'll see what I can do with all this wonderful information. Thank you so much! (Of course, you will be credited)

Return to “Scripting”