1eccbcca18
The component is initialized with any combination of three flags, EMP_PROTECT_SELF protects against effects that target the object itself, EMP_PROTECT_WIRES protects against wires being messed with similar to the NO_EMP_WIRES_1 flag which this PR removes, EMP_PROTECT_CONTENTS protects against things that are inside the object like organs, internal "non-virtual" power cells and the like This enables (but doesn't introduce) new mechanics such as adding EMP shielding at runtime to any atom, or taking it away.
174 lines
6.1 KiB
Plaintext
174 lines
6.1 KiB
Plaintext
/obj/item/organ/heart
|
|
name = "heart"
|
|
desc = "I feel bad for the heartless bastard who lost this."
|
|
icon_state = "heart-on"
|
|
zone = BODY_ZONE_CHEST
|
|
slot = ORGAN_SLOT_HEART
|
|
// Heart attack code is in code/modules/mob/living/carbon/human/life.dm
|
|
var/beating = 1
|
|
var/icon_base = "heart"
|
|
attack_verb = list("beat", "thumped")
|
|
var/beat = BEAT_NONE//is this mob having a heatbeat sound played? if so, which?
|
|
|
|
/obj/item/organ/heart/update_icon()
|
|
if(beating)
|
|
icon_state = "[icon_base]-on"
|
|
else
|
|
icon_state = "[icon_base]-off"
|
|
|
|
/obj/item/organ/heart/Remove(mob/living/carbon/M, special = 0)
|
|
..()
|
|
if(!special)
|
|
addtimer(CALLBACK(src, .proc/stop_if_unowned), 120)
|
|
|
|
/obj/item/organ/heart/proc/stop_if_unowned()
|
|
if(!owner)
|
|
Stop()
|
|
|
|
/obj/item/organ/heart/attack_self(mob/user)
|
|
..()
|
|
if(!beating)
|
|
user.visible_message("<span class='notice'>[user] squeezes [src] to \
|
|
make it beat again!</span>","<span class='notice'>You squeeze [src] to make it beat again!</span>")
|
|
Restart()
|
|
addtimer(CALLBACK(src, .proc/stop_if_unowned), 80)
|
|
|
|
/obj/item/organ/heart/proc/Stop()
|
|
beating = 0
|
|
update_icon()
|
|
return 1
|
|
|
|
/obj/item/organ/heart/proc/Restart()
|
|
beating = 1
|
|
update_icon()
|
|
return 1
|
|
|
|
/obj/item/organ/heart/prepare_eat()
|
|
var/obj/S = ..()
|
|
S.icon_state = "heart-off"
|
|
return S
|
|
|
|
/obj/item/organ/heart/on_life()
|
|
if(owner.client && beating)
|
|
var/sound/slowbeat = sound('sound/health/slowbeat.ogg', repeat = TRUE)
|
|
var/sound/fastbeat = sound('sound/health/fastbeat.ogg', repeat = TRUE)
|
|
var/mob/living/carbon/H = owner
|
|
|
|
if(H.health <= HEALTH_THRESHOLD_CRIT && beat != BEAT_SLOW)
|
|
beat = BEAT_SLOW
|
|
H.playsound_local(get_turf(H), slowbeat,40,0, channel = CHANNEL_HEARTBEAT)
|
|
to_chat(owner, "<span class = 'notice'>You feel your heart slow down...</span>")
|
|
if(beat == BEAT_SLOW && H.health > HEALTH_THRESHOLD_CRIT)
|
|
H.stop_sound_channel(CHANNEL_HEARTBEAT)
|
|
beat = BEAT_NONE
|
|
|
|
if(H.jitteriness)
|
|
if(H.health > HEALTH_THRESHOLD_FULLCRIT && (!beat || beat == BEAT_SLOW))
|
|
H.playsound_local(get_turf(H),fastbeat,40,0, channel = CHANNEL_HEARTBEAT)
|
|
beat = BEAT_FAST
|
|
else if(beat == BEAT_FAST)
|
|
H.stop_sound_channel(CHANNEL_HEARTBEAT)
|
|
beat = BEAT_NONE
|
|
|
|
/obj/item/organ/heart/cursed
|
|
name = "cursed heart"
|
|
desc = "A heart that, when inserted, will force you to pump it manually."
|
|
icon_state = "cursedheart-off"
|
|
icon_base = "cursedheart"
|
|
actions_types = list(/datum/action/item_action/organ_action/cursed_heart)
|
|
var/last_pump = 0
|
|
var/add_colour = TRUE //So we're not constantly recreating colour datums
|
|
var/pump_delay = 30 //you can pump 1 second early, for lag, but no more (otherwise you could spam heal)
|
|
var/blood_loss = 100 //600 blood is human default, so 5 failures (below 122 blood is where humans die because reasons?)
|
|
|
|
//How much to heal per pump, negative numbers would HURT the player
|
|
var/heal_brute = 0
|
|
var/heal_burn = 0
|
|
var/heal_oxy = 0
|
|
|
|
|
|
/obj/item/organ/heart/cursed/attack(mob/living/carbon/human/H, mob/living/carbon/human/user, obj/target)
|
|
if(H == user && istype(H))
|
|
playsound(user,'sound/effects/singlebeat.ogg',40,1)
|
|
user.temporarilyRemoveItemFromInventory(src, TRUE)
|
|
Insert(user)
|
|
else
|
|
return ..()
|
|
|
|
/obj/item/organ/heart/cursed/on_life()
|
|
if(world.time > (last_pump + pump_delay))
|
|
if(ishuman(owner) && owner.client) //While this entire item exists to make people suffer, they can't control disconnects.
|
|
var/mob/living/carbon/human/H = owner
|
|
if(H.dna && !(NOBLOOD in H.dna.species.species_traits))
|
|
H.blood_volume = max(H.blood_volume - blood_loss, 0)
|
|
to_chat(H, "<span class = 'userdanger'>You have to keep pumping your blood!</span>")
|
|
if(add_colour)
|
|
H.add_client_colour(/datum/client_colour/cursed_heart_blood) //bloody screen so real
|
|
add_colour = FALSE
|
|
else
|
|
last_pump = world.time //lets be extra fair *sigh*
|
|
|
|
/obj/item/organ/heart/cursed/Insert(mob/living/carbon/M, special = 0)
|
|
..()
|
|
if(owner)
|
|
to_chat(owner, "<span class ='userdanger'>Your heart has been replaced with a cursed one, you have to pump this one manually otherwise you'll die!</span>")
|
|
|
|
/datum/action/item_action/organ_action/cursed_heart
|
|
name = "Pump your blood"
|
|
|
|
//You are now brea- pumping blood manually
|
|
/datum/action/item_action/organ_action/cursed_heart/Trigger()
|
|
. = ..()
|
|
if(. && istype(target, /obj/item/organ/heart/cursed))
|
|
var/obj/item/organ/heart/cursed/cursed_heart = target
|
|
|
|
if(world.time < (cursed_heart.last_pump + (cursed_heart.pump_delay-10))) //no spam
|
|
to_chat(owner, "<span class='userdanger'>Too soon!</span>")
|
|
return
|
|
|
|
cursed_heart.last_pump = world.time
|
|
playsound(owner,'sound/effects/singlebeat.ogg',40,1)
|
|
to_chat(owner, "<span class = 'notice'>Your heart beats.</span>")
|
|
|
|
var/mob/living/carbon/human/H = owner
|
|
if(istype(H))
|
|
if(H.dna && !(NOBLOOD in H.dna.species.species_traits))
|
|
H.blood_volume = min(H.blood_volume + cursed_heart.blood_loss*0.5, BLOOD_VOLUME_MAXIMUM)
|
|
H.remove_client_colour(/datum/client_colour/cursed_heart_blood)
|
|
cursed_heart.add_colour = TRUE
|
|
H.adjustBruteLoss(-cursed_heart.heal_brute)
|
|
H.adjustFireLoss(-cursed_heart.heal_burn)
|
|
H.adjustOxyLoss(-cursed_heart.heal_oxy)
|
|
|
|
|
|
/datum/client_colour/cursed_heart_blood
|
|
priority = 100 //it's an indicator you're dieing, so it's very high priority
|
|
colour = "red"
|
|
|
|
/obj/item/organ/heart/cybernetic
|
|
name = "cybernetic heart"
|
|
desc = "An electronic device designed to mimic the functions of an organic human heart. Offers no benefit over an organic heart other than being easy to make."
|
|
icon_state = "heart-c"
|
|
synthetic = TRUE
|
|
|
|
/obj/item/organ/heart/cybernetic/emp_act()
|
|
. = ..()
|
|
if(. & EMP_PROTECT_SELF)
|
|
return
|
|
Stop()
|
|
|
|
/obj/item/organ/heart/freedom
|
|
name = "heart of freedom"
|
|
desc = "This heart pumps with the passion to give... something freedom."
|
|
synthetic = TRUE //the power of freedom prevents heart attacks
|
|
var/min_next_adrenaline = 0
|
|
|
|
/obj/item/organ/heart/freedom/on_life()
|
|
. = ..()
|
|
if(owner.health < 5 && world.time > min_next_adrenaline)
|
|
min_next_adrenaline = world.time + rand(250, 600) //anywhere from 4.5 to 10 minutes
|
|
to_chat(owner, "<span class='userdanger'>You feel yourself dying, but you refuse to give up!</span>")
|
|
owner.heal_overall_damage(15, 15)
|
|
if(owner.reagents.get_reagent_amount("ephedrine") < 20)
|
|
owner.reagents.add_reagent("ephedrine", 10)
|