mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-30 08:37:43 +01:00
Acid particles (+unsorted acid/burning/thermite component changes) (#75248)
This PR is way less than the file changes make it seem like it is. Okay, first, the boring part: - Picking up burning items is now a signal registered on the burning component itself, instead of being a direct /obj/item/attack_hand() check - Sear sound now has an SFX define for convenience, since it is very commonly used - Fire stacks when extinguished on mobs will no longer clean acid on items (WTF?)
This commit is contained in:
@@ -131,8 +131,6 @@
|
||||
#define FIRE_MINIMUM_TEMPERATURE_TO_SPREAD (150+T0C)
|
||||
///Minimum temperature for fire to exist on a turf (100 °C or 373 K)
|
||||
#define FIRE_MINIMUM_TEMPERATURE_TO_EXIST (100+T0C)
|
||||
///Minimum temperature for items on fire
|
||||
#define BURNING_ITEM_MINIMUM_TEMPERATURE (150+T0C)
|
||||
///Multiplier for the temperature shared to other turfs
|
||||
#define FIRE_SPREAD_RADIOSITY_SCALE 0.85
|
||||
///Helper for small fires to grow
|
||||
|
||||
@@ -144,3 +144,6 @@
|
||||
#define SHOES_MIN_TEMP_PROTECT 2.0
|
||||
/// For gloves
|
||||
#define SHOES_MAX_TEMP_PROTECT 1500
|
||||
|
||||
///Minimum temperature for items on fire
|
||||
#define BURNING_ITEM_MINIMUM_TEMPERATURE (150+T0C)
|
||||
|
||||
@@ -147,6 +147,7 @@ GLOBAL_LIST_INIT(announcer_keys, list(
|
||||
#define SFX_EXPLOSION_CREAKING "explosion_creaking"
|
||||
#define SFX_HISS "hiss"
|
||||
#define SFX_HONKBOT_E "honkbot_e"
|
||||
#define SFX_GOOSE "goose"
|
||||
#define SFX_HULL_CREAKING "hull_creaking"
|
||||
#define SFX_HYPERTORUS_CALM "hypertorus_calm"
|
||||
#define SFX_HYPERTORUS_MELTING "hypertorus_melting"
|
||||
@@ -168,3 +169,4 @@ GLOBAL_LIST_INIT(announcer_keys, list(
|
||||
#define SFX_CRUNCHY_BUSH_WHACK "crunchy_bush_whack"
|
||||
#define SFX_TREE_CHOP "tree_chop"
|
||||
#define SFX_ROCK_TAP "rock_tap"
|
||||
#define SFX_SEAR "sear"
|
||||
|
||||
@@ -15,43 +15,45 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
var/acid_volume
|
||||
/// The maximum volume of acid on the parent [/atom].
|
||||
var/max_volume = INFINITY
|
||||
/// Acid overlay appearance we apply
|
||||
var/acid_overlay
|
||||
/// The ambiant sound of acid eating away at the parent [/atom].
|
||||
var/datum/looping_sound/acid/sizzle
|
||||
/// Used exclusively for melting turfs. TODO: Move integrity to the atom level so that this can be dealt with there.
|
||||
var/parent_integrity = 30
|
||||
/// How far the acid melting of turfs has progressed
|
||||
var/stage = 0
|
||||
/// Acid overlay appearance we apply
|
||||
var/acid_overlay
|
||||
/// The ambient sound of acid eating away at the parent [/atom].
|
||||
var/datum/looping_sound/acid/sizzle
|
||||
/// Particle holder for acid particles (sick)
|
||||
var/obj/effect/abstract/particle_holder/particle_effect
|
||||
/// The proc used to handle the parent [/atom] when processing. TODO: Unify damage and resistance flags so that this doesn't need to exist!
|
||||
var/datum/callback/process_effect
|
||||
|
||||
/datum/component/acid/Initialize(acid_power = ACID_POWER_MELT_TURF, acid_volume = 50, acid_overlay = GLOB.acid_overlay)
|
||||
/datum/component/acid/Initialize(acid_power = ACID_POWER_MELT_TURF, acid_volume = 50, acid_overlay = GLOB.acid_overlay, acid_particles = /particles/acid)
|
||||
if(!isatom(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
//not incompatible, but pointless
|
||||
|
||||
// The parent object cannot have acid. Not incompatible, but should not really happen.
|
||||
var/atom/atom_parent = parent
|
||||
if((acid_power) <= 0 || (acid_volume <= 0))
|
||||
stack_trace("Acid component added to an atom ([atom_parent.type]) with insufficient acid power ([acid_power]) or acid volume ([acid_volume]).")
|
||||
if(atom_parent.resistance_flags & UNACIDABLE)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
//Not incompatible, but pointless
|
||||
if((acid_power <= 0) || (acid_volume <= 0))
|
||||
qdel(src)
|
||||
stack_trace("Tried to add /datum/component/acid to an atom ([atom_parent.type]) with insufficient acid power ([acid_power]) or acid volume ([acid_volume]).")
|
||||
return
|
||||
|
||||
if(isliving(parent))
|
||||
max_volume = MOB_ACID_VOLUME_MAX
|
||||
process_effect = CALLBACK(src, PROC_REF(process_mob), parent)
|
||||
src.max_volume = MOB_ACID_VOLUME_MAX
|
||||
src.process_effect = CALLBACK(src, PROC_REF(process_mob), parent)
|
||||
else if(isturf(parent))
|
||||
max_volume = TURF_ACID_VOLUME_MAX
|
||||
process_effect = CALLBACK(src, PROC_REF(process_turf), parent)
|
||||
src.max_volume = TURF_ACID_VOLUME_MAX
|
||||
src.process_effect = CALLBACK(src, PROC_REF(process_turf), parent)
|
||||
//if we failed all other checks, we must be an /atom/movable that uses integrity
|
||||
else if(atom_parent.uses_integrity)
|
||||
// The parent object cannot have acid. Not incompatible, but should not really happen.
|
||||
if(atom_parent.resistance_flags & UNACIDABLE)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
max_volume = MOVABLE_ACID_VOLUME_MAX
|
||||
process_effect = CALLBACK(src, PROC_REF(process_movable), parent)
|
||||
src.max_volume = MOVABLE_ACID_VOLUME_MAX
|
||||
src.process_effect = CALLBACK(src, PROC_REF(process_movable), parent)
|
||||
//or not...
|
||||
else
|
||||
stack_trace("Tried to add /datum/component/acid to an atom ([atom_parent.type]) which does not use atom_integrity!")
|
||||
@@ -61,23 +63,28 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
set_volume(acid_volume)
|
||||
src.acid_overlay = acid_overlay
|
||||
|
||||
sizzle = new(parent, TRUE)
|
||||
sizzle = new(atom_parent, TRUE)
|
||||
if(acid_particles)
|
||||
// acid particles look pretty bad when they stack on mobs, so that behavior is not wanted for items
|
||||
particle_effect = new(atom_parent, acid_particles, isitem(atom_parent) ? NONE : PARTICLE_ATTACH_MOB)
|
||||
START_PROCESSING(SSacid, src)
|
||||
|
||||
/datum/component/acid/Destroy(force, silent)
|
||||
STOP_PROCESSING(SSacid, src)
|
||||
if(sizzle)
|
||||
QDEL_NULL(sizzle)
|
||||
if(particle_effect)
|
||||
QDEL_NULL(particle_effect)
|
||||
if(process_effect)
|
||||
QDEL_NULL(process_effect)
|
||||
return ..()
|
||||
|
||||
/datum/component/acid/RegisterWithParent()
|
||||
RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, PROC_REF(on_attack_hand))
|
||||
RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine))
|
||||
RegisterSignal(parent, COMSIG_ATOM_EXPOSE_REAGENT, PROC_REF(on_expose_reagent))
|
||||
RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(on_update_overlays))
|
||||
RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, PROC_REF(on_clean))
|
||||
RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, PROC_REF(on_attack_hand))
|
||||
RegisterSignal(parent, COMSIG_ATOM_EXPOSE_REAGENT, PROC_REF(on_expose_reagent))
|
||||
if(isturf(parent))
|
||||
RegisterSignal(parent, COMSIG_ATOM_ENTERED, PROC_REF(on_entered))
|
||||
var/atom/atom_parent = parent
|
||||
@@ -85,11 +92,12 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
|
||||
/datum/component/acid/UnregisterFromParent()
|
||||
UnregisterSignal(parent, list(
|
||||
COMSIG_ATOM_ATTACK_HAND,
|
||||
COMSIG_ATOM_EXAMINE,
|
||||
COMSIG_ATOM_EXPOSE_REAGENT,
|
||||
COMSIG_ATOM_UPDATE_OVERLAYS,
|
||||
COMSIG_COMPONENT_CLEAN_ACT,
|
||||
COMSIG_ATOM_ATTACK_HAND,
|
||||
COMSIG_ATOM_EXPOSE_REAGENT))
|
||||
))
|
||||
if(isturf(parent))
|
||||
UnregisterSignal(parent, COMSIG_ATOM_ENTERED)
|
||||
var/atom/atom_parent = parent
|
||||
@@ -98,6 +106,8 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
|
||||
/// Averages corrosive power and sums volume.
|
||||
/datum/component/acid/InheritComponent(datum/component/new_comp, i_am_original, acid_power, acid_volume)
|
||||
if(!i_am_original)
|
||||
return
|
||||
acid_power = ((src.acid_power * src.acid_volume) + (acid_power * acid_volume)) / (src.acid_volume + acid_volume)
|
||||
set_volume(src.acid_volume + acid_volume)
|
||||
|
||||
@@ -109,6 +119,11 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
|
||||
/// Handles the slow corrosion of the parent [/atom].
|
||||
/datum/component/acid/process(seconds_per_tick)
|
||||
// If we somehow got unacidable, we need to bail out
|
||||
var/atom/parent_atom = parent
|
||||
if(parent_atom.resistance_flags & UNACIDABLE)
|
||||
qdel(src)
|
||||
return
|
||||
process_effect?.InvokeAsync(seconds_per_tick)
|
||||
if(QDELING(src)) //The process effect deals damage, and on turfs diminishes the acid volume, potentially destroying the component. Let's not destroy it twice.
|
||||
return
|
||||
@@ -122,6 +137,8 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
|
||||
/// Handles processing on a [/mob/living].
|
||||
/datum/component/acid/proc/process_mob(mob/living/target, seconds_per_tick)
|
||||
if(target.resistance_flags & ACID_PROOF)
|
||||
return
|
||||
target.acid_act(acid_power, acid_volume * seconds_per_tick)
|
||||
|
||||
/// Handles processing on a [/turf].
|
||||
@@ -135,7 +152,11 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
if(applied_targets)
|
||||
set_volume(acid_volume - (acid_used * applied_targets))
|
||||
|
||||
// Snowflake code for handling acid melting walls. TODO: Move integrity handling to the atom level so this can be desnowflaked.
|
||||
if(target_turf.resistance_flags & ACID_PROOF)
|
||||
return
|
||||
|
||||
// Snowflake code for handling acid melting walls.
|
||||
// We really should consider making turfs use atom_integrity, but for now this is just for acids.
|
||||
if(acid_power < ACID_POWER_MELT_TURF)
|
||||
return
|
||||
|
||||
@@ -189,25 +210,22 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
set_volume(acid_volume + reac_volume)
|
||||
return NONE
|
||||
|
||||
/// Handles searing the hand of anyone who tries to touch this without protection.
|
||||
/datum/component/acid/proc/on_attack_hand(atom/parent_atom, mob/living/carbon/user)
|
||||
/// Handles searing the hand of anyone who tries to touch parent without protection.
|
||||
/datum/component/acid/proc/on_attack_hand(atom/source, mob/living/carbon/user)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!istype(user))
|
||||
return NONE
|
||||
if((parent_atom == user) || (parent_atom.loc == user))
|
||||
return NONE // So people can take their own clothes off.
|
||||
if((acid_power * acid_volume) < ACID_LEVEL_HANDBURN)
|
||||
return NONE
|
||||
if(user.gloves?.resistance_flags & (UNACIDABLE|ACID_PROOF))
|
||||
if(!iscarbon(user) || user.can_touch_acid(source, acid_power, acid_volume))
|
||||
return NONE
|
||||
|
||||
var/obj/item/bodypart/affecting = user.get_bodypart("[(user.active_hand_index % 2 == 0) ? "r" : "l" ]_arm")
|
||||
if(!affecting?.receive_damage(0, 5))
|
||||
var/obj/item/bodypart/affecting = user.get_active_hand()
|
||||
//Should not happen!
|
||||
if(!affecting)
|
||||
return NONE
|
||||
|
||||
to_chat(user, span_warning("The acid on \the [parent_atom] burns your hand!"))
|
||||
playsound(parent_atom, 'sound/weapons/sear.ogg', 50, TRUE)
|
||||
affecting.receive_damage(burn = 5)
|
||||
to_chat(user, span_userdanger("The acid on \the [source] burns your hand!"))
|
||||
INVOKE_ASYNC(user, TYPE_PROC_REF(/mob, emote), "scream")
|
||||
playsound(source, SFX_SEAR, 50, TRUE)
|
||||
user.update_damage_overlays()
|
||||
return COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
|
||||
@@ -226,7 +244,8 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
return
|
||||
|
||||
var/acid_used = min(acid_volume * 0.05, 20)
|
||||
if(crosser.acid_act(acid_power, acid_used, FEET))
|
||||
playsound(crosser, 'sound/weapons/sear.ogg', 50, TRUE)
|
||||
to_chat(crosser, span_userdanger("The acid on the [parent] burns you!"))
|
||||
set_volume(max(acid_volume - acid_used, 10))
|
||||
if(!crosser.acid_act(acid_power, acid_used, FEET))
|
||||
return
|
||||
playsound(crosser, SFX_SEAR, 50, TRUE)
|
||||
to_chat(crosser, span_userdanger("The acid on the [parent] burns you!"))
|
||||
set_volume(max(acid_volume - acid_used, 10))
|
||||
|
||||
@@ -18,10 +18,12 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
if(!atom_parent.uses_integrity)
|
||||
stack_trace("Tried to add /datum/component/burning to an atom ([atom_parent.type]) that does not use atom_integrity!")
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
// only flammable atoms should have this component, but it's not really an error if we try to apply this to a non flammable one
|
||||
if(!(atom_parent.resistance_flags & FLAMMABLE) || (atom_parent.resistance_flags & FIRE_PROOF))
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
src.fire_overlay = fire_overlay
|
||||
if(fire_particles)
|
||||
// burning particles look pretty bad when they stack on mobs, so that behavior is not wanted for items
|
||||
@@ -30,20 +32,27 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
|
||||
/datum/component/burning/Destroy(force, silent)
|
||||
STOP_PROCESSING(SSburning, src)
|
||||
fire_overlay = null
|
||||
if(particle_effect)
|
||||
QDEL_NULL(particle_effect)
|
||||
return ..()
|
||||
|
||||
/datum/component/burning/RegisterWithParent()
|
||||
RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine))
|
||||
RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, PROC_REF(on_attack_hand))
|
||||
RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(on_update_overlays))
|
||||
RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine))
|
||||
RegisterSignal(parent, COMSIG_ATOM_EXTINGUISH, PROC_REF(on_extinguish))
|
||||
var/atom/atom_parent = parent
|
||||
atom_parent.resistance_flags |= ON_FIRE
|
||||
atom_parent.update_appearance()
|
||||
|
||||
/datum/component/burning/UnregisterFromParent()
|
||||
UnregisterSignal(parent, list(COMSIG_ATOM_EXAMINE, COMSIG_ATOM_UPDATE_OVERLAYS, COMSIG_ATOM_EXTINGUISH))
|
||||
UnregisterSignal(parent, list(
|
||||
COMSIG_ATOM_ATTACK_HAND,
|
||||
COMSIG_ATOM_UPDATE_OVERLAYS,
|
||||
COMSIG_ATOM_EXAMINE,
|
||||
COMSIG_ATOM_EXTINGUISH,
|
||||
))
|
||||
var/atom/atom_parent = parent
|
||||
if(!QDELETED(atom_parent))
|
||||
atom_parent.resistance_flags &= ~ON_FIRE
|
||||
@@ -51,7 +60,7 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
|
||||
/datum/component/burning/process(seconds_per_tick)
|
||||
var/atom/atom_parent = parent
|
||||
// Check if the parent somehow became fireproof
|
||||
// Check if the parent somehow became fireproof, remove component if so
|
||||
if(atom_parent.resistance_flags & FIRE_PROOF)
|
||||
atom_parent.extinguish()
|
||||
return
|
||||
@@ -63,6 +72,27 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
|
||||
examine_list += span_danger("[source.p_theyre(TRUE)] burning!")
|
||||
|
||||
/// Handles searing the hand of anyone who tries to touch parent without protection.
|
||||
/datum/component/burning/proc/on_attack_hand(atom/source, mob/living/carbon/user)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!iscarbon(user) || user.can_touch_burning(source))
|
||||
to_chat(user, span_notice("You put out the fire on [source]."))
|
||||
source.extinguish()
|
||||
return COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
|
||||
var/obj/item/bodypart/affecting = user.get_active_hand()
|
||||
//Should not happen!
|
||||
if(!affecting)
|
||||
return NONE
|
||||
|
||||
affecting.receive_damage(burn = 5)
|
||||
to_chat(user, span_userdanger("You burn your hand on [source]!"))
|
||||
INVOKE_ASYNC(user, TYPE_PROC_REF(/mob, emote), "scream")
|
||||
playsound(source, SFX_SEAR, 50, TRUE)
|
||||
user.update_damage_overlays()
|
||||
return COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
|
||||
/// Maintains the burning overlay on the parent atom
|
||||
/datum/component/burning/proc/on_update_overlays(atom/source, list/overlays)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
var/burn_require
|
||||
/// The thermite overlay
|
||||
var/thermite_overlay
|
||||
/// Default thermite overlay, do not touch
|
||||
var/static/mutable_appearance/default_thermite_overlay = mutable_appearance('icons/effects/effects.dmi', "thermite")
|
||||
/// Callback related to burning, stored so the timer can be easily reset without losing the user
|
||||
var/datum/callback/burn_callback
|
||||
/// The timer for burning parent, calls burn_callback when done
|
||||
@@ -13,8 +15,6 @@
|
||||
/// The thermite fire overlay
|
||||
var/obj/effect/overlay/thermite/fakefire
|
||||
|
||||
/// Default thermite overlay, do not touch
|
||||
var/static/mutable_appearance/default_thermite_overlay = mutable_appearance('icons/effects/effects.dmi', "thermite")
|
||||
/// Blacklist of turfs that cannot have thermite on it
|
||||
var/static/list/blacklist = typecacheof(list(
|
||||
/turf/open/lava,
|
||||
@@ -54,32 +54,34 @@
|
||||
|
||||
/datum/component/thermite/Destroy()
|
||||
thermite_overlay = null
|
||||
if(burn_callback)
|
||||
QDEL_NULL(burn_callback)
|
||||
if(burn_timer)
|
||||
deltimer(burn_timer)
|
||||
burn_timer = null
|
||||
if(burn_callback)
|
||||
QDEL_NULL(burn_callback)
|
||||
if(fakefire)
|
||||
QDEL_NULL(fakefire)
|
||||
return ..()
|
||||
|
||||
/datum/component/thermite/RegisterWithParent()
|
||||
RegisterSignal(parent, COMSIG_ATOM_ATTACKBY, PROC_REF(attackby_react))
|
||||
RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, PROC_REF(on_attack_hand))
|
||||
RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine))
|
||||
RegisterSignal(parent, COMSIG_ATOM_FIRE_ACT, PROC_REF(on_fire_act))
|
||||
RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(on_update_overlays))
|
||||
RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, PROC_REF(clean_react))
|
||||
RegisterSignal(parent, COMSIG_ATOM_ATTACKBY, PROC_REF(attackby_react))
|
||||
RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine))
|
||||
RegisterSignal(parent, COMSIG_QDELETING, PROC_REF(parent_qdeleting)) //probably necessary because turfs are wack
|
||||
var/turf/turf_parent = parent
|
||||
turf_parent.update_appearance()
|
||||
|
||||
/datum/component/thermite/UnregisterFromParent()
|
||||
UnregisterSignal(parent, list(
|
||||
COMSIG_ATOM_ATTACKBY,
|
||||
COMSIG_ATOM_ATTACK_HAND,
|
||||
COMSIG_ATOM_EXAMINE,
|
||||
COMSIG_ATOM_FIRE_ACT,
|
||||
COMSIG_ATOM_UPDATE_OVERLAYS,
|
||||
COMSIG_COMPONENT_CLEAN_ACT,
|
||||
COMSIG_ATOM_ATTACKBY,
|
||||
COMSIG_ATOM_EXAMINE,
|
||||
COMSIG_QDELETING,
|
||||
))
|
||||
var/turf/turf_parent = parent
|
||||
@@ -118,7 +120,7 @@
|
||||
fakefire = new(parent_turf)
|
||||
burn_callback = CALLBACK(src, PROC_REF(burn_parent), user)
|
||||
burn_timer = addtimer(burn_callback, min(amount * 0.35 SECONDS, 20 SECONDS), TIMER_STOPPABLE)
|
||||
//unregister everything mechanical, we are burning up
|
||||
//unregister everything related to burning
|
||||
UnregisterSignal(parent, list(COMSIG_COMPONENT_CLEAN_ACT, COMSIG_ATOM_ATTACKBY, COMSIG_ATOM_FIRE_ACT))
|
||||
|
||||
/**
|
||||
@@ -145,7 +147,7 @@
|
||||
/datum/component/thermite/proc/clean_react(datum/source, strength)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
//Thermite is just some loose powder, you could probably clean it with your hands. << todo?
|
||||
//Thermite is just some loose powder, you could probably clean it with your hands
|
||||
qdel(src)
|
||||
|
||||
return COMPONENT_CLEANED
|
||||
@@ -166,6 +168,29 @@
|
||||
if(exposed_temperature >= 1922)
|
||||
thermite_melt()
|
||||
|
||||
/// Handles searing the hand of anyone who tries to touch parent without protection, while burning
|
||||
/datum/component/thermite/proc/on_attack_hand(atom/source, mob/living/carbon/user)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
//not burning
|
||||
if(!fakefire)
|
||||
return NONE
|
||||
|
||||
if(!iscarbon(user) || user.can_touch_burning(source))
|
||||
return NONE
|
||||
|
||||
var/obj/item/bodypart/affecting = user.get_active_hand()
|
||||
//Should not happen!
|
||||
if(!affecting)
|
||||
return NONE
|
||||
|
||||
affecting.receive_damage(burn = 5)
|
||||
to_chat(user, span_userdanger("The ignited thermite on \the [source] burns your hand!"))
|
||||
INVOKE_ASYNC(user, TYPE_PROC_REF(/mob, emote), "scream")
|
||||
playsound(source, SFX_SEAR, 50, TRUE)
|
||||
user.update_damage_overlays()
|
||||
return COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
|
||||
/**
|
||||
* attackby reaction, ignites the thermite if its a flame creating object
|
||||
*
|
||||
|
||||
@@ -272,11 +272,7 @@
|
||||
cache_stacks()
|
||||
update_overlay()
|
||||
update_particles()
|
||||
if(!iscarbon(owner))
|
||||
return
|
||||
|
||||
for(var/obj/item/equipped in owner.get_equipped_items())
|
||||
equipped.wash(CLEAN_TYPE_ACID)
|
||||
equipped.extinguish()
|
||||
|
||||
/datum/status_effect/fire_handler/fire_stacks/on_remove()
|
||||
|
||||
@@ -47,17 +47,6 @@
|
||||
|
||||
var/list/container = list()
|
||||
|
||||
/obj/effect/overlay/thermite
|
||||
name = "thermite"
|
||||
desc = "Looks hot."
|
||||
icon = 'icons/effects/fire.dmi'
|
||||
icon_state = "2" //what?
|
||||
anchored = TRUE
|
||||
opacity = TRUE
|
||||
density = TRUE
|
||||
layer = FLY_LAYER
|
||||
plane = ABOVE_GAME_PLANE
|
||||
|
||||
//Makes a tile fully lit no matter what
|
||||
/obj/effect/fullbright
|
||||
icon = 'icons/effects/alphacolors.dmi'
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
return
|
||||
|
||||
/obj/effect/overlay/beam//Not actually a projectile, just an effect.
|
||||
name="beam"
|
||||
icon='icons/effects/beam.dmi'
|
||||
icon_state="b_beam"
|
||||
name = "beam"
|
||||
icon = 'icons/effects/beam.dmi'
|
||||
icon_state = "b_beam"
|
||||
var/atom/BeamSource
|
||||
|
||||
/obj/effect/overlay/beam/Initialize(mapload)
|
||||
@@ -24,6 +24,16 @@
|
||||
icon_state = "shieldsparkles"
|
||||
anchored = TRUE
|
||||
|
||||
/obj/effect/overlay/thermite
|
||||
name = "thermite"
|
||||
desc = "Looks hot."
|
||||
icon = 'icons/effects/fire.dmi'
|
||||
icon_state = "2" //what?
|
||||
anchored = TRUE
|
||||
plane = ABOVE_GAME_PLANE
|
||||
layer = FLY_LAYER
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
|
||||
/obj/effect/overlay/vis
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
anchored = TRUE
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
// Acid related particles.
|
||||
/particles/acid
|
||||
icon = 'icons/effects/particles/acid.dmi'
|
||||
icon_state = list("goop_1" = 6, "goop_2" = 2, "goop_3" = 1)
|
||||
width = 100
|
||||
height = 100
|
||||
count = 100
|
||||
spawning = 0.5
|
||||
color = "#FFFFFF80" //to get 96 alpha
|
||||
lifespan = 1.5 SECONDS
|
||||
fade = 1 SECONDS
|
||||
grow = -0.025
|
||||
gravity = list(0, 0.15)
|
||||
position = generator(GEN_SPHERE, 0, 16, NORMAL_RAND)
|
||||
spin = generator(GEN_NUM, -15, 15, NORMAL_RAND)
|
||||
@@ -1,21 +1,4 @@
|
||||
// Fire related particles.
|
||||
/particles/embers
|
||||
icon = 'icons/effects/particles/generic.dmi'
|
||||
icon_state = list("dot"=4,"cross"=1,"curl"=1)
|
||||
width = 64
|
||||
height = 96
|
||||
count = 500
|
||||
spawning = 5
|
||||
lifespan = 3 SECONDS
|
||||
fade = 1 SECONDS
|
||||
color = 0
|
||||
color_change = 0.05
|
||||
gradient = list("#FBAF4D", "#FCE6B6", "#FD481C")
|
||||
position = generator(GEN_BOX, list(-12,-16,0), list(12,16,0), NORMAL_RAND)
|
||||
drift = generator(GEN_VECTOR, list(-0.1,0), list(0.1,0.025), UNIFORM_RAND)
|
||||
spin = generator(GEN_NUM, list(-15,15), NORMAL_RAND)
|
||||
scale = generator(GEN_VECTOR, list(0.5,0.5), list(2,2), NORMAL_RAND)
|
||||
|
||||
/particles/bonfire
|
||||
icon = 'icons/effects/particles/bonfire.dmi'
|
||||
icon_state = "bonfire"
|
||||
@@ -33,3 +16,20 @@
|
||||
scale = generator(GEN_VECTOR, list(0.3, 0.3), list(1,1), NORMAL_RAND)
|
||||
rotation = 30
|
||||
spin = generator(GEN_NUM, -20, 20)
|
||||
|
||||
/particles/embers
|
||||
icon = 'icons/effects/particles/generic.dmi'
|
||||
icon_state = list("dot" = 4,"cross" = 1,"curl" = 1)
|
||||
width = 64
|
||||
height = 96
|
||||
count = 500
|
||||
spawning = 5
|
||||
lifespan = 3 SECONDS
|
||||
fade = 1 SECONDS
|
||||
color = 0
|
||||
color_change = 0.05
|
||||
gradient = list("#FBAF4D", "#FCE6B6", "#FD481C")
|
||||
position = generator(GEN_BOX, list(-12,-16,0), list(12,16,0), NORMAL_RAND)
|
||||
drift = generator(GEN_VECTOR, list(-0.1,0), list(0.1,0.025), UNIFORM_RAND)
|
||||
spin = generator(GEN_NUM, list(-15,15), NORMAL_RAND)
|
||||
scale = generator(GEN_VECTOR, list(0.5,0.5), list(2,2), NORMAL_RAND)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//general or un-matched particles, make a new file if a few can be sorted together.
|
||||
// General or un-matched particles, make a new file if a few can be sorted together.
|
||||
/particles/pollen
|
||||
icon = 'icons/effects/particles/pollen.dmi'
|
||||
icon_state = "pollen"
|
||||
|
||||
@@ -521,26 +521,6 @@
|
||||
/obj/item/proc/attempt_pickup(mob/user)
|
||||
. = TRUE
|
||||
|
||||
if(resistance_flags & ON_FIRE)
|
||||
var/mob/living/carbon/C = user
|
||||
var/can_handle_hot = FALSE
|
||||
if(!istype(C))
|
||||
can_handle_hot = TRUE
|
||||
else if(C.gloves && (C.gloves.max_heat_protection_temperature > 360))
|
||||
can_handle_hot = TRUE
|
||||
else if(HAS_TRAIT(C, TRAIT_RESISTHEAT) || HAS_TRAIT(C, TRAIT_RESISTHEATHANDS))
|
||||
can_handle_hot = TRUE
|
||||
|
||||
if(can_handle_hot)
|
||||
extinguish()
|
||||
to_chat(user, span_notice("You put out the fire on [src]."))
|
||||
else
|
||||
to_chat(user, span_warning("You burn your hand on [src]!"))
|
||||
var/obj/item/bodypart/affecting = C.get_bodypart("[(user.active_hand_index % 2 == 0) ? "r" : "l" ]_arm")
|
||||
if(affecting?.receive_damage( 0, 5 )) // 5 burn damage
|
||||
C.update_damage_overlays()
|
||||
return
|
||||
|
||||
if(!(interaction_flags_item & INTERACT_ITEM_ATTACK_HAND_PICKUP)) //See if we're supposed to auto pickup.
|
||||
return
|
||||
|
||||
@@ -878,7 +858,7 @@
|
||||
|
||||
/obj/item/proc/get_dismember_sound()
|
||||
if(damtype == BURN)
|
||||
. = 'sound/weapons/sear.ogg'
|
||||
. = SFX_SEAR
|
||||
else
|
||||
. = SFX_DESECRATION
|
||||
|
||||
|
||||
+21
-19
@@ -184,35 +184,35 @@
|
||||
/proc/get_sfx(soundin)
|
||||
if(istext(soundin))
|
||||
switch(soundin)
|
||||
if (SFX_SHATTER)
|
||||
if(SFX_SHATTER)
|
||||
soundin = pick('sound/effects/glassbr1.ogg','sound/effects/glassbr2.ogg','sound/effects/glassbr3.ogg')
|
||||
if (SFX_EXPLOSION)
|
||||
if(SFX_EXPLOSION)
|
||||
soundin = pick('sound/effects/explosion1.ogg','sound/effects/explosion2.ogg')
|
||||
if (SFX_EXPLOSION_CREAKING)
|
||||
if(SFX_EXPLOSION_CREAKING)
|
||||
soundin = pick('sound/effects/explosioncreak1.ogg', 'sound/effects/explosioncreak2.ogg')
|
||||
if (SFX_HULL_CREAKING)
|
||||
if(SFX_HULL_CREAKING)
|
||||
soundin = pick('sound/effects/creak1.ogg', 'sound/effects/creak2.ogg', 'sound/effects/creak3.ogg')
|
||||
if (SFX_SPARKS)
|
||||
if(SFX_SPARKS)
|
||||
soundin = pick('sound/effects/sparks1.ogg','sound/effects/sparks2.ogg','sound/effects/sparks3.ogg','sound/effects/sparks4.ogg')
|
||||
if (SFX_RUSTLE)
|
||||
if(SFX_RUSTLE)
|
||||
soundin = pick('sound/effects/rustle1.ogg','sound/effects/rustle2.ogg','sound/effects/rustle3.ogg','sound/effects/rustle4.ogg','sound/effects/rustle5.ogg')
|
||||
if (SFX_BODYFALL)
|
||||
if(SFX_BODYFALL)
|
||||
soundin = pick('sound/effects/bodyfall1.ogg','sound/effects/bodyfall2.ogg','sound/effects/bodyfall3.ogg','sound/effects/bodyfall4.ogg')
|
||||
if (SFX_PUNCH)
|
||||
if(SFX_PUNCH)
|
||||
soundin = pick('sound/weapons/punch1.ogg','sound/weapons/punch2.ogg','sound/weapons/punch3.ogg','sound/weapons/punch4.ogg')
|
||||
if (SFX_CLOWN_STEP)
|
||||
if(SFX_CLOWN_STEP)
|
||||
soundin = pick('sound/effects/footstep/clownstep1.ogg','sound/effects/footstep/clownstep2.ogg')
|
||||
if (SFX_SUIT_STEP)
|
||||
if(SFX_SUIT_STEP)
|
||||
soundin = pick('sound/effects/suitstep1.ogg','sound/effects/suitstep2.ogg')
|
||||
if (SFX_SWING_HIT)
|
||||
if(SFX_SWING_HIT)
|
||||
soundin = pick('sound/weapons/genhit1.ogg', 'sound/weapons/genhit2.ogg', 'sound/weapons/genhit3.ogg')
|
||||
if (SFX_HISS)
|
||||
if(SFX_HISS)
|
||||
soundin = pick('sound/voice/hiss1.ogg','sound/voice/hiss2.ogg','sound/voice/hiss3.ogg','sound/voice/hiss4.ogg')
|
||||
if (SFX_PAGE_TURN)
|
||||
if(SFX_PAGE_TURN)
|
||||
soundin = pick('sound/effects/pageturn1.ogg', 'sound/effects/pageturn2.ogg','sound/effects/pageturn3.ogg')
|
||||
if (SFX_RICOCHET)
|
||||
if(SFX_RICOCHET)
|
||||
soundin = pick( 'sound/weapons/effects/ric1.ogg', 'sound/weapons/effects/ric2.ogg','sound/weapons/effects/ric3.ogg','sound/weapons/effects/ric4.ogg','sound/weapons/effects/ric5.ogg')
|
||||
if (SFX_TERMINAL_TYPE)
|
||||
if(SFX_TERMINAL_TYPE)
|
||||
soundin = pick(list(
|
||||
'sound/machines/terminal_button01.ogg',
|
||||
'sound/machines/terminal_button02.ogg',
|
||||
@@ -223,11 +223,11 @@
|
||||
'sound/machines/terminal_button07.ogg',
|
||||
'sound/machines/terminal_button08.ogg',
|
||||
))
|
||||
if (SFX_DESECRATION)
|
||||
if(SFX_DESECRATION)
|
||||
soundin = pick('sound/misc/desecration-01.ogg', 'sound/misc/desecration-02.ogg', 'sound/misc/desecration-03.ogg')
|
||||
if (SFX_IM_HERE)
|
||||
if(SFX_IM_HERE)
|
||||
soundin = pick('sound/hallucinations/im_here1.ogg', 'sound/hallucinations/im_here2.ogg')
|
||||
if (SFX_CAN_OPEN)
|
||||
if(SFX_CAN_OPEN)
|
||||
soundin = pick('sound/effects/can_open1.ogg', 'sound/effects/can_open2.ogg', 'sound/effects/can_open3.ogg')
|
||||
if(SFX_BULLET_MISS)
|
||||
soundin = pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg')
|
||||
@@ -260,7 +260,7 @@
|
||||
'sound/weapons/bladeslice.ogg',
|
||||
'sound/weapons/flashbang.ogg',
|
||||
))
|
||||
if("goose")
|
||||
if(SFX_GOOSE)
|
||||
soundin = pick('sound/creatures/goose1.ogg', 'sound/creatures/goose2.ogg', 'sound/creatures/goose3.ogg', 'sound/creatures/goose4.ogg')
|
||||
if(SFX_WARPSPEED)
|
||||
soundin = 'sound/runtime/hyperspace/hyperspace_begin.ogg'
|
||||
@@ -414,4 +414,6 @@
|
||||
soundin = pick('sound/effects/treechop1.ogg', 'sound/effects/treechop2.ogg', 'sound/effects/treechop3.ogg')
|
||||
if(SFX_ROCK_TAP)
|
||||
soundin = pick('sound/effects/rocktap1.ogg', 'sound/effects/rocktap2.ogg', 'sound/effects/rocktap3.ogg')
|
||||
if(SFX_SEAR)
|
||||
soundin = 'sound/weapons/sear.ogg'
|
||||
return soundin
|
||||
|
||||
@@ -1364,6 +1364,32 @@
|
||||
log_combat(shover, target, "shoved", addition = "into [name]")
|
||||
return COMSIG_CARBON_SHOVE_HANDLED
|
||||
|
||||
/**
|
||||
* This proc is used to determine whether or not the mob can handle touching an acid affected object.
|
||||
*/
|
||||
/mob/living/carbon/proc/can_touch_acid(atom/acided_atom, acid_power, acid_volume)
|
||||
// So people can take their own clothes off
|
||||
if((acided_atom == src) || (acided_atom.loc == src))
|
||||
return TRUE
|
||||
if((acid_power * acid_volume) < ACID_LEVEL_HANDBURN)
|
||||
return TRUE
|
||||
if(gloves?.resistance_flags & (UNACIDABLE | ACID_PROOF))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* This proc is used to determine whether or not the mob can handle touching a burning object.
|
||||
*/
|
||||
/mob/living/carbon/proc/can_touch_burning(atom/burning_atom, acid_power, acid_volume)
|
||||
// So people can take their own clothes off
|
||||
if((burning_atom == src) || (burning_atom.loc == src))
|
||||
return TRUE
|
||||
if(HAS_TRAIT(src, TRAIT_RESISTHEAT) || HAS_TRAIT(src, TRAIT_RESISTHEATHANDS))
|
||||
return TRUE
|
||||
if(gloves?.max_heat_protection_temperature >= BURNING_ITEM_MINIMUM_TEMPERATURE)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* This proc is a helper for spraying blood for things like slashing/piercing wounds and dismemberment.
|
||||
*
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
/mob/living/carbon/get_active_hand()
|
||||
var/which_hand = BODY_ZONE_PRECISE_L_HAND
|
||||
if(!(active_hand_index % 2))
|
||||
if(!(active_hand_index % RIGHT_HANDS))
|
||||
which_hand = BODY_ZONE_PRECISE_R_HAND
|
||||
return get_bodypart(check_zone(which_hand))
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
|
||||
/mob/living/carbon/has_left_hand(check_disabled = TRUE)
|
||||
for(var/obj/item/bodypart/hand_instance in hand_bodyparts)
|
||||
if(!(hand_instance.held_index % 2) || (check_disabled && hand_instance.bodypart_disabled))
|
||||
if(!(hand_instance.held_index % RIGHT_HANDS) || (check_disabled && hand_instance.bodypart_disabled))
|
||||
continue
|
||||
return TRUE
|
||||
return FALSE
|
||||
@@ -70,7 +70,7 @@
|
||||
|
||||
/mob/living/carbon/has_right_hand(check_disabled = TRUE)
|
||||
for(var/obj/item/bodypart/hand_instance in hand_bodyparts)
|
||||
if(hand_instance.held_index % 2 || (check_disabled && hand_instance.bodypart_disabled))
|
||||
if(hand_instance.held_index % RIGHT_HANDS || (check_disabled && hand_instance.bodypart_disabled))
|
||||
continue
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 349 B |
Binary file not shown.
|
Before Width: | Height: | Size: 261 B After Width: | Height: | Size: 283 B |
Binary file not shown.
|
Before Width: | Height: | Size: 450 B After Width: | Height: | Size: 545 B |
@@ -1766,6 +1766,7 @@
|
||||
#include "code\game\objects\effects\effect_system\fluid_spread\effects_foam.dm"
|
||||
#include "code\game\objects\effects\effect_system\fluid_spread\effects_smoke.dm"
|
||||
#include "code\game\objects\effects\landmarks\atmospherics_sanity_landmarks.dm"
|
||||
#include "code\game\objects\effects\particles\acid.dm"
|
||||
#include "code\game\objects\effects\particles\fire.dm"
|
||||
#include "code\game\objects\effects\particles\misc.dm"
|
||||
#include "code\game\objects\effects\particles\note_particles.dm"
|
||||
|
||||
Reference in New Issue
Block a user