mirror of
https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13.git
synced 2026-01-03 13:44:27 +00:00
Merge branch 'master' into upstream-merge-30056
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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,10 @@
|
||||
#define GRAB_NECK 2
|
||||
#define GRAB_KILL 3
|
||||
|
||||
//slowdown when in softcrit
|
||||
#define SOFTCRIT_MIN_SLOWDOWN 8
|
||||
#define SOFTCRIT_ADD_SLOWDOWN 6
|
||||
|
||||
//Attack types for checking shields/hit reactions
|
||||
#define MELEE_ATTACK 1
|
||||
#define UNARMED_ATTACK 2
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// 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:
|
||||
@@ -16,3 +16,9 @@
|
||||
#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)
|
||||
#define COMSIG_PARENT_ATTACKBY "atom_attackby" //from the base of atom/attackby: (obj/item, mob/living, params)
|
||||
#define COMSIG_PARENT_EXAMINE "atom_examine" //from the 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_SING_PULL "atom_sing_pull" //from base of atom/singularity_pull(): (S, current_size)
|
||||
#define COMSIG_MOVABLE_CROSSED "movable_crossed" //from base of atom/movable/Crossed(): (atom/movable)
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -315,9 +315,16 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
|
||||
#define APPEARANCE_CONSIDER_ALPHA ~RESET_ALPHA
|
||||
#define APPEARANCE_LONG_GLIDE LONG_GLIDE
|
||||
|
||||
// Consider these images/atoms as part of the UI/HUD
|
||||
#define APPEARANCE_UI_IGNORE_ALPHA RESET_COLOR|RESET_TRANSFORM|NO_CLIENT_COLOR|RESET_ALPHA
|
||||
#define APPEARANCE_UI RESET_COLOR|RESET_TRANSFORM|NO_CLIENT_COLOR
|
||||
#ifndef PIXEL_SCALE
|
||||
#define PIXEL_SCALE 0
|
||||
#if DM_VERSION >= 512
|
||||
#error HEY, PIXEL_SCALE probably exists now, remove this gross ass shim.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Consider these images/atoms as part of the UI/HUD
|
||||
#define APPEARANCE_UI_IGNORE_ALPHA RESET_COLOR|RESET_TRANSFORM|NO_CLIENT_COLOR|RESET_ALPHA|PIXEL_SCALE
|
||||
#define APPEARANCE_UI RESET_COLOR|RESET_TRANSFORM|NO_CLIENT_COLOR
|
||||
|
||||
//Just space
|
||||
#define SPACE_ICON_STATE "[((x + y) ^ ~(x * y) + z) % 25]"
|
||||
@@ -440,3 +447,13 @@ 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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -47,4 +47,22 @@
|
||||
#define SEC_DEPT_ENGINEERING "Engineering"
|
||||
#define SEC_DEPT_MEDICAL "Medical"
|
||||
#define SEC_DEPT_SCIENCE "Science"
|
||||
#define SEC_DEPT_SUPPLY "Supply"
|
||||
#define SEC_DEPT_SUPPLY "Supply"
|
||||
|
||||
// Playtime tracking system, see jobs_exp.dm
|
||||
#define EXP_TYPE_LIVING "Living"
|
||||
#define EXP_TYPE_CREW "Crew"
|
||||
#define EXP_TYPE_COMMAND "Command"
|
||||
#define EXP_TYPE_ENGINEERING "Engineering"
|
||||
#define EXP_TYPE_MEDICAL "Medical"
|
||||
#define EXP_TYPE_SCIENCE "Science"
|
||||
#define EXP_TYPE_SUPPLY "Supply"
|
||||
#define EXP_TYPE_SECURITY "Security"
|
||||
#define EXP_TYPE_SILICON "Silicon"
|
||||
#define EXP_TYPE_SERVICE "Service"
|
||||
#define EXP_TYPE_ANTAG "Antag"
|
||||
#define EXP_TYPE_SPECIAL "Special"
|
||||
#define EXP_TYPE_GHOST "Ghost"
|
||||
|
||||
//Flags in the players table in the db
|
||||
#define DB_FLAG_EXEMPT 1
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,8 @@
|
||||
#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
|
||||
var/turf/T = get_turf(A)
|
||||
return T ? T.loc : null
|
||||
|
||||
/proc/get_area_name(atom/X)
|
||||
var/area/Y = get_area(X)
|
||||
|
||||
57
code/__HELPERS/shell.dm
Normal file
57
code/__HELPERS/shell.dm
Normal file
@@ -0,0 +1,57 @@
|
||||
//Runs the command in the system's shell, returns a list of (error code, stdout, stderr)
|
||||
|
||||
#define SHELLEO_NAME "data/shelleo."
|
||||
#define SHELLEO_ERR ".err"
|
||||
#define SHELLEO_OUT ".out"
|
||||
/world/proc/shelleo(command)
|
||||
var/static/list/shelleo_ids = list()
|
||||
var/stdout = ""
|
||||
var/stderr = ""
|
||||
var/errorcode = 1
|
||||
var/shelleo_id
|
||||
var/out_file = ""
|
||||
var/err_file = ""
|
||||
var/static/list/interpreters = list("[MS_WINDOWS]" = "cmd /c", "[UNIX]" = "sh -c")
|
||||
var/interpreter = interpreters["[world.system_type]"]
|
||||
if(interpreter)
|
||||
for(var/seo_id in shelleo_ids)
|
||||
if(!shelleo_ids[seo_id])
|
||||
shelleo_ids[seo_id] = TRUE
|
||||
shelleo_id = "[seo_id]"
|
||||
break
|
||||
if(!shelleo_id)
|
||||
shelleo_id = "[shelleo_ids.len + 1]"
|
||||
shelleo_ids += shelleo_id
|
||||
shelleo_ids[shelleo_id] = TRUE
|
||||
out_file = "[SHELLEO_NAME][shelleo_id][SHELLEO_OUT]"
|
||||
err_file = "[SHELLEO_NAME][shelleo_id][SHELLEO_ERR]"
|
||||
errorcode = shell("[interpreter] \"[command]\" > [out_file] 2> [err_file]")
|
||||
if(fexists(out_file))
|
||||
stdout = file2text(out_file)
|
||||
fdel(out_file)
|
||||
if(fexists(err_file))
|
||||
stderr = file2text(err_file)
|
||||
fdel(err_file)
|
||||
shelleo_ids[shelleo_id] = FALSE
|
||||
else
|
||||
CRASH("Operating System: [world.system_type] not supported") // If you encounter this error, you are encouraged to update this proc with support for the new operating system
|
||||
. = list(errorcode, stdout, stderr)
|
||||
#undef SHELLEO_NAME
|
||||
#undef SHELLEO_ERR
|
||||
#undef SHELLEO_OUT
|
||||
|
||||
/proc/shell_url_scrub(url)
|
||||
var/static/regex/bad_chars_regex = regex("\[^#%&./:=?\\w]*", "g")
|
||||
var/scrubbed_url = ""
|
||||
var/bad_match = ""
|
||||
var/last_good = 1
|
||||
var/bad_chars = 1
|
||||
do
|
||||
bad_chars = bad_chars_regex.Find(url)
|
||||
scrubbed_url += copytext(url, last_good, bad_chars)
|
||||
if(bad_chars)
|
||||
bad_match = url_encode(bad_chars_regex.match)
|
||||
scrubbed_url += bad_match
|
||||
last_good = bad_chars + length(bad_match)
|
||||
while(bad_chars)
|
||||
. = scrubbed_url
|
||||
@@ -1,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
|
||||
//
|
||||
|
||||
@@ -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 0
|
||||
#define DB_MINOR_VERSION 3
|
||||
|
||||
11
code/_compile_options.dm.rej
Normal file
11
code/_compile_options.dm.rej
Normal file
@@ -0,0 +1,11 @@
|
||||
diff a/code/_compile_options.dm b/code/_compile_options.dm (rejected hunks)
|
||||
@@ -69,7 +69,7 @@
|
||||
#error You need version 511 or higher
|
||||
#endif
|
||||
|
||||
-//Update this whenever the db schema changes
|
||||
+//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 2
|
||||
+#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]
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
* If you are diagonally adjacent, ensure you can pass through at least one of the mutually adjacent square.
|
||||
* Passing through in this case ignores anything with the LETPASSTHROW pass flag, such as tables, racks, and morgue trays.
|
||||
*/
|
||||
/turf/Adjacent(atom/neighbor, atom/target = null, atom/movable/mover = null)
|
||||
/turf/Adjacent(atom/neighbor, atom/target = null, atom/movable/mover = null)
|
||||
var/turf/T0 = get_turf(neighbor)
|
||||
|
||||
if(T0 == src) //same turf
|
||||
@@ -37,7 +37,7 @@
|
||||
// Non diagonal case
|
||||
if(T0.x == x || T0.y == y)
|
||||
// Check for border blockages
|
||||
return T0.ClickCross(get_dir(T0,src), border_only = 1, target_atom = target, mover = mover) && src.ClickCross(get_dir(src,T0), border_only = 1, target_atom = target, mover = mover)
|
||||
return T0.ClickCross(get_dir(T0,src), border_only = 1, target_atom = target, mover = mover) && src.ClickCross(get_dir(src,T0), border_only = 1, target_atom = target, mover = mover)
|
||||
|
||||
// Diagonal case
|
||||
var/in_dir = get_dir(T0,src) // eg. northwest (1+8) = 9 (00001001)
|
||||
@@ -45,16 +45,16 @@
|
||||
var/d2 = in_dir&12 // eg. west (1+8)&12 (0000 1100) = 8 (0000 1000)
|
||||
|
||||
for(var/d in list(d1,d2))
|
||||
if(!T0.ClickCross(d, border_only = 1, target_atom = target, mover = mover))
|
||||
if(!T0.ClickCross(d, border_only = 1, target_atom = target, mover = mover))
|
||||
continue // could not leave T0 in that direction
|
||||
|
||||
var/turf/T1 = get_step(T0,d)
|
||||
if(!T1 || T1.density)
|
||||
continue
|
||||
if(!T1.ClickCross(get_dir(T1,src), border_only = 0, target_atom = target, mover = mover) || !T1.ClickCross(get_dir(T1,T0), border_only = 0, target_atom = target, mover = mover))
|
||||
if(!T1 || T1.density)
|
||||
continue
|
||||
if(!T1.ClickCross(get_dir(T1,src), border_only = 0, target_atom = target, mover = mover) || !T1.ClickCross(get_dir(T1,T0), border_only = 0, target_atom = target, mover = mover))
|
||||
continue // couldn't enter or couldn't leave T1
|
||||
|
||||
if(!src.ClickCross(get_dir(src,T1), border_only = 1, target_atom = target, mover = mover))
|
||||
if(!src.ClickCross(get_dir(src,T1), border_only = 1, target_atom = target, mover = mover))
|
||||
continue // could not enter src
|
||||
|
||||
return 1 // we don't care about our own density
|
||||
@@ -70,7 +70,7 @@
|
||||
return TRUE
|
||||
if(!isturf(loc))
|
||||
return FALSE
|
||||
if(loc.Adjacent(neighbor,target = neighbor, mover = src))
|
||||
if(loc.Adjacent(neighbor,target = neighbor, mover = src))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -85,20 +85,19 @@
|
||||
|
||||
/*
|
||||
This checks if you there is uninterrupted airspace between that turf and this one.
|
||||
This is defined as any dense ON_BORDER_1 object, or any dense object without LETPASSTHROW.
|
||||
This is defined as any dense ON_BORDER_1 object, or any dense object without LETPASSTHROW.
|
||||
The border_only flag allows you to not objects (for source and destination squares)
|
||||
*/
|
||||
/turf/proc/ClickCross(target_dir, border_only, target_atom = null, atom/movable/mover = null)
|
||||
/turf/proc/ClickCross(target_dir, border_only, target_atom = null, atom/movable/mover = null)
|
||||
for(var/obj/O in src)
|
||||
if((mover && O.CanPass(mover,get_step(src,target_dir))) || (!mover && !O.density))
|
||||
continue
|
||||
if(O == target_atom || (O.pass_flags & LETPASSTHROW)) //check if there's a dense object present on the turf
|
||||
if((mover && O.CanPass(mover,get_step(src,target_dir))) || (!mover && !O.density))
|
||||
continue
|
||||
if(O == target_atom || O == mover || (O.pass_flags & LETPASSTHROW)) //check if there's a dense object present on the turf
|
||||
continue // LETPASSTHROW is used for anything you can click through (or the firedoor special case, see above)
|
||||
|
||||
if( O.flags_1&ON_BORDER_1) // windows are on border, check them first
|
||||
if( O.flags_1&ON_BORDER_1) // windows are on border, check them first
|
||||
if( O.dir & target_dir || O.dir & (O.dir-1) ) // full tile windows are just diagonals mechanically
|
||||
return 0 //O.dir&(O.dir-1) is false for any cardinal direction, but true for diagonal ones
|
||||
|
||||
else if( !border_only ) // dense, not on border, cannot pass over
|
||||
return 0
|
||||
return 1
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
56
code/citadel/custom_loadout/custom_items.dm
Normal file
56
code/citadel/custom_loadout/custom_items.dm
Normal file
@@ -0,0 +1,56 @@
|
||||
|
||||
//For custom items.
|
||||
|
||||
/obj/item/custom/ceb_soap
|
||||
name = "Cebutris' Soap"
|
||||
desc = "A generic bar of soap that doesn't really seem to work right."
|
||||
gender = PLURAL
|
||||
icon = 'icons/obj/custom.dmi'
|
||||
icon_state = "cebu"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
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
|
||||
61
code/citadel/custom_loadout/load_to_mob.dm
Normal file
61
code/citadel/custom_loadout/load_to_mob.dm
Normal file
@@ -0,0 +1,61 @@
|
||||
|
||||
//Proc that does the actual loading of items to mob
|
||||
/*Itemlists are formatted as
|
||||
"[typepath]" = number_of_it_to_spawn
|
||||
*/
|
||||
|
||||
#define DROP_TO_FLOOR 0
|
||||
#define LOADING_TO_HUMAN 1
|
||||
|
||||
/proc/handle_roundstart_items(mob/living/M, ckey_override, job_override, special_override)
|
||||
if(!istype(M) || (!M.ckey && !ckey_override) || (!M.mind && (!job_override || !special_override)))
|
||||
return FALSE
|
||||
return load_itemlist_to_mob(M, parse_custom_roundstart_items(ckey_override? ckey_override : M.ckey, M.name, job_override? job_override : M.mind.assigned_role, special_override? special_override : M.mind.special_role), TRUE, TRUE, FALSE)
|
||||
|
||||
//Just incase there's extra mob selections in the future.....
|
||||
/proc/load_itemlist_to_mob(mob/living/L, list/itemlist, drop_on_floor_if_full = TRUE, load_to_all_slots = TRUE, replace_slots = FALSE)
|
||||
if(!istype(L) || !islist(itemlist))
|
||||
return FALSE
|
||||
var/loading_mode = DROP_TO_FLOOR
|
||||
var/turf/current_turf = get_turf(L)
|
||||
if(ishuman(L))
|
||||
loading_mode = LOADING_TO_HUMAN
|
||||
switch(loading_mode)
|
||||
if(DROP_TO_FLOOR)
|
||||
for(var/I in itemlist)
|
||||
var/typepath = text2path(I)
|
||||
if(!typepath)
|
||||
continue
|
||||
for(var/i = 0, i < itemlist[I], i++)
|
||||
new typepath(current_turf)
|
||||
return TRUE
|
||||
if(LOADING_TO_HUMAN)
|
||||
return load_itemlist_to_human(L, itemlist, drop_on_floor_if_full, load_to_all_slots, replace_slots)
|
||||
|
||||
/proc/load_itemlist_to_human(mob/living/carbon/human/H, list/itemlist, drop_on_floor_if_full = TRUE, load_to_all_slots = TRUE, replace_slots = FALSE)
|
||||
if(!istype(H) || !islist(itemlist))
|
||||
return FALSE
|
||||
var/turf/T = get_turf(H)
|
||||
for(var/item in itemlist)
|
||||
var/path = item
|
||||
if(!ispath(path))
|
||||
path = text2path(path)
|
||||
if(!path)
|
||||
continue
|
||||
var/amount = itemlist[item]
|
||||
for(var/i in 1 to amount)
|
||||
var/atom/movable/loaded_atom = new path
|
||||
if(!istype(loaded_atom))
|
||||
QDEL_NULL(loaded_atom)
|
||||
continue
|
||||
if(!istype(loaded_atom, /obj/item))
|
||||
loaded_atom.forceMove(T)
|
||||
continue
|
||||
var/obj/item/loaded = loaded_atom
|
||||
var/obj/item/storage/S = H.get_item_by_slot(slot_back)
|
||||
if(istype(S))
|
||||
S.handle_item_insertion(loaded, TRUE, H) //Force it into their backpack
|
||||
continue
|
||||
if(!H.put_in_hands(loaded)) //They don't have one/somehow that failed, put it in their hands
|
||||
loaded.forceMove(T) //Guess we're just dumping it on the floor!
|
||||
return TRUE
|
||||
71
code/citadel/custom_loadout/read_from_file.dm
Normal file
71
code/citadel/custom_loadout/read_from_file.dm
Normal file
@@ -0,0 +1,71 @@
|
||||
|
||||
GLOBAL_LIST(custom_item_list)
|
||||
//Layered list in form of custom_item_list[ckey][job][items][amounts]
|
||||
//ckey is key, job is specific jobs, or "ALL" for all jobs, items for items, amounts for amount of item.
|
||||
|
||||
//File should be in the format of ckey|exact job name/exact job name/or put ALL instead of any job names|/path/to/item=amount;/path/to/item=amount
|
||||
//Each ckey should be in a different line
|
||||
//if there's multiple entries of a single ckey the later ones will add to the earlier definitions.
|
||||
|
||||
/proc/reload_custom_roundstart_items_list(custom_filelist)
|
||||
if(!custom_filelist)
|
||||
custom_filelist = "config/custom_roundstart_items.txt"
|
||||
GLOB.custom_item_list = list()
|
||||
var/list/file_lines = world.file2list(custom_filelist)
|
||||
for(var/line in file_lines)
|
||||
if(length(line) == 0) //Emptyline, no one cares.
|
||||
continue
|
||||
if(copytext(line,1,3) == "//") //Commented line, ignore.
|
||||
continue
|
||||
var/ckey_str_sep = findtext(line, "|") //Process our stuff..
|
||||
var/char_str_sep = findtext(line, "|", ckey_str_sep+1)
|
||||
var/job_str_sep = findtext(line, "|", char_str_sep+1)
|
||||
var/item_str_sep = findtext(line, "|", job_str_sep+1)
|
||||
var/ckey_str = ckey(copytext(line, 1, ckey_str_sep))
|
||||
var/char_str = copytext(line, ckey_str_sep+1, char_str_sep)
|
||||
var/job_str = copytext(line, char_str_sep+1, job_str_sep)
|
||||
var/item_str = copytext(line, job_str_sep+1, item_str_sep)
|
||||
if(!ckey_str || !char_str || !job_str || !item_str || !length(ckey_str) || !length(char_str) || !length(job_str) || !length(item_str))
|
||||
log_admin("Errored custom_items_whitelist line: [line] - Component/separator missing!")
|
||||
if(!islist(GLOB.custom_item_list[ckey_str]))
|
||||
GLOB.custom_item_list[ckey_str] = list() //Initialize list for this ckey if it isn't initialized..
|
||||
var/list/characters = splittext(char_str, "/")
|
||||
for(var/character in characters)
|
||||
if(!islist(GLOB.custom_item_list[ckey_str][character]))
|
||||
GLOB.custom_item_list[ckey_str][character] = list()
|
||||
var/list/jobs = splittext(job_str, "/")
|
||||
for(var/job in jobs)
|
||||
for(var/character in characters)
|
||||
if(!islist(GLOB.custom_item_list[ckey_str][character][job]))
|
||||
GLOB.custom_item_list[ckey_str][character][job] = list() //Initialize item list for this job of this ckey if not already initialized.
|
||||
var/list/item_strings = splittext(item_str, ";") //Get item strings in format of /path/to/item=amount
|
||||
for(var/item_string in item_strings)
|
||||
var/path_str_sep = findtext(item_string, "=")
|
||||
var/path = copytext(item_string, 1, path_str_sep) //Path to spawn
|
||||
var/amount = copytext(item_string, path_str_sep+1) //Amount to spawn
|
||||
//world << "DEBUG: Item string [item_string] processed"
|
||||
amount = text2num(amount)
|
||||
path = text2path(path)
|
||||
if(!ispath(path) || !isnum(amount))
|
||||
log_admin("Errored custom_items_whitelist line: [line] - Path/number for item missing or invalid.")
|
||||
for(var/character in characters)
|
||||
for(var/job in jobs)
|
||||
if(!GLOB.custom_item_list[ckey_str][character][job][path]) //Doesn't exist, make it exist!
|
||||
GLOB.custom_item_list[ckey_str][character][job][path] = amount
|
||||
else
|
||||
GLOB.custom_item_list[ckey_str][character][job][path] += amount //Exists, we want more~
|
||||
return GLOB.custom_item_list
|
||||
|
||||
/proc/parse_custom_roundstart_items(ckey, char_name = "ALL", job_name = "ALL", special_role)
|
||||
var/list/ret = list()
|
||||
if(GLOB.custom_item_list[ckey])
|
||||
for(var/char in GLOB.custom_item_list[ckey])
|
||||
if((char_name == char) || (char_name == "ALL") || (char == "ALL"))
|
||||
for(var/job in GLOB.custom_item_list[ckey][char])
|
||||
if((job_name == job) || (job == "ALL") || (job_name == "ALL") || (special_role && (job == special_role)))
|
||||
for(var/item_path in GLOB.custom_item_list[ckey][char][job])
|
||||
if(ret[item_path])
|
||||
ret[item_path] += GLOB.custom_item_list[ckey][char][job][item_path]
|
||||
else
|
||||
ret[item_path] = GLOB.custom_item_list[ckey][char][job][item_path]
|
||||
return ret
|
||||
@@ -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()
|
||||
..()
|
||||
|
||||
@@ -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,15 @@
|
||||
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
|
||||
var/use_exp_restrictions_heads_hours = 0
|
||||
var/use_exp_restrictions_heads_department = FALSE
|
||||
var/use_exp_restrictions_other = FALSE
|
||||
var/use_exp_restrictions_admin_bypass = FALSE
|
||||
|
||||
//Population cap vars
|
||||
var/soft_popcap = 0
|
||||
@@ -168,6 +183,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
|
||||
@@ -266,6 +282,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)
|
||||
@@ -287,18 +305,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)
|
||||
@@ -336,6 +356,18 @@
|
||||
use_age_restriction_for_jobs = 1
|
||||
if("use_account_age_for_jobs")
|
||||
use_account_age_for_jobs = 1
|
||||
if("use_exp_tracking")
|
||||
use_exp_tracking = TRUE
|
||||
if("use_exp_restrictions_heads")
|
||||
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 = TRUE
|
||||
if("use_exp_restrictions_other")
|
||||
use_exp_restrictions_other = TRUE
|
||||
if("use_exp_restrictions_admin_bypass")
|
||||
use_exp_restrictions_admin_bypass = TRUE
|
||||
if("lobby_countdown")
|
||||
lobby_countdown = text2num(value)
|
||||
if("round_end_countdown")
|
||||
@@ -450,10 +482,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")
|
||||
@@ -533,6 +571,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]'")
|
||||
@@ -556,6 +596,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")
|
||||
@@ -799,6 +841,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
|
||||
@@ -851,6 +894,7 @@
|
||||
|
||||
|
||||
/datum/configuration/proc/loadsql(filename)
|
||||
filename = "[GLOB.config_dir][filename]"
|
||||
var/list/Lines = world.file2list(filename)
|
||||
for(var/t in Lines)
|
||||
if(!t)
|
||||
|
||||
24
code/controllers/configuration.dm.rej
Normal file
24
code/controllers/configuration.dm.rej
Normal file
@@ -0,0 +1,24 @@
|
||||
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")
|
||||
@@ -1,102 +1,102 @@
|
||||
/**
|
||||
* Failsafe
|
||||
*
|
||||
* Pretty much pokes the MC to make sure it's still alive.
|
||||
**/
|
||||
|
||||
GLOBAL_REAL(Failsafe, /datum/controller/failsafe)
|
||||
|
||||
/datum/controller/failsafe // This thing pretty much just keeps poking the master controller
|
||||
name = "Failsafe"
|
||||
|
||||
// The length of time to check on the MC (in deciseconds).
|
||||
// Set to 0 to disable.
|
||||
var/processing_interval = 20
|
||||
// The alert level. For every failed poke, we drop a DEFCON level. Once we hit DEFCON 1, restart the MC.
|
||||
var/defcon = 5
|
||||
//the world.time of the last check, so the mc can restart US if we hang.
|
||||
// (Real friends look out for *eachother*)
|
||||
var/lasttick = 0
|
||||
|
||||
// Track the MC iteration to make sure its still on track.
|
||||
var/master_iteration = 0
|
||||
var/running = TRUE
|
||||
|
||||
/datum/controller/failsafe/New()
|
||||
// Highlander-style: there can only be one! Kill off the old and replace it with the new.
|
||||
if(Failsafe != src)
|
||||
if(istype(Failsafe))
|
||||
qdel(Failsafe)
|
||||
Failsafe = src
|
||||
Initialize()
|
||||
|
||||
/datum/controller/failsafe/Initialize()
|
||||
set waitfor = 0
|
||||
Failsafe.Loop()
|
||||
if(!QDELETED(src))
|
||||
qdel(src) //when Loop() returns, we delete ourselves and let the mc recreate us
|
||||
|
||||
/datum/controller/failsafe/Destroy()
|
||||
running = FALSE
|
||||
..()
|
||||
return QDEL_HINT_HARDDEL_NOW
|
||||
|
||||
/datum/controller/failsafe/proc/Loop()
|
||||
while(running)
|
||||
lasttick = world.time
|
||||
if(!Master)
|
||||
// Replace the missing Master! This should never, ever happen.
|
||||
new /datum/controller/master()
|
||||
// Only poke it if overrides are not in effect.
|
||||
if(processing_interval > 0)
|
||||
if(Master.processing && Master.iteration)
|
||||
// Check if processing is done yet.
|
||||
if(Master.iteration == master_iteration)
|
||||
switch(defcon)
|
||||
if(4,5)
|
||||
--defcon
|
||||
if(3)
|
||||
to_chat(GLOB.admins, "<span class='adminnotice'>Notice: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5-defcon) * processing_interval] ticks.")
|
||||
--defcon
|
||||
if(2)
|
||||
to_chat(GLOB.admins, "<span class='boldannounce'>Warning: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5-defcon) * processing_interval] ticks. Automatic restart in [processing_interval] ticks.</span>")
|
||||
--defcon
|
||||
if(1)
|
||||
|
||||
to_chat(GLOB.admins, "<span class='boldannounce'>Warning: DEFCON [defcon_pretty()]. The Master Controller has still not fired within the last [(5-defcon) * processing_interval] ticks. Killing and restarting...</span>")
|
||||
--defcon
|
||||
var/rtn = Recreate_MC()
|
||||
if(rtn > 0)
|
||||
defcon = 4
|
||||
master_iteration = 0
|
||||
to_chat(GLOB.admins, "<span class='adminnotice'>MC restarted successfully</span>")
|
||||
else if(rtn < 0)
|
||||
log_game("FailSafe: Could not restart MC, runtime encountered. Entering defcon 0")
|
||||
to_chat(GLOB.admins, "<span class='boldannounce'>ERROR: DEFCON [defcon_pretty()]. Could not restart MC, runtime encountered. I will silently keep retrying.</span>")
|
||||
//if the return number was 0, it just means the mc was restarted too recently, and it just needs some time before we try again
|
||||
//no need to handle that specially when defcon 0 can handle it
|
||||
if(0) //DEFCON 0! (mc failed to restart)
|
||||
var/rtn = Recreate_MC()
|
||||
if(rtn > 0)
|
||||
defcon = 4
|
||||
master_iteration = 0
|
||||
to_chat(GLOB.admins, "<span class='adminnotice'>MC restarted successfully</span>")
|
||||
else
|
||||
defcon = min(defcon + 1,5)
|
||||
master_iteration = Master.iteration
|
||||
if (defcon <= 1)
|
||||
sleep(processing_interval*2)
|
||||
else
|
||||
sleep(processing_interval)
|
||||
else
|
||||
defcon = 5
|
||||
sleep(initial(processing_interval))
|
||||
|
||||
/datum/controller/failsafe/proc/defcon_pretty()
|
||||
return defcon
|
||||
|
||||
/datum/controller/failsafe/stat_entry()
|
||||
if(!statclick)
|
||||
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
|
||||
|
||||
stat("Failsafe Controller:", statclick.update("Defcon: [defcon_pretty()] (Interval: [Failsafe.processing_interval] | Iteration: [Failsafe.master_iteration])"))
|
||||
/**
|
||||
* Failsafe
|
||||
*
|
||||
* Pretty much pokes the MC to make sure it's still alive.
|
||||
**/
|
||||
|
||||
GLOBAL_REAL(Failsafe, /datum/controller/failsafe)
|
||||
|
||||
/datum/controller/failsafe // This thing pretty much just keeps poking the master controller
|
||||
name = "Failsafe"
|
||||
|
||||
// The length of time to check on the MC (in deciseconds).
|
||||
// Set to 0 to disable.
|
||||
var/processing_interval = 20
|
||||
// The alert level. For every failed poke, we drop a DEFCON level. Once we hit DEFCON 1, restart the MC.
|
||||
var/defcon = 5
|
||||
//the world.time of the last check, so the mc can restart US if we hang.
|
||||
// (Real friends look out for *eachother*)
|
||||
var/lasttick = 0
|
||||
|
||||
// Track the MC iteration to make sure its still on track.
|
||||
var/master_iteration = 0
|
||||
var/running = TRUE
|
||||
|
||||
/datum/controller/failsafe/New()
|
||||
// Highlander-style: there can only be one! Kill off the old and replace it with the new.
|
||||
if(Failsafe != src)
|
||||
if(istype(Failsafe))
|
||||
qdel(Failsafe)
|
||||
Failsafe = src
|
||||
Initialize()
|
||||
|
||||
/datum/controller/failsafe/Initialize()
|
||||
set waitfor = 0
|
||||
Failsafe.Loop()
|
||||
if(!QDELETED(src))
|
||||
qdel(src) //when Loop() returns, we delete ourselves and let the mc recreate us
|
||||
|
||||
/datum/controller/failsafe/Destroy()
|
||||
running = FALSE
|
||||
..()
|
||||
return QDEL_HINT_HARDDEL_NOW
|
||||
|
||||
/datum/controller/failsafe/proc/Loop()
|
||||
while(running)
|
||||
lasttick = world.time
|
||||
if(!Master)
|
||||
// Replace the missing Master! This should never, ever happen.
|
||||
new /datum/controller/master()
|
||||
// Only poke it if overrides are not in effect.
|
||||
if(processing_interval > 0)
|
||||
if(Master.processing && Master.iteration)
|
||||
// Check if processing is done yet.
|
||||
if(Master.iteration == master_iteration)
|
||||
switch(defcon)
|
||||
if(4,5)
|
||||
--defcon
|
||||
if(3)
|
||||
message_admins("<span class='adminnotice'>Notice: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5-defcon) * processing_interval] ticks.</span>")
|
||||
--defcon
|
||||
if(2)
|
||||
to_chat(GLOB.admins, "<span class='boldannounce'>Warning: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5-defcon) * processing_interval] ticks. Automatic restart in [processing_interval] ticks.</span>")
|
||||
--defcon
|
||||
if(1)
|
||||
|
||||
to_chat(GLOB.admins, "<span class='boldannounce'>Warning: DEFCON [defcon_pretty()]. The Master Controller has still not fired within the last [(5-defcon) * processing_interval] ticks. Killing and restarting...</span>")
|
||||
--defcon
|
||||
var/rtn = Recreate_MC()
|
||||
if(rtn > 0)
|
||||
defcon = 4
|
||||
master_iteration = 0
|
||||
to_chat(GLOB.admins, "<span class='adminnotice'>MC restarted successfully</span>")
|
||||
else if(rtn < 0)
|
||||
log_game("FailSafe: Could not restart MC, runtime encountered. Entering defcon 0")
|
||||
to_chat(GLOB.admins, "<span class='boldannounce'>ERROR: DEFCON [defcon_pretty()]. Could not restart MC, runtime encountered. I will silently keep retrying.</span>")
|
||||
//if the return number was 0, it just means the mc was restarted too recently, and it just needs some time before we try again
|
||||
//no need to handle that specially when defcon 0 can handle it
|
||||
if(0) //DEFCON 0! (mc failed to restart)
|
||||
var/rtn = Recreate_MC()
|
||||
if(rtn > 0)
|
||||
defcon = 4
|
||||
master_iteration = 0
|
||||
to_chat(GLOB.admins, "<span class='adminnotice'>MC restarted successfully</span>")
|
||||
else
|
||||
defcon = min(defcon + 1,5)
|
||||
master_iteration = Master.iteration
|
||||
if (defcon <= 1)
|
||||
sleep(processing_interval*2)
|
||||
else
|
||||
sleep(processing_interval)
|
||||
else
|
||||
defcon = 5
|
||||
sleep(initial(processing_interval))
|
||||
|
||||
/datum/controller/failsafe/proc/defcon_pretty()
|
||||
return defcon
|
||||
|
||||
/datum/controller/failsafe/stat_entry()
|
||||
if(!statclick)
|
||||
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
|
||||
|
||||
stat("Failsafe Controller:", statclick.update("Defcon: [defcon_pretty()] (Interval: [Failsafe.processing_interval] | Iteration: [Failsafe.master_iteration])"))
|
||||
|
||||
@@ -1,269 +1,281 @@
|
||||
SUBSYSTEM_DEF(blackbox)
|
||||
name = "Blackbox"
|
||||
wait = 6000
|
||||
flags = SS_NO_TICK_CHECK | SS_NO_INIT
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
init_order = INIT_ORDER_BLACKBOX
|
||||
|
||||
var/list/msg_common = list()
|
||||
var/list/msg_science = list()
|
||||
var/list/msg_command = list()
|
||||
var/list/msg_medical = list()
|
||||
var/list/msg_engineering = list()
|
||||
var/list/msg_security = list()
|
||||
var/list/msg_deathsquad = list()
|
||||
var/list/msg_syndicate = list()
|
||||
var/list/msg_service = list()
|
||||
var/list/msg_cargo = list()
|
||||
var/list/msg_other = list()
|
||||
|
||||
var/list/feedback = list() //list of datum/feedback_variable
|
||||
|
||||
var/sealed = FALSE //time to stop tracking stats?
|
||||
|
||||
//poll population
|
||||
/datum/controller/subsystem/blackbox/fire()
|
||||
if(!SSdbcore.Connect())
|
||||
return
|
||||
var/playercount = 0
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
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]')")
|
||||
query_record_playercount.Execute()
|
||||
|
||||
/datum/controller/subsystem/blackbox/Recover()
|
||||
msg_common = SSblackbox.msg_common
|
||||
msg_science = SSblackbox.msg_science
|
||||
msg_command = SSblackbox.msg_command
|
||||
msg_medical = SSblackbox.msg_medical
|
||||
msg_engineering = SSblackbox.msg_engineering
|
||||
msg_security = SSblackbox.msg_security
|
||||
msg_deathsquad = SSblackbox.msg_deathsquad
|
||||
msg_syndicate = SSblackbox.msg_syndicate
|
||||
msg_service = SSblackbox.msg_service
|
||||
msg_cargo = SSblackbox.msg_cargo
|
||||
msg_other = SSblackbox.msg_other
|
||||
|
||||
feedback = SSblackbox.feedback
|
||||
|
||||
sealed = SSblackbox.sealed
|
||||
|
||||
//no touchie
|
||||
/datum/controller/subsystem/blackbox/can_vv_get(var_name)
|
||||
if(var_name == "feedback")
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/blackbox/vv_edit_var(var_name, var_value)
|
||||
return FALSE
|
||||
|
||||
/datum/controller/subsystem/blackbox/Shutdown()
|
||||
sealed = FALSE
|
||||
set_val("ahelp_unresolved", GLOB.ahelp_tickets.active_tickets.len)
|
||||
|
||||
var/pda_msg_amt = 0
|
||||
var/rc_msg_amt = 0
|
||||
|
||||
for (var/obj/machinery/message_server/MS in GLOB.message_servers)
|
||||
if (MS.pda_msgs.len > pda_msg_amt)
|
||||
pda_msg_amt = MS.pda_msgs.len
|
||||
if (MS.rc_msgs.len > rc_msg_amt)
|
||||
rc_msg_amt = MS.rc_msgs.len
|
||||
|
||||
set_details("radio_usage","")
|
||||
|
||||
add_details("radio_usage","COM-[msg_common.len]")
|
||||
add_details("radio_usage","SCI-[msg_science.len]")
|
||||
add_details("radio_usage","HEA-[msg_command.len]")
|
||||
add_details("radio_usage","MED-[msg_medical.len]")
|
||||
add_details("radio_usage","ENG-[msg_engineering.len]")
|
||||
add_details("radio_usage","SEC-[msg_security.len]")
|
||||
add_details("radio_usage","DTH-[msg_deathsquad.len]")
|
||||
add_details("radio_usage","SYN-[msg_syndicate.len]")
|
||||
add_details("radio_usage","SRV-[msg_service.len]")
|
||||
add_details("radio_usage","CAR-[msg_cargo.len]")
|
||||
add_details("radio_usage","OTH-[msg_other.len]")
|
||||
add_details("radio_usage","PDA-[pda_msg_amt]")
|
||||
add_details("radio_usage","RC-[rc_msg_amt]")
|
||||
|
||||
if (!SSdbcore.Connect())
|
||||
return
|
||||
|
||||
var/list/sqlrowlist = list()
|
||||
|
||||
for (var/datum/feedback_variable/FV in feedback)
|
||||
sqlrowlist += list(list("time" = "Now()", "round_id" = GLOB.round_id, "var_name" = "'[sanitizeSQL(FV.get_variable())]'", "var_value" = FV.get_value(), "details" = "'[sanitizeSQL(FV.get_details())]'"))
|
||||
|
||||
if (!length(sqlrowlist))
|
||||
return
|
||||
|
||||
SSdbcore.MassInsert(format_table_name("feedback"), sqlrowlist, ignore_errors = TRUE, delayed = TRUE)
|
||||
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/LogBroadcast(blackbox_msg, freq)
|
||||
if(sealed)
|
||||
return
|
||||
switch(freq)
|
||||
if(1459)
|
||||
msg_common += blackbox_msg
|
||||
if(1351)
|
||||
msg_science += blackbox_msg
|
||||
if(1353)
|
||||
msg_command += blackbox_msg
|
||||
if(1355)
|
||||
msg_medical += blackbox_msg
|
||||
if(1357)
|
||||
msg_engineering += blackbox_msg
|
||||
if(1359)
|
||||
msg_security += blackbox_msg
|
||||
if(1441)
|
||||
msg_deathsquad += blackbox_msg
|
||||
if(1213)
|
||||
msg_syndicate += blackbox_msg
|
||||
if(1349)
|
||||
msg_service += blackbox_msg
|
||||
if(1347)
|
||||
msg_cargo += blackbox_msg
|
||||
else
|
||||
msg_other += blackbox_msg
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/find_feedback_datum(variable)
|
||||
for(var/datum/feedback_variable/FV in feedback)
|
||||
if(FV.get_variable() == variable)
|
||||
return FV
|
||||
|
||||
var/datum/feedback_variable/FV = new(variable)
|
||||
feedback += FV
|
||||
return FV
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/set_val(variable, value)
|
||||
if(sealed)
|
||||
return
|
||||
var/datum/feedback_variable/FV = find_feedback_datum(variable)
|
||||
FV.set_value(value)
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/inc(variable, value)
|
||||
if(sealed)
|
||||
return
|
||||
var/datum/feedback_variable/FV = find_feedback_datum(variable)
|
||||
FV.inc(value)
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/dec(variable,value)
|
||||
if(sealed)
|
||||
return
|
||||
var/datum/feedback_variable/FV = find_feedback_datum(variable)
|
||||
FV.dec(value)
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/set_details(variable,details)
|
||||
if(sealed)
|
||||
return
|
||||
var/datum/feedback_variable/FV = find_feedback_datum(variable)
|
||||
FV.set_details(details)
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/add_details(variable,details)
|
||||
if(sealed)
|
||||
return
|
||||
var/datum/feedback_variable/FV = find_feedback_datum(variable)
|
||||
FV.add_details(details)
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/ReportDeath(mob/living/L)
|
||||
if(sealed)
|
||||
return
|
||||
if(!SSdbcore.Connect())
|
||||
return
|
||||
if(!L || !L.key || !L.mind)
|
||||
return
|
||||
var/turf/T = get_turf(L)
|
||||
var/area/placeofdeath = get_area(T.loc)
|
||||
var/sqlname = sanitizeSQL(L.real_name)
|
||||
var/sqlkey = sanitizeSQL(L.ckey)
|
||||
var/sqljob = sanitizeSQL(L.mind.assigned_role)
|
||||
var/sqlspecial = sanitizeSQL(L.mind.special_role)
|
||||
var/sqlpod = sanitizeSQL(placeofdeath.name)
|
||||
var/laname
|
||||
var/lakey
|
||||
if(L.lastattacker && ismob(L.lastattacker))
|
||||
var/mob/LA = L.lastattacker
|
||||
laname = sanitizeSQL(LA.real_name)
|
||||
lakey = sanitizeSQL(LA.key)
|
||||
var/sqlbrute = sanitizeSQL(L.getBruteLoss())
|
||||
var/sqlfire = sanitizeSQL(L.getFireLoss())
|
||||
var/sqlbrain = sanitizeSQL(L.getBrainLoss())
|
||||
var/sqloxy = sanitizeSQL(L.getOxyLoss())
|
||||
var/sqltox = sanitizeSQL(L.getToxLoss())
|
||||
var/sqlclone = sanitizeSQL(L.getCloneLoss())
|
||||
var/sqlstamina = sanitizeSQL(L.getStaminaLoss())
|
||||
var/x_coord = sanitizeSQL(L.x)
|
||||
var/y_coord = sanitizeSQL(L.y)
|
||||
var/z_coord = sanitizeSQL(L.z)
|
||||
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])")
|
||||
query_report_death.Execute()
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/Seal()
|
||||
if(sealed)
|
||||
return
|
||||
if(IsAdminAdvancedProcCall())
|
||||
var/msg = "[key_name_admin(usr)] sealed the blackbox!"
|
||||
message_admins(msg)
|
||||
log_game("Blackbox sealed[IsAdminAdvancedProcCall() ? " by [key_name(usr)]" : ""].")
|
||||
sealed = TRUE
|
||||
|
||||
//feedback variable datum, for storing all kinds of data
|
||||
/datum/feedback_variable
|
||||
var/variable
|
||||
var/value
|
||||
var/details
|
||||
|
||||
/datum/feedback_variable/New(param_variable, param_value = 0)
|
||||
variable = param_variable
|
||||
value = param_value
|
||||
|
||||
/datum/feedback_variable/proc/inc(num = 1)
|
||||
if (isnum(value))
|
||||
value += num
|
||||
else
|
||||
value = text2num(value)
|
||||
if (isnum(value))
|
||||
value += num
|
||||
else
|
||||
value = num
|
||||
|
||||
/datum/feedback_variable/proc/dec(num = 1)
|
||||
if (isnum(value))
|
||||
value -= num
|
||||
else
|
||||
value = text2num(value)
|
||||
if (isnum(value))
|
||||
value -= num
|
||||
else
|
||||
value = -num
|
||||
|
||||
/datum/feedback_variable/proc/set_value(num)
|
||||
if (isnum(num))
|
||||
value = num
|
||||
|
||||
/datum/feedback_variable/proc/get_value()
|
||||
if (!isnum(value))
|
||||
return 0
|
||||
return value
|
||||
|
||||
/datum/feedback_variable/proc/get_variable()
|
||||
return variable
|
||||
|
||||
SUBSYSTEM_DEF(blackbox)
|
||||
name = "Blackbox"
|
||||
wait = 6000
|
||||
flags = SS_NO_TICK_CHECK
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
init_order = INIT_ORDER_BLACKBOX
|
||||
|
||||
var/list/msg_common = list()
|
||||
var/list/msg_science = list()
|
||||
var/list/msg_command = list()
|
||||
var/list/msg_medical = list()
|
||||
var/list/msg_engineering = list()
|
||||
var/list/msg_security = list()
|
||||
var/list/msg_deathsquad = list()
|
||||
var/list/msg_syndicate = list()
|
||||
var/list/msg_service = list()
|
||||
var/list/msg_cargo = list()
|
||||
var/list/msg_other = list()
|
||||
|
||||
var/list/feedback = list() //list of datum/feedback_variable
|
||||
var/triggertime = 0
|
||||
var/sealed = FALSE //time to stop tracking stats?
|
||||
|
||||
|
||||
/datum/controller/subsystem/blackbox/Initialize()
|
||||
triggertime = world.time
|
||||
. = ..()
|
||||
|
||||
//poll population
|
||||
/datum/controller/subsystem/blackbox/fire()
|
||||
if(!SSdbcore.Connect())
|
||||
return
|
||||
var/playercount = 0
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
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, 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
|
||||
msg_command = SSblackbox.msg_command
|
||||
msg_medical = SSblackbox.msg_medical
|
||||
msg_engineering = SSblackbox.msg_engineering
|
||||
msg_security = SSblackbox.msg_security
|
||||
msg_deathsquad = SSblackbox.msg_deathsquad
|
||||
msg_syndicate = SSblackbox.msg_syndicate
|
||||
msg_service = SSblackbox.msg_service
|
||||
msg_cargo = SSblackbox.msg_cargo
|
||||
msg_other = SSblackbox.msg_other
|
||||
|
||||
feedback = SSblackbox.feedback
|
||||
|
||||
sealed = SSblackbox.sealed
|
||||
|
||||
//no touchie
|
||||
/datum/controller/subsystem/blackbox/can_vv_get(var_name)
|
||||
if(var_name == "feedback")
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/blackbox/vv_edit_var(var_name, var_value)
|
||||
return FALSE
|
||||
|
||||
/datum/controller/subsystem/blackbox/Shutdown()
|
||||
sealed = FALSE
|
||||
set_val("ahelp_unresolved", GLOB.ahelp_tickets.active_tickets.len)
|
||||
|
||||
var/pda_msg_amt = 0
|
||||
var/rc_msg_amt = 0
|
||||
|
||||
for (var/obj/machinery/message_server/MS in GLOB.message_servers)
|
||||
if (MS.pda_msgs.len > pda_msg_amt)
|
||||
pda_msg_amt = MS.pda_msgs.len
|
||||
if (MS.rc_msgs.len > rc_msg_amt)
|
||||
rc_msg_amt = MS.rc_msgs.len
|
||||
|
||||
set_details("radio_usage","")
|
||||
|
||||
add_details("radio_usage","COM-[msg_common.len]")
|
||||
add_details("radio_usage","SCI-[msg_science.len]")
|
||||
add_details("radio_usage","HEA-[msg_command.len]")
|
||||
add_details("radio_usage","MED-[msg_medical.len]")
|
||||
add_details("radio_usage","ENG-[msg_engineering.len]")
|
||||
add_details("radio_usage","SEC-[msg_security.len]")
|
||||
add_details("radio_usage","DTH-[msg_deathsquad.len]")
|
||||
add_details("radio_usage","SYN-[msg_syndicate.len]")
|
||||
add_details("radio_usage","SRV-[msg_service.len]")
|
||||
add_details("radio_usage","CAR-[msg_cargo.len]")
|
||||
add_details("radio_usage","OTH-[msg_other.len]")
|
||||
add_details("radio_usage","PDA-[pda_msg_amt]")
|
||||
add_details("radio_usage","RC-[rc_msg_amt]")
|
||||
|
||||
if (!SSdbcore.Connect())
|
||||
return
|
||||
|
||||
var/list/sqlrowlist = list()
|
||||
|
||||
for (var/datum/feedback_variable/FV in feedback)
|
||||
sqlrowlist += list(list("time" = "Now()", "round_id" = GLOB.round_id, "var_name" = "'[sanitizeSQL(FV.get_variable())]'", "var_value" = FV.get_value(), "details" = "'[sanitizeSQL(FV.get_details())]'"))
|
||||
|
||||
if (!length(sqlrowlist))
|
||||
return
|
||||
|
||||
SSdbcore.MassInsert(format_table_name("feedback"), sqlrowlist, ignore_errors = TRUE, delayed = TRUE)
|
||||
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/LogBroadcast(blackbox_msg, freq)
|
||||
if(sealed)
|
||||
return
|
||||
switch(freq)
|
||||
if(1459)
|
||||
msg_common += blackbox_msg
|
||||
if(1351)
|
||||
msg_science += blackbox_msg
|
||||
if(1353)
|
||||
msg_command += blackbox_msg
|
||||
if(1355)
|
||||
msg_medical += blackbox_msg
|
||||
if(1357)
|
||||
msg_engineering += blackbox_msg
|
||||
if(1359)
|
||||
msg_security += blackbox_msg
|
||||
if(1441)
|
||||
msg_deathsquad += blackbox_msg
|
||||
if(1213)
|
||||
msg_syndicate += blackbox_msg
|
||||
if(1349)
|
||||
msg_service += blackbox_msg
|
||||
if(1347)
|
||||
msg_cargo += blackbox_msg
|
||||
else
|
||||
msg_other += blackbox_msg
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/find_feedback_datum(variable)
|
||||
for(var/datum/feedback_variable/FV in feedback)
|
||||
if(FV.get_variable() == variable)
|
||||
return FV
|
||||
|
||||
var/datum/feedback_variable/FV = new(variable)
|
||||
feedback += FV
|
||||
return FV
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/set_val(variable, value)
|
||||
if(sealed)
|
||||
return
|
||||
var/datum/feedback_variable/FV = find_feedback_datum(variable)
|
||||
FV.set_value(value)
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/inc(variable, value)
|
||||
if(sealed)
|
||||
return
|
||||
var/datum/feedback_variable/FV = find_feedback_datum(variable)
|
||||
FV.inc(value)
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/dec(variable,value)
|
||||
if(sealed)
|
||||
return
|
||||
var/datum/feedback_variable/FV = find_feedback_datum(variable)
|
||||
FV.dec(value)
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/set_details(variable,details)
|
||||
if(sealed)
|
||||
return
|
||||
var/datum/feedback_variable/FV = find_feedback_datum(variable)
|
||||
FV.set_details(details)
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/add_details(variable,details)
|
||||
if(sealed)
|
||||
return
|
||||
var/datum/feedback_variable/FV = find_feedback_datum(variable)
|
||||
FV.add_details(details)
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/ReportDeath(mob/living/L)
|
||||
if(sealed)
|
||||
return
|
||||
if(!SSdbcore.Connect())
|
||||
return
|
||||
if(!L || !L.key || !L.mind)
|
||||
return
|
||||
var/turf/T = get_turf(L)
|
||||
var/area/placeofdeath = get_area(T.loc)
|
||||
var/sqlname = sanitizeSQL(L.real_name)
|
||||
var/sqlkey = sanitizeSQL(L.ckey)
|
||||
var/sqljob = sanitizeSQL(L.mind.assigned_role)
|
||||
var/sqlspecial = sanitizeSQL(L.mind.special_role)
|
||||
var/sqlpod = sanitizeSQL(placeofdeath.name)
|
||||
var/laname
|
||||
var/lakey
|
||||
if(L.lastattacker && ismob(L.lastattacker))
|
||||
var/mob/LA = L.lastattacker
|
||||
laname = sanitizeSQL(LA.real_name)
|
||||
lakey = sanitizeSQL(LA.key)
|
||||
var/sqlbrute = sanitizeSQL(L.getBruteLoss())
|
||||
var/sqlfire = sanitizeSQL(L.getFireLoss())
|
||||
var/sqlbrain = sanitizeSQL(L.getBrainLoss())
|
||||
var/sqloxy = sanitizeSQL(L.getOxyLoss())
|
||||
var/sqltox = sanitizeSQL(L.getToxLoss())
|
||||
var/sqlclone = sanitizeSQL(L.getCloneLoss())
|
||||
var/sqlstamina = sanitizeSQL(L.getStaminaLoss())
|
||||
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, last_words, suicide) VALUES ('[sqlpod]', '[x_coord]', '[y_coord]', '[z_coord]', '[map]', INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]', [GLOB.round_id], '[SQLtime()]', '[sqljob]', '[sqlspecial]', '[sqlname]', '[sqlkey]', '[laname]', '[lakey]', [sqlbrute], [sqlfire], [sqlbrain], [sqloxy], [sqltox], [sqlclone], [sqlstamina], '[last_words]', [suicide])")
|
||||
query_report_death.Execute()
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/Seal()
|
||||
if(sealed)
|
||||
return
|
||||
if(IsAdminAdvancedProcCall())
|
||||
var/msg = "[key_name_admin(usr)] sealed the blackbox!"
|
||||
message_admins(msg)
|
||||
log_game("Blackbox sealed[IsAdminAdvancedProcCall() ? " by [key_name(usr)]" : ""].")
|
||||
sealed = TRUE
|
||||
|
||||
//feedback variable datum, for storing all kinds of data
|
||||
/datum/feedback_variable
|
||||
var/variable
|
||||
var/value
|
||||
var/list/details
|
||||
|
||||
/datum/feedback_variable/New(param_variable, param_value = 0)
|
||||
variable = param_variable
|
||||
value = param_value
|
||||
|
||||
/datum/feedback_variable/proc/inc(num = 1)
|
||||
if (isnum(value))
|
||||
value += num
|
||||
else
|
||||
value = text2num(value)
|
||||
if (isnum(value))
|
||||
value += num
|
||||
else
|
||||
value = num
|
||||
|
||||
/datum/feedback_variable/proc/dec(num = 1)
|
||||
if (isnum(value))
|
||||
value -= num
|
||||
else
|
||||
value = text2num(value)
|
||||
if (isnum(value))
|
||||
value -= num
|
||||
else
|
||||
value = -num
|
||||
|
||||
/datum/feedback_variable/proc/set_value(num)
|
||||
if (isnum(num))
|
||||
value = num
|
||||
|
||||
/datum/feedback_variable/proc/get_value()
|
||||
if (!isnum(value))
|
||||
return 0
|
||||
return value
|
||||
|
||||
/datum/feedback_variable/proc/get_variable()
|
||||
return variable
|
||||
|
||||
/datum/feedback_variable/proc/set_details(deets)
|
||||
details = "\"[deets]\""
|
||||
details = list("\"[deets]\"")
|
||||
|
||||
/datum/feedback_variable/proc/add_details(deets)
|
||||
if (!details)
|
||||
set_details(deets)
|
||||
else
|
||||
details += " | \"[deets]\""
|
||||
|
||||
/datum/feedback_variable/proc/get_details()
|
||||
return details
|
||||
|
||||
/datum/feedback_variable/proc/get_parsed()
|
||||
return list(variable,value,details)
|
||||
details += "\"[deets]\""
|
||||
|
||||
/datum/feedback_variable/proc/get_details()
|
||||
return details.Join(" | ")
|
||||
|
||||
/datum/feedback_variable/proc/get_parsed()
|
||||
return list(variable,value,details.Join(" | "))
|
||||
|
||||
10
code/controllers/subsystem/blackbox.dm.rej
Normal file
10
code/controllers/subsystem/blackbox.dm.rej
Normal file
@@ -0,0 +1,10 @@
|
||||
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))
|
||||
|
||||
@@ -73,6 +73,8 @@ SUBSYSTEM_DEF(job)
|
||||
return 0
|
||||
if(!job.player_old_enough(player.client))
|
||||
return 0
|
||||
if(job.required_playtime_remaining(player.client))
|
||||
return 0
|
||||
var/position_limit = job.total_positions
|
||||
if(!latejoin)
|
||||
position_limit = job.spawn_positions
|
||||
@@ -95,6 +97,9 @@ SUBSYSTEM_DEF(job)
|
||||
if(!job.player_old_enough(player.client))
|
||||
Debug("FOC player not old enough, Player: [player]")
|
||||
continue
|
||||
if(job.required_playtime_remaining(player.client))
|
||||
Debug("FOC player not enough xp, Player: [player]")
|
||||
continue
|
||||
if(flag && (!(flag in player.client.prefs.be_special)))
|
||||
Debug("FOC flag failed, Player: [player], Flag: [flag], ")
|
||||
continue
|
||||
@@ -130,6 +135,10 @@ SUBSYSTEM_DEF(job)
|
||||
Debug("GRJ player not old enough, Player: [player]")
|
||||
continue
|
||||
|
||||
if(job.required_playtime_remaining(player.client))
|
||||
Debug("GRJ player not enough xp, Player: [player]")
|
||||
continue
|
||||
|
||||
if(player.mind && job.title in player.mind.restricted_roles)
|
||||
Debug("GRJ incompatible with antagonist role, Player: [player], Job: [job.title]")
|
||||
continue
|
||||
@@ -300,6 +309,10 @@ SUBSYSTEM_DEF(job)
|
||||
Debug("DO player not old enough, Player: [player], Job:[job.title]")
|
||||
continue
|
||||
|
||||
if(job.required_playtime_remaining(player.client))
|
||||
Debug("DO player not enough xp, Player: [player], Job:[job.title]")
|
||||
continue
|
||||
|
||||
if(player.mind && job.title in player.mind.restricted_roles)
|
||||
Debug("DO incompatible with antagonist role, Player: [player], Job:[job.title]")
|
||||
continue
|
||||
@@ -407,7 +420,7 @@ SUBSYSTEM_DEF(job)
|
||||
|
||||
if(job && H)
|
||||
job.after_spawn(H, M)
|
||||
|
||||
handle_roundstart_items(H, M.ckey, H.mind.assigned_role, H.mind.special_role)
|
||||
return H
|
||||
|
||||
|
||||
@@ -463,6 +476,9 @@ SUBSYSTEM_DEF(job)
|
||||
if(!job.player_old_enough(player.client))
|
||||
level6++
|
||||
continue
|
||||
if(job.required_playtime_remaining(player.client))
|
||||
level6++
|
||||
continue
|
||||
if(player.client.prefs.GetJobDepartment(job, 1) & job.flag)
|
||||
level1++
|
||||
else if(player.client.prefs.GetJobDepartment(job, 2) & job.flag)
|
||||
|
||||
@@ -2,15 +2,15 @@ SUBSYSTEM_DEF(persistence)
|
||||
name = "Persistence"
|
||||
init_order = INIT_ORDER_PERSISTENCE
|
||||
flags = SS_NO_FIRE
|
||||
var/savefile/secret_satchels
|
||||
var/secret_satchels
|
||||
var/list/satchel_blacklist = list() //this is a typecache
|
||||
var/list/new_secret_satchels = list() //these are objects
|
||||
var/old_secret_satchels = ""
|
||||
var/list/old_secret_satchels = ""
|
||||
|
||||
var/list/obj/structure/chisel_message/chisel_messages = list()
|
||||
var/list/saved_messages = list()
|
||||
|
||||
var/savefile/trophy_sav
|
||||
var/trophy_sav
|
||||
var/list/saved_trophies = list()
|
||||
|
||||
/datum/controller/subsystem/persistence/Initialize()
|
||||
@@ -21,67 +21,53 @@ SUBSYSTEM_DEF(persistence)
|
||||
..()
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/LoadSatchels()
|
||||
secret_satchels = new /savefile("data/npc_saves/SecretSatchels.sav")
|
||||
secret_satchels = file("data/npc_saves/SecretSatchels[SSmapping.config.map_name].json")
|
||||
if(!fexists(secret_satchels))
|
||||
return
|
||||
satchel_blacklist = typecacheof(list(/obj/item/stack/tile/plasteel, /obj/item/crowbar))
|
||||
secret_satchels[SSmapping.config.map_name] >> old_secret_satchels
|
||||
|
||||
var/list/expanded_old_satchels = list()
|
||||
var/placed_satchels = 0
|
||||
|
||||
if(!isnull(old_secret_satchels))
|
||||
expanded_old_satchels = splittext(old_secret_satchels,"#")
|
||||
if(PlaceSecretSatchel(expanded_old_satchels))
|
||||
placed_satchels++
|
||||
else
|
||||
expanded_old_satchels.len = 0
|
||||
var/list/json = list()
|
||||
json = json_decode(file2text(secret_satchels))
|
||||
old_secret_satchels = json["data"]
|
||||
var/placed_satchel = 0
|
||||
if(old_secret_satchels.len)
|
||||
if(old_secret_satchels.len >= 20) //guards against low drop pools assuring that one player cannot reliably find his own gear.
|
||||
var/pos = rand(1, old_secret_satchels.len)
|
||||
old_secret_satchels.Cut(pos, pos+1)
|
||||
var/obj/item/storage/backpack/satchel/flat/F = new()
|
||||
F.x = old_secret_satchels[pos]["x"]
|
||||
F.y = old_secret_satchels[pos]["y"]
|
||||
F.z = ZLEVEL_STATION
|
||||
var/path = text2path(old_secret_satchels[pos]["saved_obj"])
|
||||
if(!ispath(path))
|
||||
return
|
||||
if(isfloorturf(F.loc) && !istype(F.loc, /turf/open/floor/plating/))
|
||||
F.hide(1)
|
||||
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
|
||||
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_satchels) >= (50 - expanded_old_satchels.len) * 0.1)) //up to six tiles, more than enough to kill anything that moves
|
||||
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
|
||||
break
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/PlaceSecretSatchel(list/expanded_old_satchels)
|
||||
var/satchel_string
|
||||
|
||||
if(expanded_old_satchels.len >= 20) //guards against low drop pools assuring that one player cannot reliably find his own gear.
|
||||
satchel_string = pick_n_take(expanded_old_satchels)
|
||||
|
||||
old_secret_satchels = jointext(expanded_old_satchels,"#")
|
||||
WRITE_FILE(secret_satchels[SSmapping.config.map_name], old_secret_satchels)
|
||||
|
||||
var/list/chosen_satchel = splittext(satchel_string,"|")
|
||||
if(!chosen_satchel || isemptylist(chosen_satchel) || chosen_satchel.len != 3) //Malformed
|
||||
return 0
|
||||
|
||||
var/path = text2path(chosen_satchel[3]) //If the item no longer exist, this returns null
|
||||
if(!path)
|
||||
return 0
|
||||
|
||||
var/obj/item/storage/backpack/satchel/flat/F = new()
|
||||
F.x = text2num(chosen_satchel[1])
|
||||
F.y = text2num(chosen_satchel[2])
|
||||
F.z = ZLEVEL_STATION
|
||||
if(isfloorturf(F.loc) && !istype(F.loc, /turf/open/floor/plating/))
|
||||
F.hide(1)
|
||||
new path(F)
|
||||
return 1
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/LoadPoly()
|
||||
for(var/mob/living/simple_animal/parrot/Poly/P in GLOB.living_mob_list)
|
||||
twitterize(P.speech_buffer, "polytalk")
|
||||
break //Who's been duping the bird?!
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/LoadChiselMessages()
|
||||
var/savefile/chisel_messages_sav = new /savefile("data/npc_saves/ChiselMessages.sav")
|
||||
var/saved_json
|
||||
chisel_messages_sav[SSmapping.config.map_name] >> saved_json
|
||||
var/json_file = file("data/npc_saves/ChiselMessages[SSmapping.config.map_name].json")
|
||||
if(!fexists(json_file))
|
||||
return
|
||||
var/list/json
|
||||
json = json_decode(file2text(json_file))
|
||||
|
||||
if(!saved_json)
|
||||
if(!json)
|
||||
return
|
||||
|
||||
var/list/saved_messages = json_decode(saved_json)
|
||||
var/list/saved_messages = json["data"]
|
||||
|
||||
for(var/item in saved_messages)
|
||||
if(!islist(item))
|
||||
@@ -109,19 +95,16 @@ SUBSYSTEM_DEF(persistence)
|
||||
log_world("Loaded [saved_messages.len] engraved messages on map [SSmapping.config.map_name]")
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/LoadTrophies()
|
||||
trophy_sav = new /savefile("data/npc_saves/TrophyItems.sav")
|
||||
var/saved_json
|
||||
trophy_sav >> saved_json
|
||||
trophy_sav = file("data/npc_saves/TrophyItems.json")
|
||||
if(!fexists(trophy_sav))
|
||||
return
|
||||
var/list/json = list()
|
||||
json = json_decode(file2text(trophy_sav))
|
||||
|
||||
if(!saved_json)
|
||||
if(!json)
|
||||
return
|
||||
|
||||
var/decoded_json = json_decode(saved_json)
|
||||
|
||||
if(!islist(decoded_json))
|
||||
return
|
||||
|
||||
saved_trophies = decoded_json
|
||||
saved_trophies = json["data"]
|
||||
|
||||
SetUpTrophies(saved_trophies.Copy())
|
||||
|
||||
@@ -156,6 +139,7 @@ SUBSYSTEM_DEF(persistence)
|
||||
CollectTrophies()
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/CollectSecretSatchels()
|
||||
var/list/satchels = list()
|
||||
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)
|
||||
@@ -170,25 +154,37 @@ SUBSYSTEM_DEF(persistence)
|
||||
savable_obj += O.type
|
||||
if(isemptylist(savable_obj))
|
||||
continue
|
||||
old_secret_satchels += "[F.x]|[F.y]|[pick(savable_obj)]#"
|
||||
WRITE_FILE(secret_satchels[SSmapping.config.map_name], old_secret_satchels)
|
||||
var/list/data = list()
|
||||
data["x"] = F.x
|
||||
data["y"] = F.y
|
||||
data["saved_obj"] = pick(savable_obj)
|
||||
satchels += list(data)
|
||||
var/list/file_data = list()
|
||||
file_data["data"] = satchels
|
||||
fdel(secret_satchels)
|
||||
WRITE_FILE(secret_satchels, json_encode(file_data))
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/CollectChiselMessages()
|
||||
var/savefile/chisel_messages_sav = new /savefile("data/npc_saves/ChiselMessages.sav")
|
||||
var/json_file = file("data/npc_saves/ChiselMessages[SSmapping.config.map_name].json")
|
||||
|
||||
for(var/obj/structure/chisel_message/M in chisel_messages)
|
||||
saved_messages += list(M.pack())
|
||||
|
||||
log_world("Saved [saved_messages.len] engraved messages on map [SSmapping.config.map_name]")
|
||||
|
||||
WRITE_FILE(chisel_messages_sav[SSmapping.config.map_name], json_encode(saved_messages))
|
||||
var/list/file_data = list()
|
||||
file_data["data"] = saved_messages
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/SaveChiselMessage(obj/structure/chisel_message/M)
|
||||
saved_messages += list(M.pack()) // dm eats one list
|
||||
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/CollectTrophies()
|
||||
WRITE_FILE(trophy_sav, json_encode(saved_trophies))
|
||||
var/list/file_data = list()
|
||||
file_data["data"] = saved_trophies
|
||||
fdel(trophy_sav)
|
||||
WRITE_FILE(trophy_sav, json_encode(file_data))
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/SaveTrophy(obj/structure/displaycase/trophy/T)
|
||||
if(!T.added_roundstart && T.showpiece)
|
||||
@@ -196,4 +192,4 @@ SUBSYSTEM_DEF(persistence)
|
||||
data["path"] = T.showpiece.type
|
||||
data["message"] = T.trophy_message
|
||||
data["placer_key"] = T.placer_key
|
||||
saved_trophies += list(data)
|
||||
saved_trophies += list(data)
|
||||
30
code/controllers/subsystem/server_maint.dm.rej
Normal file
30
code/controllers/subsystem/server_maint.dm.rej
Normal file
@@ -0,0 +1,30 @@
|
||||
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)
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -465,6 +465,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))
|
||||
@@ -513,7 +519,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
|
||||
@@ -533,7 +539,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>")
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -172,6 +172,7 @@
|
||||
|
||||
/datum/action/item_action/rcl
|
||||
name = "Change Cable Color"
|
||||
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
||||
button_icon_state = "rcl_rainbow"
|
||||
|
||||
/datum/action/item_action/startchainsaw
|
||||
@@ -405,27 +406,24 @@
|
||||
/datum/action/item_action/initialize_ninja_suit
|
||||
name = "Toggle ninja suit"
|
||||
|
||||
/datum/action/item_action/ninjajaunt
|
||||
name = "Phase Jaunt (10E)"
|
||||
desc = "Utilizes the internal VOID-shift device to rapidly transit in direction facing."
|
||||
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
||||
button_icon_state = "ninja_phase"
|
||||
|
||||
/datum/action/item_action/ninjasmoke
|
||||
name = "Smoke Bomb"
|
||||
desc = "Blind your enemies momentarily with a well-placed smoke bomb."
|
||||
button_icon_state = "smoke"
|
||||
icon_icon = 'icons/mob/actions/actions_spells.dmi'
|
||||
|
||||
/datum/action/item_action/ninjaboost
|
||||
check_flags = AB_CHECK_RESTRAINED|AB_CHECK_CONSCIOUS
|
||||
check_flags = NONE
|
||||
name = "Adrenaline Boost"
|
||||
desc = "Inject a secret chemical that will counteract all movement-impairing effect."
|
||||
button_icon_state = "repulse"
|
||||
icon_icon = 'icons/mob/actions/actions_spells.dmi'
|
||||
|
||||
/datum/action/item_action/ninjapulse
|
||||
name = "EM Burst (25E)"
|
||||
desc = "Disable any nearby technology with a electro-magnetic pulse."
|
||||
button_icon_state = "emp"
|
||||
icon_icon = 'icons/mob/actions/actions_spells.dmi'
|
||||
|
||||
/datum/action/item_action/ninjastar
|
||||
name = "Create Throwing Stars (1E)"
|
||||
@@ -448,8 +446,8 @@
|
||||
/datum/action/item_action/ninja_stealth
|
||||
name = "Toggle Stealth"
|
||||
desc = "Toggles stealth mode on and off."
|
||||
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
||||
button_icon_state = "ninja_cloak"
|
||||
icon_icon = 'icons/mob/actions/actions_minor_antag.dmi'
|
||||
|
||||
/datum/action/item_action/toggle_glove
|
||||
name = "Toggle interaction"
|
||||
@@ -491,7 +489,7 @@
|
||||
S.action = src
|
||||
name = S.name
|
||||
desc = S.desc
|
||||
button_icon = S.action_icon
|
||||
icon_icon = S.action_icon
|
||||
button_icon_state = S.action_icon_state
|
||||
background_icon_state = S.action_background_icon_state
|
||||
button.name = name
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/space_ninja(H), slot_wear_mask)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/glasses/night(H), slot_glasses)
|
||||
H.equip_to_slot_or_del(EK, slot_belt)
|
||||
H.equip_to_slot_or_del(new /obj/item/device/flashlight(H), slot_r_store)
|
||||
H.equip_to_slot_or_del(new /obj/item/grenade/plastic/x4(H), slot_l_store)
|
||||
H.equip_to_slot_or_del(new /obj/item/tank/internals/emergency_oxygen(H), slot_s_store)
|
||||
H.equip_to_slot_or_del(new /obj/item/tank/jetpack/carbondioxide(H), slot_back)
|
||||
|
||||
92
code/datums/components/archaeology.dm
Normal file
92
code/datums/components/archaeology.dm
Normal file
@@ -0,0 +1,92 @@
|
||||
/datum/component/archaeology
|
||||
dupe_type = COMPONENT_DUPE_UNIQUE
|
||||
var/list/archdrops
|
||||
var/prob2drop
|
||||
var/dug
|
||||
|
||||
/datum/component/archaeology/Initialize(_prob2drop, list/_archdrops = list())
|
||||
prob2drop = Clamp(_prob2drop, 0, 100)
|
||||
archdrops = _archdrops
|
||||
RegisterSignal(COMSIG_PARENT_ATTACKBY,.proc/Dig)
|
||||
RegisterSignal(COMSIG_ATOM_EX_ACT, .proc/BombDig)
|
||||
RegisterSignal(COMSIG_ATOM_SING_PULL, .proc/SingDig)
|
||||
|
||||
/datum/component/archaeology/InheritComponent(datum/component/archaeology/A, i_am_original)
|
||||
var/list/other_archdrops = A.archdrops
|
||||
var/list/_archdrops = archdrops
|
||||
for(var/I in other_archdrops)
|
||||
_archdrops[I] += other_archdrops[I]
|
||||
|
||||
/datum/component/archaeology/proc/Dig(mob/user, obj/item/W)
|
||||
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]"
|
||||
OT.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()
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -18,6 +18,7 @@ Bonus
|
||||
/datum/symptom/voice_change
|
||||
|
||||
name = "Voice Change"
|
||||
desc = "The virus alters the pitch and tone of the host's vocal cords, changing how their voice sounds."
|
||||
stealth = -1
|
||||
resistance = -2
|
||||
stage_speed = -2
|
||||
@@ -30,6 +31,9 @@ Bonus
|
||||
var/scramble_language = FALSE
|
||||
var/datum/language/current_language
|
||||
var/datum/language_holder/original_language
|
||||
threshold_desc = "<b>Transmission 14:</b> The host's language center of the brain is damaged, leading to complete inability to speak or understand any language.<br>\
|
||||
<b>Stage Speed 7:</b> Changes voice more often.<br>\
|
||||
<b>Stealth 3:</b> The symptom remains hidden until active."
|
||||
|
||||
/datum/symptom/voice_change/Start(datum/disease/advance/A)
|
||||
..()
|
||||
|
||||
@@ -22,6 +22,7 @@ Bonus
|
||||
/datum/symptom/vomit
|
||||
|
||||
name = "Vomiting"
|
||||
desc = "The virus causes nausea and irritates the stomach, causing occasional vomit."
|
||||
stealth = -2
|
||||
resistance = -1
|
||||
stage_speed = 0
|
||||
@@ -33,6 +34,9 @@ Bonus
|
||||
symptom_delay_max = 80
|
||||
var/vomit_blood = FALSE
|
||||
var/proj_vomit = 0
|
||||
threshold_desc = "<b>Resistance 7:</b> Host will vomit blood, causing internal damage.<br>\
|
||||
<b>Transmission 7:</b> Host will projectile vomit, increasing vomiting range.<br>\
|
||||
<b>Stealth 4:</b> The symptom remains hidden until active."
|
||||
|
||||
/datum/symptom/vomit/Start(datum/disease/advance/A)
|
||||
..()
|
||||
|
||||
@@ -18,6 +18,7 @@ Bonus
|
||||
/datum/symptom/weight_gain
|
||||
|
||||
name = "Weight Gain"
|
||||
desc = "The virus mutates the host's metabolism, making it gain weight much faster than normal."
|
||||
stealth = -3
|
||||
resistance = -3
|
||||
stage_speed = -2
|
||||
@@ -27,6 +28,7 @@ Bonus
|
||||
base_message_chance = 100
|
||||
symptom_delay_min = 15
|
||||
symptom_delay_max = 45
|
||||
threshold_desc = "<b>Stealth 4:</b> The symptom is less noticeable."
|
||||
|
||||
/datum/symptom/weight_gain/Start(datum/disease/advance/A)
|
||||
..()
|
||||
@@ -66,6 +68,7 @@ Bonus
|
||||
/datum/symptom/weight_loss
|
||||
|
||||
name = "Weight Loss"
|
||||
desc = "The virus mutates the host's metabolism, making it almost unable to gain nutrition from food."
|
||||
stealth = -3
|
||||
resistance = -2
|
||||
stage_speed = -2
|
||||
@@ -75,6 +78,7 @@ Bonus
|
||||
base_message_chance = 100
|
||||
symptom_delay_min = 15
|
||||
symptom_delay_max = 45
|
||||
threshold_desc = "<b>Stealth 4:</b> The symptom is less noticeable."
|
||||
|
||||
/datum/symptom/weight_loss/Start(datum/disease/advance/A)
|
||||
..()
|
||||
@@ -116,6 +120,7 @@ Bonus
|
||||
/datum/symptom/weight_even
|
||||
|
||||
name = "Weight Even"
|
||||
desc = "The virus alters the host's metabolism, making it far more efficient then normal, and synthesizing nutrients from normally unedible sources."
|
||||
stealth = -3
|
||||
resistance = -2
|
||||
stage_speed = -2
|
||||
|
||||
@@ -18,6 +18,8 @@ BONUS
|
||||
/datum/symptom/youth
|
||||
|
||||
name = "Eternal Youth"
|
||||
desc = "The virus becomes symbiotically connected to the cells in the host's body, preventing and reversing aging. \
|
||||
The virus, in turn, becomes more resistant, spreads faster, and is harder to spot, although it doesn't thrive as well without a host."
|
||||
stealth = 3
|
||||
resistance = 4
|
||||
stage_speed = 4
|
||||
|
||||
@@ -6,8 +6,14 @@
|
||||
var/date
|
||||
|
||||
/datum/getrev/New()
|
||||
if(world.RunningService() && fexists(SERVICE_PR_TEST_JSON))
|
||||
testmerge = json_decode(file2text(SERVICE_PR_TEST_JSON))
|
||||
if(world.RunningService())
|
||||
var/file_name
|
||||
if(ServiceVersion()) //will return null for versions < 3.0.91.0
|
||||
file_name = SERVICE_PR_TEST_JSON_OLD
|
||||
else
|
||||
file_name = SERVICE_PR_TEST_JSON
|
||||
if(fexists(file_name))
|
||||
testmerge = json_decode(file2text(file_name))
|
||||
#ifdef SERVERTOOLS
|
||||
else if(!world.RunningService() && fexists("../prtestjob.lk")) //tgs2 support
|
||||
var/list/tmp = world.file2list("..\\prtestjob.lk")
|
||||
|
||||
@@ -4,142 +4,142 @@
|
||||
// -Cyberboss
|
||||
|
||||
/datum/map_config
|
||||
var/config_filename = "_maps/boxstation.json"
|
||||
var/map_name = "Box Station"
|
||||
var/map_path = "map_files/BoxStation"
|
||||
var/map_file = "BoxStation.dmm"
|
||||
var/config_filename = "_maps/boxstation.json"
|
||||
var/map_name = "Box Station"
|
||||
var/map_path = "map_files/BoxStation"
|
||||
var/map_file = "BoxStation.dmm"
|
||||
|
||||
var/minetype = "lavaland"
|
||||
var/minetype = "lavaland"
|
||||
|
||||
var/list/transition_config = list(CENTCOM = SELFLOOPING,
|
||||
var/list/transition_config = list(CENTCOM = SELFLOOPING,
|
||||
MAIN_STATION = CROSSLINKED,
|
||||
EMPTY_AREA_1 = CROSSLINKED,
|
||||
EMPTY_AREA_2 = CROSSLINKED,
|
||||
MINING = SELFLOOPING,
|
||||
EMPTY_AREA_3 = CROSSLINKED,
|
||||
EMPTY_AREA_4 = CROSSLINKED,
|
||||
EMPTY_AREA_5 = CROSSLINKED,
|
||||
EMPTY_AREA_6 = CROSSLINKED,
|
||||
EMPTY_AREA_7 = CROSSLINKED,
|
||||
EMPTY_AREA_8 = CROSSLINKED)
|
||||
var/defaulted = TRUE //if New failed
|
||||
EMPTY_AREA_1 = CROSSLINKED,
|
||||
EMPTY_AREA_2 = CROSSLINKED,
|
||||
MINING = SELFLOOPING,
|
||||
EMPTY_AREA_3 = CROSSLINKED,
|
||||
EMPTY_AREA_4 = CROSSLINKED,
|
||||
EMPTY_AREA_5 = CROSSLINKED,
|
||||
EMPTY_AREA_6 = CROSSLINKED,
|
||||
EMPTY_AREA_7 = CROSSLINKED,
|
||||
EMPTY_AREA_8 = CROSSLINKED)
|
||||
var/defaulted = TRUE //if New failed
|
||||
|
||||
var/config_max_users = 0
|
||||
var/config_min_users = 0
|
||||
var/voteweight = 1
|
||||
var/allow_custom_shuttles = "yes"
|
||||
var/config_max_users = 0
|
||||
var/config_min_users = 0
|
||||
var/voteweight = 1
|
||||
var/allow_custom_shuttles = "yes"
|
||||
/datum/map_config/New(filename = "data/next_map.json", default_to_box, delete_after)
|
||||
if(default_to_box)
|
||||
return
|
||||
LoadConfig(filename)
|
||||
if(delete_after)
|
||||
fdel(filename)
|
||||
if(default_to_box)
|
||||
return
|
||||
LoadConfig(filename)
|
||||
if(delete_after)
|
||||
fdel(filename)
|
||||
|
||||
/datum/map_config/proc/LoadConfig(filename)
|
||||
if(!fexists(filename))
|
||||
log_world("map_config not found: [filename]")
|
||||
return
|
||||
if(!fexists(filename))
|
||||
log_world("map_config not found: [filename]")
|
||||
return
|
||||
|
||||
var/json = file(filename)
|
||||
if(!json)
|
||||
log_world("Could not open map_config: [filename]")
|
||||
return
|
||||
var/json = file(filename)
|
||||
if(!json)
|
||||
log_world("Could not open map_config: [filename]")
|
||||
return
|
||||
|
||||
json = file2text(json)
|
||||
if(!json)
|
||||
log_world("map_config is not text: [filename]")
|
||||
return
|
||||
json = file2text(json)
|
||||
if(!json)
|
||||
log_world("map_config is not text: [filename]")
|
||||
return
|
||||
|
||||
json = json_decode(json)
|
||||
if(!json)
|
||||
log_world("map_config is not json: [filename]")
|
||||
return
|
||||
json = json_decode(json)
|
||||
if(!json)
|
||||
log_world("map_config is not json: [filename]")
|
||||
return
|
||||
|
||||
if(!ValidateJSON(json))
|
||||
log_world("map_config failed to validate for above reason: [filename]")
|
||||
return
|
||||
if(!ValidateJSON(json))
|
||||
log_world("map_config failed to validate for above reason: [filename]")
|
||||
return
|
||||
|
||||
config_filename = filename
|
||||
config_filename = filename
|
||||
|
||||
map_name = json["map_name"]
|
||||
map_path = json["map_path"]
|
||||
map_file = json["map_file"]
|
||||
map_name = json["map_name"]
|
||||
map_path = json["map_path"]
|
||||
map_file = json["map_file"]
|
||||
|
||||
minetype = json["minetype"]
|
||||
allow_custom_shuttles = json["allow_custom_shuttles"]
|
||||
minetype = json["minetype"]
|
||||
allow_custom_shuttles = json["allow_custom_shuttles"]
|
||||
|
||||
var/list/jtcl = json["transition_config"]
|
||||
var/list/jtcl = json["transition_config"]
|
||||
|
||||
if(jtcl != "default")
|
||||
transition_config.Cut()
|
||||
if(jtcl != "default")
|
||||
transition_config.Cut()
|
||||
|
||||
for(var/I in jtcl)
|
||||
transition_config[TransitionStringToEnum(I)] = TransitionStringToEnum(jtcl[I])
|
||||
for(var/I in jtcl)
|
||||
transition_config[TransitionStringToEnum(I)] = TransitionStringToEnum(jtcl[I])
|
||||
|
||||
defaulted = FALSE
|
||||
defaulted = FALSE
|
||||
|
||||
#define CHECK_EXISTS(X) if(!istext(json[X])) { log_world(X + "missing from json!"); return; }
|
||||
/datum/map_config/proc/ValidateJSON(list/json)
|
||||
CHECK_EXISTS("map_name")
|
||||
CHECK_EXISTS("map_path")
|
||||
CHECK_EXISTS("map_file")
|
||||
CHECK_EXISTS("minetype")
|
||||
CHECK_EXISTS("transition_config")
|
||||
CHECK_EXISTS("allow_custom_shuttles")
|
||||
CHECK_EXISTS("map_name")
|
||||
CHECK_EXISTS("map_path")
|
||||
CHECK_EXISTS("map_file")
|
||||
CHECK_EXISTS("minetype")
|
||||
CHECK_EXISTS("transition_config")
|
||||
CHECK_EXISTS("allow_custom_shuttles")
|
||||
|
||||
var/path = GetFullMapPath(json["map_path"], json["map_file"])
|
||||
if(!fexists(path))
|
||||
log_world("Map file ([path]) does not exist!")
|
||||
return
|
||||
var/path = GetFullMapPath(json["map_path"], json["map_file"])
|
||||
if(!fexists(path))
|
||||
log_world("Map file ([path]) does not exist!")
|
||||
return
|
||||
|
||||
if(json["transition_config"] != "default")
|
||||
if(!islist(json["transition_config"]))
|
||||
log_world("transition_config is not a list!")
|
||||
return
|
||||
if(json["transition_config"] != "default")
|
||||
if(!islist(json["transition_config"]))
|
||||
log_world("transition_config is not a list!")
|
||||
return
|
||||
|
||||
var/list/jtcl = json["transition_config"]
|
||||
for(var/I in jtcl)
|
||||
if(isnull(TransitionStringToEnum(I)))
|
||||
log_world("Invalid transition_config option: [I]!")
|
||||
if(isnull(TransitionStringToEnum(jtcl[I])))
|
||||
log_world("Invalid transition_config option: [I]!")
|
||||
var/list/jtcl = json["transition_config"]
|
||||
for(var/I in jtcl)
|
||||
if(isnull(TransitionStringToEnum(I)))
|
||||
log_world("Invalid transition_config option: [I]!")
|
||||
if(isnull(TransitionStringToEnum(jtcl[I])))
|
||||
log_world("Invalid transition_config option: [I]!")
|
||||
|
||||
return TRUE
|
||||
return TRUE
|
||||
#undef CHECK_EXISTS
|
||||
|
||||
/datum/map_config/proc/TransitionStringToEnum(string)
|
||||
switch(string)
|
||||
if("CROSSLINKED")
|
||||
return CROSSLINKED
|
||||
if("SELFLOOPING")
|
||||
return SELFLOOPING
|
||||
if("UNAFFECTED")
|
||||
return UNAFFECTED
|
||||
if("MAIN_STATION")
|
||||
return MAIN_STATION
|
||||
if("CENTCOM")
|
||||
return CENTCOM
|
||||
if("MINING")
|
||||
return MINING
|
||||
if("EMPTY_AREA_1")
|
||||
return EMPTY_AREA_1
|
||||
if("EMPTY_AREA_2")
|
||||
return EMPTY_AREA_2
|
||||
if("EMPTY_AREA_3")
|
||||
return EMPTY_AREA_3
|
||||
if("EMPTY_AREA_4")
|
||||
return EMPTY_AREA_4
|
||||
if("EMPTY_AREA_5")
|
||||
return EMPTY_AREA_5
|
||||
if("EMPTY_AREA_6")
|
||||
return EMPTY_AREA_6
|
||||
if("EMPTY_AREA_7")
|
||||
return EMPTY_AREA_7
|
||||
if("EMPTY_AREA_8")
|
||||
return EMPTY_AREA_8
|
||||
switch(string)
|
||||
if("CROSSLINKED")
|
||||
return CROSSLINKED
|
||||
if("SELFLOOPING")
|
||||
return SELFLOOPING
|
||||
if("UNAFFECTED")
|
||||
return UNAFFECTED
|
||||
if("MAIN_STATION")
|
||||
return MAIN_STATION
|
||||
if("CENTCOM")
|
||||
return CENTCOM
|
||||
if("MINING")
|
||||
return MINING
|
||||
if("EMPTY_AREA_1")
|
||||
return EMPTY_AREA_1
|
||||
if("EMPTY_AREA_2")
|
||||
return EMPTY_AREA_2
|
||||
if("EMPTY_AREA_3")
|
||||
return EMPTY_AREA_3
|
||||
if("EMPTY_AREA_4")
|
||||
return EMPTY_AREA_4
|
||||
if("EMPTY_AREA_5")
|
||||
return EMPTY_AREA_5
|
||||
if("EMPTY_AREA_6")
|
||||
return EMPTY_AREA_6
|
||||
if("EMPTY_AREA_7")
|
||||
return EMPTY_AREA_7
|
||||
if("EMPTY_AREA_8")
|
||||
return EMPTY_AREA_8
|
||||
|
||||
/datum/map_config/proc/GetFullMapPath(mp = map_path, mf = map_file)
|
||||
return "_maps/[mp]/[mf]"
|
||||
return "_maps/[mp]/[mf]"
|
||||
|
||||
/datum/map_config/proc/MakeNextMap()
|
||||
return config_filename == "data/next_map.json" || fcopy(config_filename, "data/next_map.json")
|
||||
return config_filename == "data/next_map.json" || fcopy(config_filename, "data/next_map.json")
|
||||
|
||||
@@ -302,7 +302,7 @@
|
||||
traitor_mob.mind.store_memory("<B>Radio Frequency:</B> [format_frequency(R.traitor_frequency)] ([R.name]).")
|
||||
|
||||
else if(uplink_loc == PDA)
|
||||
PDA.lock_code = "[rand(100,999)] [pick("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")]"
|
||||
PDA.lock_code = "[rand(100,999)] [pick(GLOB.phonetic_alphabet)]"
|
||||
|
||||
if(!silent) to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [PDA.name]. Simply enter the code \"[PDA.lock_code]\" into the ringtone select to unlock its hidden features.")
|
||||
traitor_mob.mind.store_memory("<B>Uplink Passcode:</B> [PDA.lock_code] ([PDA.name]).")
|
||||
@@ -358,6 +358,9 @@
|
||||
if(!SSticker.HasRoundStarted())
|
||||
alert("Not before round-start!", "Alert")
|
||||
return
|
||||
if(QDELETED(src) || QDELETED(current))
|
||||
alert("This mind doesn't have a mob, or is deleted! For some reason!", "Edit Memory")
|
||||
return
|
||||
|
||||
var/out = "<B>[name]</B>[(current&&(current.real_name!=name))?" (as [current.real_name])":""]<br>"
|
||||
out += "Mind currently owned by key: [key] [active?"(synced)":"(not synced)"]<br>"
|
||||
@@ -365,193 +368,40 @@
|
||||
out += "Faction and special role: <b><font color='red'>[special_role]</font></b><br>"
|
||||
|
||||
var/list/sections = list(
|
||||
"revolution",
|
||||
"cult",
|
||||
"wizard",
|
||||
"traitor", // "traitorchan",
|
||||
"changeling",
|
||||
"nuclear",
|
||||
"traitor", // "traitorchan",
|
||||
"monkey",
|
||||
"wizard",
|
||||
"revolution",
|
||||
"cult",
|
||||
"clockcult",
|
||||
"abductor",
|
||||
"devil",
|
||||
"ninja"
|
||||
"ninja",
|
||||
"monkey"
|
||||
)
|
||||
var/text = ""
|
||||
|
||||
if(ishuman(current))
|
||||
/** REVOLUTION ***/
|
||||
text = "revolution"
|
||||
if (SSticker.mode.config_tag=="revolution")
|
||||
text = uppertext(text)
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
if (assigned_role in GLOB.command_positions)
|
||||
text += "<b>HEAD</b>|loyal|employee|headrev|rev"
|
||||
else if (src in SSticker.mode.head_revolutionaries)
|
||||
var/last_healthy_headrev = TRUE
|
||||
for(var/I in SSticker.mode.head_revolutionaries)
|
||||
if(I == src)
|
||||
continue
|
||||
var/mob/M = I
|
||||
if(M.z == ZLEVEL_STATION && !M.stat)
|
||||
last_healthy_headrev = FALSE
|
||||
break
|
||||
text += "head|loyal|<a href='?src=\ref[src];revolution=clear'>employee</a>|<b>[last_healthy_headrev ? "<font color='red'>LAST </font> " : ""]HEADREV</b>|<a href='?src=\ref[src];revolution=rev'>rev</a>"
|
||||
text += "<br>Flash: <a href='?src=\ref[src];revolution=flash'>give</a>"
|
||||
|
||||
var/list/L = current.get_contents()
|
||||
var/obj/item/device/assembly/flash/flash = locate() in L
|
||||
if (flash)
|
||||
if(!flash.crit_fail)
|
||||
text += "|<a href='?src=\ref[src];revolution=takeflash'>take</a>."
|
||||
else
|
||||
text += "|<a href='?src=\ref[src];revolution=takeflash'>take</a>|<a href='?src=\ref[src];revolution=repairflash'>repair</a>."
|
||||
else
|
||||
text += "."
|
||||
|
||||
text += " <a href='?src=\ref[src];revolution=reequip'>Reequip</a> (gives traitor uplink)."
|
||||
if (objectives.len==0)
|
||||
text += "<br>Objectives are empty! <a href='?src=\ref[src];revolution=autoobjectives'>Set to kill all heads</a>."
|
||||
else if(current.isloyal())
|
||||
text += "head|<b>LOYAL</b>|employee|<a href='?src=\ref[src];revolution=headrev'>headrev</a>|rev"
|
||||
else if (src in SSticker.mode.revolutionaries)
|
||||
text += "head|loyal|<a href='?src=\ref[src];revolution=clear'>employee</a>|<a href='?src=\ref[src];revolution=headrev'>headrev</a>|<b>REV</b>"
|
||||
else
|
||||
text += "head|loyal|<b>EMPLOYEE</b>|<a href='?src=\ref[src];revolution=headrev'>headrev</a>|<a href='?src=\ref[src];revolution=rev'>rev</a>"
|
||||
|
||||
if(current && current.client && (ROLE_REV in current.client.prefs.be_special))
|
||||
text += "|Enabled in Prefs"
|
||||
else
|
||||
text += "|Disabled in Prefs"
|
||||
|
||||
sections["revolution"] = text
|
||||
|
||||
/** Abductors **/
|
||||
text = "Abductor"
|
||||
if(SSticker.mode.config_tag == "abductor")
|
||||
text = uppertext(text)
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
if(src in SSticker.mode.abductors)
|
||||
text += "<b>Abductor</b>|<a href='?src=\ref[src];abductor=clear'>human</a>"
|
||||
text += "|<a href='?src=\ref[src];common=undress'>undress</a>|<a href='?src=\ref[src];abductor=equip'>equip</a>"
|
||||
else
|
||||
text += "<a href='?src=\ref[src];abductor=abductor'>Abductor</a>|<b>human</b>"
|
||||
|
||||
if(current && current.client && (ROLE_ABDUCTOR in current.client.prefs.be_special))
|
||||
text += "|Enabled in Prefs"
|
||||
else
|
||||
text += "|Disabled in Prefs"
|
||||
|
||||
sections["abductor"] = text
|
||||
|
||||
/** NUCLEAR ***/
|
||||
text = "nuclear"
|
||||
if (SSticker.mode.config_tag=="nuclear")
|
||||
text = uppertext(text)
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
if (src in SSticker.mode.syndicates)
|
||||
text += "<b>OPERATIVE</b>|<a href='?src=\ref[src];nuclear=clear'>nanotrasen</a>"
|
||||
text += "<br><a href='?src=\ref[src];nuclear=lair'>To shuttle</a>, <a href='?src=\ref[src];common=undress'>undress</a>, <a href='?src=\ref[src];nuclear=dressup'>dress up</a>."
|
||||
var/code
|
||||
for (var/obj/machinery/nuclearbomb/bombue in GLOB.machines)
|
||||
if (length(bombue.r_code) <= 5 && bombue.r_code != "LOLNO" && bombue.r_code != "ADMIN")
|
||||
code = bombue.r_code
|
||||
break
|
||||
if (code)
|
||||
text += " Code is [code]. <a href='?src=\ref[src];nuclear=tellcode'>tell the code.</a>"
|
||||
else
|
||||
text += "<a href='?src=\ref[src];nuclear=nuclear'>operative</a>|<b>NANOTRASEN</b>"
|
||||
|
||||
if(current && current.client && (ROLE_OPERATIVE in current.client.prefs.be_special))
|
||||
text += "|Enabled in Prefs"
|
||||
else
|
||||
text += "|Disabled in Prefs"
|
||||
|
||||
sections["nuclear"] = text
|
||||
|
||||
/** WIZARD ***/
|
||||
text = "wizard"
|
||||
if (SSticker.mode.config_tag=="wizard")
|
||||
text = uppertext(text)
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
if ((src in SSticker.mode.wizards) || (src in SSticker.mode.apprentices))
|
||||
text += "<b>YES</b>|<a href='?src=\ref[src];wizard=clear'>no</a>"
|
||||
text += "<br><a href='?src=\ref[src];wizard=lair'>To lair</a>, <a href='?src=\ref[src];common=undress'>undress</a>, <a href='?src=\ref[src];wizard=dressup'>dress up</a>, <a href='?src=\ref[src];wizard=name'>let choose name</a>."
|
||||
if (objectives.len==0)
|
||||
text += "<br>Objectives are empty! <a href='?src=\ref[src];wizard=autoobjectives'>Randomize!</a>"
|
||||
else
|
||||
text += "<a href='?src=\ref[src];wizard=wizard'>yes</a>|<b>NO</b>"
|
||||
|
||||
if(current && current.client && (ROLE_WIZARD in current.client.prefs.be_special))
|
||||
text += "|Enabled in Prefs"
|
||||
else
|
||||
text += "|Disabled in Prefs"
|
||||
|
||||
sections["wizard"] = text
|
||||
|
||||
/** CULT ***/
|
||||
text = "cult"
|
||||
if (SSticker.mode.config_tag=="cult")
|
||||
text = uppertext(text)
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
if(iscultist(current))
|
||||
text += "loyal|<a href='?src=\ref[src];cult=clear'>employee</a>|<b>CULTIST</b>"
|
||||
text += "<br>Give <a href='?src=\ref[src];cult=tome'>tome</a>|<a href='?src=\ref[src];cult=amulet'>amulet</a>."
|
||||
|
||||
else if(current.isloyal())
|
||||
text += "<b>LOYAL</b>|employee|<a href='?src=\ref[src];cult=cultist'>cultist</a>"
|
||||
else if(is_convertable_to_cult(current))
|
||||
text += "loyal|<b>EMPLOYEE</b>|<a href='?src=\ref[src];cult=cultist'>cultist</a>"
|
||||
else
|
||||
text += "loyal|<b>EMPLOYEE</b>|<i>cannot serve Nar-Sie</i>"
|
||||
|
||||
if(current && current.client && (ROLE_CULTIST in current.client.prefs.be_special))
|
||||
text += "|Enabled in Prefs"
|
||||
else
|
||||
text += "|Disabled in Prefs"
|
||||
|
||||
sections["cult"] = text
|
||||
|
||||
/** CLOCKWORK CULT **/
|
||||
text = "clockwork cult"
|
||||
if(SSticker.mode.config_tag == "clockwork cult")
|
||||
text = uppertext(text)
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
if(is_servant_of_ratvar(current))
|
||||
text += "loyal|<a href='?src=\ref[src];clockcult=clear'>employee</a>|<b>SERVANT</b>"
|
||||
text += "<br><a href='?src=\ref[src];clockcult=slab'>Give slab</a>"
|
||||
else if(current.isloyal())
|
||||
text += "<b>LOYAL</b>|employee|<a href='?src=\ref[src];clockcult=servant'>servant</a>"
|
||||
else if(is_eligible_servant(current))
|
||||
text += "loyal|<b>EMPLOYEE</b>|<a href='?src=\ref[src];clockcult=servant'>servant</a>"
|
||||
else
|
||||
text += "loyal|<b>EMPLOYEE</b>|<i>cannot serve Ratvar</i>"
|
||||
|
||||
if(current && current.client && (ROLE_SERVANT_OF_RATVAR in current.client.prefs.be_special))
|
||||
text += "|Enabled in Prefs"
|
||||
else
|
||||
text += "|Disabled in Prefs"
|
||||
|
||||
sections["clockcult"] = text
|
||||
|
||||
/** TRAITOR ***/
|
||||
text = "traitor"
|
||||
if (SSticker.mode.config_tag=="traitor" || SSticker.mode.config_tag=="traitorchan")
|
||||
text = uppertext(text)
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
if (src in SSticker.mode.traitors)
|
||||
text += "<b>TRAITOR</b>|<a href='?src=\ref[src];traitor=clear'>loyal</a>"
|
||||
text += "<b>TRAITOR</b> | <a href='?src=\ref[src];traitor=clear'>loyal</a>"
|
||||
if (objectives.len==0)
|
||||
text += "<br>Objectives are empty! <a href='?src=\ref[src];traitor=autoobjectives'>Randomize</a>!"
|
||||
else
|
||||
text += "<a href='?src=\ref[src];traitor=traitor'>traitor</a>|<b>LOYAL</b>"
|
||||
text += "<a href='?src=\ref[src];traitor=traitor'>traitor</a> | <b>LOYAL</b>"
|
||||
|
||||
if(current && current.client && (ROLE_TRAITOR in current.client.prefs.be_special))
|
||||
text += "|Enabled in Prefs"
|
||||
text += " | Enabled in Prefs"
|
||||
else
|
||||
text += "|Disabled in Prefs"
|
||||
text += " | Disabled in Prefs"
|
||||
|
||||
sections["traitor"] = text
|
||||
|
||||
|
||||
if(ishuman(current) || ismonkey(current))
|
||||
|
||||
/** CHANGELING ***/
|
||||
@@ -560,34 +410,35 @@
|
||||
text = uppertext(text)
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
if ((src in SSticker.mode.changelings) && special_role)
|
||||
text += "<b>YES</b>|<a href='?src=\ref[src];changeling=clear'>no</a>"
|
||||
text += "<b>YES</b> | <a href='?src=\ref[src];changeling=clear'>no</a>"
|
||||
if (objectives.len==0)
|
||||
text += "<br>Objectives are empty! <a href='?src=\ref[src];changeling=autoobjectives'>Randomize!</a>"
|
||||
if(changeling && changeling.stored_profiles.len && (current.real_name != changeling.first_prof.name) )
|
||||
text += "<br><a href='?src=\ref[src];changeling=initialdna'>Transform to initial appearance.</a>"
|
||||
else if(src in SSticker.mode.changelings) //Station Aligned Changeling
|
||||
text += "<b>YES (but not an antag)</b>|<a href='?src=\ref[src];changeling=clear'>no</a>"
|
||||
text += "<b>YES (but not an antag)</b> | <a href='?src=\ref[src];changeling=clear'>no</a>"
|
||||
if (objectives.len==0)
|
||||
text += "<br>Objectives are empty! <a href='?src=\ref[src];changeling=autoobjectives'>Randomize!</a>"
|
||||
if(changeling && changeling.stored_profiles.len && (current.real_name != changeling.first_prof.name) )
|
||||
text += "<br><a href='?src=\ref[src];changeling=initialdna'>Transform to initial appearance.</a>"
|
||||
else
|
||||
text += "<a href='?src=\ref[src];changeling=changeling'>yes</a>|<b>NO</b>"
|
||||
text += "<a href='?src=\ref[src];changeling=changeling'>yes</a> | <b>NO</b>"
|
||||
|
||||
if(current && current.client && (ROLE_CHANGELING in current.client.prefs.be_special))
|
||||
text += "|Enabled in Prefs"
|
||||
text += " | Enabled in Prefs"
|
||||
else
|
||||
text += "|Disabled in Prefs"
|
||||
text += " | Disabled in Prefs"
|
||||
|
||||
sections["changeling"] = text
|
||||
|
||||
|
||||
/** MONKEY ***/
|
||||
text = "monkey"
|
||||
if (SSticker.mode.config_tag=="monkey")
|
||||
text = uppertext(text)
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
if (ishuman(current))
|
||||
text += "<a href='?src=\ref[src];monkey=healthy'>healthy</a>|<a href='?src=\ref[src];monkey=infected'>infected</a>|<b>HUMAN</b>|other"
|
||||
text += "<a href='?src=\ref[src];monkey=healthy'>healthy</a> | <a href='?src=\ref[src];monkey=infected'>infected</a> | <b>HUMAN</b> | other"
|
||||
else if(ismonkey(current))
|
||||
var/found = FALSE
|
||||
for(var/datum/disease/transformation/jungle_fever/JF in current.viruses)
|
||||
@@ -595,63 +446,222 @@
|
||||
break
|
||||
|
||||
if(found)
|
||||
text += "<a href='?src=\ref[src];monkey=healthy'>healthy</a>|<b>INFECTED</b>|<a href='?src=\ref[src];monkey=human'>human</a>|other"
|
||||
text += "<a href='?src=\ref[src];monkey=healthy'>healthy</a> | <b>INFECTED</b> | <a href='?src=\ref[src];monkey=human'>human</a> | other"
|
||||
else
|
||||
text += "<b>HEALTHY</b>|<a href='?src=\ref[src];monkey=infected'>infected</a>|<a href='?src=\ref[src];monkey=human'>human</a>|other"
|
||||
text += "<b>HEALTHY</b> | <a href='?src=\ref[src];monkey=infected'>infected</a> | <a href='?src=\ref[src];monkey=human'>human</a> | other"
|
||||
|
||||
else
|
||||
text += "healthy|infected|human|<b>OTHER</b>"
|
||||
text += "healthy | infected | human | <b>OTHER</b>"
|
||||
|
||||
if(current && current.client && (ROLE_MONKEY in current.client.prefs.be_special))
|
||||
text += "|Enabled in Prefs"
|
||||
text += " | Enabled in Prefs"
|
||||
else
|
||||
text += "|Disabled in Prefs"
|
||||
text += " | Disabled in Prefs"
|
||||
|
||||
sections["monkey"] = text
|
||||
|
||||
/** devil ***/
|
||||
text = "devil"
|
||||
if(SSticker.mode.config_tag == "devil")
|
||||
text = uppertext(text)
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
var/datum/antagonist/devil/devilinfo = has_antag_datum(ANTAG_DATUM_DEVIL)
|
||||
if(devilinfo)
|
||||
if(!devilinfo.ascendable)
|
||||
text += "<b>DEVIL</b>|<a href='?src=\ref[src];devil=ascendable_devil'>Ascendable Devil</a>|sintouched|<a href='?src=\ref[src];devil=clear'>human</a>"
|
||||
if(ishuman(current))
|
||||
|
||||
/** NUCLEAR ***/
|
||||
text = "nuclear"
|
||||
if (SSticker.mode.config_tag=="nuclear")
|
||||
text = uppertext(text)
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
if (src in SSticker.mode.syndicates)
|
||||
text += "<b>OPERATIVE</b> | <a href='?src=\ref[src];nuclear=clear'>nanotrasen</a>"
|
||||
text += "<br><a href='?src=\ref[src];nuclear=lair'>To shuttle</a>, <a href='?src=\ref[src];common=undress'>undress</a>, <a href='?src=\ref[src];nuclear=dressup'>dress up</a>."
|
||||
var/code
|
||||
for (var/obj/machinery/nuclearbomb/bombue in GLOB.machines)
|
||||
if (length(bombue.r_code) <= 5 && bombue.r_code != "LOLNO" && bombue.r_code != "ADMIN")
|
||||
code = bombue.r_code
|
||||
break
|
||||
if (code)
|
||||
text += " Code is [code]. <a href='?src=\ref[src];nuclear=tellcode'>tell the code.</a>"
|
||||
else
|
||||
text += "<a href='?src=\ref[src];devil=devil'>DEVIL</a>|<b>ASCENDABLE DEVIL</b>|sintouched|<a href='?src=\ref[src];devil=clear'>human</a>"
|
||||
else if(src in SSticker.mode.sintouched)
|
||||
text += "devil|Ascendable Devil|<b>SINTOUCHED</b>|<a href='?src=\ref[src];devil=clear'>human</a>"
|
||||
else
|
||||
text += "<a href='?src=\ref[src];devil=devil'>devil</a>|<a href='?src=\ref[src];devil=ascendable_devil'>Ascendable Devil</a>|<a href='?src=\ref[src];devil=sintouched'>sintouched</a>|<b>HUMAN</b>"
|
||||
text += "<a href='?src=\ref[src];nuclear=nuclear'>operative</a> | <b>NANOTRASEN</b>"
|
||||
|
||||
if(current && current.client && (ROLE_DEVIL in current.client.prefs.be_special))
|
||||
text += "|Enabled in Prefs"
|
||||
else
|
||||
text += "|Disabled in Prefs"
|
||||
sections["devil"] = text
|
||||
|
||||
/** NINJA ***/
|
||||
text = "ninja"
|
||||
if(SSticker.mode.config_tag == "ninja")
|
||||
text = uppertext(text)
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
var/datum/antagonist/ninja/ninjainfo = has_antag_datum(ANTAG_DATUM_NINJA)
|
||||
if(ninjainfo)
|
||||
if(ninjainfo.helping_station)
|
||||
text += "<a href='?src=\ref[src];ninja=clear'>employee</a> | syndicate | <b>NANOTRASEN</b> | <b><a href='?src=\ref[src];ninja=equip'>EQUIP</a></b>"
|
||||
if(current && current.client && (ROLE_OPERATIVE in current.client.prefs.be_special))
|
||||
text += " | Enabled in Prefs"
|
||||
else
|
||||
text += "<a href='?src=\ref[src];ninja=clear'>employee</a> | <b>SYNDICATE</b> | nanotrasen | <b><a href='?src=\ref[src];ninja=equip'>EQUIP</a></b>"
|
||||
else
|
||||
text += "<b>EMPLOYEE</b> | <a href='?src=\ref[src];ninja=syndicate'>syndicate</a> | <a href='?src=\ref[src];ninja=nanotrasen'>nanotrasen</a> | <a href='?src=\ref[src];ninja=random'>random allegiance</a>"
|
||||
if(current && current.client && (ROLE_NINJA in current.client.prefs.be_special))
|
||||
text += " | Enabled in Prefs"
|
||||
else
|
||||
text += " | Disabled in Prefs"
|
||||
sections["ninja"] = text
|
||||
text += " | Disabled in Prefs"
|
||||
|
||||
sections["nuclear"] = text
|
||||
|
||||
|
||||
/** SILICON ***/
|
||||
/** WIZARD ***/
|
||||
text = "wizard"
|
||||
if (SSticker.mode.config_tag=="wizard")
|
||||
text = uppertext(text)
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
if ((src in SSticker.mode.wizards) || (src in SSticker.mode.apprentices))
|
||||
text += "<b>YES</b> | <a href='?src=\ref[src];wizard=clear'>no</a>"
|
||||
text += "<br><a href='?src=\ref[src];wizard=lair'>To lair</a>, <a href='?src=\ref[src];common=undress'>undress</a>, <a href='?src=\ref[src];wizard=dressup'>dress up</a>, <a href='?src=\ref[src];wizard=name'>let choose name</a>."
|
||||
if (objectives.len==0)
|
||||
text += "<br>Objectives are empty! <a href='?src=\ref[src];wizard=autoobjectives'>Randomize!</a>"
|
||||
else
|
||||
text += "<a href='?src=\ref[src];wizard=wizard'>yes</a> | <b>NO</b>"
|
||||
|
||||
if(current && current.client && (ROLE_WIZARD in current.client.prefs.be_special))
|
||||
text += " | Enabled in Prefs"
|
||||
else
|
||||
text += " | Disabled in Prefs"
|
||||
|
||||
sections["wizard"] = text
|
||||
|
||||
|
||||
/** REVOLUTION ***/
|
||||
text = "revolution"
|
||||
if (SSticker.mode.config_tag=="revolution")
|
||||
text = uppertext(text)
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
if (assigned_role in GLOB.command_positions)
|
||||
text += "<b>HEAD</b> | not mindshielded | employee | headrev | rev"
|
||||
else if (src in SSticker.mode.head_revolutionaries)
|
||||
var/last_healthy_headrev = TRUE
|
||||
for(var/I in SSticker.mode.head_revolutionaries)
|
||||
if(I == src)
|
||||
continue
|
||||
var/mob/M = I
|
||||
if(M.z == ZLEVEL_STATION && !M.stat)
|
||||
last_healthy_headrev = FALSE
|
||||
break
|
||||
text += "head | not mindshielded | <a href='?src=\ref[src];revolution=clear'>employee</a> | <b>[last_healthy_headrev ? "<font color='red'>LAST </font> " : ""]HEADREV</b> | <a href='?src=\ref[src];revolution=rev'>rev</a>"
|
||||
text += "<br>Flash: <a href='?src=\ref[src];revolution=flash'>give</a>"
|
||||
|
||||
var/list/L = current.get_contents()
|
||||
var/obj/item/device/assembly/flash/flash = locate() in L
|
||||
if (flash)
|
||||
if(!flash.crit_fail)
|
||||
text += " | <a href='?src=\ref[src];revolution=takeflash'>take</a>."
|
||||
else
|
||||
text += " | <a href='?src=\ref[src];revolution=takeflash'>take</a> | <a href='?src=\ref[src];revolution=repairflash'>repair</a>."
|
||||
else
|
||||
text += "."
|
||||
|
||||
text += " <a href='?src=\ref[src];revolution=reequip'>Reequip</a> (gives traitor uplink)."
|
||||
if (objectives.len==0)
|
||||
text += "<br>Objectives are empty! <a href='?src=\ref[src];revolution=autoobjectives'>Set to kill all heads</a>."
|
||||
else if(current.isloyal())
|
||||
text += "head | <b>MINDSHIELDED</b> | employee | <a href='?src=\ref[src];revolution=headrev'>headrev</a> | rev"
|
||||
else if (src in SSticker.mode.revolutionaries)
|
||||
text += "head | not mindshielded | <a href='?src=\ref[src];revolution=clear'>employee</a> | <a href='?src=\ref[src];revolution=headrev'>headrev</a> | <b>REV</b>"
|
||||
else
|
||||
text += "head | not mindshielded | <b>EMPLOYEE</b> | <a href='?src=\ref[src];revolution=headrev'>headrev</a> | <a href='?src=\ref[src];revolution=rev'>rev</a>"
|
||||
|
||||
if(current && current.client && (ROLE_REV in current.client.prefs.be_special))
|
||||
text += " | Enabled in Prefs"
|
||||
else
|
||||
text += " | Disabled in Prefs"
|
||||
|
||||
sections["revolution"] = text
|
||||
|
||||
/** Abductors **/
|
||||
text = "Abductor"
|
||||
if(SSticker.mode.config_tag == "abductor")
|
||||
text = uppertext(text)
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
if(src in SSticker.mode.abductors)
|
||||
text += "<b>Abductor</b> | <a href='?src=\ref[src];abductor=clear'>human</a>"
|
||||
text += " | <a href='?src=\ref[src];common=undress'>undress</a> | <a href='?src=\ref[src];abductor=equip'>equip</a>"
|
||||
else
|
||||
text += "<a href='?src=\ref[src];abductor=abductor'>abductor</a> | <b>human</b>"
|
||||
|
||||
if(current && current.client && (ROLE_ABDUCTOR in current.client.prefs.be_special))
|
||||
text += " | Enabled in Prefs"
|
||||
else
|
||||
text += " | Disabled in Prefs"
|
||||
|
||||
sections["abductor"] = text
|
||||
|
||||
|
||||
/** DEVIL ***/
|
||||
text = "devil"
|
||||
if(SSticker.mode.config_tag == "devil")
|
||||
text = uppertext(text)
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
var/datum/antagonist/devil/devilinfo = has_antag_datum(ANTAG_DATUM_DEVIL)
|
||||
if(devilinfo)
|
||||
if(!devilinfo.ascendable)
|
||||
text += "<b>DEVIL</b> | <a href='?src=\ref[src];devil=ascendable_devil'>ascendable devil</a> | sintouched | <a href='?src=\ref[src];devil=clear'>human</a>"
|
||||
else
|
||||
text += "<a href='?src=\ref[src];devil=devil'>DEVIL</a> | <b>ASCENDABLE DEVIL</b> | sintouched | <a href='?src=\ref[src];devil=clear'>human</a>"
|
||||
else if(src in SSticker.mode.sintouched)
|
||||
text += "devil | ascendable devil | <b>SINTOUCHED</b> | <a href='?src=\ref[src];devil=clear'>human</a>"
|
||||
else
|
||||
text += "<a href='?src=\ref[src];devil=devil'>devil</a> | <a href='?src=\ref[src];devil=ascendable_devil'>ascendable devil</a> | <a href='?src=\ref[src];devil=sintouched'>sintouched</a> | <b>HUMAN</b>"
|
||||
|
||||
if(current && current.client && (ROLE_DEVIL in current.client.prefs.be_special))
|
||||
text += " | Enabled in Prefs"
|
||||
else
|
||||
text += " | Disabled in Prefs"
|
||||
sections["devil"] = text
|
||||
|
||||
|
||||
/** NINJA ***/
|
||||
text = "ninja"
|
||||
if(SSticker.mode.config_tag == "ninja")
|
||||
text = uppertext(text)
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
var/datum/antagonist/ninja/ninjainfo = has_antag_datum(ANTAG_DATUM_NINJA)
|
||||
if(ninjainfo)
|
||||
if(ninjainfo.helping_station)
|
||||
text += "<a href='?src=\ref[src];ninja=clear'>employee</a> | syndicate | <b>NANOTRASEN</b> | <b><a href='?src=\ref[src];ninja=equip'>EQUIP</a></b>"
|
||||
else
|
||||
text += "<a href='?src=\ref[src];ninja=clear'>employee</a> | <b>SYNDICATE</b> | nanotrasen | <b><a href='?src=\ref[src];ninja=equip'>EQUIP</a></b>"
|
||||
else
|
||||
text += "<b>EMPLOYEE</b> | <a href='?src=\ref[src];ninja=syndicate'>syndicate</a> | <a href='?src=\ref[src];ninja=nanotrasen'>nanotrasen</a> | <a href='?src=\ref[src];ninja=random'>random allegiance</a>"
|
||||
if(current && current.client && (ROLE_NINJA in current.client.prefs.be_special))
|
||||
text += " | Enabled in Prefs"
|
||||
else
|
||||
text += " | Disabled in Prefs"
|
||||
sections["ninja"] = text
|
||||
|
||||
|
||||
if(!issilicon(current))
|
||||
/** CULT ***/
|
||||
text = "cult"
|
||||
if (SSticker.mode.config_tag=="cult")
|
||||
text = uppertext(text)
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
if(iscultist(current))
|
||||
text += "not mindshielded | <a href='?src=\ref[src];cult=clear'>employee</a> | <b>CULTIST</b>"
|
||||
text += "<br>Give <a href='?src=\ref[src];cult=tome'>tome</a> | <a href='?src=\ref[src];cult=amulet'>amulet</a>."
|
||||
else if(is_convertable_to_cult(current))
|
||||
text += "not mindshielded | <b>EMPLOYEE</b> | <a href='?src=\ref[src];cult=cultist'>cultist</a>"
|
||||
else
|
||||
text += "[!current.isloyal() ? "not mindshielded" : "<b>MINDSHIELDED</b>"] | <b>EMPLOYEE</b> | <i>cannot serve Nar-Sie</i>"
|
||||
|
||||
if(current && current.client && (ROLE_CULTIST in current.client.prefs.be_special))
|
||||
text += " | Enabled in Prefs"
|
||||
else
|
||||
text += " | Disabled in Prefs"
|
||||
|
||||
sections["cult"] = text
|
||||
|
||||
|
||||
if(ishuman(current) || issilicon(current))
|
||||
/** CLOCKWORK CULT **/
|
||||
text = "clockwork cult"
|
||||
if(SSticker.mode.config_tag == "clockwork cult")
|
||||
text = uppertext(text)
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
if(is_servant_of_ratvar(current))
|
||||
text += "not mindshielded | <a href='?src=\ref[src];clockcult=clear'>employee</a> | <b>SERVANT</b>"
|
||||
text += "<br><a href='?src=\ref[src];clockcult=slab'>Give slab</a>"
|
||||
else if(is_eligible_servant(current))
|
||||
text += "not mindshielded | <b>EMPLOYEE</b> | <a href='?src=\ref[src];clockcult=servant'>servant</a>"
|
||||
else
|
||||
text += "[!current.isloyal() ? "not mindshielded" : "<b>MINDSHIELDED</b>"] | <b>EMPLOYEE</b> | <i>cannot serve Ratvar</i>"
|
||||
|
||||
if(current && current.client && (ROLE_SERVANT_OF_RATVAR in current.client.prefs.be_special))
|
||||
text += " | Enabled in Prefs"
|
||||
else
|
||||
text += " | Disabled in Prefs"
|
||||
|
||||
sections["clockcult"] = text
|
||||
|
||||
|
||||
/** SILICON ***/
|
||||
if(issilicon(current))
|
||||
text = "silicon"
|
||||
var/mob/living/silicon/robot/robot = current
|
||||
@@ -685,7 +695,7 @@
|
||||
text = "Uplink: <a href='?src=\ref[src];common=uplink'>give</a>"
|
||||
var/obj/item/device/uplink/U = find_syndicate_uplink()
|
||||
if(U)
|
||||
text += "|<a href='?src=\ref[src];common=takeuplink'>take</a>"
|
||||
text += " | <a href='?src=\ref[src];common=takeuplink'>take</a>"
|
||||
if (check_rights(R_FUN, 0))
|
||||
text += ", <a href='?src=\ref[src];common=crystals'>[U.telecrystals]</a> TC"
|
||||
else
|
||||
@@ -710,7 +720,10 @@
|
||||
|
||||
out += "<a href='?src=\ref[src];obj_announce=1'>Announce objectives</a><br><br>"
|
||||
|
||||
usr << browse(out, "window=edit_memory[src];size=500x600")
|
||||
var/datum/browser/popup = new(usr, "edit_memory", "", 600, 600)
|
||||
popup.set_content(out)
|
||||
popup.open()
|
||||
//usr << browse(out, "window=edit_memory[src];size=575x600")
|
||||
|
||||
|
||||
/datum/mind/Topic(href, href_list)
|
||||
@@ -837,7 +850,7 @@
|
||||
if(objective&&objective.type==text2path("/datum/objective/[new_obj_type]"))
|
||||
def_num = objective.target_amount
|
||||
|
||||
var/target_number = input("Input target number:", "Objective", def_num) as num|null
|
||||
var/target_number = input("Input target number:", "Objective", def_num) as num | null
|
||||
if (isnull(target_number))//Ordinarily, you wouldn't need isnull. In this case, the value may already exist.
|
||||
return
|
||||
|
||||
@@ -1267,7 +1280,7 @@
|
||||
sleep(0) //because deleting of virus is doing throught spawn(0) //What
|
||||
log_admin("[key_name(usr)] attempting to humanize [key_name(current)]")
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] attempting to humanize [key_name_admin(current)]</span>")
|
||||
H = M.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_DEFAULTMSG)
|
||||
H = M.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_DEFAULTMSG)
|
||||
if(H)
|
||||
src = H.mind
|
||||
|
||||
@@ -1301,7 +1314,7 @@
|
||||
if(check_rights(R_FUN, 0))
|
||||
var/obj/item/device/uplink/U = find_syndicate_uplink()
|
||||
if(U)
|
||||
var/crystals = input("Amount of telecrystals for [key]","Syndicate uplink", U.telecrystals) as null|num
|
||||
var/crystals = input("Amount of telecrystals for [key]","Syndicate uplink", U.telecrystals) as null | num
|
||||
if(!isnull(crystals))
|
||||
U.telecrystals = crystals
|
||||
message_admins("[key_name_admin(usr)] changed [current]'s telecrystal count to [crystals].")
|
||||
@@ -1348,6 +1361,7 @@
|
||||
if(!(src in SSticker.mode.syndicates))
|
||||
SSticker.mode.syndicates += src
|
||||
SSticker.mode.update_synd_icons_added(src)
|
||||
assigned_role = "Syndicate"
|
||||
special_role = "Syndicate"
|
||||
SSticker.mode.forge_syndicate_objectives(src)
|
||||
SSticker.mode.greet_syndicate(src)
|
||||
@@ -1585,7 +1599,7 @@
|
||||
/mob/living/carbon/human/mind_initialize()
|
||||
..()
|
||||
if(!mind.assigned_role)
|
||||
mind.assigned_role = "Assistant" //defualt
|
||||
mind.assigned_role = "Unassigned" //default
|
||||
|
||||
//XENO
|
||||
/mob/living/carbon/alien/mind_initialize()
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
name = "Asteroid 1"
|
||||
description = "I-spy with my little eye, something beginning with R."
|
||||
|
||||
|
||||
/datum/map_template/ruin/space/asteroid2
|
||||
id = "asteroid2"
|
||||
suffix = "asteroid2.dmm"
|
||||
@@ -247,4 +248,10 @@
|
||||
id = "miracle"
|
||||
suffix = "miracle.dmm"
|
||||
name = "Ordinary Space Tile"
|
||||
description = "Absolutely nothing strange going on here please move along, plenty more space to see right this way!"
|
||||
description = "Absolutely nothing strange going on here please move along, plenty more space to see right this way!"
|
||||
|
||||
/datum/map_template/ruin/space/gondoland
|
||||
id = "gondolaasteroid"
|
||||
suffix = "gondolaasteroid.dmm"
|
||||
name = "Gondoland"
|
||||
description = "Just an ordinary rock- wait, what's that thing?"
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
status_type = STATUS_EFFECT_UNIQUE
|
||||
alert_type = /obj/screen/alert/status_effect/freon
|
||||
var/icon/cube
|
||||
var/can_melt = TRUE
|
||||
|
||||
/obj/screen/alert/status_effect/freon
|
||||
name = "Frozen Solid"
|
||||
@@ -20,7 +21,7 @@
|
||||
|
||||
/datum/status_effect/freon/tick()
|
||||
owner.update_canmove()
|
||||
if(owner && owner.bodytemperature >= 310.055)
|
||||
if(can_melt && owner.bodytemperature >= 310.055)
|
||||
qdel(src)
|
||||
|
||||
/datum/status_effect/freon/on_remove()
|
||||
@@ -29,3 +30,7 @@
|
||||
owner.cut_overlay(cube)
|
||||
owner.bodytemperature += 100
|
||||
owner.update_canmove()
|
||||
|
||||
/datum/status_effect/freon/watcher
|
||||
duration = 8
|
||||
can_melt = FALSE
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
var/list/priority_overlays //overlays that should remain on top and not normally removed when using cut_overlay functions, like c4.
|
||||
|
||||
var/datum/proximity_monitor/proximity_monitor
|
||||
var/buckle_message_cooldown = 0
|
||||
|
||||
/atom/New(loc, ...)
|
||||
//atom creation method that preloads variables at creation
|
||||
@@ -291,7 +292,10 @@
|
||||
else
|
||||
to_chat(user, "Nothing.")
|
||||
|
||||
/atom/proc/relaymove()
|
||||
/atom/proc/relaymove(mob/user)
|
||||
if(buckle_message_cooldown <= world.time)
|
||||
buckle_message_cooldown = world.time + 50
|
||||
to_chat(user, "<span class='warning'>You can't move while buckled to [src]!</span>")
|
||||
return
|
||||
|
||||
/atom/proc/contents_explosion(severity, target)
|
||||
@@ -300,6 +304,7 @@
|
||||
/atom/proc/ex_act(severity, target)
|
||||
set waitfor = FALSE
|
||||
contents_explosion(severity, target)
|
||||
SendSignal(COMSIG_ATOM_EX_ACT, severity, target)
|
||||
|
||||
/atom/proc/blob_act(obj/structure/blob/B)
|
||||
return
|
||||
@@ -464,8 +469,8 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
|
||||
/atom/proc/singularity_act()
|
||||
return
|
||||
|
||||
/atom/proc/singularity_pull()
|
||||
return
|
||||
/atom/proc/singularity_pull(obj/singularity/S, current_size)
|
||||
SendSignal(COMSIG_ATOM_SING_PULL, S, current_size)
|
||||
|
||||
/atom/proc/acid_act(acidpwr, acid_volume)
|
||||
return
|
||||
@@ -609,10 +614,10 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
|
||||
. += "---"
|
||||
var/turf/curturf = get_turf(src)
|
||||
if (curturf)
|
||||
.["Jump to"] = "?_src_=holder;adminplayerobservecoodjump=1;X=[curturf.x];Y=[curturf.y];Z=[curturf.z]"
|
||||
.["Add reagent"] = "?_src_=vars;addreagent=\ref[src]"
|
||||
.["Trigger EM pulse"] = "?_src_=vars;emp=\ref[src]"
|
||||
.["Trigger explosion"] = "?_src_=vars;explode=\ref[src]"
|
||||
.["Jump to"] = "?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[curturf.x];Y=[curturf.y];Z=[curturf.z]"
|
||||
.["Add reagent"] = "?_src_=vars;[HrefToken()];addreagent=\ref[src]"
|
||||
.["Trigger EM pulse"] = "?_src_=vars;[HrefToken()];emp=\ref[src]"
|
||||
.["Trigger explosion"] = "?_src_=vars;[HrefToken()];explode=\ref[src]"
|
||||
|
||||
/atom/proc/drop_location()
|
||||
var/atom/L = loc
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
|
||||
#ifndef PIXEL_SCALE
|
||||
#define PIXEL_SCALE 0
|
||||
#if DM_VERSION >= 512
|
||||
#error HEY, PIXEL_SCALE probably exists now, remove this gross ass shim.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/atom/movable
|
||||
layer = OBJ_LAYER
|
||||
var/last_move = null
|
||||
@@ -222,7 +215,7 @@
|
||||
//to differentiate it, naturally everyone forgot about this immediately and so some things
|
||||
//would bump twice, so now it's called Collide
|
||||
/atom/movable/proc/Collide(atom/A)
|
||||
if((A))
|
||||
if(A)
|
||||
if(throwing)
|
||||
throwing.hit_atom(A)
|
||||
. = 1
|
||||
@@ -504,7 +497,7 @@
|
||||
/atom/movable/vv_get_dropdown()
|
||||
. = ..()
|
||||
. -= "Jump to"
|
||||
.["Follow"] = "?_src_=holder;adminplayerobservefollow=\ref[src]"
|
||||
.["Follow"] = "?_src_=holder;[HrefToken()];adminplayerobservefollow=\ref[src]"
|
||||
|
||||
/atom/movable/proc/ex_check(ex_id)
|
||||
if(!ex_id)
|
||||
|
||||
@@ -108,6 +108,7 @@
|
||||
new_objective.explanation_text = "Protect [usr.real_name], the wizard."
|
||||
M.mind.objectives += new_objective
|
||||
SSticker.mode.apprentices += M.mind
|
||||
M.mind.assigned_role = "Apprentice"
|
||||
M.mind.special_role = "apprentice"
|
||||
SSticker.mode.update_wiz_icons_added(M.mind)
|
||||
SEND_SOUND(M, sound('sound/effects/magic.ogg'))
|
||||
|
||||
9
code/game/gamemodes/antag_spawner.dm.rej
Normal file
9
code/game/gamemodes/antag_spawner.dm.rej
Normal file
@@ -0,0 +1,9 @@
|
||||
diff a/code/game/gamemodes/antag_spawner.dm b/code/game/gamemodes/antag_spawner.dm (rejected hunks)
|
||||
@@ -108,6 +108,7 @@
|
||||
new_objective.explanation_text = "Protect [usr.real_name], the wizard."
|
||||
M.mind.objectives += new_objective
|
||||
SSticker.mode.apprentices += M.mind
|
||||
+ M.mind.assigned_role = "Apprentice"
|
||||
M.mind.special_role = "apprentice"
|
||||
SSticker.mode.update_wiz_icons_added(M.mind)
|
||||
M << sound('sound/effects/magic.ogg')
|
||||
@@ -7,11 +7,9 @@
|
||||
brute_resist = 0.25
|
||||
explosion_block = 3
|
||||
point_return = 4
|
||||
atmosblock = 1
|
||||
atmosblock = TRUE
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 90, acid = 90)
|
||||
|
||||
|
||||
|
||||
/obj/structure/blob/shield/scannerreport()
|
||||
if(atmosblock)
|
||||
return "Will prevent the spread of atmospheric changes."
|
||||
@@ -26,10 +24,10 @@
|
||||
icon_state = "blob_shield_damaged"
|
||||
name = "weakened strong blob"
|
||||
desc = "A wall of twitching tendrils."
|
||||
atmosblock = 0
|
||||
atmosblock = FALSE
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
name = initial(name)
|
||||
desc = initial(desc)
|
||||
atmosblock = 1
|
||||
air_update_turf(1)
|
||||
atmosblock = TRUE
|
||||
air_update_turf(1)
|
||||
@@ -363,7 +363,7 @@
|
||||
to_chat(src, "<i>Node Blobs</i> are blobs which grow, like the core. Like the core it can activate resource and factory blobs.")
|
||||
to_chat(src, "<b>In addition to the buttons on your HUD, there are a few click shortcuts to speed up expansion and defense.</b>")
|
||||
to_chat(src, "<b>Shortcuts:</b> Click = Expand Blob <b>|</b> Middle Mouse Click = Rally Spores <b>|</b> Ctrl Click = Create Shield Blob <b>|</b> Alt Click = Remove Blob")
|
||||
to_chat(src, "Attempting to talk will send a message to all other GLOB.overminds, allowing you to coordinate with them.")
|
||||
to_chat(src, "Attempting to talk will send a message to all other overminds, allowing you to coordinate with them.")
|
||||
if(!placed && autoplace_max_time <= world.time)
|
||||
to_chat(src, "<span class='big'><font color=\"#EE4000\">You will automatically place your blob core in [round((autoplace_max_time - world.time)/600, 0.5)] minutes.</font></span>")
|
||||
to_chat(src, "<span class='big'><font color=\"#EE4000\">You [manualplace_min_time ? "will be able to":"can"] manually place your blob core by pressing the Place Blob Core button in the bottom right corner of the screen.</font></span>")
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
opacity = 0
|
||||
anchored = TRUE
|
||||
layer = BELOW_MOB_LAYER
|
||||
CanAtmosPass = ATMOS_PASS_PROC
|
||||
var/point_return = 0 //How many points the blob gets back when it removes a blob of that type. If less than 0, blob cannot be removed.
|
||||
max_integrity = 30
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 80, acid = 70)
|
||||
@@ -16,19 +17,9 @@
|
||||
var/heal_timestamp = 0 //we got healed when?
|
||||
var/brute_resist = 0.5 //multiplies brute damage by this
|
||||
var/fire_resist = 1 //multiplies burn damage by this
|
||||
var/atmosblock = 0 //if the blob blocks atmos and heat spread
|
||||
var/atmosblock = FALSE //if the blob blocks atmos and heat spread
|
||||
var/mob/camera/blob/overmind
|
||||
|
||||
/obj/structure/blob/attack_hand(mob/M)
|
||||
. = ..()
|
||||
M.changeNext_move(CLICK_CD_MELEE)
|
||||
var/a = pick("gently stroke", "nuzzle", "affectionatly pet", "cuddle")
|
||||
M.visible_message("<span class='notice'>[M] [a]s [src]!</span>", "<span class='notice'>You [a] [src]!</span>")
|
||||
to_chat(overmind, "<span class='notice'>[M] [a]s you!</span>")
|
||||
playsound(src, 'sound/effects/blobattack.ogg', 50, 1) //SQUISH SQUISH
|
||||
|
||||
|
||||
|
||||
/obj/structure/blob/Initialize()
|
||||
var/area/Ablob = get_area(loc)
|
||||
if(Ablob.blob_allowed) //Is this area allowed for winning as blob?
|
||||
@@ -37,17 +28,16 @@
|
||||
setDir(pick(GLOB.cardinals))
|
||||
update_icon()
|
||||
.= ..()
|
||||
ConsumeTile()
|
||||
if(atmosblock)
|
||||
CanAtmosPass = ATMOS_PASS_NO
|
||||
air_update_turf(1)
|
||||
ConsumeTile()
|
||||
|
||||
/obj/structure/blob/proc/creation_action() //When it's created by the overmind, do this.
|
||||
return
|
||||
|
||||
/obj/structure/blob/Destroy()
|
||||
if(atmosblock)
|
||||
atmosblock = 0
|
||||
atmosblock = FALSE
|
||||
air_update_turf(1)
|
||||
GLOB.blobs_legit -= src //if it was in the legit blobs list, it isn't now
|
||||
GLOB.blobs -= src //it's no longer in the all blobs list either
|
||||
@@ -79,6 +69,9 @@
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/structure/blob/CanAtmosPass(turf/T)
|
||||
return !atmosblock
|
||||
|
||||
/obj/structure/blob/CanAStarPass(ID, dir, caller)
|
||||
. = 0
|
||||
if(ismovableatom(caller))
|
||||
@@ -97,8 +90,10 @@
|
||||
/obj/structure/blob/proc/Life()
|
||||
return
|
||||
|
||||
/obj/structure/blob/proc/Pulse_Area(pulsing_overmind = overmind, claim_range = 10, pulse_range = 3, expand_range = 2)
|
||||
src.Be_Pulsed()
|
||||
/obj/structure/blob/proc/Pulse_Area(mob/camera/blob/pulsing_overmind, claim_range = 10, pulse_range = 3, expand_range = 2)
|
||||
if(QDELETED(pulsing_overmind))
|
||||
pulsing_overmind = overmind
|
||||
Be_Pulsed()
|
||||
var/expanded = FALSE
|
||||
if(prob(70) && expand())
|
||||
expanded = TRUE
|
||||
@@ -353,4 +348,4 @@
|
||||
icon_state = "blob"
|
||||
name = "blob"
|
||||
desc = "A thick wall of writhing tendrils."
|
||||
brute_resist = 0.25
|
||||
brute_resist = 0.25
|
||||
@@ -1,4 +1,4 @@
|
||||
//Augmented Eyesight: Gives you thermal and night vision - bye bye, flashlights. Also, high DNA cost because of how powerful it is.
|
||||
//Augmented Eyesight: Gives you x-ray vision or protection from flashes. Also, high DNA cost because of how powerful it is.
|
||||
//Possible todo: make a custom message for directing a penlight/flashlight at the eyes - not sure what would display though.
|
||||
|
||||
/obj/effect/proc_holder/changeling/augmented_eyesight
|
||||
@@ -7,21 +7,31 @@
|
||||
helptext = "Grants us thermal vision or flash protection. We will become a lot more vulnerable to flash-based devices while thermal vision is active."
|
||||
chemical_cost = 0
|
||||
dna_cost = 2 //Would be 1 without thermal vision
|
||||
active = 0 //Whether or not vision is enhanced
|
||||
active = FALSE
|
||||
|
||||
/obj/effect/proc_holder/changeling/augmented_eyesight/on_purchase(mob/user) //The ability starts inactive, so we should be protected from flashes.
|
||||
var/obj/item/organ/eyes/E = user.getorganslot("eye_sight")
|
||||
if (E)
|
||||
E.flash_protect = 2 //Adjust the user's eyes' flash protection
|
||||
to_chat(user, "We adjust our eyes to protect them from bright lights.")
|
||||
else
|
||||
to_chat(user, "We can't adjust our eyes if we don't have any!")
|
||||
|
||||
/obj/effect/proc_holder/changeling/augmented_eyesight/sting_action(mob/living/carbon/human/user)
|
||||
if(!istype(user))
|
||||
return
|
||||
var/obj/item/organ/eyes/E = user.getorganslot("eye_sight")
|
||||
if(E)
|
||||
if(E.flash_protect)
|
||||
E.sight_flags |= SEE_MOBS
|
||||
E.flash_protect = -1
|
||||
if(!active)
|
||||
E.sight_flags |= SEE_MOBS | SEE_OBJS | SEE_TURFS //Add sight flags to the user's eyes
|
||||
E.flash_protect = -1 //Adjust the user's eyes' flash protection
|
||||
to_chat(user, "We adjust our eyes to sense prey through walls.")
|
||||
active = TRUE //Defined in code/modules/spells/spell.dm
|
||||
else
|
||||
E.sight_flags -= SEE_MOBS
|
||||
E.flash_protect = 2
|
||||
E.sight_flags ^= SEE_MOBS | SEE_OBJS | SEE_TURFS //Remove sight flags from the user's eyes
|
||||
E.flash_protect = 2 //Adjust the user's eyes' flash protection
|
||||
to_chat(user, "We adjust our eyes to protect them from bright lights.")
|
||||
active = FALSE
|
||||
user.update_sight()
|
||||
else
|
||||
to_chat(user, "We can't adjust our eyes if we don't have any!")
|
||||
@@ -31,7 +41,11 @@
|
||||
return 1
|
||||
|
||||
|
||||
/obj/effect/proc_holder/changeling/augmented_eyesight/on_refund(mob/user)
|
||||
/obj/effect/proc_holder/changeling/augmented_eyesight/on_refund(mob/user) //Get rid of x-ray vision and flash protection when the user refunds this ability
|
||||
var/obj/item/organ/eyes/E = user.getorganslot("eye_sight")
|
||||
if(E)
|
||||
E.sight_flags -= SEE_MOBS
|
||||
if (active)
|
||||
E.sight_flags ^= SEE_MOBS | SEE_OBJS | SEE_TURFS
|
||||
else
|
||||
E.flash_protect = 0
|
||||
user.update_sight()
|
||||
@@ -247,7 +247,7 @@
|
||||
|
||||
|
||||
/obj/item/gun/magic/tentacle/shoot_with_empty_chamber(mob/living/user as mob|obj)
|
||||
to_chat(user, "<span class='warning'>The [name] is not ready yet.<span>")
|
||||
to_chat(user, "<span class='warning'>The [name] is not ready yet.</span>")
|
||||
|
||||
/obj/item/gun/magic/tentacle/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] coils [src] tightly around [user.p_their()] neck! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
@@ -343,10 +343,10 @@
|
||||
on_hit(I) //grab the item as if you had hit it directly with the tentacle
|
||||
return 1
|
||||
else
|
||||
to_chat(firer, "<span class='danger'>You can't seem to pry [I] off [C]'s hands!<span>")
|
||||
to_chat(firer, "<span class='danger'>You can't seem to pry [I] off [C]'s hands!</span>")
|
||||
return 0
|
||||
else
|
||||
to_chat(firer, "<span class='danger'>[C] has nothing in hand to disarm!<span>")
|
||||
to_chat(firer, "<span class='danger'>[C] has nothing in hand to disarm!</span>")
|
||||
return 0
|
||||
|
||||
if(INTENT_GRAB)
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
if(!selected_dna)
|
||||
return
|
||||
if(NOTRANSSTING in selected_dna.dna.species.species_traits)
|
||||
to_chat(user, "<span class = 'notice'>That DNA is not compatible with changeling retrovirus!")
|
||||
to_chat(user, "<span class = 'notice'>That DNA is not compatible with changeling retrovirus!</span>")
|
||||
return
|
||||
..()
|
||||
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
to_chat(user, "<span class='inathneq'>An emergency shuttle has arrived and this prism is no longer useful; attempt to activate it to gain a partial refund of components used.</span>")
|
||||
else
|
||||
var/efficiency = get_efficiency_mod(TRUE)
|
||||
to_chat(user, "<span class='inathneq_small'>It requires at least <b>[get_delay_cost()]W</b> of power to attempt to delay the arrival of an emergency shuttle by <b>[2 * efficiency]</b> minutes.</span>")
|
||||
to_chat(user, "<span class='inathneq_small'>This cost increases by <b>[delay_cost_increase]W</b> for every previous activation.</span>")
|
||||
to_chat(user, "<span class='inathneq_small'>It requires at least <b>[DisplayPower(get_delay_cost())]</b> of power to attempt to delay the arrival of an emergency shuttle by <b>[2 * efficiency]</b> minutes.</span>")
|
||||
to_chat(user, "<span class='inathneq_small'>This cost increases by <b>[DisplayPower(delay_cost_increase)]</b> for every previous activation.</span>")
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/prolonging_prism/forced_disable(bad_effects)
|
||||
if(active)
|
||||
@@ -126,7 +126,7 @@
|
||||
if(!hex_combo)
|
||||
hex_combo = mutable_appearance('icons/effects/64x64.dmi', n, RIPPLE_LAYER)
|
||||
else
|
||||
hex_combo.overlays += mutable_appearance('icons/effects/64x64.dmi', n, RIPPLE_LAYER)
|
||||
hex_combo.add_overlay(mutable_appearance('icons/effects/64x64.dmi', n, RIPPLE_LAYER))
|
||||
if(hex_combo) //YOU BUILT A HEXAGON
|
||||
hex_combo.pixel_x = -16
|
||||
hex_combo.pixel_y = -16
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
to_chat(mob, "<span class='userdanger'>Unfortunately, you weren't able to get a [item_name]. This is very bad and you should adminhelp immediately (press F1).</span>")
|
||||
return 0
|
||||
else
|
||||
to_chat(mob, "<span class='danger'>You have a [item_name] in your [where].")
|
||||
to_chat(mob, "<span class='danger'>You have a [item_name] in your [where].</span>")
|
||||
if(where == "backpack")
|
||||
var/obj/item/storage/B = mob.back
|
||||
B.orient2hud(mob)
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
if(B.current)
|
||||
B.current.update_action_buttons_icon()
|
||||
if(!B.current.incapacitated())
|
||||
to_chat(B.current,"<span class='cultlarge'>[Nominee] has died in the process of attempting to win the cult's support!")
|
||||
to_chat(B.current,"<span class='cultlarge'>[Nominee] has died in the process of attempting to win the cult's support!</span>")
|
||||
return FALSE
|
||||
if(!Nominee.mind)
|
||||
GLOB.cult_vote_called = FALSE
|
||||
@@ -126,7 +126,7 @@
|
||||
if(B.current)
|
||||
B.current.update_action_buttons_icon()
|
||||
if(!B.current.incapacitated())
|
||||
to_chat(B.current,"<span class='cultlarge'>[Nominee] has gone catatonic in the process of attempting to win the cult's support!")
|
||||
to_chat(B.current,"<span class='cultlarge'>[Nominee] has gone catatonic in the process of attempting to win the cult's support!</span>")
|
||||
return FALSE
|
||||
if(LAZYLEN(yes_voters) <= LAZYLEN(asked_cultists) * 0.5)
|
||||
GLOB.cult_vote_called = FALSE
|
||||
@@ -134,7 +134,7 @@
|
||||
if(B.current)
|
||||
B.current.update_action_buttons_icon()
|
||||
if(!B.current.incapacitated())
|
||||
to_chat(B.current, "<span class='cultlarge'>[Nominee] could not win the cult's support and shall continue to serve as an acolyte.")
|
||||
to_chat(B.current, "<span class='cultlarge'>[Nominee] could not win the cult's support and shall continue to serve as an acolyte.</span>")
|
||||
return FALSE
|
||||
GLOB.cult_mastered = TRUE
|
||||
SSticker.mode.remove_cultist(Nominee.mind, TRUE)
|
||||
@@ -144,7 +144,7 @@
|
||||
for(var/datum/action/innate/cult/mastervote/vote in B.current.actions)
|
||||
vote.Remove(B.current)
|
||||
if(!B.current.incapacitated())
|
||||
to_chat(B.current,"<span class='cultlarge'>[Nominee] has won the cult's support and is now their master. Follow [Nominee.p_their()] orders to the best of your ability!")
|
||||
to_chat(B.current,"<span class='cultlarge'>[Nominee] has won the cult's support and is now their master. Follow [Nominee.p_their()] orders to the best of your ability!</span>")
|
||||
return TRUE
|
||||
|
||||
/datum/action/innate/cult/master/IsAvailable()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user