After taking a quick look, I'm seeing four ways you could do this.
You could patch e.g. the vending_trigger_post_think()
function, which is one the functions that will run when you purchase a perk, in _zm_perks.gsc
, but that would require some doing. You'd have to fix all the decompilation errors in that gsc and then recompile it. Could be pretty easy, but could also be that it's straight up missing some code and you'd have to fill it in yourself.
This approach would surely give you the most control, and you could customize anything and everything about it. If this happens to be one of those gscs that doesn't have terrible decompilation errors, this is a really good approach.
Another way, which already seems pretty good, would be changing the perks that are associated with the perk machine triggers. This way you wouldn't have to recompile the _zm_perks
gsc.
This is the beginning of the vending_trigger_think()
function, which is holds the logic for each perk machine's trigger.
vending_trigger_think()
{
self endon( "death" );
wait 0.01;
perk = self.script_noteworthy;
...
The function is owned by each perk machine's trigger, so self
is the trigger.
So what you could do is just change the value of trigger's script_noteworthy
.
Without doing any testing, I think it'd be done with just doing this:
(jugger to speedcola)
foreach (trigger in getentarray("zombie_vending", "targetname"))
if (trigger.script_noteworthy == "specialty_armorvest")
trigger.script_noteworthy = "specialty_fastreload";
Though, you'd need to get that to run before the init() in _zm_perks
, which might not be that easy.
But in that case, could of course just notify the desired trigger with a "death"
, and then restart the desired trigger's logic function (vending_trigger_think()
)
However, this approach would come with the downside(?) of your hud saying speed cola when you're standing next to the jugger machine. Basically the machine acts exactly like the speed cola machine.
And then the third approach I could quickly think of:
In the vending_trigger_post_think()
function, which is the function that runs after you make a perk purchase, there is a very helpful little line of code:
vending_trigger_post_think( player, perk )
{
player endon( "disconnect" );
player endon( "end_game" );
...
if ( isDefined( level.perk_bought_func ) )
{
player [[ level.perk_bought_func ]]( perk );
}
...
}
A globally defined function that runs after you buy (and finished drinking) the perk.
Now that's lucky.
Be very easy to add your own custom logic onto that function. And in your case, I guess your desired custom logic would be removing the purchased perk and replacing it with another perk.
And on top of that, you can add whatever else custom logic as well.
I'd consider this the best approach, since you won't have to deal with recompiling the _zm_perks
gsc, and you can basically still have a lot of control over what actually happens upon buying the perk by just removing it and then doing whatever.
The fourth way, is basically a duplicate of the above, with the downside of not having a direct way to tell what perk the player just bought.
Players are notified with a "burp"
(this occurs in the aforementioned vending_trigger_post_think()
function) upon finishing drinking a perk bottle. So could listen for that notification and then do the same as above, remove the perk that was just bought and replace it whatever else. You'd just have to create your own custom logic for determining that perk was just bought.
Most definitely not a bad approach, but I don't really see any reason to do this, since the previous approach I suggested just straight up passes the name of perk to the level.perk_bought_func
function.
So yeah, there most definitely are way more ways of doing this. This is just what I could see after taking a quick glance at the _zm_perks
gsc.
Though, I don't think it can get any better than using the globally defined level.perk_bought_func
function. At least for the usage you seem to be after.