Zscriptifying the Stunner Rifle
- Gothic
- Topic Author
- Moderator
Less
More
- Posts: 1259
7 months 1 week ago - 2 months 3 weeks ago #1
by Gothic
Zscriptifying the Stunner Rifle was created by Gothic
There was a whole lot here about reworking the stunner rifle, but due to a bug with the forum software, deleting your attachments will leave your threads blanked. Oh well, the deed is done anyways.
Last edit: 2 months 3 weeks ago by Gothic.
The topic has been locked.
- DeVloek
- Arachnotron
Less
More
- Posts: 401
7 months 1 week ago - 7 months 1 week ago #2
by DeVloek
Replied by DeVloek on topic Zscriptifying the Stunner Rifle
Nice work! Finally this weapon has a purpose, it was pretty much useless before since it only worked on vanilla Doom monsters and nothing else, and probably didn't work at all when another mod also modified vanilla monsters.
Glancing over the code, one thing that comes to mind right now that I'd do is to get rid of the StunnerFX actor and spawn textured particles instead. Afaik even actors with the NOINTERACTION flag are more performance-costly than particles. I think that's because actors belong to the game logic so they are restricted to one CPU core, and particles don't so they are threaded, I could be wrong though. In any case, particles are less straining (how much depends on the count ofc), I heard from several modders who replaced non-interactive actors with particles and the performance went up.
Also I'd give stunned actors a dynamic light, the sparkly fx looks strange in a dark room.
edit: testing the gun on some custom monsters I noticed that the stun isn't refreshed when hitting the same monster again. So if you hit a monster that has been stunned for 299 tics, it will still wake up. Not sure if that's intended, I personally would change it so the duration is always refreshed with each consecutive hit. Maybe reduce the duration if that turns out to be too OP. Or better yet, reduce the duration based on the monster's hitpoints or pain chance or both. So it's easier to stun cannon fodder and harder to stun bosses. That's quite an overhaul of the original weapon mechanics though, but I'd be willing to help with that if it's something you wanna do.
Glancing over the code, one thing that comes to mind right now that I'd do is to get rid of the StunnerFX actor and spawn textured particles instead. Afaik even actors with the NOINTERACTION flag are more performance-costly than particles. I think that's because actors belong to the game logic so they are restricted to one CPU core, and particles don't so they are threaded, I could be wrong though. In any case, particles are less straining (how much depends on the count ofc), I heard from several modders who replaced non-interactive actors with particles and the performance went up.
Also I'd give stunned actors a dynamic light, the sparkly fx looks strange in a dark room.
edit: testing the gun on some custom monsters I noticed that the stun isn't refreshed when hitting the same monster again. So if you hit a monster that has been stunned for 299 tics, it will still wake up. Not sure if that's intended, I personally would change it so the duration is always refreshed with each consecutive hit. Maybe reduce the duration if that turns out to be too OP. Or better yet, reduce the duration based on the monster's hitpoints or pain chance or both. So it's easier to stun cannon fodder and harder to stun bosses. That's quite an overhaul of the original weapon mechanics though, but I'd be willing to help with that if it's something you wanna do.
Last edit: 7 months 1 week ago by DeVloek.
The topic has been locked.
- Gothic
- Topic Author
- Moderator
Less
More
- Posts: 1259
7 months 1 week ago #3
by Gothic
Replied by Gothic on topic Zscriptifying the Stunner Rifle
1
The topic has been locked.
- DeVloek
- Arachnotron
Less
More
- Posts: 401
7 months 1 week ago #4
by DeVloek
if you change it to
the game won't crash anymore.
I'm running out of time now but will take a more thorough look into dynamic stun duration later, shouldn't be too hard to make both health and painchance have an effect on the duration. My idea is to give every victim a basic stun duration of, say, 100 tics, and then add more based on how low their health and how high their painchance is, up to the original value of 300 tics. The values could be adjusted ofc.
Replied by DeVloek on topic Zscriptifying the Stunner Rifle
That is easily fixed by adding a nullcheck for the owner, something which you should always do first thing in the InitEffect(), DoEffect(), and EndEffect() overrides. The particular line that caused the crash wasI tried removing "!victim.CheckInventory("StunEffect",1)" but the game crashed.
Code:
owner.A_RemoveLight("StunLight");
Code:
if (owner) owner.A_RemoveLight("StunLight");
I don't think the flagcheck for NOPAIN is necessary at all anymore. Unless I'm missing something, it was only necessary for the original behavior since it relied on the pain state of a monster, which isn't the case anymore, so I removed it from the code entirely and it still works fine on the monsters I've been testing it with.I'd be up for adding a health check for monsters. I would ignore the pain chance, because monsters with "Painchance 0" or the +NOPAIN flag would be unaffected.
I'm running out of time now but will take a more thorough look into dynamic stun duration later, shouldn't be too hard to make both health and painchance have an effect on the duration. My idea is to give every victim a basic stun duration of, say, 100 tics, and then add more based on how low their health and how high their painchance is, up to the original value of 300 tics. The values could be adjusted ofc.
The topic has been locked.
- DeVloek
- Arachnotron
Less
More
- Posts: 401
7 months 1 week ago - 7 months 1 week ago #5
by DeVloek
Replied by DeVloek on topic Zscriptifying the Stunner Rifle
OK so I managed to dynamically change the stun duration based on the victim's health and painchance.
This is the formula:
effecttics is the field that is directly responsible for the powerup's duration.
healthfactor increases when the victim loses health (since the stun projectile deals damage, this value increases immediately and even multiple times because of the RIPPER flag).
painfactor increases when the painchance increases (so it usually stays the same for each victim unless some other mod changes it).
This means the higher the painchance and the lower the current hp compared to max hp, the longer the duration. The result is clamped between 35 and 350 tics (1-10 seconds), imo this is pretty much balanced.
So a freshly spawned Cyberdemon will be stunned for only 1s, while a Zombieman with already low hp will be stunned for the full 10 seconds.
I also added a debug message that prints all the values involved when the victim is hit, so you can adjust the calculation to your liking.
I tried to maintain your code indentation style, and I commented everything I changed/added. I also fixed a bug with negative state durations. I only found it because I tested the gun on a target dummy that just vanished when the stun effect was over. It shouldn't happen with normal monsters but you never know, hence this fix.
download:
https://drive.google.com/file/d/1UvTA-CkjnReChQ1ScsnE9CeriqjqhEf6/view?usp=sharing
This is the formula:
Code:
baseduration = 200;
maxhealth = owner.GetMaxHealth(true);
curhealth = owner.health;
healthfactor = maxhealth / curhealth;
painfactor = owner.painchance * 0.00390625;
effecttics = clamp(baseduration * healthfactor * painfactor,35,350);
healthfactor increases when the victim loses health (since the stun projectile deals damage, this value increases immediately and even multiple times because of the RIPPER flag).
painfactor increases when the painchance increases (so it usually stays the same for each victim unless some other mod changes it).
This means the higher the painchance and the lower the current hp compared to max hp, the longer the duration. The result is clamped between 35 and 350 tics (1-10 seconds), imo this is pretty much balanced.
So a freshly spawned Cyberdemon will be stunned for only 1s, while a Zombieman with already low hp will be stunned for the full 10 seconds.
I also added a debug message that prints all the values involved when the victim is hit, so you can adjust the calculation to your liking.
I tried to maintain your code indentation style, and I commented everything I changed/added. I also fixed a bug with negative state durations. I only found it because I tested the gun on a target dummy that just vanished when the stun effect was over. It shouldn't happen with normal monsters but you never know, hence this fix.
download:
https://drive.google.com/file/d/1UvTA-CkjnReChQ1ScsnE9CeriqjqhEf6/view?usp=sharing
Last edit: 7 months 1 week ago by DeVloek. Reason: moved all the edits into a new post with better formatting
The topic has been locked.
- DeVloek
- Arachnotron
Less
More
- Posts: 401
7 months 1 week ago - 7 months 1 week ago #6
by DeVloek
Replied by DeVloek on topic Zscriptifying the Stunner Rifle
I made so many edits to the previous post that i should better make a new one with proper formatting instead.
download:
https://drive.google.com/file/d/1UvTA-CkjnReChQ1ScsnE9CeriqjqhEf6/view?usp=sharing
edit: actually, a baseduration of 350 feels better for balance. This will always stun zombiemen for the full 10 seconds, cacodemons for ~5, barons for ~2, and cyberdemons still for 1 second. I also added
to not punish the player too much when they get stunned. If you disagree with any of those values feel free to adjust them, maybe adjust the clamp values or the painfactor [strike]multiplier[/strike] divider for further finetuning.
another edit: uploaded a small update that just cleans up the code a little bit. I moved the variable declarations directly into the effecttics calculation, they aren't needed anywhere else. I also added another variable to be able to divide the owner.painchance by 255 instead of multiplying by a very small number. Should make it easier to finetune this parameter too.
- Increased baseduration to 200, so Barons with a painchance of 50 are stunned for ~1 second and monsters with higher painchance are stunned longer. To stun a Cyberdemon (painchance 20) for longer than 1 second you'll have to wear him down until his health is low enough (in my tests it was ~1500 hp), and once he's on his last breath the stun duration increases drastically
- This works on the player too, you'll be unable to move for 200 tics at 100 hp and 100 tics at 200 hp. If this is too long or too short you could check for owner.player and adjust it.
- If you stun a chaingunguy while he is firing, he will be stuck with a muzzleflash and it looks like time froze. To avoid this I added the following lines to InitEffect();
Code:if (owner.FindState("pain")) owner.frame = owner.FindState("pain").frame; else if (owner.FindState("see")) owner.frame = owner.FindState("see").frame;
Maybe this could be finetuned to only happen if a monster is in its missile state, but many custom monsters have custom missile states that don't share the name, so I think this is the best solution for now. - Changed the attached light color to purple because I think that looks better on cacodemons
download:
https://drive.google.com/file/d/1UvTA-CkjnReChQ1ScsnE9CeriqjqhEf6/view?usp=sharing
edit: actually, a baseduration of 350 feels better for balance. This will always stun zombiemen for the full 10 seconds, cacodemons for ~5, barons for ~2, and cyberdemons still for 1 second. I also added
Code:
if (owner.player) effecttics *= 0.5;
another edit: uploaded a small update that just cleans up the code a little bit. I moved the variable declarations directly into the effecttics calculation, they aren't needed anywhere else. I also added another variable to be able to divide the owner.painchance by 255 instead of multiplying by a very small number. Should make it easier to finetune this parameter too.
Last edit: 7 months 1 week ago by DeVloek.
The topic has been locked.
- Gothic
- Topic Author
- Moderator
Less
More
- Posts: 1259
7 months 3 days ago #7
by Gothic
Replied by Gothic on topic Zscriptifying the Stunner Rifle
Nice job. Too bad it won't be as broken as it was in Stronghold (a powered up Stunner Rifle was the end to a Cyberdemon or a Terminator)
I'd say this is ready to go.
I'd say this is ready to go.
The topic has been locked.
- DeVloek
- Arachnotron
Less
More
- Posts: 401
7 months 3 days ago #8
by DeVloek
I don't see anything like that in the code so I assume powering it up is an exclusive thing to Stronghold? I never played it so I don't know how it works, but if you feel the gun should be more effective against big baddies we can surely figure something out.
Replied by DeVloek on topic Zscriptifying the Stunner Rifle
Too bad it won't be as broken as it was in Stronghold (a powered up Stunner Rifle was the end to a Cyberdemon or a Terminator)
I don't see anything like that in the code so I assume powering it up is an exclusive thing to Stronghold? I never played it so I don't know how it works, but if you feel the gun should be more effective against big baddies we can surely figure something out.
The topic has been locked.
- Gothic
- Topic Author
- Moderator
Less
More
- Posts: 1259
7 months 2 days ago #9
by Gothic
Replied by Gothic on topic Zscriptifying the Stunner Rifle
No worries, it's fine as it is now.
It has been updated. Hopefully nothing has been broken.
It has been updated. Hopefully nothing has been broken.
The topic has been locked.