mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-24 05:30:05 +01:00
[MIRROR] Riot armor and helmets (and similar gear) protect against more melee-based attacks (like RNG punches), bottles aren't near guaranteed knockdowns (#26633)
* Riot armor and helmets (and similar gear) protect against more melee-based attacks (like RNG punches), bottles aren't near guaranteed knockdowns (#81365) <!-- Write **BELOW** The Headers and **ABOVE** The comments else it may not be viewable. --> <!-- You can view Contributing.MD for a detailed description of the pull request process. --> partially includes Syndicate modsuits and other suits with a module) TRAIT_SHOVE_KNOCKDOWN_BLOCKED is now called TRAIT_BRAWLING_KNOCKDOWN_BLOCKED. This is possessed by riot suits, SWAT suits and now **plate armor**. Not the chaplain variety, because fuck them I guess. (this was apparently deliberate so don't complain to me, okay?) Anyone with this trait is now unable to be knocked down by; - Pure RNG on blunt objects attacks to the chest (Probability is otherwise altered by melee armor already) - Unarmed punches, both RNG and deterministic - Bodies thrown at them. Instead, dealing stamina damage and causing them to become staggered. A new trait called TRAIT_HEAD_INJURY_BLOCKED, which protects from various head injury related effects. This is possessed by riot helmets, SWAT helmets, plate helmets, hardhats and applied to MODsuits with armor boosters activated/the infiltrator suit while active. The trait is also granted to anyone wearing a modsuit with the Head Protection module installed. This can be printed from round start, and comes pre-installed into all the engineering modsuits, security moduits, research modsuit and magnate modsuit. (I had to bump up the security modsuit complexity a bit to put it in iunno if we have a policy about that) Anyone with this trait is protected against: - Bottle smashes to the head. - RNG Blunt force trauma to the head by blunt objects (Probability is otherwise altered by melee armor already) - Partially protects against getting your spine snapped during a bad tackle (this used to be a check ONLY for the riot helmet or hardhat) The bottle smash's chance of a knockdown is based on the force and knockdown duration of the bottle, altered by relevant head melee armor. It's no longer basically guaranteed due to weird math that would determine whether or not you were knocked down only if your armor exceeded certain values or not. Any instance that would check either for riot armor or riot helmets instead checks for the new traits. People weren't particularly happy with the possibility of getting ownzoned by a naked assistant or random toolbox-wielding tider while in dedicated melee protection armor as a result of pure RNG jank. [There was a whole thread here about it](https://tgstation13.org/phpBB/viewtopic.php?f=83&t=35645) with regards to unarmed combat. If you're in riot gear, you should feel like you can confidently combat improvised/blunt weapons at a cost of general protection from the more serious dangers to your wellbeing (AKA lead poisoning or heatstroke. Get it....it's bullets and lasers...) For some reason, bottle smash knockdowns, despite using the values just...conveniently don't get blocked by armor except for extreme values? If at all? I felt like this was really weird for something with such a hefty and fairly powerful knockdown effect, particularly one you can lob at someones head at range. I remember, way back when I first started playing, that this was a feature that used to stun, and one I used a lot to get cheap kills. The amount of bullshit stuns I got on people with it still haunt me to this day. It hasn't improved in the current era, despite being a knockdown, simply because any knockdown still takes several seconds to exit. An arbitrarily low knockdown is still a several second one. It's time to bring this in line with similar equipment. Rather than using flat values that are _clearly_ meant to be only applicable to riot armor the decade ago that the code was written, let's use traits instead. That's way better than relying on magic numbers that may become irrelevant when the code around it changes, which anyone touching that code may not even be aware existed. Since we're using a trait, we can actually allow modsuits to occasionally fill defensive niches that aren't strictly armor values. Handy. <!-- If your PR modifies aspects of the game that can be concretely observed by players or admins you should add a changelog. If your change does NOT meet this description, remove this section. Be sure to properly mark your PRs to prevent unnecessary GBP loss. You can read up on GBP and it's effects on PRs in the tgstation guides for contributors. Please note that maintainers freely reserve the right to remove and add tags should they deem it appropriate. You can attempt to finagle the system all you want, but it's best to shoot for clear communication right off the bat. --> 🆑 balance: Nanotrasen, in direct response to the increasing danger posed by wannabe martial artists and rioters in the fringes of the Spinward Sector, have upgraded the impact dampeners found in their riot armor. Staff have also started to rediscover the value of medieval armor; it isn't particularly easy to topple a knight in a suit of plate with just your fists. balance: Melee-focused armor is now more able to protect you from various RNG-based knockdowns, such as critical hits from punches (as well as the ones applied through the staggered status), shoves, critical hits with a blunt weapon to the chest, and body throws. balance: Melee-focused helmets also protect you from head injuries, such as bottle smashes, accidentally hitting something dense during a tackle, and critical hits from a blunt weapon to the head. balance: Bottlesmash knockdowns are less reliable in general. add: A new module, the Safety-First Head Protection module, protects you from head trauma! Available in most modsuits expected to take hits to the head often. And from roundstart exofabricators. /🆑 <!-- Both 🆑's are required for the changelog to work! You can put your name to the right of the first 🆑 if you want to overwrite your GitHub username as author ingame. --> <!-- You can use multiple of the same prefix (they're only used for the icon ingame) and delete the unneeded ones. Despite some of the tags, changelogs should generally represent how a player might be affected by the changes rather than a summary of the PR's contents. --> * oh well --------- Co-authored-by: necromanceranne <40847847+necromanceranne@users.noreply.github.com> Co-authored-by: Useroth <37159550+Useroth@users.noreply.github.com>
This commit is contained in:
co-authored by
necromanceranne
Useroth
parent
11ecffbf8d
commit
a0d0f8a7cd
@@ -211,8 +211,10 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
|
||||
#define TRAIT_BLOOD_DEFICIENCY "blood_deficiency"
|
||||
#define TRAIT_JOLLY "jolly"
|
||||
#define TRAIT_NOCRITDAMAGE "no_crit"
|
||||
/// Prevents shovies against a dense object from knocking them down.
|
||||
#define TRAIT_SHOVE_KNOCKDOWN_BLOCKED "shove_knockdown_blocked"
|
||||
/// Prevents shovies and some strong blows such as unarmed punches and (unreliably) tackles the owner down
|
||||
#define TRAIT_BRAWLING_KNOCKDOWN_BLOCKED "brawling_knockdown_blocked"
|
||||
/// Prevents some severe head injuries being sustained from heavy collisions or blunt force injuries.
|
||||
#define TRAIT_HEAD_INJURY_BLOCKED "head_injury_blocked"
|
||||
/// Prevents staggering.
|
||||
#define TRAIT_NO_STAGGER "no_stagger"
|
||||
/// Getting hit by thrown movables won't push you away
|
||||
|
||||
@@ -140,6 +140,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
"TRAIT_BONSAI" = TRAIT_BONSAI,
|
||||
"TRAIT_BOOZE_SLIDER" = TRAIT_BOOZE_SLIDER,
|
||||
"TRAIT_BRAINWASHING" = TRAIT_BRAINWASHING,
|
||||
"TRAIT_BRAWLING_KNOCKDOWN_BLOCKED" = TRAIT_BRAWLING_KNOCKDOWN_BLOCKED,
|
||||
"TRAIT_BYPASS_EARLY_IRRADIATED_CHECK" = TRAIT_BYPASS_EARLY_IRRADIATED_CHECK,
|
||||
"TRAIT_BYPASS_MEASURES" = TRAIT_BYPASS_MEASURES,
|
||||
"TRAIT_CANNOT_BE_UNBUCKLED" = TRAIT_CANNOT_BE_UNBUCKLED,
|
||||
@@ -237,6 +238,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
"TRAIT_HAS_CRANIAL_FISSURE" = TRAIT_HAS_CRANIAL_FISSURE,
|
||||
"TRAIT_HAS_MARKINGS" = TRAIT_HAS_MARKINGS,
|
||||
"TRAIT_HATED_BY_DOGS" = TRAIT_HATED_BY_DOGS,
|
||||
"TRAIT_HEAD_INJURY_BLOCKED" = TRAIT_HEAD_INJURY_BLOCKED,
|
||||
"TRAIT_HEALS_FROM_CARP_RIFTS" = TRAIT_HEALS_FROM_CARP_RIFTS,
|
||||
"TRAIT_HEALS_FROM_CULT_PYLONS" = TRAIT_HEALS_FROM_CULT_PYLONS,
|
||||
"TRAIT_HEAR_THROUGH_DARKNESS" = TRAIT_HEAR_THROUGH_DARKNESS,
|
||||
@@ -401,7 +403,6 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
"TRAIT_SHAVED" = TRAIT_SHAVED,
|
||||
"TRAIT_SHIFTY_EYES" = TRAIT_SHIFTY_EYES,
|
||||
"TRAIT_SHOCKIMMUNE" = TRAIT_SHOCKIMMUNE,
|
||||
"TRAIT_SHOVE_KNOCKDOWN_BLOCKED" = TRAIT_SHOVE_KNOCKDOWN_BLOCKED,
|
||||
"TRAIT_SIGN_LANG" = TRAIT_SIGN_LANG,
|
||||
"TRAIT_PAPER_MASTER" = TRAIT_PAPER_MASTER,
|
||||
"TRAIT_SILENT_FOOTSTEPS" = TRAIT_SILENT_FOOTSTEPS,
|
||||
|
||||
@@ -390,7 +390,7 @@
|
||||
glasses.add_mob_blood(src)
|
||||
update_worn_glasses()
|
||||
|
||||
if(!attacking_item.get_sharpness() && armor_block < 50)
|
||||
if(!attacking_item.get_sharpness() && !HAS_TRAIT(src, TRAIT_HEAD_INJURY_BLOCKED))
|
||||
if(prob(damage_done))
|
||||
adjustOrganLoss(ORGAN_SLOT_BRAIN, 20)
|
||||
if(stat == CONSCIOUS)
|
||||
@@ -420,7 +420,7 @@
|
||||
w_uniform.add_mob_blood(src)
|
||||
update_worn_undersuit()
|
||||
|
||||
if(stat == CONSCIOUS && !attacking_item.get_sharpness() && armor_block < 50)
|
||||
if(stat == CONSCIOUS && !attacking_item.get_sharpness() && !HAS_TRAIT(src, TRAIT_BRAWLING_KNOCKDOWN_BLOCKED))
|
||||
if(prob(damage_done))
|
||||
visible_message(
|
||||
span_danger("[src] is knocked down!"),
|
||||
|
||||
@@ -400,7 +400,7 @@
|
||||
defense_mod += 2
|
||||
if(tackle_target.mob_negates_gravity())
|
||||
defense_mod += 1
|
||||
if(HAS_TRAIT(tackle_target, TRAIT_SHOVE_KNOCKDOWN_BLOCKED)) // riot armor and such
|
||||
if(HAS_TRAIT(tackle_target, TRAIT_BRAWLING_KNOCKDOWN_BLOCKED)) // riot armor and such
|
||||
defense_mod += 5
|
||||
|
||||
var/obj/item/organ/external/tail/lizard/el_tail = tackle_target.get_organ_slot(ORGAN_SLOT_EXTERNAL_TAIL)
|
||||
@@ -451,7 +451,7 @@
|
||||
attack_mod += 15
|
||||
human_sacker.adjustStaminaLoss(100) //AHAHAHAHAHAHAHAHA
|
||||
|
||||
if(HAS_TRAIT(human_sacker, TRAIT_SHOVE_KNOCKDOWN_BLOCKED)) // tackling with riot specialized armor, like riot armor, is effective but tiring
|
||||
if(HAS_TRAIT(human_sacker, TRAIT_BRAWLING_KNOCKDOWN_BLOCKED)) // tackling with riot specialized armor, like riot armor, is effective but tiring
|
||||
attack_mod += 2
|
||||
human_sacker.adjustStaminaLoss(20)
|
||||
|
||||
@@ -499,14 +499,10 @@
|
||||
var/danger_zone = (speed - 1) * 13 // for every extra speed we have over 1, take away 13 of the safest chance
|
||||
danger_zone = max(min(danger_zone, 100), 1)
|
||||
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/S = user
|
||||
var/head_slot = S.get_item_by_slot(ITEM_SLOT_HEAD)
|
||||
var/suit_slot = S.get_item_by_slot(ITEM_SLOT_OCLOTHING)
|
||||
if(head_slot && (istype(head_slot,/obj/item/clothing/head/helmet) || istype(head_slot,/obj/item/clothing/head/utility/hardhat)))
|
||||
oopsie_mod -= 6
|
||||
if(suit_slot && (istype(suit_slot,/obj/item/clothing/suit/armor/riot)))
|
||||
oopsie_mod -= 6
|
||||
if(HAS_TRAIT(user, TRAIT_BRAWLING_KNOCKDOWN_BLOCKED))
|
||||
oopsie_mod -= 6
|
||||
if(HAS_TRAIT(user, TRAIT_HEAD_INJURY_BLOCKED))
|
||||
oopsie_mod -= 6
|
||||
|
||||
if(HAS_TRAIT(user, TRAIT_CLUMSY))
|
||||
oopsie_mod += 6 //honk!
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
var/hat_type = "yellow"
|
||||
///Whether the headlamp is on or off.
|
||||
var/on = FALSE
|
||||
|
||||
clothing_traits = list(TRAIT_HEAD_INJURY_BLOCKED)
|
||||
|
||||
/datum/armor/utility_hardhat
|
||||
melee = 15
|
||||
@@ -224,6 +224,7 @@
|
||||
light_color = "#fff2bf"
|
||||
worn_y_offset = 1
|
||||
dog_fashion = /datum/dog_fashion/head/pumpkin/unlit
|
||||
clothing_traits = list()
|
||||
|
||||
/obj/item/clothing/head/utility/hardhat/pumpkinhead/set_light_on(new_value)
|
||||
. = ..()
|
||||
@@ -277,6 +278,6 @@
|
||||
flags_inv = 0
|
||||
armor_type = /datum/armor/none
|
||||
light_range = 1 //luminosity when on
|
||||
|
||||
clothing_traits = list()
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/reindeer
|
||||
|
||||
@@ -184,6 +184,7 @@
|
||||
visor_flags_inv = HIDEFACE|HIDESNOUT
|
||||
flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF
|
||||
visor_flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF
|
||||
clothing_traits = list(TRAIT_HEAD_INJURY_BLOCKED)
|
||||
|
||||
/datum/armor/toggleable_riot
|
||||
melee = 50
|
||||
@@ -247,6 +248,7 @@
|
||||
strip_delay = 80
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
dog_fashion = null
|
||||
clothing_traits = list(TRAIT_HEAD_INJURY_BLOCKED)
|
||||
|
||||
/datum/armor/helmet_swat
|
||||
melee = 40
|
||||
@@ -394,6 +396,7 @@
|
||||
flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH
|
||||
strip_delay = 80
|
||||
dog_fashion = null
|
||||
clothing_traits = list(TRAIT_HEAD_INJURY_BLOCKED)
|
||||
|
||||
/datum/armor/helmet_knight
|
||||
melee = 50
|
||||
|
||||
@@ -306,7 +306,7 @@
|
||||
armor_type = /datum/armor/armor_riot
|
||||
strip_delay = 80
|
||||
equip_delay_other = 60
|
||||
clothing_traits = list(TRAIT_SHOVE_KNOCKDOWN_BLOCKED)
|
||||
clothing_traits = list(TRAIT_BRAWLING_KNOCKDOWN_BLOCKED)
|
||||
|
||||
/datum/armor/armor_riot
|
||||
melee = 50
|
||||
@@ -410,7 +410,7 @@
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT
|
||||
slowdown = 0.7
|
||||
body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
|
||||
clothing_traits = list(TRAIT_SHOVE_KNOCKDOWN_BLOCKED)
|
||||
clothing_traits = list(TRAIT_BRAWLING_KNOCKDOWN_BLOCKED)
|
||||
|
||||
|
||||
//All of the armor below is mostly unused
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
// as a wise man once wrote: "pull over that ass too fat"
|
||||
REMOVE_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT)
|
||||
// that'd be a too cheeky shield bashing strat
|
||||
ADD_TRAIT(src, TRAIT_SHOVE_KNOCKDOWN_BLOCKED, INNATE_TRAIT)
|
||||
ADD_TRAIT(src, TRAIT_BRAWLING_KNOCKDOWN_BLOCKED, INNATE_TRAIT)
|
||||
AddComponent(/datum/component/seethrough_mob)
|
||||
|
||||
/mob/living/carbon/alien/adult/royal/on_lying_down(new_lying_angle)
|
||||
|
||||
@@ -85,12 +85,18 @@
|
||||
span_userdanger("You violently crash into [victim][extra_speed ? " extra hard" : ""], but [victim] managed to block the worst of it!"))
|
||||
log_combat(src, victim, "crashed into and was blocked by")
|
||||
return
|
||||
else if(HAS_TRAIT(src, TRAIT_BRAWLING_KNOCKDOWN_BLOCKED))
|
||||
victim.take_bodypart_damage(10 + 5 * extra_speed, check_armor = TRUE, wound_bonus = extra_speed * 5)
|
||||
victim.apply_damage(10 + 10 * extra_speed, STAMINA)
|
||||
victim.adjust_staggered_up_to(STAGGERED_SLOWDOWN_LENGTH * 2, 10 SECONDS)
|
||||
visible_message(span_danger("[src] crashes into [victim][extra_speed ? " really hard" : ""], but [victim] was able to stay on their feet!"),\
|
||||
span_userdanger("You violently crash into [victim][extra_speed ? " extra hard" : ""], but [victim] managed to stay on their feet!"))
|
||||
else
|
||||
victim.Paralyze(2 SECONDS)
|
||||
victim.take_bodypart_damage(10 + 5 * extra_speed, check_armor = TRUE, wound_bonus = extra_speed * 5)
|
||||
visible_message(span_danger("[src] crashes into [victim][extra_speed ? " really hard" : ""], knocking them both over!"),\
|
||||
span_userdanger("You violently crash into [victim][extra_speed ? " extra hard" : ""]!"))
|
||||
log_combat(src, victim, "crashed into")
|
||||
log_combat(src, victim, "crashed into")
|
||||
|
||||
if(oof_noise)
|
||||
playsound(src,'sound/weapons/punch1.ogg',50,TRUE)
|
||||
|
||||
@@ -1229,16 +1229,15 @@ GLOBAL_LIST_EMPTY(features_by_species)
|
||||
log_combat(user, target, "punched")
|
||||
|
||||
//If we rolled a punch high enough to hit our stun threshold, or our target is staggered and they have at least 40 damage+stamina loss, we knock them down
|
||||
if((target.stat != DEAD) && prob(limb_accuracy) || (target.stat != DEAD) && staggered && (target.getStaminaLoss() + user.getBruteLoss()) >= 40)
|
||||
target.visible_message(span_danger("[user] knocks [target] down!"), \
|
||||
span_userdanger("You're knocked down by [user]!"), span_hear("You hear aggressive shuffling followed by a loud thud!"), COMBAT_MESSAGE_RANGE, user)
|
||||
to_chat(user, span_danger("You knock [target] down!"))
|
||||
/* SKYRAT EDIT REMOVAL - Less combat lethality and hard stuns
|
||||
var/knockdown_duration = 4 SECONDS + (target.getStaminaLoss() + (target.getBruteLoss()*0.5))*0.8 //50 total damage = 4 second base stun + 4 second stun modifier = 8 second knockdown duration
|
||||
target.apply_effect(knockdown_duration, EFFECT_KNOCKDOWN, armor_block)
|
||||
SKYRAT EDIT REMOVAL END */
|
||||
target.StaminaKnockdown(20) //SKYRAT EDIT ADDITION
|
||||
log_combat(user, target, "got a stun punch with their previous punch")
|
||||
//This does not work against opponents who are knockdown immune, such as from wearing riot armor.
|
||||
if(!HAS_TRAIT(src, TRAIT_BRAWLING_KNOCKDOWN_BLOCKED))
|
||||
if((target.stat != DEAD) && prob(limb_accuracy) || (target.stat != DEAD) && staggered && (target.getStaminaLoss() + user.getBruteLoss()) >= 40)
|
||||
target.visible_message(span_danger("[user] knocks [target] down!"), \
|
||||
span_userdanger("You're knocked down by [user]!"), span_hear("You hear aggressive shuffling followed by a loud thud!"), COMBAT_MESSAGE_RANGE, user)
|
||||
to_chat(user, span_danger("You knock [target] down!"))
|
||||
var/knockdown_duration = 4 SECONDS + (target.getStaminaLoss() + (target.getBruteLoss()*0.5))*0.8 //50 total damage = 4 second base stun + 4 second stun modifier = 8 second knockdown duration
|
||||
target.apply_effect(knockdown_duration, EFFECT_KNOCKDOWN, armor_block)
|
||||
log_combat(user, target, "got a stun punch with their previous punch")
|
||||
|
||||
/datum/species/proc/disarm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
|
||||
if(user.body_position != STANDING_UP)
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
return
|
||||
if(!(shove_flags & SHOVE_KNOCKDOWN_BLOCKED))
|
||||
target.Knockdown(SHOVE_KNOCKDOWN_HUMAN)
|
||||
if(!HAS_TRAIT(src, TRAIT_SHOVE_KNOCKDOWN_BLOCKED))
|
||||
if(!HAS_TRAIT(src, TRAIT_BRAWLING_KNOCKDOWN_BLOCKED))
|
||||
Knockdown(SHOVE_KNOCKDOWN_COLLATERAL)
|
||||
target.visible_message(span_danger("[shover] shoves [target.name] into [name]!"),
|
||||
span_userdanger("You're shoved into [name] by [shover]!"), span_hear("You hear aggressive shuffling followed by a loud thud!"), COMBAT_MESSAGE_RANGE, src)
|
||||
|
||||
@@ -756,7 +756,7 @@
|
||||
. |= SHOVE_CAN_MOVE
|
||||
if(!buckled)
|
||||
. |= SHOVE_CAN_HIT_SOMETHING
|
||||
if(HAS_TRAIT(src, TRAIT_SHOVE_KNOCKDOWN_BLOCKED))
|
||||
if(HAS_TRAIT(src, TRAIT_BRAWLING_KNOCKDOWN_BLOCKED))
|
||||
. |= SHOVE_KNOCKDOWN_BLOCKED
|
||||
|
||||
///Send the chat feedback message for shoving
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
TRAIT_MADNESS_IMMUNE,
|
||||
TRAIT_MARTIAL_ARTS_IMMUNE,
|
||||
TRAIT_NOFIRE_SPREAD,
|
||||
TRAIT_SHOVE_KNOCKDOWN_BLOCKED,
|
||||
TRAIT_BRAWLING_KNOCKDOWN_BLOCKED,
|
||||
)
|
||||
|
||||
add_traits(traits_to_apply, ROUNDSTART_TRAIT)
|
||||
|
||||
@@ -698,7 +698,7 @@
|
||||
a few years out of date, leading to an overall lower capacity for modules."
|
||||
default_skin = "security"
|
||||
armor_type = /datum/armor/mod_theme_security
|
||||
complexity_max = DEFAULT_MAX_COMPLEXITY - 3
|
||||
complexity_max = DEFAULT_MAX_COMPLEXITY - 2
|
||||
slowdown_inactive = 1
|
||||
slowdown_active = 0.5
|
||||
allowed_suit_storage = list(
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
/obj/item/mod/module/flashlight,
|
||||
/obj/item/mod/module/tether,
|
||||
/obj/item/mod/module/magboot,
|
||||
/obj/item/mod/module/headprotector,
|
||||
)
|
||||
default_pins = list(
|
||||
/obj/item/mod/module/magboot,
|
||||
@@ -72,6 +73,7 @@
|
||||
/obj/item/mod/module/magboot,
|
||||
/obj/item/mod/module/t_ray,
|
||||
/obj/item/mod/module/quick_carry,
|
||||
/obj/item/mod/module/headprotector,
|
||||
)
|
||||
default_pins = list(
|
||||
/obj/item/mod/module/magboot,
|
||||
@@ -87,6 +89,7 @@
|
||||
/obj/item/mod/module/rad_protection,
|
||||
/obj/item/mod/module/flashlight,
|
||||
/obj/item/mod/module/jetpack,
|
||||
/obj/item/mod/module/headprotector,
|
||||
)
|
||||
default_pins = list(
|
||||
/obj/item/mod/module/magboot/advanced,
|
||||
@@ -153,6 +156,7 @@
|
||||
/obj/item/mod/module/flashlight,
|
||||
/obj/item/mod/module/circuit,
|
||||
/obj/item/mod/module/t_ray,
|
||||
/obj/item/mod/module/headprotector,
|
||||
)
|
||||
|
||||
/obj/item/mod/control/pre_equipped/security
|
||||
@@ -165,6 +169,7 @@
|
||||
/obj/item/mod/module/criminalcapture,
|
||||
/obj/item/mod/module/dispenser/mirage,
|
||||
/obj/item/mod/module/quick_cuff,
|
||||
/obj/item/mod/module/headprotector,
|
||||
)
|
||||
|
||||
/obj/item/mod/control/pre_equipped/safeguard
|
||||
@@ -179,6 +184,7 @@
|
||||
/obj/item/mod/module/projectile_dampener,
|
||||
/obj/item/mod/module/pepper_shoulders,
|
||||
/obj/item/mod/module/quick_cuff,
|
||||
/obj/item/mod/module/headprotector,
|
||||
)
|
||||
default_pins = list(
|
||||
/obj/item/mod/module/jetpack,
|
||||
@@ -194,6 +200,7 @@
|
||||
/obj/item/mod/module/jetpack/advanced,
|
||||
/obj/item/mod/module/pathfinder,
|
||||
/obj/item/mod/module/quick_cuff,
|
||||
/obj/item/mod/module/headprotector,
|
||||
)
|
||||
default_pins = list(
|
||||
/obj/item/mod/module/jetpack/advanced,
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
module_type = MODULE_TOGGLE
|
||||
active_power_cost = DEFAULT_CHARGE_DRAIN * 0.3
|
||||
removable = FALSE
|
||||
incompatible_modules = list(/obj/item/mod/module/armor_booster, /obj/item/mod/module/welding)
|
||||
incompatible_modules = list(/obj/item/mod/module/armor_booster, /obj/item/mod/module/welding, /obj/item/mod/module/headprotector)
|
||||
cooldown_time = 0.5 SECONDS
|
||||
overlay_state_inactive = "module_armorbooster_off"
|
||||
overlay_state_active = "module_armorbooster_on"
|
||||
@@ -26,6 +26,8 @@
|
||||
var/list/armor_mod = /datum/armor/mod_module_armor_boost
|
||||
/// List of parts of the suit that are spaceproofed, for giving them back the pressure protection.
|
||||
var/list/spaceproofed = list()
|
||||
/// List of traits added when the mod is activated
|
||||
var/list/traits_to_add = list(TRAIT_HEAD_INJURY_BLOCKED)
|
||||
|
||||
/datum/armor/mod_module_armor_boost
|
||||
melee = 25
|
||||
@@ -50,6 +52,7 @@
|
||||
actual_speed_added = max(0, min(mod.slowdown_active, speed_added))
|
||||
mod.slowdown -= actual_speed_added
|
||||
mod.wearer.update_equipment_speed_mods()
|
||||
mod.wearer.add_traits(traits_to_add, MOD_TRAIT)
|
||||
var/list/parts = mod.mod_parts + mod
|
||||
for(var/obj/item/part as anything in parts)
|
||||
part.set_armor(part.get_armor().add_other_armor(armor_mod))
|
||||
@@ -69,6 +72,7 @@
|
||||
balloon_alert(mod.wearer, "armor retracts, EVA ready")
|
||||
mod.slowdown += actual_speed_added
|
||||
mod.wearer.update_equipment_speed_mods()
|
||||
mod.wearer.remove_traits(traits_to_add, MOD_TRAIT)
|
||||
var/list/parts = mod.mod_parts + mod
|
||||
for(var/obj/item/part as anything in parts)
|
||||
part.set_armor(part.get_armor().subtract_other_armor(armor_mod))
|
||||
@@ -483,12 +487,15 @@
|
||||
/obj/item/mod/module/infiltrator
|
||||
name = "MOD infiltration core programs module"
|
||||
desc = "The primary stealth systems operating within the suit. Utilizing electromagnetic signals, \
|
||||
the wearer simply cannot be observed closely, or heard clearly by those around them."
|
||||
the wearer simply cannot be observed closely, or heard clearly by those around them.\
|
||||
It also contains some dampening systems to help protect a user from blows to the head."
|
||||
icon_state = "infiltrator"
|
||||
complexity = 0
|
||||
removable = FALSE
|
||||
idle_power_cost = DEFAULT_CHARGE_DRAIN * 0
|
||||
incompatible_modules = list(/obj/item/mod/module/infiltrator, /obj/item/mod/module/armor_booster, /obj/item/mod/module/welding)
|
||||
incompatible_modules = list(/obj/item/mod/module/infiltrator, /obj/item/mod/module/armor_booster, /obj/item/mod/module/welding, /obj/item/mod/module/headprotector)
|
||||
/// List of traits added when the suit is activated
|
||||
var/list/traits_to_add = list(TRAIT_SILENT_FOOTSTEPS, TRAIT_UNKNOWN, TRAIT_HEAD_INJURY_BLOCKED)
|
||||
|
||||
/obj/item/mod/module/infiltrator/on_install()
|
||||
mod.item_flags |= EXAMINE_SKIP
|
||||
@@ -497,11 +504,11 @@
|
||||
mod.item_flags &= ~EXAMINE_SKIP
|
||||
|
||||
/obj/item/mod/module/infiltrator/on_suit_activation()
|
||||
mod.wearer.add_traits(list(TRAIT_SILENT_FOOTSTEPS, TRAIT_UNKNOWN), MOD_TRAIT)
|
||||
mod.wearer.add_traits(traits_to_add, MOD_TRAIT)
|
||||
mod.helmet.flash_protect = FLASH_PROTECTION_WELDER
|
||||
|
||||
/obj/item/mod/module/infiltrator/on_suit_deactivation(deleting = FALSE)
|
||||
mod.wearer.remove_traits(list(TRAIT_SILENT_FOOTSTEPS, TRAIT_UNKNOWN), MOD_TRAIT)
|
||||
mod.wearer.remove_traits(traits_to_add, MOD_TRAIT)
|
||||
if(deleting)
|
||||
return
|
||||
mod.helmet.flash_protect = initial(mod.helmet.flash_protect)
|
||||
|
||||
@@ -204,6 +204,24 @@
|
||||
rcd_scan(src, fade_time = 10 SECONDS)
|
||||
drain_power(use_power_cost)
|
||||
|
||||
///Safety-First Head Protection - Protects your brain matter from sudden impacts.
|
||||
/obj/item/mod/module/headprotector
|
||||
name = "MOD Safety-First Head Protection module"
|
||||
desc = "A series of dampening plates are installed along the back and upper areas of \
|
||||
the helmet. These plates absorb abrupt kinetic shocks delivered to the skull. \
|
||||
The bulk of this module prevents it from being installed in any suit that is capable \
|
||||
of combat armor adjustments. However, the rudimentry nature of the module makes it \
|
||||
relatively easy to install into most other suits."
|
||||
icon_state = "welding"
|
||||
complexity = 1
|
||||
incompatible_modules = list(/obj/item/mod/module/armor_booster, /obj/item/mod/module/infiltrator)
|
||||
|
||||
/obj/item/mod/module/constructor/on_suit_activation()
|
||||
ADD_TRAIT(mod.wearer, TRAIT_HEAD_INJURY_BLOCKED, MOD_TRAIT)
|
||||
|
||||
/obj/item/mod/module/constructor/on_suit_deactivation(deleting = FALSE)
|
||||
REMOVE_TRAIT(mod.wearer, TRAIT_HEAD_INJURY_BLOCKED, MOD_TRAIT)
|
||||
|
||||
///Mister - Sprays water over an area.
|
||||
/obj/item/mod/module/mister
|
||||
name = "MOD water mister module"
|
||||
|
||||
@@ -587,10 +587,10 @@
|
||||
incompatible_modules = list(/obj/item/mod/module/shove_blocker)
|
||||
|
||||
/obj/item/mod/module/shove_blocker/on_suit_activation()
|
||||
mod.wearer.add_traits(list(TRAIT_SHOVE_KNOCKDOWN_BLOCKED, TRAIT_NO_STAGGER, TRAIT_NO_THROW_HITPUSH), MOD_TRAIT)
|
||||
mod.wearer.add_traits(list(TRAIT_BRAWLING_KNOCKDOWN_BLOCKED, TRAIT_NO_STAGGER, TRAIT_NO_THROW_HITPUSH), MOD_TRAIT)
|
||||
|
||||
/obj/item/mod/module/shove_blocker/on_suit_deactivation(deleting = FALSE)
|
||||
mod.wearer.remove_traits(list(TRAIT_SHOVE_KNOCKDOWN_BLOCKED, TRAIT_NO_STAGGER, TRAIT_NO_THROW_HITPUSH), MOD_TRAIT)
|
||||
mod.wearer.remove_traits(list(TRAIT_BRAWLING_KNOCKDOWN_BLOCKED, TRAIT_NO_STAGGER, TRAIT_NO_THROW_HITPUSH), MOD_TRAIT)
|
||||
|
||||
/obj/item/mod/module/shove_blocker/locked
|
||||
name = "superglued MOD bulwark module"
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
var/obj/item/bodypart/affecting = user.zone_selected //Find what the player is aiming at
|
||||
|
||||
var/armor_block = 0 //Get the target's armor values for normal attack damage.
|
||||
var/armor_duration = 0 //The more force the bottle has, the longer the duration.
|
||||
var/knockdown_effectiveness = 0 //The more force the bottle has, the longer the duration.
|
||||
|
||||
//Calculating duration and calculating damage.
|
||||
if(ishuman(target))
|
||||
@@ -95,23 +95,23 @@
|
||||
if(istype(H.head, /obj/item/clothing/head) && affecting == BODY_ZONE_HEAD)
|
||||
headarmor = H.head.get_armor_rating(MELEE)
|
||||
//Calculate the knockdown duration for the target.
|
||||
armor_duration = (bottle_knockdown_duration - headarmor) + force
|
||||
knockdown_effectiveness = (bottle_knockdown_duration - headarmor) + force
|
||||
|
||||
else
|
||||
//Only humans can have armor, right?
|
||||
armor_block = living_target.run_armor_check(affecting, MELEE)
|
||||
if(affecting == BODY_ZONE_HEAD)
|
||||
armor_duration = bottle_knockdown_duration + force
|
||||
knockdown_effectiveness = bottle_knockdown_duration + force
|
||||
//Apply the damage!
|
||||
armor_block = min(90,armor_block)
|
||||
living_target.apply_damage(force, BRUTE, affecting, armor_block)
|
||||
|
||||
// You are going to knock someone down for longer if they are not wearing a helmet.
|
||||
var/head_attack_message = ""
|
||||
if(affecting == BODY_ZONE_HEAD && iscarbon(target))
|
||||
if(affecting == BODY_ZONE_HEAD && iscarbon(target) && !HAS_TRAIT(target, TRAIT_HEAD_INJURY_BLOCKED))
|
||||
head_attack_message = " on the head"
|
||||
if(armor_duration)
|
||||
living_target.apply_effect(min(armor_duration, 200) , EFFECT_KNOCKDOWN)
|
||||
if(knockdown_effectiveness && prob(knockdown_effectiveness))
|
||||
living_target.apply_effect(min(knockdown_effectiveness, 200) , EFFECT_KNOCKDOWN)
|
||||
|
||||
//Display an attack message.
|
||||
if(target != user)
|
||||
|
||||
@@ -2052,6 +2052,17 @@
|
||||
category = list(
|
||||
RND_CATEGORY_MODSUIT_MODULES + RND_SUBCATEGORY_MODSUIT_MODULES_ENGINEERING
|
||||
)
|
||||
/datum/design/module/mod_head_protection
|
||||
name = "Safety-First Head Protection Module"
|
||||
id = "mod_safety"
|
||||
materials = list(
|
||||
/datum/material/iron =SMALL_MATERIAL_AMOUNT*5,
|
||||
/datum/material/glass =HALF_SHEET_MATERIAL_AMOUNT,
|
||||
)
|
||||
build_path = /obj/item/mod/module/headprotector
|
||||
category = list(
|
||||
RND_CATEGORY_MODSUIT_MODULES + RND_SUBCATEGORY_MODSUIT_MODULES_ENGINEERING
|
||||
)
|
||||
/datum/design/module/mod_t_ray
|
||||
name = "T-Ray Scanner Module"
|
||||
id = "mod_t_ray"
|
||||
|
||||
@@ -210,6 +210,7 @@
|
||||
"mod_plating_standard",
|
||||
"mod_storage",
|
||||
"mod_welding",
|
||||
"mod_safety",
|
||||
"mod_mouthhole",
|
||||
"mod_flashlight",
|
||||
"mod_longfall",
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
actions_types = list(/datum/action/item_action/hev_toggle/nri, /datum/action/item_action/hev_toggle_notifs/nri, /datum/action/item_action/toggle_spacesuit)
|
||||
resistance_flags = FIRE_PROOF|UNACIDABLE|ACID_PROOF|FREEZE_PROOF
|
||||
clothing_flags = STOPSPRESSUREDAMAGE|SNUG_FIT
|
||||
clothing_traits = list(TRAIT_SHOVE_KNOCKDOWN_BLOCKED)
|
||||
clothing_traits = list(TRAIT_BRAWLING_KNOCKDOWN_BLOCKED)
|
||||
|
||||
activation_song = null //No nice song.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user