Merge branch 'master' into upstream-merge-32624

This commit is contained in:
deathride58
2017-12-04 17:12:53 -05:00
511 changed files with 6808 additions and 4394 deletions
+12 -8
View File
@@ -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
View File
@@ -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"
+7
View File
@@ -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)
+2
View File
@@ -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
+5
View File
@@ -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))
+5
View File
@@ -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
+1
View File
@@ -0,0 +1 @@
#define HID_RESTRICTED_END 101 //the first nonrestricted ID, automatically assigned on connection creation.
+6 -1
View File
@@ -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)
+7 -1
View File
@@ -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
+5 -4
View File
@@ -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;\
}
}
+3 -1
View File
@@ -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)
+1 -1
View File
@@ -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
+21
View File
@@ -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)
+3 -3
View File
@@ -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
+1
View File
@@ -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)
+1
View File
@@ -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)
+3 -1
View File
@@ -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))
+3 -3
View File
@@ -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
View File
@@ -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

+2 -2
View File
@@ -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
+164 -166
View File
@@ -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(" | "))
+8 -1
View File
@@ -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]")
+25 -18
View File
@@ -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
+14
View File
@@ -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()
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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)
+7
View File
@@ -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)
+29 -5
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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()]"))
+3
View File
@@ -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)
-113
View File
@@ -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
+2 -2
View File
@@ -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
+3 -1
View File
@@ -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)
+4 -4
View File
@@ -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
View File
@@ -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)
+2 -1
View File
@@ -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()`
+21 -11
View File
@@ -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
+19 -20
View File
@@ -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)
+1 -1
View File
@@ -10,4 +10,4 @@
if(istype(victim))
for(var/datum/disease/D in diseases)
victim.ContactContractDisease(D, "feet")
return TRUE
return COMPONENT_ACTIVATED
+3 -3
View File
@@ -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())
+59
View File
@@ -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
+2 -2
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+20 -3
View File
@@ -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
+23 -1
View File
@@ -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
+15 -4
View File
@@ -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 ..()
+6 -3
View File
@@ -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()
-9
View File
@@ -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)
+332 -197
View File
@@ -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
+1
View File
@@ -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()
..()
+2
View File
@@ -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()
..()
+2
View File
@@ -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()
+1
View File
@@ -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()
..()
+2 -1
View File
@@ -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)
+1 -1
View File
@@ -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)
+3
View File
@@ -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()
+128
View File
@@ -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
View File
@@ -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
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-537
View File
@@ -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
+148
View File
@@ -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)
+30
View File
@@ -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
+20
View File
@@ -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?
+36
View File
@@ -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
+74
View File
@@ -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)
+231
View File
@@ -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)
+18
View File
@@ -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)
+112
View File
@@ -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
+9 -8
View File
@@ -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
+4 -1
View File
@@ -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
-4
View File
@@ -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 ..()
-33
View File
@@ -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
View File
@@ -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
+8
View File
@@ -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 */
/*
+1 -1
View File
@@ -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
+2 -9
View File
@@ -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
+1 -1
View File
@@ -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
+4 -4
View File
@@ -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)
+5 -5
View File
@@ -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