mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-22 04:30:44 +01:00
Refactors firestacks into status effects (#66573)
This PR refactors firestacks into two status effects: fire_stacks, which behave like normal firestacks you have right now, and wet_stacks, which are your negative fire stacks right now. This allows for custom fires with custom behaviors and icons to be made. Some fire related is moved away from species(what the fuck was it even doing there) into these as well. Oh and I fixed the bug where monkeys on fire had a human fire overlay, why wasn't this fixed already, it's like ancient. Also changed some related proc names to be snake_case like everything should be. This allows for custom fire types with custom behaviours, like freezing freon fire or radioactive tritium fire. Removing vars from living and moving them to status effects for modularity is also good. Nothing to argue about since there's nothing player-facing
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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!
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -214,9 +214,9 @@
|
||||
msg += "<b>[t_He] [t_has] severe cellular damage!</b>\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"
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 //
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
. = ..()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -49,9 +49,6 @@
|
||||
/mob/proc/update_hair()
|
||||
return
|
||||
|
||||
/mob/proc/update_fire()
|
||||
return
|
||||
|
||||
/mob/proc/update_inv_gloves()
|
||||
return
|
||||
|
||||
|
||||
Reference in New Issue
Block a user