Merge branch 'master' into upstream-merge-32624
This commit is contained in:
+12
-8
@@ -127,15 +127,19 @@
|
||||
#define TOXINLOVER 24
|
||||
#define DIGITIGRADE 25 //Uses weird leg sprites. Optional for Lizards, required for ashwalkers. Don't give it to other races unless you make sprites for this (see human_parts_greyscale.dmi)
|
||||
#define NO_UNDERWEAR 26
|
||||
#define MUTCOLORS2 27
|
||||
#define MUTCOLORS3 28
|
||||
#define NOLIVER 29
|
||||
#define NOSTOMACH 30
|
||||
#define NOLIVER 27
|
||||
#define NOSTOMACH 28
|
||||
#define NO_DNA_COPY 29
|
||||
#define DRINKSBLOOD 30
|
||||
#define SPECIES_ORGANIC 31
|
||||
#define SPECIES_INORGANIC 32
|
||||
#define SPECIES_UNDEAD 33
|
||||
#define SPECIES_ROBOTIC 34
|
||||
//citadel code
|
||||
#define NOAROUSAL 29 //Stops all arousal effects
|
||||
#define NOGENITALS 30 //Cannot create, use, or otherwise have genitals
|
||||
#define NO_DNA_COPY 31
|
||||
#define DRINKSBLOOD 32
|
||||
#define MUTCOLORS2 35
|
||||
#define MUTCOLORS3 36
|
||||
#define NOAROUSAL 37 //Stops all arousal effects
|
||||
#define NOGENITALS 38 //Cannot create, use, or otherwise have genitals
|
||||
|
||||
#define ORGAN_SLOT_BRAIN "brain"
|
||||
#define ORGAN_SLOT_APPENDIX "appendix"
|
||||
|
||||
+26
-20
@@ -16,31 +16,37 @@
|
||||
#define DIAG_BOT_HUD "12"// Bot HUDs
|
||||
#define DIAG_TRACK_HUD "13"// Mech tracking beacon
|
||||
#define DIAG_AIRLOCK_HUD "14"//Airlock shock overlay
|
||||
#define DIAG_PATH_HUD "15"//Bot path indicators
|
||||
//for antag huds. these are used at the /mob level
|
||||
#define ANTAG_HUD "15"
|
||||
#define ANTAG_HUD "16"
|
||||
|
||||
//by default everything in the hud_list of an atom is an image
|
||||
//a value in hud_list with one of these will change that behavior
|
||||
#define HUD_LIST_LIST 1
|
||||
|
||||
//data HUD (medhud, sechud) defines
|
||||
//Don't forget to update human/New() if you change these!
|
||||
#define DATA_HUD_SECURITY_BASIC 1
|
||||
#define DATA_HUD_SECURITY_ADVANCED 2
|
||||
#define DATA_HUD_MEDICAL_BASIC 3
|
||||
#define DATA_HUD_MEDICAL_ADVANCED 4
|
||||
#define DATA_HUD_DIAGNOSTIC 5
|
||||
#define DATA_HUD_SECURITY_BASIC 1
|
||||
#define DATA_HUD_SECURITY_ADVANCED 2
|
||||
#define DATA_HUD_MEDICAL_BASIC 3
|
||||
#define DATA_HUD_MEDICAL_ADVANCED 4
|
||||
#define DATA_HUD_DIAGNOSTIC_BASIC 5
|
||||
#define DATA_HUD_DIAGNOSTIC_ADVANCED 6
|
||||
//antag HUD defines
|
||||
#define ANTAG_HUD_CULT 6
|
||||
#define ANTAG_HUD_REV 7
|
||||
#define ANTAG_HUD_OPS 8
|
||||
#define ANTAG_HUD_WIZ 9
|
||||
#define ANTAG_HUD_SHADOW 10
|
||||
#define ANTAG_HUD_TRAITOR 11
|
||||
#define ANTAG_HUD_NINJA 12
|
||||
#define ANTAG_HUD_CHANGELING 13
|
||||
#define ANTAG_HUD_ABDUCTOR 14
|
||||
#define ANTAG_HUD_DEVIL 15
|
||||
#define ANTAG_HUD_SINTOUCHED 16
|
||||
#define ANTAG_HUD_SOULLESS 17
|
||||
#define ANTAG_HUD_CLOCKWORK 18
|
||||
#define ANTAG_HUD_BROTHER 19
|
||||
#define ANTAG_HUD_CULT 7
|
||||
#define ANTAG_HUD_REV 8
|
||||
#define ANTAG_HUD_OPS 9
|
||||
#define ANTAG_HUD_WIZ 10
|
||||
#define ANTAG_HUD_SHADOW 11
|
||||
#define ANTAG_HUD_TRAITOR 12
|
||||
#define ANTAG_HUD_NINJA 13
|
||||
#define ANTAG_HUD_CHANGELING 14
|
||||
#define ANTAG_HUD_ABDUCTOR 15
|
||||
#define ANTAG_HUD_DEVIL 16
|
||||
#define ANTAG_HUD_SINTOUCHED 17
|
||||
#define ANTAG_HUD_SOULLESS 18
|
||||
#define ANTAG_HUD_CLOCKWORK 19
|
||||
#define ANTAG_HUD_BROTHER 20
|
||||
|
||||
// Notification action types
|
||||
#define NOTIFY_JUMP "jump"
|
||||
|
||||
@@ -10,6 +10,11 @@
|
||||
#define COMPONENT_DUPE_ALLOWED 1 //duplicates allowed
|
||||
#define COMPONENT_DUPE_UNIQUE 2 //new component is deleted
|
||||
|
||||
// Signal return value flags
|
||||
// The other defines are under the signal they're used in
|
||||
|
||||
#define COMPONENT_ACTIVATED 1 // call parent.ComponentActivated(comp) and component.AfterComponentActivated()
|
||||
|
||||
// All signals. Format:
|
||||
// When the signal is called: (signal arguments)
|
||||
|
||||
@@ -19,9 +24,11 @@
|
||||
#define COMSIG_PARENT_QDELETED "parent_qdeleted" //before a datum's Destroy() is called: ()
|
||||
|
||||
#define COMSIG_COMPONENT_CLEAN_ACT "clean_act" //called on an object to clean it of cleanables. Usualy with soap: (num/strength)
|
||||
#define COMSIG_COMPONENT_NTNET_RECIEVE "ntnet_recieve" //called on an object by its NTNET connection component on recieve. (sending_id(number), sending_netname(text), data(datum/netdata))
|
||||
|
||||
// /atom signals
|
||||
#define COMSIG_PARENT_ATTACKBY "atom_attackby" //from base of atom/attackby(): (/obj/item, /mob/living, params)
|
||||
#define COMPONENT_NO_AFTERATTACK 2 //Return this in response if you don't want afterattack to be called
|
||||
#define COMSIG_ATOM_HULK_ATTACK "hulk_attack" //from base of atom/attack_hulk(): (/mob/living/carbon/human)
|
||||
#define COMSIG_PARENT_EXAMINE "atom_examine" //from base of atom/examine(): (/mob)
|
||||
#define COMSIG_ATOM_ENTERED "atom_entered" //from base of atom/Entered(): (/atom/movable, /atom)
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#define IC_FORMAT_BOOLEAN "\<BOOL\>"
|
||||
#define IC_FORMAT_REF "\<REF\>"
|
||||
#define IC_FORMAT_LIST "\<LIST\>"
|
||||
#define IC_FORMAT_INDEX "\<INDEX\>"
|
||||
|
||||
#define IC_FORMAT_PULSE "\<PULSE\>"
|
||||
|
||||
@@ -33,6 +34,7 @@
|
||||
#define IC_PINTYPE_BOOLEAN /datum/integrated_io/boolean
|
||||
#define IC_PINTYPE_REF /datum/integrated_io/ref
|
||||
#define IC_PINTYPE_LIST /datum/integrated_io/lists
|
||||
#define IC_PINTYPE_INDEX /datum/integrated_io/index
|
||||
|
||||
#define IC_PINTYPE_PULSE_IN /datum/integrated_io/activate
|
||||
#define IC_PINTYPE_PULSE_OUT /datum/integrated_io/activate/out
|
||||
|
||||
@@ -59,6 +59,9 @@
|
||||
#define iszombie(A) (is_species(A, /datum/species/zombie))
|
||||
#define ishumanbasic(A) (is_species(A, /datum/species/human))
|
||||
|
||||
//why arent catpeople a subspecies
|
||||
#define iscatperson(A) (ishumanbasic(A) && ( A.dna.features["ears"] == "Cat" || A.dna.features["human_tail"] == "Cat") )
|
||||
|
||||
//more carbon mobs
|
||||
#define ismonkey(A) (istype(A, /mob/living/carbon/monkey))
|
||||
|
||||
@@ -186,3 +189,5 @@ GLOBAL_LIST_INIT(glass_sheet_types, typecacheof(list(
|
||||
/obj/item/stack/sheet/plasmarglass)))
|
||||
|
||||
#define is_glass_sheet(O) (is_type_in_typecache(O, GLOB.glass_sheet_types))
|
||||
|
||||
#define isblobmonster(O) (istype(O, /mob/living/simple_animal/hostile/blob))
|
||||
@@ -478,3 +478,8 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
|
||||
|
||||
#define SYRINGE_DRAW 0
|
||||
#define SYRINGE_INJECT 1
|
||||
|
||||
//gold slime core spawning
|
||||
#define NO_SPAWN 0
|
||||
#define HOSTILE_SPAWN 1
|
||||
#define FRIENDLY_SPAWN 2
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
#define HID_RESTRICTED_END 101 //the first nonrestricted ID, automatically assigned on connection creation.
|
||||
@@ -11,4 +11,9 @@
|
||||
#define INGEST 2 //ingestion
|
||||
#define VAPOR 3 //foam, spray, blob attack
|
||||
#define PATCH 4 //patches
|
||||
#define INJECT 5 //injection
|
||||
#define INJECT 5 //injection
|
||||
|
||||
//defines passed through to the on_reagent_change proc
|
||||
#define DEL_REAGENT 1 //reagent deleted (fully cleared)
|
||||
#define ADD_REAGENT 2 // reagent added
|
||||
#define REM_REAGENT 3 // reagent removed (may still exist)
|
||||
|
||||
@@ -49,4 +49,10 @@
|
||||
#define LOGCHAT "chat"
|
||||
#define LOGASAY "adminsay"
|
||||
#define LOGCOMMENT "comment"
|
||||
#define LOGOOC "ooc"
|
||||
#define LOGOOC "ooc"
|
||||
|
||||
|
||||
#define LINGHIVE_NONE 0
|
||||
#define LINGHIVE_OUTSIDER 1
|
||||
#define LINGHIVE_LING 2
|
||||
#define LINGHIVE_LINK 3
|
||||
@@ -51,9 +51,10 @@
|
||||
#define INIT_ORDER_TICKER 13
|
||||
#define INIT_ORDER_MAPPING 12
|
||||
#define INIT_ORDER_ATOMS 11
|
||||
#define INIT_ORDER_LANGUAGE 10
|
||||
#define INIT_ORDER_MACHINES 9
|
||||
#define INIT_ORDER_CIRCUIT 8
|
||||
#define INIT_ORDER_NETWORKS 10
|
||||
#define INIT_ORDER_LANGUAGE 9
|
||||
#define INIT_ORDER_MACHINES 8
|
||||
#define INIT_ORDER_CIRCUIT 7
|
||||
#define INIT_ORDER_TIMER 1
|
||||
#define INIT_ORDER_DEFAULT 0
|
||||
#define INIT_ORDER_AIR -1
|
||||
@@ -100,4 +101,4 @@
|
||||
A.overlays.Cut();\
|
||||
}\
|
||||
A.flags_1 &= ~OVERLAY_QUEUED_1;\
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,7 +225,8 @@
|
||||
else // A variation of get_hear inlined here to take advantage of the compiler's fastpath for obj/mob in view
|
||||
var/lum = T.luminosity
|
||||
T.luminosity = 6 // This is the maximum luminosity
|
||||
processing_list = viewers(R, T)
|
||||
for(var/mob/M in view(R, T))
|
||||
processing_list += M
|
||||
for(var/obj/O in view(R, T))
|
||||
processing_list += O
|
||||
T.luminosity = lum
|
||||
@@ -311,6 +312,7 @@
|
||||
else
|
||||
return get_step(start, EAST)
|
||||
|
||||
|
||||
/proc/try_move_adjacent(atom/movable/AM)
|
||||
var/turf/T = get_turf(AM)
|
||||
for(var/direction in GLOB.cardinals)
|
||||
|
||||
@@ -949,7 +949,7 @@ GLOBAL_LIST_EMPTY(friendly_animal_types)
|
||||
if(!GLOB.friendly_animal_types.len)
|
||||
for(var/T in typesof(/mob/living/simple_animal))
|
||||
var/mob/living/simple_animal/SA = T
|
||||
if(initial(SA.gold_core_spawnable) == 2)
|
||||
if(initial(SA.gold_core_spawnable) == FRIENDLY_SPAWN)
|
||||
GLOB.friendly_animal_types += SA
|
||||
|
||||
|
||||
|
||||
@@ -232,3 +232,24 @@ GLOBAL_LIST_INIT(sqrtTable, list(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4,
|
||||
if(round(num) != num)
|
||||
return round(num--)
|
||||
else return num
|
||||
|
||||
//proc/get_overlap()
|
||||
// Returns a list where [1] is all x values and [2] is all y values that overlap between the given pair of rectangles
|
||||
/proc/get_overlap(x1, y1, x2, y2, x3, y3, x4, y4)
|
||||
var/list/region_x1 = list()
|
||||
var/list/region_y1 = list()
|
||||
var/list/region_x2 = list()
|
||||
var/list/region_y2 = list()
|
||||
|
||||
// These loops create loops filled with x/y values that the boundaries inhabit
|
||||
// ex: list(5, 6, 7, 8, 9)
|
||||
for(var/i in min(x1, x2) to max(x1, x2))
|
||||
region_x1["[i]"] = TRUE
|
||||
for(var/i in min(y1, y2) to max(y1, y2))
|
||||
region_y1["[i]"] = TRUE
|
||||
for(var/i in min(x3, x4) to max(x3, x4))
|
||||
region_x2["[i]"] = TRUE
|
||||
for(var/i in min(y3, y4) to max(y3, y4))
|
||||
region_y2["[i]"] = TRUE
|
||||
|
||||
return list(region_x1 & region_x2, region_y1 & region_y2)
|
||||
@@ -35,7 +35,7 @@
|
||||
#define MAX_CHARTER_LEN 80
|
||||
|
||||
//MINOR TWEAKS/MISC
|
||||
#define AGE_MIN 17 //youngest a character can be
|
||||
#define AGE_MIN 18 //youngest a character can be
|
||||
#define AGE_MAX 85 //oldest a character can be
|
||||
#define WIZARD_AGE_MIN 30 //youngest a wizard can be
|
||||
#define APPRENTICE_AGE_MIN 29 //youngest an apprentice can be
|
||||
@@ -79,5 +79,5 @@
|
||||
|
||||
//Update this whenever the db schema changes
|
||||
//make sure you add an update to the schema_version stable in the db changelog
|
||||
#define DB_MAJOR_VERSION 3
|
||||
#define DB_MINOR_VERSION 4
|
||||
#define DB_MAJOR_VERSION 4
|
||||
#define DB_MINOR_VERSION 0
|
||||
|
||||
@@ -24,6 +24,7 @@ GLOBAL_LIST_EMPTY(landmarks_list) //list of all landmarks created
|
||||
GLOBAL_LIST_EMPTY(start_landmarks_list) //list of all spawn points created
|
||||
GLOBAL_LIST_EMPTY(department_security_spawns) //list of all department security spawns
|
||||
GLOBAL_LIST_EMPTY(generic_event_spawns) //list of all spawns for events
|
||||
GLOBAL_LIST_EMPTY(jobspawn_overrides) //These will take precedence over normal spawnpoints if created.
|
||||
|
||||
GLOBAL_LIST_EMPTY(wizardstart)
|
||||
GLOBAL_LIST_EMPTY(nukeop_start)
|
||||
|
||||
@@ -24,6 +24,7 @@ GLOBAL_LIST_EMPTY(pai_list)
|
||||
GLOBAL_LIST_EMPTY(available_ai_shells)
|
||||
GLOBAL_LIST_INIT(simple_animals, list(list(),list(),list())) // One for each AI_* status define
|
||||
GLOBAL_LIST_EMPTY(spidermobs) //all sentient spider mobs
|
||||
GLOBAL_LIST_EMPTY(bots_list)
|
||||
|
||||
GLOBAL_LIST_EMPTY(language_datum_instances)
|
||||
GLOBAL_LIST_EMPTY(all_languages)
|
||||
|
||||
@@ -34,7 +34,9 @@
|
||||
|
||||
// No comment
|
||||
/atom/proc/attackby(obj/item/W, mob/user, params)
|
||||
return SendSignal(COMSIG_PARENT_ATTACKBY, W, user, params)
|
||||
if(SendSignal(COMSIG_PARENT_ATTACKBY, W, user, params) & COMPONENT_NO_AFTERATTACK)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/attackby(obj/item/I, mob/living/user, params)
|
||||
return ..() || (can_be_hit && I.attack_obj(src, user))
|
||||
|
||||
@@ -121,7 +121,7 @@ GLOBAL_VAR_INIT(miscreants_allowed, FALSE)
|
||||
prefs.chat_toggles ^= CHAT_LOOC
|
||||
prefs.save_preferences()
|
||||
src << "You will [(prefs.chat_toggles & CHAT_LOOC) ? "now" : "no longer"] see messages on the LOOC channel."
|
||||
SSblackbox.add_details("admin_verb","TLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "TLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/datum/admins/proc/togglelooc()
|
||||
set category = "Server"
|
||||
@@ -130,7 +130,7 @@ GLOBAL_VAR_INIT(miscreants_allowed, FALSE)
|
||||
toggle_looc()
|
||||
log_admin("[key_name(usr)] toggled LOOC.")
|
||||
message_admins("[key_name_admin(usr)] toggled LOOC.")
|
||||
SSblackbox.add_details("admin_verb","TLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "TLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/proc/toggle_looc(toggle = null)
|
||||
if(toggle != null) //if we're specifically en/disabling ooc
|
||||
@@ -150,7 +150,7 @@ GLOBAL_VAR_INIT(miscreants_allowed, FALSE)
|
||||
|
||||
log_admin("[key_name(usr)] toggled Dead LOOC.")
|
||||
message_admins("[key_name_admin(usr)] toggled Dead LOOC.")
|
||||
SSblackbox.add_details("admin_verb","TDLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "TDLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
|
||||
/mob/living/carbon/proc/has_penis()
|
||||
|
||||
+11
-10
@@ -215,7 +215,7 @@
|
||||
damage = 15
|
||||
armour_penetration = 10
|
||||
light_range = 2
|
||||
speed = 1.2
|
||||
speed = 0.6
|
||||
range = 25
|
||||
light_color = LIGHT_COLOR_RED
|
||||
|
||||
@@ -224,10 +224,10 @@
|
||||
icon_state = "magjectile-nl"
|
||||
damage = 1
|
||||
knockdown = 0
|
||||
stamina = 30
|
||||
stamina = 25
|
||||
armour_penetration = -10
|
||||
light_range = 2
|
||||
speed = 1.2
|
||||
speed = 0.7
|
||||
range = 25
|
||||
light_color = LIGHT_COLOR_BLUE
|
||||
|
||||
@@ -257,7 +257,7 @@
|
||||
origin_tech = "magnets=5"
|
||||
ammo_type = /obj/item/ammo_casing/caseless/anlmags
|
||||
caliber = "mags"
|
||||
max_ammo = 7
|
||||
max_ammo = 15
|
||||
multiple_sprites = 2
|
||||
|
||||
/obj/item/ammo_box/magazine/mmag/small/lethal
|
||||
@@ -279,7 +279,7 @@
|
||||
mag_type = /obj/item/ammo_box/magazine/mmag/small
|
||||
can_suppress = 0
|
||||
casing_ejector = 0
|
||||
fire_delay = 5
|
||||
fire_delay = 2
|
||||
origin_tech = "combat=4;magnets=4"
|
||||
|
||||
/obj/item/gun/ballistic/automatic/pistol/mag/update_icon()
|
||||
@@ -389,7 +389,7 @@
|
||||
damage = 20
|
||||
armour_penetration = 25
|
||||
light_range = 3
|
||||
speed = 1.2
|
||||
speed = 0.7
|
||||
range = 35
|
||||
light_color = LIGHT_COLOR_RED
|
||||
|
||||
@@ -398,10 +398,10 @@
|
||||
icon_state = "magjectile-large-nl"
|
||||
damage = 0
|
||||
knockdown = 0
|
||||
stamina = 35
|
||||
stamina = 20
|
||||
armour_penetration = -10
|
||||
light_range = 3
|
||||
speed = 1.0
|
||||
speed = 0.65
|
||||
range = 35
|
||||
light_color = LIGHT_COLOR_BLUE
|
||||
|
||||
@@ -430,7 +430,7 @@
|
||||
origin_tech = "magnets=6"
|
||||
ammo_type = /obj/item/ammo_casing/caseless/anlmagm
|
||||
caliber = "magm"
|
||||
max_ammo = 15
|
||||
max_ammo = 27
|
||||
multiple_sprites = 2
|
||||
|
||||
/obj/item/ammo_box/magazine/mmag/lethal
|
||||
@@ -439,6 +439,7 @@
|
||||
icon_state = "mediummagmag"
|
||||
origin_tech = "combat=6"
|
||||
ammo_type = /obj/item/ammo_casing/caseless/amagm
|
||||
max_ammo = 21
|
||||
|
||||
///the gun itself///
|
||||
|
||||
@@ -455,7 +456,7 @@
|
||||
can_suppress = 0
|
||||
burst_size = 3
|
||||
fire_delay = 2
|
||||
spread = 30
|
||||
spread = 20
|
||||
recoil = 1
|
||||
casing_ejector = 0
|
||||
|
||||
|
||||
@@ -104,6 +104,16 @@
|
||||
resistance_flags = FLAMMABLE
|
||||
squeak_override = list('sound/misc/server-ready.ogg'= 1)
|
||||
|
||||
/obj/item/clothing/neck/cloak/festive
|
||||
name = "Celebratory Cloak of Morozko"
|
||||
desc = " It probably will protect from snow, charcoal or elves."
|
||||
icon = 'icons/obj/custom.dmi'
|
||||
icon_state = "festive-w"
|
||||
item_state = "festive-i"
|
||||
icon = 'icons/obj/custom.dmi'
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
body_parts_covered = CHEST|GROIN|LEGS|ARMS
|
||||
|
||||
|
||||
/*Zigfie*/
|
||||
|
||||
@@ -197,4 +207,15 @@
|
||||
item_state = "pink"
|
||||
|
||||
|
||||
/*Fractious*/
|
||||
|
||||
/obj/item/clothing/suit/vermillion
|
||||
name = "vermillion clothing"
|
||||
desc = "Some clothing."
|
||||
icon_state = "vermillion-w"
|
||||
item_state = "vermillion-i"
|
||||
body_parts_covered = CHEST|GROIN|LEGS|ARMS|HANDS
|
||||
icon = 'icons/obj/custom.dmi'
|
||||
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 768 B After Width: | Height: | Size: 668 B |
@@ -45,9 +45,9 @@ INITIALIZE_IMMEDIATE(/obj/effect/statclick)
|
||||
switch(controller)
|
||||
if("Master")
|
||||
Recreate_MC()
|
||||
SSblackbox.add_details("admin_verb","Restart Master Controller")
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Restart Master Controller")
|
||||
if("Failsafe")
|
||||
new /datum/controller/failsafe()
|
||||
SSblackbox.add_details("admin_verb","Restart Failsafe Controller")
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Restart Failsafe Controller")
|
||||
|
||||
message_admins("Admin [key_name_admin(usr)] has restarted the [controller] controller.")
|
||||
|
||||
@@ -381,3 +381,7 @@ CONFIG_TWEAK(flag/ValidateAndSet(str_val))
|
||||
. = ..()
|
||||
if(. && Master.current_runlevel)
|
||||
world.sleep_offline = !value
|
||||
|
||||
CONFIG_DEF(number/rounds_until_hard_restart)
|
||||
value = -1
|
||||
min_val = 0
|
||||
|
||||
@@ -5,21 +5,12 @@ SUBSYSTEM_DEF(blackbox)
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
init_order = INIT_ORDER_BLACKBOX
|
||||
|
||||
var/list/msg_common = list()
|
||||
var/list/msg_science = list()
|
||||
var/list/msg_command = list()
|
||||
var/list/msg_medical = list()
|
||||
var/list/msg_engineering = list()
|
||||
var/list/msg_security = list()
|
||||
var/list/msg_deathsquad = list()
|
||||
var/list/msg_syndicate = list()
|
||||
var/list/msg_service = list()
|
||||
var/list/msg_cargo = list()
|
||||
var/list/msg_other = list()
|
||||
|
||||
var/list/feedback = list() //list of datum/feedback_variable
|
||||
var/triggertime = 0
|
||||
var/sealed = FALSE //time to stop tracking stats?
|
||||
var/list/research_levels = list() //list of highest tech levels attained that isn't lost lost by destruction of RD computers
|
||||
var/list/versions = list("time_dilation_current" = 2,
|
||||
"science_techweb_unlock" = 2) //associative list of any feedback variables that have had their format changed since creation and their current version, remember to update this
|
||||
|
||||
|
||||
/datum/controller/subsystem/blackbox/Initialize()
|
||||
@@ -44,20 +35,7 @@ SUBSYSTEM_DEF(blackbox)
|
||||
|
||||
|
||||
/datum/controller/subsystem/blackbox/Recover()
|
||||
msg_common = SSblackbox.msg_common
|
||||
msg_science = SSblackbox.msg_science
|
||||
msg_command = SSblackbox.msg_command
|
||||
msg_medical = SSblackbox.msg_medical
|
||||
msg_engineering = SSblackbox.msg_engineering
|
||||
msg_security = SSblackbox.msg_security
|
||||
msg_deathsquad = SSblackbox.msg_deathsquad
|
||||
msg_syndicate = SSblackbox.msg_syndicate
|
||||
msg_service = SSblackbox.msg_service
|
||||
msg_cargo = SSblackbox.msg_cargo
|
||||
msg_other = SSblackbox.msg_other
|
||||
|
||||
feedback = SSblackbox.feedback
|
||||
|
||||
sealed = SSblackbox.sealed
|
||||
|
||||
//no touchie
|
||||
@@ -71,32 +49,14 @@ SUBSYSTEM_DEF(blackbox)
|
||||
|
||||
/datum/controller/subsystem/blackbox/Shutdown()
|
||||
sealed = FALSE
|
||||
set_val("ahelp_unresolved", GLOB.ahelp_tickets.active_tickets.len)
|
||||
|
||||
var/pda_msg_amt = 0
|
||||
var/rc_msg_amt = 0
|
||||
|
||||
record_feedback("tally", "ahelp_stats", GLOB.ahelp_tickets.active_tickets.len, "unresolved")
|
||||
for (var/obj/machinery/message_server/MS in GLOB.message_servers)
|
||||
if (MS.pda_msgs.len > pda_msg_amt)
|
||||
pda_msg_amt = MS.pda_msgs.len
|
||||
if (MS.rc_msgs.len > rc_msg_amt)
|
||||
rc_msg_amt = MS.rc_msgs.len
|
||||
|
||||
set_details("radio_usage","")
|
||||
|
||||
add_details("radio_usage","COM-[msg_common.len]")
|
||||
add_details("radio_usage","SCI-[msg_science.len]")
|
||||
add_details("radio_usage","HEA-[msg_command.len]")
|
||||
add_details("radio_usage","MED-[msg_medical.len]")
|
||||
add_details("radio_usage","ENG-[msg_engineering.len]")
|
||||
add_details("radio_usage","SEC-[msg_security.len]")
|
||||
add_details("radio_usage","DTH-[msg_deathsquad.len]")
|
||||
add_details("radio_usage","SYN-[msg_syndicate.len]")
|
||||
add_details("radio_usage","SRV-[msg_service.len]")
|
||||
add_details("radio_usage","CAR-[msg_cargo.len]")
|
||||
add_details("radio_usage","OTH-[msg_other.len]")
|
||||
add_details("radio_usage","PDA-[pda_msg_amt]")
|
||||
add_details("radio_usage","RC-[rc_msg_amt]")
|
||||
if (MS.pda_msgs.len)
|
||||
record_feedback("tally", "radio_usage", MS.pda_msgs.len, "PDA")
|
||||
if (MS.rc_msgs.len)
|
||||
record_feedback("tally", "radio_usage", MS.rc_msgs.len, "request console")
|
||||
if(research_levels.len)
|
||||
SSblackbox.record_feedback("associative", "high_research_level", 1, research_levels)
|
||||
|
||||
if (!SSdbcore.Connect())
|
||||
return
|
||||
@@ -104,79 +64,183 @@ SUBSYSTEM_DEF(blackbox)
|
||||
var/list/sqlrowlist = list()
|
||||
|
||||
for (var/datum/feedback_variable/FV in feedback)
|
||||
sqlrowlist += list(list("time" = "Now()", "round_id" = GLOB.round_id, "var_name" = "'[sanitizeSQL(FV.get_variable())]'", "var_value" = FV.get_value(), "details" = "'[sanitizeSQL(FV.get_details())]'"))
|
||||
var/sqlversion = 1
|
||||
if(FV.key in versions)
|
||||
sqlversion = versions[FV.key]
|
||||
sqlrowlist += list(list("datetime" = "Now()", "round_id" = GLOB.round_id, "key_name" = "'[sanitizeSQL(FV.key)]'", "key_type" = "'[FV.key_type]'", "version" = "[sqlversion]", "json" = "'[sanitizeSQL(json_encode(FV.json))]'"))
|
||||
|
||||
if (!length(sqlrowlist))
|
||||
return
|
||||
|
||||
SSdbcore.MassInsert(format_table_name("feedback"), sqlrowlist, ignore_errors = TRUE, delayed = TRUE)
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/Seal()
|
||||
if(sealed)
|
||||
return
|
||||
if(IsAdminAdvancedProcCall())
|
||||
message_admins("[key_name_admin(usr)] sealed the blackbox!")
|
||||
log_game("Blackbox sealed[IsAdminAdvancedProcCall() ? " by [key_name(usr)]" : ""].")
|
||||
sealed = TRUE
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/LogBroadcast(blackbox_msg, freq)
|
||||
/datum/controller/subsystem/blackbox/proc/log_research(tech, level)
|
||||
if(!(tech in research_levels) || research_levels[tech] < level)
|
||||
research_levels[tech] = level
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/LogBroadcast(freq)
|
||||
if(sealed)
|
||||
return
|
||||
switch(freq)
|
||||
if(1459)
|
||||
msg_common += blackbox_msg
|
||||
if(1351)
|
||||
msg_science += blackbox_msg
|
||||
if(1353)
|
||||
msg_command += blackbox_msg
|
||||
if(1355)
|
||||
msg_medical += blackbox_msg
|
||||
if(1357)
|
||||
msg_engineering += blackbox_msg
|
||||
if(1359)
|
||||
msg_security += blackbox_msg
|
||||
if(1441)
|
||||
msg_deathsquad += blackbox_msg
|
||||
if(1213)
|
||||
msg_syndicate += blackbox_msg
|
||||
if(1349)
|
||||
msg_service += blackbox_msg
|
||||
if(1347)
|
||||
msg_cargo += blackbox_msg
|
||||
record_feedback("tally", "radio_usage", 1, "common")
|
||||
if(GLOB.SCI_FREQ)
|
||||
record_feedback("tally", "radio_usage", 1, "science")
|
||||
if(GLOB.COMM_FREQ)
|
||||
record_feedback("tally", "radio_usage", 1, "command")
|
||||
if(GLOB.MED_FREQ)
|
||||
record_feedback("tally", "radio_usage", 1, "medical")
|
||||
if(GLOB.ENG_FREQ)
|
||||
record_feedback("tally", "radio_usage", 1, "engineering")
|
||||
if(GLOB.SEC_FREQ)
|
||||
record_feedback("tally", "radio_usage", 1, "security")
|
||||
if(GLOB.SYND_FREQ)
|
||||
record_feedback("tally", "radio_usage", 1, "syndicate")
|
||||
if(GLOB.SERV_FREQ)
|
||||
record_feedback("tally", "radio_usage", 1, "service")
|
||||
if(GLOB.SUPP_FREQ)
|
||||
record_feedback("tally", "radio_usage", 1, "supply")
|
||||
if(GLOB.CENTCOM_FREQ)
|
||||
record_feedback("tally", "radio_usage", 1, "centcom")
|
||||
if(GLOB.AIPRIV_FREQ)
|
||||
record_feedback("tally", "radio_usage", 1, "ai private")
|
||||
if(GLOB.REDTEAM_FREQ)
|
||||
record_feedback("tally", "radio_usage", 1, "CTF red team")
|
||||
if(GLOB.BLUETEAM_FREQ)
|
||||
record_feedback("tally", "radio_usage", 1, "CTF blue team")
|
||||
else
|
||||
msg_other += blackbox_msg
|
||||
record_feedback("tally", "radio_usage", 1, "other")
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/find_feedback_datum(variable)
|
||||
/datum/controller/subsystem/blackbox/proc/find_feedback_datum(key, key_type)
|
||||
for(var/datum/feedback_variable/FV in feedback)
|
||||
if(FV.get_variable() == variable)
|
||||
if(FV.key == key)
|
||||
return FV
|
||||
|
||||
var/datum/feedback_variable/FV = new(variable)
|
||||
var/datum/feedback_variable/FV = new(key, key_type)
|
||||
feedback += FV
|
||||
return FV
|
||||
/*
|
||||
feedback data can be recorded in 5 formats:
|
||||
"text"
|
||||
used for simple single-string records i.e. the current map
|
||||
further calls to the same key will append saved data unless the overwrite argument is true or it already exists
|
||||
when encoded calls made with overwrite will lack square brackets
|
||||
calls: SSblackbox.record_feedback("text", "example", 1, "sample text")
|
||||
SSblackbox.record_feedback("text", "example", 1, "other text")
|
||||
json: {"data":["sample text","other text"]}
|
||||
"amount"
|
||||
used to record simple counts of data i.e. the number of ahelps recieved
|
||||
further calls to the same key will add or subtract (if increment argument is a negative) from the saved amount
|
||||
calls: SSblackbox.record_feedback("amount", "example", 8)
|
||||
SSblackbox.record_feedback("amount", "example", 2)
|
||||
json: {"data":10}
|
||||
"tally"
|
||||
used to track the number of occurances of multiple related values i.e. how many times each type of gun is fired
|
||||
further calls to the same key will:
|
||||
add or subtract from the saved value of the data key if it already exists
|
||||
append the key and it's value if it doesn't exist
|
||||
calls: SSblackbox.record_feedback("tally", "example", 1, "sample data")
|
||||
SSblackbox.record_feedback("tally", "example", 4, "sample data")
|
||||
SSblackbox.record_feedback("tally", "example", 2, "other data")
|
||||
json: {"data":{"sample data":5,"other data":2}}
|
||||
"nested tally"
|
||||
used to track the number of occurances of structured semi-relational values i.e. the results of arcade machines
|
||||
similar to running total, but related values are nested in a multi-dimensional array built
|
||||
the final element in the data list is used as the tracking key, all prior elements are used for nesting
|
||||
all data list elements must be strings
|
||||
further calls to the same key will:
|
||||
add or subtract from the saved value of the data key if it already exists in the same multi-dimensional position
|
||||
append the key and it's value if it doesn't exist
|
||||
calls: SSblackbox.record_feedback("nested tally", "example", 1, list("fruit", "orange", "apricot"))
|
||||
SSblackbox.record_feedback("nested tally", "example", 2, list("fruit", "orange", "orange"))
|
||||
SSblackbox.record_feedback("nested tally", "example", 3, list("fruit", "orange", "apricot"))
|
||||
SSblackbox.record_feedback("nested tally", "example", 10, list("fruit", "red", "apple"))
|
||||
SSblackbox.record_feedback("nested tally", "example", 1, list("vegetable", "orange", "carrot"))
|
||||
json: {"data":{"fruit":{"orange":{"apricot":4,"orange":2},"red":{"apple":10}},"vegetable":{"orange":{"carrot":1}}}}
|
||||
tracking values associated with a number can't merge with a nesting value, trying to do so will append the list
|
||||
call: SSblackbox.record_feedback("nested tally", "example", 3, list("fruit", "orange"))
|
||||
json: {"data":{"fruit":{"orange":{"apricot":4,"orange":2},"red":{"apple":10},"orange":3},"vegetable":{"orange":{"carrot":1}}}}
|
||||
"associative"
|
||||
used to record text that's associated with a value i.e. coordinates
|
||||
further calls to the same key will append a new list to existing data
|
||||
calls: SSblackbox.record_feedback("associative", "example", 1, list("text" = "example", "path" = /obj/item, "number" = 4))
|
||||
SSblackbox.record_feedback("associative", "example", 1, list("number" = 7, "text" = "example", "other text" = "sample"))
|
||||
json: {"data":{"1":{"text":"example","path":"/obj/item","number":"4"},"2":{"number":"7","text":"example","other text":"sample"}}}
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/set_val(variable, value)
|
||||
if(sealed)
|
||||
Versioning
|
||||
If the format of a feedback variable is ever changed, i.e. how many levels of nesting are used or a new type of data is added to it, add it to the versions list
|
||||
When feedback is being saved if a key is in the versions list the value specified there will be used, otherwise all keys are assumed to be version = 1
|
||||
versions is an associative list, remember to use the same string in it as defined on a feedback variable, example:
|
||||
list/versions = list("round_end_stats" = 4,
|
||||
"admin_toggle" = 2,
|
||||
"gun_fired" = 2)
|
||||
*/
|
||||
/datum/controller/subsystem/blackbox/proc/record_feedback(key_type, key, increment, data, overwrite)
|
||||
if(sealed || !key_type || !istext(key) || !isnum(increment || !data))
|
||||
return
|
||||
var/datum/feedback_variable/FV = find_feedback_datum(variable)
|
||||
FV.set_value(value)
|
||||
var/datum/feedback_variable/FV = find_feedback_datum(key, key_type)
|
||||
switch(key_type)
|
||||
if("text")
|
||||
if(!istext(data))
|
||||
return
|
||||
if(!islist(FV.json["data"]))
|
||||
FV.json["data"] = list()
|
||||
if(overwrite)
|
||||
FV.json["data"] = data
|
||||
else
|
||||
FV.json["data"] |= data
|
||||
if("amount")
|
||||
FV.json["data"] += increment
|
||||
if("tally")
|
||||
if(!islist(FV.json["data"]))
|
||||
FV.json["data"] = list()
|
||||
FV.json["data"]["[data]"] += increment
|
||||
if("nested tally")
|
||||
if(!islist(data))
|
||||
return
|
||||
if(!islist(FV.json["data"]))
|
||||
FV.json["data"] = list()
|
||||
FV.json["data"] = record_feedback_recurse_list(FV.json["data"], data, increment)
|
||||
if("associative")
|
||||
if(!islist(data))
|
||||
return
|
||||
if(!islist(FV.json["data"]))
|
||||
FV.json["data"] = list()
|
||||
var/pos = length(FV.json["data"]) + 1
|
||||
FV.json["data"]["[pos]"] = list() //in 512 "pos" can be replaced with "[FV.json["data"].len+1]"
|
||||
for(var/i in data)
|
||||
FV.json["data"]["[pos]"]["[i]"] = "[data[i]]" //and here with "[FV.json["data"].len]"
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/inc(variable, value)
|
||||
if(sealed)
|
||||
return
|
||||
var/datum/feedback_variable/FV = find_feedback_datum(variable)
|
||||
FV.inc(value)
|
||||
/datum/controller/subsystem/blackbox/proc/record_feedback_recurse_list(list/L, list/key_list, increment, depth = 1)
|
||||
if(depth == key_list.len)
|
||||
if(L.Find(key_list[depth]))
|
||||
L["[key_list[depth]]"] += increment
|
||||
else
|
||||
var/list/LFI = list(key_list[depth] = increment)
|
||||
L += LFI
|
||||
else
|
||||
if(!L.Find(key_list[depth]))
|
||||
var/list/LGD = list(key_list[depth] = list())
|
||||
L += LGD
|
||||
L["[key_list[depth-1]]"] = .(L["[key_list[depth]]"], key_list, increment, ++depth)
|
||||
return L
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/dec(variable,value)
|
||||
if(sealed)
|
||||
return
|
||||
var/datum/feedback_variable/FV = find_feedback_datum(variable)
|
||||
FV.dec(value)
|
||||
/datum/feedback_variable
|
||||
var/key
|
||||
var/key_type
|
||||
var/list/json = list()
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/set_details(variable,details)
|
||||
if(sealed)
|
||||
return
|
||||
var/datum/feedback_variable/FV = find_feedback_datum(variable)
|
||||
FV.set_details(details)
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/add_details(variable,details)
|
||||
if(sealed)
|
||||
return
|
||||
var/datum/feedback_variable/FV = find_feedback_datum(variable)
|
||||
FV.add_details(details)
|
||||
/datum/feedback_variable/New(new_key, new_key_type)
|
||||
key = new_key
|
||||
key_type = new_key_type
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/ReportDeath(mob/living/L)
|
||||
if(sealed)
|
||||
@@ -208,69 +272,3 @@ SUBSYSTEM_DEF(blackbox)
|
||||
var/map = sanitizeSQL(SSmapping.config.map_name)
|
||||
var/datum/DBQuery/query_report_death = SSdbcore.NewQuery("INSERT INTO [format_table_name("death")] (pod, x_coord, y_coord, z_coord, mapname, server_ip, server_port, round_id, tod, job, special, name, byondkey, laname, lakey, bruteloss, fireloss, brainloss, oxyloss, toxloss, cloneloss, staminaloss, last_words, suicide) VALUES ('[sqlpod]', '[x_coord]', '[y_coord]', '[z_coord]', '[map]', INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]', [GLOB.round_id], '[SQLtime()]', '[sqljob]', '[sqlspecial]', '[sqlname]', '[sqlkey]', '[laname]', '[lakey]', [sqlbrute], [sqlfire], [sqlbrain], [sqloxy], [sqltox], [sqlclone], [sqlstamina], '[last_words]', [suicide])")
|
||||
query_report_death.Execute()
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/Seal()
|
||||
if(sealed)
|
||||
return
|
||||
if(IsAdminAdvancedProcCall())
|
||||
var/msg = "[key_name_admin(usr)] sealed the blackbox!"
|
||||
message_admins(msg)
|
||||
log_game("Blackbox sealed[IsAdminAdvancedProcCall() ? " by [key_name(usr)]" : ""].")
|
||||
sealed = TRUE
|
||||
|
||||
//feedback variable datum, for storing all kinds of data
|
||||
/datum/feedback_variable
|
||||
var/variable
|
||||
var/value
|
||||
var/list/details
|
||||
|
||||
/datum/feedback_variable/New(param_variable, param_value = 0)
|
||||
variable = param_variable
|
||||
value = param_value
|
||||
|
||||
/datum/feedback_variable/proc/inc(num = 1)
|
||||
if (isnum(value))
|
||||
value += num
|
||||
else
|
||||
value = text2num(value)
|
||||
if (isnum(value))
|
||||
value += num
|
||||
else
|
||||
value = num
|
||||
|
||||
/datum/feedback_variable/proc/dec(num = 1)
|
||||
if (isnum(value))
|
||||
value -= num
|
||||
else
|
||||
value = text2num(value)
|
||||
if (isnum(value))
|
||||
value -= num
|
||||
else
|
||||
value = -num
|
||||
|
||||
/datum/feedback_variable/proc/set_value(num)
|
||||
if (isnum(num))
|
||||
value = num
|
||||
|
||||
/datum/feedback_variable/proc/get_value()
|
||||
if (!isnum(value))
|
||||
return 0
|
||||
return value
|
||||
|
||||
/datum/feedback_variable/proc/get_variable()
|
||||
return variable
|
||||
|
||||
/datum/feedback_variable/proc/set_details(deets)
|
||||
details = list("\"[deets]\"")
|
||||
|
||||
/datum/feedback_variable/proc/add_details(deets)
|
||||
if (!details)
|
||||
set_details(deets)
|
||||
else
|
||||
details += "\"[deets]\""
|
||||
|
||||
/datum/feedback_variable/proc/get_details()
|
||||
return details ? details.Join(" | ") : null
|
||||
|
||||
/datum/feedback_variable/proc/get_parsed()
|
||||
return list(variable,value,details.Join(" | "))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
SUBSYSTEM_DEF(disease)
|
||||
name = "Disease"
|
||||
flags = SS_NO_FIRE | SS_NO_INIT
|
||||
flags = SS_NO_FIRE
|
||||
|
||||
var/list/active_diseases = list() //List of Active disease in all mobs; purely for quick referencing.
|
||||
var/list/diseases
|
||||
@@ -12,6 +12,13 @@ SUBSYSTEM_DEF(disease)
|
||||
if(!diseases)
|
||||
diseases = subtypesof(/datum/disease)
|
||||
|
||||
/datum/controller/subsystem/disease/Initialize(timeofday)
|
||||
var/list/all_common_diseases = diseases - typesof(/datum/disease/advance)
|
||||
for(var/common_disease_type in all_common_diseases)
|
||||
var/datum/disease/prototype = new common_disease_type()
|
||||
archive_diseases[prototype.GetDiseaseID()] = prototype
|
||||
..()
|
||||
|
||||
/datum/controller/subsystem/disease/stat_entry(msg)
|
||||
..("P:[active_diseases.len]")
|
||||
|
||||
|
||||
@@ -393,6 +393,8 @@ SUBSYSTEM_DEF(job)
|
||||
continue
|
||||
S = sloc
|
||||
break
|
||||
if(length(GLOB.jobspawn_overrides[rank]))
|
||||
S = pick(GLOB.jobspawn_overrides[rank])
|
||||
if(S)
|
||||
SendToAtom(H, S, buckle = FALSE)
|
||||
if(!S) //if there isn't a spawnpoint send them to latejoin, if there's no latejoin go yell at your mapper
|
||||
@@ -462,36 +464,37 @@ SUBSYSTEM_DEF(job)
|
||||
|
||||
/datum/controller/subsystem/job/proc/HandleFeedbackGathering()
|
||||
for(var/datum/job/job in occupations)
|
||||
var/tmp_str = "|[job.title]|"
|
||||
|
||||
var/level1 = 0 //high
|
||||
var/level2 = 0 //medium
|
||||
var/level3 = 0 //low
|
||||
var/level4 = 0 //never
|
||||
var/level5 = 0 //banned
|
||||
var/level6 = 0 //account too young
|
||||
var/high = 0 //high
|
||||
var/medium = 0 //medium
|
||||
var/low = 0 //low
|
||||
var/never = 0 //never
|
||||
var/banned = 0 //banned
|
||||
var/young = 0 //account too young
|
||||
for(var/mob/dead/new_player/player in GLOB.player_list)
|
||||
if(!(player.ready == PLAYER_READY_TO_PLAY && player.mind && !player.mind.assigned_role))
|
||||
continue //This player is not ready
|
||||
if(jobban_isbanned(player, job.title))
|
||||
level5++
|
||||
banned++
|
||||
continue
|
||||
if(!job.player_old_enough(player.client))
|
||||
level6++
|
||||
young++
|
||||
continue
|
||||
if(job.required_playtime_remaining(player.client))
|
||||
level6++
|
||||
young++
|
||||
continue
|
||||
if(player.client.prefs.GetJobDepartment(job, 1) & job.flag)
|
||||
level1++
|
||||
high++
|
||||
else if(player.client.prefs.GetJobDepartment(job, 2) & job.flag)
|
||||
level2++
|
||||
medium++
|
||||
else if(player.client.prefs.GetJobDepartment(job, 3) & job.flag)
|
||||
level3++
|
||||
else level4++ //not selected
|
||||
|
||||
tmp_str += "HIGH=[level1]|MEDIUM=[level2]|LOW=[level3]|NEVER=[level4]|BANNED=[level5]|YOUNG=[level6]|-"
|
||||
SSblackbox.add_details("job_preferences",tmp_str)
|
||||
low++
|
||||
else never++ //not selected
|
||||
SSblackbox.record_feedback("nested tally", "job_preferences", high, list("[job.title]", "high"))
|
||||
SSblackbox.record_feedback("nested tally", "job_preferences", medium, list("[job.title]", "medium"))
|
||||
SSblackbox.record_feedback("nested tally", "job_preferences", low, list("[job.title]", "low"))
|
||||
SSblackbox.record_feedback("nested tally", "job_preferences", never, list("[job.title]", "never"))
|
||||
SSblackbox.record_feedback("nested tally", "job_preferences", banned, list("[job.title]", "banned"))
|
||||
SSblackbox.record_feedback("nested tally", "job_preferences", young, list("[job.title]", "young"))
|
||||
|
||||
/datum/controller/subsystem/job/proc/PopcapReached()
|
||||
var/hpc = CONFIG_GET(number/hard_popcap)
|
||||
@@ -535,6 +538,10 @@ SUBSYSTEM_DEF(job)
|
||||
M.forceMove(get_turf(A))
|
||||
|
||||
/datum/controller/subsystem/job/proc/SendToLateJoin(mob/M, buckle = TRUE)
|
||||
if(M.mind && M.mind.assigned_role && length(GLOB.jobspawn_overrides[M.mind.assigned_role])) //We're doing something special today.
|
||||
SendToAtom(M,pick(GLOB.jobspawn_overrides[M.mind.assigned_role]),FALSE)
|
||||
return
|
||||
|
||||
if(latejoin_trackers.len)
|
||||
SendToAtom(M, pick(latejoin_trackers), buckle)
|
||||
else
|
||||
|
||||
@@ -62,6 +62,7 @@ SUBSYSTEM_DEF(mapping)
|
||||
repopulate_sorted_areas()
|
||||
// Set up Z-level transistions.
|
||||
setup_map_transitions()
|
||||
generate_station_area_list()
|
||||
..()
|
||||
|
||||
/* Nuke threats, for making the blue tiles on the station go RED
|
||||
@@ -139,6 +140,19 @@ SUBSYSTEM_DEF(mapping)
|
||||
INIT_ANNOUNCE(msg)
|
||||
#undef INIT_ANNOUNCE
|
||||
|
||||
GLOBAL_LIST_EMPTY(the_station_areas)
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/generate_station_area_list()
|
||||
var/list/station_areas_blacklist = typecacheof(list(/area/space, /area/mine, /area/ruin))
|
||||
for(var/area/A in world)
|
||||
var/turf/picked = safepick(get_area_turfs(A.type))
|
||||
if(picked && (picked.z in GLOB.station_z_levels))
|
||||
if(!(A.type in GLOB.the_station_areas) && !is_type_in_typecache(A, station_areas_blacklist))
|
||||
GLOB.the_station_areas.Add(A.type)
|
||||
|
||||
if(!GLOB.the_station_areas.len)
|
||||
log_world("ERROR: Station areas list failed to generate!")
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/maprotate()
|
||||
var/players = GLOB.clients.len
|
||||
var/list/mapvotes = list()
|
||||
|
||||
@@ -29,7 +29,7 @@ SUBSYSTEM_DEF(overlays)
|
||||
|
||||
|
||||
/datum/controller/subsystem/overlays/Shutdown()
|
||||
text2file("[GLOB.log_directory]/overlay.log", render_stats(stats))
|
||||
text2file(render_stats(stats), "[GLOB.log_directory]/overlay.log")
|
||||
|
||||
|
||||
/datum/controller/subsystem/overlays/Recover()
|
||||
|
||||
@@ -6,13 +6,11 @@ PROCESSING_SUBSYSTEM_DEF(circuit)
|
||||
|
||||
var/cipherkey
|
||||
|
||||
var/list/all_exonet_connections = list() //Address = connection datum.
|
||||
var/list/obj/machinery/exonet_node/all_exonet_nodes = list()
|
||||
|
||||
var/list/all_components = list() // Associative list of [component_name]:[component_path] pairs
|
||||
var/list/cached_components = list() // Associative list of [component_path]:[component] pairs
|
||||
var/list/all_assemblies = list() // Associative list of [assembly_name]:[assembly_path] pairs
|
||||
var/list/cached_assemblies = list() // Associative list of [assembly_path]:[assembly] pairs
|
||||
var/list/all_circuits = list() // Associative list of [circuit_name]:[circuit_path] pairs
|
||||
var/list/circuit_fabricator_recipe_list = list() // Associative list of [category_name]:[list_of_circuit_paths] pairs
|
||||
var/cost_multiplier = MINERAL_MATERIAL_AMOUNT / 10 // Each circuit cost unit is 200cm3
|
||||
|
||||
@@ -58,22 +56,3 @@ PROCESSING_SUBSYSTEM_DEF(circuit)
|
||||
/obj/item/device/integrated_electronics/debugger,
|
||||
/obj/item/device/integrated_electronics/analyzer
|
||||
)
|
||||
|
||||
/datum/controller/subsystem/processing/circuit/proc/get_exonet_node()
|
||||
for(var/i in 1 to all_exonet_nodes.len)
|
||||
var/obj/machinery/exonet_node/E = all_exonet_nodes[i]
|
||||
if(E.is_operating())
|
||||
return E
|
||||
|
||||
/datum/controller/subsystem/processing/circuit/proc/get_exonet_address(addr)
|
||||
return all_exonet_connections[addr]
|
||||
|
||||
|
||||
// Proc: get_atom_from_address()
|
||||
// Parameters: 1 (target_address - the desired address to find)
|
||||
// Description: Searches an address for the atom it is attached for, otherwise returns null.
|
||||
|
||||
/datum/controller/subsystem/processing/circuit/proc/get_atom_from_address(var/target_address)
|
||||
var/datum/exonet_protocol/exonet = SScircuit.get_exonet_address(target_address)
|
||||
if(exonet)
|
||||
return exonet.holder
|
||||
@@ -0,0 +1,36 @@
|
||||
PROCESSING_SUBSYSTEM_DEF(networks)
|
||||
name = "Networks"
|
||||
priority = 80
|
||||
wait = 1
|
||||
stat_tag = "NET"
|
||||
flags = SS_KEEP_TIMING
|
||||
init_order = INIT_ORDER_NETWORKS
|
||||
var/datum/ntnet/station/station_network
|
||||
var/assignment_hardware_id = HID_RESTRICTED_END
|
||||
var/list/networks_by_id = list() //id = network
|
||||
var/list/interfaces_by_id = list() //hardware id = component interface
|
||||
|
||||
/datum/controller/subsystem/processing/networks/Initialize()
|
||||
station_network = new
|
||||
station_network.register_map_supremecy()
|
||||
. = ..()
|
||||
|
||||
/datum/controller/subsystem/processing/networks/proc/register_network(datum/ntnet/network)
|
||||
if(!networks_by_id[network.network_id])
|
||||
networks_by_id[network.network_id] = network
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/controller/subsystem/processing/networks/proc/unregister_network(datum/ntnet/network)
|
||||
networks_by_id -= network.network_id
|
||||
return TRUE
|
||||
|
||||
/datum/controller/subsystem/processing/networks/proc/register_interface(datum/component/ntnet_interface/D)
|
||||
if(!interfaces_by_id[D.hardware_id])
|
||||
interfaces_by_id[D.hardware_id] = D
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/controller/subsystem/processing/networks/proc/unregister_interface(datum/component/ntnet_interface/D)
|
||||
interfaces_by_id -= D.hardware_id
|
||||
return TRUE
|
||||
@@ -13,6 +13,6 @@ PROCESSING_SUBSYSTEM_DEF(radiation)
|
||||
return
|
||||
warned_atoms[ref] = TRUE
|
||||
var/atom/master = contamination.parent
|
||||
SSblackbox.add_details("contaminated", "[master.type]")
|
||||
SSblackbox.record_feedback("tally", "contaminated", 1, master.type)
|
||||
var/msg = "has become contamintaed with enough radiation to contaminate other objects. || Source: [contamination.source] || Strength: [contamination.strength]"
|
||||
master.investigate_log(msg, INVESTIGATE_RADIATION)
|
||||
@@ -3,6 +3,13 @@ SUBSYSTEM_DEF(radio)
|
||||
flags = SS_NO_FIRE|SS_NO_INIT
|
||||
|
||||
var/list/datum/radio_frequency/frequencies = list()
|
||||
var/list/saymodes = list()
|
||||
|
||||
/datum/controller/subsystem/radio/PreInit(timeofday)
|
||||
for(var/_SM in subtypesof(/datum/saymode))
|
||||
var/datum/saymode/SM = new _SM()
|
||||
saymodes[SM.key] = SM
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/radio/proc/add_object(obj/device, new_frequency as num, filter = null as text|null)
|
||||
var/f_text = num2text(new_frequency)
|
||||
|
||||
@@ -167,7 +167,7 @@ SUBSYSTEM_DEF(shuttle)
|
||||
var/mob/M = I
|
||||
if(M.stat != DEAD)
|
||||
++alive
|
||||
|
||||
|
||||
var/total = GLOB.joined_player_list.len
|
||||
|
||||
if(alive / total <= threshold)
|
||||
@@ -247,7 +247,7 @@ SUBSYSTEM_DEF(shuttle)
|
||||
|
||||
log_game("[key_name(user)] has called the shuttle.")
|
||||
if(call_reason)
|
||||
SSblackbox.add_details("shuttle_reason", call_reason)
|
||||
SSblackbox.record_feedback("text", "shuttle_reason", 1, "[call_reason]")
|
||||
log_game("Shuttle call reason: [call_reason]")
|
||||
message_admins("[key_name_admin(user)] has called the shuttle. (<A HREF='?_src_=holder;[HrefToken()];trigger_centcom_recall=1'>TRIGGER CENTCOM RECALL</A>)")
|
||||
|
||||
@@ -622,6 +622,30 @@ SUBSYSTEM_DEF(shuttle)
|
||||
return TRUE
|
||||
|
||||
/datum/controller/subsystem/shuttle/proc/get_containing_shuttle(atom/A)
|
||||
for(var/obj/docking_port/mobile/M in mobile)
|
||||
if(M.is_in_shuttle_bounds(A))
|
||||
return M
|
||||
var/list/mobile_cache = mobile
|
||||
for(var/i in 1 to mobile_cache.len)
|
||||
var/obj/docking_port/port = mobile_cache[i]
|
||||
if(port.is_in_shuttle_bounds(A))
|
||||
return port
|
||||
|
||||
/datum/controller/subsystem/shuttle/proc/get_containing_dock(atom/A)
|
||||
. = list()
|
||||
var/list/stationary_cache = stationary
|
||||
for(var/i in 1 to stationary_cache.len)
|
||||
var/obj/docking_port/port = stationary_cache[i]
|
||||
if(port.is_in_shuttle_bounds(A))
|
||||
. += port
|
||||
|
||||
/datum/controller/subsystem/shuttle/proc/get_dock_overlap(x0, y0, x1, y1, z)
|
||||
. = list()
|
||||
var/list/stationary_cache = stationary
|
||||
for(var/i in 1 to stationary_cache.len)
|
||||
var/obj/docking_port/port = stationary_cache[i]
|
||||
if(!port || port.z != z)
|
||||
continue
|
||||
var/list/bounds = port.return_coords()
|
||||
var/list/overlap = get_overlap(x0, y0, x1, y1, bounds[1], bounds[2], bounds[3], bounds[4])
|
||||
var/list/xs = overlap[1]
|
||||
var/list/ys = overlap[2]
|
||||
if(xs.len && ys.len)
|
||||
.[port] = overlap
|
||||
@@ -319,7 +319,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
//Cleanup some stuff
|
||||
for(var/obj/effect/landmark/start/S in GLOB.landmarks_list)
|
||||
//Deleting Startpoints but we need the ai point to AI-ize people later
|
||||
if(S.name != "AI")
|
||||
if(S.delete_after_roundstart)
|
||||
qdel(S)
|
||||
|
||||
//assign crew objectives and generate miscreants
|
||||
|
||||
@@ -35,4 +35,4 @@ SUBSYSTEM_DEF(time_track)
|
||||
last_tick_realtime = current_realtime
|
||||
last_tick_byond_time = current_byondtime
|
||||
last_tick_tickcount = current_tickcount
|
||||
SSblackbox.add_details("time_dilation_current", time_dilation_current)
|
||||
SSblackbox.record_feedback("associative", "time_dilation_current", 1, list("[time_dilation_current]" = "[SQLtime()]"))
|
||||
|
||||
@@ -357,6 +357,9 @@ SUBSYSTEM_DEF(timer)
|
||||
|
||||
wait = max(wait, 0)
|
||||
|
||||
if(wait >= INFINITY)
|
||||
CRASH("Attempted to create timer with INFINITY delay")
|
||||
|
||||
var/hash
|
||||
|
||||
if (flags & TIMER_UNIQUE)
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
Exonet Protocol Version 2
|
||||
|
||||
This is designed to be a fairly simple fake-networking system, allowing you to send and receive messages
|
||||
between the exonet_protocol datums, and for atoms to react to those messages, based on the contents of the message.
|
||||
Hopefully, this can evolve to be a more robust fake-networking system and allow for some devious network hacking in the future.
|
||||
|
||||
Version 1 never existed.
|
||||
|
||||
*Setting up*
|
||||
|
||||
To set up the exonet link, define a variable on your desired atom it is like this;
|
||||
var/datum/exonet_protocol/exonet = null
|
||||
Afterwards, before you want to do networking, call exonet = New(src), then exonet.make_address(string), and give it a string to hash into the new IP.
|
||||
The reason it needs a string is so you can have the addresses be persistant, assuming no-one already took it first.
|
||||
|
||||
When you're no longer wanting to use the address and want to free it up, like when you want to Destroy() it, you need to call remove_address()
|
||||
Destroy() also automatically calls remove_address().
|
||||
|
||||
*Sending messages*
|
||||
|
||||
To send a message to another datum, you need to know it's EPv2 (fake IP) address. Once you know that, call send_message(), place your
|
||||
intended address in the first argument, then the message in the second. For example, send_message(exonet.address, "ping") will make you
|
||||
ping yourself.
|
||||
|
||||
*Receiving messages*
|
||||
You don't need to do anything special to receive the messages, other than give your target exonet datum an address as well. Once something hits
|
||||
your datum with send_message(), receive_message() is called, and the default action is to call receive_exonet_message() on the datum's holder.
|
||||
You'll want to override receive_exonet_message() on your atom, and define what will occur when the message is received.
|
||||
The receiving atom will receive the origin atom (the atom that sent the message), the origin address, and finally the message itself.
|
||||
It's suggested to start with an if or switch statement for the message, to determine what to do.
|
||||
*/
|
||||
|
||||
/datum/exonet_protocol
|
||||
var/address = "" //Resembles IPv6, but with only five 'groups', e.g. XXXX:XXXX:XXXX:XXXX:XXXX
|
||||
var/atom/holder
|
||||
|
||||
/datum/exonet_protocol/New(var/atom/H)
|
||||
holder = H
|
||||
|
||||
/datum/exonet_protocol/Destroy()
|
||||
remove_address()
|
||||
holder = null
|
||||
return ..()
|
||||
|
||||
// Proc: make_address()
|
||||
// Parameters: 1 (string - used to make into a hash that will be part of the new address)
|
||||
// Description: Allocates a new address based on the string supplied. It results in consistant addresses for each round assuming it is not already taken..
|
||||
/datum/exonet_protocol/proc/make_address(var/string)
|
||||
if(!string)
|
||||
return
|
||||
var/hex = copytext(md5(string),1,25)
|
||||
if(!hex)
|
||||
return
|
||||
var/addr_1 = copytext(hex,1,5)
|
||||
var/addr_2 = copytext(hex,5,9)
|
||||
var/addr_3 = copytext(hex,9,13)
|
||||
var/addr_4 = copytext(hex,13,17)
|
||||
address = "fc00:[addr_1]:[addr_2]:[addr_3]:[addr_4]"
|
||||
if(SScircuit.all_exonet_connections[address])
|
||||
stack_trace("WARNING: Exonet address collision in make_address. Holder type if applicable is [holder? holder.type : "NO HOLDER"]!")
|
||||
SScircuit.all_exonet_connections[address] = src
|
||||
|
||||
|
||||
// Proc: make_arbitrary_address()
|
||||
// Parameters: 1 (new_address - the desired address)
|
||||
// Description: Allocates that specific address, if it is available.
|
||||
/datum/exonet_protocol/proc/make_arbitrary_address(var/new_address)
|
||||
if(new_address)
|
||||
if(new_address == SScircuit.get_exonet_address(new_address) ) //Collision test.
|
||||
return FALSE
|
||||
address = new_address
|
||||
SScircuit.all_exonet_connections[address] = src
|
||||
return TRUE
|
||||
|
||||
|
||||
// Proc: remove_address()
|
||||
// Parameters: None
|
||||
// Description: Deallocates the address, freeing it for use.
|
||||
/datum/exonet_protocol/proc/remove_address()
|
||||
SScircuit.all_exonet_connections -= address
|
||||
address = ""
|
||||
|
||||
|
||||
|
||||
// Proc: send_message()
|
||||
// Parameters: 3 (target_address - the desired address to send the message to, data_type - text stating what the content is meant to be used for,
|
||||
// content - the actual 'message' being sent to the address)
|
||||
// Description: Sends the message to target_address, by calling receive_message() on the desired datum. Returns true if the message is recieved.
|
||||
/datum/exonet_protocol/proc/send_message(var/target_address, var/data_type, var/content)
|
||||
if(!address)
|
||||
return FALSE
|
||||
var/obj/machinery/exonet_node/node = SScircuit.get_exonet_node()
|
||||
if(!node) // Telecomms went boom, ion storm, etc.
|
||||
return FALSE
|
||||
var/datum/exonet_protocol/exonet = SScircuit.get_exonet_address(target_address)
|
||||
if(exonet)
|
||||
node.write_log(address, target_address, data_type, content)
|
||||
return exonet.receive_message(holder, address, data_type, content)
|
||||
|
||||
// Proc: receive_message()
|
||||
// Parameters: 4 (origin_atom - the origin datum's holder, origin_address - the address the message originated from,
|
||||
// data_type - text stating what the content is meant to be used for, content - the actual 'message' being sent from origin_atom)
|
||||
// Description: Called when send_message() successfully reaches the intended datum. By default, calls receive_exonet_message() on the holder atom.
|
||||
/datum/exonet_protocol/proc/receive_message(var/atom/origin_atom, var/origin_address, var/data_type, var/content)
|
||||
holder.receive_exonet_message(origin_atom, origin_address, data_type, content)
|
||||
return TRUE // for send_message()
|
||||
|
||||
// Proc: receive_exonet_message()
|
||||
// Parameters: 3 (origin_atom - the origin datum's holder, origin_address - the address the message originated from, message - the message that was sent)
|
||||
// Description: Override this to make your atom do something when a message is received.
|
||||
/atom/proc/receive_exonet_message(var/atom/origin_atom, var/origin_address, var/message, var/text)
|
||||
return
|
||||
@@ -177,7 +177,7 @@
|
||||
to_chat(owner.current, "<span class='notice'>We have removed our evolutions from this form, and are now ready to readapt.</span>")
|
||||
reset_powers()
|
||||
canrespec = 0
|
||||
SSblackbox.add_details("changeling_power_purchase","Readapt")
|
||||
SSblackbox.record_feedback("tally", "changeling_power_purchase", 1, "Readapt")
|
||||
return 1
|
||||
else
|
||||
to_chat(owner.current, "<span class='danger'>You lack the power to readapt your evolutions!</span>")
|
||||
@@ -277,7 +277,7 @@
|
||||
if(stored_profiles.len > dna_max)
|
||||
if(!push_out_profile())
|
||||
return
|
||||
|
||||
|
||||
if(!first_prof)
|
||||
first_prof = prof
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
var/datum/action/innate/cult/comm/communion = new
|
||||
var/datum/action/innate/cult/mastervote/vote = new
|
||||
job_rank = ROLE_CULTIST
|
||||
var/ignore_implant = FALSE
|
||||
|
||||
/datum/antagonist/cult/Destroy()
|
||||
QDEL_NULL(communion)
|
||||
@@ -65,7 +66,7 @@
|
||||
|
||||
/datum/antagonist/cult/can_be_owned(datum/mind/new_owner)
|
||||
. = ..()
|
||||
if(.)
|
||||
if(. && !ignore_implant)
|
||||
. = is_convertable_to_cult(new_owner.current)
|
||||
|
||||
/datum/antagonist/cult/on_gain()
|
||||
@@ -121,6 +122,7 @@
|
||||
var/datum/action/innate/cult/master/finalreck/reckoning = new
|
||||
var/datum/action/innate/cult/master/cultmark/bloodmark = new
|
||||
var/datum/action/innate/cult/master/pulse/throwing = new
|
||||
ignore_implant = TRUE
|
||||
|
||||
/datum/antagonist/cult/master/Destroy()
|
||||
QDEL_NULL(reckoning)
|
||||
|
||||
@@ -134,11 +134,11 @@
|
||||
|
||||
/datum/antagonist/rev/farewell()
|
||||
if(ishuman(owner.current))
|
||||
owner.current.visible_message("[owner.current] looks like they just remembered their real allegiance!", \
|
||||
"<span class='userdanger'><FONT size = 3>You are no longer a brainwashed revolutionary! Your memory is hazy from the time you were a rebel...the only thing you remember is the name of the one who brainwashed you...</FONT></span>")
|
||||
owner.current.visible_message("[owner.current] looks like they just remembered their real allegiance!")
|
||||
to_chat(owner, "<span class='userdanger'><FONT size = 3>You are no longer a brainwashed revolutionary! Your memory is hazy from the time you were a rebel...the only thing you remember is the name of the one who brainwashed you...</FONT></span>")
|
||||
else if(issilicon(owner.current))
|
||||
owner.current.visible_message("The frame beeps contentedly, purging the hostile memory engram from the MMI before initalizing it.", \
|
||||
"<span class='userdanger'><FONT size = 3>The frame's firmware detects and deletes your neural reprogramming! You remember nothing but the name of the one who flashed you.</FONT></span>")
|
||||
owner.current.visible_message("The frame beeps contentedly, purging the hostile memory engram from the MMI before initalizing it.")
|
||||
to_chat(owner, "<span class='userdanger'><FONT size = 3>The frame's firmware detects and deletes your neural reprogramming! You remember nothing but the name of the one who flashed you.</FONT></span>")
|
||||
|
||||
/datum/antagonist/rev/proc/remove_revolutionary(borged, deconverter)
|
||||
log_attack("[owner.current] (Key: [key_name(owner.current)]) has been deconverted from the revolution by [deconverter] (Key: [key_name(deconverter)])!")
|
||||
|
||||
+7
-1
@@ -29,7 +29,8 @@
|
||||
icon = beam_icon
|
||||
icon_state = beam_icon_state
|
||||
beam_type = btype
|
||||
addtimer(CALLBACK(src,.proc/End), time)
|
||||
if(time < INFINITY)
|
||||
addtimer(CALLBACK(src,.proc/End), time)
|
||||
|
||||
/datum/beam/proc/Start()
|
||||
Draw()
|
||||
@@ -149,6 +150,11 @@
|
||||
owner = null
|
||||
return ..()
|
||||
|
||||
/obj/effect/ebeam/singularity_pull()
|
||||
return
|
||||
/obj/effect/ebeam/singularity_act()
|
||||
return
|
||||
|
||||
/atom/proc/Beam(atom/BeamTarget,icon_state="b_beam",icon='icons/effects/beam.dmi',time=50, maxdistance=10,beam_type=/obj/effect/ebeam,beam_sleep_time = 3)
|
||||
var/datum/beam/newbeam = new(src,BeamTarget,icon,icon_state,time,maxdistance,beam_type,beam_sleep_time)
|
||||
INVOKE_ASYNC(newbeam, /datum/beam/.proc/Start)
|
||||
|
||||
@@ -34,7 +34,7 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
|
||||
* Lazy associated list of type -> component/list of components.
|
||||
1. `/datum/component/var/enabled` (protected, boolean)
|
||||
* If the component is enabled. If not, it will not react to signals
|
||||
* `TRUE` by default
|
||||
* `FALSE` by default, set to `TRUE` when a signal is registered
|
||||
1. `/datum/component/var/dupe_mode` (protected, enum)
|
||||
* How duplicate component types are handled when added to the datum.
|
||||
* `COMPONENT_DUPE_HIGHLANDER` (default): Old component will be deleted, new component will first have `/datum/component/proc/InheritComponent(datum/component/old, FALSE)` on it
|
||||
@@ -78,6 +78,7 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
|
||||
1. `/datum/proc/SendSignal(signal, ...)` (public, final)
|
||||
* Call to send a signal to the components of the target datum
|
||||
* Extra arguments are to be specified in the signal definition
|
||||
* Returns a bitflag with signal specific information assembled from all activated components
|
||||
1. `/datum/component/New(datum/parent, ...)` (private, final)
|
||||
* Runs internal setup for the component
|
||||
* Extra arguments are passed to `Initialize()`
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/datum/component
|
||||
var/enabled = TRUE
|
||||
var/enabled = FALSE
|
||||
var/dupe_mode = COMPONENT_DUPE_HIGHLANDER
|
||||
var/dupe_type
|
||||
var/list/signal_procs
|
||||
@@ -10,6 +10,14 @@
|
||||
qdel(src)
|
||||
CRASH("[type] instantiated!")
|
||||
|
||||
//check for common mishaps
|
||||
if(!isnum(dupe_mode))
|
||||
qdel(src)
|
||||
CRASH("[type]: Invalid dupe_mode!")
|
||||
if(dupe_type && !ispath(dupe_type))
|
||||
qdel(src)
|
||||
CRASH("[type]: Invalid dupe_type!")
|
||||
|
||||
parent = P
|
||||
var/list/arguments = args.Copy()
|
||||
arguments.Cut(1, 2)
|
||||
@@ -125,6 +133,8 @@
|
||||
if(!istype(proc_or_callback, /datum/callback)) //if it wasnt a callback before, it is now
|
||||
proc_or_callback = CALLBACK(src, proc_or_callback)
|
||||
procs[sig_type] = proc_or_callback
|
||||
|
||||
enabled = TRUE
|
||||
|
||||
/datum/component/proc/InheritComponent(datum/component/C, i_am_original)
|
||||
return
|
||||
@@ -156,36 +166,36 @@
|
||||
/datum/proc/SendSignal(sigtype, ...)
|
||||
var/list/comps = datum_components
|
||||
if(!comps)
|
||||
return FALSE
|
||||
return NONE
|
||||
var/list/arguments = args.Copy()
|
||||
arguments.Cut(1, 2)
|
||||
var/target = comps[/datum/component]
|
||||
if(!length(target))
|
||||
var/datum/component/C = target
|
||||
if(!C.enabled)
|
||||
return FALSE
|
||||
var/list/sps = C.signal_procs
|
||||
var/datum/callback/CB = LAZYACCESS(sps, sigtype)
|
||||
return NONE
|
||||
var/datum/callback/CB = C.signal_procs[sigtype]
|
||||
if(!CB)
|
||||
return FALSE
|
||||
return NONE
|
||||
. = CB.InvokeAsync(arglist(arguments))
|
||||
if(.)
|
||||
if(. & COMPONENT_ACTIVATED)
|
||||
ComponentActivated(C)
|
||||
C.AfterComponentActivated()
|
||||
else
|
||||
. = FALSE
|
||||
. = NONE
|
||||
for(var/I in target)
|
||||
var/datum/component/C = I
|
||||
if(!C.enabled)
|
||||
continue
|
||||
var/list/sps = C.signal_procs
|
||||
var/datum/callback/CB = LAZYACCESS(sps, sigtype)
|
||||
var/datum/callback/CB = C.signal_procs[sigtype]
|
||||
if(!CB)
|
||||
continue
|
||||
if(CB.InvokeAsync(arglist(arguments)))
|
||||
var/retval = CB.InvokeAsync(arglist(arguments))
|
||||
. |= retval
|
||||
if(retval & COMPONENT_ACTIVATED)
|
||||
ComponentActivated(C)
|
||||
C.AfterComponentActivated()
|
||||
. = TRUE
|
||||
|
||||
/datum/proc/ComponentActivated(datum/component/C)
|
||||
set waitfor = FALSE
|
||||
|
||||
@@ -20,27 +20,26 @@
|
||||
/datum/component/archaeology/proc/Dig(obj/item/W, mob/living/user)
|
||||
if(dug)
|
||||
to_chat(user, "<span class='notice'>Looks like someone has dug here already.</span>")
|
||||
return FALSE
|
||||
else
|
||||
var/digging_speed
|
||||
if (istype(W, /obj/item/shovel))
|
||||
var/obj/item/shovel/S = W
|
||||
digging_speed = S.digspeed
|
||||
else if (istype(W, /obj/item/pickaxe))
|
||||
var/obj/item/pickaxe/P = W
|
||||
digging_speed = P.digspeed
|
||||
return
|
||||
|
||||
var/digging_speed
|
||||
if (istype(W, /obj/item/shovel))
|
||||
var/obj/item/shovel/S = W
|
||||
digging_speed = S.digspeed
|
||||
else if (istype(W, /obj/item/pickaxe))
|
||||
var/obj/item/pickaxe/P = W
|
||||
digging_speed = P.digspeed
|
||||
|
||||
if (digging_speed && isturf(user.loc))
|
||||
to_chat(user, "<span class='notice'>You start digging...</span>")
|
||||
playsound(parent, 'sound/effects/shovel_dig.ogg', 50, 1)
|
||||
|
||||
if (digging_speed && isturf(user.loc))
|
||||
to_chat(user, "<span class='notice'>You start digging...</span>")
|
||||
playsound(parent, 'sound/effects/shovel_dig.ogg', 50, 1)
|
||||
|
||||
if(do_after(user, digging_speed, target = parent))
|
||||
to_chat(user, "<span class='notice'>You dig a hole.</span>")
|
||||
gets_dug()
|
||||
dug = TRUE
|
||||
SSblackbox.add_details("pick_used_mining",W.type)
|
||||
return TRUE
|
||||
return FALSE
|
||||
if(do_after(user, digging_speed, target = parent))
|
||||
to_chat(user, "<span class='notice'>You dig a hole.</span>")
|
||||
gets_dug()
|
||||
dug = TRUE
|
||||
SSblackbox.record_feedback("tally", "pick_used_mining", 1, W.type)
|
||||
return COMPONENT_NO_AFTERATTACK
|
||||
|
||||
/datum/component/archaeology/proc/gets_dug()
|
||||
if(dug)
|
||||
|
||||
@@ -10,4 +10,4 @@
|
||||
if(istype(victim))
|
||||
for(var/datum/disease/D in diseases)
|
||||
victim.ContactContractDisease(D, "feet")
|
||||
return TRUE
|
||||
return COMPONENT_ACTIVATED
|
||||
@@ -53,11 +53,11 @@
|
||||
/datum/component/material_container/proc/OnAttackBy(obj/item/I, mob/living/user)
|
||||
var/list/tc = allowed_typecache
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
return FALSE
|
||||
return
|
||||
if((I.flags_2 & (HOLOGRAM_2 | NO_MAT_REDEMPTION_2)) || (tc && !is_type_in_typecache(I, tc)))
|
||||
to_chat(user, "<span class='warning'>[parent] won't accept [I]!</span>")
|
||||
return FALSE
|
||||
. = TRUE
|
||||
return
|
||||
. = COMPONENT_ACTIVATED | COMPONENT_NO_AFTERATTACK
|
||||
last_insert_success = FALSE
|
||||
var/datum/callback/pc = precondition
|
||||
if(pc && !pc.Invoke())
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
//Thing meant for allowing datums and objects to access a NTnet network datum.
|
||||
/datum/proc/ntnet_recieve(datum/netdata/data)
|
||||
return
|
||||
|
||||
/datum/proc/ntnet_send(datum/netdata/data, netid)
|
||||
GET_COMPONENT(NIC, /datum/component/ntnet_interface)
|
||||
if(!NIC)
|
||||
return FALSE
|
||||
return NIC.__network_send(data, netid)
|
||||
|
||||
/datum/component/ntnet_interface
|
||||
var/hardware_id //text
|
||||
var/network_name = "" //text
|
||||
var/list/networks_connected_by_id = list() //id = datum/ntnet
|
||||
|
||||
/datum/component/ntnet_interface/Initialize(force_ID, force_name = "NTNet Device", autoconnect_station_network = TRUE) //Don't force ID unless you know what you're doing!
|
||||
if(!force_ID)
|
||||
hardware_id = "[SSnetworks.assignment_hardware_id++]"
|
||||
else
|
||||
hardware_id = force_ID
|
||||
network_name = force_name
|
||||
SSnetworks.register_interface(src)
|
||||
if(autoconnect_station_network)
|
||||
register_connection(SSnetworks.station_network)
|
||||
|
||||
/datum/component/ntnet_interface/Destroy()
|
||||
unregister_all_connections()
|
||||
SSnetworks.unregister_interface(src)
|
||||
return ..()
|
||||
|
||||
/datum/component/ntnet_interface/proc/__network_recieve(datum/netdata/data) //Do not directly proccall!
|
||||
parent.SendSignal(COMSIG_COMPONENT_NTNET_RECIEVE, data)
|
||||
parent.ntnet_recieve(data)
|
||||
|
||||
/datum/component/ntnet_interface/proc/__network_send(datum/netdata/data, netid) //Do not directly proccall!
|
||||
if(netid)
|
||||
if(networks_connected_by_id[netid])
|
||||
var/datum/ntnet/net = networks_connected_by_id[netid]
|
||||
return net.process_data_transmit(src, data)
|
||||
return FALSE
|
||||
for(var/i in networks_connected_by_id)
|
||||
var/datum/ntnet/net = networks_connected_by_id[i]
|
||||
net.process_data_transmit(src, data)
|
||||
return TRUE
|
||||
|
||||
/datum/component/ntnet_interface/proc/register_connection(datum/ntnet/net)
|
||||
if(net.interface_connect(src))
|
||||
networks_connected_by_id[net.network_id] = net
|
||||
return TRUE
|
||||
|
||||
/datum/component/ntnet_interface/proc/unregister_all_connections()
|
||||
for(var/i in networks_connected_by_id)
|
||||
unregister_connection(networks_connected_by_id[i])
|
||||
return TRUE
|
||||
|
||||
/datum/component/ntnet_interface/proc/unregister_connection(datum/ntnet/net)
|
||||
net.interface_disconnect(src)
|
||||
networks_connected_by_id -= net.network_id
|
||||
return TRUE
|
||||
@@ -14,8 +14,8 @@
|
||||
|
||||
/datum/component/spraycan_paintable/proc/Repaint(obj/item/toy/crayon/spraycan/spraycan, mob/living/user)
|
||||
if(!istype(spraycan) || user.a_intent == INTENT_HARM)
|
||||
return FALSE
|
||||
. = TRUE
|
||||
return
|
||||
. = COMPONENT_NO_AFTERATTACK
|
||||
if(spraycan.is_capped)
|
||||
to_chat(user, "<span class='warning'>Take the cap off first!</span>")
|
||||
return
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
var/mob/victim = AM
|
||||
if(istype(victim) && !victim.is_flying() && victim.slip(intensity, parent, lube_flags))
|
||||
slip_victim = victim
|
||||
return TRUE
|
||||
return COMPONENT_ACTIVATED
|
||||
|
||||
/datum/component/slippery/AfterComponentActivated()
|
||||
slip_victim = null
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
if(ishuman(C))
|
||||
var/mob/living/carbon/human/H = C
|
||||
if(istype(H.dna.species, /datum/species/skeleton))
|
||||
return ..() //undeads are unaffected by the spook-pocalypse.
|
||||
return //undeads are unaffected by the spook-pocalypse.
|
||||
if(istype(H.dna.species, /datum/species/zombie))
|
||||
H.adjustStaminaLoss(25)
|
||||
H.Knockdown(15) //zombies can't resist the doot
|
||||
|
||||
@@ -3,13 +3,30 @@
|
||||
var/amount
|
||||
var/overlay
|
||||
|
||||
var/static/list/blacklist = typecacheof(/turf/closed/wall/mineral/diamond)
|
||||
var/static/list/resistlist = typecacheof(/turf/closed/wall/r_wall)
|
||||
var/static/list/blacklist = typecacheof(
|
||||
/turf/open/lava,
|
||||
/turf/open/space,
|
||||
/turf/open/water,
|
||||
/turf/open/chasm,
|
||||
)
|
||||
|
||||
var/static/list/immunelist = typecacheof(
|
||||
/turf/closed/wall/mineral/diamond,
|
||||
/turf/closed/indestructible,
|
||||
/turf/open/indestructible,
|
||||
)
|
||||
|
||||
var/static/list/resistlist = typecacheof(
|
||||
/turf/closed/wall/r_wall,
|
||||
)
|
||||
|
||||
/datum/component/thermite/Initialize(_amount)
|
||||
if(!istype(parent, /turf))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
. = COMPONENT_INCOMPATIBLE
|
||||
CRASH("A thermite component has been applied to an incorrect object. parent: [parent]")
|
||||
if(blacklist[parent.type])
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
if(immunelist[parent.type])
|
||||
_amount*=0 //Yeah the overlay can still go on it and be cleaned but you arent burning down a diamond wall
|
||||
if(resistlist[parent.type])
|
||||
_amount*=0.25
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
.["Show VV To Player"] = "?_src_=vars;[HrefToken(TRUE)];expose=[REF(src)]"
|
||||
|
||||
|
||||
/datum/proc/on_reagent_change()
|
||||
/datum/proc/on_reagent_change(changetype)
|
||||
return
|
||||
|
||||
|
||||
@@ -748,6 +748,28 @@
|
||||
src.give_disease(M)
|
||||
href_list["datumrefresh"] = href_list["give_spell"]
|
||||
|
||||
else if(href_list["ninja"])
|
||||
if(!check_rights(R_FUN))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/M = locate(href_list["ninja"]) in GLOB.carbon_list
|
||||
if(!istype(M))
|
||||
to_chat(usr, "This can only be used on instances of type /mob")
|
||||
return
|
||||
|
||||
if(tgalert(usr, "Are you sure you want to make [M] into a ninja?", "Confirmation", "Yes", "No") == "No")
|
||||
return
|
||||
|
||||
if(!M.mind)
|
||||
M.mind_initialize()
|
||||
|
||||
var/datum/antagonist/ninja/hiyah = M.mind.has_antag_datum(/datum/antagonist/ninja)
|
||||
if(!hiyah)
|
||||
hiyah = add_ninja(M)
|
||||
if(hiyah)
|
||||
hiyah.equip_space_ninja()
|
||||
href_list["datumrefresh"] = href_list["ninja"]
|
||||
|
||||
else if(href_list["gib"])
|
||||
if(!check_rights(R_FUN))
|
||||
return
|
||||
|
||||
@@ -143,14 +143,25 @@
|
||||
//Proc to use when you 100% want to infect someone, as long as they aren't immune
|
||||
/mob/proc/ForceContractDisease(datum/disease/D)
|
||||
if(!CanContractDisease(D))
|
||||
return 0
|
||||
return FALSE
|
||||
AddDisease(D)
|
||||
|
||||
|
||||
/mob/living/carbon/human/CanContractDisease(datum/disease/D)
|
||||
if(dna && (VIRUSIMMUNE in dna.species.species_traits) && !D.bypasses_immunity)
|
||||
return 0
|
||||
|
||||
if(dna)
|
||||
if((VIRUSIMMUNE in dna.species.species_traits) && !D.bypasses_immunity)
|
||||
return FALSE
|
||||
|
||||
var/can_infect = FALSE
|
||||
for(var/host_type in D.infectable_hosts)
|
||||
if(host_type in dna.species.species_traits)
|
||||
can_infect = TRUE
|
||||
break
|
||||
if(!can_infect)
|
||||
return FALSE
|
||||
|
||||
for(var/thing in D.required_organs)
|
||||
if(!((locate(thing) in bodyparts) || (locate(thing) in internal_organs)))
|
||||
return 0
|
||||
return FALSE
|
||||
return ..()
|
||||
@@ -30,6 +30,8 @@
|
||||
var/list/required_organs = list()
|
||||
var/needs_all_cures = TRUE
|
||||
var/list/strain_data = list() //dna_spread special bullshit
|
||||
var/list/infectable_hosts = list(SPECIES_ORGANIC) //if the disease can spread on organics, synthetics, or undead
|
||||
var/process_dead = FALSE //if this ticks while the host is dead
|
||||
|
||||
/datum/disease/Destroy()
|
||||
affected_mob = null
|
||||
@@ -101,8 +103,9 @@
|
||||
/datum/disease/proc/cure(add_resistance = TRUE)
|
||||
if(affected_mob)
|
||||
if(disease_flags & CAN_RESIST)
|
||||
if(add_resistance && !(type in affected_mob.resistances))
|
||||
affected_mob.resistances += type
|
||||
var/id = GetDiseaseID()
|
||||
if(add_resistance && !(id in affected_mob.resistances))
|
||||
affected_mob.resistances += id
|
||||
remove_virus()
|
||||
qdel(src)
|
||||
|
||||
@@ -119,7 +122,7 @@
|
||||
|
||||
|
||||
/datum/disease/proc/GetDiseaseID()
|
||||
return type
|
||||
return "[type]"
|
||||
|
||||
//don't use this proc directly. this should only ever be called by cure()
|
||||
/datum/disease/proc/remove_virus()
|
||||
|
||||
@@ -95,15 +95,6 @@
|
||||
return 0
|
||||
return 1
|
||||
|
||||
// To add special resistances.
|
||||
/datum/disease/advance/cure(resistance=1)
|
||||
if(affected_mob)
|
||||
var/id = "[GetDiseaseID()]"
|
||||
if(resistance && !(id in affected_mob.resistances))
|
||||
affected_mob.resistances[id] = id
|
||||
remove_virus()
|
||||
qdel(src) //delete the datum to stop it processing
|
||||
|
||||
// Returns the advance disease with a different reference memory.
|
||||
/datum/disease/advance/Copy(process = 0)
|
||||
return new /datum/disease/advance(process, src, 1)
|
||||
|
||||
@@ -9,20 +9,15 @@
|
||||
base_message_chance = 20 //here used for the overlays
|
||||
symptom_delay_min = 1
|
||||
symptom_delay_max = 1
|
||||
var/hide_healing = FALSE
|
||||
var/passive_message = "" //random message to infected but not actively healing people
|
||||
threshold_desc = "<b>Stage Speed 6:</b> Doubles healing speed.<br>\
|
||||
<b>Stage Speed 11:</b> Triples healing speed.<br>\
|
||||
<b>Stealth 4:</b> Healing will no longer be visible to onlookers."
|
||||
|
||||
/datum/symptom/heal/Start(datum/disease/advance/A)
|
||||
if(!..())
|
||||
return
|
||||
if(A.properties["stealth"] >= 4) //invisible healing
|
||||
hide_healing = TRUE
|
||||
if(A.properties["stage_rate"] >= 6) //stronger healing
|
||||
power = 2
|
||||
if(A.properties["stage_rate"] >= 11) //even stronger healing
|
||||
power = 3
|
||||
|
||||
/datum/symptom/heal/Activate(datum/disease/advance/A)
|
||||
if(!..())
|
||||
@@ -31,299 +26,439 @@
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(4, 5)
|
||||
Heal(M, A)
|
||||
var/effectiveness = CanHeal(A)
|
||||
if(!effectiveness)
|
||||
if(passive_message && prob(2) && passive_message_condition(M))
|
||||
to_chat(M, passive_message)
|
||||
return
|
||||
else
|
||||
Heal(M, A, effectiveness)
|
||||
return
|
||||
|
||||
/datum/symptom/heal/proc/Heal(mob/living/M, datum/disease/advance/A)
|
||||
return 1
|
||||
/datum/symptom/heal/proc/CanHeal(datum/disease/advance/A)
|
||||
return power
|
||||
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
/datum/symptom/heal/proc/Heal(mob/living/M, datum/disease/advance/A, actual_power)
|
||||
return TRUE
|
||||
|
||||
Toxin Filter
|
||||
/datum/symptom/heal/proc/passive_message_condition(mob/living/M)
|
||||
return TRUE
|
||||
|
||||
Little bit hidden.
|
||||
Lowers resistance tremendously.
|
||||
Decreases stage speed tremendously.
|
||||
Decreases transmittablity temrendously.
|
||||
Fatal Level.
|
||||
|
||||
Bonus
|
||||
Heals toxins in the affected mob's blood stream.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/heal/toxin
|
||||
name = "Toxic Filter"
|
||||
desc = "The virus synthesizes regenerative chemicals in the bloodstream, repairing damage caused by toxins."
|
||||
name = "Starlight Condensation"
|
||||
desc = "The virus reacts to direct starlight, producing regenerative chemicals that can cure toxin damage."
|
||||
stealth = 1
|
||||
resistance = -4
|
||||
stage_speed = -4
|
||||
transmittable = -4
|
||||
resistance = -3
|
||||
stage_speed = -3
|
||||
transmittable = -3
|
||||
level = 6
|
||||
passive_message = "<span class='notice'>You miss the feeling of starlight on your skin.</span>"
|
||||
var/nearspace_penalty = 0.3
|
||||
threshold_desc = "<b>Stage Speed 6:</b> Increases healing speed.<br>\
|
||||
<b>Transmission 6:</b> Removes penalty for only being close to space."
|
||||
|
||||
/datum/symptom/heal/toxin/Heal(mob/living/M, datum/disease/advance/A)
|
||||
var/heal_amt = 1 * power
|
||||
if(M.toxloss > 0 && prob(base_message_chance) && !hide_healing)
|
||||
new /obj/effect/temp_visual/heal(get_turf(M), "#66FF99")
|
||||
/datum/symptom/heal/toxin/Start(datum/disease/advance/A)
|
||||
if(!..())
|
||||
return
|
||||
if(A.properties["transmission"] >= 6)
|
||||
nearspace_penalty = 1
|
||||
if(A.properties["stage_rate"] >= 6)
|
||||
power = 2
|
||||
|
||||
/datum/symptom/heal/toxin/CanHeal(datum/disease/advance/A)
|
||||
var/mob/living/M = A.affected_mob
|
||||
if(istype(get_turf(M), /turf/open/space))
|
||||
return power
|
||||
else
|
||||
for(var/turf/T in view(M, 2))
|
||||
if(istype(T, /turf/open/space))
|
||||
return power * nearspace_penalty
|
||||
|
||||
/datum/symptom/heal/toxin/Heal(mob/living/M, datum/disease/advance/A, actual_power)
|
||||
var/heal_amt = actual_power
|
||||
if(M.getToxLoss() && prob(5))
|
||||
to_chat(M, "<span class='notice'>Your skin tingles as the starlight purges toxins from your bloodstream.</span>")
|
||||
M.adjustToxLoss(-heal_amt)
|
||||
return 1
|
||||
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
/datum/symptom/heal/toxin/passive_message_condition(mob/living/M)
|
||||
if(M.getToxLoss())
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
Apoptosis
|
||||
|
||||
Lowers resistance.
|
||||
Decreases stage speed.
|
||||
Decreases transmittablity.
|
||||
|
||||
Bonus
|
||||
Heals toxins in the affected mob's blood stream faster.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/heal/toxin/plus
|
||||
|
||||
name = "Apoptoxin filter"
|
||||
/datum/symptom/heal/chem
|
||||
name = "Toxolysis"
|
||||
stealth = 0
|
||||
resistance = -2
|
||||
stage_speed = -2
|
||||
transmittable = -2
|
||||
level = 8
|
||||
desc = "The virus stimulates production of special stem cells in the bloodstream, causing rapid reparation of any damage caused by toxins."
|
||||
level = 7
|
||||
var/food_conversion = FALSE
|
||||
desc = "The virus rapidly breaks down any foreign chemicals in the bloodstream."
|
||||
threshold_desc = "<b>Resistance 7:</b> Increases chem removal speed.<br>\
|
||||
<b>Stage Speed 6:</b> Consumed chemicals nourish the host."
|
||||
|
||||
/datum/symptom/heal/toxin/plus/Heal(mob/living/M, datum/disease/advance/A)
|
||||
var/heal_amt = 2 * power
|
||||
if(M.toxloss > 0 && prob(base_message_chance) && !hide_healing)
|
||||
new /obj/effect/temp_visual/heal(get_turf(M), "#00FF00")
|
||||
M.adjustToxLoss(-heal_amt)
|
||||
/datum/symptom/heal/chem/Start(datum/disease/advance/A)
|
||||
if(!..())
|
||||
return
|
||||
if(A.properties["stage_rate"] >= 6)
|
||||
food_conversion = TRUE
|
||||
if(A.properties["resistance"] >= 7)
|
||||
power = 2
|
||||
|
||||
/datum/symptom/heal/chem/Heal(mob/living/M, datum/disease/advance/A, actual_power)
|
||||
for(var/datum/reagent/R in M.reagents.reagent_list) //Not just toxins!
|
||||
M.reagents.remove_reagent(R.id, actual_power)
|
||||
if(food_conversion)
|
||||
M.nutrition += 0.3
|
||||
if(prob(2))
|
||||
to_chat(M, "<span class='notice'>You feel a mild warmth as your blood purifies itself.</span>")
|
||||
return 1
|
||||
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Regeneration
|
||||
|
||||
Little bit hidden.
|
||||
Lowers resistance tremendously.
|
||||
Decreases stage speed tremendously.
|
||||
Decreases transmittablity temrendously.
|
||||
Fatal Level.
|
||||
/datum/symptom/heal/metabolism
|
||||
name = "Metabolic Boost"
|
||||
stealth = -1
|
||||
resistance = -2
|
||||
stage_speed = 2
|
||||
transmittable = 1
|
||||
level = 7
|
||||
var/triple_metabolism = FALSE
|
||||
var/reduced_hunger = FALSE
|
||||
desc = "The virus causes the host's metabolism to accelerate rapidly, making them process chemicals twice as fast,\
|
||||
but also causing increased hunger."
|
||||
threshold_desc = "<b>Stealth 3:</b> Reduces hunger rate.<br>\
|
||||
<b>Stage Speed 10:</b> Chemical metabolization is tripled instead of doubled."
|
||||
|
||||
Bonus
|
||||
Heals brute damage slowly over time.
|
||||
/datum/symptom/heal/metabolism/Start(datum/disease/advance/A)
|
||||
if(!..())
|
||||
return
|
||||
if(A.properties["stage_rate"] >= 10)
|
||||
triple_metabolism = TRUE
|
||||
if(A.properties["stealth"] >= 3)
|
||||
reduced_hunger = TRUE
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
/datum/symptom/heal/metabolism/Heal(mob/living/carbon/C, datum/disease/advance/A, actual_power)
|
||||
if(!istype(C))
|
||||
return
|
||||
C.reagents.metabolize(C, can_overdose=TRUE) //this works even without a liver; it's intentional since the virus is metabolizing by itself
|
||||
if(triple_metabolism)
|
||||
C.reagents.metabolize(C, can_overdose=TRUE)
|
||||
C.overeatduration = max(C.overeatduration - 2, 0)
|
||||
var/lost_nutrition = 9 - (reduced_hunger * 5)
|
||||
C.nutrition = max(C.nutrition - (lost_nutrition * HUNGER_FACTOR), 0) //Hunger depletes at 10x the normal speed
|
||||
if(prob(2))
|
||||
to_chat(C, "<span class='notice'>You feel an odd gurgle in your stomach, as if it was working much faster than normal.</span>")
|
||||
return 1
|
||||
|
||||
/datum/symptom/heal/brute
|
||||
|
||||
name = "Regeneration"
|
||||
desc = "The virus stimulates the regenerative process in the host, causing faster wound healing."
|
||||
name = "Cellular Molding"
|
||||
desc = "The virus is able to shift cells around when in conditions of high heat, repairing existing physical damage."
|
||||
stealth = 1
|
||||
resistance = -4
|
||||
stage_speed = -4
|
||||
transmittable = -4
|
||||
resistance = -3
|
||||
stage_speed = -3
|
||||
transmittable = -3
|
||||
level = 6
|
||||
passive_message = "<span class='notice'>You feel the flesh pulsing under your skin for a moment, but it's too cold to move.</span>"
|
||||
threshold_desc = "<b>Stage Speed 8:</b> Doubles healing speed."
|
||||
|
||||
/datum/symptom/heal/brute/Heal(mob/living/carbon/M, datum/disease/advance/A)
|
||||
var/heal_amt = 2 * power
|
||||
/datum/symptom/heal/brute/Start(datum/disease/advance/A)
|
||||
if(!..())
|
||||
return
|
||||
if(A.properties["stage_rate"] >= 8)
|
||||
power = 2
|
||||
|
||||
/datum/symptom/heal/brute/CanHeal(datum/disease/advance/A)
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(M.bodytemperature)
|
||||
if(0 to 340)
|
||||
return FALSE
|
||||
if(340 to BODYTEMP_HEAT_DAMAGE_LIMIT)
|
||||
. = 0.3 * power
|
||||
if(BODYTEMP_HEAT_DAMAGE_LIMIT to 400)
|
||||
. = 0.75 * power
|
||||
if(400 to 460)
|
||||
. = power
|
||||
else
|
||||
. = 1.5 * power
|
||||
|
||||
if(M.on_fire)
|
||||
. *= 2
|
||||
|
||||
/datum/symptom/heal/brute/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power)
|
||||
var/heal_amt = 2 * actual_power
|
||||
|
||||
var/list/parts = M.get_damaged_bodyparts(1,0) //brute only
|
||||
|
||||
if(!parts.len)
|
||||
return
|
||||
|
||||
if(prob(5))
|
||||
to_chat(M, "<span class='notice'>You feel your flesh moving beneath your heated skin, mending your wounds.</span>")
|
||||
|
||||
for(var/obj/item/bodypart/L in parts)
|
||||
if(L.heal_damage(heal_amt/parts.len, 0))
|
||||
M.update_damage_overlays()
|
||||
|
||||
if(prob(base_message_chance) && !hide_healing)
|
||||
new /obj/effect/temp_visual/heal(get_turf(M), "#FF3333")
|
||||
|
||||
return 1
|
||||
|
||||
/datum/symptom/heal/brute/passive_message_condition(mob/living/M)
|
||||
if(M.getBruteLoss())
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Flesh Mending
|
||||
|
||||
No resistance change.
|
||||
Decreases stage speed.
|
||||
Decreases transmittablity.
|
||||
Fatal Level.
|
||||
|
||||
Bonus
|
||||
Heals brute damage over time. Turns cloneloss into burn damage.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/heal/brute/plus
|
||||
|
||||
name = "Flesh Mending"
|
||||
desc = "The virus rapidly mutates into body cells, effectively allowing it to quickly fix the host's wounds."
|
||||
/datum/symptom/heal/coma
|
||||
name = "Regenerative Coma"
|
||||
desc = "The virus causes the host to fall into a death-like coma when severely damaged, then rapidly fixes the damage."
|
||||
stealth = 0
|
||||
resistance = 0
|
||||
stage_speed = -2
|
||||
transmittable = -2
|
||||
level = 8
|
||||
passive_message = "<span class='notice'>The pain from your wounds makes you feel oddly sleepy...</span>"
|
||||
var/deathgasp = FALSE
|
||||
var/active_coma = FALSE //to prevent multiple coma procs
|
||||
threshold_desc = "<b>Stealth 2:</b> Host appears to die when falling into a coma.<br>\
|
||||
<b>Stage Speed 7:</b> Increases healing speed."
|
||||
|
||||
/datum/symptom/heal/brute/plus/Heal(mob/living/carbon/M, datum/disease/advance/A)
|
||||
var/heal_amt = 4 * power
|
||||
/datum/symptom/heal/coma/Start(datum/disease/advance/A)
|
||||
if(!..())
|
||||
return
|
||||
if(A.properties["stage_rate"] >= 7)
|
||||
power = 1.5
|
||||
if(A.properties["stealth"] >= 2)
|
||||
deathgasp = TRUE
|
||||
|
||||
var/list/parts = M.get_damaged_bodyparts(1,0) //brute only
|
||||
/datum/symptom/heal/coma/CanHeal(datum/disease/advance/A)
|
||||
var/mob/living/M = A.affected_mob
|
||||
if(M.status_flags & FAKEDEATH)
|
||||
return power
|
||||
else if(M.IsUnconscious() || M.stat == UNCONSCIOUS)
|
||||
return power * 0.9
|
||||
else if(M.stat == SOFT_CRIT)
|
||||
return power * 0.5
|
||||
else if(M.IsSleeping())
|
||||
return power * 0.25
|
||||
else if(M.getBruteLoss() + M.getFireLoss() >= 70 && !active_coma)
|
||||
to_chat(M, "<span class='warning'>You feel yourself slip into a regenerative coma...</span>")
|
||||
active_coma = TRUE
|
||||
addtimer(CALLBACK(src, .proc/coma, M), 60)
|
||||
|
||||
if(M.getCloneLoss() > 0)
|
||||
M.adjustCloneLoss(-1)
|
||||
M.take_bodypart_damage(0, 1) //Deals BURN damage, which is not cured by this symptom
|
||||
if(!hide_healing)
|
||||
new /obj/effect/temp_visual/heal(get_turf(M), "#33FFCC")
|
||||
/datum/symptom/heal/coma/proc/coma(mob/living/M)
|
||||
if(deathgasp)
|
||||
M.emote("deathgasp")
|
||||
M.status_flags |= FAKEDEATH
|
||||
M.update_stat()
|
||||
M.update_canmove()
|
||||
addtimer(CALLBACK(src, .proc/uncoma, M), 300)
|
||||
|
||||
/datum/symptom/heal/coma/proc/uncoma(mob/living/M)
|
||||
if(!active_coma)
|
||||
return
|
||||
active_coma = FALSE
|
||||
M.status_flags &= ~FAKEDEATH
|
||||
M.update_stat()
|
||||
M.update_canmove()
|
||||
|
||||
/datum/symptom/heal/coma/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power)
|
||||
var/heal_amt = 4 * actual_power
|
||||
|
||||
var/list/parts = M.get_damaged_bodyparts(1,1)
|
||||
|
||||
if(!parts.len)
|
||||
return
|
||||
|
||||
for(var/obj/item/bodypart/L in parts)
|
||||
if(L.heal_damage(heal_amt/parts.len, 0))
|
||||
if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len))
|
||||
M.update_damage_overlays()
|
||||
|
||||
if(prob(base_message_chance) && !hide_healing)
|
||||
new /obj/effect/temp_visual/heal(get_turf(M), "#CC1100")
|
||||
if(active_coma && M.getBruteLoss() + M.getFireLoss() == 0)
|
||||
uncoma(M)
|
||||
|
||||
return 1
|
||||
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Tissue Regrowth
|
||||
|
||||
Little bit hidden.
|
||||
Lowers resistance tremendously.
|
||||
Decreases stage speed tremendously.
|
||||
Decreases transmittablity temrendously.
|
||||
Fatal Level.
|
||||
|
||||
Bonus
|
||||
Heals burn damage slowly over time.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
/datum/symptom/heal/coma/passive_message_condition(mob/living/M)
|
||||
if((M.getBruteLoss() + M.getFireLoss()) > 30)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/symptom/heal/burn
|
||||
|
||||
name = "Tissue Regrowth"
|
||||
desc = "The virus recycles dead and burnt tissues, speeding up the healing of damage caused by burns."
|
||||
name = "Tissue Hydration"
|
||||
desc = "The virus uses excess water inside and outside the body to repair burned tisue cells."
|
||||
stealth = 1
|
||||
resistance = -4
|
||||
stage_speed = -4
|
||||
transmittable = -4
|
||||
resistance = -3
|
||||
stage_speed = -3
|
||||
transmittable = -3
|
||||
level = 6
|
||||
passive_message = "<span class='notice'>Your burned skin feels oddly dry...</span>"
|
||||
var/absorption_coeff = 1
|
||||
threshold_desc = "<b>Resistance 5:</b> Water is consumed at a much slower rate.<br>\
|
||||
<b>Stage Speed 7:</b> Increases healing speed."
|
||||
|
||||
/datum/symptom/heal/burn/Heal(mob/living/carbon/M, datum/disease/advance/A)
|
||||
var/heal_amt = 2 * power
|
||||
/datum/symptom/heal/burn/Start(datum/disease/advance/A)
|
||||
if(!..())
|
||||
return
|
||||
if(A.properties["stage_rate"] >= 7)
|
||||
power = 2
|
||||
if(A.properties["stealth"] >= 2)
|
||||
absorption_coeff = 0.25
|
||||
|
||||
/datum/symptom/heal/burn/CanHeal(datum/disease/advance/A)
|
||||
. = 0
|
||||
var/mob/living/M = A.affected_mob
|
||||
if(M.fire_stacks < 0)
|
||||
M.fire_stacks = min(M.fire_stacks + 1 * absorption_coeff, 0)
|
||||
. += power
|
||||
if(M.reagents.has_reagent("holywater"))
|
||||
M.reagents.remove_reagent("holywater", 0.5 * absorption_coeff)
|
||||
. += power * 0.75
|
||||
else if(M.reagents.has_reagent("water"))
|
||||
M.reagents.remove_reagent("water", 0.5 * absorption_coeff)
|
||||
. += power * 0.5
|
||||
|
||||
/datum/symptom/heal/burn/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power)
|
||||
var/heal_amt = 2 * actual_power
|
||||
|
||||
var/list/parts = M.get_damaged_bodyparts(0,1) //burn only
|
||||
|
||||
if(!parts.len)
|
||||
return
|
||||
|
||||
if(prob(5))
|
||||
to_chat(M, "<span class='notice'>You feel yourself absorbing the water around you to soothe your burned skin.</span>")
|
||||
|
||||
for(var/obj/item/bodypart/L in parts)
|
||||
if(L.heal_damage(0, heal_amt/parts.len))
|
||||
M.update_damage_overlays()
|
||||
|
||||
if(prob(base_message_chance) && !hide_healing)
|
||||
new /obj/effect/temp_visual/heal(get_turf(M), "#FF9933")
|
||||
return 1
|
||||
|
||||
/datum/symptom/heal/burn/passive_message_condition(mob/living/M)
|
||||
if(M.getFireLoss())
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Heat Resistance //Needs a better name
|
||||
|
||||
No resistance change.
|
||||
Decreases stage speed.
|
||||
Decreases transmittablity.
|
||||
Fatal Level.
|
||||
|
||||
Bonus
|
||||
Heals burn damage over time, and helps stabilize body temperature.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/heal/burn/plus
|
||||
|
||||
name = "Temperature Adaptation"
|
||||
desc = "The virus quickly balances body heat, while also replacing tissues damaged by external sources."
|
||||
/datum/symptom/heal/plasma
|
||||
name = "Plasma Fixation"
|
||||
desc = "The virus draws plasma from the atmosphere and from inside the body to stabilize body temperature and heal burns."
|
||||
stealth = 0
|
||||
resistance = 0
|
||||
stage_speed = -2
|
||||
transmittable = -2
|
||||
level = 8
|
||||
passive_message = "<span class='notice'>You feel an odd attraction to plasma.</span>"
|
||||
var/temp_rate = 1
|
||||
threshold_desc = "<b>Transmission 6:</b> Increases temperature adjustment rate.<br>\
|
||||
<b>Stage Speed 7:</b> Increases healing speed."
|
||||
|
||||
/datum/symptom/heal/burn/plus/Heal(mob/living/carbon/M, datum/disease/advance/A)
|
||||
var/heal_amt = 4 * power
|
||||
/datum/symptom/heal/plasma/Start(datum/disease/advance/A)
|
||||
if(!..())
|
||||
return
|
||||
if(A.properties["stage_rate"] >= 7)
|
||||
power = 2
|
||||
if(A.properties["trasmission"] >= 6)
|
||||
temp_rate = 4
|
||||
|
||||
/datum/symptom/heal/plasma/CanHeal(datum/disease/advance/A)
|
||||
var/mob/living/M = A.affected_mob
|
||||
var/datum/gas_mixture/environment
|
||||
var/list/gases
|
||||
|
||||
. = 0
|
||||
|
||||
if(M.loc)
|
||||
environment = M.loc.return_air()
|
||||
if(environment)
|
||||
gases = environment.gases
|
||||
if(gases["plasma"] && gases["plasma"][MOLES] > gases["plasma"][GAS_META][META_GAS_MOLES_VISIBLE]) //if there's enough plasma in the air to see
|
||||
. += power * 0.5
|
||||
if(M.reagents.has_reagent("plasma"))
|
||||
. += power * 0.75
|
||||
|
||||
/datum/symptom/heal/plasma/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power)
|
||||
var/heal_amt = 4 * actual_power
|
||||
|
||||
var/list/parts = M.get_damaged_bodyparts(0,1) //burn only
|
||||
|
||||
if(prob(5))
|
||||
to_chat(M, "<span class='notice'>You feel yourself absorbing plasma inside and around you...</span>")
|
||||
|
||||
if(M.bodytemperature > 310)
|
||||
M.bodytemperature = max(310, M.bodytemperature - (10 * heal_amt * TEMPERATURE_DAMAGE_COEFFICIENT))
|
||||
M.bodytemperature = max(310, M.bodytemperature - (20 * temp_rate * TEMPERATURE_DAMAGE_COEFFICIENT))
|
||||
if(prob(5))
|
||||
to_chat(M, "<span class='notice'>You feel less hot.</span>")
|
||||
else if(M.bodytemperature < 311)
|
||||
M.bodytemperature = min(310, M.bodytemperature + (10 * heal_amt * TEMPERATURE_DAMAGE_COEFFICIENT))
|
||||
M.bodytemperature = min(310, M.bodytemperature + (20 * temp_rate * TEMPERATURE_DAMAGE_COEFFICIENT))
|
||||
if(prob(5))
|
||||
to_chat(M, "<span class='notice'>You feel warmer.</span>")
|
||||
|
||||
if(!parts.len)
|
||||
return
|
||||
if(prob(5))
|
||||
to_chat(M, "<span class='notice'>The pain from your burns fades rapidly.</span>")
|
||||
|
||||
for(var/obj/item/bodypart/L in parts)
|
||||
if(L.heal_damage(0, heal_amt/parts.len))
|
||||
M.update_damage_overlays()
|
||||
|
||||
if(prob(base_message_chance) && !hide_healing)
|
||||
new /obj/effect/temp_visual/heal(get_turf(M), "#CC6600")
|
||||
return 1
|
||||
|
||||
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
DNA Restoration
|
||||
|
||||
Not well hidden.
|
||||
Lowers resistance minorly.
|
||||
Does not affect stage speed.
|
||||
Decreases transmittablity greatly.
|
||||
Very high level.
|
||||
|
||||
Bonus
|
||||
Heals brain damage, treats radiation, cleans SE of non-power mutations.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/heal/dna
|
||||
|
||||
name = "Deoxyribonucleic Acid Restoration"
|
||||
desc = "The virus repairs the host's genome, purging negative mutations."
|
||||
/datum/symptom/heal/radiation
|
||||
name = "Radioactive Resonance"
|
||||
desc = "The virus uses radiation to fix damage through dna mutations."
|
||||
stealth = -1
|
||||
resistance = -1
|
||||
resistance = -2
|
||||
stage_speed = 0
|
||||
transmittable = -3
|
||||
level = 5
|
||||
symptom_delay_min = 3
|
||||
symptom_delay_max = 8
|
||||
threshold_desc = "<b>Stage Speed 6:</b> Additionally heals brain damage.<br>\
|
||||
<b>Stage Speed 11:</b> Increases brain damage healing."
|
||||
level = 6
|
||||
symptom_delay_min = 1
|
||||
symptom_delay_max = 1
|
||||
passive_message = "<span class='notice'>Your skin glows faintly for a moment.</span>"
|
||||
var/cellular_damage = FALSE
|
||||
threshold_desc = "<b>Transmission 6:</b> Additionally heals cellular damage.<br>\
|
||||
<b>Resistance 7:</b> Increases healing speed."
|
||||
|
||||
/datum/symptom/heal/dna/Heal(mob/living/carbon/M, datum/disease/advance/A)
|
||||
var/amt_healed = 2 * (power - 1)
|
||||
M.adjustBrainLoss(-amt_healed)
|
||||
//Non-power mutations, excluding race, so the virus does not force monkey -> human transformations.
|
||||
var/list/unclean_mutations = (GLOB.not_good_mutations|GLOB.bad_mutations) - GLOB.mutations_list[RACEMUT]
|
||||
M.dna.remove_mutation_group(unclean_mutations)
|
||||
M.radiation = max(M.radiation - (2 * amt_healed), 0)
|
||||
/datum/symptom/heal/radiation/Start(datum/disease/advance/A)
|
||||
if(!..())
|
||||
return
|
||||
if(A.properties["resistance"] >= 7)
|
||||
power = 2
|
||||
if(A.properties["trasmission"] >= 6)
|
||||
cellular_damage = TRUE
|
||||
|
||||
/datum/symptom/heal/radiation/CanHeal(datum/disease/advance/A)
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(M.radiation)
|
||||
if(0)
|
||||
return FALSE
|
||||
if(1 to RAD_MOB_SAFE)
|
||||
return 0.25
|
||||
if(RAD_MOB_SAFE to RAD_BURN_THRESHOLD)
|
||||
return 0.5
|
||||
if(RAD_BURN_THRESHOLD to RAD_MOB_MUTATE)
|
||||
return 0.75
|
||||
if(RAD_MOB_MUTATE to RAD_MOB_KNOCKDOWN)
|
||||
return 1
|
||||
else
|
||||
return 1.5
|
||||
|
||||
/datum/symptom/heal/radiation/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power)
|
||||
var/heal_amt = actual_power
|
||||
|
||||
if(cellular_damage)
|
||||
M.adjustCloneLoss(-heal_amt * 0.5)
|
||||
|
||||
var/list/parts = M.get_damaged_bodyparts(1,1)
|
||||
|
||||
if(!parts.len)
|
||||
return
|
||||
|
||||
if(prob(4))
|
||||
to_chat(M, "<span class='notice'>Your skin glows faintly, and you feel your wounds mending themselves.</span>")
|
||||
|
||||
for(var/obj/item/bodypart/L in parts)
|
||||
if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len))
|
||||
M.update_damage_overlays()
|
||||
return 1
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/datum/symptom/undead_adaptation
|
||||
name = "Necrotic Metabolism"
|
||||
desc = "The virus is able to thrive and act even within dead hosts."
|
||||
stealth = 2
|
||||
resistance = -2
|
||||
stage_speed = 1
|
||||
transmittable = 0
|
||||
level = 5
|
||||
severity = 0
|
||||
|
||||
/datum/symptom/undead_adaptation/Start(datum/disease/advance/A)
|
||||
if(!..())
|
||||
return
|
||||
A.process_dead = TRUE
|
||||
A.infectable_hosts |= SPECIES_UNDEAD
|
||||
|
||||
/datum/symptom/inorganic_adaptation
|
||||
name = "Inorganic Biology"
|
||||
desc = "The virus can survive and replicate even in an inorganic environment, increasing its resistance and infection rate."
|
||||
stealth = -1
|
||||
resistance = 4
|
||||
stage_speed = -2
|
||||
transmittable = 3
|
||||
level = 5
|
||||
severity = 0
|
||||
|
||||
/datum/symptom/inorganic_adaptation/Start(datum/disease/advance/A)
|
||||
if(!..())
|
||||
return
|
||||
A.infectable_hosts |= SPECIES_INORGANIC
|
||||
@@ -1,56 +1,6 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Weight Gain
|
||||
|
||||
Very Very Noticable.
|
||||
Decreases resistance.
|
||||
Decreases stage speed.
|
||||
Reduced transmittable.
|
||||
Intense Level.
|
||||
|
||||
Bonus
|
||||
Increases the weight gain of the mob,
|
||||
forcing it to eventually turn fat.
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/weight_gain
|
||||
|
||||
name = "Weight Gain"
|
||||
desc = "The virus mutates the host's metabolism, making it gain weight much faster than normal."
|
||||
stealth = -3
|
||||
resistance = -3
|
||||
stage_speed = -2
|
||||
transmittable = -2
|
||||
level = 4
|
||||
severity = 3
|
||||
base_message_chance = 100
|
||||
symptom_delay_min = 15
|
||||
symptom_delay_max = 45
|
||||
threshold_desc = "<b>Stealth 4:</b> The symptom is less noticeable."
|
||||
|
||||
/datum/symptom/weight_gain/Start(datum/disease/advance/A)
|
||||
if(!..())
|
||||
return
|
||||
if(A.properties["stealth"] >= 4) //warn less often
|
||||
base_message_chance = 25
|
||||
|
||||
/datum/symptom/weight_gain/Activate(datum/disease/advance/A)
|
||||
if(!..())
|
||||
return
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(1, 2, 3, 4)
|
||||
if(prob(base_message_chance))
|
||||
to_chat(M, "<span class='warning'>[pick("You feel blubbery.", "Your stomach hurts.")]</span>")
|
||||
else
|
||||
M.overeatduration = min(M.overeatduration + 100, 600)
|
||||
M.nutrition = min(M.nutrition + 100, NUTRITION_LEVEL_FULL)
|
||||
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Weight Loss
|
||||
|
||||
Very Very Noticable.
|
||||
@@ -70,8 +20,8 @@ Bonus
|
||||
|
||||
name = "Weight Loss"
|
||||
desc = "The virus mutates the host's metabolism, making it almost unable to gain nutrition from food."
|
||||
stealth = -3
|
||||
resistance = -2
|
||||
stealth = -2
|
||||
resistance = 2
|
||||
stage_speed = -2
|
||||
transmittable = -2
|
||||
level = 3
|
||||
@@ -99,43 +49,3 @@ Bonus
|
||||
to_chat(M, "<span class='warning'><i>[pick("So hungry...", "You'd kill someone for a bite of food...", "Hunger cramps seize you...")]</i></span>")
|
||||
M.overeatduration = max(M.overeatduration - 100, 0)
|
||||
M.nutrition = max(M.nutrition - 100, 0)
|
||||
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Weight Even
|
||||
|
||||
Very Noticable.
|
||||
Decreases resistance.
|
||||
Decreases stage speed.
|
||||
Reduced transmittable.
|
||||
High level.
|
||||
|
||||
Bonus
|
||||
Causes the weight of the mob to
|
||||
be even, meaning eating isn't
|
||||
required anymore.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/weight_even
|
||||
|
||||
name = "Weight Even"
|
||||
desc = "The virus alters the host's metabolism, making it far more efficient then normal, and synthesizing nutrients from normally unedible sources."
|
||||
stealth = -3
|
||||
resistance = -2
|
||||
stage_speed = -2
|
||||
transmittable = -2
|
||||
level = 4
|
||||
symptom_delay_min = 5
|
||||
symptom_delay_max = 5
|
||||
|
||||
/datum/symptom/weight_even/Activate(datum/disease/advance/A)
|
||||
if(!..())
|
||||
return
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(4, 5)
|
||||
M.overeatduration = 0
|
||||
M.nutrition = NUTRITION_LEVEL_WELL_FED + 50
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
desc = "If left untreated subject will regurgitate bees."
|
||||
severity = VIRUS_SEVERITY_MEDIUM
|
||||
infectable_hosts = list(SPECIES_ORGANIC, SPECIES_UNDEAD) //bees nesting in corpses
|
||||
|
||||
/datum/disease/beesease/stage_act()
|
||||
..()
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
permeability_mod = 0.75
|
||||
desc = "This disease disrupts the magnetic field of your body, making it act as if a powerful magnet. Injections of iron help stabilize the field."
|
||||
severity = VIRUS_SEVERITY_MEDIUM
|
||||
infectable_hosts = list(SPECIES_ORGANIC, SPECIES_ROBOTIC)
|
||||
process_dead = TRUE
|
||||
|
||||
/datum/disease/magnitis/stage_act()
|
||||
..()
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
viable_mobtypes = list(/mob/living/carbon/human)
|
||||
desc = "Subject is possesed by the vengeful spirit of a parrot. Call the priest."
|
||||
severity = VIRUS_SEVERITY_MEDIUM
|
||||
infectable_hosts = list(SPECIES_ORGANIC, SPECIES_UNDEAD, SPECIES_INORGANIC, SPECIES_ROBOTIC)
|
||||
bypasses_immunity = TRUE //2spook
|
||||
var/mob/living/simple_animal/parrot/Poly/ghost/parrot
|
||||
|
||||
/datum/disease/parrot_possession/stage_act()
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
viable_mobtypes = list(/mob/living/carbon/human)
|
||||
permeability_mod = 1
|
||||
severity = VIRUS_SEVERITY_BIOHAZARD
|
||||
process_dead = TRUE
|
||||
|
||||
/datum/disease/rhumba_beat/stage_act()
|
||||
..()
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
stage4 = list("<span class='danger'>Your skin feels very loose.</span>", "<span class='danger'>You can feel... something...inside you.</span>")
|
||||
stage5 = list("<span class='danger'>Your skin feels as if it's about to burst off!</span>")
|
||||
new_form = /mob/living/silicon/robot
|
||||
|
||||
infectable_hosts = list(SPECIES_ORGANIC, SPECIES_UNDEAD, SPECIES_ROBOTIC)
|
||||
|
||||
/datum/disease/transformation/robot/stage_act()
|
||||
..()
|
||||
@@ -240,3 +240,4 @@
|
||||
stage4 = list("<span class='danger'>You're ravenous.</span>")
|
||||
stage5 = list("<span class='danger'>You have become a morph.</span>")
|
||||
new_form = /mob/living/simple_animal/hostile/morph
|
||||
infectable_hosts = list(SPECIES_ORGANIC, SPECIES_INORGANIC, SPECIES_UNDEAD) //magic!
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
var/obj/item/oldcell = locate (/obj/item/stock_parts/cell) in m
|
||||
QDEL_NULL(oldcell)
|
||||
m.CheckParts(holder.contents)
|
||||
SSblackbox.record_feedback("tally", "mechas_created", 1, m.name)
|
||||
QDEL_NULL(holder)
|
||||
|
||||
/datum/construction/proc/set_desc(index as num)
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
if(line)
|
||||
var/tmcommit = testmerge[line]["commit"]
|
||||
log_world("Test merge active of PR #[line] commit [tmcommit]")
|
||||
SSblackbox.add_details("testmerged_prs","[line]|[tmcommit]")
|
||||
SSblackbox.record_feedback("nested tally", "testmerged_prs", 1, list("[line]", "[tmcommit]"))
|
||||
log_world("Based off origin/master commit [originmastercommit]")
|
||||
else
|
||||
log_world(originmastercommit)
|
||||
|
||||
@@ -119,6 +119,9 @@
|
||||
playSpecials(destturf,effectout,soundout)
|
||||
if(ismegafauna(teleatom))
|
||||
message_admins("[teleatom] [ADMIN_FLW(teleatom)] has teleported from [ADMIN_COORDJMP(curturf)] to [ADMIN_COORDJMP(destturf)].")
|
||||
if(ismob(teleatom))
|
||||
var/mob/M = teleatom
|
||||
M.cancel_camera()
|
||||
return 1
|
||||
|
||||
/datum/teleport/proc/teleport()
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
#define HOLOPAD_MAX_DIAL_TIME 200
|
||||
|
||||
#define HOLORECORD_DELAY "delay"
|
||||
#define HOLORECORD_SAY "say"
|
||||
#define HOLORECORD_SOUND "sound"
|
||||
#define HOLORECORD_LANGUAGE "lang"
|
||||
#define HOLORECORD_PRESET "preset"
|
||||
#define HOLORECORD_RENAME "rename"
|
||||
|
||||
#define HOLORECORD_MAX_LENGTH 200
|
||||
|
||||
/mob/camera/aiEye/remote/holo/setLoc()
|
||||
. = ..()
|
||||
var/obj/machinery/holopad/H = origin
|
||||
@@ -184,3 +193,122 @@
|
||||
|
||||
/datum/action/innate/end_holocall/Activate()
|
||||
hcall.Disconnect(hcall.calling_holopad)
|
||||
|
||||
|
||||
//RECORDS
|
||||
/datum/holorecord
|
||||
var/caller_name = "Unknown" //Caller name
|
||||
var/image/caller_image
|
||||
var/list/entries = list()
|
||||
var/language = /datum/language/common //Initial language, can be changed by HOLORECORD_LANGUAGE entries
|
||||
|
||||
/obj/item/disk/holodisk
|
||||
name = "holorecord disk"
|
||||
desc = "Stores recorder holocalls."
|
||||
icon_state = "holodisk"
|
||||
var/datum/holorecord/record
|
||||
//Preset variables
|
||||
var/preset_image_type
|
||||
var/preset_record_text
|
||||
|
||||
/obj/item/disk/holodisk/Initialize(mapload)
|
||||
. = ..()
|
||||
if(preset_record_text)
|
||||
build_record()
|
||||
|
||||
/obj/item/disk/holodisk/Destroy()
|
||||
QDEL_NULL(record)
|
||||
return ..()
|
||||
|
||||
/obj/item/disk/holodisk/proc/build_record()
|
||||
record = new
|
||||
var/list/lines = splittext(preset_record_text,"\n")
|
||||
for(var/line in lines)
|
||||
var/prepared_line = trim(line)
|
||||
if(!length(prepared_line))
|
||||
continue
|
||||
var/splitpoint = findtext(prepared_line," ")
|
||||
if(!splitpoint)
|
||||
continue
|
||||
var/command = copytext(prepared_line,1,splitpoint)
|
||||
var/value = copytext(prepared_line,splitpoint+1)
|
||||
switch(command)
|
||||
if("DELAY")
|
||||
var/delay_value = text2num(value)
|
||||
if(!delay_value)
|
||||
continue
|
||||
record.entries += list(list(HOLORECORD_DELAY,delay_value))
|
||||
if("NAME")
|
||||
if(!record.caller_name)
|
||||
record.caller_name = value
|
||||
else
|
||||
record.entries += list(list(HOLORECORD_RENAME,value))
|
||||
if("SAY")
|
||||
record.entries += list(list(HOLORECORD_SAY,value))
|
||||
if("SOUND")
|
||||
record.entries += list(list(HOLORECORD_SOUND,value))
|
||||
if("LANGUAGE")
|
||||
var/lang_type = text2path(value)
|
||||
if(ispath(lang_type,/datum/language))
|
||||
record.entries += list(list(HOLORECORD_LANGUAGE,lang_type))
|
||||
if("PRESET")
|
||||
var/preset_type = text2path(value)
|
||||
if(ispath(preset_type,/datum/preset_holoimage))
|
||||
record.entries += list(list(HOLORECORD_PRESET,preset_type))
|
||||
if(!preset_image_type)
|
||||
record.caller_image = image('icons/mob/animal.dmi',"old")
|
||||
else
|
||||
var/datum/preset_holoimage/H = new preset_image_type
|
||||
record.caller_image = H.build_image()
|
||||
|
||||
//These build caller image from outfit and some additional data, for use by mappers for ruin holorecords
|
||||
/datum/preset_holoimage
|
||||
var/nonhuman_mobtype //Fill this if you just want something nonhuman
|
||||
var/outfit_type
|
||||
var/species_type = /datum/species/human
|
||||
|
||||
/datum/preset_holoimage/proc/build_image()
|
||||
if(nonhuman_mobtype)
|
||||
var/mob/living/L = nonhuman_mobtype
|
||||
. = image(initial(L.icon),initial(L.icon_state))
|
||||
else
|
||||
var/mob/living/carbon/human/dummy/mannequin = generate_or_wait_for_human_dummy("HOLODISK_PRESET")
|
||||
if(species_type)
|
||||
mannequin.set_species(species_type)
|
||||
if(outfit_type)
|
||||
mannequin.equipOutfit(outfit_type,TRUE)
|
||||
mannequin.setDir(SOUTH)
|
||||
COMPILE_OVERLAYS(mannequin)
|
||||
. = getFlatIcon(mannequin)
|
||||
unset_busy_human_dummy("HOLODISK_PRESET")
|
||||
|
||||
/obj/item/disk/holodisk/example
|
||||
preset_image_type = /datum/preset_holoimage/clown
|
||||
preset_record_text = {"
|
||||
NAME Clown
|
||||
DELAY 10
|
||||
SAY Why did the chaplain cross the maint ?
|
||||
DELAY 20
|
||||
SAY He wanted to get to the other side!
|
||||
SOUND clownstep
|
||||
DELAY 30
|
||||
LANGUAGE /datum/language/narsie
|
||||
SAY Helped him get there!
|
||||
DELAY 10
|
||||
SAY ALSO IM SECRETLY A GORILLA
|
||||
DELAY 10
|
||||
PRESET /datum/preset_holoimage/gorilla
|
||||
NAME Gorilla
|
||||
LANGUAGE /datum/language/common
|
||||
SAY OOGA
|
||||
DELAY 20"}
|
||||
|
||||
/datum/preset_holoimage/engineer
|
||||
outfit_type = /datum/outfit/job/engineer/gloved/rig
|
||||
|
||||
/datum/preset_holoimage/gorilla
|
||||
nonhuman_mobtype = /mob/living/simple_animal/hostile/gorilla
|
||||
|
||||
/datum/preset_holoimage/clown
|
||||
outfit_type = /datum/outfit/job/clown
|
||||
|
||||
|
||||
+16
-2
@@ -1,12 +1,15 @@
|
||||
/* HUD DATUMS */
|
||||
|
||||
GLOBAL_LIST_EMPTY(all_huds)
|
||||
|
||||
//GLOBAL HUD LIST
|
||||
GLOBAL_LIST_INIT(huds, list(
|
||||
DATA_HUD_SECURITY_BASIC = new/datum/atom_hud/data/human/security/basic(),
|
||||
DATA_HUD_SECURITY_ADVANCED = new/datum/atom_hud/data/human/security/advanced(),
|
||||
DATA_HUD_MEDICAL_BASIC = new/datum/atom_hud/data/human/medical/basic(),
|
||||
DATA_HUD_MEDICAL_ADVANCED = new/datum/atom_hud/data/human/medical/advanced(),
|
||||
DATA_HUD_DIAGNOSTIC = new/datum/atom_hud/data/diagnostic(),
|
||||
DATA_HUD_DIAGNOSTIC_BASIC = new/datum/atom_hud/data/diagnostic/basic(),
|
||||
DATA_HUD_DIAGNOSTIC_ADVANCED = new/datum/atom_hud/data/diagnostic/advanced(),
|
||||
ANTAG_HUD_CULT = new/datum/atom_hud/antag(),
|
||||
ANTAG_HUD_REV = new/datum/atom_hud/antag(),
|
||||
ANTAG_HUD_OPS = new/datum/atom_hud/antag(),
|
||||
@@ -28,6 +31,17 @@ GLOBAL_LIST_INIT(huds, list(
|
||||
var/list/mob/hudusers = list() //list with all mobs who can see the hud
|
||||
var/list/hud_icons = list() //these will be the indexes for the atom's hud_list
|
||||
|
||||
/datum/atom_hud/New()
|
||||
GLOB.all_huds += src
|
||||
|
||||
/datum/atom_hud/Destroy()
|
||||
for(var/v in hudusers)
|
||||
remove_hud_from(v)
|
||||
for(var/v in hudatoms)
|
||||
remove_from_hud(v)
|
||||
GLOB.all_huds -= src
|
||||
return ..()
|
||||
|
||||
/datum/atom_hud/proc/remove_hud_from(mob/M)
|
||||
if(!M || !hudusers[M])
|
||||
return
|
||||
@@ -77,7 +91,7 @@ GLOBAL_LIST_INIT(huds, list(
|
||||
|
||||
//MOB PROCS
|
||||
/mob/proc/reload_huds()
|
||||
for(var/datum/atom_hud/hud in (GLOB.huds|GLOB.active_alternate_appearances))
|
||||
for(var/datum/atom_hud/hud in GLOB.all_huds)
|
||||
if(hud && hud.hudusers[src])
|
||||
for(var/atom/A in hud.hudatoms)
|
||||
hud.add_to_single_hud(src, A)
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
/datum/looping_sound/supermatter
|
||||
mid_sounds = list('sound/machines/sm/supermatter1.ogg'=1,'sound/machines/sm/supermatter2.ogg'=1,'sound/machines/sm/supermatter3.ogg'=1)
|
||||
mid_length = 6
|
||||
mid_length = 10
|
||||
volume = 1
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -113,543 +113,6 @@ GLOBAL_LIST_EMPTY(mutations_list)
|
||||
/datum/mutation/human/proc/get_spans()
|
||||
return list()
|
||||
|
||||
/datum/mutation/human/hulk
|
||||
|
||||
name = "Hulk"
|
||||
quality = POSITIVE
|
||||
get_chance = 15
|
||||
lowest_value = 256 * 12
|
||||
text_gain_indication = "<span class='notice'>Your muscles hurt!</span>"
|
||||
species_allowed = list("fly") //no skeleton/lizard hulk
|
||||
health_req = 25
|
||||
|
||||
/datum/mutation/human/hulk/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
var/status = CANSTUN | CANKNOCKDOWN | CANUNCONSCIOUS | CANPUSH
|
||||
owner.status_flags &= ~status
|
||||
owner.update_body_parts()
|
||||
|
||||
/datum/mutation/human/hulk/on_attack_hand(mob/living/carbon/human/owner, atom/target, proximity)
|
||||
if(proximity) //no telekinetic hulk attack
|
||||
return target.attack_hulk(owner)
|
||||
|
||||
/datum/mutation/human/hulk/on_life(mob/living/carbon/human/owner)
|
||||
if(owner.health < 0)
|
||||
on_losing(owner)
|
||||
to_chat(owner, "<span class='danger'>You suddenly feel very weak.</span>")
|
||||
|
||||
/datum/mutation/human/hulk/on_losing(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.status_flags |= CANSTUN | CANKNOCKDOWN | CANUNCONSCIOUS | CANPUSH
|
||||
owner.update_body_parts()
|
||||
|
||||
/datum/mutation/human/hulk/say_mod(message)
|
||||
if(message)
|
||||
message = "[uppertext(replacetext(message, ".", "!"))]!!"
|
||||
return message
|
||||
|
||||
/datum/mutation/human/telekinesis
|
||||
|
||||
name = "Telekinesis"
|
||||
quality = POSITIVE
|
||||
get_chance = 20
|
||||
lowest_value = 256 * 12
|
||||
text_gain_indication = "<span class='notice'>You feel smarter!</span>"
|
||||
limb_req = "head"
|
||||
|
||||
/datum/mutation/human/telekinesis/New()
|
||||
..()
|
||||
visual_indicators |= mutable_appearance('icons/effects/genetics.dmi', "telekinesishead", -MUTATIONS_LAYER)
|
||||
|
||||
/datum/mutation/human/telekinesis/get_visual_indicator(mob/living/carbon/human/owner)
|
||||
return visual_indicators[1]
|
||||
|
||||
/datum/mutation/human/telekinesis/on_ranged_attack(mob/living/carbon/human/owner, atom/target)
|
||||
target.attack_tk(owner)
|
||||
|
||||
/datum/mutation/human/cold_resistance
|
||||
|
||||
name = "Cold Resistance"
|
||||
quality = POSITIVE
|
||||
get_chance = 25
|
||||
lowest_value = 256 * 12
|
||||
text_gain_indication = "<span class='notice'>Your body feels warm!</span>"
|
||||
time_coeff = 5
|
||||
|
||||
/datum/mutation/human/cold_resistance/New()
|
||||
..()
|
||||
visual_indicators |= mutable_appearance('icons/effects/genetics.dmi', "fire", -MUTATIONS_LAYER)
|
||||
|
||||
/datum/mutation/human/cold_resistance/get_visual_indicator(mob/living/carbon/human/owner)
|
||||
return visual_indicators[1]
|
||||
|
||||
/datum/mutation/human/cold_resistance/on_life(mob/living/carbon/human/owner)
|
||||
if(owner.getFireLoss())
|
||||
if(prob(1))
|
||||
owner.heal_bodypart_damage(0,1) //Is this really needed?
|
||||
|
||||
/datum/mutation/human/x_ray
|
||||
|
||||
name = "X Ray Vision"
|
||||
quality = POSITIVE
|
||||
get_chance = 25
|
||||
lowest_value = 256 * 12
|
||||
text_gain_indication = "<span class='notice'>The walls suddenly disappear!</span>"
|
||||
time_coeff = 2
|
||||
|
||||
/datum/mutation/human/x_ray/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
|
||||
owner.update_sight()
|
||||
|
||||
/datum/mutation/human/x_ray/on_losing(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.update_sight()
|
||||
|
||||
/datum/mutation/human/nearsight
|
||||
|
||||
name = "Near Sightness"
|
||||
quality = MINOR_NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You can't see very well.</span>"
|
||||
|
||||
/datum/mutation/human/nearsight/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.become_nearsighted()
|
||||
|
||||
/datum/mutation/human/nearsight/on_losing(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.cure_nearsighted()
|
||||
|
||||
/datum/mutation/human/epilepsy
|
||||
|
||||
name = "Epilepsy"
|
||||
quality = NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You get a headache.</span>"
|
||||
|
||||
/datum/mutation/human/epilepsy/on_life(mob/living/carbon/human/owner)
|
||||
if(prob(1) && owner.stat == CONSCIOUS)
|
||||
owner.visible_message("<span class='danger'>[owner] starts having a seizure!</span>", "<span class='userdanger'>You have a seizure!</span>")
|
||||
owner.Unconscious(200)
|
||||
owner.Jitter(1000)
|
||||
addtimer(CALLBACK(src, .proc/jitter_less, owner), 90)
|
||||
|
||||
/datum/mutation/human/epilepsy/proc/jitter_less(mob/living/carbon/human/owner)
|
||||
if(owner)
|
||||
owner.jitteriness = 10
|
||||
|
||||
/datum/mutation/human/bad_dna
|
||||
name = "Unstable DNA"
|
||||
quality = NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You feel strange.</span>"
|
||||
|
||||
/datum/mutation/human/bad_dna/on_acquiring(mob/living/carbon/human/owner)
|
||||
to_chat(owner, text_gain_indication)
|
||||
var/mob/new_mob
|
||||
if(prob(95))
|
||||
if(prob(50))
|
||||
new_mob = owner.randmutb()
|
||||
else
|
||||
new_mob = owner.randmuti()
|
||||
else
|
||||
new_mob = owner.randmutg()
|
||||
if(new_mob && ismob(new_mob))
|
||||
owner = new_mob
|
||||
. = owner
|
||||
on_losing(owner)
|
||||
|
||||
/datum/mutation/human/cough
|
||||
name = "Cough"
|
||||
quality = MINOR_NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You start coughing.</span>"
|
||||
|
||||
/datum/mutation/human/cough/on_life(mob/living/carbon/human/owner)
|
||||
if(prob(5) && owner.stat == CONSCIOUS)
|
||||
owner.drop_all_held_items()
|
||||
owner.emote("cough")
|
||||
|
||||
/datum/mutation/human/dwarfism
|
||||
name = "Dwarfism"
|
||||
quality = POSITIVE
|
||||
get_chance = 15
|
||||
lowest_value = 256 * 12
|
||||
|
||||
/datum/mutation/human/dwarfism/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.resize = 0.8
|
||||
owner.update_transform()
|
||||
owner.pass_flags |= PASSTABLE
|
||||
owner.visible_message("<span class='danger'>[owner] suddenly shrinks!</span>", "<span class='notice'>Everything around you seems to grow..</span>")
|
||||
|
||||
/datum/mutation/human/dwarfism/on_losing(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.resize = 1.25
|
||||
owner.update_transform()
|
||||
owner.pass_flags &= ~PASSTABLE
|
||||
owner.visible_message("<span class='danger'>[owner] suddenly grows!</span>", "<span class='notice'>Everything around you seems to shrink..</span>")
|
||||
|
||||
/datum/mutation/human/clumsy
|
||||
|
||||
name = "Clumsiness"
|
||||
quality = MINOR_NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You feel lightheaded.</span>"
|
||||
|
||||
/datum/mutation/human/clumsy/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.disabilities |= CLUMSY
|
||||
|
||||
/datum/mutation/human/clumsy/on_losing(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.disabilities &= ~CLUMSY
|
||||
|
||||
/datum/mutation/human/tourettes
|
||||
name = "Tourettes Syndrome"
|
||||
quality = NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You twitch.</span>"
|
||||
|
||||
/datum/mutation/human/tourettes/on_life(mob/living/carbon/human/owner)
|
||||
if(prob(10) && owner.stat == CONSCIOUS)
|
||||
owner.Stun(200)
|
||||
switch(rand(1, 3))
|
||||
if(1)
|
||||
owner.emote("twitch")
|
||||
if(2 to 3)
|
||||
owner.say("[prob(50) ? ";" : ""][pick("SHIT", "PISS", "FUCK", "CUNT", "COCKSUCKER", "MOTHERFUCKER", "TITS")]")
|
||||
var/x_offset_old = owner.pixel_x
|
||||
var/y_offset_old = owner.pixel_y
|
||||
var/x_offset = owner.pixel_x + rand(-2,2)
|
||||
var/y_offset = owner.pixel_y + rand(-1,1)
|
||||
animate(owner, pixel_x = x_offset, pixel_y = y_offset, time = 1)
|
||||
animate(owner, pixel_x = x_offset_old, pixel_y = y_offset_old, time = 1)
|
||||
|
||||
/datum/mutation/human/nervousness
|
||||
name = "Nervousness"
|
||||
quality = MINOR_NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You feel nervous.</span>"
|
||||
|
||||
/datum/mutation/human/nervousness/on_life(mob/living/carbon/human/owner)
|
||||
if(prob(10))
|
||||
owner.stuttering = max(10, owner.stuttering)
|
||||
|
||||
/datum/mutation/human/deaf
|
||||
name = "Deafness"
|
||||
quality = NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You can't seem to hear anything.</span>"
|
||||
|
||||
/datum/mutation/human/deaf/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.disabilities |= DEAF
|
||||
|
||||
/datum/mutation/human/deaf/on_losing(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.disabilities &= ~DEAF
|
||||
|
||||
/datum/mutation/human/blind
|
||||
name = "Blindness"
|
||||
quality = NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You can't seem to see anything.</span>"
|
||||
|
||||
/datum/mutation/human/blind/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.become_blind()
|
||||
|
||||
/datum/mutation/human/blind/on_losing(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.cure_blind()
|
||||
|
||||
|
||||
/datum/mutation/human/race
|
||||
name = "Monkified"
|
||||
quality = NEGATIVE
|
||||
time_coeff = 2
|
||||
|
||||
/datum/mutation/human/race/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(owner.has_brain_worms())
|
||||
to_chat(owner, "<span class='warning'>You feel something strongly clinging to your humanity!</span>")
|
||||
return
|
||||
if(..())
|
||||
return
|
||||
. = owner.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE)
|
||||
|
||||
/datum/mutation/human/race/on_losing(mob/living/carbon/monkey/owner)
|
||||
if(owner && istype(owner) && owner.stat != DEAD && (owner.dna.mutations.Remove(src)))
|
||||
. = owner.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE)
|
||||
|
||||
/datum/mutation/human/chameleon
|
||||
name = "Chameleon"
|
||||
quality = POSITIVE
|
||||
get_chance = 20
|
||||
lowest_value = 256 * 12
|
||||
text_gain_indication = "<span class='notice'>You feel one with your surroundings.</span>"
|
||||
text_lose_indication = "<span class='notice'>You feel oddly exposed.</span>"
|
||||
time_coeff = 5
|
||||
|
||||
/datum/mutation/human/chameleon/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.alpha = CHAMELEON_MUTATION_DEFAULT_TRANSPARENCY
|
||||
|
||||
/datum/mutation/human/chameleon/on_life(mob/living/carbon/human/owner)
|
||||
owner.alpha = max(0, owner.alpha - 25)
|
||||
|
||||
/datum/mutation/human/chameleon/on_move(mob/living/carbon/human/owner)
|
||||
owner.alpha = CHAMELEON_MUTATION_DEFAULT_TRANSPARENCY
|
||||
|
||||
/datum/mutation/human/chameleon/on_attack_hand(mob/living/carbon/human/owner, atom/target, proximity)
|
||||
if(proximity) //stops tk from breaking chameleon
|
||||
owner.alpha = CHAMELEON_MUTATION_DEFAULT_TRANSPARENCY
|
||||
return
|
||||
|
||||
/datum/mutation/human/chameleon/on_losing(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.alpha = 255
|
||||
|
||||
/datum/mutation/human/wacky
|
||||
name = "Wacky"
|
||||
quality = MINOR_NEGATIVE
|
||||
text_gain_indication = "<span class='sans'>You feel an off sensation in your voicebox.</span>"
|
||||
text_lose_indication = "<span class='notice'>The off sensation passes.</span>"
|
||||
|
||||
/datum/mutation/human/wacky/get_spans()
|
||||
return list(SPAN_SANS)
|
||||
|
||||
/datum/mutation/human/mute
|
||||
name = "Mute"
|
||||
quality = NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You feel unable to express yourself at all.</span>"
|
||||
text_lose_indication = "<span class='danger'>You feel able to speak freely again.</span>"
|
||||
|
||||
/datum/mutation/human/mute/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.disabilities |= MUTE
|
||||
|
||||
/datum/mutation/human/mute/on_losing(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.disabilities &= ~MUTE
|
||||
|
||||
/datum/mutation/human/smile
|
||||
name = "Smile"
|
||||
quality = MINOR_NEGATIVE
|
||||
dna_block = NON_SCANNABLE
|
||||
text_gain_indication = "<span class='notice'>You feel so happy. Nothing can be wrong with anything. :)</span>"
|
||||
text_lose_indication = "<span class='notice'>Everything is terrible again. :(</span>"
|
||||
|
||||
/datum/mutation/human/smile/say_mod(message)
|
||||
if(message)
|
||||
message = " [message] "
|
||||
//Time for a friendly game of SS13
|
||||
message = replacetext(message," stupid "," smart ")
|
||||
message = replacetext(message," retard "," genius ")
|
||||
message = replacetext(message," unrobust "," robust ")
|
||||
message = replacetext(message," dumb "," smart ")
|
||||
message = replacetext(message," awful "," great ")
|
||||
message = replacetext(message," gay ",pick(" nice "," ok "," alright "))
|
||||
message = replacetext(message," horrible "," fun ")
|
||||
message = replacetext(message," terrible "," terribly fun ")
|
||||
message = replacetext(message," terrifying "," wonderful ")
|
||||
message = replacetext(message," gross "," cool ")
|
||||
message = replacetext(message," disgusting "," amazing ")
|
||||
message = replacetext(message," loser "," winner ")
|
||||
message = replacetext(message," useless "," useful ")
|
||||
message = replacetext(message," oh god "," cheese and crackers ")
|
||||
message = replacetext(message," jesus "," gee wiz ")
|
||||
message = replacetext(message," weak "," strong ")
|
||||
message = replacetext(message," kill "," hug ")
|
||||
message = replacetext(message," murder "," tease ")
|
||||
message = replacetext(message," ugly "," beautiful ")
|
||||
message = replacetext(message," douchbag "," nice guy ")
|
||||
message = replacetext(message," whore "," lady ")
|
||||
message = replacetext(message," nerd "," smart guy ")
|
||||
message = replacetext(message," moron "," fun person ")
|
||||
message = replacetext(message," IT'S LOOSE "," EVERYTHING IS FINE ")
|
||||
message = replacetext(message," sex "," hug fight ")
|
||||
message = replacetext(message," idiot "," genius ")
|
||||
message = replacetext(message," fat "," thin ")
|
||||
message = replacetext(message," beer "," water with ice ")
|
||||
message = replacetext(message," drink "," water ")
|
||||
message = replacetext(message," feminist "," empowered woman ")
|
||||
message = replacetext(message," i hate you "," you're mean ")
|
||||
message = replacetext(message," nigger "," african american ")
|
||||
message = replacetext(message," jew "," jewish ")
|
||||
message = replacetext(message," shit "," shiz ")
|
||||
message = replacetext(message," crap "," poo ")
|
||||
message = replacetext(message," slut "," tease ")
|
||||
message = replacetext(message," ass "," butt ")
|
||||
message = replacetext(message," damn "," dang ")
|
||||
message = replacetext(message," fuck "," ")
|
||||
message = replacetext(message," penis "," privates ")
|
||||
message = replacetext(message," cunt "," privates ")
|
||||
message = replacetext(message," dick "," jerk ")
|
||||
message = replacetext(message," vagina "," privates ")
|
||||
return trim(message)
|
||||
|
||||
/datum/mutation/human/unintelligable
|
||||
name = "Unintelligable"
|
||||
quality = NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You can't seem to form any coherent thoughts!</span>"
|
||||
text_lose_indication = "<span class='danger'>Your mind feels more clear.</span>"
|
||||
|
||||
/datum/mutation/human/unintelligable/say_mod(message)
|
||||
if(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
|
||||
message = "[prefix][uppertext(jointext(rearranged," "))]!!"
|
||||
return message
|
||||
|
||||
/datum/mutation/human/swedish
|
||||
name = "Swedish"
|
||||
quality = MINOR_NEGATIVE
|
||||
dna_block = NON_SCANNABLE
|
||||
text_gain_indication = "<span class='notice'>You feel Swedish, however that works.</span>"
|
||||
text_lose_indication = "<span class='notice'>The feeling of Swedishness passes.</span>"
|
||||
|
||||
/datum/mutation/human/swedish/say_mod(message)
|
||||
if(message)
|
||||
message = replacetext(message,"w","v")
|
||||
message = replacetext(message,"j","y")
|
||||
message = replacetext(message,"a",pick("�","�","�","a"))
|
||||
message = replacetext(message,"bo","bjo")
|
||||
message = replacetext(message,"o",pick("�","�","o"))
|
||||
if(prob(30))
|
||||
message += " Bork[pick("",", bork",", bork, bork")]!"
|
||||
return message
|
||||
|
||||
/datum/mutation/human/chav
|
||||
name = "Chav"
|
||||
quality = MINOR_NEGATIVE
|
||||
dna_block = NON_SCANNABLE
|
||||
text_gain_indication = "<span class='notice'>Ye feel like a reet prat like, innit?</span>"
|
||||
text_lose_indication = "<span class='notice'>You no longer feel like being rude and sassy.</span>"
|
||||
|
||||
/datum/mutation/human/chav/say_mod(message)
|
||||
if(message)
|
||||
message = " [message] "
|
||||
message = replacetext(message," looking at "," gawpin' at ")
|
||||
message = replacetext(message," great "," bangin' ")
|
||||
message = replacetext(message," man "," mate ")
|
||||
message = replacetext(message," friend ",pick(" mate "," bruv "," bledrin "))
|
||||
message = replacetext(message," what "," wot ")
|
||||
message = replacetext(message," drink "," wet ")
|
||||
message = replacetext(message," get "," giz ")
|
||||
message = replacetext(message," what "," wot ")
|
||||
message = replacetext(message," no thanks "," wuddent fukken do one ")
|
||||
message = replacetext(message," i don't know "," wot mate ")
|
||||
message = replacetext(message," no "," naw ")
|
||||
message = replacetext(message," robust "," chin ")
|
||||
message = replacetext(message," hi "," how what how ")
|
||||
message = replacetext(message," hello "," sup bruv ")
|
||||
message = replacetext(message," kill "," bang ")
|
||||
message = replacetext(message," murder "," bang ")
|
||||
message = replacetext(message," windows "," windies ")
|
||||
message = replacetext(message," window "," windy ")
|
||||
message = replacetext(message," break "," do ")
|
||||
message = replacetext(message," your "," yer ")
|
||||
message = replacetext(message," security "," coppers ")
|
||||
return trim(message)
|
||||
|
||||
/datum/mutation/human/elvis
|
||||
name = "Elvis"
|
||||
quality = MINOR_NEGATIVE
|
||||
dna_block = NON_SCANNABLE
|
||||
text_gain_indication = "<span class='notice'>You feel pretty good, honeydoll.</span>"
|
||||
text_lose_indication = "<span class='notice'>You feel a little less conversation would be great.</span>"
|
||||
|
||||
/datum/mutation/human/elvis/on_life(mob/living/carbon/human/owner)
|
||||
switch(pick(1,2))
|
||||
if(1)
|
||||
if(prob(15))
|
||||
var/list/dancetypes = list("swinging", "fancy", "stylish", "20'th century", "jivin'", "rock and roller", "cool", "salacious", "bashing", "smashing")
|
||||
var/dancemoves = pick(dancetypes)
|
||||
owner.visible_message("<b>[owner]</b> busts out some [dancemoves] moves!")
|
||||
if(2)
|
||||
if(prob(15))
|
||||
owner.visible_message("<b>[owner]</b> [pick("jiggles their hips", "rotates their hips", "gyrates their hips", "taps their foot", "dances to an imaginary song", "jiggles their legs", "snaps their fingers")]!")
|
||||
|
||||
/datum/mutation/human/elvis/say_mod(message)
|
||||
if(message)
|
||||
message = " [message] "
|
||||
message = replacetext(message," i'm not "," I aint ")
|
||||
message = replacetext(message," girl ",pick(" honey "," baby "," baby doll "))
|
||||
message = replacetext(message," man ",pick(" son "," buddy "," brother"," pal "," friendo "))
|
||||
message = replacetext(message," out of "," outta ")
|
||||
message = replacetext(message," thank you "," thank you, thank you very much ")
|
||||
message = replacetext(message," what are you "," whatcha ")
|
||||
message = replacetext(message," yes ",pick(" sure", "yea "))
|
||||
message = replacetext(message," faggot "," square ")
|
||||
message = replacetext(message," muh valids "," getting my kicks ")
|
||||
return trim(message)
|
||||
|
||||
/datum/mutation/human/stoner
|
||||
name = "Stoner"
|
||||
quality = NEGATIVE
|
||||
dna_block = NON_SCANNABLE
|
||||
text_gain_indication = "<span class='notice'>You feel...totally chill, man!</span>"
|
||||
text_lose_indication = "<span class='notice'>You feel like you have a better sense of time.</span>"
|
||||
|
||||
/datum/mutation/human/stoner/on_acquiring(mob/living/carbon/human/owner)
|
||||
..()
|
||||
owner.grant_language(/datum/language/beachbum)
|
||||
owner.remove_language(/datum/language/common)
|
||||
|
||||
/datum/mutation/human/stoner/on_losing(mob/living/carbon/human/owner)
|
||||
..()
|
||||
owner.grant_language(/datum/language/common)
|
||||
owner.remove_language(/datum/language/beachbum)
|
||||
|
||||
/datum/mutation/human/laser_eyes
|
||||
name = "Laser Eyes"
|
||||
quality = POSITIVE
|
||||
dna_block = NON_SCANNABLE
|
||||
text_gain_indication = "<span class='notice'>You feel pressure building up behind your eyes.</span>"
|
||||
layer_used = FRONT_MUTATIONS_LAYER
|
||||
limb_req = "head"
|
||||
|
||||
/datum/mutation/human/laser_eyes/New()
|
||||
..()
|
||||
visual_indicators |= mutable_appearance('icons/effects/genetics.dmi', "lasereyes", -FRONT_MUTATIONS_LAYER)
|
||||
|
||||
/datum/mutation/human/laser_eyes/get_visual_indicator(mob/living/carbon/human/owner)
|
||||
return visual_indicators[1]
|
||||
|
||||
/datum/mutation/human/laser_eyes/on_ranged_attack(mob/living/carbon/human/owner, atom/target, mouseparams)
|
||||
if(owner.a_intent == INTENT_HARM)
|
||||
owner.LaserEyes(target, mouseparams)
|
||||
|
||||
|
||||
/mob/living/carbon/proc/update_mutations_overlay()
|
||||
return
|
||||
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
//These mutations change your overall "form" somehow, like size
|
||||
|
||||
//Epilepsy gives a very small chance to have a seizure every life tick, knocking you unconscious.
|
||||
/datum/mutation/human/epilepsy
|
||||
name = "Epilepsy"
|
||||
quality = NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You get a headache.</span>"
|
||||
|
||||
/datum/mutation/human/epilepsy/on_life(mob/living/carbon/human/owner)
|
||||
if(prob(1) && owner.stat == CONSCIOUS)
|
||||
owner.visible_message("<span class='danger'>[owner] starts having a seizure!</span>", "<span class='userdanger'>You have a seizure!</span>")
|
||||
owner.Unconscious(200)
|
||||
owner.Jitter(1000)
|
||||
addtimer(CALLBACK(src, .proc/jitter_less, owner), 90)
|
||||
|
||||
/datum/mutation/human/epilepsy/proc/jitter_less(mob/living/carbon/human/owner)
|
||||
if(owner)
|
||||
owner.jitteriness = 10
|
||||
|
||||
|
||||
//Unstable DNA induces random mutations!
|
||||
/datum/mutation/human/bad_dna
|
||||
name = "Unstable DNA"
|
||||
quality = NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You feel strange.</span>"
|
||||
|
||||
/datum/mutation/human/bad_dna/on_acquiring(mob/living/carbon/human/owner)
|
||||
to_chat(owner, text_gain_indication)
|
||||
var/mob/new_mob
|
||||
if(prob(95))
|
||||
if(prob(50))
|
||||
new_mob = owner.randmutb()
|
||||
else
|
||||
new_mob = owner.randmuti()
|
||||
else
|
||||
new_mob = owner.randmutg()
|
||||
if(new_mob && ismob(new_mob))
|
||||
owner = new_mob
|
||||
. = owner
|
||||
on_losing(owner)
|
||||
|
||||
|
||||
//Cough gives you a chronic cough that causes you to drop items.
|
||||
/datum/mutation/human/cough
|
||||
name = "Cough"
|
||||
quality = MINOR_NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You start coughing.</span>"
|
||||
|
||||
/datum/mutation/human/cough/on_life(mob/living/carbon/human/owner)
|
||||
if(prob(5) && owner.stat == CONSCIOUS)
|
||||
owner.drop_all_held_items()
|
||||
owner.emote("cough")
|
||||
|
||||
|
||||
//Dwarfism shrinks your body and lets you pass tables.
|
||||
/datum/mutation/human/dwarfism
|
||||
name = "Dwarfism"
|
||||
quality = POSITIVE
|
||||
get_chance = 15
|
||||
lowest_value = 256 * 12
|
||||
|
||||
/datum/mutation/human/dwarfism/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.resize = 0.8
|
||||
owner.update_transform()
|
||||
owner.pass_flags |= PASSTABLE
|
||||
owner.visible_message("<span class='danger'>[owner] suddenly shrinks!</span>", "<span class='notice'>Everything around you seems to grow..</span>")
|
||||
|
||||
/datum/mutation/human/dwarfism/on_losing(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.resize = 1.25
|
||||
owner.update_transform()
|
||||
owner.pass_flags &= ~PASSTABLE
|
||||
owner.visible_message("<span class='danger'>[owner] suddenly grows!</span>", "<span class='notice'>Everything around you seems to shrink..</span>")
|
||||
|
||||
|
||||
//Clumsiness has a very large amount of small drawbacks depending on item.
|
||||
/datum/mutation/human/clumsy
|
||||
name = "Clumsiness"
|
||||
quality = MINOR_NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You feel lightheaded.</span>"
|
||||
|
||||
/datum/mutation/human/clumsy/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.disabilities |= CLUMSY
|
||||
|
||||
/datum/mutation/human/clumsy/on_losing(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.disabilities &= ~CLUMSY
|
||||
|
||||
|
||||
//Tourettes causes you to randomly stand in place and shout.
|
||||
/datum/mutation/human/tourettes
|
||||
name = "Tourettes Syndrome"
|
||||
quality = NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You twitch.</span>"
|
||||
|
||||
/datum/mutation/human/tourettes/on_life(mob/living/carbon/human/owner)
|
||||
if(prob(10) && owner.stat == CONSCIOUS)
|
||||
owner.Stun(200)
|
||||
switch(rand(1, 3))
|
||||
if(1)
|
||||
owner.emote("twitch")
|
||||
if(2 to 3)
|
||||
owner.say("[prob(50) ? ";" : ""][pick("SHIT", "PISS", "FUCK", "CUNT", "COCKSUCKER", "MOTHERFUCKER", "TITS")]")
|
||||
var/x_offset_old = owner.pixel_x
|
||||
var/y_offset_old = owner.pixel_y
|
||||
var/x_offset = owner.pixel_x + rand(-2,2)
|
||||
var/y_offset = owner.pixel_y + rand(-1,1)
|
||||
animate(owner, pixel_x = x_offset, pixel_y = y_offset, time = 1)
|
||||
animate(owner, pixel_x = x_offset_old, pixel_y = y_offset_old, time = 1)
|
||||
|
||||
|
||||
//Deafness makes you deaf.
|
||||
/datum/mutation/human/deaf
|
||||
name = "Deafness"
|
||||
quality = NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You can't seem to hear anything.</span>"
|
||||
|
||||
/datum/mutation/human/deaf/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.disabilities |= DEAF
|
||||
|
||||
/datum/mutation/human/deaf/on_losing(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.disabilities &= ~DEAF
|
||||
|
||||
|
||||
//Monified turns you into a monkey.
|
||||
/datum/mutation/human/race
|
||||
name = "Monkified"
|
||||
quality = NEGATIVE
|
||||
time_coeff = 2
|
||||
|
||||
/datum/mutation/human/race/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
. = owner.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE)
|
||||
|
||||
/datum/mutation/human/race/on_losing(mob/living/carbon/monkey/owner)
|
||||
if(owner && istype(owner) && owner.stat != DEAD && (owner.dna.mutations.Remove(src)))
|
||||
. = owner.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE)
|
||||
@@ -0,0 +1,30 @@
|
||||
//Chameleon causes the owner to slowly become transparent when not moving.
|
||||
/datum/mutation/human/chameleon
|
||||
name = "Chameleon"
|
||||
quality = POSITIVE
|
||||
get_chance = 20
|
||||
lowest_value = 256 * 12
|
||||
text_gain_indication = "<span class='notice'>You feel one with your surroundings.</span>"
|
||||
text_lose_indication = "<span class='notice'>You feel oddly exposed.</span>"
|
||||
time_coeff = 5
|
||||
|
||||
/datum/mutation/human/chameleon/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.alpha = CHAMELEON_MUTATION_DEFAULT_TRANSPARENCY
|
||||
|
||||
/datum/mutation/human/chameleon/on_life(mob/living/carbon/human/owner)
|
||||
owner.alpha = max(0, owner.alpha - 25)
|
||||
|
||||
/datum/mutation/human/chameleon/on_move(mob/living/carbon/human/owner)
|
||||
owner.alpha = CHAMELEON_MUTATION_DEFAULT_TRANSPARENCY
|
||||
|
||||
/datum/mutation/human/chameleon/on_attack_hand(mob/living/carbon/human/owner, atom/target, proximity)
|
||||
if(proximity) //stops tk from breaking chameleon
|
||||
owner.alpha = CHAMELEON_MUTATION_DEFAULT_TRANSPARENCY
|
||||
return
|
||||
|
||||
/datum/mutation/human/chameleon/on_losing(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.alpha = 255
|
||||
@@ -0,0 +1,20 @@
|
||||
//Cold Resistance gives your entire body an orange halo, and makes you immune to the effects of vacuum and cold.
|
||||
/datum/mutation/human/cold_resistance
|
||||
name = "Cold Resistance"
|
||||
quality = POSITIVE
|
||||
get_chance = 25
|
||||
lowest_value = 256 * 12
|
||||
text_gain_indication = "<span class='notice'>Your body feels warm!</span>"
|
||||
time_coeff = 5
|
||||
|
||||
/datum/mutation/human/cold_resistance/New()
|
||||
..()
|
||||
visual_indicators |= mutable_appearance('icons/effects/genetics.dmi', "fire", -MUTATIONS_LAYER)
|
||||
|
||||
/datum/mutation/human/cold_resistance/get_visual_indicator(mob/living/carbon/human/owner)
|
||||
return visual_indicators[1]
|
||||
|
||||
/datum/mutation/human/cold_resistance/on_life(mob/living/carbon/human/owner)
|
||||
if(owner.getFireLoss())
|
||||
if(prob(1))
|
||||
owner.heal_bodypart_damage(0,1) //Is this really needed?
|
||||
@@ -0,0 +1,36 @@
|
||||
//Hulk turns your skin green, and allows you to punch through walls.
|
||||
/datum/mutation/human/hulk
|
||||
name = "Hulk"
|
||||
quality = POSITIVE
|
||||
get_chance = 15
|
||||
lowest_value = 256 * 12
|
||||
text_gain_indication = "<span class='notice'>Your muscles hurt!</span>"
|
||||
species_allowed = list("fly") //no skeleton/lizard hulk
|
||||
health_req = 25
|
||||
|
||||
/datum/mutation/human/hulk/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
var/status = CANSTUN | CANKNOCKDOWN | CANUNCONSCIOUS | CANPUSH
|
||||
owner.status_flags &= ~status
|
||||
owner.update_body_parts()
|
||||
|
||||
/datum/mutation/human/hulk/on_attack_hand(mob/living/carbon/human/owner, atom/target, proximity)
|
||||
if(proximity) //no telekinetic hulk attack
|
||||
return target.attack_hulk(owner)
|
||||
|
||||
/datum/mutation/human/hulk/on_life(mob/living/carbon/human/owner)
|
||||
if(owner.health < 0)
|
||||
on_losing(owner)
|
||||
to_chat(owner, "<span class='danger'>You suddenly feel very weak.</span>")
|
||||
|
||||
/datum/mutation/human/hulk/on_losing(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.status_flags |= CANSTUN | CANKNOCKDOWN | CANUNCONSCIOUS | CANPUSH
|
||||
owner.update_body_parts()
|
||||
|
||||
/datum/mutation/human/hulk/say_mod(message)
|
||||
if(message)
|
||||
message = "[uppertext(replacetext(message, ".", "!"))]!!"
|
||||
return message
|
||||
@@ -0,0 +1,74 @@
|
||||
//Nearsightedness restricts your vision by several tiles.
|
||||
/datum/mutation/human/nearsight
|
||||
name = "Near Sightness"
|
||||
quality = MINOR_NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You can't see very well.</span>"
|
||||
|
||||
/datum/mutation/human/nearsight/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.become_nearsighted()
|
||||
|
||||
/datum/mutation/human/nearsight/on_losing(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.cure_nearsighted()
|
||||
|
||||
|
||||
//Blind makes you blind. Who knew?
|
||||
/datum/mutation/human/blind
|
||||
name = "Blindness"
|
||||
quality = NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You can't seem to see anything.</span>"
|
||||
|
||||
/datum/mutation/human/blind/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.become_blind()
|
||||
|
||||
/datum/mutation/human/blind/on_losing(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.cure_blind()
|
||||
|
||||
|
||||
//X-Ray Vision lets you see through walls.
|
||||
/datum/mutation/human/x_ray
|
||||
name = "X Ray Vision"
|
||||
quality = POSITIVE
|
||||
get_chance = 25
|
||||
lowest_value = 256 * 12
|
||||
text_gain_indication = "<span class='notice'>The walls suddenly disappear!</span>"
|
||||
time_coeff = 2
|
||||
|
||||
/datum/mutation/human/x_ray/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
|
||||
owner.update_sight()
|
||||
|
||||
/datum/mutation/human/x_ray/on_losing(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.update_sight()
|
||||
|
||||
|
||||
//Laser Eyes lets you shoot lasers from your eyes!
|
||||
/datum/mutation/human/laser_eyes
|
||||
name = "Laser Eyes"
|
||||
quality = POSITIVE
|
||||
dna_block = NON_SCANNABLE
|
||||
text_gain_indication = "<span class='notice'>You feel pressure building up behind your eyes.</span>"
|
||||
layer_used = FRONT_MUTATIONS_LAYER
|
||||
limb_req = "head"
|
||||
|
||||
/datum/mutation/human/laser_eyes/New()
|
||||
..()
|
||||
visual_indicators |= mutable_appearance('icons/effects/genetics.dmi', "lasereyes", -FRONT_MUTATIONS_LAYER)
|
||||
|
||||
/datum/mutation/human/laser_eyes/get_visual_indicator(mob/living/carbon/human/owner)
|
||||
return visual_indicators[1]
|
||||
|
||||
/datum/mutation/human/laser_eyes/on_ranged_attack(mob/living/carbon/human/owner, atom/target, mouseparams)
|
||||
if(owner.a_intent == INTENT_HARM)
|
||||
owner.LaserEyes(target, mouseparams)
|
||||
@@ -0,0 +1,231 @@
|
||||
//These are all minor mutations that affect your speech somehow.
|
||||
//Individual ones aren't commented since their functions should be evident at a glance
|
||||
|
||||
/datum/mutation/human/nervousness
|
||||
name = "Nervousness"
|
||||
quality = MINOR_NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You feel nervous.</span>"
|
||||
|
||||
/datum/mutation/human/nervousness/on_life(mob/living/carbon/human/owner)
|
||||
if(prob(10))
|
||||
owner.stuttering = max(10, owner.stuttering)
|
||||
|
||||
|
||||
/datum/mutation/human/wacky
|
||||
name = "Wacky"
|
||||
quality = MINOR_NEGATIVE
|
||||
text_gain_indication = "<span class='sans'>You feel an off sensation in your voicebox.</span>"
|
||||
text_lose_indication = "<span class='notice'>The off sensation passes.</span>"
|
||||
|
||||
/datum/mutation/human/wacky/get_spans()
|
||||
return list(SPAN_SANS)
|
||||
|
||||
|
||||
/datum/mutation/human/mute
|
||||
name = "Mute"
|
||||
quality = NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You feel unable to express yourself at all.</span>"
|
||||
text_lose_indication = "<span class='danger'>You feel able to speak freely again.</span>"
|
||||
|
||||
/datum/mutation/human/mute/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.disabilities |= MUTE
|
||||
|
||||
/datum/mutation/human/mute/on_losing(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.disabilities &= ~MUTE
|
||||
|
||||
|
||||
/datum/mutation/human/smile
|
||||
name = "Smile"
|
||||
quality = MINOR_NEGATIVE
|
||||
dna_block = NON_SCANNABLE
|
||||
text_gain_indication = "<span class='notice'>You feel so happy. Nothing can be wrong with anything. :)</span>"
|
||||
text_lose_indication = "<span class='notice'>Everything is terrible again. :(</span>"
|
||||
|
||||
/datum/mutation/human/smile/say_mod(message)
|
||||
if(message)
|
||||
message = " [message] "
|
||||
//Time for a friendly game of SS13
|
||||
message = replacetext(message," stupid "," smart ")
|
||||
message = replacetext(message," retard "," genius ")
|
||||
message = replacetext(message," unrobust "," robust ")
|
||||
message = replacetext(message," dumb "," smart ")
|
||||
message = replacetext(message," awful "," great ")
|
||||
message = replacetext(message," gay ",pick(" nice "," ok "," alright "))
|
||||
message = replacetext(message," horrible "," fun ")
|
||||
message = replacetext(message," terrible "," terribly fun ")
|
||||
message = replacetext(message," terrifying "," wonderful ")
|
||||
message = replacetext(message," gross "," cool ")
|
||||
message = replacetext(message," disgusting "," amazing ")
|
||||
message = replacetext(message," loser "," winner ")
|
||||
message = replacetext(message," useless "," useful ")
|
||||
message = replacetext(message," oh god "," cheese and crackers ")
|
||||
message = replacetext(message," jesus "," gee wiz ")
|
||||
message = replacetext(message," weak "," strong ")
|
||||
message = replacetext(message," kill "," hug ")
|
||||
message = replacetext(message," murder "," tease ")
|
||||
message = replacetext(message," ugly "," beautiful ")
|
||||
message = replacetext(message," douchbag "," nice guy ")
|
||||
message = replacetext(message," whore "," lady ")
|
||||
message = replacetext(message," nerd "," smart guy ")
|
||||
message = replacetext(message," moron "," fun person ")
|
||||
message = replacetext(message," IT'S LOOSE "," EVERYTHING IS FINE ")
|
||||
message = replacetext(message," sex "," hug fight ")
|
||||
message = replacetext(message," idiot "," genius ")
|
||||
message = replacetext(message," fat "," thin ")
|
||||
message = replacetext(message," beer "," water with ice ")
|
||||
message = replacetext(message," drink "," water ")
|
||||
message = replacetext(message," feminist "," empowered woman ")
|
||||
message = replacetext(message," i hate you "," you're mean ")
|
||||
message = replacetext(message," nigger "," african american ")
|
||||
message = replacetext(message," jew "," jewish ")
|
||||
message = replacetext(message," shit "," shiz ")
|
||||
message = replacetext(message," crap "," poo ")
|
||||
message = replacetext(message," slut "," tease ")
|
||||
message = replacetext(message," ass "," butt ")
|
||||
message = replacetext(message," damn "," dang ")
|
||||
message = replacetext(message," fuck "," ")
|
||||
message = replacetext(message," penis "," privates ")
|
||||
message = replacetext(message," cunt "," privates ")
|
||||
message = replacetext(message," dick "," jerk ")
|
||||
message = replacetext(message," vagina "," privates ")
|
||||
return trim(message)
|
||||
|
||||
|
||||
/datum/mutation/human/unintelligable
|
||||
name = "Unintelligable"
|
||||
quality = NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You can't seem to form any coherent thoughts!</span>"
|
||||
text_lose_indication = "<span class='danger'>Your mind feels more clear.</span>"
|
||||
|
||||
/datum/mutation/human/unintelligable/say_mod(message)
|
||||
if(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
|
||||
message = "[prefix][uppertext(jointext(rearranged," "))]!!"
|
||||
return message
|
||||
|
||||
|
||||
/datum/mutation/human/swedish
|
||||
name = "Swedish"
|
||||
quality = MINOR_NEGATIVE
|
||||
dna_block = NON_SCANNABLE
|
||||
text_gain_indication = "<span class='notice'>You feel Swedish, however that works.</span>"
|
||||
text_lose_indication = "<span class='notice'>The feeling of Swedishness passes.</span>"
|
||||
|
||||
/datum/mutation/human/swedish/say_mod(message)
|
||||
if(message)
|
||||
message = replacetext(message,"w","v")
|
||||
message = replacetext(message,"j","y")
|
||||
message = replacetext(message,"a",pick("�","�","�","a"))
|
||||
message = replacetext(message,"bo","bjo")
|
||||
message = replacetext(message,"o",pick("�","�","o"))
|
||||
if(prob(30))
|
||||
message += " Bork[pick("",", bork",", bork, bork")]!"
|
||||
return message
|
||||
|
||||
|
||||
/datum/mutation/human/chav
|
||||
name = "Chav"
|
||||
quality = MINOR_NEGATIVE
|
||||
dna_block = NON_SCANNABLE
|
||||
text_gain_indication = "<span class='notice'>Ye feel like a reet prat like, innit?</span>"
|
||||
text_lose_indication = "<span class='notice'>You no longer feel like being rude and sassy.</span>"
|
||||
|
||||
/datum/mutation/human/chav/say_mod(message)
|
||||
if(message)
|
||||
message = " [message] "
|
||||
message = replacetext(message," looking at "," gawpin' at ")
|
||||
message = replacetext(message," great "," bangin' ")
|
||||
message = replacetext(message," man "," mate ")
|
||||
message = replacetext(message," friend ",pick(" mate "," bruv "," bledrin "))
|
||||
message = replacetext(message," what "," wot ")
|
||||
message = replacetext(message," drink "," wet ")
|
||||
message = replacetext(message," get "," giz ")
|
||||
message = replacetext(message," what "," wot ")
|
||||
message = replacetext(message," no thanks "," wuddent fukken do one ")
|
||||
message = replacetext(message," i don't know "," wot mate ")
|
||||
message = replacetext(message," no "," naw ")
|
||||
message = replacetext(message," robust "," chin ")
|
||||
message = replacetext(message," hi "," how what how ")
|
||||
message = replacetext(message," hello "," sup bruv ")
|
||||
message = replacetext(message," kill "," bang ")
|
||||
message = replacetext(message," murder "," bang ")
|
||||
message = replacetext(message," windows "," windies ")
|
||||
message = replacetext(message," window "," windy ")
|
||||
message = replacetext(message," break "," do ")
|
||||
message = replacetext(message," your "," yer ")
|
||||
message = replacetext(message," security "," coppers ")
|
||||
return trim(message)
|
||||
|
||||
|
||||
/datum/mutation/human/elvis
|
||||
name = "Elvis"
|
||||
quality = MINOR_NEGATIVE
|
||||
dna_block = NON_SCANNABLE
|
||||
text_gain_indication = "<span class='notice'>You feel pretty good, honeydoll.</span>"
|
||||
text_lose_indication = "<span class='notice'>You feel a little less conversation would be great.</span>"
|
||||
|
||||
/datum/mutation/human/elvis/on_life(mob/living/carbon/human/owner)
|
||||
switch(pick(1,2))
|
||||
if(1)
|
||||
if(prob(15))
|
||||
var/list/dancetypes = list("swinging", "fancy", "stylish", "20'th century", "jivin'", "rock and roller", "cool", "salacious", "bashing", "smashing")
|
||||
var/dancemoves = pick(dancetypes)
|
||||
owner.visible_message("<b>[owner]</b> busts out some [dancemoves] moves!")
|
||||
if(2)
|
||||
if(prob(15))
|
||||
owner.visible_message("<b>[owner]</b> [pick("jiggles their hips", "rotates their hips", "gyrates their hips", "taps their foot", "dances to an imaginary song", "jiggles their legs", "snaps their fingers")]!")
|
||||
|
||||
/datum/mutation/human/elvis/say_mod(message)
|
||||
if(message)
|
||||
message = " [message] "
|
||||
message = replacetext(message," i'm not "," I aint ")
|
||||
message = replacetext(message," girl ",pick(" honey "," baby "," baby doll "))
|
||||
message = replacetext(message," man ",pick(" son "," buddy "," brother"," pal "," friendo "))
|
||||
message = replacetext(message," out of "," outta ")
|
||||
message = replacetext(message," thank you "," thank you, thank you very much ")
|
||||
message = replacetext(message," what are you "," whatcha ")
|
||||
message = replacetext(message," yes ",pick(" sure", "yea "))
|
||||
message = replacetext(message," faggot "," square ")
|
||||
message = replacetext(message," muh valids "," getting my kicks ")
|
||||
return trim(message)
|
||||
|
||||
|
||||
/datum/mutation/human/stoner
|
||||
name = "Stoner"
|
||||
quality = NEGATIVE
|
||||
dna_block = NON_SCANNABLE
|
||||
text_gain_indication = "<span class='notice'>You feel...totally chill, man!</span>"
|
||||
text_lose_indication = "<span class='notice'>You feel like you have a better sense of time.</span>"
|
||||
|
||||
/datum/mutation/human/stoner/on_acquiring(mob/living/carbon/human/owner)
|
||||
..()
|
||||
owner.grant_language(/datum/language/beachbum)
|
||||
owner.remove_language(/datum/language/common)
|
||||
|
||||
/datum/mutation/human/stoner/on_losing(mob/living/carbon/human/owner)
|
||||
..()
|
||||
owner.grant_language(/datum/language/common)
|
||||
owner.remove_language(/datum/language/beachbum)
|
||||
@@ -0,0 +1,18 @@
|
||||
//Telekinesis lets you interact with objects from range, and gives you a light blue halo around your head.
|
||||
/datum/mutation/human/telekinesis
|
||||
name = "Telekinesis"
|
||||
quality = POSITIVE
|
||||
get_chance = 20
|
||||
lowest_value = 256 * 12
|
||||
text_gain_indication = "<span class='notice'>You feel smarter!</span>"
|
||||
limb_req = "head"
|
||||
|
||||
/datum/mutation/human/telekinesis/New()
|
||||
..()
|
||||
visual_indicators |= mutable_appearance('icons/effects/genetics.dmi', "telekinesishead", -MUTATIONS_LAYER)
|
||||
|
||||
/datum/mutation/human/telekinesis/get_visual_indicator(mob/living/carbon/human/owner)
|
||||
return visual_indicators[1]
|
||||
|
||||
/datum/mutation/human/telekinesis/on_ranged_attack(mob/living/carbon/human/owner, atom/target)
|
||||
target.attack_tk(owner)
|
||||
@@ -0,0 +1,112 @@
|
||||
/datum/saymode
|
||||
var/key
|
||||
var/mode
|
||||
|
||||
//Return FALSE if you have handled the message. Otherwise, return TRUE and saycode will continue doing saycode things.
|
||||
//user = whoever said the message
|
||||
//message = the message
|
||||
//language = the language.
|
||||
/datum/saymode/proc/handle_message(mob/living/user, message, datum/language/language)
|
||||
return TRUE
|
||||
|
||||
|
||||
/datum/saymode/changeling
|
||||
key = "g"
|
||||
mode = MODE_CHANGELING
|
||||
|
||||
/datum/saymode/changeling/handle_message(mob/living/user, message, datum/language/language)
|
||||
switch(user.lingcheck())
|
||||
if(LINGHIVE_LINK)
|
||||
var/msg = "<i><font color=#800040><b>[user.mind]:</b> [message]</font></i>"
|
||||
for(var/_M in GLOB.mob_list)
|
||||
var/mob/M = _M
|
||||
if(M in GLOB.dead_mob_list)
|
||||
var/link = FOLLOW_LINK(M, user)
|
||||
to_chat(M, "[link] [msg]")
|
||||
else
|
||||
switch(M.lingcheck())
|
||||
if(LINGHIVE_LINK, LINGHIVE_LING)
|
||||
to_chat(M, msg)
|
||||
if(LINGHIVE_OUTSIDER)
|
||||
if(prob(40))
|
||||
to_chat(M, "<i><font color=#800080>We can faintly sense an outsider trying to communicate through the hivemind...</font></i>")
|
||||
if(LINGHIVE_LING)
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
var/msg = "<i><font color=#800080><b>[changeling.changelingID]:</b> [message]</font></i>"
|
||||
log_talk(src,"[changeling.changelingID]/[user.key] : [message]",LOGSAY)
|
||||
for(var/_M in GLOB.mob_list)
|
||||
var/mob/M = _M
|
||||
if(M in GLOB.dead_mob_list)
|
||||
var/link = FOLLOW_LINK(M, user)
|
||||
to_chat(M, "[link] [msg]")
|
||||
else
|
||||
switch(M.lingcheck())
|
||||
if(LINGHIVE_LINK)
|
||||
to_chat(M, msg)
|
||||
if(LINGHIVE_LING)
|
||||
to_chat(M, msg)
|
||||
if(LINGHIVE_OUTSIDER)
|
||||
if(prob(40))
|
||||
to_chat(M, "<i><font color=#800080>We can faintly sense another of our kind trying to communicate through the hivemind...</font></i>")
|
||||
if(LINGHIVE_OUTSIDER)
|
||||
to_chat(user, "<i><font color=#800080>Our senses have not evolved enough to be able to communicate this way...</font></i>")
|
||||
return FALSE
|
||||
|
||||
|
||||
/datum/saymode/xeno
|
||||
key = "a"
|
||||
mode = MODE_ALIEN
|
||||
|
||||
/datum/saymode/xeno/handle_message(mob/living/user, message, datum/language/language)
|
||||
if(user.hivecheck())
|
||||
user.alien_talk(message)
|
||||
return FALSE
|
||||
|
||||
|
||||
/datum/saymode/vocalcords
|
||||
key = "x"
|
||||
mode = MODE_VOCALCORDS
|
||||
|
||||
/datum/saymode/vocalcords/handle_message(mob/living/user, message, datum/language/language)
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
var/obj/item/organ/vocal_cords/V = C.getorganslot(ORGAN_SLOT_VOICE)
|
||||
if(V && V.can_speak_with())
|
||||
V.handle_speech(message) //message
|
||||
V.speak_with(message) //action
|
||||
return FALSE
|
||||
|
||||
|
||||
/datum/saymode/binary //everything that uses .b (silicons, drones, blobbernauts/spores, swarmers)
|
||||
key = "b"
|
||||
mode = MODE_BINARY
|
||||
|
||||
/datum/saymode/binary/handle_message(mob/living/user, message, datum/language/language)
|
||||
if(isswarmer(user))
|
||||
var/mob/living/simple_animal/hostile/swarmer/S = user
|
||||
S.swarmer_chat(message)
|
||||
return FALSE
|
||||
if(isblobmonster(user))
|
||||
var/mob/living/simple_animal/hostile/blob/B = user
|
||||
B.blob_chat(message)
|
||||
return FALSE
|
||||
if(isdrone(user))
|
||||
var/mob/living/simple_animal/drone/D = user
|
||||
D.drone_chat(message)
|
||||
return FALSE
|
||||
if(user.binarycheck())
|
||||
user.robot_talk(message)
|
||||
return FALSE
|
||||
return FALSE
|
||||
|
||||
|
||||
/datum/saymode/holopad
|
||||
key = "h"
|
||||
mode = MODE_HOLOPAD
|
||||
|
||||
/datum/saymode/holopad/handle_message(mob/living/user, message, datum/language/language)
|
||||
if(isAI(user))
|
||||
var/mob/living/silicon/ai/AI = user
|
||||
AI.holopad_talk(message, language)
|
||||
return FALSE
|
||||
return FALSE
|
||||
@@ -23,12 +23,12 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
|
||||
if(!istype(I))
|
||||
continue
|
||||
if(I.include_modes.len)
|
||||
if(!gamemode && SSticker && !(SSticker.mode.type in I.include_modes))
|
||||
if(!gamemode && SSticker && SSticker.mode && !(SSticker.mode.type in I.include_modes))
|
||||
continue
|
||||
if(gamemode && !(gamemode in I.include_modes))
|
||||
continue
|
||||
if(I.exclude_modes.len)
|
||||
if(!gamemode && SSticker && (SSticker.mode.type in I.exclude_modes))
|
||||
if(!gamemode && SSticker && SSticker.mode && (SSticker.mode.type in I.exclude_modes))
|
||||
continue
|
||||
if(gamemode && (gamemode in I.exclude_modes))
|
||||
continue
|
||||
@@ -91,6 +91,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
|
||||
|
||||
/datum/uplink_item/proc/spawn_item(turf/loc, datum/component/uplink/U, mob/user)
|
||||
if(item)
|
||||
SSblackbox.record_feedback("nested tally", "traitor_uplink_items_bought", 1, list("[initial(name)]", "[cost]"))
|
||||
return new item(loc)
|
||||
|
||||
/datum/uplink_item/Destroy()
|
||||
@@ -1168,7 +1169,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
|
||||
/datum/uplink_item/cyber_implants/spawn_item(turf/loc, obj/item/device/uplink/U)
|
||||
if(item)
|
||||
if(istype(item, /obj/item/organ))
|
||||
SSblackbox.add_details("traitor_uplink_items_bought", "[item]|[cost]")
|
||||
SSblackbox.record_feedback("nested tally", "traitor_uplink_items_bought", 1, list("[initial(name)]", "[cost]"))
|
||||
return new /obj/item/storage/box/cyber_implants(loc, item)
|
||||
else
|
||||
return ..()
|
||||
@@ -1349,7 +1350,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
|
||||
cant_discount = TRUE
|
||||
|
||||
/datum/uplink_item/badass/surplus/spawn_item(turf/loc, datum/component/uplink/U)
|
||||
var/list/uplink_items = get_uplink_items(SSticker.mode)
|
||||
var/list/uplink_items = get_uplink_items(SSticker && SSticker.mode? SSticker.mode : null)
|
||||
|
||||
var/crate_value = 50
|
||||
var/obj/structure/closet/crate/C = new(loc)
|
||||
@@ -1366,7 +1367,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
|
||||
var/obj/goods = new I.item(C)
|
||||
U.purchase_log.LogPurchase(goods, I.cost)
|
||||
|
||||
SSblackbox.add_details("traitor_uplink_items_bought", "[name]|[cost]")
|
||||
SSblackbox.record_feedback("nested tally", "traitor_uplink_items_bought", 1, list("[initial(name)]", "[cost]"))
|
||||
return C
|
||||
|
||||
/datum/uplink_item/badass/random
|
||||
@@ -1377,7 +1378,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
|
||||
cant_discount = TRUE
|
||||
|
||||
/datum/uplink_item/badass/random/spawn_item(turf/loc, datum/component/uplink/U)
|
||||
var/list/uplink_items = get_uplink_items(SSticker.mode)
|
||||
var/list/uplink_items = get_uplink_items(SSticker && SSticker.mode? SSticker.mode : null)
|
||||
var/list/possible_items = list()
|
||||
for(var/category in uplink_items)
|
||||
for(var/item in uplink_items[category])
|
||||
@@ -1392,6 +1393,6 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
|
||||
var/datum/uplink_item/I = pick(possible_items)
|
||||
U.telecrystals -= I.cost
|
||||
U.spent_telecrystals += I.cost
|
||||
SSblackbox.add_details("traitor_uplink_items_bought","[name]|[I.cost]")
|
||||
SSblackbox.add_details("traitor_random_uplink_items_gotten","[I.name]")
|
||||
SSblackbox.record_feedback("nested tally", "traitor_uplink_items_bought", 1, list("[initial(I.name)]", "[cost]"))
|
||||
SSblackbox.record_feedback("tally", "traitor_random_uplink_items_gotten", 1, initial(I.name))
|
||||
return new I.item(loc)
|
||||
|
||||
@@ -20,10 +20,11 @@
|
||||
|
||||
overlay_layer = ABOVE_OPEN_TURF_LAYER //Covers floors only
|
||||
immunity_type = "lava"
|
||||
|
||||
|
||||
/datum/weather/floor_is_lava/weather_act(mob/living/L)
|
||||
for(var/obj/structure/O in L.loc)
|
||||
if(O.density)
|
||||
for(var/obj/structure/O in L.loc)
|
||||
if(O.density || (L in O.buckled_mobs && istype(O, /obj/structure/bed)))
|
||||
return
|
||||
if(L.loc.density)
|
||||
return
|
||||
|
||||
@@ -42,4 +42,7 @@
|
||||
if(WIRE_LIMIT)
|
||||
C.strength_upper_limit = (mend ? 2 : 3)
|
||||
if(C.strength_upper_limit < C.strength)
|
||||
C.remove_strength()
|
||||
C.remove_strength()
|
||||
|
||||
/datum/wires/particle_accelerator/control_box/emp_pulse() // to prevent singulo from pulsing wires
|
||||
return
|
||||
@@ -30,10 +30,6 @@ GLOBAL_LIST_EMPTY(active_alternate_appearances)
|
||||
appearance_key = key
|
||||
|
||||
/datum/atom_hud/alternate_appearance/Destroy()
|
||||
for(var/v in hudusers)
|
||||
remove_hud_from(v)
|
||||
for(var/v in hudatoms)
|
||||
remove_from_hud(v)
|
||||
GLOB.active_alternate_appearances -= src
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -1486,36 +1486,3 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/tcommsat/lounge
|
||||
name = "Telecommunications Satellite Lounge"
|
||||
icon_state = "tcomsatlounge"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
Lists of areas to be used with is_type_in_list.
|
||||
Used in gamemodes code at the moment. --rastaf0
|
||||
*/
|
||||
|
||||
//SPACE STATION 13
|
||||
GLOBAL_LIST_INIT(the_station_areas, list (
|
||||
/area/bridge,
|
||||
/area/chapel,
|
||||
/area/construction,
|
||||
/area/crew_quarters,
|
||||
/area/engine,
|
||||
/area/hallway,
|
||||
/area/holodeck,
|
||||
/area/hydroponics,
|
||||
/area/janitor,
|
||||
/area/lawoffice,
|
||||
/area/library,
|
||||
/area/maintenance,
|
||||
/area/medical,
|
||||
/area/quartermaster,
|
||||
/area/science,
|
||||
/area/security,
|
||||
/area/solar,
|
||||
/area/storage,
|
||||
/area/teleporter,
|
||||
/area/ai_monitored/storage/eva, //do not try to simplify to "/area/ai_monitored" --rastaf0
|
||||
/area/ai_monitored/turret_protected/ai_upload, //do not try to simplify to "/area/ai_monitored/turret_protected" --rastaf0
|
||||
/area/ai_monitored/turret_protected/ai_upload_foyer,
|
||||
/area/ai_monitored/turret_protected/ai,
|
||||
))
|
||||
+1
-17
@@ -421,22 +421,6 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
|
||||
/atom/proc/wash_cream()
|
||||
return 1
|
||||
|
||||
/atom/proc/get_global_map_pos()
|
||||
if(!islist(GLOB.global_map) || isemptylist(GLOB.global_map))
|
||||
return
|
||||
var/cur_x = null
|
||||
var/cur_y = null
|
||||
var/list/y_arr = null
|
||||
for(cur_x=1,cur_x<=GLOB.global_map.len,cur_x++)
|
||||
y_arr = GLOB.global_map[cur_x]
|
||||
cur_y = y_arr.Find(src.z)
|
||||
if(cur_y)
|
||||
break
|
||||
if(cur_x && cur_y)
|
||||
return list("x"=cur_x,"y"=cur_y)
|
||||
else
|
||||
return 0
|
||||
|
||||
/atom/proc/isinspace()
|
||||
if(isspaceturf(get_turf(src)))
|
||||
return 1
|
||||
@@ -634,4 +618,4 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
|
||||
return
|
||||
|
||||
/atom/proc/wirecutter_act(mob/user, obj/item/tool)
|
||||
return
|
||||
return
|
||||
|
||||
@@ -50,8 +50,16 @@
|
||||
hud_icons = list(ID_HUD, IMPTRACK_HUD, IMPLOYAL_HUD, IMPCHEM_HUD, WANTED_HUD)
|
||||
|
||||
/datum/atom_hud/data/diagnostic
|
||||
|
||||
/datum/atom_hud/data/diagnostic/basic
|
||||
hud_icons = list (DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_TRACK_HUD, DIAG_AIRLOCK_HUD)
|
||||
|
||||
/datum/atom_hud/data/diagnostic/advanced
|
||||
hud_icons = list (DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_TRACK_HUD, DIAG_AIRLOCK_HUD, DIAG_PATH_HUD)
|
||||
|
||||
/datum/atom_hud/data/bot_path
|
||||
hud_icons = list(DIAG_PATH_HUD)
|
||||
|
||||
/* MED/SEC/DIAG HUD HOOKS */
|
||||
|
||||
/*
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
return
|
||||
used = TRUE
|
||||
var/mob/dead/observer/theghost = pick(nuke_candidates)
|
||||
spawn_antag(theghost.client, get_turf(src), "syndieborg")
|
||||
spawn_antag(theghost.client, get_turf(src), "syndieborg", user)
|
||||
do_sparks(4, TRUE, src)
|
||||
qdel(src)
|
||||
else
|
||||
|
||||
@@ -56,13 +56,6 @@
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/blob/handle_inherent_channels(message, message_mode)
|
||||
if(message_mode == MODE_BINARY)
|
||||
blob_chat(message)
|
||||
return 1
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/blob/proc/blob_chat(msg)
|
||||
var/spanned_message = say_quote(msg, get_spans())
|
||||
var/rendered = "<font color=\"#EE4000\"><b>\[Blob Telepathy\] [real_name]</b> [spanned_message]</font>"
|
||||
@@ -100,7 +93,7 @@
|
||||
var/death_cloud_size = 1 //size of cloud produced from a dying spore
|
||||
var/mob/living/carbon/human/oldguy
|
||||
var/is_zombie = 0
|
||||
gold_core_spawnable = 1
|
||||
gold_core_spawnable = HOSTILE_SPAWN
|
||||
|
||||
/mob/living/simple_animal/hostile/blob/blobspore/Initialize(mapload, var/obj/structure/blob/factory/linked_node)
|
||||
if(istype(linked_node))
|
||||
@@ -299,4 +292,4 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/blob/blobbernaut/independent
|
||||
independent = TRUE
|
||||
gold_core_spawnable = 1
|
||||
gold_core_spawnable = HOSTILE_SPAWN
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
GLOB.poi_list |= src
|
||||
update_icon() //so it atleast appears
|
||||
if(!placed && !overmind)
|
||||
qdel(src)
|
||||
return INITIALIZE_HINT_QDEL
|
||||
if(overmind)
|
||||
update_icon()
|
||||
point_rate = new_rate
|
||||
|
||||
@@ -114,19 +114,19 @@
|
||||
for(var/datum/objective/objective in team.objectives)
|
||||
if(objective.check_completion())
|
||||
text += "<br><B>Objective #[objective_count]</B>: [objective.explanation_text] <font color='green'><B>Success!</B></font> [istype(objective, /datum/objective/crew) ? "<font color='grey'>(Optional)</font>" : ""]"
|
||||
SSblackbox.add_details("traitor_objective","[objective.type]|SUCCESS")
|
||||
SSblackbox.record_feedback("nested tally", "traitor_objective", 1, list("[objective.type]", "SUCCESS"))
|
||||
else
|
||||
text += "<br><B>Objective #[objective_count]</B>: [objective.explanation_text] <font color='red'>Fail.</font> [istype(objective, /datum/objective/crew) ? "<font color='grey'>(Optional)</font>" : ""]"
|
||||
SSblackbox.add_details("traitor_objective","[objective.type]|FAIL")
|
||||
SSblackbox.record_feedback("nested tally", "traitor_objective", 1, list("[objective.type]", "FAIL"))
|
||||
if(!(istype(objective, /datum/objective/crew)))
|
||||
win = FALSE
|
||||
objective_count++
|
||||
if(win)
|
||||
text += "<br><font color='green'><B>The blood brothers were successful!</B></font>"
|
||||
SSblackbox.add_details("brother_success","SUCCESS")
|
||||
SSblackbox.record_feedback("tally", "brother_success", 1, "SUCCESS")
|
||||
else
|
||||
text += "<br><font color='red'><B>The blood brothers have failed!</B></font>"
|
||||
SSblackbox.add_details("brother_success","FAIL")
|
||||
SSblackbox.record_feedback("tally", "brother_success", 1, "FAIL")
|
||||
text += "<br>"
|
||||
to_chat(world, text)
|
||||
|
||||
|
||||
@@ -115,20 +115,20 @@ GLOBAL_VAR(changeling_team_objective_type) //If this is not null, we hand our th
|
||||
for(var/datum/objective/objective in changeling.objectives)
|
||||
if(objective.check_completion())
|
||||
text += "<br><b>Objective #[count]</b>: [objective.explanation_text] <font color='green'><b>Success!</b></font> [istype(objective, /datum/objective/crew) ? "<font color='grey'>(Optional)</font>" : ""]"
|
||||
SSblackbox.add_details("changeling_objective","[objective.type]|SUCCESS")
|
||||
SSblackbox.record_feedback("nested tally", "changeling_objective", 1, list("[objective.type]", "SUCCESS"))
|
||||
else
|
||||
text += "<br><b>Objective #[count]</b>: [objective.explanation_text] <span class='danger'>Fail.</span> [istype(objective, /datum/objective/crew) ? "<font color='grey'>(Optional)</font>" : ""]"
|
||||
SSblackbox.add_details("changeling_objective","[objective.type]|FAIL")
|
||||
SSblackbox.record_feedback("nested tally", "changeling_objective", 1, list("[objective.type]", "FAIL"))
|
||||
if(!(istype(objective, /datum/objective/crew)))
|
||||
changelingwin = 0
|
||||
count++
|
||||
|
||||
if(changelingwin)
|
||||
text += "<br><font color='green'><b>The changeling was successful!</b></font>"
|
||||
SSblackbox.add_details("changeling_success","SUCCESS")
|
||||
SSblackbox.record_feedback("tally", "changeling_success", 1, "SUCCESS")
|
||||
else
|
||||
text += "<br><span class='boldannounce'>The changeling has failed.</span>"
|
||||
SSblackbox.add_details("changeling_success","FAIL")
|
||||
SSblackbox.record_feedback("tally", "changeling_success", 1, "FAIL")
|
||||
text += "<br>"
|
||||
|
||||
to_chat(world, text)
|
||||
@@ -174,4 +174,4 @@ GLOBAL_VAR(changeling_team_objective_type) //If this is not null, we hand our th
|
||||
if(equip)
|
||||
user.equip_to_slot_or_del(C, GLOB.slot2slot[slot])
|
||||
|
||||
user.regenerate_icons()
|
||||
user.regenerate_icons()
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
/obj/effect/proc_holder/changeling/proc/on_purchase(mob/user, is_respec)
|
||||
if(!is_respec)
|
||||
SSblackbox.add_details("changeling_power_purchase",name)
|
||||
SSblackbox.record_feedback("tally", "changeling_power_purchase", 1, name)
|
||||
|
||||
/obj/effect/proc_holder/changeling/proc/on_refund(mob/user)
|
||||
return
|
||||
@@ -35,7 +35,7 @@
|
||||
return
|
||||
var/datum/antagonist/changeling/c = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(sting_action(user, target))
|
||||
SSblackbox.add_details("changeling_powers",name)
|
||||
SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("[name]"))
|
||||
sting_feedback(user, target)
|
||||
c.chem_charges -= chemical_cost
|
||||
|
||||
|
||||
@@ -41,13 +41,13 @@
|
||||
to_chat(target, "<span class='userdanger'>You feel a sharp stabbing pain!</span>")
|
||||
target.take_overall_damage(40)
|
||||
|
||||
SSblackbox.add_details("changeling_powers","Absorb DNA|[i]")
|
||||
SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("Absorb DNA", "[i]"))
|
||||
if(!do_mob(user, target, 150))
|
||||
to_chat(user, "<span class='warning'>Our absorption of [target] has been interrupted!</span>")
|
||||
changeling.isabsorbing = 0
|
||||
return
|
||||
|
||||
SSblackbox.add_details("changeling_powers","Absorb DNA|4")
|
||||
SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("Absorb DNA", "4"))
|
||||
user.visible_message("<span class='danger'>[user] sucks the fluids from [target]!</span>", "<span class='notice'>We have absorbed [target].</span>")
|
||||
to_chat(target, "<span class='userdanger'>You are absorbed by the changeling!</span>")
|
||||
|
||||
|
||||
@@ -50,14 +50,14 @@
|
||||
to_chat(target, "<span class='userdanger'>A migraine throbs behind your eyes, you hear yourself screaming - but your mouth has not opened!</span>")
|
||||
for(var/mi in GLOB.mob_list)
|
||||
var/mob/M = mi
|
||||
if(M.lingcheck() == 2)
|
||||
if(M.lingcheck() == LINGHIVE_LING)
|
||||
to_chat(M, "<i><font color=#800080>We can sense a foreign presence in the hivemind...</font></i>")
|
||||
target.mind.linglink = 1
|
||||
target.say(":g AAAAARRRRGGGGGHHHHH!!")
|
||||
to_chat(target, "<font color=#800040><span class='boldannounce'>You can now communicate in the changeling hivemind, say \":g message\" to communicate!</span>")
|
||||
target.reagents.add_reagent("salbutamol", 40) // So they don't choke to death while you interrogate them
|
||||
sleep(1800)
|
||||
SSblackbox.add_details("changeling_powers","Hivemind Link|[i]")
|
||||
SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("[name]", "[i]"))
|
||||
if(!do_mob(user, target, 20))
|
||||
to_chat(user, "<span class='warning'>Our link with [target] has ended!</span>")
|
||||
changeling.islinking = 0
|
||||
|
||||
@@ -10,6 +10,13 @@
|
||||
light_power = 3
|
||||
light_color = "#6A4D2F"
|
||||
|
||||
|
||||
/obj/effect/clockwork/city_of_cogs_rift/singularity_act()
|
||||
return
|
||||
|
||||
/obj/effect/clockwork/city_of_cogs_rift/singularity_pull()
|
||||
return
|
||||
|
||||
/obj/effect/clockwork/city_of_cogs_rift/Initialize()
|
||||
. = ..()
|
||||
visible_message("<span class='warning'>The air above [loc] shimmers and pops as a [name] forms there!</span>")
|
||||
|
||||
@@ -10,6 +10,11 @@
|
||||
/obj/effect/clockwork/overlay/ex_act()
|
||||
return FALSE
|
||||
|
||||
/obj/effect/clockwork/overlay/singularity_act()
|
||||
return
|
||||
/obj/effect/clockwork/overlay/singularity_pull()
|
||||
return
|
||||
|
||||
/obj/effect/clockwork/overlay/singularity_pull(S, current_size)
|
||||
return
|
||||
|
||||
|
||||
@@ -11,6 +11,12 @@
|
||||
animate(src, alpha = 0, time = 10)
|
||||
QDEL_IN(src, 10)
|
||||
|
||||
/obj/effect/clockwork/general_marker/singularity_act()
|
||||
return
|
||||
|
||||
/obj/effect/clockwork/general_marker/singularity_pull()
|
||||
return
|
||||
|
||||
/obj/effect/clockwork/general_marker/inathneq
|
||||
name = "Inath-neq, the Resonant Cogwheel"
|
||||
desc = "A humanoid form blazing with blue fire. It radiates an aura of kindness and caring."
|
||||
|
||||
@@ -18,3 +18,9 @@
|
||||
to_chat(L, "<span class='danger'>The space beyond here can't be accessed by you or other servants.</span>")
|
||||
return
|
||||
return TRUE
|
||||
|
||||
/obj/effect/clockwork/servant_blocker/singularity_act()
|
||||
return
|
||||
|
||||
/obj/effect/clockwork/servant_blocker/singularity_pull()
|
||||
return
|
||||
|
||||
@@ -109,6 +109,14 @@
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
/obj/effect/clockwork/spatial_gateway/singularity_act()
|
||||
return
|
||||
|
||||
/obj/effect/clockwork/spatial_gateway/singularity_pull()
|
||||
return
|
||||
|
||||
|
||||
/obj/effect/clockwork/spatial_gateway/CollidedWith(atom/movable/AM)
|
||||
..()
|
||||
if(!QDELETED(AM))
|
||||
|
||||
@@ -162,6 +162,12 @@
|
||||
user = caster
|
||||
INVOKE_ASYNC(src, .proc/judicialblast)
|
||||
|
||||
/obj/effect/clockwork/judicial_marker/singularity_act()
|
||||
return
|
||||
|
||||
/obj/effect/clockwork/judicial_marker/singularity_pull()
|
||||
return
|
||||
|
||||
/obj/effect/clockwork/judicial_marker/proc/judicialblast()
|
||||
playsound(src, 'sound/magic/magic_missile.ogg', 50, 1, 1, 1)
|
||||
flick("judicial_marker", src)
|
||||
|
||||
@@ -66,7 +66,7 @@ Applications: 8 servants, 3 caches, and 100 CV
|
||||
else
|
||||
successful = TRUE
|
||||
if(slab && !slab.no_cost && !GLOB.ratvar_awakens) //if the slab exists and isn't debug and ratvar isn't up, log the scripture as being used
|
||||
SSblackbox.add_details("clockcult_scripture_recited", name)
|
||||
SSblackbox.record_feedback("tally", "clockcult_scripture_recited", 1, name)
|
||||
if(slab)
|
||||
slab.busy = null
|
||||
post_recital()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user