AAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
This commit is contained in:
Improvedname
2020-03-20 22:50:57 +01:00
parent 83affc126f
commit f376b64f31
69 changed files with 777 additions and 334 deletions
@@ -56,7 +56,7 @@
if(used)
to_chat(H, "You already used this contract!")
return
var/list/candidates = pollCandidatesForMob("Do you want to play as a wizard's [href_list["school"]] apprentice?", ROLE_WIZARD, null, ROLE_WIZARD, 150, src)
var/list/candidates = pollCandidatesForMob("Do you want to play as a wizard's [href_list["school"]] apprentice?", ROLE_WIZARD, null, ROLE_WIZARD, 150, src, ignore_category = POLL_IGNORE_WIZARD)
if(LAZYLEN(candidates))
if(QDELETED(src))
return
@@ -235,7 +235,7 @@
return
if(used)
return
var/list/candidates = pollCandidatesForMob("Do you want to play as a [initial(demon_type.name)]?", ROLE_ALIEN, null, ROLE_ALIEN, 50, src)
var/list/candidates = pollCandidatesForMob("Do you want to play as a [initial(demon_type.name)]?", ROLE_ALIEN, null, ROLE_ALIEN, 50, src, ignore_category = POLL_IGNORE_DEMON)
if(LAZYLEN(candidates))
if(used || QDELETED(src))
return
@@ -1,5 +1,5 @@
/datum/surgery/organ_extraction
name = "experimental dissection"
name = "experimental organ replacement"
steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/incise, /datum/surgery_step/extract_organ, /datum/surgery_step/gland_insert)
possible_locs = list(BODY_ZONE_CHEST)
ignore_clothes = 1
+10 -5
View File
@@ -644,6 +644,11 @@
desc = "A spell that will absorb blood from anything you touch.<br>Touching cultists and constructs can heal them.<br><b>Clicking the hand will potentially let you focus the spell into something stronger.</b>"
color = "#7D1717"
/obj/item/melee/blood_magic/manipulator/examine(mob/user)
. = ..()
if(iscultist(user))
to_chat(user, "<span class='cultitalic'>The [name] currently has <b>[uses]</b> blood charges left.</span>")
/obj/item/melee/blood_magic/manipulator/afterattack(atom/target, mob/living/carbon/human/user, proximity)
if(proximity)
if(ishuman(target))
@@ -678,9 +683,9 @@
if(ratio>1)
ratio = 1
uses -= round(overall_damage)
H.visible_message("<span class='warning'>[H] is fully healed by [H==user ? "[H.p_their()]":"[H]'s"]'s blood magic!</span>")
H.visible_message("<span class='warning'>[H] is fully healed by [H==user ? "[H.p_their()]":"[user]'s"] blood magic!</span>")
else
H.visible_message("<span class='warning'>[H] is partially healed by [H==user ? "[H.p_their()]":"[H]'s"] blood magic.</span>")
H.visible_message("<span class='warning'>[H] is partially healed by [H==user ? "[H.p_their()]":"[user]'s"] blood magic.</span>")
uses = 0
ratio *= -1
H.adjustOxyLoss((overall_damage*ratio) * (H.getOxyLoss() / overall_damage), 0)
@@ -762,7 +767,7 @@
switch(choice)
if("Blood Spear (150)")
if(uses < 150)
to_chat(user, "<span class='cultitalic'>You need 200 charges to perform this rite.</span>")
to_chat(user, "<span class='cultitalic'>You need 150 charges to perform this rite.</span>")
else
uses -= 150
var/turf/T = get_turf(user)
@@ -778,7 +783,7 @@
"<span class='cultitalic'>A [rite.name] materializes at your feet.</span>")
if("Blood Bolt Barrage (300)")
if(uses < 300)
to_chat(user, "<span class='cultitalic'>You need 400 charges to perform this rite.</span>")
to_chat(user, "<span class='cultitalic'>You need 300 charges to perform this rite.</span>")
else
var/obj/rite = new /obj/item/gun/ballistic/shotgun/boltaction/enchanted/arcane_barrage/blood()
uses -= 300
@@ -790,7 +795,7 @@
qdel(rite)
if("Blood Beam (500)")
if(uses < 500)
to_chat(user, "<span class='cultitalic'>You need 600 charges to perform this rite.</span>")
to_chat(user, "<span class='cultitalic'>You need 500 charges to perform this rite.</span>")
else
var/obj/rite = new /obj/item/blood_beam()
uses -= 500
@@ -666,6 +666,7 @@
righthand_file = 'icons/mob/inhands/weapons/polearms_righthand.dmi'
slot_flags = 0
force = 17
force_unwielded = 17
force_wielded = 24
throwforce = 40
throw_speed = 2
+6 -42
View File
@@ -185,9 +185,6 @@ structure_check() searches for nearby cultist structures required for the invoca
color = RUNE_COLOR_OFFER
req_cultists = 1
rune_in_use = FALSE
var/mob/living/currentconversionman
var/conversiontimeout
var/conversionresult
/obj/effect/rune/convert/do_invoke_glow()
return
@@ -236,34 +233,14 @@ structure_check() searches for nearby cultist structures required for the invoca
/obj/effect/rune/convert/proc/do_convert(mob/living/convertee, list/invokers)
if(invokers.len < 2)
for(var/M in invokers)
to_chat(M, "<span class='danger'>You need at least two invokers to convert [convertee]!</span>")
to_chat(M, "<span class='warning'>You need at least two invokers to convert [convertee]!</span>")
log_game("Offer rune failed - tried conversion with one invoker")
return 0
if(convertee.anti_magic_check(TRUE, TRUE))
if(convertee.anti_magic_check(TRUE, TRUE, FALSE, 0)) //Not chargecost because it can be spammed
for(var/M in invokers)
to_chat(M, "<span class='warning'>Something is shielding [convertee]'s mind!</span>")
log_game("Offer rune failed - convertee had anti-magic")
return 0
to_chat(convertee, "<span class='cult italic'><b>The world goes red. All at once you are aware of an evil, eldritch truth taking roots into your mind.\n\
<a href='?src=\ref[src];signmeup=1'>Click here to become a follower of Nar'sie</a></b>, or suffer a fate worse than death.</span>")
INVOKE_ASYNC(src, .proc/optinalert, convertee)
currentconversionman = convertee
conversiontimeout = world.time + (14 SECONDS)
convertee.Stun(140)
ADD_TRAIT(convertee, TRAIT_MUTE, "conversionrune")
flash_color(convertee, list("#960000", "#960000", "#960000", rgb(0,0,0)), 50)
conversionresult = FALSE
while(world.time < conversiontimeout && convertee && !conversionresult)
stoplag(1)
currentconversionman = null
if(!convertee)
return FALSE
REMOVE_TRAIT(convertee, TRAIT_MUTE, "conversionrune")
if(get_turf(convertee) != get_turf(src))
return FALSE
if(!conversionresult)
do_sacrifice(convertee, invokers, TRUE)
return FALSE
var/brutedamage = convertee.getBruteLoss()
var/burndamage = convertee.getFireLoss()
if(brutedamage || burndamage)
@@ -275,6 +252,8 @@ structure_check() searches for nearby cultist structures required for the invoca
SSticker.mode.add_cultist(convertee.mind, 1)
new /obj/item/melee/cultblade/dagger(get_turf(src))
convertee.mind.special_role = ROLE_CULTIST
to_chat(convertee, "<span class='cult italic'><b>Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible, truth. The veil of reality has been ripped away \
and something evil takes root.</b></span>")
to_chat(convertee, "<span class='cult italic'><b>Assist your new compatriots in their dark dealings. Your goal is theirs, and theirs is yours. You serve the Geometer above all else. Bring it back.\
</b></span>")
if(ishuman(convertee))
@@ -284,18 +263,7 @@ structure_check() searches for nearby cultist structures required for the invoca
H.cultslurring = 0
return 1
/obj/effect/rune/convert/proc/optinalert(mob/living/convertee)
var/alert = alert(convertee, "Will you embrace the Geometer of Blood or perish in futile resistance?", "Choose your own fate", "Join the Blood Cult", "Suffer a horrible demise")
if(alert == "Join the Blood Cult")
signmeup(convertee)
/obj/effect/rune/convert/proc/signmeup(mob/living/convertee)
if(currentconversionman == usr)
conversionresult = TRUE
else
to_chat(usr, "<span class='cult italic'>Your fate has already been set in stone.</span>")
/obj/effect/rune/convert/proc/do_sacrifice(mob/living/sacrificial, list/invokers, force_a_sac)
/obj/effect/rune/convert/proc/do_sacrifice(mob/living/sacrificial, list/invokers)
var/mob/living/first_invoker = invokers[1]
if(!first_invoker)
return FALSE
@@ -305,7 +273,7 @@ structure_check() searches for nearby cultist structures required for the invoca
var/big_sac = FALSE
if(!force_a_sac && (((ishuman(sacrificial) || iscyborg(sacrificial)) && sacrificial.stat != DEAD) || C.cult_team.is_sacrifice_target(sacrificial.mind)) && invokers.len < 3)
if((((ishuman(sacrificial) || iscyborg(sacrificial)) && sacrificial.stat != DEAD) || C.cult_team.is_sacrifice_target(sacrificial.mind)) && invokers.len < 3)
for(var/M in invokers)
to_chat(M, "<span class='cult italic'>[sacrificial] is too greatly linked to the world! You need three acolytes!</span>")
log_game("Offer rune failed - not enough acolytes and target is living or sac target")
@@ -345,10 +313,6 @@ structure_check() searches for nearby cultist structures required for the invoca
sacrificial.gib()
return TRUE
/obj/effect/rune/convert/Topic(href, href_list)
if(href_list["signmeup"])
signmeup(usr)
/obj/effect/rune/empower
cultist_name = "Empower"
cultist_desc = "allows cultists to prepare greater amounts of blood magic at far less of a cost."
@@ -11,9 +11,9 @@
viable_mobtypes = list(/mob/living/carbon/human)
disease_flags = CURABLE
permeability_mod = 1
severity = DISEASE_SEVERITY_HARMFUL
var/stagedamage = 0 //Highest stage reached.
severity = DISEASE_SEVERITY_DANGEROUS
var/finalstage = 0 //Because we're spawning off the cure in the final stage, we need to check if we've done the final stage's effects.
var/datum/mood_event/revenant_blight/depression
/datum/disease/revblight/cure()
if(affected_mob)
@@ -21,12 +21,13 @@
if(affected_mob.dna && affected_mob.dna.species)
affected_mob.dna.species.handle_mutant_bodyparts(affected_mob)
affected_mob.dna.species.handle_hair(affected_mob)
to_chat(affected_mob, "<span class='notice'>You feel better.</span>")
SEND_SIGNAL(affected_mob, COMSIG_CLEAR_MOOD_EVENT, "rev_blight")
..()
/datum/disease/revblight/stage_act()
if(!finalstage)
if(affected_mob.lying && prob(stage*6))
if(affected_mob.lying && prob(stage*4))
to_chat(affected_mob, "<span class='notice'>You feel better.</span>")
cure()
return
if(prob(stage*3))
@@ -34,10 +35,6 @@
affected_mob.confused += 8
affected_mob.adjustStaminaLoss(8)
new /obj/effect/temp_visual/revenant(affected_mob.loc)
if(stagedamage < stage)
stagedamage++
affected_mob.adjustToxLoss(stage*2) //should, normally, do about 30 toxin damage.
new /obj/effect/temp_visual/revenant(affected_mob.loc)
if(prob(45))
affected_mob.adjustStaminaLoss(stage)
..() //So we don't increase a stage before applying the stage damage.
@@ -46,9 +43,13 @@
if(prob(5))
affected_mob.emote("pale")
if(3)
if(!depression)
depression = SEND_SIGNAL(affected_mob, COMSIG_ADD_MOOD_EVENT, "rev_blight", /datum/mood_event/revenant_blight)
SEND_SIGNAL(affected_mob, COMSIG_DECREASE_SANITY, 0.12, SANITY_CRAZY)
if(prob(10))
affected_mob.emote(pick("pale","shiver"))
if(4)
SEND_SIGNAL(affected_mob, COMSIG_DECREASE_SANITY, 0.18, SANITY_CRAZY)
if(prob(15))
affected_mob.emote(pick("pale","shiver","cries"))
if(5)
@@ -56,12 +57,18 @@
finalstage = TRUE
to_chat(affected_mob, "<span class='revenbignotice'>You feel like [pick("nothing's worth it anymore", "nobody ever needed your help", "nothing you did mattered", "everything you tried to do was worthless")].</span>")
affected_mob.adjustStaminaLoss(45)
new /obj/effect/temp_visual/revenant(affected_mob.loc)
if(affected_mob.dna && affected_mob.dna.species)
if(affected_mob.dna?.species)
affected_mob.dna.species.handle_mutant_bodyparts(affected_mob,"#1d2953")
affected_mob.dna.species.handle_hair(affected_mob,"#1d2953")
affected_mob.visible_message("<span class='warning'>[affected_mob] looks terrifyingly gaunt...</span>", "<span class='revennotice'>You suddenly feel like your skin is <i>wrong</i>...</span>")
affected_mob.add_atom_colour("#1d2953", TEMPORARY_COLOUR_PRIORITY)
addtimer(CALLBACK(src, .proc/cure), 100)
else
return
new /obj/effect/temp_visual/revenant(affected_mob.loc)
addtimer(CALLBACK(src, .proc/curses), 150)
/datum/disease/revblight/proc/curses()
if(QDELETED(affected_mob))
return
affected_mob.playsound_local(affected_mob, 'sound/effects/curse5.ogg', 40, 1, -1)
to_chat(affected_mob, "<span class='revendanger'>You sense the terrific curse of a vengeful ghost befall upon you...</span>")
affected_mob.apply_necropolis_curse(null, 7 MINUTES) //Once the blight has done its course without being cured beforehand, it will cast a necrocurse to compensate how underpowered it's.
cure()
@@ -410,7 +410,9 @@
FermiChem = TRUE//If the chemical uses the Fermichem reaction mechanics
FermiExplode = FALSE //If the chemical explodes in a special way
PurityMin = 0 //The minimum purity something has to be above, otherwise it explodes.
clear_conversion = REACTION_CLEAR_INVERSE
/*
/datum/chemical_reaction/neurotoxin/FermiFinish(datum/reagents/holder, var/atom/my_atom)
var/datum/reagent/consumable/ethanol/neurotoxin/Nt = locate(/datum/reagent/consumable/ethanol/neurotoxin) in my_atom.reagents.reagent_list
if(Nt)
@@ -418,6 +420,7 @@
if(Nt.purity < 0.5)
holder.remove_reagent(src.id, cached_volume)
holder.add_reagent("neurosmash", cached_volume)
*/
/datum/chemical_reaction/snowwhite
name = "Snow White"
+8 -3
View File
@@ -271,9 +271,13 @@
if(restrained())
changeNext_move(CLICK_CD_BREAKOUT)
last_special = world.time + CLICK_CD_BREAKOUT
var/buckle_cd = 600
if(handcuffed)
var/obj/item/restraints/O = src.get_item_by_slot(SLOT_HANDCUFFED)
buckle_cd = O.breakouttime
visible_message("<span class='warning'>[src] attempts to unbuckle [p_them()]self!</span>", \
"<span class='notice'>You attempt to unbuckle yourself... (This will take around one minute and you need to stay still.)</span>")
if(do_after(src, 600, 0, target = src))
"<span class='notice'>You attempt to unbuckle yourself... (This will take around [round(buckle_cd/600,1)] minute\s, and you need to stay still.)</span>")
if(do_after(src, buckle_cd, 0, target = src))
if(!buckled)
return
buckled.user_unbuckle_mob(src,src)
@@ -809,7 +813,8 @@
drop_all_held_items()
stop_pulling()
throw_alert("handcuffed", /obj/screen/alert/restrained/handcuffed, new_master = src.handcuffed)
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "handcuffed", /datum/mood_event/handcuffed)
if(handcuffed.demoralize_criminals)
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "handcuffed", /datum/mood_event/handcuffed)
else
clear_alert("handcuffed")
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "handcuffed")
@@ -16,5 +16,5 @@
blacklisted = 1
use_skintones = 0
species_traits = list(NOBLOOD,EYECOLOR,NOGENITALS)
inherent_traits = list(TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOHUNGER)
inherent_traits = list(TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOLIMBDISABLE,TRAIT_NOHUNGER)
sexes = 0
@@ -12,7 +12,7 @@
damage_overlay_type = "synth"
limbs_id = "synth"
var/list/initial_species_traits = list(NOTRANSSTING) //for getting these values back for assume_disguise()
var/list/initial_inherent_traits = list(TRAIT_VIRUSIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOHUNGER,TRAIT_NOBREATH)
var/list/initial_inherent_traits = list(TRAIT_VIRUSIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOHUNGER,TRAIT_NOLIMBDISABLE,TRAIT_NOBREATH)
var/disguise_fail_health = 75 //When their health gets to this level their synthflesh partially falls off
var/datum/species/fake_species = null //a species to do most of our work for us, unless we're damaged
+7
View File
@@ -35,6 +35,7 @@
*/
if(stat == DEAD)
stop_sound_channel(CHANNEL_HEARTBEAT)
handle_death()
rot()
//Updates the number of stored chemicals for powers
@@ -43,6 +44,12 @@
if(stat != DEAD)
return 1
//Procs called while dead
/mob/living/carbon/proc/handle_death()
for(var/datum/reagent/R in reagents.reagent_list)
if(R.chemical_flags & REAGENT_DEAD_PROCESS)
R.on_mob_dead(src)
///////////////
// BREATHING //
///////////////
@@ -44,7 +44,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
var/reset = 0 //if the summoner has reset the guardian already
var/cooldown = 0
var/mob/living/carbon/summoner
var/range = 10 //how far from the user the spirit can be
var/range = 13 //how far from the user the spirit can be
var/toggle_button_type = /obj/screen/guardian/ToggleMode/Inactive //what sort of toggle button the hud uses
var/datum/guardianname/namedatum = new/datum/guardianname()
var/playstyle_string = "<span class='holoparasite bold'>You are a standard Guardian. You shouldn't exist!</span>"
@@ -1,7 +1,5 @@
//Assassin
/mob/living/simple_animal/hostile/guardian/assassin
melee_damage_lower = 15
melee_damage_upper = 15
attacktext = "slashes"
attack_sound = 'sound/weapons/bladeslice.ogg'
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1)
@@ -12,7 +10,7 @@
toggle_button_type = /obj/screen/guardian/ToggleMode/Assassin
var/toggle = FALSE
var/stealthcooldown = 160
var/stealthcooldown = 100
var/obj/screen/alert/canstealthalert
var/obj/screen/alert/instealthalert
@@ -1,13 +1,10 @@
//Charger
/mob/living/simple_animal/hostile/guardian/charger
melee_damage_lower = 15
melee_damage_upper = 15
ranged = 1 //technically
ranged_message = "charges"
ranged_cooldown_time = 40
speed = -1
damage_coeff = list(BRUTE = 0.6, BURN = 0.6, TOX = 0.6, CLONE = 0.6, STAMINA = 0, OXY = 0.6)
playstyle_string = "<span class='holoparasite'>As a <b>charger</b> type you do medium damage, have medium damage resistance, move very fast, and can charge at a location, damaging any target hit and forcing them to drop any items they are holding.</span>"
ranged_cooldown_time = 20
damage_coeff = list(BRUTE = 0, BURN = 0.5, TOX = 0.5, CLONE = 0.5, STAMINA = 0, OXY = 0.5)
playstyle_string = "<span class='holoparasite'>As a <b>charger</b> type you do medium damage, take half damage, immunity to brute damage, move very fast, and can charge at a location, damaging any target hit and forcing them to drop any items they are holding.</span>"
magic_fluff_string = "<span class='holoparasite'>..And draw the Hunter, an alien master of rapid assault.</span>"
tech_fluff_string = "<span class='holoparasite'>Boot sequence complete. Charge modules loaded. Holoparasite swarm online.</span>"
carp_fluff_string = "<span class='holoparasite'>CARP CARP CARP! Caught one! It's a charger carp, that likes running at people. But it doesn't have any legs...</span>"
@@ -3,7 +3,7 @@
melee_damage_lower = 10
melee_damage_upper = 10
damage_coeff = list(BRUTE = 0.75, BURN = 0.75, TOX = 0.75, CLONE = 0.75, STAMINA = 0, OXY = 0.75)
playstyle_string = "<span class='holoparasite'>As a <b>dextrous</b> type you can hold items, store an item within yourself, and have medium damage resistance, but do low damage on attacks. Recalling and leashing will force you to drop unstored items!</span>"
playstyle_string = "<span class='holoparasite'>As a <b>dextrous</b> type you can hold items, store an item within yourself, and take half damage, but do low damage on attacks. Recalling and leashing will force you to drop unstored items!</span>"
magic_fluff_string = "<span class='holoparasite'>..And draw the Drone, a dextrous master of construction and repair.</span>"
tech_fluff_string = "<span class='holoparasite'>Boot sequence complete. Dextrous combat modules loaded. Holoparasite swarm online.</span>"
carp_fluff_string = "<span class='holoparasite'>CARP CARP CARP! You caught one! It can hold stuff in its fins, sort of.</span>"
@@ -1,10 +1,7 @@
//Bomb
/mob/living/simple_animal/hostile/guardian/bomb
melee_damage_lower = 15
melee_damage_upper = 15
damage_coeff = list(BRUTE = 0.6, BURN = 0.6, TOX = 0.6, CLONE = 0.6, STAMINA = 0, OXY = 0.6)
range = 13
playstyle_string = "<span class='holoparasite'>As an <b>explosive</b> type, you have moderate close combat abilities, may explosively teleport targets on attack, and are capable of converting nearby items and objects into disguised bombs via alt click.</span>"
playstyle_string = "<span class='holoparasite'>As an <b>explosive</b> type, you have moderate close combat abilities, take half damage, may explosively teleport targets on attack, and are capable of converting nearby items and objects into disguised bombs via alt click.</span>"
magic_fluff_string = "<span class='holoparasite'>..And draw the Scientist, master of explosive death.</span>"
tech_fluff_string = "<span class='holoparasite'>Boot sequence complete. Explosive modules active. Holoparasite swarm online.</span>"
carp_fluff_string = "<span class='holoparasite'>CARP CARP CARP! Caught one! It's an explosive carp! Boom goes the fishy.</span>"
@@ -1,13 +1,13 @@
//Fire
/mob/living/simple_animal/hostile/guardian/fire
a_intent = INTENT_HELP
melee_damage_lower = 7
melee_damage_upper = 7
melee_damage_lower = 10
melee_damage_upper = 10
attack_sound = 'sound/items/welder.ogg'
attacktext = "ignites"
damage_coeff = list(BRUTE = 0.7, BURN = 0.7, TOX = 0.7, CLONE = 0.7, STAMINA = 0, OXY = 0.7)
range = 7
playstyle_string = "<span class='holoparasite'>As a <b>chaos</b> type, you have only light damage resistance, but will ignite any enemy you bump into. In addition, your melee attacks will cause human targets to see everyone as you.</span>"
melee_damage_type = BURN
damage_coeff = list(BRUTE = 0.7, BURN = 0, TOX = 0.7, CLONE = 0.7, STAMINA = 0, OXY = 0.7)
playstyle_string = "<span class='holoparasite'>As a <b>chaos</b> type, you take 30% damage reduction to all but burn, which you are immune to. You will ignite any enemy you bump into. in addition, your melee attacks will cause human targets to see everyone as you.</span>"
magic_fluff_string = "<span class='holoparasite'>..And draw the Wizard, bringer of endless chaos!</span>"
tech_fluff_string = "<span class='holoparasite'>Boot sequence complete. Crowd control modules activated. Holoparasite swarm online.</span>"
carp_fluff_string = "<span class='holoparasite'>CARP CARP CARP! You caught one! OH GOD, EVERYTHING'S ON FIRE. Except you and the fish.</span>"
@@ -38,6 +38,6 @@
/mob/living/simple_animal/hostile/guardian/fire/proc/collision_ignite(AM as mob|obj)
if(isliving(AM))
var/mob/living/M = AM
if(!hasmatchingsummoner(M) && M != summoner && M.fire_stacks < 7)
M.fire_stacks = 7
if(!hasmatchingsummoner(M) && M != summoner && M.fire_stacks < 10)
M.fire_stacks = 10
M.IgniteMob()
@@ -4,14 +4,13 @@
layer = LYING_MOB_LAYER
/mob/living/simple_animal/hostile/guardian/beam
melee_damage_lower = 7
melee_damage_upper = 7
melee_damage_lower = 10
melee_damage_upper = 10
attacktext = "shocks"
melee_damage_type = BURN
attack_sound = 'sound/machines/defib_zap.ogg'
damage_coeff = list(BRUTE = 0.7, BURN = 0.7, TOX = 0.7, CLONE = 0.7, STAMINA = 0, OXY = 0.7)
range = 7
playstyle_string = "<span class='holoparasite'>As a <b>lightning</b> type, you will apply lightning chains to targets on attack and have a lightning chain to your summoner. Lightning chains will shock anyone near them.</span>"
playstyle_string = "<span class='holoparasite'>As a <b>lightning</b> type, you have 30% damage reduction, apply lightning chains to targets on attack and have a lightning chain to your summoner. Lightning chains will shock anyone near them.</span>"
magic_fluff_string = "<span class='holoparasite'>..And draw the Tesla, a shocking, lethal source of power.</span>"
tech_fluff_string = "<span class='holoparasite'>Boot sequence complete. Lightning modules active. Holoparasite swarm online.</span>"
carp_fluff_string = "<span class='holoparasite'>CARP CARP CARP! Caught one! It's a lightning carp! Everyone else goes zap zap.</span>"
@@ -31,7 +30,7 @@
var/datum/beam/C = pick(enemychains)
qdel(C)
enemychains -= C
enemychains += Beam(target, "lightning[rand(1,12)]", time=70, maxdistance=7, beam_type=/obj/effect/ebeam/chain)
enemychains += Beam(target, "lightning[rand(1,12)]", time=70, maxdistance=13, beam_type=/obj/effect/ebeam/chain)
/mob/living/simple_animal/hostile/guardian/beam/Destroy()
removechains()
@@ -1,7 +1,5 @@
//Protector
/mob/living/simple_animal/hostile/guardian/protector
melee_damage_lower = 15
melee_damage_upper = 15
range = 15 //worse for it due to how it leashes
damage_coeff = list(BRUTE = 0.4, BURN = 0.4, TOX = 0.4, CLONE = 0.4, STAMINA = 0, OXY = 0.4)
playstyle_string = "<span class='holoparasite'>As a <b>protector</b> type you cause your summoner to leash to you instead of you leashing to them and have two modes; Combat Mode, where you do and take medium damage, and Protection Mode, where you do and take almost no damage, but move slightly slower.</span>"
@@ -33,9 +31,9 @@
cooldown = world.time + 10
if(toggle)
cut_overlays()
melee_damage_lower = initial(melee_damage_lower)
melee_damage_upper = initial(melee_damage_upper)
speed = initial(speed)
melee_damage_lower = 15
melee_damage_upper = 15
speed = 0
damage_coeff = list(BRUTE = 0.4, BURN = 0.4, TOX = 0.4, CLONE = 0.4, STAMINA = 0, OXY = 0.4)
to_chat(src, "<span class='danger'><B>You switch to combat mode.</span></B>")
toggle = FALSE
@@ -44,8 +42,8 @@
if(namedatum)
shield_overlay.color = namedatum.colour
add_overlay(shield_overlay)
melee_damage_lower = 2
melee_damage_upper = 2
melee_damage_lower = 5
melee_damage_upper = 5
speed = 1
damage_coeff = list(BRUTE = 0.05, BURN = 0.05, TOX = 0.05, CLONE = 0.05, STAMINA = 0, OXY = 0.05) //damage? what's damage?
to_chat(src, "<span class='danger'><B>You switch to protection mode.</span></B>")
@@ -16,8 +16,7 @@
ranged_cooldown_time = 1 //fast!
projectilesound = 'sound/effects/hit_on_shattered_glass.ogg'
ranged = 1
range = 13
playstyle_string = "<span class='holoparasite'>As a <b>ranged</b> type, you have only light damage resistance, but are capable of spraying shards of crystal at incredibly high speed. You can also deploy surveillance snares to monitor enemy movement. Finally, you can switch to scout mode, in which you can't attack, but can move without limit.</span>"
playstyle_string = "<span class='holoparasite'>As a <b>ranged</b> type, you have 10% damage reduction, but are capable of spraying shards of crystal at incredibly high speed. You can also deploy surveillance snares to monitor enemy movement. Finally, you can switch to scout mode, in which you can't attack, but can move without limit.</span>"
magic_fluff_string = "<span class='holoparasite'>..And draw the Sentinel, an alien master of ranged combat.</span>"
tech_fluff_string = "<span class='holoparasite'>Boot sequence complete. Ranged combat modules active. Holoparasite swarm online.</span>"
carp_fluff_string = "<span class='holoparasite'>CARP CARP CARP! Caught one, it's a ranged carp. This fishy can watch people pee in the ocean.</span>"
@@ -36,7 +35,7 @@
obj_damage = initial(obj_damage)
environment_smash = initial(environment_smash)
alpha = 255
range = initial(range)
range = 13
to_chat(src, "<span class='danger'><B>You switch to combat mode.</span></B>")
toggle = FALSE
else
@@ -3,9 +3,9 @@
melee_damage_lower = 20
melee_damage_upper = 20
obj_damage = 80
next_move_modifier = 0.8 //attacks 20% faster
next_move_modifier = 0.5 //attacks 50% faster
environment_smash = ENVIRONMENT_SMASH_WALLS
playstyle_string = "<span class='holoparasite'>As a <b>standard</b> type you have no special abilities, but have a high damage resistance and a powerful attack capable of smashing through walls.</span>"
playstyle_string = "<span class='holoparasite'>As a <b>standard</b> type you have no special abilities, but take half damage and have powerful attack capable of smashing through walls.</span>"
magic_fluff_string = "<span class='holoparasite'>..And draw the Assistant, faceless and generic, but never to be underestimated.</span>"
tech_fluff_string = "<span class='holoparasite'>Boot sequence complete. Standard combat modules loaded. Holoparasite swarm online.</span>"
carp_fluff_string = "<span class='holoparasite'>CARP CARP CARP! You caught one! It's really boring and standard. Better punch some walls to ease the tension.</span>"
@@ -2,11 +2,8 @@
/mob/living/simple_animal/hostile/guardian/healer
a_intent = INTENT_HARM
friendly = "heals"
speed = 0
damage_coeff = list(BRUTE = 0.7, BURN = 0.7, TOX = 0.7, CLONE = 0.7, STAMINA = 0, OXY = 0.7)
melee_damage_lower = 15
melee_damage_upper = 15
playstyle_string = "<span class='holoparasite'>As a <b>support</b> type, you may toggle your basic attacks to a healing mode. In addition, Alt-Clicking on an adjacent object or mob will warp them to your bluespace beacon after a short delay.</span>"
playstyle_string = "<span class='holoparasite'>As a <b>support</b> type, you have 30% damage reduction and may toggle your basic attacks to a healing mode. In addition, Alt-Clicking on an adjacent object or mob will warp them to your bluespace beacon after a short delay.</span>"
magic_fluff_string = "<span class='holoparasite'>..And draw the CMO, a potent force of life... and death.</span>"
carp_fluff_string = "<span class='holoparasite'>CARP CARP CARP! You caught a support carp. It's a kleptocarp!</span>"
tech_fluff_string = "<span class='holoparasite'>Boot sequence complete. Support modules active. Holoparasite swarm online.</span>"
@@ -118,11 +118,11 @@
switch(fail_tick)
if(0 to 200)
fail_tick += (2*(fail_chance))
M.rad_act(40)
M.rad_act(400)
to_chat(M, "<span class='userdanger'>Your [name] feels warmer.</span>")
if(201 to INFINITY)
SSobj.processing.Remove(src)
M.rad_act(80)
M.rad_act(800)
crit_fail = 1
to_chat(M, "<span class='userdanger'>Your [name]'s reactor overloads!</span>")
+33 -19
View File
@@ -1,4 +1,4 @@
#define CHEMICAL_QUANTISATION_LEVEL 0.0001
#define CHEMICAL_QUANTISATION_LEVEL 0.001
/proc/build_chemical_reagent_list()
//Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id
@@ -466,7 +466,7 @@
if (C.FermiChem == TRUE && !continue_reacting)
if (chem_temp > C.ExplodeTemp) //This is first to ensure explosions.
var/datum/chemical_reaction/fermi/Ferm = selected_reaction
var/datum/chemical_reaction/Ferm = selected_reaction
fermiIsReacting = FALSE
SSblackbox.record_feedback("tally", "fermi_chem", 1, ("[Ferm] explosion"))
Ferm.FermiExplode(src, my_atom, volume = total_volume, temp = chem_temp, pH = pH)
@@ -496,7 +496,12 @@
//Standard reaction mechanics:
else
if (C.FermiChem == TRUE)//Just to make sure
if (C.FermiChem == TRUE)//Just to make sure, should only proc when grenades are combining.
if (chem_temp > C.ExplodeTemp) //To allow fermigrenades
var/datum/chemical_reaction/fermi/Ferm = selected_reaction
fermiIsReacting = FALSE
SSblackbox.record_feedback("tally", "fermi_chem", 1, ("[Ferm] explosion"))
Ferm.FermiExplode(src, my_atom, volume = total_volume, temp = chem_temp, pH = pH)
return 0
for(var/B in cached_required_reagents) //
@@ -539,7 +544,7 @@
return 0
/datum/reagents/process()
var/datum/chemical_reaction/fermi/C = fermiReactID
var/datum/chemical_reaction/C = fermiReactID
var/list/cached_required_reagents = C.required_reagents//update reagents list
var/list/cached_results = C.results//resultant chemical list
@@ -575,16 +580,16 @@
return
/datum/reagents/proc/fermiEnd()
var/datum/chemical_reaction/fermi/C = fermiReactID
var/datum/chemical_reaction/C = fermiReactID
STOP_PROCESSING(SSprocessing, src)
fermiIsReacting = FALSE
reactedVol = 0
targetVol = 0
//pH check, handled at the end to reduce calls.
if(istype(my_atom, /obj/item/reagent_containers))
var/obj/item/reagent_containers/RC = my_atom
RC.pH_check()
C.FermiFinish(src, my_atom)
C.FermiFinish(src, my_atom, reactedVol)
reactedVol = 0
targetVol = 0
handle_reactions()
update_total()
//Reaction sounds and words
@@ -595,7 +600,7 @@
to_chat(M, "<span class='notice'>[iconhtml] [C.mix_message]</span>")
/datum/reagents/proc/fermiReact(selected_reaction, cached_temp, cached_pH, reactedVol, targetVol, cached_required_reagents, cached_results, multiplier)
var/datum/chemical_reaction/fermi/C = selected_reaction
var/datum/chemical_reaction/C = selected_reaction
var/deltaT = 0
var/deltapH = 0
var/stepChemAmmount = 0
@@ -704,7 +709,7 @@
return (reactedVol)
//Currently calculates it irrespective of required reagents at the start
/datum/reagents/proc/reactant_purity(var/datum/chemical_reaction/fermi/C, holder)
/datum/reagents/proc/reactant_purity(var/datum/chemical_reaction/C, holder)
var/list/cached_reagents = reagent_list
var/i = 0
var/cachedPurity
@@ -714,6 +719,14 @@
i++
return cachedPurity/i
/datum/reagents/proc/uncache_purity(id)
var/datum/reagent/R = has_reagent("[id]")
if(!R)
return
if(R.cached_purity == 1)
return
R.purity = R.cached_purity
/datum/reagents/proc/isolate_reagent(reagent)
var/list/cached_reagents = reagent_list
for(var/_reagent in cached_reagents)
@@ -745,11 +758,14 @@
total_volume = 0
for(var/reagent in cached_reagents)
var/datum/reagent/R = reagent
if(R.volume < CHEMICAL_QUANTISATION_LEVEL)
if(R.volume == 0)
del_reagent(R.id)
if((R.volume < 0.01) && !fermiIsReacting)
del_reagent(R.id)
else
total_volume += R.volume
if(!reagent_list)
pH = 7
return 0
/datum/reagents/proc/clear_reagents()
@@ -878,17 +894,15 @@
var/datum/reagent/R = A
if (R.id == reagent) //IF MERGING
//Add amount and equalize purity
R.volume += amount
R.volume += round(amount, CHEMICAL_QUANTISATION_LEVEL)
R.purity = ((R.purity * R.volume) + (other_purity * amount)) /((R.volume + amount)) //This should add the purity to the product
update_total()
if(my_atom)
my_atom.on_reagent_change(ADD_REAGENT)
if(isliving(my_atom))
if(R.OnMobMergeCheck == TRUE)//Forces on_mob_add proc when a chem is merged
if(R.chemical_flags & REAGENT_ONMOBMERGE)//Forces on_mob_add proc when a chem is merged
R.on_mob_add(my_atom, amount)
//else
// R.on_merge(data, amount, my_atom, other_purity)
R.on_merge(data, amount, my_atom, other_purity)
if(!no_react)
handle_reactions()
@@ -900,13 +914,13 @@
var/datum/reagent/R = new D.type(data)
cached_reagents += R
R.holder = src
R.volume = amount
R.volume = round(amount, CHEMICAL_QUANTISATION_LEVEL)
R.purity = other_purity
R.loc = get_turf(my_atom)
if(data)
R.data = data
R.on_new(data)
if(R.addProc == TRUE)//Allows on new without data overhead.
if(R.chemical_flags & REAGENT_FORCEONNEW)//Allows on new without data overhead.
R.on_new(pH) //Add more as desired.
@@ -1134,4 +1148,4 @@
if(initial(R.can_synth))
random_reagents += initial(R.id)
var/picked_reagent = pick(random_reagents)
return picked_reagent
return picked_reagent
@@ -79,6 +79,15 @@
return
return ..()
if(beaker)
if(istype(I, /obj/item/reagent_containers/dropper))
var/obj/item/reagent_containers/dropper/D = I
D.afterattack(beaker, user, 1)
if(istype(I, /obj/item/reagent_containers/syringe))
var/obj/item/reagent_containers/syringe/S = I
S.afterattack(beaker, user, 1)
/obj/machinery/chem_heater/on_deconstruction()
replace_beaker()
return ..()
@@ -233,6 +233,12 @@
else
reagents.remove_reagent(id, amount)
. = TRUE
else if (amount == -1) // -1 means custom amount
useramount = input("Enter the Amount you want to transfer:", name, useramount) as num|null
if (useramount > 0)
end_fermi_reaction()
reagents.trans_id_to(beaker, id, useramount)
. = TRUE
if("toggleMode")
mode = !mode
@@ -332,7 +338,7 @@
var/vol_part = min(reagents.total_volume, 30)
if(text2num(many))
amount_full = round(reagents.total_volume / 30)
vol_part = reagents.total_volume % 30
vol_part = ((reagents.total_volume*1000) % 30000) / 1000 //% operator doesn't support decimals.
var/name = stripped_input(usr, "Name:","Name your bottle!", (reagents.total_volume ? reagents.get_master_reagent_name() : " "), MAX_NAME_LEN)
if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr)))
return
@@ -379,7 +385,34 @@
reagents.trans_to(P, vol_part)
. = TRUE
//END CITADEL ADDITIONS
if("analyze")
if("analyzeBeak")
var/datum/reagent/R = GLOB.chemical_reagents_list[params["id"]]
if(R)
var/state = "Unknown"
if(initial(R.reagent_state) == 1)
state = "Solid"
else if(initial(R.reagent_state) == 2)
state = "Liquid"
else if(initial(R.reagent_state) == 3)
state = "Gas"
var/const/P = 3 //The number of seconds between life ticks
var/T = initial(R.metabolization_rate) * (60 / P)
var/datum/chemical_reaction/Rcr = get_chemical_reaction(R.id)
if(Rcr && Rcr.FermiChem)
fermianalyze = TRUE
var/pHpeakCache = (Rcr.OptimalpHMin + Rcr.OptimalpHMax)/2
var/datum/reagent/targetReagent = beaker.reagents.has_reagent("[R.id]")
if(!targetReagent)
CRASH("Tried to find a reagent that doesn't exist in the chem_master!")
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold), "purityF" = targetReagent.purity, "inverseRatioF" = initial(R.inverse_chem_val), "purityE" = initial(Rcr.PurityMin), "minTemp" = initial(Rcr.OptimalTempMin), "maxTemp" = initial(Rcr.OptimalTempMax), "eTemp" = initial(Rcr.ExplodeTemp), "pHpeak" = pHpeakCache)
else
fermianalyze = FALSE
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold))
screen = "analyze"
return
if("analyzeBuff")
var/datum/reagent/R = GLOB.chemical_reagents_list[params["id"]]
if(R)
var/state = "Unknown"
@@ -395,7 +428,11 @@
fermianalyze = TRUE
var/datum/chemical_reaction/Rcr = get_chemical_reaction(R.id)
var/pHpeakCache = (Rcr.OptimalpHMin + Rcr.OptimalpHMax)/2
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold), "purityF" = initial(R.purity), "inverseRatioF" = initial(R.InverseChemVal), "purityE" = initial(Rcr.PurityMin), "minTemp" = initial(Rcr.OptimalTempMin), "maxTemp" = initial(Rcr.OptimalTempMax), "eTemp" = initial(Rcr.ExplodeTemp), "pHpeak" = pHpeakCache)
var/datum/reagent/targetReagent = reagents.has_reagent("[R.id]")
if(!targetReagent)
CRASH("Tried to find a reagent that doesn't exist in the chem_master!")
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold), "purityF" = targetReagent.purity, "inverseRatioF" = initial(R.inverse_chem_val), "purityE" = initial(Rcr.PurityMin), "minTemp" = initial(Rcr.OptimalTempMin), "maxTemp" = initial(Rcr.OptimalTempMax), "eTemp" = initial(Rcr.ExplodeTemp), "pHpeak" = pHpeakCache)
else
fermianalyze = FALSE
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold))
@@ -451,4 +488,4 @@
condi = TRUE
#undef PILL_STYLE_COUNT
#undef RANDOM_PILL_STYLE
#undef RANDOM_PILL_STYLE
+79 -12
View File
@@ -32,19 +32,19 @@
var/addiction_stage3_end = 30
var/addiction_stage4_end = 40
var/overdosed = 0 // You fucked up and this is now triggering its overdose effects, purge that shit quick.
var/self_consuming = FALSE
var/self_consuming = FALSE //I think this uhhh, makes weird stuff happen when metabolising, but... doesn't seem to do what I think, so I'm gonna leave it.
//Fermichem vars:
var/purity = 1 //How pure a chemical is from 0 - 1.
var/addProc = FALSE //If the chemical should force an on_new() call
var/purity = 1 //How pure a chemical is from 0 - 1.
var/cached_purity = 1
var/turf/loc = null //Should be the creation location!
var/pH = 7 //pH of the specific reagent, used for calculating the sum pH of a holder.
var/ImpureChem = "fermiTox"// What chemical is metabolised with an inpure reaction
var/InverseChemVal = 0.25 // If the impurity is below 0.5, replace ALL of the chem with InverseChem upon metabolising
var/InverseChem = "fermiTox"// What chem is metabolised when purity is below InverseChemVal, this shouldn't be made, but if it does, well, I guess I'll know about it.
var/DoNotSplit = FALSE // If impurity is handled within the main chem itself
var/OnMobMergeCheck = FALSE //Call on_mob_life proc when reagents are merging.
//var/SplitChem = FALSE //If the chem splits on metabolism
var/impure_chem // What chemical is metabolised with an inpure reaction
var/inverse_chem_val = 0 // If the impurity is below 0.5, replace ALL of the chem with inverse_chemupon metabolising
var/inverse_chem // What chem is metabolised when purity is below inverse_chem_val, this shouldn't be made, but if it does, well, I guess I'll know about it.
var/metabolizing = FALSE
var/invisible = FALSE //Set to true if it doesn't appear on handheld health analyzers.
var/chemical_flags // See fermi/readme.dm REAGENT_DEAD_PROCESS, REAGENT_DONOTSPLIT, REAGENT_ONLYINVERSE, REAGENT_ONMOBMERGE, REAGENT_INVISIBLE, REAGENT_FORCEONNEW, REAGENT_SNEAKYNAME
/datum/reagent/Destroy() // This should only be called by the holder, so it's already handled clearing its references
. = ..()
@@ -73,8 +73,47 @@
holder.remove_reagent(src.id, metabolization_rate * M.metabolism_efficiency) //By default it slowly disappears.
return
//called when a mob processes chems when dead.
/datum/reagent/proc/on_mob_dead(mob/living/carbon/M)
if(!(chemical_flags & REAGENT_DEAD_PROCESS)) //justincase
return
current_cycle++
if(holder)
holder.remove_reagent(src.id, metabolization_rate * M.metabolism_efficiency) //By default it slowly disappears.
return
// Called when this reagent is first added to a mob
/datum/reagent/proc/on_mob_add(mob/living/L)
/datum/reagent/proc/on_mob_add(mob/living/L, amount)
if(!iscarbon(L))
return
var/mob/living/carbon/M = L
if (purity == 1)
log_game("CHEM: [L] ckey: [L.key] has ingested [volume]u of [id]")
return
if(cached_purity == 1)
cached_purity = purity
else if(purity < 0)
CRASH("Purity below 0 for chem: [id], Please let Fermis Know!")
if(chemical_flags & REAGENT_DONOTSPLIT)
return
if ((inverse_chem_val > purity) && (inverse_chem))//Turns all of a added reagent into the inverse chem
M.reagents.remove_reagent(id, amount, FALSE)
M.reagents.add_reagent(inverse_chem, amount, FALSE, other_purity = 1-cached_purity)
var/datum/reagent/R = M.reagents.has_reagent("[inverse_chem]")
if(R.chemical_flags & REAGENT_SNEAKYNAME)
R.name = name//Negative effects are hidden
if(R.chemical_flags & REAGENT_INVISIBLE)
R.chemical_flags |= (REAGENT_INVISIBLE)
log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume]u of [inverse_chem]")
return
else if (impure_chem)
var/impureVol = amount * (1 - purity) //turns impure ratio into impure chem
if(!(chemical_flags & REAGENT_SPLITRETAINVOL))
M.reagents.remove_reagent(id, (impureVol), FALSE)
M.reagents.add_reagent(impure_chem, impureVol, FALSE, other_purity = 1-cached_purity)
log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume - impureVol]u of [id]")
log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume]u of [impure_chem]")
return
// Called when this reagent is removed while inside a mob
@@ -97,7 +136,35 @@
return
// Called when two reagents of the same are mixing.
/datum/reagent/proc/on_merge(data)
/datum/reagent/proc/on_merge(data, amount, mob/living/carbon/M, purity)
if(!iscarbon(M))
return
if (purity == 1)
log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume]u of [id]")
return
cached_purity = purity //purity SHOULD be precalculated from the add_reagent, update cache.
if (purity < 0)
CRASH("Purity below 0 for chem: [id], Please let Fermis Know!")
if(chemical_flags & REAGENT_DONOTSPLIT)
return
if ((inverse_chem_val > purity) && (inverse_chem)) //INVERT
M.reagents.remove_reagent(id, amount, FALSE)
M.reagents.add_reagent(inverse_chem, amount, FALSE, other_purity = 1-cached_purity)
var/datum/reagent/R = M.reagents.has_reagent("[inverse_chem]")
if(R.chemical_flags & REAGENT_SNEAKYNAME)
R.name = name//Negative effects are hidden
if(R.chemical_flags & REAGENT_INVISIBLE)
R.chemical_flags |= (REAGENT_INVISIBLE)
log_game("FERMICHEM: [M] ckey: [M.key] has merged [volume]u of [inverse_chem]")
return
else if (impure_chem) //SPLIT
var/impureVol = amount * (1 - purity)
if(!(chemical_flags & REAGENT_SPLITRETAINVOL))
M.reagents.remove_reagent(id, impureVol, FALSE)
M.reagents.add_reagent(impure_chem, impureVol, FALSE, other_purity = 1-cached_purity)
log_game("FERMICHEM: [M] ckey: [M.key] has merged [volume - impureVol]u of [id]")
log_game("FERMICHEM: [M] ckey: [M.key] has merged [volume]u of [impure_chem]")
return
/datum/reagent/proc/on_update(atom/A)
@@ -146,4 +213,4 @@
for (var/datum/reagent/R in reagent_list)
rs += "[R.name], [R.volume]"
return rs.Join(" | ")
return rs.Join(" | ")
@@ -1384,6 +1384,10 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_name = "Neurotoxin"
glass_desc = "A drink that is guaranteed to knock you silly."
pH = 4.3
//SplitChem = TRUE
impure_chem = "neuroweak"
inverse_chem_val = 0.5 //Clear conversion
inverse_chem = "neuroweak"
/datum/reagent/consumable/ethanol/neurotoxin/proc/pickt()
return (pick(TRAIT_PARALYSIS_L_ARM,TRAIT_PARALYSIS_R_ARM,TRAIT_PARALYSIS_R_LEG,TRAIT_PARALYSIS_L_LEG))
@@ -0,0 +1,26 @@
//Reagents produced by metabolising/reacting fermichems inoptimally, i.e. inverse_chems or impure_chems
//Inverse = Splitting
//Invert = Whole conversion
/datum/reagent/impure
chemical_flags = REAGENT_INVISIBLE | REAGENT_SNEAKYNAME //by default, it will stay hidden on splitting, but take the name of the source on inverting
/datum/reagent/impure/fermiTox
name = "Chemical Isomers"
id = "fermiTox"
description = "Toxic chemical isomers made from impure reactions. At low volumes will cause light toxin damage, but as the volume increases, it deals larger amounts, damages the liver, then eventually the heart."
data = "merge"
color = "FFFFFF"
can_synth = FALSE
var/potency = 1 //potency multiplies the volume when added.
//I'm concerned this is too weak, but I also don't want deathmixes.
//TODO: liver damage, 100+ heart
/datum/reagent/impure/fermiTox/on_mob_life(mob/living/carbon/C, method)
if(C.dna && istype(C.dna.species, /datum/species/jelly))
C.adjustToxLoss(-2)
else
C.adjustToxLoss(2)
..()
@@ -1587,7 +1587,7 @@
color = "#ffa6ff" //rgb: 255,166,255
taste_description = "a bad idea"
id = "laughtervirusfood"
/datum/reagent/consumable/virus_food/advvirusfood
name = "highly unstable virus food"
color = "#ffffff" //rgb: 255,255,255 ITS PURE WHITE CMON
@@ -2151,7 +2151,7 @@
can_synth = FALSE
var/datum/dna/original_dna
var/reagent_ticks = 0
invisible = TRUE
chemical_flags = REAGENT_INVISIBLE
/datum/reagent/changeling_string/on_mob_metabolize(mob/living/carbon/C)
if(C && C.dna && data["desired_dna"])
@@ -32,6 +32,7 @@
var/RateUpLim = 10 // Optimal/max rate possible if all conditions are perfect
var/FermiChem = FALSE // If the chemical uses the Fermichem reaction mechanics//If the chemical uses the Fermichem reaction mechanics
var/FermiExplode = FALSE // If the chemical explodes in a special way
var/clear_conversion //bitflags for clear conversions; REACTION_CLEAR_IMPURE or REACTION_CLEAR_INVERSE
var/PurityMin = 0.15 //If purity is below 0.15, it explodes too. Set to 0 to disable this.
+64 -22
View File
@@ -17,6 +17,7 @@
var/spillable = FALSE
var/beaker_weakness_bitflag = NONE//Bitflag!
var/container_HP = 2
var/cached_icon
var/splashable = FALSE
/obj/item/reagent_containers/Initialize(mapload, vol)
@@ -149,30 +150,71 @@
/obj/item/reagent_containers/proc/temp_check()
if(beaker_weakness_bitflag & TEMP_WEAK)
if(reagents.chem_temp >= 444)//assuming polypropylene
var/list/seen = viewers(5, get_turf(src))
var/iconhtml = icon2html(src, seen)
for(var/mob/M in seen)
to_chat(M, "<span class='notice'>[iconhtml] \The [src]'s melts from the temperature!</span>")
playsound(get_turf(src), 'sound/FermiChem/heatmelt.ogg', 80, 1)
to_chat(M, "<span class='warning'><i>[iconhtml] Have you tried using glass or meta beakers for high temperature reactions? These are immune to temperature effects.</i></span>")
SSblackbox.record_feedback("tally", "fermi_chem", 1, "Times beakers have melted from temperature")
qdel(src)
START_PROCESSING(SSobj, src)
//melts glass beakers
/obj/item/reagent_containers/proc/pH_check()
if(beaker_weakness_bitflag & PH_WEAK)
if((reagents.pH < 0.5) || (reagents.pH > 13.5))
var/list/seen = viewers(5, get_turf(src))
var/iconhtml = icon2html(src, seen)
container_HP--
if(container_HP <= 0)
for(var/mob/M in seen)
to_chat(M, "<span class='notice'>[iconhtml] \The [src]'s melts from the extreme pH!</span>")
playsound(get_turf(src), 'sound/FermiChem/acidmelt.ogg', 80, 1)
SSblackbox.record_feedback("tally", "fermi_chem", 1, "Times beakers have melted from pH")
qdel(src)
if((reagents.pH < 1.5) || (reagents.pH > 12.5))
START_PROCESSING(SSobj, src)
/obj/item/reagent_containers/process()
if(!cached_icon)
cached_icon = icon_state
var/damage
var/cause
if(beaker_weakness_bitflag & PH_WEAK)
if(reagents.pH < 2)
damage = (2 - reagents.pH)/20
cause = "from the extreme pH"
playsound(get_turf(src), 'sound/FermiChem/bufferadd.ogg', 50, 1)
if(reagents.pH > 12)
damage = (reagents.pH - 12)/20
cause = "from the extreme pH"
playsound(get_turf(src), 'sound/FermiChem/bufferadd.ogg', 50, 1)
if(beaker_weakness_bitflag & TEMP_WEAK)
if(reagents.chem_temp >= 444)
if(damage)
damage += (reagents.chem_temp/444)/5
else
for(var/mob/M in seen)
to_chat(M, "<span class='notice'>[iconhtml] \The [src]'s is damaged by the extreme pH and begins to deform!</span>")
playsound(get_turf(src), 'sound/FermiChem/bufferadd.ogg', 50, 1)
to_chat(M, "<span class='warning'><i>[iconhtml] Have you tried using plastic beakers (XL) or metabeakers for high pH reactions? These beakers are immune to pH effects.</i></span>")
damage = (reagents.chem_temp/444)/5
if(cause)
cause += " and "
cause += "from the high temperature"
playsound(get_turf(src), 'sound/FermiChem/heatdam.ogg', 50, 1)
if(!damage || damage <= 0)
STOP_PROCESSING(SSobj, src)
container_HP -= damage
var/list/seen = viewers(5, get_turf(src))
var/iconhtml = icon2html(src, seen)
var/damage_percent = ((container_HP / initial(container_HP)*100))
switch(damage_percent)
if(-INFINITY to 0)
for(var/mob/M in seen)
to_chat(M, "<span class='notice'>[iconhtml] \The [src]'s melts [cause]!</span>")
playsound(get_turf(src), 'sound/FermiChem/acidmelt.ogg', 80, 1)
SSblackbox.record_feedback("tally", "fermi_chem", 1, "Times beakers have melted")
STOP_PROCESSING(SSobj, src)
qdel(src)
return
if(0 to 35)
icon_state = "[cached_icon]_m3"
desc = "[initial(desc)] It is severely deformed."
if(35 to 70)
icon_state = "[cached_icon]_m2"
desc = "[initial(desc)] It is deformed."
if(70 to 85)
desc = "[initial(desc)] It is mildly deformed."
icon_state = "[cached_icon]_m1"
update_icon()
if(prob(25))
for(var/mob/M in seen)
to_chat(M, "<span class='notice'>[iconhtml] \The [src]'s is damaged by [cause] and begins to deform!</span>")
@@ -90,3 +90,9 @@
update_pack_name()
else
return ..()
/obj/item/reagent_containers/blood/bluespace
name = "bluespace blood pack"
desc = "Contains blood used for transfusion, this one has been made with bluespace technology to hold much more blood. Must be attached to an IV drip."
icon_state = "bsbloodpack"
volume = 600 //its a blood bath!
@@ -6,7 +6,7 @@
reagent_flags = OPENCONTAINER
spillable = TRUE
resistance_flags = ACID_PROOF
container_HP = 3
container_HP = 2
/obj/item/reagent_containers/glass/attack(mob/M, mob/user, obj/target)
@@ -115,7 +115,6 @@
item_state = "beaker"
materials = list(MAT_GLASS=500)
beaker_weakness_bitflag = PH_WEAK
container_HP = 5
/obj/item/reagent_containers/glass/beaker/Initialize()
. = ..()
@@ -126,34 +125,36 @@
/obj/item/reagent_containers/glass/beaker/on_reagent_change(changetype)
update_icon()
/obj/item/reagent_containers/glass/bottle/viralbase
name = "Highly potent Viral Base Bottle"
desc = "A small bottle. Contains a trace amount of a substance found by scientists that can be used to create extremely advanced diseases once exposed to uranium."
list_reagents = list("viralbase" = 1)
/obj/item/reagent_containers/glass/beaker/update_icon()
if(!cached_icon)
cached_icon = icon_state
cut_overlays()
if(reagents.total_volume)
var/mutable_appearance/filling = mutable_appearance('icons/obj/reagentfillings.dmi', "[icon_state]10")
var/mutable_appearance/filling = mutable_appearance('icons/obj/reagentfillings.dmi', "[cached_icon]10")
var/percent = round((reagents.total_volume / volume) * 100)
switch(percent)
if(0 to 9)
filling.icon_state = "[icon_state]-10"
filling.icon_state = "[cached_icon]-10"
if(10 to 24)
filling.icon_state = "[icon_state]10"
filling.icon_state = "[cached_icon]10"
if(25 to 49)
filling.icon_state = "[icon_state]25"
filling.icon_state = "[cached_icon]25"
if(50 to 74)
filling.icon_state = "[icon_state]50"
filling.icon_state = "[cached_icon]50"
if(75 to 79)
filling.icon_state = "[icon_state]75"
filling.icon_state = "[cached_icon]75"
if(80 to 90)
filling.icon_state = "[icon_state]80"
filling.icon_state = "[cached_icon]80"
if(91 to INFINITY)
filling.icon_state = "[icon_state]100"
filling.icon_state = "[cached_icon]100"
filling.color = mix_color_from_reagents(reagents.reagent_list)
add_overlay(filling)
@@ -172,7 +173,7 @@
volume = 100
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,50,100)
container_HP = 6
container_HP = 3
/obj/item/reagent_containers/glass/beaker/plastic
name = "x-large beaker"
@@ -232,7 +233,7 @@
volume = 300
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,50,100,300)
container_HP = 8
container_HP = 4
/obj/item/reagent_containers/glass/beaker/cryoxadone
list_reagents = list("cryoxadone" = 30)
@@ -289,7 +290,7 @@
SLOT_L_STORE, SLOT_R_STORE,\
SLOT_GENERC_DEXTROUS_STORAGE
)
container_HP = 2
container_HP = 1
/obj/item/reagent_containers/glass/bucket/Initialize()
beaker_weakness_bitflag |= TEMP_WEAK
@@ -343,7 +344,7 @@
materials = list(MAT_GLASS=0)
volume = 50
amount_per_transfer_from_this = 10
container_HP = 2
container_HP = 1
/obj/item/reagent_containers/glass/beaker/waterbottle/Initialize()
beaker_weakness_bitflag |= TEMP_WEAK
@@ -359,7 +360,7 @@
list_reagents = list("water" = 100)
volume = 100
amount_per_transfer_from_this = 20
container_HP = 2
container_HP = 1
/obj/item/reagent_containers/glass/beaker/waterbottle/large/empty
list_reagents = list()
@@ -738,6 +738,13 @@
research_icon_state = "surgery_any"
var/surgery
/datum/design/surgery/experimental_dissection
name = "Experimental Dissection"
desc = "A surgical procedure which deeply analyzes the biology of a corpse, and automatically adds new findings to the research database."
id = "surgery_exp_dissection"
surgery = /datum/surgery/advanced/bioware/experimental_dissection
research_icon_state = "surgery_chest"
/datum/design/surgery/lobotomy
name = "Lobotomy"
desc = "An invasive surgical procedure which guarantees removal of almost all brain traumas, but might cause another permanent trauma in return."
@@ -808,6 +815,22 @@
surgery = /datum/surgery/advanced/bioware/vein_threading
research_icon_state = "surgery_chest"
/datum/design/surgery/ligament_hook
name = "Ligament Hook"
desc = "A surgical procedure which reshapes the connections between torso and limbs, making it so limbs can be attached manually if severed. \
However this weakens the connection, making them easier to detach as well."
id = "surgery_ligament_hook"
surgery = /datum/surgery/advanced/bioware/ligament_hook
research_icon_state = "surgery_chest"
/datum/design/surgery/ligament_reinforcement
name = "Ligament Reinforcement"
desc = "A surgical procedure which adds a protective tissue and bone cage around the connections between the torso and limbs, preventing dismemberment. \
However, the nerve connections as a result are more easily interrupted, making it easier to disable limbs with damage."
id = "surgery_ligament_reinforcement"
surgery = /datum/surgery/advanced/bioware/ligament_reinforcement
research_icon_state = "surgery_chest"
/datum/design/surgery/necrotic_revival
name = "Necrotic Revival"
desc = "An experimental surgical procedure that stimulates the growth of a Romerol tumor inside the patient's brain. Requires zombie powder or rezadone."
@@ -907,7 +930,15 @@
category = list("Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
/datum/design/bsblood_bag
name = "Blue Space Empty Blood Bag"
desc = "A large sterilized plastic bag for blood."
id = "bsblood_bag"
build_path = /obj/item/reagent_containers/blood/bluespace
build_type = PROTOLATHE
materials = list(MAT_GLASS = 2500, MAT_PLASTIC = 4500, MAT_BLUESPACE = 250)
category = list("Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
/datum/design/adv_dis_hypo
name = "Disposable Hypospray MK.II"
+6 -6
View File
@@ -116,7 +116,7 @@
display_name = "Advanced Surgery"
description = "When simple medicine doesn't cut it."
prereq_ids = list("adv_biotech")
design_ids = list("surgery_lobotomy", "surgery_reconstruction","surgery_toxinhealing", "organbox",)
design_ids = list("surgery_lobotomy", "surgery_reconstruction","surgery_toxinhealing", "organbox", "surgery_exp_dissection")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
@@ -125,7 +125,7 @@
display_name = "Experimental Surgery"
description = "When evolution isn't fast enough."
prereq_ids = list("adv_surgery")
design_ids = list("surgery_revival","surgery_pacify","surgery_vein_thread","surgery_nerve_splice","surgery_nerve_ground","surgery_viral_bond")
design_ids = list("surgery_revival","surgery_pacify","surgery_vein_thread","surgery_nerve_splice","surgery_ligament_hook","surgery_ligament_reinforcement","surgery_nerve_ground","surgery_viral_bond")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000)
export_price = 5000
@@ -273,7 +273,7 @@
display_name = "Bluespace Pockets"
description = "Studies into the mysterious alternate dimension known as bluespace and how to place items in the threads of reality."
prereq_ids = list("adv_power", "adv_bluespace", "adv_biotech", "adv_plasma")
design_ids = list( "bluespacebodybag","bag_holding", "bluespace_pod", "borg_upgrade_trashofholding", "blutrash", "satchel_holding")
design_ids = list( "bluespacebodybag","bag_holding", "bluespace_pod", "borg_upgrade_trashofholding", "blutrash", "satchel_holding", "bsblood_bag")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5500)
export_price = 5000
@@ -1017,7 +1017,7 @@
prereq_ids = list("biotech","engineering")
boost_item_paths = list(/obj/item/gun/energy/alien, /obj/item/scalpel/alien, /obj/item/hemostat/alien, /obj/item/retractor/alien, /obj/item/circular_saw/alien,
/obj/item/cautery/alien, /obj/item/surgicaldrill/alien, /obj/item/screwdriver/abductor, /obj/item/wrench/abductor, /obj/item/crowbar/abductor, /obj/item/multitool/abductor,
/obj/item/weldingtool/abductor, /obj/item/wirecutters/abductor, /obj/item/circuitboard/machine/abductor, /obj/item/abductor_baton, /obj/item/abductor, /obj/item/stack/sheet/mineral/abductor)
/obj/item/weldingtool/abductor, /obj/item/wirecutters/abductor, /obj/item/circuitboard/machine/abductor, /obj/item/abductor_baton, /obj/item/abductor, /obj/item/stack/sheet/mineral/abductor, /obj/item/stock_parts/cell/infinite/abductor)
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000)
export_price = 20000
hidden = TRUE
@@ -1031,7 +1031,7 @@
design_ids = list("alien_scalpel", "alien_hemostat", "alien_retractor", "alien_saw", "alien_drill", "alien_cautery")
boost_item_paths = list(/obj/item/gun/energy/alien, /obj/item/scalpel/alien, /obj/item/hemostat/alien, /obj/item/retractor/alien, /obj/item/circular_saw/alien,
/obj/item/cautery/alien, /obj/item/surgicaldrill/alien, /obj/item/screwdriver/abductor, /obj/item/wrench/abductor, /obj/item/crowbar/abductor, /obj/item/multitool/abductor,
/obj/item/weldingtool/abductor, /obj/item/wirecutters/abductor, /obj/item/circuitboard/machine/abductor, /obj/item/abductor_baton, /obj/item/abductor)
/obj/item/weldingtool/abductor, /obj/item/wirecutters/abductor, /obj/item/circuitboard/machine/abductor, /obj/item/abductor_baton, /obj/item/abductor, /obj/item/stock_parts/cell/infinite/abductor)
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 20000
hidden = TRUE
@@ -1043,7 +1043,7 @@
prereq_ids = list("alientech", "adv_engi")
design_ids = list("alien_wrench", "alien_wirecutters", "alien_screwdriver", "alien_crowbar", "alien_welder", "alien_multitool")
boost_item_paths = list(/obj/item/screwdriver/abductor, /obj/item/wrench/abductor, /obj/item/crowbar/abductor, /obj/item/multitool/abductor,
/obj/item/weldingtool/abductor, /obj/item/wirecutters/abductor, /obj/item/circuitboard/machine/abductor, /obj/item/abductor_baton, /obj/item/abductor)
/obj/item/weldingtool/abductor, /obj/item/wirecutters/abductor, /obj/item/circuitboard/machine/abductor, /obj/item/abductor_baton, /obj/item/abductor, /obj/item/stock_parts/cell/infinite/abductor)
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 20000
hidden = TRUE
@@ -27,9 +27,9 @@
return 0
charge_tick = 0
var/mob/living/M = loc
if(istype(M) && M.blood_volume >= 20)
if(istype(M) && M.blood_volume >= 5)
charges++
M.blood_volume -= 20
M.blood_volume -= 5
if(charges == 1)
recharge_newshot()
return 1
@@ -0,0 +1,72 @@
/datum/surgery/advanced/bioware/experimental_dissection
name = "Experimental Dissection"
desc = "A surgical procedure which deeply analyzes the biology of a corpse, and automatically adds new findings to the research database."
steps = list(/datum/surgery_step/incise,
/datum/surgery_step/retract_skin,
/datum/surgery_step/clamp_bleeders,
/datum/surgery_step/incise,
/datum/surgery_step/dissection,
/datum/surgery_step/close)
possible_locs = list(BODY_ZONE_CHEST)
bioware_target = BIOWARE_DISSECTION
/datum/surgery/advanced/bioware/experimental_dissection/can_start(mob/user, mob/living/carbon/target)
. = ..()
if(iscyborg(user))
return FALSE //robots cannot be creative
//(also this surgery shouldn't be consistently successful, and cyborgs have a 100% success rate on surgery)
if(target.stat != DEAD)
return FALSE
/datum/surgery_step/dissection
name = "dissection"
implements = list(/obj/item/scalpel = 60, /obj/item/kitchen/knife = 30, /obj/item/shard = 15)
time = 125
/datum/surgery_step/dissection/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
display_results(user, target, "<span class='notice'>You start dissecting [target].</span>",
"[user] starts dissecting [target].",
"[user] starts dissecting [target].")
/datum/surgery_step/dissection/proc/check_value(mob/living/carbon/target)
if(isalienroyal(target))
return 10000
else if(isalienadult(target))
return 5000
else if(ismonkey(target))
return 1000
else if(ishuman(target))
var/mob/living/carbon/human/H = target
if(H.dna && H.dna.species)
if(isabductor(H))
return 8000
if(isgolem(H) || iszombie(H))
return 4000
if(isjellyperson(H) || ispodperson(H))
return 3000
return 2000
/datum/surgery_step/dissection/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
display_results(user, target, "<span class='notice'>You dissect [target], and add your discoveries to the research database!</span>",
"[user] dissects [target], adding [user.p_their()] discoveries to the research database!",
"[user] dissects [target]!")
SSresearch.science_tech.add_point_list(list(TECHWEB_POINT_TYPE_GENERIC = check_value(target)))
var/obj/item/bodypart/L = target.get_bodypart(BODY_ZONE_CHEST)
target.apply_damage(80, BRUTE, L)
new /datum/bioware/dissected(target)
return TRUE
/datum/surgery_step/dissection/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
display_results(user, target, "<span class='notice'>You dissect [target], but do not find anything particularly interesting.</span>",
"[user] dissects [target], however it seems [user.p_they()] didn't find anything useful.",
"[user] dissects [target], but looks a little dissapointed.")
SSresearch.science_tech.add_point_list(list(TECHWEB_POINT_TYPE_GENERIC = (check_value(target) * 0.2)))
var/obj/item/bodypart/L = target.get_bodypart(BODY_ZONE_CHEST)
target.apply_damage(80, BRUTE, L)
new /datum/bioware/dissected(target)
return TRUE
/datum/bioware/dissected
name = "Dissected"
desc = "This body has been dissected and analyzed. It is no longer worth experimenting on."
mod_type = BIOWARE_DISSECTION
@@ -0,0 +1,45 @@
/datum/surgery/advanced/bioware/ligament_hook
name = "Ligament Hook"
desc = "A surgical procedure which reshapes the connections between torso and limbs, making it so limbs can be attached manually if severed. \
However this weakens the connection, making them easier to detach as well."
steps = list(/datum/surgery_step/incise,
/datum/surgery_step/retract_skin,
/datum/surgery_step/clamp_bleeders,
/datum/surgery_step/incise,
/datum/surgery_step/incise,
/datum/surgery_step/reshape_ligaments,
/datum/surgery_step/close)
possible_locs = list(BODY_ZONE_CHEST)
bioware_target = BIOWARE_LIGAMENTS
/datum/surgery_step/reshape_ligaments
name = "reshape ligaments"
accept_hand = TRUE
time = 125
/datum/surgery_step/reshape_ligaments/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
display_results(user, target, "<span class='notice'>You start reshaping [target]'s ligaments into a hook-like shape.</span>",
"[user] starts reshaping [target]'s ligaments into a hook-like shape.",
"[user] starts manipulating [target]'s ligaments.")
/datum/surgery_step/reshape_ligaments/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
display_results(user, target, "<span class='notice'>You finish reshaping [target]'s ligaments into a connective hook!</span>",
"[user] finishes reshaping [target]'s ligaments into a connective hook!",
"[user] finishes manipulating [target]'s ligaments!")
new /datum/bioware/hooked_ligaments(target)
return TRUE
/datum/bioware/hooked_ligaments
name = "Hooked Ligaments"
desc = "The ligaments and nerve endings that connect the torso to the limbs are formed into a hook-like shape, so limbs can be attached without requiring surgery, but are easier to sever."
mod_type = BIOWARE_LIGAMENTS
/datum/bioware/hooked_ligaments/on_gain()
..()
ADD_TRAIT(owner, TRAIT_LIMBATTACHMENT, "ligament_hook")
ADD_TRAIT(owner, TRAIT_EASYDISMEMBER, "ligament_hook")
/datum/bioware/hooked_ligaments/on_lose()
..()
REMOVE_TRAIT(owner, TRAIT_LIMBATTACHMENT, "ligament_hook")
REMOVE_TRAIT(owner, TRAIT_EASYDISMEMBER, "ligament_hook")
@@ -0,0 +1,45 @@
/datum/surgery/advanced/bioware/ligament_reinforcement
name = "Ligament Reinforcement"
desc = "A surgical procedure which adds a protective tissue and bone cage around the connections between the torso and limbs, preventing dismemberment. \
However, the nerve connections as a result are more easily interrupted, making it easier to disable limbs with damage."
steps = list(/datum/surgery_step/incise,
/datum/surgery_step/retract_skin,
/datum/surgery_step/clamp_bleeders,
/datum/surgery_step/incise,
/datum/surgery_step/incise,
/datum/surgery_step/reinforce_ligaments,
/datum/surgery_step/close)
possible_locs = list(BODY_ZONE_CHEST)
bioware_target = BIOWARE_LIGAMENTS
/datum/surgery_step/reinforce_ligaments
name = "reinforce ligaments"
accept_hand = TRUE
time = 125
/datum/surgery_step/reinforce_ligaments/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
display_results(user, target, "<span class='notice'>You start reinforcing [target]'s ligaments.</span>",
"[user] starts reinforcing [target]'s ligaments.",
"[user] starts manipulating [target]'s ligaments.")
/datum/surgery_step/reinforce_ligaments/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
display_results(user, target, "<span class='notice'>You finish reinforcing [target]'s ligaments!</span>",
"[user] finishes reinforcing [target]'s ligaments!",
"[user] finishes manipulating [target]'s ligaments!")
new /datum/bioware/reinforced_ligaments(target)
return TRUE
/datum/bioware/reinforced_ligaments
name = "Reinforced Ligaments"
desc = "The ligaments and nerve endings that connect the torso to the limbs are protected by a mix of bone and tissues, and are much harder to separate from the body, but are also easier to disable."
mod_type = BIOWARE_LIGAMENTS
/datum/bioware/reinforced_ligaments/on_gain()
..()
ADD_TRAIT(owner, TRAIT_NODISMEMBER, "reinforced_ligaments")
ADD_TRAIT(owner, TRAIT_EASYLIMBDISABLE, "reinforced_ligaments")
/datum/bioware/reinforced_ligaments/on_lose()
..()
REMOVE_TRAIT(owner, TRAIT_NODISMEMBER, "reinforced_ligaments")
REMOVE_TRAIT(owner, TRAIT_EASYLIMBDISABLE, "reinforced_ligaments")
+2 -2
View File
@@ -235,7 +235,7 @@
return BODYPART_DISABLED_PARALYSIS
if(can_dismember() && !HAS_TRAIT(owner, TRAIT_NODISMEMBER))
. = disabled //inertia, to avoid limbs healing 0.1 damage and being re-enabled
if((get_damage(TRUE) >= max_damage))
if((get_damage(TRUE) >= max_damage) || (HAS_TRAIT(owner, TRAIT_EASYLIMBDISABLE) && (get_damage(TRUE) >= (max_damage * 0.6)))) //Easy limb disable disables the limb at 40% health instead of 0%
return BODYPART_DISABLED_DAMAGE
if(disabled && (get_damage(TRUE) <= (max_damage * 0.5)))
return BODYPART_NOT_DISABLED
@@ -861,7 +861,7 @@
icon_state = "default_monkey_r_leg"
animal_origin = MONKEY_BODYPART
px_y = 4
/obj/item/bodypart/r_leg/monkey/teratoma
icon_state = "teratoma_r_leg"
animal_origin = TERATOMA_BODYPART