Closed mikota closed 1 year ago
no offense to anyone, but personally i was never a fan of the randomness of the weapons - i suspect a lot of players found it to be annoying
the way randomness is currently isn't too bad, but i, for one, am certainly not in favor of amplifying it further and would instead lean toward reducing it
perhaps more reasoning on my part is warranted...
when valve got their hands on cs they dumbed it down in an attempt to level the playing field, part of that being increasing bullet randomness, and this pissed off a lot of users to the point where, years later, they apparently reduced/reverted some of the changes
IMHO, going in the same general direction as valve with FreeCS regarding randomness is a potential mistake
personally, i'm not a fan of bullet randomness at all - no matter what the gun is or what the player is doing (running/jumping/falling/etc.) i would prefer if the bullets land wherever the crosshair does
just my $0.2 :)
The Nuclide changes can be migrated to cstrike
by implementing Physics_InputPreMove
into the player class there and calling the super function (super::Physics_InputPreMove
) so that you don't have to implement the entire thing, then doing the punchangle *= [...]
modifications there. That way the change can be kept only to CS and not affecting the other games.
I do think, judging by the video you'd posted on Matrix, that it appears closer to the shooting in CS than my attempt. Good job! I think @atomGit has a point regarding randomness and we can try to work around some of that (or it can always be turned into a cvar... we can indeed have both things).
or it can always be turned into a cvar
ah, yeah - i like that idea!
that should suit everyone, especially if randomness could be selected on a scale from 0-10 or whatever
The Nuclide changes can be migrated to
cstrike
by implementingPhysics_InputPreMove
into the player class there and calling the super function (super::Physics_InputPreMove
) so that you don't have to implement the entire thing, then doing thepunchangle *= [...]
modifications there. That way the change can be kept only to CS and not affecting the other games.
Thank you I will try to figure it out.
As far as @atomGit 's accuracy concerns, it's a complicated issue. The first problem comes from the fact that we don't have shared terminology about the way it works, and so it's hard to talk about it..
For example, Beta 1.0 of Counter-Strike is the most random of all the versions in many ways. Even while standing still with the M4 or the USP, your bullets will fly way outside your crosshair (usually called first shot accuracy). If you spam the USP they fly even more (usually called firing inaccuracy spread), and when continuously firing the M4, it gets incredibly ridiculous (bullets go farther if you're standing still than if you run and gun the same weapon in CS 1.6), and the iconic CS recoil pattern is not there yet.
In Beta 4.0, a lot of that firing inaccuracy spread was gone, but many weapons still retained the wacky first shot accuracy where you can't hit the broad side of a barn even with your first shot. As well as that, the base recoil now works the way it does in CS 1.6, and the way it works in the current version of my changes - the recoil has a base strength for each automatic weapon, and it gets amplified during the early to mid part of the spray and winds down towards the end. As well as that, the weapon randomly switches horizontal direction - as it does in 1.6 and my current version (I'd call this recoil direction randomness).
To top it off, there is some movement spread inaccuracy (bullets flying in a random radius after recoil is calculated) in Beta 4.0, but I'm not sure exactly how it works. What I am sure of though, is that there is also movement recoil inaccuracy (recoil gets stronger and recoil variance gets stronger the more you move), and it's pretty strong.
In Beta 6.0, there is again differences. Firing inaccuracy spread seems to have come back, though weaker, and then there's this, and then there's that...
Point is, there was never a point where bullets would just go where your crosshair is in CS, unless there's some secret Beta -36.2b I'm not aware of. Each version had it's own systems, and each new version seems to have, alongside adding new ones, kept the old ones but with tweaked values. The later versions, post beta, are very complex. If you really wanted to, you could create for example Beta 4.0 behavior in this commit's system by setting float divisor
in Cstrike_CalculateAccuracy
to a very high value (to remove the firing inaccuracy spread) and adding a big constant to the return value, such as 0.05f
(to add the ridiculously bad first shot accuracy). You could also remove the recoil going above the crosshair altogether, but then you're not playing any version of CS (maybe it's RQ3, maybe it's Urban Terror?)
With that said, I'm not a hater of weakening the randomness. The goal here was to create something close to original Counter-Strike, but even with that, my changes are still less random than 1.6, in some cases by a lot, and I'm down to lower it further in certain cases (and it's not my project anyway - this should be @eukara 's decision). I'll try to create cvar(s?) that control the amount of random stuff, but what does that even mean (one cvar to control all randomness, or separate cvar for firing inaccuracy spread, seperate for firing inaccuracy recoil variance, separate for first shot accuracy multiplier, separate for base recoil strength, separate for recoil above crosshair multiplier, separate for etc etc etc...)?
I'll try to figure it out and welcome suggestions on how exactly to do it, but I definitely don't think a recreation of CS should disable all the randomness and recoil, because then you're not playing CS.
hi again @mikota
... but what does that even mean (one cvar to control all randomness, or separate cvar for firing inaccuracy spread, seperate for firing inaccuracy recoil variance, separate for first shot accuracy multiplier, separate for base recoil strength, separate for recoil above crosshair multiplier, separate for etc etc etc...)?
i'm admittedly out of my league here, but perhaps a KISS approach would be good enough where randomness in all conditions could be scaled with a single cvar??? i assume that would keep everything proportional
assuming that's not too difficult, i'd still propose that the lowest value be 0 - no, or minimal randomness - and the default value be... whatever
I trust your judgment @mikota. I know coming from games like ProMode/CPMA that there's demand for a mode that involves little randomness (or some predictable patterns at the least, which is what I attempted with exception to shotguns obviously).
I didn't have much confidence in my ability to recreate the spray patterns/recoil to the degree that you did, so I tried to at least make something that played okay - striking the balance between pleasing players that look for a challenge while being 'close enough' to everyone else who's only casually played CS.
So I'm not bullish about my implementation and I'm very happy that you contributed this here :)
hi again @mikota
... but what does that even mean (one cvar to control all randomness, or separate cvar for firing inaccuracy spread, seperate for firing inaccuracy recoil variance, separate for first shot accuracy multiplier, separate for base recoil strength, separate for recoil above crosshair multiplier, separate for etc etc etc...)?
i'm admittedly out of my league here, but perhaps a KISS approach would be good enough where randomness in all conditions could be scaled with a single cvar??? i assume that would keep everything proportional
assuming that's not too difficult, i'd still propose that the lowest value be 0 - no, or minimal randomness - and the default value be... whatever
There's multiple types of choices randomness goes through, some of it is very much desired. One example is the direction a bullet/punch may fly. For example it may choose to go left, or go right relative to the player camera. If you turned off randomness in the left/right scenario, it'll only ever go into one direction.
Vertically, as everyone knows it will generally go up (by the amount specified by the 'shot multiplier', and gradually get lower when not firing).
So what one could do is take the 'shot multiplier' into account when choosing the direction. This isn't random but generally might feel so to the players that don't pay much attention.
Of course, we can add various scalers to all the different aspects of firing - which I am not against entirely as people will have an easier time tweaking the game to their liking. It just needs to be thoroughly documented so people have an idea of what they're exactly changing.
I manually upped some of the SMG values to make them more accurate.
I also added these cvars:
guns_recoil_strength
: controls how strongly recoil is applied to guns (through cs_shotmultiplier
) and how strongly gun recoil affects view punch (punchangle
via g_CstrikeBulletRecoil.Apply
)guns_movement_inaccuracy
: controls how much moving affects your random bullet spread (via Cstrike_CalculateAccuracy()
) and recoil strength/varianceguns_firing_inaccuracy
: controls how much spread and recoil variance is applied to your bullets the longer you shootguns_random_recoil_direction
: controls if recoil direction can change by chanceThis is as simple as I could make it, I think. If you set all of these to zero, automatic rifles will basically behave like a quake MG (except more accurate).
Default values for all of these are 1. I tried to do a dummy recoil pattern for when guns_random_recoil_direction
is set to zero as @eukara mentioned but it's not perfect yet.
The Nuclide changes can be migrated to
cstrike
by implementingPhysics_InputPreMove
into the player class there and calling the super function (super::Physics_InputPreMove
) so that you don't have to implement the entire thing, then doing thepunchangle *= [...]
modifications there. That way the change can be kept only to CS and not affecting the other games.
This still needs to be done. And I'm also getting errors in the console about writing to a read only variable in CstrikeBulletRecoil
class.
As far as what the default values for the new cvars should be, I'd personally let them stay at 1, as it's closest to feeling like Counter-Strike to me. Obviously, the values could be lowered up to zero if you want more quake-style gameplay. If you want the shooting to feel like Counter-Strike but still be able to jump around and spray all over the place, halving the value of guns_movement_inaccuracy
and guns_firing_inaccuracy
is a possible change. If you decide to lower the recoil, I recommed you don't set guns_recoil_strength
to anything less than 0.8
, as the effect that cvar has on the recoil is very drastic even with small increments/changes.
The error is probably about you writing into your m_flRandomSpread
when the class it belongs to was never instanced. You can have classes in QC that are basically just namespaces, but if you want to write into class specific attributes you have to allocate them as an object.
One simple, quick and dirty fix is (if you want m_flRandomSpread to be a global that applies to weapon operations for all clients) to check for a global variable of that class, see if it is NULL or world and if so, to instance it. For example in any of the methods:
if (!g_cstrikeBulletRecoil)
g_cstrikeBulletRecoil = spawn(CstrikeBulletRecoil);
/* now we have a valid instance to write into */
g_cstrikeBulletRecoil.m_flRandomSpread = [...]
Of course, if you want these to be player specific, the code would have to be different (allocating an instance per player, within the player.qc code). But that's why the code is not running as expected.
The error is probably about you writing into your
m_flRandomSpread
when the class it belongs to was never instanced. You can have classes in QC that are basically just namespaces, but if you want to write into class specific attributes you have to allocate them as an object.One simple, quick and dirty fix is (if you want m_flRandomSpread to be a global that applies to weapon operations for all clients) to check for a global variable of that class, see if it is NULL or world and if so, to instance it. For example in any of the methods:
if (!g_cstrikeBulletRecoil) g_cstrikeBulletRecoil = spawn(CstrikeBulletRecoil); /* now we have a valid instance to write into */ g_cstrikeBulletRecoil.m_flRandomSpread = [...]
Of course, if you want these to be player specific, the code would have to be different (allocating an instance per player, within the player.qc code). But that's why the code is not running as expected.
I decided to remove that part of the code as it was unnecessary anyway. This final commit brings the punchangle stuff into the cstrike codebase, as well as small tweaks to the recoil system.
Looks all good. Thank you very much for this rework effort!
@mikota - how does one make use of these new autocvar_fcs_guns_*
cvars? it seems they're not recognized when entering them in the console and i'd like to add them to server.cfg
@mikota - how does one make use of these new
autocvar_fcs_guns_*
cvars? it seems they're not recognized when entering them in the console and i'd like to add them to server.cfg
They're all prefixed with fcs_guns_
. For example, fcs_guns_movement_inaccuracy 0.1
should make running and gunning a lot more viable if that's what you prefer. They work on my machine, but I have an old build atm so something might've gotten borked in the meantime.
The changes to the gunplay this rework entails are shown off in this video
This is a rework of the recoil system in FreeCS. The hope is to bring it closer to the original feel of Counter-Strike. There are numerous changes to the system:
g_CstrikeBulletRecoil.ApplyPre(player pl, float strength)
andg_CstrikeBulletRecoil.ApplyPost(player pl, float strength)
Calls to these two functions are infixed between theTraceAttack
in a weapon's fire routine. They apply the current value of the punchangle to player'sv_angle
, with a little randomness. Afloat strength
value of 1 is enough for more guns, lower values are used for pistols and higher for high-recoil guns.Cstrike_CalculateAccuracy()
's internal calculation has been changed to return more extreme higher values (more inaccurate) the longer into the spray the player is. Lower values of the parameterfloat divisor
should now be used. A new parameter,float movement_penalty
has been added which amplifies the inaccuracy due to running or jumping (a value of 1 is used for SMG's, which can run and gun, whereas for rifles, >2 is used). To add extra first shot inaccuracy to the weapon, a constant is added to the return value of the function call (e.g.accuracy = Cstrike_CalculateAccuracy(pl,20,1.5) + 0.003f
).Calls to
Cstrike_ShotMultiplierAdd()
have been moved to the bottom of weapon fire routines, after the call to TraceAttack. As well as that, a new parameterfloat strength
has been added which allows for finer control of recoil feel. The function has been completely reworked to bring the feel of the recoil closer to the original. The algorithm uses two new member variables of the player:float cs_hor_rec_sign
, which signifies which direction (left/right) the horizontal recoil is going, andfloat cs_prev_hor_rec
, which is the previous value of the horizontal recoil.-The punchangle recovery has been slightly modified. The important one is the recovery of the vertical recoil/punchangle. The new formula used to calculate the recovery is less sudden for very high vertical recoil compared to the original. This code had to be changed in the Nuclide source, so you can see it here: https://github.com/mikota/nuclide/commit/bde001b781fd69ae8f012bfa1d47842a32b6b258