mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-22 04:22:39 +01:00
Fixes projectiles always hitting. When a projectile rolled a 'miss', and returned Null as it's bodypart to hit, it was being defaulted to hit the torso. This meant that a low accuracy weapon, was not more likely to miss than a high accuracy one. In fact, low accuracy was a significant buff, because it made your shots scatter to random limbs 30% of the time. There was also no reason ever to aim for the torso, shooting the head or hands was mechanically correct. This is why mercs one handing the STS in burst mode were breaking so many hands. <img width="386" height="226" alt="image" src="https://github.com/user-attachments/assets/a0c2992f-ca5b-41cb-84c9-c6a3f74e09d0" /> This is the table of the chance to hit the torso, after this fix. Point blank shots (range 1 and 2) always hit. Almost all lasers have 2 accuracy (when wielded, if they are 2 handed) Almost all ballistics have 1 accuracy (likewise when wielded, if possible) Snipers have up to 4 accuracy. (When scoped) Burst fire imposes an accuracy malus, the STS-35 is the heaviest malus outside of admin spawn guns like the L6 SAW. burst=5, burst_accuracy=list(1,0,0,-1,-1) This means the first shot of the burst is accuracy 1, then it falls off. If you aim for a different body part, these are the base chances to miss: BP_HEAD = 70, BP_CHEST = 10, BP_GROIN = 20, BP_L_LEG = 40, BP_R_LEG = 40, BP_L_ARM = 40, BP_R_ARM = 40, BP_L_HAND = 60, BP_R_HAND = 60, BP_L_FOOT = 60, BP_R_FOOT = 60 There is a minimum 30% chance to hit, regardless of any modifiers.
64 lines
2.5 KiB
Plaintext
64 lines
2.5 KiB
Plaintext
/**
|
|
* Component used for the Firearms skill. Mobs with this component will have their weapon handling characteristics modified by their skill rank
|
|
* but only if this component is present. Essentially it provides a penalty to gun accuracy at ranks below the "Skill Diff", and a bonus for ranks above it.
|
|
*/
|
|
/datum/component/skill/firearms
|
|
/**
|
|
* Accuracy modifier to fired guns per point of "Skill Diff".
|
|
* As an "Effective increase" in tiles to the target being shot.
|
|
*/
|
|
var/accuracy_per_skill_diff = 0.5
|
|
|
|
/**
|
|
* Dispersion modifier to fired guns per point of "Skill Diff".
|
|
* As an arc-length in Degrees.
|
|
*/
|
|
var/dispersion_per_skill_diff = 30
|
|
|
|
/// %chance per point of "Skill Diff" to fumble changing a weapon's safety.
|
|
var/safety_fumble_per_skill_diff = 15
|
|
|
|
/// %chance for a completely untrained person to shoot themself in the foot accidentally.
|
|
var/footgun_chance = 1
|
|
|
|
/datum/component/skill/firearms/Initialize(var/level = SKILL_LEVEL_UNFAMILIAR)
|
|
. = ..()
|
|
if (!parent)
|
|
return
|
|
|
|
RegisterSignal(parent, COMSIG_BEFORE_GUN_FIRE, PROC_REF(handle_accuracy), override = TRUE)
|
|
RegisterSignal(parent, COMSIG_GUN_TOGGLE_FIRING_MODE, PROC_REF(safety_fumble), override = TRUE)
|
|
|
|
/datum/component/skill/firearms/Destroy()
|
|
if (!parent)
|
|
return ..()
|
|
|
|
UnregisterSignal(parent, COMSIG_BEFORE_GUN_FIRE)
|
|
UnregisterSignal(parent, COMSIG_GUN_TOGGLE_FIRING_MODE)
|
|
return ..()
|
|
|
|
/datum/component/skill/firearms/proc/handle_accuracy(mob/shooter, accuracy_decrease, dispersion_increase)
|
|
SIGNAL_HANDLER
|
|
var/skill_diff = skill_diff_reference - skill_level
|
|
|
|
// Count the target as being one tile further away from the shooter
|
|
// per the difference between a skilled professional, and the shooter's skill level
|
|
*accuracy_decrease = *accuracy_decrease + accuracy_per_skill_diff * skill_diff
|
|
|
|
// Unskilled shooters get an increased firing arc for their guns
|
|
// to a maximum of 30 degrees when fully untrained.
|
|
*dispersion_increase = *dispersion_increase + dispersion_per_skill_diff * skill_diff
|
|
|
|
/datum/component/skill/firearms/proc/safety_fumble(mob/shooter, obj/item/gun/shoota, cancelled)
|
|
SIGNAL_HANDLER
|
|
if (cancelled || skill_level >= skill_diff_reference)
|
|
return // Trained and up will never fumble the safety. Except if morale has anything to say about that...
|
|
|
|
if (!prob(safety_fumble_per_skill_diff * (skill_diff_reference - skill_level)))
|
|
return // if they pass the skill check.
|
|
|
|
*cancelled = TRUE
|
|
shooter.visible_message(
|
|
SPAN_DANGER("\The [shooter] fumbles with \the [shoota]'s safety!"),
|
|
SPAN_DANGER("You fumble with \the [shoota]'s safety!"))
|