Merge branch 'master' into upstream-merge-32161

This commit is contained in:
LetterJay
2017-11-11 23:02:13 -06:00
committed by GitHub
625 changed files with 27981 additions and 20284 deletions
+1 -1
View File
@@ -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)
+6 -3
View File
@@ -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
+1
View File
@@ -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)
+1 -1
View File
@@ -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"
+67
View File
@@ -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)))
+2 -2
View File
@@ -8,7 +8,7 @@
#define ismovableatom(A) (istype(A, /atom/movable))
#define isatom(A) (istype(A, /atom))
#define isatom(A) (isloc(A))
//Turfs
//#define isturf(A) (istype(A, /turf)) This is actually a byond built-in. Added here for completeness sake.
@@ -183,4 +183,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))
+1 -1
View File
@@ -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
+2
View File
@@ -10,6 +10,8 @@
#define T20C 293.15 // 20degC
#define TCMB 2.7 // -270.3degC
#define SHORT_REAL_LIMIT 16777216
//"fancy" math for calculating time in ms from tick_usage percentage and the length of ticks
//percent_of_tick_used * (ticklag * 100(to convert to ms)) / 100(percent ratio)
//collapsed to percent_of_tick_used * tick_lag
+29
View File
@@ -0,0 +1,29 @@
#define PROFILE_START ;PROFILE_STORE = list();PROFILE_SET;
#define PROFILE_STOP ;PROFILE_STORE = null;
#define PROFILE_SET ;PROFILE_TIME = TICK_USAGE_REAL; PROFILE_LINE = __LINE__; PROFILE_FILE = __FILE__; PROFILE_SLEEPCHECK = world.time;
#define PROFILE_TICK ;\
if (PROFILE_STORE) {\
var/PROFILE_TICK_USAGE_REAL = TICK_USAGE_REAL;\
if (PROFILE_SLEEPCHECK == world.time) {\
var/PROFILE_STRING = "[PROFILE_FILE]:[PROFILE_LINE] - [__FILE__]:[__LINE__]";\
var/list/PROFILE_ITEM = PROFILE_STORE[PROFILE_STRING];\
if (!PROFILE_ITEM) {\
PROFILE_ITEM = new(PROFILE_ITEM_LEN);\
PROFILE_STORE[PROFILE_STRING] = PROFILE_ITEM;\
PROFILE_ITEM[PROFILE_ITEM_TIME] = 0;\
PROFILE_ITEM[PROFILE_ITEM_COUNT] = 0;\
};\
PROFILE_ITEM[PROFILE_ITEM_TIME] += TICK_DELTA_TO_MS(PROFILE_TICK_USAGE_REAL-PROFILE_TIME);\
var/PROFILE_INCR_AMOUNT = min(1, 2**round(PROFILE_ITEM[PROFILE_ITEM_COUNT]/SHORT_REAL_LIMIT));\
if (prob(100/PROFILE_INCR_AMOUNT)) {\
PROFILE_ITEM[PROFILE_ITEM_COUNT] += PROFILE_INCR_AMOUNT;\
};\
};\
PROFILE_SET;\
};
#define PROFILE_ITEM_LEN 2
#define PROFILE_ITEM_TIME 1
#define PROFILE_ITEM_COUNT 2
+6 -1
View File
@@ -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
+69 -23
View File
@@ -1,23 +1,69 @@
//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')
+2
View File
@@ -0,0 +1,2 @@
#define WALL_DENT_HIT 1
#define WALL_DENT_SHOT 2
+9
View File
@@ -58,4 +58,13 @@ GLOBAL_VAR_INIT(cmp_field, "name")
. = B.failures - A.failures
if (!.)
. = B.qdels - A.qdels
/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))
/proc/cmp_profile_time_dsc(list/A, list/B)
return B[PROFILE_ITEM_TIME] - A[PROFILE_ITEM_TIME]
/proc/cmp_profile_count_dsc(list/A, list/B)
return B[PROFILE_ITEM_COUNT] - A[PROFILE_ITEM_COUNT]
+1 -1
View File
@@ -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.
+1 -1
View File
@@ -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)
+4 -2
View File
@@ -43,8 +43,10 @@
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)
var/datum/comm_message/message = new
message.title = title
message.content = text
C.add_message(message)
P.update_icon()
/proc/minor_announce(message, title = "Attention:", alert)
+1 -1
View File
@@ -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
+13
View File
@@ -518,6 +518,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)
+2 -1
View File
@@ -15,7 +15,7 @@
Override makes it so the alert is not replaced until cleared by a clear_alert with clear_override, and it's used for hallucinations.
*/
if(!category)
if(!category || QDELETED(src))
return
var/obj/screen/alert/thealert
@@ -629,4 +629,5 @@ so as to remain in compliance with the most up-to-date laws."
. = ..()
severity = 0
master = null
mob_viewer = null
screen_loc = ""
+177 -175
View File
@@ -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
+1 -1
View File
@@ -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
+7 -7
View File
@@ -53,19 +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))
+31
View File
@@ -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"
+5
View File
@@ -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)
+328 -17
View File
@@ -111,7 +111,7 @@
w_class = WEIGHT_CLASS_BULKY
can_suppress = 0
burst_size = 1
fire_delay = 20
fire_delay = 40
select = 0
actions_types = list()
casing_ejector = 0
@@ -140,14 +140,14 @@
/datum/supply_pack/security/armory/spinfusor
name = "Stormhammer Spinfusor Crate"
cost = 7000
cost = 14000
contains = list(/obj/item/gun/ballistic/automatic/spinfusor,
/obj/item/gun/ballistic/automatic/spinfusor)
crate_name = "spinfusor crate"
/datum/supply_pack/security/armory/spinfusorammo
name = "Spinfusor Disk Crate"
cost = 4000
cost = 7000
contains = list(/obj/item/ammo_box/aspinfusor,
/obj/item/ammo_box/aspinfusor,
/obj/item/ammo_box/aspinfusor,
@@ -210,19 +210,23 @@
/obj/item/projectile/bullet/mags
icon = 'icons/obj/guns/cit_guns.dmi'
icon_state = "magjectile"
damage = 25
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
icon = 'icons/obj/guns/cit_guns.dmi'
icon_state = "magjectile-nl"
damage = 2
knockdown = 15
stamina = 50
damage = 1
knockdown = 0
stamina = 30
armour_penetration = -10
light_range = 2
speed = 1.2
range = 25
light_color = LIGHT_COLOR_BLUE
@@ -378,19 +382,23 @@
/obj/item/projectile/bullet/magrifle
icon = 'icons/obj/guns/cit_guns.dmi'
icon_state = "magjectile-large"
damage = 30
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 = 5
knockdown = 30
stamina = 75
armour_penetration = 0
damage = 1
knockdown = 0
stamina = 35
armour_penetration = -10
light_range = 3
speed = 1.0
range = 35
light_color = LIGHT_COLOR_BLUE
///ammo casings///
@@ -443,7 +451,7 @@
can_suppress = 0
burst_size = 3
fire_delay = 2
spread = 15
spread = 30
recoil = 1
casing_ejector = 0
@@ -494,7 +502,7 @@
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"
@@ -719,8 +727,8 @@ obj/item/projectile/bullet/c10mm/soporific
if((blocked != 100) && isliving(target))
var/mob/living/L = target
L.blur_eyes(6)
if(L.staminaloss >= 60)
L.Sleeping(250)
if(L.getStaminaLoss() >= 60)
L.Sleeping(300)
else
L.adjustStaminaLoss(25)
return 1
@@ -753,7 +761,7 @@ obj/item/projectile/bullet/c10mm/soporific
/obj/item/projectile/bullet/cflechettes //shreds flesh and forces bleeding
name = "flechette (serrated)"
damage = 8
damage = 15
dismemberment = 10
armour_penetration = -80
@@ -921,3 +929,306 @@ obj/item/projectile/bullet/c10mm/soporific
materials = list(MAT_METAL = 7500, MAT_GLASS = 1000)
build_path = /obj/item/gun/energy/laser/practice/raygun
category = list("hacked", "Misc")
/*/////////////////////////////////////////////////////////////////////////////////////////////
The Recolourable Gun
*//////////////////////////////////////////////////////////////////////////////////////////////
/obj/item/gun/ballistic/automatic/pistol/p37
name = "\improper CX Mk.37P"
desc = "A modern reimagining of an old legendary gun, the Mk.37 is a handgun with a toggle-locking mechanism manufactured by CX Armories. \
This model is coated with a special polychromic material. \
Has a small warning on the receiver that boldly states 'WARNING: WILL DETONATE UPON UNAUTHORIZED USE'. \
Uses 9mm bullets loaded into proprietary magazines."
icon = 'icons/obj/guns/cit_guns.dmi'
icon_state = "p37"
w_class = WEIGHT_CLASS_NORMAL
spawnwithmagazine = FALSE
mag_type = /obj/item/ammo_box/magazine/m9mm/p37
can_suppress = FALSE
pin = /obj/item/device/firing_pin/dna/dredd //goes boom if whoever isn't DNA locked to it tries to use it
actions_types = list(/datum/action/item_action/pick_color)
var/frame_color = "#808080" //RGB
var/receiver_color = "#808080"
var/body_color = "#0098FF"
var/barrel_color = "#808080"
var/tip_color = "#808080"
var/arm_color = "#808080"
var/grip_color = "#00FFCB" //Does not actually colour the grip, just the lights surrounding it
var/energy_color = "#00FFCB"
///Defining all the colourable bits and displaying them///
/obj/item/gun/ballistic/automatic/pistol/p37/update_icon()
var/mutable_appearance/frame_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_frame")
var/mutable_appearance/receiver_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_receiver")
var/mutable_appearance/body_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_body")
var/mutable_appearance/barrel_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_barrel")
var/mutable_appearance/tip_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_tip")
var/mutable_appearance/grip_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_grip")
var/mutable_appearance/energy_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_light")
var/mutable_appearance/arm_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_arm")
var/mutable_appearance/arm_overlay_e = mutable_appearance('icons/obj/guns/cit_guns.dmi', "p37_arm-e")
if(frame_color)
frame_overlay.color = frame_color
if(receiver_color)
receiver_overlay.color = receiver_color
if(body_color)
body_overlay.color = body_color
if(barrel_color)
barrel_overlay.color = barrel_color
if(tip_color)
tip_overlay.color = tip_color
if(grip_color)
grip_overlay.color = grip_color
if(energy_color)
energy_overlay.color = energy_color
if(arm_color)
arm_overlay.color = arm_color
if(arm_color)
arm_overlay_e.color = arm_color
cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
add_overlay(frame_overlay)
add_overlay(receiver_overlay)
add_overlay(body_overlay)
add_overlay(barrel_overlay)
add_overlay(tip_overlay)
add_overlay(grip_overlay)
add_overlay(energy_overlay)
if(magazine) //does not need a cut_overlays proc call here because it's already called further up
add_overlay("p37_mag")
if(chambered)
cut_overlay(arm_overlay_e)
add_overlay(arm_overlay)
else
cut_overlay(arm_overlay)
add_overlay(arm_overlay_e)
///letting you actually recolor things///
/obj/item/gun/ballistic/automatic/pistol/p37/ui_action_click(mob/user, var/datum/action/A)
if(istype(A, /datum/action/item_action/pick_color))
var/choice = input(user,"Mk.37P polychrome options", "Gun Recolor") in list("Frame Color","Receiver Color","Body Color",
"Barrel Color", "Barrel Tip Color", "Grip Light Color",
"Light Color", "Arm Color", "*CANCEL*")
switch(choice)
if("Frame Color")
var/frame_color_input = input(usr,"Choose Frame Color") as color|null
if(frame_color_input)
frame_color = sanitize_hexcolor(frame_color_input, desired_format=6, include_crunch=1)
update_icon()
if("Receiver Color")
var/receiver_color_input = input(usr,"Choose Receiver Color") as color|null
if(receiver_color_input)
receiver_color = sanitize_hexcolor(receiver_color_input, desired_format=6, include_crunch=1)
update_icon()
if("Body Color")
var/body_color_input = input(usr,"Choose Body Color") as color|null
if(body_color_input)
body_color = sanitize_hexcolor(body_color_input, desired_format=6, include_crunch=1)
update_icon()
if("Barrel Color")
var/barrel_color_input = input(usr,"Choose Barrel Color") as color|null
if(barrel_color_input)
barrel_color = sanitize_hexcolor(barrel_color_input, desired_format=6, include_crunch=1)
update_icon()
if("Barrel Tip Color")
var/tip_color_input = input(usr,"Choose Barrel Tip Color") as color|null
if(tip_color_input)
tip_color = sanitize_hexcolor(tip_color_input, desired_format=6, include_crunch=1)
update_icon()
if("Grip Light Color")
var/grip_color_input = input(usr,"Choose Grip Light Color") as color|null
if(grip_color_input)
grip_color = sanitize_hexcolor(grip_color_input, desired_format=6, include_crunch=1)
update_icon()
if("Light Color")
var/energy_color_input = input(usr,"Choose Light Color") as color|null
if(energy_color_input)
energy_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
update_icon()
if("Arm Color")
var/arm_color_input = input(usr,"Choose Arm Color") as color|null
if(arm_color_input)
arm_color = sanitize_hexcolor(arm_color_input, desired_format=6, include_crunch=1)
update_icon()
A.UpdateButtonIcon()
else
..()
///boolets///
/obj/item/projectile/bullet/c9mm/frangible
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 = 5
stamina = 30
speed = 1.2
range = 14
knockdown = 0
/obj/item/ammo_casing/c9mm/frangible
name = "9mm frangible bullet casing"
desc = "A 9mm frangible bullet casing."
projectile_type = /obj/item/projectile/bullet/c9mm/frangible
/obj/item/ammo_casing/c9mm/rubber
name = "9mm rubber bullet casing"
desc = "A 9mm rubber bullet casing."
projectile_type = /obj/item/projectile/bullet/c9mm/rubber
/obj/item/ammo_box/magazine/m9mm/p37
name = "\improper P37 magazine (9mm frangible)"
desc = "A gun magazine. Loaded with plastic composite rounds which fragment upon impact to minimize collateral damage."
icon = 'icons/obj/guns/cit_guns.dmi'
icon_state = "11mm" //topkek
ammo_type = /obj/item/ammo_casing/c9mm/frangible
caliber = "9mm"
max_ammo = 11
multiple_sprites = 1
/obj/item/ammo_box/magazine/m9mm/p37/fmj
name = "\improper P37 magazine (9mm)"
ammo_type = /obj/item/ammo_casing/c9mm
desc = "A gun magazine. Loaded with conventional full metal jacket rounds."
/obj/item/ammo_box/magazine/m9mm/p37/rubber
name = "\improper P37 magazine (9mm Non-Lethal Rubbershot)"
ammo_type = /obj/item/ammo_casing/c9mm/rubber
desc = "A gun magazine. Loaded with less-than-lethal rubber bullets."
/obj/item/ammo_box/c9mm/frangible
name = "ammo box (9mm frangible)"
ammo_type = /obj/item/ammo_casing/c9mm/frangible
/obj/item/ammo_box/c9mm/rubber
name = "ammo box (9mm non-lethal rubbershot)"
ammo_type = /obj/item/ammo_casing/c9mm/rubber
/datum/design/c9mmfrag
name = "Box of 9mm Frangible Bullets"
id = "9mm_frag"
build_type = AUTOLATHE
materials = list(MAT_METAL = 25000)
build_path = /obj/item/ammo_box/c9mm/frangible
category = list("hacked", "Security")
/datum/design/c9mmrubber
name = "Box of 9mm Rubber Bullets"
id = "9mm_rubber"
build_type = AUTOLATHE
materials = list(MAT_METAL = 30000)
build_path = /obj/item/ammo_box/c9mm/rubber
category = list("initial", "Security")
///Security Variant///
/obj/item/gun/ballistic/automatic/pistol/p37/sec
name = "\improper CX Mk.37S"
desc = "A modern reimagining of an old legendary gun, the Mk.37 is a handgun with a toggle-locking mechanism manufactured by CX Armories. Uses 9mm bullets loaded into proprietary magazines."
spawnwithmagazine = FALSE
pin = /obj/item/device/firing_pin/implant/mindshield
actions_types = list() //so you can't recolor it
frame_color = "#808080" //RGB
receiver_color = "#808080"
body_color = "#282828"
barrel_color = "#808080"
tip_color = "#808080"
arm_color = "#800000"
grip_color = "#FFFF00" //Does not actually colour the grip, just the lights surrounding it
energy_color = "#FFFF00"
///Foam Variant because WE NEED MEMES///
/obj/item/gun/ballistic/automatic/pistol/p37/foam
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)
/datum/design/foam_p37
name = "Foam Force Mk.37F"
id = "foam_p37"
build_type = AUTOLATHE
materials = list(MAT_METAL = 15000, MAT_GLASS = 10000)
build_path = /obj/item/gun/ballistic/automatic/pistol/p37/foam
category = list("hacked", "Misc")
/*/////////////////////////////////////////////////////////////////////////////////////////////
The Recolourable Energy Gun
*//////////////////////////////////////////////////////////////////////////////////////////////
obj/item/gun/energy/e_gun/cx
name = "\improper CX Model D Energy Gun"
desc = "An overpriced hybrid energy gun with two settings: disable, and kill. Manufactured by CX Armories. Has a polychromic coating."
icon = 'icons/obj/guns/cit_guns.dmi'
icon_state = "cxe"
lefthand_file = 'icons/mob/citadel/guns_lefthand.dmi'
righthand_file = 'icons/mob/citadel/guns_righthand.dmi'
ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/laser)
origin_tech = "combat=4;magnets=3"
flight_x_offset = 15
flight_y_offset = 10
actions_types = list(/datum/action/item_action/pick_color)
var/body_color = "#252528"
obj/item/gun/energy/e_gun/cx/update_icon()
..()
var/mutable_appearance/body_overlay = mutable_appearance('icons/obj/guns/cit_guns.dmi', "cxegun_body")
if(body_color)
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")
var/body_color_input = input(usr,"Choose Body Color") as color|null
if(body_color_input)
body_color = sanitize_hexcolor(body_color_input, desired_format=6, include_crunch=1)
update_icon()
A.UpdateButtonIcon()
else
..()
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
+20 -6
View File
@@ -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
..()
@@ -372,3 +372,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)
+3 -3
View File
@@ -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)
+3 -1
View File
@@ -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)
+11
View File
@@ -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
+1 -1
View File
@@ -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()
+1 -1
View File
@@ -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))
+2 -2
View File
@@ -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
+3 -1
View File
@@ -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)
+1 -2
View File
@@ -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
+3 -3
View File
@@ -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)
+13 -7
View File
@@ -26,7 +26,7 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
### Defines
1. `COMPONENT_INCOMPATIBLE` Return this from `/datum/component/Initialize` to have the component be deleted if it's applied to an incorrect type. `parent` must not be modified if this is to be returned.
1. `COMPONENT_INCOMPATIBLE` Return this from `/datum/component/Initialize` or `datum/component/OnTransfer` to have the component be deleted if it's applied to an incorrect type. `parent` must not be modified if this is to be returned.
### Vars
@@ -42,12 +42,13 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
* `COMPONENT_DUPE_UNIQUE`: New component will be deleted, old component will first have `/datum/component/proc/InheritComponent(datum/component/new, TRUE)` on it
1. `/datum/component/var/dupe_type` (protected, type)
* Definition of a duplicate component type
* `null` means exact match on `type`
* `null` means exact match on `type` (default)
* Any other type means that and all subtypes
1. `/datum/component/var/list/signal_procs` (private)
* Associated lazy list of signals -> `/datum/callback`s that will be run when the parent datum recieves that signal
1. `/datum/component/var/datum/parent` (protected, read-only)
* The datum this component belongs to
* Never `null` in child procs
### Procs
@@ -72,7 +73,7 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
* Will only be called if a component's callback returns `TRUE`
1. `/datum/proc/TakeComponent(datum/component/C)` (public, final)
* Properly transfers ownership of a component from one datum to another
* Singals `COMSIG_COMPONENT_REMOVING` on the parent
* Signals `COMSIG_COMPONENT_REMOVING` on the parent
* Called on the datum you want to own the component with another datum's component
1. `/datum/proc/SendSignal(signal, ...)` (public, final)
* Call to send a signal to the components of the target datum
@@ -86,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`
@@ -96,10 +99,13 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
1. `/datum/component/proc/AfterComponentActivated()` (abstract, async)
* Called on a component that was activated after it's `parent`'s `ComponentActivated()` is called
1. `/datum/component/proc/OnTransfer(datum/new_parent)` (abstract, no-sleep)
* Called before the new `parent` is assigned in `TakeComponent()`, after the remove signal, before the added signal
* Called before `new_parent` is assigned to `parent` in `TakeComponent()`
* Allows the component to react to ownership transfers
1. `/datum/component/proc/_RemoveNoSignal()` (private, final)
* Internal, clears the parent var and removes the component from the parents component list
1. `/datum/component/proc/_RemoveFromParent()` (private, final)
* Clears `parent` and removes the component from it's component list
1. `/datum/component/proc/_CheckDupesAndJoinParent` (private, final)
* Tries to add the component to it's `parent`s `datum_components` list
* Properly handles duplicate situations based on the `dupe_mode` var
1. `/datum/component/proc/RegisterSignal(signal(string/list of strings), proc_ref(type), override(boolean))` (protected, final) (Consider removing for performance gainz)
* If signal is a list it will be as if RegisterSignal was called for each of the entries with the same following arguments
* Makes a component listen for the specified `signal` on it's `parent` datum.
+64 -44
View File
@@ -6,35 +6,45 @@
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)
/datum/component/proc/_CheckDupesAndJoinParent()
var/datum/P = parent
var/dm = dupe_mode
var/datum/component/old
if(dm != COMPONENT_DUPE_ALLOWED)
var/dt = dupe_type
var/datum/component/old
if(!dt)
old = P.GetExactComponent(type)
else
old = P.GetComponent(dt)
if(old)
//One or the other has to die
switch(dm)
if(COMPONENT_DUPE_UNIQUE)
old.InheritComponent(src, TRUE)
parent = null //prevent COMPONENT_REMOVING signal
qdel(src)
qdel(src, TRUE, TRUE)
return
if(COMPONENT_DUPE_HIGHLANDER)
InheritComponent(old, FALSE)
qdel(old)
//let the others know
P.SendSignal(COMSIG_COMPONENT_ADDED, src)
qdel(old, FALSE, TRUE)
//provided we didn't eat someone
if(!old)
//let the others know
P.SendSignal(COMSIG_COMPONENT_ADDED, src)
//lazy init the parent's dc list
var/list/dc = P.datum_components
@@ -47,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
@@ -70,35 +80,34 @@
/datum/component/proc/Initialize(...)
return
/datum/component/Destroy()
/datum/component/Destroy(force=FALSE, silent=FALSE)
enabled = FALSE
var/datum/P = parent
if(P)
_RemoveNoSignal()
if(!force)
_RemoveFromParent()
if(!silent)
P.SendSignal(COMSIG_COMPONENT_REMOVING, src)
parent = null
LAZYCLEARLIST(signal_procs)
return ..()
/datum/component/proc/_RemoveNoSignal()
/datum/component/proc/_RemoveFromParent()
var/datum/P = parent
if(P)
var/list/dc = P.datum_components
var/our_type = type
for(var/I in _GetInverseTypeList(our_type))
var/list/components_of_type = dc[I]
if(islist(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
else
dc[I] = subtracted
else //just us
dc -= I
if(!dc.len)
P.datum_components = null
parent = null
var/list/dc = P.datum_components
for(var/I in _GetInverseTypeList())
var/list/components_of_type = dc[I]
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
else
dc[I] = subtracted
else //just us
dc -= I
if(!dc.len)
P.datum_components = 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
@@ -112,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
@@ -125,8 +136,15 @@
set waitfor = FALSE
return
/datum/component/proc/_GetInverseTypeList(current_type)
. = list(current_type)
/datum/component/proc/_GetInverseTypeList(our_type = type)
#if DM_VERSION > 511
#warning Remove this hack for http://www.byond.com/forum/?post=73469
#endif
set invisibility = 101
//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
@@ -138,7 +156,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
@@ -174,7 +192,7 @@
if(!dc)
return null
. = dc[c_type]
if(islist(.))
if(length(.))
return .[1]
/datum/proc/GetExactComponent(c_type)
@@ -183,7 +201,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
@@ -194,14 +212,14 @@
if(!dc)
return null
. = dc[c_type]
if(!islist(.))
if(!length(.))
return list(.)
/datum/proc/AddComponent(new_type, ...)
var/nt = new_type
args[1] = src
var/datum/component/C = new nt(arglist(args))
return QDELING(C) ? GetComponent(new_type) : C
return QDELING(C) ? GetExactComponent(new_type) : C
/datum/proc/LoadComponent(component_type, ...)
. = GetComponent(component_type)
@@ -213,13 +231,15 @@
return
var/datum/helicopter = C.parent
if(helicopter == src)
//wat
//if we're taking to the same thing no need for anything
return
C._RemoveNoSignal()
if(C.OnTransfer(src) == COMPONENT_INCOMPATIBLE)
qdel(C)
return
C._RemoveFromParent()
helicopter.SendSignal(COMSIG_COMPONENT_REMOVING, C)
C.OnTransfer(src)
C.parent = src
SendSignal(COMSIG_COMPONENT_ADDED, C)
C._CheckDupesAndJoinParent()
/datum/proc/TransferComponents(datum/target)
var/list/dc = datum_components
+53
View File
@@ -0,0 +1,53 @@
/datum/component/decal
dupe_mode = COMPONENT_DUPE_ALLOWED
var/cleanable
var/mutable_appearance/pic
/datum/component/decal/Initialize(_icon, _icon_state, _dir, _cleanable=CLEAN_GOD, _color, _layer=TURF_LAYER)
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
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)
/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)
+9 -5
View File
@@ -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)
+60
View File
@@ -0,0 +1,60 @@
/datum/component/spooky
var/too_spooky = TRUE //will it spawn a new instrument?
/datum/component/spooky/Initialize()
RegisterSignal(COMSIG_ITEM_ATTACK, .proc/spectral_attack)
/datum/component/spooky/proc/spectral_attack(mob/living/carbon/C, mob/user)
if(ishuman(user)) //this weapon wasn't meant for mortals.
var/mob/living/carbon/human/U = user
if(!istype(U.dna.species, /datum/species/skeleton))
U.adjustStaminaLoss(35) //Extra Damage
U.Jitter(35)
U.stuttering = 20
if(U.getStaminaLoss() > 95)
to_chat(U, "<font color ='red', size ='4'><B>Your ears weren't meant for this spectral sound.</B></font>")
spectral_change(U)
return
if(ishuman(C))
var/mob/living/carbon/human/H = C
if(istype(H.dna.species, /datum/species/skeleton))
return ..() //undeads are unaffected by the spook-pocalypse.
if(istype(H.dna.species, /datum/species/zombie))
H.adjustStaminaLoss(25)
H.Knockdown(15) //zombies can't resist the doot
C.Jitter(35)
C.stuttering = 20
if((!istype(H.dna.species, /datum/species/skeleton)) && (!istype(H.dna.species, /datum/species/golem)) && (!istype(H.dna.species, /datum/species/android)) && (!istype(H.dna.species, /datum/species/jelly)))
C.adjustStaminaLoss(25) //boneless humanoids don't lose the will to live
to_chat(C, "<font color='red' size='4'><B>DOOT</B></span>")
spectral_change(H)
else //the sound will spook monkeys.
C.Jitter(15)
C.stuttering = 20
/datum/component/spooky/proc/spectral_change(mob/living/carbon/human/H, mob/user)
if((H.getStaminaLoss() > 95) && (!istype(H.dna.species, /datum/species/skeleton)) && (!istype(H.dna.species, /datum/species/golem)) && (!istype(H.dna.species, /datum/species/android)) && (!istype(H.dna.species, /datum/species/jelly)))
H.Knockdown(20)
H.set_species(/datum/species/skeleton)
H.visible_message("<span class='warning'>[H] has given up on life as a mortal.</span>")
var/T = get_turf(H)
if(too_spooky)
if(prob(30))
new/obj/item/device/instrument/saxophone/spectral(T)
else if(prob(30))
new/obj/item/device/instrument/trumpet/spectral(T)
else if(prob(30))
new/obj/item/device/instrument/trombone/spectral(T)
else
to_chat(H, "The spooky gods forgot to ship your instrument. Better luck next unlife.")
to_chat(H, "<B>You are the spooky skeleton!</B>")
to_chat(H, "A new life and identity has begun. Help your fellow skeletons into bringing out the spooky-pocalypse. You haven't forgotten your past life, and are still beholden to past loyalties.")
change_name(H) //time for a new name!
/datum/component/spooky/proc/change_name(mob/living/carbon/human/H)
var/t = stripped_input(H, "Enter your new skeleton name", H.real_name, null, MAX_NAME_LEN)
if(!t)
t = "spooky skeleton"
H.fully_replace_character_name(H.real_name, t)
+51
View File
@@ -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)
+4 -6
View File
@@ -13,7 +13,7 @@
// 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
var/list/timers = active_timers
active_timers = null
@@ -25,14 +25,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._RemoveNoSignal()
qdel(C)
qdel(C, FALSE, TRUE)
else
var/datum/component/C = all_components
C._RemoveNoSignal()
qdel(C)
qdel(C, FALSE, TRUE)
dc.Cut()
return QDEL_HINT_QUEUE
+19 -17
View File
@@ -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
+3 -2
View File
@@ -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
+47
View File
@@ -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
+9 -14
View File
@@ -13,7 +13,6 @@
//Order matters here.
var/list/transition_config = list(CENTCOM = SELFLOOPING,
CITY_OF_COGS = SELFLOOPING,
MAIN_STATION = CROSSLINKED,
EMPTY_AREA_1 = CROSSLINKED,
EMPTY_AREA_2 = CROSSLINKED,
@@ -69,12 +68,11 @@
map_path = json["map_path"]
map_file = json["map_file"]
minetype = json["minetype"]
allow_custom_shuttles = json["allow_custom_shuttles"]
minetype = json["minetype"] || minetype
allow_custom_shuttles = json["allow_custom_shuttles"] == TRUE
var/list/jtcl = json["transition_config"]
if(jtcl != "default")
var/jtcl = json["transition_config"]
if(jtcl && jtcl != "default")
transition_config.Cut()
for(var/I in jtcl)
@@ -87,25 +85,22 @@
CHECK_EXISTS("map_name")
CHECK_EXISTS("map_path")
CHECK_EXISTS("map_file")
CHECK_EXISTS("minetype")
CHECK_EXISTS("transition_config")
CHECK_EXISTS("allow_custom_shuttles")
var/path = GetFullMapPath(json["map_path"], json["map_file"])
if(!fexists(path))
log_world("Map file ([path]) does not exist!")
return
if(json["transition_config"] != "default")
if(!islist(json["transition_config"]))
var/tc = json["transition_config"]
if(tc != null && tc != "default")
if(!islist(tc))
log_world("transition_config is not a list!")
return
var/list/jtcl = json["transition_config"]
for(var/I in jtcl)
for(var/I in tc)
if(isnull(TransitionStringToEnum(I)))
log_world("Invalid transition_config option: [I]!")
if(isnull(TransitionStringToEnum(jtcl[I])))
if(isnull(TransitionStringToEnum(tc[I])))
log_world("Invalid transition_config option: [I]!")
return TRUE
+1 -1
View File
@@ -1039,7 +1039,7 @@
remove_wizard()
log_admin("[key_name(usr)] has de-wizard'ed [current].")
if("wizard")
if(has_antag_datum(/datum/antagonist/wizard))
if(!has_antag_datum(/datum/antagonist/wizard))
special_role = "Wizard"
add_antag_datum(/datum/antagonist/wizard)
message_admins("[key_name_admin(usr)] has wizard'ed [current].")
+18
View File
@@ -0,0 +1,18 @@
//these are real globals so you can use profiling to profile early world init stuff.
GLOBAL_REAL_VAR(list/PROFILE_STORE)
GLOBAL_REAL_VAR(PROFILE_LINE)
GLOBAL_REAL_VAR(PROFILE_FILE)
GLOBAL_REAL_VAR(PROFILE_SLEEPCHECK)
GLOBAL_REAL_VAR(PROFILE_TIME)
/proc/profile_show(user, sort = /proc/cmp_profile_avg_time_dsc)
sortTim(PROFILE_STORE, sort, TRUE)
var/list/lines = list()
for (var/entry in PROFILE_STORE)
var/list/data = PROFILE_STORE[entry]
lines += "[entry] => [num2text(data[PROFILE_ITEM_TIME], 10)]ms ([data[PROFILE_ITEM_COUNT]]) (avg:[num2text(data[PROFILE_ITEM_TIME]/(data[PROFILE_ITEM_COUNT] || 1), 99)])"
user << browse("<ol><li>[lines.Join("</li><li>")]</li></ol>", "window=[url_encode(GUID())]")
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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"
+2
View File
@@ -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")
+47 -4
View File
@@ -5,18 +5,15 @@
telegraph_message = "<span class='boldwarning'>An eerie moan rises on the wind. Sheets of burning ash blacken the horizon. Seek shelter.</span>"
telegraph_duration = 300
telegraph_sound = 'sound/lavaland/ash_storm_windup.ogg'
telegraph_overlay = "light_ash"
weather_message = "<span class='userdanger'><i>Smoldering clouds of scorching ash billow down around you! Get inside!</i></span>"
weather_duration_lower = 600
weather_duration_upper = 1200
weather_sound = 'sound/lavaland/ash_storm_start.ogg'
weather_overlay = "ash_storm"
end_message = "<span class='boldannounce'>The shrieking wind whips away the last of the ash and falls to its usual murmur. It should be safe to go outside now.</span>"
end_duration = 300
end_sound = 'sound/lavaland/ash_storm_end.ogg'
end_overlay = "light_ash"
area_type = /area/lavaland/surface/outdoors
@@ -26,6 +23,53 @@
probability = 90
var/datum/looping_sound/active_outside_ashstorm/sound_ao = new(list(), FALSE, TRUE)
var/datum/looping_sound/active_inside_ashstorm/sound_ai = new(list(), FALSE, TRUE)
var/datum/looping_sound/weak_outside_ashstorm/sound_wo = new(list(), FALSE, TRUE)
var/datum/looping_sound/weak_inside_ashstorm/sound_wi = new(list(), FALSE, TRUE)
/datum/weather/ash_storm/telegraph()
. = ..()
var/list/inside_areas = list()
var/list/outside_areas = list()
var/list/eligible_areas = SSmapping.areas_in_z["[target_z]"]
for(var/i in 1 to eligible_areas.len)
var/area/place = eligible_areas[i]
if(place.outdoors)
outside_areas += place
else
inside_areas += place
CHECK_TICK
sound_ao.output_atoms = outside_areas
sound_ai.output_atoms = inside_areas
sound_wo.output_atoms = outside_areas
sound_wi.output_atoms = inside_areas
sound_wo.start()
sound_wi.start()
/datum/weather/ash_storm/start()
. = ..()
sound_wo.stop()
sound_wi.stop()
sound_ao.start()
sound_ai.start()
/datum/weather/ash_storm/wind_down()
. = ..()
sound_ao.stop()
sound_ai.stop()
sound_wo.start()
sound_wi.start()
/datum/weather/ash_storm/end()
. = ..()
sound_wo.stop()
sound_wi.stop()
/datum/weather/ash_storm/proc/is_ash_immune(mob/living/L)
if(ismecha(L.loc)) //Mechs are immune
return TRUE
@@ -50,7 +94,6 @@
desc = "A passing ash storm blankets the area in harmless embers."
weather_message = "<span class='notice'>Gentle embers waft down around you like grotesque snow. The storm seems to have passed you by...</span>"
weather_sound = 'sound/lavaland/ash_storm_windup.ogg'
weather_overlay = "light_ash"
end_message = "<span class='notice'>The emberfall slows, stops. Another layer of hardened soot to the basalt beneath your feet.</span>"
+4 -4
View File
@@ -74,7 +74,7 @@
"white",
"yellow"
)
var/list/my_possible_colors = possible_colors.Copy()
for(var/wire in shuffle(wires))
@@ -163,9 +163,9 @@
for(var/wire in possible_wires)
if(prob(33))
pulse(wire)
remaining_pulses--
if(remaining_pulses >= 0)
break
remaining_pulses--
if(!remaining_pulses)
break
// Overridable Procs
/datum/wires/proc/interactable(mob/user)
+21 -23
View File
@@ -41,7 +41,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
power_environ = FALSE
valid_territory = FALSE
outdoors = TRUE
ambientsounds = list('sound/ambience/ambispace.ogg','sound/ambience/title2.ogg')
ambientsounds = SPACE
blob_allowed = FALSE //Eating up space doesn't count for victory as a blob.
/area/space/nearstation
@@ -65,6 +65,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
has_gravity = TRUE
blob_allowed = FALSE //Nope, no winning on the asteroid as a blob. Gotta eat the station.
valid_territory = FALSE
ambientsounds = MINING
/area/asteroid/cave
name = "Asteroid - Underground"
@@ -75,6 +76,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/asteroid/artifactroom
name = "Asteroid - Artifact"
icon_state = "cave"
ambientsounds = RUINS
/area/asteroid/artifactroom/Initialize()
. = ..()
@@ -96,14 +98,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
//Maintenance
/area/maintenance
ambientsounds = 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', //Xeno Breathing Hisses, Hahahaha I'm not even sorry.
'sound/voice/lowHiss3.ogg',
'sound/voice/lowHiss4.ogg')
ambientsounds = MAINTENANCE
valid_territory = FALSE
@@ -647,7 +642,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/chapel
icon_state = "chapel"
ambientsounds = list('sound/ambience/ambicha1.ogg','sound/ambience/ambicha2.ogg','sound/ambience/ambicha3.ogg','sound/ambience/ambicha4.ogg')
ambientsounds = HOLY
flags_1 = NONE
clockwork_warp_allowed = FALSE
clockwork_warp_fail = "The consecration here prevents you from warping in."
@@ -678,7 +673,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
//Engineering
/area/engine
ambientsounds = list('sound/ambience/ambisin1.ogg','sound/ambience/ambisin2.ogg','sound/ambience/ambisin3.ogg','sound/ambience/ambisin4.ogg')
ambientsounds = ENGINEERING
/area/engine/engine_smes
name = "Engineering SMES"
@@ -732,6 +727,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
valid_territory = FALSE
blob_allowed = FALSE
flags_1 = NONE
ambientsounds = ENGINEERING
/area/solar/asteroid/aft
name = "Aft Asteroid Solar"
@@ -858,37 +854,36 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
name = "Teleporter Room"
icon_state = "teleporter"
music = "signal"
ambientsounds = ENGINEERING
/area/teleporter/quantum/cargo
name = "Cargo Quantum Pad"
icon_state = "teleporter"
music = "signal"
/area/teleporter/quantum/docking
name = "Docking Quantum Pad"
icon_state = "teleporter"
music = "signal"
/area/teleporter/quantum/research
name = "Research Quantum Pad"
icon_state = "teleporter"
music = "signal"
/area/teleporter/quantum/security
name = "Security Quantum Pad"
icon_state = "teleporter"
music = "signal"
/area/gateway
name = "Gateway"
icon_state = "teleporter"
music = "signal"
ambientsounds = ENGINEERING
//MedBay
/area/medical
name = "Medical"
icon_state = "medbay3"
ambientsounds = MEDICAL
/area/medical/abandoned
name = "Abandoned Medbay"
@@ -952,7 +947,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/medical/morgue
name = "Morgue"
icon_state = "morgue"
ambientsounds = list('sound/ambience/ambimo1.ogg','sound/ambience/ambimo2.ogg')
ambientsounds = SPOOKY
/area/medical/chemistry
name = "Chemistry"
@@ -988,6 +983,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/security
name = "Security"
icon_state = "security"
ambientsounds = HIGHSEC
/area/security/main
name = "Security Office"
@@ -1029,7 +1025,6 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/security/detectives_office/private_investigators_office
name = "Private Investigator's Office"
icon_state = "detective"
ambientsounds = list('sound/ambience/ambidet1.ogg','sound/ambience/ambidet2.ogg')
/area/security/range
name = "Firing Range"
@@ -1310,6 +1305,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/construction
name = "Construction Area"
icon_state = "yellow"
ambientsounds = ENGINEERING
/area/construction/minisat_exterior
name = "Minisat Exterior"
@@ -1361,27 +1357,32 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/ai_monitored/security/armory
name = "Armory"
icon_state = "armory"
ambientsounds = HIGHSEC
/area/ai_monitored/storage/eva
name = "EVA Storage"
icon_state = "eva"
ambientsounds = HIGHSEC
/area/ai_monitored/storage/secure
name = "AI Satellite Storage"
icon_state = "storage"
ambientsounds = HIGHSEC
/area/ai_monitored/storage/emergency
name = "Emergency Storage"
icon_state = "storage"
ambientsounds = HIGHSEC
/area/ai_monitored/storage/satellite
name = "AI Satellite Maint"
icon_state = "storage"
ambientsounds = HIGHSEC
//Turret_protected
/area/ai_monitored/turret_protected
ambientsounds = list('sound/ambience/ambimalf.ogg')
ambientsounds = list('sound/ambience/ambimalf.ogg', 'sound/ambience/ambitech.ogg', 'sound/ambience/ambitech2.ogg', 'sound/ambience/ambiatmos.ogg', 'sound/ambience/ambiatmos2.ogg')
/area/ai_monitored/turret_protected/ai_upload
name = "AI Upload Chamber"
@@ -1450,7 +1451,8 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/tcommsat
clockwork_warp_allowed = FALSE
clockwork_warp_fail = "For safety reasons, warping here is disallowed; the radio and bluespace noise could cause catastrophic results."
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg', 'sound/ambience/ambitech.ogg',\
'sound/ambience/ambitech2.ogg', 'sound/ambience/ambitech3.ogg', 'sound/ambience/ambimystery.ogg')
/area/tcommsat/entrance
name = "Telecomms Teleporter"
@@ -1463,22 +1465,18 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/ai_monitored/turret_protected/tcomsat
name = "Telecomms Satellite"
icon_state = "tcomsatlob"
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
/area/ai_monitored/turret_protected/tcomfoyer
name = "Telecomms Foyer"
icon_state = "tcomsatentrance"
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
/area/ai_monitored/turret_protected/tcomwest
name = "Telecommunications Satellite West Wing"
icon_state = "tcomsatwest"
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
/area/ai_monitored/turret_protected/tcomeast
name = "Telecommunications Satellite East Wing"
icon_state = "tcomsateast"
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
/area/tcommsat/computer
name = "Telecomms Control Room"
+23 -9
View File
@@ -54,12 +54,7 @@
var/global/global_uid = 0
var/uid
var/list/ambientsounds = 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')
var/list/ambientsounds = GENERIC
flags_1 = CAN_BE_DIRTY_1
var/list/firedoors
@@ -107,7 +102,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
uid = ++global_uid
related = list(src)
map_name = name // Save the initial (the name set in the map) name of the area.
if(requires_power)
luminosity = 0
else
@@ -125,13 +120,32 @@ GLOBAL_LIST_EMPTY(teleportlocs)
. = ..()
power_change() // all machines set to current power level, also updates icon
blend_mode = BLEND_MULTIPLY // Putting this in the constructor so that it stops the icons being screwed up in the map editor.
if(!IS_DYNAMIC_LIGHTING(src))
add_overlay(/obj/effect/fullbright)
if(contents.len)
var/list/areas_in_z = SSmapping.areas_in_z
var/z
for(var/i in 1 to contents.len)
var/atom/thing = contents[i]
if(!thing)
continue
z = thing.z
break
if(!z)
WARNING("No z found for [src]")
return
if(!areas_in_z["[z]"])
areas_in_z["[z]"] = list()
areas_in_z["[z]"] += src
return INITIALIZE_HINT_LATELOAD
/area/LateInitialize()
power_change() // all machines set to current power level, also updates icon
/area/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
+2 -1
View File
@@ -8,6 +8,7 @@ Unused icons for new areas are "awaycontent1" ~ "awaycontent30"
name = "Strange Location"
icon_state = "away"
has_gravity = TRUE
ambientsounds = AWAY_MISSION
/area/awaymission/beach
name = "Beach"
@@ -15,7 +16,7 @@ Unused icons for new areas are "awaycontent1" ~ "awaycontent30"
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
requires_power = FALSE
has_gravity = TRUE
ambientsounds = list('sound/ambience/shore.ogg', 'sound/ambience/seag1.ogg','sound/ambience/seag2.ogg','sound/ambience/seag2.ogg')
ambientsounds = list('sound/ambience/shore.ogg', 'sound/ambience/seag1.ogg','sound/ambience/seag2.ogg','sound/ambience/seag2.ogg','sound/ambience/ambiodd.ogg','sound/ambience/ambinice.ogg')
/area/awaymission/errorroom
name = "Super Secret Room"
+1
View File
@@ -96,6 +96,7 @@
noteleport = TRUE
blob_allowed = FALSE //Not... entirely sure this will ever come up... but if the bus makes blobs AND ops, it shouldn't aim for the ops to win.
flags_1 = NONE
ambientsounds = HIGHSEC
/area/syndicate_mothership/control
name = "Syndicate Control Room"
+5 -4
View File
@@ -15,8 +15,8 @@
power_equip = FALSE
power_light = FALSE
outdoors = TRUE
ambientsounds = list('sound/ambience/ambimine.ogg')
flags_1 = NONE
ambientsounds = MINING
/area/mine/unexplored
name = "Mine"
@@ -29,8 +29,8 @@
power_equip = FALSE
power_light = FALSE
outdoors = TRUE
ambientsounds = list('sound/ambience/ambimine.ogg')
flags_1 = NONE
ambientsounds = MINING
/area/mine/lobby
name = "Mining Station"
@@ -77,6 +77,7 @@
/area/mine/laborcamp/security
name = "Labor Camp Security"
icon_state = "security"
ambientsounds = HIGHSEC
@@ -98,7 +99,7 @@
power_equip = FALSE
power_light = FALSE
requires_power = TRUE
ambientsounds = list('sound/ambience/ambilava.ogg')
ambientsounds = MINING
/area/lavaland/underground
name = "Lavaland Caves"
@@ -110,7 +111,7 @@
power_environ = FALSE
power_equip = FALSE
power_light = FALSE
ambientsounds = list('sound/ambience/ambilava.ogg')
ambientsounds = MINING
/area/lavaland/surface/outdoors
+4 -2
View File
@@ -5,6 +5,7 @@
//icon = "ICON FILENAME"
//icon_state = "NAME OF ICON"
requires_power = FALSE
ambientsounds = SPOOKY
/area/hell/trial1
name = "Hell Trial1"
@@ -32,6 +33,7 @@
/area/prison
name = "Prison Station"
icon_state = "brig"
ambientsounds = HIGHSEC
/area/prison/arrival_airlock
name = "Prison Station Airlock"
@@ -73,7 +75,7 @@
/area/prison/morgue
name = "Prison Morgue"
icon_state = "morgue"
ambientsounds = list('sound/ambience/ambimo1.ogg','sound/ambience/ambimo2.ogg')
ambientsounds = SPOOKY
/area/prison/medical_research
name = "Prison Genetic Research"
@@ -99,7 +101,7 @@
/area/prison/solitary
name = "Solitary Confinement"
icon_state = "brig"
/area/prison/execution_room
name = "Prisoner Education Chamber"
icon_state = "execution_room"
+1 -1
View File
@@ -6,6 +6,7 @@
has_gravity = TRUE
hidden = TRUE
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
ambientsounds = RUINS
/area/ruin/unpowered
@@ -16,4 +17,3 @@
/area/ruin/powered
requires_power = FALSE
+2 -2
View File
@@ -22,7 +22,7 @@
power_environ = FALSE
valid_territory = FALSE
outdoors = TRUE
ambientsounds = list('sound/ambience/ambispace.ogg','sound/ambience/title2.ogg')
ambientsounds = SPACE
blob_allowed = FALSE
/////////////
@@ -434,4 +434,4 @@
/area/ruin/space/has_grav/whiteship/box
name = "Abandoned Ship"
icon_state = "red"
icon_state = "red"
+2 -1
View File
@@ -18,6 +18,7 @@
/area/shuttle/syndicate
name = "Syndicate Infiltrator"
blob_allowed = FALSE
ambientsounds = HIGHSEC
/area/shuttle/syndicate/bridge
name = "Syndicate Infiltrator Control"
@@ -106,4 +107,4 @@
/area/shuttle/syndicate_scout
name = "Syndicate Scout"
blob_allowed = FALSE
blob_allowed = FALSE
+1
View File
@@ -2,6 +2,7 @@
/area/spacecontent
name = "space"
ambientsounds = AWAY_MISSION
/area/spacecontent/a1
icon_state = "spacecontent1"
-26
View File
@@ -244,32 +244,6 @@
else if(src in container)
return 1
/*
* atom/proc/search_contents_for(path,list/filter_path=null)
* Recursevly searches all atom contens (including contents contents and so on).
*
* ARGS: path - search atom contents for atoms of this type
* list/filter_path - if set, contents of atoms not of types in this list are excluded from search.
*
* RETURNS: list of found atoms
*/
/atom/proc/search_contents_for(path,list/filter_path=null)
var/list/found = list()
for(var/atom/A in src)
if(istype(A, path))
found += A
if(filter_path)
var/pass = 0
for(var/type in filter_path)
pass |= istype(A, type)
if(!pass)
continue
if(A.contents.len)
found += A.search_contents_for(path,filter_path)
return found
/atom/proc/examine(mob/user)
//This reformat names to get a/an properly working on item descriptions when they are bloody
var/f_name = "\a [src]."
@@ -226,6 +226,8 @@
. = ..()
if(!independent) //no pulling people deep into the blob
verbs -= /mob/living/verb/pulled
else
pass_flags &= ~PASSBLOB
/mob/living/simple_animal/hostile/blob/blobbernaut/Life()
if(..())
+7 -4
View File
@@ -91,10 +91,13 @@ GLOBAL_LIST_EMPTY(blob_nodes)
if(!Ablob.blob_allowed)
continue
playsound(L, 'sound/effects/splat.ogg', 50, 1)
L.death()
new/mob/living/simple_animal/hostile/blob/blobspore(T)
if(!("blob" in L.faction))
playsound(L, 'sound/effects/splat.ogg', 50, 1)
L.death()
new/mob/living/simple_animal/hostile/blob/blobspore(T)
else
L.fully_heal()
for(var/V in GLOB.sortedAreas)
var/area/A = V
@@ -273,6 +273,7 @@ Credit where due:
if(plasmaman && !visualsOnly) //If we need to breathe from the plasma tank, we should probably start doing that
H.internal = H.get_item_for_held_index(2)
H.update_internals_hud_icon(1)
H.sec_hud_set_ID()
/obj/item/paper/servant_primer
name = "The Ark And You: A Primer On Servitude"
@@ -38,8 +38,11 @@
beckon(AM)
/obj/effect/clockwork/city_of_cogs_rift/proc/beckon(atom/movable/AM)
var/turf/T = get_turf(pick(GLOB.city_of_cogs_spawns))
if(is_servant_of_ratvar(AM))
T = GLOB.ark_of_the_clockwork_justiciar ? get_step(GLOB.ark_of_the_clockwork_justiciar, SOUTH) : get_turf(pick(GLOB.servant_spawns))
AM.visible_message("<span class='danger'>[AM] passes through [src]!</span>", ignored_mob = AM)
AM.forceMove(pick(!is_servant_of_ratvar(AM) ? GLOB.city_of_cogs_spawns : GLOB.servant_spawns))
AM.forceMove(T)
AM.visible_message("<span class='danger'>[AM] materializes from the air!</span>", \
"<span class='boldannounce'>You pass through [src] and appear [is_servant_of_ratvar(AM) ? "back at the City of Cogs" : "somewhere unfamiliar. Looks like it was a one-way trip.."].</span>")
do_sparks(5, TRUE, src)
@@ -104,7 +104,7 @@ List of nuances:
if(isliving(AM))
var/mob/living/L = AM
if(!whisper)
L.say(message, "clock", spans, language=/datum/language/common)
L.say(message, "clock", spans, language=/datum/language/common, ignore_spam = TRUE)
else
L.whisper(message, "clock", spans, language=/datum/language/common)
else
@@ -1,8 +1,7 @@
/obj/item/clockwork/slab //Clockwork slab: The most important tool in Ratvar's arsenal. Allows scripture recital, tutorials, and generates components.
name = "clockwork slab"
desc = "A strange metal tablet. A clock in the center turns around and around."
clockwork_desc = "A link between you and the Celestial Derelict. It contains information, recites scripture, and is your most vital tool as a Servant.\n\
Hitting a slab, a Servant with a slab, or a cache will <b>transfer</b> this slab's components into the target, the target's slab, or the global cache, respectively."
clockwork_desc = "A link between you and the Celestial Derelict. It contains information, recites scripture, and is your most vital tool as a Servant."
icon_state = "dread_ipad"
lefthand_file = 'icons/mob/inhands/antag/clockwork_lefthand.dmi'
righthand_file = 'icons/mob/inhands/antag/clockwork_righthand.dmi'
@@ -231,7 +230,7 @@
this will cause you to whisper your message aloud, so doing so in a public place is very suspicious and you should try to restrict it to private use.<br><br>"
dat += "If you aren't willing or don't have the time to read through every section, you can still help your teammates! Ask if they've set up a base. If they have, head there \
and ask however you can help; chances are there's always something. If not, it's your job as a Servant to get one up and running! Try to find a secluded, low-traffic area, \
like the auxilary base or somewhere deep in maintenance. You'll want to go into the Drivers section of the slab and look for <i>Tinkerer's Cache.</i> Find a nice spot and \
like the auxiliary base or somewhere deep in maintenance. You'll want to go into the Drivers section of the slab and look for <i>Tinkerer's Cache.</i> Find a nice spot and \
create one. This serves as a storage for <i>components,</i> the cult's primary resource. (Your slab's probably produced a few by now.) By attacking that cache with this \
slab, you'll offload all your components into it, and all Servants will be able to use those components from any distance - all Tinkerer's Caches are linked!<br><br>"
dat += "Once you have a base up and running, contact your fellows and let them know. You should come back here often to drop off the slab's components, and your fellows \
@@ -250,7 +249,7 @@
teamwork is an instrumental component of your success.<br><br>" //get it? component? ha!
dat += "As a Servant of Ratvar, the tools you are given focus around building and maintaining bases and outposts. A great deal of your power comes from stationary \
structures, and without constructing a base somewhere, it's essentially impossible to succeed. Finding a good spot to build a base can be difficult, and it's recommended \
that you choose an area in low-traffic part of the station (such as the auxilary base). Make sure to disconnect any cameras in the area beforehand.<br><br>"
that you choose an area in low-traffic part of the station (such as the auxiliary base). Make sure to disconnect any cameras in the area beforehand.<br><br>"
dat += "Because of how complex being a Servant is, it isn't possible to fit much information into this section. It's highly recommended that you read the <b>Components</b> \
and <b>Scripture</b> sections next. Not knowing how these two systems work will cripple both you and your fellows, and lead to a frustrating experience for everyone.<br><br>"
dat += "<font color=#BE8700 size=3>-=-=-=-=-=-</font>"
@@ -17,6 +17,7 @@
attack_sound = 'sound/weapons/bladeslice.ogg'
weather_immunities = list("lava")
movement_type = FLYING
a_intent = INTENT_HARM
loot = list(/obj/item/clockwork/component/geis_capacitor/fallen_armor)
light_range = 2
light_power = 1.1
@@ -24,7 +25,6 @@
unique abilities, you're a fearsome fighter in one-on-one combat, and your shield protects from projectiles!<br><br>Obey the Servants and do as they \
tell you. Your primary goal is to defend the Ark from destruction; they are your allies in this, and should be protected from harm.</b>"
empower_string = "<span class='neovgre'>The Anima Bulwark's power flows through you! Your weapon will strike harder, your armor is sturdier, and your shield is more durable.</span>"
var/deflect_chance = 40 //Chance to deflect any given projectile (non-damaging energy projectiles are always deflected)
var/max_shield_health = 3
var/shield_health = 3 //Amount of projectiles that can be deflected within
var/shield_health_regen = 0 //When world.time equals this, shield health will regenerate
@@ -55,8 +55,6 @@
obj_damage = 100
max_shield_health = INFINITY
else if(GLOB.ratvar_approaches) //Hefty health bonus and slight attack damage increase
health = 200
maxHealth = 200
melee_damage_upper = 15
melee_damage_lower = 15
attacktext = "carves"
@@ -53,6 +53,7 @@ Applications: 8 servants, 3 caches, and 100 CV
if(slab.busy)
to_chat(invoker, "<span class='warning'>[slab] refuses to work, displaying the message: \"[slab.busy]!\"</span>")
return FALSE
pre_recital()
slab.busy = "Invocation ([name]) in progress"
if(GLOB.ratvar_awakens)
channel_time *= 0.5 //if ratvar has awoken, half channel time and no cost
@@ -176,6 +177,9 @@ Applications: 8 servants, 3 caches, and 100 CV
/datum/clockwork_scripture/proc/scripture_fail() //Called if the scripture fails to invoke.
/datum/clockwork_scripture/proc/pre_recital() //Called before the scripture is recited
/datum/clockwork_scripture/proc/post_recital() //Called after the scripture is recited
//Channeled scripture begins instantly but runs constantly
@@ -7,12 +7,12 @@
/datum/clockwork_scripture/create_object/construct/clockwork_marauder
descname = "Well-Rounded Combat Construct"
name = "Clockwork Marauder"
desc = "Creates a shell for a clockwork marauder, a balanced frontline construct."
desc = "Creates a shell for a clockwork marauder, a balanced frontline construct that can deflect projectiles with its shield."
invocations = list("Arise, avatar of Arbiter!", "Defend the Ark with vengeful zeal.")
channel_time = 50
power_cost = 1000
creator_message = "<span class='brass'>Your slab disgorges several chunks of replicant alloy that form into a suit of thrumming armor.</span>"
usage_tip = "The marauder's shield can effectively deflect energy-based projectiles."
usage_tip = "Reciting this scripture multiple times in a short period will cause it to take longer!"
tier = SCRIPTURE_APPLICATION
one_per_tile = TRUE
primary_component = BELLIGERENT_EYE
@@ -22,6 +22,9 @@
object_path = /obj/item/clockwork/construct_chassis/clockwork_marauder
construct_type = /mob/living/simple_animal/hostile/clockwork/marauder
combat_construct = TRUE
var/static/recent_marauders = 0
var/static/time_since_last_marauder = 0
var/static/scaled_recital_time = 0
/datum/clockwork_scripture/create_object/construct/clockwork_marauder/update_construct_limit()
var/human_servants = 0
@@ -32,15 +35,30 @@
construct_limit = human_servants / 4 //1 per 4 human servants, and a maximum of 3 marauders
construct_limit = Clamp(construct_limit, 1, 3)
/datum/clockwork_scripture/create_object/prolonging_prism/check_special_requirements()
if(SSshuttle.emergency.mode == SHUTTLE_DOCKED || SSshuttle.emergency.mode == SHUTTLE_IGNITING || SSshuttle.emergency.mode == SHUTTLE_STRANDED || SSshuttle.emergency.mode == SHUTTLE_ESCAPE)
to_chat(invoker, "<span class='inathneq'>\"It is too late to construct one of these, champion.\"</span>")
return FALSE
var/turf/T = get_turf(invoker)
if(!T || !(T.z in GLOB.station_z_levels))
to_chat(invoker, "<span class='inathneq'>\"You must be on the station to construct one of these, champion.\"</span>")
return FALSE
return ..()
/datum/clockwork_scripture/create_object/construct/clockwork_marauder/pre_recital()
channel_time = initial(channel_time)
calculate_scaling()
if(scaled_recital_time)
to_chat(invoker, "<span class='warning'>The Hierophant Network is under strain from repeated summoning, making this scripture [scaled_recital_time / 10] seconds slower!</span>")
channel_time += scaled_recital_time
return TRUE
/datum/clockwork_scripture/create_object/construct/clockwork_marauder/scripture_effects()
. = ..()
time_since_last_marauder = world.time
recent_marauders++
calculate_scaling()
/datum/clockwork_scripture/create_object/construct/clockwork_marauder/proc/calculate_scaling()
var/WT = world.time
var/MT = time_since_last_marauder //Cast it for quicker reference
var/marauders_to_exclude = 0
if(world.time >= time_since_last_marauder + MARAUDER_SCRIPTURE_SCALING_THRESHOLD)
marauders_to_exclude = round(WT - MT) / MARAUDER_SCRIPTURE_SCALING_THRESHOLD //If at least 20 seconds have passed, lose one marauder for each 20 seconds
//i.e. world.time = 10000, last marauder = 9000, so we lose 5 marauders from the recent count since 10k - 9k = 1k, 1k / 200 = 5
time_since_last_marauder = world.time //So that it can't be spammed to make the marauder exclusion plummet; this emulates "ticking"
recent_marauders = max(0, recent_marauders - marauders_to_exclude)
scaled_recital_time = min(recent_marauders * MARAUDER_SCRIPTURE_SCALING_TIME, MARAUDER_SCRIPTURE_SCALING_MAX)
//Mania Motor: Creates a malevolent transmitter that will broadcast the whispers of Sevtug into the minds of nearby nonservants, causing a variety of mental effects at a power cost.
@@ -129,7 +129,11 @@
/datum/clockwork_scripture/abscond/scripture_effects()
var/take_pulling = invoker.pulling && isliving(invoker.pulling) && get_clockwork_power(ABSCOND_ABDUCTION_COST)
var/turf/T = get_turf(pick(GLOB.servant_spawns))
var/turf/T
if(GLOB.ark_of_the_clockwork_justiciar)
T = get_step(GLOB.ark_of_the_clockwork_justiciar, SOUTH)
else
T = get_turf(pick(GLOB.servant_spawns))
invoker.visible_message("<span class='warning'>[invoker] flickers and phases out of existence!</span>", \
"<span class='bold sevtug_small'>You feel a dizzying sense of vertigo as you're yanked back to Reebe!</span>")
T.visible_message("<span class='warning'>[invoker] flickers and phases into existence!</span>")
@@ -134,11 +134,20 @@
var/damage = max((obj_integrity * 0.7) / severity, 100) //requires multiple bombs to take down
take_damage(damage, BRUTE, "bomb", 0)
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/get_arrival_time()
if(seconds_until_activation)
return (seconds_until_activation*10)
if(grace_period)
return (grace_period*10)
else if(GATEWAY_RATVAR_ARRIVAL - progress_in_seconds > 0)
return (round(max((GATEWAY_RATVAR_ARRIVAL - progress_in_seconds) / (GATEWAY_SUMMON_RATE), 0), 1)*10)
return -10
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/get_arrival_text(s_on_time)
if(seconds_until_activation)
return "[seconds_until_activation][s_on_time ? "S" : ""]"
return "[get_arrival_time()][s_on_time ? "S" : ""]"
if(grace_period)
return "[grace_period][s_on_time ? "S" : ""]"
return "[get_arrival_time()][s_on_time ? "S" : ""]"
. = "IMMINENT"
if(!obj_integrity)
. = "DETONATING"
@@ -151,12 +160,12 @@
icon_state = initial(icon_state)
if(is_servant_of_ratvar(user) || isobserver(user))
if(!active)
to_chat(user, "<span class='big'><b>Seconds until the Ark's activation:</b> [get_arrival_text(TRUE)]</span>")
to_chat(user, "<span class='big'><b>Time until the Ark's activation:</b> [DisplayTimeText(get_arrival_time())]</span>")
else
if(grace_period)
to_chat(user, "<span class='big'><b>Crew grace period time remaining:</b> [get_arrival_text(TRUE)]</span>")
to_chat(user, "<span class='big'><b>Crew grace period time remaining:</b> [DisplayTimeText(get_arrival_time())]</span>")
else
to_chat(user, "<span class='big'><b>Seconds until Ratvar's arrival:</b> [get_arrival_text(TRUE)]</span>")
to_chat(user, "<span class='big'><b>Time until Ratvar's arrival:</b> [DisplayTimeText(get_arrival_time())]</span>")
switch(progress_in_seconds)
if(-INFINITY to GATEWAY_REEBE_FOUND)
to_chat(user, "<span class='heavy_brass'>The Ark is feeding power into the bluespace field.</span>")
@@ -266,7 +275,7 @@
CHECK_TICK
/obj/structure/destructible/clockwork/massive/celestial_gateway/attack_ghost(mob/user)
if(!user.client || !user.client.holder)
if(!IsAdminGhost(user))
return
if(GLOB.servants_active)
to_chat(user, "<span class='danger'>The Ark is already counting down.</span>")
@@ -275,6 +284,7 @@
if(alert(user, "REALLY activate the Ark's countdown?", name, "Yes", "No") == "Yes")
if(alert(user, "You're REALLY SURE? This cannot be undone.", name, "Yes - Activate the Ark", "No") == "Yes - Activate the Ark")
message_admins("<span class='danger'>Admin [key_name_admin(user)] started the Ark's countdown!</span>")
log_admin("Admin [key_name(user)] started the Ark's countdown on a non-clockcult mode!")
to_chat(user, "<span class='userdanger'>The gamemode is now being treated as clockwork cult, and the Ark is counting down from 30 \
minutes. You will need to create servant players yourself.</span>")
final_countdown(35)
+4
View File
@@ -256,6 +256,10 @@
SSticker.news_report = CULT_FAILURE
text += "<br><B>Objective #[obj_count]</B>: [explanation]"
if(cult.len)
text += "<br><b>The cultists were:</b>"
for(var/datum/mind/M in cult)
text += printplayer(M)
to_chat(world, text)
..()
return 1
+1 -1
View File
@@ -324,7 +324,7 @@
icon_state = "cult_armor"
item_state = "cult_armor"
desc = "A heavily-armored exosuit worn by warriors of the Nar-Sien cult. It can withstand hard vacuum."
w_class = WEIGHT_CLASS_SMALL
w_class = WEIGHT_CLASS_BULKY
allowed = list(/obj/item/tome, /obj/item/melee/cultblade, /obj/item/tank/internals/)
armor = list(melee = 70, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30, fire = 40, acid = 75)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/cult
+1 -1
View File
@@ -137,7 +137,7 @@ structure_check() searches for nearby cultist structures required for the invoca
for(var/M in invokers)
var/mob/living/L = M
if(invocation)
L.say(invocation, language = /datum/language/common)
L.say(invocation, language = /datum/language/common, ignore_spam = TRUE)
if(invoke_damage)
L.apply_damage(invoke_damage, BRUTE)
to_chat(L, "<span class='cultitalic'>[src] saps your strength!</span>")
+2 -3
View File
@@ -225,8 +225,8 @@
/obj/item/paper/talisman/horror/afterattack(mob/living/target, mob/living/user)
if(iscultist(user) && (get_dist(user, target) < 7))
to_chat(user, "<span class='cultitalic'>You disturb [target] with visions of madness!</span>")
if(iscarbon(target))
to_chat(user, "<span class='cultitalic'>You disturb [target] with visions of madness!</span>")
var/mob/living/carbon/H = target
H.reagents.add_reagent("mindbreaker", 12)
if(is_servant_of_ratvar(target))
@@ -234,8 +234,7 @@
target.emote("scream")
target.confused = max(0, target.confused + 3)
target.flash_act()
qdel(src)
qdel(src)
//Talisman of Fabrication: Creates a construct shell out of 25 metal sheets, or converts plasteel into runed metal up to 25 times
/obj/item/paper/talisman/construction
@@ -17,6 +17,7 @@
var/ascended = FALSE
sight = (SEE_TURFS | SEE_OBJS)
status_flags = CANPUSH
spacewalk = TRUE
mob_size = MOB_SIZE_LARGE
var/mob/living/oldform
var/list/devil_overlays[DEVIL_TOTAL_LAYERS]
@@ -135,9 +136,6 @@
"<span class='userdanger'>[attack_message]</span>", null, COMBAT_MESSAGE_RANGE)
return TRUE
/mob/living/carbon/true_devil/Process_Spacemove(movement_dir = 0)
return 1
/mob/living/carbon/true_devil/singularity_act()
if(ascended)
return 0
@@ -679,7 +679,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
C.images -= I
/mob/living/silicon/ai/proc/can_place_transformer(datum/action/innate/ai/place_transformer/action)
if(!eyeobj || !isturf(loc) || !canUseTopic() || !action)
if(!eyeobj || !isturf(loc) || incapacitated() || !action)
return
var/turf/middle = get_turf(eyeobj)
var/list/turfs = list(middle, locate(middle.x - 1, middle.y, middle.z), locate(middle.x + 1, middle.y, middle.z))
+4 -2
View File
@@ -98,7 +98,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
var/z_original = ZLEVEL_STATION_PRIMARY
var/threat = 0 // used for determining which meteors are most interesting
var/lifetime = DEFAULT_METEOR_LIFETIME
var/timerid = null
var/list/meteordrop = list(/obj/item/ore/iron)
var/dropamt = 2
@@ -117,6 +117,8 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
get_hit()
/obj/effect/meteor/Destroy()
if (timerid)
deltimer(timerid)
GLOB.meteor_list -= src
SSaugury.unregister_doom(src)
walk(src,0) //this cancels the walk_towards() proc
@@ -127,7 +129,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
GLOB.meteor_list += src
SSaugury.register_doom(src, threat)
SpinAnimation()
QDEL_IN(src, lifetime)
timerid = QDEL_IN(src, lifetime)
chase_target(target)
/obj/effect/meteor/Collide(atom/A)
@@ -21,6 +21,7 @@
maxHealth = INFINITY
layer = GHOST_LAYER
healable = FALSE
spacewalk = TRUE
sight = SEE_SELF
see_in_dark = 8
@@ -153,8 +154,6 @@
//Immunities
/mob/living/simple_animal/revenant/Process_Spacemove(movement_dir = 0)
return 1
/mob/living/simple_animal/revenant/ex_act(severity, target)
return 1 //Immune to the effects of explosions.
+4 -2
View File
@@ -91,9 +91,11 @@
var/obj/item/device/nuclear_challenge/challenge = new /obj/item/device/nuclear_challenge
synd_mind.current.put_in_hands(challenge, TRUE)
var/list/foundIDs = synd_mind.current.search_contents_for(/obj/item/card/id)
var/static/id_cache = typecacheof(/obj/item/card/id)
var/list/foundIDs = typecache_filter_list(synd_mind.current.GetAllContents(), id_cache)
if(foundIDs.len)
for(var/obj/item/card/id/ID in foundIDs)
for(var/i in 1 to foundIDs.len)
var/obj/item/card/id/ID = foundIDs[i]
ID.name = "lead agent card"
ID.access += ACCESS_SYNDICATE_LEADER
else
+2 -1
View File
@@ -83,7 +83,7 @@
/datum/game_mode/traitor/proc/add_latejoin_traitor(datum/mind/character)
var/datum/antagonist/traitor/new_antag = new antag_datum(character)
new_antag.should_specialise = TRUE
character.add_antag_datum(antag_datum)
character.add_antag_datum(new_antag)
@@ -147,6 +147,7 @@
else
text += "<br><font color='red'><B>The [special_role_text] has failed!</B></font>"
SSblackbox.add_details("traitor_success","FAIL")
SEND_SOUND(traitor.current, 'sound/ambience/ambifailure.ogg')
text += "<br>"
+1 -1
View File
@@ -425,7 +425,7 @@
/datum/spellbook_entry/item/warpwhistle
name = "Warp Whistle"
desc = "A strange whistle that will transport you to a distant safe place on the station. There is a window of vulnerability at the begining of every use."
desc = "A strange whistle that will transport you to a distant safe place on the station. There is a window of vulnerability at the beginning of every use."
item_path = /obj/item/warpwhistle
category = "Mobility"
cost = 1
+11
View File
@@ -506,3 +506,14 @@ Class Procs:
. = ..()
if (AM == occupant)
occupant = null
/obj/machinery/proc/adjust_item_drop_location(atom/movable/AM) // Adjust item drop location to a 3x3 grid inside the tile, returns slot id from 0 to 8
var/md5 = md5(AM.name) // Oh, and it's deterministic too. A specific item will always drop from the same slot.
#if DM_VERSION > 511
#warn Refactor the loop in /obj/machinery/proc/adjust_item_drop_location() to make use of 512's list-like access to characters in a string
#endif
for (var/i in 1 to 32)
. += hex2num(copytext(md5,i,i+1))
. = . % 9
AM.pixel_x = -8 + ((.%3)*8)
AM.pixel_y = -8 + (round( . / 3)*8)
+107 -136
View File
@@ -8,10 +8,9 @@
circuit = /obj/item/circuitboard/computer/communications
var/authenticated = 0
var/auth_id = "Unknown" //Who is currently logged in?
var/list/messagetitle = list()
var/list/messagetext = list()
var/currmsg = 0
var/aicurrmsg = 0
var/list/datum/comm_message/messages = list()
var/datum/comm_message/currmsg
var/datum/comm_message/aicurrmsg
var/state = STATE_DEFAULT
var/aistate = STATE_DEFAULT
var/message_cooldown = 0
@@ -48,7 +47,7 @@
/obj/machinery/computer/communications/process()
if(..())
if(state != STATE_STATUSDISPLAY)
src.updateDialog()
updateDialog()
/obj/machinery/computer/communications/Topic(href, href_list)
@@ -65,7 +64,7 @@
switch(href_list["operation"])
// main interface
if("main")
src.state = STATE_DEFAULT
state = STATE_DEFAULT
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
if("login")
var/mob/M = usr
@@ -75,13 +74,13 @@
I = M.get_idcard()
if(I && istype(I))
if(src.check_access(I))
if(check_access(I))
authenticated = 1
auth_id = "[I.registered_name] ([I.assignment])"
if((20 in I.access))
authenticated = 2
playsound(src, 'sound/machines/terminal_on.ogg', 50, 0)
if(src.emagged)
if(emagged)
authenticated = 2
auth_id = "Unknown"
to_chat(M, "<span class='warning'>[src] lets out a quiet alarm as its login is overriden.</span>")
@@ -132,7 +131,7 @@
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
if("announce")
if(src.authenticated==2)
if(authenticated==2)
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
make_announcement(usr)
@@ -186,53 +185,56 @@
to_chat(usr, "Not enough credits.")
if("callshuttle")
src.state = STATE_DEFAULT
if(src.authenticated)
src.state = STATE_CALLSHUTTLE
state = STATE_DEFAULT
if(authenticated)
state = STATE_CALLSHUTTLE
if("callshuttle2")
if(src.authenticated)
if(authenticated)
SSshuttle.requestEvac(usr, href_list["call"])
if(SSshuttle.emergency.timer)
post_status("shuttle")
src.state = STATE_DEFAULT
state = STATE_DEFAULT
if("cancelshuttle")
src.state = STATE_DEFAULT
if(src.authenticated)
src.state = STATE_CANCELSHUTTLE
state = STATE_DEFAULT
if(authenticated)
state = STATE_CANCELSHUTTLE
if("cancelshuttle2")
if(src.authenticated)
if(authenticated)
SSshuttle.cancelEvac(usr)
src.state = STATE_DEFAULT
state = STATE_DEFAULT
if("messagelist")
src.currmsg = 0
src.state = STATE_MESSAGELIST
currmsg = 0
state = STATE_MESSAGELIST
if("viewmessage")
src.state = STATE_VIEWMESSAGE
if (!src.currmsg)
state = STATE_VIEWMESSAGE
if (!currmsg)
if(href_list["message-num"])
src.currmsg = text2num(href_list["message-num"])
var/msgnum = text2num(href_list["message-num"])
currmsg = messages[msgnum]
else
src.state = STATE_MESSAGELIST
state = STATE_MESSAGELIST
if("delmessage")
src.state = (src.currmsg) ? STATE_DELMESSAGE : STATE_MESSAGELIST
state = currmsg ? STATE_DELMESSAGE : STATE_MESSAGELIST
if("delmessage2")
if(src.authenticated)
if(src.currmsg)
var/title = src.messagetitle[src.currmsg]
var/text = src.messagetext[src.currmsg]
src.messagetitle.Remove(title)
src.messagetext.Remove(text)
if(src.currmsg == src.aicurrmsg)
src.aicurrmsg = 0
src.currmsg = 0
src.state = STATE_MESSAGELIST
if(authenticated)
if(currmsg)
if(aicurrmsg == currmsg)
aicurrmsg = null
messages -= currmsg
currmsg = null
state = STATE_MESSAGELIST
else
src.state = STATE_VIEWMESSAGE
state = STATE_VIEWMESSAGE
if("respond")
var/answer = text2num(href_list["answer"])
if(!currmsg || !answer || currmsg.possible_answers.len < answer)
state = STATE_MESSAGELIST
currmsg.answered = answer
state = STATE_VIEWMESSAGE
if("status")
src.state = STATE_STATUSDISPLAY
state = STATE_STATUSDISPLAY
if("securitylevel")
src.tmp_alertlevel = text2num( href_list["newalertlevel"] )
tmp_alertlevel = text2num( href_list["newalertlevel"] )
if(!tmp_alertlevel)
tmp_alertlevel = 0
state = STATE_CONFIRM_LEVEL
@@ -245,12 +247,12 @@
make_maint_all_access()
log_game("[key_name(usr)] enabled emergency maintenance access.")
message_admins("[key_name_admin(usr)] enabled emergency maintenance access.")
src.state = STATE_DEFAULT
state = STATE_DEFAULT
if("disableemergency")
revoke_maint_all_access()
log_game("[key_name(usr)] disabled emergency maintenance access.")
message_admins("[key_name_admin(usr)] disabled emergency maintenance access.")
src.state = STATE_DEFAULT
state = STATE_DEFAULT
// Status display stuff
if("setstat")
@@ -265,14 +267,14 @@
if("setmsg1")
stat_msg1 = reject_bad_text(input("Line 1", "Enter Message Text", stat_msg1) as text|null, 40)
src.updateDialog()
updateDialog()
if("setmsg2")
stat_msg2 = reject_bad_text(input("Line 2", "Enter Message Text", stat_msg2) as text|null, 40)
src.updateDialog()
updateDialog()
// OMG CENTCOM LETTERHEAD
if("MessageCentCom")
if(src.authenticated==2)
if(authenticated==2)
if(!checkCCcooldown())
to_chat(usr, "<span class='warning'>Arrays recycling. Please stand by.</span>")
return
@@ -288,7 +290,7 @@
// OMG SYNDICATE ...LETTERHEAD
if("MessageSyndicate")
if((src.authenticated==2) && (src.emagged))
if((authenticated==2) && (emagged))
if(!checkCCcooldown())
to_chat(usr, "<span class='warning'>Arrays recycling. Please stand by.</span>")
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
@@ -306,10 +308,10 @@
to_chat(usr, "<span class='notice'>Backup routing data restored!</span>")
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
emagged = FALSE
src.updateDialog()
updateDialog()
if("nukerequest") //When there's no other way
if(src.authenticated==2)
if(authenticated==2)
if(!checkCCcooldown())
to_chat(usr, "<span class='warning'>Arrays recycling. Please stand by.</span>")
return
@@ -325,41 +327,45 @@
// AI interface
if("ai-main")
src.aicurrmsg = 0
src.aistate = STATE_DEFAULT
aicurrmsg = null
aistate = STATE_DEFAULT
if("ai-callshuttle")
src.aistate = STATE_CALLSHUTTLE
aistate = STATE_CALLSHUTTLE
if("ai-callshuttle2")
SSshuttle.requestEvac(usr, href_list["call"])
src.aistate = STATE_DEFAULT
aistate = STATE_DEFAULT
if("ai-messagelist")
src.aicurrmsg = 0
src.aistate = STATE_MESSAGELIST
aicurrmsg = null
aistate = STATE_MESSAGELIST
if("ai-viewmessage")
src.aistate = STATE_VIEWMESSAGE
if (!src.aicurrmsg)
aistate = STATE_VIEWMESSAGE
if (!aicurrmsg)
if(href_list["message-num"])
src.aicurrmsg = text2num(href_list["message-num"])
var/msgnum = text2num(href_list["message-num"])
aicurrmsg = messages[msgnum]
else
src.aistate = STATE_MESSAGELIST
aistate = STATE_MESSAGELIST
if("ai-delmessage")
src.aistate = (src.aicurrmsg) ? STATE_DELMESSAGE : STATE_MESSAGELIST
aistate = aicurrmsg ? STATE_DELMESSAGE : STATE_MESSAGELIST
if("ai-delmessage2")
if(src.aicurrmsg)
var/title = src.messagetitle[src.aicurrmsg]
var/text = src.messagetext[src.aicurrmsg]
src.messagetitle.Remove(title)
src.messagetext.Remove(text)
if(src.currmsg == src.aicurrmsg)
src.currmsg = 0
src.aicurrmsg = 0
src.aistate = STATE_MESSAGELIST
if(aicurrmsg)
if(currmsg == aicurrmsg)
currmsg = null
messages -= aicurrmsg
aicurrmsg = null
aistate = STATE_MESSAGELIST
if("ai-respond")
var/answer = text2num(href_list["answer"])
if(!aicurrmsg || !answer || aicurrmsg.possible_answers.len < answer)
aistate = STATE_MESSAGELIST
aicurrmsg.answered = answer
aistate = STATE_VIEWMESSAGE
if("ai-status")
src.aistate = STATE_STATUSDISPLAY
aistate = STATE_STATUSDISPLAY
if("ai-announce")
make_announcement(usr, 1)
if("ai-securitylevel")
src.tmp_alertlevel = text2num( href_list["newalertlevel"] )
tmp_alertlevel = text2num( href_list["newalertlevel"] )
if(!tmp_alertlevel)
tmp_alertlevel = 0
var/old_level = GLOB.security_level
@@ -380,24 +386,23 @@
if(SEC_LEVEL_BLUE)
SSblackbox.inc("alert_comms_blue",1)
tmp_alertlevel = 0
src.aistate = STATE_DEFAULT
aistate = STATE_DEFAULT
if("ai-changeseclevel")
src.aistate = STATE_ALERT_LEVEL
aistate = STATE_ALERT_LEVEL
if("ai-emergencyaccess")
src.aistate = STATE_TOGGLE_EMERGENCY
aistate = STATE_TOGGLE_EMERGENCY
if("ai-enableemergency")
make_maint_all_access()
log_game("[key_name(usr)] enabled emergency maintenance access.")
message_admins("[key_name_admin(usr)] enabled emergency maintenance access.")
src.aistate = STATE_DEFAULT
aistate = STATE_DEFAULT
if("ai-disableemergency")
revoke_maint_all_access()
log_game("[key_name(usr)] disabled emergency maintenance access.")
message_admins("[key_name_admin(usr)] disabled emergency maintenance access.")
src.aistate = STATE_DEFAULT
aistate = STATE_DEFAULT
src.updateUsrDialog()
updateUsrDialog()
/obj/machinery/computer/communications/attackby(obj/I, mob/user, params)
if(istype(I, /obj/item/card/id))
@@ -417,7 +422,7 @@
/obj/machinery/computer/communications/attack_hand(mob/user)
if(..())
return
if (src.z > 6)
if (z > 6)
to_chat(user, "<span class='boldannounce'>Unable to establish a connection</span>: \black You're too far away from the station!")
return
@@ -429,19 +434,19 @@
var/datum/browser/popup = new(user, "communications", "Communications Console", 400, 500)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
if(issilicon(user))
var/dat2 = src.interact_ai(user) // give the AI a different interact proc to limit its access
var/dat2 = interact_ai(user) // give the AI a different interact proc to limit its access
if(dat2)
dat += dat2
popup.set_content(dat)
popup.open()
return
switch(src.state)
switch(state)
if(STATE_DEFAULT)
if (src.authenticated)
if (authenticated)
if(SSshuttle.emergencyCallAmount)
if(SSshuttle.emergencyLastCallLoc)
dat += "Most recent shuttle call/recall traced to: <b>[format_text(SSshuttle.emergencyLastCallLoc.name)]</b><BR>"
@@ -458,18 +463,13 @@
else
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=cancelshuttle'>Cancel Shuttle Call</A> \]"
<<<<<<< HEAD
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=status'>Set Status Display</A> \]"
if (src.authenticated==2)
=======
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=status'>Set Status Display</A> \]"
if (authenticated==2)
>>>>>>> 626302c... Merge pull request #32161 from ninjanomnom/512-experimental
dat += "<BR><BR><B>Captain Functions</B>"
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=announce'>Make a Captain's Announcement</A> \]"
if(CONFIG_GET(string/cross_server_address))
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=crossserver'>Send a message to an allied station</A> \]"
if(SSmapping.config.allow_custom_shuttles == "yes")
if(SSmapping.config.allow_custom_shuttles)
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=purchase_menu'>Purchase Shuttle</A> \]"
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=changeseclevel'>Change Alert Level</A> \]"
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=emergencyaccess'>Emergency Maintenance Access</A> \]"
@@ -489,16 +489,6 @@
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
if(STATE_MESSAGELIST)
dat += "Messages:"
<<<<<<< HEAD
for(var/i = 1; i<=src.messagetitle.len; i++)
dat += "<BR><A HREF='?src=\ref[src];operation=viewmessage;message-num=[i]'>[src.messagetitle[i]]</A>"
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
if(STATE_VIEWMESSAGE)
if (src.currmsg)
dat += "<B>[src.messagetitle[src.currmsg]]</B><BR><BR>[src.messagetext[src.currmsg]]"
if (src.authenticated)
dat += "<BR><BR>\[ <A HREF='?src=\ref[src];operation=delmessage'>Delete</a> \]"
=======
for(var/i in 1 to messages.len)
var/datum/comm_message/M = messages[i]
dat += "<BR><A HREF='?src=[REF(src)];operation=viewmessage;message-num=[i]'>[M.title]</A>"
@@ -514,22 +504,16 @@
var/answered = currmsg.possible_answers[currmsg.answered]
dat += "<br> Archived Answer : [answered]"
dat += "<BR><BR>\[ <A HREF='?src=[REF(src)];operation=delmessage'>Delete</A> \]"
>>>>>>> 626302c... Merge pull request #32161 from ninjanomnom/512-experimental
else
src.state = STATE_MESSAGELIST
src.attack_hand(user)
return
aistate = STATE_MESSAGELIST
attack_hand(user)
return null
if(STATE_DELMESSAGE)
<<<<<<< HEAD
if (src.currmsg)
dat += "Are you sure you want to delete this message? \[ <A HREF='?src=\ref[src];operation=delmessage2'>OK</A> | <A HREF='?src=\ref[src];operation=viewmessage'>Cancel</A> \]"
=======
if (currmsg)
dat += "Are you sure you want to delete this message? \[ <A HREF='?src=[REF(src)];operation=delmessage2'>OK</A> | <A HREF='?src=[REF(src)];operation=viewmessage'>Cancel</A> \]"
>>>>>>> 626302c... Merge pull request #32161 from ninjanomnom/512-experimental
else
src.state = STATE_MESSAGELIST
src.attack_hand(user)
state = STATE_MESSAGELIST
attack_hand(user)
return
if(STATE_STATUSDISPLAY)
dat += "Set Status Displays<BR>"
@@ -574,11 +558,7 @@
dat += "Prerequisites: [S.prerequisites]<BR>"
dat += "<A href='?src=[REF(src)];operation=buyshuttle;chosen_shuttle=[REF(S)]'>(<font color=red><i>Purchase</i></font>)</A><BR><BR>"
<<<<<<< HEAD
dat += "<BR><BR>\[ [(src.state != STATE_DEFAULT) ? "<A HREF='?src=\ref[src];operation=main'>Main Menu</A> | " : ""]<A HREF='?src=\ref[user];mach_close=communications'>Close</A> \]"
=======
dat += "<BR><BR>\[ [(state != STATE_DEFAULT) ? "<A HREF='?src=[REF(src)];operation=main'>Main Menu</A> | " : ""]<A HREF='?src=[REF(user)];mach_close=communications'>Close</A> \]"
>>>>>>> 626302c... Merge pull request #32161 from ninjanomnom/512-experimental
popup.set_content(dat)
popup.open()
@@ -624,7 +604,7 @@
/obj/machinery/computer/communications/proc/interact_ai(mob/living/silicon/ai/user)
var/dat = ""
switch(src.aistate)
switch(aistate)
if(STATE_DEFAULT)
if(SSshuttle.emergencyCallAmount)
if(SSshuttle.emergencyLastCallLoc)
@@ -648,14 +628,6 @@
dat += get_call_shuttle_form(1)
if(STATE_MESSAGELIST)
dat += "Messages:"
<<<<<<< HEAD
for(var/i = 1; i<=src.messagetitle.len; i++)
dat += "<BR><A HREF='?src=\ref[src];operation=ai-viewmessage;message-num=[i]'>[src.messagetitle[i]]</A>"
if(STATE_VIEWMESSAGE)
if (src.aicurrmsg)
dat += "<B>[src.messagetitle[src.aicurrmsg]]</B><BR><BR>[src.messagetext[src.aicurrmsg]]"
dat += "<BR><BR>\[ <A HREF='?src=\ref[src];operation=ai-delmessage'>Delete</A> \]"
=======
for(var/i in 1 to messages.len)
var/datum/comm_message/M = messages[i]
dat += "<BR><A HREF='?src=[REF(src)];operation=ai-viewmessage;message-num=[i]'>[M.title]</A>"
@@ -670,22 +642,16 @@
var/answered = aicurrmsg.possible_answers[aicurrmsg.answered]
dat += "<br> Archived Answer : [answered]"
dat += "<BR><BR>\[ <A HREF='?src=[REF(src)];operation=ai-delmessage'>Delete</A> \]"
>>>>>>> 626302c... Merge pull request #32161 from ninjanomnom/512-experimental
else
src.aistate = STATE_MESSAGELIST
src.attack_hand(user)
aistate = STATE_MESSAGELIST
attack_hand(user)
return null
if(STATE_DELMESSAGE)
<<<<<<< HEAD
if(src.aicurrmsg)
dat += "Are you sure you want to delete this message? \[ <A HREF='?src=\ref[src];operation=ai-delmessage2'>OK</A> | <A HREF='?src=\ref[src];operation=ai-viewmessage'>Cancel</A> \]"
=======
if(aicurrmsg)
dat += "Are you sure you want to delete this message? \[ <A HREF='?src=[REF(src)];operation=ai-delmessage2'>OK</A> | <A HREF='?src=[REF(src)];operation=ai-viewmessage'>Cancel</A> \]"
>>>>>>> 626302c... Merge pull request #32161 from ninjanomnom/512-experimental
else
src.aistate = STATE_MESSAGELIST
src.attack_hand(user)
aistate = STATE_MESSAGELIST
attack_hand(user)
return
if(STATE_STATUSDISPLAY)
@@ -716,11 +682,7 @@
dat += "<b>Emergency Maintenance Access is currently <font color='green'>DISABLED</font></b>"
dat += "<BR>Lift access restrictions on maintenance and external airlocks? <BR>\[ <A HREF='?src=[REF(src)];operation=ai-enableemergency'>OK</A> | <A HREF='?src=[REF(src)];operation=ai-viewmessage'>Cancel</A> \]"
<<<<<<< HEAD
dat += "<BR><BR>\[ [(src.aistate != STATE_DEFAULT) ? "<A HREF='?src=\ref[src];operation=ai-main'>Main Menu</A> | " : ""]<A HREF='?src=\ref[user];mach_close=communications'>Close</A> \]"
=======
dat += "<BR><BR>\[ [(aistate != STATE_DEFAULT) ? "<A HREF='?src=[REF(src)];operation=ai-main'>Main Menu</A> | " : ""]<A HREF='?src=[REF(user)];mach_close=communications'>Close</A> \]"
>>>>>>> 626302c... Merge pull request #32161 from ninjanomnom/512-experimental
return dat
/obj/machinery/computer/communications/proc/make_announcement(mob/living/user, is_silicon)
@@ -762,3 +724,12 @@
/obj/machinery/computer/communications/proc/overrideCooldown()
var/obj/item/circuitboard/computer/communications/CM = circuit
CM.lastTimeUsed = 0
/obj/machinery/computer/communications/proc/add_message(datum/comm_message/new_message)
messages += new_message
/datum/comm_message
var/title
var/content
var/list/possible_answers = list()
var/answered
+1 -1
View File
@@ -575,7 +575,7 @@
if(4)
R.fields["blood_type"] = random_blood_type()
if(5)
R.fields["p_stat"] = pick("*Unconcious*", "Active", "Physically Unfit")
R.fields["p_stat"] = pick("*Unconscious*", "Active", "Physically Unfit")
if(6)
R.fields["m_stat"] = pick("*Insane*", "*Unstable*", "*Watch*", "Stable")
continue
+9 -4
View File
@@ -118,6 +118,15 @@
max_integrity = normal_integrity
if(damage_deflection == AIRLOCK_DAMAGE_DEFLECTION_N && security_level > AIRLOCK_SECURITY_METAL)
damage_deflection = AIRLOCK_DAMAGE_DEFLECTION_R
prepare_huds()
var/datum/atom_hud/data/diagnostic/diag_hud = GLOB.huds[DATA_HUD_DIAGNOSTIC]
diag_hud.add_to_hud(src)
diag_hud_set_electrified()
return INITIALIZE_HINT_LATELOAD
/obj/machinery/door/airlock/LateInitialize()
. = ..()
if(abandoned)
var/outcome = rand(1,100)
switch(outcome)
@@ -136,10 +145,6 @@
welded = TRUE
if(24 to 30)
panel_open = TRUE
prepare_huds()
var/datum/atom_hud/data/diagnostic/diag_hud = GLOB.huds[DATA_HUD_DIAGNOSTIC]
diag_hud.add_to_hud(src)
diag_hud_set_electrified()
update_icon()
+10 -21
View File
@@ -69,9 +69,9 @@ Buildable meters
return ..()
/obj/item/pipe/proc/setPipingLayer(new_layer = PIPING_LAYER_DEFAULT)
var/obj/machinery/atmospherics/fakeA = get_pipe_cache(pipe_type)
var/obj/machinery/atmospherics/fakeA = pipe_type
if(fakeA.pipe_flags & PIPING_ALL_LAYER)
if(initial(fakeA.pipe_flags) & PIPING_ALL_LAYER)
new_layer = PIPING_LAYER_DEFAULT
piping_layer = new_layer
@@ -80,9 +80,9 @@ Buildable meters
layer = initial(layer) + ((piping_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_LCHANGE)
/obj/item/pipe/proc/update()
var/obj/machinery/atmospherics/A = get_pipe_cache(pipe_type)
name = "[A.name] fitting"
icon_state = A.pipe_state
var/obj/machinery/atmospherics/fakeA = pipe_type
name = "[initial(fakeA.name)] fitting"
icon_state = initial(fakeA.pipe_state)
// rotate the pipe item clockwise
@@ -147,17 +147,6 @@ Buildable meters
/obj/item/pipe/attack_self(mob/user)
return rotate()
/obj/item/pipe/proc/get_pipe_cache(type, direction)
var/static/list/obj/machinery/atmospherics/check_cache
if(!islist(check_cache))
check_cache = list()
if(!check_cache[type])
check_cache[type] = list()
if(!check_cache[type]["[direction]"])
check_cache[type]["[direction]"] = new type(null, null, direction)
return check_cache[type]["[direction]"]
/obj/item/pipe/attackby(obj/item/W, mob/user, params)
if (!istype(W, /obj/item/wrench))
return ..()
@@ -167,15 +156,15 @@ Buildable meters
fixdir()
var/obj/machinery/atmospherics/fakeA = get_pipe_cache(pipe_type, dir)
var/obj/machinery/atmospherics/fakeA = pipe_type
var/flags = initial(fakeA.pipe_flags)
for(var/obj/machinery/atmospherics/M in loc)
if((M.pipe_flags & fakeA.pipe_flags & PIPING_ONE_PER_TURF)) //Only one dense/requires density object per tile, eg connectors/cryo/heater/coolers.
if((M.pipe_flags & flags & PIPING_ONE_PER_TURF)) //Only one dense/requires density object per tile, eg connectors/cryo/heater/coolers.
to_chat(user, "<span class='warning'>Something is hogging the tile!</span>")
return TRUE
if((M.piping_layer != piping_layer) && !((M.pipe_flags | fakeA.pipe_flags) & PIPING_ALL_LAYER)) //don't continue if either pipe goes across all layers
if((M.piping_layer != piping_layer) && !((M.pipe_flags | flags) & PIPING_ALL_LAYER)) //don't continue if either pipe goes across all layers
continue
if(M.GetInitDirections() & fakeA.GetInitDirections()) // matches at least one direction on either type of pipe
if(M.GetInitDirections() & SSair.get_init_dirs(pipe_type, dir)) // matches at least one direction on either type of pipe
to_chat(user, "<span class='warning'>There is already a pipe at that location!</span>")
return TRUE
// no conflicts found
@@ -16,7 +16,7 @@
use_power = IDLE_POWER_USE //this turret uses and requires power
idle_power_usage = 50 //when inactive, this turret takes up constant 50 Equipment power
active_power_usage = 300 //when active, this turret takes up constant 300 Equipment power
req_access = list(ACCESS_SECURITY)
req_access = list(ACCESS_SEC_DOORS)
power_channel = EQUIP //drains power from the EQUIPMENT channel
var/base_icon_state = "standard"
+4 -4
View File
@@ -980,8 +980,8 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
/obj/item/clothing/mask/gas/cyborg = 1, /obj/item/clothing/suit/holidaypriest = 1, /obj/item/clothing/head/wizard/marisa/fake = 1,
/obj/item/clothing/suit/wizrobe/marisa/fake = 1, /obj/item/clothing/under/sundress = 1, /obj/item/clothing/head/witchwig = 1, /obj/item/staff/broom = 1,
/obj/item/clothing/suit/wizrobe/fake = 1, /obj/item/clothing/head/wizard/fake = 1, /obj/item/staff = 3, /obj/item/clothing/mask/gas/sexyclown = 1,
/obj/item/clothing/under/rank/clown/sexy = 1, /obj/item/clothing/mask/gas/sexymime = 1, /obj/item/clothing/under/sexymime = 1, /obj/item/clothing/mask/rat/bat = 1, /obj/item/clothing/mask/rat/bee = 1, /obj/item/clothing/mask/rat/bear = 1, /obj/item/clothing/mask/rat/raven = 1, /obj/item/clothing/mask/rat/jackal = 1, /obj/item/clothing/mask/rat/fox = 1, /obj/item/clothing/mask/rat/tribal = 1, /obj/item/clothing/mask/rat = 1, /obj/item/clothing/suit/apron/overalls = 1,
/obj/item/clothing/head/rabbitears =1, /obj/item/clothing/head/sombrero = 1, /obj/item/clothing/head/sombrero/green = 1, /obj/item/clothing/suit/poncho = 1,
/obj/item/clothing/under/rank/clown/sexy = 1, /obj/item/clothing/mask/gas/sexymime = 1, /obj/item/clothing/under/sexymime = 1, /obj/item/clothing/mask/rat/bat = 1, /obj/item/clothing/mask/rat/bee = 1, /obj/item/clothing/mask/rat/bear = 1, /obj/item/clothing/mask/rat/raven = 1, /obj/item/clothing/mask/rat/jackal = 1, /obj/item/clothing/mask/rat/fox = 1, /obj/item/clothing/mask/frog = 1, /obj/item/clothing/mask/rat/tribal = 1, /obj/item/clothing/mask/rat = 1,
/obj/item/clothing/suit/apron/overalls = 1, /obj/item/clothing/head/rabbitears =1, /obj/item/clothing/head/sombrero = 1, /obj/item/clothing/head/sombrero/green = 1, /obj/item/clothing/suit/poncho = 1,
/obj/item/clothing/suit/poncho/green = 1, /obj/item/clothing/suit/poncho/red = 1,
/obj/item/clothing/under/maid = 1, /obj/item/clothing/under/janimaid = 1, /obj/item/clothing/glasses/cold=1, /obj/item/clothing/glasses/heat=1,
/obj/item/clothing/suit/whitedress = 1,
@@ -998,8 +998,8 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
/obj/item/clothing/head/cueball = 1,
/obj/item/clothing/under/scratch = 1,
/obj/item/clothing/under/sailor = 1,
/obj/item/clothing/ears/headphones = 2,
/obj/item/clothing/head/wig/random = 3)
/obj/item/clothing/ears/headphones = 2,
/obj/item/clothing/head/wig/random = 3)
contraband = list(/obj/item/clothing/suit/judgerobe = 1, /obj/item/clothing/head/powdered_wig = 1, /obj/item/gun/magic/wand = 2, /obj/item/clothing/glasses/sunglasses/garb = 2, /obj/item/clothing/glasses/sunglasses/blindfold = 1, /obj/item/clothing/mask/muzzle = 2)
premium = list(/obj/item/clothing/suit/pirate/captain = 2, /obj/item/clothing/head/pirate/captain = 2, /obj/item/clothing/head/helmet/roman = 1, /obj/item/clothing/head/helmet/roman/legionaire = 1, /obj/item/clothing/under/roman = 1, /obj/item/clothing/shoes/roman = 1, /obj/item/shield/riot/roman = 1, /obj/item/skub = 1)
refill_canister = /obj/item/vending_refill/autodrobe
@@ -6,7 +6,7 @@
name = "exosuit drill"
desc = "Equipment for engineering and combat exosuits. This is the drill that'll pierce the heavens!"
icon_state = "mecha_drill"
equip_cooldown = 30
equip_cooldown = 15
energy_drain = 10
force = 15
@@ -99,7 +99,7 @@
desc = "Equipment for engineering and combat exosuits. This is an upgraded version of the drill that'll pierce the heavens!"
icon_state = "mecha_diamond_drill"
origin_tech = "materials=4;engineering=4"
equip_cooldown = 20
equip_cooldown = 10
force = 15
@@ -108,16 +108,16 @@
desc = "Equipment for engineering and combat exosuits. It will automatically check surrounding rock for useful minerals."
icon_state = "mecha_analyzer"
selectable = 0
equip_cooldown = 30
equip_cooldown = 15
var/scanning_time = 0
/obj/item/mecha_parts/mecha_equipment/mining_scanner/New()
..()
START_PROCESSING(SSobj, src)
START_PROCESSING(SSfastprocess, src)
/obj/item/mecha_parts/mecha_equipment/mining_scanner/process()
if(!loc)
STOP_PROCESSING(SSobj, src)
STOP_PROCESSING(SSfastprocess, src)
qdel(src)
if(istype(loc, /obj/mecha/working) && scanning_time <= world.time)
var/obj/mecha/working/mecha = loc
+1 -1
View File
@@ -106,7 +106,7 @@
if(recharge_port && !QDELETED(recharge_port))
data["recharge_port"] = list("mech" = null)
if(recharge_port.recharging_mech && !QDELETED(recharge_port.recharging_mech))
data["recharge_port"]["mech"] = list("health" = recharge_port.recharging_mech.obj_integrity, "max_integrity" = recharge_port.recharging_mech.max_integrity, "cell" = null)
data["recharge_port"]["mech"] = list("health" = recharge_port.recharging_mech.obj_integrity, "maxhealth" = recharge_port.recharging_mech.max_integrity, "cell" = null)
if(recharge_port.recharging_mech.cell && !QDELETED(recharge_port.recharging_mech.cell))
data["recharge_port"]["mech"]["cell"] = list(
"critfail" = recharge_port.recharging_mech.cell.crit_fail,
+1 -1
View File
@@ -22,7 +22,7 @@
/atom/movable/MouseDrop_T(mob/living/M, mob/living/user)
. = ..()
if(can_buckle && istype(M))
if(can_buckle && istype(M) && istype(user))
if(user_buckle_mob(M, user))
return 1
+12 -6
View File
@@ -5,20 +5,26 @@
icon_state = "rune1"
gender = NEUTER
var/do_icon_rotate = TRUE
var/rotation = 0
var/paint_colour = "#FFFFFF"
/obj/effect/decal/cleanable/crayon/Initialize(mapload, main = "#FFFFFF", var/type = "rune1", var/e_name = "rune", var/rotation = 0, var/alt_icon = null)
/obj/effect/decal/cleanable/crayon/Initialize(mapload, main, type, e_name, graf_rot, alt_icon = null)
. = ..()
name = e_name
if(e_name)
name = e_name
desc = "A [name] vandalizing the station."
if(alt_icon)
icon = alt_icon
icon_state = type
if(type)
icon_state = type
if(graf_rot)
rotation = graf_rot
if(rotation && do_icon_rotate)
var/matrix/M = matrix()
M.Turn(rotation)
src.transform = M
add_atom_colour(main, FIXED_COLOUR_PRIORITY)
if(main)
paint_colour = main
add_atom_colour(paint_colour, FIXED_COLOUR_PRIORITY)

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