Merge branch 'master' into xantholne-cowboy02

This commit is contained in:
Unknown
2020-01-08 20:36:22 -07:00
56 changed files with 623 additions and 279 deletions

View File

@@ -84,8 +84,8 @@
//It is called from your coffin on close (by you only)
if(poweron_masquerade == TRUE || owner.current.AmStaked())
return FALSE
owner.current.adjustStaminaLoss(-2 + (regenRate * -10) * mult, 0) // Humans lose stamina damage really quickly. Vamps should heal more.
owner.current.adjustCloneLoss(-1 * (regenRate * 4) * mult, 0)
owner.current.adjustStaminaLoss(-2 + (regenRate * 8) * mult, 0) // Humans lose stamina damage really quickly. Vamps should heal more.
owner.current.adjustCloneLoss(-0.1 * (regenRate * 2) * mult, 0)
owner.current.adjustOrganLoss(ORGAN_SLOT_BRAIN, -1 * (regenRate * 4) * mult) //adjustBrainLoss(-1 * (regenRate * 4) * mult, 0)
// No Bleeding
if(ishuman(owner.current)) //NOTE Current bleeding is horrible, not to count the amount of blood ballistics delete.
@@ -97,7 +97,7 @@
var/fireheal = 0 // BURN: Heal in Coffin while Fakedeath, or when damage above maxhealth (you can never fully heal fire)
var/amInCoffinWhileTorpor = istype(C.loc, /obj/structure/closet/crate/coffin) && (mult == 0 || HAS_TRAIT(C, TRAIT_DEATHCOMA)) // Check for mult 0 OR death coma. (mult 0 means we're testing from coffin)
if(amInCoffinWhileTorpor)
mult *= 5 // Increase multiplier if we're sleeping in a coffin.
mult *= 4 // Increase multiplier if we're sleeping in a coffin.
fireheal = min(C.getFireLoss_nonProsthetic(), regenRate) // NOTE: Burn damage ONLY heals in torpor.
costMult = 0.25
C.ExtinguishMob()
@@ -118,6 +118,8 @@
if(bruteheal + fireheal + toxinheal > 0) // Just a check? Don't heal/spend, and return.
if(mult == 0)
return TRUE
if(owner.current.stat >= UNCONSCIOUS) //Faster regeneration while unconcious, so you dont have to wait all day
mult *= 2
// We have damage. Let's heal (one time)
C.adjustBruteLoss(-bruteheal * mult, forced = TRUE)// Heal BRUTE / BURN in random portions throughout the body.
C.adjustFireLoss(-fireheal * mult, forced = TRUE)
@@ -187,19 +189,19 @@
/datum/antagonist/bloodsucker/proc/HandleDeath()
// FINAL DEATH
// Fire Damage? (above double health)
if (owner.current.getFireLoss_nonProsthetic() >= owner.current.getMaxHealth() * 2)
if(owner.current.getFireLoss_nonProsthetic() >= owner.current.getMaxHealth() * 1.5)
FinalDeath()
return
// Staked while "Temp Death" or Asleep
if (owner.current.StakeCanKillMe() && owner.current.AmStaked())
if(owner.current.StakeCanKillMe() && owner.current.AmStaked())
FinalDeath()
return
// Not "Alive"?
if (!owner.current || !isliving(owner.current) || isbrain(owner.current) || !get_turf(owner.current))
if(!owner.current || !isliving(owner.current) || isbrain(owner.current) || !get_turf(owner.current))
FinalDeath()
return
// Missing Brain or Heart?
if (!owner.current.HaveBloodsuckerBodyparts())
if(!owner.current.HaveBloodsuckerBodyparts())
FinalDeath()
return
// Disable Powers: Masquerade * NOTE * This should happen as a FLAW!
@@ -212,21 +214,21 @@
var/total_toxloss = owner.current.getToxLoss() //This is neater than just putting it in total_damage
var/total_damage = total_brute + total_burn + total_toxloss
// Died? Convert to Torpor (fake death)
if (owner.current.stat >= DEAD)
if(owner.current.stat >= DEAD)
Torpor_Begin()
to_chat(owner, "<span class='danger'>Your immortal body will not yet relinquish your soul to the abyss. You enter Torpor.</span>")
sleep(30) //To avoid spam
if (poweron_masquerade == TRUE)
to_chat(owner, "<span class='warning'>Your wounds will not heal until you disable the <span class='boldnotice'>Masquerade</span> power.</span>")
// End Torpor:
else // No damage, OR toxin healed AND brute healed and NOT in coffin (since you cannot heal burn)
if (total_damage <= 0 || total_toxloss <= 0 && total_brute <= 0 && !istype(owner.current.loc, /obj/structure/closet/crate/coffin))
if(total_damage <= 0 || total_toxloss <= 0 && total_brute <= 0 && !istype(owner.current.loc, /obj/structure/closet/crate/coffin))
// Not Daytime, Not in Torpor
if (!SSticker.mode.is_daylight() && HAS_TRAIT_FROM(owner.current, TRAIT_DEATHCOMA, "bloodsucker"))
if(!SSticker.mode.is_daylight() && HAS_TRAIT_FROM(owner.current, TRAIT_DEATHCOMA, "bloodsucker"))
Torpor_End()
// Fake Unconscious
if (poweron_masquerade == TRUE && total_damage >= owner.current.getMaxHealth() - HEALTH_THRESHOLD_FULLCRIT)
if(poweron_masquerade == TRUE && total_damage >= owner.current.getMaxHealth() - HEALTH_THRESHOLD_FULLCRIT)
owner.current.Unconscious(20,1)
//HEALTH_THRESHOLD_CRIT 0
//HEALTH_THRESHOLD_FULLCRIT -30
//HEALTH_THRESHOLD_DEAD -100
@@ -241,8 +243,8 @@
owner.current.update_sight()
owner.current.reload_fullscreen()
// Disable ALL Powers
for (var/datum/action/bloodsucker/power in powers)
if (power.active && !power.can_use_in_torpor)
for(var/datum/action/bloodsucker/power in powers)
if(power.active && !power.can_use_in_torpor)
power.DeactivatePower()
@@ -281,7 +283,7 @@
// Free my Vassals!
FreeAllVassals()
// Elders get Dusted
if (vamplevel >= 4) // (vamptitle)
if(vamplevel >= 4) // (vamptitle)
owner.current.visible_message("<span class='warning'>[owner.current]'s skin crackles and dries, their skin and bones withering to dust. A hollow cry whips from what is now a sandy pile of remains.</span>", \
"<span class='userdanger'>Your soul escapes your withering body as the abyss welcomes you to your Final Death.</span>", \
"<span class='italics'>You hear a dry, crackling sound.</span>")
@@ -306,7 +308,7 @@
if (!isliving(src))
return
var/mob/living/L = src
if (!L.AmBloodsucker())
if(!L.AmBloodsucker())
return
// We're a vamp? Try to eat food...
var/datum/antagonist/bloodsucker/bloodsuckerdatum = mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
@@ -315,7 +317,7 @@
/datum/antagonist/bloodsucker/proc/handle_eat_human_food(var/food_nutrition) // Called from snacks.dm and drinks.dm
set waitfor = FALSE
if (!owner.current || !iscarbon(owner.current))
if(!owner.current || !iscarbon(owner.current))
return
var/mob/living/carbon/C = owner.current
// Remove Nutrition, Give Bad Food

View File

@@ -35,8 +35,8 @@
var/warn_sun_burn = FALSE // So we only get the sun burn message once per day.
var/had_toxlover = FALSE
// LISTS
var/static/list/defaultTraits = list (TRAIT_STABLEHEART, TRAIT_NOBREATH, TRAIT_SLEEPIMMUNE, TRAIT_NOCRITDAMAGE, TRAIT_RESISTCOLD, TRAIT_RADIMMUNE, TRAIT_VIRUSIMMUNE, TRAIT_NIGHT_VISION, \
TRAIT_NOSOFTCRIT, TRAIT_NOHARDCRIT, TRAIT_AGEUSIA, TRAIT_COLDBLOODED, TRAIT_NONATURALHEAL, TRAIT_NOMARROW, TRAIT_NOPULSE, TRAIT_NOCLONE)
var/static/list/defaultTraits = list (TRAIT_STABLEHEART, TRAIT_NOBREATH, TRAIT_SLEEPIMMUNE, TRAIT_NOCRITDAMAGE, TRAIT_RESISTCOLD, TRAIT_RADIMMUNE, TRAIT_NIGHT_VISION, \
TRAIT_NOSOFTCRIT, TRAIT_NOHARDCRIT, TRAIT_AGEUSIA, TRAIT_COLDBLOODED, TRAIT_NONATURALHEAL, TRAIT_NOMARROW, TRAIT_NOPULSE, TRAIT_VIRUSIMMUNE)
// NOTES: TRAIT_AGEUSIA <-- Doesn't like flavors.
// REMOVED: TRAIT_NODEATH
// TO ADD:
@@ -334,7 +334,7 @@ datum/antagonist/bloodsucker/proc/SpendRank()
// Assign True Reputation
if(vamplevel == 4)
SelectReputation(am_fledgling = FALSE, forced = TRUE)
to_chat(owner.current, "<span class='notice'>You are now a rank [vamplevel] Bloodsucker. Your strength, resistence, health, feed rate, regen rate, and maximum blood have all increased!</span>")
to_chat(owner.current, "<span class='notice'>You are now a rank [vamplevel] Bloodsucker. Your strength, health, feed rate, regen rate, and maximum blood have all increased!</span>")
to_chat(owner.current, "<span class='notice'>Your existing powers have all ranked up as well!</span>")
update_hud(TRUE)
owner.current.playsound_local(null, 'sound/effects/pope_entry.ogg', 25, 1) // Play THIS sound for user only. The "null" is where turf would go if a location was needed. Null puts it right in their head.

View File

@@ -56,11 +56,6 @@
var/obj/item/organ/eyes/vassal/E = new
E.Insert(owner.current)
/obj/item/organ/eyes/vassal/
lighting_alpha = 180 // LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE <--- This is too low a value at 128. We need to SEE what the darkness is so we can hide in it.
see_in_dark = 12
flash_protect = -1 //These eyes are weaker to flashes, but let you see in the dark
/datum/antagonist/vassal/proc/remove_thrall_eyes()
var/obj/item/organ/eyes/E = new
E.Insert(owner.current)

View File

@@ -51,6 +51,11 @@
return "<span class='danger'>no</span>" // Bloodsuckers don't have a heartbeat at all when stopped (default is "an unstable")
// EYES //
/obj/item/organ/eyes/vassal/
lighting_alpha = 180 // LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE <--- This is too low a value at 128. We need to SEE what the darkness is so we can hide in it.
see_in_dark = 12
flash_protect = -1 //These eyes are weaker to flashes, but let you see in the dark
/obj/item/organ/eyes/vassal/bloodsucker
flash_protect = 2 //Eye healing isnt working properly
sight_flags = SEE_MOBS // Taken from augmented_eyesight.dm

View File

@@ -78,7 +78,7 @@
var/mob/living/carbon/C = target
// Needs to be Down/Slipped in some way to Stake.
if(!C.can_be_staked() || target == user)
to_chat(user, "<span class='danger'>You cant stake [target] when they are moving moving about! They have to be laying down!</span>")
to_chat(user, "<span class='danger'>You can't stake [target] when they are moving about! They have to be laying down or grabbed by the neck!</span>")
return
// Oops! Can't.
if(HAS_TRAIT(C, TRAIT_PIERCEIMMUNE))
@@ -113,7 +113,7 @@
// Can this target be staked? If someone stands up before this is complete, it fails. Best used on someone stationary.
/mob/living/carbon/proc/can_be_staked()
//return resting || IsKnockdown() || IsUnconscious() || (stat && (stat != SOFT_CRIT || pulledby)) || (has_trait(TRAIT_FAKEDEATH)) || resting || IsStun() || IsFrozen() || (pulledby && pulledby.grab_state >= GRAB_NECK)
return (src.resting || src.lying)
return (resting || lying || IsUnconscious() || pulledby && pulledby.grab_state >= GRAB_NECK)
// ABOVE: Taken from update_mobility() in living.dm
/obj/item/stake/hardened

View File

@@ -130,7 +130,7 @@
/obj/structure/bloodsucker/vassalrack/MouseDrop_T(atom/movable/O, mob/user)
if(!O.Adjacent(src) || O == user || !isliving(O) || !isliving(user) || useLock || has_buckled_mobs() || user.incapacitated())
return
if(!anchored && user.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER))
if(!anchored && isvamp(user))
to_chat(user, "<span class='danger'>Until this rack is secured in place, it cannot serve its purpose.</span>")
return
// PULL TARGET: Remember if I was pullin this guy, so we can restore this
@@ -183,7 +183,7 @@
/obj/structure/bloodsucker/vassalrack/user_unbuckle_mob(mob/living/M, mob/user)
// Attempt Unbuckle
if(!user.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER))
if(!isvamp(user))
if(M == user)
M.visible_message("<span class='danger'>[user] tries to release themself from the rack!</span>",\
"<span class='danger'>You attempt to release yourself from the rack!</span>") // For sound if not seen --> "<span class='italics'>You hear a squishy wet noise.</span>")
@@ -453,7 +453,7 @@
/obj/structure/bloodsucker/candelabrum/examine(mob/user)
. = ..()
if((user.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)) || isobserver(user))
if((isvamp()) || isobserver(user))
. += {"<span class='cult'>This is a magical candle which drains at the sanity of mortals who are not under your command while it is active.</span>"}
. += {"<span class='cult'>You can alt click on it from any range to turn it on remotely, or simply be next to it and click on it to turn it on and off normally.</span>"}
/* if(user.mind.has_antag_datum(ANTAG_DATUM_VASSAL)
@@ -461,15 +461,13 @@
You can turn it on and off by clicking on it while you are next to it</span>"} */
/obj/structure/bloodsucker/candelabrum/attack_hand(mob/user)
var/datum/antagonist/bloodsucker/V = user.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER) //I wish there was a better way to do this
var/datum/antagonist/vassal/T = user.mind.has_antag_datum(ANTAG_DATUM_VASSAL)
if(istype(V) || istype(T))
if(isvamp(user) || istype(T))
toggle()
/obj/structure/bloodsucker/candelabrum/AltClick(mob/user)
var/datum/antagonist/bloodsucker/V = user.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
// Bloodsuckers can turn their candles on from a distance. SPOOOOKY.
if(istype(V))
if(isvamp(user))
toggle()
/obj/structure/bloodsucker/candelabrum/proc/toggle(mob/user)
@@ -486,8 +484,7 @@
if(lit)
for(var/mob/living/carbon/human/H in viewers(7, src))
var/datum/antagonist/vassal/T = H.mind.has_antag_datum(ANTAG_DATUM_VASSAL)
var/datum/antagonist/bloodsucker/V = H.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
if(V || T) //We dont want vassals or vampires affected by this
if(isvamp(H) || T) //We dont want vassals or vampires affected by this
return
H.hallucination = 20
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "vampcandle", /datum/mood_event/vampcandle)

View File

@@ -9,8 +9,9 @@
bloodsucker_can_buy = TRUE
amToggle = TRUE
warn_constant_cost = TRUE
var/was_running
var/light_min = 0.5 // If lum is above this, no good.
var/light_min = 0.2 // If lum is above this, no good.
/datum/action/bloodsucker/cloak/CheckCanUse(display_error)
. = ..()
@@ -26,18 +27,16 @@
/datum/action/bloodsucker/cloak/ActivatePower()
var/datum/antagonist/bloodsucker/bloodsuckerdatum = owner.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
var/mob/living/user = owner
var/was_running = (user.m_intent == MOVE_INTENT_RUN)
was_running = (user.m_intent == MOVE_INTENT_RUN)
if(was_running)
user.toggle_move_intent()
ADD_TRAIT(user, TRAIT_NORUNNING, "cloak of darkness")
while(bloodsuckerdatum && ContinueActive(user) || user.m_intent == MOVE_INTENT_RUN)
// Pay Blood Toll (if awake)
owner.alpha = max(0, owner.alpha - min(75, 20 + 15 * level_current))
owner.alpha = max(20, owner.alpha - min(75, 10 + 5 * level_current))
bloodsuckerdatum.AddBloodVolume(-0.2)
sleep(5) // Check every few ticks that we haven't disabled this power
// Return to Running (if you were before)
if(was_running && user.m_intent != MOVE_INTENT_RUN)
user.toggle_move_intent()
/datum/action/bloodsucker/cloak/ContinueActive(mob/living/user, mob/living/target)
if (!..())
@@ -55,3 +54,5 @@
..()
REMOVE_TRAIT(user, TRAIT_NORUNNING, "cloak of darkness")
user.alpha = 255
if(was_running && user.m_intent != MOVE_INTENT_RUN)
user.toggle_move_intent()

View File

@@ -51,14 +51,17 @@
REMOVE_TRAIT(user, TRAIT_COLDBLOODED, "bloodsucker")
REMOVE_TRAIT(user, TRAIT_NOHARDCRIT, "bloodsucker")
REMOVE_TRAIT(user, TRAIT_NOSOFTCRIT, "bloodsucker")
REMOVE_TRAIT(user, TRAIT_VIRUSIMMUNE, "bloodsucker")
var/obj/item/organ/heart/vampheart/H = user.getorganslot(ORGAN_SLOT_HEART)
var/obj/item/organ/eyes/vassal/bloodsucker/E = user.getorganslot(ORGAN_SLOT_EYES)
E.flash_protect = 0
// WE ARE ALIVE! //
bloodsuckerdatum.poweron_masquerade = TRUE
while(bloodsuckerdatum && ContinueActive(user))
// HEART
if (istype(H))
if(istype(H))
H.FakeStart()
// PASSIVE (done from LIFE)
@@ -67,7 +70,7 @@
// Don't Heal
// Pay Blood Toll (if awake)
if (user.stat == CONSCIOUS)
if(user.stat == CONSCIOUS)
bloodsuckerdatum.AddBloodVolume(-0.2)
sleep(20) // Check every few ticks that we haven't disabled this power
@@ -89,9 +92,13 @@
ADD_TRAIT(user, TRAIT_COLDBLOODED, "bloodsucker")
ADD_TRAIT(user, TRAIT_NOHARDCRIT, "bloodsucker")
ADD_TRAIT(user, TRAIT_NOSOFTCRIT, "bloodsucker")
ADD_TRAIT(user, TRAIT_VIRUSIMMUNE, "bloodsucker")
// HEART
var/obj/item/organ/heart/H = user.getorganslot(ORGAN_SLOT_HEART)
var/obj/item/organ/eyes/vassal/bloodsucker/E = user.getorganslot(ORGAN_SLOT_EYES)
H.Stop()
E.flash_protect = 2
to_chat(user, "<span class='notice'>Your heart beats one final time, while your skin dries out and your icy pallor returns.</span>")

View File

@@ -89,17 +89,14 @@
if(istype(target))
target.Stun(40) //Utterly useless without this, its okay since there are so many checks to go through
target.silent = 45 //Shhhh little lamb
target.apply_status_effect(STATUS_EFFECT_MESMERIZE, 45) //So you cant rotate with combat mode, plus fancy status alert
if(do_mob(user, target, 40, 0, TRUE, extra_checks=CALLBACK(src, .proc/ContinueActive, user, target)))
PowerActivatedSuccessfully() // PAY COST! BEGIN COOLDOWN!
var/power_time = 90 + level_current * 12
target.silent = power_time + 20
target.apply_status_effect(STATUS_EFFECT_MESMERIZE, 100 + level_current * 15)
target.apply_status_effect(STATUS_EFFECT_MESMERIZE, power_time + 80)
to_chat(user, "<span class='notice'>[target] is fixed in place by your hypnotic gaze.</span>")
target.Stun(power_time)
//target.silent += power_time / 10 // Silent isn't based on ticks.
target.next_move = world.time + power_time // <--- Use direct change instead. We want an unmodified delay to their next move // target.changeNext_move(power_time) // check click.dm
target.notransform = TRUE // <--- Fuck it. We tried using next_move, but they could STILL resist. We're just doing a hard freeze.
spawn(power_time)

View File

@@ -89,13 +89,7 @@
user.invisibility = INVISIBILITY_MAXIMUM
// LOSE CUFFS
if(user.handcuffed)
var/obj/O = user.handcuffed
user.dropItemToGround(O)
if(user.legcuffed)
var/obj/O = user.legcuffed
user.dropItemToGround(O)
// Wait...
sleep(mist_delay / 2)

View File

@@ -26,6 +26,7 @@
spacewalk = TRUE
sight = SEE_SELF
throwforce = 0
blood_volume = 0
see_in_dark = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE

View File

@@ -0,0 +1,50 @@
/obj/item/assembly/playback
name = "playback device"
desc = "A small electronic device able to record a voice sample, and repeat that sample when it receive a signal."
icon_state = "radio"
materials = list(MAT_METAL=500, MAT_GLASS=50)
flags_1 = HEAR_1
attachable = TRUE
verb_say = "beeps"
verb_ask = "beeps"
verb_exclaim = "beeps"
var/listening = FALSE
var/recorded = "" //the activation message
var/languages
/obj/item/assembly/playback/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode, atom/movable/source)
. = ..()
if(speaker == src)
return
if(listening && !radio_freq)
record_speech(speaker, raw_message, message_language)
/obj/item/assembly/playback/proc/record_speech(atom/movable/speaker, raw_message, datum/language/message_language)
recorded = raw_message
listening = FALSE
languages = message_language
say("Activation message is '[recorded]'.", language = message_language)
/obj/item/assembly/playback/activate()
if(recorded == "") // Why say anything when there isn't anything to say
return FALSE
say("[recorded]", language = languages) // Repeat the message in the language it was said in
return TRUE
/obj/item/assembly/playback/proc/record()
if(!secured || holder)
return FALSE
listening = !listening
say("[listening ? "Now" : "No longer"] recording input.")
return TRUE
/obj/item/assembly/playback/attack_self(mob/user)
if(!user)
return FALSE
record()
return TRUE
/obj/item/assembly/playback/toggle_secure()
. = ..()
listening = FALSE

View File

@@ -15,6 +15,7 @@
verb_exclaim = "beeps"
var/listening = FALSE
var/recorded = "" //the activation message
var/languages // The Message's language
var/mode = 1
var/static/list/modes = list("inclusive",
"exclusive",
@@ -33,23 +34,25 @@
if(listening && !radio_freq)
record_speech(speaker, raw_message, message_language)
else
if(check_activation(speaker, raw_message))
addtimer(CALLBACK(src, .proc/pulse, 0), 10)
if(message_language == languages) // If it isn't in the same language as the message, don't try to find the message
if(check_activation(speaker, raw_message))
addtimer(CALLBACK(src, .proc/pulse, 0), 10)
/obj/item/assembly/voice/proc/record_speech(atom/movable/speaker, raw_message, datum/language/message_language)
languages = message_language // Assign the message's language to a variable to use it elsewhere
switch(mode)
if(INCLUSIVE_MODE)
recorded = raw_message
listening = FALSE
say("Activation message is '[recorded]'.", message_language)
say("Activation message is '[recorded]'.", language = languages) // Say the message in the language it was said in
if(EXCLUSIVE_MODE)
recorded = raw_message
listening = FALSE
say("Activation message is '[recorded]'.", message_language)
say("Activation message is '[recorded]'.", language = languages)
if(RECOGNIZER_MODE)
recorded = speaker.GetVoice()
listening = FALSE
say("Your voice pattern is saved.", message_language)
say("Your voice pattern is saved.", language = languages)
if(VOICE_SENSOR_MODE)
if(length(raw_message))
addtimer(CALLBACK(src, .proc/pulse, 0), 10)

View File

@@ -1,144 +1,147 @@
/*********************Hivelord stabilizer****************/
/obj/item/hivelordstabilizer
name = "stabilizing serum"
icon = 'icons/obj/chemical.dmi'
icon_state = "bottle19"
desc = "Inject certain types of monster organs with this stabilizer to preserve their healing powers indefinitely."
w_class = WEIGHT_CLASS_TINY
/obj/item/hivelordstabilizer/afterattack(obj/item/organ/M, mob/user)
. = ..()
var/obj/item/organ/regenerative_core/C = M
if(!istype(C, /obj/item/organ/regenerative_core))
to_chat(user, "<span class='warning'>The stabilizer only works on certain types of monster organs, generally regenerative in nature.</span>")
return ..()
C.preserved()
to_chat(user, "<span class='notice'>You inject the [M] with the stabilizer. It will no longer go inert.</span>")
qdel(src)
/************************Hivelord core*******************/
/obj/item/organ/regenerative_core
name = "regenerative core"
desc = "All that remains of a hivelord. It can be used to heal completely, but it will rapidly decay into uselessness."
icon_state = "roro core 2"
item_flags = NOBLUDGEON
slot = "hivecore"
force = 0
actions_types = list(/datum/action/item_action/organ_action/use)
var/inert = 0
var/preserved = 0
/obj/item/organ/regenerative_core/Initialize()
. = ..()
addtimer(CALLBACK(src, .proc/inert_check), 2400)
/obj/item/organ/regenerative_core/proc/inert_check()
if(!preserved)
go_inert()
/obj/item/organ/regenerative_core/proc/preserved(implanted = 0)
inert = FALSE
preserved = TRUE
update_icon()
desc = "All that remains of a hivelord. It is preserved, allowing you to use it to heal completely without danger of decay."
if(implanted)
SSblackbox.record_feedback("nested tally", "hivelord_core", 1, list("[type]", "implanted"))
else
SSblackbox.record_feedback("nested tally", "hivelord_core", 1, list("[type]", "stabilizer"))
/obj/item/organ/regenerative_core/proc/go_inert()
inert = TRUE
name = "decayed regenerative core"
desc = "All that remains of a hivelord. It has decayed, and is completely useless."
SSblackbox.record_feedback("nested tally", "hivelord_core", 1, list("[type]", "inert"))
update_icon()
/obj/item/organ/regenerative_core/ui_action_click()
if(inert)
to_chat(owner, "<span class='notice'>[src] breaks down as it tries to activate.</span>")
else
owner.revive(full_heal = 1)
owner.log_message("[owner] used an implanted [src] to heal themselves! Keep fighting, it's just a flesh wound!", LOG_ATTACK, color="green") //Logging for implanted legion core use
qdel(src)
/obj/item/organ/regenerative_core/on_life()
..()
if(owner.health < owner.crit_threshold)
ui_action_click()
/obj/item/organ/regenerative_core/afterattack(atom/target, mob/user, proximity_flag)
. = ..()
if(proximity_flag && ishuman(target))
var/mob/living/carbon/human/H = target
if(inert)
to_chat(user, "<span class='notice'>[src] has decayed and can no longer be used to heal.</span>")
return
else
if(H.stat == DEAD)
to_chat(user, "<span class='notice'>[src] are useless on the dead.</span>")
return
if(H != user)
H.visible_message("[user] forces [H] to apply [src]... [H.p_they()] quickly regenerate all injuries!")
SSblackbox.record_feedback("nested tally", "hivelord_core", 1, list("[type]", "used", "other"))
else
to_chat(user, "<span class='notice'>You start to smear [src] on yourself. It feels and smells disgusting, but you feel amazingly refreshed in mere moments.</span>")
SSblackbox.record_feedback("nested tally", "hivelord_core", 1, list("[type]", "used", "self"))
H.revive(full_heal = 1)
qdel(src)
user.log_message("[user] used [src] to heal [H]! Wake the fuck up, Samurai!", LOG_ATTACK, color="green") //Logging for 'old' style legion core use, when clicking on a sprite of yourself or another.
/obj/item/organ/regenerative_core/attack_self(mob/user) //Knouli's first hack! Allows for the use of the core in hand rather than needing to click on the target, yourself, to selfheal. Its a rip of the proc just above - but skips on distance check and only uses 'user' rather than 'target'
if(ishuman(user)) //Check if user is human, no need for distance check as it's self heal
var/mob/living/carbon/human/H = user //Set H to user rather than target
if(inert) //Inert cores are useless
to_chat(user, "<span class='notice'>[src] has decayed and can no longer be used to heal.</span>")
return
else //Skip on check if the target to be healed is dead as, if you are dead, you're not going to be able to use it on yourself!
to_chat(user, "<span class='notice'>You start to smear [src] on yourself. It feels and smells disgusting, but you feel amazingly refreshed in mere moments.</span>")
SSblackbox.record_feedback("nested tally", "hivelord_core", 1, list("[type]", "used", "self"))
H.revive(full_heal = 1)
qdel(src)
H.log_message("[H] used [src] to heal themselves! Making use of Knouli's sexy and intelligent use-in-hand proc!", LOG_ATTACK, color="green") //Logging for 'new' style legion core use, when using the core in-hand.
/obj/item/organ/regenerative_core/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
. = ..()
if(!preserved && !inert)
preserved(TRUE)
owner.visible_message("<span class='notice'>[src] stabilizes as it's inserted.</span>")
/obj/item/organ/regenerative_core/Remove(mob/living/carbon/M, special = 0)
if(!inert && !special)
owner.visible_message("<span class='notice'>[src] rapidly decays as it's removed.</span>")
go_inert()
return ..()
/obj/item/organ/regenerative_core/prepare_eat()
return null
/*************************Legion core********************/
/obj/item/organ/regenerative_core/legion
desc = "A strange rock that crackles with power. It can be used to heal completely, but it will rapidly decay into uselessness."
icon_state = "legion_soul"
/obj/item/organ/regenerative_core/legion/Initialize()
. = ..()
update_icon()
/obj/item/organ/regenerative_core/update_icon()
icon_state = inert ? "legion_soul_inert" : "legion_soul"
cut_overlays()
if(!inert && !preserved)
add_overlay("legion_soul_crackle")
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
/obj/item/organ/regenerative_core/legion/go_inert()
..()
desc = "[src] has become inert. It has decayed, and is completely useless."
/obj/item/organ/regenerative_core/legion/preserved(implanted = 0)
..()
desc = "[src] has been stabilized. It is preserved, allowing you to use it to heal completely without danger of decay."
/*********************Hivelord stabilizer****************/
/obj/item/hivelordstabilizer
name = "stabilizing serum"
icon = 'icons/obj/chemical.dmi'
icon_state = "bottle19"
desc = "Inject certain types of monster organs with this stabilizer to preserve their healing powers indefinitely."
w_class = WEIGHT_CLASS_TINY
/obj/item/hivelordstabilizer/afterattack(obj/item/organ/M, mob/user)
. = ..()
var/obj/item/organ/regenerative_core/C = M
if(!istype(C, /obj/item/organ/regenerative_core))
to_chat(user, "<span class='warning'>The stabilizer only works on certain types of monster organs, generally regenerative in nature.</span>")
return ..()
C.preserved()
to_chat(user, "<span class='notice'>You inject the [M] with the stabilizer. It will no longer go inert.</span>")
qdel(src)
/************************Hivelord core*******************/
/obj/item/organ/regenerative_core
name = "regenerative core"
desc = "All that remains of a hivelord. It can be used to heal completely, but it will rapidly decay into uselessness."
icon_state = "roro core 2"
item_flags = NOBLUDGEON
slot = "hivecore"
force = 0
actions_types = list(/datum/action/item_action/organ_action/use)
var/inert = 0
var/preserved = 0
/obj/item/organ/regenerative_core/Initialize()
. = ..()
addtimer(CALLBACK(src, .proc/inert_check), 2400)
/obj/item/organ/regenerative_core/proc/inert_check()
if(!preserved)
go_inert()
/obj/item/organ/regenerative_core/proc/preserved(implanted = 0)
inert = FALSE
preserved = TRUE
update_icon()
desc = "All that remains of a hivelord. It is preserved, allowing you to use it to heal completely without danger of decay."
if(implanted)
SSblackbox.record_feedback("nested tally", "hivelord_core", 1, list("[type]", "implanted"))
else
SSblackbox.record_feedback("nested tally", "hivelord_core", 1, list("[type]", "stabilizer"))
/obj/item/organ/regenerative_core/proc/go_inert()
inert = TRUE
name = "decayed regenerative core"
desc = "All that remains of a hivelord. It has decayed, and is completely useless."
SSblackbox.record_feedback("nested tally", "hivelord_core", 1, list("[type]", "inert"))
update_icon()
/obj/item/organ/regenerative_core/ui_action_click()
if(inert)
to_chat(owner, "<span class='notice'>[src] breaks down as it tries to activate.</span>")
else
owner.revive(full_heal = 1)
owner.log_message("[owner] used an implanted [src] to heal themselves! Keep fighting, it's just a flesh wound!", LOG_ATTACK, color="green") //Logging for implanted legion core use
qdel(src)
/obj/item/organ/regenerative_core/on_life()
..()
if(owner.health < owner.crit_threshold)
ui_action_click()
/obj/item/organ/regenerative_core/afterattack(atom/target, mob/user, proximity_flag)
. = ..()
if(proximity_flag && ishuman(target))
var/mob/living/carbon/human/H = target
if(inert)
to_chat(user, "<span class='notice'>[src] has decayed and can no longer be used to heal.</span>")
return
if(isvamp(user))
to_chat(user, "<span class='notice'>[src] breaks down as it fails to heal your unholy self</span>")
return
else
if(H.stat == DEAD)
to_chat(user, "<span class='notice'>[src] are useless on the dead.</span>")
return
if(H != user)
H.visible_message("[user] forces [H] to apply [src]... [H.p_they()] quickly regenerate all injuries!")
SSblackbox.record_feedback("nested tally", "hivelord_core", 1, list("[type]", "used", "other"))
else
to_chat(user, "<span class='notice'>You start to smear [src] on yourself. It feels and smells disgusting, but you feel amazingly refreshed in mere moments.</span>")
SSblackbox.record_feedback("nested tally", "hivelord_core", 1, list("[type]", "used", "self"))
H.revive(full_heal = 1)
qdel(src)
user.log_message("[user] used [src] to heal [H]! Wake the fuck up, Samurai!", LOG_ATTACK, color="green") //Logging for 'old' style legion core use, when clicking on a sprite of yourself or another.
/obj/item/organ/regenerative_core/attack_self(mob/user) //Knouli's first hack! Allows for the use of the core in hand rather than needing to click on the target, yourself, to selfheal. Its a rip of the proc just above - but skips on distance check and only uses 'user' rather than 'target'
if(ishuman(user)) //Check if user is human, no need for distance check as it's self heal
var/mob/living/carbon/human/H = user //Set H to user rather than target
if(inert) //Inert cores are useless
to_chat(user, "<span class='notice'>[src] has decayed and can no longer be used to heal.</span>")
return
else //Skip on check if the target to be healed is dead as, if you are dead, you're not going to be able to use it on yourself!
to_chat(user, "<span class='notice'>You start to smear [src] on yourself. It feels and smells disgusting, but you feel amazingly refreshed in mere moments.</span>")
SSblackbox.record_feedback("nested tally", "hivelord_core", 1, list("[type]", "used", "self"))
H.revive(full_heal = 1)
qdel(src)
H.log_message("[H] used [src] to heal themselves! Making use of Knouli's sexy and intelligent use-in-hand proc!", LOG_ATTACK, color="green") //Logging for 'new' style legion core use, when using the core in-hand.
/obj/item/organ/regenerative_core/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
. = ..()
if(!preserved && !inert)
preserved(TRUE)
owner.visible_message("<span class='notice'>[src] stabilizes as it's inserted.</span>")
/obj/item/organ/regenerative_core/Remove(mob/living/carbon/M, special = 0)
if(!inert && !special)
owner.visible_message("<span class='notice'>[src] rapidly decays as it's removed.</span>")
go_inert()
return ..()
/obj/item/organ/regenerative_core/prepare_eat()
return null
/*************************Legion core********************/
/obj/item/organ/regenerative_core/legion
desc = "A strange rock that crackles with power. It can be used to heal completely, but it will rapidly decay into uselessness."
icon_state = "legion_soul"
/obj/item/organ/regenerative_core/legion/Initialize()
. = ..()
update_icon()
/obj/item/organ/regenerative_core/update_icon()
icon_state = inert ? "legion_soul_inert" : "legion_soul"
cut_overlays()
if(!inert && !preserved)
add_overlay("legion_soul_crackle")
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
/obj/item/organ/regenerative_core/legion/go_inert()
..()
desc = "[src] has become inert. It has decayed, and is completely useless."
/obj/item/organ/regenerative_core/legion/preserved(implanted = 0)
..()
desc = "[src] has been stabilized. It is preserved, allowing you to use it to heal completely without danger of decay."

View File

@@ -29,6 +29,7 @@
var/obj/machinery/machine = null
var/next_move = null
var/create_area_cooldown
var/notransform = null //Carbon
var/eye_blind = 0 //Carbon
var/eye_blurry = 0 //Carbon

View File

@@ -155,7 +155,7 @@
reagent_state = SOLID
color = "#FFFFFF" // rgb: 255, 255, 255
taste_mult = 1.5 // stop sugar drowning out other flavours
nutriment_factor = 10 * REAGENTS_METABOLISM
nutriment_factor = 5 * REAGENTS_METABOLISM
metabolization_rate = 2 * REAGENTS_METABOLISM
overdose_threshold = 200 // Hyperglycaemic shock
taste_description = "sweetness"

View File

@@ -172,9 +172,8 @@
var/total_damage = brute + burn
if(total_damage > can_inflict)
var/excess = total_damage - can_inflict
brute = round(brute * (excess / total_damage),DAMAGE_PRECISION)
burn = round(burn * (excess / total_damage),DAMAGE_PRECISION)
brute = round(brute * (max_damage / total_damage),DAMAGE_PRECISION)
burn = round(burn * (max_damage / total_damage),DAMAGE_PRECISION)
brute_dam += brute
burn_dam += burn

View File

@@ -19,7 +19,7 @@
TGS_ERROR_LOG("Custom command [command_name] can't be used as it is empty or contains illegal characters!")
warned_command_names[command_name] = TRUE
continue
if(command_name_types[command_name])
if(warnings_only)
TGS_ERROR_LOG("Custom commands [command_name_types[command_name]] and [stc] have the same name, only [command_name_types[command_name]] will be available!")
@@ -55,24 +55,24 @@ The MIT License
Copyright (c) 2017 Jordan Brown
Permission is hereby granted, free of charge,
to any person obtaining a copy of this software and
associated documentation files (the "Software"), to
deal in the Software without restriction, including
without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom
the Software is furnished to do so,
Permission is hereby granted, free of charge,
to any person obtaining a copy of this software and
associated documentation files (the "Software"), to
deal in the Software without restriction, including
without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom
the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice
The above copyright notice and this permission notice
shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

View File

@@ -1,6 +1,7 @@
/obj/machinery/vending/assist
products = list(/obj/item/assembly/prox_sensor = 7,
/obj/item/assembly/igniter = 6,
/obj/item/assembly/playback = 4,
/obj/item/assembly/signaler = 6,
/obj/item/wirecutters = 3,
/obj/item/stock_parts/cell/crap = 6,