firebreath change + update to tg genetics + calc patch

This commit is contained in:
Seris02
2020-02-22 19:42:33 +08:00
parent b811194d85
commit 84d08fe122
22 changed files with 807 additions and 86 deletions

View File

@@ -12,6 +12,7 @@
#define MUTATE /datum/mutation/human/bad_dna
#define COUGH /datum/mutation/human/cough
#define DWARFISM /datum/mutation/human/dwarfism
#define GIGANTISM /datum/mutation/human/gigantism
#define CLOWNMUT /datum/mutation/human/clumsy
#define TOURETTES /datum/mutation/human/tourettes
#define DEAFMUT /datum/mutation/human/deaf
@@ -30,17 +31,28 @@
#define ELVIS /datum/mutation/human/elvis
#define RADIOACTIVE /datum/mutation/human/radioactive
#define GLOWY /datum/mutation/human/glow
#define ANTIGLOWY /datum/mutation/human/glow/anti
#define TELEPATHY /datum/mutation/human/telepathy
#define FIREBREATH /datum/mutation/human/firebreath
#define VOID /datum/mutation/human/void
#define TONGUESPIKE /datum/mutation/human/tongue_spike
#define TONGUESPIKECHEM /datum/mutation/human/tongue_spike/chem
#define STRONG /datum/mutation/human/strong
#define STIMMED /datum/mutation/human/stimmed
#define FIRESWEAT /datum/mutation/human/fire
#define THERMAL /datum/mutation/human/thermal
#define INSULATED /datum/mutation/human/insulated
#define SHOCKTOUCH /datum/mutation/human/shock
#define ANTENNA /datum/mutation/human/antenna
#define PARANOIA /datum/mutation/human/paranoia
#define MINDREAD /datum/mutation/human/mindreader
#define INSULATED /datum/mutation/human/insulated
#define SHOCKTOUCH /datum/mutation/human/shock
#define OLFACTION /datum/mutation/human/olfaction
#define ACIDFLESH /datum/mutation/human/acidflesh
#define BADBLINK /datum/mutation/human/badblink
#define SPASTIC /datum/mutation/human/spastic
#define GELADIKINESIS /datum/mutation/human/geladikinesis
#define CRYOKINESIS /datum/mutation/human/cryokinesis
#define SPIDER_WEB /datum/mutation/human/webbing
#define UI_CHANGED "ui changed"
#define UE_CHANGED "ue changed"

View File

@@ -34,7 +34,7 @@
/datum/mutation/human/firebreath/modify()
if(power)
var/obj/effect/proc_holder/spell/aimed/firebreath/S = power
S.strength = GET_MUTATION_POWER(src)
S.strength = 4 + GET_MUTATION_POWER(src)
/obj/effect/proc_holder/spell/aimed/firebreath
name = "Fire Breath"
@@ -43,13 +43,12 @@
charge_max = 1200
clothes_req = FALSE
range = 20
projectile_type = /obj/item/projectile/magic/aoe/fireball/firebreath
base_icon_state = "fireball"
action_icon_state = "fireball0"
sound = 'sound/magic/demon_dies.ogg' //horrifying lizard noises
active_msg = "You built up heat in your mouth."
deactive_msg = "You swallow the flame."
var/strength = 1
var/strength = 4
/obj/effect/proc_holder/spell/aimed/firebreath/before_cast(list/targets)
. = ..()
@@ -61,19 +60,46 @@
to_chat(C,"<span class='warning'>Something in front of your mouth caught fire!</span>")
return FALSE
/obj/effect/proc_holder/spell/aimed/firebreath/ready_projectile(obj/item/projectile/P, atom/target, mob/user, iteration)
if(!istype(P, /obj/item/projectile/magic/aoe/fireball))
return
var/obj/item/projectile/magic/aoe/fireball/F = P
F.exp_fire += strength
/obj/effect/proc_holder/spell/aimed/firebreath/cast(list/targets, mob/living/user)
var/turf/T = user.loc
if(!isturf(T))
return FALSE
firecone(T,user.dir,strength)
remove_ranged_ability()
charge_counter = 0
start_recharge()
on_deactivation(user)
/obj/item/projectile/magic/aoe/fireball/firebreath
name = "fire breath"
exp_heavy = 0
exp_light = 0
exp_flash = 0
exp_fire= 4
/proc/firecone(loc,dir,length)
var/addsides = FALSE
var/list/turf/recentturf = list(loc)
for (var/i = 0;i < length;i++)
var/list/turf/h = list()
for (var/turf/g in recentturf)
var/frontturf = get_step(g,dir)
if (addsides)
var/rightturf = get_step(frontturf,turn(dir,90))
var/leftturf = get_step(frontturf,turn(dir,270))
if (!(rightturf in h))
h += rightturf
if (!(leftturf in h))
h += leftturf
if (!(frontturf in h))
h += frontturf
for (var/turf/j in h)
if (j.blocks_air)
h -= j
continue
for (var/obj/o in j)
if (o.CanAtmosPass == ATMOS_PASS_PROC ? !o.CanAtmosPass(loc) : !o.CanAtmosPass)
h -= j
continue
for (var/turf/l in h)
new /obj/effect/hotspot(l)
l.hotspot_expose(700,50,1)
sleep(1)
recentturf = h
addsides = !addsides
/datum/mutation/human/void
name = "Void Magnet"
@@ -161,4 +187,318 @@
return ..()
else
to_chat(user,"<span class='warning'>The electricity doesn't seem to affect [target]...</span>")
return ..()
return ..()
/datum/mutation/human/olfaction
name = "Transcendent Olfaction"
desc = "Your sense of smell is comparable to that of a canine."
quality = POSITIVE
difficulty = 12
text_gain_indication = "<span class='notice'>Smells begin to make more sense...</span>"
text_lose_indication = "<span class='notice'>Your sense of smell goes back to normal.</span>"
power = /obj/effect/proc_holder/spell/targeted/olfaction
instability = 30
synchronizer_coeff = 1
var/reek = 200
/datum/mutation/human/olfaction/modify()
if(power)
var/obj/effect/proc_holder/spell/targeted/olfaction/S = power
S.sensitivity = GET_MUTATION_SYNCHRONIZER(src)
/obj/effect/proc_holder/spell/targeted/olfaction
name = "Remember the Scent"
desc = "Get a scent off of the item you're currently holding to track it. With an empty hand, you'll track the scent you've remembered."
charge_max = 100
clothes_req = FALSE
range = -1
include_user = TRUE
action_icon_state = "nose"
var/mob/living/carbon/tracking_target
var/list/mob/living/carbon/possible = list()
var/sensitivity = 1
/obj/effect/proc_holder/spell/targeted/olfaction/cast(list/targets, mob/living/user = usr)
//can we sniff? is there miasma in the air?
var/datum/gas_mixture/air = user.loc.return_air()
var/list/cached_gases = air.gases
if(cached_gases[/datum/gas/miasma])
user.adjust_disgust(sensitivity * 45)
to_chat(user, "<span class='warning'>With your overly sensitive nose, you get a whiff of stench and feel sick! Try moving to a cleaner area!</span>")
return
var/atom/sniffed = user.get_active_held_item()
if(sniffed)
var/old_target = tracking_target
possible = list()
var/list/prints = sniffed.fingerprints
for(var/mob/living/carbon/C in GLOB.carbon_list)
if(prints[md5(C.dna.uni_identity)])
possible |= C
if(!length(possible))
to_chat(user,"<span class='warning'>Despite your best efforts, there are no scents to be found on [sniffed]...</span>")
return
tracking_target = input(user, "Choose a scent to remember.", "Scent Tracking") as null|anything in sortNames(possible)
if(!tracking_target)
if(!old_target)
to_chat(user,"<span class='warning'>You decide against remembering any scents. Instead, you notice your own nose in your peripheral vision. This goes on to remind you of that one time you started breathing manually and couldn't stop. What an awful day that was.</span>")
return
tracking_target = old_target
on_the_trail(user)
return
to_chat(user,"<span class='notice'>You pick up the scent of [tracking_target]. The hunt begins.</span>")
on_the_trail(user)
return
if(!tracking_target)
to_chat(user,"<span class='warning'>You're not holding anything to smell, and you haven't smelled anything you can track. You smell your skin instead; it's kinda salty.</span>")
return
on_the_trail(user)
/obj/effect/proc_holder/spell/targeted/olfaction/proc/on_the_trail(mob/living/user)
if(!tracking_target)
to_chat(user,"<span class='warning'>You're not tracking a scent, but the game thought you were. Something's gone wrong! Report this as a bug.</span>")
return
if(tracking_target == user)
to_chat(user,"<span class='warning'>You smell out the trail to yourself. Yep, it's you.</span>")
return
if(usr.z < tracking_target.z)
to_chat(user,"<span class='warning'>The trail leads... way up above you? Huh. They must be really, really far away.</span>")
return
else if(usr.z > tracking_target.z)
to_chat(user,"<span class='warning'>The trail leads... way down below you? Huh. They must be really, really far away.</span>")
return
var/direction_text = "[dir2text(get_dir(usr, tracking_target))]"
if(direction_text)
to_chat(user,"<span class='notice'>You consider [tracking_target]'s scent. The trail leads <b>[direction_text].</b></span>")
/datum/mutation/human/self_amputation
name = "Autotomy"
desc = "Allows a creature to voluntary discard a random appendage."
quality = POSITIVE
text_gain_indication = "<span class='notice'>Your joints feel loose.</span>"
instability = 30
power = /obj/effect/proc_holder/spell/self/self_amputation
energy_coeff = 1
synchronizer_coeff = 1
/obj/effect/proc_holder/spell/self/self_amputation
name = "Drop a limb"
desc = "Concentrate to make a random limb pop right off your body."
clothes_req = FALSE
human_req = FALSE
charge_max = 100
action_icon_state = "autotomy"
/obj/effect/proc_holder/spell/self/self_amputation/cast(list/targets, mob/user = usr)
if(!iscarbon(user))
return
var/mob/living/carbon/C = user
if(HAS_TRAIT(C, TRAIT_NODISMEMBER))
return
var/list/parts = list()
for(var/X in C.bodyparts)
var/obj/item/bodypart/BP = X
if(BP.body_part != HEAD && BP.body_part != CHEST)
if(BP.dismemberable)
parts += BP
if(!parts.len)
to_chat(usr, "<span class='notice'>You can't shed any more limbs!</span>")
return
var/obj/item/bodypart/BP = pick(parts)
BP.dismember()
//spider webs
/datum/mutation/human/webbing
name = "Webbing Production"
desc = "Allows the user to lay webbing, and travel through it."
quality = POSITIVE
text_gain_indication = "<span class='notice'>Your skin feels webby.</span>"
instability = 15
power = /obj/effect/proc_holder/spell/self/lay_genetic_web
/obj/effect/proc_holder/spell/self/lay_genetic_web
name = "Lay Web"
desc = "Drops a web. Only you will be able to traverse your web easily, making it pretty good for keeping you safe."
clothes_req = FALSE
human_req = FALSE
charge_max = 4 SECONDS //the same time to lay a web
action_icon = 'icons/mob/actions/actions_genetic.dmi'
action_icon_state = "lay_web"
/obj/effect/proc_holder/spell/self/lay_genetic_web/cast_check(skipcharge = 0,mob/user = usr)
. = ..()
if(!isturf(user.loc))
to_chat(user, "<span class='warning'>You can't lay webs here!</span>")
return FALSE
var/turf/T = get_turf(user)
var/obj/structure/spider/stickyweb/genetic/W = locate() in T
if(W)
to_chat(user, "<span class='warning'>There's already a web here!</span>")
return FALSE
/obj/effect/proc_holder/spell/self/lay_genetic_web/cast(list/targets, mob/user = usr)
var/turf/T = get_turf(user)
user.visible_message("<span class='notice'>[user] begins to secrete a sticky substance.</span>","<span class='notice'>You begin to lay a web.</span>")
if(!do_after(user, 4 SECONDS, target = T))
to_chat(user, "<span class='warning'>Your web spinning was interrupted!</span>")
return
else
new /obj/structure/spider/stickyweb/genetic(T, user)
/datum/mutation/human/tongue_spike
name = "Tongue Spike"
desc = "Allows a creature to voluntary shoot their tongue out as a deadly weapon."
quality = POSITIVE
text_gain_indication = "<span class='notice'>Your feel like you can throw your voice.</span>"
instability = 15
power = /obj/effect/proc_holder/spell/self/tongue_spike
energy_coeff = 1
synchronizer_coeff = 1
/obj/effect/proc_holder/spell/self/tongue_spike
name = "Launch spike"
desc = "Shoot your tongue out in the direction you're facing, embedding it and dealing damage until they remove it."
clothes_req = FALSE
human_req = TRUE
charge_max = 100
action_icon = 'icons/mob/actions/actions_genetic.dmi'
action_icon_state = "spike"
var/spike_path = /obj/item/hardened_spike
/obj/effect/proc_holder/spell/self/tongue_spike/cast(list/targets, mob/user = usr)
if(!iscarbon(user))
return
var/mob/living/carbon/C = user
if(HAS_TRAIT(C, TRAIT_NODISMEMBER))
return
var/obj/item/organ/tongue/tongue
for(var/org in C.internal_organs)
if(istype(org, /obj/item/organ/tongue))
tongue = org
break
if(!tongue)
to_chat(C, "<span class='notice'>You don't have a tongue to shoot!</span>")
return
tongue.Remove(C, special = TRUE)
var/obj/item/hardened_spike/spike = new spike_path(get_turf(C), C)
tongue.forceMove(spike)
spike.throw_at(get_edge_target_turf(C,C.dir), 14, 4, C)
/obj/item/hardened_spike
name = "biomass spike"
desc = "Hardened biomass, shaped into a spike. Very pointy!"
icon_state = "tonguespike"
force = 2
throwforce = 15 //15 + 2 (WEIGHT_CLASS_SMALL) * 4 (EMBEDDED_IMPACT_PAIN_MULTIPLIER) = i didnt do the math
throw_speed = 4
embedding = list("embedded_pain_multiplier" = 4, "embed_chance" = 100, "embedded_fall_chance" = 0, "embedded_ignore_throwspeed_threshold" = TRUE)
w_class = WEIGHT_CLASS_SMALL
sharpness = IS_SHARP
var/mob/living/carbon/human/fired_by
/obj/item/hardened_spike/Initialize(mapload, firedby)
. = ..()
fired_by = firedby
addtimer(CALLBACK(src, .proc/checkembedded), 5 SECONDS)
/obj/item/hardened_spike/proc/checkembedded()
if(ishuman(loc))
var/mob/living/carbon/human/embedtest = loc
for(var/l in embedtest.bodyparts)
var/obj/item/bodypart/limb = l
if(src in limb.embedded_objects)
return limb
unembedded()
/obj/item/hardened_spike/unembedded()
var/turf/T = get_turf(src)
visible_message("<span class='warning'>[src] cracks and twists, changing shape!</span>")
for(var/i in contents)
var/obj/o = i
o.forceMove(T)
qdel(src)
/datum/mutation/human/tongue_spike/chem
name = "Chem Spike"
desc = "Allows a creature to voluntary shoot their tongue out as biomass, allowing a long range transfer of chemicals."
quality = POSITIVE
text_gain_indication = "<span class='notice'>Your feel like you can really connect with people by throwing your voice.</span>"
instability = 15
locked = TRUE
power = /obj/effect/proc_holder/spell/self/tongue_spike/chem
energy_coeff = 1
synchronizer_coeff = 1
/obj/effect/proc_holder/spell/self/tongue_spike/chem
name = "Launch chem spike"
desc = "Shoot your tongue out in the direction you're facing, embedding it for a very small amount of damage. While the other person has the spike embedded, you can transfer your chemicals to them."
action_icon_state = "spikechem"
spike_path = /obj/item/hardened_spike/chem
/obj/item/hardened_spike/chem
name = "chem spike"
desc = "Hardened biomass, shaped into... something."
icon_state = "tonguespikechem"
throwforce = 2 //2 + 2 (WEIGHT_CLASS_SMALL) * 0 (EMBEDDED_IMPACT_PAIN_MULTIPLIER) = i didnt do the math again but very low or smthin
embedding = list("embedded_pain_multiplier" = 0, "embed_chance" = 100, "embedded_fall_chance" = 0, "embedded_pain_chance" = 0, "embedded_ignore_throwspeed_threshold" = TRUE) //never hurts once it's in you
var/been_places = FALSE
var/datum/action/innate/send_chems/chems
/obj/item/hardened_spike/chem/embedded(mob/living/carbon/human/embedded_mob)
if(been_places)
return
been_places = TRUE
chems = new
chems.transfered = embedded_mob
chems.spikey = src
to_chat(fired_by, "<span class='notice'>Link established! Use the \"Transfer Chemicals\" ability to send your chemicals to the linked target!</span>")
chems.Grant(fired_by)
/obj/item/hardened_spike/chem/unembedded()
to_chat(fired_by, "<span class='warning'>Link lost!</span>")
QDEL_NULL(chems)
..()
/datum/action/innate/send_chems
icon_icon = 'icons/mob/actions/actions_genetic.dmi'
background_icon_state = "bg_spell"
check_flags = AB_CHECK_CONSCIOUS
button_icon_state = "spikechemswap"
name = "Transfer Chemicals"
desc = "Send all of your reagents into whomever the chem spike is embedded in. One use."
var/obj/item/hardened_spike/chem/spikey
var/mob/living/carbon/human/transfered
/datum/action/innate/send_chems/Activate()
if(!ishuman(transfered) || !ishuman(owner))
return
var/mob/living/carbon/human/transferer = owner
to_chat(transfered, "<span class='warning'>You feel a tiny prick!</span>")
transferer.reagents.trans_to(transfered, transferer.reagents.total_volume, 1, 1, 0, transfered_by = transferer)
var/obj/item/bodypart/L = spikey.checkembedded()
L.embedded_objects -= spikey
//this is where it would deal damage, if it transfers chems it removes itself so no damage
spikey.forceMove(get_turf(L))
transfered.visible_message("<span class='notice'>[spikey] falls out of [transfered]!</span>")
if(!transfered.has_embedded_objects())
transfered.clear_alert("embeddedobject")
SEND_SIGNAL(transfered, COMSIG_CLEAR_MOOD_EVENT, "embedded")
spikey.unembedded()

View File

@@ -246,6 +246,21 @@
return
REMOVE_TRAIT(owner, TRAIT_SHOCKIMMUNE, "genetics")
/datum/mutation/human/glow/anti
name = "Anti-Glow"
desc = "Your skin seems to attract and absorb nearby light creating 'darkness' around you."
text_gain_indication = "<span class='notice'>Your light around you seems to disappear.</span>"
glow = -3.5 //Slightly stronger, since negating light tends to be harder than making it.
locked = TRUE
/datum/mutation/human/stimmed
name = "Stimmed"
desc = "The user's chemical balance is more robust."
quality = POSITIVE
text_gain_indication = "<span class='notice'>You feel stimmed.</span>"
difficulty = 16
/datum/mutation/human/paranoia
name = "Paranoia"
desc = "Subject is easily terrified, and may suffer from hallucinations."
@@ -259,4 +274,92 @@
owner.jitteriness = min(max(0, owner.jitteriness + 5), 30)
if(prob(25))
to_chat(owner,"<span class='warning'>You feel someone creeping in on you...</span>")
owner.hallucination += 20
owner.hallucination += 20
/datum/mutation/human/badblink
name = "Spatial Instability"
desc = "The victim of the mutation has a very weak link to spatial reality, and may be displaced. Often causes extreme nausea."
quality = NEGATIVE
text_gain_indication = "<span class='warning'>The space around you twists sickeningly.</span>"
text_lose_indication = "<span class'notice'>The space around you settles back to normal.</span>"
difficulty = 18//high so it's hard to unlock and abuse
instability = 10
synchronizer_coeff = 1
energy_coeff = 1
power_coeff = 1
var/warpchance = 0
/datum/mutation/human/badblink/on_life()
if(prob(warpchance))
var/warpmessage = pick(
"<span class='warning'>With a sickening 720-degree twist of [owner.p_their()] back, [owner] vanishes into thin air.</span>",
"<span class='warning'>[owner] does some sort of strange backflip into another dimension. It looks pretty painful.</span>",
"<span class='warning'>[owner] does a jump to the left, a step to the right, and warps out of reality.</span>",
"<span class='warning'>[owner]'s torso starts folding inside out until it vanishes from reality, taking [owner] with it.</span>",
"<span class='warning'>One moment, you see [owner]. The next, [owner] is gone.</span>")
owner.visible_message(warpmessage, "<span class='userdanger'>You feel a wave of nausea as you fall through reality!</span>")
var/warpdistance = rand(10,15) * GET_MUTATION_POWER(src)
do_teleport(owner, get_turf(owner), warpdistance, channel = TELEPORT_CHANNEL_FREE)
owner.adjust_disgust(GET_MUTATION_SYNCHRONIZER(src) * (warpchance * warpdistance))
warpchance = 0
owner.visible_message("<span class='danger'>[owner] appears out of nowhere!</span>")
else
warpchance += 0.25 * GET_MUTATION_ENERGY(src)
/datum/mutation/human/acidflesh
name = "Acidic Flesh"
desc = "Subject has acidic chemicals building up underneath the skin. This is often lethal."
quality = NEGATIVE
text_gain_indication = "<span class='userdanger'>A horrible burning sensation envelops you as your flesh turns to acid!</span>"
text_lose_indication = "<span class'notice'>A feeling of relief fills you as your flesh goes back to normal.</span>"
difficulty = 18//high so it's hard to unlock and use on others
var/msgcooldown = 0
/datum/mutation/human/acidflesh/on_life()
if(prob(25))
if(world.time > msgcooldown)
to_chat(owner, "<span class='danger'>Your acid flesh bubbles...</span>")
msgcooldown = world.time + 200
if(prob(15))
owner.acid_act(rand(30,50), 10)
owner.visible_message("<span class='warning'>[owner]'s skin bubbles and pops.</span>", "<span class='userdanger'>Your bubbling flesh pops! It burns!</span>")
playsound(owner,'sound/weapons/sear.ogg', 50, TRUE)
/datum/mutation/human/gigantism
name = "Gigantism"//negative version of dwarfism
desc = "The cells within the subject spread out to cover more area, making the subject appear larger."
quality = MINOR_NEGATIVE
difficulty = 12
/datum/mutation/human/gigantism/on_acquiring(mob/living/carbon/human/owner)
if(..())
return
owner.resize = 1.25
owner.update_transform()
owner.visible_message("<span class='danger'>[owner] suddenly grows!</span>", "<span class='notice'>Everything around you seems to shrink..</span>")
/datum/mutation/human/gigantism/on_losing(mob/living/carbon/human/owner)
if(..())
return
owner.resize = 0.8
owner.update_transform()
owner.visible_message("<span class='danger'>[owner] suddenly shrinks!</span>", "<span class='notice'>Everything around you seems to grow..</span>")
/datum/mutation/human/spastic
name = "Spastic"
desc = "Subject suffers from muscle spasms."
quality = NEGATIVE
text_gain_indication = "<span class='warning'>You flinch.</span>"
text_lose_indication = "<span class'notice'>Your flinching subsides.</span>"
difficulty = 16
/datum/mutation/human/spastic/on_acquiring()
if(..())
return
owner.apply_status_effect(STATUS_EFFECT_SPASMS)
/datum/mutation/human/spastic/on_losing()
if(..())
return
owner.remove_status_effect(STATUS_EFFECT_SPASMS)

View File

@@ -0,0 +1,42 @@
/datum/mutation/human/geladikinesis
name = "Geladikinesis"
desc = "Allows the user to concentrate moisture and sub-zero forces into snow."
quality = POSITIVE
text_gain_indication = "<span class='notice'>Your hand feels cold.</span>"
instability = 10
difficulty = 10
synchronizer_coeff = 1
power = /obj/effect/proc_holder/spell/targeted/conjure_item/snow
/obj/effect/proc_holder/spell/targeted/conjure_item/snow
name = "Create Snow"
desc = "Concentrates cryokinetic forces to create snow, useful for snow-like construction."
item_type = /obj/item/stack/sheet/mineral/snow
charge_max = 50
action_icon_state = "snow"
/datum/mutation/human/cryokinesis
name = "Cryokinesis"
desc = "Draws negative energy from the sub-zero void to freeze surrounding temperatures at subject's will."
quality = POSITIVE //upsides and downsides
text_gain_indication = "<span class='notice'>Your hand feels cold.</span>"
instability = 20
difficulty = 12
synchronizer_coeff = 1
power = /obj/effect/proc_holder/spell/aimed/cryo
/obj/effect/proc_holder/spell/aimed/cryo
name = "Cryobeam"
desc = "This power fires a frozen bolt at a target."
charge_max = 150
cooldown_min = 150
clothes_req = FALSE
range = 3
projectile_type = /obj/item/projectile/temp/cryo
base_icon_state = "icebeam"
action_icon_state = "icebeam"
active_msg = "You focus your cryokinesis!"
deactive_msg = "You relax."
active = FALSE

View File

@@ -21,4 +21,12 @@
/datum/generecipe/mindread
required = "/datum/mutation/human/antenna; /datum/mutation/human/paranoia"
result = MINDREAD
result = MINDREAD
/datum/generecipe/antiglow
required = "/datum/mutation/human/glow; /datum/mutation/human/void"
result = ANTIGLOWY
/datum/generecipe/tonguechem
required = "/datum/mutation/human/tongue_spike; /datum/mutation/human/stimmed"
result = TONGUESPIKECHEM

View File

@@ -27,3 +27,4 @@
return
REMOVE_TRAIT(owner, TRAIT_RESISTCOLD, "cold_resistance")
REMOVE_TRAIT(owner, TRAIT_RESISTLOWPRESSURE, "cold_resistance")

View File

@@ -28,6 +28,7 @@
take_damage(5, BURN, 0, 0)
/obj/structure/spider/stickyweb
var/genetic = FALSE
icon_state = "stickyweb1"
/obj/structure/spider/stickyweb/Initialize()
@@ -36,6 +37,8 @@
. = ..()
/obj/structure/spider/stickyweb/CanPass(atom/movable/mover, turf/target)
if (genetic)
return
if(istype(mover, /mob/living/simple_animal/hostile/poison/giant_spider))
return TRUE
else if(isliving(mover))
@@ -48,6 +51,27 @@
return prob(30)
return TRUE
/obj/structure/spider/stickyweb/genetic //for the spider genes in genetics
genetic = TRUE
var/mob/living/allowed_mob
/obj/structure/spider/stickyweb/genetic/Initialize(mapload, allowedmob)
allowed_mob = allowedmob
. = ..()
/obj/structure/spider/stickyweb/genetic/CanPass(atom/movable/mover, turf/target)
. = ..() //this is the normal spider web return aka a spider would make this TRUE
if(mover == allowed_mob)
return TRUE
else if(isliving(mover)) //we change the spider to not be able to go through here
if(mover.pulledby == allowed_mob)
return TRUE
if(prob(50))
to_chat(mover, "<span class='danger'>You get stuck in \the [src] for a moment.</span>")
return FALSE
else if(istype(mover, /obj/item/projectile))
return prob(30)
/obj/structure/spider/eggcluster
name = "egg cluster"
desc = "They seem to pulse slightly with an inner life."

View File

@@ -852,3 +852,9 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
if (HAS_TRAIT(src, TRAIT_NODROP))
return
return ..()
/obj/item/proc/embedded(mob/living/carbon/human/embedded_mob)
return
/obj/item/proc/unembedded()
return

View File

@@ -619,7 +619,7 @@
is_capped = TRUE
self_contained = FALSE // Don't disappear when they're empty
can_change_colour = TRUE
reagent_contents = list(/datum/reagent/fuel = 1, /datum/reagent/consumable/ethanol = 1)
pre_noise = TRUE

View File

@@ -786,7 +786,7 @@ SLIME SCANNER
item_state = "healthanalyzer"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
desc = "A hand-held scanner able to swiftly scan someone for potential mutations. Hold near a DNA console to update from their database."
desc = "A hand-held scanner for analyzing someones gene sequence on the fly. Hold near a DNA console to update the internal database."
flags_1 = CONDUCT_1
item_flags = NOBLUDGEON
slot_flags = ITEM_SLOT_BELT
@@ -796,13 +796,25 @@ SLIME SCANNER
throw_range = 7
materials = list(MAT_METAL=200)
var/list/discovered = list() //hit a dna console to update the scanners database
var/list/buffer
var/ready = TRUE
var/cooldown = 200
/obj/item/sequence_scanner/attack(mob/living/M, mob/living/carbon/human/user)
user.visible_message("<span class='notice'>[user] has analyzed [M]'s genetic sequence.</span>")
add_fingerprint(user)
if (!HAS_TRAIT(M, TRAIT_RADIMMUNE)) //no scanning if its a husk or DNA-less Species
user.visible_message("<span class='notice'>[user] analyzes [M]'s genetic sequence.</span>", \
"<span class='notice'>You analyze [M]'s genetic sequence.</span>")
gene_scan(M, user)
gene_scan(M, user, src)
else
user.visible_message("<span class='notice'>[user] failed to analyse [M]'s genetic sequence.</span>", "<span class='warning'>[M] has no readable genetic sequence!</span>")
/obj/item/sequence_scanner/attack_self(mob/user)
display_sequence(user)
/obj/item/sequence_scanner/attack_self_tk(mob/user)
return
/obj/item/sequence_scanner/afterattack(obj/O, mob/user, proximity)
. = ..()
@@ -812,28 +824,58 @@ SLIME SCANNER
if(istype(O, /obj/machinery/computer/scan_consolenew))
var/obj/machinery/computer/scan_consolenew/C = O
if(C.stored_research)
to_chat(user, "<span class='notice'>[name] database updated.</span>")
to_chat(user, "<span class='notice'>[name] linked to central research database.</span>")
discovered = C.stored_research.discovered_mutations
else
to_chat(user,"<span class='warning'>No database to update from.</span>")
/proc/gene_scan(mob/living/carbon/C, mob/living/user, obj/item/sequence_scanner/G)
/obj/item/sequence_scanner/proc/gene_scan(mob/living/carbon/C, mob/living/user)
if(!iscarbon(C) || !C.has_dna())
return
to_chat(user, "<span class='notice'>[C.name]'s potential mutations.")
for(var/A in C.dna.mutation_index)
var/datum/mutation/human/HM = GET_INITIALIZED_MUTATION(A)
var/mut_name
if(G && (A in G.discovered))
mut_name = "[HM.name] ([HM.alias])"
else
mut_name = HM.alias
var/temp = GET_GENE_STRING(HM.type, C.dna)
var/display
for(var/i in 0 to length(temp) / DNA_MUTATION_BLOCKS-1)
if(i)
display += "-"
display += copytext(temp, 1 + i*DNA_MUTATION_BLOCKS, DNA_MUTATION_BLOCKS*(1+i) + 1)
buffer = C.dna.mutation_index
to_chat(user, "<span class='notice'>Subject [C.name]'s DNA sequence has been saved to buffer.</span>")
if(LAZYLEN(buffer))
for(var/A in buffer)
to_chat(user, "<span class='notice'>[get_display_name(A)]</span>")
to_chat(user, "<span class='boldnotice'>- [mut_name] > [display]</span>")
/obj/item/sequence_scanner/proc/display_sequence(mob/living/user)
if(!LAZYLEN(buffer) || !ready)
return
var/list/options = list()
for(var/A in buffer)
options += get_display_name(A)
var/answer = input(user, "Analyze Potential", "Sequence Analyzer") as null|anything in sortList(options)
if(answer && ready && user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
var/sequence
for(var/A in buffer) //this physically hurts but i dont know what anything else short of an assoc list
if(get_display_name(A) == answer)
sequence = buffer[A]
break
if(sequence)
var/display
for(var/i in 0 to length_char(sequence) / DNA_MUTATION_BLOCKS-1)
if(i)
display += "-"
display += copytext_char(sequence, 1 + i*DNA_MUTATION_BLOCKS, DNA_MUTATION_BLOCKS*(1+i) + 1)
to_chat(user, "<span class='boldnotice'>[display]</span><br>")
ready = FALSE
icon_state = "[icon_state]_recharging"
addtimer(CALLBACK(src, .proc/recharge), cooldown, TIMER_UNIQUE)
/obj/item/sequence_scanner/proc/recharge()
icon_state = initial(icon_state)
ready = TRUE
/obj/item/sequence_scanner/proc/get_display_name(mutation)
var/datum/mutation/human/HM = GET_INITIALIZED_MUTATION(mutation)
if(!HM)
return "ERROR"
if(mutation in discovered)
return "[HM.name] ([HM.alias])"
else
return HM.alias

View File

@@ -296,54 +296,14 @@
name = "\improper DNA injector (Anti-Laser Eyes)"
remove_mutations = list(LASEREYES)
/obj/item/dnainjector/thermalmut
name = "\improper DNA injector (Thermal Vision)"
add_mutations = list(THERMAL)
/obj/item/dnainjector/antithermal
name = "\improper DNA injector (Anti-Thermal Vision)"
remove_mutations = list(THERMAL)
/obj/item/dnainjector/telepathymut
name = "\improper DNA injector (Telepathy)"
add_mutations = list(TELEPATHY)
/obj/item/dnainjector/antitelepathy
name = "\improper DNA injector (Anti-Telepathy)"
remove_mutations = list(TELEPATHY)
/obj/item/dnainjector/voidmut
name = "\improper DNA injector (Void Magnet)"
/obj/item/dnainjector/void
name = "\improper DNA injector (Void)"
add_mutations = list(VOID)
/obj/item/dnainjector/antivoid
name = "\improper DNA injector (Anti-Void Magnet)"
name = "\improper DNA injector (Anti-Void)"
remove_mutations = list(VOID)
/obj/item/dnainjector/firebreathmut
name = "\improper DNA injector (Firebreath)"
add_mutations = list(FIREBREATH)
/obj/item/dnainjector/antifirebreath
name = "\improper DNA injector (Anti-Firebreath)"
remove_mutations = list(FIREBREATH)
/obj/item/dnainjector/insulatedmut
name = "\improper DNA injector (Insulated)"
add_mutations = list(INSULATED)
/obj/item/dnainjector/antiinsulated
name = "\improper DNA injector (Anti-Insulated)"
remove_mutations = list(INSULATED)
/obj/item/dnainjector/shocktouchmut
name = "\improper DNA injector (Shock Touch)"
add_mutations = list(SHOCKTOUCH)
/obj/item/dnainjector/antishocktouch
name = "\improper DNA injector (Anti-Shock Touch)"
remove_mutations = list(SHOCKTOUCH)
/obj/item/dnainjector/antenna
name = "\improper DNA injector (Antenna)"
add_mutations = list(ANTENNA)
@@ -368,6 +328,133 @@
name = "\improper DNA injector (Anti-Mindread)"
remove_mutations = list(MINDREAD)
/obj/item/dnainjector/radioactive
name = "\improper DNA injector (Radioactive)"
add_mutations = list(RADIOACTIVE)
/obj/item/dnainjector/antiradioactive
name = "\improper DNA injector (Anti-Radioactive)"
remove_mutations = list(RADIOACTIVE)
/obj/item/dnainjector/olfaction
name = "\improper DNA injector (Olfaction)"
add_mutations = list(OLFACTION)
/obj/item/dnainjector/antiolfaction
name = "\improper DNA injector (Anti-Olfaction)"
remove_mutations = list(OLFACTION)
/obj/item/dnainjector/insulated
name = "\improper DNA injector (Insulated)"
add_mutations = list(INSULATED)
/obj/item/dnainjector/antiinsulated
name = "\improper DNA injector (Anti-Insulated)"
remove_mutations = list(INSULATED)
/obj/item/dnainjector/shock
name = "\improper DNA injector (Shock Touch)"
add_mutations = list(SHOCKTOUCH)
/obj/item/dnainjector/antishock
name = "\improper DNA injector (Anti-Shock Touch)"
remove_mutations = list(SHOCKTOUCH)
/obj/item/dnainjector/spacialinstability
name = "\improper DNA injector (Spacial Instability)"
add_mutations = list(BADBLINK)
/obj/item/dnainjector/antispacialinstability
name = "\improper DNA injector (Anti-Spacial Instability)"
remove_mutations = list(BADBLINK)
/obj/item/dnainjector/acidflesh
name = "\improper DNA injector (Acid Flesh)"
add_mutations = list(ACIDFLESH)
/obj/item/dnainjector/antiacidflesh
name = "\improper DNA injector (Acid Flesh)"
remove_mutations = list(ACIDFLESH)
/obj/item/dnainjector/gigantism
name = "\improper DNA injector (Gigantism)"
add_mutations = list(GIGANTISM)
/obj/item/dnainjector/antigigantism
name = "\improper DNA injector (Anti-Gigantism)"
remove_mutations = list(GIGANTISM)
/obj/item/dnainjector/spastic
name = "\improper DNA injector (Spastic)"
add_mutations = list(SPASTIC)
/obj/item/dnainjector/antispastic
name = "\improper DNA injector (Anti-Spastic)"
remove_mutations = list(SPASTIC)
/obj/item/dnainjector/geladikinesis
name = "\improper DNA injector (Geladikinesis)"
add_mutations = list(GELADIKINESIS)
/obj/item/dnainjector/antigeladikinesis
name = "\improper DNA injector (Anti-Geladikinesis)"
remove_mutations = list(GELADIKINESIS)
/obj/item/dnainjector/cryokinesis
name = "\improper DNA injector (Cryokinesis)"
add_mutations = list(CRYOKINESIS)
/obj/item/dnainjector/anticryokinesis
name = "\improper DNA injector (Anti-Cryokinesis)"
remove_mutations = list(CRYOKINESIS)
/obj/item/dnainjector/thermal
name = "\improper DNA injector (Thermal Vision)"
add_mutations = list(THERMAL)
/obj/item/dnainjector/antithermal
name = "\improper DNA injector (Anti-Thermal Vision)"
remove_mutations = list(THERMAL)
/obj/item/dnainjector/glow
name = "\improper DNA injector (Glowy)"
add_mutations = list(GLOWY)
/obj/item/dnainjector/removeglow
name = "\improper DNA injector (Anti-Glowy)"
remove_mutations = list(GLOWY)
/obj/item/dnainjector/antiglow
name = "\improper DNA injector (Antiglowy)"
add_mutations = list(ANTIGLOWY)
/obj/item/dnainjector/removeantiglow
name = "\improper DNA injector (Anti-Antiglowy)"
remove_mutations = list(ANTIGLOWY)
/obj/item/dnainjector/firebreath
name = "\improper DNA injector (Firebreath)"
add_mutations = list(FIREBREATH)
/obj/item/dnainjector/antifirebreath
name = "\improper DNA injector (Anti-Firebreath)"
remove_mutations = list(FIREBREATH)
/obj/item/dnainjector/tonguespike
name = "\improper DNA injector (Tongue Spike)"
add_mutations = list(TONGUESPIKE)
/obj/item/dnainjector/antitonguespike
name = "\improper DNA injector (Anti-Tongue Spike)"
remove_mutations = list(TONGUESPIKE)
/obj/item/dnainjector/spiderweb
name = "\improper DNA injector (Spider Web)"
add_mutations = list(SPIDER_WEB)
/obj/item/dnainjector/antispiderweb
name = "\improper DNA injector (Anti-Spider Web)"
remove_mutations = list(SPIDER_WEB)
/obj/item/dnainjector/timed
var/duration = 600

View File

@@ -96,6 +96,7 @@
user.dropItemToGround(src, TRUE) //user.drop_item() // "drop item" doesn't seem to exist anymore. New proc is user.dropItemToGround() but it doesn't seem like it's needed now?
var/obj/item/bodypart/B = C.get_bodypart("chest") // This was all taken from hitby() in human_defense.dm
B.embedded_objects |= src
embedded()
add_mob_blood(target)//Place blood on the stake
loc = C // Put INSIDE the character
B.receive_damage(w_class * embedding.embedded_impact_pain_multiplier)

View File

@@ -66,6 +66,7 @@
L.embedded_objects |= I
I.add_mob_blood(src)//it embedded itself in you, of course it's bloody!
I.forceMove(src)
I.embedded()
L.receive_damage(I.w_class*I.embedding.embedded_impact_pain_multiplier)
visible_message("<span class='danger'>[I] embeds itself in [src]'s [L.name]!</span>","<span class='userdanger'>[I] embeds itself in your [L.name]!</span>")
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "embedded", /datum/mood_event/embedded)

View File

@@ -316,6 +316,7 @@
BP.receive_damage(I.w_class*I.embedding.embedded_fall_pain_multiplier)
BP.embedded_objects -= I
I.forceMove(drop_location())
I.unembedded()
visible_message("<span class='danger'>[I] falls out of [name]'s [BP.name]!</span>","<span class='userdanger'>[I] falls out of your [BP.name]!</span>")
if(!has_embedded_objects())
clear_alert("embeddedobject")

View File

@@ -16,3 +16,8 @@
/obj/item/projectile/temp/hot
name = "heat beam"
temperature = 400
/obj/item/projectile/temp/cryo
name = "cryo beam"
range = 3
temperature = -240 // Single slow shot reduces temp greatly

View File

@@ -128,6 +128,49 @@
invocation_type ="none"
..()
/obj/effect/proc_holder/spell/targeted/touch/mimerope
name = "Invisible Rope"
desc = "Form an invisible rope to tie people or trip people with."
school = "mime"
panel = "Mime"
invocation_type = "emote"
invocation_emote_self = "<span class='notice'>You start fabricate an invisible rope.</span>"
charge_max = 700
sound = null
clothes_req = 0
range = -1
include_user = 1
action_icon_state = "mime"
action_background_icon_state = "bg_mime"
hand_path = /obj/item/melee/touch_attack/mimerope
/obj/effect/proc_holder/spell/targeted/touch/mimerope/Click()
if(usr && usr.mind)
if(!usr.mind.miming)
to_chat(usr, "<span class='notice'>You must dedicate yourself to silence first.</span>")
return
if (usr.get_active_held_item())
to_chat(usr, "<span class='notice'>Your hands must be free to create the invisible rope.</span>")
return
invocation = "<B>[usr.real_name]</B> is twirling an invisible rope in [usr.p_their()] hands."
else
invocation_type ="none"
/obj/effect/proc_holder/spell/targeted/touch/mimerope/cast(list/targets,mob/user = usr)
usr.put_in_hands()
/obj/item/melee/touch_attack/mimerope
item_state = ""
icon_state = ""
name = "mime rope"
desc = "An invisible rope."
/obj/item/restraints/handcuffs/cable/mime
name = "mime restraints"
desc = "An invisible rope."
item_state = ""
icon_state = ""
/obj/item/book/granter/spell/mimery_blockade
spell = /obj/effect/proc_holder/spell/targeted/forcewall/mime

View File

@@ -102,6 +102,7 @@
for(var/obj/item/I in embedded_objects)
embedded_objects -= I
I.forceMove(src)
I.unembedded()
if(!C.has_embedded_objects())
C.clear_alert("embeddedobject")
SEND_SIGNAL(C, COMSIG_CLEAR_MOOD_EVENT, "embedded")

View File

@@ -161,6 +161,7 @@
for(var/obj/item/I in L.embedded_objects)
L.embedded_objects -= I
I.forceMove(T)
I.unembedded()
clear_alert("embeddedobject")
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "embedded")

View File

@@ -25,6 +25,7 @@
objects++
I.forceMove(get_turf(H))
L.embedded_objects -= I
I.unembedded()
if(!H.has_embedded_objects())
H.clear_alert("embeddedobject")
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "embedded")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

View File

@@ -19,6 +19,7 @@
L.embedded_objects -= I
L.receive_damage(I.embedding.embedded_unsafe_removal_pain_multiplier*I.w_class*painmul)//It hurts to rip it out, get surgery you dingus. And if you're ripping it out quickly via resist, it's gonna hurt even more
I.forceMove(get_turf(src))
I.unembedded()
user.put_in_hands(I)
user.emote("scream")
user.visible_message("[user] rips [I] out of [user.p_their()] [L.name]!","<span class='notice'>You remove [I] from your [L.name].</span>")

View File

@@ -522,11 +522,12 @@
#include "code\datums\mutations\antenna.dm"
#include "code\datums\mutations\body.dm"
#include "code\datums\mutations\chameleon.dm"
#include "code\datums\mutations\cold_resistance.dm"
#include "code\datums\mutations\cold.dm"
#include "code\datums\mutations\combined.dm"
#include "code\datums\mutations\hulk.dm"
#include "code\datums\mutations\radioactive.dm"
#include "code\datums\mutations\sight.dm"
#include "code\datums\mutations\space_adaptation.dm"
#include "code\datums\mutations\speech.dm"
#include "code\datums\mutations\telekinesis.dm"
#include "code\datums\ruins\lavaland.dm"