This commit is contained in:
Seris02
2020-01-11 11:29:30 +08:00
930 changed files with 28101 additions and 20202 deletions
@@ -484,11 +484,9 @@
user.do_attack_animation(L)
if(ishuman(L))
var/mob/living/carbon/human/H = L
if(H.check_shields(src, 0, "[user]'s [name]", MELEE_ATTACK))
playsound(H, 'sound/weapons/genhit.ogg', 50, TRUE)
return FALSE
if(L.check_shields(src, 0, "[user]'s [name]", MELEE_ATTACK))
playsound(L, 'sound/weapons/genhit.ogg', 50, TRUE)
return FALSE
switch (mode)
if(BATON_STUN)
@@ -797,7 +795,7 @@
icon_state = "bed"
can_buckle = 1
var/static/list/injected_reagents = list("corazone")
var/static/list/injected_reagents = list(/datum/reagent/medicine/corazone)
/obj/structure/table/optable/abductor/Crossed(atom/movable/AM)
. = ..()
@@ -143,9 +143,9 @@
create_reagents(10)
if(overmind && overmind.blob_reagent_datum)
reagents.add_reagent(overmind.blob_reagent_datum.id, 10)
reagents.add_reagent(overmind.blob_reagent_datum.type, 10)
else
reagents.add_reagent("spore", 10)
reagents.add_reagent(/datum/reagent/toxin/spore, 10)
// Attach the smoke spreader and setup/start it.
S.attach(location)
@@ -3,6 +3,7 @@
icon = 'icons/mob/blob.dmi'
icon_state = "blob_shield"
desc = "A solid wall of slightly twitching tendrils."
var/damaged_desc = "A wall of twitching tendrils."
max_integrity = 150
brute_resist = 0.25
explosion_block = 3
@@ -21,10 +22,10 @@
/obj/structure/blob/shield/update_icon()
..()
if(obj_integrity <= 70)
icon_state = "blob_shield_damaged"
name = "weakened strong blob"
desc = "A wall of twitching tendrils."
if(obj_integrity < max_integrity * 0.5)
icon_state = "[initial(icon_state)]_damaged"
name = "weakened [initial(name)]"
desc = "[damaged_desc]"
atmosblock = FALSE
if(!weakened)
armor = armor.setRating("melee" = 15, "bullet" = 15, "laser" = 5, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90)
@@ -37,4 +38,27 @@
if(weakened)
armor = armor.setRating("melee" = 25, "bullet" = 25, "laser" = 15, "energy" = 10, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90)
weakened = FALSE
air_update_turf(1)
air_update_turf(1)
/obj/structure/blob/shield/reflective
name = "reflective blob"
desc = "A solid wall of slightly twitching tendrils with a reflective glow."
damaged_desc = "A wall of twitching tendrils with a reflective glow."
icon_state = "blob_glow"
flags_1 = CHECK_RICOCHET_1
point_return = 8
max_integrity = 50
brute_resist = 1
explosion_block = 2
/obj/structure/blob/shield/reflective/handle_ricochet(obj/item/projectile/P)
var/turf/p_turf = get_turf(P)
var/face_direction = get_dir(src, p_turf)
var/face_angle = dir2angle(face_direction)
var/incidence_s = GET_ANGLE_OF_INCIDENCE(face_angle, (P.Angle + 180))
if(abs(incidence_s) > 90 && abs(incidence_s) < 270)
return FALSE
var/new_angle_s = SIMPLIFY_DEGREES(face_angle + incidence_s)
P.setAngle(new_angle_s)
visible_message("<span class='warning'>[P] reflects off [src]!</span>")
return TRUE
+16 -6
View File
@@ -113,12 +113,22 @@
/mob/camera/blob/verb/create_shield_power()
set category = "Blob"
set name = "Create Shield Blob (15)"
set desc = "Create a shield blob, which will block fire and is hard to kill."
set name = "Create/Upgrade Shield Blob (15)"
set desc = "Create a shield blob, which will block fire and is hard to kill. Using this on an existing shield blob turns it into a reflective blob, capable of reflecting most projectiles but making it much weaker than usual to brute attacks."
create_shield()
/mob/camera/blob/proc/create_shield(turf/T)
createSpecial(15, /obj/structure/blob/shield, 0, 0, T)
var/obj/structure/blob/shield/S = locate(/obj/structure/blob/shield) in T
if(S)
if(!can_buy(15))
return
if(S.obj_integrity < S.max_integrity * 0.5)
to_chat(src, "<span class='warning'>This shield blob is too damaged to be modified properly!</span>")
return
to_chat(src, "<span class='warning'>You secrete a reflective ooze over the shield blob, allowing it to reflect projectiles at the cost of reduced intregrity.</span>")
S.change_to(/obj/structure/blob/shield/reflective, src)
else
createSpecial(15, /obj/structure/blob/shield, 0, 0, T)
/mob/camera/blob/verb/create_resource()
set category = "Blob"
@@ -156,7 +166,7 @@
if(!can_buy(40))
return
var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as a [blob_reagent_datum.name] blobbernaut?", ROLE_BLOB, null, ROLE_BLOB, 50) //players must answer rapidly
var/list/mob/candidates = pollGhostCandidates("Do you want to play as a [blob_reagent_datum.name] blobbernaut?", ROLE_BLOB, null, ROLE_BLOB, 50) //players must answer rapidly
if(LAZYLEN(candidates)) //if we got at least one candidate, they're a blobbernaut now.
B.max_integrity = initial(B.max_integrity) * 0.25 //factories that produced a blobbernaut have much lower health
B.obj_integrity = min(B.obj_integrity, B.max_integrity)
@@ -171,7 +181,7 @@
blobber.update_icons()
blobber.adjustHealth(blobber.maxHealth * 0.5)
blob_mobs += blobber
var/mob/dead/observer/C = pick(candidates)
var/mob/C = pick(candidates)
C.transfer_ckey(blobber)
SEND_SOUND(blobber, sound('sound/effects/blobattack.ogg'))
SEND_SOUND(blobber, sound('sound/effects/attackblob.ogg'))
@@ -359,7 +369,7 @@
to_chat(src, "<b>You can expand, which will attack people, damage objects, or place a Normal Blob if the tile is clear.</b>")
to_chat(src, "<i>Normal Blobs</i> will expand your reach and can be upgraded into special blobs that perform certain functions.")
to_chat(src, "<b>You can upgrade normal blobs into the following types of blob:</b>")
to_chat(src, "<i>Shield Blobs</i> are strong and expensive blobs which take more damage. In additon, they are fireproof and can block air, use these to protect yourself from station fires.")
to_chat(src, "<i>Shield Blobs</i> are strong and expensive blobs which take more damage. In additon, they are fireproof and can block air, use these to protect yourself from station fires. Upgrading them again will result in a reflective blob, capable of reflecting most projectiles at the cost of the strong blob's extra health.")
to_chat(src, "<i>Resource Blobs</i> are blobs which produce more resources for you, build as many of these as possible to consume the station. This type of blob must be placed near node blobs or your core to work.")
to_chat(src, "<i>Factory Blobs</i> are blobs that spawn blob spores which will attack nearby enemies. This type of blob must be placed near node blobs or your core to work.")
to_chat(src, "<i>Blobbernauts</i> can be produced from factories for a cost, and are hard to kill, powerful, and moderately smart. The factory used to create one will become fragile and briefly unable to produce spores.")
@@ -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
@@ -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:
@@ -183,7 +183,7 @@
BuyPower(new /datum/action/bloodsucker/masquerade)
BuyPower(new /datum/action/bloodsucker/veil)
// Traits
for (var/T in defaultTraits)
for(var/T in defaultTraits)
ADD_TRAIT(owner.current, T, "bloodsucker")
if(HAS_TRAIT(owner.current, TRAIT_TOXINLOVER)) //No slime bonuses here, no thank you
had_toxlover = TRUE
@@ -200,10 +200,10 @@
var/mob/living/carbon/human/H = owner.current
var/datum/species/S = H.dna.species
// Make Changes
S.brutemod *= 0.5 // <-------------------- Start small, but burn mod increases based on rank!
S.coldmod = 0
S.stunmod *= 0.25
S.siemens_coeff *= 0.75 //base electrocution coefficient 1
H.physiology.brute_mod *= 0.8 // <-------------------- Start small, but burn mod increases based on rank!
H.physiology.cold_mod = 0
H.physiology.stun_mod *= 0.35
H.physiology.siemens_coeff *= 0.75 //base electrocution coefficient 1
//S.heatmod += 0.5 // Heat shouldn't affect. Only Fire.
//S.punchstunthreshold = 8 //damage at which punches from this race will stun 9
S.punchdamagelow += 1 //lowest possible punch damage 0
@@ -319,12 +319,10 @@ datum/antagonist/bloodsucker/proc/SpendRank()
if(ishuman(owner.current))
var/mob/living/carbon/human/H = owner.current
var/datum/species/S = H.dna.species
S.burnmod *= 0.025 // Slightly more burn damage
S.stunmod *= 0.95 // Slightly less stun time.
S.punchdamagelow += 0.5
S.punchdamagehigh += 0.5 // NOTE: This affects the hitting power of Brawn.
// More Health
owner.current.setMaxHealth(owner.current.maxHealth + 5)
owner.current.setMaxHealth(owner.current.maxHealth + 10)
// Vamp Stats
regenRate += 0.05 // Points of brute healed (starts at 0.3)
feedAmount += 2 // Increase how quickly I munch down vics (15)
@@ -336,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.
@@ -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)
@@ -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
@@ -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
@@ -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>")
@@ -275,7 +275,7 @@
// All done!
if(convert_progress <= 0)
// FAIL: Can't be Vassal
if(!SSticker.mode.can_make_vassal(target, user, display_warning=FALSE) && HAS_TRAIT(target, TRAIT_MINDSHIELD)) // If I'm an unconvertable Antag ONLY
if(!SSticker.mode.can_make_vassal(target, user, display_warning=FALSE) || HAS_TRAIT(target, TRAIT_MINDSHIELD)) // If I'm an unconvertable Antag ONLY
to_chat(user, "<span class='danger'>[target] doesn't respond to your persuasion. It doesn't appear they can be converted to follow you, they either have a mindshield or their external loyalties are too difficult for you to break.<i>\[ALT+click to release\]</span>")
convert_progress ++ // Pop it back up some. Avoids wasting Blood on a lost cause.
// SUCCESS: All done!
@@ -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)
@@ -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()
@@ -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>")
@@ -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)
@@ -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)
@@ -13,5 +13,5 @@
//Recover from stuns.
/obj/effect/proc_holder/changeling/adrenaline/sting_action(mob/living/user)
user.do_adrenaline(0, FALSE, 70, 0, TRUE, list("epinephrine" = 3, "changelingmeth" = 10, "mannitol" = 10, "regen_jelly" = 10, "changelingadrenaline" = 5), "<span class='notice'>Energy rushes through us.</span>", 0, 0.75, 0)
user.do_adrenaline(0, FALSE, 70, 0, TRUE, list(/datum/reagent/medicine/epinephrine = 3, /datum/reagent/drug/methamphetamine/changeling = 10, /datum/reagent/medicine/mannitol = 10, /datum/reagent/medicine/regen_jelly = 10, /datum/reagent/medicine/changelingadrenaline = 5), "<span class='notice'>Energy rushes through us.</span>", 0, 0.75, 0)
return TRUE
@@ -58,7 +58,7 @@
target.mind.linglink = 1
target.say("[MODE_TOKEN_CHANGELING] AAAAARRRRGGGGGHHHHH!!")
to_chat(target, "<font color=#800040><span class='boldannounce'>You can now communicate in the changeling hivemind, say \"[MODE_TOKEN_CHANGELING] message\" to communicate!</span>")
target.reagents.add_reagent("salbutamol", 40) // So they don't choke to death while you interrogate them
target.reagents.add_reagent(/datum/reagent/medicine/salbutamol, 40) // So they don't choke to death while you interrogate them
sleep(1800)
SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("[name]", "[i]"))
if(!do_mob(user, target, 20))
@@ -500,7 +500,7 @@
/obj/item/clothing/suit/space/changeling/process()
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
H.reagents.add_reagent("salbutamol", REAGENTS_METABOLISM)
H.reagents.add_reagent(/datum/reagent/medicine/salbutamol, REAGENTS_METABOLISM)
/obj/item/clothing/head/helmet/space/changeling
name = "flesh mass"
@@ -28,10 +28,10 @@
C.vomit(0, toxic = TRUE)
O.forceMove(get_turf(user))
user.reagents.add_reagent("mutadone", 10)
user.reagents.add_reagent("pen_jelly", 20)
user.reagents.add_reagent("antihol", 10)
user.reagents.add_reagent("mannitol", 25)
user.reagents.add_reagent(/datum/reagent/medicine/mutadone, 10)
user.reagents.add_reagent(/datum/reagent/medicine/pen_acid/pen_jelly, 20)
user.reagents.add_reagent(/datum/reagent/medicine/antihol, 10)
user.reagents.add_reagent(/datum/reagent/medicine/mannitol, 25)
if(isliving(user))
var/mob/living/L = user
@@ -104,11 +104,11 @@
var/mob/living/carbon/C = target
. = TRUE
if(istype(C))
if(C.reagents.has_reagent("changeling_sting_real"))
C.reagents.add_reagent("changeling_sting_real",120)
if(C.reagents.has_reagent(/datum/reagent/changeling_string))
C.reagents.add_reagent(/datum/reagent/changeling_string,120)
log_combat(user, target, "stung", "transformation sting", ", extending the duration.")
else
C.reagents.add_reagent("changeling_sting_real",120,list("desired_dna" = selected_dna.dna))
C.reagents.add_reagent(/datum/reagent/changeling_string,120,list("desired_dna" = selected_dna.dna))
log_combat(user, target, "stung", "transformation sting", " new identity is '[selected_dna.dna.real_name]'")
@@ -243,8 +243,8 @@
/obj/effect/proc_holder/changeling/sting/LSD/sting_action(mob/user, mob/target)
log_combat(user, target, "stung", "LSD sting")
if(target.reagents)
target.reagents.add_reagent("regenerative_materia", 5)
target.reagents.add_reagent("mindbreaker", 5)
target.reagents.add_reagent(/datum/reagent/blob/regenerative_materia, 5)
target.reagents.add_reagent(/datum/reagent/toxin/mindbreaker, 5)
return TRUE
/obj/effect/proc_holder/changeling/sting/cryo
@@ -262,5 +262,5 @@
/obj/effect/proc_holder/changeling/sting/cryo/sting_action(mob/user, mob/target)
log_combat(user, target, "stung", "cryo sting")
if(target.reagents)
target.reagents.add_reagent("frostoil", 30)
target.reagents.add_reagent(/datum/reagent/consumable/frostoil, 30)
return TRUE
@@ -100,7 +100,7 @@
var/burndamage = L.getFireLoss()
var/oxydamage = L.getOxyLoss()
var/totaldamage = brutedamage + burndamage + oxydamage
if(!totaldamage && (!L.reagents || !L.reagents.has_reagent("holywater")))
if(!totaldamage && (!L.reagents || !L.reagents.has_reagent(/datum/reagent/water/holywater)))
to_chat(ranged_ability_user, "<span class='inathneq'>\"[L] is unhurt and untainted.\"</span>")
return TRUE
@@ -108,7 +108,7 @@
to_chat(ranged_ability_user, "<span class='brass'>You bathe [L == ranged_ability_user ? "yourself":"[L]"] in Inath-neq's power!</span>")
var/targetturf = get_turf(L)
var/has_holy_water = (L.reagents && L.reagents.has_reagent("holywater"))
var/has_holy_water = (L.reagents && L.reagents.has_reagent(/datum/reagent/water/holywater))
var/healseverity = max(round(totaldamage*0.05, 1), 1) //shows the general severity of the damage you just healed, 1 glow per 20
for(var/i in 1 to healseverity)
new /obj/effect/temp_visual/heal(targetturf, "#1E8CE1")
@@ -129,7 +129,7 @@
playsound(targetturf, 'sound/magic/staff_healing.ogg', 50, 1)
if(has_holy_water)
L.reagents.remove_reagent("holywater", 1000)
L.reagents.del_reagent(/datum/reagent/water/holywater)
remove_ranged_ability()
@@ -7,7 +7,7 @@
w_class = WEIGHT_CLASS_NORMAL
resistance_flags = FIRE_PROOF | ACID_PROOF
flags_inv = HIDEEARS|HIDEHAIR|HIDEFACE|HIDESNOUT
mutantrace_variation = MUTANTRACE_VARIATION
mutantrace_variation = STYLE_MUZZLE
armor = list("melee" = 50, "bullet" = 70, "laser" = -25, "energy" = 0, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
/obj/item/clothing/head/helmet/clockwork/Initialize()
@@ -103,7 +103,7 @@
. = ..()
addtimer(CALLBACK(src, .proc/check_on_mob, user), 1) //dropped is called before the item is out of the slot, so we need to check slightly later
/obj/item/clockwork/slab/worn_overlays(isinhands = FALSE, icon_file)
/obj/item/clockwork/slab/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
. = list()
if(isinhands && item_state && inhand_overlay)
var/mutable_appearance/M = mutable_appearance(icon_file, "slab_[inhand_overlay]")
@@ -139,7 +139,7 @@
var/new_thing_type = fabrication_values["new_obj_type"]
if(isturf(target)) //if our target is a turf, we're just going to ChangeTurf it and assume it'll work out.
var/turf/T = target
T.ChangeTurf(new_thing_type)
T.ChangeTurf(new_thing_type, flags = CHANGETURF_INHERIT_AIR)
else
if(new_thing_type)
if(fabrication_values["dir_in_new"])
@@ -59,7 +59,7 @@
if(anchored)
T.PlaceOnTop(/turf/closed/wall/clockwork)
else
T.PlaceOnTop(/turf/open/floor/clockwork)
T.PlaceOnTop(/turf/open/floor/clockwork, flags = CHANGETURF_INHERIT_AIR)
new /obj/structure/falsewall/brass(T)
qdel(src)
else
+5 -5
View File
@@ -331,7 +331,7 @@
flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDEEARS|HIDEEYES|HIDESNOUT
armor = list("melee" = 30, "bullet" = 30, "laser" = 30,"energy" = 20, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 10, "acid" = 10)
flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH
mutantrace_variation = MUTANTRACE_VARIATION
mutantrace_variation = STYLE_MUZZLE
/obj/item/clothing/suit/magusred
name = "magus robes"
@@ -424,7 +424,7 @@
return 1
return 0
/obj/item/clothing/suit/hooded/cultrobes/cult_shield/worn_overlays(isinhands)
/obj/item/clothing/suit/hooded/cultrobes/cult_shield/worn_overlays(isinhands, icon_file, style_flags = NONE)
. = list()
if(!isinhands && current_charges)
. += mutable_appearance('icons/effects/cult_effects.dmi', "shield-cult", MOB_LAYER + 0.01)
@@ -487,7 +487,7 @@
icon = 'icons/obj/drinks.dmi'
icon_state = "holyflask"
color = "#333333"
list_reagents = list("unholywater" = 50)
list_reagents = list(/datum/reagent/fuel/unholywater = 50)
/obj/item/shuttle_curse
name = "cursed orb"
@@ -797,7 +797,7 @@
if(ishuman(target))
var/mob/living/carbon/human/H = target
if(H.stat != DEAD)
H.reagents.add_reagent("unholywater", 4)
H.reagents.add_reagent(/datum/reagent/fuel/unholywater, 4)
if(isshade(target) || isconstruct(target))
var/mob/living/simple_animal/M = target
if(M.health+5 < M.maxHealth)
@@ -898,7 +898,7 @@
if(ishuman(target))
var/mob/living/carbon/human/H = target
if(H.stat != DEAD)
H.reagents.add_reagent("unholywater", 7)
H.reagents.add_reagent(/datum/reagent/fuel/unholywater, 7)
if(isshade(target) || isconstruct(target))
var/mob/living/simple_animal/M = target
if(M.health+15 < M.maxHealth)
@@ -239,9 +239,9 @@
var/turf/T = safepick(validturfs)
if(T)
if(istype(T, /turf/open/floor/plating))
T.PlaceOnTop(/turf/open/floor/engine/cult)
T.PlaceOnTop(/turf/open/floor/engine/cult, flags = CHANGETURF_INHERIT_AIR)
else
T.ChangeTurf(/turf/open/floor/engine/cult)
T.ChangeTurf(/turf/open/floor/engine/cult, flags = CHANGETURF_INHERIT_AIR)
else
var/turf/open/floor/engine/cult/F = safepick(cultturfs)
if(F)
+4 -4
View File
@@ -24,11 +24,11 @@ This file contains the cult dagger and rune list code
/obj/item/melee/cultblade/dagger/attack(mob/living/M, mob/living/user)
if(iscultist(M))
if(M.reagents && M.reagents.has_reagent("holywater")) //allows cultists to be rescued from the clutches of ordained religion
if(M.reagents && M.reagents.has_reagent(/datum/reagent/water/holywater)) //allows cultists to be rescued from the clutches of ordained religion
to_chat(user, "<span class='cult'>You remove the taint from [M].</span>" )
var/holy2unholy = M.reagents.get_reagent_amount("holywater")
M.reagents.del_reagent("holywater")
M.reagents.add_reagent("unholywater",holy2unholy)
var/holy2unholy = M.reagents.get_reagent_amount(/datum/reagent/water/holywater)
M.reagents.del_reagent(/datum/reagent/water/holywater)
M.reagents.add_reagent(/datum/reagent/fuel/unholywater,holy2unholy)
log_combat(user, M, "smacked", src, " removing the holy water from them")
return FALSE
. = ..()
+2 -2
View File
@@ -384,14 +384,14 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
if(BANISH_WATER)
if(iscarbon(body))
var/mob/living/carbon/H = body
return H.reagents.has_reagent("holy water")
return H.reagents.has_reagent(/datum/reagent/water/holywater)
return 0
if(BANISH_COFFIN)
return (body && istype(body.loc, /obj/structure/closet/crate/coffin))
if(BANISH_FORMALDYHIDE)
if(iscarbon(body))
var/mob/living/carbon/H = body
return H.reagents.has_reagent("formaldehyde")
return H.reagents.has_reagent(/datum/reagent/toxin/formaldehyde)
return 0
if(BANISH_RUNES)
if(body)
@@ -5,6 +5,14 @@
antagpanel_category = "ClownOp"
nukeop_outfit = /datum/outfit/syndicate/clownop
/datum/antagonist/nukeop/clownop/on_gain()
. = ..()
ADD_TRAIT(owner, TRAIT_CLOWN_MENTALITY, NUKEOP_ANTAGONIST)
/datum/antagonist/nukeop/clownop/on_removal()
REMOVE_TRAIT(owner, TRAIT_CLOWN_MENTALITY, NUKEOP_ANTAGONIST)
return ..()
/datum/antagonist/nukeop/leader/clownop
name = "Clown Operative Leader"
roundend_category = "clown operatives"
@@ -76,9 +76,10 @@ GLOBAL_VAR_INIT(war_declared, FALSE)
CONFIG_SET(number/shuttle_refuel_delay, max(CONFIG_GET(number/shuttle_refuel_delay), CHALLENGE_SHUTTLE_DELAY))
if(istype(SSticker.mode, /datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
var/threat_spent = CONFIG_GET(number/dynamic_warops_cost)
mode.spend_threat(threat_spent)
mode.log_threat("Nuke ops spent [threat_spent] on war ops.")
if(!(mode.storyteller.flags & WAROPS_ALWAYS_ALLOWED))
var/threat_spent = CONFIG_GET(number/dynamic_warops_cost)
mode.spend_threat(threat_spent)
mode.log_threat("Nuke ops spent [threat_spent] on war ops.")
SSblackbox.record_feedback("amount", "nuclear_challenge_mode", 1)
qdel(src)
@@ -101,12 +102,13 @@ GLOBAL_VAR_INIT(war_declared, FALSE)
return FALSE
if(istype(SSticker.mode, /datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
if(mode.threat_level < CONFIG_GET(number/dynamic_warops_requirement))
to_chat(user, "Due to the dynamic space in which the station resides, you are too deep into Nanotrasen territory to reasonably go loud.")
return FALSE
else if(mode.threat < CONFIG_GET(number/dynamic_warops_cost))
to_chat(user, "Due to recent threats on the station, Nanotrasen is looking too closely for a war declaration to be wise.")
return FALSE
if(!(mode.storyteller.flags & WAROPS_ALWAYS_ALLOWED))
if(mode.threat_level < CONFIG_GET(number/dynamic_warops_requirement))
to_chat(user, "Due to the dynamic space in which the station resides, you are too deep into Nanotrasen territory to reasonably go loud.")
return FALSE
else if(mode.threat < CONFIG_GET(number/dynamic_warops_cost))
to_chat(user, "Due to recent threats on the station, Nanotrasen is looking too closely for a war declaration to be wise.")
return FALSE
return TRUE
/obj/item/nuclear_challenge/clownops
@@ -513,7 +513,7 @@
/obj/machinery/nuclearbomb/beer/proc/fizzbuzz()
var/datum/reagents/R = new/datum/reagents(1000)
R.my_atom = src
R.add_reagent("beer", 100)
R.add_reagent(/datum/reagent/consumable/ethanol/beer, 100)
var/datum/effect_system/foam_spread/foam = new
foam.set_up(200, get_turf(src), R)
@@ -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
@@ -353,7 +353,7 @@
to_chat(H, "<span class='revenminor'>You feel [pick("suddenly sick", "a surge of nausea", "like your skin is <i>wrong</i>")].</span>")
else
if(mob.reagents)
mob.reagents.add_reagent("plasma", 5)
mob.reagents.add_reagent(/datum/reagent/toxin/plasma, 5)
else
mob.adjustToxLoss(5)
for(var/obj/structure/spacevine/vine in T) //Fucking with botanists, the ability.
@@ -80,6 +80,8 @@
if(istype(SSticker.mode,/datum/game_mode/dynamic))
mode = SSticker.mode
is_dynamic = TRUE
if(mode.storyteller.flags & NO_ASSASSIN)
is_hijacker = FALSE
if(GLOB.joined_player_list.len>=GLOB.dynamic_high_pop_limit)
is_hijacker = (prob(10) && mode.threat_level > CONFIG_GET(number/dynamic_hijack_high_population_requirement))
else
@@ -180,7 +182,7 @@
destroy_objective.owner = owner
destroy_objective.find_target()
add_objective(destroy_objective)
else if(prob(30))
else if(prob(30) || (is_dynamic && (mode.storyteller.flags & NO_ASSASSIN)))
var/datum/objective/maroon/maroon_objective = new
maroon_objective.owner = owner
maroon_objective.find_target()