From d8c1932cb90851dc2de720e6f53fd977cdbab221 Mon Sep 17 00:00:00 2001 From: Cameron Lennox Date: Mon, 13 Apr 2026 00:30:02 -0400 Subject: [PATCH] Flammable Items, Abstractness, and hypnosis (#19267) * Laser Eyes * Update dna.dm * Mecha * Update positive_genes.dm * These * These 2 * yeh * Rest of these * Update turf.dm * Update food.dm * Some moar * mooove * Update vorestation.dme * Update burning.dm * firesuit * flags * HYPNOCOLOR * xd * no filter * dc * Update ore_bag.dm * Update misc.dm * Update misc.dm --- archive/maps/gateway_archive_vr/labyrinth.dm | 2 +- archive/maps/gateway_archive_vr/wildwest.dm | 4 +- code/ATMOSPHERICS/atmospherics.dm | 4 +- .../components/binary_devices/passive_gate.dm | 2 +- .../components/binary_devices/pump.dm | 2 +- .../components/binary_devices/volume_pump.dm | 2 +- .../components/omni_devices/omni_base.dm | 2 +- .../components/portables_connector.dm | 2 +- .../trinary_devices/trinary_base.dm | 2 +- code/ATMOSPHERICS/components/tvalve.dm | 2 +- .../components/unary/heat_exchanger.dm | 2 +- .../components/unary/outlet_injector.dm | 2 +- .../components/unary/vent_pump.dm | 2 +- .../components/unary/vent_scrubber.dm | 2 +- code/ATMOSPHERICS/components/valve.dm | 2 +- code/ATMOSPHERICS/pipes/pipe_base.dm | 2 +- code/__defines/_flags.dm | 20 +++ code/__defines/atmos.dm | 3 + code/__defines/combat.dm | 28 +++++ code/__defines/dna.dm | 2 +- code/__defines/flags.dm | 7 ++ code/__defines/mecha.dm | 2 +- code/__defines/obj_flags.dm | 32 +++++ code/__defines/span.dm | 2 + code/__defines/subsystems.dm | 1 + code/__defines/traits/declarations.dm | 5 + code/_onclick/click.dm | 2 +- code/_onclick/other_mobs.dm | 5 +- .../subsystems/processing/fire_burning.dm | 6 + code/datums/components/burning.dm | 115 ++++++++++++++++++ code/defines/obj/weapon.dm | 3 + code/game/atom/atom_defense.dm | 109 +++++++++++++++++ .../game/atom/atoms_initializing_EXPENSIVE.dm | 3 + code/game/gamemodes/cult/cultify/obj.dm | 3 + code/game/machinery/deployable_vr.dm | 1 + code/game/machinery/machinery.dm | 2 +- code/game/machinery/wishgranter.dm | 2 +- code/game/mecha/components/_component.dm | 2 +- code/game/mecha/equipment/mecha_equipment.dm | 4 +- code/game/mecha/equipment/tools/catapult.dm | 2 +- .../mecha/equipment/tools/extinguisher.dm | 2 +- code/game/mecha/equipment/tools/generator.dm | 2 +- .../game/mecha/equipment/tools/inflatables.dm | 2 +- code/game/mecha/equipment/tools/orescanner.dm | 2 +- code/game/mecha/equipment/tools/passenger.dm | 2 +- code/game/mecha/equipment/tools/powertool.dm | 2 +- code/game/mecha/equipment/tools/rcd.dm | 2 +- code/game/mecha/equipment/tools/sleeper.dm | 2 +- .../game/mecha/equipment/tools/syringe_gun.dm | 6 +- .../mecha/equipment/tools/weldinglaser.dm | 6 +- code/game/objects/effects/effect_system.dm | 1 + .../objects/items/devices/radio/intercom.dm | 2 +- .../objects/items/stacks/tiles/tile_types.dm | 3 + .../weapons/circuitboards/circuitboard.dm | 2 +- .../circuitboards/computer/air_management.dm | 2 +- .../circuitboards/computer/camera_monitor.dm | 2 +- .../weapons/circuitboards/computer/shuttle.dm | 2 +- .../weapons/circuitboards/computer/supply.dm | 2 +- .../objects/items/weapons/gift_wrappaper.dm | 1 + .../objects/items/weapons/storage/bags.dm | 15 ++- .../objects/items/weapons/storage/boxes.dm | 1 + .../objects/items/weapons/storage/internal.dm | 1 + .../items/weapons/storage/laundry_basket.dm | 1 + .../objects/items/weapons/storage/ore_bag.dm | 4 +- .../game/objects/items/weapons/tanks/tanks.dm | 1 + code/game/objects/mail.dm | 1 + code/game/objects/obj_defense.dm | 79 ++++++++++++ code/game/objects/objs.dm | 9 ++ code/game/objects/structures/bedsheet_bin.dm | 1 + code/game/objects/structures/bonfire.dm | 8 +- code/game/objects/structures/catwalk.dm | 4 +- code/game/objects/structures/gargoyle.dm | 2 +- .../structures/stool_bed_chair_nest/chairs.dm | 1 + code/game/turfs/turf.dm | 3 + code/modules/blob2/blobs/base_blob.dm | 2 +- code/modules/clothing/clothing.dm | 1 + code/modules/clothing/ears/earrings.dm | 2 + code/modules/clothing/ears/ears.dm | 2 + code/modules/clothing/glasses/glasses.dm | 1 + code/modules/clothing/gloves/arm_guards.dm | 1 + code/modules/clothing/gloves/color.dm | 1 + code/modules/clothing/gloves/gauntlets.dm | 1 + code/modules/clothing/gloves/miscellaneous.dm | 4 + code/modules/clothing/head/collectable.dm | 1 + code/modules/clothing/head/hardhat.dm | 1 + code/modules/clothing/head/helmet.dm | 1 + code/modules/clothing/head/misc_special.dm | 1 + code/modules/clothing/head/pilot_helmet.dm | 1 + code/modules/clothing/head/pilot_helmet_vr.dm | 1 + code/modules/clothing/masks/breath.dm | 1 + code/modules/clothing/masks/gasmask.dm | 1 + code/modules/clothing/masks/monitor.dm | 1 + .../clothing/masks/tesh_synth_facemask.dm | 1 + code/modules/clothing/shoes/boots.dm | 1 + code/modules/clothing/shoes/leg_guards.dm | 1 + code/modules/clothing/shoes/magboots.dm | 1 + code/modules/clothing/shoes/miscellaneous.dm | 2 + .../clothing/shoes/miscellaneous_vr.dm | 1 + code/modules/clothing/spacesuits/breaches.dm | 1 + code/modules/clothing/spacesuits/rig/rig.dm | 1 + .../clothing/spacesuits/rig/rig_pieces.dm | 8 ++ .../modules/clothing/spacesuits/spacesuits.dm | 2 + code/modules/clothing/suits/aliens/vox.dm | 1 + code/modules/clothing/suits/armor.dm | 1 + code/modules/clothing/suits/bio.dm | 2 + code/modules/clothing/suits/bio_vr.dm | 0 code/modules/clothing/suits/hooded_vr.dm | 1 + .../modules/clothing/suits/reactive_armour.dm | 1 + code/modules/clothing/suits/shiny.dm | 0 code/modules/clothing/suits/utility.dm | 3 + code/modules/examine/descriptions/items.dm | 31 +++++ code/modules/food/food.dm | 1 + code/modules/library/lib_items.dm | 1 + code/modules/materials/sheets/gems.dm | 1 + .../materials/sheets/organic/textiles.dm | 4 + code/modules/materials/sheets/plastic.dm | 1 + code/modules/mining/mine_items.dm | 1 + code/modules/mining/shelter_atoms_vr.dm | 4 +- code/modules/mob/living/carbon/carbon.dm | 16 +++ .../mob/living/carbon/carbon_defines.dm | 12 ++ .../mob/living/carbon/human/human_defines.dm | 5 - .../mob/living/carbon/human/inventory.dm | 3 - .../carbon/human/species/station/monkey.dm | 2 +- .../species/station/traits/positive_genes.dm | 2 +- .../mob/living/carbon/human/update_icons.dm | 2 +- code/modules/news/newspaper.dm | 1 + .../overmap/ships/engines/gas_thruster.dm | 4 +- .../overmap/ships/engines/ion_thruster.dm | 4 +- code/modules/overmap/ships/ship.dm | 4 +- code/modules/paperwork/paper.dm | 1 + code/modules/paperwork/photography.dm | 1 + .../reagents/reagent_containers/glass.dm | 1 + code/modules/recycling/disposal_machines.dm | 6 +- .../tg/machinery/destructive_analyzer.dm | 11 +- interface/stylesheet.dm | 8 ++ maps/gateway_vr/wildwest.dm | 4 +- sound/items/tools/welder.ogg | Bin 0 -> 21042 bytes sound/items/weapons/sear.ogg | Bin 0 -> 7712 bytes sound/items/weapons/smash.ogg | Bin 0 -> 6992 bytes sound/items/weapons/tap.ogg | Bin 0 -> 4556 bytes .../tgui-panel/styles/tgchat/chat-dark.scss | 58 ++++----- .../tgui-panel/styles/tgchat/chat-light.scss | 58 ++++----- .../styles/tgchat/chat-vchatdark.scss | 58 ++++----- .../styles/tgchat/chat-vchatlight.scss | 58 ++++----- vorestation.dme | 6 +- 145 files changed, 791 insertions(+), 203 deletions(-) create mode 100644 code/__defines/combat.dm create mode 100644 code/controllers/subsystems/processing/fire_burning.dm create mode 100644 code/datums/components/burning.dm create mode 100644 code/game/atom/atom_defense.dm create mode 100644 code/game/objects/obj_defense.dm delete mode 100644 code/modules/clothing/suits/bio_vr.dm delete mode 100644 code/modules/clothing/suits/shiny.dm create mode 100644 sound/items/tools/welder.ogg create mode 100644 sound/items/weapons/sear.ogg create mode 100644 sound/items/weapons/smash.ogg create mode 100644 sound/items/weapons/tap.ogg diff --git a/archive/maps/gateway_archive_vr/labyrinth.dm b/archive/maps/gateway_archive_vr/labyrinth.dm index 26b4e92108..4bec1d66c5 100644 --- a/archive/maps/gateway_archive_vr/labyrinth.dm +++ b/archive/maps/gateway_archive_vr/labyrinth.dm @@ -151,7 +151,7 @@ icon_state = "mecha_honker" energy_drain = 200 equip_cooldown = 150 - range = MELEE|RANGED + range = MECH_MELEE|RANGED can_attach(obj/mecha/combat/honker/M as obj) if(!istype(M)) diff --git a/archive/maps/gateway_archive_vr/wildwest.dm b/archive/maps/gateway_archive_vr/wildwest.dm index d16e6080c9..8b8e3e0f24 100644 --- a/archive/maps/gateway_archive_vr/wildwest.dm +++ b/archive/maps/gateway_archive_vr/wildwest.dm @@ -44,8 +44,8 @@ if("Power") to_chat(user, span_boldwarning("Your wish is granted, but at a terrible cost...")) to_chat(user, span_warning("The Wish Granter punishes you for your selfishness, claiming your soul and warping your body to match the darkness in your heart.")) - if (!(LASER in user.mutations)) - user.mutations.Add(LASER) + if (!(LASER_EYES in user.mutations)) + user.mutations.Add(LASER_EYES) to_chat(user, span_notice("You feel pressure building behind your eyes.")) if (!(COLD_RESISTANCE in user.mutations)) user.mutations.Add(COLD_RESISTANCE) diff --git a/code/ATMOSPHERICS/atmospherics.dm b/code/ATMOSPHERICS/atmospherics.dm index aba125e7b8..584b5b6a99 100644 --- a/code/ATMOSPHERICS/atmospherics.dm +++ b/code/ATMOSPHERICS/atmospherics.dm @@ -157,7 +157,7 @@ Pipelines + Other Objects -> Pipe network return TRUE // Deconstruct into a pipe item. -/obj/machinery/atmospherics/proc/deconstruct() +/obj/machinery/atmospherics/atom_deconstruct() if(QDELETED(src)) return if(construction_type) @@ -258,7 +258,7 @@ Pipelines + Other Objects -> Pipe network var/datum/gas_mixture/int_air = return_air() var/datum/gas_mixture/env_air = our_turf.return_air() var/internal_pressure = int_air.return_pressure()-env_air.return_pressure() - deconstruct() + atom_deconstruct() // Release pressure playsound(our_turf, 'sound/effects/bang.ogg', 70, 0, 0) playsound(our_turf, 'sound/effects/clang2.ogg', 70, 0, 0) diff --git a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm index ec2debcc1e..309f7612b0 100644 --- a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm +++ b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm @@ -292,7 +292,7 @@ span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \ span_notice("You have unfastened \the [src]."), \ "You hear ratchet.") - deconstruct() + atom_deconstruct() #undef REGULATE_NONE #undef REGULATE_INPUT diff --git a/code/ATMOSPHERICS/components/binary_devices/pump.dm b/code/ATMOSPHERICS/components/binary_devices/pump.dm index 3b1a28e2dc..6566b31dc8 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pump.dm @@ -253,7 +253,7 @@ Thus, the two variables affect pump operation are set in New(): span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \ span_notice("You have unfastened \the [src]."), \ "You hear ratchet.") - deconstruct() + atom_deconstruct() /obj/machinery/atmospherics/binary/pump/click_alt(mob/user) user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) diff --git a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm index c138cfcdbc..4aadbbc178 100644 --- a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm @@ -292,7 +292,7 @@ Thus, the two variables affect pump operation are set in New(): span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \ span_notice("You have unfastened \the [src]."), \ "You hear ratchet.") - deconstruct() + atom_deconstruct() /obj/machinery/atmospherics/binary/volume_pump/proc/multitool_act(var/obj/item/W as obj, var/mob/user as mob) if(!overclocked) diff --git a/code/ATMOSPHERICS/components/omni_devices/omni_base.dm b/code/ATMOSPHERICS/components/omni_devices/omni_base.dm index e767140ff2..8ac1cc5916 100644 --- a/code/ATMOSPHERICS/components/omni_devices/omni_base.dm +++ b/code/ATMOSPHERICS/components/omni_devices/omni_base.dm @@ -95,7 +95,7 @@ span_infoplain(span_bold("\The [user]") + "unfastens \the [src]."), \ span_notice("You have unfastened \the [src]."), \ "You hear a ratchet.") - deconstruct() + atom_deconstruct() /obj/machinery/atmospherics/omni/attack_hand(user as mob) if(..()) diff --git a/code/ATMOSPHERICS/components/portables_connector.dm b/code/ATMOSPHERICS/components/portables_connector.dm index 8f163cd670..b4310a32f1 100644 --- a/code/ATMOSPHERICS/components/portables_connector.dm +++ b/code/ATMOSPHERICS/components/portables_connector.dm @@ -165,4 +165,4 @@ span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \ span_notice("You have unfastened \the [src]."), \ "You hear a ratchet.") - deconstruct() + atom_deconstruct() diff --git a/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm b/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm index 60421bdbae..1ab257d871 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm @@ -65,7 +65,7 @@ span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \ span_notice("You have unfastened \the [src]."), \ "You hear a ratchet.") - deconstruct() + atom_deconstruct() // Housekeeping and pipe network stuff below /obj/machinery/atmospherics/trinary/get_neighbor_nodes_for_init() diff --git a/code/ATMOSPHERICS/components/tvalve.dm b/code/ATMOSPHERICS/components/tvalve.dm index 548127f502..dd7aefd914 100644 --- a/code/ATMOSPHERICS/components/tvalve.dm +++ b/code/ATMOSPHERICS/components/tvalve.dm @@ -340,7 +340,7 @@ span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \ span_notice("You have unfastened \the [src]."), \ "You hear a ratchet.") - deconstruct() + atom_deconstruct() /obj/machinery/atmospherics/tvalve/mirrored icon_state = "map_tvalvem0" diff --git a/code/ATMOSPHERICS/components/unary/heat_exchanger.dm b/code/ATMOSPHERICS/components/unary/heat_exchanger.dm index c12bd6a6fb..b80f8c6c50 100644 --- a/code/ATMOSPHERICS/components/unary/heat_exchanger.dm +++ b/code/ATMOSPHERICS/components/unary/heat_exchanger.dm @@ -88,4 +88,4 @@ span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \ span_notice("You have unfastened \the [src]."), \ "You hear a ratchet.") - deconstruct() + atom_deconstruct() diff --git a/code/ATMOSPHERICS/components/unary/outlet_injector.dm b/code/ATMOSPHERICS/components/unary/outlet_injector.dm index c53456d657..c3cb1f6898 100644 --- a/code/ATMOSPHERICS/components/unary/outlet_injector.dm +++ b/code/ATMOSPHERICS/components/unary/outlet_injector.dm @@ -198,7 +198,7 @@ span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \ span_notice("You have unfastened \the [src]."), \ "You hear a ratchet.") - deconstruct() + atom_deconstruct() /obj/machinery/atmospherics/unary/outlet_injector/click_ctrl(mob/user) if (volume_rate == ATMOS_DEFAULT_VOLUME_PUMP + 500 || use_power == USE_POWER_OFF) diff --git a/code/ATMOSPHERICS/components/unary/vent_pump.dm b/code/ATMOSPHERICS/components/unary/vent_pump.dm index ef4b80e154..5e5480fa81 100644 --- a/code/ATMOSPHERICS/components/unary/vent_pump.dm +++ b/code/ATMOSPHERICS/components/unary/vent_pump.dm @@ -442,7 +442,7 @@ span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \ span_notice("You have unfastened \the [src]."), \ "You hear a ratchet.") - deconstruct() + atom_deconstruct() /obj/machinery/atmospherics/unary/vent_pump/proc/multitool_act(obj/item/W, mob/user) var/list/options = list( diff --git a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm index 98b7c1489f..7c84656da6 100644 --- a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm +++ b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm @@ -315,7 +315,7 @@ span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \ span_notice("You have unfastened \the [src]."), \ "You hear a ratchet.") - deconstruct() + atom_deconstruct() /obj/machinery/atmospherics/unary/vent_scrubber/examine(mob/user) . = ..() diff --git a/code/ATMOSPHERICS/components/valve.dm b/code/ATMOSPHERICS/components/valve.dm index 3c26d21cb4..dd69c91cb4 100644 --- a/code/ATMOSPHERICS/components/valve.dm +++ b/code/ATMOSPHERICS/components/valve.dm @@ -304,7 +304,7 @@ span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \ span_notice("You have unfastened \the [src]."), \ "You hear a ratchet.") - deconstruct() + atom_deconstruct() /obj/machinery/atmospherics/valve/examine(mob/user) . = ..() diff --git a/code/ATMOSPHERICS/pipes/pipe_base.dm b/code/ATMOSPHERICS/pipes/pipe_base.dm index 32bb9f0262..506e91c8c7 100644 --- a/code/ATMOSPHERICS/pipes/pipe_base.dm +++ b/code/ATMOSPHERICS/pipes/pipe_base.dm @@ -161,7 +161,7 @@ span_hear("You hear a ratchet.")) if(unsafe_wrenching) unsafe_pressure_release(user, internal_pressure) - deconstruct() + atom_deconstruct() /obj/machinery/atmospherics/pipe/proc/change_color(var/new_color) //only pass valid pipe colors please ~otherwise your pipe will turn invisible diff --git a/code/__defines/_flags.dm b/code/__defines/_flags.dm index 8ee22fdfc6..9372421e09 100644 --- a/code/__defines/_flags.dm +++ b/code/__defines/_flags.dm @@ -1,6 +1,26 @@ /// 33554431 (2^24 - 1) is the maximum value our bitflags can reach. #define MAX_BITFLAG_DIGITS 8 +//Fire and Acid stuff, for resistance_flags +#define LAVA_PROOF (1<<0) +/// 100% immune to fire damage (but not necessarily to lava or heat) +#define FIRE_PROOF (1<<1) +/// atom is flammable and can have the burning component +#define FLAMMABLE (1<<2) +/// currently burning +#define ON_FIRE (1<<3) +/// acid can't even appear on it, let alone melt it. +#define UNACIDABLE (1<<4) +/// acid stuck on it doesn't melt it. +#define ACID_PROOF (1<<5) +/// doesn't take damage +#define INDESTRUCTIBLE (1<<6) +/// can't be frozen +#define FREEZE_PROOF (1<<7) +/// can't be shuttle crushed. +#define SHUTTLE_CRUSH_PROOF (1<<8) +/// can't be destroyed by bombs +#define BOMB_PROOF (1<<9) ///Object will protect itself. #define EMP_PROTECT_SELF (1<<0) ///Object will protect its contents from being EMPed. diff --git a/code/__defines/atmos.dm b/code/__defines/atmos.dm index 7a7b22d4aa..efdfebad54 100644 --- a/code/__defines/atmos.dm +++ b/code/__defines/atmos.dm @@ -100,3 +100,6 @@ #define TANK_MAX_RELEASE_PRESSURE (3*ONE_ATMOSPHERE) #define TANK_DEFAULT_RELEASE_PRESSURE ONE_ATMOSPHERE #define MAX_ATMOS_TEMPERATURE 1e30 //Without having a max temp, you can get .inf temps + +///Minimum temperature for items on fire +#define BURNING_ITEM_MINIMUM_TEMPERATURE (150+T0C) diff --git a/code/__defines/combat.dm b/code/__defines/combat.dm new file mode 100644 index 0000000000..566ae635ca --- /dev/null +++ b/code/__defines/combat.dm @@ -0,0 +1,28 @@ +//We will round to this value in damage calculations. +#define DAMAGE_PRECISION 0.1 + +//Damage flag defines // + +/// Involves corrosive substances. +#define ACID "acid" +/// Involved in checking whether a disease can infect or spread. Also involved in xeno neurotoxin. +#define BIO "bio" +/// Involves a shockwave, usually from an explosion. +#define BOMB "bomb" +/// Involves a solid projectile. +#define BULLET "bullet" +/// Involves being eaten +#define CONSUME "consume" +/// Involves an EMP or energy-based projectile. +#define ENERGY "energy" +/// Involves fire or temperature extremes. +#define FIRE "fire" +/// Involves a laser. +#define LASER "laser" +/// Involves a melee attack or a thrown object. +#define MELEE "melee" +/// Involved in checking the likelihood of applying a wound to a mob. +#define WOUND "wound" + +/// Calculates the new armour value after armour penetration. Can return negative values, and those must be caught. +#define PENETRATE_ARMOUR(armour, penetration) (penetration >= 100 ? 0 : 100 * (armour - penetration) / (100 - penetration)) diff --git a/code/__defines/dna.dm b/code/__defines/dna.dm index 2ea27cb14d..1ada12848f 100644 --- a/code/__defines/dna.dm +++ b/code/__defines/dna.dm @@ -11,7 +11,7 @@ #define FAT 6 #define HUSK 7 #define NOCLONE 8 -#define LASER 9 // Harm intent - click anywhere to shoot lasers from eyes. +#define LASER_EYES 9 // Harm intent - click anywhere to shoot lasers from eyes. #define HEAL 10 // Healing people with hands. #define FLASHPROOF 11 // Flashproof eyes. diff --git a/code/__defines/flags.dm b/code/__defines/flags.dm index 3f630bbecf..a02417893a 100644 --- a/code/__defines/flags.dm +++ b/code/__defines/flags.dm @@ -50,6 +50,13 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204 #define INFINITE_AIR (1<<6) // Provides an infinite air supply. #define NOSTRIP (1<<7) // Items that should never get stripped #define DROPDEL (1<<8) // Items that delete upon being dropped +/** + * for all things that are technically items but don't want to be treated as such, given on a case-by-case basis + * examples of use are hand items, omni-toolsets, non-limb limbs (hand eater, mounted chainsaw, many null rods), borg modules, bodyparts, organs, etc. + * This is used for general exclusion, such as preventing insertions into other items + * Basically, these aren't "real" items. <= wow thanks for the fucking insight sherlock +*/ +#define ABSTRACT (1<<9) // Flags for pass_flags. - Used in /atom/var/pass_flags #define PASSTABLE (1<<0) diff --git a/code/__defines/mecha.dm b/code/__defines/mecha.dm index 5441794f5c..bc4c137275 100644 --- a/code/__defines/mecha.dm +++ b/code/__defines/mecha.dm @@ -8,7 +8,7 @@ #define MECHA_PROC_DAMAGE 2 #define MECHA_PROC_INT_TEMP 4 -#define MELEE 1 +#define MECH_MELEE 1 #define RANGED 2 #define MECH_FACTION_NT "nano" diff --git a/code/__defines/obj_flags.dm b/code/__defines/obj_flags.dm index 0f6f1127e0..8f5627ad86 100644 --- a/code/__defines/obj_flags.dm +++ b/code/__defines/obj_flags.dm @@ -1,3 +1,35 @@ +// Flags for the obj_flags var on /obj +/// Object has been affected by a cryptographic sequencer (EMAG) disabling it or causing other malicious effects +#define EMAGGED (1<<0) +/// Can this be bludgeoned by items +#define CAN_BE_HIT (1<<1) +/// Admin possession yes/no +#define DANGEROUS_POSSESSION (1<<2) +/// Can you customize the description/name of the thing +#define UNIQUE_RENAME (1<<3) +/// If it can be renamed, is its description excluded +#define RENAME_NO_DESC (1<<4) +/// Should this object block z falling from loc +#define BLOCK_Z_OUT_DOWN (1<<5) +/// Should this object block z uprise from loc +#define BLOCK_Z_OUT_UP (1<<6) +/// Should this object block z falling from above +#define BLOCK_Z_IN_DOWN (1<<7) +/// Should this object block z uprise from below +#define BLOCK_Z_IN_UP (1<<8) +/// Does this object prevent things from being built on it +#define BLOCKS_CONSTRUCTION (1<<9) +/// Does this object prevent same-direction things from being built on it +#define BLOCKS_CONSTRUCTION_DIR (1<<10) +/// Can we ignore density when building on this object (for example, directional windows and grilles) +#define IGNORE_DENSITY (1<<11) +/// Can this object conduct electricity +#define CONDUCTS_ELECTRICITY (1<<12) +/// Atoms don't spawn anything when deconstructed (they just vanish) +#define NO_DEBRIS_AFTER_DECONSTRUCTION (1<<13) +/// Flag which tells an object to hang onto an support atom on late initialize. Usefull only during mapload and supported by some atoms only +#define MOUNT_ON_LATE_INITIALIZE (1<<14) + /// Flags for specifically what kind of items to get in get_equipped_items #define INCLUDE_POCKETS (1<<0) #define INCLUDE_ACCESSORIES (1<<1) diff --git a/code/__defines/span.dm b/code/__defines/span.dm index 1b41f3ca4d..446731c70e 100644 --- a/code/__defines/span.dm +++ b/code/__defines/span.dm @@ -163,6 +163,8 @@ #define span_lightpurple(str) ("" + str + "") #define span_darkpink(str) ("" + str + "") #define span_rose(str) ("" + str + "") +#define span_hypnophrase(str) ("" + str + "") + /* System and Debug */ // System filter diff --git a/code/__defines/subsystems.dm b/code/__defines/subsystems.dm index 5fe7d4a2c3..966d9c5862 100644 --- a/code/__defines/subsystems.dm +++ b/code/__defines/subsystems.dm @@ -131,6 +131,7 @@ #define FIRE_PRIORITY_CHARSETUP 25 #define FIRE_PRIORITY_AIRFLOW 30 #define FIRE_PRIORITY_AIR 35 +#define FIRE_PRIORITY_BURNING 40 #define FIRE_PRIORITY_OBJ 40 #define FIRE_PRIORITY_PROCESS 45 #define FIRE_PRIORITY_THROWING 45 diff --git a/code/__defines/traits/declarations.dm b/code/__defines/traits/declarations.dm index b305044f2a..02abee557c 100644 --- a/code/__defines/traits/declarations.dm +++ b/code/__defines/traits/declarations.dm @@ -57,6 +57,11 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_ELECTROVORE_OBLIGATE "electrovore_obligate" // adds wet stacks when licking someone #define TRAIT_SLOBBER "slobber" +/// Trait from being under the floor in some manner +#define TRAIT_UNDERFLOOR "underfloor" +#define TRAIT_RESISTHEAT "resist_heat" +/// For when you want to be able to touch hot things, but still want fire to be an issue. +#define TRAIT_RESISTHEATHANDS "resist_heat_handsonly" // Owner will be considered a tiny mob for some interactions, such as airlocks not opening unless they have a client, or being vacuumed up by the vacpack #define TRAIT_AMBIENT_PEST_MOB "ambient_pest_mob" ///Trait given by /datum/component/germ_sensitive diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 5ce4dff908..0a22f5b87b 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -246,7 +246,7 @@ */ /mob/proc/RangedAttack(var/atom/A, var/params) if(!mutations.len) return - if((LASER in mutations) && a_intent == I_HURT) + if((LASER_EYES in mutations) && a_intent == I_HURT) LaserEyes(A) // moved into a proc below else if(has_telegrip()) if(get_dist(src, A) > TK_MAXRANGE) diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index d510b2a9f4..91dbd24b18 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -2,9 +2,6 @@ /atom/proc/attack_generic(mob/user as mob) return 0 -/atom/proc/take_damage(var/damage) - return 0 - /* Humans: Adds an exception for gloves, to allow special glove types like the ninja ones. @@ -47,7 +44,7 @@ if(!gloves && !mutations.len && !spitting) return var/obj/item/clothing/gloves/G = gloves - if((LASER in mutations) && a_intent == I_HURT) + if((LASER_EYES in mutations) && a_intent == I_HURT) LaserEyes(A) // moved into a proc below else if(istype(G) && G.Touch(A,0)) // for magic gloves diff --git a/code/controllers/subsystems/processing/fire_burning.dm b/code/controllers/subsystems/processing/fire_burning.dm new file mode 100644 index 0000000000..6cde5e3c34 --- /dev/null +++ b/code/controllers/subsystems/processing/fire_burning.dm @@ -0,0 +1,6 @@ +/// The subsystem used to tick [/datum/component/burning] instances. +PROCESSING_SUBSYSTEM_DEF(burning) + name = "Burning" + priority = FIRE_PRIORITY_BURNING + flags = SS_NO_INIT|SS_BACKGROUND + runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME diff --git a/code/datums/components/burning.dm b/code/datums/components/burning.dm new file mode 100644 index 0000000000..2875554d7f --- /dev/null +++ b/code/datums/components/burning.dm @@ -0,0 +1,115 @@ +GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/effects/fire.dmi', "fire", appearance_flags = RESET_COLOR|KEEP_APART)) + +/** + * Component representing an atom being on fire. + * Should not be used on mobs, they use the fire stacks status effects. + * Can only be used on atoms that use the integrity system. + */ +/datum/component/burning + /// Fire overlay appearance we apply + var/fire_overlay + /// Particle holder for fire particles, if any. Still utilized over shared holders because they're movable-only + var/obj/effect/abstract/particle_holder/particle_effect + /// Particle type we're using for cleaning up our shared holder + var/particle_type + +/datum/component/burning/Initialize(fire_overlay = GLOB.fire_overlay, fire_particles = /particles/smoke/burning) + if(!isatom(parent)) + return COMPONENT_INCOMPATIBLE + var/atom/atom_parent = parent + if(!atom_parent.uses_integrity) + stack_trace("Tried to add /datum/component/burning to an atom ([atom_parent.type]) that does not use atom_integrity!") + return COMPONENT_INCOMPATIBLE + + // only flammable atoms should have this component, but it's not really an error if we try to apply this to a non flammable one + if(!(atom_parent.resistance_flags & FLAMMABLE) || (atom_parent.resistance_flags & FIRE_PROOF)) + qdel(src) + return + + src.fire_overlay = fire_overlay + if (fire_particles) + if(ismovable(parent)) + var/atom/movable/movable_parent = parent + // burning particles look pretty bad when they stack on mobs, so that behavior is not wanted for items + movable_parent.add_shared_particles(fire_particles, "[fire_particles]_[isitem(parent)]", isitem(parent) ? NONE : PARTICLE_ATTACH_MOB) + particle_type = fire_particles + else + particle_effect = new(atom_parent, fire_particles) + START_PROCESSING(SSburning, src) + +/datum/component/burning/Destroy(force) + STOP_PROCESSING(SSburning, src) + fire_overlay = null + if(particle_effect) + QDEL_NULL(particle_effect) + if (ismovable(parent) && particle_type) + var/atom/movable/movable_parent = parent + movable_parent.remove_shared_particles("[particle_type]_[isitem(parent)]") + return ..() + +/datum/component/burning/RegisterWithParent() + RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, PROC_REF(on_attack_hand)) + RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(on_update_overlays)) + RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) + RegisterSignal(parent, COMSIG_ATOM_EXTINGUISH, PROC_REF(on_extinguish)) + var/atom/atom_parent = parent + atom_parent.resistance_flags |= ON_FIRE + atom_parent.update_icon() + +/datum/component/burning/UnregisterFromParent() + UnregisterSignal(parent, list( + COMSIG_ATOM_ATTACK_HAND, + COMSIG_ATOM_UPDATE_OVERLAYS, + COMSIG_ATOM_EXAMINE, + COMSIG_ATOM_EXTINGUISH, + )) + var/atom/atom_parent = parent + if(!QDELETED(atom_parent)) + atom_parent.resistance_flags &= ~ON_FIRE + atom_parent.update_icon() + +/datum/component/burning/process(seconds_per_tick) + var/atom/atom_parent = parent + // Check if the parent somehow became fireproof, remove component if so + if(atom_parent.resistance_flags & FIRE_PROOF) + atom_parent.extinguish() + return + atom_parent.take_damage(10 * seconds_per_tick, BURN, FIRE, FALSE) + +/// Alerts any examiners that the parent is on fire (even though it should be rather obvious) +/datum/component/burning/proc/on_examine(atom/source, mob/user, list/examine_list) + SIGNAL_HANDLER + + examine_list += span_danger("[source.p_Theyre()] burning!") + +/// Handles searing the hand of anyone who tries to touch parent without protection. +/datum/component/burning/proc/on_attack_hand(atom/source, mob/living/carbon/user) + SIGNAL_HANDLER + + if(!iscarbon(user) || user.can_touch_burning(source)) + to_chat(user, span_notice("You put out the fire on [source].")) + source.extinguish() + return COMPONENT_CANCEL_ATTACK_CHAIN + + user.apply_damage(5, BURN, user.get_active_hand()) + to_chat(user, span_userdanger("You burn your hand on [source]!")) + user.emote("scream") + playsound(source, 'sound/items/weapons/sear.ogg', 50, TRUE) + return COMPONENT_CANCEL_ATTACK_CHAIN + +/// Maintains the burning overlay on the parent atom +/datum/component/burning/proc/on_update_overlays(atom/source, list/overlays) + SIGNAL_HANDLER + + //most likely means the component is being removed + if(!(source.resistance_flags & ON_FIRE)) + return + + if(fire_overlay) + overlays += fire_overlay + +/// Deletes the component when the atom gets extinguished +/datum/component/burning/proc/on_extinguish(atom/source, list/overlays) + SIGNAL_HANDLER + + qdel(src) diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm index ffe3274ee7..7565438fc2 100644 --- a/code/defines/obj/weapon.dm +++ b/code/defines/obj/weapon.dm @@ -73,6 +73,7 @@ w_class = ITEMSIZE_SMALL throw_speed = 4 throw_range = 5 + resistance_flags = FLAMMABLE /obj/item/disk name = "disk" @@ -86,6 +87,7 @@ icon_state = "nucleardisk" item_state = "card-id" w_class = ITEMSIZE_SMALL + resistance_flags = INDESTRUCTIBLE | FIRE_PROOF /* /obj/item/game_kit @@ -109,6 +111,7 @@ var/obj/item/gift = null item_state = "gift" w_class = ITEMSIZE_LARGE + resistance_flags = FLAMMABLE /*/obj/item/syndicate_uplink name = "station bounced radio" diff --git a/code/game/atom/atom_defense.dm b/code/game/atom/atom_defense.dm new file mode 100644 index 0000000000..8aa4a6b668 --- /dev/null +++ b/code/game/atom/atom_defense.dm @@ -0,0 +1,109 @@ +/atom + ///any atom that uses integrity and can be damaged must set this to true, otherwise the integrity procs will throw an error + var/uses_integrity = FALSE + + VAR_PRIVATE/atom_integrity //defaults to max_integrity + var/max_integrity = 500 + var/integrity_failure = 0 //0 if we have no special broken behavior, otherwise is a percentage of at what point the atom breaks. 0.5 being 50% + ///Damage under this value will be completely ignored + var/damage_deflection = 0 + + var/resistance_flags = NONE // INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ON_FIRE | UNACIDABLE | ACID_PROOF + +/// The essential proc to call when an atom must receive damage of any kind. +/atom/proc/take_damage(damage_amount, damage_type = BRUTE, damage_flag = "", sound_effect = TRUE, attack_dir, armour_penetration = 0) + if(!uses_integrity) + CRASH("[src] had /atom/proc/take_damage() called on it without it being a type that has uses_integrity = TRUE!") + if(QDELETED(src)) + CRASH("[src] taking damage after deletion") + if(atom_integrity <= 0) + CRASH("[src] taking damage while having <= 0 integrity") + if(sound_effect) + play_attack_sound(damage_amount, damage_type, damage_flag) + if(resistance_flags & INDESTRUCTIBLE) + return + damage_amount = run_atom_armor(damage_amount, damage_type, damage_flag, attack_dir, armour_penetration) + if(damage_amount < DAMAGE_PRECISION) + return + if(SEND_SIGNAL(src, COMSIG_ATOM_TAKE_DAMAGE, damage_amount, damage_type, damage_flag, sound_effect, attack_dir, armour_penetration) & COMPONENT_NO_TAKE_DAMAGE) + return + + . = damage_amount + + var/previous_atom_integrity = atom_integrity + + update_integrity(atom_integrity - damage_amount) + + var/integrity_failure_amount = integrity_failure * max_integrity + + //BREAKING FIRST + if(integrity_failure && previous_atom_integrity > integrity_failure_amount && atom_integrity <= integrity_failure_amount) + atom_break(damage_flag) + + //DESTROYING SECOND + if(atom_integrity <= 0 && previous_atom_integrity > 0) + atom_destruction(damage_flag) + +///the sound played when the atom is damaged. +/atom/proc/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) + switch(damage_type) + if(BRUTE) + if(damage_amount) + playsound(src, 'sound/items/weapons/smash.ogg', 50, TRUE) + else + playsound(src, 'sound/items/weapons/tap.ogg', 50, TRUE) + if(BURN) + playsound(src.loc, 'sound/items/tools/welder.ogg', 100, TRUE) + +/// Handles the integrity of an atom changing. This must be called instead of changing integrity directly. +/atom/proc/update_integrity(new_value) + SHOULD_NOT_OVERRIDE(TRUE) + if(!uses_integrity) + CRASH("/atom/proc/update_integrity() was called on [src] when it doesn't use integrity!") + var/old_value = atom_integrity + new_value = max(0, new_value) + if(atom_integrity == new_value) + return + atom_integrity = new_value + on_update_integrity(old_value, new_value) + return new_value + +/// Handle updates to your atom's integrity +/atom/proc/on_update_integrity(old_value, new_value) + SHOULD_NOT_SLEEP(TRUE) + SHOULD_CALL_PARENT(TRUE) + SEND_SIGNAL(src, COMSIG_ATOM_INTEGRITY_CHANGED, old_value, new_value) + +/// Called after the atom takes damage and integrity is below integrity_failure level +/atom/proc/atom_break(damage_flag) + SHOULD_CALL_PARENT(TRUE) + SEND_SIGNAL(src, COMSIG_ATOM_BREAK, damage_flag) + +/// Called when integrity is repaired above the breaking point having been broken before +/atom/proc/atom_fix() + SHOULD_CALL_PARENT(TRUE) + SEND_SIGNAL(src, COMSIG_ATOM_FIX) + +///what happens when the atom's integrity reaches zero. +/atom/proc/atom_destruction(damage_flag) + SHOULD_CALL_PARENT(TRUE) + SEND_SIGNAL(src, COMSIG_ATOM_DESTRUCTION, damage_flag) + +///returns the damage value of the attack after processing the atom's various armor protections +///Damage_flag can be any of the following: "melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0 +///MELEE, BULLET, LASER, ENERGY, BOMB, BIO, and "rad" +/atom/proc/run_atom_armor(damage_amount, damage_type, damage_flag = 0, attack_dir, armour_penetration = 0) + if(!uses_integrity) + CRASH("/atom/proc/run_atom_armor was called on [src] without being implemented as a type that uses integrity!") + if(damage_flag == MELEE && damage_amount < damage_deflection) + return 0 + if(damage_type != BRUTE && damage_type != BURN) + return 0 + var/armor_protection = 0 + if(isitem(src)) //Only items have armor until we get armor datums. + var/obj/item/item_to_check = src + if(damage_flag) + armor_protection = item_to_check.armor[damage_flag] + if(armor_protection) //Only apply weak-against-armor/hollowpoint effects if there actually IS armor. + armor_protection = clamp(PENETRATE_ARMOUR(armor_protection, armour_penetration), min(armor_protection, 0), 100) + return round(damage_amount * (100 - armor_protection) * 0.01, DAMAGE_PRECISION) diff --git a/code/game/atom/atoms_initializing_EXPENSIVE.dm b/code/game/atom/atoms_initializing_EXPENSIVE.dm index fd5d4961a0..d94889d3bc 100644 --- a/code/game/atom/atoms_initializing_EXPENSIVE.dm +++ b/code/game/atom/atoms_initializing_EXPENSIVE.dm @@ -130,6 +130,9 @@ if(color) add_atom_colour(color, FIXED_COLOUR_PRIORITY) + if(uses_integrity) + atom_integrity = max_integrity + /* if (light_system == COMPLEX_LIGHT && light_power && light_range) update_light() diff --git a/code/game/gamemodes/cult/cultify/obj.dm b/code/game/gamemodes/cult/cultify/obj.dm index c80aa41e37..c8860ab75c 100644 --- a/code/game/gamemodes/cult/cultify/obj.dm +++ b/code/game/gamemodes/cult/cultify/obj.dm @@ -109,6 +109,9 @@ new /obj/structure/simple_door/wood(loc) ..() +/obj/structure/simple_door/wood + resistance_flags = FLAMMABLE + /obj/structure/simple_door/wood/cultify() return diff --git a/code/game/machinery/deployable_vr.dm b/code/game/machinery/deployable_vr.dm index bb9fc07ed4..f772bd0c95 100644 --- a/code/game/machinery/deployable_vr.dm +++ b/code/game/machinery/deployable_vr.dm @@ -16,6 +16,7 @@ var/static/list/cutout_types var/static/list/painters = list(/obj/item/reagent_containers/glass/paint, /obj/item/floor_painter)//, /obj/item/closet_painter) + resistance_flags = FLAMMABLE /obj/structure/barricade/cutout/Initialize(mapload) . = ..() diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 1042e4b562..80512c7ec9 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -473,7 +473,7 @@ Class Procs: A.update_desc() A.update_icon() M.loc = null - M.deconstruct(src) + M.atom_deconstruct(TRUE, src) qdel(src) return 1 diff --git a/code/game/machinery/wishgranter.dm b/code/game/machinery/wishgranter.dm index 71b9041ee5..2972b36964 100644 --- a/code/game/machinery/wishgranter.dm +++ b/code/game/machinery/wishgranter.dm @@ -35,7 +35,7 @@ if("Power") to_chat(user, span_boldwarning("Your wish is granted, but at a terrible cost...")) to_chat(user, span_warning("The Wish Granter punishes you for your selfishness, claiming your soul.")) - if (!(LASER in user.mutations)) + if (!(LASER_EYES in user.mutations)) user.mutations.Add(LASER) to_chat(user, span_notice("You feel pressure building behind your eyes.")) if (!(COLD_RESISTANCE in user.mutations)) diff --git a/code/game/mecha/components/_component.dm b/code/game/mecha/components/_component.dm index e4693a62cc..3f4e694f9e 100644 --- a/code/game/mecha/components/_component.dm +++ b/code/game/mecha/components/_component.dm @@ -17,7 +17,7 @@ var/integrity var/integrity_danger_mod = 0.5 // Multiplier for comparison to max_integrity before problems start. - var/max_integrity = 100 + max_integrity = 100 var/step_delay = 0 diff --git a/code/game/mecha/equipment/mecha_equipment.dm b/code/game/mecha/equipment/mecha_equipment.dm index deccee9b04..e05cd04aa2 100644 --- a/code/game/mecha/equipment/mecha_equipment.dm +++ b/code/game/mecha/equipment/mecha_equipment.dm @@ -12,7 +12,7 @@ var/equip_ready = TRUE var/energy_drain = 0 var/obj/mecha/chassis = null - var/range = MELEE //bitflags + var/range = MECH_MELEE //bitflags /// Bitflag. Used by exosuit fabricator to assign sub-categories based on which exosuits can equip this. var/mech_flags = NONE var/salvageable = TRUE @@ -117,7 +117,7 @@ return range&RANGED /obj/item/mecha_parts/mecha_equipment/proc/is_melee() - return range&MELEE + return range&MECH_MELEE /obj/item/mecha_parts/mecha_equipment/proc/enable_special_checks(atom/target) if(ispath(required_type)) diff --git a/code/game/mecha/equipment/tools/catapult.dm b/code/game/mecha/equipment/tools/catapult.dm index 7241b10daa..f4457551ae 100644 --- a/code/game/mecha/equipment/tools/catapult.dm +++ b/code/game/mecha/equipment/tools/catapult.dm @@ -5,7 +5,7 @@ origin_tech = list(TECH_BLUESPACE = 2, TECH_MAGNET = 3) equip_cooldown = 10 energy_drain = 100 - range = MELEE|RANGED + range = MECH_MELEE|RANGED var/atom/movable/locked var/mode = 1 //1 - gravsling 2 - gravpush diff --git a/code/game/mecha/equipment/tools/extinguisher.dm b/code/game/mecha/equipment/tools/extinguisher.dm index 19821337de..8debd7bb6b 100644 --- a/code/game/mecha/equipment/tools/extinguisher.dm +++ b/code/game/mecha/equipment/tools/extinguisher.dm @@ -5,7 +5,7 @@ icon_state = "mecha_exting" equip_cooldown = 5 energy_drain = 0 - range = MELEE|RANGED + range = MECH_MELEE|RANGED required_type = list(/obj/mecha/working) var/spray_particles = 5 var/spray_amount = 5 //units of liquid per particle. 5 is enough to wet the floor - it's a big fire extinguisher, so should be fine diff --git a/code/game/mecha/equipment/tools/generator.dm b/code/game/mecha/equipment/tools/generator.dm index 3b8323984c..af1f77ee49 100644 --- a/code/game/mecha/equipment/tools/generator.dm +++ b/code/game/mecha/equipment/tools/generator.dm @@ -5,7 +5,7 @@ origin_tech = list(TECH_PHORON = 2, TECH_POWER = 2, TECH_ENGINEERING = 1) equip_cooldown = 10 energy_drain = 0 - range = MELEE + range = MECH_MELEE var/coeff = 100 var/obj/item/stack/material/fuel var/fuel_type = /obj/item/stack/material/phoron diff --git a/code/game/mecha/equipment/tools/inflatables.dm b/code/game/mecha/equipment/tools/inflatables.dm index 271df20146..a8b4b056ef 100644 --- a/code/game/mecha/equipment/tools/inflatables.dm +++ b/code/game/mecha/equipment/tools/inflatables.dm @@ -5,7 +5,7 @@ origin_tech = list(TECH_MATERIAL = 5, TECH_MAGNET = 3) equip_cooldown = 3 energy_drain = 30 - range = MELEE + range = MECH_MELEE equip_type = EQUIP_UTILITY ready_sound = 'sound/effects/spray.ogg' required_type = list(/obj/mecha/working/ripley) diff --git a/code/game/mecha/equipment/tools/orescanner.dm b/code/game/mecha/equipment/tools/orescanner.dm index 02018347a2..83612e1104 100644 --- a/code/game/mecha/equipment/tools/orescanner.dm +++ b/code/game/mecha/equipment/tools/orescanner.dm @@ -5,7 +5,7 @@ origin_tech = list(TECH_MATERIAL = 2, TECH_MAGNET = 2, TECH_POWER = 2) equip_cooldown = 5 energy_drain = 30 - range = MELEE|RANGED + range = MECH_MELEE|RANGED equip_type = EQUIP_SPECIAL ready_sound = 'sound/items/goggles_charge.ogg' required_type = list(/obj/mecha/working/ripley) diff --git a/code/game/mecha/equipment/tools/passenger.dm b/code/game/mecha/equipment/tools/passenger.dm index d81c736a74..cb556ed390 100644 --- a/code/game/mecha/equipment/tools/passenger.dm +++ b/code/game/mecha/equipment/tools/passenger.dm @@ -4,7 +4,7 @@ icon_state = "mecha_passenger" origin_tech = list(TECH_ENGINEERING = 1, TECH_BIO = 1) energy_drain = 10 - range = MELEE + range = MECH_MELEE equip_cooldown = 20 var/mob/living/carbon/occupant = null var/door_locked = 1 diff --git a/code/game/mecha/equipment/tools/powertool.dm b/code/game/mecha/equipment/tools/powertool.dm index 75133c798f..c1f6a95953 100644 --- a/code/game/mecha/equipment/tools/powertool.dm +++ b/code/game/mecha/equipment/tools/powertool.dm @@ -5,7 +5,7 @@ origin_tech = list(TECH_MATERIAL = 2, TECH_MAGNET = 2, TECH_POWER = 2) equip_cooldown = 3 energy_drain = 15 - range = MELEE + range = MECH_MELEE equip_type = EQUIP_UTILITY ready_sound = 'sound/items/Ratchet.ogg' required_type = list(/obj/mecha/working/ripley) diff --git a/code/game/mecha/equipment/tools/rcd.dm b/code/game/mecha/equipment/tools/rcd.dm index f1980e079d..71e2a3a668 100644 --- a/code/game/mecha/equipment/tools/rcd.dm +++ b/code/game/mecha/equipment/tools/rcd.dm @@ -6,7 +6,7 @@ origin_tech = list(TECH_MATERIAL = 4, TECH_BLUESPACE = 3, TECH_MAGNET = 4, TECH_POWER = 4) equip_cooldown = 10 energy_drain = 250 - range = MELEE|RANGED + range = MECH_MELEE|RANGED equip_type = EQUIP_SPECIAL var/obj/item/rcd/electric/mounted/mecha/my_rcd = null diff --git a/code/game/mecha/equipment/tools/sleeper.dm b/code/game/mecha/equipment/tools/sleeper.dm index e25a834be6..06a2085343 100644 --- a/code/game/mecha/equipment/tools/sleeper.dm +++ b/code/game/mecha/equipment/tools/sleeper.dm @@ -5,7 +5,7 @@ icon_state = "sleeper_0" origin_tech = list(TECH_DATA = 2, TECH_BIO = 3) energy_drain = 20 - range = MELEE + range = MECH_MELEE equip_cooldown = 30 mech_flags = EXOSUIT_MODULE_MEDICAL var/mob/living/carbon/human/occupant = null diff --git a/code/game/mecha/equipment/tools/syringe_gun.dm b/code/game/mecha/equipment/tools/syringe_gun.dm index 5395401be3..10ee161b4b 100644 --- a/code/game/mecha/equipment/tools/syringe_gun.dm +++ b/code/game/mecha/equipment/tools/syringe_gun.dm @@ -13,7 +13,7 @@ energy_drain = 10 var/mode = 0 //0 - fire syringe, 1 - analyze reagents. var/datum/global_iterator/mech_synth/synth - range = MELEE|RANGED + range = MECH_MELEE|RANGED equip_cooldown = 10 origin_tech = list(TECH_MATERIAL = 3, TECH_BIO = 4, TECH_MAGNET = 4, TECH_DATA = 3) required_type = list(/obj/mecha/medical) @@ -280,7 +280,7 @@ desc = "A small shoulder-mounted dronebay containing a rapid response drone capable of moderately stabilizing a patient near the exosuit." icon_state = "mecha_dronebay" origin_tech = list(TECH_PHORON = 3, TECH_MAGNET = 6, TECH_BIO = 5, TECH_DATA = 4) - range = MELEE|RANGED + range = MECH_MELEE|RANGED equip_cooldown = 3 SECONDS required_type = list(/obj/mecha/medical) @@ -496,7 +496,7 @@ origin_tech = list(TECH_MATERIAL = 5, TECH_MAGNET = 5, TECH_BIO = 5) equip_cooldown = 5 SECONDS energy_drain = 100 - range = MELEE + range = MECH_MELEE equip_type = EQUIP_UTILITY ready_sound = 'sound/weapons/flash.ogg' required_type = list(/obj/mecha/medical) diff --git a/code/game/mecha/equipment/tools/weldinglaser.dm b/code/game/mecha/equipment/tools/weldinglaser.dm index bd30119657..58a43fc47c 100644 --- a/code/game/mecha/equipment/tools/weldinglaser.dm +++ b/code/game/mecha/equipment/tools/weldinglaser.dm @@ -5,7 +5,7 @@ origin_tech = list(TECH_MATERIAL = 4, TECH_MAGNET = 3, TECH_POWER = 4, TECH_PHORON = 2) equip_cooldown = 3 energy_drain = 15 - range = MELEE + range = MECH_MELEE equip_type = EQUIP_UTILITY ready_sound = 'sound/items/Ratchet.ogg' required_type = list(/obj/mecha/working/ripley) @@ -27,8 +27,8 @@ ..() if(enable_special) - range = MELEE|RANGED + range = MECH_MELEE|RANGED my_tool.reach = 7 else - range = MELEE + range = MECH_MELEE my_tool.reach = 1 diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm index 9228ead42d..ab53dae46a 100644 --- a/code/game/objects/effects/effect_system.dm +++ b/code/game/objects/effects/effect_system.dm @@ -6,6 +6,7 @@ would spawn and follow the beaker, even if it is carried or thrown. */ /obj/effect light_on = TRUE + uses_integrity = FALSE /obj/effect/effect name = "effect" diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm index be5aec3d29..e1cd41d0db 100644 --- a/code/game/objects/items/devices/radio/intercom.dm +++ b/code/game/objects/items/devices/radio/intercom.dm @@ -160,7 +160,7 @@ A.anchored = TRUE A.state = 2 A.update_icon() - M.deconstruct(src) + M.atom_deconstruct(TRUE, src) qdel(src) else src.attack_hand(user) diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm index cba0398f89..60c3ad46ff 100644 --- a/code/game/objects/items/stacks/tiles/tile_types.dm +++ b/code/game/objects/items/stacks/tiles/tile_types.dm @@ -85,6 +85,7 @@ drop_sound = 'sound/items/drop/herb.ogg' pickup_sound = 'sound/items/pickup/herb.ogg' craftable = TRUE + resistance_flags = FLAMMABLE /* * Wood @@ -102,6 +103,7 @@ no_variants = FALSE drop_sound = 'sound/items/drop/wooden.ogg' pickup_sound = 'sound/items/pickup/wooden.ogg' + resistance_flags = FLAMMABLE /obj/item/stack/tile/wood/alt name = "wood floor tile" @@ -396,6 +398,7 @@ no_variants = FALSE drop_sound = 'sound/items/drop/cloth.ogg' pickup_sound = 'sound/items/pickup/cloth.ogg' + resistance_flags = FLAMMABLE /obj/item/stack/tile/carpet/teal desc = "A piece of teal carpet. It is the same size as a normal floor tile!" diff --git a/code/game/objects/items/weapons/circuitboards/circuitboard.dm b/code/game/objects/items/weapons/circuitboards/circuitboard.dm index 8e2ea7d44d..25c0510f58 100644 --- a/code/game/objects/items/weapons/circuitboards/circuitboard.dm +++ b/code/game/objects/items/weapons/circuitboards/circuitboard.dm @@ -34,7 +34,7 @@ //Called when a computer is deconstructed to produce a circuitboard. //Only used by computers, as other machines store their circuitboard instance. -/obj/item/circuitboard/proc/deconstruct(var/obj/machinery/M) +/obj/item/circuitboard/atom_deconstruct(disassembled = TRUE, var/obj/machinery/M) if(istype(M, build_path)) return 1 return 0 diff --git a/code/game/objects/items/weapons/circuitboards/computer/air_management.dm b/code/game/objects/items/weapons/circuitboards/computer/air_management.dm index 55b4b8f712..d50a6adb55 100644 --- a/code/game/objects/items/weapons/circuitboards/computer/air_management.dm +++ b/code/game/objects/items/weapons/circuitboards/computer/air_management.dm @@ -25,6 +25,6 @@ if (..(C)) C.frequency = frequency -/obj/item/circuitboard/air_management/deconstruct(var/obj/machinery/computer/general_air_control/C) +/obj/item/circuitboard/air_management/atom_deconstruct(disassembled = TRUE, var/obj/machinery/computer/general_air_control/C) if (..(C)) frequency = C.frequency diff --git a/code/game/objects/items/weapons/circuitboards/computer/camera_monitor.dm b/code/game/objects/items/weapons/circuitboards/computer/camera_monitor.dm index 04d56c9745..50441b2071 100644 --- a/code/game/objects/items/weapons/circuitboards/computer/camera_monitor.dm +++ b/code/game/objects/items/weapons/circuitboards/computer/camera_monitor.dm @@ -48,7 +48,7 @@ if (..(C)) C.set_network(network.Copy()) -/obj/item/circuitboard/security/deconstruct(var/obj/machinery/computer/security/C) +/obj/item/circuitboard/security/atom_deconstruct(disassembled = TRUE, var/obj/machinery/computer/security/C) if (..(C)) network = C.network.Copy() diff --git a/code/game/objects/items/weapons/circuitboards/computer/shuttle.dm b/code/game/objects/items/weapons/circuitboards/computer/shuttle.dm index 40221f995d..48359b53e8 100644 --- a/code/game/objects/items/weapons/circuitboards/computer/shuttle.dm +++ b/code/game/objects/items/weapons/circuitboards/computer/shuttle.dm @@ -11,7 +11,7 @@ var/shuttle_tag = null // If set, link constructed console to this shuttle. If null, auto-detect. hidden = TRUE // todo - Make properly constructable in round -/obj/item/circuitboard/shuttle_console/deconstruct(obj/machinery/computer/shuttle_control/M) +/obj/item/circuitboard/shuttle_console/atom_deconstruct(disassembled = TRUE, obj/machinery/computer/shuttle_control/M) shuttle_tag = M.shuttle_tag if(shuttle_tag) name = T_BOARD("[shuttle_tag] control console") diff --git a/code/game/objects/items/weapons/circuitboards/computer/supply.dm b/code/game/objects/items/weapons/circuitboards/computer/supply.dm index 30168a939c..7e044a3abc 100644 --- a/code/game/objects/items/weapons/circuitboards/computer/supply.dm +++ b/code/game/objects/items/weapons/circuitboards/computer/supply.dm @@ -17,7 +17,7 @@ if (..(SC)) SC.can_order_contraband = contraband_enabled -/obj/item/circuitboard/supplycomp/deconstruct(var/obj/machinery/computer/supplycomp/SC) +/obj/item/circuitboard/supplycomp/atom_deconstruct(disassembled = TRUE, var/obj/machinery/computer/supplycomp/SC) if (..(SC)) contraband_enabled = SC.can_order_contraband diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm index fcbfe2be69..5d501c65e8 100644 --- a/code/game/objects/items/weapons/gift_wrappaper.dm +++ b/code/game/objects/items/weapons/gift_wrappaper.dm @@ -17,6 +17,7 @@ pickup_sound = 'sound/items/pickup/cardboardbox.ogg' ///Var used for attack_hand chain. var/special_handling = FALSE + resistance_flags = FLAMMABLE /obj/item/a_gift/Initialize(mapload) . = ..() diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm index 30de779f36..a9b72d452c 100644 --- a/code/game/objects/items/weapons/storage/bags.dm +++ b/code/game/objects/items/weapons/storage/bags.dm @@ -51,6 +51,7 @@ max_storage_space = ITEMSIZE_SMALL * 21 can_hold = list() // any cant_hold = list(/obj/item/disk/nuclear) + resistance_flags = FLAMMABLE /obj/item/storage/bag/trash/update_icon() if(contents.len == 0) @@ -68,6 +69,7 @@ origin_tech = list(TECH_BLUESPACE = 3) max_w_class = ITEMSIZE_NORMAL max_storage_space = ITEMSIZE_COST_NORMAL * 10 // Slightly less than BoH + resistance_flags = FIRE_PROOF /obj/item/storage/bag/trash/holding/update_icon() return @@ -87,6 +89,7 @@ max_w_class = ITEMSIZE_SMALL can_hold = list() // any cant_hold = list(/obj/item/disk/nuclear) + resistance_flags = FLAMMABLE // ----------------------------- // Plant bag @@ -100,6 +103,7 @@ max_w_class = ITEMSIZE_NORMAL w_class = ITEMSIZE_SMALL can_hold = list(/obj/item/reagent_containers/food/snacks/grown,/obj/item/seeds,/obj/item/grown) + resistance_flags = FLAMMABLE /obj/item/storage/bag/plants/large name = "large plant bag" @@ -124,6 +128,7 @@ storage_slots = 7 allow_quick_empty = 1 // this function is superceded + resistance_flags = FIRE_PROOF /obj/item/storage/bag/sheetsnatcher/can_be_inserted(obj/item/W as obj, stop_messages = 0) if(!istype(W,/obj/item/stack/material)) @@ -281,6 +286,7 @@ max_w_class = ITEMSIZE_NORMAL w_class = ITEMSIZE_SMALL can_hold = list(/obj/item/coin,/obj/item/spacecash,/obj/item/spacecasinocash) + resistance_flags = FLAMMABLE // ----------------------------- // Chemistry Bag @@ -294,6 +300,7 @@ w_class = ITEMSIZE_LARGE slowdown = 1 //you probably shouldn't be running with chemicals can_hold = list(/obj/item/reagent_containers/pill,/obj/item/reagent_containers/glass/beaker,/obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/hypospray/autoinjector) + resistance_flags = FLAMMABLE // ----------------------------- // Xeno Bag @@ -307,6 +314,7 @@ max_w_class = ITEMSIZE_NORMAL w_class = ITEMSIZE_SMALL can_hold = list(/obj/item/slime_extract,/obj/item/slimepotion, /obj/item/reagent_containers/food/snacks/monkeycube) + resistance_flags = FLAMMABLE // ----------------------------- // Virology Bag @@ -319,7 +327,8 @@ max_storage_space = ITEMSIZE_COST_SMALL * 12 max_w_class = ITEMSIZE_NORMAL w_class = ITEMSIZE_SMALL - can_hold = list(/obj/item/reagent_containers/glass/beaker/vial/) + can_hold = list(/obj/item/reagent_containers/glass/beaker/vial) + resistance_flags = FLAMMABLE // ----------------------------- // Food Bag @@ -333,6 +342,7 @@ max_w_class = ITEMSIZE_NORMAL w_class = ITEMSIZE_SMALL can_hold = list(/obj/item/reagent_containers/food/snacks,/obj/item/reagent_containers/food/condiment) + resistance_flags = FLAMMABLE // ----------------------------- // Food Bag (Service Hound) @@ -348,6 +358,7 @@ can_hold = list(/obj/item/reagent_containers/food/snacks,/obj/item/reagent_containers/food/condiment, /obj/item/reagent_containers/glass/beaker,/obj/item/reagent_containers/glass/bottle,/obj/item/coin,/obj/item/spacecash, /obj/item/reagent_containers/food/snacks/grown,/obj/item/seeds,/obj/item/grown,/obj/item/reagent_containers/pill) + resistance_flags = FIRE_PROOF // ----------------------------- // Evidence Bag @@ -361,6 +372,7 @@ max_w_class = ITEMSIZE_NORMAL w_class = ITEMSIZE_SMALL can_hold = list(/obj/item/forensics/swab,/obj/item/sample/print,/obj/item/sample/fibers,/obj/item/evidencebag) + resistance_flags = FLAMMABLE // ----------------------------- // Santa bag @@ -377,6 +389,7 @@ max_storage_space = ITEMSIZE_COST_NORMAL * 100 // can store a ton of shit! can_hold = list() // any cant_hold = list(/obj/item/disk/nuclear) + resistance_flags = FIRE_PROOF //ho ho ho /obj/item/storage/bag/santabag/update_icon() if(contents.len < 10) diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index 25793869b2..2713fa66a5 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -34,6 +34,7 @@ use_sound = 'sound/items/storage/box.ogg' drop_sound = 'sound/items/drop/cardboardbox.ogg' pickup_sound = 'sound/items/pickup/cardboardbox.ogg' + resistance_flags = FLAMMABLE // BubbleWrap - A box can be folded up to make card /obj/item/storage/box/attack_self(mob/user) diff --git a/code/game/objects/items/weapons/storage/internal.dm b/code/game/objects/items/weapons/storage/internal.dm index 9d139a91c8..ded7773644 100644 --- a/code/game/objects/items/weapons/storage/internal.dm +++ b/code/game/objects/items/weapons/storage/internal.dm @@ -3,6 +3,7 @@ /obj/item/storage/internal preserve_item = 1 var/obj/item/master_item + item_flags = ABSTRACT /obj/item/storage/internal/Initialize(mapload) . = ..() diff --git a/code/game/objects/items/weapons/storage/laundry_basket.dm b/code/game/objects/items/weapons/storage/laundry_basket.dm index 340fb24684..b2a82ac9e9 100644 --- a/code/game/objects/items/weapons/storage/laundry_basket.dm +++ b/code/game/objects/items/weapons/storage/laundry_basket.dm @@ -19,6 +19,7 @@ allow_quick_gather = 1 collection_mode = 1 var/linked + resistance_flags = FLAMMABLE /obj/item/storage/laundry_basket/attack_hand(mob/living/user as mob) diff --git a/code/game/objects/items/weapons/storage/ore_bag.dm b/code/game/objects/items/weapons/storage/ore_bag.dm index e6bf6cd975..6fef5bfbfc 100644 --- a/code/game/objects/items/weapons/storage/ore_bag.dm +++ b/code/game/objects/items/weapons/storage/ore_bag.dm @@ -43,19 +43,21 @@ var/last_update = 0 drop_sound = 'sound/items/drop/backpack.ogg' pickup_sound = 'sound/items/pickup/backpack.ogg' + item_flags = FLAMMABLE /obj/item/ore_bag/holding name = "mining satchel of holding" desc = "Like a mining satchel, but when you put your hand in, you're pretty sure you can feel time itself." icon_state = "satchel_bspace" max_storage_space = ITEMSIZE_COST_NORMAL * 15000 // This should never, ever, ever be reached. + item_flags = FIRE_PROOF /obj/item/ore_bag/sleeper name = "processing chamber" desc = "A mining satchel built into a sleeper. VORE!!!" icon_state = "satchel_bspace" max_storage_space = 500 - //item_flags = ABSTRACT //Enable once we have abstract PR merged. + item_flags = INDESTRUCTIBLE | ABSTRACT /obj/item/ore_bag/attackby(obj/item/W, mob/user) if(current_capacity >= max_storage_space) diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm index e97e5320b4..b807b82ec6 100644 --- a/code/game/objects/items/weapons/tanks/tanks.dm +++ b/code/game/objects/items/weapons/tanks/tanks.dm @@ -596,6 +596,7 @@ GLOBAL_LIST_EMPTY(tank_gauge_cache) desc = "Used as a stand in to trigger single tank assemblies... but you shouldn't see this." var/obj/item/tank/tank = null var/obj/item/assembly_holder/assembly = null + item_flags = ABSTRACT /obj/item/tankassemblyproxy/receive_signal() //This is mainly called by the sensor through sense() to the holder, and from the holder to here. diff --git a/code/game/objects/mail.dm b/code/game/objects/mail.dm index 79c769a162..2b8312e183 100644 --- a/code/game/objects/mail.dm +++ b/code/game/objects/mail.dm @@ -51,6 +51,7 @@ ///Var for attack_self chainn var/special_handling = FALSE + resistance_flags = FLAMMABLE /obj/item/mail/container_resist(mob/living/M) if(istype(M, /mob/living/voice)) return diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm new file mode 100644 index 0000000000..e86384a9be --- /dev/null +++ b/code/game/objects/obj_defense.dm @@ -0,0 +1,79 @@ +///Called when the obj is exposed to fire. +/obj/fire_act(exposed_temperature, exposed_volume) + if(HAS_TRAIT(src, TRAIT_UNDERFLOOR)) + return + var/potential_damage = 0.02 * exposed_temperature + if(exposed_temperature && !(resistance_flags & FIRE_PROOF) && (potential_damage > damage_deflection)) + take_damage(clamp(potential_damage, 0, 20), BURN, FIRE, 0) + if(QDELETED(src)) // take_damage() can send our obj to an early grave, let's stop here if that happens + return + if(!(resistance_flags & ON_FIRE) && (resistance_flags & FLAMMABLE) && !(resistance_flags & FIRE_PROOF)) + AddComponent(/datum/component/burning, custom_fire_overlay() || GLOB.fire_overlay, burning_particles) + SEND_SIGNAL(src, COMSIG_ATOM_FIRE_ACT, exposed_temperature, exposed_volume) + return TRUE + return ..() + +/// Returns a custom fire overlay, if any +/obj/proc/custom_fire_overlay() + return custom_fire_overlay + +///called when the obj is destroyed by acid. +/obj/proc/acid_melt() + deconstruct(FALSE) + +/// Should be called when the atom is destroyed by fire, comparable to acid_melt() proc +/obj/proc/burn() + deconstruct(FALSE) + +/** + * Custom behaviour per atom subtype on how they should deconstruct themselves + * Arguments + * + * * disassembled - TRUE means we cleanly took this atom apart using tools. FALSE means this was destroyed in a violent way + */ +/obj/proc/atom_deconstruct(disassembled = TRUE) + PROTECTED_PROC(TRUE) + + return + +/** + * The interminate proc between deconstruct() & atom_deconstruct(). By default this delegates deconstruction to + * atom_deconstruct if NO_DEBRIS_AFTER_DECONSTRUCTION is absent but subtypes can override this to handle NO_DEBRIS_AFTER_DECONSTRUCTION in their + * own unique way. Override this if for example you want to dump out important content like mobs from the + * atom before deconstruction regardless if NO_DEBRIS_AFTER_DECONSTRUCTION is present or not + * Arguments + * + * * disassembled - TRUE means we cleanly took this atom apart using tools. FALSE means this was destroyed in a violent way + */ +/obj/proc/handle_deconstruct(disassembled = TRUE) + SHOULD_CALL_PARENT(FALSE) + + if(!(obj_flags & NO_DEBRIS_AFTER_DECONSTRUCTION)) + atom_deconstruct(disassembled) + +/obj/proc/deconstruct(disassembled = TRUE) + SHOULD_NOT_OVERRIDE(TRUE) + + //allow objects to deconstruct themselves + handle_deconstruct(disassembled) + + //inform objects we were deconstructed + SEND_SIGNAL(src, COMSIG_OBJ_DECONSTRUCT, disassembled) + + for(var/obj/item/item in contents) + if(item.item_flags & ABSTRACT) + continue + item.forceMove(get_turf(src)) + + //delete our self + qdel(src) + +///what happens when the obj's integrity reaches zero. +/obj/atom_destruction(damage_flag) + . = ..() + if(damage_flag == ACID) + acid_melt() + else if(damage_flag == FIRE) + burn() + else + deconstruct(FALSE) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 6dcfb46196..94be45148a 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -18,6 +18,15 @@ var/micro_target = FALSE var/explosion_resistance + /// Cached custom fire overlay + var/custom_fire_overlay + /// Particles this obj uses when burning, if any + var/burning_particles + + var/obj_flags = CAN_BE_HIT + + uses_integrity = TRUE + /obj/Destroy() STOP_PROCESSING(SSobj, src) diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index acd13bbd6c..990dda2293 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -20,6 +20,7 @@ LINEN BINS pickup_sound = 'sound/items/pickup/clothing.ogg' ///var used for attack_self chain var/special_handling = FALSE + resistance_flags = FLAMMABLE /obj/item/bedsheet/Initialize(mapload) . = ..() diff --git a/code/game/objects/structures/bonfire.dm b/code/game/objects/structures/bonfire.dm index 8e0ad9f162..9b8f2207e8 100644 --- a/code/game/objects/structures/bonfire.dm +++ b/code/game/objects/structures/bonfire.dm @@ -12,6 +12,7 @@ var/datum/material/material var/set_temperature = T0C + 30 //K var/heating_power = 80000 + resistance_flags = FIRE_PROOF /obj/structure/bonfire/Initialize(mapload, material_name) . = ..() @@ -170,7 +171,7 @@ START_PROCESSING(SSobj, src) visible_message(span_warning("\The [src] starts burning!")) -/obj/structure/bonfire/proc/burn() +/obj/structure/bonfire/proc/burn_bonfire() var/turf/current_location = get_turf(src) current_location.hotspot_expose(1000, 500) for(var/A in current_location) @@ -225,7 +226,7 @@ extinguish() return if(!grill) - burn() + burn_bonfire() if(burning) var/W = get_fuel_amount() @@ -279,6 +280,7 @@ var/next_fuel_consumption = 0 var/set_temperature = T0C + 20 //K var/heating_power = 40000 + resistance_flags = FIRE_PROOF /obj/structure/fireplace/attackby(obj/item/W, mob/user) if(istype(W, /obj/item/stack/material/wood) || istype(W, /obj/item/stack/material/log) ) @@ -365,7 +367,7 @@ START_PROCESSING(SSobj, src) visible_message(span_warning("\The [src] starts burning!")) -/obj/structure/fireplace/proc/burn() +/obj/structure/fireplace/proc/burn_bonfire() var/turf/current_location = get_turf(src) current_location.hotspot_expose(1000, 500) for(var/A in current_location) diff --git a/code/game/objects/structures/catwalk.dm b/code/game/objects/structures/catwalk.dm index 98dff9edb3..7526b3a75b 100644 --- a/code/game/objects/structures/catwalk.dm +++ b/code/game/objects/structures/catwalk.dm @@ -80,7 +80,7 @@ if(Adjacent(user)) attack_hand(user) -/obj/structure/catwalk/proc/deconstruct(mob/user) +/obj/structure/catwalk/atom_deconstruct(disassembled = TRUE, mob/user) playsound(src, 'sound/items/Welder.ogg', 100, 1) to_chat(user, span_notice("Slicing \the [src] joints ...")) //Lattice would delete itself, but let's save ourselves a new obj @@ -97,7 +97,7 @@ if(C.has_tool_quality(TOOL_WELDER)) var/obj/item/weldingtool/WT = C.get_welder() if(WT.isOn() && WT.remove_fuel(0, user)) - deconstruct(user) + atom_deconstruct(TRUE, user) return if(C.has_tool_quality(TOOL_CROWBAR) && plated_tile) hatch_open = !hatch_open diff --git a/code/game/objects/structures/gargoyle.dm b/code/game/objects/structures/gargoyle.dm index 1ad6080fbb..4d422f9407 100644 --- a/code/game/objects/structures/gargoyle.dm +++ b/code/game/objects/structures/gargoyle.dm @@ -13,7 +13,7 @@ var/flapping var/obj_integrity = 100 var/original_int = 100 - var/max_integrity = 100 + max_integrity = 100 var/stored_examine var/identifier = "statue" var/material = "stone" diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm index bcd6366510..3203f38651 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm @@ -261,6 +261,7 @@ applies_material_colour = 1 var/sofa_material = MAT_CARPET var/corner_piece = FALSE + resistance_flags = FLAMMABLE /obj/structure/bed/chair/sofa/update_icon() if(applies_material_colour && sofa_material) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index b81d5683ec..9f8ef61ccd 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -111,6 +111,9 @@ if(Be) Be.multiz_turf_new(src, UP) + if(uses_integrity) + atom_integrity = max_integrity + /turf/Destroy() if (!changing_turf) stack_trace("Improper turf qdel. Do not qdel turfs directly.") diff --git a/code/modules/blob2/blobs/base_blob.dm b/code/modules/blob2/blobs/base_blob.dm index 8ab26dd06d..6ca7f7e0f2 100644 --- a/code/modules/blob2/blobs/base_blob.dm +++ b/code/modules/blob2/blobs/base_blob.dm @@ -11,7 +11,7 @@ GLOBAL_LIST_EMPTY(all_blobs) layer = MOB_LAYER + 0.1 var/integrity = 0 var/point_return = 0 //How many points the blob gets back when it removes a blob of that type. If less than 0, blob cannot be removed. - var/max_integrity = 30 + max_integrity = 30 var/health_regen = 2 //how much health this blob regens when pulsed var/pulse_timestamp = 0 //we got pulsed when? var/heal_timestamp = 0 //we got healed when? diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 8f05b052bc..e3d96ac75b 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -3,6 +3,7 @@ siemens_coefficient = 0.9 drop_sound = 'sound/items/drop/clothing.ogg' pickup_sound = 'sound/items/pickup/clothing.ogg' + resistance_flags = FLAMMABLE var/list/species_restricted = null //Only these species can wear this kit. var/list/accessories diff --git a/code/modules/clothing/ears/earrings.dm b/code/modules/clothing/ears/earrings.dm index 34cadc8e0a..d870e6d171 100644 --- a/code/modules/clothing/ears/earrings.dm +++ b/code/modules/clothing/ears/earrings.dm @@ -3,6 +3,7 @@ name = DEVELOPER_WARNING_NAME desc = "An earring of some kind." icon = 'icons/inventory/ears/item.dmi' + resistance_flags = FIRE_PROOF /obj/item/clothing/ears/earring/stud name = "pearl stud earrings" @@ -17,6 +18,7 @@ /obj/item/clothing/ears/earring/stud/wood name = "wood stud earrings" color = "#824b28" + resistance_flags = FLAMMABLE /obj/item/clothing/ears/earring/stud/iron name = "iron stud earrings" diff --git a/code/modules/clothing/ears/ears.dm b/code/modules/clothing/ears/ears.dm index cf93be8e28..eb92180f09 100644 --- a/code/modules/clothing/ears/ears.dm +++ b/code/modules/clothing/ears/ears.dm @@ -9,6 +9,7 @@ item_state_slots = list(slot_r_hand_str = "earmuffs", slot_l_hand_str = "earmuffs") slot_flags = SLOT_EARS | SLOT_TWOEARS ear_protection = 2 + resistance_flags = FIRE_PROOF /obj/item/clothing/ears/earmuffs/headphones name = "headphones" @@ -48,6 +49,7 @@ w_class = ITEMSIZE_TINY slot_flags = SLOT_EARS species_restricted = list(SPECIES_SKRELL) + resistance_flags = FIRE_PROOF /obj/item/clothing/ears/skrell/chain name = "Gold headtail chains" diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm index c7042d7ca5..97b932fbae 100644 --- a/code/modules/clothing/glasses/glasses.dm +++ b/code/modules/clothing/glasses/glasses.dm @@ -29,6 +29,7 @@ BLIND // can't see anything var/list/away_planes //Holder for disabled planes drop_sound = 'sound/items/drop/accessory.ogg' pickup_sound = 'sound/items/pickup/accessory.ogg' + resistance_flags = FIRE_PROOF sprite_sheets = list( SPECIES_TESHARI = 'icons/inventory/eyes/mob_teshari.dmi', diff --git a/code/modules/clothing/gloves/arm_guards.dm b/code/modules/clothing/gloves/arm_guards.dm index 54491de295..138943980e 100644 --- a/code/modules/clothing/gloves/arm_guards.dm +++ b/code/modules/clothing/gloves/arm_guards.dm @@ -7,6 +7,7 @@ w_class = ITEMSIZE_NORMAL drop_sound = 'sound/items/drop/metalshield.ogg' pickup_sound = 'sound/items/pickup/axe.ogg' + resistance_flags = FIRE_PROOF /obj/item/clothing/gloves/arm_guard/mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = FALSE) if(..()) //This will only run if no other problems occured when equiping. diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm index d69aaa853c..c2986ae002 100644 --- a/code/modules/clothing/gloves/color.dm +++ b/code/modules/clothing/gloves/color.dm @@ -31,6 +31,7 @@ permeability_coefficient = 0.05 min_cold_protection_temperature = GLOVES_MIN_COLD_PROTECTION_TEMPERATURE max_heat_protection_temperature = GLOVES_MAX_HEAT_PROTECTION_TEMPERATURE + resistance_flags = FIRE_PROOF /obj/item/clothing/gloves/orange name = "orange gloves" diff --git a/code/modules/clothing/gloves/gauntlets.dm b/code/modules/clothing/gloves/gauntlets.dm index 7fe039ee49..3ee8a85fa7 100644 --- a/code/modules/clothing/gloves/gauntlets.dm +++ b/code/modules/clothing/gloves/gauntlets.dm @@ -12,6 +12,7 @@ glove_level = 3 overgloves = 1 punch_force = 5 + resistance_flags = FIRE_PROOF /obj/item/clothing/gloves/gauntlets/mob_can_equip(mob/user, slot, disable_warning = FALSE) var/mob/living/carbon/human/H = user diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm index 89ee70d0bd..6b165e59ca 100644 --- a/code/modules/clothing/gloves/miscellaneous.dm +++ b/code/modules/clothing/gloves/miscellaneous.dm @@ -20,6 +20,7 @@ min_cold_protection_temperature = GLOVES_MIN_COLD_PROTECTION_TEMPERATURE max_heat_protection_temperature = GLOVES_MAX_HEAT_PROTECTION_TEMPERATURE + resistance_flags = FIRE_PROOF /obj/item/clothing/gloves/swat desc = "These tactical gloves are somewhat fire and impact-resistant." @@ -30,6 +31,7 @@ permeability_coefficient = 0.05 min_cold_protection_temperature = GLOVES_MIN_COLD_PROTECTION_TEMPERATURE max_heat_protection_temperature = GLOVES_MAX_HEAT_PROTECTION_TEMPERATURE + resistance_flags = FIRE_PROOF /obj/item/clothing/gloves/combat //Combined effect of SWAT gloves and insulated gloves desc = "These tactical gloves are somewhat fire and impact resistant." @@ -40,6 +42,7 @@ permeability_coefficient = 0.05 min_cold_protection_temperature = GLOVES_MIN_COLD_PROTECTION_TEMPERATURE max_heat_protection_temperature = GLOVES_MAX_HEAT_PROTECTION_TEMPERATURE + resistance_flags = FIRE_PROOF /obj/item/clothing/gloves/sterile name = "sterile gloves" @@ -112,6 +115,7 @@ min_cold_protection_temperature = GLOVES_MIN_COLD_PROTECTION_TEMPERATURE max_heat_protection_temperature = GLOVES_MAX_HEAT_PROTECTION_TEMPERATURE + resistance_flags = FIRE_PROOF /obj/item/clothing/gloves/ranger var/glovecolor = "white" diff --git a/code/modules/clothing/head/collectable.dm b/code/modules/clothing/head/collectable.dm index b171d66795..f26c000524 100644 --- a/code/modules/clothing/head/collectable.dm +++ b/code/modules/clothing/head/collectable.dm @@ -69,6 +69,7 @@ desc = "A Collectable Welding Helmet. Now with 80% less lead! Not for actual welding. Any welding done while wearing this Helmet is done so at the owner's own risk!" icon_state = "welding" body_parts_covered = HEAD|FACE|EYES + resistance_flags = FIRE_PROOF /obj/item/clothing/head/collectable/slime name = "collectable slime hat" diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm index 5dd877f04e..ccdda3a843 100644 --- a/code/modules/clothing/head/hardhat.dm +++ b/code/modules/clothing/head/hardhat.dm @@ -24,6 +24,7 @@ ear_protection = 1 drop_sound = 'sound/items/drop/helm.ogg' pickup_sound = 'sound/items/pickup/helm.ogg' + resistance_flags = FIRE_PROOF /obj/item/clothing/head/hardhat/orange icon_state = "hardhat0_orange" diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index 69feb2c9dc..867d41034d 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -14,6 +14,7 @@ ear_protection = 1 drop_sound = 'sound/items/drop/helm.ogg' pickup_sound = 'sound/items/pickup/helm.ogg' + resistance_flags = FIRE_PROOF /obj/item/clothing/head/helmet/solgov name = "\improper Solar Confederate Government helmet" diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm index a6d07319e4..78f759b9f3 100644 --- a/code/modules/clothing/head/misc_special.dm +++ b/code/modules/clothing/head/misc_special.dm @@ -32,6 +32,7 @@ drop_sound = 'sound/items/drop/helm.ogg' pickup_sound = 'sound/items/pickup/helm.ogg' special_handling = TRUE + resistance_flags = FIRE_PROOF /obj/item/clothing/head/welding/attack_self(mob/user) . = ..(user) diff --git a/code/modules/clothing/head/pilot_helmet.dm b/code/modules/clothing/head/pilot_helmet.dm index e658c80ad5..bdfcdf60d3 100644 --- a/code/modules/clothing/head/pilot_helmet.dm +++ b/code/modules/clothing/head/pilot_helmet.dm @@ -20,6 +20,7 @@ var/list/images var/list/raw_images var/last_status + resistance_flags = FIRE_PROOF /obj/item/clothing/head/pilot/Initialize(mapload) . = ..() diff --git a/code/modules/clothing/head/pilot_helmet_vr.dm b/code/modules/clothing/head/pilot_helmet_vr.dm index 0e5e5597b3..7305c54fe0 100644 --- a/code/modules/clothing/head/pilot_helmet_vr.dm +++ b/code/modules/clothing/head/pilot_helmet_vr.dm @@ -10,6 +10,7 @@ w_class = ITEMSIZE_NORMAL actions_types = list(/datum/action/item_action/toggle_visor) special_handling = TRUE + resistance_flags = FIRE_PROOF /obj/item/clothing/head/pilot_vr/attack_self(mob/user) . = ..(user) diff --git a/code/modules/clothing/masks/breath.dm b/code/modules/clothing/masks/breath.dm index 5d06eb3c49..5a1874126c 100644 --- a/code/modules/clothing/masks/breath.dm +++ b/code/modules/clothing/masks/breath.dm @@ -13,6 +13,7 @@ pickup_sound = 'sound/items/pickup/component.ogg' drop_sound = 'sound/items/drop/component.ogg' special_handling = TRUE + resistance_flags = FIRE_PROOF /obj/item/clothing/mask/breath/proc/adjust_mask(mob/user) diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm index 121b1485c9..b0c22eaeb6 100644 --- a/code/modules/clothing/masks/gasmask.dm +++ b/code/modules/clothing/masks/gasmask.dm @@ -14,6 +14,7 @@ var/list/filtered_gases = list(GAS_PHORON, GAS_N2O) armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 75, rad = 0) pickup_sound = 'sound/items/pickup/rubber.ogg' + resistance_flags = FIRE_PROOF /obj/item/clothing/mask/gas/filter_air(datum/gas_mixture/air) var/datum/gas_mixture/gas_filtered = new diff --git a/code/modules/clothing/masks/monitor.dm b/code/modules/clothing/masks/monitor.dm index ef1656e34a..7e578ce608 100644 --- a/code/modules/clothing/masks/monitor.dm +++ b/code/modules/clothing/masks/monitor.dm @@ -11,6 +11,7 @@ icon_state = "monitor" var/monitor_state_index = "blank" + resistance_flags = FIRE_PROOF /obj/item/clothing/mask/monitor/set_dir() diff --git a/code/modules/clothing/masks/tesh_synth_facemask.dm b/code/modules/clothing/masks/tesh_synth_facemask.dm index c28f918b6c..6e51bcc171 100644 --- a/code/modules/clothing/masks/tesh_synth_facemask.dm +++ b/code/modules/clothing/masks/tesh_synth_facemask.dm @@ -11,6 +11,7 @@ var/lstat var/visor_state = "Neutral" //Separating this from lstat so that it could potentially be used for an override system or something var/mob/living/carbon/maskmaster + resistance_flags = FIRE_PROOF | ACID_PROOF | INDESTRUCTIBLE | BOMB_PROOF |FREEZE_PROOF /obj/item/clothing/mask/synthfacemask/equipped() ..() diff --git a/code/modules/clothing/shoes/boots.dm b/code/modules/clothing/shoes/boots.dm index dc1e57d541..81895b4bb3 100644 --- a/code/modules/clothing/shoes/boots.dm +++ b/code/modules/clothing/shoes/boots.dm @@ -132,6 +132,7 @@ max_heat_protection_temperature = SHOE_MAX_HEAT_PROTECTION_TEMPERATURE snow_speed = -1 step_volume_mod = 0.8 + resistance_flags = FIRE_PROOF /obj/item/clothing/shoes/boots/winter/security name = "security winter boots" diff --git a/code/modules/clothing/shoes/leg_guards.dm b/code/modules/clothing/shoes/leg_guards.dm index 0b90c91654..4f713db32f 100644 --- a/code/modules/clothing/shoes/leg_guards.dm +++ b/code/modules/clothing/shoes/leg_guards.dm @@ -9,6 +9,7 @@ can_hold_knife = TRUE drop_sound = 'sound/items/drop/boots.ogg' pickup_sound = 'sound/items/pickup/boots.ogg' + resistance_flags = FIRE_PROOF /obj/item/clothing/shoes/leg_guard/mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = FALSE) if(..()) //This will only run if no other problems occured when equiping. diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm index de0ae49d54..954ee26738 100644 --- a/code/modules/clothing/shoes/magboots.dm +++ b/code/modules/clothing/shoes/magboots.dm @@ -23,6 +23,7 @@ step_volume_mod = 1.3 drop_sound = 'sound/items/drop/metalboots.ogg' pickup_sound = 'sound/items/pickup/toolbox.ogg' + resistance_flags = FIRE_PROOF /obj/item/clothing/shoes/magboots/proc/set_slowdown() slowdown = shoes? max(SHOES_SLOWDOWN, shoes.slowdown): SHOES_SLOWDOWN //So you can't put on magboots to make you walk faster. diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index f51742b6c7..05a35439cc 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -11,6 +11,7 @@ step_volume_mod = 0.5 drop_sound = 'sound/items/drop/rubber.ogg' pickup_sound = 'sound/items/pickup/rubber.ogg' + resistance_flags = FIRE_PROOF | ACID_PROOF /obj/item/clothing/shoes/mime name = "mime shoes" @@ -28,6 +29,7 @@ species_restricted = null drop_sound = 'sound/items/drop/rubber.ogg' pickup_sound = 'sound/items/pickup/rubber.ogg' + resistance_flags = ACID_PROOF /obj/item/clothing/shoes/dress name = "dress shoes" diff --git a/code/modules/clothing/shoes/miscellaneous_vr.dm b/code/modules/clothing/shoes/miscellaneous_vr.dm index e6a9df77f0..5ce2576482 100644 --- a/code/modules/clothing/shoes/miscellaneous_vr.dm +++ b/code/modules/clothing/shoes/miscellaneous_vr.dm @@ -17,6 +17,7 @@ var/recharging_rate = 60 //default 6 seconds between each dash var/recharging_time = 0 //time until next dash // var/jumping = FALSE //are we mid-jump? We have no throw_at callback, so we have to check user.throwing. + resistance_flags = FIRE_PROOF /obj/item/clothing/shoes/bhop/ui_action_click(mob/unused_user, actiontype) var/mob/living/user = loc diff --git a/code/modules/clothing/spacesuits/breaches.dm b/code/modules/clothing/spacesuits/breaches.dm index 0aff5ee814..40089d44a9 100644 --- a/code/modules/clothing/spacesuits/breaches.dm +++ b/code/modules/clothing/spacesuits/breaches.dm @@ -18,6 +18,7 @@ var/brute_damage = 0 // Specifically brute damage. var/burn_damage = 0 // Specifically burn damage. var/base_name // Used to keep the original name safe while we apply modifiers. + resistance_flags = FIRE_PROOF | ACID_PROOF /obj/item/clothing/suit/space/Initialize(mapload) . = ..() diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index 39ed270aaf..d8aabb6ef0 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -104,6 +104,7 @@ var/protean = 0 var/obj/item/storage/backpack/rig_storage permeability_coefficient = 0 //Protect the squishies, after all this shit should be waterproof. + resistance_flags = FIRE_PROOF | ACID_PROOF /obj/item/rig/Initialize(mapload) . = ..() diff --git a/code/modules/clothing/spacesuits/rig/rig_pieces.dm b/code/modules/clothing/spacesuits/rig/rig_pieces.dm index 87f68ef32a..d9150fafaa 100644 --- a/code/modules/clothing/spacesuits/rig/rig_pieces.dm +++ b/code/modules/clothing/spacesuits/rig/rig_pieces.dm @@ -26,6 +26,7 @@ species_restricted = list(SPECIES_HUMAN, SPECIES_SKRELL, SPECIES_TAJARAN, SPECIES_UNATHI, SPECIES_NEVREAN, SPECIES_AKULA, SPECIES_SERGAL, SPECIES_ZORREN_HIGH, SPECIES_VULPKANIN, SPECIES_PROMETHEAN, SPECIES_VOX, SPECIES_TESHARI, SPECIES_VASILISSAN, SPECIES_RAPALA, SPECIES_ALRAUNE, SPECIES_FENNEC, SPECIES_XENOHYBRID, SPECIES_ALTEVIAN, SPECIES_SHADEKIN) max_pressure_protection = null min_pressure_protection = null + resistance_flags = FIRE_PROOF | ACID_PROOF /obj/item/clothing/gloves/gauntlets/rig name = "gauntlets" @@ -33,10 +34,12 @@ flags = PHORONGUARD item_flags = THICKMATERIAL species_restricted = list(SPECIES_HUMAN, SPECIES_SKRELL, SPECIES_TAJARAN, SPECIES_UNATHI, SPECIES_NEVREAN, SPECIES_AKULA, SPECIES_SERGAL, SPECIES_ZORREN_HIGH, SPECIES_VULPKANIN, SPECIES_PROMETHEAN, SPECIES_VOX, SPECIES_TESHARI, SPECIES_VASILISSAN, SPECIES_RAPALA, SPECIES_ALRAUNE, SPECIES_FENNEC, SPECIES_XENOHYBRID, SPECIES_ALTEVIAN, SPECIES_SHADEKIN) + resistance_flags = FIRE_PROOF | ACID_PROOF /obj/item/clothing/shoes/magboots/rig name = "boots" species_restricted = list(SPECIES_HUMAN, SPECIES_SKRELL, SPECIES_TAJARAN, SPECIES_UNATHI, SPECIES_NEVREAN, SPECIES_AKULA, SPECIES_SERGAL, SPECIES_ZORREN_HIGH, SPECIES_VULPKANIN, SPECIES_PROMETHEAN, SPECIES_VOX, SPECIES_TESHARI, SPECIES_VASILISSAN, SPECIES_RAPALA, SPECIES_ALRAUNE, SPECIES_FENNEC, SPECIES_XENOHYBRID, SPECIES_ALTEVIAN, SPECIES_SHADEKIN) icon_base = null + resistance_flags = FIRE_PROOF | ACID_PROOF /obj/item/clothing/suit/space/rig name = "chestpiece" @@ -72,6 +75,7 @@ var/obj/item/material/knife/tacknife max_pressure_protection = null min_pressure_protection = null + resistance_flags = FIRE_PROOF | ACID_PROOF /obj/item/clothing/suit/space/rig/attack_hand(var/mob/living/M) if(tacknife) @@ -126,15 +130,19 @@ name = DEVELOPER_WARNING_NAME // "mask" body_parts_covered = HEAD|FACE|EYES flags = THICKMATERIAL|AIRTIGHT + resistance_flags = FIRE_PROOF | ACID_PROOF /obj/item/clothing/suit/lightrig name = DEVELOPER_WARNING_NAME // "suit" allowed = list(POCKET_GENERIC, POCKET_EMERGENCY) flags_inv = HIDEJUMPSUIT flags = THICKMATERIAL + resistance_flags = FIRE_PROOF | ACID_PROOF /obj/item/clothing/shoes/lightrig name = DEVELOPER_WARNING_NAME // "boots" + resistance_flags = FIRE_PROOF | ACID_PROOF /obj/item/clothing/gloves/gauntlets/lightrig flags = THICKMATERIAL + resistance_flags = FIRE_PROOF | ACID_PROOF diff --git a/code/modules/clothing/spacesuits/spacesuits.dm b/code/modules/clothing/spacesuits/spacesuits.dm index 3983caee39..cd35fd18ab 100644 --- a/code/modules/clothing/spacesuits/spacesuits.dm +++ b/code/modules/clothing/spacesuits/spacesuits.dm @@ -23,6 +23,7 @@ preserve_item = 1 flash_protection = FLASH_PROTECTION_MAJOR valid_accessory_slots = null + resistance_flags = FIRE_PROOF | ACID_PROOF var/obj/machinery/camera/camera var/list/camera_networks @@ -90,6 +91,7 @@ preserve_item = 1 valid_accessory_slots = (ACCESSORY_SLOT_OVER | ACCESSORY_SLOT_ARMBAND | ACCESSORY_SLOT_DECOR) var/list/supporting_limbs //If not-null, automatically splints breaks. Checked when removing the suit. + resistance_flags = FIRE_PROOF | ACID_PROOF //VOREStation edit start - use the specially refitted sprites by KBraid. Done this way to avoid breaking subtypes. /obj/item/clothing/suit/space/Initialize(mapload) diff --git a/code/modules/clothing/suits/aliens/vox.dm b/code/modules/clothing/suits/aliens/vox.dm index 59b41a6993..cc53b4cbd6 100644 --- a/code/modules/clothing/suits/aliens/vox.dm +++ b/code/modules/clothing/suits/aliens/vox.dm @@ -8,3 +8,4 @@ body_parts_covered = CHEST|ARMS|LEGS species_restricted = list(SPECIES_VOX) siemens_coefficient = 1 //Its literally metal + resistance_flags = FIRE_PROOF diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index d561eaa1f7..4ff2ff5c87 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -9,6 +9,7 @@ heat_protection = CHEST max_heat_protection_temperature = ARMOR_MAX_HEAT_PROTECTION_TEMPERATURE siemens_coefficient = 0.6 + resistance_flags = FIRE_PROOF /obj/item/clothing/suit/mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = FALSE) if(..()) //This will only run if no other problems occured when equiping. diff --git a/code/modules/clothing/suits/bio.dm b/code/modules/clothing/suits/bio.dm index 45d68807d8..5ef36ce227 100644 --- a/code/modules/clothing/suits/bio.dm +++ b/code/modules/clothing/suits/bio.dm @@ -13,6 +13,7 @@ siemens_coefficient = 0.9 flags = PHORONGUARD item_flags = THICKMATERIAL | ALLOW_SURVIVALFOOD + resistance_flags = UNACIDABLE /obj/item/clothing/suit/bio_suit name = "bio suit" @@ -29,6 +30,7 @@ siemens_coefficient = 0.9 flags = PHORONGUARD item_flags = THICKMATERIAL + resistance_flags = UNACIDABLE //Standard biosuit, orange stripe /obj/item/clothing/head/bio_hood/general diff --git a/code/modules/clothing/suits/bio_vr.dm b/code/modules/clothing/suits/bio_vr.dm deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/code/modules/clothing/suits/hooded_vr.dm b/code/modules/clothing/suits/hooded_vr.dm index 5735af76ea..35298a276b 100644 --- a/code/modules/clothing/suits/hooded_vr.dm +++ b/code/modules/clothing/suits/hooded_vr.dm @@ -21,6 +21,7 @@ armor = list(melee = 80, bullet = 50, laser = 10, energy = 0, bomb = 0, bio = 0, rad = 0) siemens_coefficient = 2 actions_types = list(/datum/action/item_action/toggle_knight_headgear) + resistance_flags = FIRE_PROOF /obj/item/clothing/suit/storage/hooded/knight/galahad name = "crusader's armor" diff --git a/code/modules/clothing/suits/reactive_armour.dm b/code/modules/clothing/suits/reactive_armour.dm index 830a5562cf..360dada40f 100644 --- a/code/modules/clothing/suits/reactive_armour.dm +++ b/code/modules/clothing/suits/reactive_armour.dm @@ -3,6 +3,7 @@ desc = "An experimental suit of armor, awaiting installation of an anomaly core." icon_state = "reactiveoff" w_class = ITEMSIZE_COST_LARGE + resistance_flags = FIRE_PROOF | UNACIDABLE /obj/item/clothing/suit/armor/reactive_armor_shell/attackby(obj/item/I, mob/user) . = ..() diff --git a/code/modules/clothing/suits/shiny.dm b/code/modules/clothing/suits/shiny.dm deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/code/modules/clothing/suits/utility.dm b/code/modules/clothing/suits/utility.dm index d52fbcbeef..8c0a1ec48b 100644 --- a/code/modules/clothing/suits/utility.dm +++ b/code/modules/clothing/suits/utility.dm @@ -27,6 +27,7 @@ cold_protection = CHEST|LEGS|FEET|ARMS|HANDS min_pressure_protection = 0.2 * ONE_ATMOSPHERE max_pressure_protection = 20 * ONE_ATMOSPHERE + resistance_flags = FIRE_PROOF /obj/item/clothing/suit/fire/firefighter name = "firesuit" @@ -51,6 +52,7 @@ flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|BLOCKHAIR body_parts_covered = HEAD|FACE|EYES siemens_coefficient = 0 + resistance_flags = BOMB_PROOF /obj/item/clothing/suit/bomb_suit name = "bomb suit" @@ -66,6 +68,7 @@ cold_protection = CHEST|LEGS|FEET|ARMS|HANDS max_heat_protection_temperature = ARMOR_MAX_HEAT_PROTECTION_TEMPERATURE siemens_coefficient = 0 + resistance_flags = BOMB_PROOF /obj/item/clothing/head/bomb_hood/security icon_state = "bombsuitsec" diff --git a/code/modules/examine/descriptions/items.dm b/code/modules/examine/descriptions/items.dm index ba4410af1f..7499853b07 100644 --- a/code/modules/examine/descriptions/items.dm +++ b/code/modules/examine/descriptions/items.dm @@ -75,6 +75,35 @@ else return "an average attack speed" +/atom/proc/examine_tags() + var/list/info_stats = list() + if(abstract_type == type) + info_stats += span_hypnophrase("This is an abstract concept, you should report this to a strange entity called GITHUB!") + + if(resistance_flags & INDESTRUCTIBLE) + info_stats += "It is extremely robust! It'll probably withstand anything that could happen to it!" + else + if(resistance_flags & LAVA_PROOF) + info_stats += span_info("It is made of an extremely heat-resistant material, it'd probably be able to withstand lava!
") + if(resistance_flags & (ACID_PROOF | UNACIDABLE)) + info_stats += span_info("It looks pretty robust! It'd probably be able to withstand acid!
") + if(resistance_flags & FREEZE_PROOF) + info_stats += span_info("It is made of cold-resistant materials.
") + if(resistance_flags & FIRE_PROOF) + info_stats += span_info("It is made of fire-retardant materials.
") + if(resistance_flags & SHUTTLE_CRUSH_PROOF) + info_stats += span_info("It is extremely solid. It should be able to withstand being run over by a shuttle!
") + if(resistance_flags & BOMB_PROOF) + info_stats += span_info("It looks like it could survive an explosion!
") + if(resistance_flags & FLAMMABLE) + info_stats += span_info("It looks like it could easily catch on fire.") + return info_stats + +// if(flags_1 & HOLOGRAM_1) +// .["holographic"] = "It looks like a hologram." + + //SEND_SIGNAL(src, COMSIG_ATOM_EXAMINE_TAGS, user, .) + /obj/item/get_description_info(list/additional_information) var/list/weapon_stats = list() @@ -93,6 +122,8 @@ if(reach > 1) weapon_stats += "It can attack targets up to [reach] tiles away, and can attack over certain objects." + weapon_stats += examine_tags() + if(weapon_stats.len < 1) return "" diff --git a/code/modules/food/food.dm b/code/modules/food/food.dm index cdc1c9a0f6..90cf56f54e 100644 --- a/code/modules/food/food.dm +++ b/code/modules/food/food.dm @@ -14,6 +14,7 @@ var/food_can_insert_micro = FALSE var/list/food_inserted_micros + resistance_flags = FLAMMABLE /obj/item/reagent_containers/food/verb/change_name() set name = "Rename Food" diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm index 9008a7521d..35c1540995 100644 --- a/code/modules/library/lib_items.dm +++ b/code/modules/library/lib_items.dm @@ -187,6 +187,7 @@ Book Cart End var/special_handling = FALSE drop_sound = 'sound/items/drop/book.ogg' pickup_sound = 'sound/items/pickup/book.ogg' + resistance_flags = FLAMMABLE /obj/item/book/attack_self(mob/user) . = ..(user) diff --git a/code/modules/materials/sheets/gems.dm b/code/modules/materials/sheets/gems.dm index 73458b44f9..ee2a06b97b 100644 --- a/code/modules/materials/sheets/gems.dm +++ b/code/modules/materials/sheets/gems.dm @@ -6,6 +6,7 @@ drop_sound = 'sound/items/drop/glass.ogg' pickup_sound = 'sound/items/pickup/glass.ogg' coin_type = /obj/item/coin/phoron + resistance_flags = FLAMMABLE /obj/item/stack/material/diamond name = MAT_DIAMOND diff --git a/code/modules/materials/sheets/organic/textiles.dm b/code/modules/materials/sheets/organic/textiles.dm index 090ad70123..cb41cdad15 100644 --- a/code/modules/materials/sheets/organic/textiles.dm +++ b/code/modules/materials/sheets/organic/textiles.dm @@ -8,6 +8,7 @@ strict_color_stacking = TRUE drop_sound = 'sound/items/drop/leather.ogg' pickup_sound = 'sound/items/pickup/leather.ogg' + resistance_flags = FLAMMABLE /obj/item/stack/material/cloth name = MAT_CLOTH @@ -19,6 +20,7 @@ strict_color_stacking = TRUE drop_sound = 'sound/items/drop/clothing.ogg' pickup_sound = 'sound/items/pickup/clothing.ogg' + resistance_flags = FLAMMABLE /obj/item/stack/material/cloth/diyaab color = "#c6ccf0" @@ -34,6 +36,7 @@ strict_color_stacking = TRUE drop_sound = 'sound/items/drop/clothing.ogg' pickup_sound = 'sound/items/pickup/clothing.ogg' + resistance_flags = FLAMMABLE /obj/item/stack/material/fiber name = "plant fiber" @@ -44,3 +47,4 @@ apply_colour = TRUE drop_sound = 'sound/items/drop/clothing.ogg' pickup_sound = 'sound/items/pickup/clothing.ogg' + resistance_flags = FLAMMABLE diff --git a/code/modules/materials/sheets/plastic.dm b/code/modules/materials/sheets/plastic.dm index 396eb7522d..d03e69bd3b 100644 --- a/code/modules/materials/sheets/plastic.dm +++ b/code/modules/materials/sheets/plastic.dm @@ -13,3 +13,4 @@ strict_color_stacking = TRUE drop_sound = 'sound/items/drop/cardboardbox.ogg' pickup_sound = 'sound/items/pickup/cardboardbox.ogg' + resistance_flags = FLAMMABLE diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index b5605143b1..e15904a0fe 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -162,6 +162,7 @@ icon_state = "whiteshovel" item_state = "whiteshovel" var/datum/material/material + resistance_flags = FLAMMABLE /obj/item/shovel/wood/Initialize(mapload, var/_mat) . = ..() diff --git a/code/modules/mining/shelter_atoms_vr.dm b/code/modules/mining/shelter_atoms_vr.dm index 9f9ac9126d..8e11031d9a 100644 --- a/code/modules/mining/shelter_atoms_vr.dm +++ b/code/modules/mining/shelter_atoms_vr.dm @@ -595,7 +595,7 @@ GLOBAL_LIST_EMPTY(unique_deployable) var/buildstacktype = /obj/item/stack/material/steel var/buildstackamount = 5 -/obj/structure/fans/proc/deconstruct() +/obj/structure/fans/atom_deconstruct() new buildstacktype(loc,buildstackamount) qdel(src) @@ -604,7 +604,7 @@ GLOBAL_LIST_EMPTY(unique_deployable) user.visible_message(span_warning("[user] disassembles [src]."), span_notice("You start to disassemble [src]..."), "You hear clanking and banging noises.") if(do_after(user, 4 SECONDS, target = src)) - deconstruct() + atom_deconstruct(TRUE) return TRUE return TRUE diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index f6137f9973..b9fc172682 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -670,3 +670,19 @@ log_admin("[key_name(usr)] has cured all traumas from [key_name(src)].") message_admins(span_notice("[key_name_admin(usr)] has cured all traumas from [key_name_admin(src)].")) */ + +/** + * This proc is used to determine whether or not the mob can handle touching a burning object. + */ +/mob/living/carbon/proc/can_touch_burning(atom/burning_atom, acid_power, acid_volume) + // So people can take their own clothes off + if((burning_atom == src) || (burning_atom.loc == src)) + return TRUE + if(HAS_TRAIT(src, TRAIT_RESISTHEAT) || HAS_TRAIT(src, TRAIT_RESISTHEATHANDS)) + return TRUE + if(gloves?.max_heat_protection_temperature >= BURNING_ITEM_MINIMUM_TEMPERATURE) + return TRUE + for(var/obj/item/clothing/clothing in worn_clothing) + if(clothing.max_heat_protection_temperature >= BURNING_ITEM_MINIMUM_TEMPERATURE && (clothing.heat_protection & HANDS) && (clothing.body_parts_covered & HANDS)) + return TRUE + return FALSE diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index f4c229acc5..81536e60c1 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -32,3 +32,15 @@ //the second is the message in question. var/last_taste_time = 0 var/last_taste_text = "" + + ///only used by humans + var/obj/item/gloves = null + ///only used by humans. + var/obj/item/shoes = null + ///only used by humans. + var/obj/item/glasses = null + ///only used by humans. + var/obj/item/l_ear = null + var/obj/item/r_ear = null + ///Only used by humans. + var/list/worn_clothing = list() //Contains all CLOTHING items worn diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 47306d673f..c1fdd40da2 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -67,13 +67,8 @@ //Equipment slots var/obj/item/wear_suit = null var/obj/item/w_uniform = null - var/obj/item/shoes = null var/obj/item/belt = null - var/obj/item/gloves = null - var/obj/item/glasses = null var/obj/item/head = null - var/obj/item/l_ear = null - var/obj/item/r_ear = null var/obj/item/wear_id = null var/obj/item/r_store = null var/obj/item/l_store = null diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index f21aaaa077..5783a46714 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -3,9 +3,6 @@ Add fingerprints to items when we put them in our hands. This saves us from having to call add_fingerprint() any time something is put in a human's hands programmatically. */ -/mob/living/carbon/human - var/list/worn_clothing = list() //Contains all CLOTHING items worn - /mob/living/carbon/human/verb/quick_equip() set name = "quick-equip" set hidden = 1 diff --git a/code/modules/mob/living/carbon/human/species/station/monkey.dm b/code/modules/mob/living/carbon/human/species/station/monkey.dm index 3fe83c4974..c901dd5dd5 100644 --- a/code/modules/mob/living/carbon/human/species/station/monkey.dm +++ b/code/modules/mob/living/carbon/human/species/station/monkey.dm @@ -77,7 +77,7 @@ H.emote(pick("scratch","jump","roll","tail")) // More... intense, expressions... if(prob(5) && H.mutations.len) - if((LASER in H.mutations)) + if((LASER_EYES in H.mutations)) // zappy monkeys var/list/targs = list() for(var/atom/X in orange(7, H)) diff --git a/code/modules/mob/living/carbon/human/species/station/traits/positive_genes.dm b/code/modules/mob/living/carbon/human/species/station/traits/positive_genes.dm index d06e73ba0b..b8fc82985d 100644 --- a/code/modules/mob/living/carbon/human/species/station/traits/positive_genes.dm +++ b/code/modules/mob/living/carbon/human/species/station/traits/positive_genes.dm @@ -138,7 +138,7 @@ activity_bounds = DNA_HARD_BOUNDS hidden = TRUE // Cannot start with superpowers - mutation = LASER + mutation = LASER_EYES activation_message="Your eyes feel strange..." /datum/trait/positive/superpower_hulk diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index db5b0faf85..c17e5ff373 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -578,7 +578,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) //see UpdateDamageIcon() var/image/standing = image(icon = 'icons/effects/genetics.dmi', layer = BODY_LAYER+MUTATIONS_LAYER) for(var/mut in mutations) - if(mut == LASER) + if(mut == LASER_EYES) standing.overlays += "lasereyes_s" // Leaving this as overlays += overlays_standing[MUTATIONS_LAYER] = standing diff --git a/code/modules/news/newspaper.dm b/code/modules/news/newspaper.dm index 13b1130e15..b6fd2fdca4 100644 --- a/code/modules/news/newspaper.dm +++ b/code/modules/news/newspaper.dm @@ -18,6 +18,7 @@ var/scribble_page = null drop_sound = 'sound/items/drop/wrapper.ogg' pickup_sound = 'sound/items/pickup/wrapper.ogg' + resistance_flags = FLAMMABLE /obj/item/newspaper/attack_self(mob/user) . = ..(user) diff --git a/code/modules/overmap/ships/engines/gas_thruster.dm b/code/modules/overmap/ships/engines/gas_thruster.dm index 8804b70001..00e1f7d7d0 100644 --- a/code/modules/overmap/ships/engines/gas_thruster.dm +++ b/code/modules/overmap/ships/engines/gas_thruster.dm @@ -18,7 +18,7 @@ return nozzle.get_thrust() /datum/ship_engine/gas_thruster/burn() - return nozzle.burn() + return nozzle.thrust_burn() /datum/ship_engine/gas_thruster/set_thrust_limit(var/new_limit) nozzle.thrust_limit = new_limit @@ -145,7 +145,7 @@ A = get_step(A, exhaust_dir) return blockage -/obj/machinery/atmospherics/unary/engine/proc/burn() +/obj/machinery/atmospherics/unary/engine/proc/thrust_burn() if(!is_on()) return 0 if(!check_fuel() || (use_power_oneoff(charge_per_burn) < charge_per_burn) || check_blockage()) diff --git a/code/modules/overmap/ships/engines/ion_thruster.dm b/code/modules/overmap/ships/engines/ion_thruster.dm index 12b3aec548..39f428046c 100644 --- a/code/modules/overmap/ships/engines/ion_thruster.dm +++ b/code/modules/overmap/ships/engines/ion_thruster.dm @@ -17,7 +17,7 @@ return thruster.get_thrust() /datum/ship_engine/ion/burn() - return thruster.burn() + return thruster.thrust_burn() /datum/ship_engine/ion/set_thrust_limit(var/new_limit) thruster.thrust_limit = new_limit @@ -69,7 +69,7 @@ if(!powered()) .+= list(list("Insufficient power to operate.", "bad")) -/obj/machinery/ion_engine/proc/burn() +/obj/machinery/ion_engine/proc/thrust_burn() if(!on && !powered()) return 0 use_power_oneoff(burn_cost) diff --git a/code/modules/overmap/ships/ship.dm b/code/modules/overmap/ships/ship.dm index 4ce511c58f..642dd5af79 100644 --- a/code/modules/overmap/ships/ship.dm +++ b/code/modules/overmap/ships/ship.dm @@ -91,7 +91,7 @@ //Does actual burn and returns the resulting acceleration /obj/effect/overmap/visitable/ship/proc/get_burn_acceleration() - return round(burn() / get_vessel_mass(), SHIP_MOVE_RESOLUTION) + return round(thrust_burn() / get_vessel_mass(), SHIP_MOVE_RESOLUTION) /obj/effect/overmap/visitable/ship/proc/get_vessel_mass() . = vessel_mass @@ -245,7 +245,7 @@ /obj/effect/overmap/visitable/ship/set_dir(new_dir) return ..(NORTH) // NO! We always face north. -/obj/effect/overmap/visitable/ship/proc/burn() +/obj/effect/overmap/visitable/ship/proc/thrust_burn() for(var/datum/ship_engine/E in engines) . += E.burn() diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 9bcdf2cf65..fa97592884 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -44,6 +44,7 @@ var/const/deffont = "Verdana" var/const/signfont = "Times New Roman" var/const/crayonfont = "Comic Sans MS" + resistance_flags = FLAMMABLE /obj/item/paper/card name = "blank card" diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index e72dab954d..4a6c4c5126 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -36,6 +36,7 @@ GLOBAL_VAR_INIT(photo_count, 0) var/scribble //Scribble on the back. var/icon/tiny var/photo_size = 3 + resistance_flags = FLAMMABLE /obj/item/photo/Initialize(mapload) . = ..() diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index 4125862ffb..c9f0d677ca 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -20,6 +20,7 @@ drop_sound = 'sound/items/drop/bottle.ogg' pickup_sound = 'sound/items/pickup/bottle.ogg' description_info = "Clicking on a venomous animal (or person) with the lid closed will express their venom into the beaker!" + resistance_flags = ACID_PROOF var/label_text = "" diff --git a/code/modules/recycling/disposal_machines.dm b/code/modules/recycling/disposal_machines.dm index 56e70b5148..9916a1c927 100644 --- a/code/modules/recycling/disposal_machines.dm +++ b/code/modules/recycling/disposal_machines.dm @@ -64,7 +64,7 @@ /obj/machinery/disposal/singularity_pull(S, current_size) ..() if(current_size >= STAGE_FIVE) - deconstruct() + atom_deconstruct(TRUE) // attack by item places it in to disposal /obj/machinery/disposal/attackby(obj/item/I, mob/user) @@ -102,7 +102,7 @@ if(do_after(user, 2 SECONDS * W.toolspeed, target = src)) if(!src || !W.isOn()) return to_chat(user, "You sliced the floorweld off the disposal unit.") - deconstruct() + atom_deconstruct(TRUE) return else to_chat(user, "You need more welding fuel to complete this task.") @@ -584,7 +584,7 @@ // Ideally, deconstruct would be a proc on /machinery, but you cant have nice things with polaris. // AKA: FUKKIN CHANGE THIS WHEN THAT HAPPENS!!!!!1!! pls. -Reo -/obj/machinery/disposal/proc/deconstruct(disassembled = TRUE) +/obj/machinery/disposal/atom_deconstruct(disassembled = TRUE) var/turf/T = loc /* // More nice things... Someday we'll have flags_1 and then have proper support for anything being a hologram. if(!(flags_1 & NODECONSTRUCT_1)) diff --git a/code/modules/research/tg/machinery/destructive_analyzer.dm b/code/modules/research/tg/machinery/destructive_analyzer.dm index 9d6372740d..8837deff5c 100644 --- a/code/modules/research/tg/machinery/destructive_analyzer.dm +++ b/code/modules/research/tg/machinery/destructive_analyzer.dm @@ -87,8 +87,15 @@ It is used to destroy hand-held objects and advance technological research. Used to_chat(user, span_notice("The machine rejects \the [O]!")) return if(LAZYLEN(O.contents)) - to_chat(user, span_notice("The machine rejects \the [O]! You need to clear it of all items first!")) - return + var/bad_item = FALSE + for(var/obj/item/thing in O.contents) + if(thing.item_flags & ABSTRACT) + continue + bad_item = TRUE + break + if(bad_item) + to_chat(user, span_notice("The machine rejects \the [O]! You need to clear it of all items first!")) + return busy = TRUE loaded_item = WEAKREF(O) user.drop_item() diff --git a/interface/stylesheet.dm b/interface/stylesheet.dm index 5f0efdaf8c..fa8917ced5 100644 --- a/interface/stylesheet.dm +++ b/interface/stylesheet.dm @@ -88,6 +88,14 @@ em {font-style: normal;font-weight: bold;} h1.alert, h2.alert {color: #000000;} .ghostalert {color: #5c00e6; font-style: italic; font-weight: bold;} .wingdings {font-family: Wingdings, Webdings} +.hypnophrase {color: #3bb5d3; font-weight: bold; animation: hypnocolor 1500ms infinite; animation-direction: alternate;} + @keyframes hypnocolor { + 0% {color: #0d0d0d;} + 25% {color: #410194;} + 50% {color: #7f17d8;} + 75% {color: #410194;} + 100% {color: #3bb5d3;} +} /* VOREStation Edit Start */ .emote {} diff --git a/maps/gateway_vr/wildwest.dm b/maps/gateway_vr/wildwest.dm index 757f0939eb..88b3cb9929 100644 --- a/maps/gateway_vr/wildwest.dm +++ b/maps/gateway_vr/wildwest.dm @@ -50,8 +50,8 @@ if("Power") to_chat(user, span_boldwarning("Your wish is granted, but at a terrible cost...")) to_chat(user, span_warning("The Wish Granter punishes you for your selfishness, claiming your soul and warping your body to match the darkness in your heart.")) - if (!(LASER in user.mutations)) - user.mutations.Add(LASER) + if (!(LASER_EYES in user.mutations)) + user.mutations.Add(LASER_EYES) to_chat(user, span_notice("You feel pressure building behind your eyes.")) if (!(COLD_RESISTANCE in user.mutations)) user.mutations.Add(COLD_RESISTANCE) diff --git a/sound/items/tools/welder.ogg b/sound/items/tools/welder.ogg new file mode 100644 index 0000000000000000000000000000000000000000..3e3d4afec117dea4aabc9d166cff4909513f3a4d GIT binary patch literal 21042 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 literal 0 HcmV?d00001 diff --git a/sound/items/weapons/sear.ogg b/sound/items/weapons/sear.ogg new file mode 100644 index 0000000000000000000000000000000000000000..da4c20abaed006b73b9e62b998797c040c359dcb GIT binary patch literal 7712 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