diff --git a/code/datums/spells/ethereal_jaunt.dm b/code/datums/spells/ethereal_jaunt.dm index 4b916bfc639..fc8ac705369 100644 --- a/code/datums/spells/ethereal_jaunt.dm +++ b/code/datums/spells/ethereal_jaunt.dm @@ -35,6 +35,7 @@ animation.icon_state = "liquify" animation.layer = 5 animation.master = holder + target.ExtinguishMob() if(target.buckled) target.buckled.unbuckle() if(phaseshift == 1) diff --git a/code/game/dna/genes/goon_disabilities.dm b/code/game/dna/genes/goon_disabilities.dm index d410a29e35c..3e355212d0e 100644 --- a/code/game/dna/genes/goon_disabilities.dm +++ b/code/game/dna/genes/goon_disabilities.dm @@ -338,7 +338,9 @@ usr.attack_log += text("\[[time_stamp()]\] [usr.real_name] ([usr.ckey]) cast the spell [name] on [L.real_name] ([L.ckey]).") msg_admin_attack("[usr.real_name] ([usr.ckey])[isAntag(usr) ? "(ANTAG)" : ""] has cast the spell [name] on [L.real_name] ([L.ckey]) (JMP)") - L.visible_message("\red [L.name] suddenly bursts into flames!") //uh yeah will have to fix this later it does nothing right now + L.adjust_fire_stacks(0.5) + L.visible_message("\red [L.name] suddenly bursts into flames!") + L.on_fire = 1 L.update_icon = 1 playsound(L.loc, 'sound/effects/bamf.ogg', 50, 0) diff --git a/code/game/dna/genes/goon_powers.dm b/code/game/dna/genes/goon_powers.dm index 5f74bc16251..a98313eefdb 100644 --- a/code/game/dna/genes/goon_powers.dm +++ b/code/game/dna/genes/goon_powers.dm @@ -175,6 +175,7 @@ if(!handle_suit) C.bodytemperature = max(0, C.bodytemperature - 100) C.adjustFireLoss(10) + C.ExtinguishMob() C.visible_message("\red [usr] sprays a cloud of fine ice crystals, engulfing [C]!") log_admin("[ckey(usr.key)] has used cryokinesis on [ckey(C.key)], internals no, suit no") @@ -533,6 +534,11 @@ "their hair","what to do next","their job","space","amusing things","sad things", "annoying things","happy things","something incoherent","something they did wrong") var/thoughts = "thinking about [pick(randomthoughts)]" + + if(M.fire_stacks) + pain_condition -= 50 + thoughts = "preoccupied with the fire" + if (M.radiation) pain_condition -= 25 diff --git a/code/game/gamemodes/vampire/vampire.dm b/code/game/gamemodes/vampire/vampire.dm index 7bfbc4abd5e..ec971e84e59 100644 --- a/code/game/gamemodes/vampire/vampire.dm +++ b/code/game/gamemodes/vampire/vampire.dm @@ -490,8 +490,17 @@ mob/living/carbon/human/proc/vamp_burn() if(60 to 80) src << "Your skin sizzles!" if((-INFINITY) to 60) - src << "\red You continue to burn!" + if(!on_fire) + src << "\red Your skin catches fire!" + else + src << "\red You continue to burn!" + fire_stacks += 5 + IgniteMob() emote("scream") - + else + switch(health) + if((-INFINITY) to 60) + fire_stacks++ + IgniteMob() adjustFireLoss(3) return diff --git a/code/game/gamemodes/vampire/vampire_powers.dm b/code/game/gamemodes/vampire/vampire_powers.dm index 8ec9271525e..3ec453f56d7 100644 --- a/code/game/gamemodes/vampire/vampire_powers.dm +++ b/code/game/gamemodes/vampire/vampire_powers.dm @@ -377,6 +377,7 @@ animation.icon_state = "liquify" animation.layer = 5 animation.master = holder + M.current.ExtinguishMob() if(M.current.buckled) M.current.buckled.unbuckle() flick("liquify",animation) @@ -450,6 +451,7 @@ if(!picked || !isturf(picked)) return + M.current.ExtinguishMob() if(M.current.buckled) M.current.buckled.unbuckle() var/atom/movable/overlay/animation = new /atom/movable/overlay( get_turf(usr) ) diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index 2151becf251..cb00c9cacc0 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -441,6 +441,7 @@ // M.metabslow = 1 add_fingerprint(usr) update_icon() + M.ExtinguishMob() return 1 /obj/machinery/atmospherics/unary/cryo_cell/verb/move_eject() diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm index d3474b07912..c2c01afd5cb 100644 --- a/code/game/objects/items/devices/flash.dm +++ b/code/game/objects/items/devices/flash.dm @@ -96,6 +96,10 @@ if(iscarbon(M)) flash_carbon(M, user, 5, 1) + if(overcharged) + M.adjust_fire_stacks(6) + M.IgniteMob() + burn_out() return 1 else if(issilicon(M)) diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm index bb593e3ff3f..27e3b00b489 100644 --- a/code/game/objects/items/weapons/cigs_lighters.dm +++ b/code/game/objects/items/weapons/cigs_lighters.dm @@ -163,6 +163,9 @@ CIGARETTE PACKETS ARE IN FANCY.DM /obj/item/clothing/mask/cigarette/process() var/turf/location = get_turf(src) + var/mob/living/M = loc + if(isliving(loc)) + M.IgniteMob() smoketime-- if(smoketime < 1) die() @@ -449,7 +452,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM /obj/item/weapon/lighter/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob) if(!isliving(M)) return -// M.IgniteMob() //linda shit do later + M.IgniteMob() if(!istype(M, /mob)) return diff --git a/code/game/objects/items/weapons/extinguisher.dm b/code/game/objects/items/weapons/extinguisher.dm index 422fad23ce4..902ce1e052a 100644 --- a/code/game/objects/items/weapons/extinguisher.dm +++ b/code/game/objects/items/weapons/extinguisher.dm @@ -157,6 +157,9 @@ for(var/atom/atm in get_turf(W)) if(!W) return W.reagents.reaction(atm) + if(isliving(atm)) //For extinguishing mobs on fire + var/mob/living/M = atm + M.ExtinguishMob() if(W.loc == my_target) break sleep(2) diff --git a/code/game/objects/items/weapons/tanks/watertank.dm b/code/game/objects/items/weapons/tanks/watertank.dm index 33e9bf829a8..afaebdc4fe4 100644 --- a/code/game/objects/items/weapons/tanks/watertank.dm +++ b/code/game/objects/items/weapons/tanks/watertank.dm @@ -373,6 +373,8 @@ V.welded = 1 V.update_icon() V.visible_message("[V] was frozen shut!") + for(var/mob/living/L in T) + L.ExtinguishMob() return /datum/effect/effect/system/freezing_smoke_spread diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index 399b6f47b81..5f4cfbe49c9 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -267,7 +267,9 @@ var/turf/location = get_turf(user) if (istype(location, /turf)) location.hotspot_expose(700, 50, 1) - + if(isliving(O)) + var/mob/living/L = O + L.IgniteMob() return diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index f40c2020eb1..2fdd133801b 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -205,76 +205,80 @@ /obj/machinery/shower/proc/wash(atom/movable/O as obj|mob) if(!on) return - if(iscarbon(O)) - var/mob/living/carbon/M = O - M << "You've been drenched in water!" - if(M.r_hand) - M.r_hand.clean_blood() - if(M.l_hand) - M.l_hand.clean_blood() - if(M.back) - if(M.back.clean_blood()) - M.update_inv_back(0) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - var/washgloves = 1 - var/washshoes = 1 - var/washmask = 1 - var/washears = 1 - var/washglasses = 1 + if(isliving(O)) + var/mob/living/L = O + L.ExtinguishMob() + L.fire_stacks = -20 //Douse ourselves with water to avoid fire more easily + L << "You've been drenched in water!" + if(iscarbon(O)) + var/mob/living/carbon/M = O + if(M.r_hand) + M.r_hand.clean_blood() + if(M.l_hand) + M.l_hand.clean_blood() + if(M.back) + if(M.back.clean_blood()) + M.update_inv_back(0) + if(ishuman(M)) + var/mob/living/carbon/human/H = M + var/washgloves = 1 + var/washshoes = 1 + var/washmask = 1 + var/washears = 1 + var/washglasses = 1 - if(H.wear_suit) - washgloves = !(H.wear_suit.flags_inv & HIDEGLOVES) - washshoes = !(H.wear_suit.flags_inv & HIDESHOES) + if(H.wear_suit) + washgloves = !(H.wear_suit.flags_inv & HIDEGLOVES) + washshoes = !(H.wear_suit.flags_inv & HIDESHOES) - if(H.head) - washmask = !(H.head.flags_inv & HIDEMASK) - washglasses = !(H.head.flags_inv & HIDEEYES) - washears = !(H.head.flags_inv & HIDEEARS) + if(H.head) + washmask = !(H.head.flags_inv & HIDEMASK) + washglasses = !(H.head.flags_inv & HIDEEYES) + washears = !(H.head.flags_inv & HIDEEARS) - if(H.wear_mask) - if (washears) - washears = !(H.wear_mask.flags_inv & HIDEEARS) - if (washglasses) - washglasses = !(H.wear_mask.flags_inv & HIDEEYES) + if(H.wear_mask) + if (washears) + washears = !(H.wear_mask.flags_inv & HIDEEARS) + if (washglasses) + washglasses = !(H.wear_mask.flags_inv & HIDEEYES) + + if(H.head) + if(H.head.clean_blood()) + H.update_inv_head(0,0) + if(H.wear_suit) + if(H.wear_suit.clean_blood()) + H.update_inv_wear_suit(0,0) + else if(H.w_uniform) + if(H.w_uniform.clean_blood()) + H.update_inv_w_uniform(0,0) + if(H.gloves && washgloves) + if(H.gloves.clean_blood()) + H.update_inv_gloves(0,0) + if(H.shoes && washshoes) + if(H.shoes.clean_blood()) + H.update_inv_shoes(0,0) + if(H.wear_mask && washmask) + if(H.wear_mask.clean_blood()) + H.update_inv_wear_mask(0) + if(H.glasses && washglasses) + if(H.glasses.clean_blood()) + H.update_inv_glasses(0) + if(H.l_ear && washears) + if(H.l_ear.clean_blood()) + H.update_inv_ears(0) + if(H.r_ear && washears) + if(H.r_ear.clean_blood()) + H.update_inv_ears(0) + if(H.belt) + if(H.belt.clean_blood()) + H.update_inv_belt(0) + else + if(M.wear_mask) //if the mob is not human, it cleans the mask without asking for bitflags + if(M.wear_mask.clean_blood()) + M.update_inv_wear_mask(0) - if(H.head) - if(H.head.clean_blood()) - H.update_inv_head(0,0) - if(H.wear_suit) - if(H.wear_suit.clean_blood()) - H.update_inv_wear_suit(0,0) - else if(H.w_uniform) - if(H.w_uniform.clean_blood()) - H.update_inv_w_uniform(0,0) - if(H.gloves && washgloves) - if(H.gloves.clean_blood()) - H.update_inv_gloves(0,0) - if(H.shoes && washshoes) - if(H.shoes.clean_blood()) - H.update_inv_shoes(0,0) - if(H.wear_mask && washmask) - if(H.wear_mask.clean_blood()) - H.update_inv_wear_mask(0) - if(H.glasses && washglasses) - if(H.glasses.clean_blood()) - H.update_inv_glasses(0) - if(H.l_ear && washears) - if(H.l_ear.clean_blood()) - H.update_inv_ears(0) - if(H.r_ear && washears) - if(H.r_ear.clean_blood()) - H.update_inv_ears(0) - if(H.belt) - if(H.belt.clean_blood()) - H.update_inv_belt(0) else - if(M.wear_mask) //if the mob is not human, it cleans the mask without asking for bitflags - if(M.wear_mask.clean_blood()) - M.update_inv_wear_mask(0) - - else - O.clean_blood() + O.clean_blood() if(isturf(loc)) var/turf/tile = loc diff --git a/code/modules/clothing/spacesuits/chronosuit.dm b/code/modules/clothing/spacesuits/chronosuit.dm index 0df8eeb9a54..4d6035ba2fe 100644 --- a/code/modules/clothing/spacesuits/chronosuit.dm +++ b/code/modules/clothing/spacesuits/chronosuit.dm @@ -82,6 +82,7 @@ phaseanim.density = 1 phaseanim.layer = FLY_LAYER phaseanim.master = user + user.ExtinguishMob() if(user.buckled) user.buckled.unbuckle() user.loc = holder diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm index 51f9d6a295a..49972acd934 100644 --- a/code/modules/clothing/spacesuits/plasmamen.dm +++ b/code/modules/clothing/spacesuits/plasmamen.dm @@ -16,6 +16,25 @@ icon_state = "plasmaman_suit" item_state = "plasmaman_suit" + var/next_extinguish=0 + var/extinguish_cooldown=10 SECONDS + var/extinguishes_left=10 // Yeah yeah, reagents, blah blah blah. This should be simple. + +/obj/item/clothing/suit/space/eva/plasmaman/examine(mob/user) + ..() + user << "There are [extinguishes_left] extinguisher canisters left in this suit." + +/obj/item/clothing/suit/space/eva/plasmaman/proc/Extinguish(var/mob/user) + var/mob/living/carbon/human/H=user + if(extinguishes_left) + if(next_extinguish > world.time) + return + + next_extinguish = world.time + extinguish_cooldown + extinguishes_left-- + H << "Your suit automatically extinguishes the fire." + H.ExtinguishMob() + /obj/item/clothing/head/helmet/space/eva/plasmaman name = "plasmaman helmet" desc = "A special containment helmet designed to protect a plasmaman's volatile body from outside exposure and quickly extinguish it in emergencies." diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index 690bfb31422..6e5dcdc3dea 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -87,13 +87,14 @@ // Aliens are now weak to fire. //After then, it reacts to the surrounding atmosphere based on your thermal protection - if(loc_temp > bodytemperature) - //Place is hotter than we are - var/thermal_protection = heat_protection //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to. - if(thermal_protection < 1) - bodytemperature += (1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR) - else - bodytemperature += 1 * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR) + if(!on_fire) // If you're on fire, ignore local air temperature + if(loc_temp > bodytemperature) + //Place is hotter than we are + var/thermal_protection = heat_protection //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to. + if(thermal_protection < 1) + bodytemperature += (1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR) + else + bodytemperature += 1 * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR) // bodytemperature -= max((loc_temp - bodytemperature / BODYTEMP_AUTORECOVERY_DIVISOR), BODYTEMP_AUTORECOVERY_MINIMUM) // +/- 50 degrees from 310.15K is the 'safe' zone, where no damage is dealt. @@ -104,12 +105,16 @@ if(360 to 400) apply_damage(HEAT_DAMAGE_LEVEL_1, BURN) fire_alert = max(fire_alert, 2) - if(400 to 1000) + if(400 to 460) apply_damage(HEAT_DAMAGE_LEVEL_2, BURN) fire_alert = max(fire_alert, 2) - if(1000 to INFINITY) - apply_damage(HEAT_DAMAGE_LEVEL_3, BURN) - fire_alert = max(fire_alert, 2) + if(460 to INFINITY) + if(on_fire) + apply_damage(HEAT_DAMAGE_LEVEL_3, BURN) + fire_alert = max(fire_alert, 2) + else + apply_damage(HEAT_DAMAGE_LEVEL_2, BURN) + fire_alert = max(fire_alert, 2) return /mob/living/carbon/alien/proc/handle_mutations_and_radiation() @@ -141,6 +146,13 @@ radiation -= 3 adjustToxLoss(3) +/mob/living/carbon/alien/handle_fire()//Aliens on fire code + if(..()) + return + bodytemperature += BODYTEMP_HEATING_MAX //If you're on fire, you heat up! + return + + /mob/living/carbon/alien/IsAdvancedToolUser() return has_fine_manipulation diff --git a/code/modules/mob/living/carbon/alien/humanoid/life.dm b/code/modules/mob/living/carbon/alien/humanoid/life.dm index 17313ef0467..fbb2e477081 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/life.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/life.dm @@ -50,6 +50,9 @@ //stuff in the stomach handle_stomach() + //Handle being on fire + handle_fire() + //Status updates, death etc. handle_regular_status_updates() update_canmove() diff --git a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm index 6601f0174d7..0c218c81204 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm @@ -62,6 +62,7 @@ update_inv_pockets(0) update_hud() update_icons() + update_fire() @@ -72,6 +73,21 @@ // else client.screen -= hud_used.other //Not used client.screen |= contents +/mob/living/carbon/alien/humanoid/update_fire() + overlays -= overlays_lying[X_FIRE_LAYER] + overlays -= overlays_standing[X_FIRE_LAYER] + if(on_fire) + overlays_lying[X_FIRE_LAYER] = image("icon"='icons/mob/OnFire.dmi', "icon_state"="Lying", "layer"= -X_FIRE_LAYER) + overlays_standing[X_FIRE_LAYER] = image("icon"='icons/mob/OnFire.dmi', "icon_state"="Standing", "layer"= -X_FIRE_LAYER) + if(src.lying) + overlays += overlays_lying[X_FIRE_LAYER] + else + overlays += overlays_standing[X_FIRE_LAYER] + return + else + overlays_lying[X_FIRE_LAYER] = null + overlays_standing[X_FIRE_LAYER] = null + /mob/living/carbon/alien/humanoid/update_inv_wear_suit(var/update_icons=1) if(wear_suit) var/t_state = wear_suit.item_state diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index a55ff794b41..33b15cd4d4f 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -442,6 +442,7 @@ mob/living /mob/living/carbon/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) ..() + src.IgniteMob() bodytemperature = max(bodytemperature, BODYTEMP_HEAT_DAMAGE_LIMIT+10) /mob/living/carbon/can_use_hands() diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index af6ffd0014f..fac498d9219 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -226,6 +226,11 @@ usr << "[t_He] has a pulse!" msg += "" + if(fire_stacks > 0) + msg += "[t_He] [t_is] covered in something flammable.\n" + if(fire_stacks < 0) + msg += "[t_He] looks a little soaked.\n" + if(nutrition < 100) msg += "[t_He] [t_is] severely malnourished.\n" else if(nutrition >= 500) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 09305ec2669..f8aa4a64ac9 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -80,4 +80,7 @@ var/lastFart = 0 // Toxic fart cooldown. - var/frozen = 0 //used for preventing attacks on admin-frozen people \ No newline at end of file + var/frozen = 0 //used for preventing attacks on admin-frozen people + + var/fire_dmi = 'icons/mob/OnFire.dmi' + var/fire_sprite = "Standing" \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 74904134bb2..4aa5c923a46 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -105,6 +105,9 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc handle_virus_updates() + //Check if we're on fire + handle_fire() + //stuff in the stomach handle_stomach() @@ -379,6 +382,17 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc handle_breath(breath) + if(species.name=="Plasmaman") //this is stupid as fuck + // Check if we're wearing our biosuit and mask. + if (!istype(wear_suit,/obj/item/clothing/suit/space/eva/plasmaman) || !istype(head,/obj/item/clothing/head/helmet/space/eva/plasmaman)) + //testing("Plasmaman [src] leakin'. coverflags=[cover_flags]") + // OH FUCK HE LEAKIN'. + // This was OP. + //environment.adjust(tx = environment.total_moles()*BREATH_PERCENTAGE) // About one breath's worth. (I know we aren't breathing it out, but this should be about the right amount) + src << "Your body reacts with the atmosphere and bursts into flame!" + adjust_fire_stacks(0.5) + IgniteMob() + if(breath) loc.assume_air(breath) @@ -436,16 +450,17 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc stabilize_temperature_from_calories() //After then, it reacts to the surrounding atmosphere based on your thermal protection - if(loc_temp < bodytemperature) - //Place is colder than we are - var/thermal_protection = get_cold_protection(loc_temp) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to. - if(thermal_protection < 1) - bodytemperature += min((1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_COLD_DIVISOR), BODYTEMP_COOLING_MAX) - else - //Place is hotter than we are - var/thermal_protection = get_heat_protection(loc_temp) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to. - if(thermal_protection < 1) - bodytemperature += min((1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR), BODYTEMP_HEATING_MAX) + if(!on_fire) //If you're on fire, you do not heat up or cool down based on surrounding gases + if(loc_temp < bodytemperature) + //Place is colder than we are + var/thermal_protection = get_cold_protection(loc_temp) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to. + if(thermal_protection < 1) + bodytemperature += min((1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_COLD_DIVISOR), BODYTEMP_COOLING_MAX) + else + //Place is hotter than we are + var/thermal_protection = get_heat_protection(loc_temp) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to. + if(thermal_protection < 1) + bodytemperature += min((1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR), BODYTEMP_HEATING_MAX) // +/- 50 degrees from 310.15K is the 'safe' zone, where no damage is dealt. if(bodytemperature > species.heat_level_1) @@ -460,8 +475,12 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc take_overall_damage(burn=HEAT_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature") fire_alert = max(fire_alert, 2) if(bodytemperature > species.heat_level_3 && bodytemperature < INFINITY) - take_overall_damage(burn=HEAT_DAMAGE_LEVEL_3, used_weapon = "Fire") - fire_alert = max(fire_alert, 2) + if(on_fire) + take_overall_damage(burn=HEAT_DAMAGE_LEVEL_3, used_weapon = "Fire") + fire_alert = max(fire_alert, 2) + else + take_overall_damage(burn=HEAT_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature") + fire_alert = max(fire_alert, 2) else if(bodytemperature < species.cold_level_1) fire_alert = max(fire_alert, 1) @@ -506,6 +525,29 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc return + ///FIRE CODE + handle_fire() + if(..()) + return + var/thermal_protection = 0 //Simple check to estimate how protected we are against multiple temperatures + if(wear_suit) + if(wear_suit.max_heat_protection_temperature >= FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE) + thermal_protection += (wear_suit.max_heat_protection_temperature*0.7) + if(head) + if(head.max_heat_protection_temperature >= FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE) + thermal_protection += (head.max_heat_protection_temperature*THERMAL_PROTECTION_HEAD) + thermal_protection = round(thermal_protection) + if(thermal_protection >= FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT) + return + if(thermal_protection >= FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE) + bodytemperature += 11 + return + else + bodytemperature += BODYTEMP_HEATING_MAX + return + //END FIRE CODE + + /* proc/adjust_body_temperature(current, loc_temp, boost) var/temperature = current diff --git a/code/modules/mob/living/carbon/human/species/plasmaman.dm b/code/modules/mob/living/carbon/human/species/plasmaman.dm index 1cd8f6a800b..aee4d5660f0 100644 --- a/code/modules/mob/living/carbon/human/species/plasmaman.dm +++ b/code/modules/mob/living/carbon/human/species/plasmaman.dm @@ -21,6 +21,8 @@ return message /datum/species/plasmaman/equip(var/mob/living/carbon/human/H) + H.fire_sprite = "Plasmaman" + // Unequip existing suits and hats. H.unEquip(H.wear_suit) H.unEquip(H.head) diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index fbebd13989b..3621f44c8e6 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -459,6 +459,13 @@ proc/get_damage_icon_part(damage_state, body_part) overlays_standing[TARGETED_LAYER] = null if(update_icons) update_icons() +/mob/living/carbon/human/update_fire() + remove_overlay(FIRE_LAYER) + if(on_fire) + overlays_standing[FIRE_LAYER] = image("icon"=fire_dmi, "icon_state"=fire_sprite, "layer"=-FIRE_LAYER) + else + overlays_standing[FIRE_LAYER] = null + apply_overlay(FIRE_LAYER) /* --------------------------------------- */ //For legacy support. @@ -489,6 +496,7 @@ proc/get_damage_icon_part(damage_state, body_part) update_icons() //Hud Stuff update_hud() + update_fire() /* --------------------------------------- */ //vvvvvv UPDATE_INV PROCS vvvvvv diff --git a/code/modules/mob/living/carbon/monkey/examine.dm b/code/modules/mob/living/carbon/monkey/examine.dm index 869482b13f4..5cbb5c6c7ce 100644 --- a/code/modules/mob/living/carbon/monkey/examine.dm +++ b/code/modules/mob/living/carbon/monkey/examine.dm @@ -32,6 +32,10 @@ msg += "It has minor burns.\n" else msg += "It has severe burns!\n" + if (src.fire_stacks > 0) + msg += "It's covered in something flammable.\n" + if (src.fire_stacks < 0) + msg += "It's soaked in water.\n" if (src.stat == UNCONSCIOUS) msg += "It isn't responding to anything around it; it seems to be asleep.\n" msg += "" diff --git a/code/modules/mob/living/carbon/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm index 667397ef0ef..b3f49765312 100644 --- a/code/modules/mob/living/carbon/monkey/life.dm +++ b/code/modules/mob/living/carbon/monkey/life.dm @@ -59,6 +59,9 @@ if(environment) // More error checking -- TLE handle_environment(environment) + //Check if we're on fire + handle_fire() + //Status updates, death etc. handle_regular_status_updates() update_canmove() @@ -385,10 +388,11 @@ var/turf/heat_turf = get_turf(src) environment_heat_capacity = heat_turf.heat_capacity - if((environment.temperature > (T0C + 50)) || (environment.temperature < (T0C + 10))) - var/transfer_coefficient = 1 + if(!on_fire) + if((environment.temperature > (T0C + 50)) || (environment.temperature < (T0C + 10))) + var/transfer_coefficient = 1 - handle_temperature_damage(HEAD, environment.temperature, environment_heat_capacity*transfer_coefficient) + handle_temperature_damage(HEAD, environment.temperature, environment_heat_capacity*transfer_coefficient) if(stat==2) bodytemperature += 0.1*(environment.temperature - bodytemperature)*environment_heat_capacity/(environment_heat_capacity + 270000) @@ -648,4 +652,12 @@ proc/handle_changeling() if(mind && mind.changeling) - mind.changeling.regenerate() \ No newline at end of file + mind.changeling.regenerate() + + ///FIRE CODE + handle_fire() + if(..()) + return + adjustFireLoss(6) + return + //END FIRE CODE \ No newline at end of file diff --git a/code/modules/mob/living/carbon/monkey/update_icons.dm b/code/modules/mob/living/carbon/monkey/update_icons.dm index 7a2fc194b87..7c268632876 100644 --- a/code/modules/mob/living/carbon/monkey/update_icons.dm +++ b/code/modules/mob/living/carbon/monkey/update_icons.dm @@ -20,6 +20,7 @@ update_inv_r_hand(0) update_inv_l_hand(0) update_inv_handcuffed(0) + update_fire() update_icons() //Hud Stuff update_hud() @@ -112,6 +113,15 @@ overlays_standing[TARGETED_LAYER] = null if(update_icons) update_icons() +/mob/living/carbon/monkey/update_fire() + overlays -= overlays_standing[M_FIRE_LAYER] + if(on_fire) + overlays_standing[M_FIRE_LAYER] = image("icon"='icons/mob/OnFire.dmi', "icon_state"="Standing", "layer"= -M_FIRE_LAYER) + overlays += overlays_standing[M_FIRE_LAYER] + return + else + overlays_standing[M_FIRE_LAYER] = null + //Monkey Overlays Indexes//////// #undef M_MASK_LAYER #undef M_BACK_LAYER diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 4757acd684f..b1900ffa39b 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -328,6 +328,8 @@ ear_deaf = 0 ear_damage = 0 heal_overall_damage(1000, 1000) + fire_stacks = 0 + on_fire = 0 suiciding = 0 buckled = initial(src.buckled) @@ -350,6 +352,7 @@ timeofdeath = 0 stat = CONSCIOUS + update_fire() regenerate_icons() hud_updateflag |= 1 << HEALTH_HUD hud_updateflag |= 1 << STATUS_HUD @@ -541,7 +544,6 @@ for(var/mob/O in viewers(usr, null)) O.show_message(text("\red [] resists!", L), 1) - //unbuckling yourself if(L.buckled && (L.last_special <= world.time) ) if(iscarbon(L)) @@ -635,6 +637,21 @@ //breaking out of handcuffs else if(iscarbon(L)) var/mob/living/carbon/CM = L + + if(CM.on_fire && CM.canmove) + CM.fire_stacks -= 5 + CM.weakened = max(CM.weakened, 3)//We dont check for CANWEAKEN, I don't care how immune to weakening you are, if you're rolling on the ground, you're busy. + CM.update_canmove() + CM.spin(32,2) + CM.visible_message("[CM] rolls on the floor, trying to put themselves out!", \ + "You stop, drop, and roll!") + sleep(30) + if(fire_stacks <= 0) + CM.visible_message("[CM] has successfully extinguished themselves!", \ + "You extinguish yourself.") + ExtinguishMob() + return + if(CM.handcuffed && CM.canmove && (CM.last_special <= world.time)) CM.changeNext_move(CLICK_CD_BREAKOUT) CM.last_special = world.time + CLICK_CD_BREAKOUT diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index dfbba53e86c..b61d58223c6 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -199,6 +199,45 @@ return +//Mobs on Fire +/mob/living/proc/IgniteMob() + if(fire_stacks > 0 && !on_fire) + on_fire = 1 + src.AddLuminosity(3) + update_fire() + +/mob/living/proc/ExtinguishMob() + if(on_fire) + on_fire = 0 + fire_stacks = 0 + src.AddLuminosity(-3) + update_fire() + +/mob/living/proc/update_fire() + return + +/mob/living/proc/adjust_fire_stacks(add_fire_stacks) //Adjusting the amount of fire_stacks we have on person + fire_stacks = Clamp(fire_stacks + add_fire_stacks, min = -20, max = 20) + +/mob/living/proc/handle_fire() + if(fire_stacks < 0) + fire_stacks++ //If we've doused ourselves in water to avoid fire, dry off slowly + fire_stacks = min(0, fire_stacks)//So we dry ourselves back to default, nonflammable. + if(!on_fire) + return 1 + var/datum/gas_mixture/G = loc.return_air() // Check if we're standing in an oxygenless environment + if(G.oxygen < 1) + ExtinguishMob() //If there's no oxygen in the tile we're on, put out the fire + return + var/turf/location = get_turf(src) + location.hotspot_expose(700, 50, 1) + +/mob/living/fire_act() + adjust_fire_stacks(0.5) + IgniteMob() + +//Mobs on Fire end + //This is called when the mob is thrown into a dense turf /mob/living/proc/turf_collision(var/turf/T, var/speed) src.take_organ_damage(speed*5) diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 5cfe75a02fc..1a683b9e183 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -36,6 +36,10 @@ var/cameraFollow = null var/tod = null // Time of death + + var/on_fire = 0 //The "Are we on fire?" var + var/fire_stacks = 0 //Tracks how many stacks of fire we have on, max is usually 20 + var/update_slimes = 1 var/specialsauce = 0 //Has this person consumed enough special sauce? IF so they're a ticking time bomb of death. var/implanting = 0 //Used for the mind-slave implant diff --git a/code/modules/mob/living/silicon/robot/death.dm b/code/modules/mob/living/silicon/robot/death.dm index c10269fc590..fef353eec6d 100644 --- a/code/modules/mob/living/silicon/robot/death.dm +++ b/code/modules/mob/living/silicon/robot/death.dm @@ -61,6 +61,7 @@ see_in_dark = 8 see_invisible = SEE_INVISIBLE_LEVEL_TWO updateicon() + update_fire() tod = worldtime2text() //weasellos time of death patch if(mind) mind.store_memory("Time of death: [tod]", 0) diff --git a/code/modules/mob/living/silicon/robot/examine.dm b/code/modules/mob/living/silicon/robot/examine.dm index 596e2ff23c2..94ca8afded2 100644 --- a/code/modules/mob/living/silicon/robot/examine.dm +++ b/code/modules/mob/living/silicon/robot/examine.dm @@ -21,6 +21,10 @@ msg += "It looks slightly charred.\n" else msg += "It looks severely burnt and heat-warped!\n" + if (src.fire_stacks < 0) + msg += "It's covered in water.\n" + if (src.fire_stacks > 0) + msg += "It's coated in something flammable.\n" msg += "" if(opened) diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm index eb47636ca95..976708e4e1d 100644 --- a/code/modules/mob/living/silicon/robot/life.dm +++ b/code/modules/mob/living/silicon/robot/life.dm @@ -22,6 +22,7 @@ update_gravity(mob_has_gravity()) + handle_fire() /mob/living/silicon/robot/proc/clamp_values() @@ -340,3 +341,29 @@ if(paralysis || stunned || weakened || buckled || lockcharge) canmove = 0 else canmove = 1 return canmove + +//Robots on fire +/mob/living/silicon/robot/handle_fire() + if(..()) + return + if(fire_stacks > 0) + fire_stacks-- + fire_stacks = max(0, fire_stacks) + else + ExtinguishMob() + + //adjustFireLoss(3) + return + +/mob/living/silicon/robot/update_fire() + overlays -= image("icon"='icons/mob/OnFire.dmi', "icon_state"="Standing") + if(on_fire) + overlays += image("icon"='icons/mob/OnFire.dmi', "icon_state"="Standing") + update_icons() + return + +/mob/living/silicon/robot/fire_act() + if(!on_fire) //Silicons don't gain stacks from hotspots, but hotspots can ignite them + IgniteMob() + +//Robots on fire \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 23b0407aec7..76c8c4733d7 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -510,6 +510,9 @@ return 0 return 1 +/mob/living/simple_animal/update_fire() + return + /mob/living/simple_animal/revive() ..() health = maxHealth diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index f93959aa7a3..11fb7facc5f 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -90,14 +90,13 @@ /obj/item/projectile/bullet/incendiary -/* /obj/item/projectile/bullet/incendiary/on_hit(var/atom/target, var/blocked = 0) ..() if(istype(target, /mob/living/carbon)) var/mob/living/carbon/M = target - // M.adjust_fire_stacks(1) - // M.IgniteMob() // need to find out linda shit later for this -*/ + M.adjust_fire_stacks(1) + M.IgniteMob() + /obj/item/projectile/bullet/incendiary/shell name = "incendiary slug" damage = 20 diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index a0c4cd8ac19..6201723c6ec 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -214,6 +214,13 @@ datum if(!istype(M, /mob/living)) return + // Put out fire + if(method == TOUCH) + M.adjust_fire_stacks(-(volume / 10)) + if(M.fire_stacks <= 0) + M.ExtinguishMob() + return + reaction_turf(var/turf/simulated/T, var/volume) if (!istype(T)) return src = null @@ -272,8 +279,10 @@ datum description = "YOUR FLESH! IT BURNS!" on_mob_life(var/mob/living/M as mob) + M.fire_stacks = min(5,M.fire_stacks + 3) + M.IgniteMob() //Only problem with igniting people is currently the commonly availible fire suits make you immune to being on fire M.adjustToxLoss(1) - M.adjustFireLoss(5) //does more damage since mob fire isn't a thing anymore + M.adjustFireLoss(1) //Hence the other damages... ain't I a bastard? M.adjustBrainLoss(5) holder.remove_reagent(src.id, 1) @@ -456,7 +465,9 @@ datum M << "You suddenly ignite in a holy fire!" for(var/mob/O in viewers(M, null)) O.show_message(text("[] suddenly bursts into flames!", M), 1) - M.adjustFireLoss(9) //Hence the other damages... ain't I a bastard? + M.fire_stacks = min(5,M.fire_stacks + 3) + M.IgniteMob() //Only problem with igniting people is currently the commonly availible fire suits make you immune to being on fire + M.adjustFireLoss(3) //Hence the other damages... ain't I a bastard? M.mind.vampire.nullified = max(5, M.mind.vampire.nullified + 2) holder.remove_reagent(src.id, 10 * REAGENTS_METABOLISM) //high metabolism to prevent extended uncult rolls. @@ -1004,6 +1015,8 @@ datum reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume)//Splashing people with welding fuel to make them easy to ignite! if(!istype(M, /mob/living)) return + if(method == TOUCH) + M.adjust_fire_stacks(volume / 10) return /* reaction_obj(var/obj/O, var/volume) @@ -1032,6 +1045,8 @@ datum reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume)//Splashing people with welding fuel to make them easy to ignite! if(!istype(M, /mob/living)) return + if(method == TOUCH) + M.adjust_fire_stacks(volume / 10) return reaction_obj(var/obj/O, var/volume) @@ -1119,10 +1134,12 @@ datum M.adjustToxLoss(3*REM) ..() return + reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume)//Splashing people with plasma is stronger than fuel! if(!istype(M, /mob/living)) return if(method == TOUCH) + M.adjust_fire_stacks(volume / 5) ..() return lexorin @@ -2454,6 +2471,9 @@ datum reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume)//Splashing people with ethanol isn't quite as good as fuel. if(!istype(M, /mob/living)) return + if(method == TOUCH) + M.adjust_fire_stacks(volume / 15) + return beer //It's really much more stronger than other drinks. name = "Beer" diff --git a/code/modules/reagents/newchem/pyro.dm b/code/modules/reagents/newchem/pyro.dm index 5fe609e7bda..6212bcb745a 100644 --- a/code/modules/reagents/newchem/pyro.dm +++ b/code/modules/reagents/newchem/pyro.dm @@ -37,6 +37,7 @@ /datum/reagent/clf3/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom + M.adjust_fire_stacks(4) M.adjustFireLoss(0.35*1) ..() return @@ -66,6 +67,8 @@ /datum/reagent/clf3/reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume) if(method == TOUCH && isliving(M)) + M.adjust_fire_stacks(5) + M.IgniteMob() M.bodytemperature += 30 return @@ -417,7 +420,9 @@ datum/reagent/blackpowder/reaction_turf(var/turf/T, var/volume) //oh shit /datum/reagent/phlogiston/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom - M.adjustFireLoss(0.2*1) + M.adjust_fire_stacks(1) + M.IgniteMob() + M.adjustFireLoss(0.2*M.fire_stacks) ..() return @@ -430,11 +435,13 @@ datum/reagent/blackpowder/reaction_turf(var/turf/T, var/volume) //oh shit /datum/reagent/napalm/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom + M.adjust_fire_stacks(1) ..() return /datum/reagent/napalm/reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume) if(method == TOUCH && isliving(M)) + M.adjust_fire_stacks(7) return /datum/chemical_reaction/napalm @@ -540,6 +547,9 @@ datum/reagent/firefighting_foam/reaction_mob(var/mob/living/M, var/method=TOUCH, // Put out fire if(method == TOUCH) + M.adjust_fire_stacks(-(volume / 5)) // more effective than water + if(M.fire_stacks <= 0) + M.ExtinguishMob() return datum/reagent/firefighting_foam/reaction_turf(var/turf/simulated/T, var/volume)