diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm index de9f1997a61..e2cb1e01554 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm @@ -16,7 +16,7 @@ #define COMSIG_LIVING_DOORCRUSHED "living_doorcrush" ///from base of mob/living/resist() (/mob/living) #define COMSIG_LIVING_RESIST "living_resist" -///from base of mob/living/IgniteMob() (/mob/living) +///from base of mob/living/ignite_mob() (/mob/living) #define COMSIG_LIVING_IGNITED "living_ignite" ///from base of mob/living/extinguish_mob() (/mob/living) #define COMSIG_LIVING_EXTINGUISHED "living_extinguished" diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm index 200e76b80a9..dce92503ba6 100644 --- a/code/__DEFINES/status_effects.dm +++ b/code/__DEFINES/status_effects.dm @@ -38,3 +38,4 @@ #define STASIS_CHEMICAL_EFFECT "stasis_chemical" #define STASIS_ASCENSION_EFFECT "heretic_ascension" + diff --git a/code/datums/components/igniter.dm b/code/datums/components/igniter.dm index 2d9d21022b1..7371942296e 100644 --- a/code/datums/components/igniter.dm +++ b/code/datums/components/igniter.dm @@ -1,11 +1,13 @@ /datum/component/igniter var/fire_stacks + var/fire_type -/datum/component/igniter/Initialize(fire_stacks=1) +/datum/component/igniter/Initialize(fire_stacks = 1, fire_type = /datum/status_effect/fire_handler/fire_stacks) if(!isitem(parent) && !ishostile(parent) && !isgun(parent) && !ismachinery(parent) && !isstructure(parent)) return COMPONENT_INCOMPATIBLE src.fire_stacks = fire_stacks + src.fire_type = fire_type /datum/component/igniter/RegisterWithParent() if(ismachinery(parent) || isstructure(parent) || isgun(parent)) // turrets, etc @@ -40,5 +42,5 @@ /datum/component/igniter/proc/do_igniter(atom/target) if(isliving(target)) var/mob/living/L = target - L.adjust_fire_stacks(fire_stacks) - L.IgniteMob() + L.adjust_fire_stacks(fire_stacks, fire_type) + L.ignite_mob() diff --git a/code/datums/diseases/advance/symptoms/fire.dm b/code/datums/diseases/advance/symptoms/fire.dm index f9e0555deb4..dbbe76abcf0 100644 --- a/code/datums/diseases/advance/symptoms/fire.dm +++ b/code/datums/diseases/advance/symptoms/fire.dm @@ -51,12 +51,12 @@ to_chat(M, span_warning("[pick("You feel hot.", "You hear a crackling noise.", "You smell smoke.")]")) if(4) Firestacks_stage_4(M, A) - M.IgniteMob() + M.ignite_mob() to_chat(M, span_userdanger("Your skin bursts into flames!")) M.emote("scream") if(5) Firestacks_stage_5(M, A) - M.IgniteMob() + M.ignite_mob() to_chat(M, span_userdanger("Your skin erupts into an inferno!")) M.emote("scream") @@ -134,7 +134,7 @@ Bonus M.visible_message(span_warning("[M]'s sweat sizzles and pops on contact with water!")) explosion(M, devastation_range = -1, heavy_impact_range = (-1 + explosion_power), light_impact_range = (2 * explosion_power), explosion_cause = src) Alkali_fire_stage_4(M, A) - M.IgniteMob() + M.ignite_mob() to_chat(M, span_userdanger("Your sweat bursts into flames!")) M.emote("scream") if(5) @@ -142,7 +142,7 @@ Bonus M.visible_message(span_warning("[M]'s sweat sizzles and pops on contact with water!")) explosion(M, devastation_range = -1, heavy_impact_range = (-1 + explosion_power), light_impact_range = (2 * explosion_power), explosion_cause = src) Alkali_fire_stage_5(M, A) - M.IgniteMob() + M.ignite_mob() to_chat(M, span_userdanger("Your skin erupts into an inferno!")) M.emote("scream") diff --git a/code/datums/diseases/advance/symptoms/heal.dm b/code/datums/diseases/advance/symptoms/heal.dm index da8cf315d82..f92cd30a927 100644 --- a/code/datums/diseases/advance/symptoms/heal.dm +++ b/code/datums/diseases/advance/symptoms/heal.dm @@ -455,7 +455,7 @@ . = 0 var/mob/living/M = A.affected_mob if(M.fire_stacks < 0) - M.set_fire_stacks(min(M.fire_stacks + 1 * absorption_coeff, 0)) + M.adjust_fire_stacks(min(absorption_coeff, -M.fire_stacks)) . += power if(M.reagents.has_reagent(/datum/reagent/water/holywater, needs_metabolizing = FALSE)) M.reagents.remove_reagent(/datum/reagent/water/holywater, 0.5 * absorption_coeff) diff --git a/code/datums/diseases/rhumba_beat.dm b/code/datums/diseases/rhumba_beat.dm index f6ffe59ecc0..47138170764 100644 --- a/code/datums/diseases/rhumba_beat.dm +++ b/code/datums/diseases/rhumba_beat.dm @@ -32,7 +32,7 @@ if(DT_PROB(10, delta_time)) if(prob(50)) affected_mob.adjust_fire_stacks(2) - affected_mob.IgniteMob() + affected_mob.ignite_mob() else affected_mob.emote("gasp") to_chat(affected_mob, span_danger("You feel a burning beat inside...")) diff --git a/code/datums/mutations/actions.dm b/code/datums/mutations/actions.dm index 8096870697e..d1119a4fa44 100644 --- a/code/datums/mutations/actions.dm +++ b/code/datums/mutations/actions.dm @@ -146,7 +146,7 @@ return our_lizard.adjust_fire_stacks(cone_levels) - our_lizard.IgniteMob() + our_lizard.ignite_mob() to_chat(our_lizard, span_warning("Something in front of your mouth catches fire!")) /obj/effect/proc_holder/spell/cone/staggered/firebreath/cast(list/targets, mob/user) @@ -171,7 +171,7 @@ // The actual burn damage application is not blocked by fireproofing, like space dragons. target_mob.apply_damage(max(10, 40 - (5 * level)), BURN, spread_damage = TRUE) target_mob.adjust_fire_stacks(max(2, 5 - level)) - target_mob.IgniteMob() + target_mob.ignite_mob() /obj/effect/proc_holder/spell/cone/staggered/firebreath/do_obj_cone_effect(obj/target_obj, level) // Further out objects experience less exposed_temperature and exposed_volume diff --git a/code/datums/mutations/body.dm b/code/datums/mutations/body.dm index 466c6b328b8..3fb98af58fd 100644 --- a/code/datums/mutations/body.dm +++ b/code/datums/mutations/body.dm @@ -293,7 +293,7 @@ /datum/mutation/human/fire/on_life(delta_time, times_fired) if(DT_PROB((0.05+(100-dna.stability)/19.5) * GET_MUTATION_SYNCHRONIZER(src), delta_time)) owner.adjust_fire_stacks(2 * GET_MUTATION_POWER(src)) - owner.IgniteMob() + owner.ignite_mob() /datum/mutation/human/fire/on_acquiring(mob/living/carbon/human/owner) if(..()) diff --git a/code/datums/status_effects/_status_effect.dm b/code/datums/status_effects/_status_effect.dm index 46b62f6e34a..32ea2eb8153 100644 --- a/code/datums/status_effects/_status_effect.dm +++ b/code/datums/status_effects/_status_effect.dm @@ -75,12 +75,12 @@ // Status effect process. Handles adjusting it's duration and ticks. // If you're adding processed effects, put them in [proc/tick] // instead of extending / overriding ththe process() proc. -/datum/status_effect/process(delta_time) +/datum/status_effect/process(delta_time, times_fired) if(QDELETED(owner)) qdel(src) return if(tick_interval < world.time) - tick() + tick(delta_time, times_fired) tick_interval = world.time + initial(tick_interval) if(duration != -1 && duration < world.time) qdel(src) @@ -96,7 +96,7 @@ return null /// Called every tick from process(). -/datum/status_effect/proc/tick() +/datum/status_effect/proc/tick(delta_time, times_fired) return /// Called whenever the buff expires or is removed (qdeleted) diff --git a/code/datums/status_effects/_status_effect_helpers.dm b/code/datums/status_effects/_status_effect_helpers.dm index 3f21920f516..9cd5f4f3c86 100644 --- a/code/datums/status_effects/_status_effect_helpers.dm +++ b/code/datums/status_effects/_status_effect_helpers.dm @@ -40,7 +40,8 @@ // Create the status effect with our mob + our arguments var/datum/status_effect/new_instance = new new_effect(arguments) - return new_instance + if(!QDELETED(new_instance)) + return new_instance /** * Removes all instances of a given status effect from this mob diff --git a/code/datums/status_effects/debuffs/fire_stacks.dm b/code/datums/status_effects/debuffs/fire_stacks.dm new file mode 100644 index 00000000000..98d88182218 --- /dev/null +++ b/code/datums/status_effects/debuffs/fire_stacks.dm @@ -0,0 +1,260 @@ +/datum/status_effect/fire_handler + duration = -1 + alert_type = null + status_type = STATUS_EFFECT_REFRESH //Custom code + on_remove_on_mob_delete = TRUE + tick_interval = 2 SECONDS + /// Current amount of stacks we have + var/stacks + /// Maximum of stacks that we could possibly get + var/stack_limit = 20 + /// What status effect types do we remove uppon being applied. These are just deleted without any deduction from our or their stacks when forced. + var/list/enemy_types + /// What status effect types do we merge into if they exist. Ignored when forced. + var/list/merge_types + /// What status effect types do we override if they exist. These are simply deleted when forced. + var/list/override_types + /// For how much firestacks does one our stack count + var/stack_modifier = 1 + +/datum/status_effect/fire_handler/refresh(mob/living/new_owner, new_stacks, forced = FALSE) + if(forced) + set_stacks(new_stacks) + else + adjust_stacks(new_stacks) + +/datum/status_effect/fire_handler/on_creation(mob/living/new_owner, new_stacks, forced = FALSE) + . = ..() + + if(isanimal(owner)) + qdel(src) + return + + owner = new_owner + set_stacks(new_stacks) + + for(var/enemy_type in enemy_types) + var/datum/status_effect/fire_handler/enemy_effect = owner.has_status_effect(enemy_type) + if(enemy_effect) + if(forced) + qdel(enemy_effect) + continue + + var/cur_stacks = stacks + adjust_stacks(-enemy_effect.stacks * enemy_effect.stack_modifier / stack_modifier) + enemy_effect.adjust_stacks(-cur_stacks * stack_modifier / enemy_effect.stack_modifier) + if(enemy_effect.stacks <= 0) + qdel(enemy_effect) + + if(stacks <= 0) + qdel(src) + return + + if(!forced) + var/list/merge_effects = list() + for(var/merge_type in merge_types) + var/datum/status_effect/fire_handler/merge_effect = owner.has_status_effect(merge_type) + if(merge_effect) + merge_effects += merge_effects + + if(LAZYLEN(merge_effects)) + for(var/datum/status_effect/fire_handler/merge_effect in merge_effects) + merge_effect.adjust_stacks(stacks * stack_modifier / merge_effect.stack_modifier / LAZYLEN(merge_effects)) + qdel(src) + return + + for(var/override_type in override_types) + var/datum/status_effect/fire_handler/override_effect = owner.has_status_effect(override_type) + if(override_effect) + if(forced) + qdel(override_effect) + continue + + adjust_stacks(override_effect.stacks) + qdel(override_effect) + +/** + * Setter and adjuster procs for firestacks + * + * Arguments: + * - new_stacks + * + */ + +/datum/status_effect/fire_handler/proc/set_stacks(new_stacks) + stacks = max(0, min(stack_limit, new_stacks)) + cache_stacks() + +/datum/status_effect/fire_handler/proc/adjust_stacks(new_stacks) + stacks = max(0, min(stack_limit, stacks + new_stacks)) + cache_stacks() + +/** + * Refresher for mob's fire_stacks + */ + +/datum/status_effect/fire_handler/proc/cache_stacks() + owner.fire_stacks = 0 + var/was_on_fire = owner.on_fire + owner.on_fire = FALSE + for(var/datum/status_effect/fire_handler/possible_fire in owner.status_effects) + owner.fire_stacks += possible_fire.stacks * possible_fire.stack_modifier + + if(!istype(possible_fire, /datum/status_effect/fire_handler/fire_stacks)) + continue + + var/datum/status_effect/fire_handler/fire_stacks/our_fire = possible_fire + if(our_fire.on_fire) + owner.on_fire = TRUE + + if(was_on_fire && !owner.on_fire) + owner.clear_alert(ALERT_FIRE) + else if(!was_on_fire && owner.on_fire) + owner.throw_alert(ALERT_FIRE, /atom/movable/screen/alert/fire) + +/** + * Used to update owner's effect overlay + */ + +/datum/status_effect/fire_handler/proc/update_overlay() + +/datum/status_effect/fire_handler/fire_stacks + id = "fire_stacks" //fire_stacks and wet_stacks should have different IDs or else has_status_effect won't work + + enemy_types = list(/datum/status_effect/fire_handler/wet_stacks) + stack_modifier = 1 + + /// If we're on fire + var/on_fire = FALSE + /// A weakref to the mob light emitter + var/datum/weakref/firelight_ref + /// Type of mob light emitter we use when on fire + var/firelight_type = /obj/effect/dummy/lighting_obj/moblight/fire + /// Stores current fire overlay icon state, for optimisation purposes + var/last_icon_state + +/datum/status_effect/fire_handler/fire_stacks/tick(delta_time, times_fired) + if(stacks <= 0) + qdel(src) + return TRUE + + if(!on_fire || isanimal(owner)) + return TRUE + + if(iscyborg(owner)) + adjust_stacks(-0.55 * delta_time) + else + adjust_stacks(-0.05 * delta_time) + + if(stacks <= 0) + qdel(src) + return TRUE + + var/datum/gas_mixture/air = owner.loc.return_air() + if(!air.gases[/datum/gas/oxygen] || air.gases[/datum/gas/oxygen][MOLES] < 1) + qdel(src) + return TRUE + + deal_damage(delta_time, times_fired) + update_overlay() + +/** + * Proc that handles damage dealing and all special effects + * + * Arguments: + * - delta_time + * - times_fired + * + */ + +/datum/status_effect/fire_handler/fire_stacks/proc/deal_damage(delta_time, times_fired) + owner.on_fire_stack(delta_time, times_fired, src) + + var/turf/location = get_turf(owner) + location.hotspot_expose(700, 25 * delta_time, TRUE) + +/** + * Used to deal damage to humans and count their protection. + * + * Arguments: + * - delta_time + * - times_fired + * - no_protection: When set to TRUE, fire will ignore any possible fire protection + * + */ + +/datum/status_effect/fire_handler/fire_stacks/proc/harm_human(delta_time, times_fired, no_protection = FALSE) + var/mob/living/carbon/human/victim = owner + var/thermal_protection = victim.get_thermal_protection() + + if(thermal_protection >= FIRE_IMMUNITY_MAX_TEMP_PROTECT && !no_protection) + return + + if(thermal_protection >= FIRE_SUIT_MAX_TEMP_PROTECT && !no_protection) + victim.adjust_bodytemperature(5.5 * delta_time) + return + + victim.adjust_bodytemperature((BODYTEMP_HEATING_MAX + (stacks * 12)) * 0.5 * delta_time) + SEND_SIGNAL(victim, COMSIG_ADD_MOOD_EVENT, "on_fire", /datum/mood_event/on_fire) + victim.mind?.add_memory(MEMORY_FIRE, list(DETAIL_PROTAGONIST = victim), story_value = STORY_VALUE_OKAY) + +/** + * Handles mob ignition, should be the only way to set on_fire to TRUE + * + * Arguments: + * - silent: When set to TRUE, no message is displayed + * + */ + +/datum/status_effect/fire_handler/fire_stacks/proc/ignite(silent = FALSE) + if(HAS_TRAIT(owner, TRAIT_NOFIRE)) + return FALSE + + on_fire = TRUE + if(!silent) + owner.visible_message(span_warning("[owner] catches fire!"), span_userdanger("You're set on fire!")) + + if(firelight_type) + firelight_ref = WEAKREF(new firelight_type(owner)) + + SEND_SIGNAL(owner, COMSIG_LIVING_IGNITED, owner) + cache_stacks() + update_overlay() + +/** + * Handles mob extinguishing, should be the only way to set on_fire to FALSE + */ + +/datum/status_effect/fire_handler/fire_stacks/proc/extinguish() + if(firelight_ref) + qdel(firelight_ref) + + on_fire = FALSE + SEND_SIGNAL(owner, COMSIG_CLEAR_MOOD_EVENT, "on_fire") + SEND_SIGNAL(owner, COMSIG_LIVING_EXTINGUISHED, owner) + cache_stacks() + update_overlay() + +/datum/status_effect/fire_handler/fire_stacks/on_remove() + if(on_fire) + extinguish() + set_stacks(0) + update_overlay() + +/datum/status_effect/fire_handler/fire_stacks/update_overlay() + last_icon_state = owner.update_fire_overlay(stacks, on_fire, last_icon_state) + +/datum/status_effect/fire_handler/fire_stacks/on_apply() + . = ..() + update_overlay() + +/datum/status_effect/fire_handler/wet_stacks + id = "wet_stacks" + + enemy_types = list(/datum/status_effect/fire_handler/fire_stacks) + stack_modifier = -1 + +/datum/status_effect/fire_handler/wet_stacks/tick(delta_time) + adjust_stacks(-0.5 * delta_time) + if(stacks <= 0) + qdel(src) diff --git a/code/datums/voice_of_god_command.dm b/code/datums/voice_of_god_command.dm index bf3117234a1..39113080f62 100644 --- a/code/datums/voice_of_god_command.dm +++ b/code/datums/voice_of_god_command.dm @@ -213,7 +213,7 @@ GLOBAL_LIST_INIT(voice_of_god_commands, init_voice_of_god_commands()) /datum/voice_of_god_command/burn/execute(list/listeners, mob/living/user, power_multiplier = 1, message) for(var/mob/living/target as anything in listeners) target.adjust_fire_stacks(1 * power_multiplier) - target.IgniteMob() + target.ignite_mob() /// This command heats the listeners up like boiling water. /datum/voice_of_god_command/hot diff --git a/code/game/machinery/computer/arcade/orion.dm b/code/game/machinery/computer/arcade/orion.dm index 1ba229388ee..587f8ee0c25 100644 --- a/code/game/machinery/computer/arcade/orion.dm +++ b/code/game/machinery/computer/arcade/orion.dm @@ -368,7 +368,7 @@ GLOBAL_LIST_INIT(orion_events, generate_orion_events()) reason = "You ran out of fuel, and drift, slowly, into a star." if(obj_flags & EMAGGED) gamer.adjust_fire_stacks(5) - gamer.IgniteMob() //flew into a star, so you're on fire + gamer.ignite_mob() //flew into a star, so you're on fire to_chat(gamer, span_userdanger("You feel an immense wave of heat emanate from the arcade machine. Your skin bursts into flames.")) if(obj_flags & EMAGGED) diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm index 0a4e2bffa94..0fa657a7d8f 100644 --- a/code/game/objects/buckling.dm +++ b/code/game/objects/buckling.dm @@ -131,7 +131,7 @@ if(.) if(resistance_flags & ON_FIRE) //Sets the mob on fire if you buckle them to a burning atom/movableect M.adjust_fire_stacks(1) - M.IgniteMob() + M.ignite_mob() /** * Set a mob as unbuckled from src diff --git a/code/game/objects/effects/effect_system/effects_foam.dm b/code/game/objects/effects/effect_system/effects_foam.dm index 06ff319eb64..59ef1d376c2 100644 --- a/code/game/objects/effects/effect_system/effects_foam.dm +++ b/code/game/objects/effects/effect_system/effects_foam.dm @@ -69,7 +69,7 @@ /obj/effect/particle_effect/foam/firefighting/foam_mob(mob/living/L) if(!istype(L)) return - L.adjust_fire_stacks(-2) + L.adjust_wet_stacks(2) /obj/effect/particle_effect/foam/metal name = "aluminium foam" diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 0e769f963c6..39ab7fdd5ff 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -713,7 +713,7 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e SEND_SIGNAL(src, COMSIG_MOVABLE_IMPACT, hit_atom, throwingdatum) if(get_temperature() && isliving(hit_atom)) var/mob/living/L = hit_atom - L.IgniteMob() + L.ignite_mob() var/itempush = 1 if(w_class < 4) itempush = 0 //too light to push anything diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm index 08f8356925a..10b19f187ca 100644 --- a/code/game/objects/items/cigs_lighters.dm +++ b/code/game/objects/items/cigs_lighters.dm @@ -85,7 +85,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM if(!isliving(M)) return - if(lit && M.IgniteMob()) + if(lit && M.ignite_mob()) message_admins("[ADMIN_LOOKUPFLW(user)] set [key_name_admin(M)] on fire with [src] at [AREACOORD(user)]") log_game("[key_name(user)] set [key_name(M)] on fire with [src] at [AREACOORD(user)]") @@ -312,7 +312,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM /obj/item/clothing/mask/cigarette/process(delta_time) var/mob/living/user = isliving(loc) ? loc : null - user?.IgniteMob() + user?.ignite_mob() if(!reagents.has_reagent(/datum/reagent/oxygen)) //cigarettes need oxygen var/datum/gas_mixture/air = return_air() if(!air || !air.has_gas(/datum/gas/oxygen, 1)) //or oxygen on a tile to burn @@ -802,7 +802,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM /obj/item/lighter/attack(mob/living/carbon/M, mob/living/carbon/user) - if(lit && M.IgniteMob()) + if(lit && M.ignite_mob()) message_admins("[ADMIN_LOOKUPFLW(user)] set [key_name_admin(M)] on fire with [src] at [AREACOORD(user)]") log_game("[key_name(user)] set [key_name(M)] on fire with [src] at [AREACOORD(user)]") var/obj/item/clothing/mask/cigarette/cig = help_light_cig(M) @@ -1025,7 +1025,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM if(reagents.get_reagent_amount(/datum/reagent/fuel)) //HOT STUFF vaper.adjust_fire_stacks(2) - vaper.IgniteMob() + vaper.ignite_mob() if(reagents.get_reagent_amount(/datum/reagent/toxin/plasma)) // the plasma explodes when exposed to fire var/datum/effect_system/reagents_explosion/e = new() @@ -1040,7 +1040,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM var/mob/living/M = loc if(isliving(loc)) - M.IgniteMob() + M.ignite_mob() if(!reagents.total_volume) if(ismob(loc)) diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index e09ef51ebe4..4ff77c773a1 100644 --- a/code/game/objects/items/tools/weldingtool.dm +++ b/code/game/objects/items/tools/weldingtool.dm @@ -145,7 +145,7 @@ if(isOn() && !QDELETED(attacked_atom) && isliving(attacked_atom)) // can't ignite something that doesn't exist handle_fuel_and_temps(1, user) var/mob/living/attacked_mob = attacked_atom - if(attacked_mob.IgniteMob()) + if(attacked_mob.ignite_mob()) message_admins("[ADMIN_LOOKUPFLW(user)] set [key_name_admin(attacked_mob)] on fire with [src] at [AREACOORD(user)]") log_game("[key_name(user)] set [key_name(attacked_mob)] on fire with [src] at [AREACOORD(user)]") @@ -164,7 +164,7 @@ if(!QDELETED(attacked_atom) && isliving(attacked_atom)) // can't ignite something that doesn't exist var/mob/living/attacked_mob = attacked_atom - if(attacked_mob.IgniteMob()) + if(attacked_mob.ignite_mob()) message_admins("[ADMIN_LOOKUPFLW(user)] set [key_name_admin(attacked_mob)] on fire with [src] at [AREACOORD(user)]") log_game("[key_name(user)] set [key_name(attacked_mob)] on fire with [src] at [AREACOORD(user)]") diff --git a/code/game/objects/structures/bonfire.dm b/code/game/objects/structures/bonfire.dm index 6bfb760817f..5de5b9693dc 100644 --- a/code/game/objects/structures/bonfire.dm +++ b/code/game/objects/structures/bonfire.dm @@ -145,7 +145,7 @@ else if(isliving(burn_target)) var/mob/living/burn_victim = burn_target burn_victim.adjust_fire_stacks(BONFIRE_FIRE_STACK_STRENGTH * 0.5 * delta_time) - burn_victim.IgniteMob() + burn_victim.ignite_mob() else if(isobj(burn_target)) var/obj/burned_object = burn_target if(grill && isitem(burned_object)) diff --git a/code/game/turfs/open/lava.dm b/code/game/turfs/open/lava.dm index 5c82669420f..4d9f56a4e31 100644 --- a/code/game/turfs/open/lava.dm +++ b/code/game/turfs/open/lava.dm @@ -220,7 +220,7 @@ 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() + burn_living.ignite_mob() /turf/open/lava/smooth name = "lava" diff --git a/code/modules/antagonists/blob/blobstrains/blazing_oil.dm b/code/modules/antagonists/blob/blobstrains/blazing_oil.dm index 3761f33faba..ded3be1458e 100644 --- a/code/modules/antagonists/blob/blobstrains/blazing_oil.dm +++ b/code/modules/antagonists/blob/blobstrains/blazing_oil.dm @@ -36,7 +36,7 @@ . = ..() reac_volume = return_mob_expose_reac_volume(exposed_mob, methods, reac_volume, show_message, touch_protection, overmind) exposed_mob.adjust_fire_stacks(round(reac_volume/10)) - exposed_mob.IgniteMob() + exposed_mob.ignite_mob() if(exposed_mob) exposed_mob.apply_damage(0.8*reac_volume, BURN, wound_bonus=CANT_WOUND) if(iscarbon(exposed_mob)) diff --git a/code/modules/antagonists/blob/blobstrains/pressurized_slime.dm b/code/modules/antagonists/blob/blobstrains/pressurized_slime.dm index 3398d080600..d035319219d 100644 --- a/code/modules/antagonists/blob/blobstrains/pressurized_slime.dm +++ b/code/modules/antagonists/blob/blobstrains/pressurized_slime.dm @@ -31,7 +31,7 @@ for(var/obj/O in T) O.extinguish() for(var/mob/living/L in T) - L.adjust_fire_stacks(-2.5) + L.adjust_wet_stacks(2.5) L.extinguish_mob() /datum/reagent/blob/pressurized_slime @@ -45,7 +45,7 @@ var/turf/open/location_turf = get_turf(exposed_mob) if(istype(location_turf) && prob(reac_volume)) location_turf.MakeSlippery(TURF_WET_LUBE, min_wet_time = 10 SECONDS, wet_time_to_add = 5 SECONDS) - exposed_mob.adjust_fire_stacks(-(reac_volume / 10)) + exposed_mob.adjust_wet_stacks(reac_volume / 10) exposed_mob.apply_damage(0.4*reac_volume, BRUTE, wound_bonus=CANT_WOUND) if(exposed_mob) exposed_mob.adjustStaminaLoss(reac_volume, FALSE) diff --git a/code/modules/antagonists/heretic/knowledge/ash_lore.dm b/code/modules/antagonists/heretic/knowledge/ash_lore.dm index ea56f3228c3..f9ec6a2df1e 100644 --- a/code/modules/antagonists/heretic/knowledge/ash_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/ash_lore.dm @@ -146,7 +146,7 @@ return target.adjust_fire_stacks(1) - target.IgniteMob() + target.ignite_mob() /datum/heretic_knowledge/spell/flame_birth name = "Nightwater's Rebirth" diff --git a/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_buff.dm b/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_buff.dm index f5dc22ac560..4b4ffd8d712 100644 --- a/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_buff.dm +++ b/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_buff.dm @@ -61,7 +61,7 @@ */ /datum/status_effect/unholy_determination/proc/adjust_all_damages(amount) - owner.set_fire_stacks(max(owner.fire_stacks - 1, 0)) + owner.adjust_fire_stacks(-1) owner.losebreath = max(owner.losebreath - 0.5, 0) owner.adjustToxLoss(-amount, FALSE, TRUE) diff --git a/code/modules/assembly/igniter.dm b/code/modules/assembly/igniter.dm index 2f4148ae3c4..44f2e71acb8 100644 --- a/code/modules/assembly/igniter.dm +++ b/code/modules/assembly/igniter.dm @@ -15,7 +15,7 @@ /obj/item/assembly/igniter/suicide_act(mob/living/carbon/user) user.visible_message(span_suicide("[user] is trying to ignite [user.p_them()]self with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!")) - user.IgniteMob() + user.ignite_mob() return FIRELOSS /obj/item/assembly/igniter/Initialize(mapload) diff --git a/code/modules/awaymissions/mission_code/snowdin.dm b/code/modules/awaymissions/mission_code/snowdin.dm index a7d07884a71..a64e53ae979 100644 --- a/code/modules/awaymissions/mission_code/snowdin.dm +++ b/code/modules/awaymissions/mission_code/snowdin.dm @@ -6,7 +6,7 @@ requires_power = FALSE static_lighting = FALSE base_lighting_alpha = 255 - + /area/awaymission/snowdin/outside name = "Snowdin Tundra Plains" icon_state = "awaycontent25" @@ -219,7 +219,7 @@ burn_human.visible_message(span_warning("[burn_human]'s [burn_limb.name] melts down to the bone!"), \ span_userdanger("You scream out in pain as your [burn_limb.name] 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.ignite_mob() 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!")) diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm index 008dd0a1f59..7f8706bf95d 100644 --- a/code/modules/clothing/spacesuits/plasmamen.dm +++ b/code/modules/clothing/spacesuits/plasmamen.dm @@ -22,7 +22,7 @@ if(!istype(H)) return - if(H.fire_stacks) + if(H.fire_stacks > 0) if(extinguishes_left) if(next_extinguish > world.time) return diff --git a/code/modules/clothing/suits/reactive_armour.dm b/code/modules/clothing/suits/reactive_armour.dm index df3bc20bfcb..9c4c3b43308 100644 --- a/code/modules/clothing/suits/reactive_armour.dm +++ b/code/modules/clothing/suits/reactive_armour.dm @@ -152,8 +152,8 @@ for(var/mob/living/carbon/carbon_victim in range(6, owner)) if(carbon_victim != owner) carbon_victim.adjust_fire_stacks(8) - carbon_victim.IgniteMob() - owner.set_fire_stacks(-20) + carbon_victim.ignite_mob() + owner.set_wet_stacks(20) reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration return TRUE @@ -161,7 +161,7 @@ owner.visible_message(span_danger("[src] just makes [attack_text] worse by spewing molten death on [owner]!")) playsound(get_turf(owner),'sound/magic/fireball.ogg', 100, TRUE) owner.adjust_fire_stacks(12) - owner.IgniteMob() + owner.ignite_mob() reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration return FALSE diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index 204ed0792d2..d9ce824703c 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -1475,7 +1475,7 @@ GLOBAL_LIST_INIT(hallucination_list, list( set waitfor = FALSE ..() target.set_fire_stacks(max(target.fire_stacks, 0.1)) //Placebo flammability - fire_overlay = image('icons/mob/OnFire.dmi', target, "Standing", ABOVE_MOB_LAYER) + fire_overlay = image('icons/mob/onfire.dmi', target, "human_burning", ABOVE_MOB_LAYER) if(target.client) target.client.images += fire_overlay to_chat(target, span_userdanger("You're set on fire!")) diff --git a/code/modules/hydroponics/unique_plant_genes.dm b/code/modules/hydroponics/unique_plant_genes.dm index a53924cf2f3..989739563fc 100644 --- a/code/modules/hydroponics/unique_plant_genes.dm +++ b/code/modules/hydroponics/unique_plant_genes.dm @@ -81,7 +81,7 @@ var/obj/item/seeds/our_seed = our_plant.get_plant_seed() to_chat(target, "You are lit on fire from the intense heat of [our_plant]!") target.adjust_fire_stacks(our_seed.potency / 20) - if(target.IgniteMob()) + if(target.ignite_mob()) message_admins("[ADMIN_LOOKUPFLW(user)] set [ADMIN_LOOKUPFLW(target)] on fire with [our_plant] at [AREACOORD(user)]") log_game("[key_name(user)] set [key_name(target)] on fire with [our_plant] at [AREACOORD(user)]") our_plant.investigate_log("was used by [key_name(user)] to burn [key_name(target)] at [AREACOORD(user)]", INVESTIGATE_BOTANY) diff --git a/code/modules/mob/living/carbon/alien/alien_defense.dm b/code/modules/mob/living/carbon/alien/alien_defense.dm index 427ac0f8980..336d348fc17 100644 --- a/code/modules/mob/living/carbon/alien/alien_defense.dm +++ b/code/modules/mob/living/carbon/alien/alien_defense.dm @@ -131,3 +131,6 @@ In all, this is a lot like the monkey code. /N /mob/living/carbon/alien/acid_act(acidpwr, acid_volume) return FALSE//aliens are immune to acid. + +/mob/living/carbon/alien/on_fire_stack(delta_time, times_fired, datum/status_effect/fire_handler/fire_stacks/fire_handler) + adjust_bodytemperature(BODYTEMP_HEATING_MAX * 0.5 * delta_time) diff --git a/code/modules/mob/living/carbon/alien/life.dm b/code/modules/mob/living/carbon/alien/life.dm index 19e6a17ac30..ca33aa826e7 100644 --- a/code/modules/mob/living/carbon/alien/life.dm +++ b/code/modules/mob/living/carbon/alien/life.dm @@ -46,9 +46,3 @@ //natural reduction of movement delay due to stun. if(move_delay_add > 0) move_delay_add = max(0, move_delay_add - (0.5 * rand(1, 2) * delta_time)) - -/mob/living/carbon/alien/handle_fire(delta_time, times_fired)//Aliens on fire code - . = ..() - if(.) //if the mob isn't on fire anymore - return - adjust_bodytemperature(BODYTEMP_HEATING_MAX * 0.5 * delta_time) //If you're on fire, you heat up! diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index bc59cf4aefe..d43972150ce 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -260,7 +260,6 @@ if(fire_stacks <= 0 && !QDELETED(src)) visible_message(span_danger("[src] successfully extinguishes [p_them()]self!"), \ span_notice("You extinguish yourself.")) - extinguish_mob() return /mob/living/carbon/resist_restraints() @@ -965,15 +964,6 @@ I.extinguish() //extinguishes our clothes ..() -/mob/living/carbon/fakefire(fire_icon = "Generic_mob_burning") - var/mutable_appearance/new_fire_overlay = mutable_appearance('icons/mob/OnFire.dmi', fire_icon, -FIRE_LAYER) - new_fire_overlay.appearance_flags = RESET_COLOR - overlays_standing[FIRE_LAYER] = new_fire_overlay - apply_overlay(FIRE_LAYER) - -/mob/living/carbon/fakefireextinguish() - remove_overlay(FIRE_LAYER) - /mob/living/carbon/proc/create_bodyparts() var/l_arm_index_next = -1 @@ -1424,3 +1414,27 @@ our_splatter.blood_dna_info = get_blood_dna_list() var/turf/targ = get_ranged_target_turf(src, splatter_direction, splatter_strength) our_splatter.fly_towards(targ, splatter_strength) + +/mob/living/carbon/update_fire_overlay(stacks, on_fire, last_icon_state, suffix = "") + var/fire_icon = "generic_burning[suffix]" + + if(!GLOB.fire_appearances[fire_icon]) + var/mutable_appearance/new_fire_overlay = mutable_appearance('icons/mob/onfire.dmi', fire_icon, -FIRE_LAYER) + new_fire_overlay.appearance_flags = RESET_COLOR + GLOB.fire_appearances[fire_icon] = new_fire_overlay + + if((stacks > 0 && on_fire) || HAS_TRAIT(src, TRAIT_PERMANENTLY_ONFIRE)) + if(fire_icon == last_icon_state) + return last_icon_state + + remove_overlay(FIRE_LAYER) + overlays_standing[FIRE_LAYER] = GLOB.fire_appearances[fire_icon] + apply_overlay(FIRE_LAYER) + return fire_icon + + if(!last_icon_state) + return last_icon_state + + remove_overlay(FIRE_LAYER) + apply_overlay(FIRE_LAYER) + return null diff --git a/code/modules/mob/living/carbon/carbon_update_icons.dm b/code/modules/mob/living/carbon/carbon_update_icons.dm index 483582ed7af..bcedf7a42ca 100644 --- a/code/modules/mob/living/carbon/carbon_update_icons.dm +++ b/code/modules/mob/living/carbon/carbon_update_icons.dm @@ -47,7 +47,6 @@ update_fire() update_body_parts() - /mob/living/carbon/update_inv_hands() remove_overlay(HANDS_LAYER) if (handcuffed) @@ -78,16 +77,6 @@ overlays_standing[HANDS_LAYER] = hands apply_overlay(HANDS_LAYER) - -/mob/living/carbon/update_fire(fire_icon = "Generic_mob_burning") - remove_overlay(FIRE_LAYER) - if(on_fire || HAS_TRAIT(src, TRAIT_PERMANENTLY_ONFIRE)) - var/mutable_appearance/new_fire_overlay = mutable_appearance('icons/mob/OnFire.dmi', fire_icon, -FIRE_LAYER) - new_fire_overlay.appearance_flags = RESET_COLOR - overlays_standing[FIRE_LAYER] = new_fire_overlay - - apply_overlay(FIRE_LAYER) - /mob/living/carbon/update_damage_overlays() remove_overlay(DAMAGE_LAYER) diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm index c12be3b336f..f5d81b956f2 100644 --- a/code/modules/mob/living/carbon/examine.dm +++ b/code/modules/mob/living/carbon/examine.dm @@ -96,9 +96,9 @@ if(HAS_TRAIT(src, TRAIT_DUMB)) msg += "[t_He] seem[p_s()] to be clumsy and unable to think.\n" - if(fire_stacks > 0) + if(has_status_effect(/datum/status_effect/fire_handler/fire_stacks)) msg += "[t_He] [t_is] covered in something flammable.\n" - if(fire_stacks < 0) + if(has_status_effect(/datum/status_effect/fire_handler/wet_stacks)) msg += "[t_He] look[p_s()] a little soaked.\n" if(pulledby?.grab_state) diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 740c420cb0b..431981a40f3 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -214,9 +214,9 @@ msg += "[t_He] [t_has] severe cellular damage!\n" - if(fire_stacks > 0) + if(has_status_effect(/datum/status_effect/fire_handler/fire_stacks)) msg += "[t_He] [t_is] covered in something flammable.\n" - if(fire_stacks < 0) + if(has_status_effect(/datum/status_effect/fire_handler/wet_stacks)) msg += "[t_He] look[p_s()] a little soaked.\n" diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 723f5b5f2aa..d43b174e493 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -966,3 +966,97 @@ for(var/obj/item/I in torn_items) I.take_damage(damage_amount, damage_type, damage_flag, 0) + +/** + * Used by fire code to damage worn items. + * + * Arguments: + * - delta_time + * - times_fired + * - stacks: Current amount of firestacks + * + */ + +/mob/living/carbon/human/proc/burn_clothing(delta_time, times_fired, stacks) + var/list/burning_items = list() + var/obscured = check_obscured_slots(TRUE) + //HEAD// + + if(glasses && !(obscured & ITEM_SLOT_EYES)) + burning_items += glasses + if(wear_mask && !(obscured & ITEM_SLOT_MASK)) + burning_items += wear_mask + if(wear_neck && !(obscured & ITEM_SLOT_NECK)) + burning_items += wear_neck + if(ears && !(obscured & ITEM_SLOT_EARS)) + burning_items += ears + if(head) + burning_items += head + + //CHEST// + if(w_uniform && !(obscured & ITEM_SLOT_ICLOTHING)) + burning_items += w_uniform + if(wear_suit) + burning_items += wear_suit + + //ARMS & HANDS// + var/obj/item/clothing/arm_clothes = null + if(gloves && !(obscured & ITEM_SLOT_GLOVES)) + arm_clothes = gloves + else if(wear_suit && ((wear_suit.body_parts_covered & HANDS) || (wear_suit.body_parts_covered & ARMS))) + arm_clothes = wear_suit + else if(w_uniform && ((w_uniform.body_parts_covered & HANDS) || (w_uniform.body_parts_covered & ARMS))) + arm_clothes = w_uniform + if(arm_clothes) + burning_items |= arm_clothes + + //LEGS & FEET// + var/obj/item/clothing/leg_clothes = null + if(shoes && !(obscured & ITEM_SLOT_FEET)) + leg_clothes = shoes + else if(wear_suit && ((wear_suit.body_parts_covered & FEET) || (wear_suit.body_parts_covered & LEGS))) + leg_clothes = wear_suit + else if(w_uniform && ((w_uniform.body_parts_covered & FEET) || (w_uniform.body_parts_covered & LEGS))) + leg_clothes = w_uniform + if(leg_clothes) + burning_items |= leg_clothes + + for(var/obj/item/burning in burning_items) + burning.fire_act((stacks * 25 * delta_time)) //damage taken is reduced to 2% of this value by fire_act() + +/mob/living/carbon/human/update_fire_overlay(stacks, on_fire, last_icon_state, suffix = "") + var/fire_icon = "generic_burning[suffix]" + if(stacks > HUMAN_FIRE_STACK_ICON_NUM) + if(dna && dna.species) + fire_icon = "[dna.species.fire_overlay][suffix]" + else + fire_icon = "human_burning[suffix]" + + if(!GLOB.fire_appearances[fire_icon]) + var/mutable_appearance/new_fire_overlay = mutable_appearance('icons/mob/onfire.dmi', fire_icon, -FIRE_LAYER) + new_fire_overlay.appearance_flags = RESET_COLOR + GLOB.fire_appearances[fire_icon] = new_fire_overlay + + if((stacks > 0 && on_fire) || HAS_TRAIT(src, TRAIT_PERMANENTLY_ONFIRE)) + if(fire_icon == last_icon_state) + return last_icon_state + + remove_overlay(FIRE_LAYER) + overlays_standing[FIRE_LAYER] = GLOB.fire_appearances[fire_icon] + apply_overlay(FIRE_LAYER) + return fire_icon + + if(!last_icon_state) + return last_icon_state + + remove_overlay(FIRE_LAYER) + apply_overlay(FIRE_LAYER) + return null + +/mob/living/carbon/human/on_fire_stack(delta_time, times_fired, datum/status_effect/fire_handler/fire_stacks/fire_handler) + SEND_SIGNAL(src, COMSIG_HUMAN_BURNING) + burn_clothing(delta_time, times_fired, fire_handler.stacks) + var/no_protection = FALSE + if(dna && dna.species) + no_protection = dna.species.handle_fire(src, delta_time, times_fired, no_protection) + fire_handler.harm_human(delta_time, times_fired, no_protection) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 102d3475e36..19ac4a85f51 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -64,7 +64,6 @@ /// What types of mobs are allowed to ride/buckle to this mob var/static/list/can_ride_typecache = typecacheof(list(/mob/living/carbon/human, /mob/living/simple_animal/slime, /mob/living/simple_animal/parrot)) var/lastpuke = 0 - var/last_fire_update var/account_id var/hardcore_survival_score = 0 diff --git a/code/modules/mob/living/carbon/human/human_update_icons.dm b/code/modules/mob/living/carbon/human/human_update_icons.dm index 039d1215d0f..9e7f4fe0693 100644 --- a/code/modules/mob/living/carbon/human/human_update_icons.dm +++ b/code/modules/mob/living/carbon/human/human_update_icons.dm @@ -69,10 +69,6 @@ There are several things that need to be remembered: dna.species.handle_body(src) ..() -/mob/living/carbon/human/update_fire() - ..((fire_stacks > HUMAN_FIRE_STACK_ICON_NUM) ? "Standing" : "Generic_mob_burning") - - /* --------------------------------------- */ //For legacy support. /mob/living/carbon/human/regenerate_icons() diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 6f2e1281e8a..1fea46d37c4 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -154,22 +154,6 @@ /mob/living/carbon/human/get_body_temp_cold_damage_limit() return dna.species.bodytemp_cold_damage_limit -///FIRE CODE -/mob/living/carbon/human/handle_fire(delta_time, times_fired) - . = ..() - if(.) //if the mob isn't on fire anymore - return - - if(dna) - . = dna.species.handle_fire(src, delta_time, times_fired) //do special handling based on the mob's species. TRUE = they are immune to the effects of the fire. - - if(!last_fire_update) - last_fire_update = fire_stacks - if((fire_stacks > HUMAN_FIRE_STACK_ICON_NUM && last_fire_update <= HUMAN_FIRE_STACK_ICON_NUM) || (fire_stacks <= HUMAN_FIRE_STACK_ICON_NUM && last_fire_update > HUMAN_FIRE_STACK_ICON_NUM)) - last_fire_update = fire_stacks - update_fire() - - /mob/living/carbon/human/proc/get_thermal_protection() var/thermal_protection = 0 //Simple check to estimate how protected we are against multiple temperatures if(wear_suit) @@ -181,20 +165,8 @@ thermal_protection = round(thermal_protection) return thermal_protection -/mob/living/carbon/human/IgniteMob() - //If have no DNA or can be Ignited, call parent handling to light user - //If firestacks are high enough - if(!dna || dna.species.CanIgniteMob(src)) - return ..() - . = FALSE //No ignition - -/mob/living/carbon/human/extinguish_mob() - if(!dna || !dna.species.extinguish_mob(src)) - last_fire_update = null - ..() //END FIRE CODE - //This proc returns a number made up of the flags for body parts which you are protected on. (such as HEAD, CHEST, GROIN, etc. See setup.dm for the full list) /mob/living/carbon/human/proc/get_heat_protection_flags(temperature) //Temperature is the temperature you're being exposed to. var/thermal_protection_flags = 0 diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 849920fbcc9..18f381515f2 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -165,7 +165,7 @@ GLOBAL_LIST_EMPTY(features_by_species) var/bodytemp_cold_damage_limit = BODYTEMP_COLD_DAMAGE_LIMIT /// The icon_state of the fire overlay added when sufficently ablaze and standing. see onfire.dmi - var/fire_overlay = "Standing" + var/fire_overlay = "human_burning" ///the species that body parts are surgically compatible with (found in _DEFINES/mobs.dm) ///current acceptable bitfields are HUMAN_BODY, ALIEN_BODY, LARVA_BODY, MONKEY_BODY, or NONE @@ -1721,77 +1721,7 @@ GLOBAL_LIST_EMPTY(features_by_species) ////////// /datum/species/proc/handle_fire(mob/living/carbon/human/H, delta_time, times_fired, no_protection = FALSE) - if(!CanIgniteMob(H)) - return TRUE - if(H.on_fire) - SEND_SIGNAL(H, COMSIG_HUMAN_BURNING) - //the fire tries to damage the exposed clothes and items - var/list/burning_items = list() - var/obscured = H.check_obscured_slots(TRUE) - //HEAD// - - if(H.glasses && !(obscured & ITEM_SLOT_EYES)) - burning_items += H.glasses - if(H.wear_mask && !(obscured & ITEM_SLOT_MASK)) - burning_items += H.wear_mask - if(H.wear_neck && !(obscured & ITEM_SLOT_NECK)) - burning_items += H.wear_neck - if(H.ears && !(obscured & ITEM_SLOT_EARS)) - burning_items += H.ears - if(H.head) - burning_items += H.head - - //CHEST// - if(H.w_uniform && !(obscured & ITEM_SLOT_ICLOTHING)) - burning_items += H.w_uniform - if(H.wear_suit) - burning_items += H.wear_suit - - //ARMS & HANDS// - var/obj/item/clothing/arm_clothes = null - if(H.gloves && !(obscured & ITEM_SLOT_GLOVES)) - arm_clothes = H.gloves - else if(H.wear_suit && ((H.wear_suit.body_parts_covered & HANDS) || (H.wear_suit.body_parts_covered & ARMS))) - arm_clothes = H.wear_suit - else if(H.w_uniform && ((H.w_uniform.body_parts_covered & HANDS) || (H.w_uniform.body_parts_covered & ARMS))) - arm_clothes = H.w_uniform - if(arm_clothes) - burning_items |= arm_clothes - - //LEGS & FEET// - var/obj/item/clothing/leg_clothes = null - if(H.shoes && !(obscured & ITEM_SLOT_FEET)) - leg_clothes = H.shoes - else if(H.wear_suit && ((H.wear_suit.body_parts_covered & FEET) || (H.wear_suit.body_parts_covered & LEGS))) - leg_clothes = H.wear_suit - else if(H.w_uniform && ((H.w_uniform.body_parts_covered & FEET) || (H.w_uniform.body_parts_covered & LEGS))) - leg_clothes = H.w_uniform - if(leg_clothes) - burning_items |= leg_clothes - - for(var/X in burning_items) - var/obj/item/I = X - I.fire_act((H.fire_stacks * 50)) //damage taken is reduced to 2% of this value by fire_act() - - var/thermal_protection = H.get_thermal_protection() - - if(thermal_protection >= FIRE_IMMUNITY_MAX_TEMP_PROTECT && !no_protection) - return - if(thermal_protection >= FIRE_SUIT_MAX_TEMP_PROTECT && !no_protection) - H.adjust_bodytemperature(5.5 * delta_time) - else - H.adjust_bodytemperature((BODYTEMP_HEATING_MAX + (H.fire_stacks * 12)) * 0.5 * delta_time) - SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "on_fire", /datum/mood_event/on_fire) - H.mind?.add_memory(MEMORY_FIRE, list(DETAIL_PROTAGONIST = H), story_value = STORY_VALUE_OKAY) - -/datum/species/proc/CanIgniteMob(mob/living/carbon/human/H) - if(HAS_TRAIT(H, TRAIT_NOFIRE)) - return FALSE - return TRUE - -/datum/species/proc/extinguish_mob(mob/living/carbon/human/H) - return - + return no_protection //////////// // Stun // 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 dbf39d46237..2745ff9da7e 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -173,7 +173,7 @@ to_chat(owner, span_notice("You ignite yourself!")) else to_chat(owner, span_warning("You try to ignite yourself, but fail!")) - H.IgniteMob() //firestacks are already there passively + H.ignite_mob() //firestacks are already there passively //Harder to hurt /datum/species/golem/diamond diff --git a/code/modules/mob/living/carbon/human/species_types/monkeys.dm b/code/modules/mob/living/carbon/human/species_types/monkeys.dm index 40063c834ce..a10d9c76dac 100644 --- a/code/modules/mob/living/carbon/human/species_types/monkeys.dm +++ b/code/modules/mob/living/carbon/human/species_types/monkeys.dm @@ -54,7 +54,7 @@ BODY_ZONE_R_LEG = /obj/item/bodypart/r_leg/monkey, BODY_ZONE_CHEST = /obj/item/bodypart/chest/monkey, ) - fire_overlay = "Monkey_burning" + fire_overlay = "monkey_burning" dust_anim = "dust-m" gib_anim = "gibbed-m" diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm index 6afae82ca1d..e79c5bb8178 100644 --- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm +++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm @@ -64,7 +64,7 @@ /datum/species/plasmaman/spec_life(mob/living/carbon/human/H, delta_time, times_fired) var/atmos_sealed = TRUE - if(CanIgniteMob(H)) + if(!HAS_TRAIT(H, TRAIT_NOFIRE)) atmos_sealed = FALSE else if(!isclothing(H.wear_suit) || !(H.wear_suit.clothing_flags & STOPSPRESSUREDAMAGE)) atmos_sealed = FALSE @@ -99,7 +99,7 @@ H.adjust_fire_stacks(0.25 * delta_time) if(!H.on_fire && H.fire_stacks > 0) H.visible_message(span_danger("[H]'s body reacts with the atmosphere and bursts into flames!"),span_userdanger("Your body reacts with the atmosphere and bursts into flame!")) - H.IgniteMob() + H.ignite_mob() internal_fire = TRUE else if(H.fire_stacks) @@ -117,7 +117,6 @@ no_protection = TRUE . = ..() - /datum/species/plasmaman/pre_equip_species_outfit(datum/job/job, mob/living/carbon/human/equipping, visuals_only = FALSE) if(job.plasmaman_outfit) equipping.equipOutfit(job.plasmaman_outfit, visuals_only) diff --git a/code/modules/mob/living/carbon/human/species_types/vampire.dm b/code/modules/mob/living/carbon/human/species_types/vampire.dm index 3dace5221ff..bc2658f6672 100644 --- a/code/modules/mob/living/carbon/human/species_types/vampire.dm +++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm @@ -68,7 +68,7 @@ to_chat(vampire, span_warning("You don't belong here!")) vampire.adjustFireLoss(10 * delta_time) vampire.adjust_fire_stacks(3 * delta_time) - vampire.IgniteMob() + vampire.ignite_mob() /datum/species/vampire/check_species_weakness(obj/item/weapon, mob/living/attacker) if(istype(weapon, /obj/item/nullrod/whip)) diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index fcfd8585513..c40fa5b8b56 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -71,8 +71,6 @@ handle_traits(delta_time, times_fired) // eye, ear, brain damages handle_status_effects(delta_time, times_fired) //all special effects, stun, knockdown, jitteryness, hallucination, sleeping, etc - handle_fire(delta_time, times_fired) - if(machine) machine.check_eye(src) @@ -110,23 +108,6 @@ else // this is a hot place adjust_bodytemperature(min(min(temp_delta / BODYTEMP_DIVISOR, BODYTEMP_HEATING_MAX) * delta_time, temp_delta)) -/mob/living/proc/handle_fire(delta_time, times_fired) - if(fire_stacks < 0) //If we've doused ourselves in water to avoid fire, dry off slowly - set_fire_stacks(min(0, fire_stacks + (0.5 * delta_time))) //So we dry ourselves back to default, nonflammable. - if(!on_fire) - return TRUE //the mob is no longer on fire, no need to do the rest. - if(fire_stacks > 0) - adjust_fire_stacks(-0.05 * delta_time) //the fire is slowly consumed - else - extinguish_mob() - return TRUE //mob was put out, on_fire = FALSE via extinguish_mob(), no need to update everything down the chain. - var/datum/gas_mixture/G = loc.return_air() // Check if we're standing in an oxygenless environment - if(!G.gases[/datum/gas/oxygen] || G.gases[/datum/gas/oxygen][MOLES] < 1) - extinguish_mob() //If there's no oxygen in the tile we're on, put out the fire - return TRUE - var/turf/location = get_turf(src) - location.hotspot_expose(700, 25 * delta_time, TRUE) - /** * Get the fullness of the mob * diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index ec5a6deb475..ffe76c768fa 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -839,7 +839,6 @@ hallucination = 0 heal_overall_damage(INFINITY, INFINITY, INFINITY, null, TRUE) //heal brute and burn dmg on both organic and robotic limbs, and update health right away. extinguish_mob() - fire_stacks = 0 set_confusion(0) set_drowsyness(0) jitteriness = 0 @@ -1385,27 +1384,28 @@ G.Recall() to_chat(G, span_holoparasite("Your summoner has changed form!")) -/mob/living/proc/fakefireextinguish() - return - -/mob/living/proc/fakefire() - return - /mob/living/proc/unfry_mob() //Callback proc to tone down spam from multiple sizzling frying oil dipping. REMOVE_TRAIT(src, TRAIT_OIL_FRIED, "cooking_oil_react") //Mobs on Fire -/mob/living/proc/IgniteMob() - if(fire_stacks <= 0 || on_fire) + +/// Global list that containes cached fire overlays for mobs +GLOBAL_LIST_EMPTY(fire_appearances) + +/mob/living/proc/ignite_mob() + if(fire_stacks <= 0) return FALSE - on_fire = TRUE - src.visible_message(span_warning("[src] catches fire!"), \ - span_userdanger("You're set on fire!")) - firelight_ref = WEAKREF(new /obj/effect/dummy/lighting_obj/moblight/fire(src)) - throw_alert(ALERT_FIRE, /atom/movable/screen/alert/fire) - update_fire() - SEND_SIGNAL(src, COMSIG_LIVING_IGNITED,src) - return TRUE + + var/datum/status_effect/fire_handler/fire_stacks/fire_status = has_status_effect(/datum/status_effect/fire_handler/fire_stacks) + if(!fire_status || fire_status.on_fire) + return FALSE + + return fire_status.ignite() + +/mob/living/proc/update_fire() + var/datum/status_effect/fire_handler/fire_handler = has_status_effect(/datum/status_effect/fire_handler) + if(fire_handler) + fire_handler.update_overlay() /** * Extinguish all fire on the mob @@ -1414,15 +1414,10 @@ * Signals the extinguishing. */ /mob/living/proc/extinguish_mob() - if(!on_fire) + var/datum/status_effect/fire_handler/fire_stacks/fire_status = has_status_effect(/datum/status_effect/fire_handler/fire_stacks) + if(!fire_status || !fire_status.on_fire) return - on_fire = FALSE - fire_stacks = min(0, fire_stacks) //Makes sure we don't get rid of negative firestacks. - QDEL_NULL(firelight_ref) - clear_alert(ALERT_FIRE) - SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "on_fire") - SEND_SIGNAL(src, COMSIG_LIVING_EXTINGUISHED, src) - update_fire() + remove_status_effect(/datum/status_effect/fire_handler/fire_stacks) /** * Adjust the amount of fire stacks on a mob @@ -1430,10 +1425,19 @@ * This modifies the fire stacks on a mob. * * Vars: - * * add_fire_stacks: int The amount to modify the fire stacks + * * stacks: int The amount to modify the fire stacks + * * fire_type: type Type of fire status effect that we apply, should be subtype of /datum/status_effect/fire_handler/fire_stacks */ -/mob/living/proc/adjust_fire_stacks(add_fire_stacks) - set_fire_stacks(fire_stacks + add_fire_stacks) + +/mob/living/proc/adjust_fire_stacks(stacks, fire_type = /datum/status_effect/fire_handler/fire_stacks) + if(stacks < 0) + stacks = max(-fire_stacks, stacks) + apply_status_effect(fire_type, stacks) + +/mob/living/proc/adjust_wet_stacks(stacks, wet_type = /datum/status_effect/fire_handler/wet_stacks) + if(stacks < 0) + stacks = max(fire_stacks, stacks) + apply_status_effect(wet_type, stacks) /** * Set the fire stacks on a mob @@ -1443,38 +1447,95 @@ * * Vars: * * stacks: int The amount to set fire_stacks to + * * fire_type: type Type of fire status effect that we apply, should be subtype of /datum/status_effect/fire_handler/fire_stacks + * * remove_wet_stacks: bool If we remove all wet stacks upon doing this */ -/mob/living/proc/set_fire_stacks(stacks) - fire_stacks = clamp(stacks, -20, 20) - if(fire_stacks <= 0) - extinguish_mob() +/mob/living/proc/set_fire_stacks(stacks, fire_type = /datum/status_effect/fire_handler/fire_stacks, remove_wet_stacks = TRUE) + if(stacks < 0) //Shouldn't happen, ever + CRASH("set_fire_stacks recieved negative [stacks] fire stacks") + + if(remove_wet_stacks) + remove_status_effect(/datum/status_effect/fire_handler/wet_stacks) + + if(stacks == 0) + remove_status_effect(fire_type) + return + + apply_status_effect(fire_type, stacks, TRUE) + +/mob/living/proc/set_wet_stacks(stacks, wet_type = /datum/status_effect/fire_handler/wet_stacks, remove_fire_stacks = TRUE) + if(stacks < 0) + CRASH("set_wet_stacks recieved negative [stacks] wet stacks") + + if(remove_fire_stacks) + remove_status_effect(/datum/status_effect/fire_handler/fire_stacks) + + if(stacks == 0) + remove_status_effect(wet_type) + return + + apply_status_effect(wet_type, stacks, TRUE) //Share fire evenly between the two mobs //Called in MobBump() and Crossed() -/mob/living/proc/spreadFire(mob/living/L) - if(!istype(L)) +/mob/living/proc/spreadFire(mob/living/spread_to) + if(!istype(spread_to)) return // can't spread fire to mobs that don't catch on fire - if(HAS_TRAIT(L, TRAIT_NOFIRE_SPREAD) || HAS_TRAIT(src, TRAIT_NOFIRE_SPREAD)) + if(HAS_TRAIT(spread_to, TRAIT_NOFIRE_SPREAD) || HAS_TRAIT(src, TRAIT_NOFIRE_SPREAD)) return - if(on_fire) - if(L.on_fire) // If they were also on fire - var/firesplit = (fire_stacks + L.fire_stacks)/2 - set_fire_stacks(firesplit) - L.set_fire_stacks(firesplit) - else // If they were not - set_fire_stacks(fire_stacks / 2) - L.adjust_fire_stacks(fire_stacks) - if(L.IgniteMob()) // Ignite them - log_game("[key_name(src)] bumped into [key_name(L)] and set them on fire") + var/datum/status_effect/fire_handler/fire_stacks/fire_status = has_status_effect(/datum/status_effect/fire_handler/fire_stacks) + var/datum/status_effect/fire_handler/fire_stacks/their_fire_status = spread_to.has_status_effect(/datum/status_effect/fire_handler/fire_stacks) + if(fire_status && fire_status.on_fire) + if(their_fire_status && their_fire_status.on_fire) + var/firesplit = (fire_stacks + spread_to.fire_stacks) / 2 + var/fire_type = (spread_to.fire_stacks > fire_stacks) ? their_fire_status.type : fire_status.type + set_fire_stacks(firesplit, fire_type) + spread_to.set_fire_stacks(firesplit, fire_type) + return - else if(L.on_fire) // If they were on fire and we were not - L.set_fire_stacks(L.fire_stacks / 2) - adjust_fire_stacks(L.fire_stacks) - IgniteMob() // Ignite us + adjust_fire_stacks(-fire_stacks / 2, fire_status.type) + spread_to.adjust_fire_stacks(fire_stacks, fire_status.type) + if(spread_to.ignite_mob()) + log_game("[key_name(src)] bumped into [key_name(spread_to)] and set them on fire") + return + + if(!their_fire_status || !their_fire_status.on_fire) + return + + spread_to.adjust_fire_stacks(-spread_to.fire_stacks / 2, their_fire_status.type) + adjust_fire_stacks(spread_to.fire_stacks, their_fire_status.type) + ignite_mob() + +/** + * Sets fire overlay of the mob. + * + * Vars: + * * stacks: Current amount of fire_stacks + * * on_fire: If we're lit on fire + * * last_icon_state: Holds last fire overlay icon state, used for optimization + * * suffix: Suffix for the fire icon state for special fire types + * + * This should return last_icon_state for the fire status efect + */ + +/mob/living/proc/update_fire_overlay(stacks, on_fire, last_icon_state, suffix = "") + return last_icon_state + +/** + * Handles effects happening when mob is on normal fire + * + * Vars: + * * delta_time + * * times_fired + * * fire_handler: Current fire status effect that called the proc + */ + +/mob/living/proc/on_fire_stack(delta_time, times_fired, datum/status_effect/fire_handler/fire_stacks/fire_handler) + return //Mobs on Fire end @@ -1636,9 +1697,6 @@ if(NAMEOF(src, resting)) set_resting(var_value) . = TRUE - if(NAMEOF(src, fire_stacks)) - set_fire_stacks(var_value) - . = TRUE if(NAMEOF(src, lying_angle)) set_lying_angle(var_value) . = TRUE diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 48b9fdf8ca0..6cdfddfd067 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -129,7 +129,7 @@ /mob/living/fire_act() adjust_fire_stacks(3) - IgniteMob() + ignite_mob() /mob/living/proc/grabbedby(mob/living/carbon/user, supress_message = FALSE) if(user == src || anchored || !isturf(user.loc)) diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 93c5c3ba72b..2c2895c0097 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -54,6 +54,10 @@ var/last_special = 0 ///Used by the resist verb, likely used to prevent players from bypassing next_move by logging in/out. var/timeofdeath = 0 + /// Helper vars for quick access to firestacks, these should be updated every time firestacks are adjusted + var/on_fire = FALSE + var/fire_stacks = 0 + /** * Allows mobs to move through dense areas without restriction. For instance, in space or out of holder objects. * @@ -75,11 +79,6 @@ /// Time of death var/tod = null - var/on_fire = FALSE ///The "Are we on fire?" var - /// Weak reference to the light our fire is causing, if there is one - var/datum/weakref/firelight_ref - var/fire_stacks = 0 ///Tracks how many stacks of fire we have on, max is usually 20 - var/limb_destroyer = 0 //1 Sets AI behavior that allows mobs to target and dismember limbs with their basic attack. var/mob_size = MOB_SIZE_HUMAN diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index e94cd69739a..80b12659a01 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -241,9 +241,8 @@ if(istype(A, initial(AM.power_type))) qdel(A) -/mob/living/silicon/ai/IgniteMob() - fire_stacks = 0 - . = ..() +/mob/living/silicon/ai/ignite_mob() + return FALSE /mob/living/silicon/ai/proc/set_core_display_icon(input, client/C) if(client && !C) diff --git a/code/modules/mob/living/silicon/pai/pai_defense.dm b/code/modules/mob/living/silicon/pai/pai_defense.dm index 066cd3497f5..886703c9b8c 100644 --- a/code/modules/mob/living/silicon/pai/pai_defense.dm +++ b/code/modules/mob/living/silicon/pai/pai_defense.dm @@ -61,9 +61,8 @@ src.visible_message(span_warning("The electrically-charged projectile disrupts [src]'s holomatrix, forcing [src] to fold in!")) . = ..(Proj) -/mob/living/silicon/pai/IgniteMob() - fire_stacks = 0 - . = ..() +/mob/living/silicon/pai/ignite_mob() + return FALSE /mob/living/silicon/pai/proc/take_holo_damage(amount) emitterhealth = clamp((emitterhealth - amount), -50, emittermaxhealth) diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm index 86c75b7ae8e..f881365350f 100644 --- a/code/modules/mob/living/silicon/robot/life.dm +++ b/code/modules/mob/living/silicon/robot/life.dm @@ -70,23 +70,3 @@ throw_alert(ALERT_CHARGE, /atom/movable/screen/alert/emptycell) else throw_alert(ALERT_CHARGE, /atom/movable/screen/alert/nocell) - -//Robots on fire -/mob/living/silicon/robot/handle_fire(delta_time, times_fired) - . = ..() - if(.) //if the mob isn't on fire anymore - return - if(fire_stacks > 0) - adjust_fire_stacks(-0.5 * delta_time) - else - extinguish_mob() - return TRUE - - //adjustFireLoss(3) - -/mob/living/silicon/robot/update_fire() - var/mutable_appearance/fire_overlay = mutable_appearance('icons/mob/OnFire.dmi', "Generic_mob_burning") - if(on_fire) - add_overlay(fire_overlay) - else - cut_overlay(fire_overlay) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index e0cd26a7607..1b201c068fb 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -983,3 +983,23 @@ /mob/living/silicon/robot/proc/untip_roleplay() to_chat(src, span_notice("Your frustration has empowered you! You can now right yourself faster!")) + +/mob/living/silicon/robot/update_fire_overlay(stacks, on_fire, last_icon_state, suffix = "") + var/fire_icon = "generic_burning[suffix]" + + if(!GLOB.fire_appearances[fire_icon]) + var/mutable_appearance/new_fire_overlay = mutable_appearance('icons/mob/onfire.dmi', fire_icon, -FIRE_LAYER) + new_fire_overlay.appearance_flags = RESET_COLOR + GLOB.fire_appearances[fire_icon] = new_fire_overlay + + if(stacks && on_fire) + if(last_icon_state == fire_icon) + return last_icon_state + add_overlay(GLOB.fire_appearances[fire_icon]) + return fire_icon + + if(!last_icon_state) + return last_icon_state + + cut_overlay(GLOB.fire_appearances[fire_icon]) + return null diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm index 911aeaeeec9..3b3c4d1b997 100644 --- a/code/modules/mob/living/silicon/robot/robot_defense.dm +++ b/code/modules/mob/living/silicon/robot/robot_defense.dm @@ -312,7 +312,7 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real /mob/living/silicon/robot/fire_act() if(!on_fire) //Silicons don't gain stacks from hotspots, but hotspots can ignite them - IgniteMob() + ignite_mob() /mob/living/silicon/robot/emp_act(severity) . = ..() diff --git a/code/modules/mob/living/simple_animal/guardian/types/fire.dm b/code/modules/mob/living/simple_animal/guardian/types/fire.dm index 68828e60abf..fa53d7208ea 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/fire.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/fire.dm @@ -49,4 +49,4 @@ var/mob/living/M = AM if(!hasmatchingsummoner(M) && M != summoner && M.fire_stacks < 7) M.set_fire_stacks(7) - M.IgniteMob() + M.ignite_mob() diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm b/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm index 8725c28a6c1..09a3d31bd18 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm @@ -163,7 +163,7 @@ K.transform = final living_target.adjustFireLoss(30) living_target.adjust_fire_stacks(0.2)//Just here for the showmanship - living_target.IgniteMob() + living_target.ignite_mob() playsound(living_target,'sound/weapons/sear.ogg', 50, TRUE) addtimer(CALLBACK(src, .proc/AttackRecovery), 5) return diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm index 57821a0f0c4..4c7c1a583b9 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm @@ -203,7 +203,7 @@ var/mob/living/L = target if (istype(L)) L.adjust_fire_stacks(0.1) - L.IgniteMob() + L.ignite_mob() /obj/projectile/temp/basilisk/icewing damage = 5 diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm index c050407b86f..04c704eb74b 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm @@ -294,7 +294,7 @@ if(isliving(mover)) var/mob/living/fire_walker = mover fire_walker.adjust_fire_stacks(5) - fire_walker.IgniteMob() + fire_walker.ignite_mob() /obj/structure/legionnaire_bonfire/Destroy() if(myowner != null) diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 3c419ae671c..939b00c8454 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -490,10 +490,7 @@ return FALSE return TRUE -/mob/living/simple_animal/handle_fire(delta_time, times_fired) - return TRUE - -/mob/living/simple_animal/IgniteMob() +/mob/living/simple_animal/ignite_mob() return FALSE /mob/living/simple_animal/extinguish_mob() diff --git a/code/modules/mob/mob_update_icons.dm b/code/modules/mob/mob_update_icons.dm index 91db373f663..69c3d09c834 100644 --- a/code/modules/mob/mob_update_icons.dm +++ b/code/modules/mob/mob_update_icons.dm @@ -49,9 +49,6 @@ /mob/proc/update_hair() return -/mob/proc/update_fire() - return - /mob/proc/update_inv_gloves() return diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index acf0cb81730..3faee2819e9 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -211,7 +211,7 @@ if(user.is_holding(I)) //checking if they're holding it in case TK is involved user.dropItemToGround(I) user.adjust_fire_stacks(1) - user.IgniteMob() + user.ignite_mob() return if(user.is_holding(src)) //no TK shit here. diff --git a/code/modules/paperwork/ticketmachine.dm b/code/modules/paperwork/ticketmachine.dm index 36dec11944e..ddd667c325e 100644 --- a/code/modules/paperwork/ticketmachine.dm +++ b/code/modules/paperwork/ticketmachine.dm @@ -206,7 +206,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/ticket_machine, 32) theirticket.fire_act() user.dropItemToGround(theirticket) user.adjust_fire_stacks(1) - user.IgniteMob() + user.ignite_mob() return /obj/item/ticket_machine_ticket diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index 5636cac5203..6247979ae8b 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -396,7 +396,7 @@ span_userdanger("You feel an inner fire as your skin bursts into flames!") ) burned_mob.adjust_fire_stacks(5) - burned_mob.IgniteMob() + burned_mob.ignite_mob() return /obj/singularity/proc/mezzer() diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index f14ab16058e..663d9319804 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -139,7 +139,7 @@ var/mob/living/user = loc user.visible_message(span_danger("Concentrated plasma discharges from [src] onto [user], burning them!"), span_userdanger("[src] malfunctions, spewing concentrated plasma onto you! It burns!")) user.adjust_fire_stacks(4) - user.IgniteMob() + user.ignite_mob() // Can we weld? Plasma cutter does not use charge continuously. // Amount cannot be defaulted to 1: most of the code specifies 0 in the call. diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index faf66cf394a..bd578b0545b 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -50,7 +50,7 @@ . = ..() if(iscarbon(target)) var/mob/living/carbon/M = target - M.IgniteMob() + M.ignite_mob() else if(isturf(target)) impact_effect_type = /obj/effect/temp_visual/impact_effect/red_laser/wall diff --git a/code/modules/projectiles/projectile/bullets/_incendiary.dm b/code/modules/projectiles/projectile/bullets/_incendiary.dm index a28b5f45a95..508cf3d6587 100644 --- a/code/modules/projectiles/projectile/bullets/_incendiary.dm +++ b/code/modules/projectiles/projectile/bullets/_incendiary.dm @@ -10,7 +10,7 @@ if(iscarbon(target)) var/mob/living/carbon/M = target M.adjust_fire_stacks(fire_stacks) - M.IgniteMob() + M.ignite_mob() /obj/projectile/bullet/incendiary/Move() . = ..() diff --git a/code/modules/projectiles/projectile/bullets/revolver.dm b/code/modules/projectiles/projectile/bullets/revolver.dm index 8a0b0ca51a5..8a9ce8c7649 100644 --- a/code/modules/projectiles/projectile/bullets/revolver.dm +++ b/code/modules/projectiles/projectile/bullets/revolver.dm @@ -88,7 +88,7 @@ if(iscarbon(target)) var/mob/living/carbon/M = target M.adjust_fire_stacks(6) - M.IgniteMob() + M.ignite_mob() /obj/projectile/bullet/c38/iceblox //see /obj/projectile/temp for the original code name = ".38 Iceblox bullet" diff --git a/code/modules/reagents/chemistry/items.dm b/code/modules/reagents/chemistry/items.dm index 2ef48dbe7e8..8d84e0edae6 100644 --- a/code/modules/reagents/chemistry/items.dm +++ b/code/modules/reagents/chemistry/items.dm @@ -242,7 +242,7 @@ user.visible_message(span_notice("[user] snuffs out [src]'s flame.")) /obj/item/burner/attack(mob/living/carbon/M, mob/living/carbon/user) - if(lit && M.IgniteMob()) + if(lit && M.ignite_mob()) message_admins("[ADMIN_LOOKUPFLW(user)] set [key_name_admin(M)] on fire with [src] at [AREACOORD(user)]") log_game("[key_name(user)] set [key_name(M)] on fire with [src] at [AREACOORD(user)]") return ..() diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm index 2b483db33f3..503dd19a0ff 100644 --- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm @@ -2441,7 +2441,7 @@ All effects don't start immediately, but rather get worse over time; the rate is drinker.adjust_bodytemperature(25 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * delta_time) if (DT_PROB(2.5, delta_time)) drinker.adjust_fire_stacks(1) - drinker.IgniteMob() + drinker.ignite_mob() ..() /datum/reagent/consumable/ethanol/painkiller diff --git a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm index fc96c9a079e..c32f59995e0 100644 --- a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm @@ -221,7 +221,7 @@ return exposed_mob.adjust_bodytemperature(-reac_volume * TEMPERATURE_DAMAGE_COEFFICIENT, 50) - exposed_mob.adjust_fire_stacks(-reac_volume / 2) + exposed_mob.adjust_fire_stacks(reac_volume / -2) if(reac_volume >= metabolization_rate) exposed_mob.extinguish_mob() diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index f80a33da2c2..399bf14fae7 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -395,7 +395,7 @@ /datum/reagent/hellwater/on_mob_life(mob/living/carbon/M, delta_time, times_fired) M.set_fire_stacks(min(M.fire_stacks + (1.5 * delta_time), 5)) - M.IgniteMob() //Only problem with igniting people is currently the commonly available fire suits make you immune to being on fire + M.ignite_mob() //Only problem with igniting people is currently the commonly available fire suits make you immune to being on fire M.adjustToxLoss(0.5*delta_time, 0) M.adjustFireLoss(0.5*delta_time, 0) //Hence the other damages... ain't I a bastard? M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2.5*delta_time, 150) diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm index bc6120804c9..e745a777c4f 100644 --- a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm @@ -73,7 +73,7 @@ /datum/reagent/clf3/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume) . = ..() exposed_mob.adjust_fire_stacks(min(reac_volume/5, 10)) - exposed_mob.IgniteMob() + exposed_mob.ignite_mob() if(!locate(/obj/effect/hotspot) in exposed_mob.loc) new /obj/effect/hotspot(exposed_mob.loc) @@ -185,7 +185,7 @@ exposed_mob.adjust_fire_stacks(1) var/burndmg = max(0.3*exposed_mob.fire_stacks, 0.3) exposed_mob.adjustFireLoss(burndmg, 0) - exposed_mob.IgniteMob() + exposed_mob.ignite_mob() /datum/reagent/phlogiston/on_mob_life(mob/living/carbon/metabolizer, delta_time, times_fired) metabolizer.adjust_fire_stacks(1 * REM * delta_time) diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index 21230dc4bdc..c1c93d011c9 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -424,7 +424,7 @@ /datum/reagent/toxin/spore_burning/on_mob_life(mob/living/carbon/M, delta_time, times_fired) M.adjust_fire_stacks(2 * REM * delta_time) - M.IgniteMob() + M.ignite_mob() return ..() /datum/reagent/toxin/chloralhydrate diff --git a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm index 08385f6e134..bc47036a636 100644 --- a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm +++ b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm @@ -140,7 +140,7 @@ to_chat(C, span_userdanger("The divine explosion sears you!")) C.Paralyze(40) C.adjust_fire_stacks(5) - C.IgniteMob() + C.ignite_mob() ..() /datum/chemical_reaction/gunpowder diff --git a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm index 56331313e09..efc557c93c5 100644 --- a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm +++ b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm @@ -632,7 +632,7 @@ /datum/status_effect/stabilized/darkblue/tick() if(owner.fire_stacks > 0 && prob(80)) - owner.adjust_fire_stacks(-1) + owner.adjust_wet_stacks(1) if(owner.fire_stacks <= 0) to_chat(owner, span_notice("[linked_extract] coats you in a watery goo, extinguishing the flames.")) var/obj/O = owner.get_active_held_item() diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index 158a84c807a..f34e1dba11c 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -331,7 +331,7 @@ if(SLIME_ACTIVATE_MINOR) to_chat(user, span_notice("You activate [src]. You start feeling colder!")) user.extinguish_mob() - user.adjust_fire_stacks(-20) + user.adjust_wet_stacks(20) user.reagents.add_reagent(/datum/reagent/consumable/frostoil,6) user.reagents.add_reagent(/datum/reagent/medicine/regen_jelly,7) return 100 diff --git a/code/modules/spells/spell_types/wizard.dm b/code/modules/spells/spell_types/wizard.dm index ff6decd92ab..e803bf74d74 100644 --- a/code/modules/spells/spell_types/wizard.dm +++ b/code/modules/spells/spell_types/wizard.dm @@ -291,9 +291,9 @@ if(isliving(user)) var/mob/living/caster = user if(caster.can_cast_magic(antimagic_flags)) - caster.IgniteMob() + caster.ignite_mob() else - return + return for(var/mob/living/target in targets) if(target.can_block_magic(antimagic_flags)) to_chat(user, span_warning("The spell can't seem to affect [target]!")) diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm index 516c61913a2..308d72f1022 100644 --- a/code/modules/surgery/organs/augments_arms.dm +++ b/code/modules/surgery/organs/augments_arms.dm @@ -201,7 +201,7 @@ playsound(get_turf(owner), 'sound/weapons/flashbang.ogg', 100, TRUE) to_chat(owner, span_userdanger("You feel an explosion erupt inside your [zone == BODY_ZONE_R_ARM ? "right" : "left"] arm as your implant breaks!")) owner.adjust_fire_stacks(20) - owner.IgniteMob() + owner.ignite_mob() owner.adjustFireLoss(25) organ_flags |= ORGAN_FAILING diff --git a/code/modules/unit_tests/resist.dm b/code/modules/unit_tests/resist.dm index 208c9d0cad3..28f6ea88011 100644 --- a/code/modules/unit_tests/resist.dm +++ b/code/modules/unit_tests/resist.dm @@ -5,7 +5,7 @@ TEST_ASSERT_EQUAL(human.fire_stacks, 0, "Human does not have 0 fire stacks pre-ignition") human.adjust_fire_stacks(5) - human.IgniteMob() + human.ignite_mob() TEST_ASSERT_EQUAL(human.fire_stacks, 5, "Human does not have 5 fire stacks pre-resist") diff --git a/code/modules/vehicles/mecha/_mecha.dm b/code/modules/vehicles/mecha/_mecha.dm index 07027957214..b1c3cbbd6b3 100644 --- a/code/modules/vehicles/mecha/_mecha.dm +++ b/code/modules/vehicles/mecha/_mecha.dm @@ -577,7 +577,7 @@ for(var/mob/living/cookedalive as anything in occupants) if(cookedalive.fire_stacks < 5) cookedalive.adjust_fire_stacks(1) - cookedalive.IgniteMob() + cookedalive.ignite_mob() ///Displays a special speech bubble when someone inside the mecha speaks /obj/vehicle/sealed/mecha/proc/display_speech_bubble(datum/source, list/speech_args) diff --git a/icons/mob/onfire.dmi b/icons/mob/onfire.dmi index 7768bf0269f..4fa6ec88acd 100644 Binary files a/icons/mob/onfire.dmi and b/icons/mob/onfire.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 4d7da11fe26..2d098f298b9 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1121,6 +1121,7 @@ #include "code\datums\status_effects\debuffs\dizziness.dm" #include "code\datums\status_effects\debuffs\drugginess.dm" #include "code\datums\status_effects\debuffs\drunk.dm" +#include "code\datums\status_effects\debuffs\fire_stacks.dm" #include "code\datums\status_effects\debuffs\speech_debuffs.dm" #include "code\datums\weather\weather.dm" #include "code\datums\weather\weather_types\ash_storm.dm"