Home » MODDING HQ 1.13 » v1.13 Modding, Customising, Editing » v1.13 Time Capsule (How-to Library) » New CTH System - The Formula
New CTH System - The Formula[message #250989] Wed, 05 May 2010 19:55 Go to next message

Registered:March 2006
Location: Jerusalem
Given that I have already written much of the system down, I figured it would be a good time to reveal the formula itself - how CTH and shooting would be calculated in the new system.

Hopefully, by doing so you might be able to reveal problems I haven't spotted or thought of. In-game, of course, the only feedback we get is the final result, so spotting problems just by playing would be somewhat more difficult, which is where this formula comes in handy.

Also, disclosing this formula will make it easier to play with the INI variables that will be supplied with the new system. If you know what factor comes in where, you'll have a better understanding of how to change it and by how much.

Several notes before I begin:

1. This is written in Pseudo-code like all my other articles. You don't have to understand C++ to read this, but you do have to understand basic maths and logic. That's just how these things go.

2. Any variable shown in CAPITAL LETTERS (like "NORMAL_SHOOTING_DISTANCE") is an externalized coefficient. They are placed in the INI and thus are fully tweakable. They almost always act as a sort of multiplier to some part of the formula. You'll understand once you see them.

3. The default values of the externalized coefficients is given in parenthesis, so for instance you will see "NORMAL_SHOOTING_DISTANCE(70)", meaning that the current default value is 70. Since these are fully externalized, testers will be able to change these variables as they see fit, and the values here are not by any means final - just the ones I'm using right now - and aren't guaranteed to be anywhere balanced.

4. Most coefficients are treated as FLOATs, meaning that they can take a decimal point. This is not always shown in the pseudo-code just because I'm lazy.


<font size="">CALCULATING BASE CTH</font>

Base CTH is a free amount of CTH given to the character with ANY shot with the same weapon. The initial value is based primarily on skills. After that is calculated, all conditional factors like injury are summed up together and the final result used as a percentage to modify Base CTH.

Base CTH mainly represents the amount of CTH you'll have when taking shots without extra aiming. It is supposed to represent pulling the trigger when the gun is aimed in the general direction of the target, but no time has been spent making sure that the muzzle is actually pointing towards the target itself.

Experience = Shooter's_Experience_Level * 10 * BASE_EXP_LEVEL(3)
Marksmanship = Shooter's_Marksmanship * BASE_MARKS(1)
Wisdom = Shooter's_Wisdom * BASE_WISDOM(1)
Dexterity = Shooter's_Dexterity * BASE_DEXTERITY(1)

Base_CTH = (Experience + Marksmanship + Wisdom + Dexterity)

As you can see, the most important part of the calculation so far is Experience Level, which counts as three times as much as the other skills. That's because we're only calculating a rudimentary aim level which hasn't yet employed precision aiming at all. It's just the shooter's ability to place the gun nearer the target center in a "snap shot" situation, and hence benefits more from the shooter's experience than things like marksmanship.


Base_CTH = Base_CTH / Divisor

The divisor is used here to return the sum of all skills into a range of 0-100. This is similar to averaging the skills, but taking into account the fact that some are (or can be) more important than others. We use the coefficients in a way that modding the importance of any skill would still result in a 0-100 final range.

Base_CTH is divided by 3.

This gives us a final range of 0-33. We don't want shooters who are 100% accurate with base shots, ever. Of course, at very close distance, a value of 30% would mean that the shooter stands a very good chance to hit the target even without any extra aiming involved. This would be great for pistols or burst-fire weapons, which would be very useful at close range.

Assuming no bad conditions apply to the shooter (see below), the average merc should have around 15-20 base CTH. As mercs gain experience, this should increase considerably.

Base_CTH is increased by Weapon's_Base_CTH_Modifier

Weapon's_Base_CTH_Modifier is calculated from the weapon itself and its attachments. This is a flat modifier to Base CTH. I'm not sure which weapons or attachments should give such a bonus, but it's possible. Note that this allows weapons to go past the 0-33 range. It can't go below 0 however, in cases where the weapon/attachment lower the Base CTH for any reason.

Calculating the Base Modifier

Now we've got the preliminary value for Base CTH, and we start calculating the various factors that will affect it. These are added together into a separate final number, which is then used as a percentage to modify our Base CTH. The order in which these are added is largely irrelevant, but I'll write them here in the same order I have them written in the code.

"Base_Modifier" will be used as the final sum of all bonuses/penalties.

If Shooter's_Morale is greater than 50, then
   Morale_Modifier = (Shooter's_Morale - 45) / 10
   Base_Modifier is increased by (Morale_Modifier * BASE_HIGH_MORALE(2))

Else if Shooter's_Morale is lower than 50, then
   Morale_Modifier = (Shooter's_Morale - 50 ) / 2.5
   Base_Modifier is increased by (Morale_Modifier * BASE_LOW_MORALE(-1))

Morale greater than 50 gives +2 points for 55 morale, +4 points for 65, +6 for 75, etcetera.

Morale lower than 50 gives -1 points for 47 morale, -2 for 45 morale, -3 for 42 morale, etcetera.

The difference between how low and high morale are used really isn't my fault - it's using the program's Morale Calculator formula which takes into account the fact that NPCs have a different sort of morale from player characters. Can't be helped unless I rewrite that formula to make more sense.

If Shooter is a Psycho, then
   Base_Modifier is increased by BASE_PSYCHO(-3)

Note that when a coefficient is negative, like BASE_PSYCHO is in this code, then Base_Modifier is actually DECREASED. Testers will of course be able to change that into a positive coefficient if they feel it's necessary. I personally don't think psychos should be MORE accurate than anyone else - in fact they're more likely to shoot more bullets randomly at the target...

If shooting at the same target in the same tile, then
   Base_Modifier is increased by BASE_SAME_TARGET(5)

This only happens when shooting at a target that hasn't moved since the last time you shot at it. Also, if the shooter moves, this bonus disappears. Shooting at the same tile twice also gives this bonus, whether or not the same target is standing there (or any target at all).

If Shooter's_Current_Health is below 100, then
   Base_Modifier is increased by (Bleeding_Injuries * BASE_INJURY(-30)) / Max_Life
   Base_Modifier is increased by ((Bandaged_Injuries * BASE_INJURY(-30))) / Max_Life / 3

We use injury as a percentage here. If our merc has 50% bleeding injuries compared to his own maximum health value, he gets half the penalty, which would be -15 points. It's impossible to get the full -30 point penalty of course, since that would mean the shooter is dead (100% bleeding injuries).

Note that bandaged damage is only 1/3 as powerful as bleeding injuries.

Base_Modifier is increased by (BASE_FATIGUE(-15) * Shooter's_Breath) / 100

Breath is also used as a percentage. If the shooter has 50 breath points (half the maximum for all mercs), he gets half the penalty: -7.5 points.

If Shooter is Tipsy, then
   Base_Modifier is increased by BASE_DRUNK_TIPSY(-5)
If Shooter is Drunk, then
   Base_Modifier is increased by BASE_DRUNK(-20)
If Shooter is Wasted, then
   Base_Modifier is increased by BASE_DRUNK_WASTED(-50)
If Shooter is Hung-Over, then
   Base_Modifier is increased by BASE_DRUNK_HUNGOVER(-10)

Drunkness really affects base CTH, as you can see. Each level of drunkness has its own coefficient, so you can play with the values as you see fit.

If Shooter is in gas without a gas mask, then
   Base_Modifier is increased by BASE_GASSED(-50)

Gas makes it REALLY difficult to shoot straight - it'll kill half our Base CTH.

If Shooter is being bandaged by another merc, then
   Base_Modifier is increased by BASE_BEING_BANDAGED(-5)

I've decided not to apply a great penalty on being bandaged, at least not nearly as great as it was in the old system.

If Shooter has any Suppression Shock, then
   Shock_Modifier = (Shooter's_Shock * 100) / Maximum_Shock
   Base_Modifier is increased by ((Shock_Modifier * BASE_SHOCK(-150)) / 100)

This is Shock from suppression (though severe injuries can also add shock for a few turns). As you see, the maximum possible penalty from this is a whopping -150, but this is only achievable by complete noobs under very heavy suppressing fire - they won't get any Base CTH. Maximum Shock is around 30 (depending on your HAM INI settings), and as a shooter gets more experience and morale and so forth, it's likely that his actual limit would be much lower. Still, a few shock points can be very powerful, delivering -5 points each.

Height_Modifier = Calculate Height Difference.
If Height_Modifier is lower than 0, then
   Height_Modifier = 0.

Base_Modifier is increased by ((Height_Modifier * BASE_SHOOTING_UPWARDS(-15)) / Range_to_Target)

This is a little more complex. First we determine the difference in height between the elevation of the gun and the point we are aiming at.

For shooter elevation:
  Shooter_Height = 3
  Shooter_Height = 2
  Shooter_Height = 1

For target elevation:
  Target_Height = 1
  Target_Height = 2
  Target_Height = 3

In addition, Target_Height is increased by 3 points if it is on the roof.

Basically, this means that shooting from prone stance at a target's head counts as two Height Difference points. Shooting from standing stance to the torso of a character on the roof counts as one Height Difference point. And so on.

Shooting DOWNWARDS is not affected at all. The penalty only exists when pointing the gun upwards, which is much more difficult than shooting straight or down due to the uncomfortable angles it involves.

Also note that the penalty is divided by Range_to_target, so it is strongest at close range and gets considerably weaker as we go past 10 or so tiles. Shooting at a target on a roof 10 tiles away is almost the same as shooting straight ahead, really.

Target_Skill_Modifier = either Target_Experience_Level or Target_Agility, whichever is higher.
Base_Modifier = (Target_Skill_Modifier * BASE_AGILE_TARGET(-5)) / 100

This is somewhat of a relic inherited from the old CTH system. Basically it means that a target can anticipate shots and duck out of the way. I'm not too fond of this, since it's hard to properly model it on how it would work in real life. If you don't like it, just set BASE_AGILE_TARGET to 0, and the penalty's gone. You can see I've set it pretty low to begin with - only targets with 100 experience or 100 agility will give the full -5 point penalty anyway.

If Target is not within visual range, then
   Base_Modifier is increased by BASE_INVISIBLE_TARGET(-100).

An invisible target reduces the modifier by 100 points. If you can't see the target, rudimentary aim is going to be rather inaccurate. Remember of course that extra aiming _CAN_ make up for this, and also that 0% CTH (even WITH aiming) doesn't mean you're going to miss the target. It really depends a lot on distance.

If Shooter is an enemy combatant, then
   If Difficulty Level is NOVICE, then
      Base_Modifier is increased by BASE_DIFFICULTY_NOVICE(-30)
   If Difficulty Level is EXPERIENCED, then
      Base_Modifier is increased by BASE_DIFFICULTY_EXPERIENCED(0)
   If Difficulty Level is EXPERT, then
      Base_Modifier is increased by BASE_DIFFICULTY_EXPERT(20)
   If Difficulty Level is INSANE, then
      Base_Modifier is increased by BASE_DIFFICULTY_INSANE(50)

Enemy combatants do cheat at higher difficulty levels. This is also a relic from the old CTH system, and again you can now mess with the coefficients if you don't want them to. At Experienced difficulty, they get no bonus. At INSANE difficulty, they are 50% more accurate (with their Base CTH).

Gun Handling

This is almost a separate part of the formula, and a very important one overall. This part calculates how hard it is to prepare the gun for shooting, and how hard it is to hold the gun steady. It's represented by the Gun Handling value, and takes into account several important conditions.

Please have patience while reading this - the Base_Modifier will not be adjusted until the VERY END of this formula!

Gun_Handling = Gun's AP_to_Ready cost, with all modifiers applied from attachments

Gun Handling is based primarily off the gun's Ready Costs. That value already takes into account a lot of things about weapon handling, so it stands to reason that it should be used here. At least in 1.13, StarWalker's done a good job with these, so they already correlate directly to the size, weight and shape of the gun.

Now we start modifying this value based on various conditions.

If shooting two guns at the same time, then
   Two_Guns_Modifier = BASE_TWO_GUNS(3.5)

   Two_Guns_Modifier is decreased by 1.
   For each level of AMBIDEXTROUS, do:
      Two_Guns_Modifier is divided by 2.
   Two_Guns_Modifier is increased by 1.

   Gun_Handling is multiplied by Two_Guns_Modifier

By default, shooting two guns is 3.5 times more difficult than each gun on its own. Ambidextrous mercs reduce this to 2.25 times more difficult. Note that this system opens the way to having mercs with two levels in the ambidextrous trait, where these "expert" ambi's will get only about 1.62.

The trick I did there with decreasing by 1 and increasing by 1 later is only for making sure that Ambi mercs don't shoot EASIER with two hands than with one, regardless of the value of BASE_TWO_GUNS. It's just math wizardry, so ignore it if you don't get it.

If shooting a one-handed gun with only one hand, then
   Gun_Handling is multiplied by BASE_ONE_HANDED(2)

A gun fired with just one hand is half as easy to handle as a gun fired with both hands. This happens when a one-handed gun, like a pistol or small SMG, is fired while the other hand is holding a non-gun item.

If shooting a "Heavy Weapon", then
   Heavy_Weapon_Modifier = BASE_HEAVY_WEAPON(2)

   Heavy_Weapon_Modifier is decreased by 1.
   For each level of HEAVY WEAPONS, do:
      Heavy_Weapon_Modifier is divided by 2.
   Heavy_Weapon_Modifier is increased by 1.

   Gun_Handling is multiplied by Heavy_Weapon_Modifier

Once again, math wizardry. A normal merc would find a Heavy Weapon twice as hard to shoot. HEAVY WEAPON skill reduces this to 1.5, and EXPERT HEAVY WEAPON reduces it to 1.25. Note that I'm not terribly sure about the values here, because most heavy weapons are already going to have a massive Gun Handling due to their inherently high AP_to_Ready value.

   No modifier.
   Gun_Handling is multiplied by BASE_CROUCHING_STANCE(2)
   Gun_Handling is multiplied by BASE_PRONE_STANCE(3)

Stance influences how easily we can handle our guns. Note that since we are calculating Base CTH - the amount of CTH we get for a "snap shot", we actually suffer for crouched and prone stances. Of course, these stances will benefit more when adding Extra Aiming levels. In other words, for quick fire you want to stand up, and for aimed fire you want to get down.

If PRONE and using a Bipod, then:
   Gun_Handling = (Gun_Handling * (100-Bipod_Bonus)) / 100

I'm not yet sure how to make Bipods work as far as XML tags and all that. But I do know that this is how they are going to affect gun handling. In other words, a bipod with perfect balancing (100) will eliminated Gun Handling completely, regardless of the size and weight of the gun. A bipod with 10 points will only reduce Gun Handling by 10 percent.

And finally:

Base_Modifier is increased by (Gun_Handling * BASE_GUN_HANDLING(-2))

This is where Gun Handling finally affects our base modifier. We lose two points from the modifier per Gun Handling point. At this point a pistol used with two hands while standing up gives the lowest penalty. A Sniper Rifle or Heavy Weapon while prone gives the worst penalty, could be up to -40 given the (-2) coefficient.

Final calculation

Now that Base_Modifier is all calculated, we can apply it to our Base CTH. This is done as a percentage:

Base_CTH is increased by ((Base_CTH * Base_Modifier) / 100).

If Base_Modifier was a negative number, which it usually is, then Base_CTH is decreased by that amount. For instance, -20 Base Modifier gives a 20% reduction in Base CTH. If the modifier was positive, that's an increase. For instance, 5 Base_Modifier gives a 5% increase in Base CTH.

What does it mean?

As mentioned previously, Base CTH is a free amount of CTH given for every shot with the weapon. Of course, it really depends on what weapon, what stance, and other factors as shown above. It will normally be between 0-30, while VERY skilled shooters can go higher than that, but not by much.

What this basically means is a 0-30% decrease in Muzzle Sway. At 0, muzzle sway is as large as possible, by default 22.5 degrees to either side of the target. At 30, muzzle sway is 30% smaller than the maximum, giving an angle of about 18 degrees to either side.

Of course, most shooters will want to add extra aiming points to improve their aim. This is pretty much essential for hitting targets more than a couple of tiles away. That's when we go into Aiming CTH territory, as will be explained shortly.

(To be continued)

[Updated on: Mon, 27 April 2015 23:45] by Moderator

Re: New CTH System - The Formula[message #250990] Wed, 05 May 2010 19:55 Go to previous messageGo to next message

Registered:March 2006
Location: Jerusalem
Calculating Aiming CTH

"Base CTH" represents our accuracy when making "snap shots", inaccurate unaimed shots in the rough direction of the target. At close range, these can be enough to perforate an enemy, especially when burst-fire is used at up to about 10 tiles.

However, to have any realistic chance to hit the target at about 5 tiles or beyond with a single shot, we need to reduce our Muzzle Sway considerably. That's where Aiming CTH comes in.

Aiming CTH is added on top of Base CTH when the player adds APs for the shot. Each aiming level increases CTH by a certain amount. This makes muzzle sway lower, and hence reduces the radius in which shots might deviate off the target's center. An accurate shooter, firing at a reasonable distance for his equipment, should reach fairly good odds to hit the target given enough Aiming is applied.

Aiming CTH is calculated in almost exactly the same way as Base CTH. First, a "preliminary" value is calculated using the character's skills, indicating how many points we can get under "regular" conditions. Then, we pool together all the factors that may influence aiming for better or for worse, and use these as a percentage modifier to increase or decrease Aiming CTH. Each level of aim will give us a certain part of that final value.

Despite the similarity, you'll notice that Aiming CTH is calculated based on some factors that do not affect Base CTH. For instance, gun condition affects Aiming, but not Base. The opposite is also true, as some factors that affect Base CTH do not affect Aiming CTH.

In addition, Aiming CTH has its own coefficient values, also adjustable in the INI file, separate from Base CTH coefficients. This allows testers to modify the two calculation separately.

Finally, due to the fact that Aiming is level-based, you'll see a bit at the end that decides how many of the total points each Aiming Level will actually give.


Calculating CTH Cap

We begin by calculating a value called "CTH Cap". In simple terms, this is the highest amount of CTH our shooter can possibly have. Under no circumstance will the shooter have more than this many CTH points for any shot.

This value is calculated from skills, as shown below:

Experience = Shooter's_Experience_Level * 10 * AIM_EXP_LEVEL(1)
Marksmanship = Shooter's_Marksmanship * AIM_MARKS(3)
Wisdom = Shooter's_Wisdom * AIM_WISDOM(1)
Dexterity = Shooter's_Dexterity * AIM_DEXTERITY(2)

CTH_Cap = (Experience + Marksmanship + Wisdom + Dexterity)

In aiming, Marksmanship is the most important skill, followed by dexterity. Experience Level, which played a major role in Base CTH, is now much less important.


CTH_Cap = CTH_Cap / Divisor

Once again, we divide CTH cap by the sum of the coefficients. Regardless of their values as set in the INI, this will always return a number within the scale of 0-100.

This time we do not divide by 3 as we did with Base CTH.

CTH_Cap is increased by Weapon's_CTH_Cap_Modifier
CTH_Cap = (CTH_Cap * Weapon's_CTH_Cap_Modifier) / 100

I haven't yet decided which of the above methods to use in applying a weapon's modifier. A percentage based modifier (the second option) is probably more suitable. In any case, this sort of modifier will be used primarily for attachments that somehow enable shooters to be more accurate regardless of their skill. Laser Sights are a possible candidate to receive such a modifier, as they allow the shooter to per 100% accurate with their aim, provided they can see the red dot on the target.

Maximum_Aiming_CTH = CTH_Cap - Base_CTH

The maximum amount of CTH points we can get from aiming is the difference between the Cap and the Base. In other words, our shooter begins with Base_CTH points, and with aiming can go all the way up to the CTH Cap. Of course, this will require plenty of aiming, which is why it's called the "Maximum" and not just "Aiming CTH". You'll see much later in this calculation how each aiming level gets its own Aiming CTH.

Aiming CTH Modifiers

Once again, we now start pooling all the factors that can affect our aiming into a single number, called the "Aim_Modifier". After they are all added, it will be applied as a percentage to the Maximum_Aiming_CTH, either reducing or increasing it as appropriate.

The process is very reminiscent to the calculation of the "Base_Modifier" from the previous chapter. However, the factors here have different importance.

If Weapon's_Condition is less than 50%, then
   Aim_Modifier is increased by ((50-Weapon_Condition) * AIM_GUN_CONDITION(-2.0))

Gun condition is very important for aiming, but only if the gun is properly damaged. In other words, a severely broken gun is simply harder to hold straight, or aim straight. We get -2 points per gun condition point below 50.

We'll now cover several factors that were used (and explained) in the Base Calculation above. The only difference of course is the value of the coefficients.

If Shooter's_Morale is greater than 50, then
   Morale_Modifier = (Shooter's_Morale - 45) / 10
   Aim_Modifier is increased by (Morale_Modifier * AIM_HIGH_MORALE(1))

Else if Shooter's_Morale is lower than 50, then
   Morale_Modifier = (Shooter's_Morale - 50 ) / 2.5
   Aim_Modifier is increased by (Morale_Modifier * AIM_LOW_MORALE(-2))

If Shooter is a Psycho, then
   Aim_Modifier is increased by AIM_PSYCHO(-5)

If Shooter's_Current_Health is below 100, then
   Aim_Modifier is increased by (Bleeding_Injuries * AIM_INJURY(-60)) / Max_Life
   Aim_Modifier is increased by ((Bandaged_Injuries * AIM_INJURY(-30))) / Max_Life / 3

Aim_Modifier is increased by (AIM_FATIGUE(-15) * Shooter's_Breath) / 100

If Shooter is Tipsy, then
   Aim_Modifier is increased by AIM_DRUNK_TIPSY(-10)
If Shooter is Drunk, then
   Aim_Modifier is increased by AIM_DRUNK(-40)
If Shooter is Wasted, then
   Aim_Modifier is increased by AIM_DRUNK_WASTED(-90)
If Shooter is Hung-Over, then
   Aim_Modifier is increased by AIM_DRUNK_HUNGOVER(-15)

If Shooter is in gas without a gas mask, then
   Aim_Modifier is increased by AIM_GASSED(-80)

If Shooter is being bandaged by another merc, then
   Aim_Modifier is increased by AIM_BEING_BANDAGED(-20)

If Shooter has any Suppression Shock, then
   Shock_Modifier = (Shooter's_Shock * 100) / Maximum_Shock
   Aim_Modifier = (Shock_Modifier * AIM_SHOCK(-150)) / 100

Height_Modifier = Calculate Height Difference.
If Height_Modifier is lower than 0, then
   Height_Modifier = 0.

Aim_Modifier = (Height_Modifier * AIM_SHOOTING_UPWARDS(-20)) / Range_to_Target

If Shooter is an enemy combatant, then
   If Difficulty Level is NOVICE, then
      Aim_Modifier is increased by AIM_DIFFICULTY_NOVICE(-30)
   If Difficulty Level is EXPERIENCED, then
      Aim_Modifier is increased by AIM_DIFFICULTY_EXPERIENCED(0)
   If Difficulty Level is EXPERT, then
      Aim_Modifier is increased by AIM_DIFFICULTY_EXPERT(20)
   If Difficulty Level is INSANE, then
      Aim_Modifier is increased by AIM_DIFFICULTY_INSANE(50)

If Target is not within visual range, then
   Invis_Target_Modifier = AIM_INVISIBLE_TARGET(-50).
   For each level of the SNIPER trait, do:
      Invis_Target_Modifier is divided by 2.
   Aim_Modifier is increased by Invis_Target_Modifier.

All of the above modifiers are used to alter both Base CTH and Aiming CTH. You'll notice that most of the coefficients are "harsher" than they were when calculating Base. That's because it's much easier to fire a random shot in roughly the right direction when under duress than actually ensure a shot in the right direction in such conditions.

You'll also note that shooting at the same target twice doesn't add any bonus. Nor does target agility/experience give any penalty. These should not be relevant when aiming, and only apply to Base CTH, which is more closely related to spotting the target quickly rather than actually improving your chance to hit it.

Target Visibility

The only coefficient which doesn't suffer as heavily as in Base CTH is when the target is invisible. In that formula, it reduced Base CTH to 0 (by applying -100% to it). In the Aiming CTH formula however, you can still aim at invisible targets, though only half as effectively as normal. Snipers and Expert Snipers suffer much less of a penalty, and can hit targets they can't see based solely on information from whoever does have the target in their line of sight. This is just one of several advantages that Snipers are going to have in the new CTH formula.

Even if the target is not invisible, aiming properly at it does suffer if it isn't very visible. To this end we use a formula called "SoldierToSoldierLineOfSight()", which basically measures how visible the target is by calculating cover, stance and camouflage. The returned value from this formula indicates the "relative" range to the target - meaning how far away that target might've been if it was 100% visible. In other words, a target with low visibility is actually considered to be further away than it actually is.

Let's use this in a formula:

If Visibility_Range is greater than True_Range, then
   Visibility_Ratio = Visibility_Range / True_Range
   Visibility_Penalty = 100-(100/Visibility_Ratio)
   Aim_Modifier is increased by ((Visibility_Penalty * AIM_VISIBILITY(-0.5)) / 100)

This can be a little much to take in, but the result is fairly simple. If the target is considered to be twice as far away than it actually is, visibility-wise, then we get a -25% penalty to aiming. If the target is seen as four times as far away than it actually is, we get a -37% penalty to aiming, and so forth. Again, if the target is completely invisible, we get that flat -50% penalty, as seen earlier in the formula.

Gun Handling

Now, let's have a look at how Gun Handling works. In general, the idea is the same as with Base CTH: Larger, less wieldy guns are harder to aim properly. However, unlike Base which benefits from being able to swing the gun around quickly, Aiming is more about holding the gun steady, preferably with some sort of anchoring. Therefore, the shooter benefits from a LOWER stance rather than a HIGHER one.

Gun_Handling = Gun's AP_to_Ready cost, with all modifiers applied from attachments

If shooting two guns at the same time, then
   Two_Guns_Modifier = AIM_TWO_GUNS(4)

   Two_Guns_Modifier is decreased by 1.
   For each level of AMBIDEXTROUS, do:
      Two_Guns_Modifier is divided by 2.
   Two_Guns_Modifier is increased by 1.

   Gun_Handling is increased by Two_Guns_Modifier

If shooting a one-handed gun with only one hand, then
   Gun_Handling is multiplied by AIM_ONE_HANDED(2.5)

If shooting a "Heavy Weapon", then
   Heavy_Weapon_Modifier = AIM_HEAVY_WEAPON(2)

   Heavy_Weapon_Modifier is decreased by 1.
   For each level of HEAVY WEAPONS, do:
      Heavy_Weapon_Modifier is divided by 2.
   Heavy_Weapon_Modifier is increased by 1.

   Gun_Handling is increased by Heavy_Weapon_Modifier

   Gun_Handling is multiplied by AIM_STANDING_STANCE(2.5)
   Gun_Handling is multiplied by AIM_CROUCHING_STANCE(1.5)
   No Modifier.

If PRONE and using a Bipod, then:
   Gun_Handling = (Gun_Handling * (100-Bipod_Bonus)) / 100

Again, this is largely the same as the Gun Handling formula used in Base CTH calculations, except the coefficients are different (harsher), and Prone stance is preferable to Standing stance.

Add this to the Aiming_Modifier:

Aim_Modifier is increased by (Gun_Handling * AIM_GUN_HANDLING(-1.5))

Maximum Aiming CTH and Aiming Levels

First, after combining all the above factors into a single value ("Aim_Modifier"), we apply it to our Maximum_Aiming_CTH as a percentage:

Maximum_Aiming_CTH is increased by ((Maximum_Aiming_CTH * Aim_Modifier) / 100).

This sort of calculation should be obvious by this point, so I won't explain it.

The next step, of course, is to figure out what part of this amount do we get for each aiming level?

Well, this is where things get a little sketchy, because frankly I don't know which would be the best way to go about it. It really depends on how we want aiming levels to work, and in JA2 there are no less than THREE separate systems for aiming levels:

1. "Basic JA2": With this system, used in the vanilla game, ANY weapon can have exactly four aiming levels.
2. "Basic JA2 1.13": All weapons can have up to 4 aiming levels. However, installing a 7x scope on a weapon increases this to 6, and installing a 10x Scope increases it to 8.
3. "HAM Dynamic Aim Levels": With the HAM system, weapons have various aiming level limits based on their type, the scope installed (each scope has its own limit) and the use of a bipod to stabilize.

These three systems were all designed to serve a certain purpose. Unfortunately, all of them were designed around the Old CTH system, and therefore are somewhat out of place in the new system.

In the new system, the benefits for using a scope are taken into consideration outside the CTH formula, and thus are largely separate from the CTH value. If the target is at 2x Normal Distance, the very use of a 2x scope makes a shooter far more accurate as without one, regardless of how many extra aiming levels he should add. In fact, at that distance, 75% CTH with a 2x scope is four times more accurate than 75% CTH without one, so even at max aiming a properly-equipped gun at the right distance is going to do a much better job.

In other words, CTH represents how well the gun is aimed within the limits imposed by the scope. A better scope at the proper distance gives smaller muzzle sway, making each CTH point be more valuable. By this logic, there's no reason not to let a shooter reach his maximum allowed CTH regardless of the gun he's using.

Therefore, increasing the number of aiming levels available for each gun becomes unnecessary. In fact, I am currently inclined to return to the original JA2 system - where each gun is allowed the same number of aiming levels. The point being that with the same number of aiming levels applied to it, a scoped sniper rifle is already much more accurate than a pistol, thanks to the calculations inside and around the CTH formula, owing largely to things like high Scope Magnification and low Bullet Deviation.

Maximum Aiming Levels can therefore be completely externalized to an INI setting, adjustable by players to increase or decrease the time required for a shooter to maximize his aim. If the INI setting is decreased, aiming would simply achieve maximum results FASTER. If increased, it takes more APs to aim the gun to the best of its (or the shooter's) ability. The maximum CTH achieved at the last level is the same for all guns, but it has far more weight when that gun is also more accurate and used with a higher scope magnification.

At the moment, I already have this system written into the code with 8 extra aiming levels being the maximum for all guns. Unless I hear concrete objections to this, that will be the system used with the new Shooting Mechanism.

Once we've figured that out, we need to decide how much CTH is added for each of those 8 levels. I've decided to go with a gradual increase: The first aiming level increases CTH by a majority of the points, and each subsequent level provides fewer and fewer CTH points. The final level produces a very small amount of points.

This is how it works:

For each allowed aiming level do:
   Divisor = Divisor + Aiming Level

This is simpler when written in code, so let's see examples of this:

If the number of allowed aiming levels for all guns is 8 (my current default), then the divisor is 1+2+3+4+5+6+7+8 = 36.
If the number of allowed aiming levels for all guns is 4 (JA2 default), then the divisor is 1+2+3+4 = 10.

Now we divide Maximum_Aiming_CTH into equal fractions using this divisor.

Aiming_Fraction = Maximum_Aiming_CTH / Divisor

This is where it gets all mathematical:

X = 0
While X is smaller than Current_Aiming_Level, do:
   Aiming_CTH is increased by (Maximum_Allowed_Aiming_Levels - x) * Aiming_Fraction

Yes, that's a bit hard to grasp, but again the explanation is rather simple:

Assuming 8 levels are allowed, each fraction is worth 1/36 of the Maximum_Aiming_CTH. The first aiming level will give us 8 of these fractions (8/36). The second level gives 7 fractions (7/36). The third level gives 6 fractions. The last level gives only 1 fraction.

So you see, the first level is greatly helpful, adding a substantial amount of Aiming_CTH to our shooter. The last level gives much less than that (1/8 as much as the first, in fact).

The benefits of this calculation are not immediately apparent, but they are there:

For one, this system means that to shoot with a reasonable CTH, the shooter is only going to have to add maybe one or two levels, which already gives him about 1/3 of the total amount of achievable Aiming CTH. An extra level pushes this to almost 1/2.

Secondly, the last few CTH points can have an extreme impact when trying to be as accurate as possible. Decreasing the Muzzle Sway from 20% to 15% can make a difference between a shot that can miss to a shot that can't, whereas 80% to 75% is much less so (this depends greatly on distance, of course).

Lastly, the way this system operates makes it so that a shooter in distress or wielding a large unsupported gun will simply get nothing for those last few APs, since the size of a "fraction" is too small to add up properly. This effectively limits the number of aiming levels that are of any use at all, which in many ways copies the behavior of HAM's Dynamic Aiming Limits system into the new shooting mechanism without having to make a separate formula for it or base it arbitrarily on scopes or bipods. If a bipod isn't used, the weapon's Gun Handling value will cause extra aiming to become much less useful. If a scope isn't used, extra aiming is hardly as beneficial even if it brings CTH up to high levels. Therefore, the system becomes self-contained, and doesn't require arbitrary external limits like telling a merc he can't spend more APs on a shot - he simply doesn't benefit from them, within the same rules laid out in this formula.

Scope Magnification Penalties

Here we come to a peculiar sort of modifier, which as you notice is being calculated at the very end of the formula. This penalty, called a "Scope Magnification Penalty", is one of the unique parts that makes the new CTH system so different from the old one.

As repeated several times in this article, CTH is only one factor in several that determine whether the shot will hit its target. One of the most important factors is the use of scopes. Scopes installed on a weapon provide two important effects - one positive, the other negative.

The positive effect is calculated during the actual shooting of the gun, and will be explained in greater detail below. It is applied whenever the gun is being given extra aim at the target, and is definitely crucial for hitting targets beyond a dozen tiles with any certainty.

The negative effect will be explained here. Its purpose is to DIMINISH the effectiveness of the gun when used below the scope's "optimal" range. A gun with a scope mounted on top is harder to aim properly when the target is too close. This is reflected by a categorical penalty on Aiming CTH.

To understand how this effect works, we'll need to understand the concept of the NORMAL_SHOOTING_DISTANCE. This is another coefficient, externalized to the INI file, and one which has a massive impact on everything that has to do with scopes.

NORMAL_SHOOTING_DISTANCE effectively determines the optimal range of any scope based purely on its magnification factor. A 2x scope is therefore optimal when the target is at 2*NORMAL_SHOOTING_DISTANCE. A 4x scope is optimal at 4*NORMAL, and a 10x scope at 10*NORMAL. When no scope is installed, the normal distance is largely irrelevant except for purposes of 3D maths.

The default NORMAL_SHOOTING_DISTANCE value I'm currently using is 7 tiles. This means that a 2x scope is optimal for 14 tiles, a 4x for 28 tiles (sightrange), and a 10x scope is optimal at 70 tiles. Please remember that with the new system, decimal magnification scopes (like 1.5x) are possible.

While calculating CTH, we use this "optimal distance" to determine the range at which our scope becomes a LIABILITY - making shooting harder. In realism terms, this is related to the fact that a large device is obstructing our ability to aim the weapon at close targets, using the weapon's build-in Iron Sights as we would if no scope was installed. It impedes visibility of that target, and forces us to either aim with too much magnification, or aim by feel. Both of which are treated by the CTH system as being equally detrimental.

Let's see how the code deals with this:

Scope_Mag_Factor = a value derived directly from the scope we are using. A 2x scope would put this value at 2.0.
Best_Scope_Range = NORMAL_SHOOTING_DISTANCE(7) * Scope_Mag_Factor

if Range_to_Target is less than Best_Scope_Range, then
   Scope_Ratio = Best_Scope_Range / Range_to_Target
   Aiming_CTH is divided by (Scope_Ratio * AIM_TOO_CLOSE_SCOPE(-1))

This bit of code is best illustrated as an example:

Scope is a 2x, giving us a mag factor of 2.0
Best scope range is 7 tiles * 2.0 = 14 tiles.
Target is at 10 tiles distance.

Scope Ratio = 14 Tiles / 10 tiles = 1.4
Aiming CTH is divided by 1.4

In other words, when shooting a scope at this distance, we suffer a 40% decrease in Aiming CTH due to the difficulty of aiming a 2x scoped gun at a target that isn't at the best range for that scope. Naturally, the more powerful the scope, the worse the ratio would be at this distance. A 10x scoped gun is barely aimable at all at this distance, causing Aiming_CTH to plummet sharply to just a few points if any.

This is further complicated, as you'll soon see, by the fact that at sub-optimal range we don't even receive a 2x benefit from the scope, but rather a 1.4x benefit. These two factors combine to make short-range use of scopes very unrecommended. In fact, it's probably better to spend the APs to remove the scope, then fire, if the shooter has enough APs to do so at all.

The benefits from such a system should be obvious - it constrains long-range weapons to be used as long-range weapons. It forces us to either carry extra sidearms or other small weaponry, or have some of our mercs equipped with such weapons and dedicated to close-combat. A sniper caught at close-range would be unable to shoot accurately at his assailant. On the other hand, weapons equipped with no scope would obviously be extremely ineffectual at anything more than NORMAL_SHOOTING_DISTANCE.


Adding it all up

Final CTH is simply an addition of Base and Aiming CTH, limited downwards by 0, and upwards by the CTH Cap.

Final_CTH = Base_CTH + Aiming_CTH
If Final_CTH is less than 0, then
   Final_CTH = 0
If Final_CTH is greater than CTH_Cap, then
   Final_CTH = CTH_Cap

The use of CTH_Cap for this purpose is important. It means that every shooter has an upper limit that he or she cannot cross regardless of any other factor. Remember - CTH_Cap is determined primarily by Marksmanship and Dexterity, and is meant to represent how stable the shooter is when all factors are in his favour.

Note also that an extra limit is used, the one in JA2_Options.INI, which determines the highest CTH possible for ANYONE. It is currently 99%, but that will probably go down to around 95% with the new system in place. Remember of course that 8 levels of extra aiming are usually required to reach this limit, and would be impossible if more than a few negative modifiers are applied either to Base, Aiming, or both. Shooters who calculate their CTH Cap at over 95% will benefit by effectively negating up to 5% of negative penalties, if any are applied during the calculation. Such mercs, of course, would be very, very rare.

Final CTH -> Muzzle Sway

We view CTH as being the "Chance to hit the target", but of course this is no longer so. With the new CTH system in place, the term 'CTH' is an anachronism, used here only because it is more familiar. In fact, this entire calculation was actually for our "Muzzle Sway" value, the radius inside which our gun is swaying back and forth over the target as we try to find the right moment to pull the trigger.

To do this, the program immediately inverts CTH right after it's calculated:

Muzzle Sway = 100 - Final_CTH

If CTH was 0%, Muzzle Sway is 100%. This means that the muzzle can deviate all the way up to its maximum radius (calculated later). If CTH is 95% (the proposed maximum), then the muzzle can only deviate up to 5% of this maximum radius, meaning that the gun is more stable and probably pointing straight at the target or just a little bit off. Of course, as we'll see later, without a scope this doesn't hold true at any normal engagement distance.

(Please excuse anything I might've forgotten in the above formulae. Note that gun/attachment modifiers are not yet implemented, so I probably forgot a few).

(To be continued)

Re: New CTH System - The Formula[message #250991] Wed, 05 May 2010 19:55 Go to previous messageGo to next message

Registered:March 2006
Location: Jerusalem

Shooting doesn't start and end with CTH calculation. Both with the old and new systems, after pulling the trigger the program still has several things it must process before firing the bullet. Essentially, this is where 3D Maths come in to ascertain a flightpath for the bullet.

There are several functions that handle this, which I'll refer to collectively as the "Shooting Mechanism". This mechanism begins with a function called "UseGun()", which handles the primary aspects of gunfire: Calculating CTH, adding experience, applying tracer effects, calculating bullet path, firing the bullet, and if necessary setting things up for the next bullet in an autofire or burst volley. The parts we're interested in are obviously the CTH calculation and the bullet path, both of which are handled by some complex sub-functions.

Please note that the entire system makes heavy use of maths, particularly trigonometry, to figure out distances and angles in 3D. If you don't understand trigo very well, don't worry - it's not really essential.

The Old System

The old system relies heavily on the result of the CTH formula, and does relatively adjustments to bullet flightpath little after computing the CTH value. In other words, its choice of bullet path is determined primarily by CTH.

Here's a short run-down of how the old system used to work:

CTH = Calculate the CTH for this bullet
RandomNum = A random number between 1 and 100.
If RandomNum is less than or equal to CTH, then
   Bullet_path = a straight path from the gun to the center of the target.
   Radius_of_Miss = RandomNum - CTH
   Bullet_Target_Coordinates = A random point within Radius_of_Miss of the target's center
   Bullet_path = a straight path from the gun to the new target coordinates

Fire a bullet along Bullet_Path

There's a few other parts I haven't mentioned above, such as some sort of inexplicable upwards deviation that occurs when shooting at rooftop enemies, but since this system is about to be replaced, that is largely irrelevant.

The basic idea is that the bullet will usually end up going straight for the center of the target, assuming the dice-roll against CTH was successful. Otherwise, a random point is picked within a certain distance of the target, and the bullet is shot at that new point. That distance depends on how badly the dice roll went.

CTH holds very high importance here. It basically determines everything else. In fact, even experience gain is directly related to CTH. High-reliance on the CTH system is what makes it all so exploitable, not the least because we can SEE CTH, but also because we can reliably raise CTH to high levels even if we turn CTH bars off.

The New system

With the new system in place, CTH now takes a much smaller role. Yes, it is still very important, but several uncontrollable factors now influence the shooting mechanism just as much:

1. CTH, now called "Muzzle Sway"
2. Scope Magnification
3. Target movement
4. Recoil effects
5. Bullet drop
6. Bullet deviation

Each factor works in its own way to adjust the bullet's flightpath. They can do so in one of two ways: either increase/decrease the distance to which a bullet can deviate, or actually move the center point for the shot away from the target. This runs on a "closed system", so these factors are integrated seamlessly, with no exceptions to the rules I set down.

Initial variables

The UseGun function is sort of a "doorway" into the shooting mechanism, and only sets up the very basic variables for the shot: It runs the CTH calculation, and also figures out the X/Y/Z coordinates for the very center of the target.
It then sends those variables on to deeper parts of the formula, and once those are done doing their thing, they return the new coordinates for the bullet. The system then fires the bullet directly at the given coordinates, wherever they might be.

Note that the "Target Center" coordinates are actually the center of the targeted bodypart. In other words, the "target center" isn't always the center of the torso, it could be the center of the head or the legs.

With these variables in place, we can start calculating where the bullet is going to go.

Muzzle Sway

The basis of the system is to determine how FAR the bullet can go off the target's center. That value is called the Muzzle Sway. Since many of the other parts rely on the size of the sway, we're going to need to calculate it first.

Maximum_Muzzle_Sway = (Sine of MAXIMUM_SHOOTING_ANGLE(22.5)) * Range_to_Target

The coefficient MAXIMUM_SHOOTING_ANGLE determines the maximum angle at which the bullet can fly. The original program set this at 22.5, which means shots can go in a 45 degree cone forward of the shooter. This is done to prevent bullets from going in weird direction like sideways.

We multiply the sine by the range to target, giving us the maximum radius to which any shot can deviate off the target. This draws an imaginary circle around the target center.

If we decrease the MAXIMUM_SHOOTING_ANGLE, the size of this circle becomes smaller. This causes all shots to be more accurate in proportion, because they can only be adjusted within (and based on) this circle.

Muzzle_Sway = Maximum_Muzzle_Sway * (100-CTH) / 100

Now you see how CTH affects the shooting mechanism. Basically, the inverted CTH is used as a percentage to modify the size of the circle. 20% CTH makes the radius of the Muzzle Sway circle 20% smaller. 80% CTH makes it 80% smaller, and so forth. At 0%, the circle is unchanged, and at 100% (normally unattainable) the circle is actually a dot with 0 radius.


Scopes work by dividing the size of the sway circle, essentially making shots more accurate. However, scopes only work best at a certain distance. Below that distance, the scope becomes less and less useful. Beyond that distance, the bonus loses its effect because the original size of the circle is bigger. Let's see how this works:

If at least one Extra Aiming Level has been added to the shot, then
   Scope_Best_Range = NORMAL_SHOOTING_DISTANCE(70) * Scope_Magnification_Factor
   If Range_to_Target is greater than or equal to Scope_Best_Range then
      Final_Magnification_Factor = Scope_Magnification_Factor
      Final_Magnification_Factor = Range_to_Target / NORMAL_SHOOTING_DISTANCE

If Final_Magnification_Factor is less than 1, then
   Final_Magnification_Factor = 1.

This is more simple than it sounds, but deserves an example:

Scope Mag Factor = 2.0 (a 2x scope)
Scope Best Range is then 2.0 * 70 = 140 meters (14 tiles)

If Target Range is 14 tiles or more, then the Final Mag Factor is 2.0
If Target Range is 10 tiles, then the Final Mag Factor is (10 tiles / 7 tiles) = 1.42
If Target Range is 7 tiles, then the Final Mag Factor is (7 tiles / 7 tiles) = 1.0
If Target Range is 6 tiles or less, then the Final Mag Factor is 1.0

Example #2:

Scope Mag Factor = 10.0 (a 10x scope)
Scope Best Range is then 10.0 * 70 = 700 meters (70 tiles)

If Target Range is 70 tiles or more, then the Final Mag Factor is 10.0
If Target Range is 10 tiles, then the Final Mag Factor is (10 tiles / 7 tiles) = 1.42
If Target Range is 7 tiles, then the Final Mag Factor is (7 tiles / 7 tiles) = 1.0
If Target Range is 6 tiles or less, then the Final Mag Factor is 1.0

Finally, we apply the Mag Factor to the size of the Muzzle Sway:

Muzzle_Sway is divided by Final_Magnification_Factor

So we can see that the scope actually makes the muzzle sway much smaller, assuming of course that the target is at the correct distance. If it is closer, our scope doesn't provide the same bonus. If it is more distant, the Muzzle_Sway itself is larger, while the magnification doesn't grow, making the shot harder.

In addition, you can now refer back to the CTH formula, where I've explained that scopes below their optimal distance also decrease CTH considerably. This means that a shot with a 10x scope at 10 tiles is actually harder than a shot with a 2x scope at 10 tiles, despite them both giving the same magnification factor (1.42 for both).

Moving Target Penalty

In the new CTH system, moving targets are going to be considerably harder to hit. Depending on the direction in which the target is moving, and the distance it's managed to cover, the shooter suffers an interesting effect that is unlike anything used in the old system.

What we're going to do is, instead of making the sway radius larger, we're going to move the center point away from the target, as though it is lagging "behind" the target. This effectively decreases the chance to hit that target, increasing the chance of bullets to pass "behind" it (with the definition of "behind" being based on the direction of movement).

The strength of this "lagging" effect is based on four important factors:
A) Direction of movement
B) Distance the target has covered
C) Skill of the shooter
D) The Muzzle Sway radius

We've already got the fourth value (Muzzle Sway) which we just calculated in the previous section. So we're going to calculate the other three values before continuing.

DeltaX = Target's_Final_X - Target's_Original_X
DeltaY = Target's_Final_Y - Target's_Original_Y

This measures the X/Y difference between the target's original position and its current position. The "original position" variable is saved in the target's data at the start of its turn, so this "difference" represents the amount of X and Y tiles the target has moved since the start of its most recent turn.

MoveDistance = Square Root of ((DeltaX^2)+(DeltaY^2))

This is basic Pythagorean Theorem, and gives us the actual distance covered by the target.

MoveDirection = ArcTangent2 of (DeltaX, DeltaY)

ArcTangent2, also called atan2, is a programming concept that handles trigonometry in a gridlike environment. Basically, the result of this computation is the angle of movement compared to the Positive X axis.

Positive X in the game is going from northwest to southeast. Therefore, if the program returns 0, the target is moving southeast. If it's 180, the target is moving northwest. 90 is northeast, and 270 is southwest, etcetera.

Relative_Angle = Shooting_Angle - Move_Direction
Penalty_Multiplier = Sine of Relative_Angle

Another math-based calculation (there will be many). We're actually comparing the angle of the shot to the angle of movement, and then getting a value between -1 and 1 that describes the relation between these angles. The result is that if the target is moving TOWARDS or AWAY FROM the shooter, the multiplier is 0. If the target is moving perpendicular to the shooter's line of sight, left would be 1 and right would be -1. Other angles are in between - for instance, if the target is moving equally towards and to the left of the shot line, the multiplier is 0.5.

This is an important factor, we'll be using it to diminish the effect of target movement on our shot. In other words, if the target is moving to/away from the shooter, we'll feel no negative effect from its movement no matter how fast it is moving. We'll suffer the worst effect if it is moving perpendicular to our shot.

Finally, we need to figure out how skilled our shooter is. You know the routine by now.

Experience_Level = Shooter's_Experience_Level * 10 * MOVEMENT_EXP_LEVEL(1)
Marksmanship = Shooter's_Marksmanship * MOVEMENT_MRK(1)
Wisdom = Shooter's_Wisdom * MOVEMENT_WIS(1)
Dexterity = Shooter's_Dexterity * MOVEMENT_DEX(1)

Combined_Skill = Experience_Level + Marksmanship + Wisdom + Dexterity

Combined_Skill is divided by Divisor

I've chosen to set all skill coefficients to 1, as they all seem equally important to me in this matter. You'll see how this affects the shot in a minute.

Also I was considering adding target agility and/or experience level to this formula, but haven't done so yet so it's not included.

Calculating the effect itself

Moving at a speed requires the shooter to compensate. Depending on his skills, the shooter will take some time to adjust to this movement. However, after the target has moved a certain distance, the shooter begins to compensate for the movement, effectively "leading" the target.

A skilled shooter will begin compensating much earlier, while an unskilled shooter may be unable to compensate at all.

To simulate this, we're going to add a part of the penalty for each tile of distance moved, up to a certain number of tiles. If the target moves more than this much, the penalty begins to shrink again. If the shooter is skilled enough, and the target has moved far enough, the penalty will disappear completely.

Max_Tiles_For_Penalty = (100-Combined_Skill) / (100 / MOVEMENT_TRACKING_DIFFICULTY(20))

The result of the above mathematical formula, given the default coefficient, is 1 tile per 10 combined skill. The result tells us how many tiles the target can move before the shooter starts compensating, which is obviously based on his skill. With the default value above, a character with 50 combined skill will suffer the movement penalty for any target moving up to 10 tiles a turn. If the target moves any further, the shooter start compensating, reducing the overall movement penalty. The better the shooter, the less tiles a target can move before the shooter starts compensating. Conversely, a less skilled shooter will only start compensating after the target has moved a great distance.

How does this work? Well, as mentioned above, we add a small penalty for each tile the target moves until we reach the limit. Then, we start "compensating", so the penalty starts shrinking. If the shooter's good enough, and the target moves far enough, we can compensate enough to cause the penalty to disappear.

Penalty = 0.
For each tile below Max_Tiles_For_Penalty, do:
    Penalty is increased by MOVEMENT_PENALTY_PER_TILE(0.2).
For each tile above Max_Tiles_For_Penalty, do:
    Penalty is decreased by MOVEMENT_PENALTY_PER_TILE(0.2) / 2.

This should be fairly obvious. We add 0.2 points to the penalty for each tile, until we reach the "limit" tile. Then we add nothing. Another tile, and the penalty goes back down by 0.1, and so on for every tile moved beyond that.

Example time:

Shooter's Combined Skill = 63 (Average merc)
Max_Tiles_For_Penalty = (100-63) / (100/20) = 7

Target moves 1-6 tiles, penalty is 0.2-1.2 accordingly.
Target moves 7 tiles, penalty is 1.2 (last tile not counted)
Target moves 8-20 tiles, penalty is 1.1 to 0.0 accordingly.

Of course, moving 20 tiles in a single turn is practically the limit for most soldiers. Therefore, a shooter with combined skills of 63 is unlikely to evade the movement penalty completely, but can diminish it if the target is moving far enough, or less than 7 tiles. At no point is this shooter suffering more than a 1.2 point penalty.

Another one:

Shooter's Combined Skill = 80 (Late-Game merc)
Max_Tiles_For_Penalty = (100-80) / (100/20) = 4
Target moves 1-3 tiles, penalty is 0.2-0.6 accordingly.
Target moves 4 tiles, penalty is 0.6 (last tile not counted)
Target moves 5-10 tiles, penalty is 0.5 to 0.0 accordingly.

Here, the shooter has enough skill to evade any penalty for targets moving 10 tiles or more. This is a significant improvement. Also, at no point is this merc suffering more than a 0.6 penalty, which as you'll see soon, isn't half-bad. Of course, to achieve this, the merc needs a combination of high skills and considerably high level.

But what does this penalty mean?

The Movement Penalty, as I've said earlier, is an actual relocation of the "target center point" some distance behind the target along its movement path. In other words, the shooter is aiming for the wrong location, and thus stands a significantly lower chance of hitting the target.

Muzzle Sway and the Movement Penalty value are used as multipliers to find the distance by which to move the center point. This means that the smaller the muzzle sway, the less distance it is moved from the target's real center. However, it is smaller, and thus sufficient movement can make it unlikely, or even impossible, to hit the target at all.

Let's see how it's handled:

Centerpoint_Move_Distance = Muzzle_Sway_Radius * Movement_Penalty

At a movement penalty of 1.0, the muzzle sway circle has been moved a distance equal to its radius. This means that the tip of that circle is now touching the target's real center point. If the muzzle radius was large to begin with, this doesn't significantly reduce the chance to hit the target, but then it wasn't too good to begin with anyway. If the muzzle radius is small, this movement can reduce the chance to hit the target from 50% to 10% or even less, depending on which bodypart was aimed for, etcetera.

Movement penalties over 1.0 are more interesting. At this much deviation, the tip of the circle is no longer touching the target's center point. In fact, it may not even be touching the TARGET at all. If the circle radius was large enough, penalties over 1.0 can cause the entire circle to be shifted off the target, making it impossible to hit. A smaller radius circle hasn't moved as much distance, and may still be overlapping with some part of the target. This means that better aiming is beneficial in this case, although obviously the target is still harder to hit than it would be when stationary. Expert shooters who can reach CTH in the 90's, and equipped with the proper scope for the given range, will find that the shooting circle hasn't moved by much at all, still allowing a hit on the target, albeit not at very good odds.

Centerpoint_Move_Distance is multiplied by Penalty_Angle_Multiplier

Nearly forgot this one, didn't you? This is the multiplier we calculated when we compared the movement angle and the shooting angle. If the target is moving perpendicular to the shooting angle (90 or 270 degrees), then the multiplier is 1.0, and the penalty is unadjusted. If the angle is sharper than that, the penalty is reduced. A target running towards or away from the shooter has an angle multiplier of 0, thus negating the penalty completely.

Moving the center point

This is for 3D maths enthusiasts only. In this part, we determine the location of the new Center Point for the shot, based on all the ingredients we've gathered so far.

PenaltyX = Sine of Shooting_Angle * Centerpoint_Move_Distance
PenaltyY = Cosine of Shooting_Angle * Centerpoint_Move_Distance

Centerpoint is shifted by (PenaltyX, PenaltyY)

This new point will serve as the center of our muzzle sway. The muzzle will now sway around this point, rather than around the real center of the target.

(To be continued)

Re: New CTH System - The Formula[message #250992] Wed, 05 May 2010 19:55 Go to previous messageGo to next message

Registered:March 2006
Location: Jerusalem
(This space reserved)

Re: New CTH System - The Formula[message #250998] Wed, 05 May 2010 20:58 Go to previous message

Registered:May 2009
Location: Sweden
Weapon's_Base_CTH_Modifier is calculated from the weapon itself and its attachments. This is a flat modifier to Base CTH. I'm not sure which weapons or attachments should give such a bonus, but it's possible. Note that this allows weapons to go past the 0-33 range. It can't go below 0 however, in cases where the weapon/attachment lower the Base CTH for any reason.

Laser sights, maybe? Such sighs would assist in making a more accurate snap shot, without the need for actual aiming.
Previous Topic: "How does it work?" Part 7b: Gaining Chances to Level Up
Next Topic: "How does it work?" Part 7a: Levelling Up
Goto Forum:

Current Time: Wed Apr 24 03:29:37 EEST 2019

Total time taken to generate the page: 0.00914 seconds