Refactors DNA Mutations; Refactors Mutations to use Traits (#15483)

* Refactors Mutations

* traits

* more work

* styling fix

* yet even more work

* oh hush

* almost there

* it continues yet further

* and that's genetics done

* and that's it folks

* last bit and golem fixup

* oof

* oops

* tweaks and fixes

* styling
This commit is contained in:
Fox McCloud
2021-02-21 21:25:19 +00:00
committed by GitHub
parent 324af7454c
commit 02b9445b9b
223 changed files with 2908 additions and 3049 deletions
+6 -12
View File
@@ -32,18 +32,12 @@
#define OBLITERATION 32
//Bitflags defining which status effects could be or are inflicted on a mob
#define CANSTUN 1
#define CANWEAKEN 2
#define CANPARALYSE 4
#define CANPUSH 8
#define PASSEMOTES 16 //Mob has a cortical borer or holders inside of it that need to see emotes.
#define GOTTAGOFAST 32
#define IGNORESLOWDOWN 128
#define IGNORE_SPEED_CHANGES 256
#define GOTTAGONOTSOFAST 512 //This is used for nukacola, mormal meth is a "1" speed up, nuka is 0.5 and they don't stack, feel free to use this one somewhere else
#define GODMODE 4096
#define FAKEDEATH 8192 //Replaces stuff like changeling.changeling_fakedeath
#define XENO_HOST 16384 //Tracks whether we're gonna be a baby alien's mummy.
#define CANSTUN 1
#define CANWEAKEN 2
#define CANPARALYSE 4
#define CANPUSH 8
#define PASSEMOTES 16 //Mob has a cortical borer or holders inside of it that need to see emotes.
#define GODMODE 32
//Health Defines
#define HEALTH_THRESHOLD_CRIT 0
-4
View File
@@ -35,10 +35,6 @@
#define INFORM_ADMINS_ON_RELOCATE_2 32
#define BANG_PROTECT_2 64
// An item worn in the ear slot with HEALS_EARS will heal your ears each
// Life() tick, even if normally your ears would be too damaged to heal.
#define HEALS_EARS_2 128
// A mob with OMNITONGUE has no restriction in the ability to speak
// languages that they know. So even if they wouldn't normally be able to
// through mob or tongue restrictions, this flag allows them to ignore
+6 -75
View File
@@ -25,60 +25,7 @@
// MUTATIONS
///////////////////////////////////////
// Generic mutations:
#define TK "telekenesis"
#define COLDRES "cold_resistance"
#define XRAY "xray"
#define HULK "hulk"
#define CLUMSY "clumsy"
#define FAT "fat"
#define HUSK "husk"
#define NOCLONE "noclone"
#define LASER "eyelaser" // harm intent - click anywhere to shoot lasers from eyes
#define WINGDINGS "wingdings" // Ayy lmao
#define SKELETON "skeleton"
#define BREATHLESS "breathless" // no breathing
#define REMOTE_VIEW "remove_view" // remote viewing
#define REGEN "regeneration" // health regen
#define RUN "increased_run" // no slowdown
#define REMOTE_TALK "remote_talk" // remote talking
#define MORPH "morph" // changing appearance
#define HEATRES "heat_resistance" // heat resistance
#define HALLUCINATE "hallucinate" // hallucinations
#define FINGERPRINTS "no_prints" // no fingerprints
#define NO_SHOCK "no_shock" // insulated hands
#define DWARF "dwarf" // table climbing
#define OBESITY "obesity" // Decreased metabolism
#define STRONG "strong" // (Nothing)
#define SOBER "sober" // Increased alcohol metabolism
#define PSY_RESIST "psy_resist" // Block remoteview
#define EMPATH "empathy" //Read minds
#define COMIC "comic_sans" //Comic Sans
#define LOUD "loudness" // CAUSES INTENSE YELLING
#define DIZZY "dizzy" // Trippy.
#define LISP "lisp"
#define RADIOACTIVE "radioactive"
#define CHAV "chav"
#define SWEDISH "swedish"
#define SCRAMBLED "scrambled"
#define HORNS "horns"
#define IMMOLATE "immolate"
#define CLOAK "cloak"
#define CHAMELEON "chameleon"
#define CRYO "cryokinesis"
#define EATER "matter_eater"
#define JUMPY "jumpy"
#define POLYMORPH "polymorph"
//disabilities
#define NEARSIGHTED "nearsighted"
#define EPILEPSY "epilepsy"
#define COUGHING "coughing"
#define TOURETTES "tourettes"
#define NERVOUS "nervous"
#define BLINDNESS "blind"
#define COLOURBLIND "colorblind"
#define MUTE "mute"
#define DEAF "deaf"
//Nutrition levels for humans. No idea where else to put it
#define NUTRITION_LEVEL_FAT 600
@@ -126,28 +73,12 @@
#define CLONER_MATURE_CLONE "mature"
//Species traits.
#define NO_BLOOD "no_blood"
#define NOTRANSSTING "no_trans_sting"
#define IS_WHITELISTED "whitelisted"
#define LIPS "lips"
#define NO_BLOOD "no_blood"
#define NO_BREATHE "no_breathe"
#define NO_DNA "no_dna"
#define NO_SCAN "no_scan"
#define NO_PAIN "no_pain"
#define IS_PLANT "is_plant"
#define EXOTIC_COLOR "exotic_blood_color"
#define NO_INTORGANS "no_internal_organs"
#define RADIMMUNE "rad_immunity"
#define NOGUNS "no_guns"
#define NOTRANSSTING "no_trans_sting"
#define VIRUSIMMUNE "virus_immunity"
#define NOCRITDAMAGE "no_crit"
#define RESISTHOT "resist_heat"
#define RESISTCOLD "resist_cold"
#define NO_EXAMINE "no_examine"
#define CAN_WINGDINGS "can_wingdings"
#define NO_GERMS "no_germs"
#define NO_DECAY "no_decay"
#define PIERCEIMMUNE "pierce_immunity"
#define NO_HUNGER "no_hunger"
#define EXOTIC_COLOR "exotic_blood_colour"
#define NO_OBESITY "no_obesity"
#define NO_CLONESCAN "no_clone_scan"
#define IS_PLANT "is_plant" // Convert this to a biotype TODO
+2
View File
@@ -24,6 +24,8 @@
#define is_cleanable(A) (istype(A, /obj/effect/decal/cleanable) || istype(A, /obj/effect/rune)) //if something is cleanable
#define isclothing(A) (istype(A, /obj/item/clothing))
#define is_pen(W) (istype(W, /obj/item/pen))
GLOBAL_LIST_INIT(pointed_types, typecacheof(list(
+5
View File
@@ -19,3 +19,8 @@
#define REAGENT_TOUCH 1
#define REAGENT_INGEST 2
///Health threshold for synthflesh and rezadone to unhusk someone
#define UNHUSK_DAMAGE_THRESHOLD 50
///Amount of synthflesh required to unhusk someone
#define SYNTHFLESH_UNHUSK_AMOUNT 100
+114 -8
View File
@@ -1,3 +1,6 @@
#define SIGNAL_ADDTRAIT(trait_ref) "addtrait [trait_ref]"
#define SIGNAL_REMOVETRAIT(trait_ref) "removetrait [trait_ref]"
// trait accessor defines
#define ADD_TRAIT(target, trait, source) \
do { \
@@ -6,12 +9,14 @@
target.status_traits = list(); \
_L = target.status_traits; \
_L[trait] = list(source); \
SEND_SIGNAL(target, SIGNAL_ADDTRAIT(trait), trait); \
} else { \
_L = target.status_traits; \
if (_L[trait]) { \
_L[trait] |= list(source); \
} else { \
_L[trait] = list(source); \
SEND_SIGNAL(target, SIGNAL_ADDTRAIT(trait), trait); \
} \
} \
} while (0)
@@ -31,7 +36,8 @@
} \
};\
if (!length(_L[trait])) { \
_L -= trait \
_L -= trait; \
SEND_SIGNAL(target, SIGNAL_REMOVETRAIT(trait), trait); \
}; \
if (!length(_L)) { \
target.status_traits = null \
@@ -46,31 +52,131 @@
for (var/_T in _L) { \
_L[_T] &= _S;\
if (!length(_L[_T])) { \
_L -= _T } \
};\
if (!length(_L)) { \
target.status_traits = null\
_L -= _T; \
SEND_SIGNAL(target, SIGNAL_REMOVETRAIT(_T), _T); \
}; \
};\
if (!length(_L)) { \
target.status_traits = null\
};\
}\
} while (0)
#define REMOVE_TRAITS_IN(target, sources) \
do { \
var/list/_L = target.status_traits; \
var/list/_S = sources; \
if (sources && !islist(sources)) { \
_S = list(sources); \
} else { \
_S = sources\
}; \
if (_L) { \
for (var/_T in _L) { \
_L[_T] -= _S;\
if (!length(_L[_T])) { \
_L -= _T; \
SEND_SIGNAL(target, SIGNAL_REMOVETRAIT(_T)); \
}; \
};\
if (!length(_L)) { \
target.status_traits = null\
};\
}\
} while (0)
#define HAS_TRAIT(target, trait) (target.status_traits ? (target.status_traits[trait] ? TRUE : FALSE) : FALSE)
#define HAS_TRAIT_FROM(target, trait, source) (target.status_traits ? (target.status_traits[trait] ? (source in target.status_traits[trait]) : FALSE) : FALSE)
#define HAS_TRAIT_FROM_ONLY(target, trait, source) (\
target.status_traits ?\
(target.status_traits[trait] ?\
((source in target.status_traits[trait]) && (length(target.status_traits) == 1))\
: FALSE)\
: FALSE)
#define HAS_TRAIT_NOT_FROM(target, trait, source) (target.status_traits ? (target.status_traits[trait] ? (length(target.status_traits[trait] - source) > 0) : FALSE) : FALSE)
/*
Remember to update _globalvars/traits.dm if you're adding/removing/renaming traits.
*/
//mob traits
#define TRAIT_BLIND "blind"
#define TRAIT_MUTE "mute"
#define TRAIT_DEAF "deaf"
#define TRAIT_NEARSIGHT "nearsighted"
#define TRAIT_FAT "fat"
#define TRAIT_HUSK "husk"
#define TRAIT_BADDNA "baddna"
#define TRAIT_SKELETONIZED "skeletonized"
#define TRAIT_CLUMSY "clumsy"
#define TRAIT_CHUNKYFINGERS "chunkyfingers" //means that you can't use weapons with normal trigger guards.
#define TRAIT_PACIFISM "pacifism"
#define TRAIT_WATERBREATH "waterbreathing"
#define TRAIT_IGNORESLOWDOWN "ignoreslow"
#define TRAIT_IGNOREDAMAGESLOWDOWN "ignoredamageslowdown"
#define TRAIT_GOTTAGOFAST "gottagofast"
#define TRAIT_GOTTAGONOTSOFAST "gottagonotsofast"
#define TRAIT_FAKEDEATH "fakedeath" //Makes the owner appear as dead to most forms of medical examination
#define TRAIT_XENO_HOST "xeno_host" //Tracks whether we're gonna be a baby alien's mummy.
#define TRAIT_SHOCKIMMUNE "shock_immunity"
#define TRAIT_TESLA_SHOCKIMMUNE "tesla_shock_immunity"
#define TRAIT_RESISTHEAT "resist_heat"
#define TRAIT_RESISTHEATHANDS "resist_heat_handsonly" //For when you want to be able to touch hot things, but still want fire to be an issue.
#define TRAIT_RESISTCOLD "resist_cold"
#define TRAIT_RESISTHIGHPRESSURE "resist_high_pressure"
#define TRAIT_RESISTLOWPRESSURE "resist_low_pressure"
#define TRAIT_RADIMMUNE "rad_immunity"
#define TRAIT_GENELESS "geneless"
#define TRAIT_VIRUSIMMUNE "virus_immunity"
#define TRAIT_PIERCEIMMUNE "pierce_immunity"
#define TRAIT_NOFIRE "nonflammable"
#define TRAIT_NOHUNGER "no_hunger"
#define TRAIT_NOBREATH "no_breath"
#define TRAIT_NOCRITDAMAGE "no_crit"
#define TRAIT_XRAY_VISION "xray_vision"
#define TRAIT_THERMAL_VISION "thermal_vision"
#define TRAIT_XENO_IMMUNE "xeno_immune" //prevents xeno huggies implanting skeletons
#define TRAIT_BLOODCRAWL "bloodcrawl"
#define TRAIT_BLOODCRAWL_EAT "bloodcrawl_eat"
#define TRAIT_JESTER "jester"
#define TRAIT_TESLA_SHOCKIMMUNE "tesla_shock_immunity"
#define TRAIT_DWARF "dwarf"
#define TRAIT_COMIC_SANS "comic_sans"
#define TRAIT_NOFINGERPRINTS "no_fingerprints"
#define TRAIT_SLOWDIGESTION "slow_digestion"
#define TRAIT_COLORBLIND "colorblind"
#define TRAIT_WINGDINGS "wingdings"
#define TRAIT_WATERBREATH "waterbreathing"
#define TRAIT_NOFAT "no_fatness"
#define TRAIT_NOGERMS "no_germs"
#define TRAIT_NODECAY "no_decay"
#define TRAIT_NOEXAMINE "no_examine"
#define TRAIT_NOPAIN "no_pain"
//
// common trait sources
#define TRAIT_GENERIC "generic"
#define EYE_DAMAGE "eye_damage"
#define EAR_DAMAGE "ear_damage"
#define GENETIC_MUTATION "genetic"
#define OBESITY "obesity"
#define MAGIC_TRAIT "magic"
#define SPECIES_TRAIT "species"
#define ROUNDSTART_TRAIT "roundstart" //cannot be removed without admin intervention
#define CLOTHING_TRAIT "clothing"
#define CULT_TRAIT "cult"
#define INNATE_TRAIT "innate"
// unique trait sources
#define STATUE_MUTE "statue"
#define CHANGELING_DRAIN "drain"
#define TRAIT_HULK "hulk"
#define STASIS_MUTE "stasis"
#define SCRYING_ORB "scrying-orb"
#define CULT_EYES "cult_eyes"
#define DOGGO_SPACESUIT "doggo_spacesuit"
#define FLOORCLUWNE "floorcluwne"
//quirk traits
#define TRAIT_ALCOHOL_TOLERANCE "alcohol_tolerance"
//traits that should be properly converted to genetic mutations one day
#define TRAIT_LASEREYES "laser_eyes"
+50 -4
View File
@@ -5,11 +5,57 @@
*/
GLOBAL_LIST_INIT(traits_by_type, list(
/mob = list(
"TRAIT_BLIND" = TRAIT_BLIND,
"TRAIT_MUTE" = TRAIT_MUTE,
"TRAIT_DEAF" = TRAIT_DEAF,
"TRAIT_NEARSIGHT" = TRAIT_NEARSIGHT,
"TRAIT_FAT" = TRAIT_FAT,
"TRAIT_HUSK" = TRAIT_HUSK,
"TRAIT_BADDNA" = TRAIT_BADDNA,
"TRAIT_SKELETONIZED" = TRAIT_SKELETONIZED,
"TRAIT_CLUMSY" = TRAIT_CLUMSY,
"TRAIT_CHUNKYFINGERS" = TRAIT_CHUNKYFINGERS,
"TRAIT_PACIFISM" = TRAIT_PACIFISM,
"TRAIT_WATERBREATH" = TRAIT_WATERBREATH,
"BLOODCRAWL" = TRAIT_BLOODCRAWL,
"BLOODCRAWL_EAT" = TRAIT_BLOODCRAWL_EAT,
"TRAIT_TESLA_SHOCKIMMUNE" = TRAIT_TESLA_SHOCKIMMUNE)))
"TRAIT_IGNORESLOWDOWN" = TRAIT_IGNORESLOWDOWN,
"TRAIT_IGNOREDAMAGESLOWDOWN" = TRAIT_IGNOREDAMAGESLOWDOWN,
"TRAIT_GOTTAGOFAST" = TRAIT_GOTTAGOFAST,
"TRAIT_GOTTAGONOTSOFAST" = TRAIT_GOTTAGONOTSOFAST,
"TRAIT_FAKEDEATH" = TRAIT_FAKEDEATH,
"TRAIT_XENO_HOST" = TRAIT_XENO_HOST,
"TRAIT_SHOCKIMMUNE" = TRAIT_SHOCKIMMUNE,
"TRAIT_TESLA_SHOCKIMMUNE" = TRAIT_TESLA_SHOCKIMMUNE,
"TRAIT_RESISTHEAT" = TRAIT_RESISTHEAT,
"TRAIT_RESISTHEATHANDS" = TRAIT_RESISTHEATHANDS,
"TRAIT_RESISTCOLD" = TRAIT_RESISTCOLD,
"TRAIT_RESISTHIGHPRESSURE" = TRAIT_RESISTHIGHPRESSURE,
"TRAIT_RESISTLOWPRESSURE" = TRAIT_RESISTLOWPRESSURE,
"TRAIT_RADIMMUNE" = TRAIT_RADIMMUNE,
"TRAIT_GENELESS" = TRAIT_GENELESS,
"TRAIT_VIRUSIMMUNE" = TRAIT_VIRUSIMMUNE,
"TRAIT_PIERCEIMMUNE" = TRAIT_PIERCEIMMUNE,
"TRAIT_NOFIRE" = TRAIT_NOFIRE,
"TRAIT_NOHUNGER" = TRAIT_NOHUNGER,
"TRAIT_NOBREATH" = TRAIT_NOBREATH,
"TRAIT_NOCRITDAMAGE" = TRAIT_NOCRITDAMAGE,
"TRAIT_XRAY_VISION" = TRAIT_XRAY_VISION,
"TRAIT_THERMAL_VISION" = TRAIT_THERMAL_VISION,
"TRAIT_XENO_IMMUNE" = TRAIT_XENO_IMMUNE,
"TRAIT_BLOODCRAWL" = TRAIT_BLOODCRAWL,
"TRAIT_BLOODCRAWL_EAT" = TRAIT_BLOODCRAWL_EAT,
"TRAIT_DWARF" = TRAIT_DWARF,
"TRAIT_ALCOHOL_TOLERANCE" = TRAIT_ALCOHOL_TOLERANCE,
"TRAIT_COMIC_SANS" = TRAIT_COMIC_SANS,
"TRAIT_NOFINGERPRINTS" = TRAIT_NOFINGERPRINTS,
"TRAIT_SLOWDIGESTION" = TRAIT_SLOWDIGESTION,
"TRAIT_COLORBLIND" = TRAIT_COLORBLIND,
"TRAIT_WINGDINGS" = TRAIT_WINGDINGS,
"TRAIT_WATERBREATH" = TRAIT_WATERBREATH,
"TRAIT_NOFAT" = TRAIT_NOFAT,
"TRAIT_NOGERMS" = TRAIT_NOGERMS,
"TRAIT_NODECAY" = TRAIT_NODECAY,
"TRAIT_NOEXAMINE" = TRAIT_NOEXAMINE,
"TRAIT_NOPAIN" = TRAIT_NOPAIN)))
/// value -> trait name, generated on use from trait_by_type global
GLOBAL_LIST(trait_name_map)
+3 -3
View File
@@ -12,7 +12,7 @@
if(proximity && istype(G) && G.Touch(A, 1))
return
if(HULK in mutations)
if(HAS_TRAIT(src, TRAIT_HULK))
if(proximity) //no telekinetic hulk attack
if(A.attack_hulk(src))
return
@@ -42,10 +42,10 @@
if(istype(G) && G.Touch(A, 0)) // for magic gloves
return
if((LASER in mutations) && a_intent == INTENT_HARM)
if(HAS_TRAIT(src, TRAIT_LASEREYES) && a_intent == INTENT_HARM)
LaserEyes(A)
if(TK in mutations)
if(dna.GetSEState(GLOB.teleblock))
A.attack_tk(src)
if(isturf(A) && get_dist(src, A) <= 1)
+3 -3
View File
@@ -39,11 +39,11 @@
/obj/item/attack_tk(mob/user)
if(user.stat || !isturf(loc))
return
if((TK in user.mutations) && !user.get_active_hand()) // both should already be true to get here
if(user.dna?.GetSEState(GLOB.teleblock) && !user.get_active_hand()) // both should already be true to get here
var/obj/item/tk_grab/O = new(src)
O.form_grab(user, src)
else
warning("Strange attack_tk(): TK([TK in user.mutations]) empty hand([!user.get_active_hand()])")
warning("Strange attack_tk(): TK([user.dna?.GetSEState(GLOB.teleblock)]) empty hand([!user.get_active_hand()])")
/mob/attack_tk(mob/user)
@@ -109,7 +109,7 @@
if(!host || host != user)
qdel(src)
return
if(!(TK in host.mutations))
if(!host.dna?.GetSEState(GLOB.teleblock))
qdel(src)
return
if(isobj(target) && !isturf(target.loc))
+1 -1
View File
@@ -500,7 +500,7 @@ SUBSYSTEM_DEF(jobs)
job.after_spawn(H)
//Gives glasses to the vision impaired
if(NEARSIGHTED in H.mutations)
if(HAS_TRAIT(H, TRAIT_NEARSIGHT))
var/equipped = H.equip_to_slot_or_del(new /obj/item/clothing/glasses/regular(H), slot_glasses)
if(equipped != 1)
var/obj/item/clothing/glasses/G = H.glasses
+1 -1
View File
@@ -24,7 +24,7 @@
if(ishuman(AM))
var/mob/living/carbon/human/H = AM
if(PIERCEIMMUNE in H.dna.species.species_traits)
if(HAS_TRAIT(H, TRAIT_PIERCEIMMUNE))
return
if((flags & CALTROP_IGNORE_WALKERS) && H.m_intent == MOVE_INTENT_WALK)
+4 -3
View File
@@ -142,11 +142,12 @@
/mob/living/carbon/human/CanContractDisease(datum/disease/D)
if((VIRUSIMMUNE in dna.species.species_traits) && !D.bypasses_immunity)
return 0
if(HAS_TRAIT(src, TRAIT_VIRUSIMMUNE) && !D.bypasses_immunity)
return FALSE
for(var/thing in D.required_organs)
if(!((locate(thing) in bodyparts) || (locate(thing) in internal_organs)))
return 0
return FALSE
return ..()
/mob/living/carbon/human/monkey/CanContractDisease(datum/disease/D)
@@ -16,7 +16,6 @@ Bonus
*/
/datum/symptom/deafness
name = "Deafness"
stealth = -1
resistance = -2
@@ -29,15 +28,12 @@ Bonus
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
var/obj/item/organ/internal/ears/ears = M.get_organ_slot("ears")
if(!ears)
return //cutting off your ears to cure the deafness: the ultimate own
switch(A.stage)
if(3, 4)
to_chat(M, "<span class='warning'>[pick("You hear a ringing in your ear.", "Your ears pop.")]</span>")
if(5)
if(!(DEAF in M.mutations))
to_chat(M, "<span class='userdanger'>Your ears pop and begin ringing loudly!</span>")
M.BecomeDeaf()
spawn(200)
if(M)
to_chat(M, "<span class='warning'>The ringing in your ears fades...</span>")
M.CureDeaf()
return
to_chat(M, "<span class='userdanger'>Your ears pop and begin ringing loudly!</span>")
ears.deaf = min(20, ears.deaf + 15)
@@ -44,7 +44,8 @@ Bonus
M.EyeBlurry(30)
eyes.receive_damage(5)
if(eyes.damage >= 10)
M.BecomeNearsighted()
M.become_nearsighted(EYE_DAMAGE)
if(prob(eyes.damage - 10 + 1))
if(M.BecomeBlind())
if(!M.eye_blind)
to_chat(M, "<span class='userdanger'>You go blind!</span>")
eyes.receive_damage(eyes.max_damage)
+1 -1
View File
@@ -157,7 +157,7 @@
/datum/disease/critical/hypoglycemia/has_cure()
if(ishuman(affected_mob))
var/mob/living/carbon/human/H = affected_mob
if(NO_HUNGER in H.dna.species.species_traits)
if(HAS_TRAIT(H, TRAIT_NOHUNGER))
return TRUE
if(ismachineperson(H))
return TRUE
+1 -1
View File
@@ -201,7 +201,7 @@
/datum/dog_fashion/back/hardsuit/apply(mob/living/simple_animal/pet/dog/D)
..()
D.mutations.Add(BREATHLESS)
ADD_TRAIT(D, TRAIT_NOBREATH, DOGGO_SPACESUIT)
D.atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
D.minbodytemp = 0
+36
View File
@@ -0,0 +1,36 @@
/datum/element/earhealing
element_flags = ELEMENT_DETACH
var/list/user_by_item = list()
/datum/element/earhealing/New()
START_PROCESSING(SSdcs, src)
/datum/element/earhealing/Attach(datum/target)
. = ..()
if(!isitem(target))
return ELEMENT_INCOMPATIBLE
RegisterSignal(target, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED), .proc/equippedChanged)
/datum/element/earhealing/Detach(datum/target)
. = ..()
UnregisterSignal(target, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED))
user_by_item -= target
/datum/element/earhealing/proc/equippedChanged(datum/source, mob/living/carbon/user, slot)
SIGNAL_HANDLER
if(((slot == slot_l_ear) || (slot == slot_r_ear)) && istype(user))
user_by_item[source] = user
else
user_by_item -= source
/datum/element/earhealing/process()
for(var/i in user_by_item)
var/mob/living/carbon/user = user_by_item[i]
var/obj/item/organ/internal/ears/ears = user.get_int_organ(/obj/item/organ/internal/ears)
if(!ears || HAS_TRAIT_NOT_FROM(user, TRAIT_DEAF, EAR_DAMAGE))
continue
ears.deaf = max(ears.deaf - 0.25, (ears.ear_damage < 100 ? 0 : 1)) // Do not clear deafness if our ears are too damaged
ears.ear_damage = max(ears.ear_damage - 0.025, 0)
CHECK_TICK
+1 -1
View File
@@ -976,7 +976,7 @@
current.dna = changeling.absorbed_dna[1]
current.real_name = current.dna.real_name
current.UpdateAppearance()
domutcheck(current, null)
domutcheck(current)
log_admin("[key_name(usr)] has reset [key_name(current)]'s DNA")
message_admins("[key_name_admin(usr)] has reset [key_name_admin(current)]'s DNA")
+1 -1
View File
@@ -1052,7 +1052,7 @@
H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/raise_vampires)
to_chat(H, "You have gained the ability to Raise Vampires. This extremely powerful AOE ability affects all humans near you. Vampires/thralls are healed. Corpses are raised as vampires. Others are stunned, then brain damaged, then killed.")
H.dna.SetSEState(GLOB.jumpblock, 1)
genemutcheck(H, GLOB.jumpblock, null, MUTCHK_FORCED)
singlemutcheck(H, GLOB.jumpblock, MUTCHK_FORCED)
H.update_mutations()
H.gene_stability = 100
+2 -2
View File
@@ -57,8 +57,8 @@
equip_to_slot_if_possible(new /obj/item/clothing/mask/gas/clown_hat/nodrop, slot_wear_mask, TRUE, TRUE)
dna.SetSEState(GLOB.clumsyblock, TRUE, TRUE)
dna.SetSEState(GLOB.comicblock, TRUE, TRUE)
genemutcheck(src, GLOB.clumsyblock, null, MUTCHK_FORCED)
genemutcheck(src, GLOB.comicblock, null, MUTCHK_FORCED)
singlemutcheck(src, GLOB.clumsyblock, MUTCHK_FORCED)
singlemutcheck(src, GLOB.comicblock, MUTCHK_FORCED)
if(!(iswizard(src) || (mind && mind.special_role == SPECIAL_ROLE_WIZARD_APPRENTICE))) //Mutations are permanent on non-wizards. Can still be removed by genetics fuckery but not mutadone.
dna.default_blocks.Add(GLOB.clumsyblock)
dna.default_blocks.Add(GLOB.comicblock)
+7 -11
View File
@@ -26,9 +26,8 @@
var/obj/item/organ/internal/honktumor/cursed/tumor = new
tumor.insert(src)
mutations.Add(NERVOUS)
dna.SetSEState(GLOB.nervousblock, 1, 1)
genemutcheck(src, GLOB.nervousblock, null, MUTCHK_FORCED)
singlemutcheck(src, GLOB.nervousblock, MUTCHK_FORCED)
rename_character(real_name, "cluwne")
unEquip(w_uniform, 1)
@@ -55,15 +54,12 @@
if(tumor)
tumor.remove(src)
else
mutations.Remove(CLUMSY)
mutations.Remove(GLOB.comicblock)
dna.SetSEState(GLOB.clumsyblock,0)
dna.SetSEState(GLOB.comicblock,0)
genemutcheck(src, GLOB.clumsyblock, null, MUTCHK_FORCED)
genemutcheck(src, GLOB.comicblock, null, MUTCHK_FORCED)
mutations.Remove(NERVOUS)
dna.SetSEState(GLOB.nervousblock, 0)
genemutcheck(src, GLOB.nervousblock, null, MUTCHK_FORCED)
dna.SetSEState(GLOB.clumsyblock, FALSE)
dna.SetSEState(GLOB.comicblock, FALSE)
singlemutcheck(src, GLOB.clumsyblock, MUTCHK_FORCED)
singlemutcheck(src, GLOB.comicblock, MUTCHK_FORCED)
dna.SetSEState(GLOB.nervousblock, FALSE)
singlemutcheck(src, GLOB.nervousblock, MUTCHK_FORCED)
var/obj/item/clothing/under/U = w_uniform
unEquip(w_uniform, 1)
+29 -24
View File
@@ -2,31 +2,36 @@
name = "Genetic"
desc = "This spell inflicts a set of mutations and disabilities upon the target."
var/list/mutations = list() //mutation strings
var/duration = 100 //deciseconds
/*
Disabilities
1st bit - ?
2nd bit - ?
3rd bit - ?
4th bit - ?
5th bit - ?
6th bit - ?
*/
var/list/active_on = list()
var/list/traits = list() // traits
var/list/mutations = list() // mutation defines. Set these in Initialize. Refactor this nonsense one day
var/duration = 100 // deciseconds
/obj/effect/proc_holder/spell/targeted/genetic/cast(list/targets, mob/user = usr)
for(var/mob/living/target in targets)
for(var/x in mutations)
target.mutations.Add(x)
target.update_mutations() //update target's mutation overlays
var/mob/living/carbon/human/H = target
if(ishuman(target))
H.update_body()
spawn(duration)
target.mutations.Remove(mutations)
target.update_mutations()
if(ishuman(target))
H.update_body()
if(!target.dna)
continue
for(var/A in mutations)
target.dna.SetSEState(A, TRUE)
singlemutcheck(target, A, MUTCHK_FORCED)
for(var/A in traits)
ADD_TRAIT(target, A, MAGIC_TRAIT)
active_on += target
target.regenerate_icons()
if(duration < charge_max)
addtimer(CALLBACK(src, .proc/remove, target), duration, TIMER_OVERRIDE|TIMER_UNIQUE)
return
/obj/effect/proc_holder/spell/targeted/genetic/Destroy()
for(var/V in active_on)
remove(V)
return ..()
/obj/effect/proc_holder/spell/targeted/genetic/proc/remove(mob/living/carbon/target)
active_on -= target
if(!QDELETED(target))
for(var/A in mutations)
target.dna.SetSEState(A, FALSE)
singlemutcheck(target, A, MUTCHK_FORCED)
for(var/A in traits)
REMOVE_TRAIT(target, A, MAGIC_TRAIT)
target.regenerate_icons()
+1 -1
View File
@@ -50,5 +50,5 @@
equip_to_slot_if_possible(new /obj/item/clothing/under/mime/nodrop, slot_w_uniform, TRUE, TRUE)
equip_to_slot_if_possible(new /obj/item/clothing/suit/suspenders/nodrop, slot_wear_suit, TRUE, TRUE)
dna.SetSEState(GLOB.muteblock , TRUE, TRUE)
genemutcheck(src, GLOB.muteblock , null, MUTCHK_FORCED)
singlemutcheck(src, GLOB.muteblock, MUTCHK_FORCED)
dna.default_blocks.Add(GLOB.muteblock)
+5 -10
View File
@@ -88,21 +88,16 @@
include_user = 1
centcom_cancast = 0
mutations = list(LASER, HULK)
traits = list(TRAIT_LASEREYES)
duration = 300
cooldown_min = 300 //25 deciseconds reduction per rank
action_icon_state = "mutate"
sound = 'sound/magic/mutate.ogg'
/obj/effect/proc_holder/spell/targeted/genetic/mutate/cast(list/targets, mob/user = usr)
for(var/mob/living/target in targets)
target.dna.SetSEState(GLOB.hulkblock, 1)
genemutcheck(target, GLOB.hulkblock, null, MUTCHK_FORCED)
spawn(duration)
target.dna.SetSEState(GLOB.hulkblock, 0)
genemutcheck(target, GLOB.hulkblock, null, MUTCHK_FORCED)
..()
/obj/effect/proc_holder/spell/targeted/genetic/mutate/Initialize(mapload)
. = ..()
mutations = list(GLOB.hulkblock)
/obj/effect/proc_holder/spell/targeted/smoke
name = "Smoke"
@@ -304,7 +299,7 @@
sound = 'sound/magic/blind.ogg'
/obj/effect/proc_holder/spell/targeted/genetic/blind
mutations = list(BLINDNESS)
traits = list(TRAIT_BLIND)
duration = 300
sound = 'sound/magic/blind.ogg'
+4 -4
View File
@@ -54,8 +54,8 @@
/datum/status_effect/blooddrunk/on_apply()
. = ..()
if(.)
ADD_TRAIT(owner, TRAIT_IGNOREDAMAGESLOWDOWN, "blooddrunk")
if(ishuman(owner))
owner.status_flags |= IGNORESLOWDOWN
var/mob/living/carbon/human/H = owner
for(var/X in H.bodyparts)
var/obj/item/organ/external/BP = X
@@ -81,7 +81,7 @@
H.dna.species.clone_mod *= 10
H.dna.species.stamina_mod *= 10
add_attack_logs(owner, owner, "lost blood-drunk stun immunity", ATKLOG_ALL)
owner.status_flags &= ~IGNORESLOWDOWN
REMOVE_TRAIT(owner, TRAIT_IGNOREDAMAGESLOWDOWN, "blooddrunk")
if(islist(owner.stun_absorption) && owner.stun_absorption["blooddrunk"])
owner.stun_absorption -= "blooddrunk"
@@ -215,7 +215,7 @@
alert_type = /obj/screen/alert/status_effect/regenerative_core
/datum/status_effect/regenerative_core/on_apply()
owner.status_flags |= IGNORE_SPEED_CHANGES
ADD_TRAIT(owner, TRAIT_IGNOREDAMAGESLOWDOWN, id)
owner.adjustBruteLoss(-25)
owner.adjustFireLoss(-25)
owner.remove_CC()
@@ -231,4 +231,4 @@
return TRUE
/datum/status_effect/regenerative_core/on_remove()
owner.status_flags &= ~IGNORE_SPEED_CHANGES
REMOVE_TRAIT(owner, TRAIT_IGNOREDAMAGESLOWDOWN, id)
@@ -36,7 +36,7 @@
if(prob(40))
if(ishuman(L))
var/mob/living/carbon/human/H = L
if(!(RADIMMUNE in H.dna.species.species_traits))
if(!HAS_TRAIT(H, TRAIT_RADIMMUNE))
if(prob(max(0, 100 - resist)))
randmuti(H) // Applies bad mutation
if(prob(50))
@@ -44,7 +44,7 @@
randmutb(H)
else
randmutg(H)
domutcheck(H, null, 1)
domutcheck(H, MUTCHK_FORCED)
L.rad_act(20)
+1 -1
View File
@@ -105,7 +105,7 @@
if(ishuman(user))
var/mob/living/carbon/human/H = user
var/obj/item/organ/internal/eyes/eyes = H.get_int_organ(/obj/item/organ/internal/eyes)
if(eyes && (COLOURBLIND in H.mutations)) // Check if the human has colorblindness.
if(eyes && HAS_TRAIT(H, TRAIT_COLORBLIND)) // Check if the human has colorblindness.
replace_colors = eyes.replace_colours // Get the colorblind replacement colors list.
var/list/wires_list = list()
+1 -1
View File
@@ -575,7 +575,7 @@
add_fibers(M)
//He has no prints!
if(FINGERPRINTS in M.mutations)
if(HAS_TRAIT(M, TRAIT_NOFINGERPRINTS))
if(fingerprintslast != M.key)
fingerprintshidden += "(Has no fingerprints) Real name: [M.real_name], Key: [M.key]"
fingerprintslast = M.key
+3 -3
View File
@@ -96,7 +96,7 @@
//helper for getting the appropriate health status
/proc/RoundHealth(mob/living/M)
if(M.stat == DEAD || (M.status_flags & FAKEDEATH))
if(M.stat == DEAD || (HAS_TRAIT(M, TRAIT_FAKEDEATH)))
return "health-100-dead" //what's our health? it doesn't matter, we're dead, or faking
var/maxi_health = M.maxHealth
@@ -178,7 +178,7 @@
/mob/living/carbon/med_hud_set_status()
var/image/holder = hud_list[STATUS_HUD]
var/mob/living/simple_animal/borer/B = has_brain_worms()
var/dead = stat == DEAD || (status_flags & FAKEDEATH)
var/dead = stat == DEAD || HAS_TRAIT(src, TRAIT_FAKEDEATH)
// To the right of health bar
if(dead)
var/revivable = timeofdeath && (round(world.time - timeofdeath) < DEFIB_TIME_LIMIT)
@@ -186,7 +186,7 @@
holder.icon_state = "hudflatline"
else
holder.icon_state = "huddead"
else if(status_flags & XENO_HOST)
else if(HAS_TRAIT(src, TRAIT_XENO_HOST))
holder.icon_state = "hudxeno"
else if(B && B.controlling)
holder.icon_state = "hudbrainworm"
+6 -6
View File
@@ -9,12 +9,12 @@
// and to tell our new DNA datum which values to set in order to turn something
// on or off.
GLOBAL_LIST_INIT(dna_activity_bounds, new(DNA_SE_LENGTH))
GLOBAL_LIST_INIT(assigned_gene_blocks, new(DNA_SE_LENGTH))
GLOBAL_LIST_INIT(assigned_mutation_blocks, new(DNA_SE_LENGTH))
// Used to determine what each block means (admin hax and species stuff on /vg/, mostly)
GLOBAL_LIST_INIT(assigned_blocks, new(DNA_SE_LENGTH))
GLOBAL_LIST_EMPTY(dna_genes)
GLOBAL_LIST_EMPTY(dna_mutations)
GLOBAL_LIST_EMPTY(good_blocks)
GLOBAL_LIST_EMPTY(bad_blocks)
@@ -173,7 +173,7 @@ GLOBAL_LIST_EMPTY(bad_blocks)
var/value = GetUIValue(block)
return round(1 + (value / 4096) * maxvalue)
// Is the UI gene "on" or "off"?
// Is the UI mutation "on" or "off"?
// For UI, this is simply a check of if the value is > 2050.
/datum/dna/proc/GetUIState(block)
if(block <= 0)
@@ -181,7 +181,7 @@ GLOBAL_LIST_EMPTY(bad_blocks)
return UI[block] > 2050
// Set UI gene "on" (1) or "off" (0)
// Set UI mutation "on" (1) or "off" (0)
/datum/dna/proc/SetUIState(block, on, defer = FALSE)
if(block <= 0)
return
@@ -299,7 +299,7 @@ GLOBAL_LIST_EMPTY(bad_blocks)
var/value = GetSEValue(block)
return round(1 + (value / 4096) * maxvalue)
// Is the block "on" (1) or "off" (0)? (Un-assigned genes are always off.)
// Is the block "on" (1) or "off" (0)? (Un-assigned mutations are always off.)
/datum/dna/proc/GetSEState(block)
if(block <= 0)
return FALSE
@@ -443,4 +443,4 @@ GLOBAL_LIST_EMPTY(bad_blocks)
destination.dna.species.handle_dna(destination) // Handle DNA has to be re-called as the DNA was changed.
destination.UpdateAppearance()
domutcheck(destination, null, MUTCHK_FORCED)
domutcheck(destination, MUTCHK_FORCED)
+21 -32
View File
@@ -1,67 +1,56 @@
// (Re-)Apply mutations.
// TODO: Turn into a /mob proc, change inj to a bitflag for various forms of differing behavior.
// M: Mob to mess with
// connected: Machine we're in, type unchecked so I doubt it's used beyond monkeying
// flags: See below, bitfield.
/proc/domutcheck(mob/living/M, connected = null, flags = 0)
for(var/datum/dna/gene/gene in GLOB.dna_genes)
/proc/domutcheck(mob/living/M, flags = 0)
for(var/datum/mutation/mutation in GLOB.dna_mutations)
if(!M || !M.dna)
return
if(!gene.block)
if(!mutation.block)
continue
domutation(gene, M, connected, flags)
domutation(mutation, M, flags)
// Use this to force a mut check on a single gene!
/proc/genemutcheck(mob/living/M, block, connected = null, flags = 0)
if(ishuman(M)) // Would've done this via species instead of type, but the basic mob doesn't have a species, go figure.
var/mob/living/carbon/human/H = M
if(NO_DNA in H.dna.species.species_traits)
return
// Use this to force a mut check on a single mutation!
/proc/singlemutcheck(mob/living/M, block, flags = 0)
if(!M)
return
if(HAS_TRAIT(M, TRAIT_GENELESS))
return
if(block < 0)
return
var/datum/dna/gene/gene = GLOB.assigned_gene_blocks[block]
domutation(gene, M, connected, flags)
var/datum/mutation/mutation = GLOB.assigned_mutation_blocks[block]
domutation(mutation, M, flags)
/proc/domutation(datum/dna/gene/gene, mob/living/M, connected = null, flags = 0)
if(!gene || !istype(gene))
/proc/domutation(datum/mutation/mutation, mob/living/M, flags = 0)
if(!mutation || !istype(mutation))
return FALSE
// Current state
var/gene_active = M.dna.GetSEState(gene.block)
var/mutation_active = M.dna.GetSEState(mutation.block)
// Sanity checks, don't skip.
if(!gene.can_activate(M,flags) && gene_active)
if(!mutation.can_activate(M, flags) && mutation_active)
//testing("[M] - Failed to activate [gene.name] (can_activate fail).")
return FALSE
var/defaultgenes // Do not mutate inherent species abilities
if(ishuman(M))
var/mob/living/carbon/human/H = M
defaultgenes = H.dna.species.default_genes
if((gene in defaultgenes) && gene_active)
return
// Prior state
var/gene_prior_status = (gene.type in M.active_genes)
var/changed = gene_active != gene_prior_status
var/mutation_prior_status = (mutation.type in M.active_mutations)
var/changed = mutation_active != mutation_prior_status
// If gene state has changed:
if(changed)
// Gene active (or ALWAYS ACTIVATE)
if(gene_active)
if(mutation_active)
//testing("[gene.name] activated!")
gene.activate(M,connected,flags)
mutation.activate(M)
if(M)
M.active_genes |= gene.type
M.active_mutations |= mutation.type
// If Gene is NOT active:
else
//testing("[gene.name] deactivated!")
gene.deactivate(M,connected,flags)
mutation.deactivate(M)
if(M)
M.active_genes -= gene.type
M.active_mutations -= mutation.type
+1 -1
View File
@@ -60,7 +60,7 @@
if(prob(prob))
M.dna.SetSEValue(i, rand(1, 4095), 1)
M.dna.UpdateSE()
domutcheck(M, null)
domutcheck(M)
// I haven't yet figured out what the fuck this is supposed to do.
/proc/miniscramble(input, rs, rd)
+8 -10
View File
@@ -312,10 +312,8 @@
if(!occupant)
return TRUE
if(ishuman(occupant))
var/mob/living/carbon/human/H = occupant
if(NO_DNA in H.dna.species.species_traits)
return TRUE
if(HAS_TRAIT(occupant, TRAIT_GENELESS))
return TRUE
var/radiation_protection = occupant.run_armor_check(null, "rad")
if(radiation_protection > NEGATE_MUTATION_THRESHOLD)
@@ -473,7 +471,7 @@
occupantData["name"] = connected.occupant.dna.real_name
occupantData["stat"] = connected.occupant.stat
occupantData["isViableSubject"] = 1
if((NOCLONE in connected.occupant.mutations && connected.scan_level < 3) || !connected.occupant.dna || (NO_DNA in connected.occupant.dna.species.species_traits))
if((HAS_TRAIT(connected.occupant, TRAIT_BADDNA) && connected.scan_level < 3) || !connected.occupant.dna || HAS_TRAIT(connected.occupant, TRAIT_GENELESS))
occupantData["isViableSubject"] = 0
occupantData["health"] = connected.occupant.health
occupantData["maxHealth"] = connected.occupant.maxHealth
@@ -604,7 +602,7 @@
if(prob(20 + radiation_intensity))
randmutb(connected.occupant)
domutcheck(connected.occupant, connected)
domutcheck(connected.occupant)
else
randmuti(connected.occupant)
connected.occupant.UpdateAppearance()
@@ -659,7 +657,7 @@
//testing("Irradiated SE block [real_SE_block]:[selected_se_subblock] ([original_block] now [block]) [(real_SE_block!=selected_se_block) ? "(SHIFTED)":""]!")
connected.occupant.dna.SetSESubBlock(real_SE_block, selected_se_subblock, block)
domutcheck(connected.occupant, connected)
domutcheck(connected.occupant)
else
var/radiation = (((radiation_intensity * 2) + radiation_duration) / connected.damage_coeff)
connected.occupant.apply_effect(radiation, IRRADIATE)
@@ -670,7 +668,7 @@
if(prob(80 - radiation_duration))
//testing("Random bad mut!")
randmutb(connected.occupant)
domutcheck(connected.occupant, connected)
domutcheck(connected.occupant)
else
randmuti(connected.occupant)
//testing("Random identity mut!")
@@ -723,7 +721,7 @@
if("changeLabel")
ui_modal_input(src, "changeBufferLabel", "Please enter the new buffer label:", null, list("id" = bufferId), buffer.name, UI_MODAL_INPUT_MAX_LENGTH_NAME)
if("transfer")
if(!connected.occupant || (NOCLONE in connected.occupant.mutations && connected.scan_level < 3) || !connected.occupant.dna)
if(!connected.occupant || (HAS_TRAIT(connected.occupant, TRAIT_BADDNA) && connected.scan_level < 3) || !connected.occupant.dna)
return
irradiating = 2
@@ -752,7 +750,7 @@
else if(buf.types & DNA2_BUF_SE)
connected.occupant.dna.SE = buf.dna.SE.Copy()
connected.occupant.dna.UpdateSE()
domutcheck(connected.occupant, connected)
domutcheck(connected.occupant)
if("createInjector")
if(!injector_ready)
return
-261
View File
@@ -1,261 +0,0 @@
/////////////////////
// DISABILITY GENES
//
// These activate either a mutation, disability
//
// Gene is always activated.
/////////////////////
/datum/dna/gene/disability
name = "DISABILITY"
// Mutation to give (or 0)
var/mutation = 0
// Activation message
var/activation_message = ""
// Yay, you're no longer growing 3 arms
var/deactivation_message = ""
/datum/dna/gene/disability/can_activate(mob/M, flags)
return TRUE // Always set!
/datum/dna/gene/disability/activate(mob/living/M, connected, flags)
..()
M.mutations |= mutation
if(activation_message)
to_chat(M, "<span class='warning'>[activation_message]</span>")
else
testing("[name] has no activation message.")
/datum/dna/gene/disability/deactivate(mob/living/M, connected, flags)
..()
M.mutations.Remove(mutation)
if(deactivation_message)
to_chat(M, "<span class='warning'>[deactivation_message]</span>")
else
testing("[name] has no deactivation message.")
/datum/dna/gene/disability/hallucinate
name = "Hallucinate"
activation_message = "Your mind says 'Hello'."
deactivation_message = "Sanity returns. Or does it?"
instability = -GENE_INSTABILITY_MODERATE
mutation = HALLUCINATE
/datum/dna/gene/disability/hallucinate/New()
..()
block = GLOB.hallucinationblock
/datum/dna/gene/disability/hallucinate/OnMobLife(mob/living/carbon/human/H)
if(prob(1))
H.AdjustHallucinate(45)
/datum/dna/gene/disability/epilepsy
name = "Epilepsy"
activation_message = "You get a headache."
deactivation_message = "Your headache is gone, at last."
instability = -GENE_INSTABILITY_MODERATE
mutation = EPILEPSY
/datum/dna/gene/disability/epilepsy/New()
..()
block = GLOB.epilepsyblock
/datum/dna/gene/disability/epilepsy/OnMobLife(mob/living/carbon/human/H)
if((prob(1) && H.paralysis < 1))
H.visible_message("<span class='danger'>[H] starts having a seizure!</span>","<span class='alert'>You have a seizure!</span>")
H.Paralyse(10)
H.Jitter(1000)
/datum/dna/gene/disability/cough
name = "Coughing"
activation_message = "You start coughing."
deactivation_message = "Your throat stops aching."
instability = -GENE_INSTABILITY_MINOR
mutation = COUGHING
/datum/dna/gene/disability/cough/New()
..()
block = GLOB.coughblock
/datum/dna/gene/disability/cough/OnMobLife(mob/living/carbon/human/H)
if((prob(5) && H.paralysis <= 1))
H.drop_item()
H.emote("cough")
/datum/dna/gene/disability/clumsy
name = "Clumsiness"
activation_message = "You feel lightheaded."
deactivation_message = "You regain some control of your movements"
instability = -GENE_INSTABILITY_MINOR
mutation = CLUMSY
/datum/dna/gene/disability/clumsy/New()
..()
block = GLOB.clumsyblock
/datum/dna/gene/disability/tourettes
name = "Tourettes"
activation_message = "You twitch."
deactivation_message = "Your mouth tastes like soap."
instability = -GENE_INSTABILITY_MODERATE
mutation = TOURETTES
/datum/dna/gene/disability/tourettes/New()
..()
block = GLOB.twitchblock
/datum/dna/gene/disability/tourettes/OnMobLife(mob/living/carbon/human/H)
if((prob(10) && H.paralysis <= 1))
H.Stun(10)
switch(rand(1, 3))
if(1)
H.emote("twitch")
if(2 to 3)
H.say("[prob(50) ? ";" : ""][pick("SHIT", "PISS", "FUCK", "CUNT", "COCKSUCKER", "MOTHERFUCKER", "TITS")]")
var/x_offset_old = H.pixel_x
var/y_offset_old = H.pixel_y
var/x_offset = H.pixel_x + rand(-2, 2)
var/y_offset = H.pixel_y + rand(-1, 1)
animate(H, pixel_x = x_offset, pixel_y = y_offset, time = 1)
animate(H, pixel_x = x_offset_old, pixel_y = y_offset_old, time = 1)
/datum/dna/gene/disability/nervousness
name = "Nervousness"
activation_message="You feel nervous."
deactivation_message ="You feel much calmer."
mutation = NERVOUS
/datum/dna/gene/disability/nervousness/New()
..()
block = GLOB.nervousblock
/datum/dna/gene/disability/nervousness/OnMobLife(mob/living/carbon/human/H)
if(prob(10))
H.Stuttering(10)
/datum/dna/gene/disability/blindness
name = "Blindness"
activation_message = "You can't seem to see anything."
deactivation_message = "You can see now, in case you didn't notice..."
instability = -GENE_INSTABILITY_MAJOR
mutation = BLINDNESS
/datum/dna/gene/disability/blindness/New()
..()
block = GLOB.blindblock
/datum/dna/gene/disability/blindness/activate(mob/M, connected, flags)
..()
M.update_blind_effects()
/datum/dna/gene/disability/blindness/deactivate(mob/M, connected, flags)
..()
M.update_blind_effects()
/datum/dna/gene/disability/colourblindness
name = "Colourblindness"
activation_message = "You feel a peculiar prickling in your eyes while your perception of colour changes."
deactivation_message ="Your eyes tingle unsettlingly, though everything seems to become alot more colourful."
instability = -GENE_INSTABILITY_MODERATE
mutation = COLOURBLIND
/datum/dna/gene/disability/colourblindness/New()
..()
block = GLOB.colourblindblock
/datum/dna/gene/disability/colourblindness/activate(mob/M, connected, flags)
..()
M.update_client_colour() //Handle the activation of the colourblindness on the mob.
M.update_icons() //Apply eyeshine as needed.
/datum/dna/gene/disability/colourblindness/deactivate(mob/M, connected, flags)
..()
M.update_client_colour() //Handle the deactivation of the colourblindness on the mob.
M.update_icons() //Remove eyeshine as needed.
/datum/dna/gene/disability/deaf
name = "Deafness"
activation_message="It's kinda quiet."
deactivation_message ="You can hear again!"
instability = -GENE_INSTABILITY_MAJOR
mutation = DEAF
/datum/dna/gene/disability/deaf/New()
..()
block = GLOB.deafblock
/datum/dna/gene/disability/deaf/activate(mob/M, connected, flags)
..()
M.MinimumDeafTicks(1)
/datum/dna/gene/disability/nearsighted
name = "Nearsightedness"
activation_message="Your eyes feel weird..."
deactivation_message ="You can see clearly now"
instability = -GENE_INSTABILITY_MODERATE
mutation = NEARSIGHTED
/datum/dna/gene/disability/nearsighted/New()
..()
block = GLOB.glassesblock
/datum/dna/gene/disability/nearsighted/activate(mob/living/M, connected, flags)
..()
M.update_nearsighted_effects()
/datum/dna/gene/disability/nearsighted/deactivate(mob/living/M, connected, flags)
..()
M.update_nearsighted_effects()
/datum/dna/gene/disability/lisp
name = "Lisp"
desc = "I wonder wath thith doeth."
activation_message = "Thomething doethn't feel right."
deactivation_message = "You now feel able to pronounce consonants."
mutation = LISP
/datum/dna/gene/disability/lisp/New()
..()
block = GLOB.lispblock
/datum/dna/gene/disability/lisp/OnSay(mob/M, message)
return replacetext(message,"s","th")
/datum/dna/gene/disability/comic
name = "Comic"
desc = "This will only bring death and destruction."
activation_message = "<span class='sans'>Uh oh!</span>"
deactivation_message = "Well thank god that's over with."
mutation = COMIC
/datum/dna/gene/disability/comic/New()
..()
block = GLOB.comicblock
/datum/dna/gene/disability/wingdings
name = "Alien Voice"
desc = "Garbles the subject's voice into an incomprehensible speech."
activation_message = "<span class='wingdings'>Your vocal cords feel alien.</span>"
deactivation_message = "Your vocal cords no longer feel alien."
instability = -GENE_INSTABILITY_MINOR
mutation = WINGDINGS
/datum/dna/gene/disability/wingdings/New()
..()
block = GLOB.wingdingsblock
/datum/dna/gene/disability/wingdings/OnSay(mob/M, message)
var/garbled_message = ""
for(var/i in 1 to length(message))
if(message[i] in GLOB.alphabet_uppercase)
garbled_message += pick(GLOB.alphabet_uppercase)
else if(message[i] in GLOB.alphabet)
garbled_message += pick(GLOB.alphabet)
else
garbled_message += message[i]
message = garbled_message
return message
-126
View File
@@ -1,126 +0,0 @@
/**
* Gene Datum
*
* domutcheck was getting pretty hairy. This is the solution.
*
* All genes are stored in a global variable to cut down on memory
* usage.
*
* @author N3X15 <nexisentertainment@gmail.com>
*/
/datum/dna/gene
// Display name
var/name = "BASE GENE"
// Probably won't get used but why the fuck not
var/desc="Oh god who knows what this does."
// Set in initialize()!
// What gene activates this?
var/block = 0
// Any of a number of GENE_ flags.
var/flags = 0
// Chance of the gene to cause adverse effects when active
var/instability = 0
/*
* Is the gene active in this mob's DNA?
*/
/datum/dna/gene/proc/is_active(mob/M)
return M.active_genes && (type in M.active_genes)
// Return 1 if we can activate.
// HANDLE MUTCHK_FORCED HERE!
/datum/dna/gene/proc/can_activate(mob/M, flags)
return FALSE
// Called when the gene activates. Do your magic here.
/datum/dna/gene/proc/activate(mob/living/M, connected, flags)
M.gene_stability -= instability
/**
* Called when the gene deactivates. Undo your magic here.
* Only called when the block is deactivated.
*/
/datum/dna/gene/proc/deactivate(mob/living/M, connected, flags)
M.gene_stability += instability
// This section inspired by goone's bioEffects.
/**
* Called in each life() tick.
*/
/datum/dna/gene/proc/OnMobLife(mob/M)
return
/**
* Called when the mob dies
*/
/datum/dna/gene/proc/OnMobDeath(mob/M)
return
/**
* Called when the mob says shit
*/
/datum/dna/gene/proc/OnSay(mob/M, message)
return message
/**
* Called after the mob runs update_icons.
*
* @params M The subject.
* @params g Gender (m or f)
*/
/datum/dna/gene/proc/OnDrawUnderlays(mob/M, g)
return FALSE
/////////////////////
// BASIC GENES
//
// These just chuck in a mutation and display a message.
//
// Gene is activated:
// 1. If mutation already exists in mob
// 2. If the probability roll succeeds
// 3. Activation is forced (done in domutcheck)
/////////////////////
/datum/dna/gene/basic
name = "BASIC GENE"
// Mutation to give
var/mutation = 0
// Activation probability
var/activation_prob = 100
// Possible activation messages
var/list/activation_messages = list()
// Possible deactivation messages
var/list/deactivation_messages = list()
/datum/dna/gene/basic/can_activate(mob/M, flags)
if(flags & MUTCHK_FORCED)
return TRUE
// Probability check
return prob(activation_prob)
/datum/dna/gene/basic/activate(mob/M, connected, flags)
..()
M.mutations.Add(mutation)
if(activation_messages.len)
var/msg = pick(activation_messages)
to_chat(M, "<span class='notice'>[msg]</span>")
/datum/dna/gene/basic/deactivate(mob/living/M, connected, flags)
..()
M.mutations.Remove(mutation)
if(deactivation_messages.len)
var/msg = pick(deactivation_messages)
to_chat(M, "<span class='warning'>[msg]</span>")
-292
View File
@@ -1,292 +0,0 @@
//////////////////
// DISABILITIES //
//////////////////
////////////////////////////////////////
// Totally Crippling
////////////////////////////////////////
// WAS: /datum/bioEffect/mute
/datum/dna/gene/disability/mute
name = "Mute"
desc = "Completely shuts down the speech center of the subject's brain."
activation_message = "You feel unable to express yourself at all."
deactivation_message = "You feel able to speak freely again."
instability = -GENE_INSTABILITY_MODERATE
mutation = MUTE
/datum/dna/gene/disability/mute/New()
..()
block = GLOB.muteblock
/datum/dna/gene/disability/mute/OnSay(mob/M, message)
return ""
////////////////////////////////////////
// Harmful to others as well as self
////////////////////////////////////////
/datum/dna/gene/disability/radioactive
name = "Radioactive"
desc = "The subject suffers from constant radiation sickness and causes the same on nearby organics."
activation_message = "You feel a strange sickness permeate your whole body."
deactivation_message = "You no longer feel awful and sick all over."
instability = -GENE_INSTABILITY_MAJOR
mutation = RADIOACTIVE
/datum/dna/gene/disability/radioactive/New()
..()
block = GLOB.radblock
/datum/dna/gene/disability/radioactive/can_activate(mob/M, flags)
if(!..())
return FALSE
if(ishuman(M))
var/mob/living/carbon/human/H = M
if((RADIMMUNE in H.dna.species.species_traits) && !(flags & MUTCHK_FORCED))
return FALSE
return TRUE
/datum/dna/gene/disability/radioactive/OnMobLife(mob/living/carbon/human/H)
radiation_pulse(H, 20)
/datum/dna/gene/disability/radioactive/OnDrawUnderlays(mob/M, g)
return "rads_s"
////////////////////////////////////////
// Other disabilities
////////////////////////////////////////
// WAS: /datum/bioEffect/fat
/datum/dna/gene/disability/fat
name = "Obesity"
desc = "Greatly slows the subject's metabolism, enabling greater buildup of lipid tissue."
activation_message = "You feel blubbery and lethargic!"
deactivation_message = "You feel fit!"
instability = -GENE_INSTABILITY_MINOR
mutation = OBESITY
/datum/dna/gene/disability/fat/New()
..()
block = GLOB.fatblock
// WAS: /datum/bioEffect/chav
/datum/dna/gene/disability/speech/chav
name = "Chav"
desc = "Forces the language center of the subject's brain to construct sentences in a more rudimentary manner."
activation_message = "Ye feel like a rite prat like, innit?"
deactivation_message = "You no longer feel like being rude and sassy."
mutation = CHAV
//List of swappable words. Normal word first, chav word second.
var/static/list/chavlinks = list(
"arrest" = "nick",
"arrested" = "nicked",
"ass" = "arse",
"bad" = "pants",
"bar" = "spoons",
"brain" = "noggin",
"break" = "smash",
"broke" = "smashed",
"broken" = "gone kaput",
"comdom" = "knob'ed",
"cool" = "ace",
"crazy" = "well mad",
"cup of tea" = "cuppa",
"destroyed" = "rekt",
"dick" = "prat",
"disappointed" = "gutted",
"disgusting" = "minging",
"disposals" = "bins",
"drink" = "bevvy",
"engineer" = "sparky",
"excited" = "jacked",
"fight" = "scuffle",
"food" = "nosh",
"friend" = "blud",
"fuck" = "fook",
"get" = "giz",
"girl" = "bird",
"go away" = "jog on",
"good" = "mint",
"great" = "bangin'",
"happy" = "chuffed",
"hello" = "orite",
"hi" = "sup",
"idiot" = "twit",
"isn't it" = "innit",
"kill" = "bang",
"killed" = "banged",
"man" = "bloke",
"mess" = "shambles",
"mistake" = "cock-up",
"murder" = "hench",
"murdered" = "henched",
"no" = "naw",
"really" = "propa",
"robust" = "'ard",
"run" = "leg it",
"sec" = "cops",
"security" = "coppers",
"silly" = "daft",
"steal" = "nick",
"stole" = "nicked",
"surprised" = "gobsmacked",
"suspicious" = "dodgy",
"tired" = "knackered",
"wet" = "moist",
"what" = "wot",
"window" = "windy",
"windows" = "windies",
"yes" = "ye",
"yikes" = "blimey",
"your" = "yur"
)
/datum/dna/gene/disability/speech/chav/New()
..()
block = GLOB.chavblock
/datum/dna/gene/disability/speech/chav/OnSay(mob/M, message)
var/static/regex/R = regex("\\b([chavlinks.Join("|")])\\b", "g")
message = R.Replace(message, /datum/dna/gene/disability/speech/chav/proc/replace_speech)
return message
/datum/dna/gene/disability/speech/chav/proc/replace_speech(matched)
return chavlinks[matched]
// WAS: /datum/bioEffect/swedish
/datum/dna/gene/disability/speech/swedish
name = "Swedish"
desc = "Forces the language center of the subject's brain to construct sentences in a vaguely norse manner."
activation_message = "You feel Swedish, however that works."
deactivation_message = "The feeling of Swedishness passes."
mutation = SWEDISH
/datum/dna/gene/disability/speech/swedish/New()
..()
block = GLOB.swedeblock
/datum/dna/gene/disability/speech/swedish/OnSay(mob/M, message)
// svedish
message = replacetextEx(message,"W","V")
message = replacetextEx(message,"w","v")
message = replacetextEx(message,"J","Y")
message = replacetextEx(message,"j","y")
message = replacetextEx(message,"A",pick("Å","Ä","Æ","A"))
message = replacetextEx(message,"a",pick("å","ä","æ","a"))
message = replacetextEx(message,"BO","BJO")
message = replacetextEx(message,"Bo","Bjo")
message = replacetextEx(message,"bo","bjo")
message = replacetextEx(message,"O",pick("Ö","Ø","O"))
message = replacetextEx(message,"o",pick("ö","ø","o"))
if(prob(30) && !M.is_muzzled())
message += " Bork[pick("",", bork",", bork, bork")]!"
return message
// WAS: /datum/bioEffect/unintelligable
/datum/dna/gene/disability/unintelligable
name = "Unintelligable"
desc = "Heavily corrupts the part of the brain responsible for forming spoken sentences."
activation_message = "You can't seem to form any coherent thoughts!"
deactivation_message = "Your mind feels more clear."
instability = -GENE_INSTABILITY_MINOR
mutation = SCRAMBLED
/datum/dna/gene/disability/unintelligable/New()
..()
block = GLOB.scrambleblock
/datum/dna/gene/disability/unintelligable/OnSay(mob/M, message)
var/prefix = copytext(message,1,2)
if(prefix == ";")
message = copytext(message,2)
else if(prefix in list(":","#"))
prefix += copytext(message,2,3)
message = copytext(message,3)
else
prefix=""
var/list/words = splittext(message," ")
var/list/rearranged = list()
for(var/i=1;i<=words.len;i++)
var/cword = pick(words)
words.Remove(cword)
var/suffix = copytext(cword,length(cword)-1,length(cword))
while(length(cword)>0 && (suffix in list(".",",",";","!",":","?")))
cword = copytext(cword,1 ,length(cword)-1)
suffix = copytext(cword,length(cword)-1,length(cword) )
if(length(cword))
rearranged += cword
return "[prefix][uppertext(jointext(rearranged," "))]!!"
//////////////////
// USELESS SHIT //
//////////////////
// WAS: /datum/bioEffect/strong
/datum/dna/gene/disability/strong
// pretty sure this doesn't do jack shit, putting it here until it does
name = "Strong"
desc = "Enhances the subject's ability to build and retain heavy muscles."
activation_message = "You feel buff!"
deactivation_message = "You feel wimpy and weak."
mutation = STRONG
/datum/dna/gene/disability/strong/New()
..()
block = GLOB.strongblock
// WAS: /datum/bioEffect/horns
/datum/dna/gene/disability/horns
name = "Horns"
desc = "Enables the growth of a compacted keratin formation on the subject's head."
activation_message = "A pair of horns erupt from your head."
deactivation_message = "Your horns crumble away into nothing."
mutation = HORNS
/datum/dna/gene/disability/horns/New()
..()
block = GLOB.hornsblock
/datum/dna/gene/disability/horns/OnDrawUnderlays(mob/M, g)
return "horns_s"
////////////////////////////////////////////////////////////////////////
// WAS: /datum/bioEffect/immolate
/datum/dna/gene/basic/grant_spell/immolate
name = "Incendiary Mitochondria"
desc = "The subject becomes able to convert excess cellular energy into thermal energy."
activation_messages = list("You suddenly feel rather hot.")
deactivation_messages = list("You no longer feel uncomfortably hot.")
mutation = IMMOLATE
spelltype = /obj/effect/proc_holder/spell/targeted/immolate
/datum/dna/gene/basic/grant_spell/immolate/New()
..()
block = GLOB.immolateblock
/obj/effect/proc_holder/spell/targeted/immolate
name = "Incendiary Mitochondria"
desc = "The subject becomes able to convert excess cellular energy into thermal energy."
panel = "Abilities"
charge_type = "recharge"
charge_max = 600
clothes_req = 0
stat_allowed = 0
invocation_type = "none"
range = -1
selection_type = "range"
var/list/compatible_mobs = list(/mob/living/carbon/human)
include_user = 1
action_icon_state = "genetic_incendiary"
/obj/effect/proc_holder/spell/targeted/immolate/cast(list/targets, mob/living/user = usr)
var/mob/living/carbon/L = user
L.adjust_fire_stacks(0.5)
L.visible_message("<span class='danger'>[L.name]</b> suddenly bursts into flames!</span>")
L.IgniteMob()
playsound(L.loc, 'sound/effects/bamf.ogg', 50, 0)
-620
View File
@@ -1,620 +0,0 @@
#define EAT_MOB_DELAY 300 // 30s
// WAS: /datum/bioEffect/alcres
/datum/dna/gene/basic/sober
name = "Sober"
activation_messages = list("You feel unusually sober.")
deactivation_messages = list("You feel like you could use a stiff drink.")
mutation = SOBER
/datum/dna/gene/basic/sober/New()
..()
block = GLOB.soberblock
//WAS: /datum/bioEffect/psychic_resist
/datum/dna/gene/basic/psychic_resist
name = "Psy-Resist"
desc = "Boosts efficiency in sectors of the brain commonly associated with meta-mental energies."
activation_messages = list("Your mind feels closed.")
deactivation_messages = list("You feel oddly exposed.")
mutation = PSY_RESIST
/datum/dna/gene/basic/psychic_resist/New()
..()
block = GLOB.psyresistblock
/////////////////////////
// Stealth Enhancers
/////////////////////////
/datum/dna/gene/basic/stealth
instability = GENE_INSTABILITY_MODERATE
/datum/dna/gene/basic/stealth/can_activate(mob/M, flags)
// Can only activate one of these at a time.
if(is_type_in_list(/datum/dna/gene/basic/stealth,M.active_genes))
testing("Cannot activate [type]: /datum/dna/gene/basic/stealth in M.active_genes.")
return FALSE
return ..()
/datum/dna/gene/basic/stealth/deactivate(mob/living/M, connected, flags)
..()
M.alpha = 255
// WAS: /datum/bioEffect/darkcloak
/datum/dna/gene/basic/stealth/darkcloak
name = "Cloak of Darkness"
desc = "Enables the subject to bend low levels of light around themselves, creating a cloaking effect."
activation_messages = list("You begin to fade into the shadows.")
deactivation_messages = list("You become fully visible.")
activation_prob = 25
mutation = CLOAK
/datum/dna/gene/basic/stealth/darkcloak/New()
..()
block = GLOB.shadowblock
/datum/dna/gene/basic/stealth/darkcloak/OnMobLife(mob/M)
var/turf/simulated/T = get_turf(M)
if(!istype(T))
return
var/light_available = T.get_lumcount() * 10
if(light_available <= 2)
M.alpha = round(M.alpha * 0.8)
else
M.alpha = 255
//WAS: /datum/bioEffect/chameleon
/datum/dna/gene/basic/stealth/chameleon
name = "Chameleon"
desc = "The subject becomes able to subtly alter light patterns to become invisible, as long as they remain still."
activation_messages = list("You feel one with your surroundings.")
deactivation_messages = list("You feel oddly visible.")
activation_prob = 25
mutation = CHAMELEON
/datum/dna/gene/basic/stealth/chameleon/New()
..()
block = GLOB.chameleonblock
/datum/dna/gene/basic/stealth/chameleon/OnMobLife(mob/M)
if((world.time - M.last_movement) >= 30 && !M.stat && M.canmove && !M.restrained())
M.alpha -= 25
else
M.alpha = round(255 * 0.80)
/////////////////////////////////////////////////////////////////////////////////////////
/datum/dna/gene/basic/grant_spell
var/obj/effect/proc_holder/spell/spelltype
/datum/dna/gene/basic/grant_spell/activate(mob/M, connected, flags)
M.AddSpell(new spelltype(null))
..()
return TRUE
/datum/dna/gene/basic/grant_spell/deactivate(mob/M, connected, flags)
for(var/obj/effect/proc_holder/spell/S in M.mob_spell_list)
if(istype(S, spelltype))
M.RemoveSpell(S)
..()
return TRUE
/datum/dna/gene/basic/grant_verb
var/verbtype
/datum/dna/gene/basic/grant_verb/activate(mob/M, connected, flags)
..()
M.verbs += verbtype
return TRUE
/datum/dna/gene/basic/grant_verb/deactivate(mob/M, connected, flags)
..()
M.verbs -= verbtype
// WAS: /datum/bioEffect/cryokinesis
/datum/dna/gene/basic/grant_spell/cryo
name = "Cryokinesis"
desc = "Allows the subject to lower the body temperature of others."
activation_messages = list("You notice a strange cold tingle in your fingertips.")
deactivation_messages = list("Your fingers feel warmer.")
instability = GENE_INSTABILITY_MODERATE
mutation = CRYO
spelltype = /obj/effect/proc_holder/spell/targeted/click/cryokinesis
/datum/dna/gene/basic/grant_spell/cryo/New()
..()
block = GLOB.cryoblock
/obj/effect/proc_holder/spell/targeted/click/cryokinesis
name = "Cryokinesis"
desc = "Drops the bodytemperature of another person."
panel = "Abilities"
charge_type = "recharge"
charge_max = 1200
clothes_req = FALSE
stat_allowed = FALSE
click_radius = 0
auto_target_single = FALSE // Give the clueless geneticists a way out and to have them not target themselves
selection_activated_message = "<span class='notice'>Your mind grow cold. Click on a target to cast the spell.</span>"
selection_deactivated_message = "<span class='notice'>Your mind returns to normal.</span>"
allowed_type = /mob/living/carbon
invocation_type = "none"
range = 7
selection_type = "range"
include_user = TRUE
var/list/compatible_mobs = list(/mob/living/carbon/human)
action_icon_state = "genetic_cryo"
/obj/effect/proc_holder/spell/targeted/click/cryokinesis/cast(list/targets, mob/user = usr)
var/mob/living/carbon/C = targets[1]
if(COLDRES in C.mutations)
C.visible_message("<span class='warning'>A cloud of fine ice crystals engulfs [C.name], but disappears almost instantly!</span>")
return
var/handle_suit = FALSE
if(ishuman(C))
var/mob/living/carbon/human/H = C
if(istype(H.head, /obj/item/clothing/head/helmet/space))
if(istype(H.wear_suit, /obj/item/clothing/suit/space))
handle_suit = TRUE
if(H.internal)
H.visible_message("<span class='warning'>[user] sprays a cloud of fine ice crystals, engulfing [H]!</span>",
"<span class='notice'>[user] sprays a cloud of fine ice crystals over your [H.head]'s visor.</span>")
else
H.visible_message("<span class='warning'>[user] sprays a cloud of fine ice crystals engulfing, [H]!</span>",
"<span class='warning'>[user] sprays a cloud of fine ice crystals cover your [H.head]'s visor and make it into your air vents!.</span>")
H.bodytemperature = max(0, H.bodytemperature - 100)
add_attack_logs(user, C, "Cryokinesis")
if(!handle_suit)
C.bodytemperature = max(0, C.bodytemperature - 200)
C.ExtinguishMob()
C.visible_message("<span class='warning'>[user] sprays a cloud of fine ice crystals, engulfing [C]!</span>")
add_attack_logs(user, C, "Cryokinesis- NO SUIT/INTERNALS")
//playsound(user.loc, 'bamf.ogg', 50, 0)
new/obj/effect/self_deleting(C.loc, icon('icons/effects/genetics.dmi', "cryokinesis"))
/obj/effect/self_deleting
density = 0
opacity = 0
anchored = 1
icon = null
desc = ""
//layer = 15
/obj/effect/self_deleting/New(atom/location, icon/I, duration = 20, oname = "something")
. = ..()
name = oname
loc=location
icon = I
QDEL_IN(src, duration)
///////////////////////////////////////////////////////////////////////////////////////////
// WAS: /datum/bioEffect/mattereater
/datum/dna/gene/basic/grant_spell/mattereater
name = "Matter Eater"
desc = "Allows the subject to eat just about anything without harm."
activation_messages = list("You feel hungry.")
deactivation_messages = list("You don't feel quite so hungry anymore.")
instability = GENE_INSTABILITY_MINOR
mutation = EATER
spelltype=/obj/effect/proc_holder/spell/targeted/eat
/datum/dna/gene/basic/grant_spell/mattereater/New()
..()
block = GLOB.eatblock
/obj/effect/proc_holder/spell/targeted/eat
name = "Eat"
desc = "Eat just about anything!"
panel = "Abilities"
charge_type = "recharge"
charge_max = 300
clothes_req = 0
stat_allowed = 0
invocation_type = "none"
range = 1
selection_type = "view"
action_icon_state = "genetic_eat"
var/list/types_allowed = list(
/obj/item,
/mob/living/simple_animal/pet,
/mob/living/simple_animal/hostile,
/mob/living/simple_animal/parrot,
/mob/living/simple_animal/crab,
/mob/living/simple_animal/mouse,
/mob/living/carbon/human,
/mob/living/simple_animal/slime,
/mob/living/carbon/alien/larva,
/mob/living/simple_animal/slime,
/mob/living/simple_animal/chick,
/mob/living/simple_animal/chicken,
/mob/living/simple_animal/lizard,
/mob/living/simple_animal/cow,
/mob/living/simple_animal/spiderbot
)
var/list/own_blacklist = list(
/obj/item/organ,
/obj/item/implant
)
/obj/effect/proc_holder/spell/targeted/eat/proc/doHeal(mob/user)
if(ishuman(user))
var/mob/living/carbon/human/H = user
for(var/name in H.bodyparts_by_name)
var/obj/item/organ/external/affecting = null
if(!H.bodyparts_by_name[name])
continue
affecting = H.bodyparts_by_name[name]
if(!istype(affecting, /obj/item/organ/external))
continue
affecting.heal_damage(4, 0, updating_health = FALSE)
H.UpdateDamageIcon()
H.updatehealth()
/obj/effect/proc_holder/spell/targeted/eat/choose_targets(mob/user = usr)
var/list/targets = new /list()
var/list/possible_targets = new /list()
if(!check_mouth(user))
revert_cast(user)
return
for(var/atom/movable/O in view_or_range(range, user, selection_type))
if((O in user) && is_type_in_list(O,own_blacklist))
continue
if(is_type_in_list(O,types_allowed))
if(isanimal(O))
var/mob/living/simple_animal/SA = O
if(!SA.gold_core_spawnable)
continue
possible_targets += O
targets += input("Choose the target of your hunger.", "Targeting") as null|anything in possible_targets
if(!targets.len || !targets[1]) //doesn't waste the spell
revert_cast(user)
return
if(!check_mouth(user))
revert_cast(user)
return
perform(targets, user = user)
/obj/effect/proc_holder/spell/targeted/eat/proc/check_mouth(mob/user = usr)
var/can_eat = TRUE
if(iscarbon(user))
var/mob/living/carbon/C = user
if((C.head && (C.head.flags_cover & HEADCOVERSMOUTH)) || (C.wear_mask && (C.wear_mask.flags_cover & MASKCOVERSMOUTH) && !C.wear_mask.mask_adjusted))
to_chat(C, "<span class='warning'>Your mouth is covered, preventing you from eating!</span>")
can_eat = FALSE
return can_eat
/obj/effect/proc_holder/spell/targeted/eat/cast(list/targets, mob/user = usr)
if(!targets.len)
to_chat(user, "<span class='notice'>No target found in range.</span>")
return
var/atom/movable/the_item = targets[1]
if(ishuman(the_item))
var/mob/living/carbon/human/H = the_item
var/obj/item/organ/external/limb = H.get_organ(user.zone_selected)
if(!istype(limb))
to_chat(user, "<span class='warning'>You can't eat this part of them!</span>")
revert_cast()
return FALSE
if(istype(limb,/obj/item/organ/external/head))
// Bullshit, but prevents being unable to clone someone.
to_chat(user, "<span class='warning'>You try to put \the [limb] in your mouth, but [the_item.p_their()] ears tickle your throat!</span>")
revert_cast()
return FALSE
if(istype(limb,/obj/item/organ/external/chest))
// Bullshit, but prevents being able to instagib someone.
to_chat(user, "<span class='warning'>You try to put [the_item.p_their()] [limb] in your mouth, but it's too big to fit!</span>")
revert_cast()
return FALSE
user.visible_message("<span class='danger'>[user] begins stuffing [the_item]'s [limb.name] into [user.p_their()] gaping maw!</span>")
var/oldloc = H.loc
if(!do_mob(user,H,EAT_MOB_DELAY))
to_chat(user, "<span class='danger'>You were interrupted before you could eat [the_item]!</span>")
else
if(!limb || !H)
return
if(H.loc != oldloc)
to_chat(user, "<span class='danger'>\The [limb] moved away from your mouth!</span>")
return
user.visible_message("<span class='danger'>[user] [pick("chomps","bites")] off [the_item]'s [limb]!</span>")
playsound(user.loc, 'sound/items/eatfood.ogg', 50, 0)
limb.droplimb(0, DROPLIMB_SHARP)
doHeal(user)
else
user.visible_message("<span class='danger'>[user] eats \the [the_item].</span>")
playsound(user.loc, 'sound/items/eatfood.ogg', 50, 0)
qdel(the_item)
doHeal(user)
////////////////////////////////////////////////////////////////////////
//WAS: /datum/bioEffect/jumpy
/datum/dna/gene/basic/grant_spell/jumpy
name = "Jumpy"
desc = "Allows the subject to leap great distances."
//cooldown = 30
activation_messages = list("Your leg muscles feel taut and strong.")
deactivation_messages = list("Your leg muscles shrink back to normal.")
instability = GENE_INSTABILITY_MINOR
mutation = JUMPY
spelltype =/obj/effect/proc_holder/spell/targeted/leap
/datum/dna/gene/basic/grant_spell/jumpy/New()
..()
block = GLOB.jumpblock
/obj/effect/proc_holder/spell/targeted/leap
name = "Jump"
desc = "Leap great distances!"
panel = "Abilities"
range = -1
include_user = 1
charge_type = "recharge"
charge_max = 60
clothes_req = 0
stat_allowed = 0
invocation_type = "none"
action_icon_state = "genetic_jump"
/obj/effect/proc_holder/spell/targeted/leap/cast(list/targets, mob/user = usr)
var/failure = FALSE
if(istype(user.loc,/mob/) || user.lying || user.stunned || user.buckled || user.stat)
to_chat(user, "<span class='warning'>You can't jump right now!</span>")
return
if(istype(user.loc,/turf/))
if(user.restrained())//Why being pulled while cuffed prevents you from moving
for(var/mob/M in range(user, 1))
if(M.pulling == user)
if(!M.restrained() && M.stat == 0 && M.canmove && user.Adjacent(M))
failure = TRUE
else
M.stop_pulling()
user.visible_message("<span class='danger'>[user.name]</b> takes a huge leap!</span>")
playsound(user.loc, 'sound/weapons/thudswoosh.ogg', 50, 1)
if(failure)
user.Weaken(5)
user.Stun(5)
user.visible_message("<span class='warning'>[user] attempts to leap away but is slammed back down to the ground!</span>",
"<span class='warning'>You attempt to leap away but are suddenly slammed back down to the ground!</span>",
"<span class='notice'>You hear the flexing of powerful muscles and suddenly a crash as a body hits the floor.</span>")
return FALSE
var/prevLayer = user.layer
var/prevFlying = user.flying
user.layer = 9
user.flying = TRUE
for(var/i=0, i<10, i++)
step(user, user.dir)
if(i < 5) user.pixel_y += 8
else user.pixel_y -= 8
sleep(1)
user.flying = prevFlying
if(FAT in user.mutations && prob(66))
user.visible_message("<span class='danger'>[user.name]</b> crashes due to [user.p_their()] heavy weight!</span>")
//playsound(user.loc, 'zhit.wav', 50, 1)
user.AdjustWeakened(10)
user.AdjustStunned(5)
user.layer = prevLayer
if(istype(user.loc,/obj/))
var/obj/container = user.loc
to_chat(user, "<span class='warning'>You leap and slam your head against the inside of [container]! Ouch!</span>")
user.AdjustParalysis(3)
user.AdjustWeakened(5)
container.visible_message("<span class='danger'>[user.loc]</b> emits a loud thump and rattles a bit.</span>")
playsound(user.loc, 'sound/effects/bang.ogg', 50, 1)
var/wiggle = 6
while(wiggle > 0)
wiggle--
container.pixel_x = rand(-3,3)
container.pixel_y = rand(-3,3)
sleep(1)
container.pixel_x = 0
container.pixel_y = 0
////////////////////////////////////////////////////////////////////////
// WAS: /datum/bioEffect/polymorphism
/datum/dna/gene/basic/grant_spell/polymorph
name = "Polymorphism"
desc = "Enables the subject to reconfigure their appearance to mimic that of others."
spelltype =/obj/effect/proc_holder/spell/targeted/click/polymorph
//cooldown = 1800
activation_messages = list("You don't feel entirely like yourself somehow.")
deactivation_messages = list("You feel secure in your identity.")
instability = GENE_INSTABILITY_MODERATE
mutation = POLYMORPH
/datum/dna/gene/basic/grant_spell/polymorph/New()
..()
block = GLOB.polymorphblock
/obj/effect/proc_holder/spell/targeted/click/polymorph
name = "Polymorph"
desc = "Mimic the appearance of others!"
panel = "Abilities"
charge_max = 1800
clothes_req = FALSE
stat_allowed = FALSE
click_radius = -1 // Precision required
auto_target_single = FALSE // Safety to not turn into monkey (420)
selection_activated_message = "<span class='notice'>You body becomes unstable. Click on a target to cast transform into them.</span>"
selection_deactivated_message = "<span class='notice'>Your body calms down again.</span>"
allowed_type = /mob/living/carbon/human
invocation_type = "none"
range = 1
selection_type = "range"
action_icon_state = "genetic_poly"
/obj/effect/proc_holder/spell/targeted/click/polymorph/cast(list/targets, mob/user = usr)
var/mob/living/carbon/human/target = targets[1]
user.visible_message("<span class='warning'>[user]'s body shifts and contorts.</span>")
spawn(10)
if(target && user)
playsound(user.loc, 'sound/goonstation/effects/gib.ogg', 50, 1)
var/mob/living/carbon/human/H = user
H.UpdateAppearance(target.dna.UI)
H.real_name = target.real_name
H.name = target.name
////////////////////////////////////////////////////////////////////////
// WAS: /datum/bioEffect/empath
/datum/dna/gene/basic/grant_spell/empath
name = "Empathic Thought"
desc = "The subject becomes able to read the minds of others for certain information."
spelltype = /obj/effect/proc_holder/spell/targeted/empath
activation_messages = list("You suddenly notice more about others than you did before.")
deactivation_messages = list("You no longer feel able to sense intentions.")
instability = GENE_INSTABILITY_MINOR
mutation = EMPATH
/datum/dna/gene/basic/grant_spell/empath/New()
..()
block = GLOB.empathblock
/obj/effect/proc_holder/spell/targeted/empath
name = "Read Mind"
desc = "Read the minds of others for information."
charge_max = 180
clothes_req = FALSE
human_req = TRUE
stat_allowed = CONSCIOUS
invocation_type = "none"
range = -2
selection_type = "range"
action_icon_state = "genetic_empath"
/obj/effect/proc_holder/spell/targeted/empath/choose_targets(mob/user = usr)
var/list/possible_targets = list()
for(var/mob/living/carbon/C in range(7, user))
possible_targets += C
var/target = input("Choose the target to spy on.", "Targeting") as null|mob in possible_targets
if(!target) //doesn't waste the spell
revert_cast(user)
return
perform(list(target), user = user)
/obj/effect/proc_holder/spell/targeted/empath/cast(list/targets, mob/user = usr)
for(var/mob/living/carbon/M in targets)
if(!iscarbon(M))
to_chat(user, "<span class='warning'>You may only use this on other organic beings.</span>")
return
if(PSY_RESIST in M.mutations)
to_chat(user, "<span class='warning'>You can't see into [M.name]'s mind at all!</span>")
return
if(M.stat == 2)
to_chat(user, "<span class='warning'>[M.name] is dead and cannot have [M.p_their()] mind read.</span>")
return
if(M.health < 0)
to_chat(user, "<span class='warning'>[M.name] is dying, and [M.p_their()] thoughts are too scrambled to read.</span>")
return
to_chat(user, "<span class='notice'>Mind Reading of <b>[M.name]:</b></span>")
var/pain_condition = M.health / M.maxHealth
// lower health means more pain
var/list/randomthoughts = list("what to have for lunch","the future","the past","money",
"[M.p_their()] hair","what to do next","[M.p_their()] job","space","amusing things","sad things",
"annoying things","happy things","something incoherent","something [M.p_they()] did wrong")
var/thoughts = "thinking about [pick(randomthoughts)]"
if(M.fire_stacks)
pain_condition -= 0.5
thoughts = "preoccupied with the fire"
if(M.radiation)
pain_condition -= 0.25
switch(pain_condition)
if(0.81 to INFINITY)
to_chat(user, "<span class='notice'><b>Condition</b>: [M.name] feels good.</span>")
if(0.61 to 0.8)
to_chat(user, "<span class='notice'><b>Condition</b>: [M.name] is suffering mild pain.</span>")
if(0.41 to 0.6)
to_chat(user, "<span class='notice'><b>Condition</b>: [M.name] is suffering significant pain.</span>")
if(0.21 to 0.4)
to_chat(user, "<span class='notice'><b>Condition</b>: [M.name] is suffering severe pain.</span>")
else
to_chat(user, "<span class='notice'><b>Condition</b>: [M.name] is suffering excruciating pain.</span>")
thoughts = "haunted by [M.p_their()] own mortality"
switch(M.a_intent)
if(INTENT_HELP)
to_chat(user, "<span class='notice'><b>Mood</b>: You sense benevolent thoughts from [M.name].</span>")
if(INTENT_DISARM)
to_chat(user, "<span class='notice'><b>Mood</b>: You sense cautious thoughts from [M.name].</span>")
if(INTENT_GRAB)
to_chat(user, "<span class='notice'><b>Mood</b>: You sense hostile thoughts from [M.name].</span>")
if(INTENT_HARM)
to_chat(user, "<span class='notice'><b>Mood</b>: You sense cruel thoughts from [M.name].</span>")
for(var/mob/living/L in view(7,M))
if(L == M)
continue
thoughts = "thinking about punching [L.name]"
break
else
to_chat(user, "<span class='notice'><b>Mood</b>: You sense strange thoughts from [M.name].</span>")
if(istype(M,/mob/living/carbon/human))
var/numbers[0]
var/mob/living/carbon/human/H = M
if(H.mind && H.mind.initial_account)
numbers += H.mind.initial_account.account_number
numbers += H.mind.initial_account.remote_access_pin
if(numbers.len>0)
to_chat(user, "<span class='notice'><b>Numbers</b>: You sense the number[numbers.len>1?"s":""] [english_list(numbers)] [numbers.len>1?"are":"is"] important to [M.name].</span>")
to_chat(user, "<span class='notice'><b>Thoughts</b>: [M.name] is currently [thoughts].</span>")
if(EMPATH in M.mutations)
to_chat(M, "<span class='warning'>You sense [user.name] reading your mind.</span>")
else if(prob(5) || M.mind.assigned_role=="Chaplain")
to_chat(M, "<span class='warning'>You sense someone intruding upon your thoughts...</span>")
-200
View File
@@ -1,200 +0,0 @@
///////////////////////////////////
// POWERS
///////////////////////////////////
/datum/dna/gene/basic/nobreath
name = "No Breathing"
activation_messages = list("You feel no need to breathe.")
deactivation_messages = list("You feel the need to breathe, once more.")
instability = GENE_INSTABILITY_MODERATE
mutation = BREATHLESS
activation_prob = 25
/datum/dna/gene/basic/nobreath/New()
..()
block = GLOB.breathlessblock
/datum/dna/gene/basic/regenerate
name = "Regenerate"
activation_messages = list("Your wounds start healing.")
deactivation_messages = list("Your regenerative powers feel like they've vanished.")
instability = GENE_INSTABILITY_MINOR
mutation = REGEN
/datum/dna/gene/basic/regenerate/New()
..()
block = GLOB.regenerateblock
/datum/dna/gene/basic/regenerate/OnMobLife(mob/living/carbon/human/H)
H.adjustBruteLoss(-0.1, FALSE)
H.adjustFireLoss(-0.1)
/datum/dna/gene/basic/increaserun
name = "Super Speed"
activation_messages = list("You feel swift and unencumbered.")
deactivation_messages = list("You feel slow.")
instability = GENE_INSTABILITY_MINOR
mutation = RUN
/datum/dna/gene/basic/increaserun/New()
..()
block = GLOB.increaserunblock
/datum/dna/gene/basic/increaserun/can_activate(mob/M, flags)
if(!..())
return FALSE
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.dna.species && H.dna.species.speed_mod && !(flags & MUTCHK_FORCED))
return FALSE
return TRUE
/datum/dna/gene/basic/heat_resist
name = "Heat Resistance"
activation_messages = list("Your skin is icy to the touch.")
deactivation_messages = list("Your skin no longer feels icy to the touch.")
instability = GENE_INSTABILITY_MODERATE
mutation = HEATRES
/datum/dna/gene/basic/heat_resist/New()
..()
block = GLOB.coldblock
/datum/dna/gene/basic/heat_resist/OnDrawUnderlays(mob/M, g)
return "cold_s"
/datum/dna/gene/basic/cold_resist
name = "Cold Resistance"
activation_messages = list("Your body is filled with warmth.")
deactivation_messages = list("Your body is no longer filled with warmth.")
instability = GENE_INSTABILITY_MODERATE
mutation = COLDRES
/datum/dna/gene/basic/cold_resist/New()
..()
block = GLOB.fireblock
/datum/dna/gene/basic/cold_resist/OnDrawUnderlays(mob/M, g)
return "fire_s"
/datum/dna/gene/basic/noprints
name = "No Prints"
activation_messages = list("Your fingers feel numb.")
deactivation_messages = list("your fingers no longer feel numb.")
instability = GENE_INSTABILITY_MINOR
mutation = FINGERPRINTS
/datum/dna/gene/basic/noprints/New()
..()
block = GLOB.noprintsblock
/datum/dna/gene/basic/noshock
name = "Shock Immunity"
activation_messages = list("Your skin feels dry and unreactive.")
deactivation_messages = list("Your skin no longer feels dry and unreactive.")
instability = GENE_INSTABILITY_MODERATE
mutation = NO_SHOCK
/datum/dna/gene/basic/noshock/New()
..()
block = GLOB.shockimmunityblock
/datum/dna/gene/basic/midget
name = "Midget"
activation_messages = list("Everything around you seems bigger now...")
deactivation_messages = list("Everything around you seems to shrink...")
instability = GENE_INSTABILITY_MINOR
mutation = DWARF
/datum/dna/gene/basic/midget/New()
..()
block = GLOB.smallsizeblock
/datum/dna/gene/basic/midget/activate(mob/M, connected, flags)
..()
M.pass_flags |= PASSTABLE
M.resize = 0.8
M.update_transform()
/datum/dna/gene/basic/midget/deactivate(mob/M, connected, flags)
..()
M.pass_flags &= ~PASSTABLE
M.resize = 1.25
M.update_transform()
// OLD HULK BEHAVIOR
/datum/dna/gene/basic/hulk
name = "Hulk"
activation_messages = list("Your muscles hurt.")
deactivation_messages = list("Your muscles shrink.")
instability = GENE_INSTABILITY_MAJOR
mutation = HULK
activation_prob = 15
/datum/dna/gene/basic/hulk/New()
..()
block = GLOB.hulkblock
/datum/dna/gene/basic/hulk/activate(mob/M, connected, flags)
..()
var/status = CANSTUN | CANWEAKEN | CANPARALYSE | CANPUSH
M.status_flags &= ~status
/datum/dna/gene/basic/hulk/deactivate(mob/M, connected, flags)
..()
M.status_flags |= CANSTUN | CANWEAKEN | CANPARALYSE | CANPUSH
/datum/dna/gene/basic/hulk/OnDrawUnderlays(mob/M, g)
if(HULK in M.mutations)
return "hulk_[g]_s"
return FALSE
/datum/dna/gene/basic/hulk/OnMobLife(mob/living/carbon/human/M)
if(!istype(M))
return
if((HULK in M.mutations) && M.health <= 0)
M.mutations.Remove(HULK)
M.dna.SetSEState(GLOB.hulkblock,0)
genemutcheck(M, GLOB.hulkblock,null,MUTCHK_FORCED)
M.update_mutations() //update our mutation overlays
M.update_body()
M.status_flags |= CANSTUN | CANWEAKEN | CANPARALYSE | CANPUSH //temporary fix until the problem can be solved.
to_chat(M, "<span class='danger'>You suddenly feel very weak.</span>")
/datum/dna/gene/basic/xray
name = "X-Ray Vision"
activation_messages = list("The walls suddenly disappear.")
deactivation_messages = list("the walls around you re-appear.")
instability = GENE_INSTABILITY_MAJOR
mutation = XRAY
activation_prob = 15
/datum/dna/gene/basic/xray/New()
..()
block = GLOB.xrayblock
/datum/dna/gene/basic/xray/activate(mob/living/M, connected, flags)
..()
M.update_sight()
M.update_icons() //Apply eyeshine as needed.
/datum/dna/gene/basic/xray/deactivate(mob/living/M, connected, flags)
..()
M.update_sight()
M.update_icons() //Remove eyeshine as needed.
/datum/dna/gene/basic/tk
name = "Telekenesis"
activation_messages = list("You feel smarter.")
deactivation_messages = list("You feel dumber.")
instability = GENE_INSTABILITY_MAJOR
mutation = TK
activation_prob = 15
/datum/dna/gene/basic/tk/New()
..()
block = GLOB.teleblock
/datum/dna/gene/basic/tk/OnDrawUnderlays(mob/M, g)
return "telekinesishead_s"
-42
View File
@@ -1,42 +0,0 @@
/datum/dna/gene/disability/speech/loud
name = "Loud"
desc = "Forces the speaking centre of the subjects brain to yell every sentence."
activation_message = "YOU FEEL LIKE YELLING!"
deactivation_message = "You feel like being quiet.."
mutation = LOUD
/datum/dna/gene/disability/speech/loud/New()
..()
block = GLOB.loudblock
/datum/dna/gene/disability/speech/loud/OnSay(mob/M, message)
message = replacetext(message,".","!")
message = replacetext(message,"?","?!")
message = replacetext(message,"!","!!")
return uppertext(message)
/datum/dna/gene/disability/dizzy
name = "Dizzy"
desc = "Causes the cerebellum to shut down in some places."
activation_message = "You feel very dizzy..."
deactivation_message = "You regain your balance."
instability = -GENE_INSTABILITY_MINOR
mutation = DIZZY
/datum/dna/gene/disability/dizzy/New()
..()
block = GLOB.dizzyblock
/datum/dna/gene/disability/dizzy/OnMobLife(mob/living/carbon/human/M)
if(!istype(M))
return
if(DIZZY in M.mutations)
M.Dizzy(300)
/datum/dna/gene/disability/dizzy/deactivate(mob/living/M, connected, flags)
..()
M.SetDizzy(0)
-408
View File
@@ -1,408 +0,0 @@
///////////////////Vanilla Morph////////////////////////////////////
/datum/dna/gene/basic/grant_spell/morph
name = "Morphism"
desc = "Enables the subject to reconfigure their appearance to that of any human."
spelltype =/obj/effect/proc_holder/spell/targeted/morph
activation_messages = list("Your body feels if can alter its appearance.")
deactivation_messages = list("Your body doesn't feel capable of altering its appearance.")
instability = GENE_INSTABILITY_MINOR
mutation = MORPH
/datum/dna/gene/basic/grant_spell/morph/New()
..()
block = GLOB.morphblock
/obj/effect/proc_holder/spell/targeted/morph
name = "Morph"
desc = "Mimic the appearance of your choice!"
panel = "Abilities"
charge_max = 1800
clothes_req = 0
stat_allowed = 0
invocation_type = "none"
range = -1
include_user = 1
selection_type = "range"
action_icon_state = "genetic_morph"
/obj/effect/proc_holder/spell/targeted/morph/cast(list/targets, mob/user = usr)
if(!ishuman(user))
return
if(istype(user.loc,/mob/))
to_chat(user, "<span class='warning'>You can't change your appearance right now!</span>")
return
var/mob/living/carbon/human/M = user
var/obj/item/organ/external/head/head_organ = M.get_organ("head")
var/obj/item/organ/internal/eyes/eyes_organ = M.get_int_organ(/obj/item/organ/internal/eyes)
var/new_gender = alert(user, "Please select gender.", "Character Generation", "Male", "Female")
if(new_gender)
if(new_gender == "Male")
M.change_gender(MALE)
else
M.change_gender(FEMALE)
var/new_eyes = input("Please select eye color.", "Character Generation", eyes_organ.eye_colour) as null|color
if(new_eyes)
M.change_eye_color(new_eyes)
//Alt heads.
if(head_organ.dna.species.bodyflags & HAS_ALT_HEADS)
var/list/valid_alt_heads = M.generate_valid_alt_heads()
var/new_alt_head = input("Please select alternate head", "Character Generation", head_organ.alt_head) as null|anything in valid_alt_heads
if(new_alt_head)
M.change_alt_head(new_alt_head)
// hair
var/list/valid_hairstyles = M.generate_valid_hairstyles()
var/new_style = input("Please select hair style", "Character Generation", head_organ.h_style) as null|anything in valid_hairstyles
// if new style selected (not cancel)
if(new_style)
M.change_hair(new_style)
var/new_hair = input("Please select hair color.", "Character Generation", head_organ.hair_colour) as null|color
if(new_hair)
M.change_hair_color(new_hair)
var/datum/sprite_accessory/hair_style = GLOB.hair_styles_public_list[head_organ.h_style]
if(hair_style.secondary_theme && !hair_style.no_sec_colour)
new_hair = input("Please select secondary hair color.", "Character Generation", head_organ.sec_hair_colour) as null|color
if(new_hair)
M.change_hair_color(new_hair, 1)
// facial hair
var/list/valid_facial_hairstyles = M.generate_valid_facial_hairstyles()
new_style = input("Please select facial style", "Character Generation", head_organ.f_style) as null|anything in valid_facial_hairstyles
if(new_style)
M.change_facial_hair(new_style)
var/new_facial = input("Please select facial hair color.", "Character Generation", head_organ.facial_colour) as null|color
if(new_facial)
M.change_facial_hair_color(new_facial)
var/datum/sprite_accessory/facial_hair_style = GLOB.facial_hair_styles_list[head_organ.f_style]
if(facial_hair_style.secondary_theme && !facial_hair_style.no_sec_colour)
new_facial = input("Please select secondary facial hair color.", "Character Generation", head_organ.sec_facial_colour) as null|color
if(new_facial)
M.change_facial_hair_color(new_facial, 1)
//Head accessory.
if(head_organ.dna.species.bodyflags & HAS_HEAD_ACCESSORY)
var/list/valid_head_accessories = M.generate_valid_head_accessories()
var/new_head_accessory = input("Please select head accessory style", "Character Generation", head_organ.ha_style) as null|anything in valid_head_accessories
if(new_head_accessory)
M.change_head_accessory(new_head_accessory)
var/new_head_accessory_colour = input("Please select head accessory colour.", "Character Generation", head_organ.headacc_colour) as null|color
if(new_head_accessory_colour)
M.change_head_accessory_color(new_head_accessory_colour)
//Body accessory.
if(M.dna.species.tail && M.dna.species.bodyflags & HAS_TAIL)
var/list/valid_body_accessories = M.generate_valid_body_accessories()
if(valid_body_accessories.len > 1) //By default valid_body_accessories will always have at the very least a 'none' entry populating the list, even if the user's species is not present in any of the list items.
var/new_body_accessory = input("Please select body accessory style", "Character Generation", M.body_accessory) as null|anything in valid_body_accessories
if(new_body_accessory)
M.change_body_accessory(new_body_accessory)
//Head markings.
if(M.dna.species.bodyflags & HAS_HEAD_MARKINGS)
var/list/valid_head_markings = M.generate_valid_markings("head")
var/new_marking = input("Please select head marking style", "Character Generation", M.m_styles["head"]) as null|anything in valid_head_markings
if(new_marking)
M.change_markings(new_marking, "head")
var/new_marking_colour = input("Please select head marking colour.", "Character Generation", M.m_colours["head"]) as null|color
if(new_marking_colour)
M.change_marking_color(new_marking_colour, "head")
//Body markings.
if(M.dna.species.bodyflags & HAS_BODY_MARKINGS)
var/list/valid_body_markings = M.generate_valid_markings("body")
var/new_marking = input("Please select body marking style", "Character Generation", M.m_styles["body"]) as null|anything in valid_body_markings
if(new_marking)
M.change_markings(new_marking, "body")
var/new_marking_colour = input("Please select body marking colour.", "Character Generation", M.m_colours["body"]) as null|color
if(new_marking_colour)
M.change_marking_color(new_marking_colour, "body")
//Tail markings.
if(M.dna.species.bodyflags & HAS_TAIL_MARKINGS)
var/list/valid_tail_markings = M.generate_valid_markings("tail")
var/new_marking = input("Please select tail marking style", "Character Generation", M.m_styles["tail"]) as null|anything in valid_tail_markings
if(new_marking)
M.change_markings(new_marking, "tail")
var/new_marking_colour = input("Please select tail marking colour.", "Character Generation", M.m_colours["tail"]) as null|color
if(new_marking_colour)
M.change_marking_color(new_marking_colour, "tail")
//Skin tone.
if(M.dna.species.bodyflags & HAS_SKIN_TONE)
var/new_tone = input("Please select skin tone level: 1-220 (1=albino, 35=caucasian, 150=black, 220='very' black)", "Character Generation", M.s_tone) as null|text
if(!new_tone)
new_tone = 35
else
new_tone = 35 - max(min(round(text2num(new_tone)), 220), 1)
M.change_skin_tone(new_tone)
if(M.dna.species.bodyflags & HAS_ICON_SKIN_TONE)
var/prompt = "Please select skin tone: 1-[M.dna.species.icon_skin_tones.len] ("
for(var/i = 1 to M.dna.species.icon_skin_tones.len)
prompt += "[i] = [M.dna.species.icon_skin_tones[i]]"
if(i != M.dna.species.icon_skin_tones.len)
prompt += ", "
prompt += ")"
var/new_tone = input(prompt, "Character Generation", M.s_tone) as null|text
if(!new_tone)
new_tone = 0
else
new_tone = max(min(round(text2num(new_tone)), M.dna.species.icon_skin_tones.len), 1)
M.change_skin_tone(new_tone)
//Skin colour.
if(M.dna.species.bodyflags & HAS_SKIN_COLOR)
var/new_body_colour = input("Please select body colour.", "Character Generation", M.skin_colour) as null|color
if(new_body_colour)
M.change_skin_color(new_body_colour)
M.update_dna()
M.visible_message("<span class='notice'>[M] morphs and changes [M.p_their()] appearance!</span>", "<span class='notice'>You change your appearance!</span>", "<span class='warning'>Oh, god! What the hell was that? It sounded like flesh getting squished and bone ground into a different shape!</span>")
/datum/dna/gene/basic/grant_spell/remotetalk
name = "Telepathy"
activation_messages = list("You feel you can project your thoughts.")
deactivation_messages = list("You no longer feel you can project your thoughts.")
instability = GENE_INSTABILITY_MINOR
mutation = REMOTE_TALK
spelltype =/obj/effect/proc_holder/spell/targeted/remotetalk
/datum/dna/gene/basic/grant_spell/remotetalk/New()
..()
block = GLOB.remotetalkblock
/datum/dna/gene/basic/grant_spell/remotetalk/activate(mob/living/M, connected, flags)
..()
M.AddSpell(new /obj/effect/proc_holder/spell/targeted/mindscan(null))
/datum/dna/gene/basic/grant_spell/remotetalk/deactivate(mob/user)
..()
for(var/obj/effect/proc_holder/spell/S in user.mob_spell_list)
if(istype(S, /obj/effect/proc_holder/spell/targeted/mindscan))
user.RemoveSpell(S)
/obj/effect/proc_holder/spell/targeted/remotetalk
name = "Project Mind"
desc = "Make people understand your thoughts!"
charge_max = 0
clothes_req = 0
stat_allowed = 0
invocation_type = "none"
range = -2
selection_type = "range"
action_icon_state = "genetic_project"
/obj/effect/proc_holder/spell/targeted/remotetalk/choose_targets(mob/user = usr)
var/list/targets = new /list()
var/list/validtargets = user.get_telepathic_targets()
if(!length(validtargets))
to_chat(user, "<span class='warning'>There are no valid targets!</span>")
start_recharge()
return
var/target_name = input("Choose the target to talk to.", "Targeting") as null|anything in validtargets
var/mob/living/target
if(!target_name || !(target = validtargets[target_name]))
revert_cast(user)
return
targets += target
perform(targets, user = user)
/obj/effect/proc_holder/spell/targeted/remotetalk/cast(list/targets, mob/user = usr)
if(!ishuman(user)) return
var/say = input("What do you wish to say") as text|null
if(!say || usr.stat)
return
say = strip_html(say)
say = pencode_to_html(say, usr, format = 0, fields = 0)
for(var/mob/living/target in targets)
log_say("(TPATH to [key_name(target)]) [say]", user)
user.create_log(SAY_LOG, "Telepathically said '[say]' using [src]", target)
if(REMOTE_TALK in target.mutations)
target.show_message("<span class='abductor'>You hear [user.real_name]'s voice: [say]</span>")
else
target.show_message("<span class='abductor'>You hear a voice that seems to echo around the room: [say]</span>")
user.show_message("<span class='abductor'>You project your mind into [(target in user.get_visible_mobs()) ? target.name : "the unknown entity"]: [say]</span>")
for(var/mob/dead/observer/G in GLOB.player_list)
G.show_message("<i>Telepathic message from <b>[user]</b> ([ghost_follow_link(user, ghost=G)]) to <b>[target]</b> ([ghost_follow_link(target, ghost=G)]): [say]</i>")
/obj/effect/proc_holder/spell/targeted/mindscan
name = "Scan Mind"
desc = "Offer people a chance to share their thoughts!"
charge_max = 0
clothes_req = 0
stat_allowed = 0
invocation_type = "none"
range = -2
selection_type = "range"
action_icon_state = "genetic_mindscan"
var/list/available_targets = list()
/obj/effect/proc_holder/spell/targeted/mindscan/choose_targets(mob/user = usr)
var/list/targets = list()
var/list/validtargets = user.get_telepathic_targets()
if(!length(validtargets))
to_chat(user, "<span class='warning'>There are no valid targets!</span>")
start_recharge()
return
var/target_name = input("Choose the target to listen to.", "Targeting") as null|anything in validtargets
var/mob/living/target
if(!target_name || !(target = validtargets[target_name]))
revert_cast(user)
return
targets += target
perform(targets, user = user)
/obj/effect/proc_holder/spell/targeted/mindscan/cast(list/targets, mob/user = usr)
if(!ishuman(user))
return
for(var/mob/living/target in targets)
var/message = "You feel your mind expand briefly... (Click to send a message.)"
if(REMOTE_TALK in target.mutations)
message = "You feel [user.real_name] request a response from you... (Click here to project mind.)"
user.show_message("<span class='abductor'>You offer your mind to [(target in user.get_visible_mobs()) ? target.name : "the unknown entity"].</span>")
target.show_message("<span class='abductor'><A href='?src=[UID()];target=[target.UID()];user=[user.UID()]'>[message]</a></span>")
available_targets += target
addtimer(CALLBACK(src, .proc/removeAvailability, target), 100)
/obj/effect/proc_holder/spell/targeted/mindscan/proc/removeAvailability(mob/living/target)
if(target in available_targets)
available_targets -= target
if(!(target in available_targets))
target.show_message("<span class='abductor'>You feel the sensation fade...</span>")
/obj/effect/proc_holder/spell/targeted/mindscan/Topic(href, href_list)
var/mob/living/user
if(href_list["user"])
user = locateUID(href_list["user"])
if(href_list["target"])
if(!user)
return
var/mob/living/target = locateUID(href_list["target"])
if(!(target in available_targets))
return
available_targets -= target
var/say = input("What do you wish to say") as text|null
if(!say)
return
say = strip_html(say)
say = pencode_to_html(say, target, format = 0, fields = 0)
user.create_log(SAY_LOG, "Telepathically responded '[say]' using [src]", target)
log_say("(TPATH to [key_name(target)]) [say]", user)
if(REMOTE_TALK in target.mutations)
target.show_message("<span class='abductor'>You project your mind into [user.name]: [say]</span>")
else
target.show_message("<span class='abductor'>You fill the space in your thoughts: [say]</span>")
user.show_message("<span class='abductor'>You hear [target.name]'s voice: [say]</span>")
for(var/mob/dead/observer/G in GLOB.player_list)
G.show_message("<i>Telepathic response from <b>[target]</b> ([ghost_follow_link(target, ghost=G)]) to <b>[user]</b> ([ghost_follow_link(user, ghost=G)]): [say]</i>")
/obj/effect/proc_holder/spell/targeted/mindscan/Destroy()
available_targets.Cut()
return ..()
/datum/dna/gene/basic/grant_spell/remoteview
name = "Remote Viewing"
activation_messages = list("Your mind can see things from afar.")
deactivation_messages = list("Your mind can no longer can see things from afar.")
instability = GENE_INSTABILITY_MINOR
mutation = REMOTE_VIEW
spelltype =/obj/effect/proc_holder/spell/targeted/remoteview
/datum/dna/gene/basic/grant_spell/remoteview/New()
..()
block = GLOB.remoteviewblock
/obj/effect/proc_holder/spell/targeted/remoteview
name = "Remote View"
desc = "Spy on people from any range!"
charge_max = 100
clothes_req = 0
stat_allowed = 0
invocation_type = "none"
range = -2
selection_type = "range"
action_icon_state = "genetic_view"
/obj/effect/proc_holder/spell/targeted/remoteview/choose_targets(mob/user = usr)
var/list/targets = list()
var/list/remoteviewers = list()
for(var/mob/M in GLOB.alive_mob_list)
if(M == user)
continue
if(PSY_RESIST in M.mutations)
continue
if(REMOTE_VIEW in M.mutations)
remoteviewers += M
if(!LAZYLEN(remoteviewers))
to_chat(user, "<span class='warning'>No valid targets with remote view were found!</span>")
start_recharge()
return
targets += input("Choose the target to spy on.", "Targeting") as null|anything in remoteviewers
if(!targets)
to_chat(user, "<span class='warning'>You decide against remote viewing.</span>")
start_recharge()
return
perform(targets, user = user)
/obj/effect/proc_holder/spell/targeted/remoteview/cast(list/targets, mob/user = usr)
var/mob/living/carbon/human/H
if(ishuman(user))
H = user
else
return
var/mob/target
if(istype(H.l_hand, /obj/item/tk_grab) || istype(H.r_hand, /obj/item/tk_grab))
to_chat(H, "<span class='warning'>Your mind is too busy with that telekinetic grab.</span>")
H.remoteview_target = null
H.reset_perspective()
return
if(H.client.eye != user.client.mob)
H.remoteview_target = null
H.reset_perspective()
return
for(var/mob/living/L in targets)
target = L
if(target)
H.remoteview_target = target
H.reset_perspective(target)
else
H.remoteview_target = null
H.reset_perspective()
+74
View File
@@ -0,0 +1,74 @@
/datum/mutation
/// Display name
var/name = "mutation"
/// Description of the gene
var/desc = "A mutation."
/// What gene activates this? Set in initialize()!
var/block = 0
/// Chance of the gene to cause adverse effects when active
var/instability = 0
/// Trait to give, if any
var/traits_to_add = list()
/// Activation probability
var/activation_prob = 100
/// Possible activation messages
var/list/activation_messages = list()
/// Possible deactivation messages
var/list/deactivation_messages = list()
// Is the gene active in this mob's DNA?
/datum/mutation/proc/is_active(mob/M)
return M.active_mutations && (type in M.active_mutations)
// Return TRUE if we can activate.
// HANDLE MUTCHK_FORCED HERE!
/datum/mutation/proc/can_activate(mob/M, flags)
if(flags & MUTCHK_FORCED)
return TRUE
// Probability check
return prob(activation_prob)
// Called when the gene activates. Do your magic here.
/datum/mutation/proc/activate(mob/living/M)
M.gene_stability -= instability
for(var/thing in traits_to_add)
ADD_TRAIT(M, thing, GENETIC_MUTATION)
if(length(activation_messages))
var/msg = pick(activation_messages)
to_chat(M, "<span class='notice'>[msg]</span>")
// Called when the gene deactivates. Undo your magic here.
// Only called when the block is deactivated.
/datum/mutation/proc/deactivate(mob/living/M)
M.gene_stability += instability
for(var/thing in traits_to_add)
REMOVE_TRAIT(M, thing, GENETIC_MUTATION)
if(length(deactivation_messages))
var/msg = pick(deactivation_messages)
to_chat(M, "<span class='warning'>[msg]</span>")
// This section inspired by goone's bioEffects.
// Called in each life() tick.
/datum/mutation/proc/on_life(mob/M)
return
// Called when the mob dies
/datum/mutation/proc/on_death(mob/M)
return
// Called when the mob says shit
/datum/mutation/proc/on_say(mob/M, message)
return message
// Called after the mob runs update_icons.
// @params M The subject.
// @params g Gender (m or f)
/datum/mutation/proc/on_draw_underlays(mob/M, g)
return FALSE
+549
View File
@@ -0,0 +1,549 @@
/////////////////////
// DISABILITY MUTATIONS
//
//
//
// Mutation is always activated.
/////////////////////
/datum/mutation/disability
name = "DISABILITY"
/datum/mutation/disability/can_activate(mob/M, flags)
return TRUE // Always set!
/datum/mutation/disability/hallucinate
name = "Hallucinate"
activation_messages = list("Your mind says 'Hello'.")
deactivation_messages = list("Sanity returns. Or does it?")
instability = -GENE_INSTABILITY_MODERATE
/datum/mutation/disability/hallucinate/New()
..()
block = GLOB.hallucinationblock
/datum/mutation/disability/hallucinate/on_life(mob/living/carbon/human/H)
if(prob(1))
H.AdjustHallucinate(45)
/datum/mutation/disability/epilepsy
name = "Epilepsy"
activation_messages = list("You get a headache.")
deactivation_messages = list("Your headache is gone, at last.")
instability = -GENE_INSTABILITY_MODERATE
/datum/mutation/disability/epilepsy/New()
..()
block = GLOB.epilepsyblock
/datum/mutation/disability/epilepsy/on_life(mob/living/carbon/human/H)
if((prob(1) && H.paralysis < 1))
H.visible_message("<span class='danger'>[H] starts having a seizure!</span>","<span class='alert'>You have a seizure!</span>")
H.Paralyse(10)
H.Jitter(1000)
/datum/mutation/disability/cough
name = "Coughing"
activation_messages = list("You start coughing.")
deactivation_messages = list("Your throat stops aching.")
instability = -GENE_INSTABILITY_MINOR
/datum/mutation/disability/cough/New()
..()
block = GLOB.coughblock
/datum/mutation/disability/cough/on_life(mob/living/carbon/human/H)
if((prob(5) && H.paralysis <= 1))
H.drop_item()
H.emote("cough")
/datum/mutation/disability/clumsy
name = "Clumsiness"
activation_messages = list("You feel lightheaded.")
deactivation_messages = list("You regain some control of your movements")
instability = -GENE_INSTABILITY_MINOR
traits_to_add = list(TRAIT_CLUMSY)
/datum/mutation/disability/clumsy/New()
..()
block = GLOB.clumsyblock
/datum/mutation/disability/tourettes
name = "Tourettes"
activation_messages = list("You twitch.")
deactivation_messages = list("Your mouth tastes like soap.")
instability = -GENE_INSTABILITY_MODERATE
/datum/mutation/disability/tourettes/New()
..()
block = GLOB.twitchblock
/datum/mutation/disability/tourettes/on_life(mob/living/carbon/human/H)
if((prob(10) && H.paralysis <= 1))
H.Stun(10)
switch(rand(1, 3))
if(1)
H.emote("twitch")
if(2 to 3)
H.say("[prob(50) ? ";" : ""][pick("SHIT", "PISS", "FUCK", "CUNT", "COCKSUCKER", "MOTHERFUCKER", "TITS")]")
var/x_offset_old = H.pixel_x
var/y_offset_old = H.pixel_y
var/x_offset = H.pixel_x + rand(-2, 2)
var/y_offset = H.pixel_y + rand(-1, 1)
animate(H, pixel_x = x_offset, pixel_y = y_offset, time = 1)
animate(H, pixel_x = x_offset_old, pixel_y = y_offset_old, time = 1)
/datum/mutation/disability/nervousness
name = "Nervousness"
activation_messages = list("You feel nervous.")
deactivation_messages = list("You feel much calmer.")
/datum/mutation/disability/nervousness/New()
..()
block = GLOB.nervousblock
/datum/mutation/disability/nervousness/on_life(mob/living/carbon/human/H)
if(prob(10))
H.Stuttering(10)
/datum/mutation/disability/blindness
name = "Blindness"
activation_messages = list("You can't seem to see anything.")
deactivation_messages = list("You can see now, in case you didn't notice...")
instability = -GENE_INSTABILITY_MAJOR
traits_to_add = list(TRAIT_BLIND)
/datum/mutation/disability/blindness/New()
..()
block = GLOB.blindblock
/datum/mutation/disability/blindness/activate(mob/M)
..()
M.update_blind_effects()
/datum/mutation/disability/blindness/deactivate(mob/M)
..()
M.update_blind_effects()
/datum/mutation/disability/colourblindness
name = "Colourblindness"
activation_messages = list("You feel a peculiar prickling in your eyes while your perception of colour changes.")
deactivation_messages = list("Your eyes tingle unsettlingly, though everything seems to become alot more colourful.")
instability = -GENE_INSTABILITY_MODERATE
traits_to_add = list(TRAIT_COLORBLIND)
/datum/mutation/disability/colourblindness/New()
..()
block = GLOB.colourblindblock
/datum/mutation/disability/colourblindness/activate(mob/M)
..()
M.update_client_colour() //Handle the activation of the colourblindness on the mob.
M.update_icons() //Apply eyeshine as needed.
/datum/mutation/disability/colourblindness/deactivate(mob/M)
..()
M.update_client_colour() //Handle the deactivation of the colourblindness on the mob.
M.update_icons() //Remove eyeshine as needed.
/datum/mutation/disability/deaf
name = "Deafness"
activation_messages = list("It's kinda quiet.")
deactivation_messages = list("You can hear again!")
instability = -GENE_INSTABILITY_MAJOR
traits_to_add = list(TRAIT_DEAF)
/datum/mutation/disability/deaf/New()
..()
block = GLOB.deafblock
/datum/mutation/disability/nearsighted
name = "Nearsightedness"
activation_messages = list("Your eyes feel weird...")
deactivation_messages = list("You can see clearly now")
instability = -GENE_INSTABILITY_MODERATE
traits_to_add = list(TRAIT_NEARSIGHT)
/datum/mutation/disability/nearsighted/New()
..()
block = GLOB.glassesblock
/datum/mutation/disability/nearsighted/activate(mob/living/M)
..()
M.update_nearsighted_effects()
/datum/mutation/disability/nearsighted/deactivate(mob/living/M)
..()
M.update_nearsighted_effects()
/datum/mutation/disability/lisp
name = "Lisp"
desc = "I wonder wath thith doeth."
activation_messages = list("Thomething doethn't feel right.")
deactivation_messages = list("You now feel able to pronounce consonants.")
/datum/mutation/disability/lisp/New()
..()
block = GLOB.lispblock
/datum/mutation/disability/lisp/on_say(mob/M, message)
return replacetext(message,"s","th")
/datum/mutation/disability/comic
name = "Comic"
desc = "This will only bring death and destruction."
activation_messages = list("<span class='sans'>Uh oh!</span>")
deactivation_messages = list("Well thank god that's over with.")
traits_to_add = list(TRAIT_COMIC_SANS)
/datum/mutation/disability/comic/New()
..()
block = GLOB.comicblock
/datum/mutation/disability/wingdings
name = "Alien Voice"
desc = "Garbles the subject's voice into an incomprehensible speech."
activation_messages = list("<span class='wingdings'>Your vocal cords feel alien.</span>")
deactivation_messages = list("Your vocal cords no longer feel alien.")
instability = -GENE_INSTABILITY_MINOR
traits_to_add = list(TRAIT_WINGDINGS)
/datum/mutation/disability/wingdings/New()
..()
block = GLOB.wingdingsblock
/datum/mutation/disability/wingdings/on_say(mob/M, message)
var/garbled_message = ""
for(var/i in 1 to length(message))
if(message[i] in GLOB.alphabet_uppercase)
garbled_message += pick(GLOB.alphabet_uppercase)
else if(message[i] in GLOB.alphabet)
garbled_message += pick(GLOB.alphabet)
else
garbled_message += message[i]
message = garbled_message
return message
//////////////////
// DISABILITIES //
//////////////////
////////////////////////////////////////
// Totally Crippling
////////////////////////////////////////
// WAS: /datum/bioEffect/mute
/datum/mutation/disability/mute
name = "Mute"
desc = "Completely shuts down the speech center of the subject's brain."
activation_messages = list("You feel unable to express yourself at all.")
deactivation_messages = list("You feel able to speak freely again.")
instability = -GENE_INSTABILITY_MODERATE
traits_to_add = list(TRAIT_MUTE)
/datum/mutation/disability/mute/New()
..()
block = GLOB.muteblock
/datum/mutation/disability/mute/on_say(mob/M, message)
return ""
////////////////////////////////////////
// Harmful to others as well as self
////////////////////////////////////////
/datum/mutation/disability/radioactive
name = "Radioactive"
desc = "The subject suffers from constant radiation sickness and causes the same on nearby organics."
activation_messages = list("You feel a strange sickness permeate your whole body.")
deactivation_messages = list("You no longer feel awful and sick all over.")
instability = -GENE_INSTABILITY_MAJOR
/datum/mutation/disability/radioactive/New()
..()
block = GLOB.radblock
/datum/mutation/disability/radioactive/can_activate(mob/M, flags)
if(!..())
return FALSE
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(HAS_TRAIT(H, TRAIT_RADIMMUNE) && !(flags & MUTCHK_FORCED))
return FALSE
return TRUE
/datum/mutation/disability/radioactive/on_life(mob/living/carbon/human/H)
radiation_pulse(H, 20)
/datum/mutation/disability/radioactive/on_draw_underlays(mob/M, g)
return "rads_s"
////////////////////////////////////////
// Other disabilities
////////////////////////////////////////
// WAS: /datum/bioEffect/fat
/datum/mutation/disability/fat
name = "Obesity"
desc = "Greatly slows the subject's metabolism, enabling greater buildup of lipid tissue."
activation_messages = list("You feel blubbery and lethargic!")
deactivation_messages = list("You feel fit!")
instability = -GENE_INSTABILITY_MINOR
traits_to_add = list(TRAIT_SLOWDIGESTION)
/datum/mutation/disability/fat/New()
..()
block = GLOB.fatblock
// WAS: /datum/bioEffect/chav
/datum/mutation/disability/speech/chav
name = "Chav"
desc = "Forces the language center of the subject's brain to construct sentences in a more rudimentary manner."
activation_messages = list("Ye feel like a rite prat like, innit?")
deactivation_messages = list("You no longer feel like being rude and sassy.")
//List of swappable words. Normal word first, chav word second.
var/static/list/chavlinks = list(
"arrest" = "nick",
"arrested" = "nicked",
"ass" = "arse",
"bad" = "pants",
"bar" = "spoons",
"brain" = "noggin",
"break" = "smash",
"broke" = "smashed",
"broken" = "gone kaput",
"comdom" = "knob'ed",
"cool" = "ace",
"crazy" = "well mad",
"cup of tea" = "cuppa",
"destroyed" = "rekt",
"dick" = "prat",
"disappointed" = "gutted",
"disgusting" = "minging",
"disposals" = "bins",
"drink" = "bevvy",
"engineer" = "sparky",
"excited" = "jacked",
"fight" = "scuffle",
"food" = "nosh",
"friend" = "blud",
"fuck" = "fook",
"get" = "giz",
"girl" = "bird",
"go away" = "jog on",
"good" = "mint",
"great" = "bangin'",
"happy" = "chuffed",
"hello" = "orite",
"hi" = "sup",
"idiot" = "twit",
"isn't it" = "innit",
"kill" = "bang",
"killed" = "banged",
"man" = "bloke",
"mess" = "shambles",
"mistake" = "cock-up",
"murder" = "hench",
"murdered" = "henched",
"no" = "naw",
"really" = "propa",
"robust" = "'ard",
"run" = "leg it",
"sec" = "cops",
"security" = "coppers",
"silly" = "daft",
"steal" = "nick",
"stole" = "nicked",
"surprised" = "gobsmacked",
"suspicious" = "dodgy",
"tired" = "knackered",
"wet" = "moist",
"what" = "wot",
"window" = "windy",
"windows" = "windies",
"yes" = "ye",
"yikes" = "blimey",
"your" = "yur"
)
/datum/mutation/disability/speech/chav/New()
..()
block = GLOB.chavblock
/datum/mutation/disability/speech/chav/on_say(mob/M, message)
var/static/regex/R = regex("\\b([chavlinks.Join("|")])\\b", "g")
message = R.Replace(message, /datum/mutation/disability/speech/chav/proc/replace_speech)
return message
/datum/mutation/disability/speech/chav/proc/replace_speech(matched)
return chavlinks[matched]
// WAS: /datum/bioEffect/swedish
/datum/mutation/disability/speech/swedish
name = "Swedish"
desc = "Forces the language center of the subject's brain to construct sentences in a vaguely norse manner."
activation_messages = list("You feel Swedish, however that works.")
deactivation_messages = list("The feeling of Swedishness passes.")
/datum/mutation/disability/speech/swedish/New()
..()
block = GLOB.swedeblock
/datum/mutation/disability/speech/swedish/on_say(mob/M, message)
// svedish
message = replacetextEx(message,"W","V")
message = replacetextEx(message,"w","v")
message = replacetextEx(message,"J","Y")
message = replacetextEx(message,"j","y")
message = replacetextEx(message,"A",pick("Å","Ä","Æ","A"))
message = replacetextEx(message,"a",pick("å","ä","æ","a"))
message = replacetextEx(message,"BO","BJO")
message = replacetextEx(message,"Bo","Bjo")
message = replacetextEx(message,"bo","bjo")
message = replacetextEx(message,"O",pick("Ö","Ø","O"))
message = replacetextEx(message,"o",pick("ö","ø","o"))
if(prob(30) && !M.is_muzzled())
message += " Bork[pick("",", bork",", bork, bork")]!"
return message
// WAS: /datum/bioEffect/unintelligable
/datum/mutation/disability/unintelligable
name = "Unintelligable"
desc = "Heavily corrupts the part of the brain responsible for forming spoken sentences."
activation_messages = list("You can't seem to form any coherent thoughts!")
deactivation_messages = list("Your mind feels more clear.")
instability = -GENE_INSTABILITY_MINOR
/datum/mutation/disability/unintelligable/New()
..()
block = GLOB.scrambleblock
/datum/mutation/disability/unintelligable/on_say(mob/M, message)
var/prefix = copytext(message,1,2)
if(prefix == ";")
message = copytext(message,2)
else if(prefix in list(":","#"))
prefix += copytext(message,2,3)
message = copytext(message,3)
else
prefix=""
var/list/words = splittext(message," ")
var/list/rearranged = list()
for(var/i=1;i<=words.len;i++)
var/cword = pick(words)
words.Remove(cword)
var/suffix = copytext(cword,length(cword)-1,length(cword))
while(length(cword)>0 && (suffix in list(".",",",";","!",":","?")))
cword = copytext(cword,1 ,length(cword)-1)
suffix = copytext(cword,length(cword)-1,length(cword) )
if(length(cword))
rearranged += cword
return "[prefix][uppertext(jointext(rearranged," "))]!!"
//////////////////
// USELESS SHIT //
//////////////////
// WAS: /datum/bioEffect/strong
/datum/mutation/disability/strong
// pretty sure this doesn't do jack shit, putting it here until it does
name = "Strong"
desc = "Enhances the subject's ability to build and retain heavy muscles."
activation_messages = list("You feel buff!")
deactivation_messages = list("You feel wimpy and weak.")
/datum/mutation/disability/strong/New()
..()
block = GLOB.strongblock
// WAS: /datum/bioEffect/horns
/datum/mutation/disability/horns
name = "Horns"
desc = "Enables the growth of a compacted keratin formation on the subject's head."
activation_messages = list("A pair of horns erupt from your head.")
deactivation_messages = list("Your horns crumble away into nothing.")
/datum/mutation/disability/horns/New()
..()
block = GLOB.hornsblock
/datum/mutation/disability/horns/on_draw_underlays(mob/M, g)
return "horns_s"
/datum/mutation/grant_spell/immolate
name = "Incendiary Mitochondria"
desc = "The subject becomes able to convert excess cellular energy into thermal energy."
activation_messages = list("You suddenly feel rather hot.")
deactivation_messages = list("You no longer feel uncomfortably hot.")
spelltype = /obj/effect/proc_holder/spell/targeted/immolate
/datum/mutation/grant_spell/immolate/New()
..()
block = GLOB.immolateblock
/obj/effect/proc_holder/spell/targeted/immolate
name = "Incendiary Mitochondria"
desc = "The subject becomes able to convert excess cellular energy into thermal energy."
panel = "Abilities"
charge_type = "recharge"
charge_max = 600
clothes_req = 0
stat_allowed = 0
invocation_type = "none"
range = -1
selection_type = "range"
var/list/compatible_mobs = list(/mob/living/carbon/human)
include_user = 1
action_icon_state = "genetic_incendiary"
/obj/effect/proc_holder/spell/targeted/immolate/cast(list/targets, mob/living/user = usr)
var/mob/living/carbon/L = user
L.adjust_fire_stacks(0.5)
L.visible_message("<span class='danger'>[L.name]</b> suddenly bursts into flames!</span>")
L.IgniteMob()
playsound(L.loc, 'sound/effects/bamf.ogg', 50, 0)
/datum/mutation/disability/speech/loud
name = "Loud"
desc = "Forces the speaking centre of the subjects brain to yell every sentence."
activation_messages = list("YOU FEEL LIKE YELLING!")
deactivation_messages = list("You feel like being quiet..")
/datum/mutation/disability/speech/loud/New()
..()
block = GLOB.loudblock
/datum/mutation/disability/speech/loud/on_say(mob/M, message)
message = replacetext(message,".","!")
message = replacetext(message,"?","?!")
message = replacetext(message,"!","!!")
return uppertext(message)
/datum/mutation/disability/dizzy
name = "Dizzy"
desc = "Causes the cerebellum to shut down in some places."
activation_messages = list("You feel very dizzy...")
deactivation_messages = list("You regain your balance.")
instability = -GENE_INSTABILITY_MINOR
/datum/mutation/disability/dizzy/New()
..()
block = GLOB.dizzyblock
/datum/mutation/disability/dizzy/on_life(mob/living/carbon/human/M)
if(!istype(M))
return
M.Dizzy(300)
/datum/mutation/disability/dizzy/deactivate(mob/living/M)
..()
M.SetDizzy(0)
@@ -1,14 +1,14 @@
/datum/dna/gene/monkey
/datum/mutation/monkey
name = "Monkey"
/datum/dna/gene/monkey/New()
/datum/mutation/monkey/New()
..()
block = GLOB.monkeyblock
/datum/dna/gene/monkey/can_activate(mob/M, flags)
/datum/mutation/monkey/can_activate(mob/M, flags)
return ishuman(M)
/datum/dna/gene/monkey/activate(mob/living/carbon/human/H, connected, flags)
/datum/mutation/monkey/activate(mob/living/carbon/human/H)
if(!istype(H))
return
if(issmall(H))
@@ -43,7 +43,7 @@
return H
/datum/dna/gene/monkey/deactivate(mob/living/carbon/human/H, connected, flags)
/datum/mutation/monkey/deactivate(mob/living/carbon/human/H)
if(!istype(H))
return
if(!issmall(H))
File diff suppressed because it is too large Load Diff
+5 -7
View File
@@ -112,7 +112,7 @@ GLOBAL_LIST_INIT(possible_changeling_IDs, list("Alpha","Beta","Gamma","Delta","E
if(identity_theft.target && identity_theft.target.current)
identity_theft.target_real_name = kill_objective.target.current.real_name //Whoops, forgot this.
var/mob/living/carbon/human/H = identity_theft.target.current
if(can_absorb_species(H.dna.species)) // For species that can't be absorbed - should default to an escape objective
if(!HAS_TRAIT(H, TRAIT_GENELESS)) // For species that can't be absorbed - should default to an escape objective
identity_theft.explanation_text = "Escape on the shuttle or an escape pod with the identity of [identity_theft.target_real_name], the [identity_theft.target.assigned_role] while wearing [identity_theft.target.p_their()] identification card."
changeling.objectives += identity_theft
else
@@ -139,7 +139,8 @@ GLOBAL_LIST_INIT(possible_changeling_IDs, list("Alpha","Beta","Gamma","Delta","E
if(changeling.current.mind)
if(changeling.current.mind.assigned_role == "Clown")
to_chat(changeling.current, "You have evolved beyond your clownish nature, allowing you to wield weapons without harming yourself.")
changeling.current.mutations.Remove(CLUMSY)
changeling.current.dna.SetSEState(GLOB.clumsyblock, FALSE)
singlemutcheck(changeling.current, GLOB.clumsyblock, MUTCHK_FORCED)
var/datum/action/innate/toggle_clumsy/A = new
A.Grant(changeling.current)
var/obj_count = 1
@@ -315,11 +316,11 @@ GLOBAL_LIST_INIT(possible_changeling_IDs, list("Alpha","Beta","Gamma","Delta","E
to_chat(user, "<span class='warning'>[T] is not compatible with our biology.</span>")
return
if((NOCLONE || SKELETON || HUSK) in T.mutations)
if(HAS_TRAIT(T, TRAIT_BADDNA) || HAS_TRAIT(T, TRAIT_HUSK) || HAS_TRAIT(T, TRAIT_SKELETONIZED))
to_chat(user, "<span class='warning'>DNA of [target] is ruined beyond usability!</span>")
return
if(NO_DNA in T.dna.species.species_traits)
if(HAS_TRAIT(T, TRAIT_GENELESS))
to_chat(user, "<span class='warning'>This creature does not have DNA!</span>")
return
@@ -327,6 +328,3 @@ GLOBAL_LIST_INIT(possible_changeling_IDs, list("Alpha","Beta","Gamma","Delta","E
to_chat(user, "<span class='warning'>We already have this DNA in storage!</span>")
return 1
/proc/can_absorb_species(datum/species/S)
return !(NO_DNA in S.species_traits)
@@ -73,7 +73,7 @@ the same goes for Remove(). if you override Remove(), call parent or else your p
if(req_stat < user.stat)
to_chat(user, "<span class='warning'>We are incapacitated.</span>")
return 0
if((user.status_flags & FAKEDEATH) && name!="Regenerate")
if(HAS_TRAIT(user, TRAIT_FAKEDEATH) && name != "Regenerate")
to_chat(user, "<span class='warning'>We are incapacitated.</span>")
return 0
if(c.geneticdamage > max_genetic_damage)
@@ -112,7 +112,7 @@
to_chat(user, "We have reached our capacity for abilities.")
return FALSE
if(user.status_flags & FAKEDEATH)//To avoid potential exploits by buying new powers while in stasis, which clears your verblist.
if(HAS_TRAIT(user, TRAIT_FAKEDEATH)) //To avoid potential exploits by buying new powers while in stasis, which clears your verblist.
to_chat(user, "We lack the energy to evolve new abilities right now.")
return FALSE
@@ -49,7 +49,7 @@
/obj/item/organ/internal/cyberimp/eyes/shield/ling/on_life()
..()
var/obj/item/organ/internal/eyes/E = owner.get_int_organ(/obj/item/organ/internal/eyes)
if(owner.eye_blind || owner.eye_blurry || (BLINDNESS in owner.mutations) || (NEARSIGHTED in owner.mutations) || (E && E.damage > 0))
if(owner.eye_blind || owner.eye_blurry || HAS_TRAIT(owner, TRAIT_BLIND) || HAS_TRAIT(owner, TRAIT_NEARSIGHT) || (E && E.damage > 0))
owner.reagents.add_reagent("oculine", 1)
/obj/item/organ/internal/cyberimp/eyes/shield/ling/prepare_eat()
@@ -13,10 +13,10 @@
return
if(H.dna.GetSEState(GLOB.chameleonblock))
H.dna.SetSEState(GLOB.chameleonblock, 0)
genemutcheck(H, GLOB.chameleonblock, null, MUTCHK_FORCED)
singlemutcheck(H, GLOB.chameleonblock, MUTCHK_FORCED)
else
H.dna.SetSEState(GLOB.chameleonblock, 1)
genemutcheck(H, GLOB.chameleonblock, null, MUTCHK_FORCED)
singlemutcheck(H, GLOB.chameleonblock, MUTCHK_FORCED)
SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("[name]"))
return TRUE
@@ -25,5 +25,5 @@
var/mob/living/carbon/C = user
if(C.dna.GetSEState(GLOB.chameleonblock))
C.dna.SetSEState(GLOB.chameleonblock, 0)
genemutcheck(C, GLOB.chameleonblock, null, MUTCHK_FORCED)
singlemutcheck(C, GLOB.chameleonblock, MUTCHK_FORCED)
..()
@@ -15,7 +15,7 @@
if(user.stat != DEAD)
user.emote("deathgasp")
user.timeofdeath = world.time
user.status_flags |= FAKEDEATH //play dead
ADD_TRAIT(user, TRAIT_FAKEDEATH, "changeling") //play dead
user.updatehealth("fakedeath sting")
user.update_canmove()
user.mind.changeling.regenerating = TRUE
@@ -31,7 +31,7 @@
R.Grant(user)
/datum/action/changeling/fakedeath/can_sting(var/mob/user)
if(user.status_flags & FAKEDEATH)
if(HAS_TRAIT(user, TRAIT_FAKEDEATH))
to_chat(user, "<span class='warning'>We are already regenerating.</span>")
return
if(!user.stat)//Confirmation for living changelings if they want to fake their death
@@ -25,12 +25,12 @@
return 0
to_chat(user, "<span class='notice'>We transform our appearance.</span>")
user.dna.SetSEState(GLOB.monkeyblock,0,1)
genemutcheck(user,GLOB.monkeyblock,null,MUTCHK_FORCED)
singlemutcheck(user,GLOB.monkeyblock, MUTCHK_FORCED)
if(istype(user))
user.set_species(chosen_dna.species.type)
user.dna = chosen_dna.Clone()
user.real_name = chosen_dna.real_name
domutcheck(user,null,MUTCHK_FORCED)
domutcheck(user, MUTCHK_FORCED)
user.flavor_text = ""
user.dna.UpdateSE()
user.dna.UpdateUI()
@@ -19,9 +19,9 @@
user.SetEyeBlurry(0, FALSE)
user.RestoreEars()
user.heal_overall_damage(user.getBruteLoss(), user.getFireLoss(), updating_health = FALSE)
user.CureBlind(FALSE)
user.cure_blind(null, FALSE)
user.CureDeaf()
user.CureNearsighted(FALSE)
user.cure_nearsighted(null, FALSE)
user.reagents.clear_reagents()
user.germ_level = 0
user.timeofdeath = 0
@@ -52,7 +52,7 @@
H.remove_all_embedded_objects()
for(var/datum/disease/critical/C in user.viruses)
C.cure()
user.status_flags &= ~(FAKEDEATH)
REMOVE_TRAIT(user, TRAIT_FAKEDEATH, "changeling")
user.updatehealth("revive sting")
user.update_blind_effects()
user.update_blurry_effects()
@@ -16,7 +16,7 @@
if(H.check_ear_prot() >= HEARING_PROTECTION_TOTAL)
continue
if(!M.mind || !M.mind.changeling)
M.MinimumDeafTicks(30)
M.AdjustEarDamage(0, 30)
M.AdjustConfused(20)
M.Jitter(50)
else
@@ -17,7 +17,7 @@
if(enabled)
to_chat(user, "<span class='notice'>Our muscles tense and strengthen.</span>")
else
user.status_flags &= ~GOTTAGOFAST
REMOVE_TRAIT(user, TRAIT_GOTTAGOFAST, "changeling")
to_chat(user, "<span class='notice'>Our muscles relax.</span>")
if(stacks >= 10)
to_chat(user, "<span class='danger'>We collapse in exhaustion.</span>")
@@ -25,11 +25,11 @@
user.emote("gasp")
while(enabled)
user.status_flags |= GOTTAGOFAST
ADD_TRAIT(user, TRAIT_GOTTAGOFAST, "changeling")
if(user.stat || user.staminaloss >= 90)
enabled = 0 //Let's use something exact instead of !enabled where we can.
to_chat(user, "<span class='notice'>Our muscles relax without the energy to strengthen them.</span>")
user.status_flags &= ~GOTTAGOFAST
REMOVE_TRAIT(user, TRAIT_GOTTAGOFAST, "changeling")
user.Weaken(2)
user.emote("gasp")
break
@@ -15,10 +15,10 @@
to_chat(user, "<span class='warning'>We must have an aggressive grab on creature in our active hand to do this!</span>")
return
var/mob/living/carbon/human/target = G.affecting
if((NOCLONE || SKELETON || HUSK) in target.mutations)
if(HAS_TRAIT(target, TRAIT_BADDNA) || HAS_TRAIT(target, TRAIT_HUSK) || HAS_TRAIT(target, TRAIT_SKELETONIZED))
to_chat(user, "<span class='warning'>DNA of [target] is ruined beyond usability!</span>")
return
if(!istype(target) || !target.mind || issmall(target) || (NO_DNA in target.dna.species.species_traits))
if(!istype(target) || !target.mind || issmall(target) || HAS_TRAIT(target, TRAIT_GENELESS))
to_chat(user, "<span class='warning'>[target] is not compatible with this ability.</span>")
return
if(target.mind.changeling)
@@ -94,12 +94,12 @@
/datum/action/changeling/sting/transformation/can_sting(var/mob/user, var/mob/target)
if(!..())
return
if((HUSK in target.mutations) || (!ishuman(target)))
if(HAS_TRAIT(target, TRAIT_HUSK) || (!ishuman(target)))
to_chat(user, "<span class='warning'>Our sting appears ineffective against its DNA.</span>")
return FALSE
if(ishuman(target))
var/mob/living/carbon/human/H = target
if(NO_DNA in H.dna.species.species_traits)
if(HAS_TRAIT(H, TRAIT_GENELESS))
to_chat(user, "<span class='warning'>This won't work on a creature without DNA.</span>")
return FALSE
return TRUE
@@ -167,7 +167,7 @@
/datum/action/changeling/sting/blind/sting_action(var/mob/living/user, var/mob/living/target)
add_attack_logs(user, target, "Blind sting (changeling)")
to_chat(target, "<span class='danger'>Your eyes burn horrifically!</span>")
target.BecomeNearsighted()
target.become_nearsighted(EYE_DAMAGE)
target.EyeBlind(20)
target.EyeBlurry(40)
SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("[name]"))
+4 -2
View File
@@ -88,7 +88,8 @@ GLOBAL_LIST_EMPTY(all_cults)
if(cult_mind.assigned_role == "Clown")
to_chat(cult_mind.current, "<span class='cultitalic'>A dark power has allowed you to overcome your clownish nature, letting you wield weapons without harming yourself.</span>")
cult_mind.current.mutations.Remove(CLUMSY)
cult_mind.current.dna.SetSEState(GLOB.clumsyblock, FALSE)
singlemutcheck(cult_mind.current, GLOB.clumsyblock, MUTCHK_FORCED)
var/datum/action/innate/toggle_clumsy/A = new
A.Grant(cult_mind.current)
@@ -182,7 +183,8 @@ GLOBAL_LIST_EMPTY(all_cults)
if(cult_mind.assigned_role == "Clown")
to_chat(cult_mind.current, "<span class='cultitalic'>A dark power has allowed you to overcome your clownish nature, letting you wield weapons without harming yourself.</span>")
cult_mind.current.mutations.Remove(CLUMSY)
cult_mind.current.dna.SetSEState(GLOB.clumsyblock, FALSE)
singlemutcheck(cult_mind.current, GLOB.clumsyblock, MUTCHK_FORCED)
var/datum/action/innate/toggle_clumsy/A = new
A.Grant(cult_mind.current)
SEND_SOUND(cult_mind.current, 'sound/ambience/antag/bloodcult.ogg')
+1 -1
View File
@@ -31,7 +31,7 @@
to_chat(user, "<span class='warning'>You can't speak!</span>")
return
if((MUTE in user.mutations) || user.mind.miming) //Under vow of silence/mute?
if(HAS_TRAIT(user, TRAIT_MUTE) || user.mind.miming) //Under vow of silence/mute?
user.visible_message("<span class='notice'>[user] appears to whisper to themselves.</span>",
"<span class='notice'>You begin to whisper to yourself.</span>") //Make them do *something* abnormal.
sleep(10)
+3 -3
View File
@@ -53,7 +53,7 @@
user.Confused(10)
user.Jitter(6)
if(HULK in user.mutations)
if(HAS_TRAIT(user, TRAIT_HULK))
to_chat(user, "<span class='danger'>You can't seem to hold the blade properly!</span>")
return FALSE
@@ -200,12 +200,12 @@
user.Confused(10)
user.Weaken(5)
else if(slot == slot_wear_suit)
user.status_flags |= GOTTAGOFAST
ADD_TRAIT(user, TRAIT_GOTTAGOFAST, "cultrobes")
/obj/item/clothing/suit/hooded/cultrobes/flagellant_robe/dropped(mob/user)
. = ..()
if(user)
user.status_flags &= ~GOTTAGOFAST
REMOVE_TRAIT(user, TRAIT_GOTTAGOFAST, "cultrobes")
/obj/item/clothing/head/hooded/flagellant_hood
name = "flagellant's robes"
+1 -1
View File
@@ -74,7 +74,7 @@
if(invisibility)
to_chat(user, "<span class='cultitalic'>The magic in [src] is being channeled into Redspace, reveal the structure first!</span>")
return
if(HULK in user.mutations)
if(HAS_TRAIT(user, TRAIT_HULK))
to_chat(user, "<span class='danger'>You cannot seem to manipulate this structure with your bulky hands!</span>")
return
if(!anchored)
+2 -1
View File
@@ -38,7 +38,8 @@
devil_mind.devilinfo.link_with_mob(devil_mind.current)
if(devil_mind.assigned_role == "Clown")
to_chat(devil_mind.current, "Your infernal nature allows you to wield weapons without harming yourself.")
devil_mind.current.mutations.Remove(CLUMSY)
devil_mind.current.dna.SetSEState(GLOB.clumsyblock, FALSE)
singlemutcheck(devil_mind.current, GLOB.clumsyblock, MUTCHK_FORCED)
var/datum/action/innate/toggle_clumsy/A = new
A.Grant(devil_mind.current)
spawn(10)
@@ -281,13 +281,13 @@
if(ishuman(owner))
owner.gene_stability += GENE_INSTABILITY_MODERATE // give them this gene for free
owner.dna.SetSEState(GLOB.shockimmunityblock, TRUE)
genemutcheck(owner, GLOB.shockimmunityblock, null, MUTCHK_FORCED)
singlemutcheck(owner, GLOB.shockimmunityblock, MUTCHK_FORCED)
/obj/item/organ/internal/heart/gland/electric/remove(mob/living/carbon/M, special = 0)
if(ishuman(owner))
owner.gene_stability -= GENE_INSTABILITY_MODERATE // but return it to normal once it's removed
owner.dna.SetSEState(GLOB.shockimmunityblock, FALSE)
genemutcheck(owner, GLOB.shockimmunityblock, null, MUTCHK_FORCED)
singlemutcheck(owner, GLOB.shockimmunityblock, MUTCHK_FORCED)
return ..()
/obj/item/organ/internal/heart/gland/electric/activate()
@@ -22,8 +22,7 @@
. = ..()
if(!summoner)
return
if(!(NO_SHOCK in summoner.mutations))
summoner.mutations.Add(NO_SHOCK)
ADD_TRAIT(summoner, TRAIT_SHOCKIMMUNE, "guardian")
/mob/living/simple_animal/hostile/guardian/beam/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
return FALSE //You are lightning, you should not be hurt by such things.
@@ -118,6 +117,6 @@
. = 1
/mob/living/simple_animal/hostile/guardian/beam/death(gibbed)
if(summoner && (NO_SHOCK in summoner.mutations))
summoner.mutations.Remove(NO_SHOCK)
if(summoner)
REMOVE_TRAIT(summoner, TRAIT_SHOCKIMMUNE, "guardian")
return ..()
+2 -2
View File
@@ -317,7 +317,7 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective)
for(var/datum/mind/possible_target in SSticker.minds)
if(possible_target != owner && ishuman(possible_target.current) && (possible_target.current.stat != DEAD) && possible_target.current.client)
var/mob/living/carbon/human/H = possible_target.current
if(!(NO_DNA in H.dna.species.species_traits))
if(!HAS_TRAIT(H, TRAIT_GENELESS))
possible_targets += possible_target
if(possible_targets.len > 0)
target = pick(possible_targets)
@@ -489,7 +489,7 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective)
n_p++
else if(SSticker.current_state == GAME_STATE_PLAYING)
for(var/mob/living/carbon/human/P in GLOB.player_list)
if(NO_DNA in P.dna.species.species_traits)
if(HAS_TRAIT(P, TRAIT_GENELESS))
continue
if(P.client && !(P.mind in SSticker.mode.changelings) && P.mind!=owner)
n_p++
+2 -1
View File
@@ -121,7 +121,8 @@
if(mob.mind)
if(mob.mind.assigned_role == "Clown")
to_chat(mob, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.")
mob.mutations.Remove(CLUMSY)
mob.dna.SetSEState(GLOB.clumsyblock, FALSE)
singlemutcheck(mob, GLOB.clumsyblock, MUTCHK_FORCED)
var/datum/action/innate/toggle_clumsy/A = new
A.Grant(mob)
+11 -11
View File
@@ -107,14 +107,14 @@
// Monkeyblock is always last.
GLOB.monkeyblock = DNA_SE_LENGTH
// And the genes that actually do the work. (domutcheck improvements)
// And the mutations that actually do the work. (domutcheck improvements)
var/list/blocks_assigned[DNA_SE_LENGTH]
for(var/gene_type in typesof(/datum/dna/gene))
var/datum/dna/gene/G = new gene_type
for(var/mutation_type in typesof(/datum/mutation))
var/datum/mutation/G = new mutation_type
if(G.block)
if(G.block in blocks_assigned)
warning("DNA2: Gene [G.name] trying to use already-assigned block [G.block] (used by [english_list(blocks_assigned[G.block])])")
GLOB.dna_genes.Add(G)
GLOB.dna_mutations.Add(G)
var/list/assignedToBlock[0]
if(blocks_assigned[G.block])
assignedToBlock=blocks_assigned[G.block]
@@ -122,14 +122,14 @@
blocks_assigned[G.block]=assignedToBlock
//testing("DNA2: Gene [G.name] assigned to block [G.block].")
// I WILL HAVE A LIST OF GENES THAT MATCHES THE RANDOMIZED BLOCKS GODDAMNIT!
for(var/block=1;block<=DNA_SE_LENGTH;block++)
// I WILL HAVE A LIST OF MUTATIONS THAT MATCHES THE RANDOMIZED BLOCKS GODDAMNIT!
for(var/block in 1 to DNA_SE_LENGTH)
var/name = GLOB.assigned_blocks[block]
for(var/datum/dna/gene/gene in GLOB.dna_genes)
if(gene.name == name || gene.block == block)
if(gene.block in GLOB.assigned_gene_blocks)
warning("DNA2: Gene [gene.name] trying to add to already assigned gene block list (used by [english_list(GLOB.assigned_gene_blocks[block])])")
GLOB.assigned_gene_blocks[block] = gene
for(var/datum/mutation/mutation in GLOB.dna_mutations)
if(mutation.name == name || mutation.block == block)
if(mutation.block in GLOB.assigned_mutation_blocks)
warning("DNA2: Mutation [mutation.name] trying to add to already assigned gene block list (used by [english_list(GLOB.assigned_mutation_blocks[block])])")
GLOB.assigned_mutation_blocks[block] = mutation
//testing("DNA2: [numsToAssign.len] blocks are unused: [english_list(numsToAssign)]")
+2 -1
View File
@@ -148,7 +148,8 @@ Made by Xhuis
update_shadow_icons_added(shadow_mind)
if(shadow_mind.assigned_role == "Clown")
to_chat(S, "<span class='notice'>Your alien nature has allowed you to overcome your clownishness.</span>")
S.mutations.Remove(CLUMSY)
S.dna.SetSEState(GLOB.clumsyblock, FALSE)
singlemutcheck(S, GLOB.clumsyblock, MUTCHK_FORCED)
/datum/game_mode/proc/add_thrall(datum/mind/new_thrall_mind)
if(!istype(new_thrall_mind))
+2 -1
View File
@@ -185,7 +185,8 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha
if(vampire.current.mind)
if(vampire.current.mind.assigned_role == "Clown")
to_chat(vampire.current, "Your lust for blood has allowed you to overcome your clumsy nature allowing you to wield weapons without harming yourself.")
vampire.current.mutations.Remove(CLUMSY)
vampire.current.dna.SetSEState(GLOB.clumsyblock, FALSE)
singlemutcheck(vampire.current, GLOB.clumsyblock, MUTCHK_FORCED)
var/datum/action/innate/toggle_clumsy/A = new
A.Grant(vampire.current)
var/obj_count = 1
@@ -270,7 +270,7 @@
continue
to_chat(C, "<span class='warning'><font size='3'><b>You hear a ear piercing shriek and your senses dull!</font></b></span>")
C.Weaken(4)
C.MinimumDeafTicks(20)
C.AdjustEarDamage(0, 20)
C.Stuttering(20)
C.Stun(4)
C.Jitter(150)
+33 -2
View File
@@ -220,6 +220,37 @@
damtype = BURN
force = 15
hitsound = 'sound/items/welder2.ogg'
var/mob/current_owner
/obj/item/scrying/Initialize(mapload)
. = ..()
START_PROCESSING(SSobj, src)
/obj/item/scrying/Destroy()
STOP_PROCESSING(SSobj, src)
current_owner = null
return ..()
/obj/item/scrying/process()
var/mob/holder = get(loc, /mob)
if(current_owner && current_owner != holder)
to_chat(current_owner, "<span class='notice'>Your otherworldly vision fades...</span>")
REMOVE_TRAIT(current_owner, TRAIT_XRAY_VISION, SCRYING_ORB)
current_owner.update_sight()
current_owner.update_icons()
current_owner = null
if(!current_owner && holder)
current_owner = holder
to_chat(current_owner, "<span class='notice'>You can see...everything!</span>")
ADD_TRAIT(current_owner, TRAIT_XRAY_VISION, SCRYING_ORB)
current_owner.update_sight()
current_owner.update_icons()
/obj/item/scrying/attack_self(mob/user as mob)
to_chat(user, "<span class='notice'> You can see...everything!</span>")
@@ -342,7 +373,7 @@ GLOBAL_LIST_EMPTY(multiverse)
if(duplicate_self)
M.dna = user.dna.Clone()
M.UpdateAppearance()
domutcheck(M, null)
domutcheck(M)
M.update_body()
M.update_hair()
M.update_fhair()
@@ -796,7 +827,7 @@ GLOBAL_LIST_EMPTY(multiverse)
else if(istype(I,/obj/item/bikehorn))
to_chat(target, "<span class='userdanger'>HONK</span>")
target << 'sound/items/airhorn.ogg'
target.MinimumDeafTicks(3)
target.AdjustEarDamage(0, 3)
GiveHint(target)
cooldown = world.time +cooldown_time
return
-10
View File
@@ -386,16 +386,6 @@
log_name = "SO"
category = "Artefacts"
/datum/spellbook_entry/item/scryingorb/Buy(mob/living/carbon/human/user, obj/item/spellbook/book)
if(..())
if(!(XRAY in user.mutations))
user.mutations.Add(XRAY)
user.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS)
user.see_in_dark = 8
user.lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
to_chat(user, "<span class='notice'>The walls suddenly disappear.</span>")
return TRUE
/datum/spellbook_entry/item/soulstones
name = "Six Soul Stone Shards and the spell Artificer"
desc = "Soul Stone Shards are ancient tools capable of capturing and harnessing the spirits of the dead and dying. The spell Artificer allows you to create arcane machines for the captured souls to pilot."
+1 -2
View File
@@ -149,8 +149,7 @@
if(visualsOnly)
return
H.dna.SetSEState(GLOB.soberblock,1)
H.mutations += SOBER
H.dna.SetSEState(GLOB.soberblock, TRUE)
H.check_mutations = 1
/datum/job/officer
+7 -5
View File
@@ -34,7 +34,7 @@
return
H.dna.SetSEState(GLOB.soberblock,1)
genemutcheck(H, GLOB.soberblock, null, MUTCHK_FORCED)
singlemutcheck(H, GLOB.soberblock, MUTCHK_FORCED)
H.dna.default_blocks.Add(GLOB.soberblock)
H.check_mutations = 1
@@ -292,11 +292,11 @@
implant.insert(H)
H.dna.SetSEState(GLOB.clumsyblock, TRUE)
genemutcheck(H, GLOB.clumsyblock, null, MUTCHK_FORCED)
singlemutcheck(H, GLOB.clumsyblock, MUTCHK_FORCED)
H.dna.default_blocks.Add(GLOB.clumsyblock)
if(!ismachineperson(H))
H.dna.SetSEState(GLOB.comicblock, TRUE)
genemutcheck(H, GLOB.comicblock, null, MUTCHK_FORCED)
singlemutcheck(H, GLOB.comicblock, MUTCHK_FORCED)
H.dna.default_blocks.Add(GLOB.comicblock)
H.check_mutations = TRUE
H.add_language("Clownish")
@@ -308,7 +308,8 @@
/datum/action/innate/toggle_clumsy/Activate()
var/mob/living/carbon/human/H = owner
H.mutations.Add(CLUMSY)
H.dna.SetSEState(GLOB.clumsyblock, TRUE)
singlemutcheck(H, GLOB.clumsyblock, MUTCHK_FORCED)
active = TRUE
background_icon_state = "bg_spell"
UpdateButtonIcon()
@@ -316,7 +317,8 @@
/datum/action/innate/toggle_clumsy/Deactivate()
var/mob/living/carbon/human/H = owner
H.mutations.Remove(CLUMSY)
H.dna.SetSEState(GLOB.clumsyblock, FALSE)
singlemutcheck(H, GLOB.clumsyblock, MUTCHK_FORCED)
active = FALSE
background_icon_state = "bg_default"
UpdateButtonIcon()
+6 -6
View File
@@ -321,9 +321,9 @@
occupantData["intOrgan"] = intOrganData
occupantData["blind"] = (BLINDNESS in occupant.mutations)
occupantData["colourblind"] = (COLOURBLIND in occupant.mutations)
occupantData["nearsighted"] = (NEARSIGHTED in occupant.mutations)
occupantData["blind"] = HAS_TRAIT(occupant, TRAIT_BLIND)
occupantData["colourblind"] = HAS_TRAIT(occupant, TRAIT_COLORBLIND)
occupantData["nearsighted"] = HAS_TRAIT(occupant, TRAIT_NEARSIGHT)
data["occupant"] = occupantData
return data
@@ -511,11 +511,11 @@
dat += "<td>[i.name]</td><td>N/A</td><td>[i.damage]</td><td>[infection]:[mech][dead]</td><td></td>"
dat += "</tr>"
dat += "</table>"
if(BLINDNESS in occupant.mutations)
if(HAS_TRAIT(occupant, TRAIT_BLIND))
dat += "<font color='red'>Cataracts detected.</font><BR>"
if(COLOURBLIND in occupant.mutations)
if(HAS_TRAIT(occupant, TRAIT_COLORBLIND))
dat += "<font color='red'>Photoreceptor abnormalities detected.</font><BR>"
if(NEARSIGHTED in occupant.mutations)
if(HAS_TRAIT(occupant, TRAIT_NEARSIGHT))
dat += "<font color='red'>Retinal misalignment detected.</font><BR>"
else
dat += "[src] is empty."
+1 -1
View File
@@ -274,7 +274,7 @@ GLOBAL_LIST_INIT(cloner_biomass_items, list(\
for(var/datum/language/L in R.languages)
H.add_language(L.name)
domutcheck(H, null, MUTCHK_FORCED) //Ensures species that get powers by the species proc handle_dna keep them
domutcheck(H, MUTCHK_FORCED) //Ensures species that get powers by the species proc handle_dna keep them
if(efficiency > 2 && efficiency < 5 && prob(25))
randmutb(H)
+1 -1
View File
@@ -185,7 +185,7 @@
var/patientStatus // Tell the computer what to say based on the status of the patient on the table.
var/isNewPatient = (table.patient != currentPatient) //Is this a new Patient?
if(table.patient.stat == DEAD || table.patient.status_flags & FAKEDEATH)
if(table.patient.stat == DEAD || HAS_TRAIT(table.patient, TRAIT_FAKEDEATH))
patientStatus = "Dead"
else if(table.patient.stat == CONSCIOUS)
patientStatus = "Awake"
+3 -3
View File
@@ -392,7 +392,7 @@
if(subject.get_int_organ(/obj/item/organ/internal/brain))
var/obj/item/organ/internal/brain/Brn = subject.get_int_organ(/obj/item/organ/internal/brain)
if(istype(Brn))
if(NO_SCAN in Brn.dna.species.species_traits)
if(NO_CLONESCAN in Brn.dna.species.species_traits)
set_scan_temp("[Brn.dna.species.name_plural] are not scannable.", "bad")
SStgui.update_uis(src)
return
@@ -408,7 +408,7 @@
set_scan_temp("Subject's brain is not responding. Further attempts after a short delay may succeed.", "bad")
SStgui.update_uis(src)
return
if((NOCLONE in subject.mutations) && src.scanner.scan_level < 2)
if(HAS_TRAIT(subject, TRAIT_BADDNA) && src.scanner.scan_level < 2)
set_scan_temp("Subject has incompatible genetic mutations.", "bad")
SStgui.update_uis(src)
return
@@ -432,7 +432,7 @@
var/obj/item/organ/B = subject.get_int_organ(/obj/item/organ/internal/brain)
B.dna.check_integrity()
R.dna=B.dna.Clone()
if(NO_SCAN in R.dna.species.species_traits)
if(NO_CLONESCAN in R.dna.species.species_traits)
extra_info = "Proper genetic interface not found, defaulting to genetic data of the body."
R.dna.species = new subject.dna.species.type
R.id= copytext(md5(B.dna.real_name), 2, 6)
+1 -1
View File
@@ -204,7 +204,7 @@
set name = "Rotate Frame"
set src in view(1)
if( usr.stat || usr.restrained() || (usr.status_flags & FAKEDEATH))
if( usr.stat || usr.restrained() || HAS_TRAIT(usr, TRAIT_FAKEDEATH))
return
src.dir = turn(src.dir, -90)
+2 -2
View File
@@ -115,9 +115,9 @@
if(drownee && ((drownee.lying && !drownee.player_logged) || deep_water)) //Mob lying down and not SSD or water is deep (determined by controller)
if(drownee.internal)
return //Has internals, no drowning
if((NO_BREATHE in drownee.dna.species.species_traits) || (BREATHLESS in drownee.mutations))
if(HAS_TRAIT(drownee, TRAIT_NOBREATH))
return //doesn't breathe, no drowning
if(HAS_TRAIT(drownee,TRAIT_WATERBREATH))
if(HAS_TRAIT(drownee, TRAIT_WATERBREATH))
return //fish things don't drown
if(drownee.stat == DEAD) //Dead spacemen don't drown more
+3 -3
View File
@@ -205,10 +205,10 @@
if(prob(5))
if(prob(75))
randmutb(H) // Applies bad mutation
domutcheck(H,null,1)
domutcheck(H, MUTCHK_FORCED)
else
randmutg(H) // Applies good mutation
domutcheck(H,null,1)
domutcheck(H, MUTCHK_FORCED)
/obj/machinery/transformer/xray/proc/scan(obj/item/I)
@@ -309,7 +309,7 @@
H.real_name = template.real_name
H.sync_organ_dna(assimilate = 0, old_ue = prev_ue)
H.UpdateAppearance()
domutcheck(H, null, MUTCHK_FORCED)
domutcheck(H, MUTCHK_FORCED)
H.update_mutations()
/obj/machinery/transformer/gene_applier/attackby(obj/item/I, mob/living/user, params)
+1 -1
View File
@@ -212,7 +212,7 @@
to_chat(M, "<font color='red' size='7'>HONK</font>")
M.SetSleeping(0)
M.Stuttering(20)
M.MinimumDeafTicks(30)
M.AdjustEarDamage(0, 30)
M.Weaken(3)
if(prob(30))
M.Stun(10)
+1 -1
View File
@@ -887,7 +887,7 @@
else
examine(user)
if(occupant)
user << "<span class='warning'>This exosuit has a pilot and cannot be controlled.</span>"
to_chat(user, "<span class='warning'>This exosuit has a pilot and cannot be controlled.</span>")
return
var/can_control_mech = FALSE
for(var/obj/item/mecha_parts/mecha_tracking/ai_control/A in trackers)
+5 -7
View File
@@ -68,12 +68,10 @@
/obj/effect/mine/dnascramble/mineEffect(mob/living/victim)
victim.rad_act(radiation_amount)
if(ishuman(victim))
var/mob/living/carbon/human/V = victim
if(NO_DNA in V.dna.species.species_traits)
return
if(!victim.dna || HAS_TRAIT(victim, TRAIT_GENELESS))
return
randmutb(victim)
domutcheck(victim ,null)
domutcheck(victim)
/obj/effect/mine/gas
name = "oxygen mine"
@@ -179,7 +177,7 @@
if(!victim.client || !istype(victim))
return
to_chat(victim, "<span class='notice'>You feel fast!</span>")
victim.status_flags |= GOTTAGOFAST
ADD_TRAIT(victim, TRAIT_GOTTAGOFAST, "mine")
spawn(duration)
victim.status_flags &= ~GOTTAGOFAST
REMOVE_TRAIT(victim, TRAIT_GOTTAGOFAST, "mine")
to_chat(victim, "<span class='notice'>You slow down.</span>")
+1 -1
View File
@@ -21,7 +21,7 @@
var/use_sound = 'sound/weapons/flash.ogg'
/obj/item/flash/proc/clown_check(mob/user)
if(user && (CLUMSY in user.mutations) && prob(50))
if(user && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
flash_carbon(user, user, 15, 0)
return 0
return 1
@@ -48,7 +48,7 @@
add_fingerprint(user)
if(on && user.zone_selected == "eyes")
if(((CLUMSY in user.mutations) || user.getBrainLoss() >= 60) && prob(50)) //too dumb to use flashlight properly
if((HAS_TRAIT(user, TRAIT_CLUMSY) || user.getBrainLoss() >= 60) && prob(50)) //too dumb to use flashlight properly
return ..() //just hit them in the head
if(!(istype(user, /mob/living/carbon/human) || SSticker) && SSticker.mode.name != "monkey") //don't have dexterity
@@ -74,9 +74,9 @@
if(istype(H)) //robots and aliens are unaffected
var/obj/item/organ/internal/eyes/eyes = H.get_int_organ(/obj/item/organ/internal/eyes)
if(M.stat == DEAD || !eyes || (BLINDNESS in M.mutations)) //mob is dead or fully blind
if(M.stat == DEAD || !eyes || HAS_TRAIT(M, TRAIT_BLIND)) //mob is dead or fully blind
to_chat(user, "<span class='notice'>[M]'s pupils are unresponsive to the light!</span>")
else if((XRAY in M.mutations) || eyes.see_in_dark >= 8) //The mob's either got the X-RAY vision or has a tapetum lucidum (extreme nightvision, i.e. Vulp/Tajara with COLOURBLIND & their monkey forms).
else if(HAS_TRAIT(M, TRAIT_XRAY_VISION) || eyes.see_in_dark >= 8) //The mob's either got the X-RAY vision or has a tapetum lucidum (extreme nightvision, i.e. Vulp/Tajara with COLOURBLIND & their monkey forms).
to_chat(user, "<span class='notice'>[M]'s pupils glow eerily!</span>")
else //they're okay!
if(M.flash_eyes(visual = 1))
@@ -79,11 +79,9 @@
if(!user.IsAdvancedToolUser())
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
return
if(ishuman(user))
var/mob/living/carbon/human/H = user
if((HULK in H.mutations) || (NOGUNS in H.dna.species.species_traits))
user << "<span class='warning'>Your fingers can't press the button!</span>"
return
if(HAS_TRAIT(user, TRAIT_CHUNKYFINGERS))
to_chat(user, "<span class='warning'>Your fingers can't press the button!</span>")
return
add_fingerprint(user)
+1 -1
View File
@@ -32,7 +32,7 @@
if(H && H.mind && H.mind.miming)
to_chat(user, "<span class='warning'>Your vow of silence prevents you from speaking.</span>")
return
if((COMIC in H.mutations) || H.get_int_organ(/obj/item/organ/internal/cyberimp/brain/clown_voice))
if(HAS_TRAIT(H, TRAIT_COMIC_SANS))
span = "sans"
if(spamcheck)
to_chat(user, "<span class='warning'>\The [src] needs to recharge!</span>")
+7 -7
View File
@@ -98,7 +98,7 @@ REAGENT SCANNER
var/advanced = FALSE
/obj/item/healthanalyzer/attack(mob/living/M, mob/living/user)
if(((CLUMSY in user.mutations) || user.getBrainLoss() >= 60) && prob(50))
if((HAS_TRAIT(user, TRAIT_CLUMSY) || user.getBrainLoss() >= 60) && prob(50))
user.visible_message("<span class='warning'>[user] analyzes the floor's vitals!</span>", "<span class='notice'>You stupidly try to analyze the floor's vitals!</span>")
to_chat(user, "<span class='info'>Analyzing results for The floor:\n\tOverall status: <b>Healthy</b></span>")
to_chat(user, "<span class='info'>Key: <font color='blue'>Suffocation</font>/<font color='green'>Toxin</font>/<font color='#FF8000'>Burn</font>/<font color='red'>Brute</font></span>")
@@ -130,7 +130,7 @@ REAGENT SCANNER
var/TX = H.getToxLoss() > 50 ? "<b>[H.getToxLoss()]</b>" : H.getToxLoss()
var/BU = H.getFireLoss() > 50 ? "<b>[H.getFireLoss()]</b>" : H.getFireLoss()
var/BR = H.getBruteLoss() > 50 ? "<b>[H.getBruteLoss()]</b>" : H.getBruteLoss()
if(H.status_flags & FAKEDEATH)
if(HAS_TRAIT(H, TRAIT_FAKEDEATH))
OX = fake_oxy > 50 ? "<b>[fake_oxy]</b>" : fake_oxy
to_chat(user, "<span class='notice'>Analyzing Results for [H]:\n\t Overall Status: dead</span>")
else
@@ -138,7 +138,7 @@ REAGENT SCANNER
to_chat(user, "\t Key: <font color='blue'>Suffocation</font>/<font color='green'>Toxin</font>/<font color='#FFA500'>Burns</font>/<font color='red'>Brute</font>")
to_chat(user, "\t Damage Specifics: <font color='blue'>[OX]</font> - <font color='green'>[TX]</font> - <font color='#FFA500'>[BU]</font> - <font color='red'>[BR]</font>")
to_chat(user, "<span class='notice'>Body Temperature: [H.bodytemperature-T0C]&deg;C ([H.bodytemperature*1.8-459.67]&deg;F)</span>")
if(H.timeofdeath && (H.stat == DEAD || (H.status_flags & FAKEDEATH)))
if(H.timeofdeath && (H.stat == DEAD || (HAS_TRAIT(H, TRAIT_FAKEDEATH))))
to_chat(user, "<span class='notice'>Time of Death: [station_time_timestamp("hh:mm:ss", H.timeofdeath)]</span>")
var/tdelta = round(world.time - H.timeofdeath)
if(tdelta < DEFIB_TIME_LIMIT)
@@ -155,7 +155,7 @@ REAGENT SCANNER
TX = H.getToxLoss() > 50 ? "<font color='green'><b>Dangerous amount of toxins detected</b></font>" : "Subject bloodstream toxin level minimal"
BU = H.getFireLoss() > 50 ? "<font color='#FFA500'><b>Severe burn damage detected</b></font>" : "Subject burn injury status O.K"
BR = H.getBruteLoss() > 50 ? "<font color='red'><b>Severe anatomical damage detected</b></font>" : "Subject brute-force injury status O.K"
if(H.status_flags & FAKEDEATH)
if(HAS_TRAIT(H, TRAIT_FAKEDEATH))
OX = fake_oxy > 50 ? "<span class='danger'>Severe oxygen deprivation detected</span>" : "<span class='notice'>Subject bloodstream oxygen level normal</span>"
to_chat(user, "[OX] | [TX] | [BU] | [BR]")
@@ -837,11 +837,11 @@ REAGENT SCANNER
dat += "<td>[i.name]</td><td>N/A</td><td>[i.damage]</td><td>[infection]:[mech]</td><td></td>"
dat += "</tr>"
dat += "</table>"
if(BLINDNESS in target.mutations)
if(HAS_TRAIT(target, TRAIT_BLIND))
dat += "<font color='red'>Cataracts detected.</font><BR>"
if(COLOURBLIND in target.mutations)
if(HAS_TRAIT(target, TRAIT_COLORBLIND))
dat += "<font color='red'>Photoreceptor abnormalities detected.</font><BR>"
if(NEARSIGHTED in target.mutations)
if(HAS_TRAIT(target, TRAIT_NEARSIGHT))
dat += "<font color='red'>Retinal misalignment detected.</font><BR>"
return dat
+1 -1
View File
@@ -45,7 +45,7 @@
return ..()
if(user.zone_selected != "eyes" && user.zone_selected != "head")
return ..()
if((CLUMSY in user.mutations) && prob(50))
if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
M = user
return eyestab(M,user)
+1 -1
View File
@@ -35,7 +35,7 @@
return ..()
add_fingerprint(user)
if((CLUMSY in user.mutations) && prob(50))
if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
user.visible_message("<span class='danger'>[user] accidentally clubs [user.p_them()]self with [src]!</span>", \
"<span class='userdanger'>You accidentally club yourself with [src]!</span>")
user.Weaken(force * 3)
+2 -2
View File
@@ -419,7 +419,7 @@
for(var/obj/item/organ/external/O in H.bodyparts)
total_brute += O.brute_dam
total_burn += O.burn_dam
if(total_burn <= 180 && total_brute <= 180 && !H.suiciding && !ghost && tplus < tlimit && !(NOCLONE in H.mutations) && (H.mind && H.mind.is_revivable()) && (H.get_int_organ(/obj/item/organ/internal/heart) || H.get_int_organ(/obj/item/organ/internal/brain/slime)))
if(total_burn <= 180 && total_brute <= 180 && !H.suiciding && !ghost && tplus < tlimit && !HAS_TRAIT(H, TRAIT_HUSK) && !HAS_TRAIT(H, TRAIT_BADDNA) && (H.mind && H.mind.is_revivable()) && (H.get_int_organ(/obj/item/organ/internal/heart) || H.get_int_organ(/obj/item/organ/internal/brain/slime)))
tobehealed = min(health + threshold, 0) // It's HILARIOUS without this min statement, let me tell you
tobehealed -= 5 //They get 5 of each type of damage healed so excessive combined damage will not immediately kill them after they get revived
H.adjustOxyLoss(tobehealed)
@@ -538,7 +538,7 @@
for(var/obj/item/organ/external/O in H.bodyparts)
total_brute += O.brute_dam
total_burn += O.burn_dam
if(total_burn <= 180 && total_brute <= 180 && !H.suiciding && !ghost && tplus < tlimit && !(NOCLONE in H.mutations) && (H.mind && H.mind.is_revivable()))
if(total_burn <= 180 && total_brute <= 180 && !H.suiciding && !ghost && tplus < tlimit && !HAS_TRAIT(H, TRAIT_HUSK) && (H.mind && H.mind.is_revivable()))
tobehealed = min(health + threshold, 0) // It's HILARIOUS without this min statement, let me tell you
tobehealed -= 5 //They get 5 of each type of damage healed so excessive combined damage will not immediately kill them after they get revived
H.adjustOxyLoss(tobehealed)
@@ -80,7 +80,7 @@
return
spawn(0) //Some mutations have sleeps in them, like monkey
if(!(NOCLONE in M.mutations) && !(H && (NO_DNA in H.dna.species.species_traits))) // prevents drained people from having their DNA changed
if(!HAS_TRAIT(M, TRAIT_BADDNA) && !HAS_TRAIT(M, TRAIT_GENELESS)) // prevents drained people from having their DNA changed
var/prev_ue = M.dna.unique_enzymes
// UI in syringe.
if(buf.types & DNA2_BUF_UI)
@@ -103,7 +103,7 @@
M.dna.UpdateSE()
else
M.dna.SetSEValue(block,src.GetValue())
domutcheck(M, null, forcedmutation ? MUTCHK_FORCED : 0)
domutcheck(M, forcedmutation ? MUTCHK_FORCED : FALSE)
M.update_mutations()
if(H)
H.sync_organ_dna(assimilate = 0, old_ue = prev_ue)
@@ -112,14 +112,9 @@
if(used)
to_chat(user, "<span class='warning'>This injector is used up!</span>")
return
if(!M.dna) //You know what would be nice? If the mob you're injecting has DNA, and so doesn't cause runtimes.
if(!M.dna || HAS_TRAIT(M, TRAIT_GENELESS) || HAS_TRAIT(M, TRAIT_BADDNA)) //You know what would be nice? If the mob you're injecting has DNA, and so doesn't cause runtimes.
return FALSE
if(ishuman(M)) // Would've done this via species instead of type, but the basic mob doesn't have a species, go figure.
var/mob/living/carbon/human/H = M
if(NO_DNA in H.dna.species.species_traits)
return FALSE
if(!user.IsAdvancedToolUser())
return FALSE
@@ -22,11 +22,9 @@
if(used)
return
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(NO_DNA in H.dna.species.species_traits)
to_chat(user, "<span class='warning'>You failed to inject [M], as [M.p_they()] [M.p_have()] no DNA to scramble, nor flesh to inject.</span>")
return
if(HAS_TRAIT(M, TRAIT_GENELESS))
to_chat(user, "<span class='warning'>You failed to inject [M], as [M.p_they()] [M.p_have()] no DNA to scramble, nor flesh to inject.</span>")
return
if(M == user)
user.visible_message("<span class='danger'>[user] injects [user.p_them()]self with [src]!</span>")
@@ -74,7 +74,7 @@
if(!ear_safety)
M.Stun(stun_amount)
M.Weaken(stun_amount)
M.AdjustEarDamage(rand(0, 5), 15)
M.AdjustEarDamage(5, 15)
if(iscarbon(M))
var/mob/living/carbon/C = M
var/obj/item/organ/internal/ears/ears = C.get_int_organ(/obj/item/organ/internal/ears)
@@ -83,6 +83,5 @@
to_chat(M, "<span class='warning'>Your ears start to ring badly!</span>")
if(prob(ears.ear_damage - 5))
to_chat(M, "<span class='warning'>You can't hear anything!</span>")
M.BecomeDeaf()
else if(ears.ear_damage >= 5)
to_chat(M, "<span class='warning'>Your ears start to ring!</span>")
@@ -22,7 +22,7 @@
qdel(src)
/obj/item/grenade/proc/clown_check(var/mob/living/user)
if((CLUMSY in user.mutations) && prob(50))
if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
to_chat(user, "<span class='warning'>Huh? How does this thing work?</span>")
active = 1
icon_state = initial(icon_state) + "_active"
+1 -1
View File
@@ -29,7 +29,7 @@
to_chat(user, "<span class='warning'>[src] is stuck to your hand!</span>")
return
if((CLUMSY in user.mutations) && prob(50) && (!ignoresClumsy))
if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50) && (!ignoresClumsy))
to_chat(user, "<span class='warning'>Uh... how do those things work?!</span>")
apply_cuffs(user, user)
return
+1 -1
View File
@@ -48,7 +48,7 @@
if(user.a_intent != INTENT_HELP)
if(user.zone_selected == "head" || user.zone_selected == "eyes")
if((CLUMSY in user.mutations) && prob(50))
if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
C = user
return eyestab(C, user)
else
@@ -37,7 +37,7 @@
return BRUTELOSS|FIRELOSS
/obj/item/melee/energy/attack_self(mob/living/carbon/user)
if((CLUMSY in user.mutations) && prob(50))
if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
to_chat(user, "<span class='warning'>You accidentally cut yourself with [src], like a doofus!</span>")
user.take_organ_damage(5,5)
active = !active
@@ -291,7 +291,7 @@
if(ishuman(user))
var/mob/living/carbon/human/H = user
if((CLUMSY in H.mutations) && prob(50))
if(HAS_TRAIT(H, TRAIT_CLUMSY) && prob(50))
to_chat(H, "<span class='warning'>You accidentally cut yourself with [src], like a doofus!</span>")
H.take_organ_damage(10,10)
active = !active
@@ -101,7 +101,7 @@
if(tank && !tank.air_contents.remove(gasPerThrow * pressureSetting))
to_chat(user, "<span class='warning'>\The [src] lets out a weak hiss and doesn't react!</span>")
return
if(user && (CLUMSY in user.mutations) && prob(75))
if(user && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(75))
user.visible_message("<span class='warning'>[user] loses [user.p_their()] grip on [src], causing it to go off!</span>", "<span class='userdanger'>[src] slips out of your hands and goes off!</span>")
user.drop_item()
if(prob(10))
+1 -1
View File
@@ -51,7 +51,7 @@
return
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(!H.gloves && !(PIERCEIMMUNE in H.dna.species.species_traits))
if(!H.gloves && !HAS_TRAIT(H, TRAIT_PIERCEIMMUNE))
var/obj/item/organ/external/affecting = H.get_organ("[user.hand ? "l" : "r" ]_hand")
if(affecting.is_robotic())
return

Some files were not shown because too many files have changed in this diff Show More