Merge branch 'master' into screenshake
This commit is contained in:
+148
-74
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(): ()
|
||||
@@ -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"
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
@@ -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"
|
||||
|
||||
@@ -154,3 +154,5 @@
|
||||
#define JUDGE_IGNOREMONKEYS 16
|
||||
|
||||
#define MEGAFAUNA_DEFAULT_RECOVERY_TIME 5
|
||||
|
||||
#define SHADOW_SPECIES_LIGHT_THRESHOLD 0.2
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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]")
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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
|
||||
//
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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,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
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 = ""
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -247,7 +247,7 @@
|
||||
|
||||
|
||||
/obj/screen/parallax_layer/Initialize(mapload, view)
|
||||
..()
|
||||
. = ..()
|
||||
if (!view)
|
||||
view = world.view
|
||||
update_o(view)
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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!"
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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()
|
||||
..()
|
||||
|
||||
@@ -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
|
||||
@@ -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()
|
||||
|
||||
@@ -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
@@ -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])"))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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()
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
@@ -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]")
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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'
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
@@ -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
Reference in New Issue
Block a user