Merge conflict fix

This commit is contained in:
Artur
2020-05-13 12:37:18 +03:00
985 changed files with 295527 additions and 16121 deletions
@@ -42,7 +42,7 @@
if(objective.completable)
var/completion = objective.check_completion()
if(completion >= 1)
report += "<B>Objective #[objective_count]</B>: [objective.explanation_text] <span class='greentext'><B>Success!</span>"
report += "<B>Objective #[objective_count]</B>: [objective.explanation_text] <span class='greentext'><B>Success!</B></span>"
else if(completion <= 0)
report += "<B>Objective #[objective_count]</B>: [objective.explanation_text] <span class='redtext'>Fail.</span>"
win = FALSE
@@ -492,7 +492,7 @@
user.do_attack_animation(L)
if(L.run_block(src, 0, "[user]'s [src]", ATTACK_TYPE_MELEE, 0, user, check_zone(user.zone_selected)) & BLOCK_SUCCESS)
if(L.mob_run_block(src, 0, "[user]'s [src]", ATTACK_TYPE_MELEE, 0, user, check_zone(user.zone_selected), null) & BLOCK_SUCCESS)
playsound(L, 'sound/weapons/genhit.ogg', 50, TRUE)
return FALSE
@@ -6,6 +6,7 @@
status = ORGAN_ROBOTIC
beating = TRUE
organ_flags = ORGAN_NO_SPOIL
no_pump = TRUE
var/true_name = "baseline placebo referencer"
var/cooldown_low = 300
var/cooldown_high = 300
@@ -92,6 +93,7 @@
update_gland_hud()
/obj/item/organ/heart/gland/on_life()
. = ..()
if(!beating)
// alien glands are immune to stopping.
beating = TRUE
@@ -10,7 +10,12 @@
/obj/item/organ/heart/gland/slime/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
..()
owner.faction |= "slime"
owner.grant_language(/datum/language/slime)
owner.grant_language(/datum/language/slime, TRUE, TRUE, LANGUAGE_GLAND)
/obj/item/organ/heart/gland/slime/Remove(mob/living/carbon/M, special = 0)
..()
owner.faction -= "slime"
owner.remove_language(/datum/language/slime, TRUE, TRUE, LANGUAGE_GLAND)
/obj/item/organ/heart/gland/slime/activate()
to_chat(owner, "<span class='warning'>You feel nauseated!</span>")
@@ -10,9 +10,9 @@
/obj/item/organ/heart/gland/trauma/activate()
to_chat(owner, "<span class='warning'>You feel a spike of pain in your head.</span>")
if(prob(33))
owner.gain_trauma_type(BRAIN_TRAUMA_SPECIAL, rand(TRAUMA_RESILIENCE_BASIC, TRAUMA_RESILIENCE_LOBOTOMY))
owner.gain_trauma_type(BRAIN_TRAUMA_SPECIAL, rand(TRAUMA_RESILIENCE_BASIC, TRAUMA_RESILIENCE_SURGERY))
else
if(prob(20))
owner.gain_trauma_type(BRAIN_TRAUMA_SEVERE, rand(TRAUMA_RESILIENCE_BASIC, TRAUMA_RESILIENCE_LOBOTOMY))
owner.gain_trauma_type(BRAIN_TRAUMA_SEVERE, rand(TRAUMA_RESILIENCE_BASIC, TRAUMA_RESILIENCE_SURGERY))
else
owner.gain_trauma_type(BRAIN_TRAUMA_MILD, rand(TRAUMA_RESILIENCE_BASIC, TRAUMA_RESILIENCE_LOBOTOMY))
owner.gain_trauma_type(BRAIN_TRAUMA_MILD, rand(TRAUMA_RESILIENCE_BASIC, TRAUMA_RESILIENCE_SURGERY))
@@ -42,7 +42,7 @@
/mob/living/simple_animal/hostile/blob/fire_act(exposed_temperature, exposed_volume)
..()
if(exposed_temperature)
adjustFireLoss(CLAMP(0.01 * exposed_temperature, 1, 5))
adjustFireLoss(clamp(0.01 * exposed_temperature, 1, 5))
else
adjustFireLoss(5)
@@ -203,7 +203,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
B.hud_used.blobpwrdisplay.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#82ed00'>[round(blob_core.obj_integrity)]</font></div>"
/mob/camera/blob/proc/add_points(points)
blob_points = CLAMP(blob_points + points, 0, max_blob_points)
blob_points = clamp(blob_points + points, 0, max_blob_points)
hud_used.blobpwrdisplay.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#82ed00'>[round(blob_points)]</font></div>"
/mob/camera/blob/say(message, bubble_type, var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
@@ -77,7 +77,7 @@
/obj/structure/blob/CanAStarPass(ID, dir, caller)
. = 0
if(ismovableatom(caller))
if(ismovable(caller))
var/atom/movable/mover = caller
. = . || (mover.pass_flags & PASSBLOB)
@@ -14,10 +14,10 @@
set waitfor = FALSE // Don't make on_gain() wait for this function to finish. This lets this code run on the side.
var/notice_healing
while(owner && !AmFinalDeath()) // owner.has_antag_datum(ANTAG_DATUM_BLOODSUCKER) == src
if(owner.current.stat == CONSCIOUS && !poweron_feed && !HAS_TRAIT(owner.current, TRAIT_DEATHCOMA)) // Deduct Blood
if(owner.current.stat == CONSCIOUS && !poweron_feed && !HAS_TRAIT(owner.current, TRAIT_FAKEDEATH)) // Deduct Blood
AddBloodVolume(passive_blood_drain) // -.1 currently
if(HandleHealing(1)) // Heal
if(notice_healing == FALSE && owner.current.blood_volume > 0)
if(!notice_healing && owner.current.blood_volume > 0)
to_chat(owner, "<span class='notice'>The power of your blood begins knitting your wounds...</span>")
notice_healing = TRUE
else if(notice_healing == TRUE)
@@ -25,7 +25,7 @@
HandleStarving() // Death
HandleDeath() // Standard Update
update_hud()// Daytime Sleep in Coffin
if(SSticker.mode.is_daylight() && !HAS_TRAIT_FROM(owner.current, TRAIT_DEATHCOMA, "bloodsucker"))
if(SSticker.mode.is_daylight() && !HAS_TRAIT_FROM(owner.current, TRAIT_FAKEDEATH, "bloodsucker"))
if(istype(owner.current.loc, /obj/structure/closet/crate/coffin))
Torpor_Begin()
// Wait before next pass
@@ -39,7 +39,7 @@
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/datum/antagonist/bloodsucker/proc/AddBloodVolume(value)
owner.current.blood_volume = CLAMP(owner.current.blood_volume + value, 0, max_blood_volume)
owner.current.blood_volume = clamp(owner.current.blood_volume + value, 0, max_blood_volume)
update_hud()
/datum/antagonist/bloodsucker/proc/HandleFeeding(mob/living/carbon/target, mult=1)
@@ -83,7 +83,7 @@
// NOTE: Mult of 0 is just a TEST to see if we are injured and need to go into Torpor!
//It is called from your coffin on close (by you only)
var/actual_regen = regen_rate + additional_regen
if(poweron_masquerade == TRUE || owner.current.AmStaked())
if(poweron_masquerade|| owner.current.AmStaked())
return FALSE
if(owner.current.reagents.has_reagent(/datum/reagent/consumable/garlic))
return FALSE
@@ -101,8 +101,8 @@
var/mob/living/carbon/C = owner.current
var/costMult = 1 // Coffin makes it cheaper
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_FAKEDEATH)) // Check for mult 0 OR death coma. (mult 0 means we're testing from coffin)
if(amInCoffinWhileTorpor)
// Check for mult 0 OR death coma. (mult 0 means we're testing from coffin)
if(istype(C.loc, /obj/structure/closet/crate/coffin) && (mult == 0 || HAS_TRAIT(C, TRAIT_FAKEDEATH)))
mult *= 4 // Increase multiplier if we're sleeping in a coffin.
fireheal = min(C.getFireLoss(), regen_rate) // NOTE: Burn damage ONLY heals in torpor.
C.ExtinguishMob()
@@ -112,7 +112,10 @@
CheckVampOrgans() // Heart, Eyes
if(check_limbs(costMult))
return TRUE
else if(owner.current.stat >= UNCONSCIOUS) //Faster regeneration and slight burn healing while unconcious
mult *= 2
fireheal = min(C.getFireLoss(), regen_rate * 0.2)
// BRUTE: Always Heal
var/bruteheal = min(C.getBruteLoss(), actual_regen)
var/toxinheal = min(C.getToxLoss(), actual_regen)
@@ -120,8 +123,6 @@
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)
@@ -129,7 +130,7 @@
//C.heal_overall_damage(bruteheal * mult, fireheal * mult) // REMOVED: We need to FORCE this, because otherwise, vamps won't heal EVER. Swapped to above.
AddBloodVolume((bruteheal * -0.5 + fireheal * -1 + toxinheal * -0.2) / mult * costMult) // Costs blood to heal
return TRUE // Healed! Done for this tick.
/datum/antagonist/bloodsucker/proc/check_limbs(costMult)
@@ -137,7 +138,7 @@
var/mob/living/carbon/C = owner.current
var/list/missing = C.get_missing_limbs()
if(missing.len && C.blood_volume < limb_regen_cost + 5)
return FALSE
return FALSE
for(var/targetLimbZone in missing) // 1) Find ONE Limb and regenerate it.
C.regenerate_limb(targetLimbZone, FALSE) // regenerate_limbs() <--- If you want to EXCLUDE certain parts, do it like this ----> regenerate_limbs(0, list("head"))
AddBloodVolume(50)
@@ -146,12 +147,6 @@
to_chat(C, "<span class='notice'>Your flesh knits as it regrows your [L]!</span>")
playsound(C, 'sound/magic/demon_consume.ogg', 50, TRUE)
return TRUE
/*for(var/obj/item/bodypart/BP in C.bodyparts)
if(!istype(BP) && !BP.status == 2)
return FALSE
to_chat(C, "<span class='notice'>Your body expels the [BP]!</span>")
BP.drop_limb()
return TRUE */
/datum/antagonist/bloodsucker/proc/CureDisabilities()
var/mob/living/carbon/C = owner.current
@@ -176,14 +171,14 @@
// EMPTY: Frenzy!
// BLOOD_VOLUME_GOOD: [336] Pale (handled in bloodsucker_integration.dm
// BLOOD_VOLUME_BAD: [224] Jitter
if(owner.current.blood_volume < BLOOD_VOLUME_BAD && !prob(0.5))
if(owner.current.blood_volume < BLOOD_VOLUME_BAD && !prob(0.5 && HAS_TRAIT(owner, TRAIT_FAKEDEATH)) && !poweron_masquerade)
owner.current.Jitter(3)
// BLOOD_VOLUME_SURVIVE: [122] Blur Vision
if(owner.current.blood_volume < BLOOD_VOLUME_BAD / 2)
owner.current.blur_eyes(8 - 8 * (owner.current.blood_volume / BLOOD_VOLUME_BAD))
// Nutrition
owner.current.nutrition = clamp(owner.current.blood_volume, 545, 0) //The amount of blood is how full we are.
//A bit higher regeneration based on blood volume
//A bit higher regeneration based on blood volume
if(owner.current.blood_volume < 700)
additional_regen = 0.4
else if(owner.current.blood_volume < BLOOD_VOLUME_NORMAL)
@@ -230,16 +225,16 @@
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)
if(poweron_masquerade)
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))
// Not Daytime, Not in Torpor
if(!SSticker.mode.is_daylight() && HAS_TRAIT_FROM(owner.current, TRAIT_FAKEDEATH, "bloodsucker"))
// Not Daytime, Not in Torpor, enough health to not die the moment you end torpor
if(!SSticker.mode.is_daylight() && HAS_TRAIT_FROM(owner.current, TRAIT_FAKEDEATH, "bloodsucker") && total_damage < owner.current.getMaxHealth())
Torpor_End()
// Fake Unconscious
if(poweron_masquerade == TRUE && total_damage >= owner.current.getMaxHealth() - HEALTH_THRESHOLD_FULLCRIT)
if(poweron_masquerade && total_damage >= owner.current.getMaxHealth() - HEALTH_THRESHOLD_FULLCRIT)
owner.current.Unconscious(20, 1)
/datum/antagonist/bloodsucker/proc/Torpor_Begin(amInCoffin = FALSE)
@@ -249,6 +244,7 @@
ADD_TRAIT(owner.current, TRAIT_NODEATH, "bloodsucker") // Without this, you'll just keep dying while you recover.
ADD_TRAIT(owner.current, TRAIT_RESISTHIGHPRESSURE, "bloodsucker") // So you can heal in space. Otherwise you just...heal forever.
ADD_TRAIT(owner.current, TRAIT_RESISTLOWPRESSURE, "bloodsucker")
owner.current.Jitter(0)
// Visuals
owner.current.update_sight()
owner.current.reload_fullscreen()
@@ -256,6 +252,9 @@
for(var/datum/action/bloodsucker/power in powers)
if(power.active && !power.can_use_in_torpor)
power.DeactivatePower()
if(owner.current.suiciding)
owner.current.suiciding = FALSE //Youll die but not for long.
to_chat(owner.current, "<span class='warning'>Your body keeps you going, even as you try to end yourself.</span>")
/datum/antagonist/bloodsucker/proc/Torpor_End()
owner.current.stat = SOFT_CRIT
@@ -369,8 +368,8 @@
//Puke blood only if puke_blood is true, and loose some blood, else just puke normally.
if(puke_blood)
C.blood_volume = max(0, C.blood_volume - foodInGut * 2)
C.vomit(foodInGut * 4, foodInGut * 2, 0)
else
C.vomit(foodInGut * 4, foodInGut * 2, 0)
else
C.vomit(foodInGut * 4, FALSE, 0)
C.Stun(30)
//C.Dizzy(50)
@@ -87,7 +87,7 @@
// Heads?
if (target_role == "HEAD")
target_amount = rand(1, round(SSticker.mode.num_players() / 20))
target_amount = CLAMP(target_amount,1,3)
target_amount = clamp(target_amount,1,3)
// Department?
else
switch(target_role)
@@ -100,7 +100,7 @@
if("Quartermaster")
department_string = "Cargo"
target_amount = rand(round(SSticker.mode.num_players() / 20), round(SSticker.mode.num_players() / 10))
target_amount = CLAMP(target_amount, 2, 4)
target_amount = clamp(target_amount, 2, 4)
..()
// EXPLANATION
@@ -45,15 +45,15 @@
// (FINAL LIL WARNING)
while(time_til_cycle > 5)
sleep(10)
if (cancel_me)
if(cancel_me)
return
//sleep(TIME_BLOODSUCKER_DAY_FINAL_WARN - 50)
warn_daylight(3,"<span class = 'userdanger'>Seek cover, for Sol rises!</span>")
// Part 3: Night Ending
while (time_til_cycle > 0)
while(time_til_cycle > 0)
sleep(10)
if (cancel_me)
if(cancel_me)
return
//sleep(50)
warn_daylight(4,"<span class = 'userdanger'>Solar flares bombard the station with deadly UV light!</span><br><span class = ''>Stay in cover for the next [TIME_BLOODSUCKER_DAY / 60] minutes or risk Final Death!</span>",\
@@ -69,11 +69,11 @@
while(time_til_cycle > 0)
punish_vamps()
sleep(TIME_BLOODSUCKER_BURN_INTERVAL)
if (cancel_me)
if(cancel_me)
return
//daylight_time -= TIME_BLOODSUCKER_BURN_INTERVAL
// Issue Level Up!
if(!issued_XP && time_til_cycle <= 15)
if(!issued_XP && time_til_cycle <= 5)
issued_XP = TRUE
vamps_rank_up()
@@ -20,7 +20,7 @@
var/poweron_feed = FALSE // Am I feeding?
var/poweron_masquerade = FALSE
// STATS
var/bloodsucker_level
var/bloodsucker_level
var/bloodsucker_level_unspent = 1
var/regen_rate = 0.3 // How fast do I regenerate?
var/additional_regen // How much additional blood regen we gain from bonuses such as high blood.
@@ -209,7 +209,7 @@
// Physiology
CheckVampOrgans() // Heart, Eyes
// Language
owner.current.grant_language(/datum/language/vampiric)
owner.current.grant_language(/datum/language/vampiric, TRUE, TRUE, LANGUAGE_BLOODSUCKER)
owner.hasSoul = FALSE // If false, renders the character unable to sell their soul.
owner.isholy = FALSE // is this person a chaplain or admin role allowed to use bibles
// Disabilities
@@ -227,7 +227,7 @@
// Traits
for(var/T in defaultTraits)
REMOVE_TRAIT(owner.current, T, BLOODSUCKER_TRAIT)
if(had_toxlover == TRUE)
if(had_toxlover)
ADD_TRAIT(owner.current, TRAIT_TOXINLOVER, SPECIES_TRAIT)
// Traits: Species
@@ -246,7 +246,7 @@
// Update Health
owner.current.setMaxHealth(100)
// Language
owner.current.remove_language(/datum/language/vampiric)
owner.current.remove_language(/datum/language/vampiric, TRUE, TRUE, LANGUAGE_BLOODSUCKER)
// Soul
if (owner.soulOwner == owner) // Return soul, if *I* own it.
owner.hasSoul = TRUE
@@ -649,10 +649,10 @@
return TRUE
// Check 3) If I am a BLOODSUCKER, then are they my Vassal?
if (mob_B && atom_V && (atom_V in mob_B.vassals))
return TRUE
return TRUE
// Check 4) If we are both VASSAL, then do we have the same master?
if (atom_V && mob_V && atom_V.master == mob_V.master)
return TRUE
return TRUE
return FALSE
@@ -710,7 +710,7 @@
invisibility = INVISIBILITY_ABSTRACT
/obj/screen/bloodsucker/proc/update_counter(value, valuecolor)
invisibility = 0
invisibility = 0
/obj/screen/bloodsucker/blood_counter
icon = 'icons/mob/actions/bloodsucker.dmi'
@@ -758,7 +758,7 @@
/obj/screen/bloodsucker/sunlight_counter/update_counter(value, valuecolor)
..()
maptext = "<div align='center' valign='bottom' style='position:relative; top:0px; left:6px'><font color='[valuecolor]'>[value]</font></div>"
maptext = "<div align='center' valign='bottom' style='position:relative; top:0px; left:6px'><font color='[valuecolor]'>[value]</font></div>"
/datum/antagonist/bloodsucker/proc/count_vassals(datum/mind/master)
var/datum/antagonist/bloodsucker/B = master.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
@@ -48,7 +48,7 @@
objectives += vassal_objective
objectives_given += vassal_objective
give_thrall_eyes()
owner.current.grant_language(/datum/language/vampiric)
owner.current.grant_language(/datum/language/vampiric, TRUE, TRUE, LANGUAGE_VASSAL)
// Add Antag HUD
update_vassal_icons_added(owner.current, "vassal")
. = ..()
@@ -81,7 +81,7 @@
qdel(O)
objectives_given = list()
remove_thrall_eyes()
owner.current.remove_language(/datum/language/vampiric)
owner.current.remove_language(/datum/language/vampiric, TRUE, TRUE, LANGUAGE_VASSAL)
// Clear Antag HUD
update_vassal_icons_removed(owner.current)
@@ -63,7 +63,7 @@
// Find Animals in Area
/* if(rand(0,2) == 0)
var/mobCount = 0
var/mobMax = CLAMP(area_turfs.len / 25, 1, 4)
var/mobMax = clamp(area_turfs.len / 25, 1, 4)
for (var/turf/T in area_turfs)
if(!T) continue
var/mob/living/simple_animal/SA = locate() in T
@@ -18,14 +18,11 @@
. = ..()
if(!.)
return
// must have nobody around to see the cloak
var/watchers = viewers(9,get_turf(owner))
for(var/mob/living/M in watchers)
for(var/mob/living/M in viewers(9, owner))
if(M != owner)
to_chat(owner, "<span class='warning'>You may only vanish into the shadows unseen.</span>")
return FALSE
return TRUE
/datum/action/bloodsucker/cloak/ActivatePower()
@@ -3,7 +3,7 @@
/datum/action/bloodsucker/fortitude
name = "Fortitude"//"Cellular Emporium"
name = "Fortitude"
desc = "Withstand egregious physical wounds and walk away from attacks that would stun, pierce, and dismember lesser beings. You cannot run while active."
button_icon_state = "power_fortitude"
bloodcost = 30
@@ -11,28 +11,27 @@
bloodsucker_can_buy = TRUE
amToggle = TRUE
warn_constant_cost = TRUE
var/was_running
var/this_resist // So we can raise and lower your brute resist based on what your level_current WAS.
var/fortitude_resist // So we can raise and lower your brute resist based on what your level_current WAS.
/datum/action/bloodsucker/fortitude/ActivatePower()
var/datum/antagonist/bloodsucker/bloodsuckerdatum = owner.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
var/datum/antagonist/bloodsucker/B = owner.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
var/mob/living/user = owner
to_chat(user, "<span class='notice'>Your flesh, skin, and muscles become as steel.</span>")
// Traits & Effects
ADD_TRAIT(user, TRAIT_PIERCEIMMUNE, "fortitude")
ADD_TRAIT(user, TRAIT_NODISMEMBER, "fortitude")
ADD_TRAIT(user, TRAIT_STUNIMMUNE, "fortitude")
ADD_TRAIT(user, TRAIT_NORUNNING, "fortitude")
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
this_resist = max(0.3, 0.7 - level_current * 0.1)
H.physiology.brute_mod *= this_resist//0.5
H.physiology.burn_mod *= this_resist//0.5
// Stop Running (Taken from /datum/quirk/nyctophobia in negative.dm)
var/was_running = (user.m_intent == MOVE_INTENT_RUN)
fortitude_resist = max(0.3, 0.7 - level_current * 0.1)
H.physiology.brute_mod *= fortitude_resist
H.physiology.burn_mod *= fortitude_resist
was_running = (user.m_intent == MOVE_INTENT_RUN)
if(was_running)
user.toggle_move_intent()
while(bloodsuckerdatum && ContinueActive(user) || user.m_intent == MOVE_INTENT_RUN)
while(B && ContinueActive(user) || user.m_intent == MOVE_INTENT_RUN)
if(istype(user.buckled, /obj/vehicle)) //We dont want people using fortitude being able to use vehicles
var/obj/vehicle/V = user.buckled
var/datum/component/riding/VRD = V.GetComponent(/datum/component/riding)
@@ -44,20 +43,21 @@
to_chat(user, "<span class='notice'>You fall off the [V], your weight making you too heavy to be supported by it.</span>")
// Pay Blood Toll (if awake)
if(user.stat == CONSCIOUS)
bloodsuckerdatum.AddBloodVolume(-0.5) // Used to be 0.3 blood per 2 seconds, but we're making it more expensive to keep on.
B.AddBloodVolume(-0.5)
sleep(20) // 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/fortitude/DeactivatePower(mob/living/user = owner, mob/living/target)
..()
// Restore Traits & Effects
REMOVE_TRAIT(user, TRAIT_PIERCEIMMUNE, "fortitude")
REMOVE_TRAIT(user, TRAIT_NODISMEMBER, "fortitude")
REMOVE_TRAIT(user, TRAIT_STUNIMMUNE, "fortitude")
REMOVE_TRAIT(user, TRAIT_NORUNNING, "fortitude")
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
H.physiology.brute_mod /= this_resist//0.5
H.physiology.burn_mod /= this_resist//0.5
if(!ishuman(owner))
return
var/mob/living/carbon/human/H = owner
H.physiology.brute_mod /= fortitude_resist
H.physiology.burn_mod /= fortitude_resist
if(was_running && user.m_intent == MOVE_INTENT_WALK)
user.toggle_move_intent()
@@ -1,88 +1,46 @@
// Level 1: Grapple level 2
// Level 2: Grapple 3 from Behind
// Level 3: Grapple 3 from Shadows
/datum/action/bloodsucker/targeted/lunge
/datum/action/bloodsucker/lunge
name = "Predatory Lunge"
desc = "Spring at your target and aggressively grapple them without warning. Attacks from concealment or the rear may even knock them down."
desc = "Prepare the strenght to grapple your prey."
button_icon_state = "power_lunge"
bloodcost = 10
cooldown = 120
target_range = 3
power_activates_immediately = TRUE
message_Trigger = "Whom will you ensnare within your grasp?"
must_be_capacitated = TRUE
cooldown = 30
bloodsucker_can_buy = TRUE
warn_constant_cost = TRUE
amToggle = TRUE
var/leap_skill_mod = 5
/datum/action/bloodsucker/targeted/lunge/CheckCanUse(display_error)
if(!..(display_error))// DEFAULT CHECKS
return FALSE
// Being Grabbed
if(owner.pulledby && owner.pulledby.grab_state >= GRAB_AGGRESSIVE)
if(display_error)
to_chat(owner, "<span class='warning'>You're being grabbed!</span>")
return FALSE
if(!owner.has_gravity(owner.loc))//TODO figure out how to check if theyre able to move while in nograv
if(display_error)
to_chat(owner, "<span class='warning'>You cant lunge while floating!</span>")
return FALSE
return TRUE
/datum/action/bloodsucker/lunge/New()
. = ..()
/datum/action/bloodsucker/targeted/lunge/CheckValidTarget(atom/A)
return iscarbon(A)
/datum/action/bloodsucker/lunge/Destroy()
. = ..()
UnregisterSignal(owner, COMSIG_CARBON_TACKLED)
/datum/action/bloodsucker/targeted/lunge/CheckCanTarget(atom/A, display_error)
// Check: Self
if(target == owner)
return FALSE
// Check: Range
//if (!(target in view(target_range, get_turf(owner))))
// if (display_error)
// to_chat(owner, "<span class='warning'>Your victim is too far away.</span>")
// return FALSE
// DEFAULT CHECKS (Distance)
if(!..())
return FALSE
// Check: Turf
var/mob/living/L = A
if(!isturf(L.loc))
return FALSE
return TRUE
/datum/action/bloodsucker/lunge/ActivatePower()
var/mob/living/carbon/user = owner
var/datum/antagonist/bloodsucker/B = user.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
var/datum/component/tackler/T = user.LoadComponent(/datum/component/tackler)
T.stamina_cost = 50
T.base_knockdown = 3 SECONDS
T.range = 4
T.speed = 0.8
T.skill_mod = 5 //Monstrous tackling
T.min_distance = 2
active = TRUE
user.toggle_throw_mode()
RegisterSignal(user, COMSIG_CARBON_TACKLED, .proc/DelayedDeactivatePower)
while(B && ContinueActive(user))
B.AddBloodVolume(-0.1)
sleep(5)
/datum/action/bloodsucker/targeted/lunge/FireTargetedPower(atom/A)
// set waitfor = FALSE <---- DONT DO THIS!We WANT this power to hold up ClickWithPower(), so that we can unlock the power when it's done.
var/mob/living/carbon/target = A
var/turf/T = get_turf(target)
var/mob/living/L = owner
// Clear Vars
owner.pulling = null
// Will we Knock them Down?
var/do_knockdown = !is_A_facing_B(target,owner) || owner.alpha <= 0 || istype(owner.loc, /obj/structure/closet)
// CAUSES: Target has their back to me, I'm invisible, or I'm in a Closet
// Step One: Heatseek toward Target's Turf
addtimer(CALLBACK(GLOBAL_PROC, .proc/_walk, owner, 0), 2 SECONDS)
target.playsound_local(get_turf(owner), 'sound/bloodsucker/lunge_warn.ogg', 60, FALSE, pressure_affected = FALSE) // target-only telegraphing
owner.playsound_local(owner, 'sound/bloodsucker/lunge_warn.ogg', 60, FALSE, pressure_affected = FALSE) // audio feedback to the user
if(do_mob(owner, owner, 7, TRUE, TRUE))
walk_towards(owner, T, 0.1, 10) // yes i know i shouldn't use this but i don't know how to work in anything better
if(get_turf(owner) != T && !(isliving(target) && target.Adjacent(owner)) && owner.incapacitated() && !CHECK_MOBILITY(L, MOBILITY_STAND))
var/send_dir = get_dir(owner, T)
new /datum/forced_movement(owner, get_ranged_target_turf(owner, send_dir, 1), 1, FALSE)
owner.spin(10)
// Step Two: Check if I'm at/adjectent to Target's CURRENT turf (not original...that was just a destination)
for(var/i in 1 to 6)
if (target.Adjacent(owner))
// LEVEL 2: If behind target, mute or unconscious!
if(do_knockdown) // && level_current >= 1)
target.Knockdown(15 + 10 * level_current,1)
target.adjustStaminaLoss(40 + 10 * level_current)
// Cancel Walk (we were close enough to contact them)
walk(owner, 0)
target.Stun(10,1) //Without this the victim can just walk away
target.grabbedby(owner) // Taken from mutations.dm under changelings
target.grippedby(owner, instant = TRUE) //instant aggro grab
break
sleep(3)
//Without this, the leap component would get removed too early, causing the normal crash into effects.
/datum/action/bloodsucker/lunge/proc/DelayedDeactivatePower()
addtimer(CALLBACK(src, .proc/DeactivatePower), 1 SECONDS, TIMER_UNIQUE)
/datum/action/bloodsucker/targeted/lunge/DeactivatePower(mob/living/user = owner, mob/living/target)
..() // activate = FALSE
user.update_mobility()
/datum/action/bloodsucker/lunge/DeactivatePower(mob/living/user = owner)
. = ..()
qdel(user.GetComponent(/datum/component/tackler))
UnregisterSignal(user, COMSIG_CARBON_TACKLED)
@@ -52,6 +52,7 @@
REMOVE_TRAIT(user, TRAIT_NOHARDCRIT, "bloodsucker")
REMOVE_TRAIT(user, TRAIT_NOSOFTCRIT, "bloodsucker")
REMOVE_TRAIT(user, TRAIT_VIRUSIMMUNE, "bloodsucker")
REMOVE_TRAIT(user, TRAIT_NOBREATH, "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
@@ -93,6 +94,7 @@
ADD_TRAIT(user, TRAIT_NOHARDCRIT, "bloodsucker")
ADD_TRAIT(user, TRAIT_NOSOFTCRIT, "bloodsucker")
ADD_TRAIT(user, TRAIT_VIRUSIMMUNE, "bloodsucker")
ADD_TRAIT(user, TRAIT_NOBREATH, "bloodsucker")
// HEART
var/obj/item/organ/heart/H = user.getorganslot(ORGAN_SLOT_HEART)
@@ -28,7 +28,7 @@
/datum/action/bloodsucker/targeted/trespass/CheckValidTarget(atom/A)
// Can't target my tile
if (A == get_turf(owner) || get_turf(A) == get_turf(owner))
if(A == get_turf(owner) || get_turf(A) == get_turf(owner))
return FALSE
return TRUE // All we care about is destination. Anything you click is fine.
@@ -43,13 +43,13 @@
// Are either tiles WALLS?
var/turf/from_turf = get_turf(owner)
var/this_dir // = get_dir(from_turf, target_turf)
for (var/i=1 to 2)
for(var/i=1 to 2)
// Keep Prev Direction if we've reached final turf
if (from_turf != final_turf)
if(from_turf != final_turf)
this_dir = get_dir(from_turf, final_turf) // Recalculate dir so we don't overshoot on a diagonal.
from_turf = get_step(from_turf, this_dir)
// ERROR! Wall!
if (iswallturf(from_turf))
if(iswallturf(from_turf))
if (display_error)
var/wallwarning = (i == 1) ? "in the way" : "at your destination"
to_chat(owner, "<span class='warning'>There is a solid wall [wallwarning].</span>")
@@ -84,7 +84,7 @@
user.next_move = world.time + mist_delay
user.Stun(mist_delay, ignore_canstun = TRUE)
user.notransform = TRUE
user.density = 0
user.density = FALSE
var/invis_was = user.invisibility
user.invisibility = INVISIBILITY_MAXIMUM
@@ -94,7 +94,7 @@
sleep(mist_delay / 2)
// Move & Freeze
if (isturf(target_turf))
if(isturf(target_turf))
do_teleport(owner, target_turf, no_effects=TRUE, channel = TELEPORT_CHANNEL_QUANTUM) // in teleport.dm?
user.next_move = world.time + mist_delay / 2
user.Stun(mist_delay / 2, ignore_canstun = TRUE)
@@ -93,7 +93,7 @@
H.socks = random_socks(H.gender)
//H.eye_color = random_eye_color()
REMOVE_TRAIT(H, TRAIT_DISFIGURED, null) //
H.dna.features = random_features(H.dna.species?.id)
H.dna.features = random_features(H.dna.species?.id, H.gender)
// Apply Appearance
H.update_body(TRUE) // Outfit and underwear, also body and privates.
+1 -1
View File
@@ -111,7 +111,7 @@
if(objective.completable)
var/completion = objective.check_completion()
if(completion >= 1)
parts += "<B>Objective #[objective_count]</B>: [objective.explanation_text] <span class='greentext'><B>Success!</span>"
parts += "<B>Objective #[objective_count]</B>: [objective.explanation_text] <span class='greentext'><B>Success!</B></span>"
else if(completion <= 0)
parts += "<B>Objective #[objective_count]</B>: [objective.explanation_text] <span class='redtext'>Fail.</span>"
win = FALSE
@@ -78,6 +78,7 @@
create_initial_profile()
if(give_objectives)
forge_objectives()
owner.current.grant_all_languages(FALSE, FALSE, TRUE) //Grants omnitongue. We are able to transform our body after all.
remove_clownmut()
. = ..()
@@ -430,7 +431,7 @@
objectives += destroy_objective
else
if(prob(70))
var/datum/objective/assassinate/kill_objective = new
var/datum/objective/assassinate/once/kill_objective = new
kill_objective.owner = owner
if(team_mode) //No backstabbing while in a team
kill_objective.find_target_by_role(role = ROLE_CHANGELING, role_type = 1, invert = 1)
@@ -563,7 +564,7 @@
if(objective.completable)
var/completion = objective.check_completion()
if(completion >= 1)
parts += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='greentext'><B>Success!</span>"
parts += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='greentext'><B>Success!</B></span>"
else if(completion <= 0)
parts += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='redtext'>Fail.</span>"
changelingwin = FALSE
@@ -61,10 +61,10 @@
if(user.nutrition < NUTRITION_LEVEL_WELL_FED)
user.nutrition = min((user.nutrition + target.nutrition), NUTRITION_LEVEL_WELL_FED)
if(target.mind)//if the victim has got a mind
// Absorb a lizard, speak Draconic.
user.copy_known_languages_from(target)
// Absorb a lizard, speak Draconic.
user.copy_languages(target, LANGUAGE_ABSORB)
if(target.mind && user.mind)//if the victim and user have minds
target.mind.show_memory(user, 0) //I can read your mind, kekeke. Output all their notes.
//Some of target's recent speech, so the changeling can attempt to imitate them better.
@@ -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(/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
user.do_adrenaline(0, FALSE, 70, 0, TRUE, list(/datum/reagent/medicine/epinephrine = 3, /datum/reagent/drug/methamphetamine/changeling = 10, /datum/reagent/medicine/changelingadrenaline = 5), "<span class='notice'>Energy rushes through us.</span>", 0, 0.75, 0)
return TRUE
@@ -27,12 +27,12 @@
var/obj/item/organ/eyes/E = user.getorganslot(ORGAN_SLOT_EYES)
if(E)
if(!active)
E.sight_flags |= SEE_MOBS | SEE_OBJS | SEE_TURFS //Add sight flags to the user's eyes
ADD_TRAIT(user, TRAIT_THERMAL_VISION, CHANGELING_TRAIT)
E.flash_protect = -1 //Adjust the user's eyes' flash protection
to_chat(user, "We adjust our eyes to sense prey through walls.")
active = TRUE //Defined in code/modules/spells/spell.dm
else
E.sight_flags ^= SEE_MOBS | SEE_OBJS | SEE_TURFS //Remove sight flags from the user's eyes
REMOVE_TRAIT(user, TRAIT_THERMAL_VISION, CHANGELING_TRAIT)
E.flash_protect = 2 //Adjust the user's eyes' flash protection
to_chat(user, "We adjust our eyes to protect them from bright lights.")
active = FALSE
@@ -47,10 +47,8 @@
/obj/effect/proc_holder/changeling/augmented_eyesight/on_refund(mob/user) //Get rid of X-ray vision and flash protection when the user refunds this ability
action.Remove(user)
REMOVE_TRAIT(user, TRAIT_THERMAL_VISION, CHANGELING_TRAIT)
var/obj/item/organ/eyes/E = user.getorganslot(ORGAN_SLOT_EYES)
if(E)
if (active)
E.sight_flags ^= SEE_MOBS | SEE_OBJS | SEE_TURFS
else
E.flash_protect = 0
user.update_sight()
E.flash_protect = initial(E.flash_protect)
user.update_sight()
@@ -2,7 +2,7 @@
name = "Biodegrade"
desc = "Dissolves restraints or other objects preventing free movement."
helptext = "This is obvious to nearby people, and can destroy standard restraints and closets. This ability is somewhat loud, and carries a small risk of our blood gaining violent sensitivity to heat."
chemical_cost = 30 //High cost to prevent spam
chemical_cost = 15 //High cost to prevent spam
loudness = 1
dna_cost = 2
req_human = 1
@@ -3,7 +3,6 @@
desc = "Our skin pigmentation rapidly changes to suit our current environment."
helptext = "Allows us to become invisible after a few seconds of standing still. Can be toggled on and off."
dna_cost = 2
chemical_cost = 25
req_human = 1
action_icon = 'icons/mob/actions/actions_changeling.dmi'
action_icon_state = "ling_camouflage"
@@ -23,4 +22,4 @@
action.Remove(user)
if(user.has_dna())
var/mob/living/carbon/C = user
C.dna.remove_mutation(CHAMELEON)
C.dna.remove_mutation(CHAMELEON)
@@ -1,8 +1,9 @@
/obj/effect/proc_holder/changeling/fleshmend
name = "Fleshmend"
desc = "Our flesh rapidly regenerates, healing our burns, bruises, and shortness of breath. Functions while unconscious."
desc = "Our flesh rapidly regenerates, healing our burns, bruises, and shortness of breath. Functions while unconscious. This ability is loud, and might cause our blood to react violently to heat."
helptext = "If we are on fire, the healing effect will not function. Does not regrow limbs or restore lost blood."
chemical_cost = 20
loudness = 2
dna_cost = 2
req_stat = UNCONSCIOUS
action_icon = 'icons/mob/actions/actions_changeling.dmi'
@@ -27,7 +27,7 @@
changeling.purchasedpowers -= src
var/newmob = user.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS)
var/newmob = user.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE)
changeling_transform(newmob, chosen_prof)
return TRUE
@@ -137,7 +137,7 @@
name = "Arm Blade"
desc = "We reform one of our arms into a deadly blade."
helptext = "We may retract our armblade in the same manner as we form it. Cannot be used while in lesser form. This ability is loud, and might cause our blood to react violently to heat."
chemical_cost = 20
chemical_cost = 10
dna_cost = 2
loudness = 2
req_human = 1
@@ -410,7 +410,7 @@
desc = "We reform one of our arms into a hard shield."
helptext = "Organic tissue cannot resist damage forever; the shield will break after it is hit too much. The more genomes we absorb, the stronger it is. Cannot be used while in lesser form. This ability is somewhat loud, and carries a small risk of our blood gaining violent sensitivity to heat."
chemical_cost = 20
dna_cost = 1
dna_cost = 2
loudness = 1
req_human = 1
action_icon = 'icons/mob/actions/actions_changeling.dmi'
@@ -522,12 +522,12 @@
/obj/effect/proc_holder/changeling/suit/armor
name = "Chitinous Armor"
desc = "We turn our skin into tough chitin to protect us from damage."
helptext = "Upkeep of the armor requires a low expenditure of chemicals. The armor is strong against brute force, but does not provide much protection from lasers. Cannot be used in lesser form. This ability is loud, and might cause our blood to react violently to heat."
helptext = "Upkeep of the armor requires a constant expenditure of chemicals, resulting in a reduced chemical generation. The armor is strong against brute force, but does not provide much protection from lasers. Cannot be used in lesser form. This ability is loud, and might cause our blood to react violently to heat."
chemical_cost = 20
dna_cost = 1
loudness = 2
req_human = 1
recharge_slowdown = 0.25
recharge_slowdown = 0.5
action_icon = 'icons/mob/actions/actions_changeling.dmi'
action_icon_state = "ling_armor"
action_background_icon_state = "bg_ling"
@@ -543,7 +543,7 @@
icon_state = "lingarmor"
item_flags = DROPDEL
body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 20, "bomb" = 10, "bio" = 4, "rad" = 0, "fire" = 90, "acid" = 90)
armor = list("melee" = 70, "bullet" = 60, "laser" = 30, "energy" = 40, "bomb" = 10, "bio" = 4, "rad" = 0, "fire" = 50, "acid" = 90)
flags_inv = HIDEJUMPSUIT
cold_protection = 0
heat_protection = 0
@@ -559,7 +559,7 @@
desc = "A tough, hard covering of black chitin with transparent chitin in front."
icon_state = "lingarmorhelmet"
item_flags = DROPDEL
armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 20, "bomb" = 10, "bio" = 4, "rad" = 0, "fire" = 90, "acid" = 90)
armor = list("melee" = 70, "bullet" = 60, "laser" = 30, "energy" = 40, "bomb" = 10, "bio" = 4, "rad" = 0, "fire" = 50, "acid" = 90)
flags_inv = HIDEEARS|HIDEHAIR|HIDEEYES|HIDEFACIALHAIR|HIDEFACE
/obj/item/clothing/head/helmet/changeling/Initialize()
@@ -3,7 +3,7 @@
desc = "Our lungs and vocal cords shift, allowing us to briefly emit a noise that deafens and confuses the weak-minded."
helptext = "Emits a high-frequency sound that confuses and deafens humans, blows out nearby lights and overloads cyborg sensors. This ability is somewhat loud, and carries a small risk of our blood gaining violent sensitivity to heat."
chemical_cost = 20
dna_cost = 1
dna_cost = 2
loudness = 1
req_human = 1
action_icon = 'icons/mob/actions/actions_changeling.dmi'
@@ -37,7 +37,7 @@
desc = "We shift our vocal cords to release a high-frequency sound that overloads nearby electronics."
helptext = "Emits a high-frequency sound that overloads nearby electronics. This ability is somewhat loud, and carries a small risk of our blood gaining violent sensitivity to heat."
chemical_cost = 20
dna_cost = 1
dna_cost = 2
loudness = 1
action_icon = 'icons/mob/actions/actions_changeling.dmi'
action_icon_state = "ling_dissonant"
@@ -5,7 +5,6 @@
name = "Strained Muscles"
desc = "We evolve the ability to reduce the acid buildup in our muscles, allowing us to move much faster."
helptext = "The strain will make us tired, and we will rapidly become fatigued. Standard weight restrictions, like hardsuits, still apply. Cannot be used in lesser form."
chemical_cost = 15
dna_cost = 1
req_human = 1
var/stacks = 0 //Increments every 5 seconds; damage increases over time
@@ -15,16 +14,13 @@
action_background_icon_state = "bg_ling"
/obj/effect/proc_holder/changeling/strained_muscles/sting_action(mob/living/carbon/user)
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
active = !active
if(active)
to_chat(user, "<span class='notice'>Our muscles tense and strengthen.</span>")
changeling.chem_recharge_slowdown += 0.5
else
user.remove_movespeed_modifier(MOVESPEED_ID_CHANGELING_MUSCLES)
user.remove_movespeed_modifier(/datum/movespeed_modifier/strained_muscles)
to_chat(user, "<span class='notice'>Our muscles relax.</span>")
changeling.chem_recharge_slowdown -= 0.5
if(stacks >= 20)
if(stacks >= 10)
to_chat(user, "<span class='danger'>We collapse in exhaustion.</span>")
user.DefaultCombatKnockdown(60)
user.emote("gasp")
@@ -34,26 +30,24 @@
return TRUE
/obj/effect/proc_holder/changeling/strained_muscles/proc/muscle_loop(mob/living/carbon/user)
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
while(active)
user.add_movespeed_modifier(MOVESPEED_ID_CHANGELING_MUSCLES, update=TRUE, priority=100, multiplicative_slowdown=-1, blacklisted_movetypes=(FLYING|FLOATING))
user.add_movespeed_modifier(/datum/movespeed_modifier/strained_muscles)
if(user.stat != CONSCIOUS || user.staminaloss >= 90)
active = !active
to_chat(user, "<span class='notice'>Our muscles relax without the energy to strengthen them.</span>")
user.DefaultCombatKnockdown(40)
user.remove_movespeed_modifier(MOVESPEED_ID_CHANGELING_MUSCLES)
changeling.chem_recharge_slowdown -= 0.5
user.remove_movespeed_modifier(/datum/movespeed_modifier/strained_muscles)
break
stacks++
//user.take_bodypart_damage(stacks * 0.03, 0)
user.adjustStaminaLoss(stacks*1.3) //At first the changeling may regenerate stamina fast enough to nullify fatigue, but it will stack
user.adjustStaminaLoss(stacks*1.5) //At first the changeling may regenerate stamina fast enough to nullify fatigue, but it will stack
if(stacks == 10) //Warning message that the stacks are getting too high
if(stacks == 5) //Warning message that the stacks are getting too high
to_chat(user, "<span class='warning'>Our legs are really starting to hurt...</span>")
sleep(40)
while(!active && stacks) //Damage stacks decrease fairly rapidly while not in sanic mode
while(!active && stacks) //Damage stacks decrease slowly while not in sanic mode
stacks--
sleep(20)
sleep(100)
@@ -239,7 +239,7 @@
if(!do_after(user, repair_values["healing_for_cycle"] * fabricator.speed_multiplier, target = src, \
extra_checks = CALLBACK(fabricator, /obj/item/clockwork/replica_fabricator.proc/fabricator_repair_checks, repair_values, src, user, TRUE)))
break
obj_integrity = CLAMP(obj_integrity + repair_values["healing_for_cycle"], 0, max_integrity)
obj_integrity = clamp(obj_integrity + repair_values["healing_for_cycle"], 0, max_integrity)
adjust_clockwork_power(-repair_values["power_required"])
playsound(src, 'sound/machines/click.ogg', 50, 1)
@@ -10,7 +10,7 @@
if(GLOB.ratvar_awakens)
current_power = GLOB.clockwork_power = INFINITY
else
current_power = GLOB.clockwork_power = CLAMP(GLOB.clockwork_power + amount, 0, MAX_CLOCKWORK_POWER)
current_power = GLOB.clockwork_power = clamp(GLOB.clockwork_power + amount, 0, MAX_CLOCKWORK_POWER)
for(var/obj/effect/clockwork/sigil/transmission/T in GLOB.all_clockwork_objects)
T.update_icon()
var/unlock_message
@@ -211,7 +211,7 @@
var/mob/living/carbon/C = L
C.stuttering = max(8, C.stuttering)
C.drowsyness = max(8, C.drowsyness)
C.confused += CLAMP(16 - C.confused, 0, 8)
C.confused += clamp(16 - C.confused, 0, 8)
C.apply_status_effect(STATUS_EFFECT_BELLIGERENT)
L.adjustFireLoss(15)
..()
@@ -59,7 +59,7 @@
if(issilicon(L))
L.DefaultCombatKnockdown(100)
else if(iscultist(L))
L.confused += CLAMP(10 - L.confused, 0, 5) // Spearthrow now confuses enemy cultists + just deals extra damage / sets on fire instead of hardstunning + damage
L.confused += clamp(10 - L.confused, 0, 5) // Spearthrow now confuses enemy cultists + just deals extra damage / sets on fire instead of hardstunning + damage
to_chat(L, "<span class ='userdanger'>[src] crashes into you with burning force, sending you reeling!</span>")
L.adjust_fire_stacks(2)
L.DefaultCombatKnockdown(1)
@@ -31,6 +31,7 @@
laws = new /datum/ai_laws/ratvar()
braintype = picked_name
GLOB.all_clockwork_objects += src
brainmob.add_blocked_language(subtypesof(/datum/language) - /datum/language/ratvar, LANGUAGE_CLOCKIE)
/obj/item/mmi/posibrain/soul_vessel/Destroy()
GLOB.all_clockwork_objects -= src
@@ -111,7 +111,7 @@
var/mob/living/L = M.current
if(ishuman(L) && L.stat != DEAD)
human_servants++
construct_limit = round(CLAMP((human_servants / 4), 1, 3)) //1 per 4 human servants, maximum of 3
construct_limit = round(clamp((human_servants / 4), 1, 3)) //1 per 4 human servants, maximum of 3
//Summon Neovgre: Summon a very powerful combat mech that explodes when destroyed for massive damage.
/datum/clockwork_scripture/create_object/summon_arbiter
@@ -63,4 +63,4 @@
break
if(!M)
M = H.apply_status_effect(STATUS_EFFECT_MANIAMOTOR, src)
M.severity = CLAMP(M.severity + ((11 - get_dist(src, H)) * efficiency * efficiency), 0, MAX_MANIA_SEVERITY)
M.severity = clamp(M.severity + ((11 - get_dist(src, H)) * efficiency * efficiency), 0, MAX_MANIA_SEVERITY)
@@ -91,7 +91,7 @@
current = mob_override
GLOB.all_clockwork_mobs += current
current.faction |= "ratvar"
current.grant_language(/datum/language/ratvar)
current.grant_language(/datum/language/ratvar, TRUE, TRUE, LANGUAGE_CLOCKIE)
current.update_action_buttons_icon() //because a few clockcult things are action buttons and we may be wearing/holding them for whatever reason, we need to update buttons
if(issilicon(current))
var/mob/living/silicon/S = current
@@ -102,6 +102,7 @@
R.module.rebuild_modules()
else if(isAI(S))
var/mob/living/silicon/ai/A = S
A.add_blocked_language(subtypesof(/datum/language) - /datum/language/ratvar, LANGUAGE_CLOCKIE)
A.can_be_carded = FALSE
A.requires_power = POWER_REQ_CLOCKCULT
var/list/AI_frame = list(mutable_appearance('icons/mob/clockwork_mobs.dmi', "aiframe")) //make the AI's cool frame
@@ -142,7 +143,7 @@
current = mob_override
GLOB.all_clockwork_mobs -= current
current.faction -= "ratvar"
current.remove_language(/datum/language/ratvar)
current.remove_language(/datum/language/ratvar, TRUE, TRUE, LANGUAGE_CLOCKIE)
current.clear_alert("clockinfo")
for(var/datum/action/innate/clockwork_armaments/C in owner.current.actions) //Removes any bound clockwork armor
qdel(C)
@@ -152,6 +153,7 @@
var/mob/living/silicon/S = current
if(isAI(S))
var/mob/living/silicon/ai/A = S
A.remove_blocked_language(subtypesof(/datum/language) - /datum/language/ratvar, LANGUAGE_CLOCKIE)
A.can_be_carded = initial(A.can_be_carded)
A.requires_power = initial(A.requires_power)
A.cut_overlays()
+4 -4
View File
@@ -454,16 +454,16 @@
S.emp_act(EMP_HEAVY)
else if(iscarbon(target))
var/mob/living/carbon/C = L
C.silent += CLAMP(12 - C.silent, 0, 6)
C.stuttering += CLAMP(30 - C.stuttering, 0, 15)
C.cultslurring += CLAMP(30 - C.cultslurring, 0, 15)
C.silent += clamp(12 - C.silent, 0, 6)
C.stuttering += clamp(30 - C.stuttering, 0, 15)
C.cultslurring += clamp(30 - C.cultslurring, 0, 15)
C.Jitter(15)
else // cultstun no longer hardstuns + damages hostile cultists, instead debuffs them hard + deals some damage; debuffs for a bit longer since they don't add the clockie belligerent debuff
if(iscarbon(target))
var/mob/living/carbon/C = L
C.stuttering = max(10, C.stuttering)
C.drowsyness = max(10, C.drowsyness)
C.confused += CLAMP(20 - C.confused, 0, 10)
C.confused += clamp(20 - C.confused, 0, 10)
L.adjustBruteLoss(15)
to_chat(user, "<span class='cultitalic'>In an brilliant flash of red, [L] [iscultist(L) ? "writhes in pain" : "falls to the ground!"]</span>")
uses--
+3 -3
View File
@@ -116,7 +116,7 @@
if(mob_override)
current = mob_override
current.faction |= "cult"
current.grant_language(/datum/language/narsie)
current.grant_language(/datum/language/narsie, TRUE, TRUE, LANGUAGE_CULTIST)
if(!cult_team?.cult_master)
vote.Grant(current)
communion.Grant(current)
@@ -134,7 +134,7 @@
if(mob_override)
current = mob_override
current.faction -= "cult"
current.remove_language(/datum/language/narsie)
current.remove_language(/datum/language/narsie, TRUE, TRUE, LANGUAGE_CULTIST)
vote.Remove(current)
communion.Remove(current)
magic.Remove(current)
@@ -441,7 +441,7 @@
if(objective.completable)
var/completion = objective.check_completion()
if(completion >= 1)
parts += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='greentext'><B>Success!</span>"
parts += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='greentext'><B>Success!</B></span>"
else if(completion <= 0)
parts += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='redtext'>Fail.</span>"
else
+2 -2
View File
@@ -539,7 +539,7 @@
if(SSshuttle.emergency.mode == SHUTTLE_CALL)
var/cursetime = 1800
var/timer = SSshuttle.emergency.timeLeft(1) + cursetime
var/security_num = seclevel2num(get_security_level())
var/security_num = SECLEVEL2NUM(NUM2SECLEVEL(GLOB.security_level))
var/set_coefficient = 1
switch(security_num)
if(SEC_LEVEL_GREEN)
@@ -731,7 +731,7 @@
if(!L.anti_magic_check())
if(is_servant_of_ratvar(L))
to_chat(L, "<span class='cultlarge'>\"Kneel for me, scum\"</span>")
L.confused += CLAMP(10 - L.confused, 0, 5) //confuses and lightly knockdowns + damages hostile cultists instead of hardstunning like before
L.confused += clamp(10 - L.confused, 0, 5) //confuses and lightly knockdowns + damages hostile cultists instead of hardstunning like before
L.DefaultCombatKnockdown(15)
L.adjustBruteLoss(10)
else
+2 -1
View File
@@ -527,7 +527,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
/datum/antagonist/devil/apply_innate_effects(mob/living/mob_override)
give_appropriate_spells()
owner.current.grant_all_languages(TRUE)
owner.current.grant_all_languages(TRUE, TRUE, TRUE, LANGUAGE_DEVIL)
update_hud()
.=..()
@@ -536,6 +536,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
var/obj/effect/proc_holder/spell/S = X
if(is_type_in_typecache(S, devil_spells))
owner.RemoveSpell(S)
owner.current.remove_all_languages(LANGUAGE_DEVIL)
.=..()
/datum/antagonist/devil/proc/printdevilinfo()
@@ -29,7 +29,7 @@
/mob/living/carbon/true_devil/Initialize()
create_bodyparts() //initialize bodyparts
create_internal_organs()
grant_all_languages(omnitongue=TRUE)
grant_all_languages()
..()
/mob/living/carbon/true_devil/create_internal_organs()
@@ -55,7 +55,7 @@
if(objective.completable)
var/completion = objective.check_completion()
if(completion >= 1)
result += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='greentext'><B>Success!</span>"
result += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='greentext'><B>Success!</B></span>"
else if(completion <= 0)
result += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='redtext'>Fail.</span>"
win = FALSE
@@ -128,6 +128,9 @@ the new instance inside the host to be updated to the template's stats.
link = FOLLOW_LINK(src, to_follow)
else
link = ""
// Create map text prior to modifying message for goonchat
if (client?.prefs.chat_on_map && (client.prefs.see_chat_non_mob || ismob(speaker)))
create_chat_message(speaker, message_language, raw_message, spans, message_mode)
// Recompose the message, because it's scrambled by default
message = compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mode, FALSE, source)
to_chat(src, "[link] [message]")
@@ -44,7 +44,7 @@
STOP_PROCESSING(SSobj, core)
update_icon()
GLOB.poi_list |= src
previous_level = get_security_level()
previous_level = NUM2SECLEVEL(GLOB.security_level)
/obj/machinery/nuclearbomb/Destroy()
safety = FALSE
@@ -360,7 +360,7 @@
if(NUKEUI_AWAIT_TIMER)
var/number_value = text2num(numeric_input)
if(number_value)
timer_set = CLAMP(number_value, minimum_timer_set, maximum_timer_set)
timer_set = clamp(number_value, minimum_timer_set, maximum_timer_set)
playsound(src, 'sound/machines/nuke/general_beep.ogg', 50, FALSE)
set_safety()
. = TRUE
@@ -421,7 +421,7 @@
return
timing = !timing
if(timing)
previous_level = get_security_level()
previous_level = NUM2SECLEVEL(GLOB.security_level)
detonation_timer = world.time + (timer_set * 10)
for(var/obj/item/pinpointer/nuke/syndicate/S in GLOB.pinpointer_list)
S.switch_mode_to(TRACK_INFILTRATOR)
@@ -64,8 +64,8 @@
/mob/living/simple_animal/slaughter/phasein()
. = ..()
add_movespeed_modifier(MOVESPEED_ID_SLAUGHTER, update=TRUE, priority=100, multiplicative_slowdown=-1)
addtimer(CALLBACK(src, .proc/remove_movespeed_modifier, MOVESPEED_ID_SLAUGHTER, TRUE), 6 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE)
add_movespeed_modifier(/datum/movespeed_modifier/slaughter)
addtimer(CALLBACK(src, .proc/remove_movespeed_modifier, /datum/movespeed_modifier/slaughter), 6 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE)
//The loot from killing a slaughter demon - can be consumed to allow the user to blood crawl
@@ -27,6 +27,9 @@
for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list)
if(isturf(L.loc))
spawn_locs += L.loc
for(var/obj/effect/landmark/loneopspawn/L in GLOB.landmarks_list)
if(isturf(L.loc))
spawn_locs += L.loc
if(!spawn_locs)
message_admins("No valid spawn locations found, aborting...")
@@ -65,5 +65,5 @@
/datum/traitor_class/ai/finalize_traitor(datum/antagonist/traitor/T)
T.add_law_zero()
T.owner.current.playsound_local(get_turf(T.owner.current), 'sound/ambience/antag/malf.ogg', 100, FALSE, pressure_affected = FALSE)
T.owner.current.grant_language(/datum/language/codespeak)
T.owner.current.grant_language(/datum/language/codespeak, TRUE, TRUE, LANGUAGE_MALF)
return FALSE
@@ -48,7 +48,7 @@
var/datum/traitor_class/class = GLOB.traitor_classes[C]
var/weight = LOGISTIC_FUNCTION(1.5*class.weight,chaos_weight,class.chaos,0)
weights[C] = weight * 1000
var/choice = pickweightAllowZero(weights)
var/choice = pickweight(weights, 0)
if(!choice)
choice = TRAITOR_HUMAN // it's an "easter egg"
var/datum/traitor_class/actual_class = GLOB.traitor_classes[choice]
@@ -239,7 +239,7 @@
if(objective.completable)
var/completion = objective.check_completion()
if(completion >= 1)
objectives_text += "<br><B>Objective #[count]</B>: [objective.explanation_text] <span class='greentext'><B>Success!</span>"
objectives_text += "<br><B>Objective #[count]</B>: [objective.explanation_text] <span class='greentext'><B>Success!</B></span>"
else if(completion <= 0)
objectives_text += "<br><B>Objective #[count]</B>: [objective.explanation_text] <span class='redtext'>Fail.</span>"
traitorwin = FALSE
@@ -159,7 +159,7 @@
/obj/item/scrying/attack_self(mob/user)
to_chat(user, "<span class='notice'>You can see...everything!</span>")
visible_message("<span class='danger'>[user] stares into [src], their eyes glazing over.</span>")
user.ghostize(1)
user.ghostize(1, voluntary = TRUE)
/////////////////////////////////////////Necromantic Stone///////////////////
@@ -233,7 +233,7 @@
newstruct.cancel_camera()
/obj/item/soulstone/proc/init_shade(mob/living/carbon/human/T, mob/U, vic = 0)
/obj/item/soulstone/proc/init_shade(mob/living/carbon/human/T, mob/user, vic = 0)
new /obj/effect/decal/remains/human(T.loc) //Spawns a skeleton
T.stop_sound_channel(CHANNEL_HEARTBEAT)
T.invisibility = INVISIBILITY_ABSTRACT
@@ -245,20 +245,23 @@
S.name = "Shade of [T.real_name]"
S.real_name = "Shade of [T.real_name]"
T.transfer_ckey(S)
S.language_holder = U.language_holder.copy(S)
if(U)
S.faction |= "[REF(U)]" //Add the master as a faction, allowing inter-mob cooperation
if(U && iscultist(U))
S.copy_languages(T, LANGUAGE_MIND)//Copies the old mobs languages into the new mob holder.
S.copy_languages(user, LANGUAGE_MASTER)
S.update_atom_languages()
grant_all_languages(FALSE, FALSE, TRUE) //Grants omnitongue
if(user)
S.faction |= "[REF(user)]" //Add the master as a faction, allowing inter-mob cooperation
if(user && iscultist(user))
SSticker.mode.add_cultist(S.mind, 0)
S.cancel_camera()
name = "soulstone: Shade of [T.real_name]"
icon_state = "soulstone2"
if(U && (iswizard(U) || usability))
to_chat(S, "Your soul has been captured! You are now bound to [U.real_name]'s will. Help [U.p_them()] succeed in [U.p_their()] goals at all costs.")
else if(U && iscultist(U))
if(user && (iswizard(user) || usability))
to_chat(S, "Your soul has been captured! You are now bound to [user.real_name]'s will. Help [user.p_them()] succeed in [user.p_their()] goals at all costs.")
else if(user && iscultist(user))
to_chat(S, "Your soul has been captured! You are now bound to the cult's will. Help them succeed in their goals at all costs.")
if(vic && U)
to_chat(U, "<span class='info'><b>Capture successful!</b>:</span> [T.real_name]'s soul has been ripped from [T.p_their()] body and stored within the soul stone.")
if(vic && user)
to_chat(user, "<span class='info'><b>Capture successful!</b>:</span> [T.real_name]'s soul has been ripped from [T.p_their()] body and stored within the soul stone.")
/obj/item/soulstone/proc/getCultGhost(mob/living/carbon/human/T, mob/U)
@@ -294,7 +294,7 @@
name = "Staff of Change"
desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself."
item_path = /obj/item/gun/magic/staff/change
dynamic_requirement = 60
dynamic_requirement = 200
/datum/spellbook_entry/item/staffanimation
name = "Staff of Animation"
@@ -361,7 +361,7 @@
desc = "A collection of wands that allow for a wide variety of utility. Wands have a limited number of charges, so be conservative in use. Comes in a handy belt."
item_path = /obj/item/storage/belt/wands/full
category = "Defensive"
dynamic_requirement = 60
dynamic_requirement = 200
/datum/spellbook_entry/item/armor
name = "Mastercrafted Armor Set"
@@ -386,7 +386,7 @@
name = "Plasma Fist"
desc = "A forbidden martial art designed on the surging power of plasma. Use it to harness the ancient power."
item_path = /obj/item/book/granter/martial/plasma_fist
cost = 3
cost = 2
/datum/spellbook_entry/item/guardian
name = "Guardian Deck"
+1 -1
View File
@@ -269,7 +269,7 @@
if(objective.completable)
var/completion = objective.check_completion()
if(completion >= 1)
parts += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='greentext'><B>Success!</span>"
parts += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='greentext'><B>Success!</B></span>"
else if(completion <= 0)
parts += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='redtext'>Fail.</span>"
wizardwin = FALSE