Merge branch 'master' into screenshake

This commit is contained in:
deathride58
2017-09-20 00:08:25 +00:00
committed by GitHub
880 changed files with 34006 additions and 26076 deletions
+148 -74
View File
@@ -1,74 +1,148 @@
//A set of constants used to determine which type of mute an admin wishes to apply:
//Please read and understand the muting/automuting stuff before changing these. MUTE_IC_AUTO etc = (MUTE_IC << 1)
//Therefore there needs to be a gap between the flags_1 for the automute flags_1
#define MUTE_IC 1
#define MUTE_OOC 2
#define MUTE_PRAY 4
#define MUTE_ADMINHELP 8
#define MUTE_DEADCHAT 16
#define MUTE_ALL 31
//Some constants for DB_Ban
#define BANTYPE_PERMA 1
#define BANTYPE_TEMP 2
#define BANTYPE_JOB_PERMA 3
#define BANTYPE_JOB_TEMP 4
#define BANTYPE_ANY_FULLBAN 5 //used to locate stuff to unban.
#define BANTYPE_ADMIN_PERMA 7
#define BANTYPE_ADMIN_TEMP 8
#define BANTYPE_ANY_JOB 9 //used to remove jobbans
//Please don't edit these values without speaking to Errorage first ~Carn
//Admin Permissions
#define R_BUILDMODE 1
#define R_ADMIN 2
#define R_BAN 4
#define R_FUN 8
#define R_SERVER 16
#define R_DEBUG 32
#define R_POSSESS 64
#define R_PERMISSIONS 128
#define R_STEALTH 256
#define R_POLL 512
#define R_VAREDIT 1024
#define R_SOUNDS 2048
#define R_SPAWN 4096
#if DM_VERSION > 512
#error Remove the flag below , its been long enough
#endif
//legacy , remove post 512, it was replaced by R_POLL
#define R_REJUVINATE 2
#define R_MAXPERMISSION 4096 //This holds the maximum value for a permission. It is used in iteration, so keep it updated.
#define ADMIN_QUE(user) "(<a href='?_src_=holder;adminmoreinfo=\ref[user]'>?</a>)"
#define ADMIN_FLW(user) "(<a href='?_src_=holder;adminplayerobservefollow=\ref[user]'>FLW</a>)"
#define ADMIN_PP(user) "(<a href='?_src_=holder;adminplayeropts=\ref[user]'>PP</a>)"
#define ADMIN_VV(atom) "(<a href='?_src_=vars;Vars=\ref[atom]'>VV</a>)"
#define ADMIN_SM(user) "(<a href='?_src_=holder;subtlemessage=\ref[user]'>SM</a>)"
#define ADMIN_TP(user) "(<a href='?_src_=holder;traitor=\ref[user]'>TP</a>)"
#define ADMIN_KICK(user) "(<a href='?_src_=holder;boot2=\ref[user]'>KICK</a>)"
#define ADMIN_CENTCOM_REPLY(user) "(<a href='?_src_=holder;CentComReply=\ref[user]'>RPLY</a>)"
#define ADMIN_SYNDICATE_REPLY(user) "(<a href='?_src_=holder;SyndicateReply=\ref[user]'>RPLY</a>)"
#define ADMIN_SC(user) "(<a href='?_src_=holder;adminspawncookie=\ref[user]'>SC</a>)"
#define ADMIN_SMITE(user) "(<a href='?_src_=holder;adminsmite=\ref[user]'>SMITE</a>)"
#define ADMIN_LOOKUP(user) "[key_name_admin(user)][ADMIN_QUE(user)]"
#define ADMIN_LOOKUPFLW(user) "[key_name_admin(user)][ADMIN_QUE(user)] [ADMIN_FLW(user)]"
#define ADMIN_SET_SD_CODE "(<a href='?_src_=holder;set_selfdestruct_code=1'>SETCODE</a>)"
#define ADMIN_FULLMONTY_NONAME(user) "[ADMIN_QUE(user)] [ADMIN_PP(user)] [ADMIN_VV(user)] [ADMIN_SM(user)] [ADMIN_FLW(user)] [ADMIN_TP(user)] [ADMIN_INDIVIDUALLOG(user)] [ADMIN_SMITE(user)]"
#define ADMIN_FULLMONTY(user) "[key_name_admin(user)] [ADMIN_FULLMONTY_NONAME(user)]"
#define ADMIN_JMP(src) "(<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[src.x];Y=[src.y];Z=[src.z]'>JMP</a>)"
#define COORD(src) "[src ? "([src.x],[src.y],[src.z])" : "nonexistent location"]"
#define ADMIN_COORDJMP(src) "[src ? "[COORD(src)] [ADMIN_JMP(src)]" : "nonexistent location"]"
#define ADMIN_INDIVIDUALLOG(user) "(<a href='?_src_=holder;individuallog=\ref[user]'>LOGS</a>)"
#define ADMIN_PUNISHMENT_LIGHTNING "Lightning bolt"
#define ADMIN_PUNISHMENT_BRAINDAMAGE "Brain damage"
#define ADMIN_PUNISHMENT_GIB "Gib"
#define ADMIN_PUNISHMENT_BSA "Bluespace Artillery Device"
#define AHELP_ACTIVE 1
#define AHELP_CLOSED 2
#define AHELP_RESOLVED 3
//A set of constants used to determine which type of mute an admin wishes to apply:
//Please read and understand the muting/automuting stuff before changing these. MUTE_IC_AUTO etc = (MUTE_IC << 1)
//Therefore there needs to be a gap between the flags_1 for the automute flags_1
#define MUTE_IC 1
#define MUTE_OOC 2
#define MUTE_PRAY 4
#define MUTE_ADMINHELP 8
#define MUTE_DEADCHAT 16
#define MUTE_ALL 31
//Some constants for DB_Ban
#define BANTYPE_PERMA 1
#define BANTYPE_TEMP 2
#define BANTYPE_JOB_PERMA 3
#define BANTYPE_JOB_TEMP 4
#define BANTYPE_ANY_FULLBAN 5 //used to locate stuff to unban.
#define BANTYPE_ADMIN_PERMA 7
#define BANTYPE_ADMIN_TEMP 8
#define BANTYPE_ANY_JOB 9 //used to remove jobbans
//Please don't edit these values without speaking to Errorage first ~Carn
//Admin Permissions
#define R_BUILDMODE 1
#define R_ADMIN 2
#define R_BAN 4
#define R_FUN 8
#define R_SERVER 16
#define R_DEBUG 32
#define R_POSSESS 64
#define R_PERMISSIONS 128
#define R_STEALTH 256
#define R_POLL 512
#define R_VAREDIT 1024
#define R_SOUNDS 2048
#define R_SPAWN 4096
#if DM_VERSION > 512
#error Remove the flag below , its been long enough
#endif
//legacy , remove post 512, it was replaced by R_POLL
#define R_REJUVINATE 2
#define R_MAXPERMISSION 4096 //This holds the maximum value for a permission. It is used in iteration, so keep it updated.
#define ADMIN_QUE(user) "(<a href='?_src_=holder;adminmoreinfo=\ref[user]'>?</a>)"
#define ADMIN_FLW(user) "(<a href='?_src_=holder;adminplayerobservefollow=\ref[user]'>FLW</a>)"
#define ADMIN_PP(user) "(<a href='?_src_=holder;adminplayeropts=\ref[user]'>PP</a>)"
#define ADMIN_VV(atom) "(<a href='?_src_=vars;Vars=\ref[atom]'>VV</a>)"
#define ADMIN_SM(user) "(<a href='?_src_=holder;subtlemessage=\ref[user]'>SM</a>)"
#define ADMIN_TP(user) "(<a href='?_src_=holder;traitor=\ref[user]'>TP</a>)"
#define ADMIN_KICK(user) "(<a href='?_src_=holder;boot2=\ref[user]'>KICK</a>)"
#define ADMIN_CENTCOM_REPLY(user) "(<a href='?_src_=holder;CentComReply=\ref[user]'>RPLY</a>)"
#define ADMIN_SYNDICATE_REPLY(user) "(<a href='?_src_=holder;SyndicateReply=\ref[user]'>RPLY</a>)"
#define ADMIN_SC(user) "(<a href='?_src_=holder;adminspawncookie=\ref[user]'>SC</a>)"
#define ADMIN_SMITE(user) "(<a href='?_src_=holder;adminsmite=\ref[user]'>SMITE</a>)"
#define ADMIN_LOOKUP(user) "[key_name_admin(user)][ADMIN_QUE(user)]"
#define ADMIN_LOOKUPFLW(user) "[key_name_admin(user)][ADMIN_QUE(user)] [ADMIN_FLW(user)]"
#define ADMIN_SET_SD_CODE "(<a href='?_src_=holder;set_selfdestruct_code=1'>SETCODE</a>)"
#define ADMIN_FULLMONTY_NONAME(user) "[ADMIN_QUE(user)] [ADMIN_PP(user)] [ADMIN_VV(user)] [ADMIN_SM(user)] [ADMIN_FLW(user)] [ADMIN_TP(user)] [ADMIN_INDIVIDUALLOG(user)] [ADMIN_SMITE(user)]"
#define ADMIN_FULLMONTY(user) "[key_name_admin(user)] [ADMIN_FULLMONTY_NONAME(user)]"
#define ADMIN_JMP(src) "(<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[src.x];Y=[src.y];Z=[src.z]'>JMP</a>)"
#define COORD(src) "[src ? "([src.x],[src.y],[src.z])" : "nonexistent location"]"
#define ADMIN_COORDJMP(src) "[src ? "[COORD(src)] [ADMIN_JMP(src)]" : "nonexistent location"]"
#define ADMIN_INDIVIDUALLOG(user) "(<a href='?_src_=holder;individuallog=\ref[user]'>LOGS</a>)"
#define ADMIN_PUNISHMENT_LIGHTNING "Lightning bolt"
#define ADMIN_PUNISHMENT_BRAINDAMAGE "Brain damage"
#define ADMIN_PUNISHMENT_GIB "Gib"
#define ADMIN_PUNISHMENT_BSA "Bluespace Artillery Device"
#define AHELP_ACTIVE 1
#define AHELP_CLOSED 2
#define AHELP_RESOLVED 3
//A set of constants used to determine which type of mute an admin wishes to apply:
//Please read and understand the muting/automuting stuff before changing these. MUTE_IC_AUTO etc = (MUTE_IC << 1)
//Therefore there needs to be a gap between the flags for the automute flags
#define MUTE_IC 1
#define MUTE_OOC 2
#define MUTE_PRAY 4
#define MUTE_ADMINHELP 8
#define MUTE_DEADCHAT 16
#define MUTE_ALL 31
//Some constants for DB_Ban
#define BANTYPE_PERMA 1
#define BANTYPE_TEMP 2
#define BANTYPE_JOB_PERMA 3
#define BANTYPE_JOB_TEMP 4
#define BANTYPE_ANY_FULLBAN 5 //used to locate stuff to unban.
#define BANTYPE_ADMIN_PERMA 7
#define BANTYPE_ADMIN_TEMP 8
#define BANTYPE_ANY_JOB 9 //used to remove jobbans
//Please don't edit these values without speaking to Errorage first ~Carn
//Admin Permissions
#define R_BUILDMODE 1
#define R_ADMIN 2
#define R_BAN 4
#define R_FUN 8
#define R_SERVER 16
#define R_DEBUG 32
#define R_POSSESS 64
#define R_PERMISSIONS 128
#define R_STEALTH 256
#define R_POLL 512
#define R_VAREDIT 1024
#define R_SOUNDS 2048
#define R_SPAWN 4096
#if DM_VERSION > 512
#error Remove the flag below , its been long enough
#endif
//legacy , remove post 512, it was replaced by R_POLL
#define R_REJUVINATE 2
#define R_MAXPERMISSION 4096 //This holds the maximum value for a permission. It is used in iteration, so keep it updated.
#define ADMIN_QUE(user) "(<a href='?_src_=holder;[HrefToken(TRUE)];adminmoreinfo=\ref[user]'>?</a>)"
#define ADMIN_FLW(user) "(<a href='?_src_=holder;[HrefToken(TRUE)];adminplayerobservefollow=\ref[user]'>FLW</a>)"
#define ADMIN_PP(user) "(<a href='?_src_=holder;[HrefToken(TRUE)];adminplayeropts=\ref[user]'>PP</a>)"
#define ADMIN_VV(atom) "(<a href='?_src_=vars;[HrefToken(TRUE)];Vars=\ref[atom]'>VV</a>)"
#define ADMIN_SM(user) "(<a href='?_src_=holder;[HrefToken(TRUE)];subtlemessage=\ref[user]'>SM</a>)"
#define ADMIN_TP(user) "(<a href='?_src_=holder;[HrefToken(TRUE)];traitor=\ref[user]'>TP</a>)"
#define ADMIN_KICK(user) "(<a href='?_src_=holder;[HrefToken(TRUE)];boot2=\ref[user]'>KICK</a>)"
#define ADMIN_CENTCOM_REPLY(user) "(<a href='?_src_=holder;[HrefToken(TRUE)];CentComReply=\ref[user]'>RPLY</a>)"
#define ADMIN_SYNDICATE_REPLY(user) "(<a href='?_src_=holder;[HrefToken(TRUE)];SyndicateReply=\ref[user]'>RPLY</a>)"
#define ADMIN_SC(user) "(<a href='?_src_=holder;[HrefToken(TRUE)];adminspawncookie=\ref[user]'>SC</a>)"
#define ADMIN_SMITE(user) "(<a href='?_src_=holder;[HrefToken(TRUE)];adminsmite=\ref[user]'>SMITE</a>)"
#define ADMIN_LOOKUP(user) "[key_name_admin(user)][ADMIN_QUE(user)]"
#define ADMIN_LOOKUPFLW(user) "[key_name_admin(user)][ADMIN_QUE(user)] [ADMIN_FLW(user)]"
#define ADMIN_SET_SD_CODE "(<a href='?_src_=holder;[HrefToken(TRUE)];set_selfdestruct_code=1'>SETCODE</a>)"
#define ADMIN_FULLMONTY_NONAME(user) "[ADMIN_QUE(user)] [ADMIN_PP(user)] [ADMIN_VV(user)] [ADMIN_SM(user)] [ADMIN_FLW(user)] [ADMIN_TP(user)] [ADMIN_INDIVIDUALLOG(user)] [ADMIN_SMITE(user)]"
#define ADMIN_FULLMONTY(user) "[key_name_admin(user)] [ADMIN_FULLMONTY_NONAME(user)]"
#define ADMIN_JMP(src) "(<a href='?_src_=holder;[HrefToken(TRUE)];adminplayerobservecoodjump=1;X=[src.x];Y=[src.y];Z=[src.z]'>JMP</a>)"
#define COORD(src) "[src ? "([src.x],[src.y],[src.z])" : "nonexistent location"]"
#define ADMIN_COORDJMP(src) "[src ? "[COORD(src)] [ADMIN_JMP(src)]" : "nonexistent location"]"
#define ADMIN_INDIVIDUALLOG(user) "(<a href='?_src_=holder;[HrefToken(TRUE)];individuallog=\ref[user]'>LOGS</a>)"
#define ADMIN_PUNISHMENT_LIGHTNING "Lightning bolt"
#define ADMIN_PUNISHMENT_BRAINDAMAGE "Brain damage"
#define ADMIN_PUNISHMENT_GIB "Gib"
#define ADMIN_PUNISHMENT_BSA "Bluespace Artillery Device"
#define AHELP_ACTIVE 1
#define AHELP_CLOSED 2
#define AHELP_RESOLVED 3
+1
View File
@@ -18,3 +18,4 @@
#define ANTAG_DATUM_IAA_HUMAN_CUSTOM /datum/antagonist/traitor/human/internal_affairs/custom
#define ANTAG_DATUM_IAA_AI_CUSTOM /datum/antagonist/traitor/AI/internal_affairs/custom
#define ANTAG_DATUM_IAA_AI /datum/antagonist/traitor/AI/internal_affairs
#define ANTAG_DATUM_BROTHER /datum/antagonist/brother
+1
View File
@@ -41,6 +41,7 @@
#define ANTAG_HUD_SOULLESS 17
#define ANTAG_HUD_CLOCKWORK 18
#define ANTAG_HUD_BORER 19
#define ANTAG_HUD_BROTHER 20
// Notification action types
#define NOTIFY_JUMP "jump"
+4
View File
@@ -49,6 +49,7 @@
//Health Defines
#define HEALTH_THRESHOLD_CRIT 0
#define HEALTH_THRESHOLD_FULLCRIT -30
#define HEALTH_THRESHOLD_DEAD -100
//Actual combat defines
@@ -73,6 +74,9 @@
#define GRAB_NECK 2
#define GRAB_KILL 3
//slowdown when in softcrit
#define SOFTCRIT_ADD_SLOWDOWN 6
//Attack types for checking shields/hit reactions
#define MELEE_ATTACK 1
#define UNARMED_ATTACK 2
+29 -3
View File
@@ -5,14 +5,40 @@
// How multiple components of the exact same type are handled in the same datum
#define COMPONENT_DUPE_HIGHLANDER 0 //old component is deleted (default)
#define COMPONENT_DUPE_ALLOWED 1 //duplicates allowed
#define COMPONENT_DUPE_ALLOWED 1 //duplicates allowed
#define COMPONENT_DUPE_UNIQUE 2 //new component is deleted
// All signals. Format:
// When the signal is called: (signal arguments)
// /datum signals
#define COMSIG_COMPONENT_ADDED "component_added" //when a component is added to a datum: (datum/component)
#define COMSIG_COMPONENT_REMOVING "component_removing" //before a component is removed from a datum because of RemoveComponent: (datum/component)
#define COMSIG_PARENT_QDELETED "parent_qdeleted" //before a datum's Destroy() is called: ()
#define COMSIG_ATOM_ENTERED "atom_entered" //from base of atom/Entered(): (atom/movable, atom)
#define COMSIG_MOVABLE_CROSSED "movable_crossed" //from base of atom/movable/Crossed(): (atom/movable)
// /atom signals
#define COMSIG_PARENT_ATTACKBY "atom_attackby" //from base of atom/attackby(): (obj/item, mob/living, params)
#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)
#define COMSIG_ATOM_EX_ACT "atom_ex_act" //from base of atom/ex_act(): (severity, target)
#define COMSIG_ATOM_EMP_ACT "atom_emp_act" //from base of atom/emp_act(): (severity)
#define COMSIG_ATOM_FIRE_ACT "atom_fire_act" //from base of atom/fire_act(): (exposed_temperature, exposed_volume)
#define COMSIG_ATOM_BULLET_ACT "atom_bullet_act" //from base of atom/bullet_act(): (obj/item/projectile, def_zone)
#define COMSIG_ATOM_BLOB_ACT "atom_blob_act" //from base of atom/blob_act(): (obj/structure/blob)
#define COMSIG_ATOM_ACID_ACT "atom_acid_act" //from base of atom/acid_act(): (acidpwr, acid_volume)
#define COMSIG_ATOM_EMAG_ACT "atom_emag_act" //from base of atom/emag_act(): ()
#define COMSIG_ATOM_NARSIE_ACT "atom_narsie_act" //from base of atom/narsie_act(): ()
#define COMSIG_ATOM_RATVAR_ACT "atom_ratvar_act" //from base of atom/ratvar_act(): ()
#define COMSIG_ATOM_RCD_ACT "atom_rcd_act" //from base of atom/rcd_act(): (mob, obj/item/construction/rcd, passed_mode)
#define COMSIG_ATOM_SING_PULL "atom_sing_pull" //from base of atom/singularity_pull(): (S, current_size)
// /atom/movable signals
#define COMSIG_MOVABLE_MOVED "movable_moved" //from base of atom/movable/Moved(): (atom, dir)
#define COMSIG_MOVABLE_CROSSED "movable_crossed" //from base of atom/movable/Crossed(): (atom/movable)
#define COMSIG_MOVABLE_COLLIDE "movable_collide" //from base of atom/movable/Collide(): (atom)
#define COMSIG_MOVABLE_IMPACT "movable_impact" //from base of atom/movable/throw_impact(): (atom, throwingdatum)
// /obj/machinery signals
#define COMSIG_MACHINE_PROCESS "machine_process" //from machinery subsystem fire(): ()
#define COMSIG_MACHINE_PROCESS_ATMOS "machine_process_atmos" //from air subsystem process_atmos_machinery(): ()
+1
View File
@@ -101,6 +101,7 @@
#define CAT_ROBOT "Robots"
#define CAT_MISC "Misc"
#define CAT_PRIMAL "Tribal"
#define CAT_CLOTHING "Clothing"
#define CAT_FOOD "Foods"
#define CAT_BREAD "Breads"
#define CAT_BURGER "Burgers"
+12
View File
@@ -1,5 +1,7 @@
// simple is_type and similar inline helpers
#define isdatum(D) (istype(D, /datum))
#define islist(L) (istype(L, /list))
#define in_range(source, user) (get_dist(source, user) <= 1)
@@ -25,6 +27,8 @@
#define islava(A) (istype(A, /turf/open/lava))
#define isplatingturf(A) (istype(A, /turf/open/floor/plating))
//Mobs
#define isliving(A) (istype(A, /mob/living))
@@ -158,3 +162,11 @@ GLOBAL_LIST_INIT(pointed_types, typecacheof(list(
#define issignaler(O) (istype(O, /obj/item/device/assembly/signaler))
#define istimer(O) (istype(O, /obj/item/device/assembly/timer))
GLOBAL_LIST_INIT(glass_sheet_types, typecacheof(list(
/obj/item/stack/sheet/glass,
/obj/item/stack/sheet/rglass,
/obj/item/stack/sheet/plasmaglass,
/obj/item/stack/sheet/plasmarglass)))
#define is_glass_sheet(O) (is_type_in_typecache(O, GLOB.glass_sheet_types))
+1 -1
View File
@@ -35,7 +35,7 @@ Last space-z level = empty
//zlevel defines, can be overridden for different maps in the appropriate _maps file.
#define ZLEVEL_CENTCOM 1
#define ZLEVEL_STATION 2
#define ZLEVEL_STATION_PRIMARY 2
#define ZLEVEL_MINING 5
#define ZLEVEL_LAVALAND 5
#define ZLEVEL_EMPTY_SPACE 12
+14 -7
View File
@@ -361,7 +361,6 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
#define debug_admins(msg) if (GLOB.Debug2) to_chat(GLOB.admins, "DEBUG: [msg]")
#define debug_world_log(msg) if (GLOB.Debug2) log_world("DEBUG: [msg]")
#define COORD(A) "([A.x],[A.y],[A.z])"
#define INCREMENT_TALLY(L, stat) if(L[stat]){L[stat]++}else{L[stat] = 1}
// Medal names
@@ -399,8 +398,6 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
#define NUKE_SYNDICATE_BASE 3
#define STATION_DESTROYED_NUKE 4
#define STATION_EVACUATED 5
#define GANG_LOSS 6
#define GANG_TAKEOVER 7
#define BLOB_WIN 8
#define BLOB_NUKE 9
#define BLOB_DESTROYED 10
@@ -437,10 +434,6 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
#define GIBTONITE_DETONATE 3
//for obj explosion block calculation
#define EXPLOSION_BLOCK_PROC -1
//Gangster starting influences
#define GANGSTER_SOLDIER_STARTING_INFLUENCE 5
#define GANGSTER_BOSS_STARTING_INFLUENCE 20
//for determining which type of heartbeat sound is playing
#define BEAT_FAST 1
@@ -453,3 +446,17 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
#define MOUSE_OPACITY_TRANSPARENT 0
#define MOUSE_OPACITY_ICON 1
#define MOUSE_OPACITY_OPAQUE 2
//world/proc/shelleo
#define SHELLEO_ERRORLEVEL 1
#define SHELLEO_STDOUT 2
#define SHELLEO_STDERR 3
//server security mode
#define SECURITY_SAFE 1
#define SECURITY_ULTRASAFE 2
#define SECURITY_TRUSTED 3
//Dummy mob reserve slots
#define DUMMY_HUMAN_SLOT_PREFERENCES "dummy_preference_preview"
#define DUMMY_HUMAN_SLOT_MANIFEST "dummy_manifest_generation"
+2
View File
@@ -154,3 +154,5 @@
#define JUDGE_IGNOREMONKEYS 16
#define MEGAFAUNA_DEFAULT_RECOVERY_TIME 5
#define SHADOW_SPECIES_LIGHT_THRESHOLD 0.2
-3
View File
@@ -2,6 +2,3 @@
#define TRACK_NUKE_DISK 1 //We track the nuclear authentication disk, either to protect it or steal it
#define TRACK_MALF_AI 2 //We track the malfunctioning AI, so we can prevent it from blowing us all up
#define TRACK_INFILTRATOR 3 //We track the Syndicate infiltrator, so we can get back to ship when the nuke's armed
#define TRACK_OPERATIVES 4 //We track the closest operative, so we can regroup when we need to
#define TRACK_ATOM 5 //We track a specified atom, so admins can make us function for events
#define TRACK_COORDINATES 6 //We point towards the specified coordinates on our z-level, so we can navigate
+5
View File
@@ -10,6 +10,11 @@
//if TESTING is enabled, qdel will call this object's find_references() verb.
//defines for the gc_destroyed var
#define GC_QUEUE_PREQUEUE 1
#define GC_QUEUE_CHECK 2
#define GC_QUEUE_HARDDELETE 3
#define GC_QUEUE_COUNT 3 //increase this when adding more steps.
#define GC_QUEUED_FOR_QUEUING -1
#define GC_QUEUED_FOR_HARD_DEL -2
#define GC_CURRENTLY_BEING_QDELETED -3
+3 -3
View File
@@ -18,18 +18,19 @@
#define ROLE_BLOB "blob"
#define ROLE_NINJA "space ninja"
#define ROLE_MONKEY "monkey"
#define ROLE_GANG "gangster"
#define ROLE_ABDUCTOR "abductor"
#define ROLE_REVENANT "revenant"
#define ROLE_DEVIL "devil"
#define ROLE_SERVANT_OF_RATVAR "servant of Ratvar"
#define ROLE_BORER "borer"
#define ROLE_BROTHER "blood brother"
//Missing assignment means it's not a gamemode specific role, IT'S NOT A BUG OR ERROR.
//The gamemode specific ones are just so the gamemodes can query whether a player is old enough
//(in game days played) to play that role
GLOBAL_LIST_INIT(special_roles, list(
ROLE_TRAITOR = /datum/game_mode/traitor,
ROLE_BROTHER = /datum/game_mode/traitor/bros,
ROLE_OPERATIVE = /datum/game_mode/nuclear,
ROLE_CHANGELING = /datum/game_mode/changeling,
ROLE_WIZARD = /datum/game_mode/wizard,
@@ -41,7 +42,6 @@ GLOBAL_LIST_INIT(special_roles, list(
ROLE_BLOB = /datum/game_mode/blob,
ROLE_NINJA,
ROLE_MONKEY = /datum/game_mode/monkey,
ROLE_GANG = /datum/game_mode/gang,
ROLE_REVENANT,
ROLE_ABDUCTOR = /datum/game_mode/abduction,
ROLE_DEVIL = /datum/game_mode/devil,
@@ -52,4 +52,4 @@ GLOBAL_LIST_INIT(special_roles, list(
//Job defines for what happens when you fail to qualify for any job during job selection
#define BEASSISTANT 1
#define BERANDOMJOB 2
#define RETURNTOLOBBY 3
#define RETURNTOLOBBY 3
+3 -1
View File
@@ -9,7 +9,9 @@
//keep these in sync with TGS3
#define SERVICE_WORLD_PARAM "server_service"
#define SERVICE_PR_TEST_JSON "..\\..\\prtestjob.json"
#define SERVICE_VERSION_PARAM "server_service_version"
#define SERVICE_PR_TEST_JSON "prtestjob.json"
#define SERVICE_PR_TEST_JSON_OLD "..\\..\\[SERVICE_PR_TEST_JSON]"
#define SERVICE_CMD_HARD_REBOOT "hard_reboot"
#define SERVICE_CMD_GRACEFUL_SHUTDOWN "graceful_shutdown"
+10 -5
View File
@@ -53,9 +53,14 @@
#define ENGINE_COEFF_MAX 2
#define ENGINE_DEFAULT_MAXSPEED_ENGINES 5
//Docking error flags_1
//Docking error flags
#define DOCKING_SUCCESS 0
#define DOCKING_COMPLETE 1
#define DOCKING_BLOCKED 2
#define DOCKING_IMMOBILIZED 4
#define DOCKING_AREA_EMPTY 8
#define DOCKING_BLOCKED 1
#define DOCKING_IMMOBILIZED 2
#define DOCKING_AREA_EMPTY 4
//Docking turf movements
#define MOVE_TURF 1
#define MOVE_AREA 2
#define MOVE_CONTENTS 4
+3 -2
View File
@@ -10,12 +10,13 @@
#define CHANNEL_BICYCLE 1016
//Citadel code
#define CHANNEL_PRED 1018
#define CHANNEL_PRED 1015
#define CHANNEL_PREYLOOP 1014
//THIS SHOULD ALWAYS BE THE LOWEST ONE!
//KEEP IT UPDATED
#define CHANNEL_HIGHEST_AVAILABLE 1015
#define CHANNEL_HIGHEST_AVAILABLE 1013
#define CHANNEL_HIGHEST_AVAILABLE 1017
#define SOUND_MINIMUM_PRESSURE 10
+5 -5
View File
@@ -4,8 +4,9 @@
//mob/var/stat things
#define CONSCIOUS 0
#define UNCONSCIOUS 1
#define DEAD 2
#define SOFT_CRIT 1
#define UNCONSCIOUS 2
#define DEAD 3
//mob disabilities stat
@@ -21,9 +22,8 @@
// bitflags for machine stat variable
#define BROKEN 1
#define NOPOWER 2
#define POWEROFF 4 // tbd
#define MAINT 8 // under maintaince
#define EMPED 16 // temporary broken by EMP pulse
#define MAINT 4 // under maintaince
#define EMPED 8 // temporary broken by EMP pulse
//ai power requirement defines
#define POWER_REQ_NONE 0
+1 -1
View File
@@ -56,7 +56,6 @@
#define INIT_ORDER_TIMER 1
#define INIT_ORDER_DEFAULT 0
#define INIT_ORDER_AIR -1
#define INIT_ORDER_SHUTTLE -2
#define INIT_ORDER_MINIMAP -3
#define INIT_ORDER_ASSETS -4
#define INIT_ORDER_ICON_SMOOTHING -5
@@ -64,6 +63,7 @@
#define INIT_ORDER_XKEYSCORE -10
#define INIT_ORDER_STICKY_BAN -10
#define INIT_ORDER_LIGHTING -20
#define INIT_ORDER_SHUTTLE -21
#define INIT_ORDER_SQUEAK -40
#define INIT_ORDER_PERSISTENCE -100
+8
View File
@@ -13,3 +13,11 @@ When using time2text(), please use "DDD" to find the weekday. Refrain from using
#define FRIDAY "Fri"
#define SATURDAY "Sat"
#define SUNDAY "Sun"
#define SECONDS *10
#define MINUTES SECONDS*60
#define HOURS MINUTES*60
#define TICKS *world.tick_lag
+1
View File
@@ -2,6 +2,7 @@
#define DM_HOLD "Hold"
#define DM_DIGEST "Digest"
#define DM_HEAL "Heal"
#define DM_NOISY "Noisy"
#define VORE_STRUGGLE_EMOTE_CHANCE 40
+16
View File
@@ -205,6 +205,22 @@
return null
/proc/pickweightAllowZero(list/L) //The original pickweight proc will sometimes pick entries with zero weight. I'm not sure if changing the original will break anything, so I left it be.
var/total = 0
var/item
for (item in L)
if (!L[item])
L[item] = 0
total += L[item]
total = rand(0, total)
for (item in L)
total -=L [item]
if (total <= 0 && L[item])
return item
return null
//Pick a random element from the list and remove it from the list.
/proc/pick_n_take(list/L)
if(L.len)
+4 -1
View File
@@ -85,7 +85,7 @@
/proc/log_pda(text)
if (config.log_pda)
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]PDA: [text]")
WRITE_FILE(GLOB.world_pda_log, "\[[time_stamp()]]PDA: [text]")
/proc/log_comment(text)
if (config.log_pda)
@@ -96,6 +96,9 @@
if (config.log_pda)
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]CHAT: [text]")
/proc/log_qdel(text)
WRITE_FILE(GLOB.world_qdel_log, "\[[time_stamp()]]QDEL: [text]")
/proc/log_sql(text)
WRITE_FILE(GLOB.sql_error_log, "\[[time_stamp()]]SQL: [text]")
+9
View File
@@ -49,3 +49,12 @@ GLOBAL_VAR_INIT(cmp_field, "name")
/proc/cmp_ruincost_priority(datum/map_template/ruin/A, datum/map_template/ruin/B)
return initial(A.cost) - initial(B.cost)
/proc/cmp_qdel_item_time(datum/qdel_item/A, datum/qdel_item/B)
. = B.hard_delete_time - A.hard_delete_time
if (!.)
. = B.destroy_time - A.destroy_time
if (!.)
. = B.failures - A.failures
if (!.)
. = B.qdels - A.qdels
+4 -4
View File
@@ -9,10 +9,10 @@
#define CULT_POLL_WAIT 2400
/proc/get_area(atom/A)
if (!istype(A))
return
for(A, A && !isarea(A), A=A.loc); //semicolon is for the empty statement
return A
if(isarea(A))
return A
var/turf/T = get_turf(A)
return T ? T.loc : null
/proc/get_area_name(atom/X)
var/area/Y = get_area(X)
+3 -5
View File
@@ -926,10 +926,10 @@ GLOBAL_LIST_EMPTY(friendly_animal_types)
return 0
//For creating consistent icons for human looking simple animals
/proc/get_flat_human_icon(icon_id, datum/job/J, datum/preferences/prefs)
/proc/get_flat_human_icon(icon_id, datum/job/J, datum/preferences/prefs, dummy_key)
var/static/list/humanoid_icon_cache = list()
if(!icon_id || !humanoid_icon_cache[icon_id])
var/mob/living/carbon/human/dummy/body = new()
var/mob/living/carbon/human/dummy/body = generate_or_wait_for_human_dummy(dummy_key)
if(prefs)
prefs.copy_to(body)
@@ -956,14 +956,12 @@ GLOBAL_LIST_EMPTY(friendly_animal_types)
partial = getFlatIcon(body)
out_icon.Insert(partial,dir=EAST)
qdel(body)
humanoid_icon_cache[icon_id] = out_icon
dummy_key? unset_busy_human_dummy(dummy_key) : qdel(body)
return out_icon
else
return humanoid_icon_cache[icon_id]
//Hook, override to run code on- wait this is images
//Images have dir without being an atom, so they get their own definition.
//Lame.
+1 -1
View File
@@ -39,7 +39,7 @@
priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg')
for(var/obj/machinery/computer/communications/C in GLOB.machines)
if(!(C.stat & (BROKEN|NOPOWER)) && C.z == ZLEVEL_STATION)
if(!(C.stat & (BROKEN|NOPOWER)) && (C.z in GLOB.station_z_levels))
var/obj/item/paper/P = new /obj/item/paper(C.loc)
P.name = "paper - '[title]'"
P.info = text
+57
View File
@@ -0,0 +1,57 @@
//Runs the command in the system's shell, returns a list of (error code, stdout, stderr)
#define SHELLEO_NAME "data/shelleo."
#define SHELLEO_ERR ".err"
#define SHELLEO_OUT ".out"
/world/proc/shelleo(command)
var/static/list/shelleo_ids = list()
var/stdout = ""
var/stderr = ""
var/errorcode = 1
var/shelleo_id
var/out_file = ""
var/err_file = ""
var/static/list/interpreters = list("[MS_WINDOWS]" = "cmd /c", "[UNIX]" = "sh -c")
var/interpreter = interpreters["[world.system_type]"]
if(interpreter)
for(var/seo_id in shelleo_ids)
if(!shelleo_ids[seo_id])
shelleo_ids[seo_id] = TRUE
shelleo_id = "[seo_id]"
break
if(!shelleo_id)
shelleo_id = "[shelleo_ids.len + 1]"
shelleo_ids += shelleo_id
shelleo_ids[shelleo_id] = TRUE
out_file = "[SHELLEO_NAME][shelleo_id][SHELLEO_OUT]"
err_file = "[SHELLEO_NAME][shelleo_id][SHELLEO_ERR]"
errorcode = shell("[interpreter] \"[command]\" > [out_file] 2> [err_file]")
if(fexists(out_file))
stdout = file2text(out_file)
fdel(out_file)
if(fexists(err_file))
stderr = file2text(err_file)
fdel(err_file)
shelleo_ids[shelleo_id] = FALSE
else
CRASH("Operating System: [world.system_type] not supported") // If you encounter this error, you are encouraged to update this proc with support for the new operating system
. = list(errorcode, stdout, stderr)
#undef SHELLEO_NAME
#undef SHELLEO_ERR
#undef SHELLEO_OUT
/proc/shell_url_scrub(url)
var/static/regex/bad_chars_regex = regex("\[^#%&./:=?\\w]*", "g")
var/scrubbed_url = ""
var/bad_match = ""
var/last_good = 1
var/bad_chars = 1
do
bad_chars = bad_chars_regex.Find(url)
scrubbed_url += copytext(url, last_good, bad_chars)
if(bad_chars)
bad_match = url_encode(bad_chars_regex.match)
scrubbed_url += bad_match
last_good = bad_chars + length(bad_match)
while(bad_chars)
. = scrubbed_url
+1 -1
View File
@@ -1,5 +1,5 @@
/*
// Contains VOREStation type2type functions
// Contains VOREStation based vore description type2type functions
// list2text - takes delimiter and returns text
// text2list - takes delimiter, and creates list
//
+1 -1
View File
@@ -812,7 +812,7 @@ GLOBAL_LIST_INIT(can_embed_types, typecacheof(list(
/*
Checks if that loc and dir has a item on the wall
Checks if that loc and dir has an item on the wall
*/
GLOBAL_LIST_INIT(WALLITEMS, typecacheof(list(
/obj/machinery/power/apc, /obj/machinery/airalarm, /obj/item/device/radio/intercom,
+1 -1
View File
@@ -72,4 +72,4 @@
//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 1
#define DB_MINOR_VERSION 3
+6 -42
View File
@@ -105,53 +105,17 @@ GLOBAL_LIST_INIT(TAGGERLOCATIONS, list("Disposals",
GLOBAL_LIST_INIT(guitar_notes, flist("sound/guitar/"))
GLOBAL_LIST_INIT(station_prefixes, list("", "Imperium", "Heretical", "Cuban",
"Psychic", "Elegant", "Common", "Uncommon", "Rare", "Unique",
"Houseruled", "Religious", "Atheist", "Traditional", "Houseruled",
"Mad", "Super", "Ultra", "Secret", "Top Secret", "Deep", "Death",
"Zybourne", "Central", "Main", "Government", "Uoi", "Fat",
"Automated", "Experimental", "Augmented"))
GLOBAL_LIST_INIT(station_prefixes, world.file2list("strings/station_prefixes.txt") + "")
GLOBAL_LIST_INIT(station_names, list("", "Stanford", "Dorf", "Alium",
"Prefix", "Clowning", "Aegis", "Ishimura", "Scaredy", "Death-World",
"Mime", "Honk", "Rogue", "MacRagge", "Ultrameens", "Safety", "Paranoia",
"Explosive", "Neckbear", "Donk", "Muppet", "North", "West", "East",
"South", "Slant-ways", "Widdershins", "Rimward", "Expensive",
"Procreatory", "Imperial", "Unidentified", "Immoral", "Carp", "Ork",
"Pete", "Control", "Nettle", "Aspie", "Class", "Crab", "Fist",
"Corrogated","Skeleton","Race", "Fatguy", "Gentleman", "Capitalist",
"Communist", "Bear", "Beard", "Derp", "Space", "Spess", "Star", "Moon",
"System", "Mining", "Neckbeard", "Research", "Supply", "Military",
"Orbital", "Battle", "Science", "Asteroid", "Home", "Production",
"Transport", "Delivery", "Extraplanetary", "Orbital", "Correctional",
"Robot", "Hats", "Pizza"))
GLOBAL_LIST_INIT(station_names, world.file2list("strings/station_names.txt" + ""))
GLOBAL_LIST_INIT(station_suffixes, list("Station", "Frontier",
"Suffix", "Death-trap", "Space-hulk", "Lab", "Hazard","Spess Junk",
"Fishery", "No-Moon", "Tomb", "Crypt", "Hut", "Monkey", "Bomb",
"Trade Post", "Fortress", "Village", "Town", "City", "Edition", "Hive",
"Complex", "Base", "Facility", "Depot", "Outpost", "Installation",
"Drydock", "Observatory", "Array", "Relay", "Monitor", "Platform",
"Construct", "Hangar", "Prison", "Center", "Port", "Waystation",
"Factory", "Waypoint", "Stopover", "Hub", "HQ", "Office", "Object",
"Fortification", "Colony", "Planet-Cracker", "Roost", "Fat Camp",
"Airstrip"))
GLOBAL_LIST_INIT(station_suffixes, world.file2list("strings/station_suffixes.txt"))
GLOBAL_LIST_INIT(greek_letters, list("Alpha", "Beta", "Gamma", "Delta",
"Epsilon", "Zeta", "Eta", "Theta", "Iota", "Kappa", "Lambda", "Mu",
"Nu", "Xi", "Omicron", "Pi", "Rho", "Sigma", "Tau", "Upsilon", "Phi",
"Chi", "Psi", "Omega"))
GLOBAL_LIST_INIT(greek_letters, world.file2list("strings/greek_letters.txt"))
GLOBAL_LIST_INIT(phonetic_alphabet, list("Alpha", "Bravo", "Charlie",
"Delta", "Echo", "Foxtrot", "Golf", "Hotel", "India", "Juliet",
"Kilo", "Lima", "Mike", "November", "Oscar", "Papa", "Quebec",
"Romeo", "Sierra", "Tango", "Uniform", "Victor", "Whiskey", "X-ray",
"Yankee", "Zulu"))
GLOBAL_LIST_INIT(phonetic_alphabet, world.file2list("strings/phonetic_alphabet.txt"))
GLOBAL_LIST_INIT(numbers_as_words, list("One", "Two", "Three", "Four",
"Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve",
"Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen",
"Eighteen", "Nineteen"))
GLOBAL_LIST_INIT(numbers_as_words, world.file2list("strings/numbers_as_words.txt"))
/proc/generate_number_strings()
var/list/L[198]
+56 -54
View File
@@ -1,55 +1,57 @@
#define Z_NORTH 1
#define Z_EAST 2
#define Z_SOUTH 3
#define Z_WEST 4
#define Z_NORTH 1
#define Z_EAST 2
#define Z_SOUTH 3
#define Z_WEST 4
GLOBAL_LIST_INIT(cardinals, list(NORTH, SOUTH, EAST, WEST))
GLOBAL_LIST_INIT(alldirs, list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST))
GLOBAL_LIST_INIT(diagonals, list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST))
//This list contains the z-level numbers which can be accessed via space travel and the percentile chances to get there.
//(Exceptions: extended, sandbox and nuke) -Errorage
//Was list("3" = 30, "4" = 70).
//Spacing should be a reliable method of getting rid of a body -- Urist.
//Go away Urist, I'm restoring this to the longer list. ~Errorage
GLOBAL_LIST_INIT(accessable_z_levels, list(1,3,4,5,6,7)) //Keep this to six maps, repeating z-levels is ok if needed
GLOBAL_LIST(global_map)
//list/global_map = list(list(1,5),list(4,3))//an array of map Z levels.
//Resulting sector map looks like
//|_1_|_4_|
//|_5_|_3_|
//
//1 - SS13
//4 - Derelict
//3 - AI satellite
//5 - empty space
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(wizardstart)
GLOBAL_LIST_EMPTY(newplayer_start)
GLOBAL_LIST_EMPTY(prisonwarp) //prisoners go to these
GLOBAL_LIST_EMPTY(holdingfacility) //captured people go here
GLOBAL_LIST_EMPTY(xeno_spawn)//Aliens spawn at these.
GLOBAL_LIST_EMPTY(tdome1)
GLOBAL_LIST_EMPTY(tdome2)
GLOBAL_LIST_EMPTY(tdomeobserve)
GLOBAL_LIST_EMPTY(tdomeadmin)
GLOBAL_LIST_EMPTY(prisonwarped) //list of players already warped
GLOBAL_LIST_EMPTY(blobstart)
GLOBAL_LIST_EMPTY(secequipment)
GLOBAL_LIST_EMPTY(deathsquadspawn)
GLOBAL_LIST_EMPTY(emergencyresponseteamspawn)
GLOBAL_LIST_EMPTY(ruin_landmarks)
//away missions
GLOBAL_LIST_EMPTY(awaydestinations) //a list of landmarks that the warpgate can take you to
//used by jump-to-area etc. Updated by area/updateName()
GLOBAL_LIST_EMPTY(sortedAreas)
GLOBAL_LIST_EMPTY(all_abstract_markers)
GLOBAL_LIST_INIT(alldirs, list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST))
GLOBAL_LIST_INIT(diagonals, list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST))
//This list contains the z-level numbers which can be accessed via space travel and the percentile chances to get there.
//(Exceptions: extended, sandbox and nuke) -Errorage
//Was list("3" = 30, "4" = 70).
//Spacing should be a reliable method of getting rid of a body -- Urist.
//Go away Urist, I'm restoring this to the longer list. ~Errorage
GLOBAL_LIST_INIT(accessable_z_levels, list(1,3,4,5,6,7)) //Keep this to six maps, repeating z-levels is ok if needed
GLOBAL_LIST_INIT(station_z_levels, list(ZLEVEL_STATION_PRIMARY))
GLOBAL_LIST(global_map)
//list/global_map = list(list(1,5),list(4,3))//an array of map Z levels.
//Resulting sector map looks like
//|_1_|_4_|
//|_5_|_3_|
//
//1 - SS13
//4 - Derelict
//3 - AI satellite
//5 - empty space
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(wizardstart)
GLOBAL_LIST_EMPTY(newplayer_start)
GLOBAL_LIST_EMPTY(prisonwarp) //prisoners go to these
GLOBAL_LIST_EMPTY(holdingfacility) //captured people go here
GLOBAL_LIST_EMPTY(xeno_spawn)//Aliens spawn at these.
GLOBAL_LIST_EMPTY(tdome1)
GLOBAL_LIST_EMPTY(tdome2)
GLOBAL_LIST_EMPTY(tdomeobserve)
GLOBAL_LIST_EMPTY(tdomeadmin)
GLOBAL_LIST_EMPTY(prisonwarped) //list of players already warped
GLOBAL_LIST_EMPTY(blobstart)
GLOBAL_LIST_EMPTY(secequipment)
GLOBAL_LIST_EMPTY(deathsquadspawn)
GLOBAL_LIST_EMPTY(emergencyresponseteamspawn)
GLOBAL_LIST_EMPTY(ruin_landmarks)
//away missions
GLOBAL_LIST_EMPTY(awaydestinations) //a list of landmarks that the warpgate can take you to
//used by jump-to-area etc. Updated by area/updateName()
GLOBAL_LIST_EMPTY(sortedAreas)
GLOBAL_LIST_EMPTY(all_abstract_markers)
+4
View File
@@ -4,6 +4,8 @@ GLOBAL_VAR(world_game_log)
GLOBAL_PROTECT(world_game_log)
GLOBAL_VAR(world_runtime_log)
GLOBAL_PROTECT(world_runtime_log)
GLOBAL_VAR(world_qdel_log)
GLOBAL_PROTECT(world_qdel_log)
GLOBAL_VAR(world_attack_log)
GLOBAL_PROTECT(world_attack_log)
GLOBAL_VAR(world_href_log)
@@ -14,6 +16,8 @@ GLOBAL_VAR(config_error_log)
GLOBAL_PROTECT(config_error_log)
GLOBAL_VAR(sql_error_log)
GLOBAL_PROTECT(sql_error_log)
GLOBAL_VAR(world_pda_log)
GLOBAL_PROTECT(world_pda_log)
GLOBAL_LIST_EMPTY(bombers)
GLOBAL_PROTECT(bombers)
+3 -2
View File
@@ -14,7 +14,8 @@
if(call(client.click_intercept, "InterceptClickOn")(src, params, A))
return
if(control_disabled || stat) return
if(control_disabled || incapacitated())
return
if(ismob(A))
ai_actual_track(A)
@@ -31,7 +32,7 @@
if(call(client.click_intercept, "InterceptClickOn")(src, params, A))
return
if(control_disabled || stat)
if(control_disabled || incapacitated())
return
var/turf/pixel_turf = get_turf_pixel(A)
+8 -2
View File
@@ -2,8 +2,8 @@
icon = 'icons/mob/screen_ai.dmi'
/obj/screen/ai/Click()
if(isobserver(usr))
return 1
if(isobserver(usr) || usr.incapacitated())
return TRUE
/obj/screen/ai/aicore
name = "AI core"
@@ -20,6 +20,8 @@
icon_state = "camera"
/obj/screen/ai/camera_list/Click()
if(..())
return
var/mob/living/silicon/ai/AI = usr
var/camera = input(AI, "Choose which camera you want to view", "Cameras") as null|anything in AI.get_camera_list()
AI.ai_camera_list(camera)
@@ -130,6 +132,8 @@
icon_state = "take_picture"
/obj/screen/ai/image_take/Click()
if(..())
return
if(isAI(usr))
var/mob/living/silicon/ai/AI = usr
AI.aicamera.toggle_camera_mode()
@@ -142,6 +146,8 @@
icon_state = "view_images"
/obj/screen/ai/image_view/Click()
if(..())
return
if(isAI(usr))
var/mob/living/silicon/ai/AI = usr
AI.aicamera.viewpictures()
+1 -1
View File
@@ -633,6 +633,7 @@ so as to remain in compliance with the most up-to-date laws."
/obj/screen/alert/restrained/buckled
name = "Buckled"
desc = "You've been buckled to something. Click the alert to unbuckle unless you're handcuffed."
icon_state = "buckled"
/obj/screen/alert/restrained/handcuffed
name = "Handcuffed"
@@ -698,4 +699,3 @@ so as to remain in compliance with the most up-to-date laws."
severity = 0
master = null
screen_loc = ""
+11 -7
View File
@@ -67,7 +67,7 @@
screen_loc = "CENTER-7,CENTER-7"
layer = FULLSCREEN_LAYER
plane = FULLSCREEN_PLANE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
var/severity = 0
var/show_when_dead = FALSE
@@ -95,16 +95,20 @@
layer = CRIT_LAYER
plane = FULLSCREEN_PLANE
/obj/screen/fullscreen/crit/vision
icon_state = "oxydamageoverlay"
layer = BLIND_LAYER
/obj/screen/fullscreen/blind
icon_state = "blackimageoverlay"
layer = BLIND_LAYER
plane = FULLSCREEN_PLANE
/obj/screen/fullscreen/curse
icon_state = "curse"
layer = CURSE_LAYER
plane = FULLSCREEN_PLANE
/obj/screen/fullscreen/curse
icon_state = "curse"
layer = CURSE_LAYER
plane = FULLSCREEN_PLANE
/obj/screen/fullscreen/impaired
icon_state = "impairedoverlay"
@@ -168,4 +172,4 @@
plane = LIGHTING_PLANE
layer = LIGHTING_LAYER
blend_mode = BLEND_ADD
show_when_dead = TRUE
show_when_dead = TRUE
+1 -1
View File
@@ -247,7 +247,7 @@
/obj/screen/parallax_layer/Initialize(mapload, view)
..()
. = ..()
if (!view)
view = world.view
update_o(view)
+1 -1
View File
@@ -26,7 +26,7 @@
/obj/screen/swarmer/Replicate
icon_state = "ui_replicate"
name = "Replicate (Costs 50 Resources)"
desc = "Creates a another of our kind."
desc = "Creates another of our kind."
/obj/screen/swarmer/Replicate/Click()
if(isswarmer(usr))
+1 -1
View File
@@ -21,7 +21,7 @@
/obj/attackby(obj/item/I, mob/living/user, params)
return I.attack_obj(src, user)
/mob/living/attackby(obj/item/I, mob/user, params)
/mob/living/attackby(obj/item/I, mob/living/user, params)
user.changeNext_move(CLICK_CD_MELEE)
if(user.a_intent == INTENT_HARM && stat == DEAD && butcher_results) //can we butcher it?
var/sharpness = I.is_sharp()
+35 -1
View File
@@ -26,4 +26,38 @@
build_type = PROTOLATHE
materials = list(MAT_GOLD = 2500, MAT_METAL = 5000, MAT_GLASS = 5000)
build_path = /obj/item/gun/energy/laser/carbine/nopin
category = list("Weapons")
category = list("Weapons")
/obj/item/gun/ballistic/automatic/pistol/antitank
name = "Anti Tank Pistol"
desc = "A massively impractical and silly monstrosity of a pistol that fires .50 calliber rounds. The recoil is likely to dislocate your wrist."
icon = 'icons/obj/guns/cit_guns.dmi'
icon_state = "atp"
item_state = "pistol"
recoil = 6
mag_type = /obj/item/ammo_box/magazine/sniper_rounds
fire_delay = 50
burst_size = 1
origin_tech = "combat=7"
can_suppress = 0
w_class = WEIGHT_CLASS_NORMAL
actions_types = list()
fire_sound = 'sound/weapons/blastcannon.ogg'
spread = 30 //damn thing has no rifling.
/obj/item/gun/ballistic/automatic/pistol/antitank/update_icon()
..()
if(magazine)
cut_overlays()
add_overlay("atp-mag")
else
cut_overlays()
icon_state = "[initial(icon_state)][chambered ? "" : "-e"]"
/obj/item/gun/ballistic/automatic/pistol/antitank/syndicate
name = "Syndicate Anti Tank Pistol"
desc = "A massively impractical and silly monstrosity of a pistol that fires .50 calliber rounds. The recoil is likely to dislocate a variety of joints without proper bracing."
pin = /obj/item/device/firing_pin/implant/pindicate
origin_tech = "combat=7;syndicate=6"
+14 -14
View File
@@ -46,7 +46,7 @@
name = "Female Ejaculate"
id = "femcum"
description = "Vaginal lubricant found in most mammals and other animals of similar nature. Where you found this is your own business."
taste_description = "female arousal"
taste_description = "something with a tang" // wew coders who haven't eaten out a girl.
taste_mult = 2
data = list("donor"=null,"viruses"=null,"donor_DNA"=null,"blood_type"=null,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null)
reagent_state = LIQUID
@@ -90,7 +90,7 @@
//aphrodisiac & anaphrodisiac
/datum/reagent/aphrodisiac
/datum/reagent/drug/aphrodisiac
name = "Crocin"
id = "aphro"
description = "Naturally found in the crocus and gardenia flowers, this drug acts as a natural and safe aphrodisiac."
@@ -98,7 +98,7 @@
taste_mult = 2 //Hide the roofies in stronger flavors
color = "#FFADFF"//PINK, rgb(255, 173, 255)
/datum/reagent/aphrodisiac/on_mob_life(mob/living/M)
/datum/reagent/drug/aphrodisiac/on_mob_life(mob/living/M)
if(prob(33))
M.adjustArousalLoss(2)
if(prob(5))
@@ -108,7 +108,7 @@
to_chat(M, "<span class='love'>[aroused_message]</span>")
..()
/datum/reagent/aphrodisiacplus
/datum/reagent/drug/aphrodisiacplus
name = "Hexacrocin"
id = "aphro+"
description = "Chemically condensed form of basic crocin. This aphrodisiac is extremely powerful and addictive in most animals.\
@@ -119,7 +119,7 @@
addiction_threshold = 20
overdose_threshold = 20
/datum/reagent/aphrodisiacplus/on_mob_life(mob/living/M)
/datum/reagent/drug/aphrodisiacplus/on_mob_life(mob/living/M)
if(prob(33))
M.adjustArousalLoss(6)//not quite six times as powerful, but still considerably more powerful.
if(prob(5))
@@ -135,21 +135,21 @@
aroused_message = pick("You feel a bit hot.", "You feel strong sexual urges.", "You feel in the mood.", "You're ready to go down on someone.")
to_chat(M, "<span class='love'>[aroused_message]</span>")
/datum/reagent/aphrodisiacplus/addiction_act_stage2(mob/living/M)
/datum/reagent/drug/aphrodisiacplus/addiction_act_stage2(mob/living/M)
if(prob(30))
M.adjustBrainLoss(2)
..()
/datum/reagent/aphrodisiacplus/addiction_act_stage3(mob/living/M)
/datum/reagent/drug/aphrodisiacplus/addiction_act_stage3(mob/living/M)
if(prob(30))
M.adjustBrainLoss(3)
..()
/datum/reagent/aphrodisiacplus/addiction_act_stage4(mob/living/M)
/datum/reagent/drug/aphrodisiacplus/addiction_act_stage4(mob/living/M)
if(prob(30))
M.adjustBrainLoss(4)
..()
/datum/reagent/aphrodisiacplus/overdose_process(mob/living/M)
/datum/reagent/drug/aphrodisiacplus/overdose_process(mob/living/M)
if(prob(33))
if(M.getArousalLoss() >= 100 && ishuman(M) && M.has_dna())
var/mob/living/carbon/human/H = M
@@ -163,7 +163,7 @@
M.adjustArousalLoss(2)
..()
/datum/reagent/anaphrodisiac
/datum/reagent/drug/anaphrodisiac
name = "Camphor"
id = "anaphro"
description = "Naturally found in some species of evergreen trees, camphor is a waxy substance. When injested by most animals, it acts as an anaphrodisiac\
@@ -173,12 +173,12 @@
color = "#D9D9D9"//rgb(217, 217, 217)
reagent_state = SOLID
/datum/reagent/anaphrodisiac/on_mob_life(mob/living/M)
/datum/reagent/drug/anaphrodisiac/on_mob_life(mob/living/M)
if(prob(33))
M.adjustArousalLoss(-2)
..()
/datum/reagent/anaphrodisiacplus
/datum/reagent/drug/anaphrodisiacplus
name = "Hexacamphor"
id = "anaphro+"
description = "Chemically condensed camphor. Causes an extreme reduction in libido and a permanent one if overdosed. Non-addictive."
@@ -187,12 +187,12 @@
reagent_state = SOLID
overdose_threshold = 20
/datum/reagent/anaphrodisiacplus/on_mob_life(mob/living/M)
/datum/reagent/drug/anaphrodisiacplus/on_mob_life(mob/living/M)
if(prob(33))
M.adjustArousalLoss(-4)
..()
/datum/reagent/anaphrodisiacplus/overdose_process(mob/living/M)
/datum/reagent/drug/anaphrodisiacplus/overdose_process(mob/living/M)
if(prob(33))
if(M.min_arousal > 0)
M.min_arousal -= 1
+1
View File
@@ -7,6 +7,7 @@
body_parts_covered = CHEST|ARMS
can_adjust = 1
icon = 'icons/obj/clothing/turtlenecks.dmi'
icon_override = 'icons/mob/citadel/uniforms.dmi'
/obj/item/clothing/under/bb_sweater/black
name = "black sweater"
+5 -5
View File
@@ -22,7 +22,7 @@
)
premium = list()
refill_canister = /obj/item/vending_refill/kink
/*
/obj/machinery/vending/nazivend
name = "Nazivend"
desc = "A vending machine containing Nazi German supplies. A label reads: \"Remember the gorrilions lost.\""
@@ -34,20 +34,20 @@
/obj/item/clothing/head/stalhelm = 20,
/obj/item/clothing/head/panzer = 20,
/obj/item/clothing/suit/soldiercoat = 20,
/obj/item/clothing/under/soldieruniform = 20,
// /obj/item/clothing/under/soldieruniform = 20,
/obj/item/clothing/shoes/jackboots = 20
)
contraband = list(
/obj/item/clothing/head/naziofficer = 10,
/obj/item/clothing/suit/officercoat = 10,
/obj/item/clothing/under/officeruniform = 10,
// /obj/item/clothing/suit/officercoat = 10,
// /obj/item/clothing/under/officeruniform = 10,
/obj/item/clothing/suit/space/hardsuit/nazi = 3,
/obj/item/gun/energy/plasma/MP40k = 4
)
premium = list()
refill_canister = /obj/item/vending_refill/nazi
*/
/obj/machinery/vending/sovietvend
name = "KomradeVendtink"
desc = "Rodina-mat' zovyot!"
+60 -1
View File
@@ -8,4 +8,63 @@
icon = 'icons/obj/custom.dmi'
icon_state = "cebu"
w_class = WEIGHT_CLASS_TINY
flags_1 = NOBLUDGEON_1
flags_1 = NOBLUDGEON_1
/*Inferno707*/
/obj/item/clothing/neck/cloak/inferno
name = "Kiara's Cloak"
desc = "The design on this seems a little too familiar."
icon = 'icons/obj/clothing/cloaks.dmi'
icon_state = "infcloak"
item_state = "infcloak"
w_class = WEIGHT_CLASS_SMALL
body_parts_covered = CHEST|GROIN|LEGS|ARMS
/obj/item/clothing/neck/petcollar/inferno
name = "Kiara's Collar"
desc = "A soft black collar that seems to stretch to fit whoever wears it."
icon_state = "infcollar"
item_state = "infcollar"
item_color = null
tagname = null
/*DirtyOldHarry*/
/obj/item/lighter/gold
name = "\improper Engraved Zippo"
desc = "A shiny and relatively expensive zippo lighter. There's a small etched in verse on the bottom that reads, 'No Gods, No Masters, Only Man.'"
icon = 'icons/obj/cigarettes.dmi'
icon_state = "gold_zippo"
item_state = "gold_zippo"
w_class = WEIGHT_CLASS_TINY
flags_1 = CONDUCT_1
slot_flags = SLOT_BELT
heat = 1500
resistance_flags = FIRE_PROOF
light_color = LIGHT_COLOR_FIRE
/*Zombierobin*/
/obj/item/clothing/neck/scarf/zomb //Default white color, same functionality as beanies.
name = "A special scarf"
icon_state = "zombscarf"
desc = "A fashionable collar"
item_color = "zombscarf"
dog_fashion = /datum/dog_fashion/head
/*PLACEHOLDER*/
/obj/item/toy/plush/carrot
name = "carrot plushie"
desc = "While a normal carrot would be good for your eyes, this one seems a bit more for hugging then eating."
icon = 'icons/obj/hydroponics/harvest.dmi'
icon_state = "carrot"
item_state = "carrot"
w_class = WEIGHT_CLASS_SMALL
attack_verb = list("slapped")
resistance_flags = FLAMMABLE
var/bitesound = 'sound/items/bikehorn.ogg'
+3 -4
View File
@@ -23,7 +23,6 @@
attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed")
w_class = 3
sharpness = IS_SHARP
var/emagged = 0
/obj/item/dogborg/jaws/attack(atom/A, mob/living/silicon/robot/user)
..()
@@ -173,7 +172,6 @@
icon_state = "synthtongue"
hitsound = 'sound/effects/attackblob.ogg'
cleanspeed = 80
var/emagged = 0
/obj/item/soap/tongue/New()
..()
@@ -339,7 +337,6 @@
/obj/item/hand_tele,
/obj/item/card/id/captains_spare,
/obj/item/device/aicard,
/obj/item/device/paicard,
/obj/item/gun,
/obj/item/pinpointer,
/obj/item/clothing/shoes/magboots,
@@ -354,7 +351,9 @@
/obj/item/nuke_core_container,
/obj/item/areaeditor/blueprints,
/obj/item/documents/syndicate,
/obj/item/disk/nuclear)
/obj/item/disk/nuclear,
/obj/item/bombcore,
/obj/item/grenade)
/obj/item/device/dogborg/sleeper/New()
..()
+23
View File
@@ -0,0 +1,23 @@
/obj/structure/guncase/plasma
name = "plasma rifle locker"
desc = "A locker that holds plasma rifles. Only opens in dire emergencies."
icon_state = "ecase"
case_type = "egun"
gun_category = /obj/item/gun/energy/plasma
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF //because fuck you, powergaming nerds.
/obj/structure/guncase/plasma/attackby(obj/item/W, mob/user, params)
return
/obj/structure/guncase/plasma/MouseDrop(over_object, src_location, over_location)
if(GLOB.security_level == SEC_LEVEL_RED || GLOB.security_level == SEC_LEVEL_DELTA)
. = ..()
else
to_chat(usr, "The storage unit will only unlock during a Red or Delta security alert.")
/obj/structure/guncase/plasma/attack_hand(mob/user)
return MouseDrop(user)
/obj/structure/guncase/plasma/emag_act()
to_chat(usr, "The locking mechanism is fitted with old style parts, The card has no effect.")
return
+46 -11
View File
@@ -5,6 +5,10 @@
#define SECURITY_HAS_MAINT_ACCESS 2
#define EVERYONE_HAS_MAINT_ACCESS 4
GLOBAL_VAR_INIT(config_dir, "config/")
GLOBAL_PROTECT(config_dir)
/datum/configuration/can_vv_get(var_name)
var/static/list/banned_gets = list("autoadmin", "autoadmin_rank")
if (var_name in banned_gets)
@@ -12,7 +16,7 @@
return ..()
/datum/configuration/vv_edit_var(var_name, var_value)
var/static/list/banned_edits = list("cross_address", "cross_allowed", "autoadmin", "autoadmin_rank")
var/static/list/banned_edits = list("cross_address", "cross_allowed", "autoadmin", "autoadmin_rank", "invoke_youtubedl")
if(var_name in banned_edits)
return FALSE
return ..()
@@ -90,6 +94,8 @@
var/panic_server_name
var/panic_address //Reconnect a player this linked server if this server isn't accepting new players
var/invoke_youtubedl
//IP Intel vars
var/ipintel_email
var/ipintel_rating_bad = 1
@@ -102,6 +108,8 @@
var/use_age_restriction_for_jobs = 0 //Do jobs use account age restrictions? --requires database
var/use_account_age_for_jobs = 0 //Uses the time they made the account for the job restriction stuff. New player joining alerts should be unaffected.
var/see_own_notes = 0 //Can players see their own admin notes (read-only)? Config option in config.txt
var/note_fresh_days
var/note_stale_days
var/use_exp_tracking = FALSE
var/use_exp_restrictions_heads = FALSE
@@ -121,6 +129,8 @@
//game_options.txt configs
var/force_random_names = 0
var/list/mode_names = list()
var/list/mode_reports = list()
var/list/mode_false_report_weight = list()
var/list/modes = list() // allowed modes
var/list/votable_modes = list() // votable modes
var/list/probabilities = list() // relative probability of each mode
@@ -137,11 +147,13 @@
var/irc_first_connection_alert = 0 // do we notify the irc channel when somebody is connecting for the first time?
var/traitor_scaling_coeff = 6 //how much does the amount of players get divided by to determine traitors
var/brother_scaling_coeff = 25 //how many players per brother team
var/changeling_scaling_coeff = 6 //how much does the amount of players get divided by to determine changelings
var/security_scaling_coeff = 8 //how much does the amount of players get divided by to determine open security officer positions
var/abductor_scaling_coeff = 15 //how many players per abductor team
var/traitor_objectives_amount = 2
var/brother_objectives_amount = 2
var/protect_roles_from_antagonist = 0 //If security and such can be traitor/cult/other
var/protect_assistant_from_antagonist = 0 //If assistants can be traitor/cult/other
var/enforce_human_authority = 0 //If non-human species are barred from joining as a head of staff
@@ -175,6 +187,7 @@
var/rename_cyborg = 0
var/ooc_during_round = 0
var/emojis = 0
var/no_credits_round_end = FALSE
//Used for modifying movement speed for mobs.
//Unversal modifiers
@@ -273,6 +286,8 @@
var/list/policies = list()
var/debug_admin_hrefs = FALSE //turns off admin href token protection for debugging purposes
/datum/configuration/New()
gamemode_cache = typecacheof(/datum/game_mode,TRUE)
for(var/T in gamemode_cache)
@@ -286,6 +301,8 @@
modes += M.config_tag
mode_names[M.config_tag] = M.name
probabilities[M.config_tag] = M.probability
mode_reports[M.config_tag] = M.generate_report()
mode_false_report_weight[M.config_tag] = M.false_report_weight
if(M.votable)
votable_modes += M.config_tag
qdel(M)
@@ -294,19 +311,20 @@
Reload()
/datum/configuration/proc/Reload()
load("config/config.txt")
load("config/comms.txt", "comms")
load("config/game_options.txt","game_options")
load("config/policies.txt", "policies")
loadsql("config/dbconfig.txt")
load("config.txt")
load("comms.txt", "comms")
load("game_options.txt","game_options")
load("policies.txt", "policies")
loadsql("dbconfig.txt")
reload_custom_roundstart_items_list()
if (maprotation)
loadmaplist("config/maps.txt")
loadmaplist("maps.txt")
// apply some settings from config..
GLOB.abandon_allowed = respawn
/datum/configuration/proc/load(filename, type = "config") //the type can also be game_options, in which case it uses a different switch. not making it separate to not copypaste code - Urist
filename = "[GLOB.config_dir][filename]"
var/list/Lines = world.file2list(filename)
for(var/t in Lines)
@@ -470,10 +488,16 @@
if("panic_server_address")
if(value != "byond://address:port")
panic_address = value
if("invoke_youtubedl")
invoke_youtubedl = value
if("show_irc_name")
showircname = 1
if("see_own_notes")
see_own_notes = 1
if("note_fresh_days")
note_fresh_days = text2num(value)
if("note_stale_days")
note_stale_days = text2num(value)
if("soft_popcap")
soft_popcap = text2num(value)
if("hard_popcap")
@@ -553,6 +577,8 @@
error_msg_delay = text2num(value)
if("irc_announce_new_game")
irc_announce_new_game = TRUE
if("debug_admin_hrefs")
debug_admin_hrefs = TRUE
else
#if DM_VERSION > 511
#error Replace the line below with WRITE_FILE(GLOB.config_error_log, "Unknown setting in configuration: '[name]'")
@@ -576,6 +602,8 @@
ooc_during_round = 1
if("emojis")
emojis = 1
if("no_credits_round_end")
no_credits_round_end = TRUE
if("run_delay")
run_speed = text2num(value)
if("walk_delay")
@@ -668,6 +696,8 @@
ghost_interaction = 1
if("traitor_scaling_coeff")
traitor_scaling_coeff = text2num(value)
if("brother_scaling_coeff")
brother_scaling_coeff = text2num(value)
if("changeling_scaling_coeff")
changeling_scaling_coeff = text2num(value)
if("security_scaling_coeff")
@@ -676,6 +706,8 @@
abductor_scaling_coeff = text2num(value)
if("traitor_objectives_amount")
traitor_objectives_amount = text2num(value)
if("brother_objectives_amount")
brother_objectives_amount = text2num(value)
if("probability")
var/prob_pos = findtext(value, " ")
var/prob_name = null
@@ -819,6 +851,7 @@
WRITE_FILE(GLOB.config_error_log, "Unknown setting in configuration: '[name]'")
/datum/configuration/proc/loadmaplist(filename)
filename = "[GLOB.config_dir][filename]"
var/list/Lines = world.file2list(filename)
var/datum/map_config/currentmap = null
@@ -871,6 +904,7 @@
/datum/configuration/proc/loadsql(filename)
filename = "[GLOB.config_dir][filename]"
var/list/Lines = world.file2list(filename)
for(var/t in Lines)
if(!t)
@@ -916,11 +950,12 @@
/datum/configuration/proc/pick_mode(mode_name)
// I wish I didn't have to instance the game modes in order to look up
// their information, but it is the only way (at least that I know of).
// ^ This guy didn't try hard enough
for(var/T in gamemode_cache)
var/datum/game_mode/M = new T()
if(M.config_tag && M.config_tag == mode_name)
return M
qdel(M)
var/datum/game_mode/M = T
var/ct = initial(M.config_tag)
if(ct && ct == mode_name)
return new T
return new /datum/game_mode/extended()
/datum/configuration/proc/get_runnable_modes()
-24
View File
@@ -1,24 +0,0 @@
diff a/code/controllers/configuration.dm b/code/controllers/configuration.dm (rejected hunks)
@@ -337,17 +337,17 @@
if("use_account_age_for_jobs")
use_account_age_for_jobs = 1
if("use_exp_tracking")
- use_exp_tracking = 1
+ use_exp_tracking = TRUE
if("use_exp_restrictions_heads")
- use_exp_restrictions_heads = 1
+ use_exp_restrictions_heads = TRUE
if("use_exp_restrictions_heads_hours")
use_exp_restrictions_heads_hours = text2num(value)
if("use_exp_restrictions_heads_department")
- use_exp_restrictions_heads_department = 1
+ use_exp_restrictions_heads_department = TRUE
if("use_exp_restrictions_other")
- use_exp_restrictions_other = 1
+ use_exp_restrictions_other = TRUE
if("use_exp_restrictions_admin_bypass")
- use_exp_restrictions_admin_bypass = 1
+ use_exp_restrictions_admin_bypass = TRUE
if("lobby_countdown")
lobby_countdown = text2num(value)
if("round_end_countdown")
+102 -102
View File
@@ -1,102 +1,102 @@
/**
* Failsafe
*
* Pretty much pokes the MC to make sure it's still alive.
**/
GLOBAL_REAL(Failsafe, /datum/controller/failsafe)
/datum/controller/failsafe // This thing pretty much just keeps poking the master controller
name = "Failsafe"
// The length of time to check on the MC (in deciseconds).
// Set to 0 to disable.
var/processing_interval = 20
// The alert level. For every failed poke, we drop a DEFCON level. Once we hit DEFCON 1, restart the MC.
var/defcon = 5
//the world.time of the last check, so the mc can restart US if we hang.
// (Real friends look out for *eachother*)
var/lasttick = 0
// Track the MC iteration to make sure its still on track.
var/master_iteration = 0
var/running = TRUE
/datum/controller/failsafe/New()
// Highlander-style: there can only be one! Kill off the old and replace it with the new.
if(Failsafe != src)
if(istype(Failsafe))
qdel(Failsafe)
Failsafe = src
Initialize()
/datum/controller/failsafe/Initialize()
set waitfor = 0
Failsafe.Loop()
if(!QDELETED(src))
qdel(src) //when Loop() returns, we delete ourselves and let the mc recreate us
/datum/controller/failsafe/Destroy()
running = FALSE
..()
return QDEL_HINT_HARDDEL_NOW
/datum/controller/failsafe/proc/Loop()
while(running)
lasttick = world.time
if(!Master)
// Replace the missing Master! This should never, ever happen.
new /datum/controller/master()
// Only poke it if overrides are not in effect.
if(processing_interval > 0)
if(Master.processing && Master.iteration)
// Check if processing is done yet.
if(Master.iteration == master_iteration)
switch(defcon)
if(4,5)
--defcon
if(3)
to_chat(GLOB.admins, "<span class='adminnotice'>Notice: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5-defcon) * processing_interval] ticks.")
--defcon
if(2)
to_chat(GLOB.admins, "<span class='boldannounce'>Warning: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5-defcon) * processing_interval] ticks. Automatic restart in [processing_interval] ticks.</span>")
--defcon
if(1)
to_chat(GLOB.admins, "<span class='boldannounce'>Warning: DEFCON [defcon_pretty()]. The Master Controller has still not fired within the last [(5-defcon) * processing_interval] ticks. Killing and restarting...</span>")
--defcon
var/rtn = Recreate_MC()
if(rtn > 0)
defcon = 4
master_iteration = 0
to_chat(GLOB.admins, "<span class='adminnotice'>MC restarted successfully</span>")
else if(rtn < 0)
log_game("FailSafe: Could not restart MC, runtime encountered. Entering defcon 0")
to_chat(GLOB.admins, "<span class='boldannounce'>ERROR: DEFCON [defcon_pretty()]. Could not restart MC, runtime encountered. I will silently keep retrying.</span>")
//if the return number was 0, it just means the mc was restarted too recently, and it just needs some time before we try again
//no need to handle that specially when defcon 0 can handle it
if(0) //DEFCON 0! (mc failed to restart)
var/rtn = Recreate_MC()
if(rtn > 0)
defcon = 4
master_iteration = 0
to_chat(GLOB.admins, "<span class='adminnotice'>MC restarted successfully</span>")
else
defcon = min(defcon + 1,5)
master_iteration = Master.iteration
if (defcon <= 1)
sleep(processing_interval*2)
else
sleep(processing_interval)
else
defcon = 5
sleep(initial(processing_interval))
/datum/controller/failsafe/proc/defcon_pretty()
return defcon
/datum/controller/failsafe/stat_entry()
if(!statclick)
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
stat("Failsafe Controller:", statclick.update("Defcon: [defcon_pretty()] (Interval: [Failsafe.processing_interval] | Iteration: [Failsafe.master_iteration])"))
/**
* Failsafe
*
* Pretty much pokes the MC to make sure it's still alive.
**/
GLOBAL_REAL(Failsafe, /datum/controller/failsafe)
/datum/controller/failsafe // This thing pretty much just keeps poking the master controller
name = "Failsafe"
// The length of time to check on the MC (in deciseconds).
// Set to 0 to disable.
var/processing_interval = 20
// The alert level. For every failed poke, we drop a DEFCON level. Once we hit DEFCON 1, restart the MC.
var/defcon = 5
//the world.time of the last check, so the mc can restart US if we hang.
// (Real friends look out for *eachother*)
var/lasttick = 0
// Track the MC iteration to make sure its still on track.
var/master_iteration = 0
var/running = TRUE
/datum/controller/failsafe/New()
// Highlander-style: there can only be one! Kill off the old and replace it with the new.
if(Failsafe != src)
if(istype(Failsafe))
qdel(Failsafe)
Failsafe = src
Initialize()
/datum/controller/failsafe/Initialize()
set waitfor = 0
Failsafe.Loop()
if(!QDELETED(src))
qdel(src) //when Loop() returns, we delete ourselves and let the mc recreate us
/datum/controller/failsafe/Destroy()
running = FALSE
..()
return QDEL_HINT_HARDDEL_NOW
/datum/controller/failsafe/proc/Loop()
while(running)
lasttick = world.time
if(!Master)
// Replace the missing Master! This should never, ever happen.
new /datum/controller/master()
// Only poke it if overrides are not in effect.
if(processing_interval > 0)
if(Master.processing && Master.iteration)
// Check if processing is done yet.
if(Master.iteration == master_iteration)
switch(defcon)
if(4,5)
--defcon
if(3)
message_admins("<span class='adminnotice'>Notice: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5-defcon) * processing_interval] ticks.</span>")
--defcon
if(2)
to_chat(GLOB.admins, "<span class='boldannounce'>Warning: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5-defcon) * processing_interval] ticks. Automatic restart in [processing_interval] ticks.</span>")
--defcon
if(1)
to_chat(GLOB.admins, "<span class='boldannounce'>Warning: DEFCON [defcon_pretty()]. The Master Controller has still not fired within the last [(5-defcon) * processing_interval] ticks. Killing and restarting...</span>")
--defcon
var/rtn = Recreate_MC()
if(rtn > 0)
defcon = 4
master_iteration = 0
to_chat(GLOB.admins, "<span class='adminnotice'>MC restarted successfully</span>")
else if(rtn < 0)
log_game("FailSafe: Could not restart MC, runtime encountered. Entering defcon 0")
to_chat(GLOB.admins, "<span class='boldannounce'>ERROR: DEFCON [defcon_pretty()]. Could not restart MC, runtime encountered. I will silently keep retrying.</span>")
//if the return number was 0, it just means the mc was restarted too recently, and it just needs some time before we try again
//no need to handle that specially when defcon 0 can handle it
if(0) //DEFCON 0! (mc failed to restart)
var/rtn = Recreate_MC()
if(rtn > 0)
defcon = 4
master_iteration = 0
to_chat(GLOB.admins, "<span class='adminnotice'>MC restarted successfully</span>")
else
defcon = min(defcon + 1,5)
master_iteration = Master.iteration
if (defcon <= 1)
sleep(processing_interval*2)
else
sleep(processing_interval)
else
defcon = 5
sleep(initial(processing_interval))
/datum/controller/failsafe/proc/defcon_pretty()
return defcon
/datum/controller/failsafe/stat_entry()
if(!statclick)
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
stat("Failsafe Controller:", statclick.update("Defcon: [defcon_pretty()] (Interval: [Failsafe.processing_interval] | Iteration: [Failsafe.master_iteration])"))
+1 -1
View File
@@ -422,7 +422,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
// in those cases, so we just let them run)
if (queue_node_flags & SS_NO_TICK_CHECK)
if (queue_node.tick_usage > TICK_LIMIT_RUNNING - TICK_USAGE && ran_non_ticker)
queue_node.queued_priority += queue_priority_count * 0.10
queue_node.queued_priority += queue_priority_count * 0.1
queue_priority_count -= queue_node_priority
queue_priority_count += queue_node.queued_priority
current_tick_budget -= queue_node_priority
+2 -1
View File
@@ -164,6 +164,7 @@ SUBSYSTEM_DEF(air)
currentrun.len--
if(!M || (M.process_atmos(seconds) == PROCESS_KILL))
atmos_machinery.Remove(M)
M.SendSignal(COMSIG_MACHINE_PROCESS_ATMOS)
if(MC_TICK_CHECK)
return
@@ -382,4 +383,4 @@ SUBSYSTEM_DEF(air)
#undef SSAIR_EXCITEDGROUPS
#undef SSAIR_HIGHPRESSURE
#undef SSAIR_HOTSPOT
#undef SSAIR_SUPERCONDUCTIVITY
#undef SSAIR_SUPERCONDUCTIVITY
+17 -22
View File
@@ -18,16 +18,14 @@ SUBSYSTEM_DEF(blackbox)
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?
/datum/controller/subsystem/blackbox/Initialize()
triggertime = world.time
. = ..()
//poll population
/datum/controller/subsystem/blackbox/fire()
if(!SSdbcore.Connect())
@@ -37,16 +35,14 @@ SUBSYSTEM_DEF(blackbox)
if(M.client)
playercount += 1
var/admincount = GLOB.admins.len
var/datum/DBQuery/query_record_playercount = SSdbcore.NewQuery("INSERT INTO [format_table_name("legacy_population")] (playercount, admincount, time, server_ip, server_port) VALUES ([playercount], [admincount], '[SQLtime()]', INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]')")
var/datum/DBQuery/query_record_playercount = SSdbcore.NewQuery("INSERT INTO [format_table_name("legacy_population")] (playercount, admincount, time, server_ip, server_port, round_id) VALUES ([playercount], [admincount], '[SQLtime()]', INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]', '[GLOB.round_id]')")
query_record_playercount.Execute()
if(config.use_exp_tracking)
if((triggertime < 0) || (world.time > (triggertime +3000))) //subsystem fires once at roundstart then once every 10 minutes. a 5 min check skips the first fire. The <0 is midnight rollover check
update_exp(10,FALSE)
/datum/controller/subsystem/blackbox/Recover()
msg_common = SSblackbox.msg_common
msg_science = SSblackbox.msg_science
@@ -189,8 +185,7 @@ SUBSYSTEM_DEF(blackbox)
return
if(!L || !L.key || !L.mind)
return
var/turf/T = get_turf(L)
var/area/placeofdeath = get_area(T.loc)
var/area/placeofdeath = get_area(L)
var/sqlname = sanitizeSQL(L.real_name)
var/sqlkey = sanitizeSQL(L.ckey)
var/sqljob = sanitizeSQL(L.mind.assigned_role)
@@ -212,8 +207,10 @@ SUBSYSTEM_DEF(blackbox)
var/x_coord = sanitizeSQL(L.x)
var/y_coord = sanitizeSQL(L.y)
var/z_coord = sanitizeSQL(L.z)
var/last_words = sanitizeSQL(L.last_words)
var/suicide = sanitizeSQL(L.suiciding)
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) 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])")
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()
@@ -229,7 +226,7 @@ SUBSYSTEM_DEF(blackbox)
/datum/feedback_variable
var/variable
var/value
var/details
var/list/details
/datum/feedback_variable/New(param_variable, param_value = 0)
variable = param_variable
@@ -267,19 +264,17 @@ SUBSYSTEM_DEF(blackbox)
/datum/feedback_variable/proc/get_variable()
return variable
/datum/feedback_variable/proc/set_details(text)
if (istext(text))
details = text
/datum/feedback_variable/proc/set_details(deets)
details = list("\"[deets]\"")
/datum/feedback_variable/proc/add_details(text)
if (istext(text))
if (!details)
details = "\"[text]\""
else
details += " | \"[text]\""
/datum/feedback_variable/proc/add_details(deets)
if (!details)
set_details(deets)
else
details += "\"[deets]\""
/datum/feedback_variable/proc/get_details()
return details
return details.Join(" | ")
/datum/feedback_variable/proc/get_parsed()
return list(variable,value,details)
return list(variable,value,details.Join(" | "))
@@ -1,10 +0,0 @@
diff a/code/controllers/subsystem/blackbox.dm b/code/controllers/subsystem/blackbox.dm (rejected hunks)
@@ -40,7 +40,7 @@ SUBSYSTEM_DEF(blackbox)
if(config.use_exp_tracking)
if((triggertime < 0) || (world.time > (triggertime +3000))) //subsystem fires once at roundstart then once every 10 minutes. a 5 min check skips the first fire. The <0 is midnight rollover check
- SSblackbox.update_exp(10,FALSE)
+ update_exp(10,FALSE)
/datum/controller/subsystem/blackbox/Recover()
+7
View File
@@ -14,3 +14,10 @@ SUBSYSTEM_DEF(disease)
/datum/controller/subsystem/disease/stat_entry(msg)
..("P:[active_diseases.len]")
/datum/controller/subsystem/disease/proc/get_disease_name(id)
var/datum/disease/advance/A = archive_diseases[id]
if(A.name)
return A.name
else
return "Unknown"
+3 -1
View File
@@ -116,6 +116,8 @@ SUBSYSTEM_DEF(events)
//allows a client to trigger an event
//aka Badmin Central
// > Not in modules/admin
// REEEEEEEEE
/client/proc/forceEvent()
set name = "Trigger Event"
set category = "Fun"
@@ -131,7 +133,7 @@ SUBSYSTEM_DEF(events)
var/magic = ""
var/holiday = ""
for(var/datum/round_event_control/E in SSevents.control)
dat = "<BR><A href='?src=\ref[src];forceevent=\ref[E]'>[E]</A>"
dat = "<BR><A href='?src=\ref[src];[HrefToken()];forceevent=\ref[E]'>[E]</A>"
if(E.holidayID)
holiday += dat
else if(E.wizardevent)
+208 -142
View File
@@ -1,40 +1,44 @@
SUBSYSTEM_DEF(garbage)
name = "Garbage"
priority = 15
wait = 20
wait = 2 SECONDS
flags = SS_POST_FIRE_TIMING|SS_BACKGROUND|SS_NO_INIT
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
var/collection_timeout = 3000// deciseconds to wait to let running procs finish before we just say fuck it and force del() the object
var/delslasttick = 0 // number of del()'s we've done this tick
var/gcedlasttick = 0 // number of things that gc'ed last tick
var/list/collection_timeout = list(0, 2 MINUTES, 10 SECONDS) // deciseconds to wait before moving something up in the queue to the next level
//Stat tracking
var/delslasttick = 0 // number of del()'s we've done this tick
var/gcedlasttick = 0 // number of things that gc'ed last tick
var/totaldels = 0
var/totalgcs = 0
var/highest_del_time = 0
var/highest_del_tickusage = 0
var/list/queue = list() // list of refID's of things that should be garbage collected
// refID's are associated with the time at which they time out and need to be manually del()
// we do this so we aren't constantly locating them and preventing them from being gc'd
var/list/pass_counts
var/list/fail_counts
var/list/tobequeued = list() //We store the references of things to be added to the queue separately so we can spread out GC overhead over a few ticks
var/list/items = list() // Holds our qdel_item statistics datums
var/list/didntgc = list() // list of all types that have failed to GC associated with the number of times that's happened.
// the types are stored as strings
var/list/sleptDestroy = list() //Same as above but these are paths that slept during their Destroy call
//Queue
var/list/queues
var/list/noqdelhint = list()// list of all types that do not return a QDEL_HINT
// all types that did not respect qdel(A, force=TRUE) and returned one
// of the immortality qdel hints
var/list/noforcerespect = list()
#ifdef TESTING
var/list/qdel_list = list() // list of all types that have been qdel()eted
#endif
/datum/controller/subsystem/garbage/PreInit()
queues = new(GC_QUEUE_COUNT)
pass_counts = new(GC_QUEUE_COUNT)
fail_counts = new(GC_QUEUE_COUNT)
for(var/i in 1 to GC_QUEUE_COUNT)
queues[i] = list()
pass_counts[i] = 0
fail_counts[i] = 0
/datum/controller/subsystem/garbage/stat_entry(msg)
msg += "Q:[queue.len]|D:[delslasttick]|G:[gcedlasttick]|"
var/list/counts = list()
for (var/list/L in queues)
counts += length(L)
msg += "Q:[counts.Join(",")]|D:[delslasttick]|G:[gcedlasttick]|"
msg += "GR:"
if (!(delslasttick+gcedlasttick))
msg += "n/a|"
@@ -46,116 +50,179 @@ SUBSYSTEM_DEF(garbage)
msg += "n/a|"
else
msg += "TGR:[round((totalgcs/(totaldels+totalgcs))*100, 0.01)]%"
msg += " P:[pass_counts.Join(",")]"
msg += "|F:[fail_counts.Join(",")]"
..(msg)
/datum/controller/subsystem/garbage/Shutdown()
//Adds the del() log to world.log in a format condensable by the runtime condenser found in tools
if(didntgc.len || sleptDestroy.len)
var/list/dellog = list()
for(var/path in didntgc)
dellog += "Path : [path] \n"
dellog += "Failures : [didntgc[path]] \n"
if(path in sleptDestroy)
dellog += "Sleeps : [sleptDestroy[path]] \n"
sleptDestroy -= path
for(var/path in sleptDestroy)
dellog += "Path : [path] \n"
dellog += "Sleeps : [sleptDestroy[path]] \n"
text2file(dellog.Join(), "[GLOB.log_directory]/qdel.log")
//Adds the del() log to the qdel log file
var/list/dellog = list()
//sort by how long it's wasted hard deleting
sortTim(items, cmp=/proc/cmp_qdel_item_time, associative = TRUE)
for(var/path in items)
var/datum/qdel_item/I = items[path]
dellog += "Path: [path]"
if (I.failures)
dellog += "\tFailures: [I.failures]"
dellog += "\tqdel() Count: [I.qdels]"
dellog += "\tDestroy() Cost: [I.destroy_time]ms"
if (I.hard_deletes)
dellog += "\tTotal Hard Deletes [I.hard_deletes]"
dellog += "\tTime Spent Hard Deleting: [I.hard_delete_time]ms"
if (I.slept_destroy)
dellog += "\tSleeps: [I.slept_destroy]"
if (I.no_respect_force)
dellog += "\tIgnored force: [I.no_respect_force] times"
if (I.no_hint)
dellog += "\tNo hint: [I.no_hint] times"
log_qdel(dellog.Join("\n"))
/datum/controller/subsystem/garbage/fire()
HandleToBeQueued()
if(state == SS_RUNNING)
HandleQueue()
//the fact that this resets its processing each fire (rather then resume where it left off) is intentional.
var/queue = GC_QUEUE_PREQUEUE
while (state == SS_RUNNING)
switch (queue)
if (GC_QUEUE_PREQUEUE)
HandlePreQueue()
queue = GC_QUEUE_PREQUEUE+1
if (GC_QUEUE_CHECK)
HandleQueue(GC_QUEUE_CHECK)
queue = GC_QUEUE_CHECK+1
if (GC_QUEUE_HARDDELETE)
HandleQueue(GC_QUEUE_HARDDELETE)
break
if (state == SS_PAUSED) //make us wait again before the next run.
state = SS_RUNNING
state = SS_RUNNING
//If you see this proc high on the profile, what you are really seeing is the garbage collection/soft delete overhead in byond.
//Don't attempt to optimize, not worth the effort.
/datum/controller/subsystem/garbage/proc/HandleToBeQueued()
var/list/tobequeued = src.tobequeued
var/starttime = world.time
var/starttimeofday = world.timeofday
while(tobequeued.len && starttime == world.time && starttimeofday == world.timeofday)
if (MC_TICK_CHECK)
break
var/ref = tobequeued[1]
Queue(ref)
tobequeued.Cut(1, 2)
/datum/controller/subsystem/garbage/proc/HandlePreQueue()
var/list/tobequeued = queues[GC_QUEUE_PREQUEUE]
var/static/count = 0
if (count)
var/c = count
count = 0 //so if we runtime on the Cut, we don't try again.
tobequeued.Cut(1,c+1)
/datum/controller/subsystem/garbage/proc/HandleQueue()
delslasttick = 0
gcedlasttick = 0
var/time_to_kill = world.time - collection_timeout // Anything qdel() but not GC'd BEFORE this time needs to be manually del()
var/list/queue = src.queue
var/starttime = world.time
var/starttimeofday = world.timeofday
while(queue.len && starttime == world.time && starttimeofday == world.timeofday)
for (var/ref in tobequeued)
count++
Queue(ref, GC_QUEUE_PREQUEUE+1)
if (MC_TICK_CHECK)
break
var/refID = queue[1]
if (count)
tobequeued.Cut(1,count+1)
count = 0
/datum/controller/subsystem/garbage/proc/HandleQueue(level = GC_QUEUE_CHECK)
if (level == GC_QUEUE_CHECK)
delslasttick = 0
gcedlasttick = 0
var/cut_off_time = world.time - collection_timeout[level] //ignore entries newer then this
var/list/queue = queues[level]
var/static/lastlevel
var/static/count = 0
if (count) //runtime last run before we could do this.
var/c = count
count = 0 //so if we runtime on the Cut, we don't try again.
var/list/lastqueue = queues[lastlevel]
lastqueue.Cut(1, c+1)
lastlevel = level
for (var/refID in queue)
if (!refID)
queue.Cut(1, 2)
count++
if (MC_TICK_CHECK)
break
continue
var/GCd_at_time = queue[refID]
if(GCd_at_time > time_to_kill)
if(GCd_at_time > cut_off_time)
break // Everything else is newer, skip them
queue.Cut(1, 2)
var/datum/A
A = locate(refID)
if (A && A.gc_destroyed == GCd_at_time) // So if something else coincidently gets the same ref, it's not deleted by mistake
#ifdef GC_FAILURE_HARD_LOOKUP
A.find_references()
#endif
count++
// Something's still referring to the qdel'd object. Kill it.
var/type = A.type
testing("GC: -- \ref[A] | [type] was unable to be GC'd and was deleted --")
didntgc["[type]"]++
HardDelete(A)
var/datum/D
D = locate(refID)
++delslasttick
++totaldels
else
if (!D || D.gc_destroyed != GCd_at_time) // So if something else coincidently gets the same ref, it's not deleted by mistake
++gcedlasttick
++totalgcs
pass_counts[level]++
if (MC_TICK_CHECK)
break
continue
/datum/controller/subsystem/garbage/proc/QueueForQueuing(datum/A)
if (istype(A) && A.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)
tobequeued += A
A.gc_destroyed = GC_QUEUED_FOR_QUEUING
// Something's still referring to the qdel'd object.
fail_counts[level]++
switch (level)
if (GC_QUEUE_CHECK)
#ifdef GC_FAILURE_HARD_LOOKUP
D.find_references()
#endif
var/type = D.type
var/datum/qdel_item/I = items[type]
testing("GC: -- \ref[D] | [type] was unable to be GC'd --")
I.failures++
if (GC_QUEUE_HARDDELETE)
HardDelete(D)
if (MC_TICK_CHECK)
break
continue
/datum/controller/subsystem/garbage/proc/Queue(datum/A)
if (isnull(A) || (!isnull(A.gc_destroyed) && A.gc_destroyed >= 0))
Queue(D, level+1)
if (MC_TICK_CHECK)
break
if (count)
queue.Cut(1,count+1)
count = 0
/datum/controller/subsystem/garbage/proc/PreQueue(datum/D)
if (D.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)
queues[GC_QUEUE_PREQUEUE] += D
D.gc_destroyed = GC_QUEUED_FOR_QUEUING
/datum/controller/subsystem/garbage/proc/Queue(datum/D, level = GC_QUEUE_CHECK)
if (isnull(D))
return
if (A.gc_destroyed == GC_QUEUED_FOR_HARD_DEL)
HardDelete(A)
if (D.gc_destroyed == GC_QUEUED_FOR_HARD_DEL)
level = GC_QUEUE_HARDDELETE
if (level > GC_QUEUE_COUNT)
HardDelete(D)
return
var/gctime = world.time
var/refid = "\ref[A]"
A.gc_destroyed = gctime
var/refid = "\ref[D]"
D.gc_destroyed = gctime
var/list/queue = queues[level]
if (queue[refid])
queue -= refid // Removing any previous references that were GC'd so that the current object will be at the end of the list.
queue[refid] = gctime
//this is purely to separate things profile wise.
/datum/controller/subsystem/garbage/proc/HardDelete(datum/A)
//this is mainly to separate things profile wise.
/datum/controller/subsystem/garbage/proc/HardDelete(datum/D)
var/time = world.timeofday
var/tick = TICK_USAGE
var/ticktime = world.time
var/type = A.type
var/refID = "\ref[A]"
del(A)
++delslasttick
++totaldels
var/type = D.type
var/refID = "\ref[D]"
del(D)
tick = (TICK_USAGE-tick+((world.time-ticktime)/world.tick_lag*100))
var/datum/qdel_item/I = items[type]
I.hard_deletes++
I.hard_delete_time += TICK_DELTA_TO_MS(tick)
if (tick > highest_del_tickusage)
highest_del_tickusage = tick
time = world.timeofday - time
@@ -166,18 +233,33 @@ SUBSYSTEM_DEF(garbage)
if (time > 10)
log_game("Error: [type]([refID]) took longer than 1 second to delete (took [time/10] seconds to delete)")
message_admins("Error: [type]([refID]) took longer than 1 second to delete (took [time/10] seconds to delete).")
postpone(time/5)
/datum/controller/subsystem/garbage/proc/HardQueue(datum/A)
if (istype(A) && A.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)
tobequeued += A
A.gc_destroyed = GC_QUEUED_FOR_HARD_DEL
postpone(time)
/datum/controller/subsystem/garbage/proc/HardQueue(datum/D)
if (D.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)
queues[GC_QUEUE_PREQUEUE] += D
D.gc_destroyed = GC_QUEUED_FOR_HARD_DEL
/datum/controller/subsystem/garbage/Recover()
if (istype(SSgarbage.queue))
queue |= SSgarbage.queue
if (istype(SSgarbage.tobequeued))
tobequeued |= SSgarbage.tobequeued
if (istype(SSgarbage.queues))
for (var/i in 1 to SSgarbage.queues.len)
queues[i] |= SSgarbage.queues[i]
/datum/qdel_item
var/name = ""
var/qdels = 0 //Total number of times it's passed thru qdel.
var/destroy_time = 0 //Total amount of milliseconds spent processing this type's Destroy()
var/failures = 0 //Times it was queued for soft deletion but failed to soft delete.
var/hard_deletes = 0 //Different from failures because it also includes QDEL_HINT_HARDDEL deletions
var/hard_delete_time = 0//Total amount of milliseconds spent hard deleting this type.
var/no_respect_force = 0//Number of times it's not respected force=TRUE
var/no_hint = 0 //Number of times it's not even bother to give a qdel hint
var/slept_destroy = 0 //Number of times it's slept in its destroy
/datum/qdel_item/New(mytype)
name = "[mytype]"
// Should be treated as a replacement for the 'del' keyword.
// Datums passed to this will be given a chance to clean up references to allow the GC to collect them.
@@ -185,21 +267,27 @@ SUBSYSTEM_DEF(garbage)
if(!istype(D))
del(D)
return
#ifdef TESTING
SSgarbage.qdel_list += "[D.type]"
#endif
var/datum/qdel_item/I = SSgarbage.items[D.type]
if (!I)
I = SSgarbage.items[D.type] = new /datum/qdel_item(D.type)
I.qdels++
if(isnull(D.gc_destroyed))
D.SendSignal(COMSIG_PARENT_QDELETED)
D.gc_destroyed = GC_CURRENTLY_BEING_QDELETED
var/start_time = world.time
var/start_tick = world.tick_usage
var/hint = D.Destroy(force) // Let our friend know they're about to get fucked up.
if(world.time != start_time)
SSgarbage.sleptDestroy["[D.type]"]++
I.slept_destroy++
else
I.destroy_time += TICK_USAGE_TO_MS(start_tick)
if(!D)
return
switch(hint)
if (QDEL_HINT_QUEUE) //qdel should queue the object for deletion.
SSgarbage.QueueForQueuing(D)
SSgarbage.PreQueue(D)
if (QDEL_HINT_IWILLGC)
D.gc_destroyed = world.time
return
@@ -209,28 +297,33 @@ SUBSYSTEM_DEF(garbage)
return
// Returning LETMELIVE after being told to force destroy
// indicates the objects Destroy() does not respect force
if(!SSgarbage.noforcerespect["[D.type]"])
SSgarbage.noforcerespect["[D.type]"] = "[D.type]"
#ifdef TESTING
if(!I.no_respect_force)
testing("WARNING: [D.type] has been force deleted, but is \
returning an immortal QDEL_HINT, indicating it does \
not respect the force flag for qdel(). It has been \
placed in the queue, further instances of this type \
will also be queued.")
SSgarbage.QueueForQueuing(D)
#endif
I.no_respect_force++
SSgarbage.PreQueue(D)
if (QDEL_HINT_HARDDEL) //qdel should assume this object won't gc, and queue a hard delete using a hard reference to save time from the locate()
SSgarbage.HardQueue(D)
if (QDEL_HINT_HARDDEL_NOW) //qdel should assume this object won't gc, and hard del it post haste.
SSgarbage.HardDelete(D)
if (QDEL_HINT_FINDREFERENCE)//qdel will, if TESTING is enabled, display all references to this object, then queue the object for deletion.
SSgarbage.QueueForQueuing(D)
SSgarbage.PreQueue(D)
#ifdef TESTING
D.find_references()
#endif
else
if(!SSgarbage.noqdelhint["[D.type]"])
SSgarbage.noqdelhint["[D.type]"] = "[D.type]"
#ifdef TESTING
if(!I.no_hint)
testing("WARNING: [D.type] is not returning a qdel hint. It is being placed in the queue. Further instances of this type will also be queued.")
SSgarbage.QueueForQueuing(D)
#endif
I.no_hint++
SSgarbage.PreQueue(D)
else if(D.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)
CRASH("[D.type] destroy proc was called multiple times, likely due to a qdel loop in the Destroy logic")
@@ -281,15 +374,6 @@ SUBSYSTEM_DEF(garbage)
SSgarbage.can_fire = 1
SSgarbage.next_fire = world.time + world.tick_lag
/client/verb/purge_all_destroyed_objects()
set category = "Debug"
while(SSgarbage.queue.len)
var/datum/o = locate(SSgarbage.queue[1])
if(istype(o) && o.gc_destroyed)
del(o)
SSgarbage.totaldels++
SSgarbage.queue.Cut(1, 2)
/datum/verb/qdel_then_find_references()
set category = "Debug"
set name = "qdel() then Find References"
@@ -300,24 +384,6 @@ SUBSYSTEM_DEF(garbage)
if(!running_find_references)
find_references(TRUE)
/client/verb/show_qdeleted()
set category = "Debug"
set name = "Show qdel() Log"
set desc = "Render the qdel() log and display it"
var/dat = "<B>List of things that have been qdel()eted this round</B><BR><BR>"
var/tmplist = list()
for(var/elem in SSgarbage.qdel_list)
if(!(elem in tmplist))
tmplist[elem] = 0
tmplist[elem]++
for(var/path in tmplist)
dat += "[path] - [tmplist[path]] times<BR>"
usr << browse(dat, "window=qdeletedlog")
/datum/proc/DoSearchVar(X, Xname)
if(usr && usr.client && !usr.client.running_find_references) return
if(istype(X, /datum))
+2 -1
View File
@@ -40,6 +40,7 @@ SUBSYSTEM_DEF(machines)
var/obj/machinery/thing = currentrun[currentrun.len]
currentrun.len--
if(!QDELETED(thing) && thing.process(seconds) != PROCESS_KILL)
thing.SendSignal(COMSIG_MACHINE_PROCESS)
if(thing.use_power)
thing.auto_use_power() //add back the power state
else
@@ -61,4 +62,4 @@ SUBSYSTEM_DEF(machines)
if (istype(SSmachines.processing))
processing = SSmachines.processing
if (istype(SSmachines.powernets))
powernets = SSmachines.powernets
powernets = SSmachines.powernets
+1 -1
View File
@@ -117,7 +117,7 @@ SUBSYSTEM_DEF(mapping)
var/start_time = REALTIMEOFDAY
INIT_ANNOUNCE("Loading [config.map_name]...")
TryLoadZ(config.GetFullMapPath(), FailedZs, ZLEVEL_STATION)
TryLoadZ(config.GetFullMapPath(), FailedZs, ZLEVEL_STATION_PRIMARY)
INIT_ANNOUNCE("Loaded station in [(REALTIMEOFDAY - start_time)/10]s!")
if(SSdbcore.Connect())
var/datum/DBQuery/query_round_map_name = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET map_name = '[config.map_name]' WHERE id = [GLOB.round_id]")
+1 -1
View File
@@ -5,7 +5,7 @@ SUBSYSTEM_DEF(minimap)
var/const/MINIMAP_SIZE = 2048
var/const/TILE_SIZE = 8
var/list/z_levels = list(ZLEVEL_STATION)
var/list/z_levels = list(ZLEVEL_STATION_PRIMARY)
/datum/controller/subsystem/minimap/Initialize(timeofday)
var/hash = md5(SSmapping.config.GetFullMapPath())
+4 -4
View File
@@ -35,7 +35,7 @@ SUBSYSTEM_DEF(persistence)
if(chosen_satchel.len == 3)
F.x = text2num(chosen_satchel[1])
F.y = text2num(chosen_satchel[2])
F.z = ZLEVEL_STATION
F.z = ZLEVEL_STATION_PRIMARY
path = text2path(chosen_satchel[3])
else
var/json_file = file("data/npc_saves/SecretSatchels[SSmapping.config.map_name].json")
@@ -50,7 +50,7 @@ SUBSYSTEM_DEF(persistence)
old_secret_satchels.Cut(pos, pos+1)
F.x = old_secret_satchels[pos]["x"]
F.y = old_secret_satchels[pos]["y"]
F.z = ZLEVEL_STATION
F.z = ZLEVEL_STATION_PRIMARY
path = text2path(old_secret_satchels[pos]["saved_obj"])
if(!ispath(path))
return
@@ -59,7 +59,7 @@ SUBSYSTEM_DEF(persistence)
new path(F)
placed_satchel++
var/list/free_satchels = list()
for(var/turf/T in shuffle(block(locate(TRANSITIONEDGE,TRANSITIONEDGE,ZLEVEL_STATION), locate(world.maxx-TRANSITIONEDGE,world.maxy-TRANSITIONEDGE,ZLEVEL_STATION)))) //Nontrivially expensive but it's roundstart only
for(var/turf/T in shuffle(block(locate(TRANSITIONEDGE,TRANSITIONEDGE,ZLEVEL_STATION_PRIMARY), locate(world.maxx-TRANSITIONEDGE,world.maxy-TRANSITIONEDGE,ZLEVEL_STATION_PRIMARY)))) //Nontrivially expensive but it's roundstart only
if(isfloorturf(T) && !istype(T, /turf/open/floor/plating/))
free_satchels += new /obj/item/storage/backpack/satchel/flat/secret(T)
if(!isemptylist(free_satchels) && ((free_satchels.len + placed_satchel) >= (50 - old_secret_satchels.len) * 0.1)) //up to six tiles, more than enough to kill anything that moves
@@ -171,7 +171,7 @@ SUBSYSTEM_DEF(persistence)
satchel_blacklist = typecacheof(list(/obj/item/stack/tile/plasteel, /obj/item/crowbar))
for(var/A in new_secret_satchels)
var/obj/item/storage/backpack/satchel/flat/F = A
if(QDELETED(F) || F.z != ZLEVEL_STATION || F.invisibility != INVISIBILITY_MAXIMUM)
if(QDELETED(F) || F.z != ZLEVEL_STATION_PRIMARY || F.invisibility != INVISIBILITY_MAXIMUM)
continue
var/list/savable_obj = list()
for(var/obj/O in F)
@@ -1,30 +0,0 @@
diff a/code/controllers/subsystem/server_maint.dm b/code/controllers/subsystem/server_maint.dm (rejected hunks)
@@ -6,18 +6,16 @@ SUBSYSTEM_DEF(server_maint)
flags = SS_POST_FIRE_TIMING|SS_FIRE_IN_LOBBY
priority = 10
var/list/currentrun
- var/triggertime = null
/datum/controller/subsystem/server_maint/Initialize(timeofday)
if (config.hub)
world.visibility = 1
- triggertime = REALTIMEOFDAY
..()
/datum/controller/subsystem/server_maint/fire(resumed = FALSE)
if(!resumed)
src.currentrun = GLOB.clients.Copy()
-
+
var/list/currentrun = src.currentrun
var/round_started = SSticker.HasRoundStarted()
@@ -39,8 +37,3 @@ SUBSYSTEM_DEF(server_maint)
return
#undef PING_BUFFER_TIME
- if(config.sql_enabled)
- sql_poll_population()
- if(config.use_exp_tracking)
- if(REALTIMEOFDAY > (triggertime +3000)) //server maint fires once at roundstart then once every 10 minutes. a 5 min check skips the first fire
- update_exp(10,0)
+4 -4
View File
@@ -290,7 +290,7 @@ SUBSYSTEM_DEF(shuttle)
continue
var/turf/T = get_turf(thing)
if(T && T.z == ZLEVEL_STATION)
if(T && (T.z in GLOB.station_z_levels))
callShuttle = 0
break
@@ -341,7 +341,7 @@ SUBSYSTEM_DEF(shuttle)
if(M.request(getDock(destination)))
return 2
else
if(M.dock(getDock(destination)))
if(M.dock(getDock(destination)) != DOCKING_SUCCESS)
return 2
return 0 //dock successful
@@ -356,7 +356,7 @@ SUBSYSTEM_DEF(shuttle)
if(M.request(D))
return 2
else
if(M.dock(D))
if(M.dock(D) != DOCKING_SUCCESS)
return 2
return 0 //dock successful
@@ -384,7 +384,7 @@ SUBSYSTEM_DEF(shuttle)
var/travel_dir = M.preferred_direction
// Remember, the direction is the direction we appear to be
// coming from
var/dock_angle = dir2angle(M.preferred_direction) + M.port_angle + 180
var/dock_angle = dir2angle(M.preferred_direction) + dir2angle(M.port_direction) + 180
var/dock_dir = angle2dir(dock_angle)
var/transit_width = SHUTTLE_TRANSIT_BORDER * 2
+20 -16
View File
@@ -69,6 +69,9 @@ SUBSYSTEM_DEF(ticker)
/datum/controller/subsystem/ticker/Initialize(timeofday)
load_mode()
var/list/music = world.file2list(ROUND_START_MUSIC_LIST, "\n")
var/old_login_music = trim(file2text("data/last_round_lobby_music.txt"))
if(music.len > 1)
music -= old_login_music
login_music = pick(music)
if(!GLOB.syndicate_code_phrase)
@@ -136,7 +139,8 @@ SUBSYSTEM_DEF(ticker)
if(!mode.explosion_in_progress && mode.check_finished(force_ending) || force_ending)
current_state = GAME_STATE_FINISHED
toggle_ooc(1) // Turn it on
toggle_ooc(TRUE) // Turn it on
toggle_dooc(TRUE)
declare_completion(force_ending)
Master.SetRunLevel(RUNLEVEL_POSTGAME)
@@ -163,6 +167,8 @@ SUBSYSTEM_DEF(ticker)
to_chat(world, "<B>Unable to choose playable game mode.</B> Reverting to pre-game lobby.")
return 0
mode = pickweight(runnable_modes)
if(!mode) //too few roundtypes all run too recently
mode = pick(runnable_modes)
else
mode = config.pick_mode(GLOB.master_mode)
@@ -202,7 +208,7 @@ SUBSYSTEM_DEF(ticker)
mode.announce()
if(!config.ooc_during_round)
toggle_ooc(0) // Turn it off
toggle_ooc(FALSE) // Turn it off
CHECK_TICK
GLOB.start_landmarks_list = shuffle(GLOB.start_landmarks_list) //Shuffle the order of spawn points so they dont always predictably spawn bottom-up and right-to-left
@@ -238,10 +244,10 @@ SUBSYSTEM_DEF(ticker)
PostSetup()
return 1
return TRUE
/datum/controller/subsystem/ticker/proc/PostSetup()
set waitfor = 0
set waitfor = FALSE
mode.post_setup()
GLOB.start_state = new /datum/station_state()
GLOB.start_state.count(1)
@@ -315,11 +321,6 @@ SUBSYSTEM_DEF(ticker)
flick("station_corrupted",cinematic)
SEND_SOUND(world, sound('sound/effects/ghost.ogg'))
actually_blew_up = FALSE
if("gang war") //Gang Domination (just show the override screen)
cinematic.icon_state = "intro_malf_still"
flick("intro_malf",cinematic)
actually_blew_up = FALSE
sleep(70)
if("fake") //The round isn't over, we're just freaking people out for fun
flick("intro_nuke",cinematic)
sleep(35)
@@ -392,7 +393,7 @@ SUBSYSTEM_DEF(ticker)
if(bomb && bomb.loc)
bombloc = bomb.z
else if(!station_missed)
bombloc = ZLEVEL_STATION
bombloc = ZLEVEL_STATION_PRIMARY
if(mode)
mode.explosion_in_progress = 0
@@ -470,6 +471,12 @@ SUBSYSTEM_DEF(ticker)
to_chat(world, "<BR><BR><BR><FONT size=3><B>The round has ended.</B></FONT>")
/* var/nocredits = config.no_credits_round_end
for(var/client/C in GLOB.clients)
if(!C.credits && !nocredits)
C.RollCredits()
C.playtitlemusic(40)*/
//Player status report
for(var/mob/Player in GLOB.mob_list)
if(Player.mind && !isnewplayer(Player))
@@ -518,7 +525,7 @@ SUBSYSTEM_DEF(ticker)
//Silicon laws report
for (var/mob/living/silicon/ai/aiPlayer in GLOB.mob_list)
if (aiPlayer.stat != 2 && aiPlayer.mind)
if (aiPlayer.stat != DEAD && aiPlayer.mind)
to_chat(world, "<b>[aiPlayer.name] (Played by: [aiPlayer.mind.key])'s laws at the end of the round were:</b>")
aiPlayer.show_laws(1)
else if (aiPlayer.mind) //if the dead ai has a mind, use its key instead
@@ -538,7 +545,7 @@ SUBSYSTEM_DEF(ticker)
for (var/mob/living/silicon/robot/robo in GLOB.mob_list)
if (!robo.connected_ai && robo.mind)
if (robo.stat != 2)
if (robo.stat != DEAD)
to_chat(world, "<b>[robo.name] (Played by: [robo.mind.key]) survived as an AI-less borg! Its laws were:</b>")
else
to_chat(world, "<b>[robo.name] (Played by: [robo.mind.key]) was unable to survive the rigors of being a cyborg without an AI. Its laws were:</b>")
@@ -733,10 +740,6 @@ SUBSYSTEM_DEF(ticker)
news_message = "We would like to reassure all employees that the reports of a Syndicate backed nuclear attack on [station_name()] are, in fact, a hoax. Have a secure day!"
if(STATION_EVACUATED)
news_message = "The crew of [station_name()] has been evacuated amid unconfirmed reports of enemy activity."
if(GANG_LOSS)
news_message = "Organized crime aboard [station_name()] has been stamped out by members of our ever vigilant security team. Remember to thank your assigned officers today!"
if(GANG_TAKEOVER)
news_message = "Contact with [station_name()] has been lost after a sophisticated hacking attack by organized criminal elements. Stay vigilant!"
if(BLOB_WIN)
news_message = "[station_name()] was overcome by an unknown biological outbreak, killing all crew on board. Don't let it happen to you! Remember, a clean work station is a safe work station."
if(BLOB_NUKE)
@@ -859,3 +862,4 @@ SUBSYSTEM_DEF(ticker)
)
SEND_SOUND(world, sound(round_end_sound))
text2file(login_music, "data/last_round_lobby_music.txt")
+10 -5
View File
@@ -69,7 +69,7 @@ SUBSYSTEM_DEF(timer)
if (ctime_timer.timeToRun <= REALTIMEOFDAY)
--clienttime_timers.len
var/datum/callback/callBack = ctime_timer.callBack
ctime_timer.spent = TRUE
ctime_timer.spent = REALTIMEOFDAY
callBack.InvokeAsync()
qdel(ctime_timer)
else
@@ -105,11 +105,11 @@ SUBSYSTEM_DEF(timer)
if (!callBack)
qdel(timer)
bucket_resolution = null //force bucket recreation
CRASH("Invalid timer: [timer] timer.timeToRun=[timer.timeToRun]||QDELETED(timer)=[QDELETED(timer)]||world.time=[world.time]||head_offset=[head_offset]||practical_offset=[practical_offset]||timer.spent=[timer.spent]")
CRASH("Invalid timer: [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
if (!timer.spent)
spent += timer
timer.spent = TRUE
timer.spent = world.time
callBack.InvokeAsync()
last_invoke_tick = world.time
@@ -135,9 +135,11 @@ SUBSYSTEM_DEF(timer)
. = "Timer: [TE]"
. += "Prev: [TE.prev ? TE.prev : "NULL"], Next: [TE.next ? TE.next : "NULL"]"
if(TE.spent)
. += ", SPENT"
. += ", SPENT([TE.spent])"
if(QDELETED(TE))
. += ", QDELETED"
if(!TE.callBack)
. += ", NO CALLBACK"
/datum/controller/subsystem/timer/proc/shift_buckets()
var/list/bucket_list = src.bucket_list
@@ -216,7 +218,7 @@ SUBSYSTEM_DEF(timer)
var/timeToRun
var/hash
var/list/flags
var/spent = FALSE //set to true right before running.
var/spent = 0 //time we ran the timer.
var/name //for easy debugging.
//cicular doublely linked list
var/datum/timedevent/next
@@ -243,6 +245,9 @@ SUBSYSTEM_DEF(timer)
name = "Timer: " + num2text(id, 8) + ", TTR: [timeToRun], Flags: [jointext(bitfield2list(flags, list("TIMER_UNIQUE", "TIMER_OVERRIDE", "TIMER_CLIENT_TIME", "TIMER_STOPPABLE", "TIMER_NO_HASH_WAIT")), ", ")], callBack: \ref[callBack], callBack.object: [callBack.object]\ref[callBack.object]([getcallingtype()]), callBack.delegate:[callBack.delegate]([callBack.arguments ? callBack.arguments.Join(", ") : ""])"
if (spent)
CRASH("HOLY JESUS. WHAT IS THAT? WHAT THE FUCK IS THAT?")
if (callBack.object != GLOBAL_PROC)
LAZYADD(callBack.object.active_timers, src)
+3 -4
View File
@@ -14,8 +14,8 @@ SUBSYSTEM_DEF(weather)
if(W.aesthetic)
continue
for(var/mob/living/L in GLOB.mob_list)
if(W.can_impact(L))
W.impact(L)
if(W.can_weather_act(L))
W.weather_act(L)
for(var/Z in eligible_zlevels)
var/list/possible_weather_for_this_z = list()
for(var/V in existing_weather)
@@ -30,8 +30,7 @@ SUBSYSTEM_DEF(weather)
/datum/controller/subsystem/weather/Initialize(start_timeofday)
..()
for(var/V in subtypesof(/datum/weather))
var/datum/weather/W = V
new W //weather->New will handle adding itself to the list
new V //Weather's New() will handle adding stuff to the list
/datum/controller/subsystem/weather/proc/run_weather(weather_name, Z)
if(!weather_name)
+1 -1
View File
@@ -421,7 +421,7 @@
/datum/action/item_action/ninjapulse
name = "EM Burst (25E)"
desc = "Disable any nearby technology with a electro-magnetic pulse."
desc = "Disable any nearby technology with an electro-magnetic pulse."
button_icon_state = "emp"
icon_icon = 'icons/mob/actions/actions_spells.dmi'
+48
View File
@@ -0,0 +1,48 @@
/datum/antagonist/brother
name = "Brother"
var/special_role = "blood brother"
var/datum/objective_team/brother_team/team
/datum/antagonist/brother/New(datum/mind/new_owner, datum/objective_team/brother_team/T)
team = T
return ..()
/datum/antagonist/brother/on_gain()
SSticker.mode.brothers += owner
owner.special_role = special_role
owner.objectives += team.objectives
finalize_brother()
return ..()
/datum/antagonist/brother/on_removal()
SSticker.mode.brothers -= owner
team.members -= owner
owner.objectives -= team.objectives
if(owner.current)
to_chat(owner.current,"<span class='userdanger'>You are no longer the [special_role]!</span>")
owner.special_role = null
return ..()
/datum/antagonist/brother/proc/give_meeting_area()
if(!owner.current || !team || !team.meeting_area)
return
to_chat(owner.current, "<B>Your designated meeting area:</B> [team.meeting_area]")
owner.store_memory("<b>Meeting Area</b>: [team.meeting_area]")
/datum/antagonist/brother/greet()
var/brother_text = ""
var/list/brothers = team.members - owner
for(var/i = 1 to brothers.len)
var/datum/mind/M = brothers[i]
brother_text += M.name
if(i == brothers.len - 1)
brother_text += " and "
else if(i != brothers.len)
brother_text += ", "
to_chat(owner.current, "<B><font size=3 color=red>You are the [owner.special_role] of [brother_text].</font></B>")
to_chat(owner.current, "The Syndicate only accepts those that have proven themself. Prove yourself and prove your [team.member_name]s by completing your objectives together!")
owner.announce_objectives()
give_meeting_area()
/datum/antagonist/brother/proc/finalize_brother()
SSticker.mode.update_brother_icons_added(owner)
+1 -1
View File
@@ -40,7 +40,7 @@
if(!GLOB.summon_spots.len)
while(GLOB.summon_spots.len < SUMMON_POSSIBILITIES)
var/area/summon = pick(GLOB.sortedAreas - GLOB.summon_spots)
if(summon && (summon.z == ZLEVEL_STATION) && summon.valid_territory)
if(summon && (summon.z in GLOB.station_z_levels) && summon.valid_territory)
GLOB.summon_spots += summon
SSticker.mode.cult_objectives += "eldergod"
+7 -7
View File
@@ -164,7 +164,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
update_hud()
switch(SOULVALUE)
if(0)
to_chat(owner.current, "<span class='warning'>Your hellish powers have been restored.")
to_chat(owner.current, "<span class='warning'>Your hellish powers have been restored.</span>")
give_appropriate_spells()
if(BLOOD_THRESHOLD)
increase_blood_lizard()
@@ -189,10 +189,10 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
regress_humanoid()
if(SOULVALUE < 0)
give_appropriate_spells()
to_chat(owner.current, "<span class='warning'>As punishment for your failures, all of your powers except contract creation have been revoked.")
to_chat(owner.current, "<span class='warning'>As punishment for your failures, all of your powers except contract creation have been revoked.</span>")
/datum/antagonist/devil/proc/regress_humanoid()
to_chat(owner.current, "<span class='warning'>Your powers weaken, have more contracts be signed to regain power.")
to_chat(owner.current, "<span class='warning'>Your powers weaken, have more contracts be signed to regain power.</span>")
if(ishuman(owner.current))
var/mob/living/carbon/human/H = owner.current
H.set_species(/datum/species/human, 1)
@@ -204,7 +204,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
/datum/antagonist/devil/proc/regress_blood_lizard()
var/mob/living/carbon/true_devil/D = owner.current
to_chat(D, "<span class='warning'>Your powers weaken, have more contracts be signed to regain power.")
to_chat(D, "<span class='warning'>Your powers weaken, have more contracts be signed to regain power.</span>")
D.oldform.loc = D.loc
owner.transfer_to(D.oldform)
give_appropriate_spells()
@@ -214,7 +214,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
/datum/antagonist/devil/proc/increase_blood_lizard()
to_chat(owner.current, "<span class='warning'>You feel as though your humanoid form is about to shed. You will soon turn into a blood lizard.")
to_chat(owner.current, "<span class='warning'>You feel as though your humanoid form is about to shed. You will soon turn into a blood lizard.</span>")
sleep(50)
if(ishuman(owner.current))
var/mob/living/carbon/human/H = owner.current
@@ -232,7 +232,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
/datum/antagonist/devil/proc/increase_true_devil()
to_chat(owner.current, "<span class='warning'>You feel as though your current form is about to shed. You will soon turn into a true devil.")
to_chat(owner.current, "<span class='warning'>You feel as though your current form is about to shed. You will soon turn into a true devil.</span>")
sleep(50)
var/mob/living/carbon/true_devil/A = new /mob/living/carbon/true_devil(owner.current.loc)
A.faction |= "hell"
@@ -248,7 +248,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
if(!ascendable)
return
var/mob/living/carbon/true_devil/D = owner.current
to_chat(D, "<span class='warning'>You feel as though your form is about to ascend.")
to_chat(D, "<span class='warning'>You feel as though your form is about to ascend.</span>")
sleep(50)
if(!D)
return
+1 -1
View File
@@ -131,7 +131,7 @@
//runs a list of callbacks asynchronously, returning once all of them return.
//callbacks can be repeated.
//callbacks-args is a optional list of argument lists, in the same order as the callbacks,
//callbacks-args is an optional list of argument lists, in the same order as the callbacks,
// the inner lists will be sent to the callbacks when invoked() as additional args.
//can optionly save and return a list of return values, in the same order as the original list of callbacks
//resolution is the number of byond ticks between checks.
+92
View File
@@ -0,0 +1,92 @@
/datum/component/archaeology
dupe_type = COMPONENT_DUPE_UNIQUE
var/list/archdrops
var/prob2drop
var/dug
/datum/component/archaeology/Initialize(_prob2drop, list/_archdrops = list())
prob2drop = Clamp(_prob2drop, 0, 100)
archdrops = _archdrops
RegisterSignal(COMSIG_PARENT_ATTACKBY,.proc/Dig)
RegisterSignal(COMSIG_ATOM_EX_ACT, .proc/BombDig)
RegisterSignal(COMSIG_ATOM_SING_PULL, .proc/SingDig)
/datum/component/archaeology/InheritComponent(datum/component/archaeology/A, i_am_original)
var/list/other_archdrops = A.archdrops
var/list/_archdrops = archdrops
for(var/I in other_archdrops)
_archdrops[I] += other_archdrops[I]
/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
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
/datum/component/archaeology/proc/gets_dug()
if(dug)
return
else
var/turf/open/OT = get_turf(parent)
for(var/thing in archdrops)
var/maxtodrop = archdrops[thing]
for(var/i in 1 to maxtodrop)
if(prob(prob2drop)) // can't win them all!
new thing(OT)
if(isopenturf(OT))
if(OT.postdig_icon_change)
if(istype(OT, /turf/open/floor/plating/asteroid/) && !OT.postdig_icon)
var/turf/open/floor/plating/asteroid/AOT = parent
AOT.icon_plating = "[AOT.environment_type]_dug"
AOT.icon_state = "[AOT.environment_type]_dug"
else
if(isplatingturf(OT))
var/turf/open/floor/plating/POT = parent
POT.icon_plating = "[POT.postdig_icon]"
POT.icon_state = "[OT.postdig_icon]"
if(OT.slowdown) //Things like snow slow you down until you dig them.
OT.slowdown = 0
dug = TRUE
/datum/component/archaeology/proc/SingDig(S, current_size)
switch(current_size)
if(STAGE_THREE)
if(prob(30))
gets_dug()
if(STAGE_FOUR)
if(prob(50))
gets_dug()
else
if(current_size >= STAGE_FIVE && prob(70))
gets_dug()
/datum/component/archaeology/proc/BombDig(severity, target)
switch(severity)
if(3)
return
if(2)
if(prob(20))
gets_dug()
if(1)
gets_dug()
+287 -287
View File
@@ -1,287 +1,287 @@
/datum/datacore
var/medical[] = list()
var/medicalPrintCount = 0
var/general[] = list()
var/security[] = list()
var/securityPrintCount = 0
var/securityCrimeCounter = 0
//This list tracks characters spawned in the world and cannot be modified in-game. Currently referenced by respawn_character().
var/locked[] = list()
/datum/data
var/name = "data"
/datum/data/record
name = "record"
var/list/fields = list()
/datum/data/record/Destroy()
if(src in GLOB.data_core.medical)
GLOB.data_core.medical -= src
if(src in GLOB.data_core.security)
GLOB.data_core.security -= src
if(src in GLOB.data_core.general)
GLOB.data_core.general -= src
if(src in GLOB.data_core.locked)
GLOB.data_core.locked -= src
. = ..()
/datum/data/crime
name = "crime"
var/crimeName = ""
var/crimeDetails = ""
var/author = ""
var/time = ""
var/dataId = 0
/datum/datacore/proc/createCrimeEntry(cname = "", cdetails = "", author = "", time = "")
var/datum/data/crime/c = new /datum/data/crime
c.crimeName = cname
c.crimeDetails = cdetails
c.author = author
c.time = time
c.dataId = ++securityCrimeCounter
return c
/datum/datacore/proc/addMinorCrime(id = "", datum/data/crime/crime)
for(var/datum/data/record/R in security)
if(R.fields["id"] == id)
var/list/crimes = R.fields["mi_crim"]
crimes |= crime
return
/datum/datacore/proc/removeMinorCrime(id, cDataId)
for(var/datum/data/record/R in security)
if(R.fields["id"] == id)
var/list/crimes = R.fields["mi_crim"]
for(var/datum/data/crime/crime in crimes)
if(crime.dataId == text2num(cDataId))
crimes -= crime
return
/datum/datacore/proc/removeMajorCrime(id, cDataId)
for(var/datum/data/record/R in security)
if(R.fields["id"] == id)
var/list/crimes = R.fields["ma_crim"]
for(var/datum/data/crime/crime in crimes)
if(crime.dataId == text2num(cDataId))
crimes -= crime
return
/datum/datacore/proc/addMajorCrime(id = "", datum/data/crime/crime)
for(var/datum/data/record/R in security)
if(R.fields["id"] == id)
var/list/crimes = R.fields["ma_crim"]
crimes |= crime
return
/datum/datacore/proc/manifest()
for(var/mob/dead/new_player/N in GLOB.player_list)
if(ishuman(N.new_character))
manifest_inject(N.new_character, N.client)
CHECK_TICK
/datum/datacore/proc/manifest_modify(name, assignment)
var/datum/data/record/foundrecord = find_record("name", name, GLOB.data_core.general)
if(foundrecord)
foundrecord.fields["rank"] = assignment
/datum/datacore/proc/get_manifest(monochrome, OOC)
var/list/heads = list()
var/list/sec = list()
var/list/eng = list()
var/list/med = list()
var/list/sci = list()
var/list/sup = list()
var/list/civ = list()
var/list/bot = list()
var/list/misc = list()
var/dat = {"
<head><style>
.manifest {border-collapse:collapse;}
.manifest td, th {border:1px solid [monochrome?"black":"#DEF; background-color:white; color:black"]; padding:.25em}
.manifest th {height: 2em; [monochrome?"border-top-width: 3px":"background-color: #48C; color:white"]}
.manifest tr.head th { [monochrome?"border-top-width: 1px":"background-color: #488;"] }
.manifest td:first-child {text-align:right}
.manifest tr.alt td {[monochrome?"border-top-width: 2px":"background-color: #DEF"]}
</style></head>
<table class="manifest" width='350px'>
<tr class='head'><th>Name</th><th>Rank</th></tr>
"}
var/even = 0
// sort mobs
for(var/datum/data/record/t in GLOB.data_core.general)
var/name = t.fields["name"]
var/rank = t.fields["rank"]
var/department = 0
if(rank in GLOB.command_positions)
heads[name] = rank
department = 1
if(rank in GLOB.security_positions)
sec[name] = rank
department = 1
if(rank in GLOB.engineering_positions)
eng[name] = rank
department = 1
if(rank in GLOB.medical_positions)
med[name] = rank
department = 1
if(rank in GLOB.science_positions)
sci[name] = rank
department = 1
if(rank in GLOB.supply_positions)
sup[name] = rank
department = 1
if(rank in GLOB.civilian_positions)
civ[name] = rank
department = 1
if(rank in GLOB.nonhuman_positions)
bot[name] = rank
department = 1
if(!department && !(name in heads))
misc[name] = rank
if(heads.len > 0)
dat += "<tr><th colspan=3>Heads</th></tr>"
for(var/name in heads)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[heads[name]]</td></tr>"
even = !even
if(sec.len > 0)
dat += "<tr><th colspan=3>Security</th></tr>"
for(var/name in sec)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[sec[name]]</td></tr>"
even = !even
if(eng.len > 0)
dat += "<tr><th colspan=3>Engineering</th></tr>"
for(var/name in eng)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[eng[name]]</td></tr>"
even = !even
if(med.len > 0)
dat += "<tr><th colspan=3>Medical</th></tr>"
for(var/name in med)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[med[name]]</td></tr>"
even = !even
if(sci.len > 0)
dat += "<tr><th colspan=3>Science</th></tr>"
for(var/name in sci)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[sci[name]]</td></tr>"
even = !even
if(sup.len > 0)
dat += "<tr><th colspan=3>Supply</th></tr>"
for(var/name in sup)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[sup[name]]</td></tr>"
even = !even
if(civ.len > 0)
dat += "<tr><th colspan=3>Civilian</th></tr>"
for(var/name in civ)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[civ[name]]</td></tr>"
even = !even
// in case somebody is insane and added them to the manifest, why not
if(bot.len > 0)
dat += "<tr><th colspan=3>Silicon</th></tr>"
for(var/name in bot)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[bot[name]]</td></tr>"
even = !even
// misc guys
if(misc.len > 0)
dat += "<tr><th colspan=3>Miscellaneous</th></tr>"
for(var/name in misc)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[misc[name]]</td></tr>"
even = !even
dat += "</table>"
dat = replacetext(dat, "\n", "")
dat = replacetext(dat, "\t", "")
return dat
/datum/datacore/proc/manifest_inject(mob/living/carbon/human/H, client/C)
if(H.mind && (H.mind.assigned_role != H.mind.special_role))
var/assignment
if(H.mind.assigned_role)
assignment = H.mind.assigned_role
else if(H.job)
assignment = H.job
else
assignment = "Unassigned"
var/static/record_id_num = 1001
var/id = num2hex(record_id_num++,6)
if(!C)
C = H.client
var/image = get_id_photo(H, C)
var/obj/item/photo/photo_front = new()
var/obj/item/photo/photo_side = new()
photo_front.photocreate(null, icon(image, dir = SOUTH))
photo_side.photocreate(null, icon(image, dir = WEST))
//These records should ~really~ be merged or something
//General Record
var/datum/data/record/G = new()
G.fields["id"] = id
G.fields["name"] = H.real_name
G.fields["rank"] = assignment
G.fields["age"] = H.age
if(config.mutant_races)
G.fields["species"] = H.dna.species.name
G.fields["fingerprint"] = md5(H.dna.uni_identity)
G.fields["p_stat"] = "Active"
G.fields["m_stat"] = "Stable"
G.fields["sex"] = H.gender
G.fields["photo_front"] = photo_front
G.fields["photo_side"] = photo_side
general += G
//Medical Record
var/datum/data/record/M = new()
M.fields["id"] = id
M.fields["name"] = H.real_name
M.fields["blood_type"] = H.dna.blood_type
M.fields["b_dna"] = H.dna.unique_enzymes
M.fields["mi_dis"] = "None"
M.fields["mi_dis_d"] = "No minor disabilities have been declared."
M.fields["ma_dis"] = "None"
M.fields["ma_dis_d"] = "No major disabilities have been diagnosed."
M.fields["alg"] = "None"
M.fields["alg_d"] = "No allergies have been detected in this patient."
M.fields["cdi"] = "None"
M.fields["cdi_d"] = "No diseases have been diagnosed at the moment."
M.fields["notes"] = "No notes."
medical += M
//Security Record
var/datum/data/record/S = new()
S.fields["id"] = id
S.fields["name"] = H.real_name
S.fields["criminal"] = "None"
S.fields["mi_crim"] = list()
S.fields["ma_crim"] = list()
S.fields["notes"] = "No notes."
security += S
//Locked Record
var/datum/data/record/L = new()
L.fields["id"] = md5("[H.real_name][H.mind.assigned_role]") //surely this should just be id, like the others?
L.fields["name"] = H.real_name
L.fields["rank"] = H.mind.assigned_role
L.fields["age"] = H.age
L.fields["sex"] = H.gender
L.fields["blood_type"] = H.dna.blood_type
L.fields["b_dna"] = H.dna.unique_enzymes
L.fields["enzymes"] = H.dna.struc_enzymes
L.fields["identity"] = H.dna.uni_identity
L.fields["species"] = H.dna.species.type
L.fields["features"] = H.dna.features
L.fields["image"] = image
L.fields["reference"] = H
locked += L
return
/datum/datacore/proc/get_id_photo(mob/living/carbon/human/H, client/C)
var/datum/job/J = SSjob.GetJob(H.mind.assigned_role)
var/datum/preferences/P
if(!C)
C = H.client
if(C)
P = C.prefs
return get_flat_human_icon(null, J, P)
/datum/datacore
var/medical[] = list()
var/medicalPrintCount = 0
var/general[] = list()
var/security[] = list()
var/securityPrintCount = 0
var/securityCrimeCounter = 0
//This list tracks characters spawned in the world and cannot be modified in-game. Currently referenced by respawn_character().
var/locked[] = list()
/datum/data
var/name = "data"
/datum/data/record
name = "record"
var/list/fields = list()
/datum/data/record/Destroy()
if(src in GLOB.data_core.medical)
GLOB.data_core.medical -= src
if(src in GLOB.data_core.security)
GLOB.data_core.security -= src
if(src in GLOB.data_core.general)
GLOB.data_core.general -= src
if(src in GLOB.data_core.locked)
GLOB.data_core.locked -= src
. = ..()
/datum/data/crime
name = "crime"
var/crimeName = ""
var/crimeDetails = ""
var/author = ""
var/time = ""
var/dataId = 0
/datum/datacore/proc/createCrimeEntry(cname = "", cdetails = "", author = "", time = "")
var/datum/data/crime/c = new /datum/data/crime
c.crimeName = cname
c.crimeDetails = cdetails
c.author = author
c.time = time
c.dataId = ++securityCrimeCounter
return c
/datum/datacore/proc/addMinorCrime(id = "", datum/data/crime/crime)
for(var/datum/data/record/R in security)
if(R.fields["id"] == id)
var/list/crimes = R.fields["mi_crim"]
crimes |= crime
return
/datum/datacore/proc/removeMinorCrime(id, cDataId)
for(var/datum/data/record/R in security)
if(R.fields["id"] == id)
var/list/crimes = R.fields["mi_crim"]
for(var/datum/data/crime/crime in crimes)
if(crime.dataId == text2num(cDataId))
crimes -= crime
return
/datum/datacore/proc/removeMajorCrime(id, cDataId)
for(var/datum/data/record/R in security)
if(R.fields["id"] == id)
var/list/crimes = R.fields["ma_crim"]
for(var/datum/data/crime/crime in crimes)
if(crime.dataId == text2num(cDataId))
crimes -= crime
return
/datum/datacore/proc/addMajorCrime(id = "", datum/data/crime/crime)
for(var/datum/data/record/R in security)
if(R.fields["id"] == id)
var/list/crimes = R.fields["ma_crim"]
crimes |= crime
return
/datum/datacore/proc/manifest()
for(var/mob/dead/new_player/N in GLOB.player_list)
if(ishuman(N.new_character))
manifest_inject(N.new_character, N.client)
CHECK_TICK
/datum/datacore/proc/manifest_modify(name, assignment)
var/datum/data/record/foundrecord = find_record("name", name, GLOB.data_core.general)
if(foundrecord)
foundrecord.fields["rank"] = assignment
/datum/datacore/proc/get_manifest(monochrome, OOC)
var/list/heads = list()
var/list/sec = list()
var/list/eng = list()
var/list/med = list()
var/list/sci = list()
var/list/sup = list()
var/list/civ = list()
var/list/bot = list()
var/list/misc = list()
var/dat = {"
<head><style>
.manifest {border-collapse:collapse;}
.manifest td, th {border:1px solid [monochrome?"black":"#DEF; background-color:white; color:black"]; padding:.25em}
.manifest th {height: 2em; [monochrome?"border-top-width: 3px":"background-color: #48C; color:white"]}
.manifest tr.head th { [monochrome?"border-top-width: 1px":"background-color: #488;"] }
.manifest td:first-child {text-align:right}
.manifest tr.alt td {[monochrome?"border-top-width: 2px":"background-color: #DEF"]}
</style></head>
<table class="manifest" width='350px'>
<tr class='head'><th>Name</th><th>Rank</th></tr>
"}
var/even = 0
// sort mobs
for(var/datum/data/record/t in GLOB.data_core.general)
var/name = t.fields["name"]
var/rank = t.fields["rank"]
var/department = 0
if(rank in GLOB.command_positions)
heads[name] = rank
department = 1
if(rank in GLOB.security_positions)
sec[name] = rank
department = 1
if(rank in GLOB.engineering_positions)
eng[name] = rank
department = 1
if(rank in GLOB.medical_positions)
med[name] = rank
department = 1
if(rank in GLOB.science_positions)
sci[name] = rank
department = 1
if(rank in GLOB.supply_positions)
sup[name] = rank
department = 1
if(rank in GLOB.civilian_positions)
civ[name] = rank
department = 1
if(rank in GLOB.nonhuman_positions)
bot[name] = rank
department = 1
if(!department && !(name in heads))
misc[name] = rank
if(heads.len > 0)
dat += "<tr><th colspan=3>Heads</th></tr>"
for(var/name in heads)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[heads[name]]</td></tr>"
even = !even
if(sec.len > 0)
dat += "<tr><th colspan=3>Security</th></tr>"
for(var/name in sec)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[sec[name]]</td></tr>"
even = !even
if(eng.len > 0)
dat += "<tr><th colspan=3>Engineering</th></tr>"
for(var/name in eng)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[eng[name]]</td></tr>"
even = !even
if(med.len > 0)
dat += "<tr><th colspan=3>Medical</th></tr>"
for(var/name in med)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[med[name]]</td></tr>"
even = !even
if(sci.len > 0)
dat += "<tr><th colspan=3>Science</th></tr>"
for(var/name in sci)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[sci[name]]</td></tr>"
even = !even
if(sup.len > 0)
dat += "<tr><th colspan=3>Supply</th></tr>"
for(var/name in sup)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[sup[name]]</td></tr>"
even = !even
if(civ.len > 0)
dat += "<tr><th colspan=3>Civilian</th></tr>"
for(var/name in civ)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[civ[name]]</td></tr>"
even = !even
// in case somebody is insane and added them to the manifest, why not
if(bot.len > 0)
dat += "<tr><th colspan=3>Silicon</th></tr>"
for(var/name in bot)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[bot[name]]</td></tr>"
even = !even
// misc guys
if(misc.len > 0)
dat += "<tr><th colspan=3>Miscellaneous</th></tr>"
for(var/name in misc)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[misc[name]]</td></tr>"
even = !even
dat += "</table>"
dat = replacetext(dat, "\n", "")
dat = replacetext(dat, "\t", "")
return dat
/datum/datacore/proc/manifest_inject(mob/living/carbon/human/H, client/C)
set waitfor = FALSE
if(H.mind && (H.mind.assigned_role != H.mind.special_role))
var/assignment
if(H.mind.assigned_role)
assignment = H.mind.assigned_role
else if(H.job)
assignment = H.job
else
assignment = "Unassigned"
var/static/record_id_num = 1001
var/id = num2hex(record_id_num++,6)
if(!C)
C = H.client
var/image = get_id_photo(H, C)
var/obj/item/photo/photo_front = new()
var/obj/item/photo/photo_side = new()
photo_front.photocreate(null, icon(image, dir = SOUTH))
photo_side.photocreate(null, icon(image, dir = WEST))
//These records should ~really~ be merged or something
//General Record
var/datum/data/record/G = new()
G.fields["id"] = id
G.fields["name"] = H.real_name
G.fields["rank"] = assignment
G.fields["age"] = H.age
if(config.mutant_races)
G.fields["species"] = H.dna.species.name
G.fields["fingerprint"] = md5(H.dna.uni_identity)
G.fields["p_stat"] = "Active"
G.fields["m_stat"] = "Stable"
G.fields["sex"] = H.gender
G.fields["photo_front"] = photo_front
G.fields["photo_side"] = photo_side
general += G
//Medical Record
var/datum/data/record/M = new()
M.fields["id"] = id
M.fields["name"] = H.real_name
M.fields["blood_type"] = H.dna.blood_type
M.fields["b_dna"] = H.dna.unique_enzymes
M.fields["mi_dis"] = "None"
M.fields["mi_dis_d"] = "No minor disabilities have been declared."
M.fields["ma_dis"] = "None"
M.fields["ma_dis_d"] = "No major disabilities have been diagnosed."
M.fields["alg"] = "None"
M.fields["alg_d"] = "No allergies have been detected in this patient."
M.fields["cdi"] = "None"
M.fields["cdi_d"] = "No diseases have been diagnosed at the moment."
M.fields["notes"] = "No notes."
medical += M
//Security Record
var/datum/data/record/S = new()
S.fields["id"] = id
S.fields["name"] = H.real_name
S.fields["criminal"] = "None"
S.fields["mi_crim"] = list()
S.fields["ma_crim"] = list()
S.fields["notes"] = "No notes."
security += S
//Locked Record
var/datum/data/record/L = new()
L.fields["id"] = md5("[H.real_name][H.mind.assigned_role]") //surely this should just be id, like the others?
L.fields["name"] = H.real_name
L.fields["rank"] = H.mind.assigned_role
L.fields["age"] = H.age
L.fields["sex"] = H.gender
L.fields["blood_type"] = H.dna.blood_type
L.fields["b_dna"] = H.dna.unique_enzymes
L.fields["enzymes"] = H.dna.struc_enzymes
L.fields["identity"] = H.dna.uni_identity
L.fields["species"] = H.dna.species.type
L.fields["features"] = H.dna.features
L.fields["image"] = image
L.fields["mindref"] = H.mind
locked += L
return
/datum/datacore/proc/get_id_photo(mob/living/carbon/human/H, client/C)
var/datum/job/J = SSjob.GetJob(H.mind.assigned_role)
var/datum/preferences/P
if(!C)
C = H.client
if(C)
P = C.prefs
return get_flat_human_icon(null, J, P, DUMMY_HUMAN_SLOT_MANIFEST)
+1159 -1138
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -413,7 +413,7 @@
AD.Refresh()
for(var/mob/living/carbon/human/H in shuffle(GLOB.living_mob_list))
if(H.z != ZLEVEL_STATION)
if(!(H.z in GLOB.station_z_levels))
continue
if(!H.HasDisease(D))
H.ForceContractDisease(D)
+6 -6
View File
@@ -34,20 +34,20 @@
..(process, D, copy)
// Hullucigen
// Hallucigen
/datum/disease/advance/hullucigen/New(var/process = TRUE, var/datum/disease/advance/D, var/copy = FALSE)
/datum/disease/advance/hallucigen/New(var/process = TRUE, var/datum/disease/advance/D, var/copy = FALSE)
if(!D)
name = "Reality Impairment"
name = "Second Sight"
symptoms = list(new/datum/symptom/hallucigen)
..(process, D, copy)
// Sensory Restoration
/datum/disease/advance/sensory_restoration/New(var/process = TRUE, var/datum/disease/advance/D, var/copy = FALSE)
/datum/disease/advance/mind_restoration/New(var/process = TRUE, var/datum/disease/advance/D, var/copy = FALSE)
if(!D)
name = "Reality Enhancer"
symptoms = list(new/datum/symptom/sensory_restoration)
name = "Intelligence Booster"
symptoms = list(new/datum/symptom/mind_restoration)
..(process, D, copy)
// Sensory Destruction
@@ -17,6 +17,7 @@ BONUS
/datum/symptom/beard
name = "Facial Hypertrichosis"
desc = "The virus increases hair production significantly, causing rapid beard growth."
stealth = -3
resistance = -1
stage_speed = -3
@@ -18,6 +18,7 @@ Bonus
/datum/symptom/choking
name = "Choking"
desc = "The virus causes inflammation of the host's air conduits, leading to intermittent choking."
stealth = -3
resistance = -2
stage_speed = -2
@@ -27,6 +28,8 @@ Bonus
base_message_chance = 15
symptom_delay_min = 10
symptom_delay_max = 30
threshold_desc = "<b>Stage Speed 8:</b> Causes choking more frequently.<br>\
<b>Stealth 4:</b> The symptom remains hidden until active."
/datum/symptom/choking/Start(datum/disease/advance/A)
..()
@@ -84,6 +87,7 @@ Bonus
/datum/symptom/asphyxiation
name = "Acute respiratory distress syndrome"
desc = "The virus causes shrinking of the host's lungs, causing severe asphyxiation. May also lead to heart attacks."
stealth = -2
resistance = -0
stage_speed = -1
@@ -18,6 +18,7 @@ Bonus
/datum/symptom/confusion
name = "Confusion"
desc = "The virus interferes with the proper function of the neural system, leading to bouts of confusion and erratic movement."
stealth = 1
resistance = -1
stage_speed = -3
@@ -28,6 +29,9 @@ Bonus
symptom_delay_min = 10
symptom_delay_max = 30
var/brain_damage = FALSE
threshold_desc = "<b>Resistance 6:</b> Causes brain damage over time.<br>\
<b>Transmission 6:</b> Increases confusion duration.<br>\
<b>Stealth 4:</b> The symptom remains hidden until active."
/datum/symptom/confusion/Start(datum/disease/advance/A)
..()
@@ -18,6 +18,7 @@ BONUS
/datum/symptom/cough
name = "Cough"
desc = "The virus irritates the throat of the host, causing occasional coughing."
stealth = -1
resistance = 3
stage_speed = 1
@@ -28,6 +29,11 @@ BONUS
symptom_delay_min = 2
symptom_delay_max = 15
var/infective = FALSE
threshold_desc = "<b>Resistance 3:</b> Host will drop small items when coughing.<br>\
<b>Resistance 10:</b> Occasionally causes coughing fits that stun the host.<br>\
<b>Stage Speed 6:</b> Increases cough frequency.<br>\
<b>If Airborne:</b> Coughing will infect bystanders.<br>\
<b>Stealth 4:</b> The symptom remains hidden until active."
/datum/symptom/cough/Start(datum/disease/advance/A)
..()
@@ -18,6 +18,7 @@ Bonus
/datum/symptom/deafness
name = "Deafness"
desc = "The virus causes inflammation of the eardrums, causing intermittent deafness."
stealth = -1
resistance = -2
stage_speed = -1
@@ -27,6 +28,8 @@ Bonus
base_message_chance = 100
symptom_delay_min = 25
symptom_delay_max = 80
threshold_desc = "<b>Resistance 9:</b> Causes permanent deafness, instead of intermittent.<br>\
<b>Stealth 4:</b> The symptom remains hidden until active."
/datum/symptom/deafness/Start(datum/disease/advance/A)
..()
@@ -18,7 +18,7 @@ Bonus
/datum/symptom/dizzy // Not the egg
name = "Dizziness"
stealth = 2
desc = "The virus causes inflammation of the vestibular system, leading to bouts of dizziness."
resistance = -2
stage_speed = -3
transmittable = -1
@@ -27,6 +27,8 @@ Bonus
base_message_chance = 50
symptom_delay_min = 15
symptom_delay_max = 40
threshold_desc = "<b>Transmission 6:</b> Also causes druggy vision.<br>\
<b>Stealth 4:</b> The symptom remains hidden until active."
/datum/symptom/dizzy/Start(datum/disease/advance/A)
..()
@@ -16,8 +16,8 @@ Bonus
*/
/datum/symptom/fever
name = "Fever"
desc = "The virus causes a febrile response from the host, raising its body temperature."
stealth = 0
resistance = 3
stage_speed = 3
@@ -28,6 +28,8 @@ Bonus
symptom_delay_min = 10
symptom_delay_max = 30
var/unsafe = FALSE //over the heat threshold
threshold_desc = "<b>Resistance 5:</b> Increases fever intensity, fever can overheat and harm the host.<br>\
<b>Resistance 10:</b> Further increases fever intensity."
/datum/symptom/fever/Start(datum/disease/advance/A)
..()
@@ -18,6 +18,7 @@ Bonus
/datum/symptom/fire
name = "Spontaneous Combustion"
desc = "The virus turns fat into an extremely flammable compound, and raises the body's temperature, making the host burst into flames spontaneously."
stealth = 1
resistance = -4
stage_speed = -4
@@ -28,6 +29,10 @@ Bonus
symptom_delay_min = 20
symptom_delay_max = 75
var/infective = FALSE
threshold_desc = "<b>Stage Speed 4:</b> Increases the intensity of the flames.<br>\
<b>Stage Speed 8:</b> Further increases flame intensity.<br>\
<b>Transmission 8:</b> Host will spread the virus through skin flakes when bursting into flame.<br>\
<b>Stealth 4:</b> The symptom remains hidden until active."
/datum/symptom/fire/Start(datum/disease/advance/A)
..()
@@ -94,6 +99,7 @@ Bonus
/datum/symptom/alkali
name = "Alkali perspiration"
desc = "The virus attaches to sudoriparous glands, synthesizing a chemical that bursts into flames when reacting with water, leading to self-immolation."
stealth = 2
resistance = -2
stage_speed = -2
@@ -105,6 +111,9 @@ Bonus
symptom_delay_max = 90
var/chems = FALSE
var/explosion_power = 1
threshold_desc = "<b>Resistance 9:</b> Doubles the intensity of the effect, but reduces its frequency.<br>\
<b>Stage Speed 8:</b> Increases explosion radius when the host is wet.<br>\
<b>Transmission 8:</b> Additionally synthesizes chlorine trifluoride and napalm inside the host."
/datum/symptom/alkali/Start(datum/disease/advance/A)
..()
@@ -18,6 +18,7 @@ Bonus
/datum/symptom/flesh_eating
name = "Necrotizing Fasciitis"
desc = "The virus aggressively attacks body cells, necrotizing tissues and organs."
stealth = -3
resistance = -4
stage_speed = 0
@@ -29,6 +30,8 @@ Bonus
symptom_delay_max = 60
var/bleed = FALSE
var/pain = FALSE
threshold_desc = "<b>Resistance 7:</b> Host will bleed profusely during necrosis.<br>\
<b>Transmission 8:</b> Causes extreme pain to the host, weakening it."
/datum/symptom/flesh_eating/Start(datum/disease/advance/A)
..()
@@ -80,6 +83,7 @@ Bonus
/datum/symptom/flesh_death
name = "Autophagocytosis Necrosis"
desc = "The virus rapidly consumes infected cells, leading to heavy and widespread damage."
stealth = -2
resistance = -2
stage_speed = 1
@@ -91,6 +95,8 @@ Bonus
symptom_delay_max = 6
var/chems = FALSE
var/zombie = FALSE
threshold_desc = "<b>Stage Speed 7:</b> Synthesizes Heparin and Lipolicide inside the host, causing increased bleeding and hunger.<br>\
<b>Stealth 5:</b> The symptom remains hidden until active."
/datum/symptom/flesh_death/Start(datum/disease/advance/A)
..()
@@ -16,8 +16,8 @@ Bonus
*/
/datum/symptom/genetic_mutation
name = "Deoxyribonucleic Acid Saboteur"
desc = "The virus bonds with the DNA of the host, causing damaging mutations until removed."
stealth = -2
resistance = -3
stage_speed = 0
@@ -30,6 +30,9 @@ Bonus
symptom_delay_min = 60
symptom_delay_max = 120
var/no_reset = FALSE
threshold_desc = "<b>Resistance 8:</b> Causes two harmful mutations at once.<br>\
<b>Stage Speed 10:</b> Increases mutation frequency.<br>\
<b>Stealth 5:</b> The mutations persist even if the virus is cured."
/datum/symptom/genetic_mutation/Activate(datum/disease/advance/A)
if(!..())
@@ -16,8 +16,8 @@ Bonus
*/
/datum/symptom/hallucigen
name = "Hallucigen"
desc = "The virus stimulates the brain, causing occasional hallucinations."
stealth = -2
resistance = -3
stage_speed = -3
@@ -28,6 +28,8 @@ Bonus
symptom_delay_min = 25
symptom_delay_max = 90
var/fake_healthy = FALSE
threshold_desc = "<b>Stage Speed 7:</b> Increases the amount of hallucinations.<br>\
<b>Stealth 4:</b> The virus mimics positive symptoms.."
/datum/symptom/hallucigen/Start(datum/disease/advance/A)
..()
@@ -19,6 +19,7 @@ BONUS
/datum/symptom/headache
name = "Headache"
desc = "The virus causes inflammation inside the brain, causing constant headaches."
stealth = -1
resistance = 4
stage_speed = 2
@@ -28,6 +29,9 @@ BONUS
base_message_chance = 100
symptom_delay_min = 15
symptom_delay_max = 30
threshold_desc = "<b>Stage Speed 6:</b> Headaches will cause severe pain, that weakens the host.<br>\
<b>Stage Speed 9:</b> Headaches become less frequent but far more intense, preventing any action from the host.<br>\
<b>Stealth 4:</b> Reduces headache frequency until later stages."
/datum/symptom/headache/Start(datum/disease/advance/A)
..()
@@ -45,11 +49,11 @@ BONUS
return
var/mob/living/M = A.affected_mob
if(power < 2)
if(prob(base_message_chance))
if(prob(base_message_chance) || A.stage >=4)
to_chat(M, "<span class='warning'>[pick("Your head hurts.", "Your head pounds.")]</span>")
if(power >= 2)
if(power >= 2 && A.stage >= 4)
to_chat(M, "<span class='warning'>[pick("Your head hurts a lot.", "Your head pounds incessantly.")]</span>")
M.adjustStaminaLoss(25)
if(power >= 3)
if(power >= 3 && A.stage >= 5)
to_chat(M, "<span class='userdanger'>[pick("Your head hurts!", "You feel a burning knife inside your brain!", "A wave of pain fills your head!")]</span>")
M.Stun(35)
+15 -2
View File
@@ -1,5 +1,6 @@
/datum/symptom/heal
name = "Basic Healing (does nothing)" //warning for adminspawn viruses
desc = "You should not be seeing this."
stealth = 1
resistance = -4
stage_speed = -4
@@ -9,6 +10,9 @@
symptom_delay_min = 1
symptom_delay_max = 1
var/hide_healing = FALSE
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)
..()
@@ -51,6 +55,7 @@ Bonus
/datum/symptom/heal/toxin
name = "Toxic Filter"
desc = "The virus synthesizes regenerative chemicals in the bloodstream, repairing damage caused by toxins."
stealth = 1
resistance = -4
stage_speed = -4
@@ -87,6 +92,7 @@ Bonus
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."
/datum/symptom/heal/toxin/plus/Heal(mob/living/M, datum/disease/advance/A)
var/heal_amt = 2 * power
@@ -115,6 +121,7 @@ Bonus
/datum/symptom/heal/brute
name = "Regeneration"
desc = "The virus stimulates the regenerative process in the host, causing faster wound healing."
stealth = 1
resistance = -4
stage_speed = -4
@@ -158,6 +165,7 @@ Bonus
/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."
stealth = 0
resistance = 0
stage_speed = -2
@@ -207,6 +215,7 @@ Bonus
/datum/symptom/heal/burn
name = "Tissue Regrowth"
desc = "The virus recycles dead and burnt tissues, speeding up the healing of damage caused by burns."
stealth = 1
resistance = -4
stage_speed = -4
@@ -248,7 +257,8 @@ Bonus
/datum/symptom/heal/burn/plus
name = "Heat Resistance"
name = "Temperature Adaptation"
desc = "The virus quickly balances body heat, while also replacing tissues damaged by external sources."
stealth = 0
resistance = 0
stage_speed = -2
@@ -297,6 +307,7 @@ Bonus
/datum/symptom/heal/dna
name = "Deoxyribonucleic Acid Restoration"
desc = "The virus repairs the host's genome, purging negative mutations."
stealth = -1
resistance = -1
stage_speed = 0
@@ -304,9 +315,11 @@ Bonus
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."
/datum/symptom/heal/dna/Heal(mob/living/carbon/M, datum/disease/advance/A)
var/amt_healed = 2 * power
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]
@@ -19,6 +19,7 @@ BONUS
/datum/symptom/itching
name = "Itching"
desc = "The virus irritates the skin, causing itching."
stealth = 0
resistance = 3
stage_speed = 3
@@ -28,6 +29,8 @@ BONUS
symptom_delay_min = 5
symptom_delay_max = 25
var/scratch = FALSE
threshold_desc = "<b>Transmission 6:</b> Increases frequency of itching.<br>\
<b>Stage Speed 7:</b> The host will scrath itself when itching, causing superficial damage."
/datum/symptom/itching/Start(datum/disease/advance/A)
..()
@@ -14,6 +14,7 @@ Bonus
*/
/datum/symptom/narcolepsy
name = "Narcolepsy"
desc = "The virus causes a hormone imbalance, making the host sleepy and narcoleptic."
stealth = -1
resistance = -2
stage_speed = -3
@@ -25,6 +26,8 @@ Bonus
var/sleep_level = 0
var/sleepy_ticks = 0
var/stamina = FALSE
threshold_desc = "<b>Transmission 7:</b> Also relaxes the muscles, weakening and slowing the host.<br>\
<b>Resistance 10:</b> Causes narcolepsy more often, increasing the chance of the host falling asleep."
/datum/symptom/narcolepsy/Start(datum/disease/advance/A)
..()
@@ -18,6 +18,7 @@ Bonus
/datum/symptom/oxygen
name = "Self-Respiration"
desc = "The virus rapidly synthesizes oxygen, effectively removing the need for breathing."
stealth = 1
resistance = -3
stage_speed = -3
@@ -27,6 +28,7 @@ Bonus
symptom_delay_min = 1
symptom_delay_max = 1
var/regenerate_blood = FALSE
threshold_desc = "<b>Resistance 8:</b>Additionally regenerates lost blood.<br>"
/datum/symptom/oxygen/Start(datum/disease/advance/A)
..()
@@ -15,8 +15,9 @@ Bonus
//////////////////////////////////////
*/
/datum/symptom/sensory_restoration
name = "Sensory Restoration"
/datum/symptom/mind_restoration
name = "Mind Restoration"
desc = "The virus strengthens the bonds between neurons, reducing the duration of any ailments of the mind."
stealth = -1
resistance = -4
stage_speed = -4
@@ -27,15 +28,17 @@ Bonus
symptom_delay_max = 10
var/purge_alcohol = FALSE
var/brain_heal = FALSE
threshold_desc = "<b>Resistance 6:</b> Heals brain damage.<br>\
<b>Transmission 8:</b> Purges alcohol in the bloodstream."
/datum/symptom/sensory_restoration/Start(datum/disease/advance/A)
/datum/symptom/mind_restoration/Start(datum/disease/advance/A)
..()
if(A.properties["resistance"] >= 6) //heal brain damage
brain_heal = TRUE
if(A.properties["transmittable"] >= 8) //purge alcohol
purge_alcohol = TRUE
/datum/symptom/sensory_restoration/Activate(var/datum/disease/advance/A)
/datum/symptom/mind_restoration/Activate(var/datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
@@ -15,8 +15,8 @@ BONUS
*/
/datum/symptom/shedding
name = "Alopecia"
desc = "The virus causes rapid shedding of head and body hair."
stealth = 0
resistance = 1
stage_speed = -1
@@ -16,8 +16,8 @@ Bonus
*/
/datum/symptom/shivering
name = "Shivering"
desc = "The virus inhibits the body's thermoregulation, cooling the body down."
stealth = 0
resistance = 2
stage_speed = 2
@@ -27,6 +27,8 @@ Bonus
symptom_delay_min = 10
symptom_delay_max = 30
var/unsafe = FALSE //over the cold threshold
threshold_desc = "<b>Stage Speed 5:</b> Increases cooling speed; the host can fall below safe temperature levels.<br>\
<b>Stage Speed 10:</b> Further increases cooling speed."
/datum/symptom/fever/Start(datum/disease/advance/A)
..()
@@ -17,6 +17,7 @@ BONUS
/datum/symptom/vitiligo
name = "Vitiligo"
desc = "The virus destroys skin pigment cells, causing rapid loss of pigmentation in the host."
stealth = -3
resistance = -1
stage_speed = -1
@@ -61,6 +62,7 @@ BONUS
/datum/symptom/revitiligo
name = "Revitiligo"
desc = "The virus causes increased production of skin pigment cells, making the host's skin grow darker over time."
stealth = -3
resistance = -1
stage_speed = -1
@@ -18,6 +18,7 @@ Bonus
/datum/symptom/sneeze
name = "Sneezing"
desc = "The virus causes irritation of the nasal cavity, making the host sneeze occasionally."
stealth = -2
resistance = 3
stage_speed = 0
@@ -26,6 +27,8 @@ Bonus
severity = 1
symptom_delay_min = 5
symptom_delay_max = 35
threshold_desc = "<b>Transmission 9:</b> Increases sneezing range, spreading the virus over a larger area.<br>\
<b>Stealth 4:</b> The symptom remains hidden until active."
/datum/symptom/sneeze/Start(datum/disease/advance/A)
..()
@@ -3,6 +3,8 @@
/datum/symptom
// Buffs/Debuffs the symptom has to the overall engineered disease.
var/name = ""
var/desc = "If you see this something went very wrong." //Basic symptom description
var/threshold_desc = "" //Description of threshold effects
var/stealth = 0
var/resistance = 0
var/stage_speed = 0
@@ -25,6 +27,7 @@
var/power = 1
//A neutered symptom has no effect, and only affects statistics.
var/neutered = FALSE
var/list/thresholds
/datum/symptom/New()
var/list/S = SSdisease.list_symptoms
@@ -37,7 +40,6 @@
// Called when processing of the advance disease, which holds this symptom, starts.
/datum/symptom/proc/Start(datum/disease/advance/A)
next_activation = world.time + rand(symptom_delay_min * 10, symptom_delay_max * 10) //so it doesn't instantly activate on infection
return
// Called when the advance disease is going to be deleted or when the advance disease stops processing.
/datum/symptom/proc/End(datum/disease/advance/A)
@@ -58,3 +60,6 @@
new_symp.id = id
new_symp.neutered = neutered
return new_symp
/datum/symptom/proc/generate_threshold_desc()
return
@@ -15,6 +15,7 @@ BONUS
*/
/datum/symptom/viraladaptation
name = "Viral self-adaptation"
desc = "The virus mimics the function of normal body cells, becoming harder to spot and to eradicate, but reducing its speed."
stealth = 3
resistance = 5
stage_speed = -3
@@ -38,6 +39,8 @@ BONUS
*/
/datum/symptom/viralevolution
name = "Viral evolutionary acceleration"
desc = "The virus quickly adapts to spread as fast as possible both outside and inside a host. \
This, however, makes the virus easier to spot, and less able to fight off a cure."
stealth = -2
resistance = -3
stage_speed = 5
@@ -65,6 +68,8 @@ Bonus
/datum/symptom/viralreverse
name = "Viral aggressive metabolism"
desc = "The virus sacrifices its long term survivability to gain a near-instant spread when inside a host. \
The virus will start at the lastest stage, but will eventually decay and die off by itself."
stealth = -2
resistance = 1
stage_speed = 3
@@ -73,6 +78,8 @@ Bonus
symptom_delay_min = 1
symptom_delay_max = 1
var/time_to_cure
threshold_desc = "<b>Resistance/Stage Speed:</b> Highest between these determines the amount of time before self-curing.<br>\
<b>Stealth 4:</b> Doubles the time before the virus self-cures."
/datum/symptom/viralreverse/Activate(datum/disease/advance/A)
if(!..())
@@ -18,6 +18,7 @@ Bonus
/datum/symptom/visionloss
name = "Hyphema"
desc = "The virus causes inflammation of the retina, leading to eye damage and eventually blindness."
stealth = -1
resistance = -4
stage_speed = -4
@@ -28,6 +29,8 @@ Bonus
symptom_delay_min = 25
symptom_delay_max = 80
var/remove_eyes = FALSE
threshold_desc = "<b>Resistance 12:</b> Weakens extraocular muscles, eventually leading to complete detachment of the eyes.<br>\
<b>Stealth 4:</b> The symptom remains hidden until active."
/datum/symptom/visionloss/Start(datum/disease/advance/A)
..()
@@ -88,6 +91,7 @@ Bonus
/datum/symptom/visionaid
name = "Ocular Restoration"
desc = "The virus stimulates the production and replacement of eye cells, causing the host to regenerate its eyes when damaged."
stealth = -1
resistance = -3
stage_speed = -2

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