[ZScript] Persistently (un)loaded individual guns

Handy guides on how to do things, written by users for users.

Moderators: GZDoom Developers, Raze Developers

Forum rules
Please don't start threads here asking for help. This forum is not for requesting guides, only for posting them. If you need help, the Editing forum is for you.
Post Reply
User avatar
Matt
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
Contact:

[ZScript] Persistently (un)loaded individual guns

Post by Matt »

Here's a neat magic trick:
1. Load up a weapon mod that features reloading.
2. Empty your gun and then drop it.
3. Pick up another gun of the same kind.
4. Make sure your new gun is fully loaded.
5. Drop the new gun and pick up the old one again.
6. Your old, emptied gun is now magically fully loaded.

This is usually unnoticeable in a typical mod where there's no reason to drop a weapon once you have it, but it can totally break a mod where a weapon's inherent properties can change with use - wear and tear, experience levels, ammo capacity, etc. and you might well be expected to swap out different guns of the same kind depending on need and circumstances.

To get around this without ZScript, you'd need to have a convoluted series of steps in the gun's spawn state that looks for the nearest player and forcibly extracts all the player's loaded-ammo inventory items, then replaces itself with a custominventory item that on pickup will restore the exact same numbers of those items for the player picking it up (which itself was a lot more complicated before A_SetInventory was a thing). This leads to all sorts of other weird side effects and edge cases where you'd have to worry about replacing the real weapon actor, the custominventory respawning properly in multiplayer, etc. which creates dozens of lines of additional code just to support this already edge case. Here and here are examples of the simplest and the most complicated such pickup actors one might expect, keeping in mind these particular actors represent only part of the required code.

In ZScript, you can get around all of this by making your loaded ammo counter a variable within the weapon itself. That way, you can drop it and pick it back up anytime thereafter, however many other weapons of the same kind you've reloaded, and it will have exactly the same amount of ammo it had when you dropped it (unless another player has picked it up and messed with it.)

With all that in mind, let's create a very basic reloadable pistol. I won't bother this time with a step-by-step evolution - hopefully the comments will make things clear enough.
Spoiler:
Now this works, but we've got 2 issues:
1. The amount in the gun does not show up on your HUD.
2. Dropping and picking up pistols to loot is really tedious.

For issue 1, we can either redo the HUD entirely, or create a dummy ammo item.
Spoiler:
and add the following frame to Fire, Reload, Select and Zoom:

Code: Select all

        PIST # 0 A_SetInventory("relpistmagtracker",invoker.loaded);          
and the following to the defaults:

Code: Select all

        weapon.ammotype1 "relpistmagtracker";
        weapon.ammotype2 "Clip";
        weapon.ammogive1 0; // to keep pistols from being wasted uselessly          

For issue 2, we can add the following Touch() override, by sticking this into the weapon actor definition, which basically replicates the unload function but drops a clip instead of adding it to your inventory:
Spoiler:

(Obviously all this can apply to any tracked variable you want to follow a particular weapon, besides loaded ammo: you can track wear and tear, whether it has a certain attachment installed (grenade launcher, full shotgun choke, sawed-off barrel, bayonet, scope, night sights, flashlight), any settings (semi, full-auto, zoom level etc.), whether a certain part is broken, even a custom paint job specific to each team. You can even track the original owner who brought the weapon to the map (if any) and implement a sci-fi biometric security system (yes you can use that rocket launcher but you'll be using the zombie's hand to pull the trigger so accuracy might be affected) - [wiki=ZScript_variables]any variable that can be defined for an actor can be exploited[/wiki].)
Post Reply

Return to “Tutorials”