Merge remote-tracking branch 'refs/remotes/Citadel-Station-13/master' into IHAVENOIDEAWHATTHEFUCKIMDOING
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
#define GLOBAL_PROTECT(X)\
|
||||
/datum/controller/global_vars/InitGlobal##X(){\
|
||||
..();\
|
||||
gvars_datum_protected_varlist += #X;\
|
||||
gvars_datum_protected_varlist[#X] = TRUE;\
|
||||
}
|
||||
#else
|
||||
#define GLOBAL_PROTECT(X)
|
||||
|
||||
+12
-12
@@ -116,17 +116,17 @@
|
||||
|
||||
#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_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>)"
|
||||
@@ -135,7 +135,7 @@
|
||||
#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_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"
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#define NORMPIPERATE 30 //pipe-insulation rate divisor
|
||||
#define HEATPIPERATE 8 //heat-exch pipe insulation
|
||||
#define FLOWFRAC 0.99 //fraction of gas transfered per process
|
||||
#define TANK_MELT_TEMPERATURE 1000000
|
||||
#define TANK_LEAK_PRESSURE (30.*ONE_ATMOSPHERE) //Tank starts leaking
|
||||
#define TANK_RUPTURE_PRESSURE (35.*ONE_ATMOSPHERE) //Tank spills all contents into atmosphere
|
||||
#define TANK_FRAGMENT_PRESSURE (40.*ONE_ATMOSPHERE) //Boom 3x3 base explosion
|
||||
@@ -109,7 +110,7 @@
|
||||
|
||||
#define PRESSURE_DAMAGE_COEFFICIENT 4 //The amount of pressure damage someone takes is equal to (pressure / HAZARD_HIGH_PRESSURE)*PRESSURE_DAMAGE_COEFFICIENT, with the maximum of MAX_PRESSURE_DAMAGE
|
||||
#define MAX_HIGH_PRESSURE_DAMAGE 4
|
||||
#define LOW_PRESSURE_DAMAGE 2 //The amount of damage someone takes when in a low pressure area (The pressure threshold is so low that it doesn't make sense to do any calculations, so it just applies this flat value).
|
||||
#define LOW_PRESSURE_DAMAGE 4 //The amount of damage someone takes when in a low pressure area (The pressure threshold is so low that it doesn't make sense to do any calculations, so it just applies this flat value).
|
||||
|
||||
#define COLD_SLOWDOWN_FACTOR 20 //Humans are slowed by the difference between bodytemp and BODYTEMP_COLD_DAMAGE_LIMIT divided by this
|
||||
|
||||
|
||||
@@ -66,13 +66,10 @@ GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not us
|
||||
|
||||
#define ARK_SUMMON_COST 5 //how many of each component an Ark costs to summon
|
||||
|
||||
#define ARK_CONSUME_COST 15 //how many of each component an Ark needs to consume to activate
|
||||
|
||||
//Objective text define
|
||||
#define CLOCKCULT_OBJECTIVE "Construct the Ark of the Clockwork Justicar and free Ratvar."
|
||||
|
||||
//misc clockcult stuff
|
||||
#define MARAUDER_EMERGE_THRESHOLD 65 //marauders cannot emerge unless host is at this% or less health
|
||||
|
||||
#define SIGIL_ACCESS_RANGE 2 //range at which transmission sigils can access power
|
||||
|
||||
@@ -83,3 +80,9 @@ GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not us
|
||||
#define CLOCKWORK_ARMOR_COOLDOWN 1800 //The cooldown period between summoning suits of clockwork armor
|
||||
|
||||
#define RATVARIAN_SPEAR_COOLDOWN 300 //The cooldown period between summoning another Ratvarian spear
|
||||
|
||||
#define MARAUDER_SCRIPTURE_SCALING_THRESHOLD 200 //The amount of deciseconds that must pass before marauder scripture will not gain a recital penalty
|
||||
|
||||
#define MARAUDER_SCRIPTURE_SCALING_TIME 50 //The amount of extra deciseconds tacked on to the marauder scripture recital time per recent marauder
|
||||
|
||||
#define MARAUDER_SCRIPTURE_SCALING_MAX 300 //The maximum extra time applied to the marauder scripture
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#define COMSIG_ATOM_RCD_ACT "atom_rcd_act" //from base of atom/rcd_act(): (/mob, /obj/item/construction/rcd, passed_mode)
|
||||
#define COMSIG_ATOM_SING_PULL "atom_sing_pull" //from base of atom/singularity_pull(): (S, current_size)
|
||||
#define COMSIG_ATOM_SET_LIGHT "atom_set_light" //from base of atom/set_light(): (l_range, l_power, l_color)
|
||||
#define COMSIG_ATOM_ROTATE "atom_rotate" //from base of atom/shuttleRotate(): (rotation, params)
|
||||
|
||||
#define COMSIG_CLICK "atom_click" //from base of atom/Click(): (location, control, params)
|
||||
#define COMSIG_CLICK_SHIFT "shift_click" //from base of atom/ShiftClick(): (/mob)
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#define BAN_CHAPEL "chapel"
|
||||
#define BAN_HURTPRIEST "hurtpriest"
|
||||
#define BAN_AVOIDWATER "avoidwater"
|
||||
#define BAN_STRIKEUNCONCIOUS "strikeunconcious"
|
||||
#define BAN_STRIKEUNCONSCIOUS "strikeunconscious"
|
||||
#define BAN_HURTLIZARD "hurtlizard"
|
||||
#define BAN_HURTANIMAL "hurtanimal"
|
||||
|
||||
|
||||
@@ -74,7 +74,8 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
|
||||
#define PASSGRILLE 4
|
||||
#define PASSBLOB 8
|
||||
#define PASSMOB 16
|
||||
#define LETPASSTHROW 32
|
||||
#define PASSCLOSEDTURF 32
|
||||
#define LETPASSTHROW 64
|
||||
|
||||
|
||||
//Movement Types
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
#define IC_INPUT "input"
|
||||
#define IC_OUTPUT "output"
|
||||
#define IC_ACTIVATOR "activator"
|
||||
|
||||
// Pin functionality.
|
||||
#define DATA_CHANNEL "data channel"
|
||||
#define PULSE_CHANNEL "pulse channel"
|
||||
|
||||
// Methods of obtaining a circuit.
|
||||
#define IC_SPAWN_DEFAULT 1 // If the circuit comes in the default circuit box and able to be printed in the IC printer.
|
||||
#define IC_SPAWN_RESEARCH 2 // If the circuit design will be available in the IC printer after upgrading it.
|
||||
|
||||
// Displayed along with the pin name to show what type of pin it is.
|
||||
#define IC_FORMAT_ANY "\<ANY\>"
|
||||
#define IC_FORMAT_STRING "\<TEXT\>"
|
||||
#define IC_FORMAT_CHAR "\<CHAR\>"
|
||||
#define IC_FORMAT_COLOR "\<COLOR\>"
|
||||
#define IC_FORMAT_NUMBER "\<NUM\>"
|
||||
#define IC_FORMAT_DIR "\<DIR\>"
|
||||
#define IC_FORMAT_BOOLEAN "\<BOOL\>"
|
||||
#define IC_FORMAT_REF "\<REF\>"
|
||||
#define IC_FORMAT_LIST "\<LIST\>"
|
||||
|
||||
#define IC_FORMAT_PULSE "\<PULSE\>"
|
||||
|
||||
// Used inside input/output list to tell the constructor what pin to make.
|
||||
#define IC_PINTYPE_ANY /datum/integrated_io
|
||||
#define IC_PINTYPE_STRING /datum/integrated_io/string
|
||||
#define IC_PINTYPE_CHAR /datum/integrated_io/char
|
||||
#define IC_PINTYPE_COLOR /datum/integrated_io/color
|
||||
#define IC_PINTYPE_NUMBER /datum/integrated_io/number
|
||||
#define IC_PINTYPE_DIR /datum/integrated_io/dir
|
||||
#define IC_PINTYPE_BOOLEAN /datum/integrated_io/boolean
|
||||
#define IC_PINTYPE_REF /datum/integrated_io/ref
|
||||
#define IC_PINTYPE_LIST /datum/integrated_io/lists
|
||||
|
||||
#define IC_PINTYPE_PULSE_IN /datum/integrated_io/activate
|
||||
#define IC_PINTYPE_PULSE_OUT /datum/integrated_io/activate/out
|
||||
|
||||
// Data limits.
|
||||
#define IC_MAX_LIST_LENGTH 500
|
||||
@@ -161,3 +161,70 @@
|
||||
|
||||
#define TINT_DARKENED 2 //Threshold of tint level to apply weld mask overlay
|
||||
#define TINT_BLIND 3 //Threshold of tint level to obscure vision fully
|
||||
|
||||
//Allowed equipment lists for security vests and hardsuits.
|
||||
|
||||
GLOBAL_LIST_INIT(advanced_hardsuit_allowed, typecacheof(list(
|
||||
/obj/item/ammo_box,
|
||||
/obj/item/ammo_casing,
|
||||
/obj/item/device/flashlight,
|
||||
/obj/item/gun,
|
||||
/obj/item/melee/baton,
|
||||
/obj/item/reagent_containers/spray/pepper,
|
||||
/obj/item/restraints/handcuffs,
|
||||
/obj/item/tank/internals)))
|
||||
|
||||
GLOBAL_LIST_INIT(security_hardsuit_allowed, typecacheof(list(
|
||||
/obj/item/ammo_box,
|
||||
/obj/item/ammo_casing,
|
||||
/obj/item/device/flashlight,
|
||||
/obj/item/gun/ballistic,
|
||||
/obj/item/gun/energy,
|
||||
/obj/item/melee/baton,
|
||||
/obj/item/reagent_containers/spray/pepper,
|
||||
/obj/item/restraints/handcuffs,
|
||||
/obj/item/tank/internals)))
|
||||
|
||||
GLOBAL_LIST_INIT(detective_vest_allowed, typecacheof(list(
|
||||
/obj/item/ammo_box,
|
||||
/obj/item/ammo_casing,
|
||||
/obj/item/device/detective_scanner,
|
||||
/obj/item/device/flashlight,
|
||||
/obj/item/device/taperecorder,
|
||||
/obj/item/gun/ballistic,
|
||||
/obj/item/gun/energy,
|
||||
/obj/item/lighter,
|
||||
/obj/item/melee/baton,
|
||||
/obj/item/melee/classic_baton,
|
||||
/obj/item/reagent_containers/spray/pepper,
|
||||
/obj/item/restraints/handcuffs,
|
||||
/obj/item/storage/fancy/cigarettes,
|
||||
/obj/item/tank/internals/emergency_oxygen)))
|
||||
|
||||
GLOBAL_LIST_INIT(security_vest_allowed, typecacheof(list(
|
||||
/obj/item/ammo_box,
|
||||
/obj/item/ammo_casing,
|
||||
/obj/item/device/flashlight,
|
||||
/obj/item/gun/ballistic,
|
||||
/obj/item/gun/energy,
|
||||
/obj/item/kitchen/knife/combat,
|
||||
/obj/item/melee/baton,
|
||||
/obj/item/melee/classic_baton/telescopic,
|
||||
/obj/item/reagent_containers/spray/pepper,
|
||||
/obj/item/restraints/handcuffs,
|
||||
/obj/item/tank/internals/emergency_oxygen)))
|
||||
|
||||
GLOBAL_LIST_INIT(security_wintercoat_allowed, typecacheof(list(
|
||||
/obj/item/ammo_box,
|
||||
/obj/item/ammo_casing,
|
||||
/obj/item/device/flashlight,
|
||||
/obj/item/storage/fancy/cigarettes,
|
||||
/obj/item/gun/ballistic,
|
||||
/obj/item/gun/energy,
|
||||
/obj/item/lighter,
|
||||
/obj/item/melee/baton,
|
||||
/obj/item/melee/classic_baton/telescopic,
|
||||
/obj/item/reagent_containers/spray/pepper,
|
||||
/obj/item/restraints/handcuffs,
|
||||
/obj/item/tank/internals/emergency_oxygen,
|
||||
/obj/item/toy)))
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
|
||||
#define ismovableatom(A) (istype(A, /atom/movable))
|
||||
|
||||
#define isatom(A) (istype(A, /atom))
|
||||
#define isatom(A) (isloc(A))
|
||||
|
||||
#define isweakref(D) (istype(D, /datum/weakref))
|
||||
|
||||
//Turfs
|
||||
//#define isturf(A) (istype(A, /turf)) This is actually a byond built-in. Added here for completeness sake.
|
||||
@@ -183,4 +185,4 @@ GLOBAL_LIST_INIT(glass_sheet_types, typecacheof(list(
|
||||
/obj/item/stack/sheet/plasmaglass,
|
||||
/obj/item/stack/sheet/plasmarglass)))
|
||||
|
||||
#define is_glass_sheet(O) (is_type_in_typecache(O, GLOB.glass_sheet_types))
|
||||
#define is_glass_sheet(O) (is_type_in_typecache(O, GLOB.glass_sheet_types))
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
//#define TURF_LAYER 2 //For easy recordkeeping; this is a byond define
|
||||
#define MID_TURF_LAYER 2.02
|
||||
#define HIGH_TURF_LAYER 2.03
|
||||
#define TURF_DECAL_LAYER 2.039 //Makes turf decals appear in DM how they will look inworld.
|
||||
#define ABOVE_OPEN_TURF_LAYER 2.04
|
||||
#define CLOSED_TURF_LAYER 2.05
|
||||
#define BULLET_HOLE_LAYER 2.06
|
||||
@@ -20,7 +21,6 @@
|
||||
#define LATTICE_LAYER 2.2
|
||||
#define DISPOSAL_PIPE_LAYER 2.3
|
||||
#define GAS_PIPE_HIDDEN_LAYER 2.35
|
||||
#define TURF_DECAL_LAYER 2.39
|
||||
#define WIRE_LAYER 2.4
|
||||
#define WIRE_TERMINAL_LAYER 2.45
|
||||
#define GAS_SCRUBBER_LAYER 2.46
|
||||
|
||||
+18
-16
@@ -1,20 +1,22 @@
|
||||
//Investigate logging defines
|
||||
#define INVESTIGATE_ATMOS "atmos"
|
||||
#define INVESTIGATE_BOTANY "botany"
|
||||
#define INVESTIGATE_CARGO "cargo"
|
||||
#define INVESTIGATE_EXPERIMENTOR "experimentor"
|
||||
#define INVESTIGATE_GRAVITY "gravity"
|
||||
#define INVESTIGATE_RECORDS "records"
|
||||
#define INVESTIGATE_SINGULO "singulo"
|
||||
#define INVESTIGATE_SUPERMATTER "supermatter"
|
||||
#define INVESTIGATE_TELESCI "telesci"
|
||||
#define INVESTIGATE_WIRES "wires"
|
||||
#define INVESTIGATE_ATMOS "atmos"
|
||||
#define INVESTIGATE_BOTANY "botany"
|
||||
#define INVESTIGATE_CARGO "cargo"
|
||||
#define INVESTIGATE_EXPERIMENTOR "experimentor"
|
||||
#define INVESTIGATE_GRAVITY "gravity"
|
||||
#define INVESTIGATE_RECORDS "records"
|
||||
#define INVESTIGATE_SINGULO "singulo"
|
||||
#define INVESTIGATE_SUPERMATTER "supermatter"
|
||||
#define INVESTIGATE_TELESCI "telesci"
|
||||
#define INVESTIGATE_WIRES "wires"
|
||||
#define INVESTIGATE_PORTAL "portals"
|
||||
#define INVESTIGATE_HALLUCINATIONS "hallucinations"
|
||||
#define INVESTIGATE_HALLUCINATIONS "hallucinations"
|
||||
#define INVESTIGATE_RADIATION "radiation"
|
||||
#define INVESTIGATE_EXONET "exonet"
|
||||
|
||||
//Individual logging defines
|
||||
#define INDIVIDUAL_ATTACK_LOG "Attack log"
|
||||
#define INDIVIDUAL_SAY_LOG "Say log"
|
||||
#define INDIVIDUAL_EMOTE_LOG "Emote log"
|
||||
#define INDIVIDUAL_OOC_LOG "OOC log"
|
||||
#define INDIVIDUAL_SHOW_ALL_LOG "All logs"
|
||||
#define INDIVIDUAL_ATTACK_LOG "Attack log"
|
||||
#define INDIVIDUAL_SAY_LOG "Say log"
|
||||
#define INDIVIDUAL_EMOTE_LOG "Emote log"
|
||||
#define INDIVIDUAL_OOC_LOG "OOC log"
|
||||
#define INDIVIDUAL_SHOW_ALL_LOG "All logs"
|
||||
@@ -84,3 +84,6 @@
|
||||
#define SUPERMATTER_DANGER 4 // Integrity < 50%
|
||||
#define SUPERMATTER_EMERGENCY 5 // Integrity < 25%
|
||||
#define SUPERMATTER_DELAMINATING 6 // Pretty obvious.
|
||||
|
||||
//R&D Snowflakes
|
||||
#define RD_CONSOLE_LOCKED_SCREEN 0.2
|
||||
@@ -466,9 +466,15 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
|
||||
|
||||
//Dummy mob reserve slots
|
||||
#define DUMMY_HUMAN_SLOT_PREFERENCES "dummy_preference_preview"
|
||||
|
||||
#define DUMMY_HUMAN_SLOT_MANIFEST "dummy_manifest_generation"
|
||||
|
||||
#define PR_ANNOUNCEMENTS_PER_ROUND 5 //The number of unique PR announcements allowed per round
|
||||
//This makes sure that a single person can only spam 3 reopens and 3 closes before being ignored
|
||||
|
||||
#define MAX_PROC_DEPTH 195 // 200 proc calls deep and shit breaks, this is a bit lower to give some safety room
|
||||
#define MAX_PROC_DEPTH 195 // 200 proc calls deep and shit breaks, this is a bit lower to give some safety room
|
||||
|
||||
#define DUMMY_HUMAN_SLOT_MANIFEST "dummy_manifest_generation"
|
||||
|
||||
#define SYRINGE_DRAW 0
|
||||
#define SYRINGE_INJECT 1
|
||||
|
||||
@@ -1,23 +1,17 @@
|
||||
//Construction Categories
|
||||
#define PIPE_BINARY 0 //2 directions: N/S, E/W
|
||||
#define PIPE_STRAIGHT 0 //2 directions: N/S, E/W
|
||||
#define PIPE_BENDABLE 1 //6 directions: N/S, E/W, N/E, N/W, S/E, S/W
|
||||
#define PIPE_TRINARY 2 //4 directions: N/E/S, E/S/W, S/W/N, W/N/E
|
||||
#define PIPE_TRIN_M 3 //8 directions: N->S+E, S->N+E, N->S+W, S->N+W, E->W+S, W->E+S, E->W+N, W->E+N
|
||||
#define PIPE_UNARY 4 //4 directions: N, S, E, W
|
||||
#define PIPE_QUAD 5 //1 directions: N/S/E/W
|
||||
#define PIPE_ONEDIR 5 //1 direction: N/S/E/W
|
||||
|
||||
//Disposal piping numbers - do NOT hardcode these, use the defines
|
||||
#define DISP_PIPE_STRAIGHT 0
|
||||
#define DISP_PIPE_BENT 1
|
||||
#define DISP_JUNCTION 2
|
||||
#define DISP_JUNCTION_FLIP 3
|
||||
#define DISP_YJUNCTION 4
|
||||
#define DISP_END_TRUNK 5
|
||||
#define DISP_END_BIN 6
|
||||
#define DISP_END_OUTLET 7
|
||||
#define DISP_END_CHUTE 8
|
||||
#define DISP_SORTJUNCTION 9
|
||||
#define DISP_SORTJUNCTION_FLIP 10
|
||||
//Disposal pipe relative connection directions
|
||||
#define DISP_DIR_BASE 0
|
||||
#define DISP_DIR_LEFT 1
|
||||
#define DISP_DIR_RIGHT 2
|
||||
#define DISP_DIR_FLIP 4
|
||||
#define DISP_DIR_NONE 8
|
||||
|
||||
//Transit tubes
|
||||
#define TRANSIT_TUBE_STRAIGHT 0
|
||||
|
||||
@@ -37,9 +37,9 @@
|
||||
#define EAVESDROP_EXTRA_RANGE 1 //how much past the specified message_range does the message get starred, whispering only
|
||||
|
||||
// A link given to ghost alice to follow bob
|
||||
#define FOLLOW_LINK(alice, bob) "<a href=?src=\ref[alice];follow=\ref[bob]>(F)</a>"
|
||||
#define TURF_LINK(alice, turfy) "<a href=?src=\ref[alice];x=[turfy.x];y=[turfy.y];z=[turfy.z]>(T)</a>"
|
||||
#define FOLLOW_OR_TURF_LINK(alice, bob, turfy) "<a href=?src=\ref[alice];follow=\ref[bob];x=[turfy.x];y=[turfy.y];z=[turfy.z]>(F)</a>"
|
||||
#define FOLLOW_LINK(alice, bob) "<a href=?src=[REF(alice)];follow=[REF(bob)]>(F)</a>"
|
||||
#define TURF_LINK(alice, turfy) "<a href=?src=[REF(alice)];x=[turfy.x];y=[turfy.y];z=[turfy.z]>(T)</a>"
|
||||
#define FOLLOW_OR_TURF_LINK(alice, bob, turfy) "<a href=?src=[REF(alice)];follow=[REF(bob)];x=[turfy.x];y=[turfy.y];z=[turfy.z]>(F)</a>"
|
||||
|
||||
#define LOGSAY "say"
|
||||
#define LOGWHISPER "whisper"
|
||||
|
||||
@@ -65,4 +65,9 @@
|
||||
//Docking turf movements
|
||||
#define MOVE_TURF 1
|
||||
#define MOVE_AREA 2
|
||||
#define MOVE_CONTENTS 4
|
||||
#define MOVE_CONTENTS 4
|
||||
|
||||
//Rotation params
|
||||
#define ROTATE_DIR 1
|
||||
#define ROTATE_SMOOTH 2
|
||||
#define ROTATE_OFFSET 4
|
||||
+71
-23
@@ -1,23 +1,71 @@
|
||||
//max channel is 1024. Only go lower from here, because byond tends to pick the first availiable channel to play sounds on
|
||||
#define CHANNEL_LOBBYMUSIC 1024
|
||||
#define CHANNEL_ADMIN 1023
|
||||
#define CHANNEL_VOX 1022
|
||||
#define CHANNEL_JUKEBOX 1021
|
||||
#define CHANNEL_JUSTICAR_ARK 1020
|
||||
#define CHANNEL_HEARTBEAT 1019 //sound channel for heartbeats
|
||||
#define CHANNEL_AMBIENCE 1018
|
||||
#define CHANNEL_BUZZ 1017
|
||||
#define CHANNEL_BICYCLE 1016
|
||||
|
||||
//Citadel code
|
||||
#define CHANNEL_PRED 1015
|
||||
#define CHANNEL_PREYLOOP 1014
|
||||
|
||||
//THIS SHOULD ALWAYS BE THE LOWEST ONE!
|
||||
//KEEP IT UPDATED
|
||||
|
||||
#define CHANNEL_HIGHEST_AVAILABLE 1013
|
||||
|
||||
#define CHANNEL_HIGHEST_AVAILABLE 1017
|
||||
#define SOUND_MINIMUM_PRESSURE 10
|
||||
#define FALLOFF_SOUNDS 0.5
|
||||
//max channel is 1024. Only go lower from here, because byond tends to pick the first availiable channel to play sounds on
|
||||
#define CHANNEL_LOBBYMUSIC 1024
|
||||
#define CHANNEL_ADMIN 1023
|
||||
#define CHANNEL_VOX 1022
|
||||
#define CHANNEL_JUKEBOX 1021
|
||||
#define CHANNEL_JUSTICAR_ARK 1020
|
||||
#define CHANNEL_HEARTBEAT 1019 //sound channel for heartbeats
|
||||
#define CHANNEL_AMBIENCE 1018
|
||||
#define CHANNEL_BUZZ 1017
|
||||
#define CHANNEL_BICYCLE 1016
|
||||
|
||||
//Citadel code
|
||||
#define CHANNEL_PRED 1015
|
||||
#define CHANNEL_PREYLOOP 1014
|
||||
|
||||
//THIS SHOULD ALWAYS BE THE LOWEST ONE!
|
||||
//KEEP IT UPDATED
|
||||
|
||||
#define CHANNEL_HIGHEST_AVAILABLE 1013
|
||||
|
||||
|
||||
#define SOUND_MINIMUM_PRESSURE 10
|
||||
#define FALLOFF_SOUNDS 0.5
|
||||
|
||||
|
||||
//Ambience types
|
||||
|
||||
#define GENERIC list('sound/ambience/ambigen1.ogg','sound/ambience/ambigen3.ogg',\
|
||||
'sound/ambience/ambigen4.ogg','sound/ambience/ambigen5.ogg',\
|
||||
'sound/ambience/ambigen6.ogg','sound/ambience/ambigen7.ogg',\
|
||||
'sound/ambience/ambigen8.ogg','sound/ambience/ambigen9.ogg',\
|
||||
'sound/ambience/ambigen10.ogg','sound/ambience/ambigen11.ogg',\
|
||||
'sound/ambience/ambigen12.ogg','sound/ambience/ambigen14.ogg','sound/ambience/ambigen15.ogg')
|
||||
|
||||
#define HOLY list('sound/ambience/ambicha1.ogg','sound/ambience/ambicha2.ogg','sound/ambience/ambicha3.ogg',\
|
||||
'sound/ambience/ambicha4.ogg', 'sound/ambience/ambiholy.ogg', 'sound/ambience/ambiholy2.ogg',\
|
||||
'sound/ambience/ambiholy3.ogg')
|
||||
|
||||
#define HIGHSEC list('sound/ambience/ambidanger.ogg', 'sound/ambience/ambidanger2.ogg')
|
||||
|
||||
#define RUINS list('sound/ambience/ambimine.ogg', 'sound/ambience/ambicave.ogg', 'sound/ambience/ambiruin.ogg',\
|
||||
'sound/ambience/ambiruin2.ogg', 'sound/ambience/ambiruin3.ogg', 'sound/ambience/ambiruin4.ogg',\
|
||||
'sound/ambience/ambiruin5.ogg', 'sound/ambience/ambiruin6.ogg', 'sound/ambience/ambiruin7.ogg',\
|
||||
'sound/ambience/ambidanger.ogg', 'sound/ambience/ambidanger2.ogg', 'sound/ambience/ambitech3.ogg',\
|
||||
'sound/ambience/ambimystery.ogg', 'sound/ambience/ambimaint1.ogg')
|
||||
|
||||
#define ENGINEERING list('sound/ambience/ambisin1.ogg','sound/ambience/ambisin2.ogg','sound/ambience/ambisin3.ogg','sound/ambience/ambisin4.ogg', 'sound/ambience/ambieng1.ogg',\
|
||||
'sound/ambience/ambiatmos.ogg', 'sound/ambience/ambiatmos2.ogg', 'sound/ambience/ambitech.ogg', 'sound/ambience/ambitech2.ogg', 'sound/ambience/ambitech3.ogg')
|
||||
|
||||
#define MINING list('sound/ambience/ambimine.ogg', 'sound/ambience/ambicave.ogg', 'sound/ambience/ambiruin.ogg',\
|
||||
'sound/ambience/ambiruin2.ogg', 'sound/ambience/ambiruin3.ogg', 'sound/ambience/ambiruin4.ogg',\
|
||||
'sound/ambience/ambiruin5.ogg', 'sound/ambience/ambiruin6.ogg', 'sound/ambience/ambiruin7.ogg',\
|
||||
'sound/ambience/ambidanger.ogg', 'sound/ambience/ambidanger2.ogg', 'sound/ambience/ambimaint1.ogg', 'sound/ambience/ambilava.ogg')
|
||||
|
||||
#define MEDICAL list('sound/ambience/ambinice.ogg')
|
||||
|
||||
#define SPOOKY list('sound/ambience/ambimo1.ogg','sound/ambience/ambimo2.ogg','sound/ambience/ambiruin7.ogg','sound/ambience/ambiruin6.ogg',\
|
||||
'sound/ambience/ambiodd.ogg', 'sound/ambience/ambimystery.ogg')
|
||||
|
||||
#define SPACE list('sound/ambience/ambispace.ogg', 'sound/ambience/ambispace2.ogg', 'sound/ambience/title2.ogg', 'sound/ambience/ambiatmos.ogg')
|
||||
|
||||
#define MAINTENANCE list('sound/ambience/ambimaint1.ogg', 'sound/ambience/ambimaint2.ogg', 'sound/ambience/ambimaint3.ogg', 'sound/ambience/ambimaint4.ogg',\
|
||||
'sound/ambience/ambimaint5.ogg', 'sound/voice/lowHiss2.ogg', 'sound/voice/lowHiss3.ogg', 'sound/voice/lowHiss4.ogg', 'sound/ambience/ambitech2.ogg' )
|
||||
|
||||
#define AWAY_MISSION list('sound/ambience/ambitech.ogg', 'sound/ambience/ambitech2.ogg', 'sound/ambience/ambiruin.ogg',\
|
||||
'sound/ambience/ambiruin2.ogg', 'sound/ambience/ambiruin3.ogg', 'sound/ambience/ambiruin4.ogg',\
|
||||
'sound/ambience/ambiruin5.ogg', 'sound/ambience/ambiruin6.ogg', 'sound/ambience/ambiruin7.ogg',\
|
||||
'sound/ambience/ambidanger.ogg', 'sound/ambience/ambidanger2.ogg', 'sound/ambience/ambimaint.ogg',\
|
||||
'sound/ambience/ambiatmos.ogg', 'sound/ambience/ambiatmos2.ogg', 'sound/ambience/ambiodd.ogg')
|
||||
|
||||
#define REEBE list('sound/ambience/ambireebe1.ogg', 'sound/ambience/ambireebe2.ogg', 'sound/ambience/ambireebe3.ogg')
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#define STAT_ENTRY_TIME 1
|
||||
#define STAT_ENTRY_COUNT 2
|
||||
#define STAT_ENTRY_LENGTH 2
|
||||
|
||||
|
||||
#define STAT_START_STOPWATCH var/STAT_STOP_WATCH = TICK_USAGE
|
||||
#define STAT_STOP_STOPWATCH var/STAT_TIME = TICK_USAGE_TO_MS(STAT_STOP_WATCH)
|
||||
#define STAT_LOG_ENTRY(entrylist, entryname) \
|
||||
var/list/STAT_ENTRY = entrylist[entryname] || (entrylist[entryname] = new /list(STAT_ENTRY_LENGTH));\
|
||||
STAT_ENTRY[STAT_ENTRY_TIME] += STAT_TIME;\
|
||||
var/STAT_INCR_AMOUNT = min(1, 2**round((STAT_ENTRY[STAT_ENTRY_COUNT] || 0)/SHORT_REAL_LIMIT));\
|
||||
if (STAT_INCR_AMOUNT == 1 || prob(100/STAT_INCR_AMOUNT)) {\
|
||||
STAT_ENTRY[STAT_ENTRY_COUNT] += STAT_INCR_AMOUNT;\
|
||||
};\
|
||||
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#define INIT_ORDER_ATOMS 11
|
||||
#define INIT_ORDER_LANGUAGE 10
|
||||
#define INIT_ORDER_MACHINES 9
|
||||
#define INIT_ORDER_CIRCUIT 8
|
||||
#define INIT_ORDER_TIMER 1
|
||||
#define INIT_ORDER_DEFAULT 0
|
||||
#define INIT_ORDER_AIR -1
|
||||
@@ -76,3 +77,27 @@
|
||||
#define RUNLEVEL_POSTGAME 8
|
||||
|
||||
#define RUNLEVELS_DEFAULT (RUNLEVEL_SETUP | RUNLEVEL_GAME | RUNLEVEL_POSTGAME)
|
||||
|
||||
|
||||
|
||||
|
||||
#define COMPILE_OVERLAYS(A)\
|
||||
if (TRUE) {\
|
||||
var/list/oo = A.our_overlays;\
|
||||
var/list/po = A.priority_overlays;\
|
||||
if(LAZYLEN(po)){\
|
||||
if(LAZYLEN(oo)){\
|
||||
A.overlays = oo + po;\
|
||||
}\
|
||||
else{\
|
||||
A.overlays = po;\
|
||||
}\
|
||||
}\
|
||||
else if(LAZYLEN(oo)){\
|
||||
A.overlays = oo;\
|
||||
}\
|
||||
else{\
|
||||
A.overlays.Cut();\
|
||||
}\
|
||||
A.flags_1 &= ~OVERLAY_QUEUED_1;\
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#define TOOL_NONE 0
|
||||
#define TOOL_CROWBAR 1
|
||||
#define TOOL_MULTITOOL 2
|
||||
#define TOOL_SCREWDRIVER 3
|
||||
#define TOOL_WIRECUTTER 4
|
||||
#define TOOL_WRENCH 5
|
||||
@@ -0,0 +1,2 @@
|
||||
#define WALL_DENT_HIT 1
|
||||
#define WALL_DENT_SHOT 2
|
||||
@@ -0,0 +1,93 @@
|
||||
#define BP_MAX_ROOM_SIZE 300
|
||||
|
||||
// Gets an atmos isolated contained space
|
||||
// Returns an associative list of turf|dirs pairs
|
||||
// The dirs are connected turfs in the same space
|
||||
// break_if_found is a typecache of turf types to return false if found
|
||||
/proc/detect_room(turf/origin, list/break_if_found)
|
||||
if(origin.blocks_air)
|
||||
return list(origin)
|
||||
|
||||
. = list()
|
||||
var/list/checked_turfs = list()
|
||||
var/list/found_turfs = list(origin)
|
||||
while(found_turfs.len)
|
||||
var/turf/sourceT = found_turfs[1]
|
||||
if(break_if_found[sourceT.type])
|
||||
return FALSE
|
||||
found_turfs.Cut(1, 2)
|
||||
var/dir_flags = checked_turfs[sourceT]
|
||||
for(var/dir in GLOB.alldirs)
|
||||
if(dir_flags & dir) // This means we've checked this dir before, probably from the other turf
|
||||
continue
|
||||
var/turf/checkT = get_step(sourceT, dir)
|
||||
if(!checkT)
|
||||
continue
|
||||
checked_turfs[sourceT] |= dir
|
||||
checked_turfs[checkT] |= turn(dir, 180)
|
||||
.[sourceT] |= dir
|
||||
.[checkT] |= turn(dir, 180)
|
||||
var/static/list/cardinal_cache = list("[NORTH]"=TRUE, "[EAST]"=TRUE, "[SOUTH]"=TRUE, "[WEST]"=TRUE)
|
||||
if(!cardinal_cache["[dir]"] || checkT.blocks_air || !CANATMOSPASS(sourceT, checkT))
|
||||
continue
|
||||
found_turfs += checkT // Since checkT is connected, add it to the list to be processed
|
||||
|
||||
/proc/create_area(mob/creator)
|
||||
var/static/blacklisted_turfs = typecacheof(/turf/open/space)
|
||||
var/static/blacklisted_areas = typecacheof(/area/space)
|
||||
var/list/turfs = detect_room(get_turf(creator), blacklisted_turfs)
|
||||
if(!turfs)
|
||||
to_chat(creator, "<span class='warning'>The new area must be completely airtight.</span>")
|
||||
return
|
||||
if(turfs.len > BP_MAX_ROOM_SIZE)
|
||||
to_chat(creator, "<span class='warning'>The room you're in is too big. It is [((turfs.len / BP_MAX_ROOM_SIZE)-1)*100]% larger than allowed.</span>")
|
||||
return
|
||||
// This will fuck up shuttles that use the base area type but we need to fix those anyway
|
||||
var/list/areas = list("New Area" = /area, "New Shuttle Area" = /area/shuttle/custom)
|
||||
for(var/i in 1 to turfs.len)
|
||||
var/area/place = get_area(turfs[i])
|
||||
if(blacklisted_areas[place.type])
|
||||
continue
|
||||
areas[place.name] = place
|
||||
var/area_choice = input(creator, "Choose an area to expand or make a new area.", "Area Expansion") as null|anything in areas
|
||||
area_choice = areas[area_choice]
|
||||
|
||||
if(!area_choice)
|
||||
to_chat(creator, "<span class='warning'>No choice selected. The area remains undefined.</span>")
|
||||
return
|
||||
var/area/newA
|
||||
var/area/oldA = get_area(get_turf(creator))
|
||||
if(!isarea(area_choice))
|
||||
var/str = trim(stripped_input(creator,"New area name:", "Blueprint Editing", "", MAX_NAME_LEN))
|
||||
if(!str || !length(str)) //cancel
|
||||
return
|
||||
if(length(str) > 50)
|
||||
to_chat(creator, "<span class='warning'>The given name is too long. The area remains undefined.</span>")
|
||||
return
|
||||
newA = new area_choice
|
||||
newA.setup(str)
|
||||
newA.set_dynamic_lighting()
|
||||
newA.has_gravity = oldA.has_gravity
|
||||
else
|
||||
newA = area_choice
|
||||
|
||||
for(var/i in 1 to turfs.len)
|
||||
var/turf/thing = turfs[i]
|
||||
var/area/old_area = thing.loc
|
||||
newA.contents += thing
|
||||
thing.change_area(old_area, newA)
|
||||
|
||||
var/list/related_areas = oldA.related
|
||||
for(var/i in 1 to related_areas.len)
|
||||
var/area/place = related_areas[i]
|
||||
var/list/firedoors = place.firedoors
|
||||
if(!LAZYLEN(firedoors))
|
||||
continue
|
||||
for(var/k in 1 to firedoors.len)
|
||||
var/obj/machinery/door/firedoor/FD = firedoors[k]
|
||||
FD.CalculateAffectingAreas()
|
||||
|
||||
to_chat(creator, "<span class='notice'>You have created a new area, named [newA.name]. It is now weather proof, and constructing an APC will allow it to be powered.</span>")
|
||||
return TRUE
|
||||
|
||||
#undef BP_MAX_ROOM_SIZE
|
||||
@@ -58,7 +58,12 @@ GLOBAL_VAR_INIT(cmp_field, "name")
|
||||
. = B.failures - A.failures
|
||||
if (!.)
|
||||
. = B.qdels - A.qdels
|
||||
|
||||
|
||||
/proc/cmp_generic_stat_item_time(list/A, list/B)
|
||||
. = B[STAT_ENTRY_TIME] - A[STAT_ENTRY_TIME]
|
||||
if (!.)
|
||||
. = B[STAT_ENTRY_COUNT] - A[STAT_ENTRY_COUNT]
|
||||
|
||||
/proc/cmp_profile_avg_time_dsc(list/A, list/B)
|
||||
return (B[PROFILE_ITEM_TIME]/(B[PROFILE_ITEM_COUNT] || 1)) - (A[PROFILE_ITEM_TIME]/(A[PROFILE_ITEM_COUNT] || 1))
|
||||
|
||||
|
||||
+21
-9
@@ -77,7 +77,7 @@
|
||||
|
||||
/proc/alone_in_area(area/the_area, mob/must_be_alone, check_type = /mob/living/carbon)
|
||||
var/area/our_area = get_area(the_area)
|
||||
for(var/C in GLOB.living_mob_list)
|
||||
for(var/C in GLOB.alive_mob_list)
|
||||
if(!istype(C, check_type))
|
||||
continue
|
||||
if(C == must_be_alone)
|
||||
@@ -214,17 +214,28 @@
|
||||
/proc/get_hearers_in_view(R, atom/source)
|
||||
// Returns a list of hearers in view(R) from source (ignoring luminosity). Used in saycode.
|
||||
var/turf/T = get_turf(source)
|
||||
var/list/hear = list()
|
||||
. = list()
|
||||
|
||||
if(!T)
|
||||
return hear
|
||||
return
|
||||
|
||||
var/list/range = get_hear(R, T)
|
||||
for(var/atom/movable/A in range)
|
||||
hear |= recursive_hear_check(A)
|
||||
|
||||
return hear
|
||||
var/list/processing_list = list()
|
||||
if (R == 0) // if the range is zero, we know exactly where to look for, we can skip view
|
||||
processing_list += T.contents // We can shave off one iteration by assuming turfs cannot hear
|
||||
else // A variation of get_hear inlined here to take advantage of the compiler's fastpath for obj/mob in view
|
||||
var/lum = T.luminosity
|
||||
T.luminosity = 6 // This is the maximum luminosity
|
||||
processing_list = viewers(R, T)
|
||||
for(var/obj/O in view(R, T))
|
||||
processing_list += O
|
||||
T.luminosity = lum
|
||||
|
||||
while(processing_list.len) // recursive_hear_check inlined here
|
||||
var/atom/A = processing_list[1]
|
||||
if(A.flags_1 & HEAR_1)
|
||||
. += A
|
||||
processing_list.Cut(1, 2)
|
||||
processing_list += A.contents
|
||||
|
||||
/proc/get_mobs_in_radio_ranges(list/obj/item/device/radio/radios)
|
||||
|
||||
@@ -307,7 +318,8 @@
|
||||
break
|
||||
|
||||
/proc/get_mob_by_key(key)
|
||||
for(var/mob/M in GLOB.mob_list)
|
||||
for(var/i in GLOB.player_list)
|
||||
var/mob/M = i
|
||||
if(M.ckey == lowertext(key))
|
||||
return M
|
||||
return null
|
||||
|
||||
@@ -179,6 +179,10 @@
|
||||
underlay_appearance.icon_state = DEFAULT_UNDERLAY_ICON_STATE
|
||||
underlays = U
|
||||
|
||||
// Drop posters which were previously placed on this wall.
|
||||
for(var/obj/structure/sign/poster/P in src)
|
||||
P.roll_and_drop(src)
|
||||
|
||||
|
||||
/proc/cardinal_smooth(atom/A, adjacencies)
|
||||
//NW CORNER
|
||||
|
||||
@@ -178,7 +178,7 @@ mob
|
||||
// Send the icon to src's local cache
|
||||
src<<browse_rsc(I, iconName)
|
||||
// Update the label to show it
|
||||
winset(src,"imageLabel","image='\ref[I]'");
|
||||
winset(src,"imageLabel","image='[REF(I)]'");
|
||||
|
||||
Add_Overlay()
|
||||
set name = "4. Add Overlay"
|
||||
@@ -849,7 +849,7 @@ The _flatIcons list is a cache for generated icon files.
|
||||
if(A.alpha < 255)
|
||||
flat.Blend(rgb(255, 255, 255, A.alpha), ICON_MULTIPLY)
|
||||
|
||||
return icon(flat, "", SOUTH)
|
||||
return icon(flat, "", curdir)
|
||||
|
||||
/proc/getIconMask(atom/A)//By yours truly. Creates a dynamic mask for a mob/whatever. /N
|
||||
var/icon/alpha_mask = new(A.icon,A.icon_state)//So we want the default icon and icon state of A.
|
||||
@@ -1006,23 +1006,26 @@ GLOBAL_LIST_EMPTY(friendly_animal_types)
|
||||
if(J)
|
||||
J.equip(body, TRUE, FALSE)
|
||||
|
||||
SSoverlays.Flush()
|
||||
|
||||
var/icon/out_icon = icon('icons/effects/effects.dmi', "nothing")
|
||||
|
||||
body.setDir(NORTH)
|
||||
COMPILE_OVERLAYS(body)
|
||||
var/icon/partial = getFlatIcon(body)
|
||||
out_icon.Insert(partial,dir=NORTH)
|
||||
|
||||
body.setDir(SOUTH)
|
||||
COMPILE_OVERLAYS(body)
|
||||
partial = getFlatIcon(body)
|
||||
out_icon.Insert(partial,dir=SOUTH)
|
||||
|
||||
body.setDir(WEST)
|
||||
COMPILE_OVERLAYS(body)
|
||||
partial = getFlatIcon(body)
|
||||
out_icon.Insert(partial,dir=WEST)
|
||||
|
||||
body.setDir(EAST)
|
||||
COMPILE_OVERLAYS(body)
|
||||
partial = getFlatIcon(body)
|
||||
out_icon.Insert(partial,dir=EAST)
|
||||
|
||||
@@ -1140,7 +1143,7 @@ GLOBAL_LIST_INIT(freon_color_matrix, list("#2E5E69", "#60A2A8", "#A1AFB1", rgb(0
|
||||
|
||||
// Either an atom or somebody fucked up and is gonna get a runtime, which I'm fine with.
|
||||
var/atom/A = thing
|
||||
var/key = "[istype(A.icon, /icon) ? "\ref[A.icon]" : A.icon]:[A.icon_state]"
|
||||
var/key = "[istype(A.icon, /icon) ? "[REF(A.icon)]" : A.icon]:[A.icon_state]"
|
||||
|
||||
|
||||
if (!bicon_cache[key]) // Doesn't exist, make it.
|
||||
|
||||
@@ -138,7 +138,7 @@ GLOBAL_LIST_INIT(sqrtTable, list(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4,
|
||||
var/t = round((val - min) / d)
|
||||
return val - (t * d)
|
||||
|
||||
#define NORM_ROT(rot) ((((rot % 360) + (rot - round(rot, 1))) > 0) ? ((rot % 360) + (rot - round(rot, 1))) : (((rot % 360) + (rot - round(rot, 1))) + 360))
|
||||
#define NORM_ROT(rot) ((((rot % 360) + (rot - round(rot, 1))) >= 0) ? ((rot % 360) + (rot - round(rot, 1))) : (((rot % 360) + (rot - round(rot, 1))) + 360))
|
||||
|
||||
/proc/get_angle_of_incidence(face_angle, angle_in, auto_normalize = TRUE)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/proc/priority_announce(text, title = "", sound = 'sound/ai/attention.ogg', type)
|
||||
/proc/priority_announce(text, title = "", sound = 'sound/ai/attention.ogg', type , sender_override)
|
||||
if(!text)
|
||||
return
|
||||
|
||||
@@ -13,13 +13,18 @@
|
||||
GLOB.news_network.SubmitArticle(text, "Captain's Announcement", "Station Announcements", null)
|
||||
|
||||
else
|
||||
announcement += "<h1 class='alert'>[command_name()] Update</h1>"
|
||||
if(!sender_override)
|
||||
announcement += "<h1 class='alert'>[command_name()] Update</h1>"
|
||||
else
|
||||
announcement += "<h1 class='alert'>[sender_override]</h1>"
|
||||
if (title && length(title) > 0)
|
||||
announcement += "<br><h2 class='alert'>[html_encode(title)]</h2>"
|
||||
if(title == "")
|
||||
GLOB.news_network.SubmitArticle(text, "Central Command Update", "Station Announcements", null)
|
||||
else
|
||||
GLOB.news_network.SubmitArticle(title + "<br><br>" + text, "Central Command", "Station Announcements", null)
|
||||
|
||||
if(!sender_override)
|
||||
if(title == "")
|
||||
GLOB.news_network.SubmitArticle(text, "Central Command Update", "Station Announcements", null)
|
||||
else
|
||||
GLOB.news_network.SubmitArticle(title + "<br><br>" + text, "Central Command", "Station Announcements", null)
|
||||
|
||||
announcement += "<br><span class='alert'>[html_encode(text)]</span><br>"
|
||||
announcement += "<br>"
|
||||
@@ -38,14 +43,11 @@
|
||||
if(announce)
|
||||
priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg')
|
||||
|
||||
for(var/obj/machinery/computer/communications/C in GLOB.machines)
|
||||
if(!(C.stat & (BROKEN|NOPOWER)) && (C.z in GLOB.station_z_levels))
|
||||
var/obj/item/paper/P = new /obj/item/paper(C.loc)
|
||||
P.name = "paper - '[title]'"
|
||||
P.info = text
|
||||
C.messagetitle.Add("[title]")
|
||||
C.messagetext.Add(text)
|
||||
P.update_icon()
|
||||
var/datum/comm_message/M = new
|
||||
M.title = title
|
||||
M.content = text
|
||||
|
||||
SScommunications.send_message(M)
|
||||
|
||||
/proc/minor_announce(message, title = "Attention:", alert)
|
||||
if(!message)
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
/proc/render_stats(list/stats, user, sort = /proc/cmp_generic_stat_item_time)
|
||||
sortTim(stats, sort, TRUE)
|
||||
|
||||
var/list/lines = list()
|
||||
|
||||
for (var/entry in stats)
|
||||
var/list/data = stats[entry]
|
||||
lines += "[entry] => [num2text(data[STAT_ENTRY_TIME], 10)]ms ([data[STAT_ENTRY_COUNT]]) (avg:[num2text(data[STAT_ENTRY_TIME]/(data[STAT_ENTRY_COUNT] || 1), 99)])"
|
||||
|
||||
if (user)
|
||||
user << browse("<ol><li>[lines.Join("</li><li>")]</li></ol>", "window=[url_encode("stats:[REF(stats)]")]")
|
||||
|
||||
. = lines.Join("\n")
|
||||
@@ -654,7 +654,7 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
|
||||
buffer = copytext(buffer, 1, cutoff) + punctbuffer
|
||||
if(!findtext(buffer,alphanumeric))
|
||||
continue
|
||||
if(!buffer || lentext(buffer) > 140 || lentext(buffer) <= cullshort || buffer in accepted)
|
||||
if(!buffer || lentext(buffer) > 280 || lentext(buffer) <= cullshort || buffer in accepted)
|
||||
continue
|
||||
|
||||
accepted += buffer
|
||||
|
||||
@@ -578,3 +578,23 @@
|
||||
return "turf"
|
||||
else //regex everything else (works for /proc too)
|
||||
return lowertext(replacetext("[the_type]", "[type2parent(the_type)]/", ""))
|
||||
|
||||
/proc/strtohex(str)
|
||||
if(!istext(str)||!str)
|
||||
return
|
||||
var/r
|
||||
var/c
|
||||
for(var/i = 1 to length(str))
|
||||
c= text2ascii(str,i)
|
||||
r+= num2hex(c)
|
||||
return r
|
||||
|
||||
/proc/hextostr(str)
|
||||
if(!istext(str)||!str)
|
||||
return
|
||||
var/r
|
||||
var/c
|
||||
for(var/i = 1 to length(str)/2)
|
||||
c= hex2num(copytext(str,i*2-1,i*2+1))
|
||||
r+= ascii2text(c)
|
||||
return r
|
||||
@@ -232,7 +232,7 @@ Turf and target are separate in case you want to teleport some distance from a t
|
||||
//Returns a list of unslaved cyborgs
|
||||
/proc/active_free_borgs()
|
||||
. = list()
|
||||
for(var/mob/living/silicon/robot/R in GLOB.living_mob_list)
|
||||
for(var/mob/living/silicon/robot/R in GLOB.alive_mob_list)
|
||||
if(R.connected_ai || R.shell)
|
||||
continue
|
||||
if(R.stat == DEAD)
|
||||
@@ -244,7 +244,7 @@ Turf and target are separate in case you want to teleport some distance from a t
|
||||
//Returns a list of AI's
|
||||
/proc/active_ais(check_mind=0)
|
||||
. = list()
|
||||
for(var/mob/living/silicon/ai/A in GLOB.living_mob_list)
|
||||
for(var/mob/living/silicon/ai/A in GLOB.alive_mob_list)
|
||||
if(A.stat == DEAD)
|
||||
continue
|
||||
if(A.control_disabled == 1)
|
||||
@@ -506,6 +506,7 @@ Turf and target are separate in case you want to teleport some distance from a t
|
||||
/*
|
||||
Gets all contents of contents and returns them all in a list.
|
||||
*/
|
||||
|
||||
/atom/proc/GetAllContents()
|
||||
var/list/processing_list = list(src)
|
||||
var/list/assembled = list()
|
||||
@@ -518,6 +519,19 @@ Turf and target are separate in case you want to teleport some distance from a t
|
||||
assembled += A
|
||||
return assembled
|
||||
|
||||
/atom/proc/GetAllContentsIgnoring(list/ignore_typecache)
|
||||
if(!ignore_typecache)
|
||||
return GetAllContents()
|
||||
var/list/processing = list(src)
|
||||
var/list/assembled = list()
|
||||
while(processing.len)
|
||||
var/atom/A = processing[1]
|
||||
processing.Cut(1,2)
|
||||
if(!ignore_typecache[A.type])
|
||||
processing += A.contents
|
||||
assembled += A
|
||||
return assembled
|
||||
|
||||
//Step-towards method of determining whether one atom can see another. Similar to viewers()
|
||||
/proc/can_see(atom/source, atom/target, length=5) // I couldnt be arsed to do actual raycasting :I This is horribly inaccurate.
|
||||
var/turf/current = get_turf(source)
|
||||
@@ -906,7 +920,7 @@ GLOBAL_LIST_INIT(WALLITEMS_INVERSE, typecacheof(list(
|
||||
/proc/living_player_count()
|
||||
var/living_player_count = 0
|
||||
for(var/mob in GLOB.player_list)
|
||||
if(mob in GLOB.living_mob_list)
|
||||
if(mob in GLOB.alive_mob_list)
|
||||
living_player_count += 1
|
||||
return living_player_count
|
||||
|
||||
@@ -1343,6 +1357,9 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
anchored = TRUE
|
||||
var/ready_to_die = FALSE
|
||||
|
||||
/mob/dview/Initialize() //Properly prevents this mob from gaining huds or joining any global lists
|
||||
return
|
||||
|
||||
/mob/dview/Destroy(force = FALSE)
|
||||
if(!ready_to_die)
|
||||
stack_trace("ALRIGHT WHICH FUCKER TRIED TO DELETE *MY* DVIEW?")
|
||||
@@ -1412,6 +1429,46 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
/proc/turf_z_is_planet(turf/T)
|
||||
return GLOB.z_is_planet["[T.z]"]
|
||||
|
||||
|
||||
//same as do_mob except for movables and it allows both to drift and doesn't draw progressbar
|
||||
/proc/do_atom(atom/movable/user , atom/movable/target, time = 30, uninterruptible = 0,datum/callback/extra_checks = null)
|
||||
if(!user || !target)
|
||||
return TRUE
|
||||
var/user_loc = user.loc
|
||||
|
||||
var/drifting = FALSE
|
||||
if(!user.Process_Spacemove(0) && user.inertia_dir)
|
||||
drifting = TRUE
|
||||
|
||||
var/target_drifting = FALSE
|
||||
if(!target.Process_Spacemove(0) && target.inertia_dir)
|
||||
target_drifting = TRUE
|
||||
|
||||
var/target_loc = target.loc
|
||||
|
||||
var/endtime = world.time+time
|
||||
// var/starttime = world.time
|
||||
. = TRUE
|
||||
while (world.time < endtime)
|
||||
stoplag(1)
|
||||
if(QDELETED(user) || QDELETED(target))
|
||||
. = 0
|
||||
break
|
||||
if(uninterruptible)
|
||||
continue
|
||||
|
||||
if(drifting && !user.inertia_dir)
|
||||
drifting = FALSE
|
||||
user_loc = user.loc
|
||||
|
||||
if(target_drifting && !target.inertia_dir)
|
||||
target_drifting = FALSE
|
||||
target_loc = target.loc
|
||||
|
||||
if((!drifting && user.loc != user_loc) || (!target_drifting && target.loc != target_loc) || (extra_checks && !extra_checks.Invoke()))
|
||||
. = FALSE
|
||||
break
|
||||
|
||||
//returns a GUID like identifier (using a mostly made up record format)
|
||||
//guids are not on their own suitable for access or security tokens, as most of their bits are predictable.
|
||||
// (But may make a nice salt to one)
|
||||
@@ -1427,5 +1484,18 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
var/time_low = num2hex(world.time, 3)
|
||||
|
||||
var/time_clock = num2hex(TICK_DELTA_TO_MS(world.tick_usage), 3)
|
||||
return "{[time_high]-[time_mid]-[GUID_VERSION][time_low]-[GUID_VARIANT][time_clock]-[node_id]}"
|
||||
|
||||
return "{[time_high]-[time_mid]-[GUID_VERSION][time_low]-[GUID_VARIANT][time_clock]-[node_id]}"
|
||||
// \ref behaviour got changed in 512 so this is necesary to replicate old behaviour.
|
||||
// If it ever becomes necesary to get a more performant REF(), this lies here in wait
|
||||
// #define REF(thing) (thing && istype(thing, /datum) && thing:use_tag && thing:tag ? "[thing:tag]" : "\ref[thing]")
|
||||
/proc/REF(input)
|
||||
if(istype(input, /datum))
|
||||
var/datum/thing = input
|
||||
if(thing.use_tag)
|
||||
if(!thing.tag)
|
||||
WARNING("A ref was requested of an object with use_tag set but no tag: [thing]")
|
||||
thing.use_tag = FALSE
|
||||
else
|
||||
return "\[[url_encode(thing.tag)]\]"
|
||||
return "\ref[input]"
|
||||
|
||||
@@ -12,10 +12,13 @@ GLOBAL_LIST_EMPTY(stealthminID) //reference list with IDs that store ckeys,
|
||||
GLOBAL_LIST_EMPTY(player_list) //all mobs **with clients attached**. Excludes /mob/dead/new_player
|
||||
GLOBAL_LIST_EMPTY(mob_list) //all mobs, including clientless
|
||||
GLOBAL_LIST_EMPTY(mob_directory) //mob_id -> mob
|
||||
GLOBAL_LIST_EMPTY(living_mob_list) //all alive mobs, including clientless. Excludes /mob/dead/new_player
|
||||
GLOBAL_LIST_EMPTY(alive_mob_list) //all alive mobs, including clientless. Excludes /mob/dead/new_player
|
||||
GLOBAL_LIST_EMPTY(drones_list)
|
||||
GLOBAL_LIST_EMPTY(dead_mob_list) //all dead mobs, including clientless. Excludes /mob/dead/new_player
|
||||
GLOBAL_LIST_EMPTY(joined_player_list) //all clients that have joined the game at round-start or as a latejoin.
|
||||
GLOBAL_LIST_EMPTY(silicon_mobs) //all silicon mobs
|
||||
GLOBAL_LIST_EMPTY(mob_living_list) //all instances of /mob/living and subtypes
|
||||
GLOBAL_LIST_EMPTY(carbon_list) //all instances of /mob/living/carbon and subtypes, notably does not contain brains or simple animals
|
||||
GLOBAL_LIST_EMPTY(ai_list)
|
||||
GLOBAL_LIST_EMPTY(pai_list)
|
||||
GLOBAL_LIST_EMPTY(available_ai_shells)
|
||||
|
||||
@@ -19,7 +19,6 @@ GLOBAL_LIST_INIT(nightmare_names, world.file2list("strings/names/nightmare.txt")
|
||||
GLOBAL_LIST_INIT(megacarp_first_names, world.file2list("strings/names/megacarp1.txt"))
|
||||
GLOBAL_LIST_INIT(megacarp_last_names, world.file2list("strings/names/megacarp2.txt"))
|
||||
|
||||
|
||||
GLOBAL_LIST_INIT(verbs, world.file2list("strings/names/verbs.txt"))
|
||||
GLOBAL_LIST_INIT(adjectives, world.file2list("strings/names/adjectives.txt"))
|
||||
GLOBAL_LIST_INIT(dream_strings, world.file2list("strings/dreamstrings.txt"))
|
||||
|
||||
@@ -36,4 +36,5 @@ GLOBAL_LIST_EMPTY(wire_name_directory)
|
||||
|
||||
GLOBAL_LIST_EMPTY(ai_status_displays)
|
||||
|
||||
GLOBAL_LIST_EMPTY(mob_spawners) // All mob_spawn objects
|
||||
GLOBAL_LIST_EMPTY(mob_spawners) // All mob_spawn objects
|
||||
GLOBAL_LIST_EMPTY(alert_consoles) // Station alert consoles, /obj/machinery/computer/station_alert
|
||||
@@ -25,7 +25,7 @@ GLOBAL_LIST_EMPTY(bombers)
|
||||
GLOBAL_PROTECT(bombers)
|
||||
GLOBAL_LIST_EMPTY(admin_log)
|
||||
GLOBAL_PROTECT(admin_log)
|
||||
GLOBAL_LIST_EMPTY(lastsignalers) //keeps last 100 signals here in format: "[src] used \ref[src] @ location [src.loc]: [freq]/[code]"
|
||||
GLOBAL_LIST_EMPTY(lastsignalers) //keeps last 100 signals here in format: "[src] used [REF(src)] @ location [src.loc]: [freq]/[code]"
|
||||
GLOBAL_PROTECT(lastsignalers)
|
||||
GLOBAL_LIST_EMPTY(lawchanges) //Stores who uploaded laws to which silicon-based lifeform, and what the law was
|
||||
GLOBAL_PROTECT(lawchanges)
|
||||
|
||||
+13
-12
@@ -38,6 +38,8 @@
|
||||
if(isnull(pixel_turf))
|
||||
return
|
||||
if(!can_see(A))
|
||||
if(isturf(A)) //On unmodified clients clicking the static overlay clicks the turf underneath
|
||||
return //So there's no point messaging admins
|
||||
message_admins("[key_name_admin(src)] might be running a modified client! (failed can_see on AI click of [A]([ADMIN_COORDJMP(pixel_turf)]))")
|
||||
var/message = "[key_name(src)] might be running a modified client! (failed can_see on AI click of [A]([COORD(pixel_turf)]))"
|
||||
log_admin(message)
|
||||
@@ -136,36 +138,35 @@
|
||||
/obj/machinery/door/airlock/AICtrlClick() // Bolts doors
|
||||
if(emagged)
|
||||
return
|
||||
|
||||
if(locked)
|
||||
Topic("aiEnable=4", list("aiEnable"="4"), 1)// 1 meaning no window (consistency!)
|
||||
bolt_raise(usr)
|
||||
else
|
||||
Topic("aiDisable=4", list("aiDisable"="4"), 1)
|
||||
bolt_drop(usr)
|
||||
|
||||
/obj/machinery/door/airlock/AIAltClick() // Eletrifies doors.
|
||||
if(emagged)
|
||||
return
|
||||
|
||||
if(!secondsElectrified)
|
||||
// permanent shock
|
||||
Topic("aiEnable=6", list("aiEnable"="6"), 1) // 1 meaning no window (consistency!)
|
||||
shock_perm(usr)
|
||||
else
|
||||
// disable/6 is not in Topic; disable/5 disables both temporary and permenant shock
|
||||
Topic("aiDisable=5", list("aiDisable"="5"), 1)
|
||||
shock_restore(usr)
|
||||
|
||||
/obj/machinery/door/airlock/AIShiftClick() // Opens and closes doors!
|
||||
if(emagged)
|
||||
return
|
||||
if(density)
|
||||
Topic("aiEnable=7", list("aiEnable"="7"), 1) // 1 meaning no window (consistency!)
|
||||
else
|
||||
Topic("aiDisable=7", list("aiDisable"="7"), 1)
|
||||
|
||||
user_toggle_open(usr)
|
||||
|
||||
/obj/machinery/door/airlock/AICtrlShiftClick() // Sets/Unsets Emergency Access Override
|
||||
if(emagged)
|
||||
return
|
||||
|
||||
if(!emergency)
|
||||
Topic("aiEnable=11", list("aiEnable"="11"), 1) // 1 meaning no window (consistency!)
|
||||
emergency_on(usr)
|
||||
else
|
||||
Topic("aiDisable=11", list("aiDisable"="11"), 1)
|
||||
emergency_off(usr)
|
||||
|
||||
/* APC */
|
||||
/obj/machinery/power/apc/AICtrlClick() // turns off/on APCs.
|
||||
|
||||
+14
-10
@@ -282,11 +282,13 @@
|
||||
return
|
||||
|
||||
/mob/living/carbon/MiddleClickOn(atom/A)
|
||||
if(!src.stat && src.mind && src.mind.changeling && src.mind.changeling.chosen_sting && (iscarbon(A)) && (A != src))
|
||||
next_click = world.time + 5
|
||||
mind.changeling.chosen_sting.try_to_sting(src, A)
|
||||
else
|
||||
swap_hand()
|
||||
if(!stat && mind && iscarbon(A) && A != src)
|
||||
var/datum/antagonist/changeling/C = mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(C && C.chosen_sting)
|
||||
C.chosen_sting.try_to_sting(src,A)
|
||||
next_click = world.time + 5
|
||||
return
|
||||
swap_hand()
|
||||
|
||||
/mob/living/simple_animal/drone/MiddleClickOn(atom/A)
|
||||
swap_hand()
|
||||
@@ -344,11 +346,13 @@
|
||||
return
|
||||
|
||||
/mob/living/carbon/AltClickOn(atom/A)
|
||||
if(!src.stat && src.mind && src.mind.changeling && src.mind.changeling.chosen_sting && (iscarbon(A)) && (A != src))
|
||||
next_click = world.time + 5
|
||||
mind.changeling.chosen_sting.try_to_sting(src, A)
|
||||
else
|
||||
..()
|
||||
if(!stat && mind && iscarbon(A) && A != src)
|
||||
var/datum/antagonist/changeling/C = mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(C && C.chosen_sting)
|
||||
C.chosen_sting.try_to_sting(src,A)
|
||||
next_click = world.time + 5
|
||||
return
|
||||
..()
|
||||
|
||||
/atom/proc/AltClick(mob/user)
|
||||
SendSignal(COMSIG_CLICK_ALT, user)
|
||||
|
||||
@@ -23,9 +23,6 @@
|
||||
//Middle left indicators
|
||||
#define ui_lingchemdisplay "WEST,CENTER-1:15"
|
||||
#define ui_lingstingdisplay "WEST:6,CENTER-3:11"
|
||||
#define ui_crafting "12:-10,1:5"
|
||||
#define ui_building "12:-10,1:21"
|
||||
#define ui_language_menu "11:6,2:-11"
|
||||
|
||||
#define ui_devilsouldisplay "WEST:6,CENTER-1:15"
|
||||
|
||||
@@ -85,6 +82,9 @@
|
||||
#define ui_acti "EAST-3:24,SOUTH:5"
|
||||
#define ui_zonesel "EAST-1:28,SOUTH:5"
|
||||
#define ui_acti_alt "EAST-1:28,SOUTH:5" //alternative intent switcher for when the interface is hidden (F12)
|
||||
#define ui_crafting "EAST-4:22,SOUTH:5"
|
||||
#define ui_building "EAST-4:22,SOUTH:21"
|
||||
#define ui_language_menu "EAST-4:6,SOUTH:21"
|
||||
|
||||
#define ui_borg_pull "EAST-2:26,SOUTH+1:7"
|
||||
#define ui_borg_radio "EAST-1:28,SOUTH+1:7"
|
||||
|
||||
@@ -390,7 +390,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
|
||||
var/servants = 0
|
||||
var/validservants = 0
|
||||
var/list/textlist
|
||||
for(var/mob/living/L in GLOB.living_mob_list)
|
||||
for(var/mob/living/L in GLOB.alive_mob_list)
|
||||
if(is_servant_of_ratvar(L))
|
||||
servants++
|
||||
if(ishuman(L) || issilicon(L))
|
||||
@@ -407,16 +407,13 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
|
||||
textlist += "[i] Scripture: <b>[SSticker.scripture_states[i] ? "UNLOCKED":"LOCKED"]</b><br>"
|
||||
var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar
|
||||
if(G)
|
||||
var/time_info
|
||||
var/time_info = G.get_arrival_time(FALSE)
|
||||
var/time_name
|
||||
if(G.seconds_until_activation)
|
||||
time_info = G.seconds_until_activation
|
||||
time_name = "until the Ark activates"
|
||||
else if(G.grace_period)
|
||||
time_info = G.grace_period
|
||||
time_name = "of grace period remaining"
|
||||
else if(G.progress_in_seconds)
|
||||
time_info = GATEWAY_RATVAR_ARRIVAL - G.progress_in_seconds
|
||||
time_name = "until the Ark finishes summoning"
|
||||
if(time_info)
|
||||
textlist += "<b>[time_info / 60] minutes</b> [time_name].<br>"
|
||||
|
||||
+177
-175
@@ -1,175 +1,177 @@
|
||||
|
||||
/mob
|
||||
var/list/screens = list()
|
||||
|
||||
/mob/proc/overlay_fullscreen(category, type, severity)
|
||||
var/obj/screen/fullscreen/screen
|
||||
if(screens[category])
|
||||
screen = screens[category]
|
||||
if(screen.type != type)
|
||||
clear_fullscreen(category, FALSE)
|
||||
return .()
|
||||
else if(!severity || severity == screen.severity)
|
||||
return null
|
||||
else
|
||||
screen = new type()
|
||||
|
||||
screen.icon_state = "[initial(screen.icon_state)][severity]"
|
||||
screen.severity = severity
|
||||
|
||||
screens[category] = screen
|
||||
if(client && screen.should_show_to(src))
|
||||
client.screen += screen
|
||||
return screen
|
||||
|
||||
/mob/proc/clear_fullscreen(category, animated = 10)
|
||||
var/obj/screen/fullscreen/screen = screens[category]
|
||||
if(!screen)
|
||||
return
|
||||
|
||||
screens -= category
|
||||
|
||||
if(animated)
|
||||
animate(screen, alpha = 0, time = animated)
|
||||
addtimer(CALLBACK(src, .proc/clear_fullscreen_after_animate, screen), animated, TIMER_CLIENT_TIME)
|
||||
else
|
||||
if(client)
|
||||
client.screen -= screen
|
||||
qdel(screen)
|
||||
|
||||
/mob/proc/clear_fullscreen_after_animate(obj/screen/fullscreen/screen)
|
||||
if(client)
|
||||
client.screen -= screen
|
||||
qdel(screen)
|
||||
|
||||
/mob/proc/clear_fullscreens()
|
||||
for(var/category in screens)
|
||||
clear_fullscreen(category)
|
||||
|
||||
/mob/proc/hide_fullscreens()
|
||||
if(client)
|
||||
for(var/category in screens)
|
||||
client.screen -= screens[category]
|
||||
|
||||
/mob/proc/reload_fullscreen()
|
||||
if(client)
|
||||
var/obj/screen/fullscreen/screen
|
||||
for(var/category in screens)
|
||||
screen = screens[category]
|
||||
if(screen.should_show_to(src))
|
||||
client.screen |= screen
|
||||
else
|
||||
client.screen -= screen
|
||||
|
||||
/obj/screen/fullscreen
|
||||
icon = 'icons/mob/screen_full.dmi'
|
||||
icon_state = "default"
|
||||
screen_loc = "CENTER-7,CENTER-7"
|
||||
layer = FULLSCREEN_LAYER
|
||||
plane = FULLSCREEN_PLANE
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
var/severity = 0
|
||||
var/show_when_dead = FALSE
|
||||
|
||||
/obj/screen/fullscreen/proc/should_show_to(mob/mymob)
|
||||
if(!show_when_dead && mymob.stat == DEAD)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/screen/fullscreen/Destroy()
|
||||
severity = 0
|
||||
. = ..()
|
||||
|
||||
/obj/screen/fullscreen/brute
|
||||
icon_state = "brutedamageoverlay"
|
||||
layer = UI_DAMAGE_LAYER
|
||||
plane = FULLSCREEN_PLANE
|
||||
|
||||
/obj/screen/fullscreen/oxy
|
||||
icon_state = "oxydamageoverlay"
|
||||
layer = UI_DAMAGE_LAYER
|
||||
plane = FULLSCREEN_PLANE
|
||||
|
||||
/obj/screen/fullscreen/crit
|
||||
icon_state = "passage"
|
||||
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/impaired
|
||||
icon_state = "impairedoverlay"
|
||||
|
||||
/obj/screen/fullscreen/blurry
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
screen_loc = "WEST,SOUTH to EAST,NORTH"
|
||||
icon_state = "blurry"
|
||||
|
||||
/obj/screen/fullscreen/flash
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
screen_loc = "WEST,SOUTH to EAST,NORTH"
|
||||
icon_state = "flash"
|
||||
|
||||
/obj/screen/fullscreen/flash/static
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
screen_loc = "WEST,SOUTH to EAST,NORTH"
|
||||
icon_state = "noise"
|
||||
|
||||
/obj/screen/fullscreen/high
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
screen_loc = "WEST,SOUTH to EAST,NORTH"
|
||||
icon_state = "druggy"
|
||||
|
||||
/obj/screen/fullscreen/color_vision
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
screen_loc = "WEST,SOUTH to EAST,NORTH"
|
||||
icon_state = "flash"
|
||||
alpha = 80
|
||||
|
||||
/obj/screen/fullscreen/color_vision/green
|
||||
color = "#00ff00"
|
||||
|
||||
/obj/screen/fullscreen/color_vision/red
|
||||
color = "#ff0000"
|
||||
|
||||
/obj/screen/fullscreen/color_vision/blue
|
||||
color = "#0000ff"
|
||||
|
||||
/obj/screen/fullscreen/lighting_backdrop
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
icon_state = "flash"
|
||||
transform = matrix(200, 0, 0, 0, 200, 0)
|
||||
plane = LIGHTING_PLANE
|
||||
blend_mode = BLEND_OVERLAY
|
||||
show_when_dead = TRUE
|
||||
|
||||
//Provides darkness to the back of the lighting plane
|
||||
/obj/screen/fullscreen/lighting_backdrop/lit
|
||||
invisibility = INVISIBILITY_LIGHTING
|
||||
layer = BACKGROUND_LAYER+21
|
||||
color = "#000"
|
||||
show_when_dead = TRUE
|
||||
|
||||
//Provides whiteness in case you don't see lights so everything is still visible
|
||||
/obj/screen/fullscreen/lighting_backdrop/unlit
|
||||
layer = BACKGROUND_LAYER+20
|
||||
show_when_dead = TRUE
|
||||
|
||||
/obj/screen/fullscreen/see_through_darkness
|
||||
icon_state = "nightvision"
|
||||
plane = LIGHTING_PLANE
|
||||
layer = LIGHTING_LAYER
|
||||
blend_mode = BLEND_ADD
|
||||
show_when_dead = TRUE
|
||||
/mob
|
||||
var/list/screens = list()
|
||||
|
||||
/mob/proc/overlay_fullscreen(category, type, severity)
|
||||
var/obj/screen/fullscreen/screen = screens[category]
|
||||
if (!screen || screen.type != type)
|
||||
// needs to be recreated
|
||||
clear_fullscreen(category, FALSE)
|
||||
screens[category] = screen = new type()
|
||||
else if ((!severity || severity == screen.severity) && (!client || screen.screen_loc != "CENTER-7,CENTER-7" || screen.view == client.view))
|
||||
// doesn't need to be updated
|
||||
return screen
|
||||
|
||||
screen.icon_state = "[initial(screen.icon_state)][severity]"
|
||||
screen.severity = severity
|
||||
if (client && screen.should_show_to(src))
|
||||
client.screen += screen
|
||||
if (screen.screen_loc == "CENTER-7,CENTER-7" && screen.view != client.view)
|
||||
var/scale = (1 + 2 * client.view) / 15
|
||||
screen.view = client.view
|
||||
screen.transform = matrix(scale, 0, 0, 0, scale, 0)
|
||||
|
||||
return screen
|
||||
|
||||
/mob/proc/clear_fullscreen(category, animated = 10)
|
||||
var/obj/screen/fullscreen/screen = screens[category]
|
||||
if(!screen)
|
||||
return
|
||||
|
||||
screens -= category
|
||||
|
||||
if(animated)
|
||||
animate(screen, alpha = 0, time = animated)
|
||||
addtimer(CALLBACK(src, .proc/clear_fullscreen_after_animate, screen), animated, TIMER_CLIENT_TIME)
|
||||
else
|
||||
if(client)
|
||||
client.screen -= screen
|
||||
qdel(screen)
|
||||
|
||||
/mob/proc/clear_fullscreen_after_animate(obj/screen/fullscreen/screen)
|
||||
if(client)
|
||||
client.screen -= screen
|
||||
qdel(screen)
|
||||
|
||||
/mob/proc/clear_fullscreens()
|
||||
for(var/category in screens)
|
||||
clear_fullscreen(category)
|
||||
|
||||
/mob/proc/hide_fullscreens()
|
||||
if(client)
|
||||
for(var/category in screens)
|
||||
client.screen -= screens[category]
|
||||
|
||||
/mob/proc/reload_fullscreen()
|
||||
if(client)
|
||||
var/obj/screen/fullscreen/screen
|
||||
for(var/category in screens)
|
||||
screen = screens[category]
|
||||
if(screen.should_show_to(src))
|
||||
client.screen |= screen
|
||||
else
|
||||
client.screen -= screen
|
||||
|
||||
/obj/screen/fullscreen
|
||||
icon = 'icons/mob/screen_full.dmi'
|
||||
icon_state = "default"
|
||||
screen_loc = "CENTER-7,CENTER-7"
|
||||
layer = FULLSCREEN_LAYER
|
||||
plane = FULLSCREEN_PLANE
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
var/view = 7
|
||||
var/severity = 0
|
||||
var/show_when_dead = FALSE
|
||||
|
||||
/obj/screen/fullscreen/proc/should_show_to(mob/mymob)
|
||||
if(!show_when_dead && mymob.stat == DEAD)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/screen/fullscreen/Destroy()
|
||||
severity = 0
|
||||
. = ..()
|
||||
|
||||
/obj/screen/fullscreen/brute
|
||||
icon_state = "brutedamageoverlay"
|
||||
layer = UI_DAMAGE_LAYER
|
||||
plane = FULLSCREEN_PLANE
|
||||
|
||||
/obj/screen/fullscreen/oxy
|
||||
icon_state = "oxydamageoverlay"
|
||||
layer = UI_DAMAGE_LAYER
|
||||
plane = FULLSCREEN_PLANE
|
||||
|
||||
/obj/screen/fullscreen/crit
|
||||
icon_state = "passage"
|
||||
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/impaired
|
||||
icon_state = "impairedoverlay"
|
||||
|
||||
/obj/screen/fullscreen/blurry
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
screen_loc = "WEST,SOUTH to EAST,NORTH"
|
||||
icon_state = "blurry"
|
||||
|
||||
/obj/screen/fullscreen/flash
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
screen_loc = "WEST,SOUTH to EAST,NORTH"
|
||||
icon_state = "flash"
|
||||
|
||||
/obj/screen/fullscreen/flash/static
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
screen_loc = "WEST,SOUTH to EAST,NORTH"
|
||||
icon_state = "noise"
|
||||
|
||||
/obj/screen/fullscreen/high
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
screen_loc = "WEST,SOUTH to EAST,NORTH"
|
||||
icon_state = "druggy"
|
||||
|
||||
/obj/screen/fullscreen/color_vision
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
screen_loc = "WEST,SOUTH to EAST,NORTH"
|
||||
icon_state = "flash"
|
||||
alpha = 80
|
||||
|
||||
/obj/screen/fullscreen/color_vision/green
|
||||
color = "#00ff00"
|
||||
|
||||
/obj/screen/fullscreen/color_vision/red
|
||||
color = "#ff0000"
|
||||
|
||||
/obj/screen/fullscreen/color_vision/blue
|
||||
color = "#0000ff"
|
||||
|
||||
/obj/screen/fullscreen/lighting_backdrop
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
icon_state = "flash"
|
||||
transform = matrix(200, 0, 0, 0, 200, 0)
|
||||
plane = LIGHTING_PLANE
|
||||
blend_mode = BLEND_OVERLAY
|
||||
show_when_dead = TRUE
|
||||
|
||||
//Provides darkness to the back of the lighting plane
|
||||
/obj/screen/fullscreen/lighting_backdrop/lit
|
||||
invisibility = INVISIBILITY_LIGHTING
|
||||
layer = BACKGROUND_LAYER+21
|
||||
color = "#000"
|
||||
show_when_dead = TRUE
|
||||
|
||||
//Provides whiteness in case you don't see lights so everything is still visible
|
||||
/obj/screen/fullscreen/lighting_backdrop/unlit
|
||||
layer = BACKGROUND_LAYER+20
|
||||
show_when_dead = TRUE
|
||||
|
||||
/obj/screen/fullscreen/see_through_darkness
|
||||
icon_state = "nightvision"
|
||||
plane = LIGHTING_PLANE
|
||||
layer = LIGHTING_LAYER
|
||||
blend_mode = BLEND_ADD
|
||||
show_when_dead = TRUE
|
||||
|
||||
|
||||
@@ -539,7 +539,7 @@
|
||||
screen_loc = ui_healthdoll
|
||||
|
||||
/obj/screen/splash
|
||||
icon = 'config/title_screens/images/title1.dmi'
|
||||
icon = 'icons/blank_title.png'
|
||||
icon_state = ""
|
||||
screen_loc = "1,1"
|
||||
layer = SPLASHSCREEN_LAYER
|
||||
|
||||
@@ -1,12 +1,29 @@
|
||||
|
||||
/obj/item/proc/melee_attack_chain(mob/user, atom/target, params)
|
||||
if(pre_attackby(target, user, params))
|
||||
if(!tool_check(user, target) && pre_attackby(target, user, params))
|
||||
// Return 1 in attackby() to prevent afterattack() effects (when safely moving items for example)
|
||||
var/resolved = target.attackby(src, user, params)
|
||||
if(!resolved && target && !QDELETED(src))
|
||||
afterattack(target, user, 1, params) // 1: clicking something Adjacent
|
||||
|
||||
|
||||
//Checks if the item can work as a tool, calling the appropriate tool behavior on the target
|
||||
/obj/item/proc/tool_check(mob/user, atom/target)
|
||||
switch(tool_behaviour)
|
||||
if(TOOL_NONE)
|
||||
return FALSE
|
||||
if(TOOL_CROWBAR)
|
||||
return target.crowbar_act(user, src)
|
||||
if(TOOL_MULTITOOL)
|
||||
return target.multitool_act(user, src)
|
||||
if(TOOL_SCREWDRIVER)
|
||||
return target.screwdriver_act(user, src)
|
||||
if(TOOL_WRENCH)
|
||||
return target.wrench_act(user, src)
|
||||
if(TOOL_WIRECUTTER)
|
||||
return target.wirecutter_act(user, src)
|
||||
|
||||
|
||||
// Called when the item is in the active hand, and clicked; alternately, there is an 'activate held object' verb or you can hit pagedown.
|
||||
/obj/item/proc/attack_self(mob/user)
|
||||
SendSignal(COMSIG_ITEM_ATTACK_SELF, user)
|
||||
@@ -118,5 +135,4 @@
|
||||
attack_message = "[user] has [message_verb] [src][message_hit_area] with [I]!"
|
||||
visible_message("<span class='danger'>[attack_message]</span>", \
|
||||
"<span class='userdanger'>[attack_message]</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
return 1
|
||||
|
||||
return 1
|
||||
@@ -53,23 +53,19 @@
|
||||
if(user.client)
|
||||
if(IsAdminGhost(user))
|
||||
attack_ai(user)
|
||||
if(user.client.prefs.inquisitive_ghost)
|
||||
else if(user.client.prefs.inquisitive_ghost)
|
||||
user.examinate(src)
|
||||
|
||||
/mob/living/attack_ghost(mob/dead/observer/user)
|
||||
if(user.client && user.health_scan)
|
||||
healthscan(user, src, 1, TRUE)
|
||||
return
|
||||
..()
|
||||
|
||||
// ---------------------------------------
|
||||
// And here are some good things for free:
|
||||
// Now you can click through portals, wormholes, gateways, and teleporters while observing. -Sayu
|
||||
|
||||
/obj/machinery/teleport/hub/attack_ghost(mob/user)
|
||||
var/atom/l = loc
|
||||
var/obj/machinery/computer/teleporter/com = locate(/obj/machinery/computer/teleporter, locate(l.x - 2, l.y, l.z))
|
||||
if(com && com.locked)
|
||||
user.forceMove(get_turf(com.locked))
|
||||
|
||||
/obj/effect/portal/attack_ghost(mob/user)
|
||||
if(linked)
|
||||
user.forceMove(get_turf(linked))
|
||||
|
||||
/obj/machinery/gateway/centerstation/attack_ghost(mob/user)
|
||||
if(awaygate)
|
||||
user.forceMove(awaygate.loc)
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*/////////////////////////////////////////////////////////////////////////////////
|
||||
/////// ///////
|
||||
/////// Cit's exclusive jumpsuits, uniforms, etc. go here ///////
|
||||
/////// ///////
|
||||
*//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/obj/item/clothing/under/rank/security/skirt
|
||||
name = "security skirt"
|
||||
desc = "A tactical security skirt for officers complete with Nanotrasen belt buckle."
|
||||
icon = 'icons/obj/clothing/cit_clothes.dmi'
|
||||
icon_state = "secskirt"
|
||||
icon_override = 'icons/mob/citadel/uniforms.dmi'
|
||||
item_state = "r_suit"
|
||||
item_color = "secskirt"
|
||||
|
||||
/obj/item/clothing/under/rank/head_of_security/skirt
|
||||
name = "head of security's skirt"
|
||||
desc = "A security skirt decorated for those few with the dedication to achieve the position of Head of Security."
|
||||
icon = 'icons/obj/clothing/cit_clothes.dmi'
|
||||
icon_state = "hosskirt"
|
||||
icon_override = 'icons/mob/citadel/uniforms.dmi'
|
||||
item_state = "gy_suit"
|
||||
item_color = "hosskirt"
|
||||
|
||||
/obj/item/clothing/suit/armor/hos/trenchcoat/cloak
|
||||
name = "armored trenchcloak"
|
||||
desc = "A trenchcoat enchanced with a special lightweight kevlar. This one appears to be designed to be draped over one's shoulders rather than worn normally.."
|
||||
alternate_worn_icon = 'icons/mob/citadel/suit.dmi'
|
||||
icon_state = "hostrench"
|
||||
item_state = "hostrench"
|
||||
@@ -0,0 +1,5 @@
|
||||
/obj/structure/displaycase/clown
|
||||
desc = "In the event of clown, honk glass."
|
||||
alert = 1
|
||||
start_showpiece_type = /obj/item/bikehorn
|
||||
req_access = list(ACCESS_CENT_GENERAL)
|
||||
+45
-11
@@ -180,6 +180,7 @@
|
||||
icon_state = "toy9magazine"
|
||||
max_ammo = 30
|
||||
multiple_sprites = 2
|
||||
materials = list(MAT_METAL = 200)
|
||||
|
||||
/obj/item/gun/ballistic/automatic/x9/toy
|
||||
name = "\improper Foam Force X9"
|
||||
@@ -193,6 +194,7 @@
|
||||
spread = 90 //MAXIMUM XCOM MEMES (actually that'd be 180 spread)
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
weapon_weight = WEAPON_HEAVY
|
||||
origin_tech = "combat=1;magnets=1"
|
||||
|
||||
/datum/design/foam_x9
|
||||
name = "Foam Force X9 Rifle"
|
||||
@@ -213,6 +215,8 @@
|
||||
damage = 15
|
||||
armour_penetration = 10
|
||||
light_range = 2
|
||||
speed = 1.2
|
||||
range = 25
|
||||
light_color = LIGHT_COLOR_RED
|
||||
|
||||
/obj/item/projectile/bullet/nlmags //non-lethal boolets
|
||||
@@ -220,9 +224,11 @@
|
||||
icon_state = "magjectile-nl"
|
||||
damage = 1
|
||||
knockdown = 0
|
||||
stamina = 25
|
||||
stamina = 30
|
||||
armour_penetration = -10
|
||||
light_range = 2
|
||||
speed = 1.2
|
||||
range = 25
|
||||
light_color = LIGHT_COLOR_BLUE
|
||||
|
||||
|
||||
@@ -289,6 +295,7 @@
|
||||
|
||||
/obj/item/gun/ballistic/automatic/pistol/mag/nopin
|
||||
pin = null
|
||||
spawnwithmagazine = FALSE
|
||||
|
||||
/datum/design/magpistol
|
||||
name = "Magpistol"
|
||||
@@ -347,6 +354,7 @@
|
||||
fire_sound = 'sound/weapons/magpistol.ogg'
|
||||
slot_flags = SLOT_BELT
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
origin_tech = "combat=1;magnets=1"
|
||||
|
||||
/obj/item/ammo_box/foambox/mag
|
||||
name = "ammo box (Magnetic Foam Darts)"
|
||||
@@ -378,19 +386,23 @@
|
||||
/obj/item/projectile/bullet/magrifle
|
||||
icon = 'icons/obj/guns/cit_guns.dmi'
|
||||
icon_state = "magjectile-large"
|
||||
damage = 25
|
||||
damage = 20
|
||||
armour_penetration = 25
|
||||
light_range = 3
|
||||
speed = 1.2
|
||||
range = 35
|
||||
light_color = LIGHT_COLOR_RED
|
||||
|
||||
/obj/item/projectile/bullet/nlmagrifle //non-lethal boolets
|
||||
icon = 'icons/obj/guns/cit_guns.dmi'
|
||||
icon_state = "magjectile-large-nl"
|
||||
damage = 2
|
||||
damage = 1
|
||||
knockdown = 0
|
||||
stamina = 30
|
||||
stamina = 35
|
||||
armour_penetration = -10
|
||||
light_range = 3
|
||||
speed = 1.0
|
||||
range = 35
|
||||
light_color = LIGHT_COLOR_BLUE
|
||||
|
||||
///ammo casings///
|
||||
@@ -451,6 +463,7 @@
|
||||
|
||||
/obj/item/gun/ballistic/automatic/magrifle/nopin
|
||||
pin = null
|
||||
spawnwithmagazine = FALSE
|
||||
|
||||
/datum/design/magrifle
|
||||
name = "Magrifle"
|
||||
@@ -489,15 +502,16 @@
|
||||
max_ammo = 15
|
||||
multiple_sprites = 2
|
||||
ammo_type = /obj/item/ammo_casing/caseless/foam_dart/mag
|
||||
materials = list(MAT_METAL = 200)
|
||||
|
||||
/obj/item/gun/ballistic/automatic/magrifle/toy
|
||||
name = "foamag rifle"
|
||||
desc = "A foam launching magnetic rifle. Ages 8 and up."
|
||||
icon_state = "foamagrifle"
|
||||
needs_permit = 0
|
||||
needs_permit = FALSE
|
||||
mag_type = /obj/item/ammo_box/magazine/toy/foamag
|
||||
casing_ejector = FALSE
|
||||
origin_tech = "combat=2;engineering=2;magnets=2"
|
||||
origin_tech = "combat=1;engineering=1;magnets=1"
|
||||
spread = 60
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
weapon_weight = WEAPON_HEAVY
|
||||
@@ -631,6 +645,7 @@
|
||||
charge_delay = 2
|
||||
recoil = 2
|
||||
cell_type = /obj/item/stock_parts/cell/toymagburst
|
||||
origin_tech = "combat=1;magnets=1"
|
||||
|
||||
/obj/item/stock_parts/cell/toymagburst
|
||||
name = "toy mag burst rifle power supply"
|
||||
@@ -687,6 +702,7 @@
|
||||
fire_delay = 0
|
||||
spread = 60
|
||||
actions_types = list()
|
||||
origin_tech = "combat=1;magnets=1"
|
||||
|
||||
/obj/item/gun/ballistic/automatic/toy/pistol/stealth/update_icon()
|
||||
..()
|
||||
@@ -913,6 +929,7 @@ obj/item/projectile/bullet/c10mm/soporific
|
||||
desc = "A toy laser with a classic, retro feel and look. Compatible with existing laser tag systems."
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/laser/raytag)
|
||||
selfcharge = TRUE
|
||||
origin_tech = "combat=1;magnets=1"
|
||||
|
||||
/datum/design/toyray
|
||||
name = "RayTag Gun"
|
||||
@@ -1060,6 +1077,7 @@ obj/item/projectile/bullet/c10mm/soporific
|
||||
if(arm_color_input)
|
||||
arm_color = sanitize_hexcolor(arm_color_input, desired_format=6, include_crunch=1)
|
||||
update_icon()
|
||||
A.UpdateButtonIcon()
|
||||
|
||||
else
|
||||
..()
|
||||
@@ -1070,12 +1088,16 @@ obj/item/projectile/bullet/c10mm/soporific
|
||||
name = "9mm frangible bullet"
|
||||
damage = 15
|
||||
stamina = 0
|
||||
speed = 1.0
|
||||
range = 20
|
||||
armour_penetration = -25
|
||||
|
||||
/obj/item/projectile/bullet/c9mm/rubber
|
||||
name = "9mm rubber bullet"
|
||||
damage = 2
|
||||
stamina = 25
|
||||
damage = 5
|
||||
stamina = 30
|
||||
speed = 1.2
|
||||
range = 14
|
||||
knockdown = 0
|
||||
|
||||
/obj/item/ammo_casing/c9mm/frangible
|
||||
@@ -1120,9 +1142,9 @@ obj/item/projectile/bullet/c10mm/soporific
|
||||
name = "Box of 9mm Frangible Bullets"
|
||||
id = "9mm_frag"
|
||||
build_type = AUTOLATHE
|
||||
materials = list(MAT_METAL = 30000)
|
||||
materials = list(MAT_METAL = 25000)
|
||||
build_path = /obj/item/ammo_box/c9mm/frangible
|
||||
category = list("initial", "Security")
|
||||
category = list("hacked", "Security")
|
||||
|
||||
/datum/design/c9mmrubber
|
||||
name = "Box of 9mm Rubber Bullets"
|
||||
@@ -1157,10 +1179,13 @@ obj/item/projectile/bullet/c10mm/soporific
|
||||
name = "\improper Foam Force Mk.37F"
|
||||
desc = "A licensed foam-firing reproduction of a handgun with a toggle-locking mechanism manufactured by CX Armories. This model is coated with a special polychromic material. Uses standard foam pistol magazines."
|
||||
icon_state = "p37_foam"
|
||||
pin = /obj/item/device/firing_pin
|
||||
spawnwithmagazine = TRUE
|
||||
needs_permit = FALSE
|
||||
mag_type = /obj/item/ammo_box/magazine/toy/pistol
|
||||
can_suppress = FALSE
|
||||
actions_types = list(/datum/action/item_action/pick_color)
|
||||
origin_tech = "combat=1;magnets=1"
|
||||
|
||||
/datum/design/foam_p37
|
||||
name = "Foam Force Mk.37F"
|
||||
@@ -1196,6 +1221,10 @@ obj/item/gun/energy/e_gun/cx/update_icon()
|
||||
body_overlay.color = body_color
|
||||
add_overlay(body_overlay)
|
||||
|
||||
if(ismob(loc))
|
||||
var/mob/M = loc
|
||||
M.update_inv_hands()
|
||||
|
||||
obj/item/gun/energy/e_gun/cx/ui_action_click(mob/user, var/datum/action/A)
|
||||
if(istype(A, /datum/action/item_action/pick_color))
|
||||
if(alert("Are you sure you want to repaint your gun?", "Confirm Repaint", "Yes", "No") == "Yes")
|
||||
@@ -1203,6 +1232,7 @@ obj/item/gun/energy/e_gun/cx/ui_action_click(mob/user, var/datum/action/A)
|
||||
if(body_color_input)
|
||||
body_color = sanitize_hexcolor(body_color_input, desired_format=6, include_crunch=1)
|
||||
update_icon()
|
||||
A.UpdateButtonIcon()
|
||||
else
|
||||
..()
|
||||
|
||||
@@ -1211,4 +1241,8 @@ obj/item/gun/energy/e_gun/cx/worn_overlays(isinhands, icon_file)
|
||||
if(isinhands)
|
||||
var/mutable_appearance/body_inhand = mutable_appearance(icon_file, "cxe_body")
|
||||
body_inhand.color = body_color
|
||||
. += body_inhand
|
||||
. += body_inhand
|
||||
|
||||
/obj/item/ammo_box/magazine/toy/pistol //forcing this might be a bad idea, but it'll fix the foam gun infinite material exploit
|
||||
..()
|
||||
materials = list(MAT_METAL = 200)
|
||||
@@ -32,6 +32,10 @@
|
||||
set_light(0)
|
||||
update_icon()
|
||||
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
A.UpdateButtonIcon()
|
||||
|
||||
add_fingerprint(user)
|
||||
|
||||
/obj/item/toy/sword/cx/update_icon()
|
||||
@@ -49,6 +53,10 @@
|
||||
if(active)
|
||||
add_overlay(blade_overlay)
|
||||
|
||||
if(ismob(loc))
|
||||
var/mob/M = loc
|
||||
M.update_inv_hands()
|
||||
|
||||
/obj/item/toy/sword/cx/ui_action_click(mob/user, var/datum/action/A)
|
||||
if(istype(A, /datum/action/item_action/pick_color))
|
||||
if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes")
|
||||
@@ -56,10 +64,8 @@
|
||||
if(energy_color_input)
|
||||
light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
|
||||
update_icon()
|
||||
if(ismob(loc))
|
||||
var/mob/M = loc
|
||||
M.update_inv_hands()
|
||||
update_light()
|
||||
A.UpdateButtonIcon()
|
||||
|
||||
else
|
||||
..()
|
||||
@@ -72,6 +78,9 @@
|
||||
blade_inhand.color = light_color
|
||||
. += blade_inhand
|
||||
|
||||
/obj/item/toy/sword/cx/attackby(obj/item/W, mob/living/user, params)
|
||||
return //NO MORE MAKING DUAL ESWORDS
|
||||
|
||||
/*///autolathe memes/// I really need to stop doing this and find a proper way of adding in my toys
|
||||
|
||||
/datum/design/toyneb
|
||||
@@ -143,6 +152,9 @@
|
||||
update_icon()
|
||||
transform_messages(user, supress_message_text)
|
||||
add_fingerprint(user)
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
A.UpdateButtonIcon()
|
||||
return TRUE
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/cx/transform_messages(mob/living/user, supress_message_text)
|
||||
@@ -165,6 +177,10 @@
|
||||
if(active)
|
||||
add_overlay(blade_overlay)
|
||||
|
||||
if(ismob(loc))
|
||||
var/mob/M = loc
|
||||
M.update_inv_hands()
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/cx/ui_action_click(mob/user, var/datum/action/A)
|
||||
if(istype(A, /datum/action/item_action/pick_color))
|
||||
if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes")
|
||||
@@ -172,10 +188,8 @@
|
||||
if(energy_color_input)
|
||||
light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
|
||||
update_icon()
|
||||
if(ismob(loc))
|
||||
var/mob/M = loc
|
||||
M.update_inv_hands()
|
||||
update_light()
|
||||
A.UpdateButtonIcon()
|
||||
|
||||
else
|
||||
..()
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
/datum/objective/crew/cyborgs/check_completion()
|
||||
var/borgcount = target_amount
|
||||
for(var/mob/living/silicon/robot/R in GLOB.living_mob_list)
|
||||
for(var/mob/living/silicon/robot/R in GLOB.alive_mob_list)
|
||||
if(!(R.stat == DEAD))
|
||||
borgcount--
|
||||
if(borgcount <= 0)
|
||||
@@ -42,4 +42,4 @@
|
||||
if(S && S.files && S.files.known_designs)
|
||||
if(targetdesign in S.files.known_designs)
|
||||
return TRUE
|
||||
return FALSE
|
||||
return FALSE
|
||||
|
||||
@@ -51,6 +51,11 @@
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/config_entry/proc/VASProcCallGuard(str_val)
|
||||
. = !(IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "ValidateAndSet" && GLOB.LastAdminCalledTargetRef == "[REF(src)]")
|
||||
if(!.)
|
||||
log_admin_private("Config set of [type] to [str_val] attempted by [key_name(usr)]")
|
||||
|
||||
/datum/config_entry/proc/ValidateAndSet(str_val)
|
||||
CRASH("Invalid config entry type!")
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ GLOBAL_PROTECT(config_dir)
|
||||
stat("[name]:", statclick)
|
||||
|
||||
/datum/controller/configuration/proc/Get(entry_type)
|
||||
if(IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Get" && GLOB.LastAdminCalledTargetRef == "\ref[src]")
|
||||
if(IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Get" && GLOB.LastAdminCalledTargetRef == "[REF(src)]")
|
||||
log_admin_private("Config access of [entry_type] attempted by [key_name(usr)]")
|
||||
return
|
||||
var/datum/config_entry/E = entry_type
|
||||
@@ -137,7 +137,7 @@ GLOBAL_PROTECT(config_dir)
|
||||
return E.value
|
||||
|
||||
/datum/controller/configuration/proc/Set(entry_type, new_val)
|
||||
if(IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Set" && GLOB.LastAdminCalledTargetRef == "\ref[src]")
|
||||
if(IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Set" && GLOB.LastAdminCalledTargetRef == "[REF(src)]")
|
||||
log_admin_private("Config rewrite of [entry_type] to [new_val] attempted by [key_name(usr)]")
|
||||
return
|
||||
var/datum/config_entry/E = entry_type
|
||||
|
||||
@@ -318,6 +318,8 @@ CONFIG_DEF(number/client_warn_version)
|
||||
CONFIG_DEF(string/client_warn_message)
|
||||
value = "Your version of byond may have issues or be blocked from accessing this server in the future."
|
||||
|
||||
CONFIG_DEF(flag/client_warn_popup)
|
||||
|
||||
CONFIG_DEF(number/client_error_version)
|
||||
value = null
|
||||
min_val = 500
|
||||
@@ -372,3 +374,10 @@ CONFIG_TWEAK(number/mc_tick_rate/ValidateAndSet(str_val))
|
||||
. = ..()
|
||||
if (.)
|
||||
Master.UpdateTickRate()
|
||||
|
||||
CONFIG_DEF(flag/resume_after_initializations)
|
||||
|
||||
CONFIG_TWEAK(flag/ValidateAndSet(str_val))
|
||||
. = ..()
|
||||
if(. && Master.current_runlevel)
|
||||
world.sleep_offline = !value
|
||||
|
||||
@@ -163,9 +163,20 @@ CONFIG_DEF(flag/ooc_during_round)
|
||||
CONFIG_DEF(flag/emojis)
|
||||
|
||||
CONFIG_DEF(number/run_delay) //Used for modifying movement speed for mobs.
|
||||
var/static/value_cache = 0
|
||||
|
||||
CONFIG_TWEAK(number/run_delay/ValidateAndSet())
|
||||
. = ..()
|
||||
if(.)
|
||||
value_cache = value
|
||||
|
||||
CONFIG_DEF(number/walk_delay)
|
||||
var/static/value_cache = 0
|
||||
|
||||
CONFIG_TWEAK(number/walk_delay/ValidateAndSet())
|
||||
. = ..()
|
||||
if(.)
|
||||
value_cache = value
|
||||
|
||||
CONFIG_DEF(number/human_delay) //Mob specific modifiers. NOTE: These will affect different mob types in different ways
|
||||
CONFIG_DEF(number/robot_delay)
|
||||
@@ -251,3 +262,5 @@ CONFIG_DEF(number/emergency_shuttle_autocall_threshold)
|
||||
min_val = 0
|
||||
max_val = 1
|
||||
integer = FALSE
|
||||
|
||||
CONFIG_DEF(flag/ic_printing)
|
||||
@@ -40,18 +40,18 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars)
|
||||
stat("Globals:", statclick.update("Edit"))
|
||||
|
||||
/datum/controller/global_vars/can_vv_get(var_name)
|
||||
if(var_name in gvars_datum_protected_varlist)
|
||||
if(gvars_datum_protected_varlist[var_name])
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/controller/global_vars/vv_edit_var(var_name, var_value)
|
||||
if((var_name in gvars_datum_protected_varlist))
|
||||
if(gvars_datum_protected_varlist[var_name])
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/controller/global_vars/Initialize()
|
||||
gvars_datum_init_order = list()
|
||||
gvars_datum_protected_varlist = list("gvars_datum_protected_varlist")
|
||||
gvars_datum_protected_varlist = list("gvars_datum_protected_varlist" = TRUE)
|
||||
var/list/global_procs = typesof(/datum/controller/global_vars/proc)
|
||||
var/expected_len = vars.len - gvars_datum_in_built_vars.len
|
||||
if(global_procs.len != expected_len)
|
||||
|
||||
@@ -189,10 +189,12 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
// Sort subsystems by display setting for easy access.
|
||||
sortTim(subsystems, /proc/cmp_subsystem_display)
|
||||
// Set world options.
|
||||
world.sleep_offline = 1
|
||||
world.sleep_offline = TRUE
|
||||
world.fps = CONFIG_GET(number/fps)
|
||||
var/initialized_tod = REALTIMEOFDAY
|
||||
sleep(1)
|
||||
if(CONFIG_GET(flag/resume_after_initializations))
|
||||
world.sleep_offline = FALSE
|
||||
initializations_finished_with_no_players_logged_in = initialized_tod < REALTIMEOFDAY - 10
|
||||
// Loop.
|
||||
Master.StartProcessing(0)
|
||||
|
||||
@@ -27,6 +27,7 @@ SUBSYSTEM_DEF(air)
|
||||
var/list/hotspots = list()
|
||||
var/list/networks = list()
|
||||
var/list/obj/machinery/atmos_machinery = list()
|
||||
var/list/pipe_init_dirs_cache = list()
|
||||
|
||||
|
||||
|
||||
@@ -376,6 +377,16 @@ SUBSYSTEM_DEF(air)
|
||||
AM.build_network()
|
||||
CHECK_TICK
|
||||
|
||||
/datum/controller/subsystem/air/proc/get_init_dirs(type, dir)
|
||||
if(!pipe_init_dirs_cache[type])
|
||||
pipe_init_dirs_cache[type] = list()
|
||||
|
||||
if(!pipe_init_dirs_cache[type]["[dir]"])
|
||||
var/obj/machinery/atmospherics/temp = new type(null, FALSE, dir)
|
||||
pipe_init_dirs_cache[type]["[dir]"] = temp.GetInitDirections()
|
||||
qdel(temp)
|
||||
|
||||
return pipe_init_dirs_cache[type]["[dir]"]
|
||||
|
||||
#undef SSAIR_PIPENETS
|
||||
#undef SSAIR_ATMOSMACHINERY
|
||||
|
||||
@@ -28,5 +28,19 @@ SUBSYSTEM_DEF(communications)
|
||||
log_talk(user,"[key_name(user)] has made a priority announcement: [input]",LOGSAY)
|
||||
message_admins("[key_name_admin(user)] has made a priority announcement.")
|
||||
|
||||
/datum/controller/subsystem/communications/proc/send_message(datum/comm_message/sending,print = TRUE,unique = FALSE)
|
||||
for(var/obj/machinery/computer/communications/C in GLOB.machines)
|
||||
if(!(C.stat & (BROKEN|NOPOWER)) && (C.z in GLOB.station_z_levels))
|
||||
if(unique)
|
||||
C.add_message(sending)
|
||||
else //We copy the message for each console, answers and deletions won't be shared
|
||||
var/datum/comm_message/M = new(sending.title,sending.content,sending.possible_answers.Copy())
|
||||
C.add_message(M)
|
||||
if(print)
|
||||
var/obj/item/paper/P = new /obj/item/paper(C.loc)
|
||||
P.name = "paper - '[sending.title]'"
|
||||
P.info = sending.content
|
||||
P.update_icon()
|
||||
|
||||
#undef COMMUNICATION_COOLDOWN
|
||||
#undef COMMUNICATION_COOLDOWN_AI
|
||||
|
||||
@@ -186,7 +186,7 @@ Delayed insert mode was removed in mysql 7 and only works with MyISAM type table
|
||||
/datum/DBQuery/proc/warn_execute()
|
||||
. = Execute()
|
||||
if(!.)
|
||||
to_chat(usr, "<span class='danger'>A SQL error occured during this operation, check the server logs.</span>")
|
||||
to_chat(usr, "<span class='danger'>A SQL error occurred during this operation, check the server logs.</span>")
|
||||
|
||||
/datum/DBQuery/proc/Execute(sql_query = sql, cursor_handler = default_cursor, log_error = TRUE)
|
||||
Close()
|
||||
|
||||
@@ -133,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];[HrefToken()];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)
|
||||
@@ -177,7 +177,7 @@ SUBSYSTEM_DEF(events)
|
||||
var/YY = text2num(time2text(world.timeofday, "YY")) // get the current year
|
||||
var/MM = text2num(time2text(world.timeofday, "MM")) // get the current month
|
||||
var/DD = text2num(time2text(world.timeofday, "DD")) // get the current day
|
||||
var/DDD = text2num(time2text(world.timeofday, "DDD")) // get the current weekday
|
||||
var/DDD = time2text(world.timeofday, "DDD") // get the current weekday
|
||||
var/W = weekdayofthemonth() // is this the first monday? second? etc.
|
||||
|
||||
for(var/H in subtypesof(/datum/holiday))
|
||||
|
||||
@@ -164,7 +164,7 @@ SUBSYSTEM_DEF(garbage)
|
||||
#endif
|
||||
var/type = D.type
|
||||
var/datum/qdel_item/I = items[type]
|
||||
testing("GC: -- \ref[D] | [type] was unable to be GC'd --")
|
||||
testing("GC: -- \ref[src] | [type] was unable to be GC'd --")
|
||||
I.failures++
|
||||
if (GC_QUEUE_HARDDELETE)
|
||||
HardDelete(D)
|
||||
@@ -263,7 +263,7 @@ SUBSYSTEM_DEF(garbage)
|
||||
|
||||
// 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.
|
||||
/proc/qdel(datum/D, force=FALSE)
|
||||
/proc/qdel(datum/D, force=FALSE, ...)
|
||||
if(!istype(D))
|
||||
del(D)
|
||||
return
|
||||
@@ -278,7 +278,7 @@ SUBSYSTEM_DEF(garbage)
|
||||
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.
|
||||
var/hint = D.Destroy(arglist(args.Copy(2))) // Let our friend know they're about to get fucked up.
|
||||
if(world.time != start_time)
|
||||
I.slept_destroy++
|
||||
else
|
||||
|
||||
@@ -575,7 +575,7 @@ SUBSYSTEM_DEF(job)
|
||||
///////////////////////////////////
|
||||
/datum/controller/subsystem/job/proc/get_living_heads()
|
||||
. = list()
|
||||
for(var/mob/living/carbon/human/player in GLOB.mob_list)
|
||||
for(var/mob/living/carbon/human/player in GLOB.alive_mob_list)
|
||||
if(player.stat != DEAD && player.mind && (player.mind.assigned_role in GLOB.command_positions))
|
||||
. |= player.mind
|
||||
|
||||
@@ -585,7 +585,8 @@ SUBSYSTEM_DEF(job)
|
||||
////////////////////////////
|
||||
/datum/controller/subsystem/job/proc/get_all_heads()
|
||||
. = list()
|
||||
for(var/mob/player in GLOB.mob_list)
|
||||
for(var/i in GLOB.mob_list)
|
||||
var/mob/player = i
|
||||
if(player.mind && (player.mind.assigned_role in GLOB.command_positions))
|
||||
. |= player.mind
|
||||
|
||||
@@ -594,7 +595,7 @@ SUBSYSTEM_DEF(job)
|
||||
//////////////////////////////////////////////
|
||||
/datum/controller/subsystem/job/proc/get_living_sec()
|
||||
. = list()
|
||||
for(var/mob/living/carbon/human/player in GLOB.mob_list)
|
||||
for(var/mob/living/carbon/human/player in GLOB.carbon_list)
|
||||
if(player.stat != DEAD && player.mind && (player.mind.assigned_role in GLOB.security_positions))
|
||||
. |= player.mind
|
||||
|
||||
@@ -603,6 +604,6 @@ SUBSYSTEM_DEF(job)
|
||||
////////////////////////////////////////
|
||||
/datum/controller/subsystem/job/proc/get_all_sec()
|
||||
. = list()
|
||||
for(var/mob/living/carbon/human/player in GLOB.mob_list)
|
||||
for(var/mob/living/carbon/human/player in GLOB.carbon_list)
|
||||
if(player.mind && (player.mind.assigned_role in GLOB.security_positions))
|
||||
. |= player.mind
|
||||
. |= player.mind
|
||||
|
||||
@@ -18,6 +18,8 @@ SUBSYSTEM_DEF(mapping)
|
||||
var/list/shuttle_templates = list()
|
||||
var/list/shelter_templates = list()
|
||||
|
||||
var/list/areas_in_z = list()
|
||||
|
||||
var/loading_ruins = FALSE
|
||||
|
||||
/datum/controller/subsystem/mapping/PreInit()
|
||||
@@ -124,7 +126,7 @@ SUBSYSTEM_DEF(mapping)
|
||||
query_round_map_name.Execute()
|
||||
|
||||
if(config.minetype != "lavaland")
|
||||
INIT_ANNOUNCE("WARNING: A map without lavaland set as it's minetype was loaded! This is being ignored! Update the maploader code!")
|
||||
INIT_ANNOUNCE("WARNING: A map without lavaland set as its minetype was loaded! This is being ignored! Update the maploader code!")
|
||||
|
||||
CreateSpace(ZLEVEL_SPACEMAX)
|
||||
|
||||
|
||||
@@ -7,13 +7,15 @@ SUBSYSTEM_DEF(mobs)
|
||||
var/list/currentrun = list()
|
||||
|
||||
/datum/controller/subsystem/mobs/stat_entry()
|
||||
..("P:[GLOB.mob_list.len]")
|
||||
..("P:[GLOB.mob_living_list.len]")
|
||||
|
||||
|
||||
/datum/controller/subsystem/mobs/fire(resumed = 0)
|
||||
var/seconds = wait * 0.1
|
||||
if (!resumed)
|
||||
src.currentrun = GLOB.mob_list.Copy()
|
||||
src.currentrun = GLOB.mob_living_list.Copy()
|
||||
if (GLOB.overminds.len) // blob cameras need to Life()
|
||||
src.currentrun += GLOB.overminds
|
||||
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
@@ -24,6 +26,6 @@ SUBSYSTEM_DEF(mobs)
|
||||
if(M)
|
||||
M.Life(seconds, times_fired)
|
||||
else
|
||||
GLOB.mob_list.Remove(M)
|
||||
GLOB.mob_living_list.Remove(M)
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
+44
-39
@@ -1,4 +1,4 @@
|
||||
PROCESSING_SUBSYSTEM_DEF(overlays)
|
||||
SUBSYSTEM_DEF(overlays)
|
||||
name = "Overlay"
|
||||
flags = SS_TICKER
|
||||
wait = 1
|
||||
@@ -6,62 +6,63 @@ PROCESSING_SUBSYSTEM_DEF(overlays)
|
||||
init_order = INIT_ORDER_OVERLAY
|
||||
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_SETUP
|
||||
|
||||
stat_tag = "Ov"
|
||||
currentrun = null
|
||||
var/list/queue
|
||||
var/list/stats
|
||||
var/list/overlay_icon_state_caches
|
||||
var/list/overlay_icon_cache
|
||||
var/initialized = FALSE
|
||||
|
||||
/datum/controller/subsystem/processing/overlays/PreInit()
|
||||
LAZYINITLIST(overlay_icon_state_caches)
|
||||
LAZYINITLIST(overlay_icon_cache)
|
||||
/datum/controller/subsystem/overlays/PreInit()
|
||||
overlay_icon_state_caches = list()
|
||||
overlay_icon_cache = list()
|
||||
queue = list()
|
||||
stats = list()
|
||||
|
||||
/datum/controller/subsystem/processing/overlays/Initialize()
|
||||
/datum/controller/subsystem/overlays/Initialize()
|
||||
initialized = TRUE
|
||||
Flush()
|
||||
fire(mc_check = FALSE)
|
||||
..()
|
||||
|
||||
/datum/controller/subsystem/processing/overlays/Recover()
|
||||
|
||||
/datum/controller/subsystem/overlays/stat_entry()
|
||||
..("Ov:[length(queue)]")
|
||||
|
||||
|
||||
/datum/controller/subsystem/overlays/Shutdown()
|
||||
text2file("[GLOB.log_directory]/overlay.log", render_stats(stats))
|
||||
|
||||
|
||||
/datum/controller/subsystem/overlays/Recover()
|
||||
overlay_icon_state_caches = SSoverlays.overlay_icon_state_caches
|
||||
overlay_icon_cache = SSoverlays.overlay_icon_cache
|
||||
processing = SSoverlays.processing
|
||||
queue = SSoverlays.queue
|
||||
|
||||
#define COMPILE_OVERLAYS(A)\
|
||||
var/list/oo = A.our_overlays;\
|
||||
var/list/po = A.priority_overlays;\
|
||||
if(LAZYLEN(po)){\
|
||||
if(LAZYLEN(oo)){\
|
||||
A.overlays = oo + po;\
|
||||
}\
|
||||
else{\
|
||||
A.overlays = po;\
|
||||
}\
|
||||
}\
|
||||
else if(LAZYLEN(oo)){\
|
||||
A.overlays = oo;\
|
||||
}\
|
||||
else{\
|
||||
A.overlays.Cut();\
|
||||
}\
|
||||
A.flags_1 &= ~OVERLAY_QUEUED_1
|
||||
|
||||
/datum/controller/subsystem/processing/overlays/fire(resumed = FALSE, mc_check = TRUE)
|
||||
var/list/processing = src.processing
|
||||
while(processing.len)
|
||||
var/atom/thing = processing[processing.len]
|
||||
processing.len--
|
||||
/datum/controller/subsystem/overlays/fire(resumed = FALSE, mc_check = TRUE)
|
||||
var/list/queue = src.queue
|
||||
var/static/count = 0
|
||||
if (count)
|
||||
var/c = count
|
||||
count = 0 //so if we runtime on the Cut, we don't try again.
|
||||
queue.Cut(1,c+1)
|
||||
|
||||
for (var/thing in queue)
|
||||
count++
|
||||
if(thing)
|
||||
COMPILE_OVERLAYS(thing)
|
||||
STAT_START_STOPWATCH
|
||||
var/atom/A = thing
|
||||
COMPILE_OVERLAYS(A)
|
||||
STAT_STOP_STOPWATCH
|
||||
STAT_LOG_ENTRY(stats, A.type)
|
||||
if(mc_check)
|
||||
if(MC_TICK_CHECK)
|
||||
break
|
||||
else
|
||||
CHECK_TICK
|
||||
|
||||
/datum/controller/subsystem/processing/overlays/proc/Flush()
|
||||
if(processing.len)
|
||||
testing("Flushing [processing.len] overlays")
|
||||
fire(mc_check = FALSE) //pair this thread up with the MC to get extra compile time
|
||||
if (count)
|
||||
queue.Cut(1,count+1)
|
||||
count = 0
|
||||
|
||||
/proc/iconstate2appearance(icon, iconstate)
|
||||
var/static/image/stringbro = new()
|
||||
@@ -102,6 +103,10 @@ PROCESSING_SUBSYSTEM_DEF(overlays)
|
||||
else if(isicon(overlay))
|
||||
new_overlays += icon2appearance(overlay)
|
||||
else
|
||||
if(isloc(overlay))
|
||||
var/atom/A = overlay
|
||||
if (A.flags_1 & OVERLAY_QUEUED_1)
|
||||
COMPILE_OVERLAYS(A)
|
||||
appearance_bro.appearance = overlay //this works for images and atoms too!
|
||||
if(!ispath(overlay))
|
||||
var/image/I = overlay
|
||||
@@ -110,7 +115,7 @@ PROCESSING_SUBSYSTEM_DEF(overlays)
|
||||
return new_overlays
|
||||
|
||||
#define NOT_QUEUED_ALREADY (!(flags_1 & OVERLAY_QUEUED_1))
|
||||
#define QUEUE_FOR_COMPILE flags_1 |= OVERLAY_QUEUED_1; SSoverlays.processing += src;
|
||||
#define QUEUE_FOR_COMPILE flags_1 |= OVERLAY_QUEUED_1; SSoverlays.queue += src;
|
||||
/atom/proc/cut_overlays(priority = FALSE)
|
||||
var/list/cached_overlays = our_overlays
|
||||
var/list/cached_priority = priority_overlays
|
||||
@@ -109,23 +109,23 @@ SUBSYSTEM_DEF(pai)
|
||||
dat += "<p class=\"top\">Please configure your pAI personality's options. Remember, what you enter here could determine whether or not the user requesting a personality chooses you!</p>"
|
||||
dat += "<table>"
|
||||
dat += "<tr class=\"d0\"><td>Name:</td><td>[candidate.name]</td></tr>"
|
||||
dat += "<tr class=\"d1\"><td><a href='byond://?src=\ref[src];option=name;new=1;candidate=\ref[candidate]'>\[Edit\]</a></td><td>What you plan to call yourself. Suggestions: Any character name you would choose for a station character OR an AI.</td></tr>"
|
||||
dat += "<tr class=\"d1\"><td><a href='byond://?src=[REF(src)];option=name;new=1;candidate=[REF(candidate)]'>\[Edit\]</a></td><td>What you plan to call yourself. Suggestions: Any character name you would choose for a station character OR an AI.</td></tr>"
|
||||
|
||||
dat += "<tr class=\"d0\"><td>Description:</td><td>[candidate.description]</td></tr>"
|
||||
dat += "<tr class=\"d1\"><td><a href='byond://?src=\ref[src];option=desc;new=1;candidate=\ref[candidate]'>\[Edit\]</a></td><td>What sort of pAI you typically play; your mannerisms, your quirks, etc. This can be as sparse or as detailed as you like.</td></tr>"
|
||||
dat += "<tr class=\"d1\"><td><a href='byond://?src=[REF(src)];option=desc;new=1;candidate=[REF(candidate)]'>\[Edit\]</a></td><td>What sort of pAI you typically play; your mannerisms, your quirks, etc. This can be as sparse or as detailed as you like.</td></tr>"
|
||||
|
||||
dat += "<tr class=\"d0\"><td>Preferred Role:</td><td>[candidate.role]</td></tr>"
|
||||
dat += "<tr class=\"d1\"><td><a href='byond://?src=\ref[src];option=role;new=1;candidate=\ref[candidate]'>\[Edit\]</a></td><td>Do you like to partner with sneaky social ninjas? Like to help security hunt down thugs? Enjoy watching an engineer's back while he saves the station yet again? This doesn't have to be limited to just station jobs. Pretty much any general descriptor for what you'd like to be doing works here.</td></tr>"
|
||||
dat += "<tr class=\"d1\"><td><a href='byond://?src=[REF(src)];option=role;new=1;candidate=[REF(candidate)]'>\[Edit\]</a></td><td>Do you like to partner with sneaky social ninjas? Like to help security hunt down thugs? Enjoy watching an engineer's back while he saves the station yet again? This doesn't have to be limited to just station jobs. Pretty much any general descriptor for what you'd like to be doing works here.</td></tr>"
|
||||
|
||||
dat += "<tr class=\"d0\"><td>OOC Comments:</td><td>[candidate.comments]</td></tr>"
|
||||
dat += "<tr class=\"d1\"><td><a href='byond://?src=\ref[src];option=ooc;new=1;candidate=\ref[candidate]'>\[Edit\]</a></td><td>Anything you'd like to address specifically to the player reading this in an OOC manner. \"I prefer more serious RP.\", \"I'm still learning the interface!\", etc. Feel free to leave this blank if you want.</td></tr>"
|
||||
dat += "<tr class=\"d1\"><td><a href='byond://?src=[REF(src)];option=ooc;new=1;candidate=[REF(candidate)]'>\[Edit\]</a></td><td>Anything you'd like to address specifically to the player reading this in an OOC manner. \"I prefer more serious RP.\", \"I'm still learning the interface!\", etc. Feel free to leave this blank if you want.</td></tr>"
|
||||
|
||||
dat += "</table>"
|
||||
|
||||
dat += "<br>"
|
||||
dat += "<h3><a href='byond://?src=\ref[src];option=submit;new=1;candidate=\ref[candidate]'>Submit Personality</a></h3><br>"
|
||||
dat += "<a href='byond://?src=\ref[src];option=save;new=1;candidate=\ref[candidate]'>Save Personality</a><br>"
|
||||
dat += "<a href='byond://?src=\ref[src];option=load;new=1;candidate=\ref[candidate]'>Load Personality</a><br>"
|
||||
dat += "<h3><a href='byond://?src=[REF(src)];option=submit;new=1;candidate=[REF(candidate)]'>Submit Personality</a></h3><br>"
|
||||
dat += "<a href='byond://?src=[REF(src)];option=save;new=1;candidate=[REF(candidate)]'>Save Personality</a><br>"
|
||||
dat += "<a href='byond://?src=[REF(src)];option=load;new=1;candidate=[REF(candidate)]'>Load Personality</a><br>"
|
||||
|
||||
M << browse(dat, "window=paiRecruit")
|
||||
|
||||
@@ -182,7 +182,7 @@ SUBSYSTEM_DEF(pai)
|
||||
dat += "<tr class=\"d1\"><td>Description:</td><td>[c.description]</td></tr>"
|
||||
dat += "<tr class=\"d0\"><td>Preferred Role:</td><td>[c.role]</td></tr>"
|
||||
dat += "<tr class=\"d1\"><td>OOC Comments:</td><td>[c.comments]</td></tr>"
|
||||
dat += "<tr class=\"d2\"><td><a href='byond://?src=\ref[src];download=1;candidate=\ref[c];device=\ref[p]'>\[Download [c.name]\]</a></td><td></td></tr>"
|
||||
dat += "<tr class=\"d2\"><td><a href='byond://?src=[REF(src)];download=1;candidate=[REF(c)];device=[REF(p)]'>\[Download [c.name]\]</a></td><td></td></tr>"
|
||||
|
||||
dat += "</table>"
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ SUBSYSTEM_DEF(persistence)
|
||||
break
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/LoadPoly()
|
||||
for(var/mob/living/simple_animal/parrot/Poly/P in GLOB.living_mob_list)
|
||||
for(var/mob/living/simple_animal/parrot/Poly/P in GLOB.alive_mob_list)
|
||||
twitterize(P.speech_buffer, "polytalk")
|
||||
break //Who's been duping the bird?!
|
||||
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
PROCESSING_SUBSYSTEM_DEF(circuit)
|
||||
name = "Circuit"
|
||||
stat_tag = "CIR"
|
||||
init_order = INIT_ORDER_CIRCUIT
|
||||
flags = NONE
|
||||
|
||||
var/cipherkey
|
||||
|
||||
var/list/all_exonet_connections = list() //Address = connection datum.
|
||||
var/list/obj/machinery/exonet_node/all_exonet_nodes = list()
|
||||
|
||||
var/list/all_circuits = list() // Associative list of [circuit_name]:[circuit_path] pairs
|
||||
var/list/circuit_fabricator_recipe_list = list() // Associative list of [category_name]:[list_of_circuit_paths] pairs
|
||||
|
||||
/datum/controller/subsystem/processing/circuit/Initialize(start_timeofday)
|
||||
SScircuit.cipherkey = random_string(2000+rand(0,10), GLOB.alphabet)
|
||||
circuits_init()
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/processing/circuit/proc/circuits_init()
|
||||
//Cached lists for free performance
|
||||
var/list/all_circuits = src.all_circuits
|
||||
var/list/circuit_fabricator_recipe_list = src.circuit_fabricator_recipe_list
|
||||
for(var/path in typesof(/obj/item/integrated_circuit))
|
||||
var/obj/item/integrated_circuit/IC = path
|
||||
var/name = initial(IC.name)
|
||||
all_circuits[name] = IC // Populating the complete list
|
||||
|
||||
if(!(initial(IC.spawn_flags) & (IC_SPAWN_DEFAULT | IC_SPAWN_RESEARCH)))
|
||||
continue
|
||||
|
||||
var/category = initial(IC.category_text)
|
||||
if(!circuit_fabricator_recipe_list[category])
|
||||
circuit_fabricator_recipe_list[category] = list()
|
||||
var/list/category_list = circuit_fabricator_recipe_list[category]
|
||||
category_list += IC // Populating the fabricator categories
|
||||
|
||||
circuit_fabricator_recipe_list["Assemblies"] = list(
|
||||
/obj/item/device/electronic_assembly,
|
||||
/obj/item/device/electronic_assembly/medium,
|
||||
/obj/item/device/electronic_assembly/large,
|
||||
/obj/item/device/electronic_assembly/drone
|
||||
//new /obj/item/weapon/implant/integrated_circuit,
|
||||
//new /obj/item/device/assembly/electronic_assembly
|
||||
)
|
||||
|
||||
circuit_fabricator_recipe_list["Tools"] = list(
|
||||
/obj/item/device/integrated_electronics/wirer,
|
||||
/obj/item/device/integrated_electronics/debugger,
|
||||
/obj/item/device/integrated_electronics/analyzer
|
||||
)
|
||||
|
||||
/datum/controller/subsystem/processing/circuit/proc/get_exonet_node()
|
||||
for(var/i in 1 to all_exonet_nodes.len)
|
||||
var/obj/machinery/exonet_node/E = all_exonet_nodes[i]
|
||||
if(E.is_operating())
|
||||
return E
|
||||
|
||||
/datum/controller/subsystem/processing/circuit/proc/get_exonet_address(addr)
|
||||
return all_exonet_connections[addr]
|
||||
|
||||
|
||||
// Proc: get_atom_from_address()
|
||||
// Parameters: 1 (target_address - the desired address to find)
|
||||
// Description: Searches an address for the atom it is attached for, otherwise returns null.
|
||||
|
||||
/datum/controller/subsystem/processing/circuit/proc/get_atom_from_address(var/target_address)
|
||||
var/datum/exonet_protocol/exonet = SScircuit.get_exonet_address(target_address)
|
||||
if(exonet)
|
||||
return exonet.holder
|
||||
@@ -4,38 +4,15 @@ PROCESSING_SUBSYSTEM_DEF(radiation)
|
||||
priority = 25
|
||||
|
||||
var/list/warned_atoms = list()
|
||||
var/list/next_warn = list()
|
||||
var/last_warn = 0
|
||||
|
||||
/datum/controller/subsystem/processing/radiation/proc/warn(datum/component/radioactive)
|
||||
if(!radioactive || QDELETED(radioactive))
|
||||
/datum/controller/subsystem/processing/radiation/proc/warn(datum/component/radioactive/contamination)
|
||||
if(!contamination || QDELETED(contamination))
|
||||
return
|
||||
if(warned_atoms["\ref[radioactive.parent]"])
|
||||
var/ref = REF(contamination.parent)
|
||||
if(warned_atoms[ref])
|
||||
return
|
||||
var/atom/master = radioactive.parent
|
||||
warned_atoms[ref] = TRUE
|
||||
var/atom/master = contamination.parent
|
||||
SSblackbox.add_details("contaminated", "[master.type]")
|
||||
next_warn["\ref[master]"] = "\ref[radioactive]"
|
||||
var/wait_time = max(0, 500-(world.time-last_warn))+20 // wait at least 20 ticks, longer if we just messaged
|
||||
addtimer(CALLBACK(src, .proc/send_warn), wait_time, TIMER_UNIQUE | TIMER_OVERRIDE)
|
||||
|
||||
/datum/controller/subsystem/processing/radiation/proc/send_warn()
|
||||
var/msg = "Atom(s) have become contaminated by radiation and are strong enough they could pass it on:"
|
||||
var/still_alive = FALSE
|
||||
var/list/next_warn = src.next_warn // It's free performance!
|
||||
for(var/i in next_warn)
|
||||
var/atom/parent = locate(i)
|
||||
var/datum/component/radioactive/radioactive = locate(next_warn[i])
|
||||
if(!parent || !istype(parent) || !radioactive || !istype(radioactive))
|
||||
continue
|
||||
if(!still_alive)
|
||||
msg += "\n"
|
||||
still_alive = TRUE
|
||||
else
|
||||
msg += ", "
|
||||
msg += "[parent][ADMIN_VV(parent)]source:[radioactive.source]"
|
||||
if(!still_alive)
|
||||
return
|
||||
warned_atoms += next_warn
|
||||
src.next_warn = list()
|
||||
last_warn = world.time
|
||||
message_admins(msg)
|
||||
var/msg = "has become contamintaed with enough radiation to contaminate other objects. || Source: [contamination.source] || Strength: [contamination.strength]"
|
||||
master.investigate_log(msg, INVESTIGATE_RADIATION)
|
||||
@@ -28,7 +28,9 @@ SUBSYSTEM_DEF(shuttle)
|
||||
var/emergencyCallAmount = 0 //how many times the escape shuttle was called
|
||||
var/emergencyNoEscape
|
||||
var/emergencyNoRecall = FALSE
|
||||
var/list/hostileEnvironments = list()
|
||||
var/list/hostileEnvironments = list() //Things blocking escape shuttle from leaving
|
||||
var/list/tradeBlockade = list() //Things blocking cargo from leaving.
|
||||
var/supplyBlocked = FALSE
|
||||
|
||||
//supply shuttle stuff
|
||||
var/obj/docking_port/mobile/supply/supply
|
||||
@@ -335,6 +337,30 @@ SUBSYSTEM_DEF(shuttle)
|
||||
hostileEnvironments -= bad
|
||||
checkHostileEnvironment()
|
||||
|
||||
|
||||
/datum/controller/subsystem/shuttle/proc/registerTradeBlockade(datum/bad)
|
||||
tradeBlockade[bad] = TRUE
|
||||
checkTradeBlockade()
|
||||
|
||||
/datum/controller/subsystem/shuttle/proc/clearTradeBlockade(datum/bad)
|
||||
tradeBlockade -= bad
|
||||
checkTradeBlockade()
|
||||
|
||||
|
||||
/datum/controller/subsystem/shuttle/proc/checkTradeBlockade()
|
||||
for(var/datum/d in tradeBlockade)
|
||||
if(!istype(d) || QDELETED(d))
|
||||
tradeBlockade -= d
|
||||
supplyBlocked = tradeBlockade.len
|
||||
|
||||
if(supplyBlocked && (supply.mode == SHUTTLE_IGNITING))
|
||||
supply.mode = SHUTTLE_STRANDED
|
||||
supply.timer = null
|
||||
//Make all cargo consoles speak up
|
||||
if(!supplyBlocked && (supply.mode == SHUTTLE_STRANDED))
|
||||
supply.mode = SHUTTLE_DOCKED
|
||||
//Make all cargo consoles speak up
|
||||
|
||||
/datum/controller/subsystem/shuttle/proc/checkHostileEnvironment()
|
||||
for(var/datum/d in hostileEnvironments)
|
||||
if(!istype(d) || QDELETED(d))
|
||||
|
||||
@@ -30,8 +30,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
var/list/availablefactions = list() //list of factions with openings
|
||||
var/list/scripture_states = list(SCRIPTURE_DRIVER = TRUE, \
|
||||
SCRIPTURE_SCRIPT = FALSE, \
|
||||
SCRIPTURE_APPLICATION = FALSE, \
|
||||
SCRIPTURE_JUDGEMENT = FALSE) //list of clockcult scripture states for announcements
|
||||
SCRIPTURE_APPLICATION = FALSE) //list of clockcult scripture states for announcements
|
||||
|
||||
var/delay_end = 0 //if set true, the round will not restart on it's own
|
||||
|
||||
@@ -194,6 +193,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
if(!setup())
|
||||
//setup failed
|
||||
current_state = GAME_STATE_STARTUP
|
||||
start_at = world.time + (CONFIG_GET(number/lobby_countdown) * 10)
|
||||
Master.SetRunLevel(RUNLEVEL_LOBBY)
|
||||
|
||||
if(GAME_STATE_PLAYING)
|
||||
@@ -282,8 +282,6 @@ SUBSYSTEM_DEF(ticker)
|
||||
collect_minds()
|
||||
equip_characters()
|
||||
|
||||
SSoverlays.Flush() //Flush the majority of the shit
|
||||
|
||||
GLOB.data_core.manifest()
|
||||
|
||||
transfer_characters() //transfer keys to the new mobs
|
||||
@@ -316,7 +314,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
set waitfor = FALSE
|
||||
mode.post_setup()
|
||||
GLOB.start_state = new /datum/station_state()
|
||||
GLOB.start_state.count(1)
|
||||
GLOB.start_state.count()
|
||||
//Cleanup some stuff
|
||||
for(var/obj/effect/landmark/start/S in GLOB.landmarks_list)
|
||||
//Deleting Startpoints but we need the ai point to AI-ize people later
|
||||
@@ -419,7 +417,8 @@ SUBSYSTEM_DEF(ticker)
|
||||
C.playtitlemusic(40)*/
|
||||
|
||||
//Player status report
|
||||
for(var/mob/Player in GLOB.mob_list)
|
||||
for(var/i in GLOB.mob_list)
|
||||
var/mob/Player = i
|
||||
if(Player.mind && !isnewplayer(Player))
|
||||
if(Player.stat != DEAD && !isbrain(Player))
|
||||
num_survivors++
|
||||
@@ -465,7 +464,8 @@ SUBSYSTEM_DEF(ticker)
|
||||
CHECK_TICK
|
||||
|
||||
//Silicon laws report
|
||||
for (var/mob/living/silicon/ai/aiPlayer in GLOB.mob_list)
|
||||
for (var/i in GLOB.ai_list)
|
||||
var/mob/living/silicon/ai/aiPlayer = i
|
||||
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)
|
||||
@@ -484,7 +484,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
|
||||
CHECK_TICK
|
||||
|
||||
for (var/mob/living/silicon/robot/robo in GLOB.mob_list)
|
||||
for (var/mob/living/silicon/robot/robo in GLOB.silicon_mobs)
|
||||
if (!robo.connected_ai && robo.mind)
|
||||
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>")
|
||||
@@ -615,7 +615,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
if(5) //every 5 ticks check if there is a slot available
|
||||
if(living_player_count() < hpc)
|
||||
if(next_in_line && next_in_line.client)
|
||||
to_chat(next_in_line, "<span class='userdanger'>A slot has opened! You have approximately 20 seconds to join. <a href='?src=\ref[next_in_line];late_join=override'>\>\>Join Game\<\<</a></span>")
|
||||
to_chat(next_in_line, "<span class='userdanger'>A slot has opened! You have approximately 20 seconds to join. <a href='?src=[REF(next_in_line)];late_join=override'>\>\>Join Game\<\<</a></span>")
|
||||
SEND_SOUND(next_in_line, sound('sound/misc/notice1.ogg'))
|
||||
next_in_line.LateChoices()
|
||||
return
|
||||
|
||||
@@ -243,7 +243,7 @@ SUBSYSTEM_DEF(timer)
|
||||
while(SStimer.timer_id_dict["timerid" + num2text(id, 8)])
|
||||
SStimer.timer_id_dict["timerid" + num2text(id, 8)] = src
|
||||
|
||||
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(", ") : ""])"
|
||||
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?")
|
||||
@@ -259,11 +259,11 @@ SUBSYSTEM_DEF(timer)
|
||||
var/datum/timedevent/Last = ctts[cttl]
|
||||
if(Last.timeToRun >= timeToRun)
|
||||
ctts += src
|
||||
else if(cttl > 1)
|
||||
for(var/I in cttl to 1)
|
||||
var/datum/timedevent/E = ctts[I]
|
||||
else
|
||||
for(var/i in cttl to 1 step -1)
|
||||
var/datum/timedevent/E = ctts[i]
|
||||
if(E.timeToRun <= timeToRun)
|
||||
ctts.Insert(src, I)
|
||||
ctts.Insert(i, src)
|
||||
break
|
||||
else
|
||||
ctts += src
|
||||
@@ -362,9 +362,9 @@ SUBSYSTEM_DEF(timer)
|
||||
if (flags & TIMER_UNIQUE)
|
||||
var/list/hashlist
|
||||
if(flags & TIMER_NO_HASH_WAIT)
|
||||
hashlist = list(callback.object, "(\ref[callback.object])", callback.delegate, flags & TIMER_CLIENT_TIME)
|
||||
hashlist = list(callback.object, "([REF(callback.object)])", callback.delegate, flags & TIMER_CLIENT_TIME)
|
||||
else
|
||||
hashlist = list(callback.object, "(\ref[callback.object])", callback.delegate, wait, flags & TIMER_CLIENT_TIME)
|
||||
hashlist = list(callback.object, "([REF(callback.object)])", callback.delegate, wait, flags & TIMER_CLIENT_TIME)
|
||||
hashlist += callback.arguments
|
||||
hash = hashlist.Join("|||||||")
|
||||
|
||||
|
||||
@@ -199,7 +199,7 @@ SUBSYSTEM_DEF(vote)
|
||||
text += "\n[question]"
|
||||
log_vote(text)
|
||||
var/vp = CONFIG_GET(number/vote_period)
|
||||
to_chat(world, "\n<font color='purple'><b>[text]</b>\nType <b>vote</b> or click <a href='?src=\ref[src]'>here</a> to place your votes.\nYou have [DisplayTimeText(vp)] to vote.</font>")
|
||||
to_chat(world, "\n<font color='purple'><b>[text]</b>\nType <b>vote</b> or click <a href='?src=[REF(src)]'>here</a> to place your votes.\nYou have [DisplayTimeText(vp)] to vote.</font>")
|
||||
time_remaining = round(vp/10)
|
||||
for(var/c in GLOB.clients)
|
||||
var/client/C = c
|
||||
@@ -232,36 +232,36 @@ SUBSYSTEM_DEF(vote)
|
||||
var/votes = choices[choices[i]]
|
||||
if(!votes)
|
||||
votes = 0
|
||||
. += "<li><a href='?src=\ref[src];vote=[i]'>[choices[i]]</a> ([votes] votes)</li>"
|
||||
. += "<li><a href='?src=[REF(src)];vote=[i]'>[choices[i]]</a> ([votes] votes)</li>"
|
||||
. += "</ul><hr>"
|
||||
if(admin)
|
||||
. += "(<a href='?src=\ref[src];vote=cancel'>Cancel Vote</a>) "
|
||||
. += "(<a href='?src=[REF(src)];vote=cancel'>Cancel Vote</a>) "
|
||||
else
|
||||
. += "<h2>Start a vote:</h2><hr><ul><li>"
|
||||
//restart
|
||||
var/avr = CONFIG_GET(flag/allow_vote_restart)
|
||||
if(trialmin || avr)
|
||||
. += "<a href='?src=\ref[src];vote=restart'>Restart</a>"
|
||||
. += "<a href='?src=[REF(src)];vote=restart'>Restart</a>"
|
||||
else
|
||||
. += "<font color='grey'>Restart (Disallowed)</font>"
|
||||
if(trialmin)
|
||||
. += "\t(<a href='?src=\ref[src];vote=toggle_restart'>[avr ? "Allowed" : "Disallowed"]</a>)"
|
||||
. += "\t(<a href='?src=[REF(src)];vote=toggle_restart'>[avr ? "Allowed" : "Disallowed"]</a>)"
|
||||
. += "</li><li>"
|
||||
//gamemode
|
||||
var/avm = CONFIG_GET(flag/allow_vote_mode)
|
||||
if(trialmin || avm)
|
||||
. += "<a href='?src=\ref[src];vote=gamemode'>GameMode</a>"
|
||||
. += "<a href='?src=[REF(src)];vote=gamemode'>GameMode</a>"
|
||||
else
|
||||
. += "<font color='grey'>GameMode (Disallowed)</font>"
|
||||
if(trialmin)
|
||||
. += "\t(<a href='?src=\ref[src];vote=toggle_gamemode'>[avm ? "Allowed" : "Disallowed"]</a>)"
|
||||
. += "\t(<a href='?src=[REF(src)];vote=toggle_gamemode'>[avm ? "Allowed" : "Disallowed"]</a>)"
|
||||
|
||||
. += "</li>"
|
||||
//custom
|
||||
if(trialmin)
|
||||
. += "<li><a href='?src=\ref[src];vote=custom'>Custom</a></li>"
|
||||
. += "<li><a href='?src=[REF(src)];vote=custom'>Custom</a></li>"
|
||||
. += "</ul><hr>"
|
||||
. += "<a href='?src=\ref[src];vote=close' style='position:absolute;right:50px'>Close</a>"
|
||||
. += "<a href='?src=[REF(src)];vote=close' style='position:absolute;right:50px'>Close</a>"
|
||||
return .
|
||||
|
||||
|
||||
|
||||
@@ -13,7 +13,8 @@ SUBSYSTEM_DEF(weather)
|
||||
var/datum/weather/W = V
|
||||
if(W.aesthetic)
|
||||
continue
|
||||
for(var/mob/living/L in GLOB.mob_list)
|
||||
for(var/i in GLOB.mob_living_list)
|
||||
var/mob/living/L = i
|
||||
if(W.can_weather_act(L))
|
||||
W.weather_act(L)
|
||||
for(var/Z in eligible_zlevels)
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
Exonet Protocol Version 2
|
||||
|
||||
This is designed to be a fairly simple fake-networking system, allowing you to send and receive messages
|
||||
between the exonet_protocol datums, and for atoms to react to those messages, based on the contents of the message.
|
||||
Hopefully, this can evolve to be a more robust fake-networking system and allow for some devious network hacking in the future.
|
||||
|
||||
Version 1 never existed.
|
||||
|
||||
*Setting up*
|
||||
|
||||
To set up the exonet link, define a variable on your desired atom it is like this;
|
||||
var/datum/exonet_protocol/exonet = null
|
||||
Afterwards, before you want to do networking, call exonet = New(src), then exonet.make_address(string), and give it a string to hash into the new IP.
|
||||
The reason it needs a string is so you can have the addresses be persistant, assuming no-one already took it first.
|
||||
|
||||
When you're no longer wanting to use the address and want to free it up, like when you want to Destroy() it, you need to call remove_address()
|
||||
Destroy() also automatically calls remove_address().
|
||||
|
||||
*Sending messages*
|
||||
|
||||
To send a message to another datum, you need to know it's EPv2 (fake IP) address. Once you know that, call send_message(), place your
|
||||
intended address in the first argument, then the message in the second. For example, send_message(exonet.address, "ping") will make you
|
||||
ping yourself.
|
||||
|
||||
*Receiving messages*
|
||||
You don't need to do anything special to receive the messages, other than give your target exonet datum an address as well. Once something hits
|
||||
your datum with send_message(), receive_message() is called, and the default action is to call receive_exonet_message() on the datum's holder.
|
||||
You'll want to override receive_exonet_message() on your atom, and define what will occur when the message is received.
|
||||
The receiving atom will receive the origin atom (the atom that sent the message), the origin address, and finally the message itself.
|
||||
It's suggested to start with an if or switch statement for the message, to determine what to do.
|
||||
*/
|
||||
|
||||
/datum/exonet_protocol
|
||||
var/address = "" //Resembles IPv6, but with only five 'groups', e.g. XXXX:XXXX:XXXX:XXXX:XXXX
|
||||
var/atom/holder
|
||||
|
||||
/datum/exonet_protocol/New(var/atom/H)
|
||||
holder = H
|
||||
|
||||
/datum/exonet_protocol/Destroy()
|
||||
remove_address()
|
||||
holder = null
|
||||
return ..()
|
||||
|
||||
// Proc: make_address()
|
||||
// Parameters: 1 (string - used to make into a hash that will be part of the new address)
|
||||
// Description: Allocates a new address based on the string supplied. It results in consistant addresses for each round assuming it is not already taken..
|
||||
/datum/exonet_protocol/proc/make_address(var/string)
|
||||
if(!string)
|
||||
return
|
||||
var/hex = copytext(md5(string),1,25)
|
||||
if(!hex)
|
||||
return
|
||||
var/addr_1 = copytext(hex,1,5)
|
||||
var/addr_2 = copytext(hex,5,9)
|
||||
var/addr_3 = copytext(hex,9,13)
|
||||
var/addr_4 = copytext(hex,13,17)
|
||||
address = "fc00:[addr_1]:[addr_2]:[addr_3]:[addr_4]"
|
||||
if(SScircuit.all_exonet_connections[address])
|
||||
stack_trace("WARNING: Exonet address collision in make_address. Holder type if applicable is [holder? holder.type : "NO HOLDER"]!")
|
||||
SScircuit.all_exonet_connections[address] = src
|
||||
|
||||
|
||||
// Proc: make_arbitrary_address()
|
||||
// Parameters: 1 (new_address - the desired address)
|
||||
// Description: Allocates that specific address, if it is available.
|
||||
/datum/exonet_protocol/proc/make_arbitrary_address(var/new_address)
|
||||
if(new_address)
|
||||
if(new_address == SScircuit.get_exonet_address(new_address) ) //Collision test.
|
||||
return FALSE
|
||||
address = new_address
|
||||
SScircuit.all_exonet_connections[address] = src
|
||||
return TRUE
|
||||
|
||||
|
||||
// Proc: remove_address()
|
||||
// Parameters: None
|
||||
// Description: Deallocates the address, freeing it for use.
|
||||
/datum/exonet_protocol/proc/remove_address()
|
||||
SScircuit.all_exonet_connections -= address
|
||||
address = ""
|
||||
|
||||
|
||||
|
||||
// Proc: send_message()
|
||||
// Parameters: 3 (target_address - the desired address to send the message to, data_type - text stating what the content is meant to be used for,
|
||||
// content - the actual 'message' being sent to the address)
|
||||
// Description: Sends the message to target_address, by calling receive_message() on the desired datum. Returns true if the message is recieved.
|
||||
/datum/exonet_protocol/proc/send_message(var/target_address, var/data_type, var/content)
|
||||
if(!address)
|
||||
return FALSE
|
||||
var/obj/machinery/exonet_node/node = SScircuit.get_exonet_node()
|
||||
if(!node) // Telecomms went boom, ion storm, etc.
|
||||
return FALSE
|
||||
var/datum/exonet_protocol/exonet = SScircuit.get_exonet_address(target_address)
|
||||
if(exonet)
|
||||
node.write_log(address, target_address, data_type, content)
|
||||
return exonet.receive_message(holder, address, data_type, content)
|
||||
|
||||
// Proc: receive_message()
|
||||
// Parameters: 4 (origin_atom - the origin datum's holder, origin_address - the address the message originated from,
|
||||
// data_type - text stating what the content is meant to be used for, content - the actual 'message' being sent from origin_atom)
|
||||
// Description: Called when send_message() successfully reaches the intended datum. By default, calls receive_exonet_message() on the holder atom.
|
||||
/datum/exonet_protocol/proc/receive_message(var/atom/origin_atom, var/origin_address, var/data_type, var/content)
|
||||
holder.receive_exonet_message(origin_atom, origin_address, data_type, content)
|
||||
return TRUE // for send_message()
|
||||
|
||||
// Proc: receive_exonet_message()
|
||||
// Parameters: 3 (origin_atom - the origin datum's holder, origin_address - the address the message originated from, message - the message that was sent)
|
||||
// Description: Override this to make your atom do something when a message is received.
|
||||
/atom/proc/receive_exonet_message(var/atom/origin_atom, var/origin_address, var/message, var/text)
|
||||
return
|
||||
@@ -0,0 +1,483 @@
|
||||
#define LING_FAKEDEATH_TIME 400 //40 seconds
|
||||
#define LING_DEAD_GENETICDAMAGE_HEAL_CAP 50 //The lowest value of geneticdamage handle_changeling() can take it to while dead.
|
||||
#define LING_ABSORB_RECENT_SPEECH 8 //The amount of recent spoken lines to gain on absorbing a mob
|
||||
|
||||
/datum/antagonist/changeling
|
||||
name = "Changeling"
|
||||
job_rank = ROLE_CHANGELING
|
||||
|
||||
var/you_are_greet = TRUE
|
||||
var/give_objectives = TRUE
|
||||
var/list/objectives = list()
|
||||
var/team_mode = FALSE //Should assign team objectives ?
|
||||
|
||||
//Changeling Stuff
|
||||
|
||||
var/list/stored_profiles = list() //list of datum/changelingprofile
|
||||
var/datum/changelingprofile/first_prof = null
|
||||
//var/list/absorbed_dna = list()
|
||||
//var/list/protected_dna = list() //dna that is not lost when capacity is otherwise full
|
||||
var/dna_max = 6 //How many extra DNA strands the changeling can store for transformation.
|
||||
var/absorbedcount = 0
|
||||
var/chem_charges = 20
|
||||
var/chem_storage = 75
|
||||
var/chem_recharge_rate = 1
|
||||
var/chem_recharge_slowdown = 0
|
||||
var/sting_range = 2
|
||||
var/changelingID = "Changeling"
|
||||
var/geneticdamage = 0
|
||||
var/isabsorbing = 0
|
||||
var/islinking = 0
|
||||
var/geneticpoints = 10
|
||||
var/purchasedpowers = list()
|
||||
var/mimicing = ""
|
||||
var/canrespec = 0
|
||||
var/changeling_speak = 0
|
||||
var/datum/dna/chosen_dna
|
||||
var/obj/effect/proc_holder/changeling/sting/chosen_sting
|
||||
var/datum/cellular_emporium/cellular_emporium
|
||||
var/datum/action/innate/cellular_emporium/emporium_action
|
||||
|
||||
// wip stuff
|
||||
var/static/list/all_powers = typecacheof(/obj/effect/proc_holder/changeling,TRUE)
|
||||
|
||||
|
||||
/datum/antagonist/changeling/New()
|
||||
. = ..()
|
||||
generate_name()
|
||||
create_actions()
|
||||
|
||||
/datum/antagonist/changeling/Destroy()
|
||||
QDEL_NULL(cellular_emporium)
|
||||
QDEL_NULL(emporium_action)
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/changeling/proc/generate_name()
|
||||
var/honorific
|
||||
if(owner.current.gender == FEMALE)
|
||||
honorific = "Ms."
|
||||
else
|
||||
honorific = "Mr."
|
||||
if(GLOB.possible_changeling_IDs.len)
|
||||
changelingID = pick(GLOB.possible_changeling_IDs)
|
||||
GLOB.possible_changeling_IDs -= changelingID
|
||||
changelingID = "[honorific] [changelingID]"
|
||||
else
|
||||
changelingID = "[honorific] [rand(1,999)]"
|
||||
|
||||
/datum/antagonist/changeling/proc/create_actions()
|
||||
cellular_emporium = new(src)
|
||||
emporium_action = new(cellular_emporium)
|
||||
|
||||
/datum/antagonist/changeling/on_gain()
|
||||
reset_powers()
|
||||
create_initial_profile()
|
||||
if(give_objectives)
|
||||
if(team_mode)
|
||||
forge_team_objectives()
|
||||
forge_objectives()
|
||||
remove_clownmut()
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/changeling/on_removal()
|
||||
remove_changeling_powers(FALSE)
|
||||
owner.objectives -= objectives
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/changeling/proc/remove_clownmut()
|
||||
if (owner)
|
||||
var/mob/living/carbon/human/H = owner.current
|
||||
if(istype(H) && owner.assigned_role == "Clown")
|
||||
to_chat(H, "You have evolved beyond your clownish nature, allowing you to wield weapons without harming yourself.")
|
||||
H.dna.remove_mutation(CLOWNMUT)
|
||||
|
||||
/datum/antagonist/changeling/proc/reset_properties()
|
||||
changeling_speak = 0
|
||||
chosen_sting = null
|
||||
geneticpoints = initial(geneticpoints)
|
||||
sting_range = initial(sting_range)
|
||||
chem_storage = initial(chem_storage)
|
||||
chem_recharge_rate = initial(chem_recharge_rate)
|
||||
chem_charges = min(chem_charges, chem_storage)
|
||||
chem_recharge_slowdown = initial(chem_recharge_slowdown)
|
||||
mimicing = ""
|
||||
|
||||
/datum/antagonist/changeling/proc/remove_changeling_powers(keep_free_powers=0)
|
||||
if(ishuman(owner.current) || ismonkey(owner.current))
|
||||
reset_properties()
|
||||
for(var/obj/effect/proc_holder/changeling/p in purchasedpowers)
|
||||
if((p.dna_cost == 0 && keep_free_powers) || p.always_keep)
|
||||
continue
|
||||
purchasedpowers -= p
|
||||
p.on_refund(owner.current)
|
||||
|
||||
//MOVE THIS
|
||||
if(owner.current.hud_used)
|
||||
owner.current.hud_used.lingstingdisplay.icon_state = null
|
||||
owner.current.hud_used.lingstingdisplay.invisibility = INVISIBILITY_ABSTRACT
|
||||
|
||||
/datum/antagonist/changeling/proc/reset_powers()
|
||||
if(purchasedpowers)
|
||||
remove_changeling_powers(TRUE)
|
||||
//Purchase free powers.
|
||||
for(var/path in all_powers)
|
||||
var/obj/effect/proc_holder/changeling/S = new path()
|
||||
if(!S.dna_cost)
|
||||
if(!has_sting(S))
|
||||
purchasedpowers+=S
|
||||
S.on_purchase(owner.current,TRUE)
|
||||
|
||||
/datum/antagonist/changeling/proc/has_sting(obj/effect/proc_holder/changeling/power)
|
||||
for(var/obj/effect/proc_holder/changeling/P in purchasedpowers)
|
||||
if(initial(power.name) == P.name)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
/datum/antagonist/changeling/proc/purchase_power(sting_name)
|
||||
var/obj/effect/proc_holder/changeling/thepower = null
|
||||
|
||||
for(var/path in all_powers)
|
||||
var/obj/effect/proc_holder/changeling/S = path
|
||||
if(initial(S.name) == sting_name)
|
||||
thepower = new path()
|
||||
break
|
||||
|
||||
if(!thepower)
|
||||
to_chat(owner.current, "This is awkward. Changeling power purchase failed, please report this bug to a coder!")
|
||||
return
|
||||
|
||||
if(absorbedcount < thepower.req_dna)
|
||||
to_chat(owner.current, "We lack the energy to evolve this ability!")
|
||||
return
|
||||
|
||||
if(has_sting(thepower))
|
||||
to_chat(owner.current, "We have already evolved this ability!")
|
||||
return
|
||||
|
||||
if(thepower.dna_cost < 0)
|
||||
to_chat(owner.current, "We cannot evolve this ability.")
|
||||
return
|
||||
|
||||
if(geneticpoints < thepower.dna_cost)
|
||||
to_chat(owner.current, "We have reached our capacity for abilities.")
|
||||
return
|
||||
|
||||
if(owner.current.status_flags & FAKEDEATH)//To avoid potential exploits by buying new powers while in stasis, which clears your verblist.
|
||||
to_chat(owner.current, "We lack the energy to evolve new abilities right now.")
|
||||
return
|
||||
|
||||
geneticpoints -= thepower.dna_cost
|
||||
purchasedpowers += thepower
|
||||
thepower.on_purchase(owner.current)
|
||||
|
||||
/datum/antagonist/changeling/proc/readapt()
|
||||
if(!ishuman(owner.current))
|
||||
to_chat(owner.current, "<span class='danger'>We can't remove our evolutions in this form!</span>")
|
||||
return
|
||||
if(canrespec)
|
||||
to_chat(owner.current, "<span class='notice'>We have removed our evolutions from this form, and are now ready to readapt.</span>")
|
||||
reset_powers()
|
||||
canrespec = 0
|
||||
SSblackbox.add_details("changeling_power_purchase","Readapt")
|
||||
return 1
|
||||
else
|
||||
to_chat(owner.current, "<span class='danger'>You lack the power to readapt your evolutions!</span>")
|
||||
return 0
|
||||
|
||||
//Called in life()
|
||||
/datum/antagonist/changeling/proc/regenerate()
|
||||
var/mob/living/carbon/the_ling = owner.current
|
||||
if(istype(the_ling))
|
||||
emporium_action.Grant(the_ling)
|
||||
if(the_ling.stat == DEAD)
|
||||
chem_charges = min(max(0, chem_charges + chem_recharge_rate - chem_recharge_slowdown), (chem_storage*0.5))
|
||||
geneticdamage = max(LING_DEAD_GENETICDAMAGE_HEAL_CAP,geneticdamage-1)
|
||||
else //not dead? no chem/geneticdamage caps.
|
||||
chem_charges = min(max(0, chem_charges + chem_recharge_rate - chem_recharge_slowdown), chem_storage)
|
||||
geneticdamage = max(0, geneticdamage-1)
|
||||
|
||||
|
||||
/datum/antagonist/changeling/proc/get_dna(dna_owner)
|
||||
for(var/datum/changelingprofile/prof in stored_profiles)
|
||||
if(dna_owner == prof.name)
|
||||
return prof
|
||||
|
||||
/datum/antagonist/changeling/proc/has_dna(datum/dna/tDNA)
|
||||
for(var/datum/changelingprofile/prof in stored_profiles)
|
||||
if(tDNA.is_same_as(prof.dna))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/antagonist/changeling/proc/can_absorb_dna(mob/living/carbon/human/target, var/verbose=1)
|
||||
var/mob/living/carbon/user = owner.current
|
||||
if(!istype(user))
|
||||
return
|
||||
if(stored_profiles.len)
|
||||
var/datum/changelingprofile/prof = stored_profiles[1]
|
||||
if(prof.dna == user.dna && stored_profiles.len >= dna_max)//If our current DNA is the stalest, we gotta ditch it.
|
||||
if(verbose)
|
||||
to_chat(user, "<span class='warning'>We have reached our capacity to store genetic information! We must transform before absorbing more.</span>")
|
||||
return
|
||||
if(!target)
|
||||
return
|
||||
if(NO_DNA_COPY in target.dna.species.species_traits)
|
||||
if(verbose)
|
||||
to_chat(user, "<span class='warning'>[target] is not compatible with our biology.</span>")
|
||||
return
|
||||
if((target.disabilities & NOCLONE) || (target.disabilities & HUSK))
|
||||
if(verbose)
|
||||
to_chat(user, "<span class='warning'>DNA of [target] is ruined beyond usability!</span>")
|
||||
return
|
||||
if(!ishuman(target))//Absorbing monkeys is entirely possible, but it can cause issues with transforming. That's what lesser form is for anyway!
|
||||
if(verbose)
|
||||
to_chat(user, "<span class='warning'>We could gain no benefit from absorbing a lesser creature.</span>")
|
||||
return
|
||||
if(has_dna(target.dna))
|
||||
if(verbose)
|
||||
to_chat(user, "<span class='warning'>We already have this DNA in storage!</span>")
|
||||
return
|
||||
if(!target.has_dna())
|
||||
if(verbose)
|
||||
to_chat(user, "<span class='warning'>[target] is not compatible with our biology.</span>")
|
||||
return
|
||||
return 1
|
||||
|
||||
|
||||
/datum/antagonist/changeling/proc/create_profile(mob/living/carbon/human/H, protect = 0)
|
||||
var/datum/changelingprofile/prof = new
|
||||
|
||||
H.dna.real_name = H.real_name //Set this again, just to be sure that it's properly set.
|
||||
var/datum/dna/new_dna = new H.dna.type
|
||||
H.dna.copy_dna(new_dna)
|
||||
prof.dna = new_dna
|
||||
prof.name = H.real_name
|
||||
prof.protected = protect
|
||||
|
||||
prof.underwear = H.underwear
|
||||
prof.undershirt = H.undershirt
|
||||
prof.socks = H.socks
|
||||
|
||||
var/list/slots = list("head", "wear_mask", "back", "wear_suit", "w_uniform", "shoes", "belt", "gloves", "glasses", "ears", "wear_id", "s_store")
|
||||
for(var/slot in slots)
|
||||
if(slot in H.vars)
|
||||
var/obj/item/I = H.vars[slot]
|
||||
if(!I)
|
||||
continue
|
||||
prof.name_list[slot] = I.name
|
||||
prof.appearance_list[slot] = I.appearance
|
||||
prof.flags_cover_list[slot] = I.flags_cover
|
||||
prof.item_color_list[slot] = I.item_color
|
||||
prof.item_state_list[slot] = I.item_state
|
||||
prof.exists_list[slot] = 1
|
||||
else
|
||||
continue
|
||||
|
||||
return prof
|
||||
|
||||
/datum/antagonist/changeling/proc/add_profile(datum/changelingprofile/prof)
|
||||
if(stored_profiles.len > dna_max)
|
||||
if(!push_out_profile())
|
||||
return
|
||||
|
||||
if(!first_prof)
|
||||
first_prof = prof
|
||||
|
||||
stored_profiles += prof
|
||||
absorbedcount++
|
||||
|
||||
/datum/antagonist/changeling/proc/add_new_profile(mob/living/carbon/human/H, protect = 0)
|
||||
var/datum/changelingprofile/prof = create_profile(H, protect)
|
||||
add_profile(prof)
|
||||
return prof
|
||||
|
||||
/datum/antagonist/changeling/proc/remove_profile(mob/living/carbon/human/H, force = 0)
|
||||
for(var/datum/changelingprofile/prof in stored_profiles)
|
||||
if(H.real_name == prof.name)
|
||||
if(prof.protected && !force)
|
||||
continue
|
||||
stored_profiles -= prof
|
||||
qdel(prof)
|
||||
|
||||
/datum/antagonist/changeling/proc/get_profile_to_remove()
|
||||
for(var/datum/changelingprofile/prof in stored_profiles)
|
||||
if(!prof.protected)
|
||||
return prof
|
||||
|
||||
/datum/antagonist/changeling/proc/push_out_profile()
|
||||
var/datum/changelingprofile/removeprofile = get_profile_to_remove()
|
||||
if(removeprofile)
|
||||
stored_profiles -= removeprofile
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/datum/antagonist/changeling/proc/create_initial_profile()
|
||||
var/mob/living/carbon/C = owner.current //only carbons have dna now, so we have to typecaste
|
||||
if(ishuman(C))
|
||||
add_new_profile(C)
|
||||
|
||||
/datum/antagonist/changeling/apply_innate_effects()
|
||||
//Brains optional.
|
||||
var/mob/living/carbon/C = owner.current
|
||||
if(istype(C))
|
||||
var/obj/item/organ/brain/B = C.getorganslot(ORGAN_SLOT_BRAIN)
|
||||
if(B)
|
||||
B.vital = FALSE
|
||||
B.decoy_override = TRUE
|
||||
update_changeling_icons_added()
|
||||
return
|
||||
|
||||
/datum/antagonist/changeling/remove_innate_effects()
|
||||
update_changeling_icons_removed()
|
||||
return
|
||||
|
||||
|
||||
/datum/antagonist/changeling/greet()
|
||||
if (you_are_greet)
|
||||
to_chat(owner.current, "<span class='boldannounce'>You are [changelingID], a changeling! You have absorbed and taken the form of a human.</span>")
|
||||
to_chat(owner.current, "<span class='boldannounce'>Use say \":g message\" to communicate with your fellow changelings.</span>")
|
||||
to_chat(owner.current, "<b>You must complete the following tasks:</b>")
|
||||
owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/ling_aler.ogg', 100, FALSE, pressure_affected = FALSE)
|
||||
|
||||
owner.announce_objectives()
|
||||
|
||||
/datum/antagonist/changeling/proc/forge_team_objectives()
|
||||
if(GLOB.changeling_team_objective_type)
|
||||
var/datum/objective/changeling_team_objective/team_objective = new GLOB.changeling_team_objective_type
|
||||
team_objective.owner = owner
|
||||
objectives += team_objective
|
||||
return
|
||||
|
||||
/datum/antagonist/changeling/proc/forge_objectives()
|
||||
//OBJECTIVES - random traitor objectives. Unique objectives "steal brain" and "identity theft".
|
||||
//No escape alone because changelings aren't suited for it and it'd probably just lead to rampant robusting
|
||||
//If it seems like they'd be able to do it in play, add a 10% chance to have to escape alone
|
||||
|
||||
var/escape_objective_possible = TRUE
|
||||
|
||||
//if there's a team objective, check if it's compatible with escape objectives
|
||||
for(var/datum/objective/changeling_team_objective/CTO in objectives)
|
||||
if(!CTO.escape_objective_compatible)
|
||||
escape_objective_possible = FALSE
|
||||
break
|
||||
|
||||
var/datum/objective/absorb/absorb_objective = new
|
||||
absorb_objective.owner = owner
|
||||
absorb_objective.gen_amount_goal(6, 8)
|
||||
objectives += absorb_objective
|
||||
|
||||
if(prob(60))
|
||||
if(prob(85))
|
||||
var/datum/objective/steal/steal_objective = new
|
||||
steal_objective.owner = owner
|
||||
steal_objective.find_target()
|
||||
objectives += steal_objective
|
||||
else
|
||||
var/datum/objective/download/download_objective = new
|
||||
download_objective.owner = owner
|
||||
download_objective.gen_amount_goal()
|
||||
objectives += download_objective
|
||||
|
||||
var/list/active_ais = active_ais()
|
||||
if(active_ais.len && prob(100/GLOB.joined_player_list.len))
|
||||
var/datum/objective/destroy/destroy_objective = new
|
||||
destroy_objective.owner = owner
|
||||
destroy_objective.find_target()
|
||||
objectives += destroy_objective
|
||||
else
|
||||
if(prob(70))
|
||||
var/datum/objective/assassinate/kill_objective = new
|
||||
kill_objective.owner = owner
|
||||
if(team_mode) //No backstabbing while in a team
|
||||
kill_objective.find_target_by_role(role = "Changeling", role_type = 1, invert = 1)
|
||||
else
|
||||
kill_objective.find_target()
|
||||
objectives += kill_objective
|
||||
else
|
||||
var/datum/objective/maroon/maroon_objective = new
|
||||
maroon_objective.owner = owner
|
||||
if(team_mode)
|
||||
maroon_objective.find_target_by_role(role = "Changeling", role_type = 1, invert = 1)
|
||||
else
|
||||
maroon_objective.find_target()
|
||||
objectives += maroon_objective
|
||||
|
||||
if (!(locate(/datum/objective/escape) in objectives) && escape_objective_possible)
|
||||
var/datum/objective/escape/escape_with_identity/identity_theft = new
|
||||
identity_theft.owner = owner
|
||||
identity_theft.target = maroon_objective.target
|
||||
identity_theft.update_explanation_text()
|
||||
objectives += identity_theft
|
||||
escape_objective_possible = FALSE
|
||||
|
||||
if (!(locate(/datum/objective/escape) in objectives) && escape_objective_possible)
|
||||
if(prob(50))
|
||||
var/datum/objective/escape/escape_objective = new
|
||||
escape_objective.owner = owner
|
||||
objectives += escape_objective
|
||||
else
|
||||
var/datum/objective/escape/escape_with_identity/identity_theft = new
|
||||
identity_theft.owner = owner
|
||||
if(team_mode)
|
||||
identity_theft.find_target_by_role(role = "Changeling", role_type = 1, invert = 1)
|
||||
else
|
||||
identity_theft.find_target()
|
||||
objectives += identity_theft
|
||||
escape_objective_possible = FALSE
|
||||
|
||||
owner.objectives |= objectives
|
||||
|
||||
/datum/antagonist/changeling/proc/update_changeling_icons_added()
|
||||
var/datum/atom_hud/antag/hud = GLOB.huds[ANTAG_HUD_CHANGELING]
|
||||
hud.join_hud(owner.current)
|
||||
set_antag_hud(owner.current, "changling")
|
||||
|
||||
/datum/antagonist/changeling/proc/update_changeling_icons_removed()
|
||||
var/datum/atom_hud/antag/hud = GLOB.huds[ANTAG_HUD_CHANGELING]
|
||||
hud.leave_hud(owner.current)
|
||||
set_antag_hud(owner.current, null)
|
||||
|
||||
// Profile
|
||||
|
||||
/datum/changelingprofile
|
||||
var/name = "a bug"
|
||||
|
||||
var/protected = 0
|
||||
|
||||
var/datum/dna/dna = null
|
||||
var/list/name_list = list() //associative list of slotname = itemname
|
||||
var/list/appearance_list = list()
|
||||
var/list/flags_cover_list = list()
|
||||
var/list/exists_list = list()
|
||||
var/list/item_color_list = list()
|
||||
var/list/item_state_list = list()
|
||||
|
||||
var/underwear
|
||||
var/undershirt
|
||||
var/socks
|
||||
|
||||
/datum/changelingprofile/Destroy()
|
||||
qdel(dna)
|
||||
. = ..()
|
||||
|
||||
/datum/changelingprofile/proc/copy_profile(datum/changelingprofile/newprofile)
|
||||
newprofile.name = name
|
||||
newprofile.protected = protected
|
||||
newprofile.dna = new dna.type
|
||||
dna.copy_dna(newprofile.dna)
|
||||
newprofile.name_list = name_list.Copy()
|
||||
newprofile.appearance_list = appearance_list.Copy()
|
||||
newprofile.flags_cover_list = flags_cover_list.Copy()
|
||||
newprofile.exists_list = exists_list.Copy()
|
||||
newprofile.item_color_list = item_color_list.Copy()
|
||||
newprofile.item_state_list = item_state_list.Copy()
|
||||
newprofile.underwear = underwear
|
||||
newprofile.undershirt = undershirt
|
||||
newprofile.socks = socks
|
||||
|
||||
|
||||
/datum/antagonist/changeling/xenobio
|
||||
name = "Xenobio Changeling"
|
||||
give_objectives = FALSE
|
||||
you_are_greet = FALSE
|
||||
@@ -35,7 +35,7 @@ GLOBAL_LIST_INIT(lawlorify, list (
|
||||
BAN_CHAPEL = "This devil avoids holy ground.",
|
||||
BAN_HURTPRIEST = "The annointed clergy appear to be immune to his powers.",
|
||||
BAN_AVOIDWATER = "The devil seems to have some sort of aversion to water, though it does not appear to harm him.",
|
||||
BAN_STRIKEUNCONCIOUS = "This devil only shows interest in those who are awake.",
|
||||
BAN_STRIKEUNCONSCIOUS = "This devil only shows interest in those who are awake.",
|
||||
BAN_HURTLIZARD = "This devil will not strike a lizardman first.",
|
||||
BAN_HURTANIMAL = "This devil avoids hurting animals.",
|
||||
BANISH_WATER = "To banish the devil, you must infuse its body with holy water.",
|
||||
@@ -59,7 +59,7 @@ GLOBAL_LIST_INIT(lawlorify, list (
|
||||
BAN_CHAPEL = "You must never attempt to enter the chapel.",
|
||||
BAN_HURTPRIEST = "You must never attack a priest.",
|
||||
BAN_AVOIDWATER = "You must never willingly touch a wet surface.",
|
||||
BAN_STRIKEUNCONCIOUS = "You must never strike an unconscious person.",
|
||||
BAN_STRIKEUNCONSCIOUS = "You must never strike an unconscious person.",
|
||||
BAN_HURTLIZARD = "You must never harm a lizardman outside of self defense.",
|
||||
BAN_HURTANIMAL = "You must never harm a non-sentient creature or robot outside of self defense.",
|
||||
BANE_SILVER = "Silver, in all of its forms shall be your downfall.",
|
||||
@@ -148,7 +148,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
|
||||
return pick(OBLIGATION_FOOD, OBLIGATION_FIDDLE, OBLIGATION_DANCEOFF, OBLIGATION_GREET, OBLIGATION_PRESENCEKNOWN, OBLIGATION_SAYNAME, OBLIGATION_ANNOUNCEKILL, OBLIGATION_ANSWERTONAME)
|
||||
|
||||
/proc/randomdevilban()
|
||||
return pick(BAN_HURTWOMAN, BAN_CHAPEL, BAN_HURTPRIEST, BAN_AVOIDWATER, BAN_STRIKEUNCONCIOUS, BAN_HURTLIZARD, BAN_HURTANIMAL)
|
||||
return pick(BAN_HURTWOMAN, BAN_CHAPEL, BAN_HURTPRIEST, BAN_AVOIDWATER, BAN_STRIKEUNCONSCIOUS, BAN_HURTLIZARD, BAN_HURTANIMAL)
|
||||
|
||||
/proc/randomdevilbane()
|
||||
return pick(BANE_SALT, BANE_LIGHT, BANE_IRON, BANE_WHITECLOTHES, BANE_SILVER, BANE_HARVEST, BANE_TOOLBOX)
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
/datum/antagonist/pirate
|
||||
name = "Space Pirate"
|
||||
job_rank = ROLE_TRAITOR
|
||||
var/datum/objective_team/pirate/crew
|
||||
|
||||
/datum/antagonist/pirate/greet()
|
||||
to_chat(owner, "<span class='boldannounce'>You are a Space Pirate!</span>")
|
||||
to_chat(owner, "<B>The station refused to pay for your protection, protect the ship, siphon the credits from the station and raid it for even more loot.</B>")
|
||||
owner.announce_objectives()
|
||||
|
||||
/datum/antagonist/pirate/get_team()
|
||||
return crew
|
||||
|
||||
/datum/antagonist/pirate/create_team(datum/objective_team/pirate/new_team)
|
||||
if(!new_team)
|
||||
for(var/datum/antagonist/pirate/P in GLOB.antagonists)
|
||||
if(P.crew)
|
||||
new_team = P.crew
|
||||
if(!new_team)
|
||||
crew = new /datum/objective_team/pirate
|
||||
crew.forge_objectives()
|
||||
return
|
||||
if(!istype(new_team))
|
||||
stack_trace("Wrong team type passed to [type] initialization.")
|
||||
crew = new_team
|
||||
|
||||
/datum/antagonist/pirate/on_gain()
|
||||
if(crew)
|
||||
owner.objectives |= crew.objectives
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/pirate/on_removal()
|
||||
if(crew)
|
||||
owner.objectives -= crew.objectives
|
||||
. = ..()
|
||||
|
||||
/datum/objective_team/pirate
|
||||
name = "Pirate crew"
|
||||
var/list/objectives = list()
|
||||
|
||||
/datum/objective_team/pirate/proc/forge_objectives()
|
||||
var/datum/objective/loot/getbooty = new()
|
||||
getbooty.team = src
|
||||
getbooty.storage_area = locate(/area/shuttle/pirate/vault) in GLOB.sortedAreas
|
||||
getbooty.update_initial_value()
|
||||
getbooty.update_explanation_text()
|
||||
objectives += getbooty
|
||||
for(var/datum/mind/M in members)
|
||||
M.objectives |= objectives
|
||||
|
||||
|
||||
GLOBAL_LIST_INIT(pirate_loot_cache, typecacheof(list(
|
||||
/obj/structure/reagent_dispensers/beerkeg,
|
||||
/mob/living/simple_animal/parrot,
|
||||
/obj/item/stack/sheet/mineral/gold,
|
||||
/obj/item/stack/sheet/mineral/diamond,
|
||||
/obj/item/stack/spacecash,
|
||||
/obj/item/melee/sabre,)))
|
||||
|
||||
/datum/objective/loot
|
||||
var/area/storage_area //Place where we we will look for the loot.
|
||||
explanation_text = "Acquire valuable loot and store it in designated area."
|
||||
var/target_value = 50000
|
||||
var/initial_value = 0 //Things in the vault at spawn time do not count
|
||||
|
||||
/datum/objective/loot/update_explanation_text()
|
||||
if(storage_area)
|
||||
explanation_text = "Acquire loot and store [target_value] of credits worth in [storage_area.name]."
|
||||
|
||||
/datum/objective/loot/proc/loot_listing()
|
||||
//Lists notable loot.
|
||||
if(!storage_area)
|
||||
return "Nothing"
|
||||
var/list/loot_table = list()
|
||||
for(var/atom/movable/AM in storage_area.GetAllContents())
|
||||
if(is_type_in_typecache(AM,GLOB.pirate_loot_cache))
|
||||
var/lootname = AM.name
|
||||
var/count = 1
|
||||
if(istype(AM,/obj/item/stack)) //Ugh.
|
||||
var/obj/item/stack/S = AM
|
||||
lootname = S.singular_name
|
||||
count = S.amount
|
||||
if(!loot_table[lootname])
|
||||
loot_table[lootname] = count
|
||||
else
|
||||
loot_table[lootname] += count
|
||||
var/text = ""
|
||||
for(var/key in loot_table)
|
||||
var/amount = loot_table[key]
|
||||
text += "[amount] [key][amount > 1 ? "s":""], "
|
||||
return text
|
||||
|
||||
/datum/objective/loot/proc/get_loot_value()
|
||||
if(!storage_area)
|
||||
return 0
|
||||
var/value = 0
|
||||
for(var/turf/T in storage_area.contents)
|
||||
value += export_item_and_contents(T,TRUE, TRUE, dry_run = TRUE)
|
||||
return value - initial_value
|
||||
|
||||
/datum/objective/loot/proc/update_initial_value()
|
||||
initial_value = get_loot_value()
|
||||
|
||||
/datum/objective/loot/check_completion()
|
||||
return ..() || get_loot_value() >= target_value
|
||||
|
||||
|
||||
//These need removal ASAP as everything is converted to datum antags.
|
||||
/datum/game_mode/proc/auto_declare_completion_pirates()
|
||||
var/list/datum/mind/pirates = get_antagonists(/datum/antagonist/pirate)
|
||||
var/datum/objective_team/pirate/crew
|
||||
var/text = ""
|
||||
if(pirates.len)
|
||||
text += "<br><b>Space Pirates were:</b>"
|
||||
for(var/datum/mind/M in pirates)
|
||||
text += printplayer(M)
|
||||
if(!crew)
|
||||
var/datum/antagonist/pirate/P = M.has_antag_datum(/datum/antagonist/pirate)
|
||||
crew = P.crew
|
||||
if(crew)
|
||||
text += "<br>Loot stolen: "
|
||||
var/datum/objective/loot/L = locate() in crew.objectives
|
||||
text += L.loot_listing()
|
||||
text += "<br>Total loot value : [L.get_loot_value()]/[L.target_value] credits"
|
||||
|
||||
var/all_dead = TRUE
|
||||
for(var/datum/mind/M in crew.members)
|
||||
if(considered_alive(M))
|
||||
all_dead = FALSE
|
||||
break
|
||||
if(L.check_completion() && !all_dead)
|
||||
text += "<br><font color='green'><b>The pirate crew was successful!</b></font>"
|
||||
else
|
||||
text += "<br><span class='boldannounce'>The pirate crew has failed.</span>"
|
||||
to_chat(world, text)
|
||||
@@ -132,13 +132,13 @@
|
||||
|
||||
var/output = {"<center><b>[Message]</b></center><br />
|
||||
<div style="text-align:center">
|
||||
<a style="font-size:large;float:[( Button2 ? "left" : "right" )]" href="?src=\ref[src];button=1">[Button1]</a>"}
|
||||
<a style="font-size:large;float:[( Button2 ? "left" : "right" )]" href="?src=[REF(src)];button=1">[Button1]</a>"}
|
||||
|
||||
if (Button2)
|
||||
output += {"<a style="font-size:large;[( Button3 ? "" : "float:right" )]" href="?src=\ref[src];button=2">[Button2]</a>"}
|
||||
output += {"<a style="font-size:large;[( Button3 ? "" : "float:right" )]" href="?src=[REF(src)];button=2">[Button2]</a>"}
|
||||
|
||||
if (Button3)
|
||||
output += {"<a style="font-size:large;float:right" href="?src=\ref[src];button=3">[Button3]</a>"}
|
||||
output += {"<a style="font-size:large;float:right" href="?src=[REF(src)];button=3">[Button3]</a>"}
|
||||
|
||||
output += {"</div>"}
|
||||
|
||||
@@ -253,7 +253,7 @@
|
||||
return
|
||||
var/param = "null"
|
||||
if(ref)
|
||||
param = "\ref[ref]"
|
||||
param = "[REF(ref)]"
|
||||
|
||||
winset(user, windowid, "on-close=\".windowclose [param]\"")
|
||||
|
||||
|
||||
@@ -87,9 +87,11 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
|
||||
* Signals will not be recieved while this function is running
|
||||
* Component may be deleted after this function completes without being attached
|
||||
* Do not call `qdel(src)` from this function
|
||||
1. `/datum/component/Destroy()` (virtual, no-sleep)
|
||||
1. `/datum/component/Destroy(force(bool), silent(bool))` (virtual, no-sleep)
|
||||
* Sends the `COMSIG_COMPONENT_REMOVING` signal to the parent datum if the `parent` isn't being qdeleted
|
||||
* Properly removes the component from `parent` and cleans up references
|
||||
* Setting `force` makes it not check for and remove the component from the parent
|
||||
* Setting `silent` deletes the component without sending a `COMSIG_COMPONENT_REMOVING` signal
|
||||
1. `/datum/component/proc/InheritComponent(datum/component/C, i_am_original(boolean))` (abstract, no-sleep)
|
||||
* Called on a component when a component of the same type was added to the same parent
|
||||
* See `/datum/component/var/dupe_mode`
|
||||
|
||||
@@ -6,12 +6,15 @@
|
||||
var/datum/parent
|
||||
|
||||
/datum/component/New(datum/P, ...)
|
||||
if(type == /datum/component)
|
||||
qdel(src)
|
||||
CRASH("[type] instantiated!")
|
||||
|
||||
parent = P
|
||||
var/list/arguments = args.Copy()
|
||||
arguments.Cut(1, 2)
|
||||
if(Initialize(arglist(arguments)) == COMPONENT_INCOMPATIBLE)
|
||||
parent = null
|
||||
qdel(src)
|
||||
qdel(src, TRUE, TRUE)
|
||||
return
|
||||
|
||||
_CheckDupesAndJoinParent(P)
|
||||
@@ -32,13 +35,11 @@
|
||||
switch(dm)
|
||||
if(COMPONENT_DUPE_UNIQUE)
|
||||
old.InheritComponent(src, TRUE)
|
||||
parent = null //prevent COMPONENT_REMOVING signal, no _RemoveFromParent because we aren't in their list yet
|
||||
qdel(src)
|
||||
qdel(src, TRUE, TRUE)
|
||||
return
|
||||
if(COMPONENT_DUPE_HIGHLANDER)
|
||||
InheritComponent(old, FALSE)
|
||||
old._RemoveFromParent()
|
||||
qdel(old)
|
||||
qdel(old, FALSE, TRUE)
|
||||
|
||||
//provided we didn't eat someone
|
||||
if(!old)
|
||||
@@ -56,7 +57,7 @@
|
||||
var/test = dc[I]
|
||||
if(test) //already another component of this type here
|
||||
var/list/components_of_type
|
||||
if(!islist(test))
|
||||
if(!length(test))
|
||||
components_of_type = list(test)
|
||||
dc[I] = components_of_type
|
||||
else
|
||||
@@ -79,22 +80,23 @@
|
||||
/datum/component/proc/Initialize(...)
|
||||
return
|
||||
|
||||
/datum/component/Destroy()
|
||||
/datum/component/Destroy(force=FALSE, silent=FALSE)
|
||||
enabled = FALSE
|
||||
var/datum/P = parent
|
||||
if(P)
|
||||
if(!force)
|
||||
_RemoveFromParent()
|
||||
if(!silent)
|
||||
P.SendSignal(COMSIG_COMPONENT_REMOVING, src)
|
||||
parent = null
|
||||
LAZYCLEARLIST(signal_procs)
|
||||
return ..()
|
||||
|
||||
/datum/component/proc/_RemoveFromParent()
|
||||
var/datum/P = parent
|
||||
var/list/dc = P.datum_components
|
||||
var/our_type = type
|
||||
for(var/I in _GetInverseTypeList(our_type))
|
||||
for(var/I in _GetInverseTypeList())
|
||||
var/list/components_of_type = dc[I]
|
||||
if(islist(components_of_type)) //
|
||||
if(length(components_of_type)) //
|
||||
var/list/subtracted = components_of_type - src
|
||||
if(subtracted.len == 1) //only 1 guy left
|
||||
dc[I] = subtracted[1] //make him special
|
||||
@@ -104,9 +106,8 @@
|
||||
dc -= I
|
||||
if(!dc.len)
|
||||
P.datum_components = null
|
||||
parent = null
|
||||
|
||||
/datum/component/proc/RegisterSignal(sig_type_or_types, proc_on_self, override = FALSE)
|
||||
/datum/component/proc/RegisterSignal(sig_type_or_types, proc_or_callback, override = FALSE)
|
||||
if(QDELETED(src))
|
||||
return
|
||||
var/list/procs = signal_procs
|
||||
@@ -120,8 +121,10 @@
|
||||
. = procs[sig_type]
|
||||
if(.)
|
||||
stack_trace("[sig_type] overridden. Use override = TRUE to suppress this warning")
|
||||
|
||||
procs[sig_type] = CALLBACK(src, proc_on_self)
|
||||
|
||||
if(!istype(proc_or_callback, /datum/callback)) //if it wasnt a callback before, it is now
|
||||
proc_or_callback = CALLBACK(src, proc_or_callback)
|
||||
procs[sig_type] = proc_or_callback
|
||||
|
||||
/datum/component/proc/InheritComponent(datum/component/C, i_am_original)
|
||||
return
|
||||
@@ -133,8 +136,19 @@
|
||||
set waitfor = FALSE
|
||||
return
|
||||
|
||||
/datum/component/proc/_GetInverseTypeList(current_type)
|
||||
. = list(current_type)
|
||||
/datum/component/proc/_GetInverseTypeList(our_type = type)
|
||||
#if DM_VERSION >= 513
|
||||
#warning 512 is definitely stable now, remove the old code
|
||||
#endif
|
||||
|
||||
#if DM_VERSION < 512
|
||||
//remove this when we use 512 full time
|
||||
set invisibility = 101
|
||||
#endif
|
||||
//we can do this one simple trick
|
||||
var/current_type = parent_type
|
||||
. = list(our_type, current_type)
|
||||
//and since most components are root level + 1, this won't even have to run
|
||||
while (current_type != /datum/component)
|
||||
current_type = type2parent(current_type)
|
||||
. += current_type
|
||||
@@ -146,7 +160,7 @@
|
||||
var/list/arguments = args.Copy()
|
||||
arguments.Cut(1, 2)
|
||||
var/target = comps[/datum/component]
|
||||
if(!islist(target))
|
||||
if(!length(target))
|
||||
var/datum/component/C = target
|
||||
if(!C.enabled)
|
||||
return FALSE
|
||||
@@ -182,7 +196,7 @@
|
||||
if(!dc)
|
||||
return null
|
||||
. = dc[c_type]
|
||||
if(islist(.))
|
||||
if(length(.))
|
||||
return .[1]
|
||||
|
||||
/datum/proc/GetExactComponent(c_type)
|
||||
@@ -191,7 +205,7 @@
|
||||
return null
|
||||
var/datum/component/C = dc[c_type]
|
||||
if(C)
|
||||
if(islist(C))
|
||||
if(length(C))
|
||||
C = C[1]
|
||||
if(C.type == c_type)
|
||||
return C
|
||||
@@ -202,7 +216,7 @@
|
||||
if(!dc)
|
||||
return null
|
||||
. = dc[c_type]
|
||||
if(!islist(.))
|
||||
if(!length(.))
|
||||
return list(.)
|
||||
|
||||
/datum/proc/AddComponent(new_type, ...)
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/datum/component/decal
|
||||
dupe_mode = COMPONENT_DUPE_ALLOWED
|
||||
|
||||
var/cleanable
|
||||
var/description
|
||||
var/mutable_appearance/pic
|
||||
|
||||
/datum/component/decal/Initialize(_icon, _icon_state, _dir, _cleanable=CLEAN_GOD, _color, _layer=TURF_LAYER, _description)
|
||||
if(!isatom(parent) || !_icon || !_icon_state)
|
||||
. = COMPONENT_INCOMPATIBLE
|
||||
CRASH("A turf decal was applied incorrectly to [parent.type]: icon:[_icon ? _icon : "none"] icon_state:[_icon_state ? _icon_state : "none"]")
|
||||
|
||||
// It has to be made from an image or dir breaks because of a byond bug
|
||||
var/temp_image = image(_icon, null, _icon_state, _layer, _dir)
|
||||
pic = new(temp_image)
|
||||
pic.color = _color
|
||||
|
||||
cleanable = _cleanable
|
||||
description = _description
|
||||
|
||||
apply()
|
||||
|
||||
if(_dir) // If no dir is assigned at start then it follows the atom's dir
|
||||
RegisterSignal(COMSIG_ATOM_DIR_CHANGE, .proc/rotate_react)
|
||||
if(_cleanable)
|
||||
RegisterSignal(COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_react)
|
||||
if(_description)
|
||||
RegisterSignal(COMSIG_PARENT_EXAMINE, .proc/examine)
|
||||
|
||||
/datum/component/decal/Destroy()
|
||||
remove()
|
||||
return ..()
|
||||
|
||||
/datum/component/decal/OnTransfer(atom/thing)
|
||||
remove()
|
||||
remove(thing)
|
||||
apply(thing)
|
||||
|
||||
/datum/component/decal/proc/apply(atom/thing)
|
||||
var/atom/master = thing || parent
|
||||
master.add_overlay(pic, TRUE)
|
||||
|
||||
/datum/component/decal/proc/remove(atom/thing)
|
||||
var/atom/master = thing || parent
|
||||
master.cut_overlay(pic, TRUE)
|
||||
|
||||
/datum/component/decal/proc/rotate_react(old_dir, new_dir)
|
||||
if(old_dir == new_dir)
|
||||
return
|
||||
remove()
|
||||
var/rotation = SimplifyDegrees(dir2angle(new_dir)-dir2angle(old_dir))
|
||||
pic.dir = turn(pic.dir, rotation)
|
||||
apply()
|
||||
|
||||
/datum/component/decal/proc/clean_react(strength)
|
||||
if(strength >= cleanable)
|
||||
qdel(src)
|
||||
|
||||
/datum/component/decal/proc/examine(mob/user)
|
||||
to_chat(user, description)
|
||||
@@ -37,11 +37,15 @@
|
||||
return ..()
|
||||
|
||||
/datum/component/radioactive/process()
|
||||
if(hl3_release_date && prob(50))
|
||||
radiation_pulse(parent, strength, RAD_DISTANCE_COEFFICIENT*2, FALSE, can_contaminate)
|
||||
strength -= strength / hl3_release_date
|
||||
if(strength <= RAD_BACKGROUND_RADIATION)
|
||||
qdel(src)
|
||||
if(!prob(50))
|
||||
return
|
||||
radiation_pulse(parent, strength, RAD_DISTANCE_COEFFICIENT*2, FALSE, can_contaminate)
|
||||
|
||||
if(!hl3_release_date)
|
||||
return
|
||||
strength -= strength / hl3_release_date
|
||||
if(strength <= RAD_BACKGROUND_RADIATION)
|
||||
return PROCESS_KILL
|
||||
|
||||
/datum/component/radioactive/InheritComponent(datum/component/C, i_am_original)
|
||||
if(!i_am_original)
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
/datum/component/redirect
|
||||
dupe_mode = COMPONENT_DUPE_ALLOWED
|
||||
|
||||
/datum/component/redirect/Initialize(list/signals, datum/callback/_callback)
|
||||
//It's not our job to verify the right signals are registered here, just do it.
|
||||
if(!LAZYLEN(signals) || !istype(_callback))
|
||||
. = COMPONENT_INCOMPATIBLE
|
||||
CRASH("A redirection component was initialized with incorrect args.")
|
||||
RegisterSignal(signals, _callback)
|
||||
@@ -0,0 +1,51 @@
|
||||
/datum/component/turf_decal
|
||||
var/dir
|
||||
var/icon
|
||||
var/icon_state
|
||||
var/layer
|
||||
var/group
|
||||
|
||||
/datum/component/turf_decal/Initialize(_dir, _icon, _icon_state, _layer=TURF_DECAL_LAYER, _group=TURF_DECAL_PAINT)
|
||||
if(!isturf(parent) || !_icon || !_icon_state)
|
||||
WARNING("A turf decal was applied incorrectly to [parent]: icon:[_icon ? _icon : "none"] icon_state:[_icon_state ? _icon_state : "none"]")
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
dir = _dir
|
||||
icon = _icon
|
||||
icon_state = _icon_state
|
||||
layer = _layer
|
||||
group = _group
|
||||
apply_decal()
|
||||
|
||||
RegisterSignal(COMSIG_ATOM_ROTATE, .proc/rotate_react)
|
||||
RegisterSignal(COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_react)
|
||||
|
||||
/datum/component/turf_decal/Destroy()
|
||||
remove_decal()
|
||||
return ..()
|
||||
|
||||
/datum/component/turf_decal/OnTransfer(turf/newT)
|
||||
remove_decal()
|
||||
remove_decal(newT)
|
||||
apply_decal(newT)
|
||||
|
||||
/datum/component/turf_decal/proc/get_decal()
|
||||
return image(icon, null, icon_state, layer, dir)
|
||||
|
||||
/datum/component/turf_decal/proc/apply_decal(turf/overT)
|
||||
var/turf/master = overT || parent
|
||||
master.add_decal(get_decal(), group)
|
||||
|
||||
/datum/component/turf_decal/proc/remove_decal(turf/overT)
|
||||
var/turf/master = overT || parent
|
||||
master.remove_decal(group)
|
||||
|
||||
/datum/component/turf_decal/proc/rotate_react(rotation, params)
|
||||
if(params & ROTATE_DIR)
|
||||
dir = angle2dir(rotation+dir2angle(dir))
|
||||
remove_decal()
|
||||
apply_decal()
|
||||
|
||||
/datum/component/turf_decal/proc/clean_react(strength)
|
||||
if(strength >= CLEAN_IMPRESSIVE)
|
||||
qdel(src)
|
||||
@@ -3,6 +3,8 @@
|
||||
var/list/active_timers //for SStimer
|
||||
var/list/datum_components //for /datum/components
|
||||
var/ui_screen = "home" //for tgui
|
||||
var/use_tag = FALSE
|
||||
var/datum/weakref/weak_reference
|
||||
|
||||
#ifdef TESTING
|
||||
var/running_find_references
|
||||
@@ -12,8 +14,9 @@
|
||||
// Default implementation of clean-up code.
|
||||
// This should be overridden to remove all references pointing to the object being destroyed.
|
||||
// Return the appropriate QDEL_HINT; in most cases this is QDEL_HINT_QUEUE.
|
||||
/datum/proc/Destroy(force=FALSE)
|
||||
/datum/proc/Destroy(force=FALSE, ...)
|
||||
tag = null
|
||||
weak_reference = null //ensure prompt GCing of weakref.
|
||||
var/list/timers = active_timers
|
||||
active_timers = null
|
||||
for(var/thing in timers)
|
||||
@@ -24,14 +27,12 @@
|
||||
var/list/dc = datum_components
|
||||
if(dc)
|
||||
var/all_components = dc[/datum/component]
|
||||
if(islist(all_components))
|
||||
if(length(all_components))
|
||||
for(var/I in all_components)
|
||||
var/datum/component/C = I
|
||||
C._RemoveFromParent()
|
||||
qdel(C)
|
||||
qdel(C, FALSE, TRUE)
|
||||
else
|
||||
var/datum/component/C = all_components
|
||||
C._RemoveFromParent()
|
||||
qdel(C)
|
||||
qdel(C, FALSE, TRUE)
|
||||
dc.Cut()
|
||||
return QDEL_HINT_QUEUE
|
||||
|
||||
+23
-18
@@ -25,10 +25,10 @@
|
||||
/datum/proc/vv_get_dropdown()
|
||||
. = list()
|
||||
. += "---"
|
||||
.["Call Proc"] = "?_src_=vars;[HrefToken()];proc_call=\ref[src]"
|
||||
.["Mark Object"] = "?_src_=vars;[HrefToken()];mark_object=\ref[src]"
|
||||
.["Delete"] = "?_src_=vars;[HrefToken()];delete=\ref[src]"
|
||||
.["Show VV To Player"] = "?_src_=vars;[HrefToken(TRUE)];expose=\ref[src]"
|
||||
.["Call Proc"] = "?_src_=vars;[HrefToken()];proc_call=[REF(src)]"
|
||||
.["Mark Object"] = "?_src_=vars;[HrefToken()];mark_object=[REF(src)]"
|
||||
.["Delete"] = "?_src_=vars;[HrefToken()];delete=[REF(src)]"
|
||||
.["Show VV To Player"] = "?_src_=vars;[HrefToken(TRUE)];expose=[REF(src)]"
|
||||
|
||||
|
||||
/datum/proc/on_reagent_change()
|
||||
@@ -53,7 +53,7 @@
|
||||
return
|
||||
|
||||
var/title = ""
|
||||
var/refid = "\ref[D]"
|
||||
var/refid = REF(D)
|
||||
var/icon/sprite
|
||||
var/hash
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
hash = md5(hash + AT.icon_state)
|
||||
src << browse_rsc(sprite, "vv[hash].png")
|
||||
|
||||
title = "[D] (\ref[D]) = [type]"
|
||||
title = "[D] ([REF(D)]) = [type]"
|
||||
|
||||
var/sprite_text
|
||||
if(sprite)
|
||||
@@ -394,9 +394,9 @@
|
||||
name = DA[name] //name is really the index until this line
|
||||
else
|
||||
value = DA[name]
|
||||
header = "<li style='backgroundColor:white'>(<a href='?_src_=vars;[HrefToken()];listedit=\ref[DA];index=[index]'>E</a>) (<a href='?_src_=vars;[HrefToken()];listchange=\ref[DA];index=[index]'>C</a>) (<a href='?_src_=vars;[HrefToken()];listremove=\ref[DA];index=[index]'>-</a>) "
|
||||
header = "<li style='backgroundColor:white'>(<a href='?_src_=vars;[HrefToken()];listedit=[REF(DA)];index=[index]'>E</a>) (<a href='?_src_=vars;[HrefToken()];listchange=[REF(DA)];index=[index]'>C</a>) (<a href='?_src_=vars;[HrefToken()];listremove=[REF(DA)];index=[index]'>-</a>) "
|
||||
else
|
||||
header = "<li style='backgroundColor:white'>(<a href='?_src_=vars;[HrefToken()];datumedit=\ref[DA];varnameedit=[name]'>E</a>) (<a href='?_src_=vars;[HrefToken()];datumchange=\ref[DA];varnamechange=[name]'>C</a>) (<a href='?_src_=vars;[HrefToken()];datummass=\ref[DA];varnamemass=[name]'>M</a>) "
|
||||
header = "<li style='backgroundColor:white'>(<a href='?_src_=vars;[HrefToken()];datumedit=[REF(DA)];varnameedit=[name]'>E</a>) (<a href='?_src_=vars;[HrefToken()];datumchange=[REF(DA)];varnamechange=[name]'>C</a>) (<a href='?_src_=vars;[HrefToken()];datummass=[REF(DA)];varnamemass=[name]'>M</a>) "
|
||||
else
|
||||
header = "<li>"
|
||||
|
||||
@@ -411,7 +411,7 @@
|
||||
#ifdef VARSICON
|
||||
var/icon/I = new/icon(value)
|
||||
var/rnd = rand(1,10000)
|
||||
var/rname = "tmp\ref[I][rnd].png"
|
||||
var/rname = "tmp[REF(I)][rnd].png"
|
||||
usr << browse_rsc(I, rname)
|
||||
item = "[VV_HTML_ENCODE(name)] = (<span class='value'>[value]</span>) <img class=icon src=\"[rname]\">"
|
||||
#else
|
||||
@@ -423,8 +423,8 @@
|
||||
var/rnd = rand(1, 10000)
|
||||
var/image/I = value
|
||||
|
||||
src << browse_rsc(I.icon, "tmp\ref[value][rnd].png")
|
||||
html += "[name] = <img src=\"tmp\ref[value][rnd].png\">"
|
||||
src << browse_rsc(I.icon, "tmp[REF(value)][rnd].png")
|
||||
html += "[name] = <img src=\"tmp[REF(value)][rnd].png\">"
|
||||
#else
|
||||
html += "[name] = /image (<span class='value'>[value]</span>)"
|
||||
#endif
|
||||
@@ -434,14 +434,14 @@
|
||||
|
||||
//else if (istype(value, /client))
|
||||
// var/client/C = value
|
||||
// item = "<a href='?_src_=vars;Vars=\ref[value]'>[VV_HTML_ENCODE(name)] \ref[value]</a> = [C] [C.type]"
|
||||
// item = "<a href='?_src_=vars;Vars=[REF(value)]'>[VV_HTML_ENCODE(name)] [REF(value)]</a> = [C] [C.type]"
|
||||
|
||||
else if (istype(value, /datum))
|
||||
var/datum/D = value
|
||||
if ("[D]" != "[D.type]") //if the thing as a name var, lets use it.
|
||||
item = "<a href='?_src_=vars;[HrefToken()];Vars=\ref[value]'>[VV_HTML_ENCODE(name)] \ref[value]</a> = [D] [D.type]"
|
||||
item = "<a href='?_src_=vars;[HrefToken()];Vars=[REF(value)]'>[VV_HTML_ENCODE(name)] [REF(value)]</a> = [D] [D.type]"
|
||||
else
|
||||
item = "<a href='?_src_=vars;[HrefToken()];Vars=\ref[value]'>[VV_HTML_ENCODE(name)] \ref[value]</a> = [D.type]"
|
||||
item = "<a href='?_src_=vars;[HrefToken()];Vars=[REF(value)]'>[VV_HTML_ENCODE(name)] [REF(value)]</a> = [D.type]"
|
||||
|
||||
else if (islist(value))
|
||||
var/list/L = value
|
||||
@@ -453,15 +453,15 @@
|
||||
var/val
|
||||
if (IS_NORMAL_LIST(L) && !isnum(key))
|
||||
val = L[key]
|
||||
if (!val)
|
||||
if (isnull(val)) // we still want to display non-null false values, such as 0 or ""
|
||||
val = key
|
||||
key = i
|
||||
|
||||
items += debug_variable(key, val, level + 1, sanitize = sanitize)
|
||||
|
||||
item = "<a href='?_src_=vars;[HrefToken()];Vars=\ref[value]'>[VV_HTML_ENCODE(name)] = /list ([L.len])</a><ul>[items.Join()]</ul>"
|
||||
item = "<a href='?_src_=vars;[HrefToken()];Vars=[REF(value)]'>[VV_HTML_ENCODE(name)] = /list ([L.len])</a><ul>[items.Join()]</ul>"
|
||||
else
|
||||
item = "<a href='?_src_=vars;[HrefToken()];Vars=\ref[value]'>[VV_HTML_ENCODE(name)] = /list ([L.len])</a>"
|
||||
item = "<a href='?_src_=vars;[HrefToken()];Vars=[REF(value)]'>[VV_HTML_ENCODE(name)] = /list ([L.len])</a>"
|
||||
|
||||
else
|
||||
item = "[VV_HTML_ENCODE(name)] = <span class='value'>[VV_HTML_ENCODE(value)]</span>"
|
||||
@@ -537,6 +537,11 @@
|
||||
admin_delete(D)
|
||||
href_list["datumrefresh"] = href_list["delete"]
|
||||
|
||||
else if(href_list["osay"])
|
||||
if(!check_rights(R_FUN, 0))
|
||||
return
|
||||
usr.client.object_say(locate(href_list["osay"]))
|
||||
|
||||
else if(href_list["regenerateicons"])
|
||||
if(!check_rights(0))
|
||||
return
|
||||
@@ -561,7 +566,7 @@
|
||||
var/prompt = alert("Do you want to grant [C] access to view this VV window? (they will not be able to edit or change anything nor open nested vv windows unless they themselves are an admin)", "Confirm", "Yes", "No")
|
||||
if (prompt != "Yes" || !usr.client)
|
||||
return
|
||||
message_admins("[key_name_admin(usr)] Showed [key_name_admin(C)] a <a href='?_src_=vars;[HrefToken(TRUE)];datumrefresh=\ref[thing]'>VV window</a>")
|
||||
message_admins("[key_name_admin(usr)] Showed [key_name_admin(C)] a <a href='?_src_=vars;[HrefToken(TRUE)];datumrefresh=[REF(thing)]'>VV window</a>")
|
||||
log_admin("Admin [key_name(usr)] Showed [key_name(C)] a VV window of a [thing]")
|
||||
to_chat(C, "[usr.client.holder.fakekey ? "an Administrator" : "[usr.client.key]"] has granted you access to view a View Variables window")
|
||||
C.debug_variables(thing)
|
||||
|
||||
@@ -416,7 +416,7 @@
|
||||
for(var/datum/disease/advance/AD in SSdisease.active_diseases)
|
||||
AD.Refresh()
|
||||
|
||||
for(var/mob/living/carbon/human/H in shuffle(GLOB.living_mob_list))
|
||||
for(var/mob/living/carbon/human/H in shuffle(GLOB.alive_mob_list))
|
||||
if(!(H.z in GLOB.station_z_levels))
|
||||
continue
|
||||
if(!H.HasDisease(D))
|
||||
|
||||
+19
-17
@@ -1,5 +1,6 @@
|
||||
#define EXPLOSION_THROW_SPEED 4
|
||||
#define REEBE_HUGBOX_COEFFICIENT 0.5
|
||||
#define CITYOFCOGS_CAP_MULTIPLIER 0.5
|
||||
#define MINING_CAP_MULTIPLIER 3
|
||||
|
||||
GLOBAL_LIST_EMPTY(explosions)
|
||||
//Against my better judgement, I will return the explosion datum
|
||||
@@ -53,21 +54,21 @@ GLOBAL_LIST_EMPTY(explosions)
|
||||
var/orig_dev_range = devastation_range
|
||||
var/orig_heavy_range = heavy_impact_range
|
||||
var/orig_light_range = light_impact_range
|
||||
|
||||
if(!ignorecap && epicenter.z != ZLEVEL_MINING)
|
||||
//Clamp all values to MAX_EXPLOSION_RANGE
|
||||
devastation_range = min(GLOB.MAX_EX_DEVESTATION_RANGE, devastation_range)
|
||||
heavy_impact_range = min(GLOB.MAX_EX_HEAVY_RANGE, heavy_impact_range)
|
||||
light_impact_range = min(GLOB.MAX_EX_LIGHT_RANGE, light_impact_range)
|
||||
flash_range = min(GLOB.MAX_EX_FLASH_RANGE, flash_range)
|
||||
flame_range = min(GLOB.MAX_EX_FLAME_RANGE, flame_range)
|
||||
|
||||
if(!ignorecap && epicenter.z == ZLEVEL_CITYOFCOGS)
|
||||
devastation_range = min(GLOB.MAX_EX_DEVESTATION_RANGE * REEBE_HUGBOX_COEFFICIENT, devastation_range)
|
||||
heavy_impact_range = min(GLOB.MAX_EX_HEAVY_RANGE * REEBE_HUGBOX_COEFFICIENT, heavy_impact_range)
|
||||
light_impact_range = min(GLOB.MAX_EX_LIGHT_RANGE * REEBE_HUGBOX_COEFFICIENT, light_impact_range)
|
||||
flash_range = min(GLOB.MAX_EX_FLASH_RANGE * REEBE_HUGBOX_COEFFICIENT, flash_range)
|
||||
flame_range = min(GLOB.MAX_EX_FLAME_RANGE * REEBE_HUGBOX_COEFFICIENT, flame_range)
|
||||
|
||||
//Zlevel specific bomb cap multiplier
|
||||
var/cap_multiplier = 1
|
||||
switch(epicenter.z)
|
||||
if(ZLEVEL_CITYOFCOGS)
|
||||
cap_multiplier = CITYOFCOGS_CAP_MULTIPLIER
|
||||
if(ZLEVEL_MINING)
|
||||
cap_multiplier = MINING_CAP_MULTIPLIER
|
||||
|
||||
if(!ignorecap)
|
||||
devastation_range = min(GLOB.MAX_EX_DEVESTATION_RANGE * cap_multiplier, devastation_range)
|
||||
heavy_impact_range = min(GLOB.MAX_EX_HEAVY_RANGE * cap_multiplier, heavy_impact_range)
|
||||
light_impact_range = min(GLOB.MAX_EX_LIGHT_RANGE * cap_multiplier, light_impact_range)
|
||||
flash_range = min(GLOB.MAX_EX_FLASH_RANGE * cap_multiplier, flash_range)
|
||||
flame_range = min(GLOB.MAX_EX_FLAME_RANGE * cap_multiplier, flame_range)
|
||||
|
||||
//DO NOT REMOVE THIS STOPLAG, IT BREAKS THINGS
|
||||
//not sleeping causes us to ex_act() the thing that triggered the explosion
|
||||
@@ -397,4 +398,5 @@ GLOBAL_LIST_EMPTY(explosions)
|
||||
// 5 explosion power is a (0, 1, 3) explosion.
|
||||
// 1 explosion power is a (0, 0, 1) explosion.
|
||||
|
||||
#undef REEBE_HUGBOX_COEFFICIENT
|
||||
#undef CITYOFCOGS_CAP_MULTIPLIER
|
||||
#undef MINING_CAP_MULTIPLIER
|
||||
|
||||
@@ -55,6 +55,9 @@
|
||||
to_chat(src, "[prefix]<a href=\"[CONFIG_GET(string/githuburl)]/commit/[pc]\">[copytext(pc, 1, min(length(pc), 7))]</a>")
|
||||
else
|
||||
to_chat(src, "Revision unknown")
|
||||
if(SERVER_TOOLS_PRESENT)
|
||||
to_chat(src, "Server tools version: [SERVER_TOOLS_VERSION]")
|
||||
to_chat(src, "Server tools API version: [SERVER_TOOLS_API_VERSION]")
|
||||
to_chat(src, "<b>Current Informational Settings:</b>")
|
||||
to_chat(src, "Protect Authority Roles From Traitor: [CONFIG_GET(flag/protect_roles_from_antagonist)]")
|
||||
to_chat(src, "Protect Assistant Role From Traitor: [CONFIG_GET(flag/protect_assistant_from_antagonist)]")
|
||||
|
||||
@@ -152,13 +152,14 @@
|
||||
if(istype(teleatom, /obj/item/storage/backpack/holding))
|
||||
precision = rand(1,100)
|
||||
|
||||
var/list/bagholding = teleatom.search_contents_for(/obj/item/storage/backpack/holding)
|
||||
var/static/list/bag_cache = typecacheof(/obj/item/storage/backpack/holding)
|
||||
var/list/bagholding = typecache_filter_list(teleatom.GetAllContents(), bag_cache)
|
||||
if(bagholding.len)
|
||||
precision = max(rand(1,100)*bagholding.len,100)
|
||||
if(isliving(teleatom))
|
||||
var/mob/living/MM = teleatom
|
||||
to_chat(MM, "<span class='warning'>The bluespace interface on your bag of holding interferes with the teleport!</span>")
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
// Safe location finder
|
||||
|
||||
|
||||
+13
-10
@@ -29,13 +29,12 @@ GLOBAL_LIST_INIT(huds, list(
|
||||
var/list/hud_icons = list() //these will be the indexes for the atom's hud_list
|
||||
|
||||
/datum/atom_hud/proc/remove_hud_from(mob/M)
|
||||
if(!M)
|
||||
if(!M || !hudusers[M])
|
||||
return
|
||||
if(src in M.permanent_huds)
|
||||
return
|
||||
for(var/atom/A in hudatoms)
|
||||
remove_from_single_hud(M, A)
|
||||
hudusers -= M
|
||||
if (!--hudusers[M])
|
||||
hudusers -= M
|
||||
for(var/atom/A in hudatoms)
|
||||
remove_from_single_hud(M, A)
|
||||
|
||||
/datum/atom_hud/proc/remove_from_hud(atom/A)
|
||||
if(!A)
|
||||
@@ -54,9 +53,12 @@ GLOBAL_LIST_INIT(huds, list(
|
||||
/datum/atom_hud/proc/add_hud_to(mob/M)
|
||||
if(!M)
|
||||
return
|
||||
hudusers[M] = TRUE
|
||||
for(var/atom/A in hudatoms)
|
||||
add_to_single_hud(M, A)
|
||||
if (!hudusers[M])
|
||||
hudusers[M] = 1
|
||||
for(var/atom/A in hudatoms)
|
||||
add_to_single_hud(M, A)
|
||||
else
|
||||
hudusers[M]++
|
||||
|
||||
/datum/atom_hud/proc/add_to_hud(atom/A)
|
||||
if(!A)
|
||||
@@ -77,7 +79,8 @@ GLOBAL_LIST_INIT(huds, list(
|
||||
/mob/proc/reload_huds()
|
||||
for(var/datum/atom_hud/hud in (GLOB.huds|GLOB.active_alternate_appearances))
|
||||
if(hud && hud.hudusers[src])
|
||||
hud.add_hud_to(src)
|
||||
for(var/atom/A in hud.hudatoms)
|
||||
hud.add_to_single_hud(src, A)
|
||||
|
||||
/mob/dead/new_player/reload_huds()
|
||||
return
|
||||
|
||||
@@ -21,4 +21,25 @@
|
||||
mid_sounds = list('sound/machines/generator/generator_mid1.ogg'=1, 'sound/machines/generator/generator_mid2.ogg'=1, 'sound/machines/generator/generator_mid3.ogg'=1)
|
||||
mid_length = 4
|
||||
end_sound = 'sound/machines/generator/generator_end.ogg'
|
||||
volume = 40
|
||||
volume = 40
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/datum/looping_sound/deep_fryer
|
||||
start_sound = 'sound/machines/fryer/deep_fryer_immerse.ogg' //my immersions
|
||||
start_length = 10
|
||||
mid_sounds = list('sound/machines/fryer/deep_fryer_1.ogg' = 1, 'sound/machines/fryer/deep_fryer_2.ogg' = 1)
|
||||
mid_length = 2
|
||||
end_sound = 'sound/machines/fryer/deep_fryer_emerge.ogg'
|
||||
volume = 25
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/datum/looping_sound/microwave
|
||||
start_sound = 'sound/machines/microwave/microwave-start.ogg'
|
||||
start_length = 10
|
||||
mid_sounds = list('sound/machines/microwave/microwave-mid1.ogg'=10, 'sound/machines/microwave/microwave-mid2.ogg'=1)
|
||||
mid_length = 10
|
||||
end_sound = 'sound/machines/microwave/microwave-end.ogg'
|
||||
volume = 90
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/datum/looping_sound/active_outside_ashstorm
|
||||
mid_sounds = list(
|
||||
'sound/weather/ashstorm/outside/active_mid1.ogg'=1,
|
||||
'sound/weather/ashstorm/outside/active_mid1.ogg'=1,
|
||||
'sound/weather/ashstorm/outside/active_mid1.ogg'=1
|
||||
)
|
||||
mid_length = 80
|
||||
start_sound = 'sound/weather/ashstorm/outside/active_start.ogg'
|
||||
start_length = 130
|
||||
end_sound = 'sound/weather/ashstorm/outside/active_end.ogg'
|
||||
volume = 80
|
||||
|
||||
/datum/looping_sound/active_inside_ashstorm
|
||||
mid_sounds = list(
|
||||
'sound/weather/ashstorm/inside/active_mid1.ogg'=1,
|
||||
'sound/weather/ashstorm/inside/active_mid2.ogg'=1,
|
||||
'sound/weather/ashstorm/inside/active_mid3.ogg'=1
|
||||
)
|
||||
mid_length = 80
|
||||
start_sound = 'sound/weather/ashstorm/inside/active_start.ogg'
|
||||
start_length = 130
|
||||
end_sound = 'sound/weather/ashstorm/inside/active_end.ogg'
|
||||
volume = 80
|
||||
|
||||
/datum/looping_sound/weak_outside_ashstorm
|
||||
mid_sounds = list(
|
||||
'sound/weather/ashstorm/outside/weak_mid1.ogg'=1,
|
||||
'sound/weather/ashstorm/outside/weak_mid2.ogg'=1,
|
||||
'sound/weather/ashstorm/outside/weak_mid3.ogg'=1
|
||||
)
|
||||
mid_length = 80
|
||||
start_sound = 'sound/weather/ashstorm/outside/weak_start.ogg'
|
||||
start_length = 130
|
||||
end_sound = 'sound/weather/ashstorm/outside/weak_end.ogg'
|
||||
volume = 50
|
||||
|
||||
/datum/looping_sound/weak_inside_ashstorm
|
||||
mid_sounds = list(
|
||||
'sound/weather/ashstorm/inside/weak_mid1.ogg'=1,
|
||||
'sound/weather/ashstorm/inside/weak_mid2.ogg'=1,
|
||||
'sound/weather/ashstorm/inside/weak_mid3.ogg'=1
|
||||
)
|
||||
mid_length = 80
|
||||
start_sound = 'sound/weather/ashstorm/inside/weak_start.ogg'
|
||||
start_length = 130
|
||||
end_sound = 'sound/weather/ashstorm/inside/weak_end.ogg'
|
||||
volume = 50
|
||||
@@ -29,7 +29,7 @@
|
||||
var/config_max_users = 0
|
||||
var/config_min_users = 0
|
||||
var/voteweight = 1
|
||||
var/allow_custom_shuttles = "yes"
|
||||
var/allow_custom_shuttles = TRUE
|
||||
|
||||
/datum/map_config/New(filename = "data/next_map.json", default_to_box, delete_after)
|
||||
if(default_to_box)
|
||||
@@ -69,7 +69,7 @@
|
||||
map_file = json["map_file"]
|
||||
|
||||
minetype = json["minetype"] || minetype
|
||||
allow_custom_shuttles = json["allow_custom_shuttles"] == TRUE
|
||||
allow_custom_shuttles = json["allow_custom_shuttles"] != FALSE
|
||||
|
||||
var/jtcl = json["transition_config"]
|
||||
if(jtcl && jtcl != "default")
|
||||
|
||||
+77
-91
@@ -192,15 +192,10 @@
|
||||
qdel(O)
|
||||
|
||||
/datum/mind/proc/remove_changeling()
|
||||
if(src in SSticker.mode.changelings)
|
||||
SSticker.mode.changelings -= src
|
||||
current.remove_changeling_powers()
|
||||
if(changeling)
|
||||
qdel(changeling)
|
||||
changeling = null
|
||||
special_role = null
|
||||
remove_antag_equip()
|
||||
SSticker.mode.update_changeling_icons_removed(src)
|
||||
var/datum/antagonist/changeling/C = has_antag_datum(/datum/antagonist/changeling)
|
||||
if(C)
|
||||
remove_antag_datum(/datum/antagonist/changeling)
|
||||
special_role = null
|
||||
|
||||
/datum/mind/proc/remove_traitor()
|
||||
if(src in SSticker.mode.traitors)
|
||||
@@ -255,7 +250,6 @@
|
||||
remove_wizard()
|
||||
remove_cultist()
|
||||
remove_rev()
|
||||
SSticker.mode.update_changeling_icons_removed(src)
|
||||
SSticker.mode.update_traitor_icons_removed(src)
|
||||
SSticker.mode.update_cult_icons_removed(src)
|
||||
|
||||
@@ -388,7 +382,7 @@
|
||||
|
||||
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>"
|
||||
out += "Assigned role: [assigned_role]. <a href='?src=\ref[src];role_edit=1'>Edit</a><br>"
|
||||
out += "Assigned role: [assigned_role]. <a href='?src=[REF(src)];role_edit=1'>Edit</a><br>"
|
||||
out += "Faction and special role: <b><font color='red'>[special_role]</font></b><br>"
|
||||
|
||||
var/list/sections = list(
|
||||
@@ -412,11 +406,11 @@
|
||||
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>!"
|
||||
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"
|
||||
@@ -434,7 +428,7 @@
|
||||
text = uppertext(text)
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
if(src in SSticker.mode.brothers)
|
||||
text += "<b>Brother</b> | <a href='?src=\ref[src];brother=clear'>no</a>"
|
||||
text += "<b>Brother</b> | <a href='?src=[REF(src)];brother=clear'>no</a>"
|
||||
|
||||
if(current && current.client && (ROLE_BROTHER in current.client.prefs.be_special))
|
||||
text += " | Enabled in Prefs"
|
||||
@@ -448,20 +442,15 @@
|
||||
if (SSticker.mode.config_tag=="changeling" || SSticker.mode.config_tag=="traitorchan")
|
||||
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>"
|
||||
var/datum/antagonist/changeling/C = has_antag_datum(/datum/antagonist/changeling)
|
||||
if(C)
|
||||
text += "<b>[C.name]</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>"
|
||||
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>"
|
||||
text += "<br>Objectives are empty! <a href='?src=[REF(src)];changeling=autoobjectives'>Randomize!</a>"
|
||||
if(C.stored_profiles.len && (current.real_name != C.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"
|
||||
@@ -477,7 +466,7 @@
|
||||
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)
|
||||
@@ -485,9 +474,9 @@
|
||||
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>"
|
||||
@@ -507,17 +496,17 @@
|
||||
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>."
|
||||
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>"
|
||||
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>"
|
||||
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"
|
||||
@@ -533,10 +522,10 @@
|
||||
text = uppertext(text)
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
if (has_antag_datum(/datum/antagonist/wizard))
|
||||
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>"
|
||||
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>"
|
||||
else
|
||||
text += "<a href='?src=\ref[src];wizard=wizard'>yes</a> | <b>NO</b>"
|
||||
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"
|
||||
@@ -563,28 +552,28 @@
|
||||
if(M && (M.z in GLOB.station_z_levels) && !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>"
|
||||
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>."
|
||||
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>."
|
||||
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)."
|
||||
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>."
|
||||
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"
|
||||
text += "head | <b>MINDSHIELDED</b> | employee | <a href='?src=[REF(src)];revolution=headrev'>headrev</a> | rev"
|
||||
else if (has_antag_datum(/datum/antagonist/rev))
|
||||
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>"
|
||||
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>"
|
||||
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"
|
||||
@@ -599,8 +588,8 @@
|
||||
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>"
|
||||
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>"
|
||||
|
||||
if(current && current.client && (ROLE_ABDUCTOR in current.client.prefs.be_special))
|
||||
text += " | Enabled in Prefs"
|
||||
@@ -618,13 +607,13 @@
|
||||
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>"
|
||||
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>"
|
||||
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>"
|
||||
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)];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"
|
||||
@@ -641,11 +630,11 @@
|
||||
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>"
|
||||
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>"
|
||||
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>"
|
||||
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
|
||||
@@ -660,10 +649,10 @@
|
||||
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>."
|
||||
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>"
|
||||
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>"
|
||||
|
||||
@@ -682,10 +671,10 @@
|
||||
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'>Equip</a>"
|
||||
text += "not mindshielded | <a href='?src=[REF(src)];clockcult=clear'>employee</a> | <b>SERVANT</b>"
|
||||
text += "<br><a href='?src=[REF(src)];clockcult=slab'>Equip</a>"
|
||||
else if(is_eligible_servant(current))
|
||||
text += "not mindshielded | <b>EMPLOYEE</b> | <a href='?src=\ref[src];clockcult=servant'>servant</a>"
|
||||
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>"
|
||||
|
||||
@@ -702,14 +691,14 @@
|
||||
text = "silicon"
|
||||
var/mob/living/silicon/robot/robot = current
|
||||
if (istype(robot) && robot.emagged)
|
||||
text += "<br>Cyborg: Is emagged! <a href='?src=\ref[src];silicon=unemag'>Unemag!</a><br>0th law: [robot.laws.zeroth]"
|
||||
text += "<br>Cyborg: Is emagged! <a href='?src=[REF(src)];silicon=unemag'>Unemag!</a><br>0th law: [robot.laws.zeroth]"
|
||||
var/mob/living/silicon/ai/ai = current
|
||||
if (istype(ai) && ai.connected_robots.len)
|
||||
var/n_e_robots = 0
|
||||
for (var/mob/living/silicon/robot/R in ai.connected_robots)
|
||||
if (R.emagged)
|
||||
n_e_robots++
|
||||
text += "<br>[n_e_robots] of [ai.connected_robots.len] slaved cyborgs are emagged. <a href='?src=\ref[src];silicon=unemagcyborgs'>Unemag</a>"
|
||||
text += "<br>[n_e_robots] of [ai.connected_robots.len] slaved cyborgs are emagged. <a href='?src=[REF(src)];silicon=unemagcyborgs'>Unemag</a>"
|
||||
if (SSticker.mode.config_tag == "traitorchan")
|
||||
if (sections["traitor"])
|
||||
out += sections["traitor"]+"<br>"
|
||||
@@ -727,12 +716,12 @@
|
||||
|
||||
|
||||
if(((src in SSticker.mode.traitors) || (src in SSticker.mode.syndicates)) && ishuman(current))
|
||||
text = "Uplink: <a href='?src=\ref[src];common=uplink'>give</a>"
|
||||
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"
|
||||
text += ", <a href='?src=[REF(src)];common=crystals'>[U.telecrystals]</a> TC"
|
||||
else
|
||||
text += ", [U.telecrystals] TC"
|
||||
text += "." //hiel grammar
|
||||
@@ -742,18 +731,18 @@
|
||||
|
||||
out += "<b>Memory:</b><br>"
|
||||
out += memory
|
||||
out += "<br><a href='?src=\ref[src];memory_edit=1'>Edit memory</a><br>"
|
||||
out += "<br><a href='?src=[REF(src)];memory_edit=1'>Edit memory</a><br>"
|
||||
out += "Objectives:<br>"
|
||||
if (objectives.len == 0)
|
||||
out += "EMPTY<br>"
|
||||
else
|
||||
var/obj_count = 1
|
||||
for(var/datum/objective/objective in objectives)
|
||||
out += "<B>[obj_count]</B>: [objective.explanation_text] <a href='?src=\ref[src];obj_edit=\ref[objective]'>Edit</a> <a href='?src=\ref[src];obj_delete=\ref[objective]'>Delete</a> <a href='?src=\ref[src];obj_completed=\ref[objective]'><font color=[objective.completed ? "green" : "red"]>Toggle Completion</font></a><br>"
|
||||
out += "<B>[obj_count]</B>: [objective.explanation_text] <a href='?src=[REF(src)];obj_edit=[REF(objective)]'>Edit</a> <a href='?src=[REF(src)];obj_delete=[REF(objective)]'>Delete</a> <a href='?src=[REF(src)];obj_completed=[REF(objective)]'><font color=[objective.completed ? "green" : "red"]>Toggle Completion</font></a><br>"
|
||||
obj_count++
|
||||
out += "<a href='?src=\ref[src];obj_add=1'>Add objective</a><br><br>"
|
||||
out += "<a href='?src=[REF(src)];obj_add=1'>Add objective</a><br><br>"
|
||||
|
||||
out += "<a href='?src=\ref[src];obj_announce=1'>Announce objectives</a><br><br>"
|
||||
out += "<a href='?src=[REF(src)];obj_announce=1'>Announce objectives</a><br><br>"
|
||||
|
||||
var/datum/browser/popup = new(usr, "edit_memory", "", 600, 600)
|
||||
popup.set_content(out)
|
||||
@@ -955,7 +944,7 @@
|
||||
log_admin("[key_name(usr)] has rev'ed [current].")
|
||||
else
|
||||
return
|
||||
|
||||
|
||||
if("headrev")
|
||||
if(has_antag_datum(/datum/antagonist/rev))
|
||||
var/datum/antagonist/rev/rev = has_antag_datum(/datum/antagonist/rev)
|
||||
@@ -1050,30 +1039,29 @@
|
||||
else if (href_list["changeling"])
|
||||
switch(href_list["changeling"])
|
||||
if("clear")
|
||||
remove_changeling()
|
||||
remove_antag_datum(/datum/antagonist/changeling)
|
||||
special_role = null
|
||||
to_chat(current, "<span class='userdanger'>You grow weak and lose your powers! You are no longer a changeling and are stuck in your current form!</span>")
|
||||
message_admins("[key_name_admin(usr)] has de-changeling'ed [current].")
|
||||
log_admin("[key_name(usr)] has de-changeling'ed [current].")
|
||||
if("changeling")
|
||||
if(!(src in SSticker.mode.changelings))
|
||||
SSticker.mode.changelings += src
|
||||
current.make_changeling()
|
||||
special_role = "Changeling"
|
||||
to_chat(current, "<span class='boldannounce'>Your powers are awoken. A flash of memory returns to us...we are [changeling.changelingID], a changeling!</span>")
|
||||
message_admins("[key_name_admin(usr)] has changeling'ed [current].")
|
||||
log_admin("[key_name(usr)] has changeling'ed [current].")
|
||||
SSticker.mode.update_changeling_icons_added(src)
|
||||
var/datum/antagonist/changeling/C = make_Changling()
|
||||
to_chat(current, "<span class='boldannounce'>Our powers have awoken. A flash of memory returns to us...we are [C.changelingID], a changeling!</span>")
|
||||
message_admins("[key_name_admin(usr)] has changeling'ed [current].")
|
||||
log_admin("[key_name(usr)] has changeling'ed [current].")
|
||||
if("autoobjectives")
|
||||
SSticker.mode.forge_changeling_objectives(src)
|
||||
var/datum/antagonist/changeling/C = has_antag_datum(/datum/antagonist/changeling)
|
||||
if(C)
|
||||
C.forge_objectives()
|
||||
to_chat(usr, "<span class='notice'>The objectives for changeling [key] have been generated. You can edit them and anounce manually.</span>")
|
||||
|
||||
if("initialdna")
|
||||
if( !changeling || !changeling.stored_profiles.len || !iscarbon(current))
|
||||
var/datum/antagonist/changeling/ling = has_antag_datum(/datum/antagonist/changeling)
|
||||
if( !ling || !ling.stored_profiles.len || !iscarbon(current))
|
||||
to_chat(usr, "<span class='danger'>Resetting DNA failed!</span>")
|
||||
else
|
||||
var/mob/living/carbon/C = current
|
||||
changeling.first_prof.dna.transfer_identity(C, transfer_SE=1)
|
||||
C.real_name = changeling.first_prof.name
|
||||
ling.first_prof.dna.transfer_identity(C, transfer_SE=1)
|
||||
C.real_name = ling.first_prof.name
|
||||
C.updateappearance(mutcolor_update=1)
|
||||
C.domutcheck()
|
||||
|
||||
@@ -1408,13 +1396,11 @@
|
||||
current.real_name = "[syndicate_name()] Operative #[SSticker.mode.syndicates.len-1]"
|
||||
|
||||
/datum/mind/proc/make_Changling()
|
||||
if(!(src in SSticker.mode.changelings))
|
||||
SSticker.mode.changelings += src
|
||||
current.make_changeling()
|
||||
var/datum/antagonist/changeling/C = has_antag_datum(/datum/antagonist/changeling)
|
||||
if(!C)
|
||||
C = add_antag_datum(/datum/antagonist/changeling)
|
||||
special_role = "Changeling"
|
||||
SSticker.mode.forge_changeling_objectives(src)
|
||||
SSticker.mode.greet_changeling(src)
|
||||
SSticker.mode.update_changeling_icons_added(src)
|
||||
return C
|
||||
|
||||
/datum/mind/proc/make_Wizard()
|
||||
if(!has_antag_datum(/datum/antagonist/wizard))
|
||||
|
||||
@@ -98,7 +98,8 @@
|
||||
/obj/structure/cable,
|
||||
/obj/machinery/atmospherics,
|
||||
/obj/item/ammo_casing,
|
||||
/obj/item/implant
|
||||
/obj/item/implant,
|
||||
/obj/singularity
|
||||
))
|
||||
if(!can_contaminate || blacklisted[thing.type])
|
||||
continue
|
||||
|
||||
@@ -142,7 +142,7 @@
|
||||
/datum/map_template/ruin/lavaland/ufo_crash
|
||||
name = "UFO Crash"
|
||||
id = "ufo-crash"
|
||||
description = "Turns out that keeping your abductees unconcious is really important. Who knew?"
|
||||
description = "Turns out that keeping your abductees unconscious is really important. Who knew?"
|
||||
suffix = "lavaland_surface_ufo_crash.dmm"
|
||||
cost = 5
|
||||
|
||||
|
||||
@@ -149,7 +149,7 @@
|
||||
suffix = "mini"
|
||||
name = "Ministation emergency shuttle"
|
||||
credit_cost = 1000
|
||||
description = "Despite it's namesake, this shuttle is actually only slightly smaller than standard, and still complete with a brig and medbay."
|
||||
description = "Despite its namesake, this shuttle is actually only slightly smaller than standard, and still complete with a brig and medbay."
|
||||
|
||||
/datum/map_template/shuttle/emergency/scrapheap
|
||||
suffix = "scrapheap"
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
this["desc"] = ""
|
||||
this["refs"] = list()
|
||||
for(var/spawner_obj in GLOB.mob_spawners[spawner])
|
||||
this["refs"] += "\ref[spawner_obj]"
|
||||
this["refs"] += "[REF(spawner_obj)]"
|
||||
if(!this["desc"])
|
||||
if(istype(spawner_obj, /obj/effect/mob_spawn))
|
||||
var/obj/effect/mob_spawn/MS = spawner_obj
|
||||
@@ -40,6 +40,8 @@
|
||||
|
||||
var/spawner_ref = pick(GLOB.mob_spawners[params["name"]])
|
||||
var/obj/effect/mob_spawn/MS = locate(spawner_ref) in GLOB.poi_list
|
||||
if(!MS)
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("jump")
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user