diff --git a/code/__DEFINES/~skyrat_defines/armor_defines.dm b/code/__DEFINES/~skyrat_defines/armor_defines.dm new file mode 100644 index 00000000000..bfb239621e2 --- /dev/null +++ b/code/__DEFINES/~skyrat_defines/armor_defines.dm @@ -0,0 +1,8 @@ +#define ARMOR_LEVEL_TINY 10 +#define ARMOR_LEVEL_WEAK 30 +#define ARMOR_LEVEL_MID 50 +#define ARMOR_LEVEL_INSANE 90 + +#define WOUND_ARMOR_WEAK 10 +#define WOUND_ARMOR_STANDARD 20 +#define WOUND_ARMOR_HIGH 30 diff --git a/code/__DEFINES/~skyrat_defines/traits/declarations.dm b/code/__DEFINES/~skyrat_defines/traits/declarations.dm index cad3083144d..e7eb77d9224 100644 --- a/code/__DEFINES/~skyrat_defines/traits/declarations.dm +++ b/code/__DEFINES/~skyrat_defines/traits/declarations.dm @@ -150,4 +150,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_CONDOM_BROKEN "broken" +/// If clothing can also be damaged by piercing wound checks, instead of JUST slashes and burns +#define TRAIT_CLOTHES_DAMAGED_BY_PIERCING "clothing_damaged_by_piercing" + // END TRAIT DEFINES diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 0c237f43fbf..f0af4914d60 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -629,6 +629,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_XENOARCH_QUALIFIED" = TRAIT_XENOARCH_QUALIFIED, "TRAIT_XENO_HEAL_AURA" = TRAIT_XENO_HEAL_AURA, "TRAIT_XENO_INNATE" = TRAIT_XENO_INNATE, + "TRAIT_CLOTHES_DAMAGED_BY_PIERCING" = TRAIT_CLOTHES_DAMAGED_BY_PIERCING, ), // SKYRAT EDIT ADDITION END )) diff --git a/code/_globalvars/traits/admin_tooling.dm b/code/_globalvars/traits/admin_tooling.dm index 3e061e884af..f852a1decbc 100644 --- a/code/_globalvars/traits/admin_tooling.dm +++ b/code/_globalvars/traits/admin_tooling.dm @@ -347,6 +347,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_XENOARCH_QUALIFIED" = TRAIT_XENOARCH_QUALIFIED, "TRAIT_XENO_HEAL_AURA" = TRAIT_XENO_HEAL_AURA, "TRAIT_XENO_INNATE" = TRAIT_XENO_INNATE, + "TRAIT_CLOTHES_DAMAGED_BY_PIERCING" = TRAIT_CLOTHES_DAMAGED_BY_PIERCING, ), // SKYRAT EDIT ADDITION END )) diff --git a/modular_skyrat/modules/company_imports/code/armament_datums/sol_defense.dm b/modular_skyrat/modules/company_imports/code/armament_datums/sol_defense.dm index adc25d80147..0d7e4a8eca1 100644 --- a/modular_skyrat/modules/company_imports/code/armament_datums/sol_defense.dm +++ b/modular_skyrat/modules/company_imports/code/armament_datums/sol_defense.dm @@ -2,21 +2,63 @@ category = SOL_DEFENSE_DEFENSE_NAME company_bitflag = CARGO_COMPANY_SOL_DEFENSE -// Basic armor vests +// Armor vests for protecting against bullets /datum/armament_entry/company_import/sol_defense/armor - subcategory = "Light Body Armor" - -/datum/armament_entry/company_import/sol_defense/armor/slim_vest - name = "type I vest - slim" - item_type = /obj/item/clothing/suit/armor/vest + subcategory = "Ballistic Armor" cost = PAYCHECK_CREW * 3 +/datum/armament_entry/company_import/sol_defense/armor/ballistic_helmet + item_type = /obj/item/clothing/head/helmet/sf_peacekeeper/debranded + +/datum/armament_entry/company_import/sol_defense/armor/sf_ballistic_helmet + item_type = /obj/item/clothing/head/helmet/sf_peacekeeper + +/datum/armament_entry/company_import/sol_defense/armor/soft_vest + item_type = /obj/item/clothing/suit/armor/sf_peacekeeper/debranded + +/datum/armament_entry/company_import/sol_defense/armor/sf_soft_vest + item_type = /obj/item/clothing/suit/armor/sf_peacekeeper + /datum/armament_entry/company_import/sol_defense/armor/normal_vest name = "type I vest - normal" item_type = /obj/item/clothing/suit/armor/vest/alt + +/datum/armament_entry/company_import/sol_defense/armor/slim_vest + name = "type I vest - slim" + item_type = /obj/item/clothing/suit/armor/vest + +/datum/armament_entry/company_import/sol_defense/armor_hardened + subcategory = "Hardened Armor" cost = PAYCHECK_CREW * 3 +/datum/armament_entry/company_import/sol_defense/armor_hardened/enclosed_helmet + item_type = /obj/item/clothing/head/helmet/toggleable/sf_hardened + + +/datum/armament_entry/company_import/sol_defense/armor_hardened/emt_enclosed_helmet + item_type = /obj/item/clothing/head/helmet/toggleable/sf_hardened/emt + +/datum/armament_entry/company_import/sol_defense/armor_hardened/hardened_vest + item_type = /obj/item/clothing/suit/armor/sf_hardened + +/datum/armament_entry/company_import/sol_defense/armor_hardened/emt_hardened_vest + item_type = /obj/item/clothing/suit/armor/sf_hardened/emt + +/datum/armament_entry/company_import/sol_defense/armor_sacrifice + subcategory = "Sacrifical Armor" + cost = PAYCHECK_CREW * 3 + +/datum/armament_entry/company_import/sol_defense/armor_sacrifice/sacrificial_helmet + item_type = /obj/item/clothing/head/helmet/sf_sacrificial + +/datum/armament_entry/company_import/sol_defense/armor_sacrifice/face_shield + item_type = /obj/item/sacrificial_face_shield + cost = PAYCHECK_LOWER + +/datum/armament_entry/company_import/sol_defense/armor_sacrifice/sacrificial_vest + item_type = /obj/item/clothing/suit/armor/sf_sacrificial + /datum/armament_entry/company_import/sol_defense/case subcategory = "Weapon Cases" diff --git a/modular_skyrat/modules/specialist_armor/code/cargo_packs.dm b/modular_skyrat/modules/specialist_armor/code/cargo_packs.dm new file mode 100644 index 00000000000..8dbe34ebc3c --- /dev/null +++ b/modular_skyrat/modules/specialist_armor/code/cargo_packs.dm @@ -0,0 +1,30 @@ +/datum/supply_pack/security/armory/soft_armor + name = "Soft Armor Kit Crate" + crate_name = "soft armor kit crate" + desc = "Contains three sets of SolFed-made soft body armor and matching helmets." + cost = CARGO_CRATE_VALUE * 5 + contains = list( + /obj/item/clothing/head/helmet/sf_peacekeeper/debranded = 3, + /obj/item/clothing/suit/armor/sf_peacekeeper/debranded = 3, + ) + +/datum/supply_pack/security/armory/hardened_armor + name = "Hardened Armor Kit Crate" + crate_name = "hardened armor kit crate" + desc = "Contains three sets of SolFed-made hardened body armor and matching helmets." + cost = CARGO_CRATE_VALUE * 5 + contains = list( + /obj/item/clothing/head/helmet/toggleable/sf_hardened = 3, + /obj/item/clothing/suit/armor/sf_hardened = 3, + ) + +/datum/supply_pack/security/armory/sacrificial_armor + name = "Sacrificial Armor Kit Crate" + crate_name = "sacrificial armor kit crate" + desc = "Contains three sets of SolFed-made sacrificial body armor and matching helmets." + cost = CARGO_CRATE_VALUE * 5 + contains = list( + /obj/item/clothing/head/helmet/sf_sacrificial = 3, + /obj/item/sacrificial_face_shield = 3, + /obj/item/clothing/suit/armor/sf_sacrificial = 3, + ) diff --git a/modular_skyrat/modules/specialist_armor/code/clothing_bullet_damage_component.dm b/modular_skyrat/modules/specialist_armor/code/clothing_bullet_damage_component.dm new file mode 100644 index 00000000000..48d56948660 --- /dev/null +++ b/modular_skyrat/modules/specialist_armor/code/clothing_bullet_damage_component.dm @@ -0,0 +1,81 @@ +/// Component that lets clothing be damaged in zones by piercing bullets. The parent MUST have limb_integrity set. +/datum/component/clothing_damaged_by_bullets + /// How much of the incoming projectile damage is taken, multiplier + var/projectile_damage_multiplier + /// Who is wearing the target? + var/mob/living/wearer + +/datum/component/clothing_damaged_by_bullets/Initialize(projectile_damage_multiplier = 1) + if(!istype(parent, /obj/item/clothing)) // Just in case someone loses it and tries to put this on something that's not clothing + return COMPONENT_INCOMPATIBLE + + var/obj/item/clothing/parent_clothing = parent + + src.projectile_damage_multiplier = projectile_damage_multiplier + + if(ismob(parent_clothing.loc)) + var/mob/holder = parent_clothing.loc + if(holder.is_holding(parent_clothing)) + return + set_wearer(holder) + +/datum/component/clothing_damaged_by_bullets/RegisterWithParent() + RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) + RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(on_equipped)) + RegisterSignal(parent, COMSIG_ITEM_DROPPED, PROC_REF(lost_wearer)) + +/datum/component/clothing_damaged_by_bullets/UnregisterFromParent() + UnregisterSignal(parent, list(COMSIG_ATOM_EXAMINE, COMSIG_ITEM_DROPPED, COMSIG_ITEM_EQUIPPED, COMSIG_QDELETING, COMSIG_ATOM_BULLET_ACT)) + +/// Check if we've been equipped to a valid slot to shield +/datum/component/clothing_damaged_by_bullets/proc/on_equipped(datum/source, mob/user, slot) + SIGNAL_HANDLER + + if((slot & ITEM_SLOT_HANDS)) + lost_wearer(source, user) + return + set_wearer(user) + +/// Either we've been dropped or our wearer has been QDEL'd. Either way, they're no longer our problem +/datum/component/clothing_damaged_by_bullets/proc/lost_wearer(datum/source, mob/user) + SIGNAL_HANDLER + + wearer = null + UnregisterSignal(parent, list(COMSIG_QDELETING, COMSIG_ATOM_BULLET_ACT)) + +/// Sets the wearer and registers the appropriate signals for them +/datum/component/clothing_damaged_by_bullets/proc/set_wearer(mob/user) + if(wearer == user) + return + if(!isnull(wearer)) + CRASH("[type] called set_wearer with [user] but [wearer] was already the wearer!") + + wearer = user + RegisterSignal(wearer, COMSIG_QDELETING, PROC_REF(lost_wearer)) + RegisterSignal(wearer, COMSIG_ATOM_BULLET_ACT, PROC_REF(hit_by_projectile)) + +/// Checks an incoming projectile to see if it should damage the thing we're attached to, +/datum/component/clothing_damaged_by_bullets/proc/hit_by_projectile(mob/living/dude_getting_hit, obj/projectile/hitting_projectile, def_zone) + SIGNAL_HANDLER + + var/obj/item/clothing/clothing_parent = parent + + if(!(def_zone in cover_flags2body_zones(clothing_parent.body_parts_covered))) + return + if(hitting_projectile.sharpness == SHARP_EDGED) + return + if(hitting_projectile.damage_type != BRUTE) + return + + /// This seems complex but the actual math is simple, the damage of the projectile * vest damage multiplier, divided by two if the projectile is weak to armour, then modified by wound bonus + var/total_damage = ((hitting_projectile.damage * projectile_damage_multiplier) * (hitting_projectile.weak_against_armour ? 0.5 : 1) * (1 + (hitting_projectile.wound_bonus / 10))) + var/damage_dealt = clothing_parent.take_damage(total_damage, BRUTE, hitting_projectile.armour_penetration, FALSE) + + if(clothing_parent.limb_integrity) + clothing_parent.take_damage_zone(def_zone, damage_dealt, BRUTE) + +/// Warns any examiner that the clothing we're stuck to will be damaged by piercing bullets +/datum/component/clothing_damaged_by_bullets/proc/on_examine(obj/item/source, mob/examiner, list/examine_list) + SIGNAL_HANDLER + + examine_list += "
[span_warning("This will be damaged when it protects you from bullets, taking [projectile_damage_multiplier] times the damage that the bullet deals.")]" diff --git a/modular_skyrat/modules/specialist_armor/code/hardened.dm b/modular_skyrat/modules/specialist_armor/code/hardened.dm new file mode 100644 index 00000000000..777bfed67e0 --- /dev/null +++ b/modular_skyrat/modules/specialist_armor/code/hardened.dm @@ -0,0 +1,99 @@ +// Hardened vests negate any and all projectile armor penetration, in exchange for having mid af bullet armor +/datum/armor/armor_sf_hardened + melee = ARMOR_LEVEL_WEAK + bullet = ARMOR_LEVEL_MID + laser = ARMOR_LEVEL_WEAK + energy = ARMOR_LEVEL_TINY + bomb = ARMOR_LEVEL_WEAK + fire = ARMOR_LEVEL_MID + acid = ARMOR_LEVEL_WEAK + wound = WOUND_ARMOR_WEAK + +/obj/item/clothing/suit/armor/sf_hardened + name = "'Muur' hardened armor vest" + desc = "A large white breastplate, and a semi-flexible mail of dense panels that cover the torso. \ + While not so incredible at directly stopping bullets, the vest is uniquely suited to cause bullets \ + to lose much of their armor penetrating energy before any damage can be done." + icon = 'modular_skyrat/modules/specialist_armor/icons/armor.dmi' + icon_state = "hardened_standard" + worn_icon = 'modular_skyrat/modules/specialist_armor/icons/armor_worn.dmi' + inhand_icon_state = "armor" + blood_overlay_type = "armor" + armor_type = /datum/armor/armor_sf_hardened + supports_variations_flags = CLOTHING_DIGITIGRADE_VARIATION_NO_NEW_ICON + +/obj/item/clothing/suit/armor/sf_hardened/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text, final_block_chance, damage, attack_type, damage_type) + . = ..() + + if(istype(hitby, /obj/projectile)) + var/obj/projectile/incoming_projectile = hitby + incoming_projectile.armour_penetration = 0 + playsound(owner, SFX_RICOCHET, BLOCK_SOUND_VOLUME, vary = TRUE) + +/obj/item/clothing/suit/armor/sf_hardened/examine_more(mob/user) + . = ..() + + . += "What do you do in an age where armor penetration technology keeps getting better and better, \ + and you're quite fond of not being a corpse? The 'Muur' type armor was a pretty successful attempt at an answer \ + to the question. Using some advanced materials, micro-scale projectile dampener fields, and a whole \ + host of other technologies that some poor SolFed procurement general had to talked to death about, \ + it offers a unique advantage over many armor piercing bullets. Why stop the bullet from piercing the armor \ + with more armor, when you could simply force the bullet to penetrate less and get away with less protection? \ + Some people would rather the bullet just be stopped, of course, but when you have to make choices, many choose \ + this one." + + return . + +/obj/item/clothing/suit/armor/sf_hardened/emt + name = "'Archangel' hardened armor vest" + desc = "A large white breastplate with a lone red stripe, and a semi-flexible mail of dense panels that cover the torso. \ + While not so incredible at directly stopping bullets, the vest is uniquely suited to cause bullets \ + to lose much of their armor penetrating energy before any damage can be done." + icon_state = "hardened_emt" + +/obj/item/clothing/head/helmet/toggleable/sf_hardened + name = "'Muur' enclosed helmet" + desc = "A thick-fronted helmet with extendable visor for whole face protection. The materials and geometry of the helmet \ + combine in such a way that bullets lose much of their armor penetrating energy before any damage can be done, rather than penetrate into it." + icon = 'modular_skyrat/modules/specialist_armor/icons/armor.dmi' + icon_state = "enclosed_standard" + worn_icon = 'modular_skyrat/modules/specialist_armor/icons/armor_worn.dmi' + inhand_icon_state = "helmet" + armor_type = /datum/armor/armor_sf_hardened + toggle_message = "You extend the visor on" + alt_toggle_message = "You retract the visor on" + flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT + visor_flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR + flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF + visor_flags_cover = HEADCOVERSEYES + dog_fashion = null + supports_variations_flags = CLOTHING_SNOUTED_VARIATION_NO_NEW_ICON + +/obj/item/clothing/head/helmet/toggleable/sf_hardened/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text, final_block_chance, damage, attack_type, damage_type) + . = ..() + + if(istype(hitby, /obj/projectile)) + var/obj/projectile/incoming_projectile = hitby + incoming_projectile.armour_penetration = 0 + playsound(src, SFX_RICOCHET, BLOCK_SOUND_VOLUME, vary = TRUE) + +/obj/item/clothing/head/helmet/toggleable/sf_hardened/examine_more(mob/user) + . = ..() + + . += "What do you do in an age where armor penetration technology keeps getting better and better, \ + and you're quite fond of not being a corpse? The 'Muur' type armor was a pretty successful attempt at an answer \ + to the question. Using some advanced materials, micro-scale projectile dampener fields, and a whole \ + host of other technologies that some poor SolFed procurement general had to talked to death about, \ + it offers a unique advantage over many armor piercing bullets. Why stop the bullet from piercing the armor \ + with more armor, when you could simply force the bullet to penetrate less and get away with less protection? \ + Some people would rather the bullet just be stopped, of course, but when you have to make choices, many choose \ + this one." + + return . + +/obj/item/clothing/head/helmet/toggleable/sf_hardened/emt + name = "'Archangel' enclosed helmet" + desc = "A thick-fronted helmet with extendable visor for whole face protection. The materials and geometry of the helmet \ + combine in such a way that bullets lose much of their armor penetrating energy before any damage can be done, rather than penetrate into it. \ + This one has a red stripe down the front." + icon_state = "enclosed_emt" diff --git a/modular_skyrat/modules/specialist_armor/code/peacekeeper.dm b/modular_skyrat/modules/specialist_armor/code/peacekeeper.dm new file mode 100644 index 00000000000..999d3bf9508 --- /dev/null +++ b/modular_skyrat/modules/specialist_armor/code/peacekeeper.dm @@ -0,0 +1,75 @@ +// The peacekeeper armors and helmets will be less effective at stopping bullet damage than bulletproof vests, but stronger against wounds especially, and some other damage types +/datum/armor/armor_sf_peacekeeper + melee = ARMOR_LEVEL_WEAK + bullet = ARMOR_LEVEL_MID + laser = ARMOR_LEVEL_TINY + energy = ARMOR_LEVEL_TINY + bomb = ARMOR_LEVEL_WEAK + fire = ARMOR_LEVEL_MID + acid = ARMOR_LEVEL_WEAK + wound = WOUND_ARMOR_HIGH + +/obj/item/clothing/suit/armor/sf_peacekeeper + name = "'Touvou' peacekeeper armor vest" + desc = "A bright blue vest, proudly bearing 'SF' in white on its front and back. Dense fabric with a thin layer of rolled metal \ + will protect you from bullets best, a few blunt blows, and the wounds they cause. Lasers will burn more or less straight through it." + icon = 'modular_skyrat/modules/specialist_armor/icons/armor.dmi' + icon_state = "soft_peacekeeper" + worn_icon = 'modular_skyrat/modules/specialist_armor/icons/armor_worn.dmi' + inhand_icon_state = "armor" + blood_overlay_type = "armor" + armor_type = /datum/armor/armor_sf_peacekeeper + supports_variations_flags = CLOTHING_DIGITIGRADE_VARIATION_NO_NEW_ICON + +/obj/item/clothing/suit/armor/sf_peacekeeper/examine_more(mob/user) + . = ..() + + . += "A common SolFed designed armor vest for a common cause, not having your innards become outards. \ + While heavier armors certainly exist, the 'Touvou' is relatively cheap for the protection you do get, \ + and many soldiers and officers around the galaxy will tell you the convenience of a mostly soft body armor. \ + Not for any of the protection, but for the relative comfort, especially in areas where you don't need to care \ + much if you're able to stop an anti materiel round with your chest. Likely due to all those factors, \ + it is a common sight on SolFed peacekeepers around the galaxy, alongside other misfits and corporate baddies \ + across the galaxy." + + return . + +/obj/item/clothing/suit/armor/sf_peacekeeper/debranded + name = "'Touvou' soft armor vest" + desc = "A bright white vest, notably missing an 'SF' marking on either its front or back. Dense fabric with a thin layer of rolled metal \ + will protect you from bullets best, a few blunt blows, and the wounds they cause. Lasers will burn more or less straight through it." + icon_state = "soft_civilian" + +/obj/item/clothing/head/helmet/sf_peacekeeper + name = "'Kastrol' peacekeeper helmet" + desc = "A large, almost always ill-fitting helmet painted in bright blue. It proudly bears the emblems of SolFed on its sides. \ + It will protect from bullets best, with some protection against blunt blows, but falters easily in the presence of lasers." + icon = 'modular_skyrat/modules/specialist_armor/icons/armor.dmi' + icon_state = "helmet_peacekeeper" + worn_icon = 'modular_skyrat/modules/specialist_armor/icons/armor_worn.dmi' + inhand_icon_state = "helmet" + armor_type = /datum/armor/armor_sf_peacekeeper + dog_fashion = null + flags_inv = null + supports_variations_flags = CLOTHING_SNOUTED_VARIATION_NO_NEW_ICON + +/obj/item/clothing/head/helmet/sf_peacekeeper/examine_more(mob/user) + . = ..() + + . += "A common SolFed designed ballistic helmet for a common cause, keeping your brain inside your head. \ + While heavier helmets certainly exist, the 'Kastrol' is relatively cheap for the protection you do get, \ + and many soldiers don't mind it much due to its large over-head size bypassing a lot of the fitting issues \ + some more advanced or more protective helmets might have. \ + Especially in areas where you don't need to care \ + much if you're able to stop an anti materiel round with your forehead, it does the job just fine. \ + Likely due to all those factors, \ + it is a common sight on SolFed peacekeepers around the galaxy, alongside other misfits and corporate baddies \ + across the galaxy." + + return . + +/obj/item/clothing/head/helmet/sf_peacekeeper/debranded + name = "'Kastrol' ballistic helmet" + desc = "A large, almost always ill-fitting helmet painted a dull grey. This one seems to lack any special markings. \ + It will protect from bullets best, with some protection against blunt blows, but falters easily in the presence of lasers." + icon_state = "helmet_grey" diff --git a/modular_skyrat/modules/specialist_armor/code/sacrificial.dm b/modular_skyrat/modules/specialist_armor/code/sacrificial.dm new file mode 100644 index 00000000000..45643140f83 --- /dev/null +++ b/modular_skyrat/modules/specialist_armor/code/sacrificial.dm @@ -0,0 +1,156 @@ +// Sacrificial armor has massive bullet protection, but gets damaged by being shot, thus, is sacrificing itself to protect the wearer +/datum/armor/armor_sf_sacrificial + melee = ARMOR_LEVEL_WEAK + bullet = ARMOR_LEVEL_INSANE // When the level IV plates stop the bullet but not the energy transfer + laser = ARMOR_LEVEL_TINY + energy = ARMOR_LEVEL_TINY + bomb = ARMOR_LEVEL_MID + fire = ARMOR_LEVEL_MID + acid = ARMOR_LEVEL_WEAK + wound = WOUND_ARMOR_HIGH + +/obj/item/clothing/suit/armor/sf_sacrificial + name = "'Val' sacrificial ballistic vest" + desc = "A hefty vest with a unique pattern of hexes on its outward faces. \ + As the 'sacrificial' name might imply, this vest has extremely high bullet protection \ + in exchange for allowing itself to be destroyed by impacts. It'll protect you from hell, \ + but only for so long." + icon = 'modular_skyrat/modules/specialist_armor/icons/armor.dmi' + icon_state = "hexagon" + worn_icon = 'modular_skyrat/modules/specialist_armor/icons/armor_worn.dmi' + inhand_icon_state = "armor" + blood_overlay_type = "armor" + armor_type = /datum/armor/armor_sf_sacrificial + max_integrity = 200 + limb_integrity = 200 + repairable_by = null // No being cheeky and keeping a pile of repair materials in your bag to fix it either + supports_variations_flags = CLOTHING_DIGITIGRADE_VARIATION_NO_NEW_ICON + +/obj/item/clothing/suit/armor/sf_sacrificial/Initialize(mapload) + . = ..() + + AddComponent(/datum/component/clothing_damaged_by_bullets) + +/obj/item/clothing/suit/armor/sf_sacrificial/examine_more(mob/user) + . = ..() + + . += "An extreme solution to an extreme problem. While many galactic armors have some semblance of self-repairing tech \ + in them to prevent the armor becoming useless after being shot enough, it does have its limits. Those limits tend to be \ + that the self-repairing, while handy, take the place of what could have simply been more armor. For a small market, \ + one that doesn't care if their armor lasts more than one gunfight, there exists a niche for armors such as the 'Val'. \ + Passing up self-repair for nigh-immunity to bullets, the right tool for a certain job, if you can find whatever that job may be." + + return . + +/obj/item/clothing/head/helmet/sf_sacrificial + name = "'Val' sacrificial ballistic helmet" + desc = "A large, almost always ill-fitting helmet painted in a tacticool black. \ + As the 'sacrificial' name might imply, this helmet has extremely high bullet protection \ + in exchange for allowing itself to be destroyed by impacts. It'll protect you from hell, \ + but only for so long." + icon = 'modular_skyrat/modules/specialist_armor/icons/armor.dmi' + icon_state = "bulletproof" + worn_icon = 'modular_skyrat/modules/specialist_armor/icons/armor_worn.dmi' + inhand_icon_state = "helmet" + armor_type = /datum/armor/armor_sf_sacrificial + max_integrity = 200 + limb_integrity = 200 + repairable_by = null // No being cheeky and keeping a pile of repair materials in your bag to fix it either + dog_fashion = null + flags_inv = null + supports_variations_flags = CLOTHING_SNOUTED_VARIATION_NO_NEW_ICON + /// Holds the faceshield for quick reference + var/obj/item/sacrificial_face_shield/face_shield + +/obj/item/clothing/head/helmet/sf_sacrificial/Initialize(mapload) + . = ..() + + AddComponent(/datum/component/clothing_damaged_by_bullets) + +/obj/item/clothing/head/helmet/sf_sacrificial/attackby(obj/item/attacking_item, mob/user, params) + . = ..() + + if(!(istype(attacking_item, /obj/item/sacrificial_face_shield))) + return + + add_face_shield(user, attacking_item) + +/obj/item/clothing/head/helmet/sf_sacrificial/Destroy() + QDEL_NULL(face_shield) + return ..() + +/obj/item/clothing/head/helmet/sf_sacrificial/AltClick(mob/user) + remove_face_shield(user) + +/// Attached the passed face shield to the helmet. +/obj/item/clothing/head/helmet/sf_sacrificial/proc/add_face_shield(mob/living/carbon/human/user, obj/shield_in_question) + if(face_shield) + return + if(!user.transferItemToLoc(shield_in_question, src)) + return + + flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDESNOUT + flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF + + playsound(src, 'sound/items/modsuit/magnetic_harness.ogg', 50, TRUE) + face_shield = shield_in_question + + icon_state = "bulletproof_glass" + worn_icon_state = icon_state + update_appearance() + +/// Removes the face shield from the helmet, breaking it into a glass shard decal if that's wanted, too. +/obj/item/clothing/head/helmet/sf_sacrificial/proc/remove_face_shield(mob/living/carbon/human/user, break_it) + if(!face_shield) + return + + flags_inv = initial(flags_inv) + flags_cover = initial(flags_cover) + + if(break_it) + playsound(src, SFX_SHATTER, 70, TRUE) + new /obj/effect/decal/cleanable/glass(drop_location(src)) + qdel(face_shield) + face_shield = null // just to be safe + else + user.put_in_hands(face_shield) + playsound(src, 'sound/items/modsuit/magnetic_harness.ogg', 50, TRUE) + face_shield = null + + icon_state = initial(icon_state) + worn_icon_state = icon_state // Against just to be safe + update_appearance() + +/obj/item/clothing/head/helmet/sf_sacrificial/take_damage_zone(def_zone, damage_amount, damage_type, armour_penetration) + . = ..() + + if((damage_amount > 20) && face_shield) + remove_face_shield(break_it = TRUE) + +/obj/item/clothing/head/helmet/sf_sacrificial/examine(mob/user) + . = ..() + if(face_shield) + . += span_notice("The face shield can be removed with Right-Click.") + else + . += span_notice("A face shield can be attached to it.") + + return . + +/obj/item/clothing/head/helmet/sf_sacrificial/examine_more(mob/user) + . = ..() + + . += "An extreme solution to an extreme problem. While many galactic armors have some semblance of self-repairing tech \ + in them to prevent the armor becoming useless after being shot enough, it does have its limits. Those limits tend to be \ + that the self-repairing, while handy, take the place of what could have simply been more armor. For a small market, \ + one that doesn't care if their armor lasts more than one gunfight, there exists a niche for armors such as the 'Val'. \ + Passing up self-repair for nigh-immunity to bullets, the right tool for a certain job, if you can find whatever that job may be." + + return . + +/obj/item/sacrificial_face_shield + name = "'Val' ballistic add-on face plate" + desc = "A thick piece of glass with mounting points for slotting onto a 'Val' sacrificial ballistic helmet. \ + While it does not make the helmet any stronger, it does protect your face much like a riot helmet would." + icon = 'modular_skyrat/modules/specialist_armor/icons/armor.dmi' + icon_state = "face_shield" + w_class = WEIGHT_CLASS_NORMAL diff --git a/modular_skyrat/modules/specialist_armor/icons/armor.dmi b/modular_skyrat/modules/specialist_armor/icons/armor.dmi new file mode 100644 index 00000000000..d3e56a6b051 Binary files /dev/null and b/modular_skyrat/modules/specialist_armor/icons/armor.dmi differ diff --git a/modular_skyrat/modules/specialist_armor/icons/armor_worn.dmi b/modular_skyrat/modules/specialist_armor/icons/armor_worn.dmi new file mode 100644 index 00000000000..ad052b7aaf3 Binary files /dev/null and b/modular_skyrat/modules/specialist_armor/icons/armor_worn.dmi differ diff --git a/tgstation.dme b/tgstation.dme index f7c278f7123..7797d747e1c 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -385,6 +385,7 @@ #include "code\__DEFINES\~skyrat_defines\antagonists.dm" #include "code\__DEFINES\~skyrat_defines\apc_defines.dm" #include "code\__DEFINES\~skyrat_defines\armaments.dm" +#include "code\__DEFINES\~skyrat_defines\armor_defines.dm" #include "code\__DEFINES\~skyrat_defines\atom_hud.dm" #include "code\__DEFINES\~skyrat_defines\augment.dm" #include "code\__DEFINES\~skyrat_defines\automapper.dm" @@ -7878,6 +7879,11 @@ #include "modular_skyrat\modules\space_vines\venus.dm" #include "modular_skyrat\modules\space_vines\vine_mutations.dm" #include "modular_skyrat\modules\space_vines\vine_structure.dm" +#include "modular_skyrat\modules\specialist_armor\code\cargo_packs.dm" +#include "modular_skyrat\modules\specialist_armor\code\clothing_bullet_damage_component.dm" +#include "modular_skyrat\modules\specialist_armor\code\hardened.dm" +#include "modular_skyrat\modules\specialist_armor\code\peacekeeper.dm" +#include "modular_skyrat\modules\specialist_armor\code\sacrificial.dm" #include "modular_skyrat\modules\stasisrework\code\all_nodes.dm" #include "modular_skyrat\modules\stasisrework\code\bodybag.dm" #include "modular_skyrat\modules\stasisrework\code\bodybag_structure.dm"