mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-27 05:57:24 +01:00
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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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")
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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'
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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>")
|
||||
@@ -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)
|
||||
@@ -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>")
|
||||
@@ -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"
|
||||
@@ -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)
|
||||
@@ -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()
|
||||
@@ -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
|
||||
@@ -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
@@ -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]"))
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 ..()
|
||||
|
||||
@@ -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++
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)]")
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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>")
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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>")
|
||||
|
||||
@@ -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]°C ([H.bodytemperature*1.8-459.67]°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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user