mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-01-14 19:41:53 +00:00
Deconflict
This commit is contained in:
@@ -123,8 +123,12 @@
|
||||
#define TANK_RUPTURE_PRESSURE (40.*ONE_ATMOSPHERE) //Tank spills all contents into atmosphere
|
||||
#define TANK_FRAGMENT_PRESSURE (50.*ONE_ATMOSPHERE) //Boom 3x3 base explosion
|
||||
#define TANK_FRAGMENT_SCALE (10.*ONE_ATMOSPHERE) //+1 for each SCALE kPa aboe threshold
|
||||
#define TANK_DEFAULT_RELEASE_PRESSURE 16
|
||||
|
||||
// Atmos alarm defines
|
||||
#define ATMOS_ALARM_NONE 0
|
||||
#define ATMOS_ALARM_WARNING 1
|
||||
#define ATMOS_ALARM_DANGER 2
|
||||
|
||||
//LAVALAND
|
||||
#define LAVALAND_EQUIPMENT_EFFECT_PRESSURE 50 //what pressure you have to be under to increase the effect of equipment meant for lavaland
|
||||
@@ -57,6 +57,89 @@
|
||||
#define MAX_STACK_AMOUNT_GLASS 50
|
||||
#define MAX_STACK_AMOUNT_RODS 60
|
||||
|
||||
//Colors
|
||||
#define COLOR_RED "#FF0000"
|
||||
#define COLOR_GREEN "#00FF00"
|
||||
#define COLOR_BLUE "#0000FF"
|
||||
#define COLOR_CYAN "#00FFFF"
|
||||
#define COLOR_PINK "#FF00FF"
|
||||
#define COLOR_YELLOW "#FFFF00"
|
||||
#define COLOR_ORANGE "#FF9900"
|
||||
#define COLOR_WHITE "#FFFFFF"
|
||||
#define COLOR_GRAY "#808080"
|
||||
#define COLOR_BLACK "#000000"
|
||||
#define COLOR_NAVY_BLUE "#000080"
|
||||
#define COLOR_LIGHT_GREEN "#008000"
|
||||
#define COLOR_DARK_GRAY "#404040"
|
||||
#define COLOR_MAROON "#800000"
|
||||
#define COLOR_PURPLE "#800080"
|
||||
#define COLOR_VIOLET "#9933ff"
|
||||
#define COLOR_OLIVE "#808000"
|
||||
#define COLOR_BROWN_ORANGE "#824b28"
|
||||
#define COLOR_DARK_ORANGE "#b95a00"
|
||||
#define COLOR_GRAY40 "#666666"
|
||||
#define COLOR_GRAY20 "#333333"
|
||||
#define COLOR_GRAY15 "#151515"
|
||||
#define COLOR_SEDONA "#cc6600"
|
||||
#define COLOR_DARK_BROWN "#917448"
|
||||
#define COLOR_DEEP_SKY_BLUE "#00e1ff"
|
||||
#define COLOR_LIME "#00ff00"
|
||||
#define COLOR_TEAL "#33cccc"
|
||||
#define COLOR_PALE_PINK "#bf89ba"
|
||||
#define COLOR_YELLOW_GRAY "#c9a344"
|
||||
#define COLOR_PALE_YELLOW "#c1bb7a"
|
||||
#define COLOR_WARM_YELLOW "#b3863c"
|
||||
#define COLOR_RED_GRAY "#aa5f61"
|
||||
#define COLOR_BROWN "#b19664"
|
||||
#define COLOR_GREEN_GRAY "#8daf6a"
|
||||
#define COLOR_DARK_GREEN_GRAY "#54654c"
|
||||
#define COLOR_BLUE_GRAY "#6a97b0"
|
||||
#define COLOR_DARK_BLUE_GRAY "#3e4855"
|
||||
#define COLOR_SUN "#ec8b2f"
|
||||
#define COLOR_PURPLE_GRAY "#a2819e"
|
||||
#define COLOR_BLUE_LIGHT "#33ccff"
|
||||
#define COLOR_RED_LIGHT "#ff3333"
|
||||
#define COLOR_BEIGE "#ceb689"
|
||||
#define COLOR_BABY_BLUE "#89cff0"
|
||||
#define COLOR_PALE_GREEN_GRAY "#aed18b"
|
||||
#define COLOR_PALE_RED_GRAY "#cc9090"
|
||||
#define COLOR_PALE_PURPLE_GRAY "#bda2ba"
|
||||
#define COLOR_PALE_BLUE_GRAY "#8bbbd5"
|
||||
#define COLOR_LUMINOL "#66ffff"
|
||||
#define COLOR_SILVER "#c0c0c0"
|
||||
#define COLOR_GRAY80 "#cccccc"
|
||||
#define COLOR_OFF_WHITE "#eeeeee"
|
||||
#define COLOR_GOLD "#6d6133"
|
||||
#define COLOR_NT_RED "#9d2300"
|
||||
#define COLOR_BOTTLE_GREEN "#1f6b4f"
|
||||
#define COLOR_PALE_BTL_GREEN "#57967f"
|
||||
#define COLOR_GUNMETAL "#545c68"
|
||||
#define COLOR_WALL_GUNMETAL "#353a42"
|
||||
#define COLOR_STEEL "#a8b0b2"
|
||||
#define COLOR_MUZZLE_FLASH "#ffffb2"
|
||||
#define COLOR_CHESTNUT "#996633"
|
||||
#define COLOR_BEASTY_BROWN "#663300"
|
||||
#define COLOR_WHEAT "#ffff99"
|
||||
#define COLOR_CYAN_BLUE "#3366cc"
|
||||
#define COLOR_LIGHT_CYAN "#66ccff"
|
||||
#define COLOR_PAKISTAN_GREEN "#006600"
|
||||
#define COLOR_HULL "#436b8e"
|
||||
#define COLOR_AMBER "#ffbf00"
|
||||
#define COLOR_COMMAND_BLUE "#46698c"
|
||||
#define COLOR_SKY_BLUE "#5ca1cc"
|
||||
#define COLOR_PALE_ORANGE "#b88a3b"
|
||||
#define COLOR_CIVIE_GREEN "#b7f27d"
|
||||
#define COLOR_TITANIUM "#d1e6e3"
|
||||
#define COLOR_DARK_GUNMETAL "#4c535b"
|
||||
#define COLOR_BRONZE "#8c7853"
|
||||
#define COLOR_BRASS "#b99d71"
|
||||
#define COLOR_INDIGO "#4b0082"
|
||||
#define COLOR_ALUMINIUM "#bbbbbb"
|
||||
#define COLOR_CRYSTAL "#00c8a5"
|
||||
#define COLOR_ASTEROID_ROCK "#735555"
|
||||
#define COLOR_NULLGLASS "#ff6088"
|
||||
#define COLOR_DIAMOND "#d8d4ea"
|
||||
|
||||
//FONTS:
|
||||
// Used by Paper and PhotoCopier (and PaperBin once a year).
|
||||
// Used by PDA's Notekeeper.
|
||||
@@ -270,6 +353,8 @@
|
||||
#define TRIGGER_GUARD_NONE 0
|
||||
#define TRIGGER_GUARD_NORMAL 1
|
||||
|
||||
#define CLIENT_FROM_VAR(I) (ismob(I) ? I:client : (istype(I, /client) ? I : (istype(I, /datum/mind) ? I:current?:client : null)))
|
||||
|
||||
// Macro to get the current elapsed round time, rather than total world runtime
|
||||
#define ROUND_TIME (SSticker.round_start_time ? (world.time - SSticker.round_start_time) : 0)
|
||||
|
||||
@@ -305,6 +390,8 @@
|
||||
#define BLOODY_FOOTPRINT_BASE_ALPHA 150
|
||||
#define BLOOD_GAIN_PER_STEP 100
|
||||
#define BLOOD_LOSS_PER_STEP 5
|
||||
#define BLOOD_LOSS_IN_SPREAD 20
|
||||
#define BLOOD_AMOUNT_PER_DECAL 20
|
||||
|
||||
//Bloody shoe blood states
|
||||
#define BLOOD_STATE_HUMAN "blood"
|
||||
@@ -320,7 +407,7 @@
|
||||
#define INVESTIGATE_BOMB "bombs"
|
||||
|
||||
// The SQL version required by this version of the code
|
||||
#define SQL_VERSION 8
|
||||
#define SQL_VERSION 9
|
||||
|
||||
// Vending machine stuff
|
||||
#define CAT_NORMAL 1
|
||||
@@ -402,4 +489,15 @@
|
||||
|
||||
#define DICE_NOT_RIGGED 1
|
||||
#define DICE_BASICALLY_RIGGED 2
|
||||
#define DICE_TOTALLY_RIGGED 3
|
||||
#define DICE_TOTALLY_RIGGED 3
|
||||
|
||||
// Parallax
|
||||
#define PARALLAX_DELAY_DEFAULT world.tick_lag
|
||||
#define PARALLAX_DELAY_MED 1
|
||||
#define PARALLAX_DELAY_LOW 2
|
||||
#define PARALLAX_LOOP_TIME 25
|
||||
|
||||
// Engine types
|
||||
#define ENGTYPE_SING "Singularity"
|
||||
#define ENGTYPE_SM "Supermatter"
|
||||
#define ENGTYPE_TESLA "Tesla"
|
||||
@@ -187,6 +187,7 @@
|
||||
#define isswarmer(A) (istype((A), /mob/living/simple_animal/hostile/swarmer))
|
||||
#define isguardian(A) (istype((A), /mob/living/simple_animal/hostile/guardian))
|
||||
#define isnymph(A) (istype((A), /mob/living/simple_animal/diona))
|
||||
#define ishostile(A) (istype(A, /mob/living/simple_animal/hostile))
|
||||
|
||||
#define issilicon(A) (istype((A), /mob/living/silicon))
|
||||
#define isAI(A) (istype((A), /mob/living/silicon/ai))
|
||||
|
||||
@@ -63,3 +63,12 @@
|
||||
#define EXP_TYPE_WHITELIST "Whitelist"
|
||||
|
||||
#define EXP_DEPT_TYPE_LIST list(EXP_TYPE_SERVICE, EXP_TYPE_MEDICAL, EXP_TYPE_ENGINEERING, EXP_TYPE_SCIENCE, EXP_TYPE_SECURITY, EXP_TYPE_COMMAND, EXP_TYPE_SILICON, EXP_TYPE_SPECIAL)
|
||||
|
||||
// Defines just for parallax because its levels make storing it in the regular prefs a pain in the ass
|
||||
// These dont need to be bitflags because there isnt going to be more than one at a time of these active
|
||||
// But its gonna piss off my OCD if it isnt bitflags, so deal with it, -affected
|
||||
#define PARALLAX_DISABLE 1
|
||||
#define PARALLAX_LOW 2
|
||||
#define PARALLAX_MED 4
|
||||
#define PARALLAX_HIGH 8
|
||||
#define PARALLAX_INSANE 16
|
||||
|
||||
@@ -32,3 +32,10 @@
|
||||
#define SECHUD 1
|
||||
#define MEDHUD 2
|
||||
#define ANTAGHUD 3
|
||||
|
||||
//for clothing visor toggles, these determine which vars to toggle
|
||||
#define VISOR_FLASHPROTECT (1<<0)
|
||||
#define VISOR_TINT (1<<1)
|
||||
#define VISOR_VISIONFLAGS (1<<2) //all following flags only matter for glasses
|
||||
#define VISOR_DARKNESSVIEW (1<<3)
|
||||
#define VISOR_INVISVIEW (1<<4)
|
||||
@@ -41,6 +41,7 @@
|
||||
#define SHUTTLE_STRANDED 4
|
||||
#define SHUTTLE_ESCAPE 5
|
||||
#define SHUTTLE_ENDGAME 6
|
||||
#define SHUTTLE_IGNITING 7
|
||||
|
||||
// Shuttle return values
|
||||
#define SHUTTLE_CAN_DOCK "can_dock"
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
//#define STATUS_EFFECT_WISH_GRANTERS_GIFT /datum/status_effect/wish_granters_gift //If you're currently resurrecting with the Wish Granter
|
||||
|
||||
//#define STATUS_EFFECT_BLOODDRUNK /datum/status_effect/blooddrunk //Stun immunity and greatly reduced damage taken
|
||||
#define STATUS_EFFECT_BLOODDRUNK /datum/status_effect/blooddrunk //Stun immunity and greatly reduced damage taken
|
||||
|
||||
/////////////
|
||||
// DEBUFFS //
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
#define STATUS_EFFECT_SUMMONEDGHOST /datum/status_effect/cultghost //is a cult ghost and can't use manifest runes
|
||||
|
||||
//#define STATUS_EFFECT_CRUSHERMARK /datum/status_effect/crusher_mark //if struck with a proto-kinetic crusher, takes a ton of damage
|
||||
#define STATUS_EFFECT_CRUSHERMARK /datum/status_effect/crusher_mark //if struck with a proto-kinetic crusher, takes a ton of damage
|
||||
|
||||
#define STATUS_EFFECT_SAWBLEED /datum/status_effect/saw_bleed //if the bleed builds up enough, takes a ton of damage
|
||||
|
||||
@@ -74,6 +74,6 @@
|
||||
|
||||
//#define STATUS_EFFECT_SIGILMARK /datum/status_effect/sigil_mark
|
||||
|
||||
//#define STATUS_EFFECT_CRUSHERDAMAGETRACKING /datum/status_effect/crusher_damage //tracks total kinetic crusher damage on a target
|
||||
#define STATUS_EFFECT_CRUSHERDAMAGETRACKING /datum/status_effect/crusher_damage //tracks total kinetic crusher damage on a target
|
||||
|
||||
//#define STATUS_EFFECT_SYPHONMARK /datum/status_effect/syphon_mark //tracks kills for the KA death syphon module
|
||||
#define STATUS_EFFECT_SYPHONMARK /datum/status_effect/syphon_mark //tracks kills for the KA death syphon module
|
||||
@@ -79,7 +79,8 @@
|
||||
#define INIT_ORDER_NANOMOB -23
|
||||
#define INIT_ORDER_SQUEAK -40
|
||||
#define INIT_ORDER_PATH -50
|
||||
#define INIT_ORDER_PERSISTENCE -100
|
||||
#define INIT_ORDER_PERSISTENCE -95
|
||||
#define INIT_ORDER_CHAT -100 //Should be last to ensure chat remains smooth during init.
|
||||
|
||||
// Subsystem fire priority, from lowest to highest priority
|
||||
// If the subsystem isn't listed here it's either DEFAULT or PROCESS (if it's a processing subsystem child)
|
||||
@@ -111,6 +112,7 @@
|
||||
#define FIRE_PRIORITY_MOBS 100
|
||||
#define FIRE_PRIORITY_NANOUI 110
|
||||
#define FIRE_PRIORITY_TICKER 200
|
||||
#define FIRE_PRIORITY_CHAT 400
|
||||
#define FIRE_PRIORITY_OVERLAYS 500
|
||||
#define FIRE_PRIORITY_INPUT 1000 // This must always always be the max highest priority. Player input must never be lost.
|
||||
|
||||
|
||||
@@ -19,6 +19,12 @@
|
||||
return A
|
||||
return 0
|
||||
|
||||
/proc/get_location_name(atom/X, format_text = FALSE)
|
||||
var/area/A = isarea(X) ? X : get_area(X)
|
||||
if(!A)
|
||||
return null
|
||||
return format_text ? format_text(A.name) : A.name
|
||||
|
||||
/proc/get_areas_in_range(dist=0, atom/center=usr)
|
||||
if(!dist)
|
||||
var/turf/T = get_turf(center)
|
||||
@@ -429,6 +435,17 @@
|
||||
/proc/GetBluePart(const/hexa)
|
||||
return hex2num(copytext(hexa, 6, 8))
|
||||
|
||||
/proc/lavaland_equipment_pressure_check(turf/T)
|
||||
. = FALSE
|
||||
if(!istype(T))
|
||||
return
|
||||
var/datum/gas_mixture/environment = T.return_air()
|
||||
if(!istype(environment))
|
||||
return
|
||||
var/pressure = environment.return_pressure()
|
||||
if(pressure <= LAVALAND_EQUIPMENT_EFFECT_PRESSURE)
|
||||
. = TRUE
|
||||
|
||||
/proc/GetHexColors(const/hexa)
|
||||
return list(
|
||||
GetRedPart(hexa),
|
||||
|
||||
@@ -153,29 +153,33 @@
|
||||
/turf/simulated/wall/diagonal_smooth(adjacencies)
|
||||
adjacencies = reverse_ndir(..())
|
||||
if(adjacencies)
|
||||
var/list/U = list()
|
||||
var/mutable_appearance/underlay_appearance = mutable_appearance(layer = TURF_LAYER, plane = FLOOR_PLANE)
|
||||
var/list/U = list(underlay_appearance)
|
||||
if(fixed_underlay)
|
||||
if(fixed_underlay["space"])
|
||||
U += image('icons/turf/space.dmi', SPACE_ICON_STATE, layer=TURF_LAYER)
|
||||
underlay_appearance.icon = 'icons/turf/space.dmi'
|
||||
underlay_appearance.icon_state = SPACE_ICON_STATE
|
||||
underlay_appearance.plane = PLANE_SPACE
|
||||
else
|
||||
U += image(fixed_underlay["icon"], fixed_underlay["icon_state"], layer=TURF_LAYER)
|
||||
underlay_appearance.icon = fixed_underlay["icon"]
|
||||
underlay_appearance.icon_state = fixed_underlay["icon_state"]
|
||||
else
|
||||
var/turf/T = get_step(src, turn(adjacencies, 180))
|
||||
if(T && (T.density || T.smooth))
|
||||
var/turned_adjacency = turn(adjacencies, 180)
|
||||
var/turf/T = get_step(src, turned_adjacency)
|
||||
if(!T.get_smooth_underlay_icon(underlay_appearance, src, turned_adjacency))
|
||||
T = get_step(src, turn(adjacencies, 135))
|
||||
if(T && (T.density || T.smooth))
|
||||
if(!T.get_smooth_underlay_icon(underlay_appearance, src, turned_adjacency))
|
||||
T = get_step(src, turn(adjacencies, 225))
|
||||
|
||||
if(istype(T, /turf/space) && !istype(T, /turf/space/transit))
|
||||
U += image('icons/turf/space.dmi', SPACE_ICON_STATE, layer=TURF_LAYER)
|
||||
else if(T && !T.density && !T.smooth)
|
||||
U += T
|
||||
else if(baseturf && !initial(baseturf.density) && !initial(baseturf.smooth))
|
||||
U += image(initial(baseturf.icon), initial(baseturf.icon_state), layer=TURF_LAYER)
|
||||
else
|
||||
U += DEFAULT_UNDERLAY_IMAGE
|
||||
//if all else fails, ask our own turf
|
||||
if(!T.get_smooth_underlay_icon(underlay_appearance, src, turned_adjacency) && !get_smooth_underlay_icon(underlay_appearance, src, turned_adjacency))
|
||||
underlay_appearance.icon = DEFAULT_UNDERLAY_ICON
|
||||
underlay_appearance.icon_state = DEFAULT_UNDERLAY_ICON_STATE
|
||||
underlays = U
|
||||
|
||||
// Drop posters which were previously placed on this wall.
|
||||
for(var/obj/structure/sign/poster/P in src)
|
||||
P.roll_and_drop(src)
|
||||
|
||||
/proc/cardinal_smooth(atom/A, adjacencies)
|
||||
//NW CORNER
|
||||
var/nw = "1-i"
|
||||
|
||||
@@ -545,6 +545,43 @@ proc/checkhtml(var/t)
|
||||
text = copytext(text, 1, MAX_PAPER_MESSAGE_LEN)
|
||||
return text
|
||||
|
||||
/proc/convert_pencode_arg(text, tag, arg)
|
||||
arg = sanitize_simple(html_encode(arg), list("''"="","\""="", "?"=""))
|
||||
// https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html#rule-4---css-escape-and-strictly-validate-before-inserting-untrusted-data-into-html-style-property-values
|
||||
var/list/style_attacks = list("javascript:", "expression", "byond:", "file:")
|
||||
|
||||
for(var/style_attack in style_attacks)
|
||||
if(findtext(arg, style_attack))
|
||||
// Do not attempt to render dangerous things
|
||||
return text
|
||||
|
||||
if(tag == "class")
|
||||
return "<span class='[arg]'>"
|
||||
|
||||
if(tag == "style")
|
||||
return "<span style='[arg]'>"
|
||||
|
||||
if(tag == "img")
|
||||
var/list/img_props = splittext(arg, ";")
|
||||
if(img_props.len == 3)
|
||||
return "<img src='[img_props[1]]' width='[img_props[2]]' height='[img_props[3]]'>"
|
||||
if(img_props.len == 2)
|
||||
return "<img src='[img_props[1]]' width='[img_props[2]]'>"
|
||||
return "<img src='[arg]'>"
|
||||
|
||||
return text
|
||||
|
||||
/proc/admin_pencode_to_html()
|
||||
var/text = pencode_to_html(arglist(args))
|
||||
var/regex/R = new(@"\[(.*?) (.*?)\]", "ge")
|
||||
text = R.Replace(text, /proc/convert_pencode_arg)
|
||||
|
||||
text = replacetext(text, "\[/class\]", "</span>")
|
||||
text = replacetext(text, "\[/style\]", "</span>")
|
||||
text = replacetext(text, "\[/img\]", "</img>")
|
||||
|
||||
return text
|
||||
|
||||
/proc/html_to_pencode(text)
|
||||
text = replacetext(text, "<BR>", "\n")
|
||||
text = replacetext(text, "<center>", "\[center\]")
|
||||
|
||||
@@ -47,4 +47,6 @@ GLOBAL_LIST_INIT(active_diseases, list()) //List of Active disease in all mob
|
||||
|
||||
GLOBAL_LIST_EMPTY(mob_spawners) // All mob_spawn objects
|
||||
|
||||
GLOBAL_LIST_EMPTY(explosive_walls)
|
||||
GLOBAL_LIST_EMPTY(explosive_walls)
|
||||
|
||||
GLOBAL_LIST_EMPTY(engine_beacon_list)
|
||||
@@ -209,11 +209,13 @@
|
||||
/atom/proc/AIMiddleClick()
|
||||
return
|
||||
|
||||
/obj/machinery/door/airlock/AIMiddleClick() // Toggles door bolt lights.
|
||||
if(!src.lights)
|
||||
Topic(src, list("src" = UID(), "command"="lights", "activate" = "1"), 1) // 1 meaning no window (consistency!)
|
||||
/obj/machinery/door/airlock/AIMiddleClick() // Toggles door safety.
|
||||
if(safe)
|
||||
Topic(src, list("src" = UID(), "command"="safeties", "activate" = "1"), 1) // 1 meaning no window (consistency!)
|
||||
to_chat(usr, "The door safeties have been overridden.")
|
||||
else
|
||||
Topic(src, list("src" = UID(), "command"="lights", "activate" = "0"), 1)
|
||||
Topic(src, list("src" = UID(), "command"="safeties", "activate" = "0"), 1)
|
||||
to_chat(usr, "The door safeties have been reset.")
|
||||
return
|
||||
|
||||
/obj/machinery/ai_slipper/AICtrlClick() //Turns liquid dispenser on or off
|
||||
|
||||
@@ -107,14 +107,20 @@
|
||||
#define ui_healthdoll "EAST-1:28,CENTER-1:15"
|
||||
#define ui_health "EAST-1:28,CENTER:17"
|
||||
#define ui_internal "EAST-1:28,CENTER+1:19"
|
||||
//borgs
|
||||
|
||||
//borgs
|
||||
#define ui_borg_health "EAST-1:28,CENTER-1:15" //borgs have the health display where humans have the pressure damage indicator.
|
||||
|
||||
//aliens
|
||||
#define ui_alien_health "EAST-1:28,CENTER-1:15" //aliens have the health display where humans have the pressure damage indicator.
|
||||
|
||||
|
||||
//constructs
|
||||
#define ui_construct_pull "EAST-1:28,SOUTH+1:10" //above the zone_sel icon
|
||||
#define ui_construct_health "EAST,CENTER:15" //same height as humans, hugging the right border
|
||||
|
||||
//slimes
|
||||
#define ui_slime_health "EAST,CENTER:15" //same as borgs, constructs and humans
|
||||
|
||||
//Pop-up inventory
|
||||
#define ui_shoes "WEST+1:8,SOUTH:5"
|
||||
|
||||
|
||||
@@ -2,6 +2,25 @@
|
||||
var/datum/action/linked_action
|
||||
screen_loc = null
|
||||
|
||||
/obj/screen/movable/action_button/MouseDrop(over_object)
|
||||
if((istype(over_object, /obj/screen/movable/action_button) && !istype(over_object, /obj/screen/movable/action_button/hide_toggle)))
|
||||
if(locked)
|
||||
to_chat(usr, "<span class='warning'>Action button \"[name]\" is locked, unlock it first.</span>")
|
||||
closeToolTip(usr)
|
||||
return
|
||||
var/obj/screen/movable/action_button/B = over_object
|
||||
var/list/actions = usr.actions
|
||||
actions.Swap(actions.Find(linked_action), actions.Find(B.linked_action))
|
||||
moved = FALSE
|
||||
B.moved = FALSE
|
||||
closeToolTip(usr)
|
||||
usr.update_action_buttons()
|
||||
else if(istype(over_object, /obj/screen/movable/action_button/hide_toggle))
|
||||
closeToolTip(usr)
|
||||
else
|
||||
closeToolTip(usr)
|
||||
return ..()
|
||||
|
||||
/obj/screen/movable/action_button/Click(location,control,params)
|
||||
var/list/modifiers = params2list(params)
|
||||
if(modifiers["shift"])
|
||||
@@ -29,6 +48,13 @@
|
||||
icon_state = "bg_default"
|
||||
var/hidden = 0
|
||||
|
||||
/obj/screen/movable/action_button/hide_toggle/MouseDrop(over_object)
|
||||
if(istype(over_object, /obj/screen/movable/action_button))
|
||||
closeToolTip(usr)
|
||||
else
|
||||
closeToolTip(usr)
|
||||
return ..()
|
||||
|
||||
/obj/screen/movable/action_button/hide_toggle/Click(location,control,params)
|
||||
var/list/modifiers = params2list(params)
|
||||
if(modifiers["shift"])
|
||||
@@ -83,9 +109,9 @@
|
||||
var/image/img = image(icon, src, hidden ? "show" : "hide")
|
||||
overlays += img
|
||||
|
||||
/obj/screen/movable/action_button/MouseEntered(location,control,params)
|
||||
openToolTip(usr,src,params,title = name,content = desc)
|
||||
|
||||
/obj/screen/movable/action_button/MouseEntered(location, control, params)
|
||||
if(!QDELETED(src))
|
||||
openToolTip(usr, src, params, title = name, content = desc)
|
||||
|
||||
/obj/screen/movable/action_button/MouseExited()
|
||||
closeToolTip(usr)
|
||||
|
||||
@@ -256,4 +256,10 @@
|
||||
//Add multicamera camera
|
||||
using = new /obj/screen/ai/add_multicam()
|
||||
using.screen_loc = ui_ai_add_multicam
|
||||
static_inventory += using
|
||||
static_inventory += using
|
||||
|
||||
//Intent
|
||||
using = new /obj/screen/act_intent/robot/AI()
|
||||
using.icon_state = mymob.a_intent
|
||||
static_inventory += using
|
||||
action_intent = using
|
||||
@@ -49,8 +49,8 @@
|
||||
|
||||
/obj/screen/blob/Blobbernaut
|
||||
icon_state = "ui_blobbernaut"
|
||||
name = "Produce Blobbernaut (20)"
|
||||
desc = "Produces a strong, but dumb blobbernaut from a factory blob for 20 resources.<br>The factory blob will be destroyed in the process."
|
||||
name = "Produce Blobbernaut (60)"
|
||||
desc = "Produces a strong, intelligent blobbernaut from a factory blob for 60 resources.<br>The factory blob will be destroyed in the process."
|
||||
|
||||
/obj/screen/blob/Blobbernaut/Click()
|
||||
if(isovermind(usr))
|
||||
|
||||
@@ -59,3 +59,8 @@
|
||||
using = new /obj/screen/ghost/teleport()
|
||||
using.screen_loc = ui_ghost_teleport
|
||||
static_inventory += using
|
||||
|
||||
/datum/hud/ghost/show_hud()
|
||||
mymob.client.screen = list()
|
||||
mymob.client.screen += static_inventory
|
||||
..()
|
||||
|
||||
@@ -99,6 +99,7 @@
|
||||
/datum/hud/proc/show_hud(version = 0)
|
||||
if(!ismob(mymob))
|
||||
return FALSE
|
||||
|
||||
if(!mymob.client)
|
||||
return FALSE
|
||||
|
||||
@@ -172,6 +173,7 @@
|
||||
mymob.update_action_buttons(1)
|
||||
reorganize_alerts()
|
||||
reload_fullscreen()
|
||||
update_parallax_pref(mymob)
|
||||
plane_masters_update()
|
||||
|
||||
/datum/hud/proc/plane_masters_update()
|
||||
|
||||
319
code/_onclick/hud/parallax.dm
Normal file
319
code/_onclick/hud/parallax.dm
Normal file
@@ -0,0 +1,319 @@
|
||||
/client
|
||||
var/list/parallax_layers
|
||||
var/list/parallax_layers_cached
|
||||
var/static/list/parallax_static_layers_tail = newlist(/obj/screen/parallax_pmaster, /obj/screen/parallax_space_whitifier)
|
||||
var/atom/movable/movingmob
|
||||
var/turf/previous_turf
|
||||
var/dont_animate_parallax //world.time of when we can state animate()ing parallax again
|
||||
var/last_parallax_shift //world.time of last update
|
||||
var/parallax_throttle = 0 //ds between updates
|
||||
var/parallax_movedir = 0
|
||||
var/parallax_layers_max = 3
|
||||
var/parallax_animate_timer
|
||||
|
||||
/datum/hud/proc/create_parallax()
|
||||
var/client/C = mymob.client
|
||||
if(!apply_parallax_pref())
|
||||
return
|
||||
|
||||
if(!length(C.parallax_layers_cached))
|
||||
C.parallax_layers_cached = list()
|
||||
C.parallax_layers_cached += new /obj/screen/parallax_layer/layer_1(null, C.view)
|
||||
C.parallax_layers_cached += new /obj/screen/parallax_layer/layer_2(null, C.view)
|
||||
C.parallax_layers_cached += new /obj/screen/parallax_layer/planet(null, C.view)
|
||||
C.parallax_layers_cached += new /obj/screen/parallax_layer/layer_3(null, C.view)
|
||||
|
||||
C.parallax_layers = C.parallax_layers_cached.Copy()
|
||||
|
||||
if(length(C.parallax_layers) > C.parallax_layers_max)
|
||||
C.parallax_layers.len = C.parallax_layers_max
|
||||
|
||||
C.screen |= (C.parallax_layers + C.parallax_static_layers_tail)
|
||||
|
||||
/datum/hud/proc/remove_parallax()
|
||||
var/client/C = mymob.client
|
||||
C.screen -= (C.parallax_layers_cached + C.parallax_static_layers_tail)
|
||||
C.parallax_layers = null
|
||||
|
||||
/datum/hud/proc/apply_parallax_pref()
|
||||
var/client/C = mymob.client
|
||||
if(C.prefs)
|
||||
var/pref = C.prefs.parallax
|
||||
if (isnull(pref))
|
||||
pref = PARALLAX_HIGH
|
||||
switch(C.prefs.parallax)
|
||||
if (PARALLAX_INSANE)
|
||||
C.parallax_throttle = FALSE
|
||||
C.parallax_layers_max = 4
|
||||
return TRUE
|
||||
|
||||
if (PARALLAX_MED)
|
||||
C.parallax_throttle = PARALLAX_DELAY_MED
|
||||
C.parallax_layers_max = 2
|
||||
return TRUE
|
||||
|
||||
if (PARALLAX_LOW)
|
||||
C.parallax_throttle = PARALLAX_DELAY_LOW
|
||||
C.parallax_layers_max = 1
|
||||
return TRUE
|
||||
|
||||
if (PARALLAX_DISABLE)
|
||||
return FALSE
|
||||
|
||||
C.parallax_throttle = PARALLAX_DELAY_DEFAULT
|
||||
C.parallax_layers_max = 3
|
||||
return TRUE
|
||||
|
||||
/datum/hud/proc/update_parallax_pref()
|
||||
remove_parallax()
|
||||
create_parallax()
|
||||
update_parallax()
|
||||
|
||||
// This sets which way the current shuttle is moving (returns true if the shuttle has stopped moving so the caller can append their animation)
|
||||
// Well, it would if our shuttle code had dynamic areas
|
||||
/datum/hud/proc/set_parallax_movedir(new_parallax_movedir, skip_windups)
|
||||
. = FALSE
|
||||
var/client/C = mymob.client
|
||||
if(new_parallax_movedir == C.parallax_movedir)
|
||||
return
|
||||
var/animatedir = new_parallax_movedir
|
||||
if(new_parallax_movedir == FALSE)
|
||||
var/animate_time = 0
|
||||
for(var/thing in C.parallax_layers)
|
||||
var/obj/screen/parallax_layer/L = thing
|
||||
L.icon_state = initial(L.icon_state)
|
||||
L.update_o(C.view)
|
||||
var/T = PARALLAX_LOOP_TIME / L.speed
|
||||
if(T > animate_time)
|
||||
animate_time = T
|
||||
C.dont_animate_parallax = world.time + min(animate_time, PARALLAX_LOOP_TIME)
|
||||
animatedir = C.parallax_movedir
|
||||
|
||||
var/matrix/newtransform
|
||||
switch(animatedir)
|
||||
if(NORTH)
|
||||
newtransform = matrix(1, 0, 0, 0, 1, 480)
|
||||
if(SOUTH)
|
||||
newtransform = matrix(1, 0, 0, 0, 1,-480)
|
||||
if(EAST)
|
||||
newtransform = matrix(1, 0, 480, 0, 1, 0)
|
||||
if(WEST)
|
||||
newtransform = matrix(1, 0,-480, 0, 1, 0)
|
||||
|
||||
var/shortesttimer
|
||||
for(var/thing in C.parallax_layers)
|
||||
var/obj/screen/parallax_layer/L = thing
|
||||
|
||||
var/T = PARALLAX_LOOP_TIME / L.speed
|
||||
if(isnull(shortesttimer))
|
||||
shortesttimer = T
|
||||
if(T < shortesttimer)
|
||||
shortesttimer = T
|
||||
L.transform = newtransform
|
||||
animate(L, transform = matrix(), time = T, easing = QUAD_EASING | (new_parallax_movedir ? EASE_IN : EASE_OUT), flags = ANIMATION_END_NOW)
|
||||
if(new_parallax_movedir)
|
||||
L.transform = newtransform
|
||||
animate(transform = matrix(), time = T) //queue up another animate so lag doesn't create a shutter
|
||||
|
||||
C.parallax_movedir = new_parallax_movedir
|
||||
if(C.parallax_animate_timer)
|
||||
deltimer(C.parallax_animate_timer)
|
||||
var/datum/callback/CB = CALLBACK(src, .proc/update_parallax_motionblur, C, animatedir, new_parallax_movedir, newtransform)
|
||||
if(skip_windups)
|
||||
CB.Invoke()
|
||||
else
|
||||
C.parallax_animate_timer = addtimer(CB, min(shortesttimer, PARALLAX_LOOP_TIME), TIMER_CLIENT_TIME|TIMER_STOPPABLE)
|
||||
|
||||
/datum/hud/proc/update_parallax_motionblur(client/C, animatedir, new_parallax_movedir, matrix/newtransform)
|
||||
C.parallax_animate_timer = FALSE
|
||||
for(var/thing in C.parallax_layers)
|
||||
var/obj/screen/parallax_layer/L = thing
|
||||
if(!new_parallax_movedir)
|
||||
animate(L)
|
||||
continue
|
||||
|
||||
var/newstate = initial(L.icon_state)
|
||||
if(animatedir)
|
||||
if(animatedir == NORTH || animatedir == SOUTH)
|
||||
newstate += "_vertical"
|
||||
else
|
||||
newstate += "_horizontal"
|
||||
|
||||
var/T = PARALLAX_LOOP_TIME / L.speed
|
||||
|
||||
if(newstate in icon_states(L.icon))
|
||||
L.icon_state = newstate
|
||||
L.update_o(C.view)
|
||||
|
||||
L.transform = newtransform
|
||||
|
||||
animate(L, transform = matrix(), time = T, loop = -1, flags = ANIMATION_END_NOW)
|
||||
|
||||
/datum/hud/proc/update_parallax()
|
||||
var/client/C = mymob.client
|
||||
var/turf/posobj = get_turf(C.eye)
|
||||
if(!posobj)
|
||||
return
|
||||
var/area/areaobj = posobj.loc
|
||||
|
||||
// Update the movement direction of the parallax if necessary (for shuttles)
|
||||
var/area/shuttle/SA = areaobj
|
||||
if(!SA || !SA.moving)
|
||||
set_parallax_movedir(0)
|
||||
else
|
||||
set_parallax_movedir(SA.parallax_movedir)
|
||||
|
||||
var/force
|
||||
if(!C.previous_turf || (C.previous_turf.z != posobj.z))
|
||||
C.previous_turf = posobj
|
||||
force = TRUE
|
||||
|
||||
if(!force && world.time < C.last_parallax_shift+C.parallax_throttle)
|
||||
return
|
||||
|
||||
//Doing it this way prevents parallax layers from "jumping" when you change Z-Levels.
|
||||
var/offset_x = posobj.x - C.previous_turf.x
|
||||
var/offset_y = posobj.y - C.previous_turf.y
|
||||
|
||||
if(!offset_x && !offset_y && !force)
|
||||
return
|
||||
|
||||
var/last_delay = world.time - C.last_parallax_shift
|
||||
last_delay = min(last_delay, C.parallax_throttle)
|
||||
C.previous_turf = posobj
|
||||
C.last_parallax_shift = world.time
|
||||
|
||||
for(var/thing in C.parallax_layers)
|
||||
var/obj/screen/parallax_layer/L = thing
|
||||
L.update_status(mymob)
|
||||
if(L.view_sized != C.view)
|
||||
L.update_o(C.view)
|
||||
|
||||
var/change_x
|
||||
var/change_y
|
||||
|
||||
if(L.absolute)
|
||||
L.offset_x = -(posobj.x - SSparallax.planet_x_offset) * L.speed
|
||||
L.offset_y = -(posobj.y - SSparallax.planet_y_offset) * L.speed
|
||||
else
|
||||
change_x = offset_x * L.speed
|
||||
L.offset_x -= change_x
|
||||
change_y = offset_y * L.speed
|
||||
L.offset_y -= change_y
|
||||
|
||||
if(L.offset_x > 240)
|
||||
L.offset_x -= 480
|
||||
if(L.offset_x < -240)
|
||||
L.offset_x += 480
|
||||
if(L.offset_y > 240)
|
||||
L.offset_y -= 480
|
||||
if(L.offset_y < -240)
|
||||
L.offset_y += 480
|
||||
|
||||
if(!(areaobj.parallax_movedir && areaobj.moving) && C.dont_animate_parallax <= world.time && (offset_x || offset_y) && abs(offset_x) <= max(C.parallax_throttle/world.tick_lag+1,1) && abs(offset_y) <= max(C.parallax_throttle/world.tick_lag+1,1) && (round(abs(change_x)) > 1 || round(abs(change_y)) > 1))
|
||||
L.transform = matrix(1, 0, offset_x*L.speed, 0, 1, offset_y*L.speed)
|
||||
animate(L, transform=matrix(), time = last_delay)
|
||||
|
||||
L.screen_loc = "CENTER-7:[round(L.offset_x,1)],CENTER-7:[round(L.offset_y,1)]"
|
||||
|
||||
/atom/movable/proc/update_parallax_contents()
|
||||
if(length(client_mobs_in_contents))
|
||||
for(var/thing in client_mobs_in_contents)
|
||||
var/mob/M = thing
|
||||
if(M && M.client && M.hud_used && length(M.client.parallax_layers))
|
||||
M.hud_used.update_parallax()
|
||||
|
||||
/obj/screen/parallax_layer
|
||||
icon = 'icons/effects/parallax.dmi'
|
||||
var/speed = 1
|
||||
var/offset_x = 0
|
||||
var/offset_y = 0
|
||||
var/view_sized
|
||||
var/absolute = FALSE
|
||||
blend_mode = BLEND_ADD
|
||||
plane = PLANE_SPACE_PARALLAX
|
||||
screen_loc = "CENTER-7,CENTER-7"
|
||||
mouse_opacity = 0
|
||||
|
||||
|
||||
/obj/screen/parallax_layer/New(view)
|
||||
..()
|
||||
if(!view)
|
||||
view = world.view
|
||||
update_o(view)
|
||||
|
||||
/obj/screen/parallax_layer/proc/update_o(view)
|
||||
if(!view)
|
||||
view = world.view
|
||||
var/list/new_overlays = list()
|
||||
var/count = Ceiling(view/(480/world.icon_size))+1
|
||||
for(var/x in -count to count)
|
||||
for(var/y in -count to count)
|
||||
if(x == 0 && y == 0)
|
||||
continue
|
||||
var/mutable_appearance/texture_overlay = mutable_appearance(icon, icon_state)
|
||||
texture_overlay.transform = matrix(1, 0, x*480, 0, 1, y*480)
|
||||
new_overlays += texture_overlay
|
||||
|
||||
overlays = new_overlays
|
||||
view_sized = view
|
||||
|
||||
/obj/screen/parallax_layer/proc/update_status(mob/M)
|
||||
return
|
||||
|
||||
/obj/screen/parallax_layer/layer_1
|
||||
icon_state = "layer1"
|
||||
speed = 0.6
|
||||
layer = 1
|
||||
|
||||
/obj/screen/parallax_layer/layer_2
|
||||
icon_state = "layer2"
|
||||
speed = 1
|
||||
layer = 2
|
||||
|
||||
/obj/screen/parallax_layer/layer_3
|
||||
icon_state = "layer3"
|
||||
speed = 1.4
|
||||
layer = 3
|
||||
|
||||
/obj/screen/parallax_layer/planet
|
||||
icon_state = "planet"
|
||||
blend_mode = BLEND_OVERLAY
|
||||
absolute = TRUE //Status of seperation
|
||||
speed = 3
|
||||
layer = 30
|
||||
|
||||
/obj/screen/parallax_layer/planet/update_status(mob/M)
|
||||
var/turf/T = get_turf(M)
|
||||
if(is_station_level(T.z))
|
||||
invisibility = 0
|
||||
else
|
||||
invisibility = INVISIBILITY_ABSTRACT
|
||||
|
||||
/obj/screen/parallax_layer/planet/update_o()
|
||||
return //Shit wont move
|
||||
|
||||
/obj/screen/parallax_pmaster
|
||||
appearance_flags = PLANE_MASTER
|
||||
plane = PLANE_SPACE_PARALLAX
|
||||
blend_mode = BLEND_MULTIPLY
|
||||
mouse_opacity = FALSE
|
||||
screen_loc = "CENTER-7,CENTER-7"
|
||||
|
||||
/obj/screen/parallax_space_whitifier
|
||||
appearance_flags = PLANE_MASTER
|
||||
plane = PLANE_SPACE
|
||||
color = list(
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
1, 1, 1, 1,
|
||||
0, 0, 0, 0
|
||||
)
|
||||
screen_loc = "CENTER-7,CENTER-7"
|
||||
|
||||
|
||||
#undef LOOP_NONE
|
||||
#undef LOOP_NORMAL
|
||||
#undef LOOP_REVERSE
|
||||
#undef LOOP_TIME
|
||||
@@ -95,6 +95,9 @@
|
||||
icon = 'icons/mob/screen_robot.dmi'
|
||||
screen_loc = ui_borg_intents
|
||||
|
||||
/obj/screen/act_intent/robot/AI
|
||||
screen_loc = "EAST-1:32,SOUTH:70"
|
||||
|
||||
/obj/screen/mov_intent
|
||||
name = "run/walk toggle"
|
||||
icon_state = "running"
|
||||
@@ -453,6 +456,12 @@
|
||||
/obj/screen/healths/corgi
|
||||
icon = 'icons/mob/screen_corgi.dmi'
|
||||
|
||||
/obj/screen/healths/slime
|
||||
icon = 'icons/mob/screen_slime.dmi'
|
||||
icon_state = "slime_health0"
|
||||
screen_loc = ui_slime_health
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
|
||||
/obj/screen/healths/guardian
|
||||
name = "summoner health"
|
||||
icon = 'icons/mob/guardian.dmi'
|
||||
|
||||
18
code/_onclick/hud/slime.dm
Normal file
18
code/_onclick/hud/slime.dm
Normal file
@@ -0,0 +1,18 @@
|
||||
/mob/living/carbon/slime/create_mob_hud()
|
||||
if(client && !hud_used)
|
||||
hud_used = new /datum/hud/slime(src)
|
||||
|
||||
/mob/living/simple_animal/slime/create_mob_hud()
|
||||
if(client && !hud_used)
|
||||
hud_used = new /datum/hud/slime(src)
|
||||
|
||||
/datum/hud/slime/New(mob/owner)
|
||||
..()
|
||||
mymob.healths = new /obj/screen/healths/slime()
|
||||
infodisplay += mymob.healths
|
||||
|
||||
mymob.pullin = new /obj/screen/pull()
|
||||
mymob.pullin.icon = 'icons/mob/screen_slime.dmi'
|
||||
mymob.pullin.update_icon(mymob)
|
||||
mymob.pullin.screen_loc = ui_construct_pull
|
||||
hotkeybuttons += mymob.pullin
|
||||
@@ -17,6 +17,7 @@
|
||||
else
|
||||
following = null
|
||||
forceMove(get_turf(A))
|
||||
update_parallax_contents()
|
||||
|
||||
/mob/dead/observer/ClickOn(var/atom/A, var/params)
|
||||
if(client.click_intercept)
|
||||
@@ -58,6 +59,14 @@
|
||||
/atom/proc/attack_ghost(mob/user as mob)
|
||||
return
|
||||
|
||||
// health + cyborg analyzer for ghosts
|
||||
/mob/living/attack_ghost(mob/dead/observer/user)
|
||||
if(user.client && user.health_scan)
|
||||
if(issilicon(src) || ismachine(src))
|
||||
robot_healthscan(user, src)
|
||||
else if(ishuman(src))
|
||||
healthscan(user, src, 1, TRUE)
|
||||
|
||||
// ---------------------------------------
|
||||
// And here are some good things for free:
|
||||
// Now you can click through portals, wormholes, gateways, and teleporters while observing. -Sayu
|
||||
|
||||
65
code/controllers/subsystem/chat.dm
Normal file
65
code/controllers/subsystem/chat.dm
Normal file
@@ -0,0 +1,65 @@
|
||||
SUBSYSTEM_DEF(chat)
|
||||
name = "Chat"
|
||||
flags = SS_TICKER|SS_NO_INIT
|
||||
wait = 1
|
||||
priority = FIRE_PRIORITY_CHAT
|
||||
init_order = INIT_ORDER_CHAT
|
||||
|
||||
var/list/payload = list()
|
||||
|
||||
|
||||
/datum/controller/subsystem/chat/fire()
|
||||
for(var/i in payload)
|
||||
var/client/C = i
|
||||
C << output(payload[C], "browseroutput:output")
|
||||
payload -= C
|
||||
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
|
||||
/datum/controller/subsystem/chat/proc/queue(target, message, flag)
|
||||
if(!target || !message)
|
||||
return
|
||||
|
||||
if(!istext(message))
|
||||
stack_trace("to_chat called with invalid input type")
|
||||
return
|
||||
|
||||
if(target == world)
|
||||
target = GLOB.clients
|
||||
|
||||
//Some macros remain in the string even after parsing and fuck up the eventual output
|
||||
message = replacetext(message, "\improper", "")
|
||||
message = replacetext(message, "\proper", "")
|
||||
message += "<br>"
|
||||
|
||||
|
||||
//url_encode it TWICE, this way any UTF-8 characters are able to be decoded by the Javascript.
|
||||
//Do the double-encoding here to save nanoseconds
|
||||
var/twiceEncoded = url_encode(url_encode(message))
|
||||
|
||||
if(islist(target))
|
||||
for(var/I in target)
|
||||
var/client/C = CLIENT_FROM_VAR(I) //Grab us a client if possible
|
||||
|
||||
if(!C?.chatOutput || C.chatOutput.broken) //A player who hasn't updated his skin file.
|
||||
continue
|
||||
|
||||
if(!C.chatOutput.loaded) //Client still loading, put their messages in a queue
|
||||
C.chatOutput.messageQueue += message
|
||||
continue
|
||||
|
||||
payload[C] += twiceEncoded
|
||||
|
||||
else
|
||||
var/client/C = CLIENT_FROM_VAR(target) //Grab us a client if possible
|
||||
|
||||
if(!C?.chatOutput || C.chatOutput.broken) //A player who hasn't updated his skin file.
|
||||
return
|
||||
|
||||
if(!C.chatOutput.loaded) //Client still loading, put their messages in a queue
|
||||
C.chatOutput.messageQueue += message
|
||||
return
|
||||
|
||||
payload[C] += twiceEncoded
|
||||
44
code/controllers/subsystem/parallax.dm
Normal file
44
code/controllers/subsystem/parallax.dm
Normal file
@@ -0,0 +1,44 @@
|
||||
SUBSYSTEM_DEF(parallax)
|
||||
name = "Parallax"
|
||||
wait = 2
|
||||
flags = SS_POST_FIRE_TIMING | SS_BACKGROUND
|
||||
priority = FIRE_PRIORITY_PARALLAX
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
|
||||
var/list/currentrun
|
||||
var/planet_x_offset = 128
|
||||
var/planet_y_offset = 128
|
||||
|
||||
/datum/controller/subsystem/parallax/Initialize(timeofday)
|
||||
. = ..()
|
||||
planet_y_offset = rand(100, 160)
|
||||
planet_x_offset = rand(100, 160)
|
||||
|
||||
/datum/controller/subsystem/parallax/fire(resumed = 0)
|
||||
if(!resumed)
|
||||
src.currentrun = GLOB.clients.Copy()
|
||||
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
|
||||
while(length(currentrun))
|
||||
var/client/C = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
if(!C || !C.eye)
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
continue
|
||||
var/atom/movable/A = C.eye
|
||||
if(!istype(A))
|
||||
continue
|
||||
for (A; isloc(A.loc) && !isturf(A.loc); A = A.loc);
|
||||
|
||||
if(A != C.movingmob)
|
||||
if(C.movingmob != null)
|
||||
C.movingmob.client_mobs_in_contents -= C.mob
|
||||
UNSETEMPTY(C.movingmob.client_mobs_in_contents)
|
||||
LAZYINITLIST(A.client_mobs_in_contents)
|
||||
A.client_mobs_in_contents += C.mob
|
||||
C.movingmob = A
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
currentrun = null
|
||||
@@ -196,6 +196,14 @@
|
||||
/datum/action/item_action/toggle_helmet_light
|
||||
name = "Toggle Helmet Light"
|
||||
|
||||
/datum/action/item_action/toggle_welding_screen/plasmaman
|
||||
name = "Toggle Welding Screen"
|
||||
|
||||
/datum/action/item_action/toggle_welding_screen/plasmaman/Trigger()
|
||||
var/obj/item/clothing/head/helmet/space/plasmaman/H = target
|
||||
if(istype(H))
|
||||
H.toggle_welding_screen(owner)
|
||||
|
||||
/datum/action/item_action/toggle_helmet_mode
|
||||
name = "Toggle Helmet Mode"
|
||||
|
||||
|
||||
31
code/datums/components/paintable.dm
Normal file
31
code/datums/components/paintable.dm
Normal file
@@ -0,0 +1,31 @@
|
||||
/datum/component/spraycan_paintable
|
||||
var/current_paint
|
||||
|
||||
/datum/component/spraycan_paintable/Initialize()
|
||||
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/Repaint)
|
||||
|
||||
/datum/component/spraycan_paintable/Destroy()
|
||||
RemoveCurrentCoat()
|
||||
return ..()
|
||||
|
||||
/datum/component/spraycan_paintable/proc/RemoveCurrentCoat()
|
||||
var/atom/A = parent
|
||||
A.remove_atom_colour(FIXED_COLOUR_PRIORITY, current_paint)
|
||||
|
||||
/datum/component/spraycan_paintable/proc/Repaint(datum/source, obj/item/toy/crayon/spraycan/spraycan, mob/living/user)
|
||||
if(!istype(spraycan) || user.a_intent == INTENT_HARM)
|
||||
return
|
||||
. = COMPONENT_NO_AFTERATTACK
|
||||
if(spraycan.capped)
|
||||
to_chat(user, "<span class='warning'>Take the cap off first!</span>")
|
||||
return
|
||||
if(spraycan.uses < 2)
|
||||
to_chat(user, "<span class ='warning'>There is not enough paint in the can!")
|
||||
return
|
||||
RemoveCurrentCoat()
|
||||
var/colour = spraycan.colour
|
||||
current_paint = colour
|
||||
var/atom/A = parent
|
||||
A.add_atom_colour(colour, FIXED_COLOUR_PRIORITY)
|
||||
playsound(spraycan, 'sound/effects/spray.ogg', 5, 1, 5)
|
||||
to_chat(user, "<span class='notice'>You spray [spraycan] on [A], painting it.</span>")
|
||||
@@ -1269,7 +1269,12 @@
|
||||
return
|
||||
src.debug_variables(DAT)
|
||||
|
||||
return
|
||||
if(href_list["copyoutfit"])
|
||||
if(!check_rights(R_EVENT))
|
||||
return
|
||||
var/mob/living/carbon/human/H = locateUID(href_list["copyoutfit"])
|
||||
if(istype(H))
|
||||
H.copy_outfit()
|
||||
|
||||
/client/proc/view_var_Topic_list(href, href_list, hsrc)
|
||||
if(href_list["VarsList"])
|
||||
|
||||
@@ -30,11 +30,11 @@ Bonus
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB))
|
||||
var/mob/living/carbon/M = A.affected_mob
|
||||
to_chat(M, "<span class='warning'>[pick("You feel cold.", "You start shivering.")]</span>")
|
||||
if(M.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT)
|
||||
if(M.bodytemperature > BODYTEMP_COLD_DAMAGE_LIMIT)
|
||||
Chill(M, A)
|
||||
return
|
||||
|
||||
/datum/symptom/shivering/proc/Chill(mob/living/M, datum/disease/advance/A)
|
||||
var/get_cold = (sqrtor0(16+A.totalStealth()*2))+(sqrtor0(21+A.totalResistance()*2))
|
||||
M.bodytemperature = min(M.bodytemperature - (get_cold * A.stage), BODYTEMP_COLD_DAMAGE_LIMIT + 1)
|
||||
return 1
|
||||
M.bodytemperature = max(M.bodytemperature - (get_cold * A.stage), BODYTEMP_COLD_DAMAGE_LIMIT + 1)
|
||||
return 1
|
||||
|
||||
@@ -100,15 +100,20 @@
|
||||
height = 400
|
||||
immediate_submit = TRUE
|
||||
|
||||
/datum/async_input/ranked/New()
|
||||
..()
|
||||
popup.add_script("rankedInput.js", 'html/browser/rankedInput.js')
|
||||
popup.add_head_content("<title>Drag and drop or use the buttons to reorder</title>")
|
||||
|
||||
/datum/async_input/ranked/render_choices()
|
||||
var/dat = "<div>"
|
||||
dat += "<table style='margin: auto; text-align: left;'>"
|
||||
dat += "<table id='choices' uid=[UID()] style='margin: auto; text-align: left;'>"
|
||||
for(var/i = 1, i <= choices.len, i++)
|
||||
var/choice = choices[i]
|
||||
dat += "<tr>"
|
||||
dat += "<td>[button("+", i != 1 ? "upvote=[i]" : "", , i == 1)]</td>"
|
||||
dat += "<td>[button("-", i != choices.len ? "downvote=[i]" : "", , i == choices.len)]</td>"
|
||||
dat += "<td>[i]. [choice]</td>"
|
||||
dat += "<td style='cursor: move;' index='[i]' ondrop='drop(event)' ondragover='allowDrop(event)' draggable='true' ondragstart='drag(event)'>[i]. [choice]</td>"
|
||||
dat += "</tr>"
|
||||
dat += "</table>"
|
||||
dat += "</div>"
|
||||
@@ -131,6 +136,15 @@
|
||||
show()
|
||||
return
|
||||
|
||||
if(href_list["cut"] && href_list["insert"])
|
||||
var/cut = text2num(href_list["cut"])
|
||||
var/insert = text2num(href_list["insert"])
|
||||
var/choice = choices[cut]
|
||||
choices.Cut(cut, cut + 1)
|
||||
choices.Insert(insert, choice)
|
||||
show()
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
/datum/async_input/autocomplete
|
||||
|
||||
@@ -19,14 +19,20 @@
|
||||
var/suit_store = null
|
||||
var/l_hand = null
|
||||
var/r_hand = null
|
||||
/// Should the toggle helmet proc be called on the helmet during equip
|
||||
var/toggle_helmet = TRUE
|
||||
var/pda = null
|
||||
var/internals_slot = null //ID of slot containing a gas tank
|
||||
var/list/backpack_contents = list() // In the list(path=count,otherpath=count) format
|
||||
var/list/implants = null
|
||||
var/list/cybernetic_implants = null
|
||||
var/box // Internals box. Will be inserted at the start of backpack_contents
|
||||
var/list/implants = list()
|
||||
var/list/cybernetic_implants = list()
|
||||
var/list/accessories = list()
|
||||
|
||||
var/list/chameleon_extras //extra types for chameleon outfit changes, mostly guns
|
||||
|
||||
var/can_be_admin_equipped = TRUE // Set to FALSE if your outfit requires runtime parameters
|
||||
|
||||
/datum/outfit/proc/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
//to be overriden for customization depending on client prefs,species etc
|
||||
return
|
||||
@@ -82,12 +88,24 @@
|
||||
if(pda)
|
||||
equip_item(H, pda, slot_wear_pda)
|
||||
|
||||
if(uniform)
|
||||
for(var/path in accessories)
|
||||
var/obj/item/clothing/accessory/A = new path()
|
||||
var/obj/item/clothing/under/U = uniform
|
||||
U.attach_accessory(A, H)
|
||||
|
||||
if(!visualsOnly) // Items in pockets or backpack don't show up on mob's icon.
|
||||
if(l_pocket)
|
||||
equip_item(H, l_pocket, slot_l_store)
|
||||
if(r_pocket)
|
||||
equip_item(H, r_pocket, slot_r_store)
|
||||
|
||||
if(box)
|
||||
if(!backpack_contents)
|
||||
backpack_contents = list()
|
||||
backpack_contents.Insert(1, box)
|
||||
backpack_contents[box] = 1
|
||||
|
||||
for(var/path in backpack_contents)
|
||||
var/number = backpack_contents[path]
|
||||
for(var/i in 1 to number)
|
||||
@@ -97,6 +115,10 @@
|
||||
var/obj/item/organ/internal/O = new path(H)
|
||||
O.insert(H)
|
||||
|
||||
if(!H.head && toggle_helmet && istype(H.wear_suit, /obj/item/clothing/suit/space/hardsuit))
|
||||
var/obj/item/clothing/suit/space/hardsuit/HS = H.wear_suit
|
||||
HS.ToggleHelmet()
|
||||
|
||||
post_equip(H, visualsOnly)
|
||||
|
||||
if(!visualsOnly)
|
||||
@@ -159,3 +181,97 @@
|
||||
types += chameleon_extras
|
||||
listclearnulls(types)
|
||||
return types
|
||||
|
||||
/datum/outfit/proc/save_to_file(mob/admin)
|
||||
var/stored_data = get_json_data()
|
||||
var/json = json_encode(stored_data)
|
||||
// Kinda annoying but as far as I can tell you need to make actual file.
|
||||
var/f = file("data/TempOutfitUpload")
|
||||
fdel(f)
|
||||
WRITE_FILE(f, json)
|
||||
admin << ftp(f, "[name].json")
|
||||
|
||||
/datum/outfit/proc/load_from(list/outfit_data)
|
||||
// This could probably use more strict validation.
|
||||
name = outfit_data["name"]
|
||||
uniform = text2path(outfit_data["uniform"])
|
||||
suit = text2path(outfit_data["suit"])
|
||||
toggle_helmet = text2path(outfit_data["toggle_helmet"])
|
||||
back = text2path(outfit_data["back"])
|
||||
belt = text2path(outfit_data["belt"])
|
||||
gloves = text2path(outfit_data["gloves"])
|
||||
shoes = text2path(outfit_data["shoes"])
|
||||
head = text2path(outfit_data["head"])
|
||||
mask = text2path(outfit_data["mask"])
|
||||
l_ear = text2path(outfit_data["l_ear"])
|
||||
r_ear = text2path(outfit_data["r_ear"])
|
||||
glasses = text2path(outfit_data["glasses"])
|
||||
id = text2path(outfit_data["id"])
|
||||
pda = text2path(outfit_data["pda"])
|
||||
l_pocket = text2path(outfit_data["l_pocket"])
|
||||
r_pocket = text2path(outfit_data["r_pocket"])
|
||||
suit_store = text2path(outfit_data["suit_store"])
|
||||
r_hand = text2path(outfit_data["r_hand"])
|
||||
l_hand = text2path(outfit_data["l_hand"])
|
||||
internals_slot = text2path(outfit_data["internals_slot"])
|
||||
|
||||
var/list/backpack = outfit_data["backpack_contents"]
|
||||
backpack_contents = list()
|
||||
for(var/item in backpack)
|
||||
var/itype = text2path(item)
|
||||
if(itype)
|
||||
backpack_contents[itype] = backpack[item]
|
||||
box = text2path(outfit_data["box"])
|
||||
|
||||
var/list/impl = outfit_data["implants"]
|
||||
implants = list()
|
||||
for(var/I in impl)
|
||||
var/imptype = text2path(I)
|
||||
if(imptype)
|
||||
implants += imptype
|
||||
|
||||
var/list/cybernetic_impl = outfit_data["cybernetic_implants"]
|
||||
cybernetic_implants = list()
|
||||
for(var/I in cybernetic_impl)
|
||||
var/cybtype = text2path(I)
|
||||
if(cybtype)
|
||||
cybernetic_implants += cybtype
|
||||
|
||||
var/list/accessories = outfit_data["accessories"]
|
||||
accessories = list()
|
||||
for(var/A in accessories)
|
||||
var/accessorytype = text2path(A)
|
||||
if(accessorytype)
|
||||
accessories += accessorytype
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/outfit/proc/get_json_data()
|
||||
. = list()
|
||||
.["outfit_type"] = type
|
||||
.["name"] = name
|
||||
.["uniform"] = uniform
|
||||
.["suit"] = suit
|
||||
.["toggle_helmet"] = toggle_helmet
|
||||
.["back"] = back
|
||||
.["belt"] = belt
|
||||
.["gloves"] = gloves
|
||||
.["shoes"] = shoes
|
||||
.["head"] = head
|
||||
.["mask"] = mask
|
||||
.["l_ear"] = l_ear
|
||||
.["r_ear"] = r_ear
|
||||
.["glasses"] = glasses
|
||||
.["id"] = id
|
||||
.["pda"] = pda
|
||||
.["l_pocket"] = l_pocket
|
||||
.["r_pocket"] = r_pocket
|
||||
.["suit_store"] = suit_store
|
||||
.["r_hand"] = r_hand
|
||||
.["l_hand"] = l_hand
|
||||
.["internals_slot"] = internals_slot
|
||||
.["backpack_contents"] = backpack_contents
|
||||
.["box"] = box
|
||||
.["implants"] = implants
|
||||
.["cybernetic_implants"] = cybernetic_implants
|
||||
.["accessories"] = accessories
|
||||
|
||||
@@ -78,7 +78,6 @@
|
||||
|
||||
suit = /obj/item/clothing/suit/space/hardsuit/syndi
|
||||
belt = /obj/item/storage/belt/military
|
||||
head = /obj/item/clothing/head/helmet/space/hardsuit/syndi
|
||||
mask = /obj/item/clothing/mask/gas/syndicate
|
||||
l_ear = /obj/item/radio/headset/syndicate/alt
|
||||
glasses = /obj/item/clothing/glasses/night
|
||||
@@ -110,7 +109,6 @@
|
||||
/datum/outfit/admin/syndicate/operative/freedom
|
||||
name = "Syndicate Freedom Operative"
|
||||
suit = /obj/item/clothing/suit/space/hardsuit/syndi/freedom
|
||||
head = /obj/item/clothing/head/helmet/space/hardsuit/syndi/freedom
|
||||
|
||||
|
||||
/datum/outfit/admin/syndicate_strike_team
|
||||
@@ -794,41 +792,34 @@
|
||||
|
||||
/datum/outfit/admin/hardsuit/engineer
|
||||
name = "Engineer Hardsuit"
|
||||
suit = /obj/item/clothing/suit/space/hardsuit
|
||||
head = /obj/item/clothing/head/helmet/space/hardsuit
|
||||
suit = /obj/item/clothing/suit/space/hardsuit/engine
|
||||
|
||||
/datum/outfit/admin/hardsuit/ce
|
||||
name = "CE Hardsuit"
|
||||
suit = /obj/item/clothing/suit/space/hardsuit/elite
|
||||
head = /obj/item/clothing/head/helmet/space/hardsuit/elite
|
||||
suit = /obj/item/clothing/suit/space/hardsuit/engine/elite
|
||||
shoes = /obj/item/clothing/shoes/magboots/advance
|
||||
|
||||
/datum/outfit/admin/hardsuit/mining
|
||||
name = "Mining Hardsuit"
|
||||
suit = /obj/item/clothing/suit/space/hardsuit/mining
|
||||
head = /obj/item/clothing/head/helmet/space/hardsuit/mining
|
||||
|
||||
/datum/outfit/admin/hardsuit/syndi
|
||||
name = "Syndi Hardsuit"
|
||||
suit = /obj/item/clothing/suit/space/hardsuit/syndi
|
||||
head = /obj/item/clothing/head/helmet/space/hardsuit/syndi
|
||||
shoes = /obj/item/clothing/shoes/magboots/syndie
|
||||
|
||||
/datum/outfit/admin/hardsuit/wizard
|
||||
name = "Wizard Hardsuit"
|
||||
suit = /obj/item/clothing/suit/space/hardsuit/wizard
|
||||
head = /obj/item/clothing/head/helmet/space/hardsuit/wizard
|
||||
shoes = /obj/item/clothing/shoes/magboots
|
||||
|
||||
/datum/outfit/admin/hardsuit/medical
|
||||
name = "Medical Hardsuit"
|
||||
suit = /obj/item/clothing/suit/space/hardsuit/medical
|
||||
head = /obj/item/clothing/head/helmet/space/hardsuit/medical
|
||||
|
||||
/datum/outfit/admin/hardsuit/atmos
|
||||
name = "Atmos Hardsuit"
|
||||
suit = /obj/item/clothing/suit/space/hardsuit/atmos
|
||||
head = /obj/item/clothing/head/helmet/space/hardsuit/atmos
|
||||
suit = /obj/item/clothing/suit/space/hardsuit/engine/atmos
|
||||
|
||||
|
||||
/datum/outfit/admin/tournament
|
||||
@@ -963,7 +954,6 @@
|
||||
belt = /obj/item/claymore/ceremonial
|
||||
gloves = /obj/item/clothing/gloves/combat
|
||||
shoes = /obj/item/clothing/shoes/magboots
|
||||
head = /obj/item/clothing/head/helmet/space/hardsuit/singuloth
|
||||
mask = /obj/item/clothing/mask/breath
|
||||
l_ear = /obj/item/radio/headset/ert
|
||||
glasses = /obj/item/clothing/glasses/meson/cyber
|
||||
@@ -1111,7 +1101,6 @@
|
||||
backpack_contents = list(
|
||||
/obj/item/storage/box/engineer = 1,
|
||||
/obj/item/clothing/suit/space/hardsuit/wizard = 1,
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/wizard = 1,
|
||||
/obj/item/clothing/shoes/magboots = 1,
|
||||
/obj/item/kitchen/knife/ritual = 1,
|
||||
/obj/item/clothing/suit/wizrobe/red = 1,
|
||||
|
||||
178
code/datums/outfits/plasmamen.dm
Normal file
178
code/datums/outfits/plasmamen.dm
Normal file
@@ -0,0 +1,178 @@
|
||||
/datum/outfit/plasmaman
|
||||
name = "Plasmaman"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman
|
||||
uniform = /obj/item/clothing/under/plasmaman
|
||||
r_hand = /obj/item/tank/plasma/plasmaman/belt/full
|
||||
mask = /obj/item/clothing/mask/breath
|
||||
|
||||
/datum/outfit/plasmaman/bar
|
||||
name = "Bartender Plasmaman"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/white
|
||||
uniform = /obj/item/clothing/under/plasmaman/enviroslacks
|
||||
|
||||
/datum/outfit/plasmaman/chef
|
||||
name = "Chef Plasmaman"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/chef
|
||||
uniform = /obj/item/clothing/under/plasmaman/chef
|
||||
|
||||
/datum/outfit/plasmaman/botany
|
||||
name = "Botany Plasmaman"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/botany
|
||||
uniform = /obj/item/clothing/under/plasmaman/botany
|
||||
|
||||
/datum/outfit/plasmaman/librarian
|
||||
name = "Librarian Plasmaman"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/librarian
|
||||
uniform = /obj/item/clothing/under/plasmaman/librarian
|
||||
|
||||
/datum/outfit/plasmaman/chaplain
|
||||
name = "Chaplain Plasmaman"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/chaplain
|
||||
uniform = /obj/item/clothing/under/plasmaman/chaplain
|
||||
|
||||
/datum/outfit/plasmaman/janitor
|
||||
name = "Janitor Plasmaman"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/janitor
|
||||
uniform = /obj/item/clothing/under/plasmaman/janitor
|
||||
|
||||
/datum/outfit/plasmaman/security
|
||||
name = "Security Plasmaman"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/security
|
||||
uniform = /obj/item/clothing/under/plasmaman/security
|
||||
|
||||
/datum/outfit/plasmaman/detective
|
||||
name = "Detective Plasmaman"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/white
|
||||
uniform = /obj/item/clothing/under/plasmaman/enviroslacks
|
||||
l_ear = /obj/item/radio/headset/headset_sec
|
||||
|
||||
/datum/outfit/plasmaman/warden
|
||||
name = "Warden Plasmaman"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/security/warden
|
||||
uniform = /obj/item/clothing/under/plasmaman/security/warden
|
||||
|
||||
/datum/outfit/plasmaman/hos
|
||||
name = "Head of Security Plasmaman"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/security/hos
|
||||
uniform = /obj/item/clothing/under/plasmaman/security/hos
|
||||
|
||||
/datum/outfit/plasmaman/cargo
|
||||
name = "Cargo Plasmaman"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/cargo
|
||||
uniform = /obj/item/clothing/under/plasmaman/cargo
|
||||
|
||||
/datum/outfit/plasmaman/mining
|
||||
name = "Mining Plasmaman"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/mining
|
||||
uniform = /obj/item/clothing/under/plasmaman/mining
|
||||
|
||||
/datum/outfit/plasmaman/medical
|
||||
name = "Medical Plasmaman"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/medical
|
||||
uniform = /obj/item/clothing/under/plasmaman/medical
|
||||
|
||||
/datum/outfit/plasmaman/cmo
|
||||
name = "Chief Medical Officer Plasmaman"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/cmo
|
||||
uniform = /obj/item/clothing/under/plasmaman/cmo
|
||||
|
||||
/datum/outfit/plasmaman/viro
|
||||
name = "Virology Plasmaman"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/viro
|
||||
uniform = /obj/item/clothing/under/plasmaman/viro
|
||||
|
||||
/datum/outfit/plasmaman/chemist
|
||||
name = "Chemist Plasmaman"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/chemist
|
||||
uniform = /obj/item/clothing/under/plasmaman/chemist
|
||||
|
||||
/datum/outfit/plasmaman/genetics
|
||||
name = "Genetics Plasmaman"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/genetics
|
||||
uniform = /obj/item/clothing/under/plasmaman/genetics
|
||||
|
||||
/datum/outfit/plasmaman/science
|
||||
name = "Science Plasmaman"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/science
|
||||
uniform = /obj/item/clothing/under/plasmaman/science
|
||||
|
||||
/datum/outfit/plasmaman/rd
|
||||
name = "Research Director Plasmaman"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/rd
|
||||
uniform = /obj/item/clothing/under/plasmaman/rd
|
||||
|
||||
/datum/outfit/plasmaman/robotics
|
||||
name = "Robotics Plasmaman"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/robotics
|
||||
uniform = /obj/item/clothing/under/plasmaman/robotics
|
||||
|
||||
/datum/outfit/plasmaman/engineering
|
||||
name = "Engineering Plasmaman"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/engineering
|
||||
uniform = /obj/item/clothing/under/plasmaman/engineering
|
||||
|
||||
/datum/outfit/plasmaman/ce
|
||||
name = "Chief Engineer Plasmaman"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/engineering/ce
|
||||
uniform = /obj/item/clothing/under/plasmaman/engineering/ce
|
||||
|
||||
/datum/outfit/plasmaman/atmospherics
|
||||
name = "Atmospherics Plasmaman"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/atmospherics
|
||||
uniform = /obj/item/clothing/under/plasmaman/atmospherics
|
||||
|
||||
/datum/outfit/plasmaman/mime
|
||||
name = "Plasmamime"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/mime
|
||||
uniform = /obj/item/clothing/under/plasmaman/mime
|
||||
mask = /obj/item/clothing/mask/gas/mime
|
||||
|
||||
/datum/outfit/plasmaman/clown
|
||||
name = "Plasmaclown"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/clown
|
||||
uniform = /obj/item/clothing/under/plasmaman/clown
|
||||
mask = /obj/item/clothing/mask/gas/clown_hat
|
||||
|
||||
/datum/outfit/plasmaman/hop
|
||||
name = "Head of Personnel Plasmaman"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/hop
|
||||
uniform = /obj/item/clothing/under/plasmaman/hop
|
||||
|
||||
/datum/outfit/plasmaman/captain
|
||||
name = "Captain Plasmaman"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/captain
|
||||
uniform = /obj/item/clothing/under/plasmaman/captain
|
||||
|
||||
/datum/outfit/plasmaman/blueshield
|
||||
name = "Blueshield Plasmaman"
|
||||
|
||||
head = /obj/item/clothing/head/helmet/space/plasmaman/blueshield
|
||||
uniform = /obj/item/clothing/under/plasmaman/blueshield
|
||||
190
code/datums/outfits/vv_outfit.dm
Normal file
190
code/datums/outfits/vv_outfit.dm
Normal file
@@ -0,0 +1,190 @@
|
||||
// This outfit preserves varedits made on the items
|
||||
// Created from admin helpers.
|
||||
/datum/outfit/varedit
|
||||
var/list/vv_values
|
||||
var/list/stored_access
|
||||
var/update_id_name = FALSE //If the name of the human is same as the name on the id they're wearing we'll update provided id when equipping
|
||||
|
||||
/datum/outfit/varedit/pre_equip(mob/living/carbon/human/H, visualsOnly)
|
||||
H.delete_equipment() //Applying VV to wrong objects is not reccomended.
|
||||
. = ..()
|
||||
|
||||
/datum/outfit/varedit/proc/set_equipment_by_slot(slot, item_path)
|
||||
switch(slot)
|
||||
if(slot_w_uniform)
|
||||
uniform = item_path
|
||||
if(slot_back)
|
||||
back = item_path
|
||||
if(slot_wear_suit)
|
||||
suit = item_path
|
||||
if(slot_belt)
|
||||
belt = item_path
|
||||
if(slot_gloves)
|
||||
gloves = item_path
|
||||
if(slot_shoes)
|
||||
shoes = item_path
|
||||
if(slot_head)
|
||||
head = item_path
|
||||
if(slot_wear_mask)
|
||||
mask = item_path
|
||||
if(slot_l_ear)
|
||||
l_ear = item_path
|
||||
if(slot_r_ear)
|
||||
r_ear = item_path
|
||||
if(slot_glasses)
|
||||
glasses = item_path
|
||||
if(slot_wear_id)
|
||||
id = item_path
|
||||
if(slot_wear_pda)
|
||||
pda = item_path
|
||||
if(slot_s_store)
|
||||
suit_store = item_path
|
||||
if(slot_l_store)
|
||||
l_pocket = item_path
|
||||
if(slot_r_store)
|
||||
r_pocket = item_path
|
||||
|
||||
|
||||
/proc/collect_vv(obj/item/I)
|
||||
//Temporary/Internal stuff, do not copy these.
|
||||
var/static/list/ignored_vars = list("vars","x","y","z","plane","layer","override","animate_movement","pixel_step_size","screen_loc","fingerprintslast","tip_timer")
|
||||
|
||||
if(istype(I))
|
||||
var/list/vedits = list()
|
||||
for(var/varname in I.vars)
|
||||
if(!I.can_vv_get(varname))
|
||||
continue
|
||||
if(varname in ignored_vars)
|
||||
continue
|
||||
var/vval = I.vars[varname]
|
||||
//Does it even work ?
|
||||
if(vval == initial(I.vars[varname]))
|
||||
continue
|
||||
//Only text/numbers and icons variables to make it less weirdness prone.
|
||||
if(!istext(vval) && !isnum(vval) && !isicon(vval))
|
||||
continue
|
||||
vedits[varname] = I.vars[varname]
|
||||
return vedits
|
||||
|
||||
/mob/living/carbon/human/proc/copy_outfit()
|
||||
var/datum/outfit/varedit/O = new
|
||||
|
||||
//Copy equipment
|
||||
var/list/result = list()
|
||||
var/list/slots_to_check = list(slot_w_uniform, slot_back, slot_wear_suit, slot_belt, slot_gloves, slot_shoes, slot_head, slot_wear_mask, slot_l_ear, slot_r_ear, slot_glasses, slot_wear_id, slot_wear_pda, slot_s_store, slot_l_store, slot_r_store)
|
||||
for(var/s in slots_to_check)
|
||||
var/obj/item/I = get_item_by_slot(s)
|
||||
var/vedits = collect_vv(I)
|
||||
if(vedits)
|
||||
result["[s]"] = vedits
|
||||
if(istype(I))
|
||||
O.set_equipment_by_slot(s, I.type)
|
||||
|
||||
//Copy access
|
||||
O.stored_access = list()
|
||||
var/obj/item/id_slot = get_item_by_slot(slot_wear_id)
|
||||
if(id_slot)
|
||||
O.stored_access |= id_slot.GetAccess()
|
||||
var/obj/item/card/id/ID = id_slot.GetID()
|
||||
if(ID && ID.registered_name == real_name)
|
||||
O.update_id_name = TRUE
|
||||
|
||||
//Copy hands
|
||||
if(l_hand || r_hand) //Not in the mood to let outfits transfer amputees
|
||||
var/obj/item/left_hand = l_hand
|
||||
var/obj/item/right_hand = r_hand
|
||||
if(istype(left_hand))
|
||||
O.l_hand = left_hand.type
|
||||
var/vedits = collect_vv(left_hand)
|
||||
if(vedits)
|
||||
result["LHAND"] = vedits
|
||||
if(istype(right_hand))
|
||||
O.r_hand = right_hand.type
|
||||
var/vedits = collect_vv(left_hand)
|
||||
if(vedits)
|
||||
result["RHAND"] = vedits
|
||||
O.vv_values = result
|
||||
|
||||
//Copy backpack contents if exist.
|
||||
var/obj/item/backpack = get_item_by_slot(slot_back)
|
||||
if(istype(backpack) && LAZYLEN(backpack.contents) > 0)
|
||||
var/list/typecounts = list()
|
||||
for(var/obj/item/I in backpack)
|
||||
if(typecounts[I.type])
|
||||
typecounts[I.type] += 1
|
||||
else
|
||||
typecounts[I.type] = 1
|
||||
O.backpack_contents = typecounts
|
||||
//TODO : Copy varedits from backpack stuff too.
|
||||
|
||||
//Copy implants
|
||||
O.implants = list()
|
||||
for(var/obj/item/implant/I in contents)
|
||||
if(istype(I))
|
||||
O.implants |= I.type
|
||||
|
||||
// Copy cybernetic implants
|
||||
O.cybernetic_implants = list()
|
||||
for(var/obj/item/organ/internal/CI in contents)
|
||||
if(istype(CI))
|
||||
O.cybernetic_implants |= CI.type
|
||||
|
||||
// Copy accessories
|
||||
var/obj/item/clothing/under/uniform_slot = get_item_by_slot(slot_w_uniform)
|
||||
if(uniform_slot)
|
||||
O.accessories = list()
|
||||
for(var/obj/item/clothing/accessory/A in uniform_slot.accessories)
|
||||
if(istype(A))
|
||||
O.accessories |= A
|
||||
|
||||
//Copy to outfit cache
|
||||
var/outfit_name = stripped_input(usr, "Enter the outfit name")
|
||||
O.name = outfit_name
|
||||
GLOB.custom_outfits += O
|
||||
to_chat(usr, "Outfit registered, use select equipment to equip it.")
|
||||
|
||||
/datum/outfit/varedit/post_equip(mob/living/carbon/human/H, visualsOnly)
|
||||
. = ..()
|
||||
//Apply VV
|
||||
for(var/slot in vv_values)
|
||||
var/list/edits = vv_values[slot]
|
||||
var/obj/item/I
|
||||
switch(slot)
|
||||
if("LHAND")
|
||||
I = H.l_hand
|
||||
if("RHAND")
|
||||
I = H.r_hand
|
||||
else
|
||||
I = H.get_item_by_slot(text2num(slot))
|
||||
for(var/vname in edits)
|
||||
I.vv_edit_var(vname,edits[vname])
|
||||
//Apply access
|
||||
var/obj/item/id_slot = H.get_item_by_slot(slot_wear_id)
|
||||
if(id_slot)
|
||||
var/obj/item/card/id/card = id_slot.GetID()
|
||||
if(istype(card))
|
||||
card.access |= stored_access
|
||||
if(update_id_name)
|
||||
card.registered_name = H.real_name
|
||||
card.update_label()
|
||||
|
||||
/datum/outfit/varedit/get_json_data()
|
||||
. = .. ()
|
||||
.["stored_access"] = stored_access
|
||||
.["update_id_name"] = update_id_name
|
||||
var/list/stripped_vv = list()
|
||||
for(var/slot in vv_values)
|
||||
var/list/vedits = vv_values[slot]
|
||||
var/list/stripped_edits = list()
|
||||
for(var/edit in vedits)
|
||||
if(istext(vedits[edit]) || isnum(vedits[edit]) || isnull(vedits[edit]))
|
||||
stripped_edits[edit] = vedits[edit]
|
||||
if(stripped_edits.len)
|
||||
stripped_vv[slot] = stripped_edits
|
||||
.["vv_values"] = stripped_vv
|
||||
|
||||
/datum/outfit/varedit/load_from(list/outfit_data)
|
||||
. = ..()
|
||||
stored_access = outfit_data["stored_access"]
|
||||
vv_values = outfit_data["vv_values"]
|
||||
update_id_name = outfit_data["update_id_name"]
|
||||
@@ -36,7 +36,7 @@
|
||||
return
|
||||
|
||||
var/obj/item/clothing/mask/horsehead/magichead = new /obj/item/clothing/mask/horsehead
|
||||
magichead.flags |= NODROP //curses!
|
||||
magichead.flags |= NODROP | DROPDEL //curses!
|
||||
magichead.flags_inv = null //so you can still see their face
|
||||
magichead.voicechange = 1 //NEEEEIIGHH
|
||||
target.visible_message( "<span class='danger'>[target]'s face lights up in fire, and after the event a horse's head takes its place!</span>", \
|
||||
|
||||
@@ -40,6 +40,132 @@
|
||||
playsound(owner, 'sound/weapons/bite.ogg', 50, 1)
|
||||
owner.adjustBruteLoss(3)
|
||||
|
||||
/datum/status_effect/blooddrunk
|
||||
id = "blooddrunk"
|
||||
duration = 10
|
||||
tick_interval = 0
|
||||
alert_type = /obj/screen/alert/status_effect/blooddrunk
|
||||
var/last_health = 0
|
||||
var/last_bruteloss = 0
|
||||
var/last_fireloss = 0
|
||||
var/last_toxloss = 0
|
||||
var/last_oxyloss = 0
|
||||
var/last_cloneloss = 0
|
||||
var/last_staminaloss = 0
|
||||
|
||||
/obj/screen/alert/status_effect/blooddrunk
|
||||
name = "Blood-Drunk"
|
||||
desc = "You are drunk on blood! Your pulse thunders in your ears! Nothing can harm you!" //not true, and the item description mentions its actual effect
|
||||
icon_state = "blooddrunk"
|
||||
|
||||
/datum/status_effect/blooddrunk/on_apply()
|
||||
. = ..()
|
||||
if(.)
|
||||
owner.maxHealth *= 10
|
||||
owner.bruteloss *= 10
|
||||
owner.fireloss *= 10
|
||||
if(ishuman(owner))
|
||||
var/mob/living/carbon/human/H = owner
|
||||
for(var/X in H.bodyparts)
|
||||
var/obj/item/organ/external/BP = X
|
||||
BP.max_damage *= 10
|
||||
BP.min_broken_damage *= 10
|
||||
BP.brute_dam *= 10
|
||||
BP.burn_dam *= 10
|
||||
owner.toxloss *= 10
|
||||
owner.oxyloss *= 10
|
||||
owner.cloneloss *= 10
|
||||
owner.staminaloss *= 10
|
||||
owner.updatehealth()
|
||||
last_health = owner.health
|
||||
last_bruteloss = owner.getBruteLoss()
|
||||
last_fireloss = owner.getFireLoss()
|
||||
last_toxloss = owner.getToxLoss()
|
||||
last_oxyloss = owner.getOxyLoss()
|
||||
last_cloneloss = owner.getCloneLoss()
|
||||
last_staminaloss = owner.getStaminaLoss()
|
||||
add_attack_logs(owner, owner, "gained blood-drunk stun immunity")
|
||||
var/status = CANSTUN | CANWEAKEN | CANPARALYSE | IGNORESLOWDOWN
|
||||
owner.status_flags &= ~status
|
||||
owner.playsound_local(get_turf(owner), 'sound/effects/singlebeat.ogg', 40, 1)
|
||||
|
||||
/datum/status_effect/blooddrunk/tick() //multiply the effect of healing by 10
|
||||
if(owner.health > last_health)
|
||||
var/needs_health_update = FALSE
|
||||
var/new_bruteloss = owner.getBruteLoss()
|
||||
if(new_bruteloss < last_bruteloss)
|
||||
var/heal_amount = (new_bruteloss - last_bruteloss) * 10
|
||||
owner.adjustBruteLoss(heal_amount, updating_health = FALSE)
|
||||
new_bruteloss = owner.getBruteLoss()
|
||||
needs_health_update = TRUE
|
||||
last_bruteloss = new_bruteloss
|
||||
|
||||
var/new_fireloss = owner.getFireLoss()
|
||||
if(new_fireloss < last_fireloss)
|
||||
var/heal_amount = (new_fireloss - last_fireloss) * 10
|
||||
owner.adjustFireLoss(heal_amount, updating_health = FALSE)
|
||||
new_fireloss = owner.getFireLoss()
|
||||
needs_health_update = TRUE
|
||||
last_fireloss = new_fireloss
|
||||
|
||||
var/new_toxloss = owner.getToxLoss()
|
||||
if(new_toxloss < last_toxloss)
|
||||
var/heal_amount = (new_toxloss - last_toxloss) * 10
|
||||
owner.adjustToxLoss(heal_amount, updating_health = FALSE)
|
||||
new_toxloss = owner.getToxLoss()
|
||||
needs_health_update = TRUE
|
||||
last_toxloss = new_toxloss
|
||||
|
||||
var/new_oxyloss = owner.getOxyLoss()
|
||||
if(new_oxyloss < last_oxyloss)
|
||||
var/heal_amount = (new_oxyloss - last_oxyloss) * 10
|
||||
owner.adjustOxyLoss(heal_amount, updating_health = FALSE)
|
||||
new_oxyloss = owner.getOxyLoss()
|
||||
needs_health_update = TRUE
|
||||
last_oxyloss = new_oxyloss
|
||||
|
||||
var/new_cloneloss = owner.getCloneLoss()
|
||||
if(new_cloneloss < last_cloneloss)
|
||||
var/heal_amount = (new_cloneloss - last_cloneloss) * 10
|
||||
owner.adjustCloneLoss(heal_amount, updating_health = FALSE)
|
||||
new_cloneloss = owner.getCloneLoss()
|
||||
needs_health_update = TRUE
|
||||
last_cloneloss = new_cloneloss
|
||||
|
||||
var/new_staminaloss = owner.getStaminaLoss()
|
||||
if(new_staminaloss < last_staminaloss)
|
||||
var/heal_amount = (new_staminaloss - last_staminaloss) * 10
|
||||
owner.adjustStaminaLoss(heal_amount, updating_health = FALSE)
|
||||
new_staminaloss = owner.getStaminaLoss()
|
||||
needs_health_update = TRUE
|
||||
last_staminaloss = new_staminaloss
|
||||
|
||||
if(needs_health_update)
|
||||
owner.updatehealth()
|
||||
owner.playsound_local(get_turf(owner), 'sound/effects/singlebeat.ogg', 40, 1)
|
||||
last_health = owner.health
|
||||
|
||||
/datum/status_effect/blooddrunk/on_remove()
|
||||
tick()
|
||||
owner.maxHealth *= 0.1
|
||||
owner.bruteloss *= 0.1
|
||||
owner.fireloss *= 0.1
|
||||
if(ishuman(owner))
|
||||
var/mob/living/carbon/human/H = owner
|
||||
for(var/X in H.bodyparts)
|
||||
var/obj/item/organ/external/BP = X
|
||||
BP.brute_dam *= 0.1
|
||||
BP.burn_dam *= 0.1
|
||||
BP.max_damage /= 10
|
||||
BP.min_broken_damage /= 10
|
||||
owner.toxloss *= 0.1
|
||||
owner.oxyloss *= 0.1
|
||||
owner.cloneloss *= 0.1
|
||||
owner.staminaloss *= 0.1
|
||||
owner.updatehealth()
|
||||
add_attack_logs(owner, owner, "lost blood-drunk stun immunity")
|
||||
owner.status_flags |= CANSTUN | CANWEAKEN | CANPARALYSE | IGNORESLOWDOWN
|
||||
|
||||
/datum/status_effect/exercised
|
||||
id = "Exercised"
|
||||
duration = 1200
|
||||
|
||||
@@ -9,6 +9,39 @@
|
||||
if(owner.reagents)
|
||||
owner.reagents.del_reagent("holywater") //can't be deconverted
|
||||
|
||||
/datum/status_effect/crusher_mark
|
||||
id = "crusher_mark"
|
||||
duration = 300 //if you leave for 30 seconds you lose the mark, deal with it
|
||||
status_type = STATUS_EFFECT_REPLACE
|
||||
alert_type = null
|
||||
var/mutable_appearance/marked_underlay
|
||||
var/obj/item/twohanded/kinetic_crusher/hammer_synced
|
||||
|
||||
/datum/status_effect/crusher_mark/on_creation(mob/living/new_owner, obj/item/twohanded/kinetic_crusher/new_hammer_synced)
|
||||
. = ..()
|
||||
if(.)
|
||||
hammer_synced = new_hammer_synced
|
||||
|
||||
/datum/status_effect/crusher_mark/on_apply()
|
||||
if(owner.mob_size >= MOB_SIZE_LARGE)
|
||||
marked_underlay = mutable_appearance('icons/effects/effects.dmi', "shield2")
|
||||
marked_underlay.pixel_x = -owner.pixel_x
|
||||
marked_underlay.pixel_y = -owner.pixel_y
|
||||
owner.underlays += marked_underlay
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/status_effect/crusher_mark/Destroy()
|
||||
hammer_synced = null
|
||||
if(owner)
|
||||
owner.underlays -= marked_underlay
|
||||
QDEL_NULL(marked_underlay)
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/crusher_mark/be_replaced()
|
||||
owner.underlays -= marked_underlay //if this is being called, we should have an owner at this point.
|
||||
..()
|
||||
|
||||
/datum/status_effect/saw_bleed
|
||||
id = "saw_bleed"
|
||||
duration = -1 //removed under specific conditions
|
||||
|
||||
@@ -1,5 +1,43 @@
|
||||
//entirely neutral or internal status effects go here
|
||||
|
||||
/datum/status_effect/crusher_damage //tracks the damage dealt to this mob by kinetic crushers
|
||||
id = "crusher_damage"
|
||||
duration = -1
|
||||
status_type = STATUS_EFFECT_UNIQUE
|
||||
alert_type = null
|
||||
var/total_damage = 0
|
||||
|
||||
/datum/status_effect/syphon_mark
|
||||
id = "syphon_mark"
|
||||
duration = 50
|
||||
status_type = STATUS_EFFECT_MULTIPLE
|
||||
alert_type = null
|
||||
on_remove_on_mob_delete = TRUE
|
||||
var/obj/item/borg/upgrade/modkit/bounty/reward_target
|
||||
|
||||
/datum/status_effect/syphon_mark/on_creation(mob/living/new_owner, obj/item/borg/upgrade/modkit/bounty/new_reward_target)
|
||||
. = ..()
|
||||
if(.)
|
||||
reward_target = new_reward_target
|
||||
|
||||
/datum/status_effect/syphon_mark/on_apply()
|
||||
if(owner.stat == DEAD)
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/syphon_mark/proc/get_kill()
|
||||
if(!QDELETED(reward_target))
|
||||
reward_target.get_kill(owner)
|
||||
|
||||
/datum/status_effect/syphon_mark/tick()
|
||||
if(owner.stat == DEAD)
|
||||
get_kill()
|
||||
qdel(src)
|
||||
|
||||
/datum/status_effect/syphon_mark/on_remove()
|
||||
get_kill()
|
||||
. = ..()
|
||||
|
||||
/datum/status_effect/high_five
|
||||
id = "high_five"
|
||||
duration = 40
|
||||
|
||||
@@ -160,12 +160,16 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
|
||||
containername = "vox life support supplies crate"
|
||||
|
||||
/datum/supply_packs/emergency/plasmamansupport
|
||||
name = "Plasmaman Life Support Supplies"
|
||||
contains = list(/obj/item/clothing/mask/breath,
|
||||
/obj/item/tank/emergency_oxygen/plasma,
|
||||
/obj/item/clothing/suit/space/eva/plasmaman,
|
||||
/obj/item/clothing/head/helmet/space/eva/plasmaman)
|
||||
cost = 75
|
||||
name = "Plasmaman Supply Kit"
|
||||
contains = list(/obj/item/clothing/under/plasmaman,
|
||||
/obj/item/clothing/under/plasmaman,
|
||||
/obj/item/tank/plasma/plasmaman/belt/full,
|
||||
/obj/item/tank/plasma/plasmaman/belt/full,
|
||||
/obj/item/clothing/mask/breath,
|
||||
/obj/item/clothing/mask/breath,
|
||||
/obj/item/clothing/head/helmet/space/plasmaman,
|
||||
/obj/item/clothing/head/helmet/space/plasmaman)
|
||||
cost = 20
|
||||
containertype = /obj/structure/closet/crate/secure/plasma
|
||||
containername = "plasmaman life support supplies crate"
|
||||
access = access_eva
|
||||
|
||||
@@ -207,6 +207,14 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
cost = 10
|
||||
job = list("Mime")
|
||||
|
||||
/datum/uplink_item/jobspecific/pressure_mod
|
||||
name = "Kinetic Accelerator Pressure Mod"
|
||||
desc = "A modification kit which allows Kinetic Accelerators to do greatly increased damage while indoors. Occupies 35% mod capacity."
|
||||
reference = "KPM"
|
||||
item = /obj/item/borg/upgrade/modkit/indoors
|
||||
cost = 5 //you need two for full damage, so total of 10 for maximum damage
|
||||
job = list("Shaft Miner")
|
||||
|
||||
//Chef
|
||||
/datum/uplink_item/jobspecific/specialsauce
|
||||
name = "Chef Excellence's Special Sauce"
|
||||
@@ -892,6 +900,13 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
cost = 3
|
||||
surplus = 10
|
||||
|
||||
/datum/uplink_item/stealthy_weapons/false_briefcase
|
||||
name = "False Bottomed Briefcase"
|
||||
desc = "A modified briefcase capable of storing and firing a gun under a false bottom. Use a screwdriver to pry away the false bottom and make modifications. Distinguishable upon close examination due to the added weight."
|
||||
reference = "FBBC"
|
||||
item = /obj/item/storage/briefcase/false_bottomed
|
||||
cost = 3
|
||||
|
||||
/datum/uplink_item/stealthy_weapons/soap
|
||||
name = "Syndicate Soap"
|
||||
desc = "A sinister-looking surfactant used to clean blood stains to hide murders and prevent DNA analysis. You can also drop it underfoot to slip people."
|
||||
@@ -1107,10 +1122,10 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
cost = 2
|
||||
|
||||
/datum/uplink_item/stealthy_tools/thermal
|
||||
name = "Thermal Imaging Glasses"
|
||||
desc = "These glasses are thermals disguised as engineers' optical meson scanners. They allow you to see organisms through walls by capturing the upper portion of the infra-red light spectrum, emitted as heat and light by objects. Hotter objects, such as warm bodies, cybernetic organisms and artificial intelligence cores emit more of this light than cooler objects like walls and airlocks."
|
||||
name = "Thermal Chameleon Glasses"
|
||||
desc = "These glasses are thermals with Syndicate chameleon technology built into them. They allow you to see organisms through walls by capturing the upper portion of the infra-red light spectrum, emitted as heat and light by objects. Hotter objects, such as warm bodies, cybernetic organisms and artificial intelligence cores emit more of this light than cooler objects like walls and airlocks."
|
||||
reference = "THIG"
|
||||
item = /obj/item/clothing/glasses/thermal/syndi
|
||||
item = /obj/item/clothing/glasses/chameleon/thermal
|
||||
cost = 6
|
||||
|
||||
/datum/uplink_item/stealthy_tools/traitor_belt
|
||||
@@ -1305,7 +1320,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
/datum/uplink_item/suits/hardsuit/elite
|
||||
name = "Elite Syndicate Hardsuit"
|
||||
desc = "An advanced hardsuit with superior armor and mobility to the standard Syndicate Hardsuit."
|
||||
item = /obj/item/storage/box/syndie_kit/elite_hardsuit
|
||||
item = /obj/item/clothing/suit/space/hardsuit/syndi/elite
|
||||
cost = 8
|
||||
reference = "ESHS"
|
||||
excludefrom = list()
|
||||
@@ -1314,7 +1329,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
/datum/uplink_item/suits/hardsuit/shielded
|
||||
name = "Shielded Hardsuit"
|
||||
desc = "An advanced hardsuit with built in energy shielding. The shields will rapidly recharge when not under fire."
|
||||
item = /obj/item/storage/box/syndie_kit/shielded_hardsuit
|
||||
item = /obj/item/clothing/suit/space/hardsuit/shielded/syndi
|
||||
cost = 30
|
||||
reference = "SHS"
|
||||
excludefrom = list()
|
||||
|
||||
@@ -100,9 +100,11 @@ var/list/ghostteleportlocs = list()
|
||||
requires_power = FALSE
|
||||
valid_territory = FALSE
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
|
||||
parallax_movedir = NORTH
|
||||
|
||||
/area/shuttle/arrival
|
||||
name = "\improper Arrival Shuttle"
|
||||
parallax_movedir = EAST
|
||||
|
||||
/area/shuttle/arrival/pre_game
|
||||
icon_state = "shuttle2"
|
||||
@@ -136,12 +138,14 @@ var/list/ghostteleportlocs = list()
|
||||
music = "music/escape.ogg"
|
||||
icon_state = "shuttle"
|
||||
nad_allowed = TRUE
|
||||
parallax_movedir = EAST
|
||||
|
||||
/area/shuttle/pod_4
|
||||
name = "\improper Escape Pod Four"
|
||||
music = "music/escape.ogg"
|
||||
icon_state = "shuttle"
|
||||
nad_allowed = TRUE
|
||||
parallax_movedir = EAST
|
||||
|
||||
/area/shuttle/escape_pod1
|
||||
name = "\improper Escape Pod One"
|
||||
@@ -207,6 +211,7 @@ var/list/ghostteleportlocs = list()
|
||||
/area/shuttle/transport
|
||||
icon_state = "shuttle"
|
||||
name = "\improper Transport Shuttle"
|
||||
parallax_movedir = EAST
|
||||
|
||||
/area/shuttle/transport1
|
||||
icon_state = "shuttle"
|
||||
@@ -247,6 +252,7 @@ var/list/ghostteleportlocs = list()
|
||||
/area/shuttle/specops
|
||||
name = "\improper Special Ops Shuttle"
|
||||
icon_state = "shuttlered"
|
||||
parallax_movedir = EAST
|
||||
|
||||
/area/shuttle/specops/centcom
|
||||
name = "\improper Special Ops Shuttle"
|
||||
@@ -260,6 +266,7 @@ var/list/ghostteleportlocs = list()
|
||||
name = "\improper Syndicate Elite Shuttle"
|
||||
icon_state = "shuttlered"
|
||||
nad_allowed = TRUE
|
||||
parallax_movedir = SOUTH
|
||||
|
||||
/area/shuttle/syndicate_elite/mothership
|
||||
name = "\improper Syndicate Elite Shuttle"
|
||||
@@ -273,6 +280,7 @@ var/list/ghostteleportlocs = list()
|
||||
name = "\improper Syndicate SIT Shuttle"
|
||||
icon_state = "shuttlered"
|
||||
nad_allowed = TRUE
|
||||
parallax_movedir = SOUTH
|
||||
|
||||
/area/shuttle/assault_pod
|
||||
name = "Steel Rain"
|
||||
@@ -281,6 +289,7 @@ var/list/ghostteleportlocs = list()
|
||||
/area/shuttle/administration
|
||||
name = "\improper Nanotrasen Vessel"
|
||||
icon_state = "shuttlered"
|
||||
parallax_movedir = EAST
|
||||
|
||||
/area/shuttle/administration/centcom
|
||||
name = "\improper Nanotrasen Vessel Centcom"
|
||||
@@ -380,6 +389,7 @@ var/list/ghostteleportlocs = list()
|
||||
/area/shuttle/salvage/abandoned_ship
|
||||
name = "\improper Abandoned Ship"
|
||||
icon_state = "yellow"
|
||||
parallax_movedir = WEST
|
||||
|
||||
/area/shuttle/salvage/clown_asteroid
|
||||
name = "\improper Clown Asteroid"
|
||||
@@ -412,6 +422,7 @@ var/list/ghostteleportlocs = list()
|
||||
|
||||
/area/shuttle/trade/sol
|
||||
name = "Sol Freighter"
|
||||
parallax_movedir = EAST
|
||||
|
||||
/area/shuttle/freegolem
|
||||
name = "Free Golem Ship"
|
||||
@@ -1859,6 +1870,7 @@ var/list/ghostteleportlocs = list()
|
||||
/area/shuttle/constructionsite
|
||||
name = "\improper Construction Site Shuttle"
|
||||
icon_state = "yellow"
|
||||
parallax_movedir = EAST
|
||||
|
||||
/area/shuttle/constructionsite/station
|
||||
name = "\improper Construction Site Shuttle"
|
||||
|
||||
@@ -67,6 +67,9 @@
|
||||
var/can_get_auto_cryod = TRUE
|
||||
var/hide_attacklogs = FALSE // For areas such as thunderdome, lavaland syndiebase, etc which generate a lot of spammy attacklogs. Reduces log priority.
|
||||
|
||||
var/parallax_movedir = 0
|
||||
var/moving = FALSE
|
||||
|
||||
/area/Initialize(mapload)
|
||||
GLOB.all_areas += src
|
||||
icon_state = ""
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
var/inertia_move_delay = 5
|
||||
|
||||
var/moving_diagonally = 0 //0: not doing a diagonal move. 1 and 2: doing the first/second step of the diagonal move
|
||||
|
||||
var/list/client_mobs_in_contents
|
||||
var/area/areaMaster
|
||||
|
||||
/atom/movable/New()
|
||||
@@ -215,6 +215,8 @@
|
||||
if(!inertia_moving)
|
||||
inertia_next_move = world.time + inertia_move_delay
|
||||
newtonian_move(Dir)
|
||||
if(length(client_mobs_in_contents))
|
||||
update_parallax_contents()
|
||||
return TRUE
|
||||
|
||||
// Previously known as HasEntered()
|
||||
|
||||
@@ -163,10 +163,10 @@
|
||||
icon_state = "blobbernaut"
|
||||
icon_living = "blobbernaut"
|
||||
icon_dead = "blobbernaut_dead"
|
||||
health = 240
|
||||
maxHealth = 240
|
||||
melee_damage_lower = 20
|
||||
melee_damage_upper = 20
|
||||
health = 200
|
||||
maxHealth = 200
|
||||
melee_damage_lower = 10
|
||||
melee_damage_upper = 15
|
||||
obj_damage = 60
|
||||
attacktext = "hits"
|
||||
attack_sound = 'sound/effects/blobattack.ogg'
|
||||
@@ -175,18 +175,48 @@
|
||||
maxbodytemp = 360
|
||||
force_threshold = 10
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
environment_smash = ENVIRONMENT_SMASH_RWALLS
|
||||
environment_smash = ENVIRONMENT_SMASH_STRUCTURES
|
||||
pressure_resistance = 100 //100 kPa difference required to push
|
||||
throw_pressure_limit = 120 //120 kPa difference required to throw
|
||||
see_in_dark = 8
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
|
||||
|
||||
/mob/living/simple_animal/hostile/blob/blobbernaut/Life(seconds, times_fired)
|
||||
if(stat != DEAD && (getBruteLoss() || getFireLoss())) // Heal on blob structures
|
||||
if(locate(/obj/structure/blob) in get_turf(src))
|
||||
adjustBruteLoss(-0.25)
|
||||
adjustFireLoss(-0.25)
|
||||
else
|
||||
adjustBruteLoss(0.2) // If you are at full health, you won't lose health. You'll need it. However the moment anybody sneezes on you, the decaying will begin.
|
||||
adjustFireLoss(0.2)
|
||||
|
||||
/mob/living/simple_animal/hostile/blob/blobbernaut/blob_act()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/blob/blobbernaut/New()
|
||||
..()
|
||||
if(name == "blobbernaut")
|
||||
name = text("blobbernaut ([rand(1, 1000)])")
|
||||
|
||||
/mob/living/simple_animal/hostile/blob/blobbernaut/death(gibbed)
|
||||
// Only execute the below if we successfully died
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
flick("blobbernaut_death", src)
|
||||
|
||||
/mob/living/simple_animal/hostile/blob/blobbernaut/verb/communicate_overmind()
|
||||
set category = "Blobbernaut"
|
||||
set name = "Blob Telepathy"
|
||||
set desc = "Send a message to the Overmind"
|
||||
|
||||
if(stat != DEAD)
|
||||
blob_talk()
|
||||
|
||||
/mob/living/simple_animal/hostile/blob/blobbernaut/proc/blob_talk()
|
||||
var/message = input(src, "Announce to the overmind", "Blob Telepathy")
|
||||
var/rendered = "<font color=\"#EE4000\"><i><span class='game say'>Blob Telepathy, <span class='name'>[name]([overmind])</span> <span class='message'>states, \"[message]\"</span></span></i></font>"
|
||||
if(message)
|
||||
for(var/mob/M in GLOB.mob_list)
|
||||
if(isovermind(M) || isobserver(M) || istype((M), /mob/living/simple_animal/hostile/blob/blobbernaut))
|
||||
M.show_message(rendered, 2)
|
||||
@@ -84,7 +84,7 @@
|
||||
var/rendered = "<font color=\"#EE4000\"><i><span class='game say'>Blob Telepathy, <span class='name'>[name]([blob_reagent_datum.name])</span> <span class='message'>[verb] \"[message]\"</span></span></i></font>"
|
||||
|
||||
for(var/mob/M in GLOB.mob_list)
|
||||
if(isovermind(M) || isobserver(M))
|
||||
if(isovermind(M) || isobserver(M) || istype((M), /mob/living/simple_animal/hostile/blob/blobbernaut))
|
||||
M.show_message(rendered, 2)
|
||||
|
||||
/mob/camera/blob/emote(act, m_type = 1, message = null, force)
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
if(blob_nodes.len)
|
||||
var/list/nodes = list()
|
||||
for(var/i = 1; i <= blob_nodes.len; i++)
|
||||
nodes["Blob Node #[i]"] = blob_nodes[i]
|
||||
var/obj/structure/blob/node/B = blob_nodes[i]
|
||||
nodes["Blob Node #[i] ([get_location_name(B)])"] = B
|
||||
var/node_name = input(src, "Choose a node to jump to.", "Node Jump") in nodes
|
||||
var/obj/structure/blob/node/chosen_node = nodes[node_name]
|
||||
if(chosen_node)
|
||||
@@ -207,7 +208,7 @@
|
||||
|
||||
/mob/camera/blob/verb/create_blobbernaut()
|
||||
set category = "Blob"
|
||||
set name = "Create Blobbernaut (20)"
|
||||
set name = "Create Blobbernaut (60)"
|
||||
set desc = "Create a powerful blob-being, a Blobbernaut"
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
@@ -224,7 +225,7 @@
|
||||
to_chat(src, "Unable to use this blob, find a factory blob.")
|
||||
return
|
||||
|
||||
if(!can_buy(20))
|
||||
if(!can_buy(60))
|
||||
return
|
||||
|
||||
var/mob/living/simple_animal/hostile/blob/blobbernaut/blobber = new /mob/living/simple_animal/hostile/blob/blobbernaut (get_turf(B))
|
||||
@@ -233,6 +234,14 @@
|
||||
blobber.color = blob_reagent_datum.complementary_color
|
||||
blobber.overmind = src
|
||||
blob_mobs.Add(blobber)
|
||||
spawn()
|
||||
var/list/candidates = pollCandidates("Do you want to play as a blobbernaut?", ROLE_BLOB, 1, 150)
|
||||
if(candidates.len)
|
||||
var/mob/C = pick(candidates)
|
||||
if(C)
|
||||
blobber.key = C.key
|
||||
to_chat(blobber, "<span class='biggerdanger'>You are a blobbernaut! You must assist all blob lifeforms in their mission to consume everything!</span>")
|
||||
to_chat(blobber, "<span class='danger'>You heal while standing on blob structures, however you will decay slowly if you are damaged outside of the blob.</span>")
|
||||
return
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/datum/action/changeling/headcrab
|
||||
/datum/action/changeling/headslug
|
||||
name = "Last Resort"
|
||||
desc = "We sacrifice our current body in a moment of need, placing us in control of a vessel that can plant our likeness in a new host. Costs 20 chemicals."
|
||||
helptext = "We will be placed in control of a small, fragile creature. We may attack a corpse like this to plant an egg which will slowly mature into a new form for us."
|
||||
@@ -7,12 +7,12 @@
|
||||
dna_cost = 1
|
||||
req_human = 1
|
||||
|
||||
/datum/action/changeling/headcrab/try_to_sting(mob/user, mob/target)
|
||||
/datum/action/changeling/headslug/try_to_sting(mob/user, mob/target)
|
||||
if(alert("Are you sure you wish to do this? This action cannot be undone.",,"Yes","No")=="No")
|
||||
return
|
||||
..()
|
||||
|
||||
/datum/action/changeling/headcrab/sting_action(mob/user)
|
||||
/datum/action/changeling/headslug/sting_action(mob/user)
|
||||
var/datum/mind/M = user.mind
|
||||
var/list/organs = user.get_organs_zone("head", 1)
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
S.Weaken(3)
|
||||
var/new_location = user.drop_location()
|
||||
spawn(5) // So it's not killed in explosion
|
||||
var/mob/living/simple_animal/hostile/headcrab/crab = new(new_location)
|
||||
var/mob/living/simple_animal/hostile/headslug/crab = new(new_location)
|
||||
for(var/obj/item/organ/internal/I in organs)
|
||||
I.loc = crab
|
||||
crab.origin = M
|
||||
@@ -29,7 +29,7 @@ var/global/list/all_cults = list()
|
||||
return 1
|
||||
|
||||
/proc/is_sacrifice_target(datum/mind/mind)
|
||||
if(istype(SSticker.mode.name, "cult"))
|
||||
if(SSticker.mode.name == "cult")
|
||||
var/datum/game_mode/cult/cult_mode = SSticker.mode
|
||||
if(mind == cult_mode.sacrifice_target)
|
||||
return 1
|
||||
|
||||
@@ -344,21 +344,6 @@
|
||||
else
|
||||
to_chat(C, "<span class='danger'>The veil cannot be torn here!</span>")
|
||||
|
||||
/obj/item/clothing/suit/space/eva/plasmaman/cultist
|
||||
name = "plasmaman cultist armor"
|
||||
icon_state = "plasmaman_cult"
|
||||
item_state = "plasmaman_cult"
|
||||
desc = "A bulky suit of armour, menacing with red energy. It looks like it would fit a plasmaman."
|
||||
slowdown = 1
|
||||
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30)
|
||||
|
||||
/obj/item/clothing/head/helmet/space/eva/plasmaman/cultist
|
||||
name = "plasmaman cultist helmet"
|
||||
icon_state = "plasmamanCult_helmet0"
|
||||
base_state = "plasmamanCult_helmet"
|
||||
desc = "A helmet designed by cultists. It glows menacingly with unearthly flames."
|
||||
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30)
|
||||
|
||||
/obj/item/melee/cultblade/ghost
|
||||
name = "eldritch sword"
|
||||
force = 15
|
||||
|
||||
@@ -163,6 +163,16 @@
|
||||
possible_sac_targets += player.mind
|
||||
return possible_sac_targets
|
||||
|
||||
// Handles the updating of sacrifice objectives after the sacrifice target goes to cryo and ghosts
|
||||
/datum/game_mode/cult/proc/update_sac_objective(previous_target, previous_role)
|
||||
for(var/datum/mind/cult_mind in cult)
|
||||
if(cult_mind)
|
||||
var/updated_memory = cult_mind.memory
|
||||
updated_memory = replacetext("[cult_mind.memory]", "[previous_target]", "[sacrifice_target]")
|
||||
updated_memory = replacetext("[updated_memory]", "[previous_role]", "[sacrifice_target.assigned_role]")
|
||||
cult_mind.memory = updated_memory
|
||||
|
||||
|
||||
/datum/game_mode/cult/proc/pick_objective()
|
||||
var/list/possible_objectives = list()
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/obj/item/paper/talisman
|
||||
icon = 'icons/obj/paper.dmi'
|
||||
icon_state = "paper_talisman"
|
||||
var/cultist_name = "talisman"
|
||||
var/cultist_desc = "A basic talisman. It serves no purpose."
|
||||
@@ -7,6 +8,9 @@
|
||||
var/uses = 1
|
||||
var/health_cost = 0 //The amount of health taken from the user when invoking the talisman
|
||||
|
||||
/obj/item/paper/talisman/update_icon()//overriding this so the update_icon doesn't turn them into normal looking paper
|
||||
SEND_SIGNAL(src, COMSIG_OBJ_UPDATE_ICON)
|
||||
|
||||
/obj/item/paper/talisman/examine(mob/user)
|
||||
if(iscultist(user) || user.stat == DEAD)
|
||||
to_chat(user, "<b>Name:</b> [cultist_name]")
|
||||
@@ -49,6 +53,7 @@
|
||||
//Supply Talisman: Has a few unique effects. Granted only to starter cultists.
|
||||
/obj/item/paper/talisman/supply
|
||||
cultist_name = "Supply Talisman"
|
||||
icon_state = "supply"
|
||||
cultist_desc = "A multi-use talisman that can create various objects. Intended to increase the cult's strength early on."
|
||||
invocation = null
|
||||
uses = 3
|
||||
@@ -117,6 +122,7 @@
|
||||
//Rite of Translocation: Same as rune
|
||||
/obj/item/paper/talisman/teleport
|
||||
cultist_name = "Talisman of Teleportation"
|
||||
icon_state = "teleport"
|
||||
cultist_desc = "A single-use talisman that will teleport a user to a random rune of the same keyword."
|
||||
invocation = "Sas'so c'arta forbici!"
|
||||
health_cost = 5
|
||||
@@ -159,6 +165,7 @@
|
||||
|
||||
/obj/item/paper/talisman/summon_tome
|
||||
cultist_name = "Talisman of Tome Summoning"
|
||||
icon_state = "tome"
|
||||
cultist_desc = "A one-use talisman that will call an untranslated tome from the archives of a cult."
|
||||
invocation = "N'ath reth sh'yro eth d'raggathnor!"
|
||||
health_cost = 1
|
||||
@@ -173,6 +180,7 @@
|
||||
|
||||
/obj/item/paper/talisman/true_sight
|
||||
cultist_name = "Talisman of Veiling"
|
||||
icon_state = "veil"
|
||||
cultist_desc = "A multi-use talisman that hides nearby runes. On its second use, will reveal nearby runes."
|
||||
invocation = "Kla'atu barada nikt'o!"
|
||||
health_cost = 1
|
||||
@@ -197,6 +205,7 @@
|
||||
//Rite of False Truths: Same as rune
|
||||
/obj/item/paper/talisman/make_runes_fake
|
||||
cultist_name = "Talisman of Disguising"
|
||||
icon_state = "disguising"
|
||||
cultist_desc = "A talisman that will make nearby runes appear fake."
|
||||
invocation = "By'o nar'nar!"
|
||||
|
||||
@@ -212,6 +221,7 @@
|
||||
//Rite of Disruption: Weaker than rune
|
||||
/obj/item/paper/talisman/emp
|
||||
cultist_name = "Talisman of Electromagnetic Pulse"
|
||||
icon_state = "emp"
|
||||
cultist_desc = "A talisman that will cause a moderately-sized electromagnetic pulse."
|
||||
invocation = "Ta'gh fara'qha fel d'amar det!"
|
||||
health_cost = 5
|
||||
@@ -226,6 +236,7 @@
|
||||
//Rite of Disorientation: Stuns and inhibit speech on a single target for quite some time
|
||||
/obj/item/paper/talisman/stun
|
||||
cultist_name = "Talisman of Stunning"
|
||||
icon_state = "stunning"
|
||||
cultist_desc = "A talisman that will stun and inhibit speech on a single target. To use, attack target directly."
|
||||
invocation = "Dream sign:Evil sealing talisman!"
|
||||
health_cost = 10
|
||||
@@ -271,6 +282,7 @@
|
||||
//Rite of Arming: Equips cultist armor on the user, where available
|
||||
/obj/item/paper/talisman/armor
|
||||
cultist_name = "Talisman of Arming"
|
||||
icon_state = "arming"
|
||||
cultist_desc = "A talisman that will equip the invoker with cultist equipment if there is a slot to equip it to."
|
||||
invocation = "N'ath reth sh'yro eth draggathnor!"
|
||||
|
||||
@@ -279,11 +291,8 @@
|
||||
var/mob/living/carbon/human/H = user
|
||||
user.visible_message("<span class='warning'>Otherworldly armor suddenly appears on [user]!</span>", \
|
||||
"<span class='cultitalic'>You speak the words of the talisman, arming yourself!</span>")
|
||||
if(isplasmaman(H))
|
||||
H.equip_to_slot(new /obj/item/clothing/suit/space/eva/plasmaman/cultist(H), slot_wear_suit)
|
||||
H.equip_to_slot(new /obj/item/clothing/head/helmet/space/eva/plasmaman/cultist(H), slot_head)
|
||||
else
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/suit/hooded/cultrobes/alt(user), slot_wear_suit)
|
||||
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/suit/hooded/cultrobes/alt(user), slot_wear_suit)
|
||||
H.equip_to_slot_or_del(new /obj/item/storage/backpack/cultpack(user), slot_back)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/cult(user), slot_shoes)
|
||||
H.put_in_hands(new /obj/item/melee/cultblade(user))
|
||||
@@ -301,6 +310,7 @@
|
||||
//Talisman of Horrors: Breaks the mind of the victim with nightmarish hallucinations
|
||||
/obj/item/paper/talisman/horror
|
||||
cultist_name = "Talisman of Horrors"
|
||||
icon_state = "horror"
|
||||
cultist_desc = "A talisman that will break the mind of the victim with nightmarish hallucinations."
|
||||
invocation = "Lo'Nab Na'Dm!"
|
||||
|
||||
@@ -316,6 +326,7 @@
|
||||
//Talisman of Fabrication: Creates a construct shell out of 25 metal sheets.
|
||||
/obj/item/paper/talisman/construction
|
||||
cultist_name = "Talisman of Construction"
|
||||
icon_state = "construction"
|
||||
cultist_desc = "Use this talisman on at least twenty-five metal sheets to create an empty construct shell or on plasteel to make runed metal"
|
||||
invocation = "Ethra p'ni dedol!"
|
||||
uses = 25
|
||||
@@ -360,6 +371,7 @@
|
||||
//Talisman of Shackling: Applies special cuffs directly from the talisman
|
||||
/obj/item/paper/talisman/shackle
|
||||
cultist_name = "Talisman of Shackling"
|
||||
icon_state = "shackling"
|
||||
cultist_desc = "Use this talisman on a victim to handcuff them with dark bindings."
|
||||
invocation = "In'totum Lig'abis!"
|
||||
uses = 4
|
||||
|
||||
@@ -291,11 +291,9 @@ proc/issyndicate(mob/living/M as mob)
|
||||
|
||||
if("Plasmaman")
|
||||
synd_mob.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/syndicate(synd_mob), slot_wear_mask)
|
||||
synd_mob.equip_to_slot(new /obj/item/clothing/suit/space/eva/plasmaman/nuclear(synd_mob), slot_wear_suit)
|
||||
synd_mob.equip_to_slot(new /obj/item/clothing/head/helmet/space/eva/plasmaman/nuclear(synd_mob), slot_head)
|
||||
synd_mob.equip_or_collect(new /obj/item/tank/plasma/plasmaman(synd_mob), slot_s_store)
|
||||
synd_mob.equip_or_collect(new /obj/item/plasmensuit_cartridge(synd_mob), slot_in_backpack)
|
||||
synd_mob.equip_or_collect(new /obj/item/plasmensuit_cartridge(synd_mob), slot_in_backpack)
|
||||
synd_mob.equip_or_collect(new /obj/item/extinguisher_refill(synd_mob), slot_in_backpack)
|
||||
synd_mob.equip_or_collect(new /obj/item/extinguisher_refill(synd_mob), slot_in_backpack)
|
||||
synd_mob.internal = synd_mob.get_item_by_slot(slot_s_store)
|
||||
synd_mob.update_action_buttons_icon()
|
||||
|
||||
|
||||
@@ -76,14 +76,19 @@ var/bomb_set
|
||||
|
||||
if(panel_open && (istype(O, /obj/item/multitool) || istype(O, /obj/item/wirecutters)))
|
||||
return attack_hand(user)
|
||||
|
||||
if(extended)
|
||||
if(istype(O, /obj/item/disk/nuclear))
|
||||
usr.drop_item()
|
||||
O.loc = src
|
||||
|
||||
if(istype(O, /obj/item/disk/nuclear))
|
||||
if(extended)
|
||||
if(!user.drop_item())
|
||||
to_chat(user, "<span class='notice'>\The [O] is stuck to your hand!</span>")
|
||||
return
|
||||
O.forceMove(src)
|
||||
auth = O
|
||||
add_fingerprint(user)
|
||||
return attack_hand(user)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You need to deploy \the [src] first. Right click on the sprite, select 'Make Deployable' then click on \the [src] with an empty hand.</span>")
|
||||
return
|
||||
|
||||
if(anchored)
|
||||
switch(removal_stage)
|
||||
|
||||
@@ -297,23 +297,23 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha
|
||||
to_chat(owner, "<span class='warning'>They've got no blood left to give.</span>")
|
||||
break
|
||||
if(H.stat < DEAD)
|
||||
if(!issmall(H) || H.ckey)
|
||||
if(H.ckey || H.player_ghosted) //Requires ckey regardless if monkey or humanoid, or the body has been ghosted before it died
|
||||
blood = min(20, H.blood_volume) // if they have less than 20 blood, give them the remnant else they get 20 blood
|
||||
bloodtotal += blood / 2 //divide by 2 to counted the double suction since removing cloneloss -Melandor0
|
||||
bloodusable += blood / 2
|
||||
else
|
||||
if(!issmall(H) || H.ckey)
|
||||
if(H.ckey || H.player_ghosted)
|
||||
blood = min(5, H.blood_volume) // The dead only give 5 blood
|
||||
bloodtotal += blood
|
||||
if(old_bloodtotal != bloodtotal)
|
||||
if(!issmall(H) || H.ckey) // not small OR has a ckey, monkeys with ckeys can be sucked, humanized monkeys can be sucked monkeys without ckeys cannot be sucked
|
||||
if(H.ckey || H.player_ghosted) // Requires ckey regardless if monkey or human, and has not ghosted, otherwise no power
|
||||
to_chat(owner, "<span class='notice'><b>You have accumulated [bloodtotal] [bloodtotal > 1 ? "units" : "unit"] of blood[bloodusable != old_bloodusable ? ", and have [bloodusable] left to use" : ""].</b></span>")
|
||||
check_vampire_upgrade()
|
||||
H.blood_volume = max(H.blood_volume - 25, 0)
|
||||
if(ishuman(owner))
|
||||
var/mob/living/carbon/human/V = owner
|
||||
if(issmall(H) && !H.ckey)
|
||||
to_chat(V, "<span class='notice'><b>Feeding on [H] reduces your hunger, but you get no usable blood from it.</b></span>")
|
||||
if(!H.ckey && !H.player_ghosted)//Only runs if there is no ckey and the body has not being ghosted while alive
|
||||
to_chat(V, "<span class='notice'><b>Feeding on [H] reduces your thirst, but you get no usable blood from them.</b></span>")
|
||||
V.nutrition = min(NUTRITION_LEVEL_WELL_FED, V.nutrition + 5)
|
||||
else
|
||||
V.nutrition = min(NUTRITION_LEVEL_WELL_FED, V.nutrition + (blood / 2))
|
||||
@@ -402,7 +402,14 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha
|
||||
|
||||
if(T.density)
|
||||
return
|
||||
vamp_burn(1)
|
||||
if(bloodusable >= 10) //burn through your blood to tank the light for a little while
|
||||
to_chat(owner, "<span class='warning'>The starlight saps your strength!</span>")
|
||||
bloodusable -= 10
|
||||
vamp_burn(10)
|
||||
else //You're in trouble, get out of the sun NOW
|
||||
to_chat(owner, "<span class='userdanger'>Your body is turning to ash, get out of the light now!</span>")
|
||||
owner.adjustCloneLoss(10) //I'm melting!
|
||||
vamp_burn(85)
|
||||
|
||||
/datum/vampire/proc/handle_vampire()
|
||||
if(owner.hud_used)
|
||||
@@ -419,7 +426,7 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha
|
||||
if(istype(owner.loc, /turf/space))
|
||||
check_sun()
|
||||
if(istype(owner.loc.loc, /area/chapel) && !get_ability(/datum/vampire_passive/full))
|
||||
vamp_burn(0)
|
||||
vamp_burn(7)
|
||||
nullified = max(0, nullified - 1)
|
||||
|
||||
/datum/vampire/proc/handle_vampire_cloak()
|
||||
@@ -442,8 +449,7 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha
|
||||
else
|
||||
owner.alpha = round((255 * 0.80))
|
||||
|
||||
/datum/vampire/proc/vamp_burn(severe_burn)
|
||||
var/burn_chance = severe_burn ? 35 : 8
|
||||
/datum/vampire/proc/vamp_burn(burn_chance)
|
||||
if(prob(burn_chance) && owner.health >= 50)
|
||||
switch(owner.health)
|
||||
if(75 to 100)
|
||||
|
||||
@@ -139,7 +139,6 @@
|
||||
new /obj/item/gun/magic/staff/door(get_turf(H))
|
||||
if("armor")
|
||||
new /obj/item/clothing/suit/space/hardsuit/wizard(get_turf(H))
|
||||
new /obj/item/clothing/head/helmet/space/hardsuit/wizard(get_turf(H))
|
||||
if("scrying")
|
||||
new /obj/item/scrying(get_turf(H))
|
||||
if(!(XRAY in H.mutations))
|
||||
|
||||
@@ -446,7 +446,6 @@
|
||||
if(.)
|
||||
new /obj/item/clothing/shoes/magboots/wizard(get_turf(user))
|
||||
new /obj/item/clothing/gloves/color/purple(get_turf(user)) // To complete the outfit
|
||||
new /obj/item/clothing/head/helmet/space/hardsuit/wizard(get_turf(user))
|
||||
|
||||
/datum/spellbook_entry/item/mjolnir
|
||||
name = "Mjolnir"
|
||||
@@ -934,7 +933,7 @@
|
||||
if(istype(user, /mob/living/carbon/human))
|
||||
to_chat(user, "<font size='15' color='red'><b>HOR-SIE HAS RISEN</b></font>")
|
||||
var/obj/item/clothing/mask/horsehead/magichead = new /obj/item/clothing/mask/horsehead
|
||||
magichead.flags |= NODROP //curses!
|
||||
magichead.flags |= NODROP | DROPDEL //curses!
|
||||
magichead.flags_inv = null //so you can still see their face
|
||||
magichead.voicechange = 1 //NEEEEIIGHH
|
||||
if(!user.unEquip(user.wear_mask))
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
required_players = 20
|
||||
required_enemies = 1
|
||||
recommended_enemies = 1
|
||||
var/use_huds = 0
|
||||
var/use_huds = 1
|
||||
|
||||
var/finished = 0
|
||||
var/but_wait_theres_more = 0
|
||||
|
||||
@@ -157,22 +158,30 @@
|
||||
wizard_mob.gene_stability += DEFAULT_GENE_STABILITY //magic
|
||||
return 1
|
||||
|
||||
// Checks if the game should end due to all wizards and apprentices being dead, or MMI'd/Borged
|
||||
/datum/game_mode/wizard/check_finished()
|
||||
var/wizards_alive = 0
|
||||
var/traitors_alive = 0
|
||||
|
||||
// Wizards
|
||||
for(var/datum/mind/wizard in wizards)
|
||||
if(!istype(wizard.current,/mob/living/carbon))
|
||||
continue
|
||||
if(wizard.current.stat==DEAD)
|
||||
continue
|
||||
if(istype(wizard.current, /obj/item/mmi)) // wizard is in an MMI, don't count them as alive
|
||||
continue
|
||||
wizards_alive++
|
||||
|
||||
// Apprentices - classified as "traitors"
|
||||
if(!wizards_alive)
|
||||
for(var/datum/mind/traitor in traitors)
|
||||
if(!istype(traitor.current,/mob/living/carbon))
|
||||
continue
|
||||
if(traitor.current.stat==DEAD)
|
||||
continue
|
||||
if(istype(traitor.current, /obj/item/mmi)) // apprentice is in an MMI, don't count them as alive
|
||||
continue
|
||||
traitors_alive++
|
||||
|
||||
if(wizards_alive || traitors_alive || but_wait_theres_more)
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
var/backpack = /obj/item/storage/backpack
|
||||
var/satchel = /obj/item/storage/backpack/satchel_norm
|
||||
var/dufflebag = /obj/item/storage/backpack/duffel
|
||||
var/box = /obj/item/storage/box/survival
|
||||
box = /obj/item/storage/box/survival
|
||||
|
||||
var/tmp/list/gear_leftovers = list()
|
||||
|
||||
@@ -168,12 +168,8 @@
|
||||
else
|
||||
back = backpack //Department backpack
|
||||
|
||||
if(box)
|
||||
var/spawnbox = box
|
||||
if(H.dna.species.speciesbox)
|
||||
spawnbox = H.dna.species.speciesbox
|
||||
backpack_contents.Insert(1, spawnbox) // Box always takes a first slot in backpack
|
||||
backpack_contents[spawnbox] = 1
|
||||
if(box && H.dna.species.speciesbox)
|
||||
box = H.dna.species.speciesbox
|
||||
|
||||
if(allow_loadout && H.client && (H.client.prefs.gear && H.client.prefs.gear.len))
|
||||
for(var/gear in H.client.prefs.gear)
|
||||
|
||||
@@ -175,23 +175,24 @@
|
||||
name = "Shaft Miner"
|
||||
jobtype = /datum/job/mining
|
||||
|
||||
uniform = /obj/item/clothing/under/rank/miner/lavaland
|
||||
gloves = /obj/item/clothing/gloves/color/black
|
||||
shoes = /obj/item/clothing/shoes/workboots/mining
|
||||
l_ear = /obj/item/radio/headset/headset_cargo/mining
|
||||
id = /obj/item/card/id/supply
|
||||
shoes = /obj/item/clothing/shoes/workboots/mining
|
||||
gloves = /obj/item/clothing/gloves/color/black
|
||||
uniform = /obj/item/clothing/under/rank/miner/lavaland
|
||||
l_pocket = /obj/item/reagent_containers/hypospray/autoinjector/survival
|
||||
r_pocket = /obj/item/flashlight/seclite
|
||||
r_pocket = /obj/item/storage/bag/ore
|
||||
id = /obj/item/card/id/supply
|
||||
pda = /obj/item/pda/shaftminer
|
||||
backpack_contents = list(
|
||||
/obj/item/storage/bag/ore=1,\
|
||||
/obj/item/flashlight/seclite=1,\
|
||||
/obj/item/kitchen/knife/combat/survival=1,\
|
||||
/obj/item/mining_voucher=1,\
|
||||
/obj/item/stack/marker_beacon/ten=1
|
||||
)
|
||||
|
||||
|
||||
backpack = /obj/item/storage/backpack/explorer
|
||||
satchel = /obj/item/storage/backpack/explorer
|
||||
satchel = /obj/item/storage/backpack/satchel/explorer
|
||||
box = /obj/item/storage/box/survival_mining
|
||||
|
||||
/datum/outfit/job/mining/equipped
|
||||
name = "Shaft Miner"
|
||||
@@ -210,9 +211,6 @@
|
||||
/obj/item/stack/marker_beacon/ten=1
|
||||
)
|
||||
|
||||
backpack = /obj/item/storage/backpack/explorer
|
||||
satchel = /obj/item/storage/backpack/explorer
|
||||
|
||||
/datum/outfit/job/miner/equipped/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
..()
|
||||
if(visualsOnly)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
idle_power_usage = 5
|
||||
active_power_usage = 60
|
||||
power_channel = EQUIP
|
||||
pass_flags = PASSTABLE
|
||||
var/obj/item/stock_parts/cell/charging = null
|
||||
var/chargelevel = -1
|
||||
|
||||
|
||||
@@ -178,6 +178,12 @@
|
||||
if(occupant && occupant.stat != DEAD)
|
||||
to_chat(user, "Current clone cycle is [round(get_completion())]% complete.")
|
||||
|
||||
/obj/machinery/clonepod/return_air() //non-reactive air
|
||||
var/datum/gas_mixture/GM = new
|
||||
GM.nitrogen = MOLES_O2STANDARD + MOLES_N2STANDARD
|
||||
GM.temperature = T20C
|
||||
return GM
|
||||
|
||||
/obj/machinery/clonepod/proc/get_completion()
|
||||
. = (100 * ((occupant.health + 100) / (heal_level + 100)))
|
||||
|
||||
|
||||
@@ -460,6 +460,12 @@
|
||||
desc = "Here's your chance, do your dance at the Space Jam."
|
||||
w_class = WEIGHT_CLASS_BULKY //Stops people from hiding it in their bags/pockets
|
||||
|
||||
/obj/item/beach_ball/holoball/baseball
|
||||
icon_state = "baseball"
|
||||
name = "baseball"
|
||||
item_state = "baseball"
|
||||
desc = "Take me out to the ball game."
|
||||
|
||||
/obj/structure/holohoop
|
||||
name = "basketball hoop"
|
||||
desc = "Boom, Shakalaka!"
|
||||
|
||||
@@ -330,6 +330,14 @@ to destroy them and players will be able to make replacements.
|
||||
name = "circuit board (Freezer)"
|
||||
to_chat(user, "<span class='notice'>You set the board to cooling.</span>")
|
||||
|
||||
/obj/item/circuitboard/recharger
|
||||
name = "circuit board (Recharger)"
|
||||
build_path = /obj/machinery/recharger
|
||||
board_type = "machine"
|
||||
origin_tech = "powerstorage=3;materials=2"
|
||||
frame_desc = "Requires 1 Capacitor"
|
||||
req_components = list(/obj/item/stock_parts/capacitor = 1)
|
||||
|
||||
/obj/item/circuitboard/snow_machine
|
||||
name = "circuit board (snow machine)"
|
||||
build_path = /obj/machinery/snow_machine
|
||||
@@ -591,6 +599,16 @@ to destroy them and players will be able to make replacements.
|
||||
/obj/item/stock_parts/micro_laser = 1,
|
||||
/obj/item/stock_parts/console_screen = 1)
|
||||
|
||||
/obj/item/circuitboard/reagentgrinder
|
||||
name = "circuit board (All-In-One Grinder)"
|
||||
build_path = /obj/machinery/reagentgrinder/empty
|
||||
board_type = "machine"
|
||||
origin_tech = "materials=2;engineering=2;biotech=2"
|
||||
frame_desc = "Requires 2 Manipulators and 1 Matter Bin."
|
||||
req_components = list(
|
||||
/obj/item/stock_parts/manipulator = 2,
|
||||
/obj/item/stock_parts/matter_bin = 1)
|
||||
|
||||
//Almost the same recipe as destructive analyzer to give people choices.
|
||||
/obj/item/circuitboard/experimentor
|
||||
name = "circuit board (E.X.P.E.R.I-MENTOR)"
|
||||
|
||||
@@ -371,6 +371,8 @@
|
||||
for(var/datum/mind/H in SSticker.mode.cult)
|
||||
if(H.current)
|
||||
to_chat(H.current, "<span class='danger'>[SSticker.cultdat.entity_name]</span> murmurs, <span class='cultlarge'>[occupant] is beyond your reach. Sacrifice [cult_mode.sacrifice_target.current] instead...</span></span>")
|
||||
H.current << 'sound/ambience/alarm4.ogg'
|
||||
cult_mode.update_sac_objective(occupant.mind, occupant.mind.assigned_role)
|
||||
else
|
||||
cult_mode.bypass_phase()
|
||||
|
||||
|
||||
@@ -181,12 +181,6 @@ About the new airlock wires panel:
|
||||
/obj/machinery/door/airlock/bumpopen(mob/living/simple_animal/user)
|
||||
..(user)
|
||||
|
||||
/obj/machinery/door/airlock/autoclose()
|
||||
autoclose_timer = 0
|
||||
if(!QDELETED(src) && !density && !operating && !locked && !welded && autoclose)
|
||||
close()
|
||||
return
|
||||
|
||||
/obj/machinery/door/airlock/proc/isElectrified()
|
||||
if(electrified_until != 0)
|
||||
return 1
|
||||
@@ -311,6 +305,7 @@ About the new airlock wires panel:
|
||||
/obj/machinery/door/airlock/update_icon(state=0, override=0)
|
||||
if(operating && !override)
|
||||
return
|
||||
check_unres()
|
||||
icon_state = density ? "closed" : "open"
|
||||
switch(state)
|
||||
if(0)
|
||||
@@ -333,7 +328,6 @@ About the new airlock wires panel:
|
||||
var/image/sparks_overlay
|
||||
var/image/note_overlay
|
||||
var/notetype = note_type()
|
||||
|
||||
switch(state)
|
||||
if(AIRLOCK_CLOSED)
|
||||
frame_overlay = get_airlock_overlay("closed", icon)
|
||||
@@ -516,6 +510,7 @@ About the new airlock wires panel:
|
||||
else
|
||||
to_chat(user, "There's a [note.name] pinned to the front...")
|
||||
note.examine(user)
|
||||
to_chat(user, "<span class='notice'>Use an empty hand on the airlock on grab mode to remove [note.name].</span>")
|
||||
|
||||
if(panel_open)
|
||||
switch(security_level)
|
||||
@@ -621,6 +616,31 @@ About the new airlock wires panel:
|
||||
if(user)
|
||||
attack_ai(user)
|
||||
|
||||
/obj/machinery/door/airlock/proc/check_unres() //unrestricted sides. This overlay indicates which directions the player can access even without an ID
|
||||
if(hasPower() && unres_sides)
|
||||
if(unres_sides & NORTH)
|
||||
var/image/I = image(icon='icons/obj/doors/airlocks/station/overlays.dmi', icon_state="unres_n") //layer=src.layer+1
|
||||
I.pixel_y = 32
|
||||
set_light(l_range = 1, l_power = 1, l_color = "#00FF00")
|
||||
add_overlay(I)
|
||||
if(unres_sides & SOUTH)
|
||||
var/image/I = image(icon='icons/obj/doors/airlocks/station/overlays.dmi', icon_state="unres_s") //layer=src.layer+1
|
||||
I.pixel_y = -32
|
||||
set_light(l_range = 1, l_power = 1, l_color = "#00FF00")
|
||||
add_overlay(I)
|
||||
if(unres_sides & EAST)
|
||||
var/image/I = image(icon='icons/obj/doors/airlocks/station/overlays.dmi', icon_state="unres_e") //layer=src.layer+1
|
||||
I.pixel_x = 32
|
||||
set_light(l_range = 1, l_power = 1, l_color = "#00FF00")
|
||||
add_overlay(I)
|
||||
if(unres_sides & WEST)
|
||||
var/image/I = image(icon='icons/obj/doors/airlocks/station/overlays.dmi', icon_state="unres_w") //layer=src.layer+1
|
||||
I.pixel_x = -32
|
||||
set_light(l_range = 1, l_power = 1, l_color = "#00FF00")
|
||||
add_overlay(I)
|
||||
else
|
||||
set_light(0)
|
||||
|
||||
/obj/machinery/door/airlock/CanPass(atom/movable/mover, turf/target, height=0)
|
||||
if(isElectrified() && density && istype(mover, /obj/item))
|
||||
var/obj/item/I = mover
|
||||
@@ -1078,6 +1098,10 @@ About the new airlock wires panel:
|
||||
playsound(loc, doorOpen, 30, 1)
|
||||
if(closeOther != null && istype(closeOther, /obj/machinery/door/airlock/) && !closeOther.density)
|
||||
closeOther.close()
|
||||
|
||||
if(autoclose)
|
||||
autoclose_in(normalspeed ? auto_close_time : auto_close_time_dangerous)
|
||||
|
||||
if(!density)
|
||||
return TRUE
|
||||
operating = TRUE
|
||||
@@ -1092,10 +1116,6 @@ About the new airlock wires panel:
|
||||
layer = OPEN_DOOR_LAYER
|
||||
update_icon(AIRLOCK_OPEN, 1)
|
||||
operating = FALSE
|
||||
|
||||
// The `addtimer` system has the advantage of being cancelable
|
||||
if(autoclose)
|
||||
autoclose_timer = addtimer(CALLBACK(src, .proc/autoclose), normalspeed ? auto_close_time : auto_close_time_dangerous, TIMER_UNIQUE | TIMER_STOPPABLE)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/door/airlock/close(forced=0, override = 0)
|
||||
@@ -1112,7 +1132,8 @@ About the new airlock wires panel:
|
||||
for(var/turf/turf in locs)
|
||||
for(var/atom/movable/M in turf)
|
||||
if(M.density && M != src) //something is blocking the door
|
||||
addtimer(CALLBACK(src, .proc/autoclose), 60)
|
||||
autoclose_in(60)
|
||||
return
|
||||
|
||||
use_power(360) //360 W seems much more appropriate for an actuator moving an industrial door capable of crushing people
|
||||
if(forced)
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
var/list/conf_access = null
|
||||
var/one_access = 0 //if set to 1, door would receive req_one_access instead of req_access
|
||||
var/const/max_brain_damage = 60 // Maximum brain damage a mob can have until it can't use the electronics
|
||||
var/unres_sides = 0
|
||||
var/unres_direction = null
|
||||
|
||||
/obj/item/airlock_electronics/attack_self(mob/user)
|
||||
if(!ishuman(user) && !isrobot(user))
|
||||
@@ -23,14 +25,22 @@
|
||||
return
|
||||
|
||||
var/t1 = text("<B>Access control</B><br>\n")
|
||||
t1 += "<hr>"
|
||||
t1 += "<B> Unrestricted Access Settings</B><br>"
|
||||
|
||||
var/list/Directions = list("North","South",,"East",,,,"West")
|
||||
for(var/direction in cardinal)
|
||||
if (unres_direction && unres_direction == direction)
|
||||
t1 += "<a style='color: red' href='?src=[UID()];unres_direction=[direction]'>[Directions[direction]]</a><br>"
|
||||
else
|
||||
t1 += "<a href='?src=[UID()];unres_direction=[direction]'>[Directions[direction]]</a><br>"
|
||||
|
||||
t1 += "<hr>"
|
||||
t1 += "Access requirement is set to "
|
||||
t1 += one_access ? "<a style='color: green' href='?src=[UID()];one_access=1'>ONE</a><hr>" : "<a style='color: red' href='?src=[UID()];one_access=1'>ALL</a><hr>"
|
||||
|
||||
t1 += conf_access == null ? "<font color=red>All</font><br>" : "<a href='?src=[UID()];access=all'>All</a><br>"
|
||||
|
||||
t1 += "<br>"
|
||||
|
||||
var/list/accesses = get_all_accesses()
|
||||
for(var/acc in accesses)
|
||||
var/aname = get_access_desc(acc)
|
||||
@@ -64,6 +74,14 @@
|
||||
|
||||
if(href_list["access"])
|
||||
toggle_access(href_list["access"])
|
||||
|
||||
if(href_list["unres_direction"])
|
||||
unres_direction = text2num(href_list["unres_direction"])
|
||||
if (unres_sides == unres_direction)
|
||||
unres_sides = 0
|
||||
unres_direction = null
|
||||
else
|
||||
unres_sides = unres_direction
|
||||
|
||||
attack_self(usr)
|
||||
|
||||
|
||||
@@ -14,21 +14,20 @@
|
||||
var/visible = 1
|
||||
var/operating = FALSE
|
||||
var/autoclose = 0
|
||||
var/autoclose_timer
|
||||
var/safe = TRUE //whether the door detects things and mobs in its way and reopen or crushes them.
|
||||
var/locked = FALSE //whether the door is bolted or not.
|
||||
var/glass = FALSE
|
||||
var/welded = FALSE
|
||||
var/normalspeed = 1
|
||||
var/auto_close_time = 150
|
||||
var/auto_close_time_dangerous = 5
|
||||
var/auto_close_time_dangerous = 15
|
||||
var/assemblytype //the type of door frame to drop during deconstruction
|
||||
var/datum/effect_system/spark_spread/spark_system
|
||||
var/damage_deflection = 10
|
||||
var/real_explosion_block //ignore this, just use explosion_block
|
||||
var/heat_proof = FALSE // For rglass-windowed airlocks and firedoors
|
||||
var/emergency = FALSE
|
||||
|
||||
var/unres_sides = 0 //Unrestricted sides. A bitflag for which direction (if any) can open the door with no access
|
||||
//Multi-tile doors
|
||||
var/width = 1
|
||||
|
||||
@@ -55,6 +54,10 @@
|
||||
..()
|
||||
update_dir()
|
||||
|
||||
/obj/machinery/door/power_change()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/door/proc/update_dir()
|
||||
if(width > 1)
|
||||
if(dir in list(EAST, WEST))
|
||||
@@ -73,9 +76,6 @@
|
||||
air_update_turf(1)
|
||||
update_freelook_sight()
|
||||
GLOB.airlocks -= src
|
||||
if(autoclose_timer)
|
||||
deltimer(autoclose_timer)
|
||||
autoclose_timer = 0
|
||||
QDEL_NULL(spark_system)
|
||||
return ..()
|
||||
|
||||
@@ -175,10 +175,15 @@
|
||||
/obj/machinery/door/allowed(mob/M)
|
||||
if(emergency)
|
||||
return TRUE
|
||||
if(unrestricted_side(M))
|
||||
return TRUE
|
||||
if(!requiresID())
|
||||
return FALSE // Intentional. machinery/door/requiresID() always == 1. airlocks, however, == 0 if ID scan is disabled. Yes, this var is poorly named.
|
||||
return ..()
|
||||
|
||||
/obj/machinery/door/proc/unrestricted_side(mob/M) //Allows for specific side of airlocks to be unrestrected (IE, can exit maint freely, but need access to enter)
|
||||
return get_dir(src, M) & unres_sides
|
||||
|
||||
/obj/machinery/door/proc/try_to_weld(obj/item/weldingtool/W, mob/user)
|
||||
return
|
||||
|
||||
@@ -273,11 +278,8 @@
|
||||
operating = FALSE
|
||||
air_update_turf(1)
|
||||
update_freelook_sight()
|
||||
|
||||
// The `addtimer` system has the advantage of being cancelable
|
||||
if(autoclose)
|
||||
autoclose_timer = addtimer(CALLBACK(src, .proc/autoclose), normalspeed ? auto_close_time : auto_close_time_dangerous, TIMER_UNIQUE | TIMER_STOPPABLE)
|
||||
|
||||
autoclose_in(normalspeed ? auto_close_time : auto_close_time_dangerous)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/door/proc/close()
|
||||
@@ -286,18 +288,15 @@
|
||||
if(operating || welded)
|
||||
return
|
||||
if(safe)
|
||||
for(var/atom/movable/M in get_turf(src))
|
||||
if(M.density && M != src) //something is blocking the door
|
||||
if(autoclose)
|
||||
addtimer(CALLBACK(src, .proc/autoclose), 60)
|
||||
return
|
||||
for(var/turf/turf in locs)
|
||||
for(var/atom/movable/M in turf)
|
||||
if(M.density && M != src) //something is blocking the door
|
||||
if(autoclose)
|
||||
autoclose_in(60)
|
||||
return
|
||||
|
||||
operating = TRUE
|
||||
|
||||
if(autoclose_timer)
|
||||
deltimer(autoclose_timer)
|
||||
autoclose_timer = 0
|
||||
|
||||
do_animate("closing")
|
||||
layer = closingLayer
|
||||
sleep(5)
|
||||
@@ -345,10 +344,12 @@
|
||||
return !(stat & NOPOWER)
|
||||
|
||||
/obj/machinery/door/proc/autoclose()
|
||||
autoclose_timer = 0
|
||||
if(!QDELETED(src) && !density && !operating && !locked && !welded && autoclose)
|
||||
close()
|
||||
|
||||
/obj/machinery/door/proc/autoclose_in(wait)
|
||||
addtimer(CALLBACK(src, .proc/autoclose), wait, TIMER_UNIQUE | TIMER_NO_HASH_WAIT | TIMER_OVERRIDE)
|
||||
|
||||
/obj/machinery/door/proc/update_freelook_sight()
|
||||
if(!glass && cameranet)
|
||||
cameranet.updateVisibility(src, 0)
|
||||
|
||||
@@ -160,8 +160,8 @@
|
||||
var/obj/item/stack/cable_coil/C = W
|
||||
to_chat(user, "You start adding cables to \the [src]...")
|
||||
playsound(get_turf(src), C.usesound, 50, 1)
|
||||
if(do_after(user, 20 * C.toolspeed, target = src) && (C.amount >= 3) && (build == 2))
|
||||
C.use(3)
|
||||
if(do_after(user, 20 * C.toolspeed, target = src) && (C.amount >= 2) && (build == 2))
|
||||
C.use(2)
|
||||
to_chat(user, "<span class='notice'>You've added cables to \the [src].</span>")
|
||||
build++
|
||||
update_icon()
|
||||
@@ -169,7 +169,7 @@
|
||||
if(istype(W, /obj/item/wirecutters))
|
||||
to_chat(user, "You begin to remove the wiring from \the [src].")
|
||||
if(do_after(user, 10 * W.toolspeed, target = src) && (build == 3))
|
||||
new /obj/item/stack/cable_coil(loc,3)
|
||||
new /obj/item/stack/cable_coil(loc,2)
|
||||
playsound(get_turf(src), W.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You've removed the cables from \the [src].</span>")
|
||||
build--
|
||||
@@ -179,8 +179,8 @@
|
||||
var/obj/item/stack/rods/R = W
|
||||
to_chat(user, "You begin to complete \the [src]...")
|
||||
playsound(get_turf(src), R.usesound, 50, 1)
|
||||
if(do_after(user, 20 * R.toolspeed, target = src) && (R.amount >= 3) && (build == 3))
|
||||
R.use(3)
|
||||
if(do_after(user, 20 * R.toolspeed, target = src) && (R.amount >= 2) && (build == 3))
|
||||
R.use(2)
|
||||
to_chat(user, "<span class='notice'>You've added the grille to \the [src].</span>")
|
||||
build++
|
||||
update_icon()
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
anchored = 1
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 4
|
||||
active_power_usage = 250
|
||||
active_power_usage = 200
|
||||
pass_flags = PASSTABLE
|
||||
var/obj/item/charging = null
|
||||
var/using_power = FALSE
|
||||
var/list/allowed_devices = list(/obj/item/gun/energy, /obj/item/melee/baton, /obj/item/modular_computer, /obj/item/rcs, /obj/item/bodyanalyzer)
|
||||
@@ -14,6 +15,18 @@
|
||||
var/icon_state_charged = "recharger2"
|
||||
var/icon_state_charging = "recharger1"
|
||||
var/icon_state_idle = "recharger0"
|
||||
var/recharge_coeff = 1
|
||||
|
||||
/obj/machinery/recharger/New()
|
||||
..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/circuitboard/recharger(null)
|
||||
component_parts += new /obj/item/stock_parts/capacitor(null)
|
||||
RefreshParts()
|
||||
|
||||
/obj/machinery/recharger/RefreshParts()
|
||||
for(var/obj/item/stock_parts/capacitor/C in component_parts)
|
||||
recharge_coeff = C.rating
|
||||
|
||||
/obj/machinery/recharger/attackby(obj/item/G, mob/user, params)
|
||||
if(iswrench(G))
|
||||
@@ -54,8 +67,16 @@
|
||||
else
|
||||
to_chat(user, "<span class='notice'>[src] isn't connected to anything!</span>")
|
||||
return 1
|
||||
else
|
||||
return ..()
|
||||
|
||||
if(anchored && !charging)
|
||||
if(default_deconstruction_screwdriver(user, "rechargeropen", "recharger0", G))
|
||||
return
|
||||
|
||||
if(panel_open && istype(G, /obj/item/crowbar))
|
||||
default_deconstruction_crowbar(G)
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/recharger/attack_hand(mob/user)
|
||||
if(issilicon(user))
|
||||
@@ -87,10 +108,11 @@
|
||||
if(istype(charging, /obj/item/gun/energy))
|
||||
var/obj/item/gun/energy/E = charging
|
||||
if(E.power_supply.charge < E.power_supply.maxcharge)
|
||||
E.power_supply.give(E.power_supply.chargerate)
|
||||
E.power_supply.give(E.power_supply.chargerate * recharge_coeff)
|
||||
use_power(250)
|
||||
using_power = TRUE
|
||||
|
||||
|
||||
if(istype(charging, /obj/item/melee/baton))
|
||||
var/obj/item/melee/baton/B = charging
|
||||
if(B.bcell)
|
||||
|
||||
@@ -62,8 +62,7 @@
|
||||
|
||||
/obj/machinery/suit_storage_unit/engine
|
||||
name = "engineering suit storage unit"
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/engineering
|
||||
helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/engineering
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/engine
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
magboots_type = /obj/item/clothing/shoes/magboots
|
||||
req_access = list(access_engine_equip)
|
||||
@@ -73,8 +72,7 @@
|
||||
|
||||
/obj/machinery/suit_storage_unit/ce
|
||||
name = "chief engineer's suit storage unit"
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/elite
|
||||
helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/elite
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/engine/elite
|
||||
mask_type = /obj/item/clothing/mask/gas
|
||||
magboots_type = /obj/item/clothing/shoes/magboots/advance
|
||||
req_access = list(access_ce)
|
||||
@@ -85,7 +83,6 @@
|
||||
/obj/machinery/suit_storage_unit/security
|
||||
name = "security suit storage unit"
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/security
|
||||
helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/security
|
||||
mask_type = /obj/item/clothing/mask/gas/sechailer
|
||||
magboots_type = /obj/item/clothing/shoes/magboots
|
||||
req_access = list(access_security)
|
||||
@@ -98,8 +95,7 @@
|
||||
|
||||
/obj/machinery/suit_storage_unit/atmos
|
||||
name = "atmospherics suit storage unit"
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/atmos
|
||||
helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/atmos
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/engine/atmos
|
||||
mask_type = /obj/item/clothing/mask/gas
|
||||
magboots_type = /obj/item/clothing/shoes/magboots
|
||||
req_access = list(access_atmospherics)
|
||||
@@ -110,7 +106,6 @@
|
||||
/obj/machinery/suit_storage_unit/mining
|
||||
name = "mining suit storage unit"
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/mining
|
||||
helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/mining
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
req_access = list(access_mining_station)
|
||||
|
||||
@@ -125,7 +120,6 @@
|
||||
|
||||
/obj/machinery/suit_storage_unit/cmo
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/medical
|
||||
helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/medical
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
req_access = list(access_cmo)
|
||||
|
||||
@@ -159,7 +153,6 @@
|
||||
/obj/machinery/suit_storage_unit/syndicate
|
||||
name = "syndicate suit storage unit"
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/syndi
|
||||
helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/syndi
|
||||
mask_type = /obj/item/clothing/mask/gas/syndicate
|
||||
magboots_type = /obj/item/clothing/shoes/magboots/syndie
|
||||
storage_type = /obj/item/tank/jetpack/oxygen/harness
|
||||
@@ -174,7 +167,6 @@
|
||||
|
||||
/obj/machinery/suit_storage_unit/ert/command
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/ert/commander
|
||||
helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/ert/commander
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
storage_type = /obj/item/tank/emergency_oxygen/double
|
||||
|
||||
@@ -183,7 +175,6 @@
|
||||
|
||||
/obj/machinery/suit_storage_unit/ert/security
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/ert/security
|
||||
helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/ert/security
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
storage_type = /obj/item/tank/emergency_oxygen/double
|
||||
|
||||
@@ -192,7 +183,6 @@
|
||||
|
||||
/obj/machinery/suit_storage_unit/ert/engineer
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/ert/engineer
|
||||
helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/ert/engineer
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
storage_type = /obj/item/tank/emergency_oxygen/double
|
||||
|
||||
@@ -201,7 +191,6 @@
|
||||
|
||||
/obj/machinery/suit_storage_unit/ert/medical
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/ert/medical
|
||||
helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/ert/medical
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
storage_type = /obj/item/tank/emergency_oxygen/double
|
||||
|
||||
@@ -699,7 +688,7 @@
|
||||
else
|
||||
mask.forceMove(loc)
|
||||
mask = null
|
||||
|
||||
|
||||
/obj/machinery/suit_storage_unit/proc/dispense_magboots(mob/user as mob)
|
||||
if(!magboots)
|
||||
return
|
||||
|
||||
@@ -201,6 +201,9 @@
|
||||
return FALSE
|
||||
if(!Adjacent(user))
|
||||
return FALSE
|
||||
if(!allowed(user))
|
||||
to_chat(user, "<span class='warning'>Access denied!</span>")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/syndicatebomb/proc/activate()
|
||||
@@ -273,6 +276,7 @@
|
||||
/obj/machinery/syndicatebomb/self_destruct
|
||||
name = "self destruct device"
|
||||
desc = "Do not taunt. Warranty invalid if exposed to high temperature. Not suitable for agents under 3 years of age."
|
||||
req_access = list(access_syndicate)
|
||||
payload = /obj/item/bombcore/large
|
||||
can_unanchor = FALSE
|
||||
var/explosive_wall_group = EXPLOSIVE_WALL_GROUP_SYNDICATE_BASE // If set, this bomb will also cause explosive walls in the same group to explode
|
||||
|
||||
@@ -1132,7 +1132,6 @@
|
||||
product_ads = "Go save some lives!;The best stuff for your medbay.;Only the finest tools.;Natural chemicals!;This stuff saves lives.;Don't you want some?"
|
||||
icon_state = "wallmed"
|
||||
icon_deny = "wallmed-deny"
|
||||
req_access = list(access_medical)
|
||||
density = FALSE //It is wall-mounted, and thus, not dense. --Superxpdude
|
||||
products = list(/obj/item/stack/medical/bruise_pack = 2, /obj/item/stack/medical/ointment = 2, /obj/item/reagent_containers/hypospray/autoinjector = 4, /obj/item/healthanalyzer = 1)
|
||||
contraband = list(/obj/item/reagent_containers/syringe/charcoal = 4, /obj/item/reagent_containers/syringe/antiviral = 4, /obj/item/reagent_containers/food/pill/tox = 1)
|
||||
@@ -1143,7 +1142,6 @@
|
||||
desc = "Wall-mounted Medical Equipment dispenser."
|
||||
icon_state = "wallmed"
|
||||
icon_deny = "wallmed-deny"
|
||||
req_access = list(access_medical)
|
||||
density = FALSE //It is wall-mounted, and thus, not dense. --Superxpdude
|
||||
products = list(/obj/item/reagent_containers/hypospray/autoinjector = 5, /obj/item/reagent_containers/syringe/charcoal = 3, /obj/item/stack/medical/bruise_pack = 3,
|
||||
/obj/item/stack/medical/ointment = 3, /obj/item/healthanalyzer = 3)
|
||||
|
||||
@@ -171,10 +171,8 @@
|
||||
|
||||
/obj/mecha/working/ripley/proc/update_pressure()
|
||||
var/turf/T = get_turf(loc)
|
||||
var/datum/gas_mixture/environment = T.return_air()
|
||||
var/pressure = environment.return_pressure()
|
||||
|
||||
if(pressure < 20)
|
||||
if(lavaland_equipment_pressure_check(T))
|
||||
step_in = 3
|
||||
for(var/obj/item/mecha_parts/mecha_equipment/drill/drill in equipment)
|
||||
drill.equip_cooldown = initial(drill.equip_cooldown)/2
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
desc = "It's green and acidic. It looks like... <i>blood?</i>"
|
||||
icon = 'icons/effects/blood.dmi'
|
||||
basecolor = "#05EE05"
|
||||
bloodiness = MAX_SHOE_BLOODINESS
|
||||
bloodiness = BLOOD_AMOUNT_PER_DECAL
|
||||
blood_state = BLOOD_STATE_XENO
|
||||
|
||||
/obj/effect/decal/cleanable/blood/xeno/splatter
|
||||
|
||||
@@ -17,12 +17,22 @@ var/global/list/image/splatter_cache = list()
|
||||
blood_DNA = list()
|
||||
var/base_icon = 'icons/effects/blood.dmi'
|
||||
var/blood_state = BLOOD_STATE_HUMAN
|
||||
var/bloodiness = MAX_SHOE_BLOODINESS
|
||||
bloodiness = BLOOD_AMOUNT_PER_DECAL
|
||||
var/basecolor = "#A10808" // Color when wet.
|
||||
var/amount = 5
|
||||
var/dry_timer = 0
|
||||
var/off_floor = FALSE
|
||||
|
||||
|
||||
/obj/effect/decal/cleanable/blood/replace_decal(obj/effect/decal/cleanable/blood/C)
|
||||
if(C.blood_DNA)
|
||||
blood_DNA |= C.blood_DNA.Copy()
|
||||
if(bloodiness)
|
||||
if(C.bloodiness < MAX_SHOE_BLOODINESS)
|
||||
C.bloodiness += bloodiness
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/effect/decal/cleanable/blood/Initialize()
|
||||
. = ..()
|
||||
update_icon()
|
||||
@@ -87,46 +97,6 @@ var/global/list/image/splatter_cache = list()
|
||||
/obj/effect/decal/cleanable/blood/can_bloodcrawl_in()
|
||||
return TRUE
|
||||
|
||||
//Add "bloodiness" of this blood's type, to the human's shoes
|
||||
/obj/effect/decal/cleanable/blood/Crossed(atom/movable/O, oldloc)
|
||||
if(!off_floor && ishuman(O))
|
||||
var/mob/living/carbon/human/H = O
|
||||
var/obj/item/organ/external/l_foot = H.get_organ("l_foot")
|
||||
var/obj/item/organ/external/r_foot = H.get_organ("r_foot")
|
||||
var/hasfeet = TRUE
|
||||
if(!l_foot && !r_foot)
|
||||
hasfeet = FALSE
|
||||
if(H.shoes && blood_state && bloodiness)
|
||||
var/obj/item/clothing/shoes/S = H.shoes
|
||||
var/add_blood = 0
|
||||
if(bloodiness >= BLOOD_GAIN_PER_STEP)
|
||||
add_blood = BLOOD_GAIN_PER_STEP
|
||||
else
|
||||
add_blood = bloodiness
|
||||
bloodiness -= add_blood
|
||||
S.bloody_shoes[blood_state] = min(MAX_SHOE_BLOODINESS, S.bloody_shoes[blood_state] + add_blood)
|
||||
if(blood_DNA && blood_DNA.len)
|
||||
S.add_blood(H.blood_DNA, basecolor)
|
||||
S.blood_state = blood_state
|
||||
S.blood_color = basecolor
|
||||
update_icon()
|
||||
H.update_inv_shoes()
|
||||
else if(hasfeet && blood_state && bloodiness)//Or feet
|
||||
var/add_blood = 0
|
||||
if(bloodiness >= BLOOD_GAIN_PER_STEP)
|
||||
add_blood = BLOOD_GAIN_PER_STEP
|
||||
else
|
||||
add_blood = bloodiness
|
||||
bloodiness -= add_blood
|
||||
H.bloody_feet[blood_state] = min(MAX_SHOE_BLOODINESS, H.bloody_feet[blood_state] + add_blood)
|
||||
if(!H.feet_blood_DNA)
|
||||
H.feet_blood_DNA = list()
|
||||
H.blood_state = blood_state
|
||||
H.feet_blood_DNA |= blood_DNA.Copy()
|
||||
H.feet_blood_color = basecolor
|
||||
update_icon()
|
||||
H.update_inv_shoes()
|
||||
|
||||
/obj/effect/decal/cleanable/blood/splatter
|
||||
random_icon_states = list("mgibbl1", "mgibbl2", "mgibbl3", "mgibbl4", "mgibbl5")
|
||||
amount = 2
|
||||
@@ -191,6 +161,8 @@ var/global/list/image/splatter_cache = list()
|
||||
icon_state = "gibbl5"
|
||||
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6")
|
||||
no_clear = TRUE
|
||||
mergeable_decal = FALSE
|
||||
|
||||
var/fleshcolor = "#FFFFFF"
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/update_icon()
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
icon_state = "ash"
|
||||
anchored = TRUE
|
||||
scoop_reagents = list("ash" = 10)
|
||||
mergeable_decal = FALSE
|
||||
|
||||
/obj/effect/decal/cleanable/dirt
|
||||
name = "dirt"
|
||||
@@ -97,7 +98,8 @@
|
||||
gender = NEUTER
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "molten"
|
||||
|
||||
mergeable_decal = FALSE
|
||||
|
||||
/obj/effect/decal/cleanable/molten_object/large
|
||||
name = "big gooey grey mass"
|
||||
icon_state = "big_molten"
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
icon_state = "gib1"
|
||||
basecolor = "#030303"
|
||||
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7")
|
||||
bloodiness = MAX_SHOE_BLOODINESS
|
||||
bloodiness = BLOOD_AMOUNT_PER_DECAL
|
||||
mergeable_decal = FALSE
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/robot/can_bloodcrawl_in()
|
||||
return FALSE
|
||||
|
||||
@@ -30,6 +30,7 @@ var/global/list/image/fluidtrack_cache = list()
|
||||
|
||||
|
||||
/obj/effect/decal/cleanable/blood/footprints/Crossed(atom/movable/O, oldloc)
|
||||
..()
|
||||
if(ishuman(O))
|
||||
var/mob/living/carbon/human/H = O
|
||||
var/obj/item/clothing/shoes/S = H.shoes
|
||||
@@ -40,19 +41,22 @@ var/global/list/image/fluidtrack_cache = list()
|
||||
hasfeet = FALSE
|
||||
if(S && S.bloody_shoes[blood_state] && S.blood_color == basecolor)
|
||||
S.bloody_shoes[blood_state] = max(S.bloody_shoes[blood_state] - BLOOD_LOSS_PER_STEP, 0)
|
||||
entered_dirs |= H.dir
|
||||
if(!S.blood_DNA)
|
||||
S.blood_DNA = list()
|
||||
S.blood_DNA |= blood_DNA.Copy()
|
||||
if(!(entered_dirs & H.dir))
|
||||
entered_dirs |= H.dir
|
||||
update_icon()
|
||||
else if(hasfeet && H.bloody_feet[blood_state] && H.feet_blood_color == basecolor)//Or feet //This will need to be changed.
|
||||
H.bloody_feet[blood_state] = max(H.bloody_feet[blood_state] - BLOOD_LOSS_PER_STEP, 0)
|
||||
entered_dirs |= H.dir
|
||||
if(!H.feet_blood_DNA)
|
||||
H.feet_blood_DNA = list()
|
||||
H.feet_blood_DNA |= blood_DNA.Copy()
|
||||
update_icon()
|
||||
|
||||
if(!(entered_dirs & H.dir))
|
||||
entered_dirs |= H.dir
|
||||
update_icon()
|
||||
/obj/effect/decal/cleanable/blood/footprints/Uncrossed(atom/movable/O)
|
||||
..()
|
||||
if(ishuman(O))
|
||||
var/mob/living/carbon/human/H = O
|
||||
var/obj/item/clothing/shoes/S = H.shoes
|
||||
@@ -63,17 +67,20 @@ var/global/list/image/fluidtrack_cache = list()
|
||||
hasfeet = FALSE
|
||||
if(S && S.bloody_shoes[blood_state] && S.blood_color == basecolor)
|
||||
S.bloody_shoes[blood_state] = max(S.bloody_shoes[blood_state] - BLOOD_LOSS_PER_STEP, 0)
|
||||
exited_dirs |= H.dir
|
||||
if(!S.blood_DNA)
|
||||
S.blood_DNA = list()
|
||||
S.blood_DNA |= blood_DNA.Copy()
|
||||
if(!(exited_dirs & H.dir))
|
||||
exited_dirs |= H.dir
|
||||
update_icon()
|
||||
else if(hasfeet && H.bloody_feet[blood_state] && H.feet_blood_color == basecolor)//Or feet
|
||||
H.bloody_feet[blood_state] = max(H.bloody_feet[blood_state] - BLOOD_LOSS_PER_STEP, 0)
|
||||
exited_dirs |= H.dir
|
||||
if(!H.feet_blood_DNA)
|
||||
H.feet_blood_DNA = list()
|
||||
H.feet_blood_DNA |= blood_DNA.Copy()
|
||||
update_icon()
|
||||
if(!(exited_dirs & H.dir))
|
||||
exited_dirs |= H.dir
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/effect/decal/cleanable/blood/footprints/update_icon()
|
||||
@@ -108,14 +115,14 @@ var/global/list/image/fluidtrack_cache = list()
|
||||
if(ishuman(A))
|
||||
var/mob/living/carbon/human/H = A
|
||||
FP.blood_state = H.blood_state
|
||||
FP.bloodiness = H.bloody_feet[H.blood_state]
|
||||
FP.bloodiness = H.bloody_feet[H.blood_state] - BLOOD_LOSS_IN_SPREAD
|
||||
FP.basecolor = H.feet_blood_color
|
||||
if(H.blood_DNA)
|
||||
FP.blood_DNA = H.blood_DNA.Copy()
|
||||
else if(istype(A, /obj/item/clothing/shoes))
|
||||
var/obj/item/clothing/shoes/S = A
|
||||
FP.blood_state = S.blood_state
|
||||
FP.bloodiness = S.bloody_shoes[S.blood_state]
|
||||
FP.bloodiness = S.bloody_shoes[S.blood_state] - BLOOD_LOSS_IN_SPREAD
|
||||
FP.basecolor = S.blood_color
|
||||
if(S.blood_DNA)
|
||||
FP.blood_DNA = S.blood_DNA.Copy()
|
||||
@@ -123,3 +130,8 @@ var/global/list/image/fluidtrack_cache = list()
|
||||
FP.update_icon()
|
||||
|
||||
return FP
|
||||
|
||||
/obj/effect/decal/cleanable/blood/footprints/replace_decal(obj/effect/decal/cleanable/blood/footprints/C)
|
||||
if(blood_state != C.blood_state) //We only replace footprints of the same type as us
|
||||
return
|
||||
..()
|
||||
@@ -1,11 +1,65 @@
|
||||
/obj/effect/decal/cleanable
|
||||
anchored = TRUE
|
||||
var/list/random_icon_states = list()
|
||||
var/bloodiness = 0 //0-100, amount of blood in this decal, used for making footprints and affecting the alpha of bloody footprints
|
||||
var/mergeable_decal = TRUE //when two of these are on a same tile or do we need to merge them into just one?
|
||||
|
||||
/obj/effect/decal/cleanable/proc/replace_decal(obj/effect/decal/cleanable/C) // Returns true if we should give up in favor of the pre-existing decal
|
||||
if(mergeable_decal)
|
||||
return TRUE
|
||||
|
||||
//Add "bloodiness" of this blood's type, to the human's shoes
|
||||
//This is on /cleanable because fuck this ancient mess
|
||||
/obj/effect/decal/cleanable/blood/Crossed(atom/movable/O)
|
||||
..()
|
||||
if(!off_floor && ishuman(O))
|
||||
var/mob/living/carbon/human/H = O
|
||||
var/obj/item/organ/external/l_foot = H.get_organ("l_foot")
|
||||
var/obj/item/organ/external/r_foot = H.get_organ("r_foot")
|
||||
var/hasfeet = TRUE
|
||||
if(!l_foot && !r_foot)
|
||||
hasfeet = FALSE
|
||||
if(H.shoes && blood_state && bloodiness)
|
||||
var/obj/item/clothing/shoes/S = H.shoes
|
||||
var/add_blood = 0
|
||||
if(bloodiness >= BLOOD_GAIN_PER_STEP)
|
||||
add_blood = BLOOD_GAIN_PER_STEP
|
||||
else
|
||||
add_blood = bloodiness
|
||||
bloodiness -= add_blood
|
||||
S.bloody_shoes[blood_state] = min(MAX_SHOE_BLOODINESS, S.bloody_shoes[blood_state] + add_blood)
|
||||
if(blood_DNA && blood_DNA.len)
|
||||
S.add_blood(H.blood_DNA, basecolor)
|
||||
S.blood_state = blood_state
|
||||
S.blood_color = basecolor
|
||||
update_icon()
|
||||
H.update_inv_shoes()
|
||||
else if(hasfeet && blood_state && bloodiness)//Or feet
|
||||
var/add_blood = 0
|
||||
if(bloodiness >= BLOOD_GAIN_PER_STEP)
|
||||
add_blood = BLOOD_GAIN_PER_STEP
|
||||
else
|
||||
add_blood = bloodiness
|
||||
bloodiness -= add_blood
|
||||
H.bloody_feet[blood_state] = min(MAX_SHOE_BLOODINESS, H.bloody_feet[blood_state] + add_blood)
|
||||
if(!H.feet_blood_DNA)
|
||||
H.feet_blood_DNA = list()
|
||||
H.blood_state = blood_state
|
||||
H.feet_blood_DNA |= blood_DNA.Copy()
|
||||
H.feet_blood_color = basecolor
|
||||
update_icon()
|
||||
H.update_inv_shoes()
|
||||
|
||||
/obj/effect/decal/cleanable/proc/can_bloodcrawl_in()
|
||||
return FALSE
|
||||
|
||||
/obj/effect/decal/cleanable/New()
|
||||
/obj/effect/decal/cleanable/Initialize(mapload)
|
||||
. = ..()
|
||||
if(loc && isturf(loc))
|
||||
for(var/obj/effect/decal/cleanable/C in loc)
|
||||
if(C != src && C.type == type && !QDELETED(C))
|
||||
if(replace_decal(C))
|
||||
return INITIALIZE_HINT_QDEL
|
||||
if(random_icon_states && length(src.random_icon_states) > 0)
|
||||
src.icon_state = pick(src.random_icon_states)
|
||||
if(smooth)
|
||||
|
||||
@@ -67,6 +67,23 @@
|
||||
/obj/effect/mapping_helpers/no_lava
|
||||
icon_state = "no_lava"
|
||||
|
||||
/obj/effect/mapping_helpers/airlock
|
||||
layer = DOOR_HELPER_LAYER
|
||||
|
||||
/obj/effect/mapping_helpers/airlock/unres
|
||||
name = "airlock unresctricted side helper"
|
||||
icon_state = "airlock_unres_helper"
|
||||
|
||||
/obj/effect/mapping_helpers/airlock/unres/Initialize(mapload)
|
||||
if(!mapload)
|
||||
log_world("### MAP WARNING, [src] spawned outside of mapload!")
|
||||
return
|
||||
var/obj/machinery/door/airlock/airlock = locate(/obj/machinery/door/airlock) in src.loc
|
||||
if(airlock)
|
||||
airlock.unres_sides ^= dir
|
||||
else
|
||||
log_world("### MAP WARNING, [src] failed to find an airlock at [AREACOORD(src)]")
|
||||
..()
|
||||
/obj/effect/mapping_helpers/no_lava/New()
|
||||
var/turf/T = get_turf(src)
|
||||
T.flags |= NO_LAVA_GEN
|
||||
|
||||
@@ -141,7 +141,7 @@
|
||||
new /obj/effect/hallucination/delusion(victim.loc, victim, force_kind = "demon", duration = duration, skip_nearby = 0)
|
||||
|
||||
var/obj/item/twohanded/required/chainsaw/doomslayer/chainsaw = new(victim.loc)
|
||||
chainsaw.flags |= NODROP
|
||||
chainsaw.flags |= NODROP | DROPDEL
|
||||
victim.drop_l_hand()
|
||||
victim.drop_r_hand()
|
||||
victim.put_in_hands(chainsaw)
|
||||
|
||||
@@ -140,6 +140,20 @@
|
||||
..()
|
||||
animate(src, alpha = 0, time = duration)
|
||||
|
||||
/obj/effect/temp_visual/fire
|
||||
icon = 'icons/goonstation/effects/fire.dmi'
|
||||
icon_state = "3"
|
||||
light_range = LIGHT_RANGE_FIRE
|
||||
light_color = LIGHT_COLOR_FIRE
|
||||
duration = 10
|
||||
layer = MASSIVE_OBJ_LAYER
|
||||
alpha = 250
|
||||
blend_mode = BLEND_ADD
|
||||
|
||||
/obj/effect/temp_visual/fire/New(loc)
|
||||
color = heat2color(FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
|
||||
..()
|
||||
|
||||
/obj/effect/temp_visual/revenant
|
||||
name = "spooky lights"
|
||||
icon_state = "purplesparkles"
|
||||
@@ -289,4 +303,33 @@
|
||||
|
||||
/obj/effect/temp_visual/dir_setting/firing_effect/magic
|
||||
icon_state = "shieldsparkles"
|
||||
duration = 3
|
||||
duration = 3
|
||||
|
||||
/obj/effect/temp_visual/impact_effect
|
||||
icon_state = "impact_bullet"
|
||||
duration = 5
|
||||
|
||||
/obj/effect/temp_visual/impact_effect/Initialize(mapload, x, y)
|
||||
pixel_x = x
|
||||
pixel_y = y
|
||||
return ..()
|
||||
|
||||
/obj/effect/temp_visual/impact_effect/red_laser
|
||||
icon_state = "impact_laser"
|
||||
duration = 4
|
||||
|
||||
/obj/effect/temp_visual/impact_effect/blue_laser
|
||||
icon_state = "impact_laser_blue"
|
||||
duration = 4
|
||||
|
||||
/obj/effect/temp_visual/impact_effect/green_laser
|
||||
icon_state = "impact_laser_green"
|
||||
duration = 4
|
||||
|
||||
/obj/effect/temp_visual/impact_effect/purple_laser
|
||||
icon_state = "impact_laser_purple"
|
||||
duration = 4
|
||||
|
||||
/obj/effect/temp_visual/impact_effect/ion
|
||||
icon_state = "shieldsparkles"
|
||||
duration = 6
|
||||
@@ -87,6 +87,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d
|
||||
If index term exists and icon_override is not set, this sprite sheet will be used.
|
||||
*/
|
||||
var/list/sprite_sheets = null
|
||||
var/list/sprite_sheets_inhand = null //Used to override inhand items. Use a single .dmi and suffix the icon states inside with _l and _r for each hand.
|
||||
var/icon_override = null //Used to override hardcoded clothing dmis in human clothing proc.
|
||||
var/sprite_sheets_obj = null //Used to override hardcoded clothing inventory object dmis in human clothing proc.
|
||||
|
||||
@@ -331,7 +332,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/proc/hit_reaction(mob/living/carbon/human/owner, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
/obj/item/proc/hit_reaction(mob/living/carbon/human/owner, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK, atom/movable/AM)
|
||||
SEND_SIGNAL(src, COMSIG_ITEM_HIT_REACT, args)
|
||||
if(prob(final_block_chance))
|
||||
owner.visible_message("<span class='danger'>[owner] blocks [attack_text] with [src]!</span>")
|
||||
@@ -347,6 +348,8 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d
|
||||
A.Remove(user)
|
||||
if(flags & DROPDEL)
|
||||
qdel(src)
|
||||
if((flags & NODROP) && !(initial(flags) & NODROP)) //Remove NODROP is dropped
|
||||
flags &= ~NODROP
|
||||
in_inventory = FALSE
|
||||
SEND_SIGNAL(src, COMSIG_ITEM_DROPPED,user)
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
/obj/item/storage/pill_bottle/happy
|
||||
name = "Happy pills"
|
||||
desc = "Highly illegal drug. When you want to see the rainbow."
|
||||
wrapper_color = COLOR_PINK
|
||||
|
||||
/obj/item/storage/pill_bottle/happy/New()
|
||||
..()
|
||||
@@ -18,6 +19,7 @@
|
||||
/obj/item/storage/pill_bottle/zoom
|
||||
name = "Zoom pills"
|
||||
desc = "Highly illegal drug. Trade brain for speed."
|
||||
wrapper_color = COLOR_BLUE
|
||||
|
||||
/obj/item/storage/pill_bottle/zoom/New()
|
||||
..()
|
||||
@@ -49,15 +51,12 @@
|
||||
adulterants--
|
||||
reagents.add_reagent(pick_list("chemistry_tools.json", "CYBERPUNK_drug_adulterants"), 3)
|
||||
|
||||
|
||||
|
||||
/obj/item/storage/pill_bottle/random_drug_bottle
|
||||
name = "pill bottle (???)"
|
||||
desc = "Huh."
|
||||
allow_wrap = FALSE
|
||||
|
||||
/obj/item/storage/pill_bottle/random_drug_bottle/New()
|
||||
..()
|
||||
for(var/i in 1 to 5)
|
||||
new /obj/item/reagent_containers/food/pill/random_drugs(src)
|
||||
|
||||
|
||||
|
||||
96
code/game/objects/items/devices/enginepicker.dm
Normal file
96
code/game/objects/items/devices/enginepicker.dm
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
//////////
|
||||
Item meant to spawn one of the three (Tesla / Singularity / Supermatter) engines on-station at round-start.
|
||||
Should be found in the CE's office. Not access-restricted.
|
||||
//////////
|
||||
*/
|
||||
|
||||
/obj/item/enginepicker
|
||||
name = "Bluespace Engine Delivery Device"
|
||||
desc = "A per-station bluespace-based delivery system for a unique engine Engineering Department's choice. Only one option can be chosen. Device self-destructs on use."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "enginepicker"
|
||||
|
||||
var/list/list_enginebeacons = list()
|
||||
var/isactive = FALSE
|
||||
|
||||
/obj/item/enginepicker/attack_self(mob/living/carbon/user)
|
||||
if(usr.stat || !usr.canmove || usr.restrained())
|
||||
return
|
||||
|
||||
if(!isactive)
|
||||
isactive = TRUE //Self-attack spam exploit prevention
|
||||
else
|
||||
return
|
||||
|
||||
locatebeacons()
|
||||
var/default = null
|
||||
var/E = input("Select the station's Engine:", "[src]", default) as null|anything in list_enginebeacons
|
||||
if(E)
|
||||
processchoice(E, user)
|
||||
else
|
||||
isactive = FALSE
|
||||
return
|
||||
|
||||
//This proc re-assigns all of engine beacons in the global list to a local list.
|
||||
/obj/item/enginepicker/proc/locatebeacons()
|
||||
LAZYCLEARLIST(list_enginebeacons)
|
||||
for(var/obj/item/radio/beacon/engine/B in GLOB.engine_beacon_list)
|
||||
if(B && !QDELETED(B)) //This ensures that the input pop-up won't have any qdeleted beacons
|
||||
list_enginebeacons += B
|
||||
|
||||
//Spawns and logs / announces the appropriate engine based on the choice made
|
||||
/obj/item/enginepicker/proc/processchoice(var/obj/item/radio/beacon/engine/choice, mob/living/carbon/user)
|
||||
var/issuccessful = FALSE //Check for a successful choice
|
||||
var/engtype //Engine type
|
||||
var/G //Generator that will be spawned
|
||||
var/turf/T = get_turf(choice)
|
||||
|
||||
if(choice.enginetype.len > 1) //If the beacon has multiple engine types
|
||||
var/default = null
|
||||
var/E = input("You have selected a combined beacon, which option would you prefer?", "[src]", default) as null|anything in choice.enginetype
|
||||
if(E)
|
||||
engtype = E
|
||||
issuccessful = TRUE
|
||||
else
|
||||
isactive = FALSE
|
||||
return
|
||||
|
||||
if(!engtype) //If it has only one type
|
||||
engtype = DEFAULTPICK(choice.enginetype, null) //This should(?) account for a possibly scrambled list with a single entry
|
||||
switch(engtype)
|
||||
if(ENGTYPE_TESLA)
|
||||
G = /obj/machinery/the_singularitygen/tesla
|
||||
if(ENGTYPE_SING)
|
||||
G = /obj/machinery/the_singularitygen
|
||||
|
||||
if(G) //This can only be not-null if the switch operation was successful
|
||||
issuccessful = TRUE
|
||||
|
||||
if(issuccessful)
|
||||
clearturf(T) //qdels all items / gibs all mobs on the turf. Let's not have an SM shard spawn on top of a poor sod.
|
||||
new G(T) //Spawns the switch-selected engine on the chosen beacon's turf
|
||||
|
||||
var/ailist[] = list()
|
||||
for(var/mob/living/silicon/ai/A in GLOB.living_mob_list)
|
||||
ailist += A
|
||||
if(ailist.len)
|
||||
var/mob/living/silicon/ai/announcer = pick(ailist)
|
||||
announcer.say(";Engine delivery detected. Type: [engtype].") //Let's announce the terrible choice to everyone
|
||||
|
||||
visible_message("<span class='notice'>\The [src] begins to violently vibrate and hiss, then promptly disintegrates!</span>")
|
||||
qdel(src) //Self-destructs to prevent crew from spawning multiple engines.
|
||||
else
|
||||
visible_message("<span class='notice'>\The [src] buzzes! No beacon found or selected!</span>")
|
||||
isactive = FALSE
|
||||
return
|
||||
|
||||
//Deletes objects and mobs from the beacon's turf.
|
||||
/obj/item/enginepicker/proc/clearturf(var/turf/T)
|
||||
for(var/obj/item/I in T)
|
||||
I.visible_message("\The [I] gets crushed to dust!")
|
||||
qdel(I)
|
||||
|
||||
for(var/mob/living/M in T)
|
||||
M.visible_message("\The [M] gets obliterated!")
|
||||
M.gib()
|
||||
@@ -49,8 +49,7 @@
|
||||
/obj/item/radio/beacon/bacon //Probably a better way of doing this, I'm lazy.
|
||||
|
||||
/obj/item/radio/beacon/bacon/proc/digest_delay()
|
||||
spawn(600)
|
||||
qdel(src)
|
||||
QDEL_IN(src, 600)
|
||||
|
||||
// SINGULO BEACON SPAWNER
|
||||
/obj/item/radio/beacon/syndicate
|
||||
@@ -85,3 +84,23 @@
|
||||
playsound(src, 'sound/effects/pop.ogg', 100, 1, 1)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/item/radio/beacon/engine
|
||||
desc = "A label on it reads: <i>Warning: This device is used for transportation of high-density objects used for high-yield power generation. Stay away!</i>."
|
||||
anchored = 1 //Let's not move these around. Some folk might get the idea to use these for assassinations
|
||||
var/list/enginetype = list()
|
||||
|
||||
/obj/item/radio/beacon/engine/Initialize()
|
||||
LAZYADD(GLOB.engine_beacon_list, src)
|
||||
|
||||
/obj/item/radio/beacon/engine/tesling
|
||||
name = "Engine Beacon for Tesla and Singularity"
|
||||
enginetype = list(ENGTYPE_TESLA, ENGTYPE_SING)
|
||||
|
||||
/obj/item/radio/beacon/engine/tesla
|
||||
name = "Engine Beacon for Tesla"
|
||||
enginetype = list(ENGTYPE_TESLA)
|
||||
|
||||
/obj/item/radio/beacon/engine/sing
|
||||
name = "Engine Beacon for Singularity"
|
||||
enginetype = list(ENGTYPE_SING)
|
||||
@@ -4,6 +4,10 @@
|
||||
var/radio_desc = ""
|
||||
icon_state = "headset"
|
||||
item_state = "headset"
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/ears.dmi',
|
||||
"Vox Armalis" = 'icons/mob/species/armalis/ears.dmi'
|
||||
) //We read you loud and skree-er.
|
||||
materials = list(MAT_METAL=75)
|
||||
subspace_transmission = TRUE
|
||||
canhear_range = 0 // can't hear headsets from very far away
|
||||
|
||||
@@ -135,8 +135,13 @@ REAGENT SCANNER
|
||||
user.show_message("<span class='notice'>Key: Suffocation/Toxin/Burns/Brute</span>", 1)
|
||||
user.show_message("<span class='notice'>Body Temperature: ???</span>", 1)
|
||||
return
|
||||
user.visible_message("<span class='notice'>[user] has analyzed [M]'s vitals.</span>","<span class='notice'> You have analyzed [M]'s vitals.</span>")
|
||||
|
||||
user.visible_message("<span class='notice'>[user] has analyzed [M]'s vitals.</span>","<span class='notice'> You have analyzed [M]'s vitals.</span>")
|
||||
healthscan(user, M, mode, upgraded)
|
||||
add_fingerprint(user)
|
||||
|
||||
|
||||
proc/healthscan(mob/user, mob/living/M, mode = 1, upgraded = FALSE)
|
||||
if(!ishuman(M) || M.isSynthetic())
|
||||
//these sensors are designed for organic life
|
||||
user.show_message("<span class='notice'>Analyzing Results for ERROR:\n\t Overall Status: ERROR</span>")
|
||||
@@ -271,8 +276,9 @@ REAGENT SCANNER
|
||||
user.show_message("<span class='warning'>Subject's genes are showing minor signs of instability.</span>")
|
||||
else
|
||||
user.show_message("<span class='notice'>Subject's genes are stable.</span>")
|
||||
add_fingerprint(user)
|
||||
|
||||
/obj/item/healthanalyzer/attack_self(mob/user)
|
||||
toggle_mode()
|
||||
|
||||
/obj/item/healthanalyzer/verb/toggle_mode()
|
||||
set name = "Switch Verbosity"
|
||||
|
||||
@@ -123,6 +123,7 @@
|
||||
/obj/item/storage/pill_bottle/random_meds
|
||||
name = "unlabelled pillbottle"
|
||||
desc = "The sheer recklessness of this bottle's existence astounds you."
|
||||
allow_wrap = FALSE
|
||||
var/labelled = FALSE
|
||||
|
||||
/obj/item/storage/pill_bottle/random_meds/New()
|
||||
|
||||
@@ -133,12 +133,9 @@ var/global/list/datum/stack_recipe/sinew_recipes = list ( \
|
||||
can_strengthen_clothing = typecacheof(list(
|
||||
/obj/item/clothing/suit/space/hardsuit/mining,
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/mining,
|
||||
/obj/item/clothing/suit/space/eva/plasmaman/miner,
|
||||
/obj/item/clothing/head/helmet/space/eva/plasmaman/miner,
|
||||
/obj/item/clothing/suit/hooded/explorer,
|
||||
/obj/item/clothing/head/hooded/explorer,
|
||||
/obj/item/clothing/suit/space/eva/plasmaman/explorer,
|
||||
/obj/item/clothing/head/helmet/space/eva/plasmaman/explorer
|
||||
/obj/item/clothing/head/helmet/space/plasmaman/mining
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/animalhide/goliath_hide/afterattack(atom/target, mob/user, proximity_flag)
|
||||
|
||||
@@ -178,8 +178,12 @@ var/global/list/datum/stack_recipe/wood_recipes = list(
|
||||
new /datum/stack_recipe("wooden buckler", /obj/item/shield/riot/buckler, 20, time = 40),
|
||||
new /datum/stack_recipe("apiary", /obj/structure/beebox, 40, time = 50),
|
||||
new /datum/stack_recipe("honey frame", /obj/item/honey_frame, 5, time = 10),
|
||||
new /datum/stack_recipe("wooden bucket", /obj/item/reagent_containers/glass/bucket/wooden, 3, time = 10),
|
||||
new /datum/stack_recipe("rake", /obj/item/cultivator/rake, 5, time = 10),
|
||||
new /datum/stack_recipe("ore box", /obj/structure/ore_box, 4, time = 50, one_per_turf = TRUE, on_floor = TRUE),
|
||||
new /datum/stack_recipe("baseball bat", /obj/item/melee/baseball_bat, 5, time = 15),
|
||||
new /datum/stack_recipe("fermenting barrel", /obj/structure/fermenting_barrel, 30, time = 50)
|
||||
new /datum/stack_recipe("fermenting barrel", /obj/structure/fermenting_barrel, 30, time = 50),
|
||||
new /datum/stack_recipe("firebrand", /obj/item/match/firebrand, 2, time = 100)
|
||||
)
|
||||
|
||||
/obj/item/stack/sheet/wood
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
/obj/item/defibrillator/examine(mob/user)
|
||||
..(user)
|
||||
to_chat(user,"<span class='notice'>Ctrl-click to remove the paddles from the defibrillator.")
|
||||
to_chat(user, "<span class='notice'>Ctrl-click to remove the paddles from the defibrillator.</span>")
|
||||
|
||||
/obj/item/defibrillator/proc/update_power()
|
||||
if(bcell)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
icon = 'icons/obj/dice.dmi'
|
||||
icon_state = "dicebag"
|
||||
can_hold = list(/obj/item/dice)
|
||||
allow_wrap = FALSE
|
||||
|
||||
/obj/item/storage/pill_bottle/dice/New()
|
||||
..()
|
||||
|
||||
@@ -115,7 +115,8 @@
|
||||
throw_range = 6
|
||||
materials = list(MAT_METAL=12000)
|
||||
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
sharp = 1
|
||||
sharp = TRUE
|
||||
var/bayonet = FALSE //Can this be attached to a gun?
|
||||
|
||||
/obj/item/kitchen/knife/suicide_act(mob/user)
|
||||
user.visible_message(pick("<span class='suicide'>[user] is slitting [user.p_their()] wrists with the [src.name]! It looks like [user.p_theyre()] trying to commit suicide.</span>", \
|
||||
@@ -164,6 +165,7 @@
|
||||
throwforce = 20
|
||||
origin_tech = "materials=3;combat=4"
|
||||
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "cut")
|
||||
bayonet = TRUE
|
||||
|
||||
/obj/item/kitchen/knife/combat/survival
|
||||
name = "survival knife"
|
||||
|
||||
@@ -224,3 +224,13 @@
|
||||
var/mask_item = M.get_item_by_slot(slot_wear_mask)
|
||||
if(istype(mask_item, /obj/item/clothing/mask/cigarette))
|
||||
return mask_item
|
||||
|
||||
|
||||
/obj/item/match/firebrand
|
||||
name = "firebrand"
|
||||
desc = "An unlit firebrand. It makes you wonder why it's not just called a stick."
|
||||
smoketime = 20 //40 seconds
|
||||
|
||||
/obj/item/match/firebrand/New()
|
||||
..()
|
||||
matchignite()
|
||||
@@ -18,8 +18,10 @@
|
||||
burn_state = FLAMMABLE
|
||||
burntime = 20
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/back.dmi'
|
||||
)
|
||||
"Vox" = 'icons/mob/species/vox/back.dmi',
|
||||
"Vox Armalis" = 'icons/mob/species/armalis/back.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/back.dmi'
|
||||
) //For Armalis anything but this and the nitrogen tank will use the default backpack icon.
|
||||
|
||||
/obj/item/storage/backpack/attackby(obj/item/W as obj, mob/user as mob, params)
|
||||
playsound(src.loc, "rustle", 50, 1, -5)
|
||||
@@ -398,7 +400,7 @@
|
||||
new /obj/item/gun/projectile/automatic/shotgun/bulldog(src)
|
||||
new /obj/item/ammo_box/magazine/m12g(src)
|
||||
new /obj/item/ammo_box/magazine/m12g(src)
|
||||
new /obj/item/clothing/glasses/thermal/syndi(src)
|
||||
new /obj/item/clothing/glasses/chameleon/thermal(src)
|
||||
|
||||
/obj/item/storage/backpack/duffel/syndie/med/medicalbundle
|
||||
desc = "A large duffel bag containing a tactical medkit, a Donksoft machine gun and a big jumbo box of riot darts."
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
New()
|
||||
..()
|
||||
contents = list()
|
||||
new /obj/item/clothing/mask/breath(src)
|
||||
new /obj/item/clothing/mask/gas/explorer(src)
|
||||
new /obj/item/tank/emergency_oxygen/engi(src)
|
||||
new /obj/item/crowbar/red(src)
|
||||
new /obj/item/reagent_containers/hypospray/autoinjector(src)
|
||||
@@ -372,6 +372,20 @@
|
||||
new /obj/item/implantpad(src)
|
||||
new /obj/item/locator(src)
|
||||
|
||||
/obj/item/storage/box/minertracker
|
||||
name = "boxed tracking implant kit"
|
||||
desc = "For finding those who have died on the accursed lavaworld."
|
||||
icon_state = "implant"
|
||||
|
||||
/obj/item/storage/box/minertracker/New()
|
||||
..()
|
||||
new /obj/item/implantcase/tracking(src)
|
||||
new /obj/item/implantcase/tracking(src)
|
||||
new /obj/item/implantcase/tracking(src)
|
||||
new /obj/item/implanter(src)
|
||||
new /obj/item/implantpad(src)
|
||||
new /obj/item/locator(src)
|
||||
|
||||
/obj/item/storage/box/chemimp
|
||||
name = "chemical implant kit"
|
||||
desc = "Box of stuff used to implant chemicals."
|
||||
@@ -1082,15 +1096,6 @@
|
||||
new /obj/item/stock_parts/micro_laser/quadultra(src)
|
||||
new /obj/item/stock_parts/matter_bin/bluespace(src)
|
||||
|
||||
/obj/item/storage/box/mininghardsuit
|
||||
name = "Boxed Mining Hardsuit"
|
||||
desc = "Contains a mining hardsuit and helmet. For mining."
|
||||
|
||||
/obj/item/storage/box/mininghardsuit/New()
|
||||
..()
|
||||
new /obj/item/clothing/suit/space/hardsuit/mining(src)
|
||||
new /obj/item/clothing/head/helmet/space/hardsuit/mining(src)
|
||||
|
||||
/obj/item/storage/box/hug
|
||||
name = "box of hugs"
|
||||
desc = "A special box for sensitive people."
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
item_state = "briefcase"
|
||||
flags = CONDUCT
|
||||
hitsound = "swing_hit"
|
||||
force = 8.0
|
||||
force = 8
|
||||
throw_speed = 2
|
||||
throw_range = 4
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
@@ -20,10 +20,69 @@
|
||||
force = 10
|
||||
|
||||
/obj/item/storage/briefcase/sniperbundle/New()
|
||||
..()
|
||||
..()
|
||||
new /obj/item/gun/projectile/automatic/sniper_rifle/syndicate(src)
|
||||
new /obj/item/clothing/accessory/red(src)
|
||||
new /obj/item/clothing/under/syndicate/sniper(src)
|
||||
new /obj/item/ammo_box/magazine/sniper_rounds/soporific(src)
|
||||
new /obj/item/ammo_box/magazine/sniper_rounds/soporific(src)
|
||||
new /obj/item/suppressor/specialoffer(src)
|
||||
new /obj/item/suppressor/specialoffer(src)
|
||||
|
||||
/obj/item/storage/briefcase/false_bottomed
|
||||
max_w_class = WEIGHT_CLASS_SMALL
|
||||
max_combined_w_class = 10
|
||||
|
||||
var/busy_hunting = FALSE
|
||||
var/bottom_open = FALSE //is the false bottom open?
|
||||
var/obj/item/stored_item = null //what's in the false bottom. If it's a gun, we can fire it
|
||||
|
||||
/obj/item/storage/briefcase/false_bottomed/Destroy()
|
||||
if(stored_item)//since the stored_item isn't in the briefcase' contents we gotta remind the game to delete it here.
|
||||
QDEL_NULL(stored_item)
|
||||
return ..()
|
||||
|
||||
/obj/item/storage/briefcase/false_bottomed/afterattack(atom/A, mob/user, flag, params)
|
||||
..()
|
||||
if(stored_item && istype(stored_item, /obj/item/gun) && !Adjacent(A))
|
||||
var/obj/item/gun/stored_gun = stored_item
|
||||
stored_gun.afterattack(A, user, flag, params)
|
||||
|
||||
/obj/item/storage/briefcase/false_bottomed/attackby(var/obj/item/I, mob/user)
|
||||
if(isscrewdriver(I))
|
||||
if(!bottom_open && !busy_hunting)
|
||||
to_chat(user, "You begin to hunt around the rim of the [src]...")
|
||||
busy_hunting = TRUE
|
||||
if(do_after(user, 20, target = src))
|
||||
if(user)
|
||||
to_chat(user, "You pry open the false bottom!")
|
||||
bottom_open = TRUE
|
||||
busy_hunting = FALSE
|
||||
else if(bottom_open)
|
||||
to_chat(user, "You push the false bottom down and close it with a click[stored_item ? ", with the [stored_item] snugly inside." : "."]")
|
||||
bottom_open = FALSE
|
||||
else if(bottom_open)
|
||||
if(stored_item)
|
||||
to_chat(user, "<span class='warning'>There's already something in the false bottom!</span>")
|
||||
return
|
||||
if(I.w_class > WEIGHT_CLASS_NORMAL)
|
||||
to_chat(user, "<span class='warning'>The [I] is too big to fit in the false bottom!</span>")
|
||||
return
|
||||
if(!user.drop_item(I))
|
||||
user << "<span class='warning'>The [I] is stuck to your hands!</span>"
|
||||
return
|
||||
|
||||
stored_item = I
|
||||
max_w_class = WEIGHT_CLASS_NORMAL - stored_item.w_class
|
||||
I.forceMove(null) //null space here we go - to stop it showing up in the briefcase
|
||||
to_chat(user, "You place the [I] into the false bottom of the briefcase.")
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/storage/briefcase/false_bottomed/attack_hand(mob/user)
|
||||
if(bottom_open && stored_item)
|
||||
user.put_in_hands(stored_item)
|
||||
to_chat(user, "You pull out the [stored_item] from the [src]'s false bottom.")
|
||||
stored_item = null
|
||||
max_w_class = initial(max_w_class)
|
||||
else
|
||||
return ..()
|
||||
|
||||
@@ -254,10 +254,21 @@
|
||||
var/applying_meds = FALSE //To Prevent spam clicking and generating runtimes from apply a deleting pill multiple times.
|
||||
var/rapid_intake_message = "unscrews the cap on the pill bottle and begins dumping the entire contents down their throat!"
|
||||
var/rapid_post_instake_message = "downs the entire bottle of pills in one go!"
|
||||
var/allow_wrap = TRUE
|
||||
var/wrapper_color = null
|
||||
|
||||
/obj/item/storage/pill_bottle/New()
|
||||
..()
|
||||
base_name = name
|
||||
if(allow_wrap)
|
||||
apply_wrap()
|
||||
|
||||
/obj/item/storage/pill_bottle/proc/apply_wrap()
|
||||
if(wrapper_color)
|
||||
overlays.Cut()
|
||||
var/image/I = image(icon, "pillbottle_wrap")
|
||||
I.color = wrapper_color
|
||||
overlays += I
|
||||
|
||||
/obj/item/storage/pill_bottle/attack(mob/M, mob/user)
|
||||
if(iscarbon(M) && contents.len)
|
||||
@@ -274,6 +285,9 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/storage/pill_bottle/ert
|
||||
wrapper_color = COLOR_MAROON
|
||||
|
||||
/obj/item/storage/pill_bottle/ert/New()
|
||||
..()
|
||||
new /obj/item/reagent_containers/food/pill/salicylic(src)
|
||||
@@ -319,15 +333,18 @@
|
||||
|
||||
/obj/item/storage/pill_bottle/patch_pack
|
||||
name = "Patch Pack"
|
||||
desc = "It's a container for storing medical patches."
|
||||
icon_state = "patch_pack"
|
||||
can_hold = list(/obj/item/reagent_containers/food/pill/patch)
|
||||
cant_hold = list()
|
||||
rapid_intake_message = "flips the lid of the Patch Pack open and begins rapidly stamping patches on themselves!"
|
||||
rapid_post_instake_message = "stamps the entire contents of the Patch Pack all over their entire body!"
|
||||
allow_wrap = FALSE
|
||||
|
||||
/obj/item/storage/pill_bottle/charcoal
|
||||
name = "Pill bottle (Charcoal)"
|
||||
desc = "Contains pills used to counter toxins."
|
||||
wrapper_color = COLOR_GREEN
|
||||
|
||||
New()
|
||||
..()
|
||||
@@ -342,6 +359,7 @@
|
||||
/obj/item/storage/pill_bottle/painkillers
|
||||
name = "Pill Bottle (Salicylic Acid)"
|
||||
desc = "Contains various pills for minor pain relief."
|
||||
wrapper_color = COLOR_RED
|
||||
|
||||
/obj/item/storage/pill_bottle/painkillers/New()
|
||||
..()
|
||||
@@ -354,8 +372,11 @@
|
||||
new /obj/item/reagent_containers/food/pill/salicylic(src)
|
||||
new /obj/item/reagent_containers/food/pill/salicylic(src)
|
||||
|
||||
/obj/item/storage/pill_bottle/fakedeath
|
||||
allow_wrap = FALSE
|
||||
|
||||
/obj/item/storage/pill_bottle/fakedeath/New()
|
||||
..()
|
||||
new /obj/item/reagent_containers/food/pill/fakedeath(src)
|
||||
new /obj/item/reagent_containers/food/pill/fakedeath(src)
|
||||
new /obj/item/reagent_containers/food/pill/fakedeath(src)
|
||||
new /obj/item/reagent_containers/food/pill/fakedeath(src)
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
if("thief") // 40TC
|
||||
new /obj/item/gun/energy/kinetic_accelerator/crossbow(src) // 12TC
|
||||
new /obj/item/chameleon(src) // 8TC
|
||||
new /obj/item/clothing/glasses/thermal/syndi(src) // 6TC
|
||||
new /obj/item/clothing/glasses/chameleon/thermal(src) // 6TC
|
||||
new /obj/item/clothing/gloves/color/black/thief(src) // 6TC
|
||||
new /obj/item/card/id/syndicate(src) // 2TC
|
||||
new /obj/item/clothing/shoes/chameleon/noslip(src) // 2TC
|
||||
@@ -108,7 +108,7 @@
|
||||
new /obj/item/gun/projectile/automatic/sniper_rifle/syndicate/penetrator(src) // 16TC
|
||||
new /obj/item/ammo_box/magazine/sniper_rounds/penetrator(src) // 5TC
|
||||
new /obj/item/ammo_box/magazine/sniper_rounds/soporific(src) // 3TC
|
||||
new /obj/item/clothing/glasses/thermal/syndi/sunglasses(src) // 6TC
|
||||
new /obj/item/clothing/glasses/chameleon/thermal(src) // 6TC
|
||||
new /obj/item/clothing/gloves/combat(src) // 0 TC
|
||||
new /obj/item/clothing/under/suit_jacket/really_black(src) // 0 TC
|
||||
new /obj/item/clothing/suit/storage/lawyer/blackjacket/armored(src) // 0TC
|
||||
@@ -136,36 +136,14 @@
|
||||
|
||||
/obj/item/storage/box/syndie_kit/hardsuit
|
||||
name = "Boxed Blood Red Suit and Helmet"
|
||||
can_hold = list(/obj/item/clothing/suit/space/hardsuit/syndi, /obj/item/clothing/head/helmet/space/hardsuit/syndi, /obj/item/tank/emergency_oxygen/syndi, /obj/item/clothing/mask/gas/syndicate)
|
||||
can_hold = list(/obj/item/clothing/suit/space/hardsuit/syndi, /obj/item/tank/emergency_oxygen/syndi, /obj/item/clothing/mask/gas/syndicate)
|
||||
max_w_class = WEIGHT_CLASS_NORMAL
|
||||
|
||||
/obj/item/storage/box/syndie_kit/hardsuit/New()
|
||||
..()
|
||||
new /obj/item/clothing/suit/space/hardsuit/syndi(src)
|
||||
new /obj/item/clothing/head/helmet/space/hardsuit/syndi(src)
|
||||
new /obj/item/clothing/mask/gas/syndicate(src)
|
||||
new /obj/item/tank/emergency_oxygen/syndi(src)
|
||||
return
|
||||
|
||||
/obj/item/storage/box/syndie_kit/elite_hardsuit
|
||||
name = "Boxed Elite Syndicate Hardsuit and Helmet"
|
||||
can_hold = list(/obj/item/clothing/suit/space/hardsuit/syndi/elite, /obj/item/clothing/head/helmet/space/hardsuit/syndi/elite)
|
||||
max_w_class = WEIGHT_CLASS_NORMAL
|
||||
|
||||
/obj/item/storage/box/syndie_kit/elite_hardsuit/New()
|
||||
..()
|
||||
new /obj/item/clothing/suit/space/hardsuit/syndi/elite(src)
|
||||
new /obj/item/clothing/head/helmet/space/hardsuit/syndi/elite(src)
|
||||
|
||||
/obj/item/storage/box/syndie_kit/shielded_hardsuit
|
||||
name = "Boxed Shielded Syndicate Hardsuit and Helmet"
|
||||
can_hold = list(/obj/item/clothing/suit/space/hardsuit/shielded/syndi, /obj/item/clothing/head/helmet/space/hardsuit/shielded/syndi)
|
||||
max_w_class = WEIGHT_CLASS_BULKY
|
||||
|
||||
/obj/item/storage/box/syndie_kit/shielded_hardsuit/New()
|
||||
..()
|
||||
new /obj/item/clothing/suit/space/hardsuit/shielded/syndi(src)
|
||||
new /obj/item/clothing/head/helmet/space/hardsuit/shielded/syndi(src)
|
||||
|
||||
/obj/item/storage/box/syndie_kit/conversion
|
||||
name = "box (CK)"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user