mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-24 05:30:05 +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:
@@ -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"
|
||||
|
||||
@@ -38,3 +38,4 @@
|
||||
#define STASIS_CHEMICAL_EFFECT "stasis_chemical"
|
||||
|
||||
#define STASIS_ASCENSION_EFFECT "heretic_ascension"
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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..."))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(..())
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)]")
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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!"))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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!"))
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
var/obj/item/seeds/our_seed = our_plant.get_plant_seed()
|
||||
to_chat(target, "<span class='danger'>You are lit on fire from the intense heat of [our_plant]!</span>")
|
||||
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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
. = ..()
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 ..()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]!"))
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user