diff --git a/code/__DEFINES/maps.dm b/code/__DEFINES/maps.dm index 70bb338b7b..0ee61a87f9 100644 --- a/code/__DEFINES/maps.dm +++ b/code/__DEFINES/maps.dm @@ -41,7 +41,6 @@ require only minor tweaks. //boolean - weather types that occur on the level #define ZTRAIT_SNOWSTORM "Weather_Snowstorm" #define ZTRAIT_ASHSTORM "Weather_Ashstorm" -#define ZTRAIT_ACIDRAIN "Weather_Acidrain" #define ZTRAIT_VOIDSTORM "Weather_Voidstorm" #define ZTRAIT_ICESTORM "Weather_Icestorm" #define ZTRAIT_LONGRAIN "Weather_Longrain" diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 4e97723676..920a93a906 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -263,6 +263,14 @@ /// Prevents sprinting from being active. #define TRAIT_SPRINT_LOCKED "sprint_locked" +/// Weather immunities, also protect mobs inside them. +#define TRAIT_LAVA_IMMUNE "lava_immune" //Used by lava turfs and The Floor Is Lava. +#define TRAIT_ASHSTORM_IMMUNE "ashstorm_immune" +#define TRAIT_SNOWSTORM_IMMUNE "snowstorm_immune" +#define TRAIT_RADSTORM_IMMUNE "radstorm_immune" +#define TRAIT_VOIDSTORM_IMMUNE "voidstorm_immune" +#define TRAIT_WEATHER_IMMUNE "weather_immune" //Immune to ALL weather effects. + //non-mob traits #define TRAIT_PARALYSIS "paralysis" //Used for limb-based paralysis, where replacing the limb will fix it #define VEHICLE_TRAIT "vehicle" // inherited from riding vehicles @@ -298,8 +306,8 @@ #define GHOSTROLE_TRAIT "ghostrole" #define APHRO_TRAIT "aphro" #define BLOODSUCKER_TRAIT "bloodsucker" -#define SHOES_TRAIT "shoes" //inherited from your sweet kicks #define GLOVE_TRAIT "glove" //inherited by your cool gloves +#define SHOES_TRAIT "shoes" //inherited from your sweet kicks #define BOOK_TRAIT "granter (book)" // knowledge is power #define TURF_TRAIT "turf" #define STATION_TRAIT "station-trait" diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm index 28104c4a77..709d558a42 100644 --- a/code/_globalvars/traits.dm +++ b/code/_globalvars/traits.dm @@ -126,10 +126,15 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_EMPATH" = TRAIT_EMPATH, "TRAIT_FRIENDLY" = TRAIT_FRIENDLY, "TRAIT_IWASBATONED" = TRAIT_IWASBATONED, + "TRAIT_SALT_SENSITIVE" = TRAIT_SALT_SENSITIVE, + "TRAIT_LAVA_IMMUNE" = TRAIT_LAVA_IMMUNE, + "TRAIT_ASHSTORM_IMMUNE" = TRAIT_ASHSTORM_IMMUNE, + "TRAIT_SNOWSTORM_IMMUNE" = TRAIT_SNOWSTORM_IMMUNE, + "TRAIT_VOIDSTORM_IMMUNE" = TRAIT_VOIDSTORM_IMMUNE, + "TRAIT_WEATHER_IMMUNE" = TRAIT_WEATHER_IMMUNE, "TRAIT_SPACEWALK" = TRAIT_SPACEWALK, "TRAIT_PRIMITIVE" = TRAIT_PRIMITIVE, //unable to use mechs. Given to Ash Walkers - "TRAIT_SALT_SENSITIVE" = TRAIT_SALT_SENSITIVE - ), + ), /obj/item/bodypart = list( "TRAIT_PARALYSIS" = TRAIT_PARALYSIS ), diff --git a/code/datums/action.dm b/code/datums/action.dm index b34cafc03f..aa33c68f22 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -723,6 +723,9 @@ button.maptext_height = 12 /datum/action/cooldown/IsAvailable(silent = FALSE) + . = ..() + if(!.) + return return next_use_time <= world.time /datum/action/cooldown/proc/StartCooldown() diff --git a/code/datums/weather/weather.dm b/code/datums/weather/weather.dm index 45710c6371..797b26b51d 100644 --- a/code/datums/weather/weather.dm +++ b/code/datums/weather/weather.dm @@ -64,8 +64,8 @@ var/overlay_plane = BLACKNESS_PLANE /// If the weather has no purpose but aesthetics. var/aesthetic = FALSE - /// Used by mobs to prevent them from being affected by the weather - var/immunity_type = "storm" + /// Used by mobs (or movables containing mobs, such as enviro bags) to prevent them from being affected by the weather. + var/immunity_type /// The stage of the weather, from 1-4 var/stage = END_STAGE @@ -133,15 +133,18 @@ /datum/weather/proc/start() if(stage >= MAIN_STAGE) return + SEND_GLOBAL_SIGNAL(COMSIG_WEATHER_START(type)) stage = MAIN_STAGE update_areas() - for(var/M in GLOB.player_list) - var/turf/mob_turf = get_turf(M) - if(mob_turf && (mob_turf.z in impacted_z_levels)) + for(var/z_level in impacted_z_levels) + for(var/mob/player as anything in SSmobs.clients_by_zlevel[z_level]) + var/turf/mob_turf = get_turf(player) + if(!mob_turf) + continue if(weather_message) - to_chat(M, weather_message) + to_chat(player, weather_message) if(weather_sound) - SEND_SOUND(M, sound(weather_sound)) + SEND_SOUND(player, sound(weather_sound)) if(!perpetual) addtimer(CALLBACK(src, .proc/wind_down), weather_duration) @@ -192,14 +195,27 @@ * Returns TRUE if the living mob can be affected by the weather * */ -/datum/weather/proc/can_weather_act(mob/living/L) - var/turf/mob_turf = get_turf(L) - if(mob_turf && !(mob_turf.z in impacted_z_levels)) +/datum/weather/proc/can_weather_act(mob/living/mob_to_check) + var/turf/mob_turf = get_turf(mob_to_check) + + if(!mob_turf) return - if(immunity_type in L.weather_immunities) + + if(!(mob_turf.z in impacted_z_levels)) return - if(!(get_area(L) in impacted_areas)) + + if((immunity_type && HAS_TRAIT(mob_to_check, immunity_type)) || HAS_TRAIT(mob_to_check, TRAIT_WEATHER_IMMUNE)) return + + var/atom/loc_to_check = mob_to_check.loc + while(loc_to_check != mob_turf) + if((immunity_type && HAS_TRAIT(loc_to_check, immunity_type)) || HAS_TRAIT(loc_to_check, TRAIT_WEATHER_IMMUNE)) + return + loc_to_check = loc_to_check.loc + + if(!(get_area(mob_to_check) in impacted_areas)) + return + return TRUE /** diff --git a/code/datums/weather/weather_types/acid_rain.dm b/code/datums/weather/weather_types/acid_rain.dm deleted file mode 100644 index 9fa12a0938..0000000000 --- a/code/datums/weather/weather_types/acid_rain.dm +++ /dev/null @@ -1,32 +0,0 @@ -//Acid rain is part of the natural weather cycle in the humid forests of Planetstation, and cause acid damage to anyone unprotected. -/datum/weather/acid_rain - name = "acid rain" - desc = "The planet's thunderstorms are by nature acidic, and will incinerate anyone standing beneath them without protection." - - telegraph_duration = 400 - telegraph_message = "Thunder rumbles far above. You hear droplets drumming against the canopy. Seek shelter." - telegraph_sound = 'sound/ambience/acidrain_start.ogg' - - weather_message = "Acidic rain pours down around you! Get inside!" - weather_overlay = "acid_rain" - weather_duration_lower = 600 - weather_duration_upper = 1500 - weather_sound = 'sound/ambience/acidrain_mid.ogg' - - end_duration = 100 - end_message = "The downpour gradually slows to a light shower. It should be safe outside now." - end_sound = 'sound/ambience/acidrain_end.ogg' - - area_type = /area - protect_indoors = TRUE - target_trait = ZTRAIT_ACIDRAIN - - immunity_type = "acid" // temp - - barometer_predictable = TRUE - - -/datum/weather/acid_rain/weather_act(mob/living/L) - var/resist = L.getarmor(null, ACID) - if(prob(max(0,100-resist))) - L.acid_act(20,20) diff --git a/code/datums/weather/weather_types/ash_storm.dm b/code/datums/weather/weather_types/ash_storm.dm index f67355c270..e41cb93c54 100644 --- a/code/datums/weather/weather_types/ash_storm.dm +++ b/code/datums/weather/weather_types/ash_storm.dm @@ -1,6 +1,5 @@ //A reference to this list is passed into area sound managers, and it's modified in a manner that preserves that reference in ash_storm.dm GLOBAL_LIST_EMPTY(ash_storm_sounds) -//Ash storms happen frequently on lavaland. They heavily obscure vision, and cause high fire damage to anyone caught outside. /datum/weather/ash_storm name = "ash storm" desc = "An intense atmospheric storm lifts ash off of the planet's surface and billows it down across the area, dealing intense fire damage to the unprotected." @@ -22,7 +21,7 @@ GLOBAL_LIST_EMPTY(ash_storm_sounds) protect_indoors = TRUE target_trait = ZTRAIT_ASHSTORM - immunity_type = "ash" + immunity_type = TRAIT_ASHSTORM_IMMUNE probability = 90 @@ -72,10 +71,6 @@ GLOBAL_LIST_EMPTY(ash_storm_sounds) var/thermal_protection = H.easy_thermal_protection() if(thermal_protection >= FIRE_IMMUNITY_MAX_TEMP_PROTECT) return TRUE - if(isliving(L))// if we're a non immune mob inside an immune mob we have to reconsider if that mob is immune to protect ourselves - var/mob/living/the_mob = L - if("ash" in the_mob.weather_immunities) - return TRUE // if(istype(L, /obj/structure/closet)) // var/obj/structure/closet/the_locker = L // if(the_locker.weather_protection) @@ -93,7 +88,6 @@ GLOBAL_LIST_EMPTY(ash_storm_sounds) return L.adjustFireLoss(4) - //Emberfalls are the result of an ash storm passing by close to the playable area of lavaland. They have a 10% chance to trigger in place of an ash storm. /datum/weather/ash_storm/emberfall name = "emberfall" diff --git a/code/datums/weather/weather_types/floor_is_lava.dm b/code/datums/weather/weather_types/floor_is_lava.dm index 00ecfff0b3..4da2aead72 100644 --- a/code/datums/weather/weather_types/floor_is_lava.dm +++ b/code/datums/weather/weather_types/floor_is_lava.dm @@ -19,19 +19,23 @@ target_trait = ZTRAIT_STATION overlay_layer = ABOVE_OPEN_TURF_LAYER //Covers floors only - immunity_type = "lava" + immunity_type = TRAIT_LAVA_IMMUNE -/datum/weather/floor_is_lava/weather_act(mob/living/L) - if(issilicon(L)) - return - if(istype(L.buckled, /obj/structure/bed)) - return - for(var/obj/structure/O in L.loc) - if(O.density) - return - if(L.loc.density) - return - if(!L.client) //Only sentient people are going along with it! - return - L.adjustFireLoss(3) +/datum/weather/floor_is_lava/can_weather_act(mob/living/mob_to_check) + if(!mob_to_check.client) //Only sentient people are going along with it! + return FALSE + . = ..() + if(!. || issilicon(mob_to_check) || istype(mob_to_check.buckled, /obj/structure/bed)) + return FALSE + var/turf/mob_turf = get_turf(mob_to_check) + if(mob_turf.density) //Walls are not floors. + return FALSE + for(var/obj/structure/structure_to_check in mob_turf) + if(structure_to_check.density) + return FALSE + if(mob_to_check.movement_type & FLYING) + return FALSE + +/datum/weather/floor_is_lava/weather_act(mob/living/victim) + victim.adjustFireLoss(3) diff --git a/code/datums/weather/weather_types/ice_storm.dm b/code/datums/weather/weather_types/ice_storm.dm index 451b0bdad6..fd09ff5138 100644 --- a/code/datums/weather/weather_types/ice_storm.dm +++ b/code/datums/weather/weather_types/ice_storm.dm @@ -21,7 +21,7 @@ protected_areas = list(/area/edina/protected) target_trait = ZTRAIT_ICESTORM - immunity_type = "rad" + immunity_type = TRAIT_SNOWSTORM_IMMUNE /datum/weather/ice_storm/weather_act(mob/living/L) //L.adjust_bodytemperature(-rand(10,20)) diff --git a/code/datums/weather/weather_types/radiation_storm.dm b/code/datums/weather/weather_types/radiation_storm.dm index feb1b6719a..188991e4cf 100644 --- a/code/datums/weather/weather_types/radiation_storm.dm +++ b/code/datums/weather/weather_types/radiation_storm.dm @@ -21,7 +21,7 @@ /area/ai_monitored/turret_protected/ai, /area/commons/storage/emergency/starboard, /area/commons/storage/emergency/port, /area/shuttle, /area/ruin/lavaland, /area/commons/dorms) target_trait = ZTRAIT_STATION - immunity_type = "rad" + immunity_type = TRAIT_RADSTORM_IMMUNE var/radiation_intensity = 100 diff --git a/code/datums/weather/weather_types/snow_storm.dm b/code/datums/weather/weather_types/snow_storm.dm index 8ab4839cdb..db18fc5c9e 100644 --- a/code/datums/weather/weather_types/snow_storm.dm +++ b/code/datums/weather/weather_types/snow_storm.dm @@ -19,7 +19,7 @@ protect_indoors = TRUE target_trait = ZTRAIT_SNOWSTORM - immunity_type = "snow" + immunity_type = TRAIT_SNOWSTORM_IMMUNE barometer_predictable = TRUE diff --git a/code/datums/weather/weather_types/void_storm.dm b/code/datums/weather/weather_types/void_storm.dm index 41c3b95bbf..e77a96f0fb 100644 --- a/code/datums/weather/weather_types/void_storm.dm +++ b/code/datums/weather/weather_types/void_storm.dm @@ -17,15 +17,18 @@ protect_indoors = FALSE target_trait = ZTRAIT_VOIDSTORM - immunity_type = "void" + immunity_type = TRAIT_VOIDSTORM_IMMUNE barometer_predictable = FALSE perpetual = TRUE -/datum/weather/void_storm/weather_act(mob/living/L) - if(IS_HERETIC(L) || IS_HERETIC_MONSTER(L)) - return - L.adjustOxyLoss(rand(1,3)) - L.adjustFireLoss(rand(1,3)) - L.adjust_blurriness(rand(0,1)) - L.adjust_bodytemperature(-rand(5,15)) +/datum/weather/void_storm/can_weather_act(mob/living/mob_to_check) + . = ..() + if(IS_HERETIC(mob_to_check) || IS_HERETIC_MONSTER(mob_to_check)) + return FALSE + +/datum/weather/void_storm/weather_act(mob/living/victim) + victim.adjustOxyLoss(rand(1,3)) + victim.adjustFireLoss(rand(1,3)) + victim.adjust_blurriness(rand(0,1)) + victim.adjust_bodytemperature(-rand(5,15)) diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index fc94458fb5..1918decfb1 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -325,12 +325,12 @@ as performing this in action() will cause the upgrade to end up in the borg inst /obj/item/borg/upgrade/lavaproof/action(mob/living/silicon/robot/R, user = usr) . = ..() if(.) - R.weather_immunities += "lava" + ADD_TRAIT(src, TRAIT_LAVA_IMMUNE, type) /obj/item/borg/upgrade/lavaproof/deactivate(mob/living/silicon/robot/R, user = usr) . = ..() if (.) - R.weather_immunities -= "lava" + REMOVE_TRAIT(src, TRAIT_LAVA_IMMUNE, type) /obj/item/borg/upgrade/selfrepair name = "self-repair module" diff --git a/code/game/turfs/simulated/lava.dm b/code/game/turfs/simulated/lava.dm index 5da3d079c2..943f60e752 100644 --- a/code/game/turfs/simulated/lava.dm +++ b/code/game/turfs/simulated/lava.dm @@ -17,6 +17,16 @@ barefootstep = FOOTSTEP_LAVA clawfootstep = FOOTSTEP_LAVA heavyfootstep = FOOTSTEP_LAVA + /// How much fire damage we deal to living mobs stepping on us + var/lava_damage = 20 + /// How many firestacks we add to living mobs stepping on us + var/lava_firestacks = 20 + /// How much temperature we expose objects with + var/temperature_damage = 10000 + /// mobs with this trait won't burn. + var/immunity_trait = TRAIT_LAVA_IMMUNE + /// objects with these flags won't burn. + var/immunity_resistance_flags = LAVA_PROOF /turf/open/lava/ex_act(severity, target, origin) contents_explosion(severity, target, origin) @@ -107,62 +117,98 @@ LAZYREMOVE(found_safeties, S) return LAZYLEN(found_safeties) +///Generic return value of the can_burn_stuff() proc. Does nothing. +#define LAVA_BE_IGNORING 0 +/// Another. Won't burn the target but will make the turf start processing. +#define LAVA_BE_PROCESSING 1 +/// Burns the target and makes the turf process (depending on the return value of do_burn()). +#define LAVA_BE_BURNING 2 -/turf/open/lava/proc/burn_stuff(AM) - . = 0 +///Proc that sets on fire something or everything on the turf that's not immune to lava. Returns TRUE to make the turf start processing. +/turf/open/lava/proc/burn_stuff(atom/movable/to_burn, delta_time = 1) if(is_safe()) return FALSE var/thing_to_check = src - if (AM) - thing_to_check = list(AM) - for(var/thing in thing_to_check) - if(isobj(thing)) - var/obj/O = thing - if((O.resistance_flags & (LAVA_PROOF|INDESTRUCTIBLE)) || O.throwing) + if (to_burn) + thing_to_check = list(to_burn) + for(var/atom/movable/burn_target as anything in thing_to_check) + switch(can_burn_stuff(burn_target)) + if(LAVA_BE_IGNORING) continue - . = 1 - if((O.resistance_flags & (ON_FIRE))) - continue - if(!(O.resistance_flags & FLAMMABLE)) - O.resistance_flags |= FLAMMABLE //Even fireproof things burn up in lava - if(O.resistance_flags & FIRE_PROOF) - O.resistance_flags &= ~FIRE_PROOF - if(O.armor.fire > 50) //obj with 100% fire armor still get slowly burned away. - O.armor = O.armor.setRating(fire = 50) - O.fire_act(10000, 1000) - - else if (isliving(thing)) - . = 1 - var/mob/living/L = thing - if(L.movement_type & FLYING) - continue //YOU'RE FLYING OVER IT - if("lava" in L.weather_immunities) - continue - var/buckle_check = L.buckling - if(!buckle_check) - buckle_check = L.buckled - if(isobj(buckle_check)) - var/obj/O = buckle_check - if(O.resistance_flags & LAVA_PROOF) + if(LAVA_BE_BURNING) + if(!do_burn(burn_target, delta_time)) continue - else if(isliving(buckle_check)) - var/mob/living/live = buckle_check - if("lava" in live.weather_immunities) - continue - if(iscarbon(L)) - var/mob/living/carbon/C = L - var/obj/item/clothing/S = C.get_item_by_slot(ITEM_SLOT_OCLOTHING) - var/obj/item/clothing/H = C.get_item_by_slot(ITEM_SLOT_HEAD) + . = TRUE - if(S && H && S.clothing_flags & LAVAPROTECT && H.clothing_flags & LAVAPROTECT) - return +/turf/open/lava/proc/can_burn_stuff(atom/movable/burn_target) + if(burn_target.movement_type & (FLYING|FLOATING)) //you're flying over it. + return isliving(burn_target) ? LAVA_BE_PROCESSING : LAVA_BE_IGNORING - L.adjustFireLoss(20) - if(L) //mobs turning into object corpses could get deleted here. - L.adjust_fire_stacks(20) - L.IgniteMob() + if(isobj(burn_target)) + if(burn_target.throwing) // to avoid gulag prisoners easily escaping, throwing only works for objects. + return LAVA_BE_IGNORING + var/obj/burn_obj = burn_target + if((burn_obj.resistance_flags & immunity_resistance_flags)) + return LAVA_BE_PROCESSING + return LAVA_BE_BURNING + + if (!isliving(burn_target)) + return LAVA_BE_IGNORING + + if(HAS_TRAIT(burn_target, immunity_trait)) + return LAVA_BE_PROCESSING + var/mob/living/burn_living = burn_target + var/atom/movable/burn_buckled = burn_living.buckled + if(burn_buckled) + if(burn_buckled.movement_type & (FLYING|FLOATING)) + return LAVA_BE_PROCESSING + if(isobj(burn_buckled)) + var/obj/burn_buckled_obj = burn_buckled + if(burn_buckled_obj.resistance_flags & immunity_resistance_flags) + return LAVA_BE_PROCESSING + else if(HAS_TRAIT(burn_buckled, immunity_trait)) + return LAVA_BE_PROCESSING + + if(iscarbon(burn_living)) + var/mob/living/carbon/burn_carbon = burn_living + var/obj/item/clothing/burn_suit = burn_carbon.get_item_by_slot(ITEM_SLOT_OCLOTHING) + var/obj/item/clothing/burn_helmet = burn_carbon.get_item_by_slot(ITEM_SLOT_HEAD) + if(burn_suit?.clothing_flags & LAVAPROTECT && burn_helmet?.clothing_flags & LAVAPROTECT) + return LAVA_BE_PROCESSING + + return LAVA_BE_BURNING + +#undef LAVA_BE_IGNORING +#undef LAVA_BE_PROCESSING +#undef LAVA_BE_BURNING + +/turf/open/lava/proc/do_burn(atom/movable/burn_target, delta_time = 1) + . = TRUE + if(isobj(burn_target)) + var/obj/burn_obj = burn_target + if(burn_obj.resistance_flags & ON_FIRE) // already on fire; skip it. + return + if(!(burn_obj.resistance_flags & FLAMMABLE)) + burn_obj.resistance_flags |= FLAMMABLE //Even fireproof things burn up in lava + if(burn_obj.resistance_flags & FIRE_PROOF) + burn_obj.resistance_flags &= ~FIRE_PROOF + if(burn_obj.armor.fire > 50) //obj with 100% fire armor still get slowly burned away. + burn_obj.armor = burn_obj.armor.setRating(fire = 50) + burn_obj.fire_act(temperature_damage, 1000 * delta_time) + if(istype(burn_obj, /obj/structure/closet)) + var/obj/structure/closet/burn_closet = burn_obj + for(var/burn_content in burn_closet.contents) + burn_stuff(burn_content) + + var/mob/living/burn_living = burn_target + burn_living.update_fire() + + burn_living.adjustFireLoss(lava_damage * delta_time) + if(!QDELETED(burn_living)) //mobs turning into object corpses could get deleted here. + burn_living.adjust_fire_stacks(lava_firestacks * delta_time) + burn_living.IgniteMob() /turf/open/lava/smooth name = "lava" diff --git a/code/modules/awaymissions/mission_code/snowdin.dm b/code/modules/awaymissions/mission_code/snowdin.dm index 1362c7818a..35371af4ca 100644 --- a/code/modules/awaymissions/mission_code/snowdin.dm +++ b/code/modules/awaymissions/mission_code/snowdin.dm @@ -164,11 +164,12 @@ icon_state = "liquidplasma" initial_gas_mix = "n2=82;plasma=24;TEMP=120" baseturfs = /turf/open/lava/plasma - slowdown = 2 light_range = 3 light_power = 0.75 light_color = LIGHT_COLOR_PURPLE + immunity_trait = TRAIT_SNOWSTORM_IMMUNE + immunity_resistance_flags = FREEZE_PROOF /turf/open/lava/plasma/attackby(obj/item/I, mob/user, params) var/obj/item/reagent_containers/glass/C = I @@ -178,78 +179,45 @@ C.reagents.add_reagent(/datum/reagent/toxin/plasma, rand(5, 10)) user.visible_message("[user] scoops some plasma from the [src] with \the [C].", "You scoop out some plasma from the [src] using \the [C].") -/turf/open/lava/plasma/burn_stuff(AM) - . = 0 +/turf/open/lava/plasma/do_burn(atom/movable/burn_target, delta_time = 1) + . = TRUE + if(isobj(burn_target)) + return FALSE // Does nothing against objects. Old code. - if(is_safe()) - return FALSE + var/mob/living/burn_living = burn_target + burn_living.adjustFireLoss(2) + if(QDELETED(burn_living)) + return + burn_living.adjust_fire_stacks(20) //dipping into a stream of plasma would probably make you more flammable than usual + burn_living.adjust_bodytemperature(-rand(50,65)) //its cold, man + if(!ishuman(burn_living) || DT_PROB(65, delta_time)) + return + var/mob/living/carbon/human/burn_human = burn_living + var/datum/species/burn_species = burn_human.dna.species + if(istype(burn_species, /datum/species/plasmaman) || istype(burn_species, /datum/species/android) || istype(burn_species, /datum/species/synth)) //ignore plasmamen/robotic species + return - var/thing_to_check = src - if (AM) - thing_to_check = list(AM) - for(var/thing in thing_to_check) - if(isobj(thing)) - var/obj/O = thing - if((O.resistance_flags & (FREEZE_PROOF)) || O.throwing) - continue - - else if (isliving(thing)) - . = 1 - var/mob/living/L = thing - if(L.movement_type & FLYING) - continue //YOU'RE FLYING OVER IT - if("snow" in L.weather_immunities) - continue - - var/buckle_check = L.buckling - if(!buckle_check) - buckle_check = L.buckled - if(isobj(buckle_check)) - var/obj/O = buckle_check - if(O.resistance_flags & FREEZE_PROOF) - continue - - else if(isliving(buckle_check)) - var/mob/living/live = buckle_check - if("snow" in live.weather_immunities) - continue - - L.adjustFireLoss(2) - if(L) - L.adjust_fire_stacks(20) //dipping into a stream of plasma would probably make you more flammable than usual - L.adjust_bodytemperature(-rand(50,65)) //its cold, man - if(ishuman(L))//are they a carbon? - var/list/plasma_parts = list()//a list of the organic parts to be turned into plasma limbs - var/list/robo_parts = list()//keep a reference of robotic parts so we know if we can turn them into a plasmaman - var/mob/living/carbon/human/PP = L - var/S = PP.dna.species - if(istype(S, /datum/species/plasmaman) || istype(S, /datum/species/android) || istype(S, /datum/species/synth)) //ignore plasmamen/robotic species - continue - - for(var/BP in PP.bodyparts) - var/obj/item/bodypart/NN = BP - if(NN.is_organic_limb() && NN.species_id != "plasmaman") //getting every organic, non-plasmaman limb (augments/androids are immune to this) - plasma_parts += NN - if(NN.is_robotic_limb(FALSE)) - robo_parts += NN - - if(prob(35)) //checking if the delay is over & if the victim actually has any parts to nom - PP.adjustToxLoss(15) - PP.adjustFireLoss(25) - if(plasma_parts.len) - var/obj/item/bodypart/NB = pick(plasma_parts) //using the above-mentioned list to get a choice of limbs for dismember() to use - PP.emote("scream") - NB.species_id = "plasmaman"//change the species_id of the limb to that of a plasmaman - NB.no_update = TRUE - NB.change_bodypart_status() - PP.visible_message("[L] screams in pain as [L.p_their()] [NB] melts down to the bone!", \ - "You scream out in pain as your [NB] melts down to the bone, leaving an eerie plasma-like glow where flesh used to be!") - if(!plasma_parts.len && !robo_parts.len) //a person with no potential organic limbs left AND no robotic limbs, time to turn them into a plasmaman - PP.IgniteMob() - PP.set_species(/datum/species/plasmaman) - PP.visible_message("[L] bursts into a brilliant purple flame as [L.p_their()] entire body is that of a skeleton!", \ - "Your senses numb as all of your remaining flesh is turned into a purple slurry, sloshing off your body and leaving only your bones to show in a vibrant purple!") + var/list/plasma_parts = list()//a list of the organic parts to be turned into plasma limbs + var/list/robo_parts = list()//keep a reference of robotic parts so we know if we can turn them into a plasmaman + for(var/obj/item/bodypart/burn_limb as anything in burn_human.bodyparts) + if(burn_limb.status == BODYPART_ORGANIC && burn_limb.species_id != SPECIES_PLASMAMAN) //getting every organic, non-plasmaman limb (augments/androids are immune to this) + plasma_parts += burn_limb + if(burn_limb.status == BODYPART_ROBOTIC) + robo_parts += burn_limb + burn_human.adjustToxLoss(15) + burn_human.adjustFireLoss(25) + if(plasma_parts.len) + var/obj/item/bodypart/burn_limb = pick(plasma_parts) //using the above-mentioned list to get a choice of limbs + burn_human.emote("scream") + burn_human.update_body_parts() + burn_human.visible_message(span_warning("[burn_human] screams in pain as [burn_human.p_their()] [burn_limb] melts down to the bone!"), \ + span_userdanger("You scream out in pain as your [burn_limb] melts down to the bone, leaving an eerie plasma-like glow where flesh used to be!")) + if(!plasma_parts.len && !robo_parts.len) //a person with no potential organic limbs left AND no robotic limbs, time to turn them into a plasmaman + burn_human.IgniteMob() + burn_human.set_species(/datum/species/plasmaman) + burn_human.visible_message(span_warning("[burn_human] bursts into a brilliant purple flame as [burn_human.p_their()] entire body is that of a skeleton!"), \ + span_userdanger("Your senses numb as all of your remaining flesh is turned into a purple slurry, sloshing off your body and leaving only your bones to show in a vibrant purple!")) /obj/vehicle/ridden/lavaboat/plasma name = "plasma boat" diff --git a/code/modules/mining/equipment/explorer_gear.dm b/code/modules/mining/equipment/explorer_gear.dm index 921cd9b6f0..1588dfa5c5 100644 --- a/code/modules/mining/equipment/explorer_gear.dm +++ b/code/modules/mining/equipment/explorer_gear.dm @@ -156,38 +156,48 @@ M.appearance_flags = RESET_COLOR . += M +/****************HEVA Suit and Mask****************/ -// CITADEL ADDITIONS BELOW - -/****************SEVA Suit and Mask****************/ - -/obj/item/clothing/suit/hooded/explorer/seva - name = "SEVA Suit" - desc = "A fire-proof suit for exploring hot environments. Its design and material make it easier for a Goliath to keep their grip on the wearer." - icon_state = "seva" - item_state = "seva" +/obj/item/clothing/suit/hooded/explorer/heva + name = "HEVA suit" + desc = "The Hazardous Environments extra-Vehicular Activity suit, developed by WanTon & Sons Perilous Mining and sold to Nanotrasen for missions within inhospitable, mineral-rich zones. \ + Its sleek plating deflects most biological - radioactive - and chemical substances and materials. Most notably, this will negate the effects of ash storms and give goliaths better grip against you." + icon_state = "heva" + item_state = "heva" w_class = WEIGHT_CLASS_BULKY - max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS - hoodtype = /obj/item/clothing/head/hooded/explorer/seva - armor = list(MELEE = 15, BULLET = 10, LASER = 10, ENERGY = 10, BOMB = 35, BIO = 50, RAD = 25, FIRE = 100, ACID = 25) + hoodtype = /obj/item/clothing/head/hooded/explorer/heva + armor = list(MELEE = 20, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 20, BIO = 100, RAD = 80, FIRE = 100, ACID = 80) resistance_flags = FIRE_PROOF | GOLIATH_WEAKNESS -/obj/item/clothing/head/hooded/explorer/seva - name = "SEVA Hood" - desc = "A fire-proof hood for exploring hot environments. Its design and material make it easier for a Goliath to keep their grip on the wearer." - icon_state = "seva" - item_state = "seva" - max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT - armor = list(MELEE = 10, BULLET = 10, LASER = 10, ENERGY = 10, BOMB = 35, BIO = 50, RAD = 25, FIRE = 100, ACID = 25) +/obj/item/clothing/head/hooded/explorer/heva + name = "HEVA hood" + desc = "The Hazardous Environments extra-Vehiclar Activity hood, developed by WanTon & Sons Perilous Mining. \ + Its sleek plating deflects most biological - radioactive - and chemical substances and materials. An instructive tag dictates that the provided mask is required for full protection." + icon_state = "heva" + item_state = "heva" + flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH + armor = list(MELEE = 20, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 20, BIO = 100, RAD = 20, FIRE = 60, ACID = 20) resistance_flags = FIRE_PROOF | GOLIATH_WEAKNESS -/obj/item/clothing/mask/gas/seva - name = "SEVA Mask" - desc = "A face-covering plate that can be connected to an air supply. Intended for use with the SEVA Suit." - icon_state = "seva" - item_state = "seva" - resistance_flags = FIRE_PROOF +/obj/item/clothing/head/hooded/explorer/heva/equipped(mob/living/carbon/human/user, slot) + ..() + if (slot == ITEM_SLOT_HEAD) + ADD_TRAIT(user, TRAIT_ASHSTORM_IMMUNE, "heva_suit") + +/obj/item/clothing/head/hooded/explorer/heva/dropped(mob/living/carbon/human/user) + ..() + if (HAS_TRAIT_FROM(user, TRAIT_ASHSTORM_IMMUNE, "heva_suit")) + REMOVE_TRAIT(user, TRAIT_ASHSTORM_IMMUNE, "heva_suit") + +/obj/item/clothing/mask/gas/heva + name = "HEVA mask" + desc = "The Hazardous Environments extra-Vehiclar Activity mask, developed by WanTon & Sons Perilous Mining. \ + Its sleek plating deflects most biological - radioactive - and chemical substances and materials. An instructive tag dictates that the provided protective attire is required for full protection." + icon_state = "heva" + item_state = "heva" + flags_inv = HIDEFACIALHAIR|HIDEFACE|HIDEEYES|HIDEEARS|HIDEHAIR + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 60, FIRE = 40, ACID = 50) /****************Exo-Suit and Mask****************/ diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index 6d91774465..94a46ce719 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -1043,7 +1043,7 @@ user.mind.AddSpell(D) if(4) to_chat(user, "You feel like you could walk straight through lava now.") - H.weather_immunities |= "lava" + ADD_TRAIT(user, TRAIT_LAVA_IMMUNE, type) playsound(user.loc,'sound/items/drink.ogg', rand(10,50), 1) qdel(src) diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm index 4c275c266e..97a45f7e17 100644 --- a/code/modules/mining/machine_vending.dm +++ b/code/modules/mining/machine_vending.dm @@ -236,7 +236,7 @@ /obj/machinery/mineral/equipment_vendor/proc/RedeemSVoucher(obj/item/suit_voucher/voucher, mob/redeemer) var/items = list( "Exo-suit" = image(icon = 'icons/obj/clothing/suits.dmi', icon_state = "exo"), - "SEVA suit" = image(icon = 'icons/obj/clothing/suits.dmi', icon_state = "seva")) + "HEVA suit" = image(icon = 'icons/obj/clothing/suits.dmi', icon_state = "heva")) var/selection = show_radial_menu(redeemer, src, items, require_near = TRUE, tooltips = TRUE) if(!selection || !Adjacent(redeemer) || QDELETED(voucher) || voucher.loc != redeemer) @@ -246,9 +246,9 @@ if("Exo-suit") new /obj/item/clothing/suit/hooded/explorer/exo(drop_location) new /obj/item/clothing/mask/gas/exo(drop_location) - if("SEVA suit") - new /obj/item/clothing/suit/hooded/explorer/seva(drop_location) - new /obj/item/clothing/mask/gas/seva(drop_location) + if("HEVA suit") + new /obj/item/clothing/suit/hooded/explorer/heva(drop_location) + new /obj/item/clothing/mask/gas/heva(drop_location) playsound(src, 'sound/machines/machine_vend.ogg', 50, TRUE, extrarange = -3) SSblackbox.record_feedback("tally", "suit_voucher_redeemed", 1, selection) qdel(voucher) diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm index a7044174b0..69c1488436 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm @@ -48,13 +48,11 @@ else //Maybe uses plasma in the future, although that wouldn't make any sense... leaping = 1 - weather_immunities += "lava" update_icons() throw_at(A, MAX_ALIEN_LEAP_DIST, 1, src, FALSE, TRUE, callback = CALLBACK(src, .proc/leap_end)) /mob/living/carbon/alien/humanoid/hunter/proc/leap_end() leaping = 0 - weather_immunities -= "lava" update_icons() /mob/living/carbon/alien/humanoid/hunter/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm index 2ef615a9d2..67f8023c09 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -214,11 +214,11 @@ /datum/species/golem/titanium/on_species_gain(mob/living/carbon/C, datum/species/old_species) . = ..() - C.weather_immunities |= "ash" + ADD_TRAIT(C, TRAIT_ASHSTORM_IMMUNE, SPECIES_TRAIT) /datum/species/golem/titanium/on_species_loss(mob/living/carbon/C) . = ..() - C.weather_immunities -= "ash" + REMOVE_TRAIT(C, TRAIT_ASHSTORM_IMMUNE, SPECIES_TRAIT) //Immune to ash storms and lava /datum/species/golem/plastitanium @@ -233,13 +233,13 @@ /datum/species/golem/plastitanium/on_species_gain(mob/living/carbon/C, datum/species/old_species) . = ..() - C.weather_immunities |= "lava" - C.weather_immunities |= "ash" + ADD_TRAIT(C, TRAIT_LAVA_IMMUNE, SPECIES_TRAIT) + ADD_TRAIT(C, TRAIT_ASHSTORM_IMMUNE, SPECIES_TRAIT) /datum/species/golem/plastitanium/on_species_loss(mob/living/carbon/C) . = ..() - C.weather_immunities -= "ash" - C.weather_immunities -= "lava" + REMOVE_TRAIT(C, TRAIT_LAVA_IMMUNE, SPECIES_TRAIT) + REMOVE_TRAIT(C, TRAIT_ASHSTORM_IMMUNE, SPECIES_TRAIT) //Fast and regenerates... but can only speak like an abductor /datum/species/golem/alloy diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 7b07dfb487..6024bfbf4c 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -107,8 +107,6 @@ var/hellbound = 0 //People who've signed infernal contracts are unrevivable. - var/list/weather_immunities = list() - var/stun_absorption = null //converted to a list of stun absorption sources this mob has when one is added var/blood_volume = 0 //how much blood the mob has diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index d18014f4d6..6c799607be 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -6,7 +6,6 @@ pass_flags = PASSTABLE | PASSMOB mob_size = MOB_SIZE_TINY desc = "A generic pAI mobile hard-light holographics emitter. It seems to be deactivated." - weather_immunities = list("ash") health = 500 maxHealth = 500 layer = BELOW_MOB_LAYER diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index be9ea03e6e..054de86e93 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -8,7 +8,6 @@ initial_language_holder = /datum/language_holder/synthetic see_in_dark = 8 bubble_icon = "machine" - weather_immunities = list("ash") possible_a_intents = list(INTENT_HELP, INTENT_HARM) mob_biotypes = MOB_ROBOTIC rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE @@ -60,6 +59,7 @@ diag_hud.add_to_hud(src) diag_hud_set_status() diag_hud_set_health() + ADD_TRAIT(src, TRAIT_ASHSTORM_IMMUNE, ROUNDSTART_TRAIT) /mob/living/silicon/ComponentInitialize() . = ..() diff --git a/code/modules/mob/living/simple_animal/hostile/bear.dm b/code/modules/mob/living/simple_animal/hostile/bear.dm index ba81ad72da..adca93e70f 100644 --- a/code/modules/mob/living/simple_animal/hostile/bear.dm +++ b/code/modules/mob/living/simple_animal/hostile/bear.dm @@ -61,7 +61,7 @@ icon_living = "snowbear" icon_dead = "snowbear_dead" desc = "It's a polar bear, in space, but not actually in space." - weather_immunities = list("snow") + weather_immunities = list(TRAIT_SNOWSTORM_IMMUNE) /mob/living/simple_animal/hostile/bear/russian name = "combat bear" diff --git a/code/modules/mob/living/simple_animal/hostile/dark_wizard.dm b/code/modules/mob/living/simple_animal/hostile/dark_wizard.dm index 61b8652287..dfecee745b 100644 --- a/code/modules/mob/living/simple_animal/hostile/dark_wizard.dm +++ b/code/modules/mob/living/simple_animal/hostile/dark_wizard.dm @@ -26,7 +26,7 @@ gold_core_spawnable = HOSTILE_SPAWN faction = list(ROLE_WIZARD) footstep_type = FOOTSTEP_MOB_SHOE - weather_immunities = list("lava","ash") + weather_immunities = list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE) minbodytemp = 0 maxbodytemp = INFINITY atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm index 609d4dcefa..098cbb3add 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm @@ -16,7 +16,7 @@ Difficulty: Extremely Hard mob_biotypes = MOB_ORGANIC|MOB_HUMANOID light_color = "#E4C7C5" movement_type = GROUND - weather_immunities = list("snow") + weather_immunities = list(TRAIT_SNOWSTORM_IMMUNE) speak_emote = list("roars") armour_penetration = 100 melee_damage_lower = 10 diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm index e2c82c0eff..0402220a5d 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm @@ -10,7 +10,7 @@ obj_damage = 400 light_range = 3 faction = list("mining", "boss") - weather_immunities = list("lava","ash") + weather_immunities = list(TRAIT_LAVA_IMMUNE,TRAIT_ASHSTORM_IMMUNE) movement_type = FLYING robust_searching = 1 ranged_ignores_vision = TRUE diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm index a8910f5104..d071209b64 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm @@ -52,7 +52,7 @@ GLOBAL_LIST_INIT(AISwarmerCapsByType, list(/mob/living/simple_animal/hostile/swa crusher_achievement_type = /datum/award/achievement/boss/swarmer_beacon_crusher score_achievement_type = /datum/award/score/swarmer_beacon_score faction = list("mining", "boss", "swarmer") - weather_immunities = list("lava","ash") + weather_immunities = list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE) stop_automated_movement = TRUE wander = FALSE layer = BELOW_MOB_LAYER @@ -101,7 +101,7 @@ GLOBAL_LIST_INIT(AISwarmerCapsByType, list(/mob/living/simple_animal/hostile/swa /mob/living/simple_animal/hostile/swarmer/ai wander = 1 faction = list("swarmer", "mining") - weather_immunities = list("ash") //wouldn't be fun otherwise + weather_immunities = list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE) //wouldn't be fun otherwise AIStatus = AI_ON /mob/living/simple_animal/hostile/swarmer/ai/Initialize(mapload) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm index 0d6287e50c..3a9ad12cab 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm @@ -14,7 +14,7 @@ Difficulty: Hard attack_verb_continuous = "claws" attack_verb_simple = "claw" attack_sound = 'sound/magic/demon_attack1.ogg' - weather_immunities = list("snow") + weather_immunities = list(TRAIT_SNOWSTORM_IMMUNE) speak_emote = list("roars") armour_penetration = 40 melee_damage_lower = 40 diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm index 492000e3e6..4f24bada6b 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm @@ -10,7 +10,7 @@ speak_emote = list("warbles", "quavers") emote_hear = list("trills.") emote_see = list("sniffs.", "burps.") - weather_immunities = list("lava","ash") + weather_immunities = list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE) faction = list("mining", "ashwalker") density = FALSE speak_chance = 1 diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm index f2ffd54cbd..0844cf988a 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm @@ -272,7 +272,7 @@ aggro_vision_range = 9 speed = 3 faction = list("mining") - weather_immunities = list("lava","ash") + weather_immunities = list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE) obj_damage = 30 environment_smash = ENVIRONMENT_SMASH_STRUCTURES see_in_dark = 8 @@ -321,7 +321,7 @@ gloves = /obj/item/clothing/gloves/color/black mask = /obj/item/clothing/mask/gas/explorer if(prob(20)) - suit = pickweight(list(/obj/item/clothing/suit/hooded/explorer/standard = 6, /obj/item/clothing/suit/hooded/cloak/goliath = 2, /obj/item/clothing/suit/hooded/explorer/exo = 6, /obj/item/clothing/suit/hooded/explorer/seva = 6)) + suit = pickweight(list(/obj/item/clothing/suit/hooded/explorer/standard = 6, /obj/item/clothing/suit/hooded/cloak/goliath = 2, /obj/item/clothing/suit/hooded/explorer/exo = 6, /obj/item/clothing/suit/hooded/explorer/heva = 6)) if(prob(30)) r_pocket = pickweight(list(/obj/item/stack/marker_beacon = 20, /obj/item/stack/spacecash/c1000 = 7, /obj/item/reagent_containers/hypospray/medipen/survival = 2, /obj/item/borg/upgrade/modkit/damage = 1 )) if(prob(10)) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm index c3e4f24c43..e9be18f0cb 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm @@ -3,7 +3,7 @@ vision_range = 2 atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) faction = list("mining") - weather_immunities = list("lava","ash") + weather_immunities = list(TRAIT_LAVA_IMMUNE,TRAIT_ASHSTORM_IMMUNE) obj_damage = 30 environment_smash = ENVIRONMENT_SMASH_WALLS minbodytemp = 0 diff --git a/code/modules/mob/living/simple_animal/hostile/skeleton.dm b/code/modules/mob/living/simple_animal/hostile/skeleton.dm index a812e9d3c4..f576f3b9b8 100644 --- a/code/modules/mob/living/simple_animal/hostile/skeleton.dm +++ b/code/modules/mob/living/simple_animal/hostile/skeleton.dm @@ -46,7 +46,7 @@ icon_dead = "eskimo_dead" maxHealth = 55 health = 55 - weather_immunities = list("snow") + weather_immunities = list(TRAIT_SNOWSTORM_IMMUNE) gold_core_spawnable = NO_SPAWN melee_damage_lower = 17 melee_damage_upper = 20 @@ -65,7 +65,7 @@ icon_dead = "templar_dead" maxHealth = 150 health = 150 - weather_immunities = list("snow") + weather_immunities = list(TRAIT_SNOWSTORM_IMMUNE) speed = 2 gold_core_spawnable = NO_SPAWN speak_chance = 1 @@ -86,7 +86,7 @@ speed = 5 maxHealth = 75 health = 75 - weather_immunities = list("snow") + weather_immunities = list(TRAIT_SNOWSTORM_IMMUNE) color = rgb(114,228,250) loot = list(/obj/effect/decal/remains/human{color = rgb(114,228,250)}) diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 3cb9124f48..dd172bc8c7 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -56,6 +56,9 @@ var/minbodytemp = 250 var/maxbodytemp = 350 + /// List of weather immunity traits that are then added on Initialize(), see traits.dm. + var/list/weather_immunities + ///Healable by medical stacks? Defaults to yes. var/healable = 1 @@ -165,6 +168,8 @@ AddComponent(/datum/component/personal_crafting) if(footstep_type) AddComponent(/datum/component/footstep, footstep_type) + for(var/trait in weather_immunities) + ADD_TRAIT(src, trait, ROUNDSTART_TRAIT) /mob/living/simple_animal/Destroy() GLOB.simple_animals[AIStatus] -= src diff --git a/code/modules/uplink/uplink_items/uplink_clothing.dm b/code/modules/uplink/uplink_items/uplink_clothing.dm index 4f9f8a7b67..c559ef7542 100644 --- a/code/modules/uplink/uplink_items/uplink_clothing.dm +++ b/code/modules/uplink/uplink_items/uplink_clothing.dm @@ -85,7 +85,8 @@ /datum/uplink_item/suits/wallwalkers name = "Wall Walking Boots" - desc = "Through bluespace magic stolen from an organisation that hoards technology, these boots simply allow you to slip through the atoms that make up anything, but only while walking, for safety reasons. As well as this, they unfortunately cause minor breath loss as the majority of atoms in your lungs are sucked out into any solid object you walk through." + desc = "Through bluespace magic stolen from an organisation that hoards technology, these boots simply allow you to slip through the atoms that make up anything,but only while walking, \ + for safety reasons.As well as this, they unfortunately cause minor breath loss as the majority of atoms in your lungs are sucked out into any solid object you walk through." item = /obj/item/clothing/shoes/wallwalkers cost = 6 purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) diff --git a/html/changelogs/archive/2023-03.yml b/html/changelogs/archive/2023-03.yml index 403c168281..d26d6db736 100644 --- a/html/changelogs/archive/2023-03.yml +++ b/html/changelogs/archive/2023-03.yml @@ -15,6 +15,7 @@ - rscadd: Added mime messages for all SPLURT audio emotes - tweak: All SPLURT audio emotes now use length-based cooldowns - refactor: Refactored SPLURT audio emote code + - bugfix: Fixed Cargo protolathe access (MAILSORTING instead of CARGO) 2023-03-05: thux-tk: - rscadd: new arousal meter to humanoid mob's interface diff --git a/icons/mob/clothing/head.dmi b/icons/mob/clothing/head.dmi index 26a8b1808f..3216b816ed 100644 Binary files a/icons/mob/clothing/head.dmi and b/icons/mob/clothing/head.dmi differ diff --git a/icons/mob/clothing/head_muzzled.dmi b/icons/mob/clothing/head_muzzled.dmi index d3f05135c1..3a7506d96c 100644 Binary files a/icons/mob/clothing/head_muzzled.dmi and b/icons/mob/clothing/head_muzzled.dmi differ diff --git a/icons/mob/clothing/mask.dmi b/icons/mob/clothing/mask.dmi index 3c50e4d42d..be578ae1e4 100644 Binary files a/icons/mob/clothing/mask.dmi and b/icons/mob/clothing/mask.dmi differ diff --git a/icons/mob/clothing/mask_muzzled.dmi b/icons/mob/clothing/mask_muzzled.dmi index 5e0bb46c34..d755bd2818 100644 Binary files a/icons/mob/clothing/mask_muzzled.dmi and b/icons/mob/clothing/mask_muzzled.dmi differ diff --git a/icons/mob/clothing/suit.dmi b/icons/mob/clothing/suit.dmi index e4d932c860..db15a5ea40 100644 Binary files a/icons/mob/clothing/suit.dmi and b/icons/mob/clothing/suit.dmi differ diff --git a/icons/mob/clothing/suit_digi.dmi b/icons/mob/clothing/suit_digi.dmi index a7d419545c..200aabc390 100644 Binary files a/icons/mob/clothing/suit_digi.dmi and b/icons/mob/clothing/suit_digi.dmi differ diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi index 0831f7be2f..a981bc456d 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/clothing/masks.dmi b/icons/obj/clothing/masks.dmi index 70121cb9dc..315594cfb2 100644 Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index a5ae3dcf40..d9b8f39988 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/modular_sand/code/modules/mining/lavaland/necropolis_chests.dm b/modular_sand/code/modules/mining/lavaland/necropolis_chests.dm index 09d5b00d97..c96d95d358 100644 --- a/modular_sand/code/modules/mining/lavaland/necropolis_chests.dm +++ b/modular_sand/code/modules/mining/lavaland/necropolis_chests.dm @@ -666,43 +666,58 @@ name = "lava walking medal" desc = "A golden medal. Capable of making any jumpsuit completely lava proof for a brief window of time." icon_state = "gold" - actions_types = list(/datum/action/item_action/lavawalk) - var/cool_down = 0 - var/cooldown_time = 1200 //two full minutes - var/effectduration = 100 //10 seconds of lava walking - var/storedimmunities = list() + var/datum/action/cooldown/lavawalk/lavawalk + var/effectduration = 10 SECONDS + var/timer -/obj/item/clothing/accessory/lavawalk/on_uniform_equip(obj/item/clothing/under/U, user) +/obj/item/clothing/accessory/lavawalk/ComponentInitialize() . = ..() - var/mob/living/L = U.loc - if(L && istype(L)) - for(var/datum/action/A in actions_types) - A.Grant(L) + lavawalk = new(src) + RegisterSignal(lavawalk, COMSIG_ACTION_TRIGGER, .proc/activate) -/obj/item/clothing/accessory/lavawalk/on_uniform_dropped(obj/item/clothing/under/U, user) +/obj/item/clothing/accessory/lavawalk/Destroy() . = ..() - var/mob/living/L = U.loc - if(L && istype(L)) - for(var/datum/action/A in actions_types) - A.Remove(L) + var/mob/living/user = get_atom_on_turf(src, /mob/living) + if(user && timer) + reset_user(user) + UnregisterSignal(lavawalk, COMSIG_ACTION_TRIGGER) + QDEL_NULL(lavawalk) -/datum/action/item_action/lavawalk +/obj/item/clothing/accessory/lavawalk/on_uniform_equip(obj/item/clothing/under/U, mob/living/user) + . = ..() + if(istype(user)) + lavawalk.Grant(user) + +/obj/item/clothing/accessory/lavawalk/on_uniform_dropped(obj/item/clothing/under/U, mob/living/user) + . = ..() + if(istype(user)) + if(timer) + reset_user(user) + lavawalk.Remove(user) + +/datum/action/cooldown/lavawalk name = "Lava Walk" desc = "Become immune to lava for a brief period of time." + check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_CONSCIOUS + cooldown_time = 2 MINUTES //two full minutes + use_target_appearance = TRUE -/obj/item/clothing/accessory/lavawalk/ui_action_click(mob/user, actiontype) - if(istype(actiontype, /datum/action/item_action/lavawalk)) - if(world.time >= cool_down) - var/mob/living/L = user - if(istype(L)) - storedimmunities = L.weather_immunities.Copy() - L.weather_immunities |= list("ash", "lava") - cool_down = world.time + cooldown_time - addtimer(CALLBACK(src, .proc/reset_user, L), effectduration) +/obj/item/clothing/accessory/lavawalk/proc/activate(datum/action/cooldown/lavawalk/action, obj/item/clothing/accessory/lavawalk/item) + var/mob/living/L = usr + if(istype(L)) + to_chat(L, span_notice("\The [src] begins glowing!")) + L.balloon_alert(L, "activated") + ADD_TRAIT(L, TRAIT_ASHSTORM_IMMUNE, src) + ADD_TRAIT(L, TRAIT_LAVA_IMMUNE, src) + timer = addtimer(CALLBACK(src, .proc/reset_user, L), effectduration) + action.StartCooldown() /obj/item/clothing/accessory/lavawalk/proc/reset_user(mob/living/user) - user.weather_immunities = storedimmunities - storedimmunities = list() + REMOVE_TRAIT(user, TRAIT_ASHSTORM_IMMUNE, src) + REMOVE_TRAIT(user, TRAIT_LAVA_IMMUNE, src) + to_chat(user, span_boldwarning("\The [src]'s glow dims.")) + user.balloon_alert(user, "wore off") + QDEL_NULL(timer) //Nerfing those on the chest because too OP yada yada /obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor/damaged diff --git a/modular_sand/code/modules/research/machinery/departmental_protolathe.dm b/modular_sand/code/modules/research/machinery/departmental_protolathe.dm index 4904828374..53c3fb8dbd 100644 --- a/modular_sand/code/modules/research/machinery/departmental_protolathe.dm +++ b/modular_sand/code/modules/research/machinery/departmental_protolathe.dm @@ -8,7 +8,7 @@ req_access = list(ACCESS_MEDICAL) /obj/machinery/rnd/production/protolathe/department/cargo - req_access = list(ACCESS_CARGO) + req_one_access = list(ACCESS_CARGO, ACCESS_MINING) /obj/machinery/rnd/production/protolathe/department/science req_access = list(ACCESS_RESEARCH) diff --git a/modular_sand/code/modules/research/machinery/departmental_techfab.dm b/modular_sand/code/modules/research/machinery/departmental_techfab.dm index 7f9601ab3a..dc5d7d80c8 100644 --- a/modular_sand/code/modules/research/machinery/departmental_techfab.dm +++ b/modular_sand/code/modules/research/machinery/departmental_techfab.dm @@ -8,7 +8,7 @@ req_access = list(ACCESS_MEDICAL) /obj/machinery/rnd/production/techfab/department/cargo - req_access = list(ACCESS_CARGO) + req_one_access = list(ACCESS_CARGO, ACCESS_MINING) /obj/machinery/rnd/production/techfab/department/science req_access = list(ACCESS_RESEARCH) diff --git a/tgstation.dme b/tgstation.dme index e28569d6da..9beb8183ed 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -856,7 +856,6 @@ #include "code\datums\traits\negative.dm" #include "code\datums\traits\neutral.dm" #include "code\datums\weather\weather.dm" -#include "code\datums\weather\weather_types\acid_rain.dm" #include "code\datums\weather\weather_types\ash_storm.dm" #include "code\datums\weather\weather_types\floor_is_lava.dm" #include "code\datums\weather\weather_types\ice_storm.dm" diff --git a/tgui/packages/tgui/interfaces/ApcControl.js b/tgui/packages/tgui/interfaces/ApcControl.js index 41f3818477..0005476d4a 100644 --- a/tgui/packages/tgui/interfaces/ApcControl.js +++ b/tgui/packages/tgui/interfaces/ApcControl.js @@ -2,23 +2,18 @@ import { map, sortBy } from 'common/collections'; import { flow } from 'common/fp'; import { pureComponentHooks } from 'common/react'; import { useBackend, useLocalState } from '../backend'; -import { Box, Button, Dimmer, Flex, Icon, Table, Tabs } from '../components'; +import { Box, Button, Dimmer, Icon, Table, Tabs, Stack, Section } from '../components'; import { Window } from '../layouts'; import { AreaCharge, powerRank } from './PowerMonitor'; export const ApcControl = (props, context) => { const { data } = useBackend(context); return ( - - {data.authenticated === 1 && ( - - )} - {data.authenticated === 0 && ( - - )} + + + {data.authenticated === 1 && } + {data.authenticated === 0 && } + ); }; @@ -28,25 +23,24 @@ const ApcLoggedOut = (props, context) => { const { emagged } = data; const text = emagged === 1 ? 'Open' : 'Log In'; return ( - +
); }; const ApcLoggedIn = (props, context) => { const { act, data } = useBackend(context); const { restoring } = data; - const [ - tabIndex, - setTabIndex, - ] = useLocalState(context, 'tab-index', 1); + const [tabIndex, setTabIndex] = useLocalState(context, 'tab-index', 1); return ( - <> + { )} {tabIndex === 1 && ( - <> - - - + + +
+ +
+
+ +
- - - +
+
+
)} {tabIndex === 2 && ( - - +
+ - - + +
)} - +
); }; const ControlPanel = (props, context) => { const { act, data } = useBackend(context); - const { - emagged, - logging, - } = data; - const [ - sortByField, - setSortByField, - ] = useLocalState(context, 'sortByField', null); + const { emagged, logging } = data; + const [sortByField, setSortByField] = useLocalState( + context, + 'sortByField', + 'name' + ); return ( - - + + Sort by: setSortByField(sortByField !== 'name' && 'name')} /> + onClick={() => setSortByField(sortByField !== 'name' && 'name')} + /> setSortByField( - sortByField !== 'charge' && 'charge' - )} /> + onClick={() => setSortByField(sortByField !== 'charge' && 'charge')} + /> setSortByField(sortByField !== 'draw' && 'draw')} /> - - - + onClick={() => setSortByField(sortByField !== 'draw' && 'draw')} + /> + + + {emagged === 1 && ( <>