Merge pull request #10327 from Seris02/tggenetics

ports tg genetics
This commit is contained in:
kevinz000
2020-03-11 17:01:37 -07:00
committed by GitHub
77 changed files with 2776 additions and 514 deletions
@@ -90,6 +90,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)
@@ -13,17 +13,14 @@
var/mob/living/carbon/human/H = user //SHOULD always be human, because req_human = 1
if(!istype(H)) // req_human could be done in can_sting stuff.
return
var/datum/mutation/human/HM = GLOB.mutations_list[CHAMELEON]
if(HM in H.dna.mutations)
HM.force_lose(H)
if(H.dna.get_mutation(CHAMELEON))
H.dna.remove_mutation(CHAMELEON)
else
HM.force_give(H)
H.dna.add_mutation(CHAMELEON)
return TRUE
/obj/effect/proc_holder/changeling/chameleon_skin/on_refund(mob/user)
action.Remove(user)
if(user.has_dna())
var/mob/living/carbon/C = user
var/datum/mutation/human/HM = GLOB.mutations_list[CHAMELEON]
if(HM in C.dna.mutations)
HM.force_lose(C)
C.dna.remove_mutation(CHAMELEON)
@@ -24,5 +24,5 @@
return
H.dna.add_mutation(HULK)
H.dna.add_mutation(XRAY)
H.dna.add_mutation(COLDRES)
H.dna.add_mutation(SPACEMUT)
H.dna.add_mutation(TK)
@@ -94,7 +94,7 @@
to_chat(user, "<B>Your wish is granted, but at a terrible cost...</B>")
to_chat(user, "The Wish Granter punishes you for your selfishness, claiming your soul and warping your body to match the darkness in your heart.")
user.dna.add_mutation(LASEREYES)
user.dna.add_mutation(COLDRES)
user.dna.add_mutation(SPACEMUT)
user.dna.add_mutation(XRAY)
user.set_species(/datum/species/shadow)
if("Wealth")
+7
View File
@@ -703,3 +703,10 @@ GLOBAL_LIST_EMPTY(asset_datums)
Insert(initial(D.id), I)
return ..()
/datum/asset/simple/genetics
assets = list(
"dna_discovered.gif" = 'html/dna_discovered.gif',
"dna_undiscovered.gif" = 'html/dna_undiscovered.gif',
"dna_extra.gif" = 'html/dna_extra.gif'
)
+1 -1
View File
@@ -59,7 +59,7 @@
var/datum/disease/dnaspread/DS = D
DS.strain_data["name"] = H.real_name
DS.strain_data["UI"] = H.dna.uni_identity
DS.strain_data["SE"] = H.dna.struc_enzymes
DS.strain_data["SE"] = H.dna.mutation_index
else
D = new virus_type()
else
@@ -32,4 +32,5 @@
backpack = /obj/item/storage/backpack/genetics
satchel = /obj/item/storage/backpack/satchel/gen
duffelbag = /obj/item/storage/backpack/duffelbag/med
l_pocket = /obj/item/sequence_scanner
@@ -463,30 +463,45 @@
if(cooldown < world.time)
SSblackbox.record_feedback("amount", "immortality_talisman_uses", 1)
cooldown = world.time + 600
user.visible_message("<span class='danger'>[user] vanishes from reality, leaving a hole in [user.p_their()] place!</span>")
var/obj/effect/immortality_talisman/Z = new(get_turf(src.loc))
Z.name = "hole in reality"
Z.desc = "It's shaped an awful lot like [user.name]."
Z.setDir(user.dir)
user.forceMove(Z)
user.notransform = 1
user.status_flags |= GODMODE
addtimer(CALLBACK(src, .proc/return_to_reality, user, Z), 100)
new /obj/effect/immortality_talisman(get_turf(user), user)
else
to_chat(user, "<span class='warning'>[src] is not ready yet!</span>")
/obj/item/immortality_talisman/proc/return_to_reality(mob/user, obj/effect/immortality_talisman/Z)
user.status_flags &= ~GODMODE
user.notransform = 0
user.forceMove(get_turf(Z))
user.visible_message("<span class='danger'>[user] pops back into reality!</span>")
Z.can_destroy = TRUE
qdel(Z)
/obj/effect/immortality_talisman
name = "hole in reality"
desc = "It's shaped an awful lot like a person."
icon_state = "blank"
icon = 'icons/effects/effects.dmi'
var/can_destroy = FALSE
var/vanish_description = "vanishes from reality"
var/can_destroy = TRUE
/obj/effect/immortality_talisman/Initialize(mapload, mob/new_user)
. = ..()
if(new_user)
vanish(new_user)
/obj/effect/immortality_talisman/proc/vanish(mob/user)
user.visible_message("<span class='danger'>[user] [vanish_description], leaving a hole in [user.p_their()] place!</span>")
desc = "It's shaped an awful lot like [user.name]."
setDir(user.dir)
user.forceMove(src)
user.notransform = TRUE
user.status_flags |= GODMODE
can_destroy = FALSE
addtimer(CALLBACK(src, .proc/unvanish, user), 10 SECONDS)
/obj/effect/immortality_talisman/proc/unvanish(mob/user)
user.status_flags &= ~GODMODE
user.notransform = FALSE
user.forceMove(get_turf(src))
user.visible_message("<span class='danger'>[user] pops back into reality!</span>")
can_destroy = TRUE
qdel(src)
/obj/effect/immortality_talisman/attackby()
return
@@ -503,6 +518,9 @@
else
. = ..()
/obj/effect/immortality_talisman/void
vanish_description = "is dragged into the void"
//Shared Bag
+7
View File
@@ -632,6 +632,13 @@
if(M.name == XRAY)
sight |= (SEE_TURFS|SEE_MOBS|SEE_OBJS)
see_in_dark = max(see_in_dark, 8)
if(HAS_TRAIT(src, TRAIT_THERMAL_VISION))
sight |= (SEE_MOBS)
lighting_alpha = min(lighting_alpha, LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE)
if(HAS_TRAIT(src, TRAIT_XRAY_VISION))
sight |= (SEE_TURFS|SEE_MOBS|SEE_OBJS)
see_in_dark = max(see_in_dark, 8)
if(see_override)
see_invisible = see_override
@@ -71,6 +71,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)
@@ -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")
@@ -69,6 +69,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/siemens_coeff = 1 //base electrocution coefficient
var/damage_overlay_type = "human" //what kind of damage overlays (if any) appear on our species when wounded?
var/fixed_mut_color = "" //to use MUTCOLOR with a fixed color that's independent of dna.feature["mcolor"]
var/inert_mutation = DWARFISM
var/list/special_step_sounds //Sounds to override barefeet walkng
var/grab_sound //Special sound for grabbing
var/datum/outfit/outfit_important_for_life // A path to an outfit that is important for species life e.g. plasmaman outfit
@@ -356,6 +357,14 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
else
C.type_of_meat = initial(meat)
//If their inert mutation is not the same, swap it out
if((inert_mutation != new_species.inert_mutation) && LAZYLEN(C.dna.mutation_index) && (inert_mutation in C.dna.mutation_index))
C.dna.remove_mutation(inert_mutation)
//keep it at the right spot, so we can't have people taking shortcuts
var/location = C.dna.mutation_index.Find(inert_mutation)
C.dna.mutation_index[location] = new_species.inert_mutation
C.dna.mutation_index[new_species.inert_mutation] = create_sequence(new_species.inert_mutation)
SEND_SIGNAL(C, COMSIG_SPECIES_LOSS, src)
/datum/species/proc/handle_hair(mob/living/carbon/human/H, forced_colour)
@@ -1394,7 +1403,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(radiation > RAD_MOB_MUTATE)
if(prob(1))
to_chat(H, "<span class='danger'>You mutate!</span>")
H.randmutb()
H.easy_randmut(NEGATIVE+MINOR_NEGATIVE)
H.emote("gasp")
H.domutcheck()
@@ -23,6 +23,7 @@
exotic_bloodtype = "L"
disliked_food = GRAIN | DAIRY
liked_food = GROSS | MEAT
inert_mutation = FIREBREATH
/datum/species/lizard/after_equip_job(datum/job/J, mob/living/carbon/human/H)
H.grant_language(/datum/language/draconic)
@@ -61,9 +61,9 @@
H.DefaultCombatKnockdown(100)
H.visible_message("<span class='warning'>[H] writhes in pain as [H.p_their()] vacuoles boil.</span>", "<span class='userdanger'>You writhe in pain as your vacuoles boil!</span>", "<span class='italics'>You hear the crunching of leaves.</span>")
if(prob(80))
H.randmutb()
H.easy_randmut(NEGATIVE+MINOR_NEGATIVE)
else
H.randmutg()
H.easy_randmut(POSITIVE)
H.domutcheck()
else
H.adjustFireLoss(rand(5,15))
+3 -4
View File
@@ -427,7 +427,6 @@
/mob/living/carbon/handle_mutations_and_radiation()
if(dna && dna.temporary_mutations.len)
var/datum/mutation/human/HM
for(var/mut in dna.temporary_mutations)
if(dna.temporary_mutations[mut] < world.time)
if(mut == UI_CHANGED)
@@ -450,9 +449,9 @@
dna.previous.Remove("blood_type")
dna.temporary_mutations.Remove(mut)
continue
HM = GLOB.mutations_list[mut]
HM.force_lose(src)
dna.temporary_mutations.Remove(mut)
for(var/datum/mutation/human/HM in dna.mutations)
if(HM && HM.timed)
dna.remove_mutation(HM.type)
radiation -= min(radiation, RAD_LOSS_PER_TICK)
if(radiation > RAD_MOB_SAFE)
@@ -42,7 +42,7 @@
if(radiation > RAD_MOB_MUTATE)
if(prob(1))
to_chat(src, "<span class='danger'>You mutate!</span>")
randmutb()
easy_randmut(NEGATIVE+MINOR_NEGATIVE)
emote("gasp")
domutcheck()
if(radiation > RAD_MOB_VOMIT && prob(RAD_MOB_VOMIT_PROB))
+4 -6
View File
@@ -49,9 +49,8 @@
O.updateappearance(icon_update=0)
if(tr_flags & TR_KEEPSE)
O.dna.struc_enzymes = dna.struc_enzymes
var/datum/mutation/human/race/R = GLOB.mutations_list[RACEMUT]
O.dna.struc_enzymes = R.set_se(O.dna.struc_enzymes, on=1)//we don't want to keep the race block inactive
O.dna.mutation_index = dna.mutation_index
O.dna.set_se(1, GET_INITIALIZED_MUTATION(RACEMUT))
if(suiciding)
O.suiciding = suiciding
@@ -208,9 +207,8 @@
O.name = O.real_name
if(tr_flags & TR_KEEPSE)
O.dna.struc_enzymes = dna.struc_enzymes
var/datum/mutation/human/race/R = GLOB.mutations_list[RACEMUT]
O.dna.struc_enzymes = R.set_se(O.dna.struc_enzymes, on=0)//we don't want to keep the race block active
O.dna.mutation_index = dna.mutation_index
O.dna.set_se(0, GET_INITIALIZED_MUTATION(RACEMUT))
O.domutcheck()
if(suiciding)
@@ -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
@@ -957,7 +957,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M)
/datum/reagent/medicine/mutadone/on_mob_life(mob/living/carbon/M)
M.jitteriness = 0
if(M.has_dna())
M.dna.remove_all_mutations()
M.dna.remove_all_mutations(mutadone = TRUE)
if(!QDELETED(M)) //We were a monkey, now a human
..()
@@ -40,9 +40,9 @@
if((method==VAPOR && prob(min(33, reac_volume))) || method==INGEST || method==PATCH || method==INJECT)
M.randmuti()
if(prob(98))
M.randmutb()
M.easy_randmut(NEGATIVE+MINOR_NEGATIVE)
else
M.randmutg()
M.easy_randmut(POSITIVE)
M.updateappearance()
M.domutcheck()
..()
@@ -162,6 +162,16 @@
category = list("Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
/datum/design/genescanner
name = "Genetic Sequence Analyzer"
desc = "A handy hand-held analyzers for quickly determining mutations and collecting the full sequence."
id = "genescanner"
build_path = /obj/item/sequence_scanner
build_type = PROTOLATHE
materials = list(/datum/material/iron = 1000, /datum/material/glass = 500)
category = list("Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
/datum/design/healthanalyzer_advanced
name = "Advanced Health Analyzer"
desc = "A hand-held body scanner able to distinguish vital signs of the subject with high accuracy."
@@ -20,6 +20,7 @@
var/largest_bomb_value = 0
var/organization = "Third-Party" //Organization name, used for display.
var/list/last_bitcoins = list() //Current per-second production, used for display only.
var/list/discovered_mutations = list() //Mutations discovered by genetics, this way they are shared and cant be destroyed by destroying a single console
var/list/tiers = list() //Assoc list, id = number, 1 is available, 2 is all reqs are 1, so on
/datum/techweb/New()
+1 -1
View File
@@ -71,7 +71,7 @@
display_name = "Biological Technology"
description = "What makes us tick." //the MC, silly!
prereq_ids = list("base")
design_ids = list("medicalkit", "chem_heater", "chem_master", "chem_dispenser", "sleeper", "vr_sleeper", "pandemic", "defibrillator", "defibmount", "operating", "soda_dispenser", "beer_dispenser", "healthanalyzer", "blood_bag", "bloodbankgen", "telescopiciv", "medspray")
design_ids = list("medicalkit", "chem_heater", "chem_master", "chem_dispenser", "sleeper", "vr_sleeper", "pandemic", "defibrillator", "defibmount", "operating", "soda_dispenser", "beer_dispenser", "healthanalyzer", "blood_bag", "bloodbankgen", "telescopiciv", "medspray","genescanner")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
/datum/techweb_node/adv_biotech
+3 -3
View File
@@ -80,11 +80,11 @@
school = "conjuration"
charge_max = 150
cooldown_min = 10
var/delete_old = TRUE
/obj/effect/proc_holder/spell/targeted/conjure_item/cast(list/targets, mob/user = usr)
if (item && !QDELETED(item))
qdel(item)
item = null
if (delete_old && item && !QDELETED(item))
QDEL_NULL(item)
else
for(var/mob/living/carbon/C in targets)
if(C.dropItemToGround(C.get_active_held_item()))
+43
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
@@ -1,6 +1,8 @@
/obj/effect/proc_holder/spell/targeted/touch
var/hand_path = /obj/item/melee/touch_attack
var/obj/item/melee/touch_attack/attached_hand = null
var/drawmessage = "You channel the power of the spell to your hand."
var/dropmessage = "You draw the power out of your hand."
invocation_type = "none" //you scream on connecting, not summoning
include_user = 1
range = -1
@@ -21,7 +23,7 @@
/obj/effect/proc_holder/spell/targeted/touch/cast(list/targets,mob/user = usr)
if(!QDELETED(attached_hand))
remove_hand(TRUE)
to_chat(user, "<span class='notice'>You draw the power out of your hand.</span>")
to_chat(user, "<span class='notice'>[dropmessage]</span>")
return
for(var/mob/living/carbon/C in targets)
@@ -43,7 +45,7 @@
remove_hand(TRUE)
to_chat(user, "<span class='warning'>Your hands are full!</span>")
return FALSE
to_chat(user, "<span class='notice'>You channel the power of the spell to your hand.</span>")
to_chat(user, "<span class='notice'>[drawmessage]</span>")
return TRUE
@@ -103,6 +103,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")
@@ -112,7 +113,7 @@
for(var/X in C.dna.mutations) //some mutations require having specific limbs to be kept.
var/datum/mutation/human/MT = X
if(MT.limb_req && MT.limb_req == body_zone)
MT.force_lose(C)
C.dna.force_lose(MT)
for(var/X in C.internal_organs) //internal organs inside the dismembered limb are dropped.
var/obj/item/organ/O = X
@@ -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")
@@ -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")