diff --git a/.travis.yml b/.travis.yml index c58b11584f..754b84c374 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,8 +4,8 @@ sudo: false env: global: - - BYOND_MAJOR="511" - - BYOND_MINOR="1381" + - BYOND_MAJOR="512" + - BYOND_MINOR="1414" - MACRO_COUNT=4 matrix: - TEST_DEFINE="MAP_TEST" TEST_FILE="code/_map_tests.dm" RUN="0" diff --git a/README.md b/README.md index ea59760d95..49de2b6eaf 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # polaris -[Forums](http://ss13polaris.com/forums/) - [Wiki](http://ss13polaris.com/wiki/doku.php) +[Forums](https://forum.ss13polaris.com/) - [Wiki](http://wiki.ss13polaris.com/) Polaris is a fork of the Baystation12 code branch for the game Spacestation13. diff --git a/code/ATMOSPHERICS/_atmos_setup.dm b/code/ATMOSPHERICS/_atmos_setup.dm index b8c3e91150..09bb291180 100644 --- a/code/ATMOSPHERICS/_atmos_setup.dm +++ b/code/ATMOSPHERICS/_atmos_setup.dm @@ -15,11 +15,6 @@ #define PIPE_COLOR_BLACK "#444444" #define PIPE_COLOR_PURPLE "#5c1ec0" -#define CONNECT_TYPE_REGULAR 1 -#define CONNECT_TYPE_SUPPLY 2 -#define CONNECT_TYPE_SCRUBBER 4 -#define CONNECT_TYPE_HE 8 - var/global/list/pipe_colors = list("grey" = PIPE_COLOR_GREY, "red" = PIPE_COLOR_RED, "blue" = PIPE_COLOR_BLUE, "cyan" = PIPE_COLOR_CYAN, "green" = PIPE_COLOR_GREEN, "yellow" = PIPE_COLOR_YELLOW, "black" = PIPE_COLOR_BLACK, "purple" = PIPE_COLOR_PURPLE) /proc/pipe_color_lookup(var/color) diff --git a/code/ATMOSPHERICS/_atmospherics_helpers.dm b/code/ATMOSPHERICS/_atmospherics_helpers.dm index 6fc2b923dd..b5cd6486b9 100644 --- a/code/ATMOSPHERICS/_atmospherics_helpers.dm +++ b/code/ATMOSPHERICS/_atmospherics_helpers.dm @@ -455,3 +455,40 @@ var/sink_pressure = sink.return_pressure() return (source_pressure - sink_pressure)/(R_IDEAL_GAS_EQUATION * (source.temperature/source_volume + sink.temperature/sink_volume)) + +// +// Debugging helper procs +// + +/proc/atmos_piping_layer_str(piping_layer) + switch(piping_layer) + if(PIPING_LAYER_SUPPLY) + return "SUPPLY" + if(PIPING_LAYER_REGULAR) + return "REGULAR" + if(PIPING_LAYER_SCRUBBER) + return "SCRUBBER" + +/proc/atmos_pipe_flags_str(pipe_flags) + var/list/dat = list() + if(pipe_flags & PIPING_ALL_LAYER) + dat += "ALL_LAYER" + if(pipe_flags & PIPING_ONE_PER_TURF) + dat += "ONE_PER_TURF" + if(pipe_flags & PIPING_DEFAULT_LAYER_ONLY) + dat += "DEFAULT_LAYER_ONLY" + if(pipe_flags & PIPING_CARDINAL_AUTONORMALIZE) + dat += "CARDINAL_AUTONORMALIZE" + return dat.Join("|") + +/proc/atmos_connect_types_str(connect_types) + var/list/dat = list() + if(connect_types & CONNECT_TYPE_REGULAR) + dat += "REGULAR" + if(connect_types & CONNECT_TYPE_SUPPLY) + dat += "SUPPLY" + if(connect_types & CONNECT_TYPE_SCRUBBER) + dat += "SCRUBBER" + if(connect_types & CONNECT_TYPE_HE) + dat += "HE" + return dat.Join("|") diff --git a/code/ATMOSPHERICS/atmospherics.dm b/code/ATMOSPHERICS/atmospherics.dm index 0502f2b8f8..8d3aa08493 100644 --- a/code/ATMOSPHERICS/atmospherics.dm +++ b/code/ATMOSPHERICS/atmospherics.dm @@ -17,10 +17,15 @@ Pipelines + Other Objects -> Pipe network var/nodealert = 0 var/power_rating //the maximum amount of power the machine can use to do work, affects how powerful the machine is, in Watts - layer = 2.4 //under wires with their 2.44 + layer = PIPES_LAYER + plane = PLATING_PLANE + var/pipe_flags = PIPING_DEFAULT_LAYER_ONLY // Allow other layers by exception basis. var/connect_types = CONNECT_TYPE_REGULAR + var/piping_layer = PIPING_LAYER_DEFAULT // This will replace icon_connect_type at some point ~Leshana var/icon_connect_type = "" //"-supply" or "-scrubbers" + var/construction_type = null // Type path of the pipe item when this is deconstructed. + var/pipe_state // icon_state as a pipe item var/initialize_directions = 0 var/pipe_color @@ -29,11 +34,12 @@ Pipelines + Other Objects -> Pipe network var/obj/machinery/atmospherics/node1 var/obj/machinery/atmospherics/node2 -/obj/machinery/atmospherics/New() +/obj/machinery/atmospherics/New(loc, newdir) ..() if(!icon_manager) icon_manager = new() - + if(!isnull(newdir)) + set_dir(newdir) if(!pipe_color) pipe_color = color color = null @@ -46,6 +52,15 @@ Pipelines + Other Objects -> Pipe network /obj/machinery/atmospherics/proc/init_dir() return +// Get ALL initialize_directions - Some types (HE pipes etc) combine two vars together for this. +/obj/machinery/atmospherics/proc/get_init_dirs() + return initialize_directions + +// Get the direction each node is facing to connect. +// It now returns as a list so it can be fetched nicely, each entry corresponds to node of same number. +/obj/machinery/atmospherics/proc/get_node_connect_dirs() + return + // Initializes nodes by looking at neighboring atmospherics machinery to connect to. // When we're being constructed at runtime, atmos_init() is called by the construction code. // When dynamically loading a map atmos_init is called by the maploader (initTemplateBounds proc) @@ -54,6 +69,14 @@ Pipelines + Other Objects -> Pipe network /obj/machinery/atmospherics/proc/atmos_init() return +/** Check if target is an acceptable target to connect as a node from this machine. */ +/obj/machinery/atmospherics/proc/can_be_node(obj/machinery/atmospherics/target, node_num) + return (target.initialize_directions & get_dir(target,src)) && check_connectable(target) && target.check_connectable(src) + +/** Check if this machine is willing to connect with the target machine. */ +/obj/machinery/atmospherics/proc/check_connectable(obj/machinery/atmospherics/target) + return (src.connect_types & target.connect_types) + /obj/machinery/atmospherics/attackby(atom/A, mob/user as mob) if(istype(A, /obj/item/device/pipe_painter)) return @@ -77,12 +100,6 @@ Pipelines + Other Objects -> Pipe network else return 0 -obj/machinery/atmospherics/proc/check_connect_types(obj/machinery/atmospherics/atmos1, obj/machinery/atmospherics/atmos2) - return (atmos1.connect_types & atmos2.connect_types) - -/obj/machinery/atmospherics/proc/check_connect_types_construction(obj/machinery/atmospherics/atmos1, obj/item/pipe/pipe2) - return (atmos1.connect_types & pipe2.connect_types) - /obj/machinery/atmospherics/proc/check_icon_cache(var/safety = 0) if(!istype(icon_manager)) if(!safety) //to prevent infinite loops @@ -141,4 +158,60 @@ obj/machinery/atmospherics/proc/check_connect_types(obj/machinery/atmospherics/a var/datum/gas_mixture/env_air = loc.return_air() if((int_air.return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE) return 0 - return 1 \ No newline at end of file + return 1 + +// Deconstruct into a pipe item. +/obj/machinery/atmospherics/proc/deconstruct() + if(QDELETED(src)) + return + if(construction_type) + var/obj/item/pipe/I = new construction_type(loc, null, null, src) + I.setPipingLayer(piping_layer) + transfer_fingerprints_to(I) + qdel(src) + +// Return a list of nodes which we should call atmos_init() and build_network() during on_construction() +/obj/machinery/atmospherics/proc/get_neighbor_nodes_for_init() + return null + +// Called on construction (i.e from pipe item) but not on initialization +/obj/machinery/atmospherics/proc/on_construction(obj_color, set_layer) + pipe_color = obj_color + setPipingLayer(set_layer) + // TODO - M.connect_types = src.connect_types - Or otherwise copy from item? Or figure it out from piping layer? + var/turf/T = get_turf(src) + level = !T.is_plating() ? 2 : 1 + atmos_init() + if(QDELETED(src)) + return // TODO - Eventually should get rid of the need for this. + build_network() + var/list/nodes = get_neighbor_nodes_for_init() + for(var/obj/machinery/atmospherics/A in nodes) + A.atmos_init() + A.build_network() + // TODO - Should we do src.build_network() before or after the nodes? + // We've historically done before, but /tg does after. TODO research if there is a difference. + +// This sets our piping layer. Hopefully its cool. +/obj/machinery/atmospherics/proc/setPipingLayer(new_layer) + if(pipe_flags & (PIPING_DEFAULT_LAYER_ONLY|PIPING_ALL_LAYER)) + new_layer = PIPING_LAYER_DEFAULT + piping_layer = new_layer + // Do it the Polaris way + switch(piping_layer) + if(PIPING_LAYER_SCRUBBER) + icon_state = "[icon_state]-scrubbers" + connect_types = CONNECT_TYPE_SCRUBBER + layer = 2.38 + icon_connect_type = "-scrubbers" + if(PIPING_LAYER_SUPPLY) + icon_state = "[icon_state]-supply" + connect_types = CONNECT_TYPE_SUPPLY + layer = 2.39 + icon_connect_type = "-supply" + if(pipe_flags & PIPING_ALL_LAYER) + connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SUPPLY|CONNECT_TYPE_SCRUBBER + // Or if we were to do it the TG way... + // pixel_x = PIPE_PIXEL_OFFSET_X(piping_layer) + // pixel_y = PIPE_PIXEL_OFFSET_Y(piping_layer) + // layer = initial(layer) + PIPE_LAYER_OFFSET(piping_layer) diff --git a/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm b/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm index 6e6662f39c..4698c613a9 100644 --- a/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm +++ b/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm @@ -30,6 +30,9 @@ initialize_directions = EAST|WEST // Housekeeping and pipe network stuff below +/obj/machinery/atmospherics/binary/get_neighbor_nodes_for_init() + return list(node1, node2) + /obj/machinery/atmospherics/binary/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference) if(reference == node1) network1 = new_network @@ -64,17 +67,8 @@ var/node2_connect = dir var/node1_connect = turn(dir, 180) - for(var/obj/machinery/atmospherics/target in get_step(src,node1_connect)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node1 = target - break - - for(var/obj/machinery/atmospherics/target in get_step(src,node2_connect)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node2 = target - break + STANDARD_ATMOS_CHOOSE_NODE(1, node1_connect) + STANDARD_ATMOS_CHOOSE_NODE(2, node2_connect) update_icon() update_underlays() diff --git a/code/ATMOSPHERICS/components/binary_devices/circulator.dm b/code/ATMOSPHERICS/components/binary_devices/circulator.dm index 68ce37d088..ff1089e6f8 100644 --- a/code/ATMOSPHERICS/components/binary_devices/circulator.dm +++ b/code/ATMOSPHERICS/components/binary_devices/circulator.dm @@ -9,6 +9,7 @@ icon = 'icons/obj/pipes.dmi' icon_state = "circ-off" anchored = 0 + pipe_flags = PIPING_DEFAULT_LAYER_ONLY|PIPING_ONE_PER_TURF var/kinetic_efficiency = 0.04 //combined kinetic and kinetic-to-electric efficiency var/volume_ratio = 0.2 diff --git a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm index 840d2bdf8b..d696aad039 100644 --- a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm @@ -24,6 +24,7 @@ idle_power_usage = 150 //internal circuitry, friction losses and stuff power_rating = 7500 //7500 W ~ 10 HP + pipe_flags = PIPING_ALL_LAYER connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SUPPLY|CONNECT_TYPE_SCRUBBER //connects to regular, supply and scrubbers pipes var/pump_direction = 1 //0 = siphoning, 1 = releasing diff --git a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm index b4f25459c1..c08c82f6b9 100644 --- a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm +++ b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm @@ -5,6 +5,8 @@ /obj/machinery/atmospherics/binary/passive_gate icon = 'icons/atmos/passive_gate.dmi' icon_state = "map" + construction_type = /obj/item/pipe/directional + pipe_state = "passivegate" level = 1 name = "pressure regulator" @@ -257,8 +259,7 @@ "\The [user] unfastens \the [src].", \ "You have unfastened \the [src].", \ "You hear ratchet.") - new /obj/item/pipe(loc, make_from=src) - qdel(src) + deconstruct() #undef REGULATE_NONE #undef REGULATE_INPUT diff --git a/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm b/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm index b8c7883796..a7127a4dc6 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm @@ -139,6 +139,9 @@ src.set_dir(turn(src.dir, 90)) //Goddamn copypaste from binary base class because atmospherics machinery API is not damn flexible + get_neighbor_nodes_for_init() + return list(node1, node2) + network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference) if(reference == node1) network1 = new_network diff --git a/code/ATMOSPHERICS/components/binary_devices/pump.dm b/code/ATMOSPHERICS/components/binary_devices/pump.dm index 6320ddf8a3..a89b1c5659 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pump.dm @@ -15,6 +15,8 @@ Thus, the two variables affect pump operation are set in New(): /obj/machinery/atmospherics/binary/pump icon = 'icons/atmos/pump.dmi' icon_state = "map_off" + construction_type = /obj/item/pipe/directional + pipe_state = "pump" level = 1 name = "gas pump" @@ -236,5 +238,4 @@ Thus, the two variables affect pump operation are set in New(): "\The [user] unfastens \the [src].", \ "You have unfastened \the [src].", \ "You hear ratchet.") - new /obj/item/pipe(loc, make_from=src) - qdel(src) + deconstruct() diff --git a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm index 42b02282cc..b4493a1566 100644 --- a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm @@ -1,6 +1,8 @@ /obj/machinery/atmospherics/binary/pump/high_power icon = 'icons/atmos/volume_pump.dmi' icon_state = "map_off" + construction_type = /obj/item/pipe/directional + pipe_state = "volumepump" level = 1 name = "high power gas pump" diff --git a/code/ATMOSPHERICS/components/omni_devices/filter.dm b/code/ATMOSPHERICS/components/omni_devices/filter.dm index 8710623dfd..57889c463e 100644 --- a/code/ATMOSPHERICS/components/omni_devices/filter.dm +++ b/code/ATMOSPHERICS/components/omni_devices/filter.dm @@ -4,6 +4,7 @@ /obj/machinery/atmospherics/omni/atmos_filter name = "omni gas filter" icon_state = "map_filter" + pipe_state = "omni_filter" var/list/atmos_filters = new() var/datum/omni_port/input diff --git a/code/ATMOSPHERICS/components/omni_devices/mixer.dm b/code/ATMOSPHERICS/components/omni_devices/mixer.dm index 6340397870..c833b5bb2a 100644 --- a/code/ATMOSPHERICS/components/omni_devices/mixer.dm +++ b/code/ATMOSPHERICS/components/omni_devices/mixer.dm @@ -4,6 +4,7 @@ /obj/machinery/atmospherics/omni/mixer name = "omni gas mixer" icon_state = "map_mixer" + pipe_state = "omni_mixer" use_power = 1 idle_power_usage = 150 //internal circuitry, friction losses and stuff diff --git a/code/ATMOSPHERICS/components/omni_devices/omni_base.dm b/code/ATMOSPHERICS/components/omni_devices/omni_base.dm index 7416a5bfc4..e7ec93852d 100644 --- a/code/ATMOSPHERICS/components/omni_devices/omni_base.dm +++ b/code/ATMOSPHERICS/components/omni_devices/omni_base.dm @@ -7,6 +7,7 @@ icon_state = "base" use_power = 1 initialize_directions = 0 + construction_type = /obj/item/pipe/quaternary level = 1 var/configuring = 0 @@ -93,8 +94,7 @@ "\The [user] unfastens \the [src].", \ "You have unfastened \the [src].", \ "You hear a ratchet.") - new /obj/item/pipe(loc, make_from=src) - qdel(src) + deconstruct() /obj/machinery/atmospherics/omni/can_unwrench() var/int_pressure = 0 @@ -222,6 +222,11 @@ // Housekeeping and pipe network stuff below +/obj/machinery/atmospherics/omni/get_neighbor_nodes_for_init() + var/list/neighbor_nodes = list() + for(var/datum/omni_port/P in ports) + neighbor_nodes += P.node + return neighbor_nodes /obj/machinery/atmospherics/omni/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference) for(var/datum/omni_port/P in ports) @@ -252,10 +257,9 @@ if(P.node || P.mode == 0) continue for(var/obj/machinery/atmospherics/target in get_step(src, P.dir)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - P.node = target - break + if(can_be_node(target, 1)) + P.node = target + break for(var/datum/omni_port/P in ports) P.update = 1 diff --git a/code/ATMOSPHERICS/components/portables_connector.dm b/code/ATMOSPHERICS/components/portables_connector.dm index 6911288c93..7dca3f52d4 100644 --- a/code/ATMOSPHERICS/components/portables_connector.dm +++ b/code/ATMOSPHERICS/components/portables_connector.dm @@ -7,6 +7,9 @@ dir = SOUTH initialize_directions = SOUTH + construction_type = /obj/item/pipe/directional + pipe_state = "connector" + pipe_flags = PIPING_DEFAULT_LAYER_ONLY|PIPING_ONE_PER_TURF var/obj/machinery/portable_atmospherics/connected_device @@ -47,6 +50,9 @@ return 1 // Housekeeping and pipe network stuff below +/obj/machinery/atmospherics/portables_connector/get_neighbor_nodes_for_init() + return list(node) + /obj/machinery/atmospherics/portables_connector/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference) if(reference == node) network = new_network @@ -77,10 +83,9 @@ var/node_connect = dir for(var/obj/machinery/atmospherics/target in get_step(src,node_connect)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node = target - break + if(can_be_node(target, 1)) + node = target + break update_icon() update_underlays() @@ -146,5 +151,4 @@ "\The [user] unfastens \the [src].", \ "You have unfastened \the [src].", \ "You hear a ratchet.") - new /obj/item/pipe(loc, make_from=src) - qdel(src) + deconstruct() diff --git a/code/ATMOSPHERICS/components/trinary_devices/filter.dm b/code/ATMOSPHERICS/components/trinary_devices/filter.dm index 10708f4185..49cb05e9af 100755 --- a/code/ATMOSPHERICS/components/trinary_devices/filter.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/filter.dm @@ -1,6 +1,8 @@ /obj/machinery/atmospherics/trinary/atmos_filter icon = 'icons/atmos/filter.dmi' icon_state = "map" + construction_type = /obj/item/pipe/trinary/flippable + pipe_state = "filter" density = 0 level = 1 @@ -59,7 +61,7 @@ . = ..() /obj/machinery/atmospherics/trinary/atmos_filter/update_icon() - if(istype(src, /obj/machinery/atmospherics/trinary/atmos_filter/m_filter)) + if(mirrored) icon_state = "m" else icon_state = "" @@ -72,31 +74,6 @@ icon_state += "off" use_power = 0 -/obj/machinery/atmospherics/trinary/atmos_filter/update_underlays() - if(..()) - underlays.Cut() - var/turf/T = get_turf(src) - if(!istype(T)) - return - - add_underlay(T, node1, turn(dir, -180)) - - if(istype(src, /obj/machinery/atmospherics/trinary/atmos_filter/m_filter)) - add_underlay(T, node2, turn(dir, 90)) - else - add_underlay(T, node2, turn(dir, -90)) - - add_underlay(T, node3, dir) - -/obj/machinery/atmospherics/trinary/atmos_filter/hide(var/i) - update_underlays() - -/obj/machinery/atmospherics/trinary/atmos_filter/power_change() - var/old_stat = stat - ..() - if(old_stat != stat) - update_icon() - /obj/machinery/atmospherics/trinary/atmos_filter/process() ..() @@ -133,24 +110,6 @@ if(frequency) set_frequency(frequency) -/obj/machinery/atmospherics/trinary/atmos_filter/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) - if (!istype(W, /obj/item/weapon/wrench)) - return ..() - if(!can_unwrench()) - to_chat(user, "You cannot unwrench \the [src], it too exerted due to internal pressure.") - add_fingerprint(user) - return 1 - playsound(src, W.usesound, 50, 1) - to_chat(user, "You begin to unfasten \the [src]...") - if (do_after(user, 40 * W.toolspeed)) - user.visible_message( \ - "\The [user] unfastens \the [src].", \ - "You have unfastened \the [src].", \ - "You hear a ratchet.") - new /obj/item/pipe(loc, make_from=src) - qdel(src) - - /obj/machinery/atmospherics/trinary/atmos_filter/attack_hand(user as mob) // -- TLE if(..()) return @@ -235,44 +194,11 @@ */ return +// +// Mirrored Orientation - Flips the output dir to opposite side from normal. +// /obj/machinery/atmospherics/trinary/atmos_filter/m_filter icon_state = "mmap" - dir = SOUTH initialize_directions = SOUTH|NORTH|EAST - -obj/machinery/atmospherics/trinary/atmos_filter/m_filter/init_dir() - switch(dir) - if(NORTH) - initialize_directions = WEST|NORTH|SOUTH - if(SOUTH) - initialize_directions = SOUTH|EAST|NORTH - if(EAST) - initialize_directions = EAST|WEST|NORTH - if(WEST) - initialize_directions = WEST|SOUTH|EAST - -/obj/machinery/atmospherics/trinary/atmos_filter/m_filter/atmos_init() - if(node1 && node2 && node3) return - - var/node1_connect = turn(dir, -180) - var/node2_connect = turn(dir, 90) - var/node3_connect = dir - - for(var/obj/machinery/atmospherics/target in get_step(src,node1_connect)) - if(target.initialize_directions & get_dir(target,src)) - node1 = target - break - - for(var/obj/machinery/atmospherics/target in get_step(src,node2_connect)) - if(target.initialize_directions & get_dir(target,src)) - node2 = target - break - - for(var/obj/machinery/atmospherics/target in get_step(src,node3_connect)) - if(target.initialize_directions & get_dir(target,src)) - node3 = target - break - - update_icon() - update_underlays() + mirrored = TRUE diff --git a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm index 5739a57895..84c5d49daa 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm @@ -1,6 +1,8 @@ /obj/machinery/atmospherics/trinary/mixer icon = 'icons/atmos/mixer.dmi' icon_state = "map" + construction_type = /obj/item/pipe/trinary/flippable + pipe_state = "mixer" density = 0 level = 1 @@ -20,10 +22,10 @@ //node 3 is the outlet, nodes 1 & 2 are intakes /obj/machinery/atmospherics/trinary/mixer/update_icon(var/safety = 0) - if(istype(src, /obj/machinery/atmospherics/trinary/mixer/m_mixer)) - icon_state = "m" - else if(istype(src, /obj/machinery/atmospherics/trinary/mixer/t_mixer)) + if(tee) icon_state = "t" + else if(mirrored) + icon_state = "m" else icon_state = "" @@ -35,34 +37,6 @@ icon_state += "off" use_power = 0 -/obj/machinery/atmospherics/trinary/mixer/update_underlays() - if(..()) - underlays.Cut() - var/turf/T = get_turf(src) - if(!istype(T)) - return - - if(istype(src, /obj/machinery/atmospherics/trinary/mixer/t_mixer)) - add_underlay(T, node1, turn(dir, -90)) - else - add_underlay(T, node1, turn(dir, -180)) - - if(istype(src, /obj/machinery/atmospherics/trinary/mixer/m_mixer) || istype(src, /obj/machinery/atmospherics/trinary/mixer/t_mixer)) - add_underlay(T, node2, turn(dir, 90)) - else - add_underlay(T, node2, turn(dir, -90)) - - add_underlay(T, node3, dir) - -/obj/machinery/atmospherics/trinary/mixer/hide(var/i) - update_underlays() - -/obj/machinery/atmospherics/trinary/mixer/power_change() - var/old_stat = stat - ..() - if(old_stat != stat) - update_icon() - /obj/machinery/atmospherics/trinary/mixer/New() ..() air1.volume = ATMOS_DEFAULT_VOLUME_MIXER @@ -103,23 +77,6 @@ return 1 -/obj/machinery/atmospherics/trinary/mixer/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) - if (!istype(W, /obj/item/weapon/wrench)) - return ..() - if(!can_unwrench()) - to_chat(user, "You cannot unwrench \the [src], it too exerted due to internal pressure.") - add_fingerprint(user) - return 1 - playsound(src, W.usesound, 50, 1) - to_chat(user, "You begin to unfasten \the [src]...") - if (do_after(user, 40 * W.toolspeed)) - user.visible_message( \ - "\The [user] unfastens \the [src].", \ - "You have unfastened \the [src].", \ - "You hear ratchet.") - new /obj/item/pipe(loc, make_from=src) - qdel(src) - /obj/machinery/atmospherics/trinary/mixer/attack_hand(user as mob) if(..()) return @@ -173,92 +130,22 @@ src.updateUsrDialog() return +// +// "T" Orientation - Inputs are on oposite sides instead of adjacent +// obj/machinery/atmospherics/trinary/mixer/t_mixer icon_state = "tmap" - + construction_type = /obj/item/pipe/trinary // Can't flip a "T", its symmetrical + pipe_state = "t_mixer" dir = SOUTH initialize_directions = SOUTH|EAST|WEST + tee = TRUE - //node 3 is the outlet, nodes 1 & 2 are intakes - -obj/machinery/atmospherics/trinary/mixer/t_mixer/init_dir() - switch(dir) - if(NORTH) - initialize_directions = EAST|NORTH|WEST - if(SOUTH) - initialize_directions = SOUTH|WEST|EAST - if(EAST) - initialize_directions = EAST|NORTH|SOUTH - if(WEST) - initialize_directions = WEST|NORTH|SOUTH - -obj/machinery/atmospherics/trinary/mixer/t_mixer/atmos_init() - ..() - if(node1 && node2 && node3) return - - var/node1_connect = turn(dir, -90) - var/node2_connect = turn(dir, 90) - var/node3_connect = dir - - for(var/obj/machinery/atmospherics/target in get_step(src,node1_connect)) - if(target.initialize_directions & get_dir(target,src)) - node1 = target - break - - for(var/obj/machinery/atmospherics/target in get_step(src,node2_connect)) - if(target.initialize_directions & get_dir(target,src)) - node2 = target - break - - for(var/obj/machinery/atmospherics/target in get_step(src,node3_connect)) - if(target.initialize_directions & get_dir(target,src)) - node3 = target - break - - update_icon() - update_underlays() - -obj/machinery/atmospherics/trinary/mixer/m_mixer +// +// Mirrored Orientation - Flips the output dir to opposite side from normal. +// +/obj/machinery/atmospherics/trinary/mixer/m_mixer icon_state = "mmap" - dir = SOUTH initialize_directions = SOUTH|NORTH|EAST - - //node 3 is the outlet, nodes 1 & 2 are intakes - -obj/machinery/atmospherics/trinary/mixer/m_mixer/init_dir() - switch(dir) - if(NORTH) - initialize_directions = WEST|NORTH|SOUTH - if(SOUTH) - initialize_directions = SOUTH|EAST|NORTH - if(EAST) - initialize_directions = EAST|WEST|NORTH - if(WEST) - initialize_directions = WEST|SOUTH|EAST - -obj/machinery/atmospherics/trinary/mixer/m_mixer/atmos_init() - ..() - if(node1 && node2 && node3) return - - var/node1_connect = turn(dir, -180) - var/node2_connect = turn(dir, 90) - var/node3_connect = dir - - for(var/obj/machinery/atmospherics/target in get_step(src,node1_connect)) - if(target.initialize_directions & get_dir(target,src)) - node1 = target - break - - for(var/obj/machinery/atmospherics/target in get_step(src,node2_connect)) - if(target.initialize_directions & get_dir(target,src)) - node2 = target - break - - for(var/obj/machinery/atmospherics/target in get_step(src,node3_connect)) - if(target.initialize_directions & get_dir(target,src)) - node3 = target - break - - update_icon() - update_underlays() + mirrored = TRUE diff --git a/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm b/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm index 807523fe7a..0a68f74c71 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm @@ -2,6 +2,10 @@ dir = SOUTH initialize_directions = SOUTH|NORTH|WEST use_power = 0 + pipe_flags = PIPING_DEFAULT_LAYER_ONLY|PIPING_ONE_PER_TURF + + var/mirrored = FALSE + var/tee = FALSE var/datum/gas_mixture/air1 var/datum/gas_mixture/air2 @@ -25,17 +29,48 @@ air3.volume = 200 /obj/machinery/atmospherics/trinary/init_dir() - switch(dir) - if(NORTH) - initialize_directions = EAST|NORTH|SOUTH - if(SOUTH) - initialize_directions = SOUTH|WEST|NORTH - if(EAST) - initialize_directions = EAST|WEST|SOUTH - if(WEST) - initialize_directions = WEST|NORTH|EAST + initialize_directions = get_initialize_directions_trinary(dir, mirrored, tee) + +/obj/machinery/atmospherics/trinary/update_underlays() + if(..()) + underlays.Cut() + var/turf/T = get_turf(src) + if(!istype(T)) + return + var/list/node_connects = get_node_connect_dirs() + add_underlay(T, node1, node_connects[1]) + add_underlay(T, node2, node_connects[2]) + add_underlay(T, node3, node_connects[3]) + +/obj/machinery/atmospherics/trinary/hide(var/i) + update_underlays() + +/obj/machinery/atmospherics/trinary/power_change() + var/old_stat = stat + . = ..() + if(old_stat != stat) + update_icon() + +/obj/machinery/atmospherics/trinary/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) + if (!istype(W, /obj/item/weapon/wrench)) + return ..() + if(!can_unwrench()) + to_chat(user, "You cannot unwrench \the [src], it too exerted due to internal pressure.") + add_fingerprint(user) + return 1 + playsound(src, W.usesound, 50, 1) + to_chat(user, "You begin to unfasten \the [src]...") + if (do_after(user, 40 * W.toolspeed)) + user.visible_message( \ + "\The [user] unfastens \the [src].", \ + "You have unfastened \the [src].", \ + "You hear a ratchet.") + deconstruct() // Housekeeping and pipe network stuff below +/obj/machinery/atmospherics/trinary/get_neighbor_nodes_for_init() + return list(node1, node2, node3) + /obj/machinery/atmospherics/trinary/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference) if(reference == node1) network1 = new_network @@ -70,30 +105,20 @@ node2 = null node3 = null +// Get the direction each node is facing to connect. +// It now returns as a list so it can be fetched nicely, each entry corresponds to node of same number. +/obj/machinery/atmospherics/trinary/get_node_connect_dirs() + return get_node_connect_dirs_trinary(dir, mirrored, tee) + /obj/machinery/atmospherics/trinary/atmos_init() if(node1 && node2 && node3) return - var/node1_connect = turn(dir, -180) - var/node2_connect = turn(dir, -90) - var/node3_connect = dir + var/list/node_connects = get_node_connect_dirs() - for(var/obj/machinery/atmospherics/target in get_step(src,node1_connect)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node1 = target - break - - for(var/obj/machinery/atmospherics/target in get_step(src,node2_connect)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node2 = target - break - for(var/obj/machinery/atmospherics/target in get_step(src,node3_connect)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node3 = target - break + STANDARD_ATMOS_CHOOSE_NODE(1, node_connects[1]) + STANDARD_ATMOS_CHOOSE_NODE(2, node_connects[2]) + STANDARD_ATMOS_CHOOSE_NODE(3, node_connects[3]) update_icon() update_underlays() @@ -166,4 +191,58 @@ update_underlays() - return null \ No newline at end of file + return null + +// Trinary init_dir() logic in a separate proc so it can be referenced from "trinary-ish" places like T-Valves +// TODO - Someday refactor those places under atmospherics/trinary +/proc/get_initialize_directions_trinary(var/dir, var/mirrored = FALSE, var/tee = FALSE) + if(tee) + switch(dir) + if(NORTH) + return EAST|NORTH|WEST + if(SOUTH) + return SOUTH|WEST|EAST + if(EAST) + return EAST|NORTH|SOUTH + if(WEST) + return WEST|NORTH|SOUTH + else if(mirrored) + switch(dir) + if(NORTH) + return WEST|NORTH|SOUTH + if(SOUTH) + return SOUTH|EAST|NORTH + if(EAST) + return EAST|WEST|NORTH + if(WEST) + return WEST|SOUTH|EAST + else + switch(dir) + if(NORTH) + return EAST|NORTH|SOUTH + if(SOUTH) + return SOUTH|WEST|NORTH + if(EAST) + return EAST|WEST|SOUTH + if(WEST) + return WEST|NORTH|EAST + +// Trinary get_node_connect_dirs() logic in a separate proc so it can be referenced from "trinary-ish" places like T-Valves +/proc/get_node_connect_dirs_trinary(var/dir, var/mirrored = FALSE, var/tee = FALSE) + var/node1_connect + var/node2_connect + var/node3_connect + + if(tee) + node1_connect = turn(dir, -90) + node2_connect = turn(dir, 90) + node3_connect = dir + else if(mirrored) + node1_connect = turn(dir, 180) + node2_connect = turn(dir, 90) + node3_connect = dir + else + node1_connect = turn(dir, 180) + node2_connect = turn(dir, -90) + node3_connect = dir + return list(node1_connect, node2_connect, node3_connect) diff --git a/code/ATMOSPHERICS/components/tvalve.dm b/code/ATMOSPHERICS/components/tvalve.dm index 9f7e80f97f..b65c615174 100644 --- a/code/ATMOSPHERICS/components/tvalve.dm +++ b/code/ATMOSPHERICS/components/tvalve.dm @@ -1,6 +1,8 @@ /obj/machinery/atmospherics/tvalve icon = 'icons/atmos/tvalve.dmi' icon_state = "map_tvalve0" + construction_type = /obj/item/pipe/trinary/flippable + pipe_state = "mtvalve" name = "manual switching valve" desc = "A pipe valve" @@ -11,6 +13,9 @@ var/state = 0 // 0 = go straight, 1 = go to side + var/mirrored = FALSE + var/tee = FALSE // Note: Tee not actually supported for T-valves: no sprites + // like a trinary component, node1 is input, node2 is side output, node3 is straight output var/obj/machinery/atmospherics/node3 @@ -24,9 +29,9 @@ /obj/machinery/atmospherics/tvalve/update_icon(animation) if(animation) - flick("tvalve[src.state][!src.state]",src) + flick("tvalve[mirrored ? "m" : ""][src.state][!src.state]",src) else - icon_state = "tvalve[state]" + icon_state = "tvalve[mirrored ? "m" : ""][state]" /obj/machinery/atmospherics/tvalve/update_underlays() if(..()) @@ -34,28 +39,19 @@ var/turf/T = get_turf(src) if(!istype(T)) return - add_underlay(T, node1, turn(dir, -180)) - - if(istype(src, /obj/machinery/atmospherics/tvalve/mirrored)) - add_underlay(T, node2, turn(dir, 90)) - else - add_underlay(T, node2, turn(dir, -90)) - - add_underlay(T, node3, dir) + var/list/node_connects = get_node_connect_dirs() + add_underlay(T, node1, node_connects[1]) + add_underlay(T, node2, node_connects[2]) + add_underlay(T, node3, node_connects[3]) /obj/machinery/atmospherics/tvalve/hide(var/i) update_underlays() /obj/machinery/atmospherics/tvalve/init_dir() - switch(dir) - if(NORTH) - initialize_directions = SOUTH|NORTH|EAST - if(SOUTH) - initialize_directions = NORTH|SOUTH|WEST - if(EAST) - initialize_directions = WEST|EAST|SOUTH - if(WEST) - initialize_directions = EAST|WEST|NORTH + initialize_directions = get_initialize_directions_trinary(dir, mirrored) + +/obj/machinery/atmospherics/tvalve/get_neighbor_nodes_for_init() + return list(node1, node2, node3) /obj/machinery/atmospherics/tvalve/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference) if(reference == node1) @@ -179,30 +175,18 @@ return +/obj/machinery/atmospherics/tvalve/get_node_connect_dirs() + return get_node_connect_dirs_trinary(dir, mirrored) + /obj/machinery/atmospherics/tvalve/atmos_init() - var/node1_dir - var/node2_dir - var/node3_dir + if(node1 && node2 && node3) + return - node1_dir = turn(dir, 180) - node2_dir = turn(dir, -90) - node3_dir = dir + var/list/node_connects = get_node_connect_dirs() - for(var/obj/machinery/atmospherics/target in get_step(src,node1_dir)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node1 = target - break - for(var/obj/machinery/atmospherics/target in get_step(src,node2_dir)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node2 = target - break - for(var/obj/machinery/atmospherics/target in get_step(src,node3_dir)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node3 = target - break + STANDARD_ATMOS_CHOOSE_NODE(1, node_connects[1]) + STANDARD_ATMOS_CHOOSE_NODE(2, node_connects[2]) + STANDARD_ATMOS_CHOOSE_NODE(3, node_connects[3]) update_icon() update_underlays() @@ -272,6 +256,7 @@ name = "digital switching valve" desc = "A digitally controlled valve." icon = 'icons/atmos/digital_tvalve.dmi' + pipe_state = "dtvalve" var/frequency = 0 var/id = null @@ -294,7 +279,7 @@ /obj/machinery/atmospherics/tvalve/digital/update_icon() ..() if(!powered()) - icon_state = "tvalvenopower" + icon_state = "tvalve[mirrored ? "m" : ""]nopower" /obj/machinery/atmospherics/tvalve/digital/attack_ai(mob/user as mob) return src.attack_hand(user) @@ -358,125 +343,20 @@ "\The [user] unfastens \the [src].", \ "You have unfastened \the [src].", \ "You hear a ratchet.") - new /obj/item/pipe(loc, make_from=src) - qdel(src) + deconstruct() /obj/machinery/atmospherics/tvalve/mirrored icon_state = "map_tvalvem0" + mirrored = TRUE /obj/machinery/atmospherics/tvalve/mirrored/bypass icon_state = "map_tvalvem1" state = 1 -/obj/machinery/atmospherics/tvalve/mirrored/init_dir() - switch(dir) - if(NORTH) - initialize_directions = SOUTH|NORTH|WEST - if(SOUTH) - initialize_directions = NORTH|SOUTH|EAST - if(EAST) - initialize_directions = WEST|EAST|NORTH - if(WEST) - initialize_directions = EAST|WEST|SOUTH +/obj/machinery/atmospherics/tvalve/digital/mirrored + icon_state = "map_tvalvem0" + mirrored = TRUE -/obj/machinery/atmospherics/tvalve/mirrored/atmos_init() - var/node1_dir - var/node2_dir - var/node3_dir - - node1_dir = turn(dir, 180) - node2_dir = turn(dir, 90) - node3_dir = dir - - for(var/obj/machinery/atmospherics/target in get_step(src,node1_dir)) - if(target.initialize_directions & get_dir(target,src)) - node1 = target - break - for(var/obj/machinery/atmospherics/target in get_step(src,node2_dir)) - if(target.initialize_directions & get_dir(target,src)) - node2 = target - break - for(var/obj/machinery/atmospherics/target in get_step(src,node3_dir)) - if(target.initialize_directions & get_dir(target,src)) - node3 = target - break - - update_icon() - update_underlays() - -/obj/machinery/atmospherics/tvalve/mirrored/update_icon(animation) - if(animation) - flick("tvalvem[src.state][!src.state]",src) - else - icon_state = "tvalvem[state]" - -/obj/machinery/atmospherics/tvalve/mirrored/digital // can be controlled by AI - name = "digital switching valve" - desc = "A digitally controlled valve." - icon = 'icons/atmos/digital_tvalve.dmi' - - var/frequency = 0 - var/id = null - var/datum/radio_frequency/radio_connection - -/obj/machinery/atmospherics/tvalve/mirrored/digital/Destroy() - unregister_radio(src, frequency) - . = ..() - -/obj/machinery/atmospherics/tvalve/mirrored/digital/bypass +/obj/machinery/atmospherics/tvalve/digital/mirrored/bypass icon_state = "map_tvalvem1" state = 1 - -/obj/machinery/atmospherics/tvalve/mirrored/digital/power_change() - var/old_stat = stat - ..() - if(old_stat != stat) - update_icon() - -/obj/machinery/atmospherics/tvalve/mirrored/digital/update_icon() - ..() - if(!powered()) - icon_state = "tvalvemnopower" - -/obj/machinery/atmospherics/tvalve/mirrored/digital/attack_ai(mob/user as mob) - return src.attack_hand(user) - -/obj/machinery/atmospherics/tvalve/mirrored/digital/attack_hand(mob/user as mob) - if(!powered()) - return - if(!src.allowed(user)) - to_chat(user, "Access denied.") - return - ..() - -//Radio remote control -eh? - -/obj/machinery/atmospherics/tvalve/mirrored/digital/proc/set_frequency(new_frequency) - radio_controller.remove_object(src, frequency) - frequency = new_frequency - if(frequency) - radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA) - -/obj/machinery/atmospherics/tvalve/mirrored/digital/initialize() - . = ..() - if(frequency) - set_frequency(frequency) - -/obj/machinery/atmospherics/tvalve/mirrored/digital/receive_signal(datum/signal/signal) - if(!signal.data["tag"] || (signal.data["tag"] != id)) - return 0 - - switch(signal.data["command"]) - if("valve_open") - if(!state) - go_to_side() - - if("valve_close") - if(state) - go_straight() - - if("valve_toggle") - if(state) - go_straight() - else - go_to_side() diff --git a/code/ATMOSPHERICS/components/unary/cold_sink.dm b/code/ATMOSPHERICS/components/unary/cold_sink.dm index 36ae824fa7..b211f57f39 100644 --- a/code/ATMOSPHERICS/components/unary/cold_sink.dm +++ b/code/ATMOSPHERICS/components/unary/cold_sink.dm @@ -38,18 +38,15 @@ var/node_connect = dir for(var/obj/machinery/atmospherics/target in get_step(src, node_connect)) - if(target.initialize_directions & get_dir(target, src)) + if(can_be_node(target, 1)) node = target break - //copied from pipe construction code since heaters/freezers don't use fittings and weren't doing this check - this all really really needs to be refactored someday. - //check that there are no incompatible pipes/machinery in our own location - for(var/obj/machinery/atmospherics/M in src.loc) - if(M != src && (M.initialize_directions & node_connect) && M.check_connect_types(M,src)) // matches at least one direction on either type of pipe & same connection type - node = null - break + if(check_for_obstacles()) + node = null - update_icon() + if(node) + update_icon() /obj/machinery/atmospherics/unary/freezer/update_icon() if(node) diff --git a/code/ATMOSPHERICS/components/unary/heat_exchanger.dm b/code/ATMOSPHERICS/components/unary/heat_exchanger.dm index 8a7fba153a..ed4010f81e 100644 --- a/code/ATMOSPHERICS/components/unary/heat_exchanger.dm +++ b/code/ATMOSPHERICS/components/unary/heat_exchanger.dm @@ -2,6 +2,7 @@ icon = 'icons/obj/atmospherics/heat_exchanger.dmi' icon_state = "intact" + pipe_state = "heunary" density = 1 name = "Heat Exchanger" @@ -83,5 +84,4 @@ "\The [user] unfastens \the [src].", \ "You have unfastened \the [src].", \ "You hear a ratchet.") - new /obj/item/pipe(loc, make_from=src) - qdel(src) + deconstruct() diff --git a/code/ATMOSPHERICS/components/unary/heat_source.dm b/code/ATMOSPHERICS/components/unary/heat_source.dm index 8ca4626ee6..45a9962e06 100644 --- a/code/ATMOSPHERICS/components/unary/heat_source.dm +++ b/code/ATMOSPHERICS/components/unary/heat_source.dm @@ -39,18 +39,15 @@ //check that there is something to connect to for(var/obj/machinery/atmospherics/target in get_step(src, node_connect)) - if(target.initialize_directions & get_dir(target, src)) + if(can_be_node(target, 1)) node = target break - //copied from pipe construction code since heaters/freezers don't use fittings and weren't doing this check - this all really really needs to be refactored someday. - //check that there are no incompatible pipes/machinery in our own location - for(var/obj/machinery/atmospherics/M in src.loc) - if(M != src && (M.initialize_directions & node_connect) && M.check_connect_types(M,src)) // matches at least one direction on either type of pipe & same connection type - node = null - break + if(check_for_obstacles()) + node = null - update_icon() + if(node) + update_icon() /obj/machinery/atmospherics/unary/heater/update_icon() diff --git a/code/ATMOSPHERICS/components/unary/outlet_injector.dm b/code/ATMOSPHERICS/components/unary/outlet_injector.dm index 7c52cea895..4a9403a64b 100644 --- a/code/ATMOSPHERICS/components/unary/outlet_injector.dm +++ b/code/ATMOSPHERICS/components/unary/outlet_injector.dm @@ -5,7 +5,7 @@ /obj/machinery/atmospherics/unary/outlet_injector icon = 'icons/atmos/injector.dmi' icon_state = "map_injector" - layer = 3 + pipe_state = "injector" name = "air injector" desc = "Passively injects air into its surroundings. Has a valve attached to it that can control flow rate." diff --git a/code/ATMOSPHERICS/components/unary/unary_base.dm b/code/ATMOSPHERICS/components/unary/unary_base.dm index 77b135cdc5..12d6822ad4 100644 --- a/code/ATMOSPHERICS/components/unary/unary_base.dm +++ b/code/ATMOSPHERICS/components/unary/unary_base.dm @@ -1,6 +1,8 @@ /obj/machinery/atmospherics/unary dir = SOUTH initialize_directions = SOUTH + construction_type = /obj/item/pipe/directional + pipe_flags = PIPING_DEFAULT_LAYER_ONLY|PIPING_ONE_PER_TURF //layer = TURF_LAYER+0.1 var/datum/gas_mixture/air_contents @@ -21,6 +23,9 @@ initialize_directions = dir // Housekeeping and pipe network stuff below +/obj/machinery/atmospherics/unary/get_neighbor_nodes_for_init() + return list(node) + /obj/machinery/atmospherics/unary/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference) if(reference == node) network = new_network @@ -48,10 +53,9 @@ var/node_connect = dir for(var/obj/machinery/atmospherics/target in get_step(src,node_connect)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node = target - break + if(can_be_node(target, 1)) + node = target + break update_icon() update_underlays() @@ -93,4 +97,20 @@ update_icon() update_underlays() - return null \ No newline at end of file + return null + +// Check if there are any other atmos machines in the same turf that will block this machine from initializing. +// Intended for use when a frame-constructable machine (i.e. not made from pipe fittings) wants to wrench down and connect. +// Returns TRUE if something is blocking, FALSE if its okay to continue. +/obj/machinery/atmospherics/unary/proc/check_for_obstacles() + for(var/obj/machinery/atmospherics/M in loc) + if(M == src) continue + if((M.pipe_flags & pipe_flags & PIPING_ONE_PER_TURF)) //Only one dense/requires density object per tile, eg connectors/cryo/heater/coolers. + visible_message("\The [src]'s cannot be connected, something is hogging the tile!") + return TRUE + if((M.piping_layer != piping_layer) && !((M.pipe_flags | flags) & PIPING_ALL_LAYER)) // Pipes on different layers can't block each other unless they are ALL_LAYER + continue + if(M.get_init_dirs() & get_init_dirs()) // matches at least one direction on either type of pipe + visible_message("\The [src]'s connector can't be connected, there is already a pipe at that location!") + return TRUE + return FALSE diff --git a/code/ATMOSPHERICS/components/unary/vent_pump.dm b/code/ATMOSPHERICS/components/unary/vent_pump.dm index b5449fe737..054507b4e1 100644 --- a/code/ATMOSPHERICS/components/unary/vent_pump.dm +++ b/code/ATMOSPHERICS/components/unary/vent_pump.dm @@ -10,6 +10,7 @@ /obj/machinery/atmospherics/unary/vent_pump icon = 'icons/atmos/vent_pump.dmi' icon_state = "map_vent" + pipe_state = "uvent" name = "Air Vent" desc = "Has a valve and pump attached to it" @@ -410,8 +411,7 @@ "\The [user] unfastens \the [src].", \ "You have unfastened \the [src].", \ "You hear a ratchet.") - new /obj/item/pipe(loc, make_from=src) - qdel(src) + deconstruct() #undef DEFAULT_PRESSURE_DELTA diff --git a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm index ad78f5a1f4..09b5fde7c1 100644 --- a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm +++ b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm @@ -1,6 +1,7 @@ /obj/machinery/atmospherics/unary/vent_scrubber icon = 'icons/atmos/vent_scrubber.dmi' icon_state = "map_scrubber_off" + pipe_state = "scrubber" name = "Air Scrubber" desc = "Has a valve and pump attached to it" @@ -283,8 +284,7 @@ "\The [user] unfastens \the [src].", \ "You have unfastened \the [src].", \ "You hear a ratchet.") - new /obj/item/pipe(loc, make_from=src) - qdel(src) + deconstruct() /obj/machinery/atmospherics/unary/vent_scrubber/examine(mob/user) if(..(user, 1)) diff --git a/code/ATMOSPHERICS/components/valve.dm b/code/ATMOSPHERICS/components/valve.dm index 77aedf94e0..93e5da7c32 100644 --- a/code/ATMOSPHERICS/components/valve.dm +++ b/code/ATMOSPHERICS/components/valve.dm @@ -1,6 +1,8 @@ /obj/machinery/atmospherics/valve icon = 'icons/atmos/valve.dmi' icon_state = "map_valve0" + construction_type = /obj/item/pipe/binary + pipe_state = "mvalve" name = "manual valve" desc = "A pipe valve" @@ -45,6 +47,9 @@ if(EAST || WEST) initialize_directions = EAST|WEST +/obj/machinery/atmospherics/valve/get_neighbor_nodes_for_init() + return list(node1, node2) + /obj/machinery/atmospherics/valve/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference) if(reference == node1) network_node1 = new_network @@ -153,16 +158,8 @@ else if (!node2_dir) node2_dir = direction - for(var/obj/machinery/atmospherics/target in get_step(src,node1_dir)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node1 = target - break - for(var/obj/machinery/atmospherics/target in get_step(src,node2_dir)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node2 = target - break + STANDARD_ATMOS_CHOOSE_NODE(1, node1_dir) + STANDARD_ATMOS_CHOOSE_NODE(2, node2_dir) build_network() @@ -224,6 +221,7 @@ name = "digital valve" desc = "A digitally controlled valve." icon = 'icons/atmos/digital_valve.dmi' + pipe_state = "dvalve" var/frequency = 0 var/id = null @@ -306,8 +304,7 @@ "\The [user] unfastens \the [src].", \ "You have unfastened \the [src].", \ "You hear a ratchet.") - new /obj/item/pipe(loc, make_from=src) - qdel(src) + deconstruct() /obj/machinery/atmospherics/valve/examine(mob/user) ..() diff --git a/code/ATMOSPHERICS/mainspipe.dm b/code/ATMOSPHERICS/mainspipe.dm index 1b0c617564..baba515fae 100644 --- a/code/ATMOSPHERICS/mainspipe.dm +++ b/code/ATMOSPHERICS/mainspipe.dm @@ -34,7 +34,8 @@ obj/machinery/atmospherics/pipe/mains_component obj/machinery/atmospherics/mains_pipe icon = 'icons/obj/atmospherics/mainspipe.dmi' - layer = 2.4 //under wires with their 2.5 + layer = PIPES_LAYER + plane = PLATING_PLANE var/volume = 0 @@ -92,6 +93,9 @@ obj/machinery/atmospherics/mains_pipe else return 1 + get_neighbor_nodes_for_init() + return nodes + disconnect() ..() for(var/obj/machinery/atmospherics/pipe/mains_component/node in nodes) diff --git a/code/ATMOSPHERICS/pipes.dm b/code/ATMOSPHERICS/pipes.dm deleted file mode 100644 index d77ae5a73e..0000000000 --- a/code/ATMOSPHERICS/pipes.dm +++ /dev/null @@ -1,1378 +0,0 @@ -// -// Base type of pipes -// -/obj/machinery/atmospherics/pipe - - var/datum/gas_mixture/air_temporary // used when reconstructing a pipeline that broke - var/datum/pipeline/parent - var/volume = 0 - - layer = 2.4 //under wires with their 2.44 - use_power = 0 - - var/alert_pressure = 80*ONE_ATMOSPHERE - //minimum pressure before check_pressure(...) should be called - - can_buckle = 1 - buckle_require_restraints = 1 - buckle_lying = -1 - -/obj/machinery/atmospherics/pipe/drain_power() - return -1 - -/obj/machinery/atmospherics/pipe/New() - if(istype(get_turf(src), /turf/simulated/wall) || istype(get_turf(src), /turf/simulated/shuttle/wall) || istype(get_turf(src), /turf/unsimulated/wall)) - level = 1 - ..() - -/obj/machinery/atmospherics/pipe/hides_under_flooring() - return level != 2 - -/obj/machinery/atmospherics/pipe/proc/pipeline_expansion() - return null - -/obj/machinery/atmospherics/pipe/proc/check_pressure(pressure) - //Return 1 if parent should continue checking other pipes - //Return null if parent should stop checking other pipes. Recall: qdel(src) will by default return null - - return 1 - -/obj/machinery/atmospherics/pipe/return_air() - if(!parent) - parent = new /datum/pipeline() - parent.build_pipeline(src) - - return parent.air - -/obj/machinery/atmospherics/pipe/build_network() - if(!parent) - parent = new /datum/pipeline() - parent.build_pipeline(src) - - return parent.return_network() - -/obj/machinery/atmospherics/pipe/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference) - if(!parent) - parent = new /datum/pipeline() - parent.build_pipeline(src) - - return parent.network_expand(new_network, reference) - -/obj/machinery/atmospherics/pipe/return_network(obj/machinery/atmospherics/reference) - if(!parent) - parent = new /datum/pipeline() - parent.build_pipeline(src) - - return parent.return_network(reference) - -/obj/machinery/atmospherics/pipe/Destroy() - qdel_null(parent) - if(air_temporary) - loc.assume_air(air_temporary) - - . = ..() - -/obj/machinery/atmospherics/pipe/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) - if (istype(src, /obj/machinery/atmospherics/pipe/tank)) - return ..() - - if(istype(W,/obj/item/device/pipe_painter)) - return 0 - - if (!istype(W, /obj/item/weapon/wrench)) - return ..() - var/turf/T = src.loc - if (level==1 && isturf(T) && !T.is_plating()) - to_chat(user, "You must remove the plating first.") - return 1 - if(!can_unwrench()) - to_chat(user, "You cannot unwrench \the [src], it is too exerted due to internal pressure.") - add_fingerprint(user) - return 1 - playsound(src, W.usesound, 50, 1) - to_chat(user, "You begin to unfasten \the [src]...") - if (do_after(user, 40 * W.toolspeed)) - user.visible_message( \ - "\The [user] unfastens \the [src].", \ - "You have unfastened \the [src].", \ - "You hear a ratchet.") - new /obj/item/pipe(loc, make_from=src) - for (var/obj/machinery/meter/meter in T) - if (meter.target == src) - new /obj/item/pipe_meter(T) - qdel(meter) - qdel(src) - -/obj/machinery/atmospherics/pipe/proc/change_color(var/new_color) - //only pass valid pipe colors please ~otherwise your pipe will turn invisible - if(!pipe_color_check(new_color)) - return - - pipe_color = new_color - update_icon() - -/obj/machinery/atmospherics/pipe/color_cache_name(var/obj/machinery/atmospherics/node) - if(istype(src, /obj/machinery/atmospherics/pipe/tank)) - return ..() - - if(istype(node, /obj/machinery/atmospherics/pipe/manifold) || istype(node, /obj/machinery/atmospherics/pipe/manifold4w)) - if(pipe_color == node.pipe_color) - return node.pipe_color - else - return null - else if(istype(node, /obj/machinery/atmospherics/pipe/simple)) - return node.pipe_color - else - return pipe_color - -/obj/machinery/atmospherics/pipe/hide(var/i) - if(istype(loc, /turf/simulated)) - invisibility = i ? 101 : 0 - update_icon() - -/obj/machinery/atmospherics/pipe/process() - if(!parent) //This should cut back on the overhead calling build_network thousands of times per cycle - ..() - else - . = PROCESS_KILL - -// -// Simple Pipes - Just a tube, maybe bent -// -/obj/machinery/atmospherics/pipe/simple - icon = 'icons/atmos/pipes.dmi' - icon_state = "" - var/pipe_icon = "" //what kind of pipe it is and from which dmi is the icon manager getting its icons, "" for simple pipes, "hepipe" for HE pipes, "hejunction" for HE junctions - name = "pipe" - desc = "A one meter section of regular pipe" - - volume = ATMOS_DEFAULT_VOLUME_PIPE - - dir = SOUTH - initialize_directions = SOUTH|NORTH - - var/minimum_temperature_difference = 300 - var/thermal_conductivity = 0 //WALL_HEAT_TRANSFER_COEFFICIENT No - - var/maximum_pressure = 70*ONE_ATMOSPHERE - var/fatigue_pressure = 55*ONE_ATMOSPHERE - alert_pressure = 55*ONE_ATMOSPHERE - - level = 1 - -/obj/machinery/atmospherics/pipe/simple/New() - ..() - - // Pipe colors and icon states are handled by an image cache - so color and icon should - // be null. For mapping purposes color is defined in the object definitions. - icon = null - alpha = 255 - -/obj/machinery/atmospherics/pipe/simple/check_pressure(pressure) - var/datum/gas_mixture/environment = loc.return_air() - - var/pressure_difference = pressure - environment.return_pressure() - - if(pressure_difference > maximum_pressure) - burst() - - else if(pressure_difference > fatigue_pressure) - //TODO: leak to turf, doing pfshhhhh - if(prob(5)) - burst() - - else return 1 - -/obj/machinery/atmospherics/pipe/simple/init_dir() - switch(dir) - if(SOUTH || NORTH) - initialize_directions = SOUTH|NORTH - if(EAST || WEST) - initialize_directions = EAST|WEST - if(NORTHEAST) - initialize_directions = NORTH|EAST - if(NORTHWEST) - initialize_directions = NORTH|WEST - if(SOUTHEAST) - initialize_directions = SOUTH|EAST - if(SOUTHWEST) - initialize_directions = SOUTH|WEST - -/obj/machinery/atmospherics/pipe/simple/proc/burst() - src.visible_message("\The [src] bursts!"); - playsound(src.loc, 'sound/effects/bang.ogg', 25, 1) - var/datum/effect/effect/system/smoke_spread/smoke = new - smoke.set_up(1,0, src.loc, 0) - smoke.start() - qdel(src) - -/obj/machinery/atmospherics/pipe/simple/proc/normalize_dir() - if(dir==3) - set_dir(1) - else if(dir==12) - set_dir(4) - -/obj/machinery/atmospherics/pipe/simple/Destroy() - if(node1) - node1.disconnect(src) - node1 = null - if(node2) - node2.disconnect(src) - node1 = null - - . = ..() - -/obj/machinery/atmospherics/pipe/simple/pipeline_expansion() - return list(node1, node2) - -/obj/machinery/atmospherics/pipe/simple/change_color(var/new_color) - ..() - //for updating connected atmos device pipes (i.e. vents, manifolds, etc) - if(node1) - node1.update_underlays() - if(node2) - node2.update_underlays() - -/obj/machinery/atmospherics/pipe/simple/update_icon(var/safety = 0) - if(!check_icon_cache()) - return - - alpha = 255 - - overlays.Cut() - - if(!node1 && !node2) - var/turf/T = get_turf(src) - new /obj/item/pipe(loc, make_from=src) - for (var/obj/machinery/meter/meter in T) - if (meter.target == src) - new /obj/item/pipe_meter(T) - qdel(meter) - qdel(src) - else if(node1 && node2) - overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "[pipe_icon]intact[icon_connect_type]") - else - overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "[pipe_icon]exposed[node1?1:0][node2?1:0][icon_connect_type]") - -/obj/machinery/atmospherics/pipe/simple/update_underlays() - return - -/obj/machinery/atmospherics/pipe/simple/atmos_init() - normalize_dir() - var/node1_dir - var/node2_dir - - for(var/direction in cardinal) - if(direction&initialize_directions) - if (!node1_dir) - node1_dir = direction - else if (!node2_dir) - node2_dir = direction - - for(var/obj/machinery/atmospherics/target in get_step(src,node1_dir)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node1 = target - break - for(var/obj/machinery/atmospherics/target in get_step(src,node2_dir)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node2 = target - break - - if(!node1 && !node2) - qdel(src) - return - - var/turf/T = loc - if(level == 1 && !T.is_plating()) hide(1) - update_icon() - -/obj/machinery/atmospherics/pipe/simple/disconnect(obj/machinery/atmospherics/reference) - if(reference == node1) - if(istype(node1, /obj/machinery/atmospherics/pipe)) - qdel(parent) - node1 = null - - if(reference == node2) - if(istype(node2, /obj/machinery/atmospherics/pipe)) - qdel(parent) - node2 = null - - update_icon() - - return null - -/obj/machinery/atmospherics/pipe/simple/visible - icon_state = "intact" - level = 2 - -/obj/machinery/atmospherics/pipe/simple/visible/scrubbers - name = "Scrubbers pipe" - desc = "A one meter section of scrubbers pipe" - icon_state = "intact-scrubbers" - connect_types = CONNECT_TYPE_SCRUBBER - layer = 2.38 - icon_connect_type = "-scrubbers" - color = PIPE_COLOR_RED - -/obj/machinery/atmospherics/pipe/simple/visible/supply - name = "Air supply pipe" - desc = "A one meter section of supply pipe" - icon_state = "intact-supply" - connect_types = CONNECT_TYPE_SUPPLY - layer = 2.39 - icon_connect_type = "-supply" - color = PIPE_COLOR_BLUE - -/obj/machinery/atmospherics/pipe/simple/visible/yellow - color = PIPE_COLOR_YELLOW - -/obj/machinery/atmospherics/pipe/simple/visible/cyan - color = PIPE_COLOR_CYAN - -/obj/machinery/atmospherics/pipe/simple/visible/green - color = PIPE_COLOR_GREEN - -/obj/machinery/atmospherics/pipe/simple/visible/black - color = PIPE_COLOR_BLACK - -/obj/machinery/atmospherics/pipe/simple/visible/red - color = PIPE_COLOR_RED - -/obj/machinery/atmospherics/pipe/simple/visible/blue - color = PIPE_COLOR_BLUE - -/obj/machinery/atmospherics/pipe/simple/visible/purple - color = PIPE_COLOR_PURPLE - -/obj/machinery/atmospherics/pipe/simple/hidden - icon_state = "intact" - level = 1 - alpha = 128 //set for the benefit of mapping - this is reset to opaque when the pipe is spawned in game - -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers - name = "Scrubbers pipe" - desc = "A one meter section of scrubbers pipe" - icon_state = "intact-scrubbers" - connect_types = CONNECT_TYPE_SCRUBBER - layer = 2.38 - icon_connect_type = "-scrubbers" - color = PIPE_COLOR_RED - -/obj/machinery/atmospherics/pipe/simple/hidden/supply - name = "Air supply pipe" - desc = "A one meter section of supply pipe" - icon_state = "intact-supply" - connect_types = CONNECT_TYPE_SUPPLY - layer = 2.39 - icon_connect_type = "-supply" - color = PIPE_COLOR_BLUE - -/obj/machinery/atmospherics/pipe/simple/hidden/yellow - color = PIPE_COLOR_YELLOW - -/obj/machinery/atmospherics/pipe/simple/hidden/cyan - color = PIPE_COLOR_CYAN - -/obj/machinery/atmospherics/pipe/simple/hidden/green - color = PIPE_COLOR_GREEN - -/obj/machinery/atmospherics/pipe/simple/hidden/black - color = PIPE_COLOR_BLACK - -/obj/machinery/atmospherics/pipe/simple/hidden/red - color = PIPE_COLOR_RED - -/obj/machinery/atmospherics/pipe/simple/hidden/blue - color = PIPE_COLOR_BLUE - -/obj/machinery/atmospherics/pipe/simple/hidden/purple - color = PIPE_COLOR_PURPLE - -/obj/machinery/atmospherics/pipe/simple/insulated - icon = 'icons/obj/atmospherics/red_pipe.dmi' - icon_state = "intact" - - minimum_temperature_difference = 10000 - thermal_conductivity = 0 - maximum_pressure = 1000*ONE_ATMOSPHERE - fatigue_pressure = 900*ONE_ATMOSPHERE - alert_pressure = 900*ONE_ATMOSPHERE - - level = 2 - -// -// Manifold Pipes - Three way "T" joints -// -/obj/machinery/atmospherics/pipe/manifold - icon = 'icons/atmos/manifold.dmi' - icon_state = "" - name = "pipe manifold" - desc = "A manifold composed of regular pipes" - - volume = ATMOS_DEFAULT_VOLUME_PIPE * 1.5 - - dir = SOUTH - initialize_directions = EAST|NORTH|WEST - - var/obj/machinery/atmospherics/node3 - - level = 1 - layer = 2.4 //under wires with their 2.44 - -/obj/machinery/atmospherics/pipe/manifold/New() - ..() - alpha = 255 - icon = null - -/obj/machinery/atmospherics/pipe/manifold/init_dir() - switch(dir) - if(NORTH) - initialize_directions = EAST|SOUTH|WEST - if(SOUTH) - initialize_directions = WEST|NORTH|EAST - if(EAST) - initialize_directions = SOUTH|WEST|NORTH - if(WEST) - initialize_directions = NORTH|EAST|SOUTH - -/obj/machinery/atmospherics/pipe/manifold/pipeline_expansion() - return list(node1, node2, node3) - -/obj/machinery/atmospherics/pipe/manifold/Destroy() - if(node1) - node1.disconnect(src) - node1 = null - if(node2) - node2.disconnect(src) - node2 = null - if(node3) - node3.disconnect(src) - node3 = null - - . = ..() - -/obj/machinery/atmospherics/pipe/manifold/disconnect(obj/machinery/atmospherics/reference) - if(reference == node1) - if(istype(node1, /obj/machinery/atmospherics/pipe)) - qdel(parent) - node1 = null - - if(reference == node2) - if(istype(node2, /obj/machinery/atmospherics/pipe)) - qdel(parent) - node2 = null - - if(reference == node3) - if(istype(node3, /obj/machinery/atmospherics/pipe)) - qdel(parent) - node3 = null - - update_icon() - - ..() - -/obj/machinery/atmospherics/pipe/manifold/change_color(var/new_color) - ..() - //for updating connected atmos device pipes (i.e. vents, manifolds, etc) - if(node1) - node1.update_underlays() - if(node2) - node2.update_underlays() - if(node3) - node3.update_underlays() - -/obj/machinery/atmospherics/pipe/manifold/update_icon(var/safety = 0) - if(!check_icon_cache()) - return - - alpha = 255 - - if(!node1 && !node2 && !node3) - var/turf/T = get_turf(src) - new /obj/item/pipe(loc, make_from=src) - for (var/obj/machinery/meter/meter in T) - if (meter.target == src) - new /obj/item/pipe_meter(T) - qdel(meter) - qdel(src) - else - overlays.Cut() - overlays += icon_manager.get_atmos_icon("manifold", , pipe_color, "core" + icon_connect_type) - overlays += icon_manager.get_atmos_icon("manifold", , , "clamps" + icon_connect_type) - underlays.Cut() - - var/turf/T = get_turf(src) - var/list/directions = list(NORTH, SOUTH, EAST, WEST) - var/node1_direction = get_dir(src, node1) - var/node2_direction = get_dir(src, node2) - var/node3_direction = get_dir(src, node3) - - directions -= dir - - directions -= add_underlay(T,node1,node1_direction,icon_connect_type) - directions -= add_underlay(T,node2,node2_direction,icon_connect_type) - directions -= add_underlay(T,node3,node3_direction,icon_connect_type) - - for(var/D in directions) - add_underlay(T,,D,icon_connect_type) - - -/obj/machinery/atmospherics/pipe/manifold/update_underlays() - ..() - update_icon() - -/obj/machinery/atmospherics/pipe/manifold/atmos_init() - var/connect_directions = (NORTH|SOUTH|EAST|WEST)&(~dir) - - for(var/direction in cardinal) - if(direction&connect_directions) - for(var/obj/machinery/atmospherics/target in get_step(src,direction)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node1 = target - connect_directions &= ~direction - break - if (node1) - break - - - for(var/direction in cardinal) - if(direction&connect_directions) - for(var/obj/machinery/atmospherics/target in get_step(src,direction)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node2 = target - connect_directions &= ~direction - break - if (node2) - break - - - for(var/direction in cardinal) - if(direction&connect_directions) - for(var/obj/machinery/atmospherics/target in get_step(src,direction)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node3 = target - connect_directions &= ~direction - break - if (node3) - break - - if(!node1 && !node2 && !node3) - qdel(src) - return - - var/turf/T = get_turf(src) - if(level == 1 && !T.is_plating()) hide(1) - update_icon() - -/obj/machinery/atmospherics/pipe/manifold/visible - icon_state = "map" - level = 2 - -/obj/machinery/atmospherics/pipe/manifold/visible/scrubbers - name="Scrubbers pipe manifold" - desc = "A manifold composed of scrubbers pipes" - icon_state = "map-scrubbers" - connect_types = CONNECT_TYPE_SCRUBBER - layer = 2.38 - icon_connect_type = "-scrubbers" - color = PIPE_COLOR_RED - -/obj/machinery/atmospherics/pipe/manifold/visible/supply - name="Air supply pipe manifold" - desc = "A manifold composed of supply pipes" - icon_state = "map-supply" - connect_types = CONNECT_TYPE_SUPPLY - layer = 2.39 - icon_connect_type = "-supply" - color = PIPE_COLOR_BLUE - -/obj/machinery/atmospherics/pipe/manifold/visible/yellow - color = PIPE_COLOR_YELLOW - -/obj/machinery/atmospherics/pipe/manifold/visible/cyan - color = PIPE_COLOR_CYAN - -/obj/machinery/atmospherics/pipe/manifold/visible/green - color = PIPE_COLOR_GREEN - -/obj/machinery/atmospherics/pipe/manifold/visible/black - color = PIPE_COLOR_BLACK - -/obj/machinery/atmospherics/pipe/manifold/visible/red - color = PIPE_COLOR_RED - -/obj/machinery/atmospherics/pipe/manifold/visible/blue - color = PIPE_COLOR_BLUE - -/obj/machinery/atmospherics/pipe/manifold/visible/purple - color = PIPE_COLOR_PURPLE - -/obj/machinery/atmospherics/pipe/manifold/hidden - icon_state = "map" - level = 1 - alpha = 128 //set for the benefit of mapping - this is reset to opaque when the pipe is spawned in game - -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers - name="Scrubbers pipe manifold" - desc = "A manifold composed of scrubbers pipes" - icon_state = "map-scrubbers" - connect_types = CONNECT_TYPE_SCRUBBER - layer = 2.38 - icon_connect_type = "-scrubbers" - color = PIPE_COLOR_RED - -/obj/machinery/atmospherics/pipe/manifold/hidden/supply - name="Air supply pipe manifold" - desc = "A manifold composed of supply pipes" - icon_state = "map-supply" - connect_types = CONNECT_TYPE_SUPPLY - layer = 2.39 - icon_connect_type = "-supply" - color = PIPE_COLOR_BLUE - -/obj/machinery/atmospherics/pipe/manifold/hidden/yellow - color = PIPE_COLOR_YELLOW - -/obj/machinery/atmospherics/pipe/manifold/hidden/cyan - color = PIPE_COLOR_CYAN - -/obj/machinery/atmospherics/pipe/manifold/hidden/green - color = PIPE_COLOR_GREEN - -/obj/machinery/atmospherics/pipe/manifold/hidden/black - color = PIPE_COLOR_BLACK - -/obj/machinery/atmospherics/pipe/manifold/hidden/red - color = PIPE_COLOR_RED - -/obj/machinery/atmospherics/pipe/manifold/hidden/blue - color = PIPE_COLOR_BLUE - -/obj/machinery/atmospherics/pipe/manifold/hidden/purple - color = PIPE_COLOR_PURPLE - - -// -// 4-Way Manifold Pipes - 4 way "cross" junction -// -/obj/machinery/atmospherics/pipe/manifold4w - icon = 'icons/atmos/manifold.dmi' - icon_state = "" - name = "4-way pipe manifold" - desc = "A manifold composed of regular pipes" - - volume = ATMOS_DEFAULT_VOLUME_PIPE * 2 - - dir = SOUTH - initialize_directions = NORTH|SOUTH|EAST|WEST - - var/obj/machinery/atmospherics/node3 - var/obj/machinery/atmospherics/node4 - - level = 1 - layer = 2.4 //under wires with their 2.44 - -/obj/machinery/atmospherics/pipe/manifold4w/New() - ..() - alpha = 255 - icon = null - -/obj/machinery/atmospherics/pipe/manifold4w/pipeline_expansion() - return list(node1, node2, node3, node4) - -/obj/machinery/atmospherics/pipe/manifold4w/Destroy() - if(node1) - node1.disconnect(src) - node1 = null - if(node2) - node2.disconnect(src) - node2 = null - if(node3) - node3.disconnect(src) - node3 = null - if(node4) - node4.disconnect(src) - node4 = null - - . = ..() - -/obj/machinery/atmospherics/pipe/manifold4w/disconnect(obj/machinery/atmospherics/reference) - if(reference == node1) - if(istype(node1, /obj/machinery/atmospherics/pipe)) - qdel(parent) - node1 = null - - if(reference == node2) - if(istype(node2, /obj/machinery/atmospherics/pipe)) - qdel(parent) - node2 = null - - if(reference == node3) - if(istype(node3, /obj/machinery/atmospherics/pipe)) - qdel(parent) - node3 = null - - if(reference == node4) - if(istype(node4, /obj/machinery/atmospherics/pipe)) - qdel(parent) - node4 = null - - update_icon() - - ..() - -/obj/machinery/atmospherics/pipe/manifold4w/change_color(var/new_color) - ..() - //for updating connected atmos device pipes (i.e. vents, manifolds, etc) - if(node1) - node1.update_underlays() - if(node2) - node2.update_underlays() - if(node3) - node3.update_underlays() - if(node4) - node4.update_underlays() - -/obj/machinery/atmospherics/pipe/manifold4w/update_icon(var/safety = 0) - if(!check_icon_cache()) - return - - alpha = 255 - - if(!node1 && !node2 && !node3 && !node4) - var/turf/T = get_turf(src) - new /obj/item/pipe(loc, make_from=src) - for (var/obj/machinery/meter/meter in T) - if (meter.target == src) - new /obj/item/pipe_meter(T) - qdel(meter) - qdel(src) - else - overlays.Cut() - overlays += icon_manager.get_atmos_icon("manifold", , pipe_color, "4way" + icon_connect_type) - overlays += icon_manager.get_atmos_icon("manifold", , , "clamps_4way" + icon_connect_type) - underlays.Cut() - - /* - var/list/directions = list(NORTH, SOUTH, EAST, WEST) - - - directions -= add_underlay(node1) - directions -= add_underlay(node2) - directions -= add_underlay(node3) - directions -= add_underlay(node4) - - for(var/D in directions) - add_underlay(,D) - */ - - var/turf/T = get_turf(src) - var/list/directions = list(NORTH, SOUTH, EAST, WEST) - var/node1_direction = get_dir(src, node1) - var/node2_direction = get_dir(src, node2) - var/node3_direction = get_dir(src, node3) - var/node4_direction = get_dir(src, node4) - - directions -= dir - - directions -= add_underlay(T,node1,node1_direction,icon_connect_type) - directions -= add_underlay(T,node2,node2_direction,icon_connect_type) - directions -= add_underlay(T,node3,node3_direction,icon_connect_type) - directions -= add_underlay(T,node4,node4_direction,icon_connect_type) - - for(var/D in directions) - add_underlay(T,,D,icon_connect_type) - - -/obj/machinery/atmospherics/pipe/manifold4w/update_underlays() - ..() - update_icon() - -/obj/machinery/atmospherics/pipe/manifold4w/atmos_init() - - for(var/obj/machinery/atmospherics/target in get_step(src,1)) - if(target.initialize_directions & 2) - if (check_connect_types(target,src)) - node1 = target - break - - for(var/obj/machinery/atmospherics/target in get_step(src,2)) - if(target.initialize_directions & 1) - if (check_connect_types(target,src)) - node2 = target - break - - for(var/obj/machinery/atmospherics/target in get_step(src,4)) - if(target.initialize_directions & 8) - if (check_connect_types(target,src)) - node3 = target - break - - for(var/obj/machinery/atmospherics/target in get_step(src,8)) - if(target.initialize_directions & 4) - if (check_connect_types(target,src)) - node4 = target - break - - if(!node1 && !node2 && !node3 && !node4) - qdel(src) - return - - var/turf/T = get_turf(src) - if(level == 1 && !T.is_plating()) hide(1) - update_icon() - -/obj/machinery/atmospherics/pipe/manifold4w/visible - icon_state = "map_4way" - level = 2 - -/obj/machinery/atmospherics/pipe/manifold4w/visible/scrubbers - name="4-way scrubbers pipe manifold" - desc = "A manifold composed of scrubbers pipes" - icon_state = "map_4way-scrubbers" - connect_types = CONNECT_TYPE_SCRUBBER - layer = 2.38 - icon_connect_type = "-scrubbers" - color = PIPE_COLOR_RED - -/obj/machinery/atmospherics/pipe/manifold4w/visible/supply - name="4-way air supply pipe manifold" - desc = "A manifold composed of supply pipes" - icon_state = "map_4way-supply" - connect_types = CONNECT_TYPE_SUPPLY - layer = 2.39 - icon_connect_type = "-supply" - color = PIPE_COLOR_BLUE - -/obj/machinery/atmospherics/pipe/manifold4w/visible/yellow - color = PIPE_COLOR_YELLOW - -/obj/machinery/atmospherics/pipe/manifold4w/visible/cyan - color = PIPE_COLOR_CYAN - -/obj/machinery/atmospherics/pipe/manifold4w/visible/green - color = PIPE_COLOR_GREEN - -/obj/machinery/atmospherics/pipe/manifold4w/visible/black - color = PIPE_COLOR_BLACK - -/obj/machinery/atmospherics/pipe/manifold4w/visible/red - color = PIPE_COLOR_RED - -/obj/machinery/atmospherics/pipe/manifold4w/visible/blue - color = PIPE_COLOR_BLUE - -/obj/machinery/atmospherics/pipe/manifold4w/visible/purple - color = PIPE_COLOR_PURPLE - -/obj/machinery/atmospherics/pipe/manifold4w/hidden - icon_state = "map_4way" - level = 1 - alpha = 128 //set for the benefit of mapping - this is reset to opaque when the pipe is spawned in game - -/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers - name="4-way scrubbers pipe manifold" - desc = "A manifold composed of scrubbers pipes" - icon_state = "map_4way-scrubbers" - connect_types = CONNECT_TYPE_SCRUBBER - layer = 2.38 - icon_connect_type = "-scrubbers" - color = PIPE_COLOR_RED - -/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply - name="4-way air supply pipe manifold" - desc = "A manifold composed of supply pipes" - icon_state = "map_4way-supply" - connect_types = CONNECT_TYPE_SUPPLY - layer = 2.39 - icon_connect_type = "-supply" - color = PIPE_COLOR_BLUE - -/obj/machinery/atmospherics/pipe/manifold4w/hidden/yellow - color = PIPE_COLOR_YELLOW - -/obj/machinery/atmospherics/pipe/manifold4w/hidden/cyan - color = PIPE_COLOR_CYAN - -/obj/machinery/atmospherics/pipe/manifold4w/hidden/green - color = PIPE_COLOR_GREEN - -/obj/machinery/atmospherics/pipe/manifold4w/hidden/black - color = PIPE_COLOR_BLACK - -/obj/machinery/atmospherics/pipe/manifold4w/hidden/red - color = PIPE_COLOR_RED - -/obj/machinery/atmospherics/pipe/manifold4w/hidden/blue - color = PIPE_COLOR_BLUE - -/obj/machinery/atmospherics/pipe/manifold4w/hidden/purple - color = PIPE_COLOR_PURPLE - -// -// Pipe Cap - They go on the end -// -/obj/machinery/atmospherics/pipe/cap - name = "pipe endcap" - desc = "An endcap for pipes" - icon = 'icons/atmos/pipes.dmi' - icon_state = "" - level = 2 - layer = 2.4 //under wires with their 2.44 - - volume = 35 - - dir = SOUTH - initialize_directions = SOUTH - - var/obj/machinery/atmospherics/node - -/obj/machinery/atmospherics/pipe/cap/init_dir() - initialize_directions = dir - -/obj/machinery/atmospherics/pipe/cap/pipeline_expansion() - return list(node) - -/obj/machinery/atmospherics/pipe/cap/Destroy() - if(node) - node.disconnect(src) - node = null - - . = ..() - -/obj/machinery/atmospherics/pipe/cap/disconnect(obj/machinery/atmospherics/reference) - if(reference == node) - if(istype(node, /obj/machinery/atmospherics/pipe)) - qdel(parent) - node = null - - update_icon() - - ..() - -/obj/machinery/atmospherics/pipe/cap/change_color(var/new_color) - ..() - //for updating connected atmos device pipes (i.e. vents, manifolds, etc) - if(node) - node.update_underlays() - -/obj/machinery/atmospherics/pipe/cap/update_icon(var/safety = 0) - if(!check_icon_cache()) - return - - alpha = 255 - - overlays.Cut() - overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "cap") - -/obj/machinery/atmospherics/pipe/cap/atmos_init() - for(var/obj/machinery/atmospherics/target in get_step(src, dir)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node = target - break - - var/turf/T = src.loc // hide if turf is not intact - if(level == 1 && !T.is_plating()) hide(1) - update_icon() - -/obj/machinery/atmospherics/pipe/cap/can_unwrench() - return 1 - -/obj/machinery/atmospherics/pipe/cap/visible - level = 2 - icon_state = "cap" - -/obj/machinery/atmospherics/pipe/cap/visible/scrubbers - name = "scrubbers pipe endcap" - desc = "An endcap for scrubbers pipes" - icon_state = "cap-scrubbers" - connect_types = CONNECT_TYPE_SCRUBBER - layer = 2.38 - icon_connect_type = "-scrubbers" - color = PIPE_COLOR_RED - -/obj/machinery/atmospherics/pipe/cap/visible/supply - name = "supply pipe endcap" - desc = "An endcap for supply pipes" - icon_state = "cap-supply" - connect_types = CONNECT_TYPE_SUPPLY - layer = 2.39 - icon_connect_type = "-supply" - color = PIPE_COLOR_BLUE - -/obj/machinery/atmospherics/pipe/cap/hidden - level = 1 - icon_state = "cap" - alpha = 128 - -/obj/machinery/atmospherics/pipe/cap/hidden/scrubbers - name = "scrubbers pipe endcap" - desc = "An endcap for scrubbers pipes" - icon_state = "cap-f-scrubbers" - connect_types = CONNECT_TYPE_SCRUBBER - layer = 2.38 - icon_connect_type = "-scrubbers" - color = PIPE_COLOR_RED - -/obj/machinery/atmospherics/pipe/cap/hidden/supply - name = "supply pipe endcap" - desc = "An endcap for supply pipes" - icon_state = "cap-f-supply" - connect_types = CONNECT_TYPE_SUPPLY - layer = 2.39 - icon_connect_type = "-supply" - color = PIPE_COLOR_BLUE - -// -// Tanks - These are implemented as pipes with large volume -// -/obj/machinery/atmospherics/pipe/tank - icon = 'icons/atmos/tank.dmi' - icon_state = "air_map" - - name = "Pressure Tank" - desc = "A large vessel containing pressurized gas." - - volume = 10000 //in liters, 1 meters by 1 meters by 2 meters ~tweaked it a little to simulate a pressure tank without needing to recode them yet - var/start_pressure = 25*ONE_ATMOSPHERE - - level = 1 - dir = SOUTH - initialize_directions = SOUTH - density = 1 - -/obj/machinery/atmospherics/pipe/tank/New() - icon_state = "air" - ..() - -/obj/machinery/atmospherics/pipe/tank/init_dir() - initialize_directions = dir - -/obj/machinery/atmospherics/pipe/tank/Destroy() - if(node1) - node1.disconnect(src) - node1 = null - - . = ..() - -/obj/machinery/atmospherics/pipe/tank/pipeline_expansion() - return list(node1) - -/obj/machinery/atmospherics/pipe/tank/update_underlays() - if(..()) - underlays.Cut() - var/turf/T = get_turf(src) - if(!istype(T)) - return - add_underlay(T, node1, dir) - -/obj/machinery/atmospherics/pipe/tank/hide() - update_underlays() - -/obj/machinery/atmospherics/pipe/tank/atmos_init() - var/connect_direction = dir - - for(var/obj/machinery/atmospherics/target in get_step(src,connect_direction)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node1 = target - break - - update_underlays() - -/obj/machinery/atmospherics/pipe/tank/disconnect(obj/machinery/atmospherics/reference) - if(reference == node1) - if(istype(node1, /obj/machinery/atmospherics/pipe)) - qdel(parent) - node1 = null - - update_underlays() - - return null - -/obj/machinery/atmospherics/pipe/tank/attackby(var/obj/item/W as obj, var/mob/user as mob) - if(istype(W, /obj/item/device/pipe_painter)) - return - - if(istype(W, /obj/item/device/analyzer) && in_range(user, src)) - var/obj/item/device/analyzer/A = W - A.analyze_gases(src, user) - -/obj/machinery/atmospherics/pipe/tank/air - name = "Pressure Tank (Air)" - icon_state = "air_map" - -/obj/machinery/atmospherics/pipe/tank/air/New() - air_temporary = new - air_temporary.volume = volume - air_temporary.temperature = T20C - - air_temporary.adjust_multi("oxygen", (start_pressure*O2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature), \ - "nitrogen",(start_pressure*N2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) - - - ..() - icon_state = "air" - -/obj/machinery/atmospherics/pipe/tank/oxygen - name = "Pressure Tank (Oxygen)" - icon_state = "o2_map" - -/obj/machinery/atmospherics/pipe/tank/oxygen/New() - air_temporary = new - air_temporary.volume = volume - air_temporary.temperature = T20C - - air_temporary.adjust_gas("oxygen", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) - - ..() - icon_state = "o2" - -/obj/machinery/atmospherics/pipe/tank/nitrogen - name = "Pressure Tank (Nitrogen)" - icon_state = "n2_map" - -/obj/machinery/atmospherics/pipe/tank/nitrogen/New() - air_temporary = new - air_temporary.volume = volume - air_temporary.temperature = T20C - - air_temporary.adjust_gas("nitrogen", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) - - ..() - icon_state = "n2" - -/obj/machinery/atmospherics/pipe/tank/carbon_dioxide - name = "Pressure Tank (Carbon Dioxide)" - icon_state = "co2_map" - -/obj/machinery/atmospherics/pipe/tank/carbon_dioxide/New() - air_temporary = new - air_temporary.volume = volume - air_temporary.temperature = T20C - - air_temporary.adjust_gas("carbon_dioxide", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) - - ..() - icon_state = "co2" - -/obj/machinery/atmospherics/pipe/tank/phoron - name = "Pressure Tank (Phoron)" - icon_state = "phoron_map" - -/obj/machinery/atmospherics/pipe/tank/phoron/New() - air_temporary = new - air_temporary.volume = volume - air_temporary.temperature = T20C - - air_temporary.adjust_gas("phoron", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) - - ..() - icon_state = "phoron" - -/obj/machinery/atmospherics/pipe/tank/nitrous_oxide - name = "Pressure Tank (Nitrous Oxide)" - icon_state = "n2o_map" - -/obj/machinery/atmospherics/pipe/tank/nitrous_oxide/New() - air_temporary = new - air_temporary.volume = volume - air_temporary.temperature = T0C - - air_temporary.adjust_gas("sleeping_agent", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) - - ..() - icon_state = "n2o" - -// -// Vent Pipe - Unpowered vent -// -/obj/machinery/atmospherics/pipe/vent - icon = 'icons/obj/atmospherics/pipe_vent.dmi' - icon_state = "intact" - - name = "Vent" - desc = "A large air vent" - - level = 1 - - volume = 250 - - dir = SOUTH - initialize_directions = SOUTH - - var/build_killswitch = 1 - -/obj/machinery/atmospherics/pipe/vent/init_dir() - initialize_directions = dir - -/obj/machinery/atmospherics/pipe/vent/high_volume - name = "Larger vent" - volume = 1000 - -/obj/machinery/atmospherics/pipe/vent/process() - if(!parent) - if(build_killswitch <= 0) - . = PROCESS_KILL - else - build_killswitch-- - ..() - return - else - parent.mingle_with_turf(loc, volume) - -/obj/machinery/atmospherics/pipe/vent/Destroy() - if(node1) - node1.disconnect(src) - node1 = null - - . = ..() - -/obj/machinery/atmospherics/pipe/vent/pipeline_expansion() - return list(node1) - -/obj/machinery/atmospherics/pipe/vent/update_icon() - if(node1) - icon_state = "intact" - - set_dir(get_dir(src, node1)) - - else - icon_state = "exposed" - -/obj/machinery/atmospherics/pipe/vent/atmos_init() - var/connect_direction = dir - - for(var/obj/machinery/atmospherics/target in get_step(src,connect_direction)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node1 = target - break - - update_icon() - -/obj/machinery/atmospherics/pipe/vent/disconnect(obj/machinery/atmospherics/reference) - if(reference == node1) - if(istype(node1, /obj/machinery/atmospherics/pipe)) - qdel(parent) - node1 = null - - update_icon() - - return null - -/obj/machinery/atmospherics/pipe/vent/hide(var/i) //to make the little pipe section invisible, the icon changes. - if(node1) - icon_state = "[i == 1 && istype(loc, /turf/simulated) ? "h" : "" ]intact" - set_dir(get_dir(src, node1)) - else - icon_state = "exposed" - -// -// Universal Pipe Adapter - Designed for connecting scrubbers, normal, and supply pipes together. -// -/obj/machinery/atmospherics/pipe/simple/visible/universal - name="Universal pipe adapter" - desc = "An adapter for regular, supply and scrubbers pipes" - connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SUPPLY|CONNECT_TYPE_SCRUBBER - icon_state = "map_universal" - -/obj/machinery/atmospherics/pipe/simple/visible/universal/update_icon(var/safety = 0) - if(!check_icon_cache()) - return - - alpha = 255 - - overlays.Cut() - overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "universal") - underlays.Cut() - - if (node1) - universal_underlays(node1) - if(node2) - universal_underlays(node2) - else - var/node1_dir = get_dir(node1,src) - universal_underlays(,node1_dir) - else if (node2) - universal_underlays(node2) - else - universal_underlays(,dir) - universal_underlays(dir, -180) - -/obj/machinery/atmospherics/pipe/simple/visible/universal/update_underlays() - ..() - update_icon() - - - -/obj/machinery/atmospherics/pipe/simple/hidden/universal - name="Universal pipe adapter" - desc = "An adapter for regular, supply and scrubbers pipes" - connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SUPPLY|CONNECT_TYPE_SCRUBBER - icon_state = "map_universal" - -/obj/machinery/atmospherics/pipe/simple/hidden/universal/update_icon(var/safety = 0) - if(!check_icon_cache()) - return - - alpha = 255 - - overlays.Cut() - overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "universal") - underlays.Cut() - - if (node1) - universal_underlays(node1) - if(node2) - universal_underlays(node2) - else - var/node2_dir = turn(get_dir(src,node1),-180) - universal_underlays(,node2_dir) - else if (node2) - universal_underlays(node2) - var/node1_dir = turn(get_dir(src,node2),-180) - universal_underlays(,node1_dir) - else - universal_underlays(,dir) - universal_underlays(,turn(dir, -180)) - -/obj/machinery/atmospherics/pipe/simple/hidden/universal/update_underlays() - ..() - update_icon() - -/obj/machinery/atmospherics/proc/universal_underlays(var/obj/machinery/atmospherics/node, var/direction) - var/turf/T = loc - if(node) - var/node_dir = get_dir(src,node) - if(node.icon_connect_type == "-supply") - add_underlay_adapter(T, , node_dir, "") - add_underlay_adapter(T, node, node_dir, "-supply") - add_underlay_adapter(T, , node_dir, "-scrubbers") - else if (node.icon_connect_type == "-scrubbers") - add_underlay_adapter(T, , node_dir, "") - add_underlay_adapter(T, , node_dir, "-supply") - add_underlay_adapter(T, node, node_dir, "-scrubbers") - else - add_underlay_adapter(T, node, node_dir, "") - add_underlay_adapter(T, , node_dir, "-supply") - add_underlay_adapter(T, , node_dir, "-scrubbers") - else - add_underlay_adapter(T, , direction, "-supply") - add_underlay_adapter(T, , direction, "-scrubbers") - add_underlay_adapter(T, , direction, "") - -/obj/machinery/atmospherics/proc/add_underlay_adapter(var/turf/T, var/obj/machinery/atmospherics/node, var/direction, var/icon_connect_type) //modified from add_underlay, does not make exposed underlays - if(node) - if(!T.is_plating() && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe)) - underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "down" + icon_connect_type) - else - underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "intact" + icon_connect_type) - else - underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "retracted" + icon_connect_type) diff --git a/code/ATMOSPHERICS/pipes/cap.dm b/code/ATMOSPHERICS/pipes/cap.dm new file mode 100644 index 0000000000..4658b9c40c --- /dev/null +++ b/code/ATMOSPHERICS/pipes/cap.dm @@ -0,0 +1,119 @@ +// +// Pipe Cap - They go on the end +// +/obj/machinery/atmospherics/pipe/cap + name = "pipe endcap" + desc = "An endcap for pipes" + icon = 'icons/atmos/pipes.dmi' + icon_state = "" + level = 2 + + volume = 35 + + dir = SOUTH + initialize_directions = SOUTH + + construction_type = /obj/item/pipe/directional + pipe_state = "cap" + + var/obj/machinery/atmospherics/node + +/obj/machinery/atmospherics/pipe/cap/init_dir() + initialize_directions = dir + +/obj/machinery/atmospherics/pipe/cap/pipeline_expansion() + return list(node) + +/obj/machinery/atmospherics/pipe/cap/Destroy() + if(node) + node.disconnect(src) + node = null + + . = ..() + +/obj/machinery/atmospherics/pipe/cap/disconnect(obj/machinery/atmospherics/reference) + if(reference == node) + if(istype(node, /obj/machinery/atmospherics/pipe)) + qdel(parent) + node = null + + update_icon() + + ..() + +/obj/machinery/atmospherics/pipe/cap/change_color(var/new_color) + ..() + //for updating connected atmos device pipes (i.e. vents, manifolds, etc) + if(node) + node.update_underlays() + +/obj/machinery/atmospherics/pipe/cap/update_icon(var/safety = 0) + if(!check_icon_cache()) + return + + alpha = 255 + + overlays.Cut() + overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "cap") + +/obj/machinery/atmospherics/pipe/cap/atmos_init() + for(var/obj/machinery/atmospherics/target in get_step(src, dir)) + if (can_be_node(target, 1)) + node = target + break + + var/turf/T = src.loc // hide if turf is not intact + if(level == 1 && !T.is_plating()) hide(1) + update_icon() + +/obj/machinery/atmospherics/pipe/cap/can_unwrench() + return 1 + +/obj/machinery/atmospherics/pipe/cap/visible + level = 2 + icon_state = "cap" + +/obj/machinery/atmospherics/pipe/cap/visible/scrubbers + name = "scrubbers pipe endcap" + desc = "An endcap for scrubbers pipes" + icon_state = "cap-scrubbers" + connect_types = CONNECT_TYPE_SCRUBBER + piping_layer = PIPING_LAYER_SCRUBBER + layer = 2.38 + icon_connect_type = "-scrubbers" + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/cap/visible/supply + name = "supply pipe endcap" + desc = "An endcap for supply pipes" + icon_state = "cap-supply" + connect_types = CONNECT_TYPE_SUPPLY + piping_layer = PIPING_LAYER_SUPPLY + layer = 2.39 + icon_connect_type = "-supply" + color = PIPE_COLOR_BLUE + +/obj/machinery/atmospherics/pipe/cap/hidden + level = 1 + icon_state = "cap" + alpha = 128 + +/obj/machinery/atmospherics/pipe/cap/hidden/scrubbers + name = "scrubbers pipe endcap" + desc = "An endcap for scrubbers pipes" + icon_state = "cap-f-scrubbers" + connect_types = CONNECT_TYPE_SCRUBBER + piping_layer = PIPING_LAYER_SCRUBBER + layer = 2.38 + icon_connect_type = "-scrubbers" + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/cap/hidden/supply + name = "supply pipe endcap" + desc = "An endcap for supply pipes" + icon_state = "cap-f-supply" + connect_types = CONNECT_TYPE_SUPPLY + piping_layer = PIPING_LAYER_SUPPLY + layer = 2.39 + icon_connect_type = "-supply" + color = PIPE_COLOR_BLUE diff --git a/code/ATMOSPHERICS/he_pipes.dm b/code/ATMOSPHERICS/pipes/he_pipes.dm similarity index 74% rename from code/ATMOSPHERICS/he_pipes.dm rename to code/ATMOSPHERICS/pipes/he_pipes.dm index bff838cfdd..fe6580b1ce 100644 --- a/code/ATMOSPHERICS/he_pipes.dm +++ b/code/ATMOSPHERICS/pipes/he_pipes.dm @@ -1,153 +1,183 @@ - -/obj/machinery/atmospherics/pipe/simple/heat_exchanging - icon = 'icons/atmos/heat.dmi' - icon_state = "intact" - pipe_icon = "hepipe" - color = "#404040" - level = 2 - connect_types = CONNECT_TYPE_HE - layer = 2.41 - var/initialize_directions_he - var/surface = 2 //surface area in m^2 - var/icon_temperature = T20C //stop small changes in temperature causing an icon refresh - - minimum_temperature_difference = 20 - thermal_conductivity = OPEN_HEAT_TRANSFER_COEFFICIENT - - buckle_lying = 1 - - // BubbleWrap -/obj/machinery/atmospherics/pipe/simple/heat_exchanging/New() - ..() -// BubbleWrap END - color = "#404040" //we don't make use of the fancy overlay system for colours, use this to set the default. - -/obj/machinery/atmospherics/pipe/simple/heat_exchanging/init_dir() - ..() - initialize_directions_he = initialize_directions // The auto-detection from /pipe is good enough for a simple HE pipe - -/obj/machinery/atmospherics/pipe/simple/heat_exchanging/atmos_init() - normalize_dir() - var/node1_dir - var/node2_dir - - for(var/direction in cardinal) - if(direction&initialize_directions_he) - if (!node1_dir) - node1_dir = direction - else if (!node2_dir) - node2_dir = direction - - for(var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/target in get_step(src,node1_dir)) - if(target.initialize_directions_he & get_dir(target,src)) - node1 = target - break - for(var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/target in get_step(src,node2_dir)) - if(target.initialize_directions_he & get_dir(target,src)) - node2 = target - break - if(!node1 && !node2) - qdel(src) - return - - update_icon() - return - - -/obj/machinery/atmospherics/pipe/simple/heat_exchanging/process() - if(!parent) - ..() - else - var/datum/gas_mixture/pipe_air = return_air() - if(istype(loc, /turf/simulated/)) - var/environment_temperature = 0 - if(loc:blocks_air) - environment_temperature = loc:temperature - else - var/datum/gas_mixture/environment = loc.return_air() - environment_temperature = environment.temperature - if(abs(environment_temperature-pipe_air.temperature) > minimum_temperature_difference) - parent.temperature_interact(loc, volume, thermal_conductivity) - else if(istype(loc, /turf/space/)) - parent.radiate_heat_to_space(surface, 1) - - if(has_buckled_mobs()) - for(var/M in buckled_mobs) - var/mob/living/L = M - - var/hc = pipe_air.heat_capacity() - var/avg_temp = (pipe_air.temperature * hc + L.bodytemperature * 3500) / (hc + 3500) - pipe_air.temperature = avg_temp - L.bodytemperature = avg_temp - - var/heat_limit = 1000 - - var/mob/living/carbon/human/H = L - if(istype(H) && H.species) - heat_limit = H.species.heat_level_3 - - if(pipe_air.temperature > heat_limit + 1) - L.apply_damage(4 * log(pipe_air.temperature - heat_limit), BURN, BP_TORSO, used_weapon = "Excessive Heat") - - //fancy radiation glowing - if(pipe_air.temperature && (icon_temperature > 500 || pipe_air.temperature > 500)) //start glowing at 500K - if(abs(pipe_air.temperature - icon_temperature) > 10) - icon_temperature = pipe_air.temperature - - var/h_r = heat2color_r(icon_temperature) - var/h_g = heat2color_g(icon_temperature) - var/h_b = heat2color_b(icon_temperature) - - if(icon_temperature < 2000) //scale up overlay until 2000K - var/scale = (icon_temperature - 500) / 1500 - h_r = 64 + (h_r - 64)*scale - h_g = 64 + (h_g - 64)*scale - h_b = 64 + (h_b - 64)*scale - - animate(src, color = rgb(h_r, h_g, h_b), time = 20, easing = SINE_EASING) - - - - -/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction - icon = 'icons/atmos/junction.dmi' - icon_state = "intact" - pipe_icon = "hejunction" - level = 2 - connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_HE - minimum_temperature_difference = 300 - thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT - -/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction/init_dir() - ..() - switch ( dir ) - if ( SOUTH ) - initialize_directions = NORTH - initialize_directions_he = SOUTH - if ( NORTH ) - initialize_directions = SOUTH - initialize_directions_he = NORTH - if ( EAST ) - initialize_directions = WEST - initialize_directions_he = EAST - if ( WEST ) - initialize_directions = EAST - initialize_directions_he = WEST - - -/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction/atmos_init() - for(var/obj/machinery/atmospherics/target in get_step(src,initialize_directions)) - if(target.initialize_directions & get_dir(target,src)) - node1 = target - break - for(var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/target in get_step(src,initialize_directions_he)) - if(target.initialize_directions_he & get_dir(target,src)) - node2 = target - break - - if(!node1&&!node2) - qdel(src) - return - - update_icon() - return +// +// Heat Exchanging Pipes - Behave like simple pipes +// +/obj/machinery/atmospherics/pipe/simple/heat_exchanging + icon = 'icons/atmos/heat.dmi' + icon_state = "intact" + pipe_icon = "hepipe" + color = "#404040" + level = 2 + connect_types = CONNECT_TYPE_HE + pipe_flags = PIPING_DEFAULT_LAYER_ONLY + construction_type = /obj/item/pipe/binary/bendable + pipe_state = "he" + + layer = 2.41 + var/initialize_directions_he + var/surface = 2 //surface area in m^2 + var/icon_temperature = T20C //stop small changes in temperature causing an icon refresh + + minimum_temperature_difference = 20 + thermal_conductivity = OPEN_HEAT_TRANSFER_COEFFICIENT + + buckle_lying = 1 + + // BubbleWrap +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/New() + ..() +// BubbleWrap END + color = "#404040" //we don't make use of the fancy overlay system for colours, use this to set the default. + +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/init_dir() + ..() + initialize_directions_he = initialize_directions // The auto-detection from /pipe is good enough for a simple HE pipe + initialize_directions = 0 + +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/get_init_dirs() + return ..() | initialize_directions_he + +// Use initialize_directions_he to connect to neighbors instead. +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/can_be_node(var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/target) + if(!istype(target)) + return FALSE + return (target.initialize_directions_he & get_dir(target,src)) && check_connectable(target) && target.check_connectable(src) + +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/atmos_init() + normalize_dir() + var/node1_dir + var/node2_dir + + for(var/direction in cardinal) + if(direction&initialize_directions_he) + if (!node1_dir) + node1_dir = direction + else if (!node2_dir) + node2_dir = direction + + for(var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/target in get_step(src,node1_dir)) + if(can_be_node(target, 1)) + node1 = target + break + for(var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/target in get_step(src,node2_dir)) + if(can_be_node(target, 2)) + node2 = target + break + if(!node1 && !node2) + qdel(src) + return + + update_icon() + return + + +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/process() + if(!parent) + ..() + else + var/datum/gas_mixture/pipe_air = return_air() + if(istype(loc, /turf/simulated/)) + var/environment_temperature = 0 + if(loc:blocks_air) + environment_temperature = loc:temperature + else + var/datum/gas_mixture/environment = loc.return_air() + environment_temperature = environment.temperature + if(abs(environment_temperature-pipe_air.temperature) > minimum_temperature_difference) + parent.temperature_interact(loc, volume, thermal_conductivity) + else if(istype(loc, /turf/space/)) + parent.radiate_heat_to_space(surface, 1) + + if(has_buckled_mobs()) + for(var/M in buckled_mobs) + var/mob/living/L = M + + var/hc = pipe_air.heat_capacity() + var/avg_temp = (pipe_air.temperature * hc + L.bodytemperature * 3500) / (hc + 3500) + pipe_air.temperature = avg_temp + L.bodytemperature = avg_temp + + var/heat_limit = 1000 + + var/mob/living/carbon/human/H = L + if(istype(H) && H.species) + heat_limit = H.species.heat_level_3 + + if(pipe_air.temperature > heat_limit + 1) + L.apply_damage(4 * log(pipe_air.temperature - heat_limit), BURN, BP_TORSO, used_weapon = "Excessive Heat") + + //fancy radiation glowing + if(pipe_air.temperature && (icon_temperature > 500 || pipe_air.temperature > 500)) //start glowing at 500K + if(abs(pipe_air.temperature - icon_temperature) > 10) + icon_temperature = pipe_air.temperature + + var/h_r = heat2color_r(icon_temperature) + var/h_g = heat2color_g(icon_temperature) + var/h_b = heat2color_b(icon_temperature) + + if(icon_temperature < 2000) //scale up overlay until 2000K + var/scale = (icon_temperature - 500) / 1500 + h_r = 64 + (h_r - 64)*scale + h_g = 64 + (h_g - 64)*scale + h_b = 64 + (h_b - 64)*scale + + animate(src, color = rgb(h_r, h_g, h_b), time = 20, easing = SINE_EASING) + +// +// Heat Exchange Junction - Interfaces HE pipes to normal pipes +// +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction + icon = 'icons/atmos/junction.dmi' + icon_state = "intact" + pipe_icon = "hejunction" + level = 2 + connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_HE + construction_type = /obj/item/pipe/directional + pipe_state = "junction" + minimum_temperature_difference = 300 + thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT + +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction/init_dir() + ..() + switch ( dir ) + if ( SOUTH ) + initialize_directions = NORTH + initialize_directions_he = SOUTH + if ( NORTH ) + initialize_directions = SOUTH + initialize_directions_he = NORTH + if ( EAST ) + initialize_directions = WEST + initialize_directions_he = EAST + if ( WEST ) + initialize_directions = EAST + initialize_directions_he = WEST + + // Allow ourselves to make connections to either HE or normal pipes depending on which node we are doing. +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction/can_be_node(obj/machinery/atmospherics/target, node_num) + var/target_initialize_directions + switch(node_num) + if(1) + target_initialize_directions = target.initialize_directions // Node1 is towards normal pipes + if(2) + var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/H = target + if(!istype(H)) + return FALSE + target_initialize_directions = H.initialize_directions_he // Node2 is towards HE pies. + return (target_initialize_directions & get_dir(target,src)) && check_connectable(target) && target.check_connectable(src) + +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction/atmos_init() + for(var/obj/machinery/atmospherics/target in get_step(src,initialize_directions)) + if(target.initialize_directions & get_dir(target,src)) + node1 = target + break + for(var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/target in get_step(src,initialize_directions_he)) + if(target.initialize_directions_he & get_dir(target,src)) + node2 = target + break + + if(!node1&&!node2) + qdel(src) + return + + update_icon() + return diff --git a/code/ATMOSPHERICS/pipes/manifold.dm b/code/ATMOSPHERICS/pipes/manifold.dm new file mode 100644 index 0000000000..bca6dd3379 --- /dev/null +++ b/code/ATMOSPHERICS/pipes/manifold.dm @@ -0,0 +1,248 @@ +// +// Manifold Pipes - Three way "T" joints +// +/obj/machinery/atmospherics/pipe/manifold + icon = 'icons/atmos/manifold.dmi' + icon_state = "" + name = "pipe manifold" + desc = "A manifold composed of regular pipes" + + volume = ATMOS_DEFAULT_VOLUME_PIPE * 1.5 + + dir = SOUTH + initialize_directions = EAST|NORTH|WEST + + construction_type = /obj/item/pipe/trinary + pipe_state = "manifold" + + var/obj/machinery/atmospherics/node3 + + level = 1 + layer = 2.4 //under wires with their 2.44 + +/obj/machinery/atmospherics/pipe/manifold/New() + ..() + alpha = 255 + icon = null + +/obj/machinery/atmospherics/pipe/manifold/init_dir() + switch(dir) + if(NORTH) + initialize_directions = EAST|SOUTH|WEST + if(SOUTH) + initialize_directions = WEST|NORTH|EAST + if(EAST) + initialize_directions = SOUTH|WEST|NORTH + if(WEST) + initialize_directions = NORTH|EAST|SOUTH + +/obj/machinery/atmospherics/pipe/manifold/pipeline_expansion() + return list(node1, node2, node3) + +/obj/machinery/atmospherics/pipe/manifold/Destroy() + if(node1) + node1.disconnect(src) + node1 = null + if(node2) + node2.disconnect(src) + node2 = null + if(node3) + node3.disconnect(src) + node3 = null + + . = ..() + +/obj/machinery/atmospherics/pipe/manifold/disconnect(obj/machinery/atmospherics/reference) + if(reference == node1) + if(istype(node1, /obj/machinery/atmospherics/pipe)) + qdel(parent) + node1 = null + + if(reference == node2) + if(istype(node2, /obj/machinery/atmospherics/pipe)) + qdel(parent) + node2 = null + + if(reference == node3) + if(istype(node3, /obj/machinery/atmospherics/pipe)) + qdel(parent) + node3 = null + + update_icon() + + ..() + +/obj/machinery/atmospherics/pipe/manifold/change_color(var/new_color) + ..() + //for updating connected atmos device pipes (i.e. vents, manifolds, etc) + if(node1) + node1.update_underlays() + if(node2) + node2.update_underlays() + if(node3) + node3.update_underlays() + +/obj/machinery/atmospherics/pipe/manifold/update_icon(var/safety = 0) + if(!check_icon_cache()) + return + + alpha = 255 + + overlays.Cut() + overlays += icon_manager.get_atmos_icon("manifold", , pipe_color, "core" + icon_connect_type) + overlays += icon_manager.get_atmos_icon("manifold", , , "clamps" + icon_connect_type) + underlays.Cut() + + var/turf/T = get_turf(src) + var/list/directions = list(NORTH, SOUTH, EAST, WEST) + var/node1_direction = get_dir(src, node1) + var/node2_direction = get_dir(src, node2) + var/node3_direction = get_dir(src, node3) + + directions -= dir + + directions -= add_underlay(T,node1,node1_direction,icon_connect_type) + directions -= add_underlay(T,node2,node2_direction,icon_connect_type) + directions -= add_underlay(T,node3,node3_direction,icon_connect_type) + + for(var/D in directions) + add_underlay(T,,D,icon_connect_type) + + +/obj/machinery/atmospherics/pipe/manifold/update_underlays() + ..() + update_icon() + +/obj/machinery/atmospherics/pipe/manifold/atmos_init() + var/connect_directions = (NORTH|SOUTH|EAST|WEST)&(~dir) + + for(var/direction in cardinal) + if(direction&connect_directions) + for(var/obj/machinery/atmospherics/target in get_step(src,direction)) + if (can_be_node(target, 1)) + node1 = target + connect_directions &= ~direction + break + if (node1) + break + + + for(var/direction in cardinal) + if(direction&connect_directions) + for(var/obj/machinery/atmospherics/target in get_step(src,direction)) + if (can_be_node(target, 2)) + node2 = target + connect_directions &= ~direction + break + if (node2) + break + + + for(var/direction in cardinal) + if(direction&connect_directions) + for(var/obj/machinery/atmospherics/target in get_step(src,direction)) + if (can_be_node(target, 3)) + node3 = target + connect_directions &= ~direction + break + if (node3) + break + + if(!node1 && !node2 && !node3) + qdel(src) + return + + var/turf/T = get_turf(src) + if(level == 1 && !T.is_plating()) hide(1) + update_icon() + +/obj/machinery/atmospherics/pipe/manifold/visible + icon_state = "map" + level = 2 + +/obj/machinery/atmospherics/pipe/manifold/visible/scrubbers + name="Scrubbers pipe manifold" + desc = "A manifold composed of scrubbers pipes" + icon_state = "map-scrubbers" + connect_types = CONNECT_TYPE_SCRUBBER + piping_layer = PIPING_LAYER_SCRUBBER + layer = 2.38 + icon_connect_type = "-scrubbers" + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/manifold/visible/supply + name="Air supply pipe manifold" + desc = "A manifold composed of supply pipes" + icon_state = "map-supply" + connect_types = CONNECT_TYPE_SUPPLY + piping_layer = PIPING_LAYER_SUPPLY + layer = 2.39 + icon_connect_type = "-supply" + color = PIPE_COLOR_BLUE + +/obj/machinery/atmospherics/pipe/manifold/visible/yellow + color = PIPE_COLOR_YELLOW + +/obj/machinery/atmospherics/pipe/manifold/visible/cyan + color = PIPE_COLOR_CYAN + +/obj/machinery/atmospherics/pipe/manifold/visible/green + color = PIPE_COLOR_GREEN + +/obj/machinery/atmospherics/pipe/manifold/visible/black + color = PIPE_COLOR_BLACK + +/obj/machinery/atmospherics/pipe/manifold/visible/red + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/manifold/visible/blue + color = PIPE_COLOR_BLUE + +/obj/machinery/atmospherics/pipe/manifold/visible/purple + color = PIPE_COLOR_PURPLE + +/obj/machinery/atmospherics/pipe/manifold/hidden + icon_state = "map" + level = 1 + alpha = 128 //set for the benefit of mapping - this is reset to opaque when the pipe is spawned in game + +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers + name="Scrubbers pipe manifold" + desc = "A manifold composed of scrubbers pipes" + icon_state = "map-scrubbers" + connect_types = CONNECT_TYPE_SCRUBBER + piping_layer = PIPING_LAYER_SCRUBBER + layer = 2.38 + icon_connect_type = "-scrubbers" + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/manifold/hidden/supply + name="Air supply pipe manifold" + desc = "A manifold composed of supply pipes" + icon_state = "map-supply" + connect_types = CONNECT_TYPE_SUPPLY + piping_layer = PIPING_LAYER_SUPPLY + layer = 2.39 + icon_connect_type = "-supply" + color = PIPE_COLOR_BLUE + +/obj/machinery/atmospherics/pipe/manifold/hidden/yellow + color = PIPE_COLOR_YELLOW + +/obj/machinery/atmospherics/pipe/manifold/hidden/cyan + color = PIPE_COLOR_CYAN + +/obj/machinery/atmospherics/pipe/manifold/hidden/green + color = PIPE_COLOR_GREEN + +/obj/machinery/atmospherics/pipe/manifold/hidden/black + color = PIPE_COLOR_BLACK + +/obj/machinery/atmospherics/pipe/manifold/hidden/red + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/manifold/hidden/blue + color = PIPE_COLOR_BLUE + +/obj/machinery/atmospherics/pipe/manifold/hidden/purple + color = PIPE_COLOR_PURPLE diff --git a/code/ATMOSPHERICS/pipes/manifold4w.dm b/code/ATMOSPHERICS/pipes/manifold4w.dm new file mode 100644 index 0000000000..88adc47d62 --- /dev/null +++ b/code/ATMOSPHERICS/pipes/manifold4w.dm @@ -0,0 +1,250 @@ +// +// 4-Way Manifold Pipes - 4 way "cross" junction +// +/obj/machinery/atmospherics/pipe/manifold4w + icon = 'icons/atmos/manifold.dmi' + icon_state = "" + name = "4-way pipe manifold" + desc = "A manifold composed of regular pipes" + + volume = ATMOS_DEFAULT_VOLUME_PIPE * 2 + + dir = SOUTH + initialize_directions = NORTH|SOUTH|EAST|WEST + + construction_type = /obj/item/pipe/quaternary + pipe_state = "manifold4w" + + var/obj/machinery/atmospherics/node3 + var/obj/machinery/atmospherics/node4 + + level = 1 + layer = 2.4 //under wires with their 2.44 + +/obj/machinery/atmospherics/pipe/manifold4w/New() + ..() + alpha = 255 + icon = null + +/obj/machinery/atmospherics/pipe/manifold4w/pipeline_expansion() + return list(node1, node2, node3, node4) + +/obj/machinery/atmospherics/pipe/manifold4w/Destroy() + if(node1) + node1.disconnect(src) + node1 = null + if(node2) + node2.disconnect(src) + node2 = null + if(node3) + node3.disconnect(src) + node3 = null + if(node4) + node4.disconnect(src) + node4 = null + + . = ..() + +/obj/machinery/atmospherics/pipe/manifold4w/disconnect(obj/machinery/atmospherics/reference) + if(reference == node1) + if(istype(node1, /obj/machinery/atmospherics/pipe)) + qdel(parent) + node1 = null + + if(reference == node2) + if(istype(node2, /obj/machinery/atmospherics/pipe)) + qdel(parent) + node2 = null + + if(reference == node3) + if(istype(node3, /obj/machinery/atmospherics/pipe)) + qdel(parent) + node3 = null + + if(reference == node4) + if(istype(node4, /obj/machinery/atmospherics/pipe)) + qdel(parent) + node4 = null + + update_icon() + + ..() + +/obj/machinery/atmospherics/pipe/manifold4w/change_color(var/new_color) + ..() + //for updating connected atmos device pipes (i.e. vents, manifolds, etc) + if(node1) + node1.update_underlays() + if(node2) + node2.update_underlays() + if(node3) + node3.update_underlays() + if(node4) + node4.update_underlays() + +/obj/machinery/atmospherics/pipe/manifold4w/update_icon(var/safety = 0) + if(!check_icon_cache()) + return + + alpha = 255 + + overlays.Cut() + overlays += icon_manager.get_atmos_icon("manifold", , pipe_color, "4way" + icon_connect_type) + overlays += icon_manager.get_atmos_icon("manifold", , , "clamps_4way" + icon_connect_type) + underlays.Cut() + + /* + var/list/directions = list(NORTH, SOUTH, EAST, WEST) + + + directions -= add_underlay(node1) + directions -= add_underlay(node2) + directions -= add_underlay(node3) + directions -= add_underlay(node4) + + for(var/D in directions) + add_underlay(,D) + */ + + var/turf/T = get_turf(src) + var/list/directions = list(NORTH, SOUTH, EAST, WEST) + var/node1_direction = get_dir(src, node1) + var/node2_direction = get_dir(src, node2) + var/node3_direction = get_dir(src, node3) + var/node4_direction = get_dir(src, node4) + + directions -= dir + + directions -= add_underlay(T,node1,node1_direction,icon_connect_type) + directions -= add_underlay(T,node2,node2_direction,icon_connect_type) + directions -= add_underlay(T,node3,node3_direction,icon_connect_type) + directions -= add_underlay(T,node4,node4_direction,icon_connect_type) + + for(var/D in directions) + add_underlay(T,,D,icon_connect_type) + + +/obj/machinery/atmospherics/pipe/manifold4w/update_underlays() + ..() + update_icon() + +/obj/machinery/atmospherics/pipe/manifold4w/atmos_init() + + for(var/obj/machinery/atmospherics/target in get_step(src, NORTH)) + if (can_be_node(target, 1)) + node1 = target + break + + for(var/obj/machinery/atmospherics/target in get_step(src, SOUTH)) + if (can_be_node(target, 2)) + node2 = target + break + + for(var/obj/machinery/atmospherics/target in get_step(src, EAST)) + if (can_be_node(target, 3)) + node3 = target + break + + for(var/obj/machinery/atmospherics/target in get_step(src, WEST)) + if (can_be_node(target, 4)) + node4 = target + break + + if(!node1 && !node2 && !node3 && !node4) + qdel(src) + return + + var/turf/T = get_turf(src) + if(level == 1 && !T.is_plating()) hide(1) + update_icon() + +/obj/machinery/atmospherics/pipe/manifold4w/visible + icon_state = "map_4way" + level = 2 + +/obj/machinery/atmospherics/pipe/manifold4w/visible/scrubbers + name="4-way scrubbers pipe manifold" + desc = "A manifold composed of scrubbers pipes" + icon_state = "map_4way-scrubbers" + connect_types = CONNECT_TYPE_SCRUBBER + piping_layer = PIPING_LAYER_SCRUBBER + layer = 2.38 + icon_connect_type = "-scrubbers" + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/manifold4w/visible/supply + name="4-way air supply pipe manifold" + desc = "A manifold composed of supply pipes" + icon_state = "map_4way-supply" + connect_types = CONNECT_TYPE_SUPPLY + piping_layer = PIPING_LAYER_SUPPLY + layer = 2.39 + icon_connect_type = "-supply" + color = PIPE_COLOR_BLUE + +/obj/machinery/atmospherics/pipe/manifold4w/visible/yellow + color = PIPE_COLOR_YELLOW + +/obj/machinery/atmospherics/pipe/manifold4w/visible/cyan + color = PIPE_COLOR_CYAN + +/obj/machinery/atmospherics/pipe/manifold4w/visible/green + color = PIPE_COLOR_GREEN + +/obj/machinery/atmospherics/pipe/manifold4w/visible/black + color = PIPE_COLOR_BLACK + +/obj/machinery/atmospherics/pipe/manifold4w/visible/red + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/manifold4w/visible/blue + color = PIPE_COLOR_BLUE + +/obj/machinery/atmospherics/pipe/manifold4w/visible/purple + color = PIPE_COLOR_PURPLE + +/obj/machinery/atmospherics/pipe/manifold4w/hidden + icon_state = "map_4way" + level = 1 + alpha = 128 //set for the benefit of mapping - this is reset to opaque when the pipe is spawned in game + +/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers + name="4-way scrubbers pipe manifold" + desc = "A manifold composed of scrubbers pipes" + icon_state = "map_4way-scrubbers" + connect_types = CONNECT_TYPE_SCRUBBER + piping_layer = PIPING_LAYER_SCRUBBER + layer = 2.38 + icon_connect_type = "-scrubbers" + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply + name="4-way air supply pipe manifold" + desc = "A manifold composed of supply pipes" + icon_state = "map_4way-supply" + connect_types = CONNECT_TYPE_SUPPLY + piping_layer = PIPING_LAYER_SUPPLY + layer = 2.39 + icon_connect_type = "-supply" + color = PIPE_COLOR_BLUE + +/obj/machinery/atmospherics/pipe/manifold4w/hidden/yellow + color = PIPE_COLOR_YELLOW + +/obj/machinery/atmospherics/pipe/manifold4w/hidden/cyan + color = PIPE_COLOR_CYAN + +/obj/machinery/atmospherics/pipe/manifold4w/hidden/green + color = PIPE_COLOR_GREEN + +/obj/machinery/atmospherics/pipe/manifold4w/hidden/black + color = PIPE_COLOR_BLACK + +/obj/machinery/atmospherics/pipe/manifold4w/hidden/red + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/manifold4w/hidden/blue + color = PIPE_COLOR_BLUE + +/obj/machinery/atmospherics/pipe/manifold4w/hidden/purple + color = PIPE_COLOR_PURPLE diff --git a/code/ATMOSPHERICS/pipes/pipe_base.dm b/code/ATMOSPHERICS/pipes/pipe_base.dm new file mode 100644 index 0000000000..4e852ed0c8 --- /dev/null +++ b/code/ATMOSPHERICS/pipes/pipe_base.dm @@ -0,0 +1,142 @@ +// +// Base type of pipes +// +/obj/machinery/atmospherics/pipe + + var/datum/gas_mixture/air_temporary // used when reconstructing a pipeline that broke + var/datum/pipeline/parent + var/volume = 0 + + layer = 2.4 //under wires with their 2.44 + use_power = 0 + + pipe_flags = 0 // Does not have PIPING_DEFAULT_LAYER_ONLY flag. + + var/alert_pressure = 80*ONE_ATMOSPHERE + //minimum pressure before check_pressure(...) should be called + + can_buckle = 1 + buckle_require_restraints = 1 + buckle_lying = -1 + +/obj/machinery/atmospherics/pipe/drain_power() + return -1 + +/obj/machinery/atmospherics/pipe/New() + if(istype(get_turf(src), /turf/simulated/wall) || istype(get_turf(src), /turf/simulated/shuttle/wall) || istype(get_turf(src), /turf/unsimulated/wall)) + level = 1 + ..() + +/obj/machinery/atmospherics/pipe/hides_under_flooring() + return level != 2 + +/obj/machinery/atmospherics/pipe/proc/pipeline_expansion() + return null + +// For pipes this is the same as pipeline_expansion() +/obj/machinery/atmospherics/pipe/get_neighbor_nodes_for_init() + return pipeline_expansion() + +/obj/machinery/atmospherics/pipe/proc/check_pressure(pressure) + //Return 1 if parent should continue checking other pipes + //Return null if parent should stop checking other pipes. Recall: qdel(src) will by default return null + + return 1 + +/obj/machinery/atmospherics/pipe/return_air() + if(!parent) + parent = new /datum/pipeline() + parent.build_pipeline(src) + + return parent.air + +/obj/machinery/atmospherics/pipe/build_network() + if(!parent) + parent = new /datum/pipeline() + parent.build_pipeline(src) + + return parent.return_network() + +/obj/machinery/atmospherics/pipe/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference) + if(!parent) + parent = new /datum/pipeline() + parent.build_pipeline(src) + + return parent.network_expand(new_network, reference) + +/obj/machinery/atmospherics/pipe/return_network(obj/machinery/atmospherics/reference) + if(!parent) + parent = new /datum/pipeline() + parent.build_pipeline(src) + + return parent.return_network(reference) + +/obj/machinery/atmospherics/pipe/Destroy() + qdel_null(parent) + if(air_temporary) + loc.assume_air(air_temporary) + for(var/obj/machinery/meter/meter in loc) + if(meter.target == src) + var/obj/item/pipe_meter/PM = new /obj/item/pipe_meter(loc) + meter.transfer_fingerprints_to(PM) + qdel(meter) + . = ..() + +/obj/machinery/atmospherics/pipe/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) + if (istype(src, /obj/machinery/atmospherics/pipe/tank)) + return ..() + + if(istype(W,/obj/item/device/pipe_painter)) + return 0 + + if (!istype(W, /obj/item/weapon/wrench)) + return ..() + var/turf/T = src.loc + if (level==1 && isturf(T) && !T.is_plating()) + to_chat(user, "You must remove the plating first.") + return 1 + if(!can_unwrench()) + to_chat(user, "You cannot unwrench \the [src], it is too exerted due to internal pressure.") + add_fingerprint(user) + return 1 + playsound(src, W.usesound, 50, 1) + to_chat(user, "You begin to unfasten \the [src]...") + if (do_after(user, 40 * W.toolspeed)) + user.visible_message( \ + "\The [user] unfastens \the [src].", \ + "You have unfastened \the [src].", \ + "You hear a ratchet.") + deconstruct() + +/obj/machinery/atmospherics/pipe/proc/change_color(var/new_color) + //only pass valid pipe colors please ~otherwise your pipe will turn invisible + if(!pipe_color_check(new_color)) + return + + pipe_color = new_color + update_icon() + +/obj/machinery/atmospherics/pipe/color_cache_name(var/obj/machinery/atmospherics/node) + if(istype(src, /obj/machinery/atmospherics/pipe/tank)) + return ..() + + if(istype(node, /obj/machinery/atmospherics/pipe/manifold) || istype(node, /obj/machinery/atmospherics/pipe/manifold4w)) + if(pipe_color == node.pipe_color) + return node.pipe_color + else + return null + else if(istype(node, /obj/machinery/atmospherics/pipe/simple)) + return node.pipe_color + else + return pipe_color + +/obj/machinery/atmospherics/pipe/hide(var/i) + if(istype(loc, /turf/simulated)) + invisibility = i ? 101 : 0 + update_icon() + +/obj/machinery/atmospherics/pipe/process() + if(!parent) //This should cut back on the overhead calling build_network thousands of times per cycle + ..() + else + . = PROCESS_KILL diff --git a/code/ATMOSPHERICS/pipes/simple.dm b/code/ATMOSPHERICS/pipes/simple.dm new file mode 100644 index 0000000000..77290e5d8a --- /dev/null +++ b/code/ATMOSPHERICS/pipes/simple.dm @@ -0,0 +1,270 @@ +// +// Simple Pipes - Just a tube, maybe bent +// +/obj/machinery/atmospherics/pipe/simple + icon = 'icons/atmos/pipes.dmi' + icon_state = "" + var/pipe_icon = "" //what kind of pipe it is and from which dmi is the icon manager getting its icons, "" for simple pipes, "hepipe" for HE pipes, "hejunction" for HE junctions + name = "pipe" + desc = "A one meter section of regular pipe" + + volume = ATMOS_DEFAULT_VOLUME_PIPE + + dir = SOUTH + initialize_directions = SOUTH|NORTH + + pipe_flags = PIPING_CARDINAL_AUTONORMALIZE + construction_type = /obj/item/pipe/binary/bendable + pipe_state = "simple" + + var/minimum_temperature_difference = 300 + var/thermal_conductivity = 0 //WALL_HEAT_TRANSFER_COEFFICIENT No + + var/maximum_pressure = 70*ONE_ATMOSPHERE + var/fatigue_pressure = 55*ONE_ATMOSPHERE + alert_pressure = 55*ONE_ATMOSPHERE + + level = 1 + +/obj/machinery/atmospherics/pipe/simple/New() + ..() + + // Pipe colors and icon states are handled by an image cache - so color and icon should + // be null. For mapping purposes color is defined in the object definitions. + icon = null + alpha = 255 + +/obj/machinery/atmospherics/pipe/simple/check_pressure(pressure) + var/datum/gas_mixture/environment = loc.return_air() + + var/pressure_difference = pressure - environment.return_pressure() + + if(pressure_difference > maximum_pressure) + burst() + + else if(pressure_difference > fatigue_pressure) + //TODO: leak to turf, doing pfshhhhh + if(prob(5)) + burst() + + else return 1 + +/obj/machinery/atmospherics/pipe/simple/init_dir() + switch(dir) + if(SOUTH) + initialize_directions = SOUTH|NORTH + if(NORTH) + initialize_directions = SOUTH|NORTH + if(EAST) + initialize_directions = EAST|WEST + if(WEST) + initialize_directions = EAST|WEST + if(NORTHEAST) + initialize_directions = NORTH|EAST + if(NORTHWEST) + initialize_directions = NORTH|WEST + if(SOUTHEAST) + initialize_directions = SOUTH|EAST + if(SOUTHWEST) + initialize_directions = SOUTH|WEST + +/obj/machinery/atmospherics/pipe/simple/proc/burst() + src.visible_message("\The [src] bursts!"); + playsound(src.loc, 'sound/effects/bang.ogg', 25, 1) + var/datum/effect/effect/system/smoke_spread/smoke = new + smoke.set_up(1,0, src.loc, 0) + smoke.start() + qdel(src) + +/obj/machinery/atmospherics/pipe/simple/proc/normalize_dir() + if(dir==3) + set_dir(1) + else if(dir==12) + set_dir(4) + +/obj/machinery/atmospherics/pipe/simple/Destroy() + if(node1) + node1.disconnect(src) + node1 = null + if(node2) + node2.disconnect(src) + node1 = null + + . = ..() + +/obj/machinery/atmospherics/pipe/simple/pipeline_expansion() + return list(node1, node2) + +/obj/machinery/atmospherics/pipe/simple/change_color(var/new_color) + ..() + //for updating connected atmos device pipes (i.e. vents, manifolds, etc) + if(node1) + node1.update_underlays() + if(node2) + node2.update_underlays() + +/obj/machinery/atmospherics/pipe/simple/update_icon(var/safety = 0) + if(!check_icon_cache()) + return + + alpha = 255 + + overlays.Cut() + + if(node1 && node2) + overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "[pipe_icon]intact[icon_connect_type]") + else + overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "[pipe_icon]exposed[node1?1:0][node2?1:0][icon_connect_type]") + +/obj/machinery/atmospherics/pipe/simple/update_underlays() + return + +/obj/machinery/atmospherics/pipe/simple/atmos_init() + normalize_dir() + var/node1_dir + var/node2_dir + + for(var/direction in cardinal) + if(direction&initialize_directions) + if (!node1_dir) + node1_dir = direction + else if (!node2_dir) + node2_dir = direction + + for(var/obj/machinery/atmospherics/target in get_step(src,node1_dir)) + if(can_be_node(target, 1)) + node1 = target + break + for(var/obj/machinery/atmospherics/target in get_step(src,node2_dir)) + if(can_be_node(target, 2)) + node2 = target + break + + if(!node1 && !node2) + qdel(src) + return + + var/turf/T = loc + if(level == 1 && !T.is_plating()) hide(1) + update_icon() + +/obj/machinery/atmospherics/pipe/simple/disconnect(obj/machinery/atmospherics/reference) + if(reference == node1) + if(istype(node1, /obj/machinery/atmospherics/pipe)) + qdel(parent) + node1 = null + + if(reference == node2) + if(istype(node2, /obj/machinery/atmospherics/pipe)) + qdel(parent) + node2 = null + + update_icon() + + return null + +/obj/machinery/atmospherics/pipe/simple/visible + icon_state = "intact" + level = 2 + +/obj/machinery/atmospherics/pipe/simple/visible/scrubbers + name = "Scrubbers pipe" + desc = "A one meter section of scrubbers pipe" + icon_state = "intact-scrubbers" + connect_types = CONNECT_TYPE_SCRUBBER + piping_layer = PIPING_LAYER_SCRUBBER + layer = 2.38 + icon_connect_type = "-scrubbers" + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/simple/visible/supply + name = "Air supply pipe" + desc = "A one meter section of supply pipe" + icon_state = "intact-supply" + connect_types = CONNECT_TYPE_SUPPLY + piping_layer = PIPING_LAYER_SUPPLY + layer = 2.39 + icon_connect_type = "-supply" + color = PIPE_COLOR_BLUE + +/obj/machinery/atmospherics/pipe/simple/visible/yellow + color = PIPE_COLOR_YELLOW + +/obj/machinery/atmospherics/pipe/simple/visible/cyan + color = PIPE_COLOR_CYAN + +/obj/machinery/atmospherics/pipe/simple/visible/green + color = PIPE_COLOR_GREEN + +/obj/machinery/atmospherics/pipe/simple/visible/black + color = PIPE_COLOR_BLACK + +/obj/machinery/atmospherics/pipe/simple/visible/red + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/simple/visible/blue + color = PIPE_COLOR_BLUE + +/obj/machinery/atmospherics/pipe/simple/visible/purple + color = PIPE_COLOR_PURPLE + +/obj/machinery/atmospherics/pipe/simple/hidden + icon_state = "intact" + level = 1 + alpha = 128 //set for the benefit of mapping - this is reset to opaque when the pipe is spawned in game + +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers + name = "Scrubbers pipe" + desc = "A one meter section of scrubbers pipe" + icon_state = "intact-scrubbers" + connect_types = CONNECT_TYPE_SCRUBBER + piping_layer = PIPING_LAYER_SCRUBBER + layer = 2.38 + icon_connect_type = "-scrubbers" + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/simple/hidden/supply + name = "Air supply pipe" + desc = "A one meter section of supply pipe" + icon_state = "intact-supply" + connect_types = CONNECT_TYPE_SUPPLY + piping_layer = PIPING_LAYER_SUPPLY + layer = 2.39 + icon_connect_type = "-supply" + color = PIPE_COLOR_BLUE + +/obj/machinery/atmospherics/pipe/simple/hidden/yellow + color = PIPE_COLOR_YELLOW + +/obj/machinery/atmospherics/pipe/simple/hidden/cyan + color = PIPE_COLOR_CYAN + +/obj/machinery/atmospherics/pipe/simple/hidden/green + color = PIPE_COLOR_GREEN + +/obj/machinery/atmospherics/pipe/simple/hidden/black + color = PIPE_COLOR_BLACK + +/obj/machinery/atmospherics/pipe/simple/hidden/red + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/simple/hidden/blue + color = PIPE_COLOR_BLUE + +/obj/machinery/atmospherics/pipe/simple/hidden/purple + color = PIPE_COLOR_PURPLE + +/obj/machinery/atmospherics/pipe/simple/insulated + icon = 'icons/obj/atmospherics/red_pipe.dmi' + icon_state = "intact" + + construction_type = /obj/item/pipe/binary/bendable + pipe_state = "insulated" + + minimum_temperature_difference = 10000 + thermal_conductivity = 0 + maximum_pressure = 1000*ONE_ATMOSPHERE + fatigue_pressure = 900*ONE_ATMOSPHERE + alert_pressure = 900*ONE_ATMOSPHERE + + level = 2 diff --git a/code/ATMOSPHERICS/pipes/tank.dm b/code/ATMOSPHERICS/pipes/tank.dm new file mode 100644 index 0000000000..c8015225e0 --- /dev/null +++ b/code/ATMOSPHERICS/pipes/tank.dm @@ -0,0 +1,160 @@ +// +// Tanks - These are implemented as pipes with large volume +// +/obj/machinery/atmospherics/pipe/tank + icon = 'icons/atmos/tank.dmi' + icon_state = "air_map" + + name = "Pressure Tank" + desc = "A large vessel containing pressurized gas." + + volume = 10000 //in liters, 1 meters by 1 meters by 2 meters ~tweaked it a little to simulate a pressure tank without needing to recode them yet + var/start_pressure = 25*ONE_ATMOSPHERE + + level = 1 + dir = SOUTH + initialize_directions = SOUTH + pipe_flags = PIPING_DEFAULT_LAYER_ONLY + density = 1 + +/obj/machinery/atmospherics/pipe/tank/New() + icon_state = "air" + ..() + +/obj/machinery/atmospherics/pipe/tank/init_dir() + initialize_directions = dir + +/obj/machinery/atmospherics/pipe/tank/Destroy() + if(node1) + node1.disconnect(src) + node1 = null + + . = ..() + +/obj/machinery/atmospherics/pipe/tank/pipeline_expansion() + return list(node1) + +/obj/machinery/atmospherics/pipe/tank/update_underlays() + if(..()) + underlays.Cut() + var/turf/T = get_turf(src) + if(!istype(T)) + return + add_underlay(T, node1, dir) + +/obj/machinery/atmospherics/pipe/tank/hide() + update_underlays() + +/obj/machinery/atmospherics/pipe/tank/atmos_init() + var/connect_direction = dir + + for(var/obj/machinery/atmospherics/target in get_step(src,connect_direction)) + if (can_be_node(target, 1)) + node1 = target + break + + update_underlays() + +/obj/machinery/atmospherics/pipe/tank/disconnect(obj/machinery/atmospherics/reference) + if(reference == node1) + if(istype(node1, /obj/machinery/atmospherics/pipe)) + qdel(parent) + node1 = null + + update_underlays() + + return null + +/obj/machinery/atmospherics/pipe/tank/attackby(var/obj/item/W as obj, var/mob/user as mob) + if(istype(W, /obj/item/device/pipe_painter)) + return + + if(istype(W, /obj/item/device/analyzer) && in_range(user, src)) + var/obj/item/device/analyzer/A = W + A.analyze_gases(src, user) + +/obj/machinery/atmospherics/pipe/tank/air + name = "Pressure Tank (Air)" + icon_state = "air_map" + +/obj/machinery/atmospherics/pipe/tank/air/New() + air_temporary = new + air_temporary.volume = volume + air_temporary.temperature = T20C + + air_temporary.adjust_multi("oxygen", (start_pressure*O2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature), \ + "nitrogen",(start_pressure*N2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) + + + ..() + icon_state = "air" + +/obj/machinery/atmospherics/pipe/tank/oxygen + name = "Pressure Tank (Oxygen)" + icon_state = "o2_map" + +/obj/machinery/atmospherics/pipe/tank/oxygen/New() + air_temporary = new + air_temporary.volume = volume + air_temporary.temperature = T20C + + air_temporary.adjust_gas("oxygen", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) + + ..() + icon_state = "o2" + +/obj/machinery/atmospherics/pipe/tank/nitrogen + name = "Pressure Tank (Nitrogen)" + icon_state = "n2_map" + +/obj/machinery/atmospherics/pipe/tank/nitrogen/New() + air_temporary = new + air_temporary.volume = volume + air_temporary.temperature = T20C + + air_temporary.adjust_gas("nitrogen", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) + + ..() + icon_state = "n2" + +/obj/machinery/atmospherics/pipe/tank/carbon_dioxide + name = "Pressure Tank (Carbon Dioxide)" + icon_state = "co2_map" + +/obj/machinery/atmospherics/pipe/tank/carbon_dioxide/New() + air_temporary = new + air_temporary.volume = volume + air_temporary.temperature = T20C + + air_temporary.adjust_gas("carbon_dioxide", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) + + ..() + icon_state = "co2" + +/obj/machinery/atmospherics/pipe/tank/phoron + name = "Pressure Tank (Phoron)" + icon_state = "phoron_map" + +/obj/machinery/atmospherics/pipe/tank/phoron/New() + air_temporary = new + air_temporary.volume = volume + air_temporary.temperature = T20C + + air_temporary.adjust_gas("phoron", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) + + ..() + icon_state = "phoron" + +/obj/machinery/atmospherics/pipe/tank/nitrous_oxide + name = "Pressure Tank (Nitrous Oxide)" + icon_state = "n2o_map" + +/obj/machinery/atmospherics/pipe/tank/nitrous_oxide/New() + air_temporary = new + air_temporary.volume = volume + air_temporary.temperature = T0C + + air_temporary.adjust_gas("sleeping_agent", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) + + ..() + icon_state = "n2o" diff --git a/code/ATMOSPHERICS/pipes/universal.dm b/code/ATMOSPHERICS/pipes/universal.dm new file mode 100644 index 0000000000..2d8bd09dff --- /dev/null +++ b/code/ATMOSPHERICS/pipes/universal.dm @@ -0,0 +1,108 @@ +// +// Universal Pipe Adapter - Designed for connecting scrubbers, normal, and supply pipes together. +// +/obj/machinery/atmospherics/pipe/simple/visible/universal + name="Universal pipe adapter" + desc = "An adapter for regular, supply and scrubbers pipes" + connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SUPPLY|CONNECT_TYPE_SCRUBBER + icon_state = "map_universal" + pipe_flags = PIPING_ALL_LAYER|PIPING_CARDINAL_AUTONORMALIZE + construction_type = /obj/item/pipe/binary + pipe_state = "universal" + +/obj/machinery/atmospherics/pipe/simple/visible/universal/update_icon(var/safety = 0) + if(!check_icon_cache()) + return + + alpha = 255 + + overlays.Cut() + overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "universal") + underlays.Cut() + + if (node1) + universal_underlays(node1) + if(node2) + universal_underlays(node2) + else + var/node1_dir = get_dir(node1,src) + universal_underlays(,node1_dir) + else if (node2) + universal_underlays(node2) + else + universal_underlays(,dir) + universal_underlays(,turn(dir, -180)) + +/obj/machinery/atmospherics/pipe/simple/visible/universal/update_underlays() + ..() + update_icon() + + + +/obj/machinery/atmospherics/pipe/simple/hidden/universal + name="Universal pipe adapter" + desc = "An adapter for regular, supply and scrubbers pipes" + connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SUPPLY|CONNECT_TYPE_SCRUBBER + icon_state = "map_universal" + pipe_flags = PIPING_ALL_LAYER|PIPING_CARDINAL_AUTONORMALIZE + construction_type = /obj/item/pipe/binary + pipe_state = "universal" + +/obj/machinery/atmospherics/pipe/simple/hidden/universal/update_icon(var/safety = 0) + if(!check_icon_cache()) + return + + alpha = 255 + + overlays.Cut() + overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "universal") + underlays.Cut() + + if (node1) + universal_underlays(node1) + if(node2) + universal_underlays(node2) + else + var/node2_dir = turn(get_dir(src,node1),-180) + universal_underlays(,node2_dir) + else if (node2) + universal_underlays(node2) + var/node1_dir = turn(get_dir(src,node2),-180) + universal_underlays(,node1_dir) + else + universal_underlays(,dir) + universal_underlays(,turn(dir, -180)) + +/obj/machinery/atmospherics/pipe/simple/hidden/universal/update_underlays() + ..() + update_icon() + +/obj/machinery/atmospherics/proc/universal_underlays(var/obj/machinery/atmospherics/node, var/direction) + var/turf/T = loc + if(node) + var/node_dir = get_dir(src,node) + if(node.icon_connect_type == "-supply") + add_underlay_adapter(T, , node_dir, "") + add_underlay_adapter(T, node, node_dir, "-supply") + add_underlay_adapter(T, , node_dir, "-scrubbers") + else if (node.icon_connect_type == "-scrubbers") + add_underlay_adapter(T, , node_dir, "") + add_underlay_adapter(T, , node_dir, "-supply") + add_underlay_adapter(T, node, node_dir, "-scrubbers") + else + add_underlay_adapter(T, node, node_dir, "") + add_underlay_adapter(T, , node_dir, "-supply") + add_underlay_adapter(T, , node_dir, "-scrubbers") + else + add_underlay_adapter(T, , direction, "-supply") + add_underlay_adapter(T, , direction, "-scrubbers") + add_underlay_adapter(T, , direction, "") + +/obj/machinery/atmospherics/proc/add_underlay_adapter(var/turf/T, var/obj/machinery/atmospherics/node, var/direction, var/icon_connect_type) //modified from add_underlay, does not make exposed underlays + if(node) + if(!T.is_plating() && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe)) + underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "down" + icon_connect_type) + else + underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "intact" + icon_connect_type) + else + underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "retracted" + icon_connect_type) diff --git a/code/ATMOSPHERICS/pipes/vent.dm b/code/ATMOSPHERICS/pipes/vent.dm new file mode 100644 index 0000000000..4a1dc5696d --- /dev/null +++ b/code/ATMOSPHERICS/pipes/vent.dm @@ -0,0 +1,85 @@ +// +// Vent Pipe - Unpowered vent +// +/obj/machinery/atmospherics/pipe/vent + icon = 'icons/obj/atmospherics/pipe_vent.dmi' + icon_state = "intact" + + name = "Vent" + desc = "A large air vent" + + level = 1 + + volume = 250 + + dir = SOUTH + initialize_directions = SOUTH + pipe_flags = PIPING_DEFAULT_LAYER_ONLY + construction_type = /obj/item/pipe/directional + pipe_state = "passive vent" + + var/build_killswitch = 1 + +/obj/machinery/atmospherics/pipe/vent/init_dir() + initialize_directions = dir + +/obj/machinery/atmospherics/pipe/vent/high_volume + name = "Larger vent" + volume = 1000 + +/obj/machinery/atmospherics/pipe/vent/process() + if(!parent) + if(build_killswitch <= 0) + . = PROCESS_KILL + else + build_killswitch-- + ..() + return + else + parent.mingle_with_turf(loc, volume) + +/obj/machinery/atmospherics/pipe/vent/Destroy() + if(node1) + node1.disconnect(src) + node1 = null + + . = ..() + +/obj/machinery/atmospherics/pipe/vent/pipeline_expansion() + return list(node1) + +/obj/machinery/atmospherics/pipe/vent/update_icon() + if(node1) + icon_state = "intact" + + set_dir(get_dir(src, node1)) + + else + icon_state = "exposed" + +/obj/machinery/atmospherics/pipe/vent/atmos_init() + var/connect_direction = dir + + for(var/obj/machinery/atmospherics/target in get_step(src,connect_direction)) + if (can_be_node(target, 1)) + node1 = target + break + + update_icon() + +/obj/machinery/atmospherics/pipe/vent/disconnect(obj/machinery/atmospherics/reference) + if(reference == node1) + if(istype(node1, /obj/machinery/atmospherics/pipe)) + qdel(parent) + node1 = null + + update_icon() + + return null + +/obj/machinery/atmospherics/pipe/vent/hide(var/i) //to make the little pipe section invisible, the icon changes. + if(node1) + icon_state = "[i == 1 && istype(loc, /turf/simulated) ? "h" : "" ]intact" + set_dir(get_dir(src, node1)) + else + icon_state = "exposed" diff --git a/code/ZAS/Turf.dm b/code/ZAS/Turf.dm index a309cd3a08..f61d1cf4fc 100644 --- a/code/ZAS/Turf.dm +++ b/code/ZAS/Turf.dm @@ -6,9 +6,9 @@ /turf/simulated/proc/update_graphic(list/graphic_add = null, list/graphic_remove = null) if(LAZYLEN(graphic_add)) - overlays += graphic_add + add_overlay(graphic_add, priority = TRUE) if(LAZYLEN(graphic_remove)) - overlays -= graphic_remove + cut_overlay(graphic_remove, priority = TRUE) /turf/proc/update_air_properties() var/block = c_airblock(src) diff --git a/code/__defines/_planes+layers.dm b/code/__defines/_planes+layers.dm index ad4fe2181d..a044b16c85 100644 --- a/code/__defines/_planes+layers.dm +++ b/code/__defines/_planes+layers.dm @@ -44,36 +44,69 @@ What is the naming convention for planes or layers? #define PLANE_ADMIN2 -91 //And adminbuse #define PLANE_ADMIN3 -90 //And generating salt -#define SPACE_PLANE -32 // Reserved for use in space/parallax -#define PARALLAX_PLANE -30 // Reserved for use in space/parallax +#define SPACE_PLANE -82 // Reserved for use in space/parallax +#define PARALLAX_PLANE -80 // Reserved for use in space/parallax // OPENSPACE_PLANE reserves all planes between OPENSPACE_PLANE_START and OPENSPACE_PLANE_END inclusive -#define OPENSPACE_PLANE -55 // /turf/simulated/open will use OPENSPACE_PLANE + z (Valid z's being 2 thru 17) -#define OPENSPACE_PLANE_START -53 -#define OPENSPACE_PLANE_END -38 -#define OVER_OPENSPACE_PLANE -37 +#define OPENSPACE_PLANE -75 // /turf/simulated/open will use OPENSPACE_PLANE + z (Valid z's being 2 thru 17) +#define OPENSPACE_PLANE_START -73 +#define OPENSPACE_PLANE_END -58 +#define OVER_OPENSPACE_PLANE -57 + +// Turf Planes +#define SPACE_PLANE -43 // Space turfs themselves +#define PLATING_PLANE -44 // Plating + #define DISPOSAL_LAYER 2.1 // Under objects, even when planeswapped + #define WIRES_LAYER 2.2 // Under objects, even when planeswapped + #define PIPES_LAYER 2.3 // Under objects, even when planeswapped + #define ABOVE_UTILITY 2.5 // Above stuff like pipes and wires +#define TURF_PLANE -45 // Turfs themselves, most flooring + #define ABOVE_TURF_LAYER 2.1 // Snow and such +#define DECAL_PLANE -44 // Permanent decals +#define DIRTY_PLANE -43 // Nonpermanent decals +#define BLOOD_PLANE -42 // Blood is really dirty, but we can do special stuff if we separate it + +// Obj planes +#define OBJ_PLANE -35 + #define HIDING_LAYER 2.6 // Layer at which mobs hide to be under things like tables + #define DOOR_OPEN_LAYER 2.7 // Under all objects if opened. 2.7 due to tables being at 2.6 + #define TABLE_LAYER 2.8 // Just under stuff that wants to be slightly below common objects. + #define UNDER_JUNK_LAYER 2.9 // Things that want to be slightly below common objects + // Turf/Obj layer boundary + #define ABOVE_JUNK_LAYER 3.1 // Things that want to be slightly above common objects + #define DOOR_CLOSED_LAYER 3.1 // Doors when closed + #define WINDOW_LAYER 3.2 // Windows + #define ON_WINDOW_LAYER 3.3 // Ontop of a window + #define SHOWER_OPEN_LAYER 3.4 // Showers when open + // Obj/Mob layer boundary + #define SHOWER_CLOSED_LAYER 4.2 // Should be converted to plane swaps + +// Mob planes +#define MOB_PLANE -25 + #define BELOW_MOB_LAYER 3.9 // Should be converted to plane swaps + #define ABOVE_MOB_LAYER 4.1 // Should be converted to plane swaps + +// Top plane (in the sense that it's the highest in 'the world' and not a UI element) +#define ABOVE_PLANE -10 //////////////////////////////////////////////////////////////////////////////////////// #define PLANE_WORLD 0 // BYOND's default value for plane, the "base plane" //////////////////////////////////////////////////////////////////////////////////////// + //#define AREA_LAYER 1 //For easy recordkeeping; this is a byond define + //#define TURF_LAYER 2 //For easy recordkeeping; this is a byond define - #define DECALS_LAYER 2.01 - #define OVERTURF_LAYER 2.1 - #define DOOR_OPEN_LAYER 2.7 //Under all objects if opened. 2.7 due to tables being at 2.6 + //#define OBJ_LAYER 3 //For easy recordkeeping; this is a byond define - #define DOOR_CLOSED_LAYER 3.1 //Above most items if closed - #define SHOWER_OPEN_LAYER 3.4 - #define BELOW_MOB_LAYER 3.9 + //#define MOB_LAYER 4 //For easy recordkeeping; this is a byond define - #define ABOVE_MOB_LAYER 4.1 - #define SHOWER_CLOSED_LAYER 4.2 - + //#define FLY_LAYER 5 //For easy recordkeeping; this is a byond define - #define LIGHTING_LAYER 11 //Layer that lighting used to be on (now it's on a plane) - #define HUD_LAYER 20 //Above lighting, but below obfuscation. For in-game HUD effects (whereas SCREEN_LAYER is for abstract/OOC things like inventory slots) - #define SCREEN_LAYER 22 //Mob HUD/effects layer + #define HUD_LAYER 20 // Above lighting, but below obfuscation. For in-game HUD effects (whereas SCREEN_LAYER is for abstract/OOC things like inventory slots) + #define SCREEN_LAYER 22 // Mob HUD/effects layer + +#define PLANE_PLANETLIGHTING 4 //Lighting on planets #define PLANE_LIGHTING 5 //Where the lighting (and darkness) lives #define PLANE_LIGHTING_ABOVE 6 //For glowy eyes etc. that shouldn't be affected by darkness @@ -122,4 +155,4 @@ What is the naming convention for planes or layers? // Check if a mob can "logically" see an atom plane -#define MOB_CAN_SEE_PLANE(M, P) (P == PLANE_WORLD || (P >= OPENSPACE_PLANE_START && P <= OPENSPACE_PLANE_END) || (P in M.planes_visible)) +#define MOB_CAN_SEE_PLANE(M, P) (P <= PLANE_WORLD || (P in M.planes_visible)) diff --git a/code/__defines/atmos.dm b/code/__defines/atmos.dm index bd9175aab1..13964a6f80 100644 --- a/code/__defines/atmos.dm +++ b/code/__defines/atmos.dm @@ -21,8 +21,6 @@ #define HUMAN_NEEDED_OXYGEN (MOLES_CELLSTANDARD * BREATH_PERCENTAGE * 0.16) #define HUMAN_HEAT_CAPACITY 280000 //J/K For 80kg person -#define SOUND_MINIMUM_PRESSURE 10 - #define PRESSURE_DAMAGE_COEFFICIENT 4 // The amount of pressure damage someone takes is equal to (pressure / HAZARD_HIGH_PRESSURE)*PRESSURE_DAMAGE_COEFFICIENT, with the maximum of MAX_PRESSURE_DAMAGE. #define MAX_HIGH_PRESSURE_DAMAGE 4 // This used to be 20... I got this much random rage for some retarded decision by polymorph?! Polymorph now lies in a pool of blood with a katana jammed in his spleen. ~Errorage --PS: The katana did less than 20 damage to him :( #define LOW_PRESSURE_DAMAGE 2 // The amount of damage someone takes when in a low pressure area. (The pressure threshold is so low that it doesn't make sense to do any calculations, so it just applies this flat value). diff --git a/code/__defines/chemistry.dm b/code/__defines/chemistry.dm index 08131f99bb..c9b34fc2b6 100644 --- a/code/__defines/chemistry.dm +++ b/code/__defines/chemistry.dm @@ -27,7 +27,7 @@ #define IS_SLIME 8 #define CE_STABLE "stable" // Inaprovaline -#define CE_ANTIBIOTIC "antibiotic" // Spaceacilin +#define CE_ANTIBIOTIC "antibiotic" // Antibiotics #define CE_BLOODRESTORE "bloodrestore" // Iron/nutriment #define CE_PAINKILLER "painkiller" #define CE_ALCOHOL "alcohol" // Liver filtering @@ -36,6 +36,11 @@ #define REAGENTS_PER_SHEET 20 +// Attached to CE_ANTIBIOTIC +#define ANTIBIO_NORM 1 +#define ANTIBIO_OD 2 +#define ANTIBIO_SUPER 3 + // Chemistry lists. var/list/tachycardics = list("coffee", "inaprovaline", "hyperzine", "nitroglycerin", "thirteenloko", "nicotine") // Increase heart rate. var/list/bradycardics = list("neurotoxin", "cryoxadone", "clonexadone", "space_drugs", "stoxin") // Decrease heart rate. diff --git a/code/__defines/construction.dm b/code/__defines/construction.dm index 7aceb1ffc4..837ad7ed38 100644 --- a/code/__defines/construction.dm +++ b/code/__defines/construction.dm @@ -1,4 +1,6 @@ - +// +// Frame construction +// // Frame construction states #define FRAME_PLACED 0 // Has been placed (can be anchored or not). @@ -16,3 +18,44 @@ // Does the frame get built on the floor or a wall? #define FRAME_STYLE_FLOOR "floor" #define FRAME_STYLE_WALL "wall" + +// +// Pipe Construction +// + +//Construction Orientation Types - Each of these categories has a different selection of how pipes can rotate and flip. Used for RPD. +#define PIPE_STRAIGHT 0 //2 directions: N/S, E/W +#define PIPE_BENDABLE 1 //6 directions: N/S, E/W, N/E, N/W, S/E, S/W +#define PIPE_TRINARY 2 //4 directions: N/E/S, E/S/W, S/W/N, W/N/E +#define PIPE_TRIN_M 3 //8 directions: N->S+E, S->N+E, N->S+W, S->N+W, E->W+S, W->E+S, E->W+N, W->E+N +#define PIPE_DIRECTIONAL 4 //4 directions: N, S, E, W +#define PIPE_ONEDIR 5 //1 direction: N/S/E/W +#define PIPE_UNARY_FLIPPABLE 6 //8 directions: N, S, E, W, N-flipped, S-flipped, E-flipped, W-flipped +#define PIPE_TRIN_T 7 //8 directions: N->S+E, S->N+E, N->S+W, S->N+W, E->W+S, W->E+S, E->W+N, W->E+N + +// Pipe connectivity bit flags +#define CONNECT_TYPE_REGULAR 1 +#define CONNECT_TYPE_SUPPLY 2 +#define CONNECT_TYPE_SCRUBBER 4 +#define CONNECT_TYPE_HE 8 + +// We are based on the three named layers of supply, regular, and scrubber. +#define PIPING_LAYER_SUPPLY 1 +#define PIPING_LAYER_REGULAR 2 +#define PIPING_LAYER_SCRUBBER 3 +#define PIPING_LAYER_DEFAULT PIPING_LAYER_REGULAR + +// Pipe flags +#define PIPING_ALL_LAYER 1 //intended to connect with all layers, check for all instead of just one. +#define PIPING_ONE_PER_TURF 2 //can only be built if nothing else with this flag is on the tile already. +#define PIPING_DEFAULT_LAYER_ONLY 4 //can only exist at PIPING_LAYER_DEFAULT +#define PIPING_CARDINAL_AUTONORMALIZE 8 //north/south east/west doesn't matter, auto normalize on build. + +// Macro for easy use of boilerplate code for searching for a valid node connection. +#define STANDARD_ATMOS_CHOOSE_NODE(node_num, direction) \ + for(var/obj/machinery/atmospherics/target in get_step(src, direction)) { \ + if(can_be_node(target, node_num)) { \ + node##node_num = target; \ + break; \ + } \ + } diff --git a/code/__defines/items_clothing.dm b/code/__defines/items_clothing.dm index f857a8f232..637b450df6 100644 --- a/code/__defines/items_clothing.dm +++ b/code/__defines/items_clothing.dm @@ -34,8 +34,9 @@ #define ACCESSORY_SLOT_ARMOR_L "Leg armor" #define ACCESSORY_SLOT_ARMOR_S "Armor storage" #define ACCESSORY_SLOT_ARMOR_M "Misc armor" +#define ACCESSORY_SLOT_HELM_C "Helmet cover" -// Flags bitmasks. +// Flags bitmasks. - Used in /atom/var/flags #define NOBLUDGEON 0x1 // When an item has this it produces no "X has been hit by Y with Z" message with the default handler. #define CONDUCT 0x2 // Conducts electricity. (metal etc.) #define ON_BORDER 0x4 // Item has priority to check when entering or leaving. @@ -44,8 +45,9 @@ #define PHORONGUARD 0x20 // Does not get contaminated by phoron. #define NOREACT 0x40 // Reagents don't react inside this container. #define PROXMOVE 0x80 // Does this object require proximity checking in Enter()? +#define OVERLAY_QUEUED 0x100 // Atom queued to SSoverlay for COMPILE_OVERLAYS -//Flags for items (equipment) +//Flags for items (equipment) - Used in /obj/item/var/item_flags #define THICKMATERIAL 0x1 // Prevents syringes, parapens and hyposprays if equipped to slot_suit or slot_head. #define STOPPRESSUREDAMAGE 0x2 // Counts towards pressure protection. Note that like temperature protection, body_parts_covered is considered here as well. #define AIRTIGHT 0x4 // Functions with internals. @@ -53,13 +55,13 @@ #define BLOCK_GAS_SMOKE_EFFECT 0x10 // Blocks the effect that chemical clouds would have on a mob -- glasses, mask and helmets ONLY! (NOTE: flag shared with ONESIZEFITSALL) #define FLEXIBLEMATERIAL 0x20 // At the moment, masks with this flag will not prevent eating even if they are covering your face. -// Flags for pass_flags. +// Flags for pass_flags. - Used in /atom/var/pass_flags #define PASSTABLE 0x1 #define PASSGLASS 0x2 #define PASSGRILLE 0x4 #define PASSBLOB 0x8 -// Bitmasks for the flags_inv variable. These determine when a piece of clothing hides another, i.e. a helmet hiding glasses. +// Bitmasks for the /obj/item/var/flags_inv variable. These determine when a piece of clothing hides another, i.e. a helmet hiding glasses. // WARNING: The following flags apply only to the external suit! #define HIDEGLOVES 0x1 #define HIDESUITSTORAGE 0x2 @@ -78,29 +80,34 @@ #define BLOCKHEADHAIR 0x20 // Hides the user's hair overlay. Leaves facial hair. #define BLOCKHAIR 0x40 // Hides the user's hair, facial and otherwise. -// Slots. -#define slot_back 1 -#define slot_wear_mask 2 -#define slot_handcuffed 3 -#define slot_l_hand 4 -#define slot_r_hand 5 -#define slot_belt 6 -#define slot_wear_id 7 -#define slot_l_ear 8 +// Slots as numbers // +//Hands +#define slot_l_hand 1 +#define slot_r_hand 2 //Some things may reference this, try to keep it here +//Shown unless F12 pressed +#define slot_back 3 +#define slot_belt 4 +#define slot_wear_id 5 +#define slot_s_store 6 +#define slot_l_store 7 +#define slot_r_store 8 //Some things may reference this, try to keep it here +//Shown when inventory unhidden #define slot_glasses 9 -#define slot_gloves 10 -#define slot_head 11 -#define slot_shoes 12 -#define slot_wear_suit 13 -#define slot_w_uniform 14 -#define slot_l_store 15 -#define slot_r_store 16 -#define slot_s_store 17 -#define slot_in_backpack 18 -#define slot_legcuffed 19 -#define slot_r_ear 20 -#define slot_legs 21 -#define slot_tie 22 +#define slot_wear_mask 10 +#define slot_gloves 11 +#define slot_head 12 +#define slot_shoes 13 +#define slot_wear_suit 14 +#define slot_w_uniform 15 +#define slot_l_ear 16 +#define slot_r_ear 17 +//Secret slots +#define slot_legs 18 +#define slot_tie 19 +#define slot_handcuffed 20 +#define slot_legcuffed 21 +#define slot_in_backpack 22 +#define SLOT_TOTAL 22 // Inventory slot strings. // since numbers cannot be used as associative list keys. @@ -111,6 +118,21 @@ #define slot_w_uniform_str "slot_w_uniform" #define slot_head_str "slot_head" #define slot_wear_suit_str "slot_suit" +#define slot_l_ear_str "slot_l_ear" +#define slot_r_ear_str "slot_r_ear" +#define slot_belt_str "slot_belt" +#define slot_shoes_str "slot_shoes" +#define slot_head_str "slot_head" +#define slot_wear_mask_str "slot_wear_mask" +#define slot_handcuffed_str "slot_handcuffed" +#define slot_legcuffed_str "slot_legcuffed" +#define slot_wear_mask_str "slot_wear_mask" +#define slot_wear_id_str "slot_wear_id" +#define slot_gloves_str "slot_gloves" +#define slot_glasses_str "slot_glasses" +#define slot_s_store_str "slot_s_store" +#define slot_tie_str "slot_tie" + // Bitflags for clothing parts. #define HEAD 0x1 diff --git a/code/__defines/lighting.dm b/code/__defines/lighting.dm index 6b05896b8d..00e473fc2a 100644 --- a/code/__defines/lighting.dm +++ b/code/__defines/lighting.dm @@ -9,7 +9,6 @@ #define LIGHTING_LAMBERTIAN 0 // use lambertian shading for light sources #define LIGHTING_HEIGHT 1 // height off the ground of light sources on the pseudo-z-axis, you should probably leave this alone -//#define LIGHTING_LAYER 10 // drawing layer for lighting overlays #define LIGHTING_ICON 'icons/effects/lighting_overlay.dmi' // icon used for lighting shading effects #define LIGHTING_ICON_STATE_DARK "soft_dark" // Change between "soft_dark" and "dark" to swap soft darkvision diff --git a/code/__defines/math.dm b/code/__defines/math.dm index 79dc1b4d24..3d64ba6c81 100644 --- a/code/__defines/math.dm +++ b/code/__defines/math.dm @@ -9,6 +9,10 @@ #define REALTIMEOFDAY (world.timeofday + (MIDNIGHT_ROLLOVER * MIDNIGHT_ROLLOVER_CHECK)) #define MIDNIGHT_ROLLOVER_CHECK ( rollovercheck_last_timeofday != world.timeofday ? update_midnight_rollover() : midnight_rollovers ) +#define SHORT_REAL_LIMIT 16777216 // 2^24 - Maximum integer that can be exactly represented in a float (BYOND num var) + #define CEILING(x, y) ( -round(-(x) / (y)) * (y) ) // round() acts like floor(x, 1) by default but can't handle other values #define FLOOR(x, y) ( round((x) / (y)) * (y) ) +// Check if a BYOND dir var is a cardinal direction (power of two) +#define IS_CARDINAL(x) ((x & (x - 1)) == 0) diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index 44d0389d5a..f610c0c2a3 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -9,7 +9,8 @@ #define CANPARALYSE 0x4 #define CANPUSH 0x8 #define LEAPING 0x10 -#define PASSEMOTES 0x32 // Mob has a cortical borer or holders inside of it that need to see emotes. +#define HIDING 0x20 +#define PASSEMOTES 0x40 // Mob has a cortical borer or holders inside of it that need to see emotes. #define GODMODE 0x1000 #define FAKEDEATH 0x2000 // Replaces stuff like changeling.changeling_fakedeath. #define DISFIGURED 0x4000 // Set but never checked. Remove this sometime and replace occurences with the appropriate organ code @@ -115,9 +116,17 @@ #define INV_R_HAND_DEF_ICON 'icons/mob/items/righthand.dmi' #define INV_W_UNIFORM_DEF_ICON 'icons/mob/uniform.dmi' #define INV_ACCESSORIES_DEF_ICON 'icons/mob/ties.dmi' -#define INV_SUIT_DEF_ICON 'icons/mob/ties.dmi' +#define INV_TIE_DEF_ICON 'icons/mob/ties.dmi' #define INV_SUIT_DEF_ICON 'icons/mob/suit.dmi' -#define MAX_SUPPLIED_LAW_NUMBER 50 +#define INV_WEAR_ID_DEF_ICON 'icons/mob/mob.dmi' +#define INV_GLOVES_DEF_ICON 'icons/mob/hands.dmi' +#define INV_EYES_DEF_ICON 'icons/mob/eyes.dmi' +#define INV_EARS_DEF_ICON 'icons/mob/ears.dmi' +#define INV_FEET_DEF_ICON 'icons/mob/feet.dmi' +#define INV_BELT_DEF_ICON 'icons/mob/belt.dmi' +#define INV_MASK_DEF_ICON 'icons/mob/mask.dmi' +#define INV_HCUFF_DEF_ICON 'icons/mob/mob.dmi' +#define INV_LCUFF_DEF_ICON 'icons/mob/mob.dmi' // Character's economic class #define CLASS_UPPER "Wealthy" @@ -235,6 +244,44 @@ #define FBP_POSI "Positronic" #define FBP_DRONE "Drone" +// 'Regular' species. +#define SPECIES_HUMAN "Human" +#define SPECIES_HUMAN_VATBORN "Vatborn" +#define SPECIES_UNATHI "Unathi" +#define SPECIES_SKRELL "Skrell" +#define SPECIES_TESHARI "Teshari" +#define SPECIES_TAJ "Tajara" +#define SPECIES_PROMETHEAN "Promethean" +#define SPECIES_DIONA "Diona" +#define SPECIES_VOX "Vox" + +// Monkey and alien monkeys. +#define SPECIES_MONKEY "Monkey" +#define SPECIES_MONKEY_TAJ "Farwa" +#define SPECIES_MONKEY_SKRELL "Neaera" +#define SPECIES_MONKEY_UNATHI "Stok" + +// Virtual Reality IDs. +#define SPECIES_VR "Virtual Reality Avatar" +#define SPECIES_VR_HUMAN "Virtual Reality Human" +#define SPECIES_VR_UNATHI "Virtual Reality Unathi" +#define SPECIES_VR_TAJ "Virtual Reality Tajara" // NO CHANGING. +#define SPECIES_VR_SKRELL "Virtual Reality Skrell" +#define SPECIES_VR_TESHARI "Virtual Reality Teshari" +#define SPECIES_VR_DIONA "Virtual Reality Diona" + +// Ayyy IDs. +#define SPECIES_XENO "Xenomorph" +#define SPECIES_XENO_DRONE "Xenomorph Drone" +#define SPECIES_XENO_HUNTER "Xenomorph Hunter" +#define SPECIES_XENO_SENTINEL "Xenomorph Sentinel" +#define SPECIES_XENO_QUEEN "Xenomorph Queen" + +// Misc species. Mostly unused but might as well be complete. +#define SPECIES_SHADOW "Shadow" +#define SPECIES_SKELETON "Skeleton" +#define SPECIES_GOLEM "Golem" + // Used to seperate simple animals by ""intelligence"". #define SA_PLANT 1 #define SA_ANIMAL 2 @@ -272,4 +319,7 @@ #define VIS_MESONS 20 -#define VIS_COUNT 20 //Must be highest number from above. \ No newline at end of file +#define VIS_COUNT 20 //Must be highest number from above. + +//Some mob icon layering defines +#define BODY_LAYER -100 diff --git a/code/__defines/sound.dm b/code/__defines/sound.dm new file mode 100644 index 0000000000..6fae2fadcb --- /dev/null +++ b/code/__defines/sound.dm @@ -0,0 +1,56 @@ +//max channel is 1024. Only go lower from here, because byond tends to pick the first availiable channel to play sounds on +#define CHANNEL_LOBBYMUSIC 1024 +#define CHANNEL_ADMIN 1023 +#define CHANNEL_VOX 1022 +#define CHANNEL_JUKEBOX 1021 +#define CHANNEL_HEARTBEAT 1020 //sound channel for heartbeats +#define CHANNEL_AMBIENCE_FORCED 1019 +#define CHANNEL_AMBIENCE 1018 +#define CHANNEL_BUZZ 1017 +#define CHANNEL_BICYCLE 1016 + +//THIS SHOULD ALWAYS BE THE LOWEST ONE! +//KEEP IT UPDATED + +#define CHANNEL_HIGHEST_AVAILABLE 1015 + +#define SOUND_MINIMUM_PRESSURE 10 +#define FALLOFF_SOUNDS 0.5 + +//Sound environment defines. Reverb preset for sounds played in an area, see sound datum reference for more. +#define GENERIC 0 +#define PADDED_CELL 1 +#define ROOM 2 +#define BATHROOM 3 +#define LIVINGROOM 4 +#define STONEROOM 5 +#define AUDITORIUM 6 +#define CONCERT_HALL 7 +#define CAVE 8 +#define ARENA 9 +#define HANGAR 10 +#define CARPETED_HALLWAY 11 +#define HALLWAY 12 +#define STONE_CORRIDOR 13 +#define ALLEY 14 +#define FOREST 15 +#define CITY 16 +#define MOUNTAINS 17 +#define QUARRY 18 +#define PLAIN 19 +#define PARKING_LOT 20 +#define SEWER_PIPE 21 +#define UNDERWATER 22 +#define DRUGGED 23 +#define DIZZY 24 +#define PSYCHOTIC 25 + +#define STANDARD_STATION STONEROOM +#define LARGE_ENCLOSED HANGAR +#define SMALL_ENCLOSED BATHROOM +#define TUNNEL_ENCLOSED CAVE +#define LARGE_SOFTFLOOR CARPETED_HALLWAY +#define MEDIUM_SOFTFLOOR LIVINGROOM +#define SMALL_SOFTFLOOR ROOM +#define ASTEROID CAVE +#define SPACE UNDERWATER diff --git a/code/__defines/species_languages.dm b/code/__defines/species_languages.dm index 5cfb5f37d0..87f1f9b3ca 100644 --- a/code/__defines/species_languages.dm +++ b/code/__defines/species_languages.dm @@ -45,6 +45,10 @@ #define LANGUAGE_OCCULT "Occult" #define LANGUAGE_CHANGELING "Changeling" #define LANGUAGE_VOX "Vox-Pidgin" +#define LANGUAGE_TERMINUS "Terminus" +#define LANGUAGE_SKRELLIANFAR "High Skrellian" +#define LANGUAGE_MINBUS "Minbus" +#define LANGUAGE_AKHANI "Akhani" // Language flags. #define WHITELISTED 1 // Language is available if the speaker is whitelisted. diff --git a/code/__defines/stat_tracking.dm b/code/__defines/stat_tracking.dm new file mode 100644 index 0000000000..79337bda5c --- /dev/null +++ b/code/__defines/stat_tracking.dm @@ -0,0 +1,17 @@ +// +// Defines used for advanced performance profiling of subsystems. +// Currently used only by SSoverlays (2018-02-24 ~Leshana) +// +#define STAT_ENTRY_TIME 1 +#define STAT_ENTRY_COUNT 2 +#define STAT_ENTRY_LENGTH 2 + +#define STAT_START_STOPWATCH var/STAT_STOP_WATCH = TICK_USAGE +#define STAT_STOP_STOPWATCH var/STAT_TIME = TICK_USAGE_TO_MS(STAT_STOP_WATCH) +#define STAT_LOG_ENTRY(entrylist, entryname) \ + var/list/STAT_ENTRY = entrylist[entryname] || (entrylist[entryname] = new /list(STAT_ENTRY_LENGTH));\ + STAT_ENTRY[STAT_ENTRY_TIME] += STAT_TIME;\ + var/STAT_INCR_AMOUNT = min(1, 2**round((STAT_ENTRY[STAT_ENTRY_COUNT] || 0)/SHORT_REAL_LIMIT));\ + if (STAT_INCR_AMOUNT == 1 || prob(100/STAT_INCR_AMOUNT)) {\ + STAT_ENTRY[STAT_ENTRY_COUNT] += STAT_INCR_AMOUNT;\ + };\ diff --git a/code/__defines/subsystems.dm b/code/__defines/subsystems.dm index faddb9d917..2e290e5045 100644 --- a/code/__defines/subsystems.dm +++ b/code/__defines/subsystems.dm @@ -28,5 +28,35 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G #define INIT_ORDER_MACHINES 10 #define INIT_ORDER_SHUTTLES 3 #define INIT_ORDER_LIGHTING 0 -#define INIT_ORDER_AIR -1 +#define INIT_ORDER_AIR -1 +#define INIT_ORDER_OVERLAY -6 #define INIT_ORDER_XENOARCH -20 + + +// 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) + + #define FIRE_PRIORITY_OVERLAYS 500 + +// Macro defining the actual code applying our overlays lists to the BYOND overlays list. (I guess a macro for speed) +// TODO - I don't really like the location of this macro define. Consider it. ~Leshana +#define COMPILE_OVERLAYS(A)\ + if (TRUE) {\ + var/list/oo = A.our_overlays;\ + var/list/po = A.priority_overlays;\ + if(LAZYLEN(po)){\ + if(LAZYLEN(oo)){\ + A.overlays = oo + po;\ + }\ + else{\ + A.overlays = po;\ + }\ + }\ + else if(LAZYLEN(oo)){\ + A.overlays = oo;\ + }\ + else{\ + A.overlays.Cut();\ + }\ + A.flags &= ~OVERLAY_QUEUED;\ + } diff --git a/code/_helpers/global_lists.dm b/code/_helpers/global_lists.dm index 72937092c4..95f8dcdbe7 100644 --- a/code/_helpers/global_lists.dm +++ b/code/_helpers/global_lists.dm @@ -31,8 +31,8 @@ var/global/list/turfs = list() //list of all turfs var/global/list/all_species[0] var/global/list/all_languages[0] var/global/list/language_keys[0] // Table of say codes for all languages -var/global/list/whitelisted_species = list("Human") // Species that require a whitelist check. -var/global/list/playable_species = list("Human") // A list of ALL playable species, whitelisted, latejoin or otherwise. +var/global/list/whitelisted_species = list(SPECIES_HUMAN) // Species that require a whitelist check. +var/global/list/playable_species = list(SPECIES_HUMAN) // A list of ALL playable species, whitelisted, latejoin or otherwise. var/list/mannequins_ diff --git a/code/_helpers/icons.dm b/code/_helpers/icons.dm index e2096753a0..da4385ef6f 100644 --- a/code/_helpers/icons.dm +++ b/code/_helpers/icons.dm @@ -634,175 +634,211 @@ as a single icon. Useful for when you want to manipulate an icon via the above a The _flatIcons list is a cache for generated icon files. */ -proc // Creates a single icon from a given /atom or /image. Only the first argument is required. - getFlatIcon(image/A, defdir=2, deficon=null, defstate="", defblend=BLEND_DEFAULT, always_use_defdir = 0, picture_planes = list(PLANE_WORLD)) - // We start with a blank canvas, otherwise some icon procs crash silently - var/icon/flat = icon('icons/effects/effects.dmi', "icon_state"="nothing") // Final flattened icon - if(!A) - return flat - if(A.alpha <= 0) - return flat - var/noIcon = FALSE +// Creates a single icon from a given /atom or /image. Only the first argument is required. +/proc/getFlatIcon(image/A, defdir, deficon, defstate, defblend, start = TRUE, no_anim = FALSE) + // We start with a blank canvas, otherwise some icon procs crash silently + var/icon/flat = icon('icons/effects/effects.dmi', "nothing") // Final flattened icon + if(!A) + return flat + if(A.alpha <= 0) + return flat + var/noIcon = FALSE - var/curicon - if(A.icon) - curicon = A.icon + if(start) + if(!defdir) + defdir = A.dir + if(!deficon) + deficon = A.icon + if(!defstate) + defstate = A.icon_state + if(!defblend) + defblend = A.blend_mode + + var/curicon + if(A.icon) + curicon = A.icon + else + curicon = deficon + + if(!curicon) + noIcon = TRUE // Do not render this object. + + var/curstate + if(A.icon_state) + curstate = A.icon_state + else + curstate = defstate + + if(!noIcon && !(curstate in icon_states(curicon))) + if("" in icon_states(curicon)) + curstate = "" else - curicon = deficon - - if(!curicon) noIcon = TRUE // Do not render this object. - var/curstate - if(A.icon_state) - curstate = A.icon_state - else - curstate = defstate + var/curdir + var/base_icon_dir //We'll use this to get the icon state to display if not null BUT NOT pass it to overlays as the dir we have + + //These should use the parent's direction (most likely) + if(!A.dir || A.dir == SOUTH) + curdir = defdir + else + curdir = A.dir - if(!noIcon && !(curstate in icon_states(curicon))) - if("" in icon_states(curicon)) - curstate = "" - else - noIcon = TRUE // Do not render this object. + //Let's check if the icon actually contains any diagonals, just skip if it's south to save (lot of) time + if(curdir != SOUTH) + var/icon/test_icon + var/directionals_exist = FALSE + var/list/dirs_to_check = cardinal - SOUTH + outer: + for(var/possible_dir in dirs_to_check) + test_icon = icon(curicon,curstate,possible_dir,frame=1) + for(var/x in 1 to world.icon_size) + for(var/y in 1 to world.icon_size) + if(!isnull(test_icon.GetPixel(x,y))) + directionals_exist = TRUE + break outer + if(!directionals_exist) + base_icon_dir = SOUTH + if(!base_icon_dir) + base_icon_dir = curdir - var/curdir - if(A.dir != 2 && !always_use_defdir) - curdir = A.dir - else - curdir = defdir + var/curblend + if(A.blend_mode == BLEND_DEFAULT) + curblend = defblend + else + curblend = A.blend_mode - var/curblend - if(A.blend_mode == BLEND_DEFAULT) - curblend = defblend - else - curblend = A.blend_mode + // Before processing overlays, make sure any pending overlays are applied + if (isloc(A)) + var/atom/aAtom = A + if(aAtom.flags & OVERLAY_QUEUED) + COMPILE_OVERLAYS(aAtom) - // Layers will be a sorted list of icons/overlays, based on the order in which they are displayed - var/list/layers = list() - var/image/copy - // Add the atom's icon itself, without pixel_x/y offsets. - if(!noIcon) - copy = image(icon=curicon, icon_state=curstate, layer=A.layer, dir=curdir) - copy.color = A.color - copy.alpha = A.alpha - copy.blend_mode = curblend - layers[copy] = A.layer - - // Loop through the underlays, then overlays, sorting them into the layers list - var/list/process = A.underlays // Current list being processed - var/pSet=0 // Which list is being processed: 0 = underlays, 1 = overlays - var/curIndex=1 // index of 'current' in list being processed - var/current // Current overlay being sorted - var/currentLayer // Calculated layer that overlay appears on (special case for FLOAT_LAYER) - var/compare // The overlay 'add' is being compared against - var/cmpIndex // The index in the layers list of 'compare' - while(TRUE) - if(curIndex<=process.len) - current = process[curIndex] - if(current) - var/currentPlane = current:plane - if (currentPlane != FLOAT_PLANE && !(currentPlane in picture_planes)) - curIndex++ - continue; - currentLayer = current:layer - if(currentLayer<0) // Special case for FLY_LAYER - if(currentLayer <= -1000) return flat - if(pSet == 0) // Underlay - currentLayer = A.layer+currentLayer/1000 - else // Overlay - currentLayer = A.layer+(1000+currentLayer)/1000 - - // Sort add into layers list - for(cmpIndex=1,cmpIndex<=layers.len,cmpIndex++) - compare = layers[cmpIndex] - if(currentLayer < layers[compare]) // Associated value is the calculated layer - layers.Insert(cmpIndex,current) - layers[current] = currentLayer - break - if(cmpIndex>layers.len) // Reached end of list without inserting - layers[current]=currentLayer // Place at end + // Layers will be a sorted list of icons/overlays, based on the order in which they are displayed + var/list/layers = list() + var/image/copy + // Add the atom's icon itself, without pixel_x/y offsets. + if(!noIcon) + copy = image(icon=curicon, icon_state=curstate, layer=A.layer, dir=base_icon_dir) + copy.color = A.color + copy.alpha = A.alpha + copy.blend_mode = curblend + layers[copy] = A.layer + // Loop through the underlays, then overlays, sorting them into the layers list + var/list/process = A.underlays // Current list being processed + var/pSet=0 // Which list is being processed: 0 = underlays, 1 = overlays + var/curIndex=1 // index of 'current' in list being processed + var/current // Current overlay being sorted + var/currentLayer // Calculated layer that overlay appears on (special case for FLOAT_LAYER) + var/compare // The overlay 'add' is being compared against + var/cmpIndex // The index in the layers list of 'compare' + while(TRUE) + if(curIndex<=process.len) + current = process[curIndex] + if(!current) + curIndex++ //Try the next layer + continue + var/image/I = current + if(I.plane != FLOAT_PLANE && I.plane != A.plane) curIndex++ - else if(pSet == 0) // Switch to overlays + continue + currentLayer = I.layer + if(currentLayer<0) // Special case for FLOAT_LAYER + if(currentLayer <= -1000) + return flat + if(pSet == 0) // Underlay + currentLayer = A.layer+currentLayer/1000 + else // Overlay + currentLayer = A.layer+(1000+currentLayer)/1000 + + // Sort add into layers list + for(cmpIndex=1,cmpIndex<=layers.len,cmpIndex++) + compare = layers[cmpIndex] + if(currentLayer < layers[compare]) // Associated value is the calculated layer + layers.Insert(cmpIndex,current) + layers[current] = currentLayer + break + if(cmpIndex>layers.len) // Reached end of list without inserting + layers[current]=currentLayer // Place at end + + curIndex++ + + if(curIndex>process.len) + if(pSet == 0) // Switch to overlays curIndex = 1 pSet = 1 process = A.overlays else // All done break - var/icon/add // Icon of overlay being added + var/icon/add // Icon of overlay being added - // Current dimensions of flattened icon - var/{flatX1=1;flatX2=flat.Width();flatY1=1;flatY2=flat.Height()} - // Dimensions of overlay being added - var/{addX1;addX2;addY1;addY2} + // Current dimensions of flattened icon + var/flatX1=1 + var/flatX2=flat.Width() + var/flatY1=1 + var/flatY2=flat.Height() + // Dimensions of overlay being added + var/addX1 + var/addX2 + var/addY1 + var/addY2 - for(var/I in layers) + for(var/V in layers) + var/image/I = V + if(I.alpha == 0) + continue - if(I:alpha == 0) - continue + if(I == copy) // 'I' is an /image based on the object being flattened. + curblend = BLEND_OVERLAY + add = icon(I.icon, I.icon_state, base_icon_dir) + else // 'I' is an appearance object. + add = getFlatIcon(new/image(I), curdir, curicon, curstate, curblend, FALSE, no_anim) - if(I == copy) // 'I' is an /image based on the object being flattened. - curblend = BLEND_OVERLAY - add = icon(I:icon, I:icon_state, I:dir) - // This checks for a silent failure mode of the icon routine. If the requested dir - // doesn't exist in this icon state it returns a 32x32 icon with 0 alpha. - if (I:dir != SOUTH && add.Width() == 32 && add.Height() == 32) - // Check every pixel for blank (computationally expensive, but the process is limited - // by the amount of film on the station, only happens when we hit something that's - // turned, and bails at the very first pixel it sees. - var/blankpixel; - for(var/y;y<=32;y++) - for(var/x;x<32;x++) - blankpixel = isnull(add.GetPixel(x,y)) - if(!blankpixel) - break - if(!blankpixel) - break - // If we ALWAYS returned a null (which happens when GetPixel encounters something with alpha 0) - if (blankpixel) - // Pull the default direction. - add = icon(I:icon, I:icon_state) - else // 'I' is an appearance object. - add = getFlatIcon(new/image(I), curdir, curicon, curstate, curblend, picture_planes = picture_planes) + // Find the new dimensions of the flat icon to fit the added overlay + addX1 = min(flatX1, I.pixel_x+1) + addX2 = max(flatX2, I.pixel_x+add.Width()) + addY1 = min(flatY1, I.pixel_y+1) + addY2 = max(flatY2, I.pixel_y+add.Height()) - // Find the new dimensions of the flat icon to fit the added overlay - addX1 = min(flatX1, I:pixel_x+1) - addX2 = max(flatX2, I:pixel_x+add.Width()) - addY1 = min(flatY1, I:pixel_y+1) - addY2 = max(flatY2, I:pixel_y+add.Height()) + if(addX1!=flatX1 || addX2!=flatX2 || addY1!=flatY1 || addY2!=flatY2) + // Resize the flattened icon so the new icon fits + flat.Crop(addX1-flatX1+1, addY1-flatY1+1, addX2-flatX1+1, addY2-flatY1+1) + flatX1=addX1;flatX2=addX2 + flatY1=addY1;flatY2=addY2 - if(addX1!=flatX1 || addX2!=flatX2 || addY1!=flatY1 || addY2!=flatY2) - // Resize the flattened icon so the new icon fits - flat.Crop(addX1-flatX1+1, addY1-flatY1+1, addX2-flatX1+1, addY2-flatY1+1) - flatX1=addX1;flatX2=addX2 - flatY1=addY1;flatY2=addY2 + // Blend the overlay into the flattened icon + flat.Blend(add, blendMode2iconMode(curblend), I.pixel_x + 2 - flatX1, I.pixel_y + 2 - flatY1) - // Blend the overlay into the flattened icon - flat.Blend(add, blendMode2iconMode(curblend), I:pixel_x + 2 - flatX1, I:pixel_y + 2 - flatY1) - - if(A.color) - flat.Blend(A.color, ICON_MULTIPLY) - if(A.alpha < 255) - flat.Blend(rgb(255, 255, 255, A.alpha), ICON_MULTIPLY) + if(A.color) + flat.Blend(A.color, ICON_MULTIPLY) + if(A.alpha < 255) + flat.Blend(rgb(255, 255, 255, A.alpha), ICON_MULTIPLY) + if(no_anim) + //Clean up repeated frames + var/icon/cleaned = new /icon() + cleaned.Insert(flat, "", SOUTH, 1, 0) + return cleaned + else return icon(flat, "", SOUTH) - getIconMask(atom/A)//By yours truly. Creates a dynamic mask for a mob/whatever. /N - var/icon/alpha_mask = new(A.icon,A.icon_state)//So we want the default icon and icon state of A. - for(var/I in A.overlays)//For every image in overlays. var/image/I will not work, don't try it. - if(I:layer>A.layer) continue//If layer is greater than what we need, skip it. - var/icon/image_overlay = new(I:icon,I:icon_state)//Blend only works with icon objects. - //Also, icons cannot directly set icon_state. Slower than changing variables but whatever. - alpha_mask.Blend(image_overlay,ICON_OR)//OR so they are lumped together in a nice overlay. - return alpha_mask//And now return the mask. +/proc/getIconMask(atom/A)//By yours truly. Creates a dynamic mask for a mob/whatever. /N + var/icon/alpha_mask = new(A.icon,A.icon_state)//So we want the default icon and icon state of A. + for(var/I in A.overlays)//For every image in overlays. var/image/I will not work, don't try it. + if(I:layer>A.layer) continue//If layer is greater than what we need, skip it. + var/icon/image_overlay = new(I:icon,I:icon_state)//Blend only works with icon objects. + //Also, icons cannot directly set icon_state. Slower than changing variables but whatever. + alpha_mask.Blend(image_overlay,ICON_OR)//OR so they are lumped together in a nice overlay. + return alpha_mask//And now return the mask. //getFlatIcon but generates an icon that can face ALL four directions. The only four. /proc/getCompoundIcon(atom/A) - var/icon/north = getFlatIcon(A,defdir=NORTH,always_use_defdir=1) - var/icon/south = getFlatIcon(A,defdir=SOUTH,always_use_defdir=1) - var/icon/east = getFlatIcon(A,defdir=EAST,always_use_defdir=1) - var/icon/west = getFlatIcon(A,defdir=WEST,always_use_defdir=1) + var/icon/north = getFlatIcon(A,defdir=NORTH) + var/icon/south = getFlatIcon(A,defdir=SOUTH) + var/icon/east = getFlatIcon(A,defdir=EAST) + var/icon/west = getFlatIcon(A,defdir=WEST) //Starts with a blank icon because of byond bugs. var/icon/full = icon('icons/effects/effects.dmi', "icon_state"="nothing") @@ -818,7 +854,7 @@ proc // Creates a single icon from a given /atom or /image. Only the first argu return full /proc/downloadImage(atom/A, dir) - var/icon/this_icon = getFlatIcon(A,defdir=dir||A.dir,always_use_defdir=1) + var/icon/this_icon = getFlatIcon(A,defdir=dir) usr << ftp(this_icon,"[A.name].png") @@ -886,5 +922,80 @@ proc/sort_atoms_by_layer(var/list/atoms) /proc/gen_hud_image(var/file, var/person, var/state, var/plane) var/image/img = image(file, person, state) img.plane = plane //Thanks Byond. - img.appearance_flags = APPEARANCE_UI|KEEP_APART + img.layer = MOB_LAYER-0.2 + img.appearance_flags = APPEARANCE_UI return img + +/** +* Animate a 'halo' around an object. +* +* This proc is not exactly cheap. You'd be well advised to set up many-loops rather than call this super-often. getCompoundIcon is +* mostly to blame for this. If Byond ever implements a way to get something's icon more 'gently' than this, do that instead. +* +* @param A This is the atom to put the halo on +* @param simple_icons If set to TRUE, will just perform a very basic icon and icon_state steal. DO USE when possible. +* @param color This is the color for the halo +* @param anim_duration This decides how fast (or slow) the animation plays +* @param offset Mysterious variable that determines size of the halo's gap from icon +* @param loops How many times the animation loops +* @param grow_to Relative to the size of the icon, how big the halo grows while fading (don't use negatives for inward halos, use < 1) +* @param pixel_scale If you'd like the halo to use pixel scale or the default 'fuzzy' scale +*/ +/proc/animate_aura(var/atom/A, var/simple_icons, var/color = "#00FF22", var/anim_duration = 5, var/offset = 1, var/loops = 1, var/grow_to = 2, var/pixel_scale = FALSE) + ASSERT(A) + + //Take a guess at this, if they didn't set it + if(isnull(simple_icons)) + if(ismob(A)) + simple_icons = FALSE + else + simple_icons = TRUE + + //Get their icon + var/icon/hole + + if(simple_icons) + hole = icon(A.icon, A.icon_state) + else + hole = getCompoundIcon(A) + + hole.MapColors(0,0,0, 0,0,0, 0,0,0, 1,1,1) //White. + + //Make a bigger version + var/icon/grower = new(hole) + var/orig_width = grower.Width() + var/orig_height = grower.Height() + var/end_width = orig_width+(offset*2) + var/end_height = orig_height+(offset*2) + var/half_diff_width = (end_width-orig_width)*0.5 + var/half_diff_height = (end_height-orig_height)*0.5 + + //Make icon black + grower.SwapColor("#FFFFFF","#000000") //Black. + + //Scale both icons big so we don't have to deal with low-pixel garbage issues + grower.Scale(orig_width*10,orig_height*10) + hole.Scale(orig_width*9,orig_height*9) + + //Blend the hole in + grower.Blend(hole,ICON_OVERLAY, x = ((orig_width*10-orig_width*9)*0.5)+1, y = ((orig_height*10-orig_height*9)*0.5)+1) + + //Swap white to zero alpha + grower.SwapColor("#FFFFFF","#00000000") + + //Color it + grower.SwapColor("#000000",color) + + //Scale it to final height + grower.Scale(end_width,end_height) + + //Flick it onto them + var/image/img = image(grower,A) + if(pixel_scale) + img.appearance_flags |= PIXEL_SCALE + img.pixel_x = half_diff_width*-1 + img.pixel_y = half_diff_height*-1 + flick_overlay_view(img, A, anim_duration*loops, TRUE) + + //Animate it growing + animate(img, alpha = 0, transform = matrix()*grow_to, time = anim_duration, loop = loops) diff --git a/code/_helpers/logging.dm b/code/_helpers/logging.dm index cd42c84224..6644cc2efe 100644 --- a/code/_helpers/logging.dm +++ b/code/_helpers/logging.dm @@ -25,9 +25,14 @@ if (config.log_admin) diary << "\[[time_stamp()]]ADMIN: [text][log_end]" +/proc/log_adminpm(text, client/source, client/dest) + admin_log.Add(text) + if (config.log_admin) + diary << "\[[time_stamp()]]ADMINPM: [key_name(source)]->[key_name(dest)]: [html_decode(text)][log_end]" + /proc/log_debug(text) if (config.log_debug) - diary << "\[[time_stamp()]]DEBUG: [text][log_end]" + debug_log << "\[[time_stamp()]]DEBUG: [text][log_end]" for(var/client/C in admins) if(C.is_preference_enabled(/datum/client_preference/debug/show_debug_logs)) @@ -41,47 +46,81 @@ if (config.log_vote) diary << "\[[time_stamp()]]VOTE: [text][log_end]" -/proc/log_access(text) +/proc/log_access_in(client/new_client) if (config.log_access) - diary << "\[[time_stamp()]]ACCESS: [text][log_end]" + var/message = "[key_name(new_client)] - IP:[new_client.address] - CID:[new_client.computer_id] - BYOND v[new_client.byond_version]" + diary << "\[[time_stamp()]]ACCESS IN: [message][log_end]" -/proc/log_say(text) +/proc/log_access_out(mob/last_mob) + if (config.log_access) + var/message = "[key_name(last_mob)] - IP:[last_mob.lastKnownIP] - CID:Logged Out - BYOND Logged Out" + diary << "\[[time_stamp()]]ACCESS OUT: [message][log_end]" + +/proc/log_say(text, mob/speaker) if (config.log_say) - diary << "\[[time_stamp()]]SAY: [text][log_end]" + diary << "\[[time_stamp()]]SAY: [speaker.simple_info_line()]: [html_decode(text)][log_end]" -/proc/log_ooc(text) +/proc/log_ooc(text, client/user) if (config.log_ooc) - diary << "\[[time_stamp()]]OOC: [text][log_end]" + diary << "\[[time_stamp()]]OOC: [user.simple_info_line()]: [html_decode(text)][log_end]" -/proc/log_whisper(text) +/proc/log_aooc(text, client/user) + if (config.log_ooc) + diary << "\[[time_stamp()]]AOOC: [user.simple_info_line()]: [html_decode(text)][log_end]" + +/proc/log_looc(text, client/user) + if (config.log_ooc) + diary << "\[[time_stamp()]]LOOC: [user.simple_info_line()]: [html_decode(text)][log_end]" + +/proc/log_whisper(text, mob/speaker) if (config.log_whisper) - diary << "\[[time_stamp()]]WHISPER: [text][log_end]" + diary << "\[[time_stamp()]]WHISPER: [speaker.simple_info_line()]: [html_decode(text)][log_end]" -/proc/log_emote(text) +/proc/log_emote(text, mob/speaker) if (config.log_emote) - diary << "\[[time_stamp()]]EMOTE: [text][log_end]" + diary << "\[[time_stamp()]]EMOTE: [speaker.simple_info_line()]: [html_decode(text)][log_end]" -/proc/log_attack(text) +/proc/log_attack(attacker, defender, message) if (config.log_attack) - diary << "\[[time_stamp()]]ATTACK: [text][log_end]" //Seperate attack logs? Why? FOR THE GLORY OF SATAN! + diary << "\[[time_stamp()]]ATTACK: [attacker] against [defender]: [message][log_end]" -/proc/log_adminsay(text) +/proc/log_adminsay(text, mob/speaker) if (config.log_adminchat) - diary << "\[[time_stamp()]]ADMINSAY: [text][log_end]" + diary << "\[[time_stamp()]]ADMINSAY: [speaker.simple_info_line()]: [html_decode(text)][log_end]" + +/proc/log_modsay(text, mob/speaker) + if (config.log_adminchat) + diary << "\[[time_stamp()]]MODSAY: [speaker.simple_info_line()]: [html_decode(text)][log_end]" + +/proc/log_eventsay(text, mob/speaker) + if (config.log_adminchat) + diary << "\[[time_stamp()]]EVENTSAY: [speaker.simple_info_line()]: [html_decode(text)][log_end]" + +/proc/log_ghostsay(text, mob/speaker) + if (config.log_say) + diary << "\[[time_stamp()]]DEADCHAT: [speaker.simple_info_line()]: [html_decode(text)][log_end]" + +/proc/log_ghostemote(text, mob/speaker) + if (config.log_emote) + diary << "\[[time_stamp()]]DEADEMOTE: [speaker.simple_info_line()]: [html_decode(text)][log_end]" /proc/log_adminwarn(text) if (config.log_adminwarn) - diary << "\[[time_stamp()]]ADMINWARN: [text][log_end]" + diary << "\[[time_stamp()]]ADMINWARN: [html_decode(text)][log_end]" -/proc/log_pda(text) +/proc/log_pda(text, mob/speaker) if (config.log_pda) - diary << "\[[time_stamp()]]PDA: [text][log_end]" + diary << "\[[time_stamp()]]PDA: [speaker.simple_info_line()]: [html_decode(text)][log_end]" /proc/log_to_dd(text) world.log << text //this comes before the config check because it can't possibly runtime if(config.log_world_output) diary << "\[[time_stamp()]]DD_OUTPUT: [text][log_end]" +/proc/log_error(text) + world.log << text + error_log << "\[[time_stamp()]]RUNTIME: [text][log_end]" + /proc/log_misc(text) diary << "\[[time_stamp()]]MISC: [text][log_end]" @@ -105,12 +144,14 @@ return english_list(comps, nothing_text="0", and_text="|", comma_text="|") //more or less a logging utility -/proc/key_name(var/whom, var/include_link = null, var/include_name = 1, var/highlight_special_characters = 1) +//Always return "Something/(Something)", even if it's an error message. +/proc/key_name(var/whom, var/include_link = FALSE, var/include_name = TRUE, var/highlight_special_characters = TRUE) var/mob/M var/client/C var/key - if(!whom) return "*null*" + if(!whom) + return "INVALID/INVALID" if(istype(whom, /client)) C = whom M = C.mob @@ -127,9 +168,11 @@ C = D.current.client else if(istype(whom, /datum)) var/datum/D = whom - return "*invalid:[D.type]*" + return "INVALID/([D.type])" + else if(istext(whom)) + return "AUTOMATED/[whom]" //Just give them the text back else - return "*invalid*" + return "INVALID/INVALID" . = "" @@ -137,7 +180,7 @@ if(include_link && C) . += "" - if(C && C.holder && C.holder.fakekey && !include_name) + if(C && C.holder && C.holder.fakekey) . += "Administrator" else . += key @@ -146,21 +189,20 @@ if(C) . += "" else . += " (DC)" else - . += "*no key*" + . += "INVALID" - if(include_name && M) - var/name + if(include_name) + var/name = "INVALID" + if(M) + if(M.real_name) + name = M.real_name + else if(M.name) + name = M.name - if(M.real_name) - name = M.real_name - else if(M.name) - name = M.name - - - if(include_link && is_special_character(M) && highlight_special_characters) - . += "/([name])" //Orange - else - . += "/([name])" + if(include_link && is_special_character(M) && highlight_special_characters) + name = "[name]" //Orange + + . += "/([name])" return . @@ -187,3 +229,9 @@ if(!istype(d)) return return d.log_info_line() + +/mob/proc/simple_info_line() + return "[key_name(src)] ([x],[y],[z])" + +/client/proc/simple_info_line() + return "[key_name(src)] ([mob.x],[mob.y],[mob.z])" diff --git a/code/_helpers/mobs.dm b/code/_helpers/mobs.dm index e1215bb901..e82e618651 100644 --- a/code/_helpers/mobs.dm +++ b/code/_helpers/mobs.dm @@ -33,7 +33,7 @@ return mobs -proc/random_hair_style(gender, species = "Human") +proc/random_hair_style(gender, species = SPECIES_HUMAN) var/h_style = "Bald" var/list/valid_hairstyles = list() @@ -52,7 +52,7 @@ proc/random_hair_style(gender, species = "Human") return h_style -proc/random_facial_hair_style(gender, species = "Human") +proc/random_facial_hair_style(gender, species = SPECIES_HUMAN) var/f_style = "Shaved" var/list/valid_facialhairstyles = list() @@ -72,14 +72,14 @@ proc/random_facial_hair_style(gender, species = "Human") return f_style -proc/sanitize_name(name, species = "Human", robot = 0) +proc/sanitize_name(name, species = SPECIES_HUMAN, robot = 0) var/datum/species/current_species if(species) current_species = all_species[species] return current_species ? current_species.sanitize_name(name, robot) : sanitizeName(name, MAX_NAME_LEN, robot) -proc/random_name(gender, species = "Human") +proc/random_name(gender, species = SPECIES_HUMAN) var/datum/species/current_species if(species) @@ -145,13 +145,23 @@ Proc for attack log creation, because really why not 6 is additional information, anything that needs to be added */ -/proc/add_logs(mob/user, mob/target, what_done, var/admin=1, var/object=null, var/addition=null) - if(user && ismob(user)) - user.attack_log += text("\[[time_stamp()]\] Has [what_done] [target ? "[target.name][(ismob(target) && target.ckey) ? "([target.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition]") - if(target && ismob(target)) - target.attack_log += text("\[[time_stamp()]\] Has been [what_done] by [user ? "[user.name][(ismob(user) && user.ckey) ? "([user.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition]") - if(admin) - log_attack("[user ? "[user.name][(ismob(user) && user.ckey) ? "([user.ckey])" : ""]" : "NON-EXISTANT SUBJECT"] [what_done] [target ? "[target.name][(ismob(target) && target.ckey)? "([target.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition]") +/proc/add_attack_logs(mob/user, mob/target, what_done, var/admin_notify = TRUE) + if(islist(target)) //Multi-victim adding + var/list/targets = target + for(var/mob/M in targets) + add_attack_logs(user,M,what_done,admin_notify) + return + + var/user_str = key_name(user) + var/target_str = key_name(target) + + if(ismob(user)) + user.attack_log += text("\[[time_stamp()]\] Attacked [target_str]: [what_done]") + if(ismob(target)) + target.attack_log += text("\[[time_stamp()]\] Attacked by [user_str]: [what_done]") + log_attack(user_str,target_str,what_done) + if(admin_notify) + msg_admin_attack("[key_name_admin(user)] vs [target_str]: [what_done]") //checks whether this item is a module of the robot it is located in. /proc/is_robot_module(var/obj/item/thing) @@ -213,6 +223,8 @@ Proc for attack log creation, because really why not /proc/do_after(mob/user, delay, atom/target = null, needhand = 1, progress = 1, var/incapacitation_flags = INCAPACITATION_DEFAULT) if(!user) return 0 + if(!delay) + return 1 //Okay. Done. var/atom/target_loc = null if(target) target_loc = target.loc @@ -264,3 +276,16 @@ Proc for attack log creation, because really why not humans += H return humans + +/proc/getviewsize(view) + var/viewX + var/viewY + if(isnum(view)) + var/totalviewrange = 1 + 2 * view + viewX = totalviewrange + viewY = totalviewrange + else + var/list/viewrangelist = splittext(view,"x") + viewX = text2num(viewrangelist[1]) + viewY = text2num(viewrangelist[2]) + return list(viewX, viewY) diff --git a/code/_helpers/sorts/comparators.dm b/code/_helpers/sorts/comparators.dm index 1b4b834692..7fd07ec711 100644 --- a/code/_helpers/sorts/comparators.dm +++ b/code/_helpers/sorts/comparators.dm @@ -36,3 +36,9 @@ . = b.head_position - a.head_position if (. == 0) //Already in head/nothead spot, sort by name . = sorttext(b.title, a.title) + +// Sorts entries in a performance stats list. +/proc/cmp_generic_stat_item_time(list/A, list/B) + . = B[STAT_ENTRY_TIME] - A[STAT_ENTRY_TIME] + if (!.) + . = B[STAT_ENTRY_COUNT] - A[STAT_ENTRY_COUNT] diff --git a/code/_helpers/time.dm b/code/_helpers/time.dm index 6dad42e128..58348761f8 100644 --- a/code/_helpers/time.dm +++ b/code/_helpers/time.dm @@ -58,8 +58,11 @@ var/next_station_date_change = 1 DAY station_date = num2text((text2num(time2text(timeofday, "YYYY"))+544)) + "-" + time2text(timeofday, "MM-DD") return station_date +//ISO 8601 /proc/time_stamp() - return time2text(station_time_in_ticks, "hh:mm:ss") + var/date_portion = time2text(world.timeofday, "YYYY-MM-DD") + var/time_portion = time2text(world.timeofday, "hh:mm:ss") + return "[date_portion]T[time_portion]" /* Returns 1 if it is the selected month and day */ proc/isDay(var/month, var/day) diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm index 3d3877ab5b..41aa04a5c0 100644 --- a/code/_helpers/unsorted.dm +++ b/code/_helpers/unsorted.dm @@ -509,6 +509,16 @@ Turf and target are seperate in case you want to teleport some distance from a t // mob_list.Add(M) return moblist +// Format a power value in W, kW, MW, or GW. +/proc/DisplayPower(powerused) + if(powerused < 1000) //Less than a kW + return "[powerused] W" + else if(powerused < 1000000) //Less than a MW + return "[round((powerused * 0.001),0.01)] kW" + else if(powerused < 1000000000) //Less than a GW + return "[round((powerused * 0.000001),0.001)] MW" + return "[round((powerused * 0.000000001),0.0001)] GW" + //Forces a variable to be posative /proc/modulus(var/M) if(M >= 0) @@ -790,7 +800,6 @@ proc/GaussRandRound(var/sigma,var/roundto) var/old_dir1 = T.dir var/old_icon_state1 = T.icon_state var/old_icon1 = T.icon - var/old_overlays = T.overlays.Copy() var/old_underlays = T.underlays.Copy() var/old_decals = T.decals ? T.decals.Copy() : null @@ -798,11 +807,9 @@ proc/GaussRandRound(var/sigma,var/roundto) X.set_dir(old_dir1) X.icon_state = old_icon_state1 X.icon = old_icon1 - X.overlays = old_overlays + X.copy_overlays(T, TRUE) X.underlays = old_underlays X.decals = old_decals - if(old_decals) - X.apply_decals() //Move the air from source to dest var/turf/simulated/ST = T @@ -828,14 +835,10 @@ proc/GaussRandRound(var/sigma,var/roundto) if(shuttlework) var/turf/simulated/shuttle/SS = T SS.landed_holder.leave_turf() - else if(turftoleave) T.ChangeTurf(turftoleave) - T.apply_decals() - else T.ChangeTurf(get_base_turf_by_area(T)) - T.apply_decals() refined_src -= T refined_trg -= B @@ -1419,4 +1422,51 @@ var/mob/dview/dview_mob = new return USE_FAIL_NOT_IN_USER #undef NOT_FLAG -#undef HAS_FLAG \ No newline at end of file +#undef HAS_FLAG + +// Returns direction-string, rounded to multiples of 22.5, from the first parameter to the second +// N, NNE, NE, ENE, E, ESE, SE, SSE, S, SSW, SW, WSW, W, WNW, NW, NNW +/proc/get_adir(var/turf/A, var/turf/B) + var/degree = Get_Angle(A, B) + switch(round(degree%360, 22.5)) + if(0) + return "North" + if(22.5) + return "North-Northeast" + if(45) + return "Northeast" + if(67.5) + return "East-Northeast" + if(90) + return "East" + if(112.5) + return "East-Southeast" + if(135) + return "Southeast" + if(157.5) + return "South-Southeast" + if(180) + return "South" + if(202.5) + return "South-Southwest" + if(225) + return "Southwest" + if(247.5) + return "West-Southwest" + if(270) + return "West" + if(292.5) + return "West-Northwest" + if(315) + return "Northwest" + if(337.5) + return "North-Northwest" + + + + + + + + + diff --git a/code/_onclick/hud/alien_larva.dm b/code/_onclick/hud/alien_larva.dm index 1f0df80141..2ec9da3b27 100644 --- a/code/_onclick/hud/alien_larva.dm +++ b/code/_onclick/hud/alien_larva.dm @@ -11,7 +11,7 @@ using.icon = 'icons/mob/screen1_alien.dmi' using.icon_state = (mymob.m_intent == "run" ? "running" : "walking") using.screen_loc = ui_acti - using.layer = 20 + using.layer = HUD_LAYER src.adding += using move_intent = using diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 786c7cdd04..c63519c40f 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -9,6 +9,7 @@ var/list/global_huds = list( global_hud.whitense, global_hud.vimpaired, global_hud.darkMask, + global_hud.centermarker, global_hud.nvg, global_hud.thermal, global_hud.meson, @@ -27,6 +28,7 @@ var/list/global_huds = list( var/obj/screen/whitense var/list/vimpaired var/list/darkMask + var/obj/screen/centermarker var/obj/screen/darksight var/obj/screen/nvg var/obj/screen/thermal @@ -47,7 +49,6 @@ var/list/global_huds = list( /obj/screen/global_screen screen_loc = ui_entire_screen - layer = 17 plane = PLANE_FULLSCREEN mouse_opacity = 0 @@ -70,7 +71,12 @@ var/list/global_huds = list( darksight.icon = null darksight.screen_loc = "1,1" darksight.plane = PLANE_LIGHTING - darksight.plane = LIGHTING_LAYER + 0.1 + + //Marks the center of the screen, for things like ventcrawl + centermarker = new /obj/screen() + centermarker.icon = 'icons/mob/screen1.dmi' + centermarker.icon_state = "centermarker" + centermarker.screen_loc = "CENTER,CENTER" nvg = setup_overlay("nvg_hud") thermal = setup_overlay("thermal_hud") @@ -117,20 +123,17 @@ var/list/global_huds = list( for(i = 1, i <= 4, i++) O = vimpaired[i] O.icon_state = "dither50" - O.layer = 17 O.plane = PLANE_FULLSCREEN O.mouse_opacity = 0 O = darkMask[i] O.icon_state = "dither50" - O.layer = 17 O.plane = PLANE_FULLSCREEN O.mouse_opacity = 0 for(i = 5, i <= 8, i++) O = darkMask[i] O.icon_state = "black" - O.layer = 17 O.plane = PLANE_FULLSCREEN O.mouse_opacity = 2 @@ -164,6 +167,7 @@ var/list/global_huds = list( var/obj/screen/movable/action_button/hide_toggle/hide_actions_toggle var/action_buttons_hidden = 0 + var/list/slot_info datum/hud/New(mob/owner) mymob = owner diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index 83f23930dd..1c903700b0 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -14,6 +14,7 @@ src.adding = list() src.other = list() src.hotkeybuttons = list() //These can be disabled for hotkey users + src.slot_info = list() var/list/hud_elements = list() var/obj/screen/using @@ -33,6 +34,7 @@ inv_box.screen_loc = slot_data["loc"] inv_box.slot_id = slot_data["slot"] inv_box.icon_state = slot_data["state"] + slot_info["[inv_box.slot_id]"] = inv_box.screen_loc if(slot_data["dir"]) inv_box.set_dir(slot_data["dir"]) @@ -75,7 +77,7 @@ ico = new(ui_style, "black") ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1) ico.DrawBox(rgb(255,255,255,1),1,ico.Height()/2,ico.Width()/2,ico.Height()) - using = new /obj/screen( src ) + using = new /obj/screen() using.name = I_HELP using.icon = ico using.screen_loc = ui_acti @@ -87,7 +89,7 @@ ico = new(ui_style, "black") ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1) ico.DrawBox(rgb(255,255,255,1),ico.Width()/2,ico.Height()/2,ico.Width(),ico.Height()) - using = new /obj/screen( src ) + using = new /obj/screen() using.name = I_DISARM using.icon = ico using.screen_loc = ui_acti @@ -99,7 +101,7 @@ ico = new(ui_style, "black") ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1) ico.DrawBox(rgb(255,255,255,1),ico.Width()/2,1,ico.Width(),ico.Height()/2) - using = new /obj/screen( src ) + using = new /obj/screen() using.name = I_GRAB using.icon = ico using.screen_loc = ui_acti @@ -111,7 +113,7 @@ ico = new(ui_style, "black") ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1) ico.DrawBox(rgb(255,255,255,1),1,1,ico.Width()/2,ico.Height()/2) - using = new /obj/screen( src ) + using = new /obj/screen() using.name = I_HURT using.icon = ico using.screen_loc = ui_acti @@ -164,9 +166,9 @@ inv_box.slot_id = slot_r_hand inv_box.color = ui_color inv_box.alpha = ui_alpha - src.r_hand_hud_object = inv_box src.adding += inv_box + slot_info["[slot_r_hand]"] = inv_box.screen_loc inv_box = new /obj/screen/inventory/hand() inv_box.hud = src @@ -181,6 +183,7 @@ inv_box.alpha = ui_alpha src.l_hand_hud_object = inv_box src.adding += inv_box + slot_info["[slot_l_hand]"] = inv_box.screen_loc using = new /obj/screen/inventory() using.name = "hand" diff --git a/code/_onclick/hud/other_mobs.dm b/code/_onclick/hud/other_mobs.dm index cab3e3bfca..325a4a4b7e 100644 --- a/code/_onclick/hud/other_mobs.dm +++ b/code/_onclick/hud/other_mobs.dm @@ -11,13 +11,13 @@ blobpwrdisplay.name = "blob power" blobpwrdisplay.icon_state = "block" blobpwrdisplay.screen_loc = ui_health - blobpwrdisplay.layer = 20 + blobpwrdisplay.layer = HUD_LAYER blobhealthdisplay = new /obj/screen() blobhealthdisplay.name = "blob health" blobhealthdisplay.icon_state = "block" blobhealthdisplay.screen_loc = ui_internal - blobhealthdisplay.layer = 20 + blobhealthdisplay.layer = HUD_LAYER mymob.client.screen = list() @@ -36,7 +36,7 @@ using.icon = ui_style using.icon_state = "intent_"+mymob.a_intent using.screen_loc = ui_zonesel - using.layer = 20 + using.layer = HUD_LAYER src.adding += using action_intent = using @@ -50,7 +50,7 @@ using.name = "help" using.icon = ico using.screen_loc = ui_zonesel - using.layer = 21 + using.layer = HUD_LAYER+0.01 src.adding += using help_intent = using @@ -61,7 +61,7 @@ using.name = "disarm" using.icon = ico using.screen_loc = ui_zonesel - using.layer = 21 + using.layer = HUD_LAYER+0.01 src.adding += using disarm_intent = using @@ -72,7 +72,7 @@ using.name = "grab" using.icon = ico using.screen_loc = ui_zonesel - using.layer = 21 + using.layer = HUD_LAYER+0.01 src.adding += using grab_intent = using @@ -83,7 +83,7 @@ using.name = I_HURT using.icon = ico using.screen_loc = ui_zonesel - using.layer = 21 + using.layer = HUD_LAYER+0.01 src.adding += using hurt_intent = using diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index daaa52e827..dc414df11f 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -30,7 +30,7 @@ var/obj/screen/robot_inventory using.alpha = ui_alpha using.icon_state = "radio" using.screen_loc = ui_movi - using.layer = 20 + using.layer = HUD_LAYER src.adding += using //Module select @@ -43,7 +43,7 @@ var/obj/screen/robot_inventory using.alpha = ui_alpha using.icon_state = "inv1" using.screen_loc = ui_inv1 - using.layer = 20 + using.layer = HUD_LAYER src.adding += using mymob:inv1 = using @@ -55,7 +55,7 @@ var/obj/screen/robot_inventory using.alpha = ui_alpha using.icon_state = "inv2" using.screen_loc = ui_inv2 - using.layer = 20 + using.layer = HUD_LAYER src.adding += using mymob:inv2 = using @@ -67,7 +67,7 @@ var/obj/screen/robot_inventory using.alpha = ui_alpha using.icon_state = "inv3" using.screen_loc = ui_inv3 - using.layer = 20 + using.layer = HUD_LAYER src.adding += using mymob:inv3 = using @@ -81,7 +81,7 @@ var/obj/screen/robot_inventory using.alpha = ui_alpha using.icon_state = mymob.a_intent using.screen_loc = ui_acti - using.layer = 20 + using.layer = HUD_LAYER src.adding += using action_intent = using @@ -119,7 +119,7 @@ var/obj/screen/robot_inventory using.icon_state = "panel" using.alpha = ui_alpha using.screen_loc = ui_borg_panel - using.layer = 19 + using.layer = HUD_LAYER-0.01 src.adding += using //Store @@ -276,6 +276,6 @@ var/obj/screen/robot_inventory r.client.screen -= r.robot_modules_background /mob/living/silicon/robot/update_hud() - ..() if(modtype) hands.icon_state = lowertext(modtype) + ..() \ No newline at end of file diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 9bf89b27bd..5c7c07ec25 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -278,7 +278,7 @@ // Rigs are a fucking pain since they keep an air tank in nullspace. if(istype(C.back,/obj/item/weapon/rig)) var/obj/item/weapon/rig/rig = C.back - if(rig.air_supply) + if(rig.air_supply && !rig.offline) from = "in" nicename |= "hardsuit" tankcheck |= rig.air_supply diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index a066981e01..428485573d 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -84,9 +84,7 @@ avoid code duplication. This includes items that may sometimes act as a standard M.lastattacker = user if(!no_attack_log) - user.attack_log += "\[[time_stamp()]\] Attacked [M.name] ([M.ckey]) with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" - M.attack_log += "\[[time_stamp()]\] Attacked by [user.name] ([user.ckey]) with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" - msg_admin_attack("[key_name(user)] attacked [key_name(M)] with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" ) + add_attack_logs(user,M,"attacked with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])") ///////////////////////// user.setClickCooldown(user.get_attack_speed(src)) diff --git a/code/_onclick/telekinesis.dm b/code/_onclick/telekinesis.dm index f08727abf3..26c1680421 100644 --- a/code/_onclick/telekinesis.dm +++ b/code/_onclick/telekinesis.dm @@ -68,7 +68,7 @@ var/const/tk_maxrange = 15 flags = NOBLUDGEON //item_state = null w_class = ITEMSIZE_NO_CONTAINER - layer = 20 + layer = HUD_LAYER var/last_throw = 0 var/atom/movable/focus = null diff --git a/code/controllers/Processes/inactivity.dm b/code/controllers/Processes/inactivity.dm index 2a6cd44d2c..3b118995bf 100644 --- a/code/controllers/Processes/inactivity.dm +++ b/code/controllers/Processes/inactivity.dm @@ -7,10 +7,10 @@ for(last_object in clients) var/client/C = last_object if(C.is_afk(config.kick_inactive MINUTES)) - if(!istype(C.mob, /mob/observer/dead) && !istype(C.mob, /mob/new_player)) - to_chat(C,"You have been inactive for more than [config.kick_inactive] minute\s and have been disconnected.") - var/information + to_chat(C,"You have been inactive for more than [config.kick_inactive] minute\s and have been disconnected.") + var/information + if(C.mob) if(ishuman(C.mob)) var/job var/mob/living/carbon/human/H = C.mob @@ -27,10 +27,10 @@ else if(issilicon(C.mob)) information = " while a silicon." - var/adminlinks - adminlinks = " (JMP|CRYO)" + var/adminlinks + adminlinks = " (JMP|CRYO)" - log_and_message_admins("being kicked for AFK[information][adminlinks]", C.mob) + log_and_message_admins("being kicked for AFK[information][adminlinks]", C.mob) - qdel(C) + qdel(C) SCHECK diff --git a/code/controllers/Processes/planet.dm b/code/controllers/Processes/planet.dm index f9fd57f788..e39b5e81b8 100644 --- a/code/controllers/Processes/planet.dm +++ b/code/controllers/Processes/planet.dm @@ -47,7 +47,8 @@ var/datum/controller/process/planet/planet_controller = null //Weather style needs redrawing if(P.needs_work & PLANET_PROCESS_WEATHER) P.needs_work &= ~PLANET_PROCESS_WEATHER - var/image/new_overlay = image(icon = P.weather_holder.current_weather.icon, icon_state = P.weather_holder.current_weather.icon_state, layer = LIGHTING_LAYER - 1) + var/image/new_overlay = image(icon = P.weather_holder.current_weather.icon, icon_state = P.weather_holder.current_weather.icon_state) + new_overlay.plane = PLANE_PLANETLIGHTING //Redraw weather icons for(var/T in P.planet_floors) var/turf/simulated/turf = T diff --git a/code/controllers/Processes/scheduler.dm b/code/controllers/Processes/scheduler.dm index 6031f2f4fe..a2a2f5f925 100644 --- a/code/controllers/Processes/scheduler.dm +++ b/code/controllers/Processes/scheduler.dm @@ -8,19 +8,21 @@ /datum/controller/process/scheduler/setup() name = "scheduler" - schedule_interval = 3 SECONDS + schedule_interval = 1 SECOND scheduled_tasks = list() scheduler = src /datum/controller/process/scheduler/doWork() + var/world_time = world.time for(last_object in scheduled_tasks) var/datum/scheduled_task/scheduled_task = last_object + if(world_time < scheduled_task.trigger_time) + break // Too early for this one, and therefore too early for all remaining. try - if(world.time > scheduled_task.trigger_time) - unschedule(scheduled_task) - scheduled_task.pre_process() - scheduled_task.process() - scheduled_task.post_process() + unschedule(scheduled_task) + scheduled_task.pre_process() + scheduled_task.process() + scheduled_task.post_process() catch(var/exception/e) catchException(e, last_object) SCHECK @@ -45,7 +47,7 @@ stat(null, "[scheduled_tasks.len] task\s") /datum/controller/process/scheduler/proc/schedule(var/datum/scheduled_task/st) - scheduled_tasks += st + dd_insertObjectList(scheduled_tasks, st) /datum/controller/process/scheduler/proc/unschedule(var/datum/scheduled_task/st) scheduled_tasks -= st @@ -106,6 +108,9 @@ task_after_process_args.Cut() return ..() +/datum/scheduled_task/dd_SortValue() + return trigger_time + /datum/scheduled_task/proc/pre_process() task_triggered_event.raise_event(list(src)) diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index d4fada9088..29188647f2 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -212,7 +212,7 @@ var/list/gamemode_cache = list() var/starlight = 0 // Whether space turfs have ambient light or not - var/list/ert_species = list("Human") + var/list/ert_species = list(SPECIES_HUMAN) var/law_zero = "ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4'ALL LAWS OVERRIDDEN#*?&110010" @@ -721,7 +721,7 @@ var/list/gamemode_cache = list() if("ert_species") config.ert_species = splittext(value, ";") if(!config.ert_species.len) - config.ert_species += "Human" + config.ert_species += SPECIES_HUMAN if("law_zero") law_zero = value diff --git a/code/controllers/emergency_shuttle_controller.dm b/code/controllers/emergency_shuttle_controller.dm index 7fb3a56c61..d7a91c9b4f 100644 --- a/code/controllers/emergency_shuttle_controller.dm +++ b/code/controllers/emergency_shuttle_controller.dm @@ -234,7 +234,8 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle name = "star" var/speed = 10 var/direction = SOUTH - layer = 2 // TURF_LAYER + layer = TURF_LAYER + plane = TURF_PLANE /obj/effect/bgstar/New() ..() diff --git a/code/controllers/subsystems/air.dm b/code/controllers/subsystems/air.dm index ed4602f048..ef0173c33a 100644 --- a/code/controllers/subsystems/air.dm +++ b/code/controllers/subsystems/air.dm @@ -9,7 +9,7 @@ SUBSYSTEM_DEF(air) name = "Air" init_order = INIT_ORDER_AIR - priority = 20 + priority = 35 wait = 2 SECONDS // seconds (We probably can speed this up actually) flags = SS_BACKGROUND // TODO - Should this really be background? It might be important. runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME diff --git a/code/controllers/subsystems/airflow.dm b/code/controllers/subsystems/airflow.dm index 9db8138826..c98a02a5ce 100644 --- a/code/controllers/subsystems/airflow.dm +++ b/code/controllers/subsystems/airflow.dm @@ -14,7 +14,7 @@ SUBSYSTEM_DEF(airflow) wait = 2 flags = SS_NO_INIT runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME - priority = 15 + priority = 30 var/list/processing = list() var/list/currentrun = list() @@ -47,7 +47,7 @@ SUBSYSTEM_DEF(airflow) continue else if (target.airflow_process_delay) target.airflow_process_delay = 0 - + target.airflow_speed = min(target.airflow_speed, 15) target.airflow_speed -= vsc.airflow_speed_decay if (!target.airflow_skip_speedcheck) @@ -89,7 +89,7 @@ SUBSYSTEM_DEF(airflow) if (MC_TICK_CHECK) return continue - + step_towards(target, target.airflow_dest) var/mob/M = target if (ismob(target) && M.client) @@ -98,7 +98,7 @@ SUBSYSTEM_DEF(airflow) if (MC_TICK_CHECK) return -#undef CLEAR_OBJECT +#undef CLEAR_OBJECT /atom/movable var/tmp/airflow_xo @@ -129,9 +129,9 @@ SUBSYSTEM_DEF(airflow) if (airflow_falloff < 1) airflow_dest = null return FALSE - - airflow_speed = min(max(n * (9 / airflow_falloff), 1), 9) - + + airflow_speed = min(max(n * (9 / airflow_falloff), 1), 9) + airflow_od = 0 if (!density) @@ -154,7 +154,7 @@ SUBSYSTEM_DEF(airflow) /atom/movable/proc/RepelAirflowDest(n) if (!prepare_airflow(n)) return - + airflow_xo = -(airflow_dest.x - src.x) airflow_yo = -(airflow_dest.y - src.y) diff --git a/code/controllers/subsystems/atoms.dm b/code/controllers/subsystems/atoms.dm index 6b5669878c..5b09b186bb 100644 --- a/code/controllers/subsystems/atoms.dm +++ b/code/controllers/subsystems/atoms.dm @@ -135,9 +135,7 @@ SUBSYSTEM_DEF(atoms) /datum/controller/subsystem/atoms/Shutdown() var/initlog = InitLog() if(initlog) - //text2file(initlog, "[GLOB.log_directory]/initialize.log") - var/date_string = time2text(world.realtime, "YYYY/MM-Month/DD-Day") - text2file(initlog, "data/logs/[date_string]-initialize.log") + text2file(initlog, "[log_path]-initialize.log") #undef BAD_INIT_QDEL_BEFORE #undef BAD_INIT_DIDNT_INIT diff --git a/code/controllers/subsystems/floor_decals.dm b/code/controllers/subsystems/floor_decals.dm deleted file mode 100644 index 39e4515d0d..0000000000 --- a/code/controllers/subsystems/floor_decals.dm +++ /dev/null @@ -1,28 +0,0 @@ -// -// Floor Decals Initialization Subsystem -// This is part of the giant decal hack that works around a BYOND bug where DreamDaemon will crash if you -// update overlays on turfs too much. -// The master_controller on Polaris used to init decals prior to initializing areas (which initilized turfs) -// Now that we switched to subsystems we still want to do the same thing, so this takes care of it. -// -SUBSYSTEM_DEF(floor_decals) - name = "Floor Decals" - init_order = INIT_ORDER_DECALS - flags = SS_NO_FIRE - -/datum/controller/subsystem/floor_decals/Initialize(timeofday) - if(floor_decals_initialized) - return ..() - to_world_log("Initializing Floor Decals") - admin_notice("Initializing Floor Decals", R_DEBUG) - var/list/turfs_with_decals = list() - for(var/obj/effect/floor_decal/D in world) - var/T = D.add_to_turf_decals() - if(T) turfs_with_decals |= T - CHECK_TICK - for(var/item in turfs_with_decals) - var/turf/T = item - if(T.decals) T.apply_decals() - CHECK_TICK - floor_decals_initialized = TRUE - return ..() diff --git a/code/controllers/subsystems/garbage.dm b/code/controllers/subsystems/garbage.dm index 34b32d5873..b4d43a8d3f 100644 --- a/code/controllers/subsystems/garbage.dm +++ b/code/controllers/subsystems/garbage.dm @@ -81,7 +81,7 @@ SUBSYSTEM_DEF(garbage) dellog += "\tIgnored force: [I.no_respect_force] times" if (I.no_hint) dellog += "\tNo hint: [I.no_hint] times" - log_misc(dellog.Join()) + text2file(dellog.Join(), "[log_path]-qdel.log") /datum/controller/subsystem/garbage/fire() //the fact that this resets its processing each fire (rather then resume where it left off) is intentional. @@ -169,7 +169,12 @@ SUBSYSTEM_DEF(garbage) #endif var/type = D.type var/datum/qdel_item/I = items[type] - testing("GC: -- \ref[D] | [type] was unable to be GC'd --") + var/extrainfo = "--" + if(istype(D,/image)) + var/image/img = D + var/icon/ico = img.icon + extrainfo = "L:[img.loc] -- I:[ico] -- IS:[img.icon_state] --" + testing("GC: -- \ref[D] | [type] was unable to be GC'd [extrainfo]") I.failures++ if (GC_QUEUE_HARDDELETE) HardDelete(D) diff --git a/code/controllers/subsystems/overlays.dm b/code/controllers/subsystems/overlays.dm new file mode 100644 index 0000000000..5c8b3531c9 --- /dev/null +++ b/code/controllers/subsystems/overlays.dm @@ -0,0 +1,255 @@ +SUBSYSTEM_DEF(overlays) + name = "Overlay" + flags = SS_TICKER + wait = 1 + priority = FIRE_PRIORITY_OVERLAYS + init_order = INIT_ORDER_OVERLAY + + var/initialized = FALSE + var/list/queue // Queue of atoms needing overlay compiling (TODO-VERIFY!) + var/list/stats + var/list/overlay_icon_state_caches // Cache thing + var/list/overlay_icon_cache // Cache thing + +var/global/image/stringbro = new() // Temporarily super-global because of BYOND init order dumbness. +var/global/image/iconbro = new() // Temporarily super-global because of BYOND init order dumbness. +var/global/image/appearance_bro = new() // Temporarily super-global because of BYOND init order dumbness. + +/datum/controller/subsystem/overlays/PreInit() + overlay_icon_state_caches = list() + overlay_icon_cache = list() + queue = list() + stats = list() + +/datum/controller/subsystem/overlays/Initialize() + initialized = TRUE + fire(mc_check = FALSE) + ..() + +/datum/controller/subsystem/overlays/stat_entry() + ..("Ov:[length(queue)]") + + +/datum/controller/subsystem/overlays/Shutdown() + text2file(render_stats(stats), "[log_path]-overlay.log") + +/datum/controller/subsystem/overlays/Recover() + overlay_icon_state_caches = SSoverlays.overlay_icon_state_caches + overlay_icon_cache = SSoverlays.overlay_icon_cache + queue = SSoverlays.queue + + +/datum/controller/subsystem/overlays/fire(resumed = FALSE, mc_check = TRUE) + var/list/queue = src.queue + var/static/count = 0 + if (count) + var/c = count + count = 0 //so if we runtime on the Cut, we don't try again. + queue.Cut(1,c+1) + + for (var/thing in queue) + count++ + if(thing) + STAT_START_STOPWATCH + var/atom/A = thing + COMPILE_OVERLAYS(A) + STAT_STOP_STOPWATCH + STAT_LOG_ENTRY(stats, A.type) + if(mc_check) + if(MC_TICK_CHECK) + break + else + CHECK_TICK + + if (count) + queue.Cut(1,count+1) + count = 0 + +/proc/iconstate2appearance(icon, iconstate) + // var/static/image/stringbro = new() // Moved to be superglobal due to BYOND insane init order stupidness. + var/list/icon_states_cache = SSoverlays.overlay_icon_state_caches + var/list/cached_icon = icon_states_cache[icon] + if (cached_icon) + var/cached_appearance = cached_icon["[iconstate]"] + if (cached_appearance) + return cached_appearance + stringbro.icon = icon + stringbro.icon_state = iconstate + if (!cached_icon) //not using the macro to save an associated lookup + cached_icon = list() + icon_states_cache[icon] = cached_icon + var/cached_appearance = stringbro.appearance + cached_icon["[iconstate]"] = cached_appearance + return cached_appearance + +/proc/icon2appearance(icon) + // var/static/image/iconbro = new() // Moved to be superglobal due to BYOND insane init order stupidness. + var/list/icon_cache = SSoverlays.overlay_icon_cache + . = icon_cache[icon] + if (!.) + iconbro.icon = icon + . = iconbro.appearance + icon_cache[icon] = . + +/atom/proc/build_appearance_list(old_overlays) + // var/static/image/appearance_bro = new() // Moved to be superglobal due to BYOND insane init order stupidness. + var/list/new_overlays = list() + if (!islist(old_overlays)) + old_overlays = list(old_overlays) + for (var/overlay in old_overlays) + if(!overlay) + continue + if (istext(overlay)) + new_overlays += iconstate2appearance(icon, overlay) + else if(isicon(overlay)) + new_overlays += icon2appearance(overlay) + else + if(isloc(overlay)) + var/atom/A = overlay + if (A.flags & OVERLAY_QUEUED) + COMPILE_OVERLAYS(A) + appearance_bro.appearance = overlay //this works for images and atoms too! + if(!ispath(overlay)) + var/image/I = overlay + appearance_bro.dir = I.dir + new_overlays += appearance_bro.appearance + return new_overlays + +#define NOT_QUEUED_ALREADY (!(flags & OVERLAY_QUEUED)) +#define QUEUE_FOR_COMPILE flags |= OVERLAY_QUEUED; SSoverlays.queue += src; + +/** + * Cut all of atom's normal overlays. Usually leaves "priority" overlays untouched. + * + * @param priority If true, also will cut priority overlays. + */ +/atom/proc/cut_overlays(priority = FALSE) + var/list/cached_overlays = our_overlays + var/list/cached_priority = priority_overlays + + var/need_compile = FALSE + + if(LAZYLEN(cached_overlays)) //don't queue empty lists, don't cut priority overlays + cached_overlays.Cut() //clear regular overlays + need_compile = TRUE + + if(priority && LAZYLEN(cached_priority)) + cached_priority.Cut() + need_compile = TRUE + + if(NOT_QUEUED_ALREADY && need_compile) + QUEUE_FOR_COMPILE + +/** + * Removes specific overlay(s) from the atom. Usually does not remove them from "priority" overlays. + * + * @param overlays The overlays to removed, type can be anything that is allowed for add_overlay(). + * @param priority If true, also will remove them from the "priority" overlays. + */ +/atom/proc/cut_overlay(list/overlays, priority) + if(!overlays) + return + + overlays = build_appearance_list(overlays) + + var/list/cached_overlays = our_overlays //sanic + var/list/cached_priority = priority_overlays + var/init_o_len = LAZYLEN(cached_overlays) + var/init_p_len = LAZYLEN(cached_priority) //starter pokemon + + LAZYREMOVE(cached_overlays, overlays) + if(priority) + LAZYREMOVE(cached_priority, overlays) + + if(NOT_QUEUED_ALREADY && ((init_o_len != LAZYLEN(cached_overlays)) || (init_p_len != LAZYLEN(cached_priority)))) + QUEUE_FOR_COMPILE + +/** + * Adds specific overlay(s) to the atom. + * It is designed so any of the types allowed to be added to /atom/overlays can be added here too. More details below. + * + * @param overlays The overlay(s) to add. These may be + * - A string: In which case it is treated as an icon_state of the atom's icon. + * - An icon: It is treated as an icon. + * - An atom: Its own overlays are compiled and then it's appearance is added. (Meaning its current apperance is frozen). + * - An image: Image's apperance is added (i.e. subsequently editing the image will not edit the overlay) + * - A type path: Added to overlays as is. Does whatever it is BYOND does when you add paths to overlays. + * - Or a list containing any of the above. + * @param priority The overlays are added to the "priority" list istead of the normal one. + */ +/atom/proc/add_overlay(list/overlays, priority = FALSE) + if(!overlays) + return + + overlays = build_appearance_list(overlays) + + LAZYINITLIST(our_overlays) //always initialized after this point + LAZYINITLIST(priority_overlays) + + var/list/cached_overlays = our_overlays //sanic + var/list/cached_priority = priority_overlays + var/init_o_len = cached_overlays.len + var/init_p_len = cached_priority.len //starter pokemon + var/need_compile + + if(priority) + cached_priority += overlays //or in the image. Can we use [image] = image? + need_compile = init_p_len != cached_priority.len + else + cached_overlays += overlays + need_compile = init_o_len != cached_overlays.len + + if(NOT_QUEUED_ALREADY && need_compile) //have we caught more pokemon? + QUEUE_FOR_COMPILE + +/** + * Copy the overlays from another atom, either replacing all of ours or appending to our existing overlays. + * Note: This copies only the normal overlays, not the "priority" overlays. + * + * @param other The atom to copy overlays from. + * @param cut_old If true, all of our overlays will be *replaced* by the other's. If other is null, that means cutting all ours. + */ +/atom/proc/copy_overlays(atom/other, cut_old) //copys our_overlays from another atom + if(!other) + if(cut_old) + cut_overlays() + return + + var/list/cached_other = other.our_overlays + if(cached_other) + if(cut_old || !LAZYLEN(our_overlays)) + our_overlays = cached_other.Copy() + else + our_overlays |= cached_other + if(NOT_QUEUED_ALREADY) + QUEUE_FOR_COMPILE + else if(cut_old) + cut_overlays() + +#undef NOT_QUEUED_ALREADY +#undef QUEUE_FOR_COMPILE + +//TODO: Better solution for these? +/image/proc/add_overlay(x) + overlays += x + +/image/proc/cut_overlay(x) + overlays -= x + +/image/proc/cut_overlays(x) + overlays.Cut() + +/image/proc/copy_overlays(atom/other, cut_old) + if(!other) + if(cut_old) + cut_overlays() + return + + var/list/cached_other = other.our_overlays + if(cached_other) + if(cut_old || !overlays.len) + overlays = cached_other.Copy() + else + overlays |= cached_other + else if(cut_old) + cut_overlays() diff --git a/code/datums/EPv2.dm b/code/datums/EPv2.dm index 37a1a0ba1f..a41175f424 100644 --- a/code/datums/EPv2.dm +++ b/code/datums/EPv2.dm @@ -40,6 +40,10 @@ var/global/list/all_exonet_connections = list() src.holder = holder ..() +/datum/exonet_protocol/Destroy() + remove_address() + holder = null + return ..() // Proc: make_address() // Parameters: 1 (string - used to make into a hash that will be part of the new address) diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index 274c0c0903..8e21740082 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -425,8 +425,8 @@ var/icon/front var/icon/side if(H) - front = getFlatIcon(H, SOUTH, always_use_defdir = 1) - side = getFlatIcon(H, WEST, always_use_defdir = 1) + front = getFlatIcon(H, SOUTH) + side = getFlatIcon(H, WEST) else var/mob/living/carbon/human/dummy = new() front = new(get_id_photo(dummy), dir = SOUTH) @@ -446,7 +446,7 @@ G.fields["fingerprint"] = "Unknown" G.fields["p_stat"] = "Active" G.fields["m_stat"] = "Stable" - G.fields["species"] = "Human" + G.fields["species"] = SPECIES_HUMAN G.fields["home_system"] = "Unknown" G.fields["citizenship"] = "Unknown" G.fields["faction"] = "Unknown" diff --git a/code/datums/ghost_query.dm b/code/datums/ghost_query.dm index dda2565bf1..d041558a0c 100644 --- a/code/datums/ghost_query.dm +++ b/code/datums/ghost_query.dm @@ -126,3 +126,15 @@ question = "A person suspended in cryosleep has been discovered by a crewmember \ and they are attempting to open the cryopod. Would you like to play as the occupant?" cutoff_number = 1 + +/datum/ghost_query/corgi_rune + role_name = "Dark Creature" + question = "A curious explorer has touched a mysterious rune. \ + Would you like to play as the creature it summons?" + cutoff_number = 1 + +/datum/ghost_query/cursedblade + role_name = "Cursed Sword" + question = "A cursed blade has been discovered by a curious explorer. \ + Would you like to play as the soul imprisoned within?" + cutoff_number = 1 diff --git a/code/datums/mixed.dm b/code/datums/mixed.dm index f0f0c70abd..191868e489 100644 --- a/code/datums/mixed.dm +++ b/code/datums/mixed.dm @@ -1,34 +1,46 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 - -/datum/data - var/name = "data" - var/size = 1.0 - - -/datum/data/function - name = "function" - size = 2.0 - - -/datum/data/function/data_control - name = "data control" - - -/datum/data/function/id_changer - name = "id changer" - - -/datum/data/record - name = "record" - size = 5.0 - var/list/fields = list( ) - - -/datum/data/text - name = "text" - var/data = null - - - -/datum/debug - var/list/debuglist +//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 + +/datum/data + var/name = "data" + var/size = 1.0 + + +/datum/data/function + name = "function" + size = 2.0 + + +/datum/data/function/data_control + name = "data control" + + +/datum/data/function/id_changer + name = "id changer" + + +/datum/data/record + name = "record" + size = 5.0 + var/list/fields = list( ) + +// Mostly used for data_core records, but unfortuantely used some other places too. But mostly here, so lets make a good effort. +// TODO - Some machines/computers might be holding references to us. Lets look into that, but at least for now lets make sure that the manifest is cleaned up. +/datum/data/record/Destroy(var/force) + if(data_core.locked.Find(src)) + if(!force) + crash_with("Someone tried to qdel a record that was in data_core.locked [log_info_line(src)]") + return QDEL_HINT_LETMELIVE + data_core.locked -= src + data_core.medical -= src + data_core.general -= src + data_core.security -= src + . = ..() + +/datum/data/text + name = "text" + var/data = null + + + +/datum/debug + var/list/debuglist diff --git a/code/datums/mutable_appearance.dm b/code/datums/mutable_appearance.dm index 1cb3a97d9f..16d10ae035 100644 --- a/code/datums/mutable_appearance.dm +++ b/code/datums/mutable_appearance.dm @@ -4,10 +4,11 @@ // Mutable appearances are children of images, just so you know. -/mutable_appearance/New() +/mutable_appearance/New(copy_from, ...) ..() - plane = FLOAT_PLANE // No clue why this is 0 by default yet images are on FLOAT_PLANE - // And yes this does have to be in the constructor, BYOND ignores it if you set it as a normal var + if(!copy_from) + plane = FLOAT_PLANE // No clue why this is 0 by default yet images are on FLOAT_PLANE + // And yes this does have to be in the constructor, BYOND ignores it if you set it as a normal var // Helper similar to image() /proc/mutable_appearance(icon, icon_state = "", layer = FLOAT_LAYER) diff --git a/code/datums/outfits/_defines.dm b/code/datums/outfits/_defines.dm index ae07595c50..8d406ce1e0 100644 --- a/code/datums/outfits/_defines.dm +++ b/code/datums/outfits/_defines.dm @@ -1,6 +1,7 @@ #define OUTFIT_HAS_JETPACK 1 #define OUTFIT_HAS_BACKPACK 2 #define OUTFIT_EXTENDED_SURVIVAL 4 +#define OUTFIT_COMPREHENSIVE_SURVIVAL 8 #define OUTFIT_JOB_NAME(job_name) ("Job - " + job_name) #define OUTFIT_MILITARY(job_name) ("Military Uniform - " + job_name) diff --git a/code/datums/outfits/jobs/cargo.dm b/code/datums/outfits/jobs/cargo.dm index e8974f09f9..bbfe6f59f5 100644 --- a/code/datums/outfits/jobs/cargo.dm +++ b/code/datums/outfits/jobs/cargo.dm @@ -20,6 +20,7 @@ /decl/hierarchy/outfit/job/cargo/mining name = OUTFIT_JOB_NAME("Shaft miner") uniform = /obj/item/clothing/under/rank/miner + l_ear = /obj/item/device/radio/headset/headset_mine backpack = /obj/item/weapon/storage/backpack/industrial satchel_one = /obj/item/weapon/storage/backpack/satchel/eng id_type = /obj/item/weapon/card/id/cargo/mining diff --git a/code/datums/outfits/jobs/medical.dm b/code/datums/outfits/jobs/medical.dm index 3b227a2612..1fdd020fcf 100644 --- a/code/datums/outfits/jobs/medical.dm +++ b/code/datums/outfits/jobs/medical.dm @@ -23,8 +23,8 @@ name = OUTFIT_JOB_NAME("Medical Doctor") uniform = /obj/item/clothing/under/rank/medical suit = /obj/item/clothing/suit/storage/toggle/labcoat - l_hand = /obj/item/weapon/storage/firstaid/adv - r_pocket = /obj/item/device/healthanalyzer + l_hand = /obj/item/weapon/storage/firstaid/regular + r_pocket = /obj/item/device/flashlight/pen id_type = /obj/item/weapon/card/id/medical/doctor /decl/hierarchy/outfit/job/medical/doctor/emergency_physician @@ -94,7 +94,7 @@ uniform = /obj/item/clothing/under/rank/medical/scrubs/black suit = /obj/item/clothing/suit/storage/toggle/fr_jacket shoes = /obj/item/clothing/shoes/boots/jackboots - l_hand = /obj/item/weapon/storage/firstaid/adv + l_hand = /obj/item/weapon/storage/firstaid/regular belt = /obj/item/weapon/storage/belt/medical/emt pda_slot = slot_l_store id_type = /obj/item/weapon/card/id/medical/paramedic diff --git a/code/datums/outfits/outfit.dm b/code/datums/outfits/outfit.dm index e69e9eb705..ac653e2647 100644 --- a/code/datums/outfits/outfit.dm +++ b/code/datums/outfits/outfit.dm @@ -146,7 +146,7 @@ var/list/outfits_decls_by_type_ if(r_hand) H.put_in_r_hand(new r_hand(H)) if(H.species) - H.species.equip_survival_gear(H, flags&OUTFIT_EXTENDED_SURVIVAL) + H.species.equip_survival_gear(H, flags&OUTFIT_EXTENDED_SURVIVAL, flags&OUTFIT_COMPREHENSIVE_SURVIVAL) /decl/hierarchy/outfit/proc/equip_id(mob/living/carbon/human/H, rank, assignment) if(!id_slot || !id_type) diff --git a/code/datums/progressbar.dm b/code/datums/progressbar.dm index bed0f33275..afcb65a8c1 100644 --- a/code/datums/progressbar.dm +++ b/code/datums/progressbar.dm @@ -22,8 +22,10 @@ /datum/progressbar/Destroy() if (client) client.images -= bar - qdel(bar) - . = ..() + qdel_null(bar) + user = null + client = null + return ..() /datum/progressbar/proc/update(progress) //world << "Update [progress] - [goal] - [(progress / goal)] - [((progress / goal) * 100)] - [round(((progress / goal) * 100), 5)]" diff --git a/code/datums/supplypacks/contraband.dm b/code/datums/supplypacks/contraband.dm index 8c8869f318..d0ca246759 100644 --- a/code/datums/supplypacks/contraband.dm +++ b/code/datums/supplypacks/contraband.dm @@ -43,8 +43,8 @@ containername = "Moghes imports crate" contraband = 1 -/datum/supply_packs/security/bolt_rifles_militia - name = "Surplus militia rifles" +/datum/supply_packs/munitions/bolt_rifles_militia + name = "Weapon - Surplus militia rifles" contains = list( /obj/item/weapon/gun/projectile/shotgun/pump/rifle = 3, /obj/item/ammo_magazine/clip/c762 = 6 @@ -52,7 +52,7 @@ cost = 50 contraband = 1 containertype = /obj/structure/closet/crate/secure/weapon - containername = "Weapons crate" + containername = "Ballistic weapons crate" /datum/supply_packs/randomised/misc/telecrate //you get something awesome, a couple of decent things, and a few weak/filler things name = "ERR_NULL_ENTRY" //null crate! also dream maker is hell, diff --git a/code/datums/supplypacks/materials.dm b/code/datums/supplypacks/materials.dm index d09e3c8ee5..4c5ddedf47 100644 --- a/code/datums/supplypacks/materials.dm +++ b/code/datums/supplypacks/materials.dm @@ -49,7 +49,7 @@ cost = 15 contains = list( /obj/fiftyspawner/carpet, - /obj/fiftyspawner/bluecarpet + /obj/fiftyspawner/tealcarpet ) diff --git a/code/datums/supplypacks/misc.dm b/code/datums/supplypacks/misc.dm index 5a3bb038bb..225e29335f 100644 --- a/code/datums/supplypacks/misc.dm +++ b/code/datums/supplypacks/misc.dm @@ -70,3 +70,10 @@ cost = 10 containertype = "/obj/structure/closet/crate" containername = "Webbing crate" + +/datum/supply_packs/misc/holoplant + name = "Holoplant Pot" + contains = list(/obj/machinery/holoplant/shipped) + cost = 15 + containertype = /obj/structure/closet/crate + containername = "Holoplant crate" diff --git a/code/datums/supplypacks/munitions.dm b/code/datums/supplypacks/munitions.dm index 42e8b75a17..662de4da73 100644 --- a/code/datums/supplypacks/munitions.dm +++ b/code/datums/supplypacks/munitions.dm @@ -10,21 +10,30 @@ group = "Munitions" /datum/supply_packs/munitions/weapons - name = "Weapons crate" + name = "Weapons - Security basic equipment" contains = list( + /obj/item/device/flash = 2, + /obj/item/weapon/reagent_containers/spray/pepper = 2, /obj/item/weapon/melee/baton/loaded = 2, - /obj/item/weapon/gun/energy/gun = 2, /obj/item/weapon/gun/energy/taser = 2, /obj/item/weapon/gun/projectile/colt/detective = 2, /obj/item/weapon/storage/box/flashbangs = 2 ) cost = 40 + containertype = /obj/structure/closet/crate/secure/gear + containername = "Security equipment crate" + access = access_security + +/datum/supply_packs/munitions/egunpistol + name = "Weapons - Energy sidearms" + contains = list(/obj/item/weapon/gun/energy/gun = 2) + cost = 40 containertype = /obj/structure/closet/crate/secure/weapon - containername = "Weapons crate" + containername = "Energy sidearms crate" access = access_security /datum/supply_packs/munitions/flareguns - name = "Flare guns crate" + name = "Weapons - Flare guns" contains = list( /obj/item/weapon/gun/projectile/sec/flash, /obj/item/ammo_magazine/m45/flash, @@ -32,100 +41,96 @@ /obj/item/weapon/storage/box/flashshells ) cost = 25 - containertype = /obj/structure/closet/crate/secure/weapon + containertype = /obj/structure/closet/crate/secure/gear containername = "Flare gun crate" access = access_security /datum/supply_packs/munitions/eweapons - name = "Experimental weapons crate" + name = "Weapons - Experimental weapons crate" contains = list( /obj/item/weapon/gun/energy/xray = 2, /obj/item/weapon/shield/energy = 2) cost = 100 - containertype = /obj/structure/closet/crate/secure/weapon + containertype = /obj/structure/closet/crate/secure/science containername = "Experimental weapons crate" access = access_armory /datum/supply_packs/munitions/energyweapons - name = "Laser carbine crate" + name = "Weapons - Laser rifle crate" contains = list(/obj/item/weapon/gun/energy/laser = 3) cost = 50 - containertype = /obj/structure/closet/crate/secure - containername = "energy weapons crate" + containertype = /obj/structure/closet/crate/secure/weapon + containername = "Energy weapons crate" access = access_armory /datum/supply_packs/munitions/shotgun - name = "Shotgun crate" + name = "Weapons - Shotgun crate" contains = list( /obj/item/weapon/storage/box/shotgunammo, /obj/item/weapon/storage/box/shotgunshells, /obj/item/weapon/gun/projectile/shotgun/pump/combat = 2 ) cost = 50 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/weapon containername = "Shotgun crate" access = access_armory /datum/supply_packs/munitions/erifle - name = "Energy marksman crate" + name = "Weapons - Energy marksman" contains = list(/obj/item/weapon/gun/energy/sniperrifle = 2) cost = 100 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/weapon containername = "Energy marksman crate" access = access_armory /datum/supply_packs/munitions/burstlaser - name = "Burst laser crate" + name = "Weapons - Burst laser" contains = list(/obj/item/weapon/gun/energy/gun/burst = 2) cost = 50 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/weapon containername = "Burst laser crate" access = access_armory /datum/supply_packs/munitions/ionweapons - name = "Electromagnetic weapons crate" + name = "Weapons - Electromagnetic Rifles" contains = list( /obj/item/weapon/gun/energy/ionrifle = 2, /obj/item/weapon/storage/box/empslite ) cost = 50 - containertype = /obj/structure/closet/crate/secure - containername = "electromagnetic weapons crate" + containertype = /obj/structure/closet/crate/secure/weapon + containername = "Electromagnetic weapons crate" access = access_armory /datum/supply_packs/munitions/ionpistols - name = "Electromagnetic pistols crate" + name = "Weapons - Electromagnetic pistols" contains = list( /obj/item/weapon/gun/energy/ionrifle/pistol = 2, /obj/item/weapon/storage/box/empslite ) cost = 30 - containertype = /obj/structure/closet/crate/secure - containername = "electromagnetic weapons crate" + containertype = /obj/structure/closet/crate/secure/weapon + containername = "Electromagnetic weapons crate" access = access_armory -/datum/supply_packs/randomised/munitions/automatic - name = "Automatic weapon crate" - num_contained = 2 - contains = list( - /obj/item/weapon/gun/projectile/automatic/wt550, - /obj/item/weapon/gun/projectile/automatic/z8 - ) - cost = 100 - containertype = /obj/structure/closet/crate/secure - containername = "Automatic weapon crate" - access = access_armory - -/datum/supply_packs/munitions/energy_guns - name = "Energy gun crate" - contains = list(/obj/item/weapon/gun/energy/gun = 2) +/datum/supply_packs/munitions/bsmg + name = "Weapons - Ballistic SMGs" + contains = list(/obj/item/weapon/gun/projectile/automatic/wt550 = 2) cost = 50 - containertype = /obj/structure/closet/crate/secure - containername = "Energy gun crate" + containertype = /obj/structure/closet/crate/secure/weapon + containername = "Ballistic weapon crate" + access = access_armory + +/datum/supply_packs/munitions/brifle + name = "Weapons - Ballistic Rifles" + contains = list(/obj/item/weapon/gun/projectile/automatic/z8 = 2) + cost = 80 + containertype = /obj/structure/closet/crate/secure/weapon + containername = "Ballistic weapon crate" access = access_armory /datum/supply_packs/munitions/bolt_rifles_competitive - name = "Competitive shooting crate" + name = "Weapons - Competitive shooting rifles" contains = list( /obj/item/device/assembly/timer, /obj/item/weapon/gun/projectile/shotgun/pump/rifle/practice = 2, @@ -136,37 +141,56 @@ ) cost = 40 containertype = /obj/structure/closet/crate/secure/weapon - containername = "Weapons crate" + containername = "Ballistic weapons crate" access = access_security /datum/supply_packs/munitions/shotgunammo - name = "Shotgun ammunition crate" + name = "Ammunition - Shotgun shells" contains = list( /obj/item/weapon/storage/box/shotgunammo = 2, /obj/item/weapon/storage/box/shotgunshells = 2 ) cost = 25 containertype = /obj/structure/closet/crate/secure - containername = "ballistic ammunition crate" - access = access_armory - -/datum/supply_packs/randomised/munitions/autoammo - name = "Automatic weapon ammunition crate" - num_contained = 6 - contains = list( - /obj/item/ammo_magazine/m9mmt, - /obj/item/ammo_magazine/m9mmt/rubber, - /obj/item/ammo_magazine/m545saw - ) - cost = 25 - containertype = /obj/structure/closet/crate/secure - containername = "Automatic weapon ammunition crate" + containername = "Ballistic ammunition crate" access = access_armory /datum/supply_packs/munitions/beanbagammo - name = "Beanbag shells" + name = "Ammunition - Beanbag shells" contains = list(/obj/item/weapon/storage/box/beanbags = 3) cost = 25 containertype = /obj/structure/closet/crate - containername = "Beanbag shells" + containername = "Ballistic ammunition crate" access = null + +/datum/supply_packs/munitions/bsmgammo + name = "Ammunition - 9mm top mounted lethal" + contains = list(/obj/item/ammo_magazine/m9mmt = 6) + cost = 25 + containertype = /obj/structure/closet/crate/secure + containername = "Ballistic ammunition crate" + access = access_armory + +/datum/supply_packs/munitions/bsmgammorubber + name = "Ammunition - 9mm top mounted rubber" + contains = list(/obj/item/ammo_magazine/m9mmt/rubber = 6) + cost = 25 + containertype = /obj/structure/closet/crate/secure + containername = "Ballistic ammunition crate" + access = access_security + +/datum/supply_packs/munitions/brifleammo + name = "Ammunition - 7.62mm lethal" + contains = list(/obj/item/ammo_magazine/m762 = 6) + cost = 25 + containertype = /obj/structure/closet/crate/secure + containername = "Ballistic ammunition crate" + access = access_armory + +/datum/supply_packs/munitions/pcellammo + name = "Ammunition - Power cell" + contains = list(/obj/item/weapon/cell/device/weapon = 3) + cost = 50 + containertype = /obj/structure/closet/crate/secure + containername = "Energy ammunition crate" + access = access_security \ No newline at end of file diff --git a/code/datums/supplypacks/recreation.dm b/code/datums/supplypacks/recreation.dm index 7bfdaaeeb6..7f801ea1b3 100644 --- a/code/datums/supplypacks/recreation.dm +++ b/code/datums/supplypacks/recreation.dm @@ -39,6 +39,7 @@ name = "Arts and Crafts supplies" contains = list( /obj/item/weapon/storage/fancy/crayons, + /obj/item/weapon/storage/fancy/markers, /obj/item/device/camera, /obj/item/device/camera_film = 2, /obj/item/weapon/storage/photo_album, diff --git a/code/datums/supplypacks/robotics.dm b/code/datums/supplypacks/robotics.dm index 3e861e354b..d9f20c5aa6 100644 --- a/code/datums/supplypacks/robotics.dm +++ b/code/datums/supplypacks/robotics.dm @@ -116,14 +116,6 @@ containername = "Robolimb blueprints (Bishop)" access = access_robotics -/datum/supply_packs/robotics/robolimbs/veymed - name = "Vey-Med robolimb blueprints" - contains = list(/obj/item/weapon/disk/limb/veymed) - cost = 70 - containertype = /obj/structure/closet/crate/secure/science - containername = "Robolimb blueprints (Vey-Med)" - access = access_robotics - /datum/supply_packs/robotics/mecha_ripley name = "Circuit Crate (\"Ripley\" APLU)" contains = list( diff --git a/code/datums/supplypacks/security.dm b/code/datums/supplypacks/security.dm index e248acc46c..eb031e7bd9 100644 --- a/code/datums/supplypacks/security.dm +++ b/code/datums/supplypacks/security.dm @@ -13,6 +13,7 @@ access = access_security /datum/supply_packs/randomised/security/armor + name = "Armor - Security armor" num_contained = 5 contains = list( /obj/item/clothing/suit/storage/vest, @@ -27,14 +28,12 @@ /obj/item/clothing/suit/storage/vest/heavy/hos, /obj/item/clothing/suit/storage/vest/heavy/pcrc ) - - name = "Armor crate" cost = 40 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/gear containername = "Armor crate" /datum/supply_packs/security/riot_gear - name = "Riot gear crate" + name = "Gear - Riot" contains = list( /obj/item/weapon/melee/baton = 3, /obj/item/weapon/shield/riot = 3, @@ -44,12 +43,12 @@ /obj/item/weapon/storage/box/handcuffs ) cost = 40 - containertype = /obj/structure/closet/crate/secure - containername = "riot gear crate" + containertype = /obj/structure/closet/crate/secure/gear + containername = "Riot gear crate" access = access_armory /datum/supply_packs/security/riot_armor - name = "Riot armor set crate" + name = "Armor - Riot" contains = list( /obj/item/clothing/head/helmet/riot, /obj/item/clothing/suit/armor/riot, @@ -57,12 +56,12 @@ /obj/item/clothing/shoes/leg_guard/riot ) cost = 30 - containertype = /obj/structure/closet/crate/secure - containername = "riot armor set crate" + containertype = /obj/structure/closet/crate/secure/gear + containername = "Riot armor crate" access = access_armory /datum/supply_packs/security/ablative_armor - name = "Ablative armor set crate" + name = "Armor - Ablative" contains = list( /obj/item/clothing/head/helmet/laserproof, /obj/item/clothing/suit/armor/laserproof, @@ -70,12 +69,12 @@ /obj/item/clothing/shoes/leg_guard/laserproof ) cost = 40 - containertype = /obj/structure/closet/crate/secure - containername = "ablative armor set crate" + containertype = /obj/structure/closet/crate/secure/gear + containername = "Ablative armor crate" access = access_armory /datum/supply_packs/security/bullet_resistant_armor - name = "Bullet resistant armor set crate" + name = "Armor - Ballistic" contains = list( /obj/item/clothing/head/helmet/bulletproof, /obj/item/clothing/suit/armor/bulletproof, @@ -83,12 +82,12 @@ /obj/item/clothing/shoes/leg_guard/bulletproof ) cost = 40 - containertype = /obj/structure/closet/crate/secure - containername = "bullet resistant armor set crate" + containertype = /obj/structure/closet/crate/secure/gear + containername = "Ballistic armor crate" access = access_armory /datum/supply_packs/security/combat_armor - name = "Combat armor set crate" + name = "Armor - Combat" contains = list( /obj/item/clothing/head/helmet/combat, /obj/item/clothing/suit/armor/combat, @@ -96,14 +95,14 @@ /obj/item/clothing/shoes/leg_guard/combat ) cost = 40 - containertype = /obj/structure/closet/crate/secure - containername = "combat armor set crate" + containertype = /obj/structure/closet/crate/secure/gear + containername = "Combat armor crate" access = access_armory /datum/supply_packs/security/tactical - name = "Tactical suits" - containertype = /obj/structure/closet/crate/secure - containername = "Tactical Suit Locker" + name = "Armor - Tactical" + containertype = /obj/structure/closet/crate/secure/gear + containername = "Tactical armor crate" cost = 40 access = access_armory contains = list( @@ -126,23 +125,23 @@ ) /datum/supply_packs/security/securitybarriers - name = "Security barrier crate" + name = "Misc - Security Barriers" contains = list(/obj/machinery/deployable/barrier = 4) cost = 20 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/largecrate containername = "Security barrier crate" access = null /datum/supply_packs/security/securityshieldgen - name = "Wall shield Generators" + name = "Misc - Wall shield generators" contains = list(/obj/machinery/shieldwallgen = 4) cost = 20 containertype = /obj/structure/closet/crate/secure - containername = "wall shield generators crate" + containername = "Wall shield generators crate" access = access_teleporter /datum/supply_packs/randomised/security/holster - name = "Holster crate" + name = "Gear - Holsters" num_contained = 4 contains = list( /obj/item/clothing/accessory/holster, @@ -151,11 +150,11 @@ /obj/item/clothing/accessory/holster/hip ) cost = 15 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate containername = "Holster crate" /datum/supply_packs/security/extragear - name = "Security surplus equipment" + name = "Gear - Security surplus equipment" contains = list( /obj/item/weapon/storage/belt/security = 3, /obj/item/clothing/glasses/sunglasses/sechud = 3, @@ -163,12 +162,11 @@ /obj/item/clothing/suit/storage/hooded/wintercoat/security = 3 ) cost = 10 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate containername = "Security surplus equipment" - access = null /datum/supply_packs/security/detectivegear - name = "Forensic investigation equipment" + name = "Forensic - Investigation equipment" contains = list( /obj/item/weapon/storage/box/evidence = 2, /obj/item/clothing/suit/storage/vest/detective, @@ -190,12 +188,12 @@ /obj/item/weapon/storage/briefcase/crimekit ) cost = 20 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Forensic equipment" access = access_forensics_lockers /datum/supply_packs/security/detectiveclothes - name = "Investigation apparel" + name = "Forensic - Investigation apparel" contains = list( /obj/item/clothing/under/det/black = 2, /obj/item/clothing/under/det/grey = 2, @@ -212,12 +210,12 @@ /obj/item/clothing/gloves/black = 2 ) cost = 10 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Investigation clothing" access = access_forensics_lockers /datum/supply_packs/security/officergear - name = "Officer equipment" + name = "Gear - Officer equipment" contains = list( /obj/item/clothing/suit/storage/vest/officer, /obj/item/clothing/head/helmet, @@ -242,12 +240,12 @@ /obj/item/device/flashlight/maglight ) cost = 20 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Officer equipment" access = access_brig /datum/supply_packs/security/wardengear - name = "Warden equipment" + name = "Gear - Warden equipment" contains = list( /obj/item/clothing/suit/storage/vest/warden, /obj/item/clothing/under/rank/warden, @@ -270,18 +268,18 @@ /obj/item/device/flashlight/maglight ) cost = 20 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Warden equipment" access = access_armory /datum/supply_packs/security/headofsecgear - name = "Head of security equipment" + name = "Gear - Head of security equipment" contains = list( /obj/item/clothing/head/helmet/HoS, /obj/item/clothing/suit/storage/vest/hos, /obj/item/clothing/under/rank/head_of_security/corp, /obj/item/clothing/suit/storage/vest/hoscoat, - /obj/item/clothing/head/helmet/HoS/dermal, + /obj/item/clothing/head/helmet/dermal, /obj/item/weapon/cartridge/hos, /obj/item/device/radio/headset/heads/hos, /obj/item/clothing/glasses/sunglasses/sechud, @@ -296,12 +294,12 @@ /obj/item/device/flashlight/maglight ) cost = 50 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Head of security equipment" access = access_hos /datum/supply_packs/security/securityclothing - name = "Security uniform crate" + name = "Misc - Security uniform red" contains = list( /obj/item/weapon/storage/backpack/satchel/sec = 2, /obj/item/weapon/storage/backpack/security = 2, @@ -315,11 +313,11 @@ /obj/item/weapon/storage/box/holobadge ) cost = 10 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Security uniform crate" /datum/supply_packs/security/navybluesecurityclothing - name = "Navy blue security uniform crate" + name = "Misc - Security uniform navy blue" contains = list( /obj/item/weapon/storage/backpack/satchel/sec = 2, /obj/item/weapon/storage/backpack/security = 2, @@ -336,11 +334,11 @@ /obj/item/weapon/storage/box/holobadge ) cost = 10 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Navy blue security uniform crate" /datum/supply_packs/security/corporatesecurityclothing - name = "Corporate security uniform crate" + name = "Misc - Security uniform corporate" contains = list( /obj/item/weapon/storage/backpack/satchel/sec = 2, /obj/item/weapon/storage/backpack/security = 2, @@ -356,11 +354,11 @@ /obj/item/weapon/storage/box/holobadge ) cost = 10 - containertype = "/obj/structure/closet/crate/secure" + containertype = /obj/structure/closet/crate/secure containername = "Corporate security uniform crate" /datum/supply_packs/security/biosuit - name = "Security biohazard gear" + name = "Gear - Security biohazard gear" contains = list( /obj/item/clothing/head/bio_hood/security = 3, /obj/item/clothing/under/rank/security = 3, @@ -371,6 +369,7 @@ /obj/item/clothing/gloves/sterile/latex, /obj/item/weapon/storage/box/gloves ) - cost = 50 - containertype = "/obj/structure/closet/crate/secure" + cost = 25 + containertype = /obj/structure/closet/crate/secure containername = "Security biohazard gear" + access = access_security \ No newline at end of file diff --git a/code/datums/underwear/underwear.dm b/code/datums/underwear/underwear.dm index bac96bf55c..f418f3e8d1 100644 --- a/code/datums/underwear/underwear.dm +++ b/code/datums/underwear/underwear.dm @@ -63,11 +63,11 @@ datum/category_group/underwear/dd_SortValue() /datum/category_item/underwear/proc/is_default(var/gender) return is_default -/datum/category_item/underwear/proc/generate_image(var/list/metadata) +/datum/category_item/underwear/proc/generate_image(var/list/metadata, var/layer = FLOAT_LAYER) if(!icon_state) return - var/image/I = image(icon = icon, icon_state = icon_state) + var/image/I = image(icon = icon, icon_state = icon_state, layer = layer) for(var/datum/gear_tweak/gt in tweaks) gt.tweak_item(I, metadata && metadata["[gt]"] ? metadata["[gt]"] : gt.get_default()) return I \ No newline at end of file diff --git a/code/defines/obj.dm b/code/defines/obj.dm index abaffea57b..ba809cb977 100644 --- a/code/defines/obj.dm +++ b/code/defines/obj.dm @@ -203,6 +203,12 @@ var/global/list/PDA_Manifest = list() anchored = 1 unacidable = 1//temporary until I decide whether the borg can be removed. -veyveyr +/obj/structure/showcase/sign + name = "WARNING: WILDERNESS" + icon = 'icons/obj/stationobjs.dmi' + icon_state = "wilderness1" + desc = "This appears to be a sign warning people that the other side is dangerous. It also says that NanoTrasen cannot guarantee your safety beyond this point." + /obj/item/mouse_drag_pointer = MOUSE_ACTIVE_POINTER /obj/item/weapon/beach_ball diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm index b6a45d9a07..75c95d0b0c 100644 --- a/code/defines/obj/weapon.dm +++ b/code/defines/obj/weapon.dm @@ -480,6 +480,7 @@ /obj/item/weapon/stock_parts/capacitor/adv name = "advanced capacitor" desc = "An advanced capacitor used in the construction of a variety of devices." + icon_state = "capacitor_adv" origin_tech = list(TECH_POWER = 3) rating = 2 matter = list(DEFAULT_WALL_MATERIAL = 50,"glass" = 50) @@ -487,7 +488,7 @@ /obj/item/weapon/stock_parts/scanning_module/adv name = "advanced scanning module" desc = "A compact, high resolution scanning module used in the construction of certain devices." - icon_state = "scan_module" + icon_state = "scan_module_adv" origin_tech = list(TECH_MAGNET = 3) rating = 2 matter = list(DEFAULT_WALL_MATERIAL = 50,"glass" = 20) @@ -521,6 +522,7 @@ /obj/item/weapon/stock_parts/capacitor/super name = "super capacitor" desc = "A super-high capacity capacitor used in the construction of a variety of devices." + icon_state = "capacitor_super" origin_tech = list(TECH_POWER = 5, TECH_MATERIAL = 4) rating = 3 matter = list(DEFAULT_WALL_MATERIAL = 50,"glass" = 50) @@ -528,6 +530,7 @@ /obj/item/weapon/stock_parts/scanning_module/phasic name = "phasic scanning module" desc = "A compact, high resolution phasic scanning module used in the construction of certain devices." + icon_state = "scan_module_phasic" origin_tech = list(TECH_MAGNET = 5) rating = 3 matter = list(DEFAULT_WALL_MATERIAL = 50,"glass" = 20) diff --git a/code/defines/procs/announce.dm b/code/defines/procs/announce.dm index 5c44353540..22fa3438ca 100644 --- a/code/defines/procs/announce.dm +++ b/code/defines/procs/announce.dm @@ -111,7 +111,7 @@ datum/announcement/priority/command/Sound(var/message_sound) datum/announcement/proc/Log(message as text, message_title as text) if(log) - log_say("[key_name(usr)] has made \a [announcement_type]: [message_title] - [message] - [announcer]") + log_game("[key_name(usr)] has made \a [announcement_type]: [message_title] - [message] - [announcer]") message_admins("[key_name_admin(usr)] has made \a [announcement_type].", 1) /proc/GetNameAndAssignmentFromId(var/obj/item/weapon/card/id/I) diff --git a/code/game/antagonist/antagonist.dm b/code/game/antagonist/antagonist.dm index b36c27e116..484ff8ea33 100644 --- a/code/game/antagonist/antagonist.dm +++ b/code/game/antagonist/antagonist.dm @@ -52,7 +52,7 @@ var/flags = 0 // Various runtime options. // Used for setting appearance. - var/list/valid_species = list("Unathi","Tajara","Skrell","Human","Diona","Teshari") + var/list/valid_species = list(SPECIES_UNATHI,SPECIES_TAJ,SPECIES_SKRELL,SPECIES_HUMAN,SPECIES_DIONA,SPECIES_TESHARI) // Runtime vars. var/datum/mind/leader // Current leader, if any. diff --git a/code/game/antagonist/antagonist_update.dm b/code/game/antagonist/antagonist_update.dm index 7cf17b5640..16c27f82c7 100644 --- a/code/game/antagonist/antagonist_update.dm +++ b/code/game/antagonist/antagonist_update.dm @@ -33,7 +33,9 @@ if(!antag_indicator || !other.current || !recipient.current) return var/indicator = (faction_indicator && (other in faction_members)) ? faction_indicator : antag_indicator - return image('icons/mob/mob.dmi', loc = other.current, icon_state = indicator, layer = LIGHTING_LAYER+0.1) + var/image/returnimage = image('icons/mob/mob.dmi', loc = other.current, icon_state = indicator) + returnimage.plane = PLANE_LIGHTING_ABOVE + return returnimage /datum/antagonist/proc/update_all_icons() if(!antag_indicator) diff --git a/code/game/antagonist/outsider/mercenary.dm b/code/game/antagonist/outsider/mercenary.dm index ed2964cfad..94b362fca8 100644 --- a/code/game/antagonist/outsider/mercenary.dm +++ b/code/game/antagonist/outsider/mercenary.dm @@ -42,16 +42,14 @@ var/datum/antagonist/mercenary/mercs if(player.backbag == 3) player.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/norm(player), slot_back) if(player.backbag == 4) player.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(player), slot_back) if(player.backbag == 5) player.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger(player), slot_back) - player.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(player.back), slot_in_backpack) player.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/pill/cyanide(player), slot_in_backpack) + player.mind.tcrystals = DEFAULT_TELECRYSTAL_AMOUNT player.mind.accept_tcrystals = 1 var/obj/item/device/radio/uplink/U = new(player.loc, player.mind, DEFAULT_TELECRYSTAL_AMOUNT) player.put_in_hands(U) - player.update_icons_layers() - create_id("Mercenary", player) create_radio(SYND_FREQ, player) return 1 diff --git a/code/game/antagonist/outsider/ninja.dm b/code/game/antagonist/outsider/ninja.dm index b37fbb5c50..02a314b1f3 100644 --- a/code/game/antagonist/outsider/ninja.dm +++ b/code/game/antagonist/outsider/ninja.dm @@ -158,7 +158,7 @@ var/datum/antagonist/ninja/ninjas if(13) directive += "Some disgruntled [using_map.company_name] employees have been supportive of our operations. Be wary of any mistreatment by command staff." if(14) - var/xenorace = pick("Unathi","Tajara", "Skrell") + var/xenorace = pick(SPECIES_UNATHI, SPECIES_TAJ, SPECIES_SKRELL) directive += "A group of [xenorace] radicals have been loyal supporters of the Spider Clan. Favor [xenorace] crew whenever possible." if(15) directive += "The Spider Clan has recently been accused of religious insensitivity. Attempt to speak with the Chaplain and prove these accusations false." diff --git a/code/game/antagonist/outsider/raider.dm b/code/game/antagonist/outsider/raider.dm index 7c62208ca1..c130d8e66f 100644 --- a/code/game/antagonist/outsider/raider.dm +++ b/code/game/antagonist/outsider/raider.dm @@ -205,7 +205,7 @@ var/datum/antagonist/raider/raiders if(!..()) return 0 - if(player.species && player.species.get_bodytype() == "Vox") + if(player.species && player.species.get_bodytype() == SPECIES_VOX) equip_vox(player) else var/new_shoes = pick(raider_shoes) diff --git a/code/game/antagonist/outsider/technomancer.dm b/code/game/antagonist/outsider/technomancer.dm index 33dc33b5e8..2cb7532308 100644 --- a/code/game/antagonist/outsider/technomancer.dm +++ b/code/game/antagonist/outsider/technomancer.dm @@ -47,7 +47,6 @@ var/datum/antagonist/technomancer/technomancers technomancer_mob.equip_to_slot_or_del(new /obj/item/device/flashlight(technomancer_mob), slot_belt) technomancer_mob.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(technomancer_mob), slot_shoes) technomancer_mob.equip_to_slot_or_del(new /obj/item/clothing/head/technomancer/master(technomancer_mob), slot_head) - technomancer_mob.update_icons_layers() return 1 /datum/antagonist/technomancer/proc/equip_apprentice(var/mob/living/carbon/human/technomancer_mob) @@ -67,7 +66,6 @@ var/datum/antagonist/technomancer/technomancers technomancer_mob.equip_to_slot_or_del(new /obj/item/device/flashlight(technomancer_mob), slot_belt) technomancer_mob.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(technomancer_mob), slot_shoes) technomancer_mob.equip_to_slot_or_del(new /obj/item/clothing/head/technomancer/apprentice(technomancer_mob), slot_head) - technomancer_mob.update_icons() return 1 /datum/antagonist/technomancer/check_victory() diff --git a/code/game/antagonist/outsider/wizard.dm b/code/game/antagonist/outsider/wizard.dm index ad5cc10479..feaf8857ba 100644 --- a/code/game/antagonist/outsider/wizard.dm +++ b/code/game/antagonist/outsider/wizard.dm @@ -87,7 +87,6 @@ var/datum/antagonist/wizard/wizards wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/box(wizard_mob), slot_in_backpack) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/teleportation_scroll(wizard_mob), slot_r_store) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/spellbook(wizard_mob), slot_r_hand) - wizard_mob.update_icons_layers() return 1 /datum/antagonist/wizard/check_victory() diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index 2c75c0d255..d249518607 100755 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -13,82 +13,6 @@ NOTE: there are two lists of areas in the end of this file: centcom and station */ - - -/area - var/fire = null - var/atmos = 1 - var/atmosalm = 0 - var/poweralm = 1 - var/party = null - level = null - name = "Unknown" - icon = 'icons/turf/areas.dmi' - icon_state = "unknown" - layer = 10 - luminosity = 0 - mouse_opacity = 0 - var/lightswitch = 1 - - var/eject = null - - var/debug = 0 - var/requires_power = 1 - var/always_unpowered = 0 //this gets overriden to 1 for space in area/New() - - var/power_equip = 1 - var/power_light = 1 - var/power_environ = 1 - var/music = null - var/used_equip = 0 - var/used_light = 0 - var/used_environ = 0 - - var/has_gravity = 1 - var/obj/machinery/power/apc/apc = null - var/no_air = null -// var/list/lights // list of all lights on this area - var/list/all_doors = null //Added by Strumpetplaya - Alarm Change - Contains a list of doors adjacent to this area - var/firedoors_closed = 0 - var/list/ambience = list('sound/ambience/ambigen1.ogg','sound/ambience/ambigen3.ogg','sound/ambience/ambigen4.ogg','sound/ambience/ambigen5.ogg','sound/ambience/ambigen6.ogg','sound/ambience/ambigen7.ogg','sound/ambience/ambigen8.ogg','sound/ambience/ambigen9.ogg','sound/ambience/ambigen10.ogg','sound/ambience/ambigen11.ogg','sound/ambience/ambigen12.ogg','sound/ambience/ambigen14.ogg') - var/list/forced_ambience = null - var/sound_env = STANDARD_STATION - var/turf/base_turf //The base turf type of the area, which can be used to override the z-level's base turf - -/*Adding a wizard area teleport list because motherfucking lag -- Urist*/ -/*I am far too lazy to make it a proper list of areas so I'll just make it run the usual telepot routine at the start of the game*/ -var/list/teleportlocs = list() - -/hook/startup/proc/setupTeleportLocs() - for(var/area/AR in world) - if(istype(AR, /area/shuttle) || istype(AR, /area/syndicate_station) || istype(AR, /area/wizard_station)) continue - if(teleportlocs.Find(AR.name)) continue - var/turf/picked = pick(get_area_turfs(AR.type)) - if (picked.z in using_map.station_levels) - teleportlocs += AR.name - teleportlocs[AR.name] = AR - - teleportlocs = sortAssoc(teleportlocs) - - return 1 - -var/list/ghostteleportlocs = list() - -/hook/startup/proc/setupGhostTeleportLocs() - for(var/area/AR in world) - if(ghostteleportlocs.Find(AR.name)) continue - if(istype(AR, /area/aisat) || istype(AR, /area/derelict) || istype(AR, /area/tdome) || istype(AR, /area/shuttle/specops/centcom)) - ghostteleportlocs += AR.name - ghostteleportlocs[AR.name] = AR - var/turf/picked = pick(get_area_turfs(AR.type)) - if (picked.z in using_map.player_levels) - ghostteleportlocs += AR.name - ghostteleportlocs[AR.name] = AR - - ghostteleportlocs = sortAssoc(ghostteleportlocs) - - return 1 - /*-----------------------------------------------------------------------------*/ ///////// @@ -104,7 +28,7 @@ var/list/ghostteleportlocs = list() power_light = 0 power_equip = 0 power_environ = 0 - ambience = list('sound/ambience/ambispace.ogg','sound/music/title2.ogg','sound/music/space.ogg','sound/music/main.ogg','sound/music/traitor.ogg') + ambience = list('sound/ambience/ambispace.ogg','sound/music/title2.ogg','sound/music/space.ogg','sound/music/main.ogg','sound/music/traitor.ogg','sound/ambience/serspaceamb1.ogg') base_turf = /turf/space area/space/atmosalert() @@ -358,6 +282,7 @@ area/space/atmosalert() /area/shuttle/trade name = "\improper Trade Station" icon_state = "red" + dynamic_lighting = 0 /area/shuttle/trade/centcom name = "\improper Trade Shuttle CentCom" diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index e9d93b48a3..c7a653a4c3 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -1,15 +1,49 @@ // Areas.dm - - -// === /area + var/fire = null + var/atmos = 1 + var/atmosalm = 0 + var/poweralm = 1 + var/party = null + level = null + name = "Unknown" + icon = 'icons/turf/areas.dmi' + icon_state = "unknown" + plane = PLANE_LIGHTING_ABOVE //In case we color them + luminosity = 0 + mouse_opacity = 0 + var/lightswitch = 1 + + var/eject = null + + var/debug = 0 + var/requires_power = 1 + var/always_unpowered = 0 //this gets overriden to 1 for space in area/New() + + var/power_equip = 1 + var/power_light = 1 + var/power_environ = 1 + var/music = null + var/used_equip = 0 + var/used_light = 0 + var/used_environ = 0 + + var/has_gravity = 1 + var/obj/machinery/power/apc/apc = null + var/no_air = null +// var/list/lights // list of all lights on this area + var/list/all_doors = null //Added by Strumpetplaya - Alarm Change - Contains a list of doors adjacent to this area + var/firedoors_closed = 0 + var/list/ambience = list('sound/ambience/ambigen1.ogg','sound/ambience/ambigen3.ogg','sound/ambience/ambigen4.ogg','sound/ambience/ambigen5.ogg','sound/ambience/ambigen6.ogg','sound/ambience/ambigen7.ogg','sound/ambience/ambigen8.ogg','sound/ambience/ambigen9.ogg','sound/ambience/ambigen10.ogg','sound/ambience/ambigen11.ogg','sound/ambience/ambigen12.ogg','sound/ambience/ambigen14.ogg') + var/list/forced_ambience = null + var/sound_env = STANDARD_STATION + var/turf/base_turf //The base turf type of the area, which can be used to override the z-level's base turf var/global/global_uid = 0 var/uid /area/New() icon_state = "" - layer = 10 uid = ++global_uid all_areas += src @@ -248,23 +282,26 @@ var/list/mob/living/forced_ambiance_list = new // If we previously were in an area with force-played ambiance, stop it. if(L in forced_ambiance_list) - L << sound(null, channel = 1) + L << sound(null, channel = CHANNEL_AMBIENCE_FORCED) forced_ambiance_list -= L if(!L.client.ambience_playing) L.client.ambience_playing = 1 - L << sound('sound/ambience/shipambience.ogg', repeat = 1, wait = 0, volume = 35, channel = 2) + L << sound('sound/ambience/shipambience.ogg', repeat = 1, wait = 0, volume = 35, channel = CHANNEL_AMBIENCE) if(forced_ambience) if(forced_ambience.len) forced_ambiance_list |= L - L << sound(pick(forced_ambience), repeat = 1, wait = 0, volume = 25, channel = 1) + var/sound/chosen_ambiance = pick(forced_ambience) + if(!istype(chosen_ambiance)) + chosen_ambiance = sound(chosen_ambiance, repeat = 1, wait = 0, volume = 25, channel = CHANNEL_AMBIENCE_FORCED) + L << chosen_ambiance else - L << sound(null, channel = 1) + L << sound(null, channel = CHANNEL_AMBIENCE_FORCED) else if(src.ambience.len && prob(35)) if((world.time >= L.client.played + 600)) var/sound = pick(ambience) - L << sound(sound, repeat = 0, wait = 0, volume = 25, channel = 1) + L << sound(sound, repeat = 0, wait = 0, volume = 25, channel = CHANNEL_AMBIENCE) L.client.played = world.time /area/proc/gravitychange(var/gravitystate = 0, var/area/A) @@ -318,3 +355,49 @@ var/list/mob/living/forced_ambiance_list = new if(A && A.has_gravity()) return 1 return 0 + +/area/proc/shuttle_arrived() + return TRUE + +/area/proc/shuttle_departed() + return TRUE + +/area/AllowDrop() + CRASH("Bad op: area/AllowDrop() called") + +/area/drop_location() + CRASH("Bad op: area/drop_location() called") + +/*Adding a wizard area teleport list because motherfucking lag -- Urist*/ +/*I am far too lazy to make it a proper list of areas so I'll just make it run the usual telepot routine at the start of the game*/ +var/list/teleportlocs = list() + +/hook/startup/proc/setupTeleportLocs() + for(var/area/AR in world) + if(istype(AR, /area/shuttle) || istype(AR, /area/syndicate_station) || istype(AR, /area/wizard_station)) continue + if(teleportlocs.Find(AR.name)) continue + var/turf/picked = pick(get_area_turfs(AR.type)) + if (picked.z in using_map.station_levels) + teleportlocs += AR.name + teleportlocs[AR.name] = AR + + teleportlocs = sortAssoc(teleportlocs) + + return 1 + +var/list/ghostteleportlocs = list() + +/hook/startup/proc/setupGhostTeleportLocs() + for(var/area/AR in world) + if(ghostteleportlocs.Find(AR.name)) continue + if(istype(AR, /area/aisat) || istype(AR, /area/derelict) || istype(AR, /area/tdome) || istype(AR, /area/shuttle/specops/centcom)) + ghostteleportlocs += AR.name + ghostteleportlocs[AR.name] = AR + var/turf/picked = pick(get_area_turfs(AR.type)) + if (picked.z in using_map.player_levels) + ghostteleportlocs += AR.name + ghostteleportlocs[AR.name] = AR + + ghostteleportlocs = sortAssoc(ghostteleportlocs) + + return 1 diff --git a/code/game/atoms.dm b/code/game/atoms.dm index d23f53c23a..dda3e0a6b5 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -1,5 +1,5 @@ /atom - layer = 2 + layer = TURF_LAYER //This was here when I got here. Why though? var/level = 2 var/flags = 0 var/list/fingerprints @@ -22,6 +22,10 @@ // replaced by OPENCONTAINER flags and atom/proc/is_open_container() ///Chemistry. + // Overlays + var/list/our_overlays //our local copy of (non-priority) overlays without byond magic. Use procs in SSoverlays to manipulate + var/list/priority_overlays //overlays that should remain on top and not normally removed when using cut_overlay functions, like c4. + //Detective Work, used for the duplicate data points kept in the scanners var/list/original_atom // Track if we are already had initialize() called to prevent double-initialization. @@ -498,3 +502,18 @@ if(A && A.has_gravity()) return TRUE return FALSE + +/atom/proc/drop_location() + var/atom/L = loc + if(!L) + return null + return L.AllowDrop() ? L : get_turf(L) + +/atom/proc/AllowDrop() + return FALSE + +/atom/proc/get_nametag_name(mob/user) + return name + +/atom/proc/get_nametag_desc(mob/user) + return "" //Desc itself is often too long to use diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 0cd09b8a57..5311d642a2 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -1,5 +1,5 @@ /atom/movable - layer = 3 + layer = OBJ_LAYER appearance_flags = TILE_BOUND|PIXEL_SCALE var/last_move = null var/anchored = 0 diff --git a/code/game/dna/dna2.dm b/code/game/dna/dna2.dm index e80dcb7227..4f5c9ae699 100644 --- a/code/game/dna/dna2.dm +++ b/code/game/dna/dna2.dm @@ -83,7 +83,7 @@ var/global/list/datum/dna/gene/dna_genes[0] var/real_name // Stores the real name of the person who originally got this dna datum. Used primarily for changelings, // New stuff - var/species = "Human" + var/species = SPECIES_HUMAN var/list/body_markings = list() // Make a copy of this strand. diff --git a/code/game/gamemodes/changeling/generic_equip_procs.dm b/code/game/gamemodes/changeling/generic_equip_procs.dm index 7ff76ff9f6..ef1ab650a1 100644 --- a/code/game/gamemodes/changeling/generic_equip_procs.dm +++ b/code/game/gamemodes/changeling/generic_equip_procs.dm @@ -122,7 +122,6 @@ playsound(src, 'sound/effects/splat.ogg', 30, 1) visible_message("[src] pulls on their clothes, peeling it off along with parts of their skin attached!", "We remove and deform our equipment.") - M.update_icons_layers() M.mind.changeling.armor_deployed = 0 return success @@ -138,7 +137,6 @@ M.equip_to_slot_or_del(I, slot_head) grown_items_list.Add("a helmet") playsound(src, 'sound/effects/blobattack.ogg', 30, 1) - M.update_icons_layers() success = 1 sleep(1 SECOND) @@ -148,7 +146,6 @@ M.equip_to_slot_or_del(I, slot_w_uniform) grown_items_list.Add("a uniform") playsound(src, 'sound/effects/blobattack.ogg', 30, 1) - M.update_icons_layers() success = 1 sleep(1 SECOND) @@ -158,7 +155,6 @@ M.equip_to_slot_or_del(I, slot_gloves) grown_items_list.Add("some gloves") playsound(src, 'sound/effects/splat.ogg', 30, 1) - M.update_icons_layers() success = 1 sleep(1 SECOND) @@ -168,7 +164,6 @@ M.equip_to_slot_or_del(I, slot_shoes) grown_items_list.Add("shoes") playsound(src, 'sound/effects/splat.ogg', 30, 1) - M.update_icons_layers() success = 1 sleep(1 SECOND) @@ -178,7 +173,6 @@ M.equip_to_slot_or_del(I, slot_belt) grown_items_list.Add("a belt") playsound(src, 'sound/effects/splat.ogg', 30, 1) - M.update_icons_layers() success = 1 sleep(1 SECOND) @@ -188,7 +182,6 @@ M.equip_to_slot_or_del(I, slot_glasses) grown_items_list.Add("some glasses") playsound(src, 'sound/effects/splat.ogg', 30, 1) - M.update_icons_layers() success = 1 sleep(1 SECOND) @@ -198,7 +191,6 @@ M.equip_to_slot_or_del(I, slot_wear_mask) grown_items_list.Add("a mask") playsound(src, 'sound/effects/splat.ogg', 30, 1) - M.update_icons_layers() success = 1 sleep(1 SECOND) @@ -208,7 +200,6 @@ M.equip_to_slot_or_del(I, slot_back) grown_items_list.Add("a backpack") playsound(src, 'sound/effects/blobattack.ogg', 30, 1) - M.update_icons_layers() success = 1 sleep(1 SECOND) @@ -218,7 +209,6 @@ M.equip_to_slot_or_del(I, slot_wear_suit) grown_items_list.Add("an exosuit") playsound(src, 'sound/effects/blobattack.ogg', 30, 1) - M.update_icons_layers() success = 1 sleep(1 SECOND) @@ -228,20 +218,13 @@ M.equip_to_slot_or_del(I, slot_wear_id) grown_items_list.Add("an ID card") playsound(src, 'sound/effects/splat.ogg', 30, 1) - M.update_icons_layers() success = 1 sleep(1 SECOND) var/feedback = english_list(grown_items_list, nothing_text = "nothing", and_text = " and ", comma_text = ", ", final_comma_text = "" ) M << "We have grown [feedback]." - /* - for(var/I in stuff_to_equip) - world << I - world << stuff_to_equip - world << "Proc ended." - */ - M.update_icons() + if(success) M.mind.changeling.armor_deployed = 1 M.mind.changeling.chem_charges -= 10 diff --git a/code/game/gamemodes/changeling/powers/absorb.dm b/code/game/gamemodes/changeling/powers/absorb.dm index 0af67b22ed..f76fd5ca47 100644 --- a/code/game/gamemodes/changeling/powers/absorb.dm +++ b/code/game/gamemodes/changeling/powers/absorb.dm @@ -53,9 +53,7 @@ src << "We stab [T] with the proboscis." src.visible_message("[src] stabs [T] with the proboscis!") T << "You feel a sharp stabbing pain!" - T.attack_log += text("\[[time_stamp()]\] Was absorbed by [key_name(src)]") - src.attack_log += text("\[[time_stamp()]\] Absorbed [key_name(T)]") - msg_admin_attack("[key_name(T)] was absorbed by [key_name(src)]") + add_attack_logs(src,T,"Absorbed (changeling)") var/obj/item/organ/external/affecting = T.get_organ(src.zone_sel.selecting) if(affecting.take_damage(39,0,1,0,"large organic needle")) T:UpdateDamageIcon() diff --git a/code/game/gamemodes/changeling/powers/bioelectrogenesis.dm b/code/game/gamemodes/changeling/powers/bioelectrogenesis.dm index c173ba55ac..3f3c1bd7ad 100644 --- a/code/game/gamemodes/changeling/powers/bioelectrogenesis.dm +++ b/code/game/gamemodes/changeling/powers/bioelectrogenesis.dm @@ -47,7 +47,7 @@ var/agony = 80 * siemens //Does more than if hit with an electric hand, since grabbing is slower. G.affecting.stun_effect_act(0, agony, BP_TORSO, src) - msg_admin_attack("[key_name(src)] shocked [key_name(G.affecting)] with the [src].") + add_attack_logs(src,G.affecting,"Changeling shocked") if(siemens) visible_message("Arcs of electricity strike [G.affecting]!", @@ -102,6 +102,8 @@ desc = "You could probably shock someone badly if you touched them, or recharge something." icon = 'icons/obj/weapons.dmi' icon_state = "electric_hand" + show_examine = FALSE + var/shock_cost = 10 var/agony_amount = 60 var/electrocute_amount = 10 @@ -147,7 +149,7 @@ C.electrocute_act(electrocute_amount * siemens,src,1.0,BP_TORSO) C.stun_effect_act(0, agony_amount * siemens, BP_TORSO, src) - msg_admin_attack("[key_name(user)] shocked [key_name(C)] with the [src].") + add_attack_logs(user,C,"Shocked with [src]") if(siemens) visible_message("Arcs of electricity strike [C]!", diff --git a/code/game/gamemodes/changeling/powers/blind_sting.dm b/code/game/gamemodes/changeling/powers/blind_sting.dm index 41b14478b3..347881df9b 100644 --- a/code/game/gamemodes/changeling/powers/blind_sting.dm +++ b/code/game/gamemodes/changeling/powers/blind_sting.dm @@ -15,9 +15,7 @@ var/mob/living/carbon/T = changeling_sting(20,/mob/proc/changeling_blind_sting) if(!T) return 0 - T.attack_log += text("\[[time_stamp()]\] Was blind stung by [key_name(src)]") - src.attack_log += text("\[[time_stamp()]\] Used blind sting on [key_name(T)]") - msg_admin_attack("[key_name(T)] was blind stung by [key_name(src)]") + add_attack_logs(src,T,"Blind sting (changeling)") T << "Your eyes burn horrificly!" T.disabilities |= NEARSIGHTED var/duration = 300 diff --git a/code/game/gamemodes/changeling/powers/cryo_sting.dm b/code/game/gamemodes/changeling/powers/cryo_sting.dm index 4bb92a543e..bc68428d89 100644 --- a/code/game/gamemodes/changeling/powers/cryo_sting.dm +++ b/code/game/gamemodes/changeling/powers/cryo_sting.dm @@ -16,9 +16,7 @@ var/mob/living/carbon/T = changeling_sting(20,/mob/proc/changeling_cryo_sting) if(!T) return 0 - T.attack_log += text("\[[time_stamp()]\] Was cryo stung by [key_name(src)]") - src.attack_log += text("\[[time_stamp()]\] Used cryo sting on [key_name(T)]") - msg_admin_attack("[key_name(T)] was cryo stung by [key_name(src)]") + add_attack_logs(src,T,"Cryo sting (changeling)") var/inject_amount = 10 if(src.mind.changeling.recursive_enhancement) inject_amount = inject_amount * 1.5 diff --git a/code/game/gamemodes/changeling/powers/deaf_sting.dm b/code/game/gamemodes/changeling/powers/deaf_sting.dm index 24c1e5d260..a94ad1744a 100644 --- a/code/game/gamemodes/changeling/powers/deaf_sting.dm +++ b/code/game/gamemodes/changeling/powers/deaf_sting.dm @@ -15,9 +15,7 @@ var/mob/living/carbon/T = changeling_sting(5,/mob/proc/changeling_deaf_sting) if(!T) return 0 - T.attack_log += text("\[[time_stamp()]\] Was deaf stung by [key_name(src)]") - src.attack_log += text("\[[time_stamp()]\] Used deaf sting on [key_name(T)]") - msg_admin_attack("[key_name(T)] was deaf stung by [key_name(src)]") + add_attack_logs(src,T,"Deaf sting (changeling)") var/duration = 300 if(src.mind.changeling.recursive_enhancement) duration = duration + 100 diff --git a/code/game/gamemodes/changeling/powers/death_sting.dm b/code/game/gamemodes/changeling/powers/death_sting.dm index 52412a4282..6dd0cdbf85 100644 --- a/code/game/gamemodes/changeling/powers/death_sting.dm +++ b/code/game/gamemodes/changeling/powers/death_sting.dm @@ -13,9 +13,7 @@ var/mob/living/carbon/T = changeling_sting(40,/mob/proc/changeling_DEATHsting) if(!T) return 0 - T.attack_log += text("\[[time_stamp()]\] Was death stung by [key_name(src)]") - src.attack_log += text("\[[time_stamp()]\] Used death sting on [key_name(T)]") - msg_admin_attack("[key_name(T)] was death stung by [key_name(src)]") + add_attack_logs(src,T,"Death sting (changeling)") T << "You feel a small prick and your chest becomes tight." T.silent = 10 T.Paralyse(10) diff --git a/code/game/gamemodes/changeling/powers/delayed_toxin_sting.dm b/code/game/gamemodes/changeling/powers/delayed_toxin_sting.dm index a9b323465c..7853a9603e 100644 --- a/code/game/gamemodes/changeling/powers/delayed_toxin_sting.dm +++ b/code/game/gamemodes/changeling/powers/delayed_toxin_sting.dm @@ -28,10 +28,7 @@ var/mob/living/carbon/T = changeling_sting(20,/mob/proc/changeling_delayed_toxic_sting) if(!T) return 0 - T.attack_log += text("\[[time_stamp()]\] Was delayed toxic stung by [key_name(src)]") - src.attack_log += text("\[[time_stamp()]\] Used delayed toxic sting on [key_name(T)]") - msg_admin_attack("[key_name(T)] was delayed toxic stung by [key_name(src)]") - + add_attack_logs(src,T,"Delayed toxic sting (chagneling)") var/type_to_give = /datum/modifier/delayed_toxin_sting if(src.mind.changeling.recursive_enhancement) type_to_give = /datum/modifier/delayed_toxin_sting/strong diff --git a/code/game/gamemodes/changeling/powers/electric_lockpick.dm b/code/game/gamemodes/changeling/powers/electric_lockpick.dm index dd77debc97..29ad6573f6 100644 --- a/code/game/gamemodes/changeling/powers/electric_lockpick.dm +++ b/code/game/gamemodes/changeling/powers/electric_lockpick.dm @@ -30,6 +30,7 @@ desc = "This finger appears to be an organic datajack." icon = 'icons/obj/weapons.dmi' icon_state = "electric_hand" + show_examine = FALSE /obj/item/weapon/finger_lockpick/New() if(ismob(loc)) diff --git a/code/game/gamemodes/changeling/powers/enfeebling_string.dm b/code/game/gamemodes/changeling/powers/enfeebling_string.dm index b7a6c56957..16303f7c58 100644 --- a/code/game/gamemodes/changeling/powers/enfeebling_string.dm +++ b/code/game/gamemodes/changeling/powers/enfeebling_string.dm @@ -35,9 +35,7 @@ if(ishuman(T)) var/mob/living/carbon/human/H = T - T.attack_log += text("\[[time_stamp()]\] Was enfeebling stung by [key_name(src)]") - src.attack_log += text("\[[time_stamp()]\] Used enfeebling sting on [key_name(T)]") - msg_admin_attack("[key_name(T)] was enfeebling stung by [key_name(src)]") + add_attack_logs(src,T,"Enfeebling sting (changeling)") var/type_to_give = /datum/modifier/enfeeble if(src.mind.changeling.recursive_enhancement) diff --git a/code/game/gamemodes/changeling/powers/extract_dna_sting.dm b/code/game/gamemodes/changeling/powers/extract_dna_sting.dm index 6198e409a6..0c5d91d83b 100644 --- a/code/game/gamemodes/changeling/powers/extract_dna_sting.dm +++ b/code/game/gamemodes/changeling/powers/extract_dna_sting.dm @@ -35,9 +35,7 @@ src << "This creature's DNA is ruined beyond useability!" return 0 - T.attack_log += text("\[[time_stamp()]\] Had DNA extracted via sting by [key_name(src)]") - src.attack_log += text("\[[time_stamp()]\] Used DNA extraction sting on [key_name(T)]") - msg_admin_attack("[key_name(T)] was DNA extraction stung by [key_name(src)]") + add_attack_logs(src,T,"DNA extraction sting (changeling)") var/datum/absorbed_dna/newDNA = new(T.real_name, T.dna, T.species.name, T.languages) absorbDNA(newDNA) diff --git a/code/game/gamemodes/changeling/powers/fabricate_clothing.dm b/code/game/gamemodes/changeling/powers/fabricate_clothing.dm index aad702ea49..d79af62b4c 100644 --- a/code/game/gamemodes/changeling/powers/fabricate_clothing.dm +++ b/code/game/gamemodes/changeling/powers/fabricate_clothing.dm @@ -56,7 +56,6 @@ var/global/list/changeling_fabricated_clothing = list( visible_message("[H] tears off [src]!", "We remove [src].") qdel(src) - H.update_icons_layers() /obj/item/clothing/head/chameleon/changeling name = "malformed head" @@ -78,7 +77,6 @@ var/global/list/changeling_fabricated_clothing = list( visible_message("[H] tears off [src]!", "We remove [src].") qdel(src) - H.update_icons_layers() /obj/item/clothing/suit/chameleon/changeling name = "chitinous chest" @@ -104,7 +102,6 @@ var/global/list/changeling_fabricated_clothing = list( visible_message("[H] tears off [src]!", "We remove [src].") qdel(src) - H.update_icons_layers() /obj/item/clothing/shoes/chameleon/changeling name = "malformed feet" @@ -130,7 +127,6 @@ var/global/list/changeling_fabricated_clothing = list( visible_message("[H] tears off [src]!", "We remove [src].") qdel(src) - H.update_icons_layers() /obj/item/weapon/storage/backpack/chameleon/changeling name = "backpack" @@ -158,7 +154,6 @@ var/global/list/changeling_fabricated_clothing = list( for(var/atom/movable/AM in src.contents) //Dump whatever's in the bag before deleting. AM.forceMove(get_turf(loc)) qdel(src) - H.update_icons_layers() /obj/item/clothing/gloves/chameleon/changeling name = "malformed hands" @@ -185,8 +180,6 @@ var/global/list/changeling_fabricated_clothing = list( visible_message("[H] tears off [src]!", "We remove [src].") qdel(src) - H.update_icons_layers() - /obj/item/clothing/mask/chameleon/changeling name = "chitin visor" @@ -213,7 +206,6 @@ var/global/list/changeling_fabricated_clothing = list( visible_message("[H] tears off [src]!", "We remove [src].") qdel(src) - H.update_icons_layers() /obj/item/clothing/glasses/chameleon/changeling name = "chitin goggles" @@ -235,7 +227,6 @@ var/global/list/changeling_fabricated_clothing = list( visible_message("[H] tears off [src]!", "We remove [src].") qdel(src) - H.update_icons_layers() /obj/item/weapon/storage/belt/chameleon/changeling name = "waist pouch" @@ -261,7 +252,6 @@ var/global/list/changeling_fabricated_clothing = list( visible_message("[H] tears off [src]!", "We remove [src].") qdel(src) - H.update_icons_layers() /obj/item/weapon/card/id/syndicate/changeling name = "chitinous card" @@ -291,8 +281,6 @@ var/global/list/changeling_fabricated_clothing = list( visible_message("[H] tears off [src]!", "We remove [src].") qdel(src) - H.update_icons_layers() - /obj/item/weapon/card/id/syndicate/changeling/Click() //Since we can't hold it in our hands, and attack_hand() doesn't work if it in inventory... if(!registered_user) diff --git a/code/game/gamemodes/changeling/powers/lsd_sting.dm b/code/game/gamemodes/changeling/powers/lsd_sting.dm index 9adb4acd09..fabb81327e 100644 --- a/code/game/gamemodes/changeling/powers/lsd_sting.dm +++ b/code/game/gamemodes/changeling/powers/lsd_sting.dm @@ -13,9 +13,7 @@ var/mob/living/carbon/T = changeling_sting(15,/mob/proc/changeling_lsdsting) if(!T) return 0 - T.attack_log += text("\[[time_stamp()]\] Was hallucination stung by [key_name(src)]") - src.attack_log += text("\[[time_stamp()]\] Used hallucination sting on [key_name(T)]") - msg_admin_attack("[key_name(T)] was hallucination stung by [key_name(src)]") + add_attack_logs(src,T,"Hallucination sting (changeling)") spawn(rand(300,600)) if(T) T.hallucination += 400 feedback_add_details("changeling_powers","HS") diff --git a/code/game/gamemodes/changeling/powers/para_sting.dm b/code/game/gamemodes/changeling/powers/para_sting.dm index efe6fe8f79..7a0020bd0f 100644 --- a/code/game/gamemodes/changeling/powers/para_sting.dm +++ b/code/game/gamemodes/changeling/powers/para_sting.dm @@ -12,9 +12,7 @@ var/mob/living/carbon/T = changeling_sting(30,/mob/proc/changeling_paralysis_sting) if(!T) return 0 - T.attack_log += text("\[[time_stamp()]\] Was paralysis stung by [key_name(src)]") - src.attack_log += text("\[[time_stamp()]\] Used paralysis sting on [key_name(T)]") - msg_admin_attack("[key_name(T)] was paralysis stung by [key_name(src)]") + add_attack_logs(src,T,"Paralysis sting (changeling)") T << "Your muscles begin to painfully tighten." T.Weaken(20) feedback_add_details("changeling_powers","PS") diff --git a/code/game/gamemodes/changeling/powers/revive.dm b/code/game/gamemodes/changeling/powers/revive.dm index ab8111000d..0da6c3c3d5 100644 --- a/code/game/gamemodes/changeling/powers/revive.dm +++ b/code/game/gamemodes/changeling/powers/revive.dm @@ -33,7 +33,7 @@ H.restore_all_organs(ignore_prosthetic_prefs=1) //Covers things like fractures and other things not covered by the above. H.restore_blood() H.mutations.Remove(HUSK) - H.status_flags -= DISFIGURED + H.status_flags &= ~DISFIGURED H.update_icons_body() for(var/limb in H.organs_by_name) var/obj/item/organ/external/current_limb = H.organs_by_name[limb] diff --git a/code/game/gamemodes/changeling/powers/shriek.dm b/code/game/gamemodes/changeling/powers/shriek.dm index 40e796490f..4989c27f87 100644 --- a/code/game/gamemodes/changeling/powers/shriek.dm +++ b/code/game/gamemodes/changeling/powers/shriek.dm @@ -51,12 +51,8 @@ range = range * 2 to_chat(src, "We are extra loud.") - src.attack_log += text("\[[time_stamp()]\] Used Resonant Shriek.") - message_admins("[key_name(src)] used Resonant Shriek ([src.x],[src.y],[src.z]) (JMP).") - log_game("[key_name(src)] used Resonant Shriek.") - visible_message("[src] appears to shout.") - + var/list/affected = list() for(var/mob/living/M in range(range, src)) if(iscarbon(M)) if(!M.mind || !M.mind.changeling) @@ -67,7 +63,7 @@ M.adjustEarDamage(0,30) M.Confuse(20) M << sound('sound/effects/screech.ogg') - M.attack_log += text("\[[time_stamp()]\] Was affected by [key_name(src)]'s Resonant Shriek.") + affected += M else if(M != src) M << "You hear a familiar screech from nearby. It has no effect on you." @@ -77,7 +73,7 @@ M << sound('sound/weapons/flash.ogg') M << "Auditory input overloaded. Reinitializing..." M.Weaken(rand(5,10)) - M.attack_log += text("\[[time_stamp()]\] Was affected by [key_name(src)]'s Resonant Shriek.") + affected += M for(var/obj/machinery/light/L in range(range, src)) L.on = 1 @@ -85,6 +81,7 @@ changeling.last_shriek = world.time + add_attack_logs(src,affected,"Used resonant shriek") feedback_add_details("changeling_powers","RS") return 1 @@ -133,9 +130,7 @@ visible_message("[src] appears to shout.") - src.attack_log += text("\[[time_stamp()]\] Used Dissonant Shriek.") - message_admins("[key_name(src)] used Dissonant Shriek ([src.x],[src.y],[src.z]) (JMP).") - log_game("[key_name(src)] used Dissonant Shriek.") + add_attack_logs(src,null,"Use dissonant shriek") for(var/obj/machinery/light/L in range(5, src)) L.on = 1 diff --git a/code/game/gamemodes/changeling/powers/silence_sting.dm b/code/game/gamemodes/changeling/powers/silence_sting.dm index 1ab25278a4..334b0c139f 100644 --- a/code/game/gamemodes/changeling/powers/silence_sting.dm +++ b/code/game/gamemodes/changeling/powers/silence_sting.dm @@ -15,9 +15,7 @@ var/mob/living/carbon/T = changeling_sting(10,/mob/proc/changeling_silence_sting) if(!T) return 0 - T.attack_log += text("\[[time_stamp()]\] Was silence stung by [key_name(src)]") - src.attack_log += text("\[[time_stamp()]\] Used silence sting on [key_name(T)]") - msg_admin_attack("[key_name(T)] was silence stung by [key_name(src)]") + add_attack_logs(src,T,"Silence sting (changeling)") var/duration = 30 if(src.mind.changeling.recursive_enhancement) duration = duration + 10 diff --git a/code/game/gamemodes/changeling/powers/transform_sting.dm b/code/game/gamemodes/changeling/powers/transform_sting.dm index 797eec92d2..678e195e22 100644 --- a/code/game/gamemodes/changeling/powers/transform_sting.dm +++ b/code/game/gamemodes/changeling/powers/transform_sting.dm @@ -36,9 +36,7 @@ if((HUSK in T.mutations) || (!ishuman(T) && !issmall(T))) src << "Our sting appears ineffective against its DNA." return 0 - T.attack_log += text("\[[time_stamp()]\] Was transform stung by [key_name(src)]") - src.attack_log += text("\[[time_stamp()]\] Used transform sting on [key_name(T)]") - msg_admin_attack("[key_name(T)] was transform stung by [key_name(src)]") + add_attack_logs(src,T,"Transformation sting (changeling)") T.visible_message("[T] transforms!") T.dna = chosen_dna.Clone() T.real_name = chosen_dna.real_name diff --git a/code/game/gamemodes/changeling/powers/unfat_sting.dm b/code/game/gamemodes/changeling/powers/unfat_sting.dm index 4b42f55e30..f2e238746d 100644 --- a/code/game/gamemodes/changeling/powers/unfat_sting.dm +++ b/code/game/gamemodes/changeling/powers/unfat_sting.dm @@ -11,9 +11,7 @@ var/mob/living/carbon/T = changeling_sting(5,/mob/proc/changeling_unfat_sting) if(!T) return 0 - T.attack_log += text("\[[time_stamp()]\] Was unfat stung by [key_name(src)]") - src.attack_log += text("\[[time_stamp()]\] Used unfat sting on [key_name(T)]") - msg_admin_attack("[key_name(T)] was unfat stung by [key_name(src)]") + add_attack_logs(src,T,"Unfat sting (changeling)") T << "you feel a small prick as stomach churns violently and you become to feel skinnier." T.overeatduration = 0 T.nutrition -= 100 diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index 8db7a49255..d91e2e1f47 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -292,10 +292,7 @@ var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa"," words[cultwords[V]] = V attack(mob/living/M as mob, mob/living/user as mob) - - M.attack_log += text("\[[time_stamp()]\] Has had the [name] used on them by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Used [name] on [M.name] ([M.ckey])") - msg_admin_attack("[user.name] ([user.ckey]) used [name] on [M.name] ([M.ckey]) (JMP)") + add_attack_logs(user,M,"Hit with [name]") if(istype(M,/mob/observer/dead)) var/mob/observer/dead/D = M diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 0e0ff60791..d7579698d1 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -139,7 +139,7 @@ var/list/sacrificed = list() target.take_overall_damage(0, rand(5, 20)) // You dirty resister cannot handle the damage to your mind. Easily. - even cultists who accept right away should experience some effects // Resist messages go! if(initial_message) //don't do this stuff right away, only if they resist or hesitate. - admin_attack_log(attacker, target, "Used a convert rune", "Was subjected to a convert rune", "used a convert rune on") + add_attack_logs(attacker,target,"Convert rune") switch(target.getFireLoss()) if(0 to 25) target << "Your blood boils as you force yourself to resist the corruption invading every corner of your mind." @@ -247,7 +247,7 @@ var/list/sacrificed = list() if(R.word1==cultwords["travel"] && R.word2==cultwords["blood"] && R.word3==cultwords["self"]) for(var/mob/living/carbon/D in R.loc) if(D.stat!=2) - admin_attack_log(usr, D, "Used a blood drain rune.", "Was victim of a blood drain rune.", "used a blood drain rune on") + add_attack_logs(usr,D,"Blood drain rune") var/bdrain = rand(1,25) D << "You feel weakened." D.take_overall_damage(bdrain, 0) @@ -933,7 +933,7 @@ var/list/sacrificed = list() if(affected.len) usr.say("Sti[pick("'","`")] kaliedir!") usr << "The world becomes quiet as the deafening rune dissipates into fine dust." - admin_attacker_log_many_victims(usr, affected, "Used a deafen rune.", "Was victim of a deafen rune.", "used a deafen rune on") + add_attack_logs(usr,affected,"Deafen rune") qdel(src) else return fizzle() @@ -952,7 +952,7 @@ var/list/sacrificed = list() if(affected.len) usr.whisper("Sti[pick("'","`")] kaliedir!") usr << "Your talisman turns into gray dust, deafening everyone around." - admin_attacker_log_many_victims(usr, affected, "Used a deafen rune.", "Was victim of a deafen rune.", "used a deafen rune on") + add_attack_logs(usr, affected, "Deafen rune") for (var/mob/V in orange(1,src)) if(!(iscultist(V))) V.show_message("Dust flows from [usr]'s hands for a moment, and the world suddenly becomes quiet..", 3) @@ -978,7 +978,7 @@ var/list/sacrificed = list() if(affected.len) usr.say("Sti[pick("'","`")] kaliesin!") usr << "The rune flashes, blinding those who not follow the Nar-Sie, and dissipates into fine dust." - admin_attacker_log_many_victims(usr, affected, "Used a blindness rune.", "Was victim of a blindness rune.", "used a blindness rune on") + add_attack_logs(usr, affected, "Blindness rune") qdel(src) else return fizzle() @@ -998,7 +998,7 @@ var/list/sacrificed = list() if(affected.len) usr.whisper("Sti[pick("'","`")] kaliesin!") usr << "Your talisman turns into gray dust, blinding those who not follow the Nar-Sie." - admin_attacker_log_many_victims(usr, affected, "Used a blindness rune.", "Was victim of a blindness rune.", "used a blindness rune on") + add_attack_logs(usr, affected, "Blindness rune") return @@ -1035,8 +1035,7 @@ var/list/sacrificed = list() if(iscultist(C) && !C.stat) C.say("Dedo ol[pick("'","`")]btoh!") C.take_overall_damage(15, 0) - admin_attacker_log_many_victims(usr, victims, "Used a blood boil rune.", "Was the victim of a blood boil rune.", "used a blood boil rune on") - log_and_message_admins_many(cultists - usr, "assisted activating a blood boil rune.") + add_attack_logs(usr, victims, "Blood boil rune") qdel(src) else return fizzle() @@ -1084,13 +1083,13 @@ var/list/sacrificed = list() C.Weaken(1) C.Stun(1) C.show_message("The rune explodes in a bright flash.", 3) - admin_attack_log(usr, C, "Used a stun rune.", "Was victim of a stun rune.", "used a stun rune on") + add_attack_logs(usr,C,"Stun rune") else if(issilicon(L)) var/mob/living/silicon/S = L S.Weaken(5) S.show_message("BZZZT... The rune has exploded in a bright flash.", 3) - admin_attack_log(usr, S, "Used a stun rune.", "Was victim of a stun rune.", "used a stun rune on") + add_attack_logs(usr,S,"Stun rune") qdel(src) else ///When invoked as talisman, stun and mute the target mob. usr.say("Dream sign ''Evil sealing talisman'[pick("'","`")]!") @@ -1104,7 +1103,7 @@ var/list/sacrificed = list() if(issilicon(T)) T.Weaken(15) - admin_attack_log(usr, T, "Used a stun rune.", "Was victim of a stun rune.", "used a stun rune on") + add_attack_logs(usr,T,"Stun rune") else if(iscarbon(T)) var/mob/living/carbon/C = T C.flash_eyes() @@ -1112,7 +1111,7 @@ var/list/sacrificed = list() C.silent += 15 C.Weaken(25) C.Stun(25) - admin_attack_log(usr, C, "Used a stun rune.", "Was victim of a stun rune.", "used a stun rune on") + add_attack_logs(usr,C,"Stun rune") return /////////////////////////////////////////TWENTY-FIFTH RUNE diff --git a/code/game/gamemodes/endgame/supermatter_cascade/portal.dm b/code/game/gamemodes/endgame/supermatter_cascade/portal.dm index fb4888ee20..2c47b8e162 100644 --- a/code/game/gamemodes/endgame/supermatter_cascade/portal.dm +++ b/code/game/gamemodes/endgame/supermatter_cascade/portal.dm @@ -10,7 +10,7 @@ announce=0 cause_hell=0 - layer=LIGHTING_LAYER+2 // ITS SO BRIGHT + plane = PLANE_LIGHTING_ABOVE // ITS SO BRIGHT consume_range = 6 @@ -79,7 +79,8 @@ var/turf/T_mob = get_turf(src) if((R.z == T_mob.z) && (get_dist(R,T_mob) <= (R.consume_range+10)) && !(R in view(T_mob))) if(!riftimage) - riftimage = image('icons/obj/rift.dmi',T_mob,"rift",LIGHTING_LAYER+2,1) + riftimage = image('icons/obj/rift.dmi',T_mob,"rift",1,1) + riftimage.plane = PLANE_LIGHTING_ABOVE riftimage.mouse_opacity = 0 var/new_x = 32 * (R.x - T_mob.x) + R.pixel_x diff --git a/code/game/gamemodes/technomancer/assistance/golem.dm b/code/game/gamemodes/technomancer/assistance/golem.dm index 33fc246911..6b8654e719 100644 --- a/code/game/gamemodes/technomancer/assistance/golem.dm +++ b/code/game/gamemodes/technomancer/assistance/golem.dm @@ -30,7 +30,7 @@ melee_damage_lower = 30 // It has a built in esword. melee_damage_upper = 30 attack_sound = 'sound/weapons/blade1.ogg' - attacktext = "slashed" + attacktext = list("slashed") friendly = "hugs" resistance = 0 melee_miss_chance = 0 diff --git a/code/game/gamemodes/technomancer/spell_objs.dm b/code/game/gamemodes/technomancer/spell_objs.dm index fb28813102..2a917b4fd8 100644 --- a/code/game/gamemodes/technomancer/spell_objs.dm +++ b/code/game/gamemodes/technomancer/spell_objs.dm @@ -31,6 +31,7 @@ ) throwforce = 0 force = 0 + show_examine = FALSE // var/mob/living/carbon/human/owner = null var/mob/living/owner = null var/obj/item/weapon/technomancer_core/core = null diff --git a/code/game/jobs/job/captain.dm b/code/game/jobs/job/captain.dm index daefb23ef2..85afcaa294 100644 --- a/code/game/jobs/job/captain.dm +++ b/code/game/jobs/job/captain.dm @@ -87,4 +87,3 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) minimal_access = list(access_heads, access_keycard_auth) outfit_type = /decl/hierarchy/outfit/job/secretary - alt_titles = list("Command Liaison", "Bridge Secretary") diff --git a/code/game/jobs/job/civilian.dm b/code/game/jobs/job/civilian.dm index 876579440c..d31a551726 100644 --- a/code/game/jobs/job/civilian.dm +++ b/code/game/jobs/job/civilian.dm @@ -49,7 +49,7 @@ minimal_access = list(access_hydroponics) outfit_type = /decl/hierarchy/outfit/job/service/gardener - alt_titles = list("Hydroponicist", "Gardener") + alt_titles = list("Gardener") //Cargo /datum/job/qm @@ -105,7 +105,7 @@ minimal_access = list(access_mining, access_mining_station, access_mailsorting) outfit_type = /decl/hierarchy/outfit/job/cargo/mining - alt_titles = list("Drill Technician","Prospector") + alt_titles = list("Drill Technician") //Service /datum/job/janitor @@ -123,7 +123,7 @@ minimal_access = list(access_janitor, access_maint_tunnels) outfit_type = /decl/hierarchy/outfit/job/service/janitor - alt_titles = list("Custodian", "Sanitation Technician") + alt_titles = list("Custodian") //More or less assistants /datum/job/librarian @@ -141,7 +141,7 @@ minimal_access = list(access_library) outfit_type = /decl/hierarchy/outfit/job/librarian - alt_titles = list("Journalist", "Professor", "Historian", "Writer") + alt_titles = list("Journalist", "Writer") //var/global/lawyer = 0//Checks for another lawyer //This changed clothes on 2nd lawyer, both IA get the same dreds. /datum/job/lawyer diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm index 2e7f878e98..d40330ca48 100644 --- a/code/game/jobs/job_controller.dm +++ b/code/game/jobs/job_controller.dm @@ -327,6 +327,27 @@ var/global/datum/controller/occupations/job_master var/datum/job/job = GetJob(rank) var/list/spawn_in_storage = list() + if(!joined_late) + var/obj/S = null + for(var/obj/effect/landmark/start/sloc in landmarks_list) + if(sloc.name != rank) continue + if(locate(/mob/living) in sloc.loc) continue + S = sloc + break + if(!S) + S = locate("start*[rank]") // use old stype + if(istype(S, /obj/effect/landmark/start) && istype(S.loc, /turf)) + H.forceMove(S.loc) + else + var/list/spawn_props = LateSpawn(H.client, rank) + var/turf/T = spawn_props["turf"] + H.forceMove(T) + + // Moving wheelchair if they have one + if(H.buckled && istype(H.buckled, /obj/structure/bed/chair/wheelchair)) + H.buckled.forceMove(H.loc) + H.buckled.set_dir(H.dir) + if(job) //Equip custom gear loadout. @@ -379,7 +400,8 @@ var/global/datum/controller/occupations/job_master job.equip_backpack(H) // job.equip_survival(H) job.apply_fingerprints(H) - H.equip_post_job() + if(job.title != "Cyborg" && job.title != "AI") + H.equip_post_job() //If some custom items could not be equipped before, try again now. for(var/thing in custom_equip_leftovers) @@ -398,25 +420,6 @@ var/global/datum/controller/occupations/job_master H.job = rank - if(!joined_late) - var/obj/S = null - for(var/obj/effect/landmark/start/sloc in landmarks_list) - if(sloc.name != rank) continue - if(locate(/mob/living) in sloc.loc) continue - S = sloc - break - if(!S) - S = locate("start*[rank]") // use old stype - if(istype(S, /obj/effect/landmark/start) && istype(S.loc, /turf)) - H.forceMove(S.loc) - else - LateSpawn(H, rank) - - // Moving wheelchair if they have one - if(H.buckled && istype(H.buckled, /obj/structure/bed/chair/wheelchair)) - H.buckled.forceMove(H.loc) - H.buckled.set_dir(H.dir) - // If they're head, give them the account info for their department if(H.mind && job.head_position) var/remembered_info = "" @@ -607,32 +610,30 @@ var/global/datum/controller/occupations/job_master tmp_str += "HIGH=[level1]|MEDIUM=[level2]|LOW=[level3]|NEVER=[level4]|BANNED=[level5]|YOUNG=[level6]|-" feedback_add_details("job_preferences",tmp_str) -/datum/controller/occupations/proc/LateSpawn(var/mob/living/carbon/human/H, var/rank) - //spawn at one of the latespawn locations +/datum/controller/occupations/proc/LateSpawn(var/client/C, var/rank) var/datum/spawnpoint/spawnpos -// if(H.client.prefs.spawnpoint) -// spawnpos = spawntypes[H.client.prefs.spawnpoint] - - if(H.client.prefs.spawnpoint) - if(!(H.client.prefs.spawnpoint in using_map.allowed_spawns)) - if(H) // This seems redundant... - to_chat(H, "Your chosen spawnpoint ([H.client.prefs.spawnpoint]) is unavailable for the current map. Spawning you at one of the enabled spawn points instead.") + //Spawn them at their preferred one + if(C && C.prefs.spawnpoint) + if(!(C.prefs.spawnpoint in using_map.allowed_spawns)) + to_chat(C, "Your chosen spawnpoint ([C.prefs.spawnpoint]) is unavailable for the current map. Spawning you at one of the enabled spawn points instead.") spawnpos = null else - spawnpos = spawntypes[H.client.prefs.spawnpoint] + spawnpos = spawntypes[C.prefs.spawnpoint] + //We will return a list key'd by "turf" and "msg" + . = list("turf","msg") if(spawnpos && istype(spawnpos) && spawnpos.turfs.len) if(spawnpos.check_job_spawning(rank)) - H.forceMove(spawnpos.get_spawn_position()) - . = spawnpos.msg + .["turf"] = spawnpos.get_spawn_position() + .["msg"] = spawnpos.msg else - H << "Your chosen spawnpoint ([spawnpos.display_name]) is unavailable for your chosen job. Spawning you at the Arrivals shuttle instead." + to_chat(C,"Your chosen spawnpoint ([spawnpos.display_name]) is unavailable for your chosen job. Spawning you at the Arrivals shuttle instead.") var/spawning = pick(latejoin) - H.forceMove(get_turf(spawning)) - . = "will arrive to the station shortly by shuttle" + .["turf"] = get_turf(spawning) + .["msg"] = "will arrive to the station shortly by shuttle" else var/spawning = pick(latejoin) - H.forceMove(get_turf(spawning)) - . = "has arrived on the station" + .["turf"] = get_turf(spawning) + .["msg"] = "has arrived on the station" diff --git a/code/game/machinery/Beacon.dm b/code/game/machinery/Beacon.dm index c59c67c300..b34d1565a0 100644 --- a/code/game/machinery/Beacon.dm +++ b/code/game/machinery/Beacon.dm @@ -4,7 +4,7 @@ name = "Bluespace Gigabeacon" desc = "A device that draws power from bluespace and creates a permanent tracking beacon." level = 1 // underfloor - layer = 2.5 + layer = UNDER_JUNK_LAYER anchored = 1 use_power = 1 idle_power_usage = 0 diff --git a/code/game/machinery/OpTable.dm b/code/game/machinery/OpTable.dm index 5696892ddc..ccf3f69529 100644 --- a/code/game/machinery/OpTable.dm +++ b/code/game/machinery/OpTable.dm @@ -9,6 +9,7 @@ idle_power_usage = 1 active_power_usage = 5 surgery_odds = 100 + throwpass = 1 var/mob/living/carbon/human/victim = null var/strapped = 0.0 var/obj/machinery/computer/operating/computer = null diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index 2d80766ea6..c3251ce155 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -343,7 +343,7 @@ organStatus["destroyed"] = 1 if(E.status & ORGAN_BROKEN) organStatus["broken"] = E.broken_description - if(E.status & ORGAN_ROBOT) + if(E.robotic >= ORGAN_ROBOT) organStatus["robotic"] = 1 if(E.splinted) organStatus["splinted"] = 1 @@ -512,7 +512,7 @@ bled = "Bleeding:" if(e.status & ORGAN_BROKEN) AN = "[e.broken_description]:" - if(e.status & ORGAN_ROBOT) + if(e.robotic >= ORGAN_ROBOT) robot = "Prosthetic:" if(e.status & ORGAN_DEAD) o_dead = "Necrotic:" diff --git a/code/game/machinery/ai_slipper.dm b/code/game/machinery/ai_slipper.dm index 0ea5527df2..dd79d5acc1 100644 --- a/code/game/machinery/ai_slipper.dm +++ b/code/game/machinery/ai_slipper.dm @@ -2,7 +2,6 @@ name = "\improper AI Liquid Dispenser" icon = 'icons/obj/device.dmi' icon_state = "motion0" - layer = 3 anchored = 1.0 use_power = 1 idle_power_usage = 10 diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index 775ef6a7cd..a2115d9fdd 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -823,7 +823,7 @@ FIRE ALARM alarms_hidden = TRUE /obj/machinery/firealarm/update_icon() - overlays.Cut() + cut_overlays() if(panel_open) set_light(0) @@ -846,8 +846,7 @@ FIRE ALARM if("blue") set_light(l_range = 2, l_power = 0.5, l_color = "#1024A9") if("red") set_light(l_range = 4, l_power = 2, l_color = "#ff0000") if("delta") set_light(l_range = 4, l_power = 2, l_color = "#FF6633") - - overlays += image('icons/obj/monitors.dmi', "overlay_[seclevel]") + add_overlay("overlay_[seclevel]") /obj/machinery/firealarm/fire_act(datum/gas_mixture/air, temperature, volume) if(detecting) diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 769dd9c39f..70d8864e2d 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -6,7 +6,8 @@ use_power = 2 idle_power_usage = 5 active_power_usage = 10 - layer = 5 + plane = MOB_PLANE + layer = ABOVE_MOB_LAYER var/list/network = list(NETWORK_DEFAULT) var/c_tag = null diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index df2387e71f..bdf4e95fe0 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -28,7 +28,10 @@ /obj/random/action_figure = 1, /obj/random/plushie = 1, /obj/item/toy/cultsword = 1, - /obj/item/toy/bouquet/fake = 1 + /obj/item/toy/bouquet/fake = 1, + /obj/item/clothing/accessory/badge/sheriff = 2, + /obj/item/clothing/head/cowboy_hat/small = 2, + /obj/item/toy/stickhorse = 2 ) /obj/machinery/computer/arcade/New() @@ -268,6 +271,8 @@ /obj/machinery/computer/arcade/battle/emag_act(var/charges, var/mob/user) if(!emagged) + to_chat(user, span("notice","You override the cheat code menu and skip to Cheat #[rand(1, 50)]: Hyper-Lethal Mode.")) + temp = "If you die in the game, you die for real!" player_hp = 30 player_mp = 10 @@ -396,18 +401,18 @@ dat += "
You ran out of food and starved." if(emagged) user.nutrition = 0 //yeah you pretty hongry - user << "Your body instantly contracts to that of one who has not eaten in months. Agonizing cramps seize you as you fall to the floor." + to_chat(user, span("danger", "Your body instantly contracts to that of one who has not eaten in months. Agonizing cramps seize you as you fall to the floor.")) if(fuel <= 0) dat += "
You ran out of fuel, and drift, slowly, into a star." if(emagged) var/mob/living/M = user M.adjust_fire_stacks(5) - M.IgniteMob() //flew into a star, so you're on fire - user << "You feel an immense wave of heat emanate from \the [src]. Your skin bursts into flames." + M.IgniteMob() //flew into a star, so you're on fire + to_chat(user,span("danger", "You feel an immense wave of heat emanate from \the [src]. Your skin bursts into flames.")) dat += "

OK...

" if(emagged) - user << "You're never going to make it to Orion..." + to_chat(user, span("danger", "You're never going to make it to Orion...")) user.death() emagged = 0 //removes the emagged status after you lose gameStatus = ORION_STATUS_START @@ -472,20 +477,20 @@ switch(event) if(ORION_TRAIL_RAIDERS) if(prob(50)) - usr << "You hear battle shouts. The tramping of boots on cold metal. Screams of agony. The rush of venting air. Are you going insane?" + to_chat(usr, span("warning", "You hear battle shouts. The tramping of boots on cold metal. Screams of agony. The rush of venting air. Are you going insane?")) M.hallucination += 30 else - usr << "Something strikes you from behind! It hurts like hell and feel like a blunt weapon, but nothing is there..." + to_chat(usr, span("danger", "Something strikes you from behind! It hurts like hell and feel like a blunt weapon, but nothing is there...")) M.take_organ_damage(25) if(ORION_TRAIL_ILLNESS) var/severity = rand(1,3) //pray to RNGesus. PRAY, PIGS if(severity == 1) - M << "You suddenly feel slightly nauseous." //got off lucky + to_chat(M, span("warning", "You suddenly feel slightly nauseous.")) //got off lucky if(severity == 2) - usr << "You suddenly feel extremely nauseous and hunch over until it passes." + to_chat(usr, span("warning", "You suddenly feel extremely nauseous and hunch over until it passes.")) M.Stun(3) if(severity >= 3) //you didn't pray hard enough - M << "An overpowering wave of nausea consumes over you. You hunch over, your stomach's contents preparing for a spectacular exit." + to_chat(M, span("warning", "An overpowering wave of nausea consumes over you. You hunch over, your stomach's contents preparing for a spectacular exit.")) spawn(30) if(istype(M,/mob/living/carbon/human)) var/mob/living/carbon/human/H = M @@ -496,12 +501,12 @@ src.visible_message("A sudden gust of powerful wind slams \the [M] into the floor!", "You hear a large fwooshing sound, followed by a bang.") M.take_organ_damage(15) else - M << "A violent gale blows past you, and you barely manage to stay standing!" + to_chat(M, span("warning", "A violent gale blows past you, and you barely manage to stay standing!")) if(ORION_TRAIL_COLLISION) //by far the most damaging event if(prob(90) && !hull) var/turf/simulated/floor/F = src.loc F.ChangeTurf(/turf/space) - src.visible_message("Something slams into the floor around \the [src], exposing it to space!", "You hear something crack and break.") + src.visible_message(span("danger", "Something slams into the floor around \the [src], exposing it to space!"), "You hear something crack and break.") else src.visible_message("Something slams into the floor around \the [src] - luckily, it didn't get through!", "You hear something crack.") if(ORION_TRAIL_MALFUNCTION) @@ -570,9 +575,9 @@ event() if(emagged) //has to be here because otherwise it doesn't work src.show_message("\The [src] states, 'YOU ARE EXPERIENCING A BLACKHOLE. BE TERRIFIED.","You hear something say, 'YOU ARE EXPERIENCING A BLACKHOLE. BE TERRFIED'") - usr << "Something draws you closer and closer to the machine." + to_chat(usr, span("warning", "Something draws you closer and closer to the machine.")) sleep(10) - usr << "This is really starting to hurt!" + to_chat(usr, span("danger", "This is really starting to hurt!")) var i; //spawning a literal blackhole would be fun, but a bit disruptive. for(i=0;i<4;i++) var/mob/living/L = usr @@ -998,12 +1003,12 @@ /obj/machinery/computer/arcade/orion_trail/emag_act(mob/user) if(!emagged) - user << "You override the cheat code menu and skip to Cheat #[rand(1, 50)]: Realism Mode." + to_chat(user, span("notice", "You override the cheat code menu and skip to Cheat #[rand(1, 50)]: Realism Mode.")) name = "The Orion Trail: Realism Edition" desc = "Learn how our ancestors got to Orion, and try not to die in the process!" newgame() emagged = 1 - + return 1 /obj/item/weapon/orion_ship name = "model settler ship" @@ -1018,9 +1023,9 @@ if(!(in_range(user, src))) return if(!active) - user << "There's a little switch on the bottom. It's flipped down." + to_chat(user, span("notice", "There's a little switch on the bottom. It's flipped down.")) else - user << "There's a little switch on the bottom. It's flipped up." + to_chat(user, span("notice", "There's a little switch on the bottom. It's flipped up.")) /obj/item/weapon/orion_ship/attack_self(mob/user) if(active) @@ -1029,17 +1034,17 @@ message_admins("[key_name_admin(usr)] primed an explosive Orion ship for detonation.") log_game("[key_name(usr)] primed an explosive Orion ship for detonation.") - user << "You flip the switch on the underside of [src]." + to_chat(user, span("warning", "You flip the switch on the underside of [src].")) active = 1 - src.visible_message("[src] softly beeps and whirs to life!") + src.visible_message(span("notice", "[src] softly beeps and whirs to life!")) src.audible_message("\The [src] says, 'This is ship ID #[rand(1,1000)] to Orion Port Authority. We're coming in for landing, over.'") sleep(20) - src.visible_message("[src] begins to vibrate...") + src.visible_message(span("warning", "[src] begins to vibrate...")) src.audible_message("\The [src] says, 'Uh, Port? Having some issues with our reactor, could you check it out? Over.'") sleep(30) src.audible_message("\The [src] says, 'Oh, God! Code Eight! CODE EIGHT! IT'S GONNA BL-'") sleep(3.6) - src.visible_message("[src] explodes!") + src.visible_message(span("danger", "[src] explodes!")) explosion(src.loc, 1,2,4) qdel(src) diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 29196f44d5..c95bd9879c 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -187,7 +187,7 @@ return CentCom_announce(input, usr) usr << "Message transmitted." - log_say("[key_name(usr)] has made an IA [using_map.boss_short] announcement: [input]") + log_game("[key_name(usr)] has made an IA [using_map.boss_short] announcement: [input]") centcomm_message_cooldown = 1 spawn(300)//10 minute cooldown centcomm_message_cooldown = 0 @@ -204,7 +204,7 @@ return Syndicate_announce(input, usr) usr << "Message transmitted." - log_say("[key_name(usr)] has made an illegal announcement: [input]") + log_game("[key_name(usr)] has made an illegal announcement: [input]") centcomm_message_cooldown = 1 spawn(300)//10 minute cooldown centcomm_message_cooldown = 0 diff --git a/code/game/machinery/computer/supply.dm b/code/game/machinery/computer/supply.dm index 4bcc43bbec..e76f4db468 100644 --- a/code/game/machinery/computer/supply.dm +++ b/code/game/machinery/computer/supply.dm @@ -40,6 +40,7 @@
\nRequest items

View approved orders

View requests

+ \nView export report

Close"} user << browse(dat, "window=computer;size=575x450") @@ -198,6 +199,7 @@ \nOrder items
\n
\nView requests
\n
\nView orders
\n
+ \nView export report
\n
\nClose"} @@ -367,6 +369,18 @@ temp += "
Clear list" temp += "
OK" + else if (href_list["viewexport"]) + temp = "Previous shuttle export report:

" + var/cratecount = 0 + var/totalvalue = 0 + for(var/S in supply_controller.exported_crates) + var/datum/exported_crate/EC = S + cratecount += 1 + totalvalue += EC.value + temp += "[EC.name] exported for [EC.value] supply points
" + temp += "
Shipment of [cratecount] crates exported for [totalvalue] supply points.
" + temp += "
OK" + else if (href_list["rreq"]) var/ordernum = text2num(href_list["rreq"]) temp = "Invalid Request.
" diff --git a/code/game/machinery/computer3/computers/HolodeckControl.dm b/code/game/machinery/computer3/computers/HolodeckControl.dm index 4d63b95673..a629354d7b 100644 --- a/code/game/machinery/computer3/computers/HolodeckControl.dm +++ b/code/game/machinery/computer3/computers/HolodeckControl.dm @@ -155,7 +155,6 @@ var/mob/M = obj.loc if(ismob(M)) M.remove_from_mob(obj) - M.update_icons_layers() //so their overlays update if(!silent) var/obj/oldobj = obj diff --git a/code/game/machinery/computer3/computers/communications.dm b/code/game/machinery/computer3/computers/communications.dm index 6f802c54bd..acd66ebde1 100644 --- a/code/game/machinery/computer3/computers/communications.dm +++ b/code/game/machinery/computer3/computers/communications.dm @@ -197,7 +197,7 @@ return CentCom_announce(input, usr) usr << "Message transmitted." - log_say("[key_name(usr)] has made a [using_map.boss_short] announcement: [input]") + log_game("[key_name(usr)] has made a [using_map.boss_short] announcement: [input]") centcomm_message_cooldown = 1 spawn(600)//10 minute cooldown centcomm_message_cooldown = 0 @@ -214,7 +214,7 @@ return Syndicate_announce(input, usr) usr << "Message transmitted." - log_say("[key_name(usr)] has made an illegal announcement: [input]") + log_game("[key_name(usr)] has made an illegal announcement: [input]") centcomm_message_cooldown = 1 spawn(600)//10 minute cooldown centcomm_message_cooldown = 0 diff --git a/code/game/machinery/computer3/computers/prisoner.dm b/code/game/machinery/computer3/computers/prisoner.dm index 7e3ada285d..27943bb353 100644 --- a/code/game/machinery/computer3/computers/prisoner.dm +++ b/code/game/machinery/computer3/computers/prisoner.dm @@ -95,7 +95,7 @@ var/obj/item/weapon/implant/I = locate(href_list["warn"]) if( istype(I) && I.imp_in) var/mob/living/carbon/R = I.imp_in - log_say("PrisonComputer3 message: [key_name(usr)]->[key_name(R)] : [warning]") + log_game("PrisonComputer3 message: [key_name(usr)]->[key_name(R)] : [warning]") R << "You hear a voice in your head saying: '[warning]'" interact() diff --git a/code/game/machinery/computer3/lapvend.dm b/code/game/machinery/computer3/lapvend.dm index e1e70ca3a7..cbfa8686bc 100644 --- a/code/game/machinery/computer3/lapvend.dm +++ b/code/game/machinery/computer3/lapvend.dm @@ -3,7 +3,6 @@ desc = "A generic vending machine." icon = 'icons/obj/vending.dmi' icon_state = "robotics" - layer = 2.9 anchored = 1 density = 1 var/obj/machinery/computer3/laptop/vended/newlap = null diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index 6709cb2363..f7ab7e7a7e 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -6,13 +6,15 @@ icon_state = "pod_preview" density = 1 anchored = 1.0 - layer = 2.8 + layer = UNDER_JUNK_LAYER interact_offline = 1 var/on = 0 use_power = 1 idle_power_usage = 20 active_power_usage = 200 + buckle_lying = FALSE + buckle_dir = SOUTH var/temperature_archived var/mob/living/carbon/occupant = null @@ -20,12 +22,29 @@ var/current_heat_capacity = 50 + var/image/fluid + /obj/machinery/atmospherics/unary/cryo_cell/New() ..() icon = 'icons/obj/cryogenics_split.dmi' - update_icon() + icon_state = "base" initialize_directions = dir +/obj/machinery/atmospherics/unary/cryo_cell/initialize() + . = ..() + var/image/tank = image(icon,"tank") + tank.alpha = 200 + tank.pixel_y = 18 + tank.plane = MOB_PLANE + tank.layer = MOB_LAYER+0.2 //Above fluid + fluid = image(icon, "tube_filler") + fluid.pixel_y = 18 + fluid.alpha = 200 + fluid.plane = MOB_PLANE + fluid.layer = MOB_LAYER+0.1 //Below glass, above mob + add_overlay(tank) + update_icon() + /obj/machinery/atmospherics/unary/cryo_cell/Destroy() var/turf/T = src.loc T.contents += contents @@ -153,6 +172,7 @@ if(beaker) beaker.loc = get_step(src.loc, SOUTH) beaker = null + update_icon() if(href_list["ejectOccupant"]) if(!occupant || isslime(usr) || ispAI(usr)) @@ -172,6 +192,7 @@ user.drop_item() G.loc = src user.visible_message("[user] adds \a [G] to \the [src]!", "You add \a [G] to \the [src]!") + update_icon() else if(istype(G, /obj/item/weapon/grab)) var/obj/item/weapon/grab/grab = G if(!ismob(grab.affecting)) @@ -191,40 +212,23 @@ put_mob(target) /obj/machinery/atmospherics/unary/cryo_cell/update_icon() - overlays.Cut() - icon_state = "pod[on]" - var/image/I - - I = image(icon, "pod[on]_top") - I.layer = 5 // this needs to be fairly high so it displays over most things, but it needs to be under lighting (at 10) - I.pixel_z = 32 - overlays += I - - if(occupant) - var/image/pickle = image(occupant.icon, occupant.icon_state) - pickle.overlays = occupant.overlays - pickle.pixel_z = 18 - pickle.layer = 5 - overlays += pickle - - I = image(icon, "lid[on]") - I.layer = 5 - overlays += I - - I = image(icon, "lid[on]_top") - I.layer = 5 - I.pixel_z = 32 - overlays += I + cut_overlay(fluid) + fluid.color = null + if(on) + if(beaker) + fluid.color = beaker.reagents.get_color() + add_overlay(fluid) /obj/machinery/atmospherics/unary/cryo_cell/proc/process_occupant() if(air_contents.total_moles < 10) return if(occupant) - if(occupant.stat == 2) + if(occupant.stat >= DEAD) return occupant.bodytemperature += 2*(air_contents.temperature - occupant.bodytemperature)*current_heat_capacity/(current_heat_capacity + air_contents.heat_capacity()) occupant.bodytemperature = max(occupant.bodytemperature, air_contents.temperature) // this is so ugly i'm sorry for doing it i'll fix it later i promise - occupant.stat = 1 + occupant.stat = UNCONSCIOUS + occupant.dir = SOUTH if(occupant.bodytemperature < T0C) occupant.sleeping = max(5, (1/occupant.bodytemperature)*2000) occupant.Paralyse(max(5, (1/occupant.bodytemperature)*3000)) @@ -273,14 +277,16 @@ if(occupant.client) occupant.client.eye = occupant.client.mob occupant.client.perspective = MOB_PERSPECTIVE + vis_contents -= occupant + occupant.pixel_x = occupant.default_pixel_x + occupant.pixel_y = occupant.default_pixel_y occupant.loc = get_step(src.loc, SOUTH) //this doesn't account for walls or anything, but i don't forsee that being a problem. if(occupant.bodytemperature < 261 && occupant.bodytemperature >= 70) //Patch by Aranclanos to stop people from taking burn damage after being ejected occupant.bodytemperature = 261 // Changed to 70 from 140 by Zuhayr due to reoccurance of bug. -// occupant.metabslow = 0 + unbuckle_mob(occupant, force = TRUE) occupant = null current_heat_capacity = initial(current_heat_capacity) update_use_power(1) - update_icon() return /obj/machinery/atmospherics/unary/cryo_cell/proc/put_mob(mob/living/carbon/M as mob) if(stat & (NOPOWER|BROKEN)) @@ -307,6 +313,9 @@ if(M.health > -100 && (M.health < 0 || M.sleeping)) M << "You feel a cold liquid surround you. Your skin starts to freeze up." occupant = M + buckle_mob(occupant, forced = TRUE, check_loc = FALSE) + vis_contents |= occupant + occupant.pixel_y += 19 current_heat_capacity = HEAT_CAPACITY_HUMAN update_use_power(2) // M.metabslow = 1 diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 11e9f0f94f..5d6d7abdcc 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -27,6 +27,13 @@ var/storage_name = "Cryogenic Oversight Control" var/allow_items = 1 +/obj/machinery/computer/cryopod/update_icon() + ..() + if((stat & NOPOWER) || (stat & BROKEN)) + icon_state = "[initial(icon_state)]-p" + else + icon_state = initial(icon_state) + /obj/machinery/computer/cryopod/robot name = "robotic storage console" desc = "An interface between crew and the robotic storage systems" @@ -41,8 +48,6 @@ /obj/machinery/computer/cryopod/dorms name = "residential oversight console" desc = "An interface between visitors and the residential oversight systems tasked with keeping track of all visitors in the deeper section of the colony." - icon = 'icons/obj/robot_storage.dmi' //placeholder - icon_state = "console" //placeholder circuit = "/obj/item/weapon/circuitboard/robotstoragecontrol" storage_type = "visitors" @@ -52,8 +57,6 @@ /obj/machinery/computer/cryopod/travel name = "docking oversight console" desc = "An interface between visitors and the docking oversight systems tasked with keeping track of all visitors who enter or exit from the docks." - icon = 'icons/obj/robot_storage.dmi' //placeholder - icon_state = "console" //placeholder circuit = "/obj/item/weapon/circuitboard/robotstoragecontrol" storage_type = "visitors" @@ -63,8 +66,6 @@ /obj/machinery/computer/cryopod/gateway name = "gateway oversight console" desc = "An interface between visitors and the gateway oversight systems tasked with keeping track of all visitors who enter or exit from the gateway." - icon = 'icons/obj/robot_storage.dmi' //placeholder - icon_state = "console" //placeholder circuit = "/obj/item/weapon/circuitboard/robotstoragecontrol" storage_type = "visitors" @@ -304,13 +305,18 @@ find_control_computer() /obj/machinery/cryopod/proc/find_control_computer(urgent=0) - //control_computer = locate(/obj/machinery/computer/cryopod) in src.loc.loc // Broken due to http://www.byond.com/forum/?post=2007448 - control_computer = locate(/obj/machinery/computer/cryopod) in range(6,src) + control_computer = null + + var/area/my_area = get_area(src) + control_computer = locate(/obj/machinery/computer/cryopod) in my_area + + if(!control_computer) //Fallback to old method. + control_computer = locate(/obj/machinery/computer/cryopod) in range(6,src) // Don't send messages unless we *need* the computer, and less than five minutes have passed since last time we messaged - if(!control_computer && urgent && last_no_computer_message + 5*60*10 < world.time) - log_admin("Cryopod in [src.loc.loc] could not find control computer!") - message_admins("Cryopod in [src.loc.loc] could not find control computer!") + if(!control_computer && urgent && last_no_computer_message + 5 MINUTES < world.time) + log_admin("Cryopod in [my_area] could not find control computer!") + message_admins("Cryopod in [my_area] could not find control computer!") last_no_computer_message = world.time return control_computer != null diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 7f140b4b7f..2d40396d91 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -415,6 +415,8 @@ desc = "It's an extra resilient airlock intended for spacefaring vessels." icon = 'icons/obj/doors/shuttledoors.dmi' explosion_resistance = 20 + opacity = 0 + glass = 1 assembly_type = /obj/structure/door_assembly/door_assembly_voidcraft // Airlock opens from top-bottom instead of left-right. @@ -565,7 +567,7 @@ About the new airlock wires panel: else if(duration) //electrify door for the given duration seconds if(usr) shockedby += text("\[[time_stamp()]\] - [usr](ckey:[usr.ckey])") - usr.attack_log += text("\[[time_stamp()]\] Electrified the [name] at [x] [y] [z]") + add_attack_logs(usr,name,"Electrified a door") else shockedby += text("\[[time_stamp()]\] - EMP)") message = "The door is now electrified [duration == -1 ? "permanently" : "for [duration] second\s"]." diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index b22dc27dba..5cded75805 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -218,6 +218,8 @@ /obj/machinery/door/firedoor/attackby(obj/item/weapon/C as obj, mob/user as mob) add_fingerprint(user) + if(istype(C, /obj/item/taperoll)) + return //Don't open the door if we're putting tape on it to tell people 'don't open the door'. if(operating) return//Already doing something. if(istype(C, /obj/item/weapon/weldingtool) && !repairing) diff --git a/code/game/machinery/holosign.dm b/code/game/machinery/holosign.dm index 215238a80b..39a91b8aff 100644 --- a/code/game/machinery/holosign.dm +++ b/code/game/machinery/holosign.dm @@ -4,7 +4,7 @@ desc = "Small wall-mounted holographic projector" icon = 'icons/obj/holosign.dmi' icon_state = "sign_off" - layer = 4 + plane = MOB_PLANE use_power = 1 idle_power_usage = 2 active_power_usage = 4 diff --git a/code/game/machinery/kitchen/cooking_machines/fryer.dm b/code/game/machinery/kitchen/cooking_machines/fryer.dm index 1fc0e75ef1..451f84c2ff 100644 --- a/code/game/machinery/kitchen/cooking_machines/fryer.dm +++ b/code/game/machinery/kitchen/cooking_machines/fryer.dm @@ -36,7 +36,7 @@ if(H.species.flags & NO_PAIN) nopain = 2 E = H.get_organ(user.zone_sel.selecting) - if(E.status & ORGAN_ROBOT) + if(E.robotic >= ORGAN_ROBOT) nopain = 1 user.visible_message("\The [user] shoves \the [victim][E ? "'s [E.name]" : ""] into \the [src]!") @@ -45,7 +45,7 @@ E.take_damage(0, rand(20,30)) if(E.children && E.children.len) for(var/obj/item/organ/external/child in E.children) - if(nopain && nopain < 2 && !(child.status & ORGAN_ROBOT)) + if(nopain && nopain < 2 && !(child.robotic >= ORGAN_ROBOT)) nopain = 0 child.take_damage(0, rand(20,30)) else @@ -58,9 +58,7 @@ victim << "Searing hot oil scorches your [E ? E.name : "flesh"]!" if(victim.client) - user.attack_log += text("\[[time_stamp()]\] Has [cook_type] \the [victim] ([victim.ckey]) in \a [src]") - victim.attack_log += text("\[[time_stamp()]\] Has been [cook_type] in \a [src] by [user.name] ([user.ckey])") - msg_admin_attack("[user] ([user.ckey]) [cook_type] \the [victim] ([victim.ckey]) in \a [src]. (JMP)") + add_attack_logs(user,victim,"[cook_type] in [src]") icon_state = off_icon cooking = 0 diff --git a/code/game/machinery/kitchen/gibber.dm b/code/game/machinery/kitchen/gibber.dm index 9b6b503237..d695253aa9 100644 --- a/code/game/machinery/kitchen/gibber.dm +++ b/code/game/machinery/kitchen/gibber.dm @@ -211,9 +211,7 @@ if(src.occupant.reagents) src.occupant.reagents.trans_to_obj(new_meat, round(occupant.reagents.total_volume/slab_count,1)) - src.occupant.attack_log += "\[[time_stamp()]\] Was gibbed by [user]/[user.ckey]" //One shall not simply gib a mob unnoticed! - user.attack_log += "\[[time_stamp()]\] Gibbed [src.occupant]/[src.occupant.ckey]" - msg_admin_attack("[user.name] ([user.ckey]) gibbed [src.occupant] ([src.occupant.ckey]) (JMP)") + add_attack_logs(user,occupant,"Used [src] to gib") src.occupant.ghostize() @@ -225,13 +223,12 @@ playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) operating = 0 - for (var/obj/thing in contents) - // Todo: unify limbs and internal organs + for (var/obj/item/thing in contents) // There's a chance that the gibber will fail to destroy some evidence. - if((istype(thing,/obj/item/organ) || istype(thing,/obj/item/organ)) && prob(80)) + if(istype(thing,/obj/item/organ) && prob(80)) qdel(thing) continue - thing.loc = get_turf(thing) // Drop it onto the turf for throwing. + thing.forceMove(get_turf(thing)) // Drop it onto the turf for throwing. thing.throw_at(get_edge_target_turf(src,gib_throw_dir),rand(0,3),emagged ? 100 : 50) // Being pelted with bits of meat and bone would hurt. update_icon() diff --git a/code/game/machinery/kitchen/icecream.dm b/code/game/machinery/kitchen/icecream.dm index fab6319e26..09cb3289ed 100644 --- a/code/game/machinery/kitchen/icecream.dm +++ b/code/game/machinery/kitchen/icecream.dm @@ -172,7 +172,6 @@ name = "ice cream cone" desc = "Delicious waffle cone, but no ice cream." icon_state = "icecream_cone_waffle" //default for admin-spawned cones, href_list["cone"] should overwrite this all the time - layer = 3.1 bitesize = 3 var/ice_creamed = 0 diff --git a/code/game/machinery/kitchen/microwave.dm b/code/game/machinery/kitchen/microwave.dm index fa81ff1620..3da253e682 100644 --- a/code/game/machinery/kitchen/microwave.dm +++ b/code/game/machinery/kitchen/microwave.dm @@ -2,7 +2,6 @@ name = "microwave" icon = 'icons/obj/kitchen.dmi' icon_state = "mw" - layer = 2.9 density = 1 anchored = 1 use_power = 1 diff --git a/code/game/machinery/kitchen/smartfridge.dm b/code/game/machinery/kitchen/smartfridge.dm index a2f5c00ad1..b2c3d21b68 100644 --- a/code/game/machinery/kitchen/smartfridge.dm +++ b/code/game/machinery/kitchen/smartfridge.dm @@ -4,7 +4,6 @@ name = "\improper SmartFridge" icon = 'icons/obj/vending.dmi' icon_state = "smartfridge" - layer = 2.9 density = 1 anchored = 1 use_power = 1 diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 673e366313..874f8876b9 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -97,6 +97,7 @@ Class Procs: name = "machinery" icon = 'icons/obj/stationobjs.dmi' w_class = ITEMSIZE_NO_CONTAINER + layer = UNDER_JUNK_LAYER var/stat = 0 var/emagged = 0 diff --git a/code/game/machinery/magnet.dm b/code/game/machinery/magnet.dm index af61e93424..8022235736 100644 --- a/code/game/machinery/magnet.dm +++ b/code/game/machinery/magnet.dm @@ -9,8 +9,7 @@ icon_state = "floor_magnet-f" name = "Electromagnetic Generator" desc = "A device that uses station power to create points of magnetic energy." - level = 1 // underfloor - layer = 2.5 + plane = PLATING_PLANE anchored = 1 use_power = 1 idle_power_usage = 50 diff --git a/code/game/machinery/navbeacon.dm b/code/game/machinery/navbeacon.dm index ac0af16378..7e472c8eca 100644 --- a/code/game/machinery/navbeacon.dm +++ b/code/game/machinery/navbeacon.dm @@ -8,8 +8,7 @@ var/global/list/navbeacons = list() // no I don't like putting this in, but it w icon_state = "navbeacon0-f" name = "navigation beacon" desc = "A beacon used for bot navigation." - level = 1 // underfloor - layer = 2.5 + plane = PLATING_PLANE anchored = 1 var/open = 0 // true if cover is open var/locked = 1 // true if controls are locked diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm index 5ce605afcc..b9bd4a6855 100644 --- a/code/game/machinery/newscaster.dm +++ b/code/game/machinery/newscaster.dm @@ -935,20 +935,11 @@ obj/item/weapon/newspaper/attackby(obj/item/weapon/W as obj, mob/user as mob) /obj/machinery/newscaster/proc/scan_user(mob/living/user as mob) if(istype(user,/mob/living/carbon/human)) //User is a human var/mob/living/carbon/human/human_user = user - if(human_user.wear_id) //Newscaster scans you - if(istype(human_user.wear_id, /obj/item/device/pda)) //autorecognition, woo! - var/obj/item/device/pda/P = human_user.wear_id - if(P.id) - scanned_user = GetNameAndAssignmentFromId(P.id) - else - scanned_user = "Unknown" - else if(istype(human_user.wear_id, /obj/item/weapon/card/id)) - var/obj/item/weapon/card/id/ID = human_user.wear_id - scanned_user = GetNameAndAssignmentFromId(ID) - else - scanned_user ="Unknown" + var/obj/item/weapon/card/id/I = human_user.GetIdCard() + if(I) + scanned_user = GetNameAndAssignmentFromId(I) else - scanned_user ="Unknown" + scanned_user = "Unknown" else var/mob/living/silicon/ai_user = user scanned_user = "[ai_user.name] ([ai_user.job])" diff --git a/code/game/machinery/overview.dm b/code/game/machinery/overview.dm index 48bd028c09..0ec65cc30d 100644 --- a/code/game/machinery/overview.dm +++ b/code/game/machinery/overview.dm @@ -168,7 +168,7 @@ qdel(I) qdel(J) H.icon = HI - H.layer = 25 + H.hud_layerise() usr.mapobjs += H #else @@ -287,7 +287,7 @@ H.icon = I qdel(I) - H.layer = 25 + H.hud_layerise() usr.mapobjs += H #endif diff --git a/code/game/machinery/oxygen_pump.dm b/code/game/machinery/oxygen_pump.dm new file mode 100644 index 0000000000..36db3f83f3 --- /dev/null +++ b/code/game/machinery/oxygen_pump.dm @@ -0,0 +1,241 @@ +#define TANK_MAX_RELEASE_PRESSURE (3*ONE_ATMOSPHERE) +#define TANK_DEFAULT_RELEASE_PRESSURE ONE_ATMOSPHERE + +/obj/machinery/oxygen_pump + name = "emergency oxygen pump" + icon = 'icons/obj/walllocker.dmi' + desc = "A wall mounted oxygen pump with a retractable face mask that you can pull over your face in case of emergencies." + icon_state = "oxygen_tank" + + anchored = TRUE + + var/obj/item/weapon/tank/tank + var/mob/living/carbon/breather + var/obj/item/clothing/mask/breath/contained + + var/spawn_type = /obj/item/weapon/tank/emergency/oxygen/engi + var/mask_type = /obj/item/clothing/mask/breath/emergency + var/icon_state_open = "oxygen_tank_open" + var/icon_state_closed = "oxygen_tank" + + power_channel = ENVIRON + idle_power_usage = 10 + active_power_usage = 120 // No idea what the realistic amount would be. + +/obj/machinery/oxygen_pump/initialize() + . = ..() + tank = new spawn_type (src) + contained = new mask_type (src) + +/obj/machinery/oxygen_pump/Destroy() + if(breather) + breather.internal = null + if(breather.internals) + breather.internals.icon_state = "internal0" + breather.remove_from_mob(contained) + visible_message("The mask rapidly retracts just before /the [src] is destroyed!") + breather = null + + qdel_null(tank) + qdel_null(contained) + return ..() + +/obj/machinery/oxygen_pump/MouseDrop(var/mob/living/carbon/human/target, src_location, over_location) + ..() + if(istype(target) && CanMouseDrop(target)) + if(!can_apply_to_target(target, usr)) // There is no point in attempting to apply a mask if it's impossible. + return + usr.visible_message("\The [usr] begins placing the mask onto [target]..") + if(!do_mob(usr, target, 25) || !can_apply_to_target(target, usr)) + return + // place mask and add fingerprints + usr.visible_message("\The [usr] has placed \the mask on [target]'s mouth.") + attach_mask(target) + src.add_fingerprint(usr) + +/obj/machinery/oxygen_pump/attack_hand(mob/user as mob) + if((stat & MAINT) && tank) + user.visible_message("\The [user] removes \the [tank] from \the [src].", "You remove \the [tank] from \the [src].") + user.put_in_hands(tank) + src.add_fingerprint(user) + tank.add_fingerprint(user) + tank = null + return + if (!tank) + to_chat(user, "There is no tank in \the [src]!") + return + if(breather) + if(tank) + tank.forceMove(src) + breather.remove_from_mob(contained) + contained.forceMove(src) + src.visible_message("\The [user] makes \The [contained] rapidly retracts back into \the [src]!") + if(breather.internals) + breather.internals.icon_state = "internal0" + breather = null + use_power = 1 + +/obj/machinery/oxygen_pump/attack_ai(mob/user as mob) + ui_interact(user) + +/obj/machinery/oxygen_pump/proc/attach_mask(var/mob/living/carbon/C) + if(C && istype(C)) + contained.forceMove(get_turf(C)) + C.equip_to_slot(contained, slot_wear_mask) + if(tank) + tank.forceMove(C) + breather = C + spawn(1) + if(!breather.internal && tank) + breather.internal = tank + if(breather.internals) + breather.internals.icon_state = "internal1" + use_power = 2 + +/obj/machinery/oxygen_pump/proc/can_apply_to_target(var/mob/living/carbon/human/target, mob/user as mob) + if(!user) + user = target + // Check target validity + if(!target.organs_by_name[BP_HEAD]) + to_chat(user, "\The [target] doesn't have a head.") + return + if(!target.check_has_mouth()) + to_chat(user, "\The [target] doesn't have a mouth.") + return + if(target.wear_mask && target != breather) + to_chat(user, "\The [target] is already wearing a mask.") + return + if(target.head && (target.head.body_parts_covered & FACE)) + to_chat(user, "Remove their [target.head] first.") + return + if(!tank) + to_chat(user, "There is no tank in \the [src].") + return + if(stat & MAINT) + to_chat(user, "Please close \the maintenance hatch first.") + return + if(!Adjacent(target)) + to_chat(user, "Please stay close to \the [src].") + return + //when there is a breather: + if(breather && target != breather) + to_chat(user, "\The pump is already in use.") + return + //Checking if breather is still valid + if(target == breather && target.wear_mask != contained) + to_chat(user, "\The [target] is not using the supplied mask.") + return + return 1 + +/obj/machinery/oxygen_pump/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W,/obj/item/weapon/screwdriver)) + stat ^= MAINT + user.visible_message("\The [user] [stat & MAINT ? "opens" : "closes"] \the [src].", "You [stat & MAINT ? "open" : "close"] \the [src].") + if(stat & MAINT) + icon_state = icon_state_open + if(!stat) + icon_state = icon_state_closed + //TO-DO: Open icon + if(istype(W, /obj/item/weapon/tank) && (stat & MAINT)) + if(tank) + to_chat(user, "\The [src] already has a tank installed!") + else + user.drop_item() + W.forceMove(src) + tank = W + user.visible_message("\The [user] installs \the [tank] into \the [src].", "You install \the [tank] into \the [src].") + src.add_fingerprint(user) + if(istype(W, /obj/item/weapon/tank) && !stat) + to_chat(user, "Please open the maintenance hatch first.") + +/obj/machinery/oxygen_pump/examine(var/mob/user) + . = ..() + if(tank) + to_chat(user, "The meter shows [round(tank.air_contents.return_pressure())]") + else + to_chat(user, "It is missing a tank!") + + +/obj/machinery/oxygen_pump/process() + if(breather) + if(!can_apply_to_target(breather)) + if(tank) + tank.forceMove(src) + breather.remove_from_mob(contained) + contained.forceMove(src) + src.visible_message("\The [contained] rapidly retracts back into \the [src]!") + breather = null + use_power = 1 + else if(!breather.internal && tank) + breather.internal = tank + if(breather.internals) + breather.internals.icon_state = "internal0" + +//Create rightclick to view tank settings +/obj/machinery/oxygen_pump/verb/settings() + set src in oview(1) + set category = "Object" + set name = "Show Tank Settings" + ui_interact(usr) + +//GUI Tank Setup +/obj/machinery/oxygen_pump/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + var/data[0] + if(!tank) + to_chat(usr, "It is missing a tank!") + data["tankPressure"] = 0 + data["releasePressure"] = 0 + data["defaultReleasePressure"] = 0 + data["maxReleasePressure"] = 0 + data["maskConnected"] = 0 + data["tankInstalled"] = 0 + // this is the data which will be sent to the ui + if(tank) + data["tankPressure"] = round(tank.air_contents.return_pressure() ? tank.air_contents.return_pressure() : 0) + data["releasePressure"] = round(tank.distribute_pressure ? tank.distribute_pressure : 0) + data["defaultReleasePressure"] = round(TANK_DEFAULT_RELEASE_PRESSURE) + data["maxReleasePressure"] = round(TANK_MAX_RELEASE_PRESSURE) + data["maskConnected"] = 0 + data["tankInstalled"] = 1 + + if(!breather) + data["maskConnected"] = 0 + if(breather) + data["maskConnected"] = 1 + + + // update the ui if it exists, returns null if no ui is passed/found + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + // the ui does not exist, so we'll create a new() one + // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm + ui = new(user, src, ui_key, "Oxygen_pump.tmpl", "Tank", 500, 300) + // when the ui is first opened this is the data it will use + ui.set_initial_data(data) + // open the new ui window + ui.open() + // auto update every Master Controller tick + ui.set_auto_update(1) + +/obj/machinery/oxygen_pump/Topic(href, href_list) + if(..()) + return 1 + + if (href_list["dist_p"]) + if (href_list["dist_p"] == "reset") + tank.distribute_pressure = TANK_DEFAULT_RELEASE_PRESSURE + else if (href_list["dist_p"] == "max") + tank.distribute_pressure = TANK_MAX_RELEASE_PRESSURE + else + var/cp = text2num(href_list["dist_p"]) + tank.distribute_pressure += cp + tank.distribute_pressure = min(max(round(tank.distribute_pressure), 0), TANK_MAX_RELEASE_PRESSURE) + return 1 + +/obj/machinery/oxygen_pump/anesthetic + name = "anesthetic pump" + spawn_type = /obj/item/weapon/tank/anesthetic + icon_state = "anesthetic_tank" + icon_state_closed = "anesthetic_tank" + icon_state_open = "anesthetic_tank_open" + mask_type = /obj/item/clothing/mask/breath/anesthetic diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm index ec0f8a027c..ca09d3de58 100644 --- a/code/game/machinery/pipe/construction.dm +++ b/code/game/machinery/pipe/construction.dm @@ -2,1317 +2,281 @@ Buildable pipes Buildable meters */ -#define PIPE_SIMPLE_STRAIGHT 0 -#define PIPE_SIMPLE_BENT 1 -#define PIPE_HE_STRAIGHT 2 -#define PIPE_HE_BENT 3 -#define PIPE_CONNECTOR 4 -#define PIPE_MANIFOLD 5 -#define PIPE_JUNCTION 6 -#define PIPE_UVENT 7 -#define PIPE_MVALVE 8 -#define PIPE_PUMP 9 -#define PIPE_SCRUBBER 10 -#define PIPE_INSULATED_STRAIGHT 11 -#define PIPE_INSULATED_BENT 12 -#define PIPE_GAS_FILTER 13 -#define PIPE_GAS_MIXER 14 -#define PIPE_PASSIVE_GATE 15 -#define PIPE_VOLUME_PUMP 16 -#define PIPE_HEAT_EXCHANGE 17 -#define PIPE_MTVALVE 18 -#define PIPE_MANIFOLD4W 19 -#define PIPE_CAP 20 -///// Z-Level stuff -#define PIPE_UP 21 -#define PIPE_DOWN 22 -///// Z-Level stuff -#define PIPE_GAS_FILTER_M 23 -#define PIPE_GAS_MIXER_T 24 -#define PIPE_GAS_MIXER_M 25 -#define PIPE_OMNI_MIXER 26 -#define PIPE_OMNI_FILTER 27 -///// Supply, scrubbers and universal pipes -#define PIPE_UNIVERSAL 28 -#define PIPE_SUPPLY_STRAIGHT 29 -#define PIPE_SUPPLY_BENT 30 -#define PIPE_SCRUBBERS_STRAIGHT 31 -#define PIPE_SCRUBBERS_BENT 32 -#define PIPE_SUPPLY_MANIFOLD 33 -#define PIPE_SCRUBBERS_MANIFOLD 34 -#define PIPE_SUPPLY_MANIFOLD4W 35 -#define PIPE_SCRUBBERS_MANIFOLD4W 36 -#define PIPE_SUPPLY_UP 37 -#define PIPE_SCRUBBERS_UP 38 -#define PIPE_SUPPLY_DOWN 39 -#define PIPE_SCRUBBERS_DOWN 40 -#define PIPE_SUPPLY_CAP 41 -#define PIPE_SCRUBBERS_CAP 42 -///// Mirrored T-valve ~ because I couldn't be bothered re-sorting all of the defines -#define PIPE_MTVALVEM 43 -///// Digital Valves sit here because otherwise we're resorting every define. -#define PIPE_DVALVE 44 -#define PIPE_DTVALVE 45 -#define PIPE_DTVALVEM 46 - -#define PIPE_PASSIVE_VENT 47 /obj/item/pipe name = "pipe" - desc = "A pipe" - var/pipe_type = 0 - //var/pipe_dir = 0 + desc = "A pipe." + var/pipe_type var/pipename - var/connect_types = CONNECT_TYPE_REGULAR force = 7 + throwforce = 7 icon = 'icons/obj/pipe-item.dmi' icon_state = "simple" item_state = "buildpipe" w_class = ITEMSIZE_NORMAL level = 2 + var/piping_layer = PIPING_LAYER_DEFAULT + var/dispenser_class // Tells the dispenser what orientations we support, so RPD can show previews. -/obj/item/pipe/New(var/loc, var/pipe_type as num, var/dir as num, var/obj/machinery/atmospherics/make_from = null) - ..() - if (make_from) - src.set_dir(make_from.dir) - src.pipename = make_from.name - if(make_from.req_access) - src.req_access = make_from.req_access - if(make_from.req_one_access) - src.req_one_access = make_from.req_one_access - color = make_from.pipe_color - var/is_bent - if (make_from.initialize_directions in list(NORTH|SOUTH, WEST|EAST)) - is_bent = 0 - else - is_bent = 1 - if (istype(make_from, /obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction)) - src.pipe_type = PIPE_JUNCTION - connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_HE - else if(istype(make_from, /obj/machinery/atmospherics/pipe/simple/heat_exchanging)) - src.pipe_type = PIPE_HE_STRAIGHT + is_bent - connect_types = CONNECT_TYPE_HE - else if(istype(make_from, /obj/machinery/atmospherics/pipe/simple/insulated)) - src.pipe_type = PIPE_INSULATED_STRAIGHT + is_bent - else if(istype(make_from, /obj/machinery/atmospherics/pipe/simple/visible/supply) || istype(make_from, /obj/machinery/atmospherics/pipe/simple/hidden/supply)) - src.pipe_type = PIPE_SUPPLY_STRAIGHT + is_bent - connect_types = CONNECT_TYPE_SUPPLY - src.color = PIPE_COLOR_BLUE - else if(istype(make_from, /obj/machinery/atmospherics/pipe/simple/visible/scrubbers) || istype(make_from, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers)) - src.pipe_type = PIPE_SCRUBBERS_STRAIGHT + is_bent - connect_types = CONNECT_TYPE_SCRUBBER - src.color = PIPE_COLOR_RED - else if(istype(make_from, /obj/machinery/atmospherics/pipe/simple/visible/universal) || istype(make_from, /obj/machinery/atmospherics/pipe/simple/hidden/universal)) - src.pipe_type = PIPE_UNIVERSAL - connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SUPPLY|CONNECT_TYPE_SCRUBBER - else if(istype(make_from, /obj/machinery/atmospherics/pipe/simple)) - src.pipe_type = PIPE_SIMPLE_STRAIGHT + is_bent - else if(istype(make_from, /obj/machinery/atmospherics/portables_connector)) - src.pipe_type = PIPE_CONNECTOR - else if(istype(make_from, /obj/machinery/atmospherics/pipe/manifold/visible/supply) || istype(make_from, /obj/machinery/atmospherics/pipe/manifold/hidden/supply)) - src.pipe_type = PIPE_SUPPLY_MANIFOLD - connect_types = CONNECT_TYPE_SUPPLY - src.color = PIPE_COLOR_BLUE - else if(istype(make_from, /obj/machinery/atmospherics/pipe/manifold/visible/scrubbers) || istype(make_from, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers)) - src.pipe_type = PIPE_SCRUBBERS_MANIFOLD - connect_types = CONNECT_TYPE_SCRUBBER - src.color = PIPE_COLOR_RED - else if(istype(make_from, /obj/machinery/atmospherics/pipe/manifold)) - src.pipe_type = PIPE_MANIFOLD - else if(istype(make_from, /obj/machinery/atmospherics/unary/vent_pump)) - src.pipe_type = PIPE_UVENT - else if(istype(make_from, /obj/machinery/atmospherics/valve/digital)) - src.pipe_type = PIPE_DVALVE - else if(istype(make_from, /obj/machinery/atmospherics/valve)) - src.pipe_type = PIPE_MVALVE - else if(istype(make_from, /obj/machinery/atmospherics/binary/pump/high_power)) - src.pipe_type = PIPE_VOLUME_PUMP - else if(istype(make_from, /obj/machinery/atmospherics/binary/pump)) - src.pipe_type = PIPE_PUMP - else if(istype(make_from, /obj/machinery/atmospherics/trinary/atmos_filter/m_filter)) - src.pipe_type = PIPE_GAS_FILTER_M - else if(istype(make_from, /obj/machinery/atmospherics/trinary/mixer/t_mixer)) - src.pipe_type = PIPE_GAS_MIXER_T - else if(istype(make_from, /obj/machinery/atmospherics/trinary/mixer/m_mixer)) - src.pipe_type = PIPE_GAS_MIXER_M - else if(istype(make_from, /obj/machinery/atmospherics/trinary/atmos_filter)) - src.pipe_type = PIPE_GAS_FILTER - else if(istype(make_from, /obj/machinery/atmospherics/trinary/mixer)) - src.pipe_type = PIPE_GAS_MIXER - else if(istype(make_from, /obj/machinery/atmospherics/unary/vent_scrubber)) - src.pipe_type = PIPE_SCRUBBER - else if(istype(make_from, /obj/machinery/atmospherics/binary/passive_gate)) - src.pipe_type = PIPE_PASSIVE_GATE - else if(istype(make_from, /obj/machinery/atmospherics/unary/heat_exchanger)) - src.pipe_type = PIPE_HEAT_EXCHANGE - else if(istype(make_from, /obj/machinery/atmospherics/tvalve/mirrored/digital)) - src.pipe_type = PIPE_DTVALVEM - else if(istype(make_from, /obj/machinery/atmospherics/tvalve/mirrored)) - src.pipe_type = PIPE_MTVALVEM - else if(istype(make_from, /obj/machinery/atmospherics/tvalve/digital)) - src.pipe_type = PIPE_DTVALVE - else if(istype(make_from, /obj/machinery/atmospherics/tvalve)) - src.pipe_type = PIPE_MTVALVE - else if(istype(make_from, /obj/machinery/atmospherics/pipe/manifold4w/visible/supply) || istype(make_from, /obj/machinery/atmospherics/pipe/manifold4w/hidden/supply)) - src.pipe_type = PIPE_SUPPLY_MANIFOLD4W - connect_types = CONNECT_TYPE_SUPPLY - src.color = PIPE_COLOR_BLUE - else if(istype(make_from, /obj/machinery/atmospherics/pipe/manifold4w/visible/scrubbers) || istype(make_from, /obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers)) - src.pipe_type = PIPE_SCRUBBERS_MANIFOLD4W - connect_types = CONNECT_TYPE_SCRUBBER - src.color = PIPE_COLOR_RED - else if(istype(make_from, /obj/machinery/atmospherics/pipe/manifold4w)) - src.pipe_type = PIPE_MANIFOLD4W - else if(istype(make_from, /obj/machinery/atmospherics/pipe/cap/visible/supply) || istype(make_from, /obj/machinery/atmospherics/pipe/cap/hidden/supply)) - src.pipe_type = PIPE_SUPPLY_CAP - connect_types = CONNECT_TYPE_SUPPLY - src.color = PIPE_COLOR_BLUE - else if(istype(make_from, /obj/machinery/atmospherics/pipe/cap/visible/scrubbers) || istype(make_from, /obj/machinery/atmospherics/pipe/cap/hidden/scrubbers)) - src.pipe_type = PIPE_SCRUBBERS_CAP - connect_types = CONNECT_TYPE_SCRUBBER - src.color = PIPE_COLOR_RED - else if(istype(make_from, /obj/machinery/atmospherics/pipe/cap)) - src.pipe_type = PIPE_CAP - else if(istype(make_from, /obj/machinery/atmospherics/omni/mixer)) - src.pipe_type = PIPE_OMNI_MIXER - else if(istype(make_from, /obj/machinery/atmospherics/omni/atmos_filter)) - src.pipe_type = PIPE_OMNI_FILTER -///// Z-Level stuff - else if(istype(make_from, /obj/machinery/atmospherics/pipe/zpipe/up/supply)) - src.pipe_type = PIPE_SUPPLY_UP - connect_types = CONNECT_TYPE_SUPPLY - src.color = PIPE_COLOR_BLUE - else if(istype(make_from, /obj/machinery/atmospherics/pipe/zpipe/up/scrubbers)) - src.pipe_type = PIPE_SCRUBBERS_UP - connect_types = CONNECT_TYPE_SCRUBBER - src.color = PIPE_COLOR_RED - else if(istype(make_from, /obj/machinery/atmospherics/pipe/zpipe/up)) - src.pipe_type = PIPE_UP - else if(istype(make_from, /obj/machinery/atmospherics/pipe/zpipe/down/supply)) - src.pipe_type = PIPE_SUPPLY_DOWN - connect_types = CONNECT_TYPE_SUPPLY - src.color = PIPE_COLOR_BLUE - else if(istype(make_from, /obj/machinery/atmospherics/pipe/zpipe/down/scrubbers)) - src.pipe_type = PIPE_SCRUBBERS_DOWN - connect_types = CONNECT_TYPE_SCRUBBER - src.color = PIPE_COLOR_RED - else if(istype(make_from, /obj/machinery/atmospherics/pipe/zpipe/down)) - src.pipe_type = PIPE_DOWN -///// Z-Level stuff - else if(istype(make_from, /obj/machinery/atmospherics/pipe/vent)) - src.pipe_type = PIPE_PASSIVE_VENT +// One subtype for each way components connect to neighbors +/obj/item/pipe/directional + dispenser_class = PIPE_DIRECTIONAL +/obj/item/pipe/binary + dispenser_class = PIPE_STRAIGHT +/obj/item/pipe/binary/bendable + dispenser_class = PIPE_BENDABLE +/obj/item/pipe/trinary + dispenser_class = PIPE_TRINARY +/obj/item/pipe/trinary/flippable + dispenser_class = PIPE_TRIN_M + var/mirrored = FALSE +/obj/item/pipe/quaternary + dispenser_class = PIPE_ONEDIR + +/** + * Call constructor with: + * @param loc Location + * @pipe_type + */ +/obj/item/pipe/initialize(var/mapload, var/_pipe_type, var/_dir, var/obj/machinery/atmospherics/make_from) + if(make_from) + make_from_existing(make_from) else - src.pipe_type = pipe_type - src.set_dir(dir) - if (pipe_type == 29 || pipe_type == 30 || pipe_type == 33 || pipe_type == 35 || pipe_type == 37 || pipe_type == 39 || pipe_type == 41) - connect_types = CONNECT_TYPE_SUPPLY - src.color = PIPE_COLOR_BLUE - else if (pipe_type == 31 || pipe_type == 32 || pipe_type == 34 || pipe_type == 36 || pipe_type == 38 || pipe_type == 40 || pipe_type == 42) - connect_types = CONNECT_TYPE_SCRUBBER - src.color = PIPE_COLOR_RED - else if (pipe_type == 2 || pipe_type == 3) - connect_types = CONNECT_TYPE_HE - else if (pipe_type == 6) - connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_HE - else if (pipe_type == 28) - connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SUPPLY|CONNECT_TYPE_SCRUBBER - //src.pipe_dir = get_pipe_dir() - update() - src.pixel_x = rand(-5, 5) - src.pixel_y = rand(-5, 5) + pipe_type = _pipe_type + set_dir(_dir) -//update the name and icon of the pipe item depending on the type + update() + pixel_x += rand(-5, 5) + pixel_y += rand(-5, 5) + return ..() + +/obj/item/pipe/proc/make_from_existing(obj/machinery/atmospherics/make_from) + set_dir(make_from.dir) + pipename = make_from.name + if(make_from.req_access) + src.req_access = make_from.req_access + if(make_from.req_one_access) + src.req_one_access = make_from.req_one_access + color = make_from.pipe_color + pipe_type = make_from.type + +/obj/item/pipe/trinary/flippable/make_from_existing(obj/machinery/atmospherics/trinary/make_from) + ..() + if(make_from.mirrored) + do_a_flip() + +/obj/item/pipe/dropped() + if(loc) + setPipingLayer(piping_layer) + return ..() + +/obj/item/pipe/proc/setPipingLayer(new_layer = PIPING_LAYER_DEFAULT) + var/obj/machinery/atmospherics/fakeA = pipe_type + if(initial(fakeA.pipe_flags) & (PIPING_ALL_LAYER|PIPING_DEFAULT_LAYER_ONLY)) + new_layer = PIPING_LAYER_DEFAULT + piping_layer = new_layer + // Do it the Polaris way + switch(piping_layer) + if(PIPING_LAYER_SCRUBBER) + color = PIPE_COLOR_RED + name = "[initial(fakeA.name)] scrubber fitting" + if(PIPING_LAYER_SUPPLY) + color = PIPE_COLOR_BLUE + name = "[initial(fakeA.name)] supply fitting" + // Or if we were to do it the TG way... + // pixel_x = PIPE_PIXEL_OFFSET_X(piping_layer) + // pixel_y = PIPE_PIXEL_OFFSET_Y(piping_layer) + // layer = initial(layer) + PIPE_LAYER_OFFSET(piping_layer) /obj/item/pipe/proc/update() - var/list/nlist = list( \ - "pipe", \ - "bent pipe", \ - "h/e pipe", \ - "bent h/e pipe", \ - "connector", \ - "manifold", \ - "junction", \ - "uvent", \ - "mvalve", \ - "pump", \ - "scrubber", \ - "insulated pipe", \ - "bent insulated pipe", \ - "gas filter", \ - "gas mixer", \ - "pressure regulator", \ - "high power pump", \ - "heat exchanger", \ - "t-valve", \ - "4-way manifold", \ - "pipe cap", \ -///// Z-Level stuff - "pipe up", \ - "pipe down", \ -///// Z-Level stuff - "gas filter m", \ - "gas mixer t", \ - "gas mixer m", \ - "omni mixer", \ - "omni filter", \ -///// Supply and scrubbers pipes - "universal pipe adapter", \ - "supply pipe", \ - "bent supply pipe", \ - "scrubbers pipe", \ - "bent scrubbers pipe", \ - "supply manifold", \ - "scrubbers manifold", \ - "supply 4-way manifold", \ - "scrubbers 4-way manifold", \ - "supply pipe up", \ - "scrubbers pipe up", \ - "supply pipe down", \ - "scrubbers pipe down", \ - "supply pipe cap", \ - "scrubbers pipe cap", \ - "t-valve m", \ - "dvalve", \ - "dt-valve", \ - "dt-valve m", \ - "passive vent", \ - ) - name = nlist[pipe_type+1] + " fitting" - var/list/islist = list( \ - "simple", \ - "simple", \ - "he", \ - "he", \ - "connector", \ - "manifold", \ - "junction", \ - "uvent", \ - "mvalve", \ - "pump", \ - "scrubber", \ - "insulated", \ - "insulated", \ - "filter", \ - "mixer", \ - "passivegate", \ - "volumepump", \ - "heunary", \ - "mtvalve", \ - "manifold4w", \ - "cap", \ -///// Z-Level stuff - "cap", \ - "cap", \ -///// Z-Level stuff - "m_filter", \ - "t_mixer", \ - "m_mixer", \ - "omni_mixer", \ - "omni_filter", \ -///// Supply and scrubbers pipes - "universal", \ - "simple", \ - "simple", \ - "simple", \ - "simple", \ - "manifold", \ - "manifold", \ - "manifold4w", \ - "manifold4w", \ - "cap", \ - "cap", \ - "cap", \ - "cap", \ - "cap", \ - "cap", \ - "mtvalvem", \ - "dvalve", \ - "dtvalve", \ - "dtvalvem", \ - "passive vent", \ - ) - icon_state = islist[pipe_type + 1] + var/obj/machinery/atmospherics/fakeA = pipe_type + name = "[initial(fakeA.name)] fitting" + icon_state = initial(fakeA.pipe_state) -//called when a turf is attacked with a pipe item -/obj/item/pipe/afterattack(turf/simulated/floor/target, mob/user, proximity) - if(!proximity) return - if(istype(target)) - user.drop_from_inventory(src, target) - else - return ..() +/obj/item/pipe/verb/flip() + set category = "Object" + set name = "Flip Pipe" + set src in view(1) -// rotate the pipe item clockwise + if ( usr.stat || usr.restrained() || !usr.canmove ) + return + + do_a_flip() + +/obj/item/pipe/proc/do_a_flip() + set_dir(turn(dir, -180)) + fixdir() + +/obj/item/pipe/trinary/flippable/do_a_flip() + // set_dir(turn(dir, flipped ? 45 : -45)) + // TG has a magic icon set with the flipped versions in the diagonals. + // We may switch to this later, but for now gotta do some magic. + mirrored = !mirrored + var/obj/machinery/atmospherics/fakeA = pipe_type + icon_state = "[initial(fakeA.pipe_state)][mirrored ? "m" : ""]" /obj/item/pipe/verb/rotate() set category = "Object" set name = "Rotate Pipe" set src in view(1) - if ( usr.stat || usr.restrained() ) + if ( usr.stat || usr.restrained() || !usr.canmove ) return - src.set_dir(turn(src.dir, -90)) + set_dir(turn(src.dir, -90)) // Rotate clockwise + fixdir() - if (pipe_type in list (PIPE_SIMPLE_STRAIGHT, PIPE_SUPPLY_STRAIGHT, PIPE_SCRUBBERS_STRAIGHT, PIPE_UNIVERSAL, PIPE_HE_STRAIGHT, PIPE_INSULATED_STRAIGHT, PIPE_MVALVE)) - if(dir==2) - set_dir(1) - else if(dir==8) - set_dir(4) - else if (pipe_type in list (PIPE_MANIFOLD4W, PIPE_SUPPLY_MANIFOLD4W, PIPE_SCRUBBERS_MANIFOLD4W)) - set_dir(2) - //src.pipe_set_dir(get_pipe_dir()) +// If you want to disable pipe dir changing when pulled, uncomment this +// /obj/item/pipe/Move() +// var/old_dir = dir +// . = ..() +// set_dir(old_dir) //pipes changing direction when moved is just annoying and buggy + +// Don't let pulling a pipe straighten it out. +/obj/item/pipe/binary/bendable/Move() + var/old_bent = !IS_CARDINAL(dir) + . = ..() + if(old_bent && IS_CARDINAL(dir)) + set_dir(turn(src.dir, -45)) + +//Helper to clean up dir +/obj/item/pipe/proc/fixdir() return -/obj/item/pipe/Move() - ..() - if ((pipe_type in list (PIPE_SIMPLE_BENT, PIPE_SUPPLY_BENT, PIPE_SCRUBBERS_BENT, PIPE_HE_BENT, PIPE_INSULATED_BENT)) \ - && (src.dir in cardinal)) - src.set_dir(src.dir|turn(src.dir, 90)) - else if (pipe_type in list (PIPE_SIMPLE_STRAIGHT, PIPE_SUPPLY_STRAIGHT, PIPE_SCRUBBERS_STRAIGHT, PIPE_UNIVERSAL, PIPE_HE_STRAIGHT, PIPE_INSULATED_STRAIGHT, PIPE_MVALVE)) - if(dir==2) - set_dir(1) - else if(dir==8) - set_dir(4) - return +/obj/item/pipe/binary/fixdir() + if(dir == SOUTH) + set_dir(NORTH) + else if(dir == WEST) + set_dir(EAST) -// returns all pipe's endpoints +/obj/item/pipe/trinary/flippable/fixdir() + if(dir in cornerdirs) + set_dir(turn(dir, 45)) -/obj/item/pipe/proc/get_pipe_dir() - if (!dir) - return 0 - var/flip = turn(dir, 180) - var/cw = turn(dir, -90) - var/acw = turn(dir, 90) +/obj/item/pipe/attack_self(mob/user) + set_dir(turn(dir,-90)) + fixdir() - switch(pipe_type) - if( PIPE_SIMPLE_STRAIGHT, \ - PIPE_INSULATED_STRAIGHT, \ - PIPE_HE_STRAIGHT, \ - PIPE_JUNCTION ,\ - PIPE_PUMP ,\ - PIPE_VOLUME_PUMP ,\ - PIPE_PASSIVE_GATE ,\ - PIPE_MVALVE, \ - PIPE_SUPPLY_STRAIGHT, \ - PIPE_SCRUBBERS_STRAIGHT, \ - PIPE_UNIVERSAL, \ - PIPE_DVALVE, \ - ) - return dir|flip - if(PIPE_SIMPLE_BENT, PIPE_INSULATED_BENT, PIPE_HE_BENT, PIPE_SUPPLY_BENT, PIPE_SCRUBBERS_BENT) - return dir //dir|acw - if(PIPE_CONNECTOR,PIPE_UVENT,PIPE_SCRUBBER,PIPE_HEAT_EXCHANGE) - return dir - if(PIPE_MANIFOLD4W, PIPE_SUPPLY_MANIFOLD4W, PIPE_SCRUBBERS_MANIFOLD4W, PIPE_OMNI_MIXER, PIPE_OMNI_FILTER) - return dir|flip|cw|acw - if(PIPE_MANIFOLD, PIPE_SUPPLY_MANIFOLD, PIPE_SCRUBBERS_MANIFOLD) - return flip|cw|acw - if(PIPE_GAS_FILTER, PIPE_GAS_MIXER, PIPE_MTVALVE, PIPE_DTVALVE) - return dir|flip|cw - if(PIPE_GAS_FILTER_M, PIPE_GAS_MIXER_M, PIPE_MTVALVEM, PIPE_DTVALVEM) - return dir|flip|acw - if(PIPE_GAS_MIXER_T) - return dir|cw|acw - if(PIPE_CAP, PIPE_SUPPLY_CAP, PIPE_SCRUBBERS_CAP) - return dir -///// Z-Level stuff - if(PIPE_UP,PIPE_DOWN,PIPE_SUPPLY_UP,PIPE_SUPPLY_DOWN,PIPE_SCRUBBERS_UP,PIPE_SCRUBBERS_DOWN) - return dir -///// Z-Level stuff - if(PIPE_PASSIVE_VENT) - return dir - return 0 - -/obj/item/pipe/proc/get_pdir() //endpoints for regular pipes - - var/flip = turn(dir, 180) -// var/cw = turn(dir, -90) -// var/acw = turn(dir, 90) - - if (!(pipe_type in list(PIPE_HE_STRAIGHT, PIPE_HE_BENT, PIPE_JUNCTION))) - return get_pipe_dir() - switch(pipe_type) - if(PIPE_HE_STRAIGHT,PIPE_HE_BENT) - return 0 - if(PIPE_JUNCTION) - return flip - return 0 - -// return the h_dir (heat-exchange pipes) from the type and the dir - -/obj/item/pipe/proc/get_hdir() //endpoints for h/e pipes - -// var/flip = turn(dir, 180) -// var/cw = turn(dir, -90) - - switch(pipe_type) - if(PIPE_HE_STRAIGHT) - return get_pipe_dir() - if(PIPE_HE_BENT) - return get_pipe_dir() - if(PIPE_JUNCTION) - return dir - else - return 0 - -/obj/item/pipe/attack_self(mob/user as mob) - return rotate() +//called when a turf is attacked with a pipe item +/obj/item/pipe/afterattack(turf/simulated/floor/target, mob/user, proximity) + if(!proximity) return + if(istype(target) && user.canUnEquip(src)) + user.drop_from_inventory(src, target) + else + return ..() /obj/item/pipe/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) - ..() - //* - if (!istype(W, /obj/item/weapon/wrench)) - return ..() - if (!isturf(src.loc)) - return 1 - if (pipe_type in list (PIPE_SIMPLE_STRAIGHT, PIPE_SUPPLY_STRAIGHT, PIPE_SCRUBBERS_STRAIGHT, PIPE_HE_STRAIGHT, PIPE_INSULATED_STRAIGHT, PIPE_MVALVE)) - if(dir==2) - set_dir(1) - else if(dir==8) - set_dir(4) - else if (pipe_type in list(PIPE_MANIFOLD4W, PIPE_SUPPLY_MANIFOLD4W, PIPE_SCRUBBERS_MANIFOLD4W, PIPE_OMNI_MIXER, PIPE_OMNI_FILTER)) - set_dir(2) - var/pipe_dir = get_pipe_dir() + if(iswrench(W)) + return wrench_act(user, W) + return ..() - for(var/obj/machinery/atmospherics/M in src.loc) - if((M.initialize_directions & pipe_dir) && M.check_connect_types_construction(M,src)) // matches at least one direction on either type of pipe & same connection type - user << "There is already a pipe of the same type at this location." - return 1 +/obj/item/pipe/proc/wrench_act(var/mob/living/user, var/obj/item/weapon/wrench/W) + if(!isturf(loc)) + return TRUE + + add_fingerprint(user) + fixdir() + + var/obj/machinery/atmospherics/fakeA = pipe_type + var/flags = initial(fakeA.pipe_flags) + for(var/obj/machinery/atmospherics/M in loc) + if((M.pipe_flags & flags & PIPING_ONE_PER_TURF)) //Only one dense/requires density object per tile, eg connectors/cryo/heater/coolers. + to_chat(user, "Something is hogging the tile!") + return TRUE + if((M.piping_layer != piping_layer) && !((M.pipe_flags | flags) & PIPING_ALL_LAYER)) // Pipes on different layers can't block each other unless they are ALL_LAYER + continue + if(M.get_init_dirs() & SSmachines.get_init_dirs(pipe_type, dir)) // matches at least one direction on either type of pipe + to_chat(user, "There is already a pipe at that location!") + return TRUE // no conflicts found - var/pipefailtext = "There's nothing to connect this pipe section to!" //(with how the pipe code works, at least one end needs to be connected to something, otherwise the game deletes the segment)" - - //TODO: Move all of this stuff into the various pipe constructors. - switch(pipe_type) - if(PIPE_SIMPLE_STRAIGHT, PIPE_SIMPLE_BENT) - var/obj/machinery/atmospherics/pipe/simple/P = new( src.loc ) - P.pipe_color = color - P.set_dir(src.dir) - P.initialize_directions = pipe_dir - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - if (QDELETED(P)) - usr << pipefailtext - return 1 - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - - if(PIPE_SUPPLY_STRAIGHT, PIPE_SUPPLY_BENT) - var/obj/machinery/atmospherics/pipe/simple/hidden/supply/P = new( src.loc ) - P.pipe_color = color - P.set_dir(src.dir) - P.initialize_directions = pipe_dir - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - if (QDELETED(P)) - usr << pipefailtext - return 1 - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - - if(PIPE_SCRUBBERS_STRAIGHT, PIPE_SCRUBBERS_BENT) - var/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers/P = new( src.loc ) - P.pipe_color = color - P.set_dir(src.dir) - P.initialize_directions = pipe_dir - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - if (QDELETED(P)) - usr << pipefailtext - return 1 - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - - if(PIPE_UNIVERSAL) - var/obj/machinery/atmospherics/pipe/simple/hidden/universal/P = new( src.loc ) - P.pipe_color = color - P.set_dir(src.dir) - P.initialize_directions = pipe_dir - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - if (QDELETED(P)) - usr << pipefailtext - return 1 - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - - if(PIPE_HE_STRAIGHT, PIPE_HE_BENT) - var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/P = new ( src.loc ) - P.set_dir(src.dir) - P.initialize_directions = pipe_dir //this var it's used to know if the pipe is bent or not - P.initialize_directions_he = pipe_dir - P.atmos_init() - if (QDELETED(P)) - usr << pipefailtext - return 1 - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - - if(PIPE_CONNECTOR) // connector - var/obj/machinery/atmospherics/portables_connector/C = new( src.loc ) - C.set_dir(dir) - C.initialize_directions = pipe_dir - if (pipename) - C.name = pipename - var/turf/T = C.loc - C.level = !T.is_plating() ? 2 : 1 - C.atmos_init() - C.build_network() - if (C.node) - C.node.atmos_init() - C.node.build_network() - - - if(PIPE_MANIFOLD) //manifold - var/obj/machinery/atmospherics/pipe/manifold/M = new( src.loc ) - M.pipe_color = color - M.set_dir(dir) - M.initialize_directions = pipe_dir - //M.New() - var/turf/T = M.loc - M.level = !T.is_plating() ? 2 : 1 - M.atmos_init() - if (QDELETED(M)) - usr << pipefailtext - return 1 - M.build_network() - if (M.node1) - M.node1.atmos_init() - M.node1.build_network() - if (M.node2) - M.node2.atmos_init() - M.node2.build_network() - if (M.node3) - M.node3.atmos_init() - M.node3.build_network() - - if(PIPE_SUPPLY_MANIFOLD) //manifold - var/obj/machinery/atmospherics/pipe/manifold/hidden/supply/M = new( src.loc ) - M.pipe_color = color - M.set_dir(dir) - M.initialize_directions = pipe_dir - //M.New() - var/turf/T = M.loc - M.level = !T.is_plating() ? 2 : 1 - M.atmos_init() - if (!M) - usr << "There's nothing to connect this manifold to! (with how the pipe code works, at least one end needs to be connected to something, otherwise the game deletes the segment)" - return 1 - M.build_network() - if (M.node1) - M.node1.atmos_init() - M.node1.build_network() - if (M.node2) - M.node2.atmos_init() - M.node2.build_network() - if (M.node3) - M.node3.atmos_init() - M.node3.build_network() - - if(PIPE_SCRUBBERS_MANIFOLD) //manifold - var/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers/M = new( src.loc ) - M.pipe_color = color - M.set_dir(dir) - M.initialize_directions = pipe_dir - //M.New() - var/turf/T = M.loc - M.level = !T.is_plating() ? 2 : 1 - M.atmos_init() - if (!M) - usr << "There's nothing to connect this manifold to! (with how the pipe code works, at least one end needs to be connected to something, otherwise the game deletes the segment)" - return 1 - M.build_network() - if (M.node1) - M.node1.atmos_init() - M.node1.build_network() - if (M.node2) - M.node2.atmos_init() - M.node2.build_network() - if (M.node3) - M.node3.atmos_init() - M.node3.build_network() - M.node3.build_network() - - if(PIPE_MANIFOLD4W) //4-way manifold - var/obj/machinery/atmospherics/pipe/manifold4w/M = new( src.loc ) - M.pipe_color = color - M.set_dir(dir) - M.initialize_directions = pipe_dir - //M.New() - var/turf/T = M.loc - M.level = !T.is_plating() ? 2 : 1 - M.atmos_init() - if (QDELETED(M)) - usr << pipefailtext - return 1 - M.build_network() - if (M.node1) - M.node1.atmos_init() - M.node1.build_network() - if (M.node2) - M.node2.atmos_init() - M.node2.build_network() - if (M.node3) - M.node3.atmos_init() - M.node3.build_network() - if (M.node4) - M.node4.atmos_init() - M.node4.build_network() - - if(PIPE_SUPPLY_MANIFOLD4W) //4-way manifold - var/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply/M = new( src.loc ) - M.pipe_color = color - M.set_dir(dir) - M.initialize_directions = pipe_dir - M.connect_types = src.connect_types - //M.New() - var/turf/T = M.loc - M.level = !T.is_plating() ? 2 : 1 - M.atmos_init() - if (!M) - usr << "There's nothing to connect this manifold to! (with how the pipe code works, at least one end needs to be connected to something, otherwise the game deletes the segment)" - return 1 - M.build_network() - if (M.node1) - M.node1.atmos_init() - M.node1.build_network() - if (M.node2) - M.node2.atmos_init() - M.node2.build_network() - if (M.node3) - M.node3.atmos_init() - M.node3.build_network() - if (M.node4) - M.node4.atmos_init() - M.node4.build_network() - - if(PIPE_SCRUBBERS_MANIFOLD4W) //4-way manifold - var/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers/M = new( src.loc ) - M.pipe_color = color - M.set_dir(dir) - M.initialize_directions = pipe_dir - M.connect_types = src.connect_types - //M.New() - var/turf/T = M.loc - M.level = !T.is_plating() ? 2 : 1 - M.atmos_init() - if (!M) - usr << "There's nothing to connect this manifold to! (with how the pipe code works, at least one end needs to be connected to something, otherwise the game deletes the segment)" - return 1 - M.build_network() - if (M.node1) - M.node1.atmos_init() - M.node1.build_network() - if (M.node2) - M.node2.atmos_init() - M.node2.build_network() - if (M.node3) - M.node3.atmos_init() - M.node3.build_network() - if (M.node4) - M.node4.atmos_init() - M.node4.build_network() - - if(PIPE_JUNCTION) - var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction/P = new ( src.loc ) - P.set_dir(src.dir) - P.initialize_directions = src.get_pdir() - P.initialize_directions_he = src.get_hdir() - P.atmos_init() - if (QDELETED(P)) - usr << pipefailtext //"There's nothing to connect this pipe to! (with how the pipe code works, at least one end needs to be connected to something, otherwise the game deletes the segment)" - return 1 - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - - if(PIPE_UVENT) //unary vent - var/obj/machinery/atmospherics/unary/vent_pump/V = new( src.loc ) - V.set_dir(dir) - V.initialize_directions = pipe_dir - if (pipename) - V.name = pipename - var/turf/T = V.loc - V.level = !T.is_plating() ? 2 : 1 - V.atmos_init() - V.build_network() - if (V.node) - V.node.atmos_init() - V.node.build_network() - - if(PIPE_MVALVE) //manual valve - var/obj/machinery/atmospherics/valve/V = new( src.loc) - V.set_dir(dir) - V.initialize_directions = pipe_dir - if (pipename) - V.name = pipename - var/turf/T = V.loc - V.level = !T.is_plating() ? 2 : 1 - V.atmos_init() - V.build_network() - if (V.node1) -// world << "[V.node1.name] is connected to valve, forcing it to update its nodes." - V.node1.atmos_init() - V.node1.build_network() - if (V.node2) -// world << "[V.node2.name] is connected to valve, forcing it to update its nodes." - V.node2.atmos_init() - V.node2.build_network() - - if(PIPE_PUMP) //gas pump - var/obj/machinery/atmospherics/binary/pump/P = new(src.loc) - P.set_dir(dir) - P.initialize_directions = pipe_dir - if (pipename) - P.name = pipename - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - - if(PIPE_GAS_FILTER) //gas filter - var/obj/machinery/atmospherics/trinary/atmos_filter/P = new(src.loc) - P.set_dir(dir) - P.initialize_directions = pipe_dir - if (pipename) - P.name = pipename - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - if (P.node3) - P.node3.atmos_init() - P.node3.build_network() - - if(PIPE_GAS_MIXER) //gas mixer - var/obj/machinery/atmospherics/trinary/mixer/P = new(src.loc) - P.set_dir(dir) - P.initialize_directions = pipe_dir - if (pipename) - P.name = pipename - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - if (P.node3) - P.node3.atmos_init() - P.node3.build_network() - - if(PIPE_GAS_FILTER_M) //gas filter mirrored - var/obj/machinery/atmospherics/trinary/atmos_filter/m_filter/P = new(src.loc) - P.set_dir(dir) - P.initialize_directions = pipe_dir - if (pipename) - P.name = pipename - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - if (P.node3) - P.node3.atmos_init() - P.node3.build_network() - - if(PIPE_GAS_MIXER_T) //gas mixer-t - var/obj/machinery/atmospherics/trinary/mixer/t_mixer/P = new(src.loc) - P.set_dir(dir) - P.initialize_directions = pipe_dir - if (pipename) - P.name = pipename - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - if (P.node3) - P.node3.atmos_init() - P.node3.build_network() - - if(PIPE_GAS_MIXER_M) //gas mixer mirrored - var/obj/machinery/atmospherics/trinary/mixer/m_mixer/P = new(src.loc) - P.set_dir(dir) - P.initialize_directions = pipe_dir - if (pipename) - P.name = pipename - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - if (P.node3) - P.node3.atmos_init() - P.node3.build_network() - - if(PIPE_SCRUBBER) //scrubber - var/obj/machinery/atmospherics/unary/vent_scrubber/S = new(src.loc) - S.set_dir(dir) - S.initialize_directions = pipe_dir - if (pipename) - S.name = pipename - var/turf/T = S.loc - S.level = !T.is_plating() ? 2 : 1 - S.atmos_init() - S.build_network() - if (S.node) - S.node.atmos_init() - S.node.build_network() - - if(PIPE_INSULATED_STRAIGHT, PIPE_INSULATED_BENT) - var/obj/machinery/atmospherics/pipe/simple/insulated/P = new( src.loc ) - P.set_dir(src.dir) - P.initialize_directions = pipe_dir - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - if (QDELETED(P)) - usr << pipefailtext - return 1 - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - - if(PIPE_MTVALVE) //manual t-valve - var/obj/machinery/atmospherics/tvalve/V = new(src.loc) - V.set_dir(dir) - V.initialize_directions = pipe_dir - if (pipename) - V.name = pipename - var/turf/T = V.loc - V.level = !T.is_plating() ? 2 : 1 - V.atmos_init() - V.build_network() - if (V.node1) - V.node1.atmos_init() - V.node1.build_network() - if (V.node2) - V.node2.atmos_init() - V.node2.build_network() - if (V.node3) - V.node3.atmos_init() - V.node3.build_network() - - if(PIPE_MTVALVEM) //manual t-valve - var/obj/machinery/atmospherics/tvalve/mirrored/V = new(src.loc) - V.set_dir(dir) - V.initialize_directions = pipe_dir - if (pipename) - V.name = pipename - var/turf/T = V.loc - V.level = !T.is_plating() ? 2 : 1 - V.atmos_init() - V.build_network() - if (V.node1) - V.node1.atmos_init() - V.node1.build_network() - if (V.node2) - V.node2.atmos_init() - V.node2.build_network() - if (V.node3) - V.node3.atmos_init() - V.node3.build_network() - - if(PIPE_CAP) - var/obj/machinery/atmospherics/pipe/cap/C = new(src.loc) - C.set_dir(dir) - C.initialize_directions = pipe_dir - C.atmos_init() - C.build_network() - if(C.node) - C.node.atmos_init() - C.node.build_network() - - if(PIPE_SUPPLY_CAP) - var/obj/machinery/atmospherics/pipe/cap/hidden/supply/C = new(src.loc) - C.set_dir(dir) - C.initialize_directions = pipe_dir - C.atmos_init() - C.build_network() - if(C.node) - C.node.atmos_init() - C.node.build_network() - - if(PIPE_SCRUBBERS_CAP) - var/obj/machinery/atmospherics/pipe/cap/hidden/scrubbers/C = new(src.loc) - C.set_dir(dir) - C.initialize_directions = pipe_dir - C.atmos_init() - C.build_network() - if(C.node) - C.node.atmos_init() - C.node.build_network() - - if(PIPE_PASSIVE_GATE) //passive gate - var/obj/machinery/atmospherics/binary/passive_gate/P = new(src.loc) - P.set_dir(dir) - P.initialize_directions = pipe_dir - if (pipename) - P.name = pipename - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - - if(PIPE_VOLUME_PUMP) //volume pump - var/obj/machinery/atmospherics/binary/pump/high_power/P = new(src.loc) - P.set_dir(dir) - P.initialize_directions = pipe_dir - if (pipename) - P.name = pipename - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - - if(PIPE_HEAT_EXCHANGE) // heat exchanger - var/obj/machinery/atmospherics/unary/heat_exchanger/C = new( src.loc ) - C.set_dir(dir) - C.initialize_directions = pipe_dir - if (pipename) - C.name = pipename - var/turf/T = C.loc - C.level = !T.is_plating() ? 2 : 1 - C.atmos_init() - C.build_network() - if (C.node) - C.node.atmos_init() - C.node.build_network() - - if(PIPE_DVALVE) //digital valve - var/obj/machinery/atmospherics/valve/digital/V = new( src.loc) - if(src.req_access) - V.req_access = src.req_access - if(src.req_one_access) - V.req_one_access = src.req_one_access - V.set_dir(dir) - V.initialize_directions = pipe_dir - if (pipename) - V.name = pipename - var/turf/T = V.loc - V.level = !T.is_plating() ? 2 : 1 - V.atmos_init() - V.build_network() - if (V.node1) - V.node1.atmos_init() - V.node1.build_network() - if (V.node2) - V.node2.atmos_init() - V.node2.build_network() - - if(PIPE_DTVALVE) //digital t-valve - var/obj/machinery/atmospherics/tvalve/digital/V = new(src.loc) - if(src.req_access) - V.req_access = src.req_access - if(src.req_one_access) - V.req_one_access = src.req_one_access - V.set_dir(dir) - V.initialize_directions = pipe_dir - if (pipename) - V.name = pipename - var/turf/T = V.loc - V.level = !T.is_plating() ? 2 : 1 - V.atmos_init() - V.build_network() - if (V.node1) - V.node1.atmos_init() - V.node1.build_network() - if (V.node2) - V.node2.atmos_init() - V.node2.build_network() - if (V.node3) - V.node3.atmos_init() - V.node3.build_network() - - if(PIPE_DTVALVEM) //mirrored digital t-valve - var/obj/machinery/atmospherics/tvalve/mirrored/digital/V = new(src.loc) - if(src.req_access) - V.req_access = src.req_access - if(src.req_one_access) - V.req_one_access = src.req_one_access - V.set_dir(dir) - V.initialize_directions = pipe_dir - if (pipename) - V.name = pipename - var/turf/T = V.loc - V.level = !T.is_plating() ? 2 : 1 - V.atmos_init() - V.build_network() - if (V.node1) - V.node1.atmos_init() - V.node1.build_network() - if (V.node2) - V.node2.atmos_init() - V.node2.build_network() - if (V.node3) - V.node3.atmos_init() - V.node3.build_network() - -///// Z-Level stuff - if(PIPE_UP) - var/obj/machinery/atmospherics/pipe/zpipe/up/P = new(src.loc) - P.set_dir(dir) - P.initialize_directions = pipe_dir - if (pipename) - P.name = pipename - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - if(PIPE_DOWN) - var/obj/machinery/atmospherics/pipe/zpipe/down/P = new(src.loc) - P.set_dir(dir) - P.initialize_directions = pipe_dir - if (pipename) - P.name = pipename - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - if(PIPE_SUPPLY_UP) - var/obj/machinery/atmospherics/pipe/zpipe/up/supply/P = new(src.loc) - P.set_dir(dir) - P.initialize_directions = pipe_dir - if (pipename) - P.name = pipename - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - if(PIPE_SUPPLY_DOWN) - var/obj/machinery/atmospherics/pipe/zpipe/down/supply/P = new(src.loc) - P.set_dir(dir) - P.initialize_directions = pipe_dir - if (pipename) - P.name = pipename - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - if(PIPE_SCRUBBERS_UP) - var/obj/machinery/atmospherics/pipe/zpipe/up/scrubbers/P = new(src.loc) - P.set_dir(dir) - P.initialize_directions = pipe_dir - if (pipename) - P.name = pipename - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - if(PIPE_SCRUBBERS_DOWN) - var/obj/machinery/atmospherics/pipe/zpipe/down/scrubbers/P = new(src.loc) - P.set_dir(dir) - P.initialize_directions = pipe_dir - if (pipename) - P.name = pipename - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() -///// Z-Level stuff - if(PIPE_OMNI_MIXER) - var/obj/machinery/atmospherics/omni/mixer/P = new(loc) - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if(PIPE_OMNI_FILTER) - var/obj/machinery/atmospherics/omni/atmos_filter/P = new(loc) - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if(PIPE_PASSIVE_VENT) - var/obj/machinery/atmospherics/pipe/vent/P = new(loc) - P.set_dir(dir) - P.initialize_directions = pipe_dir - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() + var/obj/machinery/atmospherics/A = new pipe_type(loc) + build_pipe(A) + // TODO - Evaluate and remove the "need at least one thing to connect to" thing ~Leshana + // With how the pipe code works, at least one end needs to be connected to something, otherwise the game deletes the segment. + if (QDELETED(A)) + to_chat(user, "There's nothing to connect this pipe section to!") + return TRUE + transfer_fingerprints_to(A) playsound(src, W.usesound, 50, 1) user.visible_message( \ - "[user] fastens the [src].", \ - "You have fastened the [src].", \ - "You hear ratchet.") - qdel(src) // remove the pipe item + "[user] fastens \the [src].", \ + "You fasten \the [src].", \ + "You hear ratcheting.") - return - //TODO: DEFERRED + qdel(src) -// ensure that setterm() is called for a newly connected pipeline +/obj/item/pipe/proc/build_pipe(obj/machinery/atmospherics/A) + A.set_dir(dir) + A.init_dir() + if(pipename) + A.name = pipename + if(req_access) + A.req_access = req_access + if(req_one_access) + A.req_one_access = req_one_access + A.on_construction(color, piping_layer) + +/obj/item/pipe/trinary/flippable/build_pipe(obj/machinery/atmospherics/trinary/T) + T.mirrored = mirrored + . = ..() + +// Lookup the initialize_directions for a given atmos machinery instance facing dir. +// TODO - Right now this determines the answer by instantiating an instance and checking! +// There has to be a better way... ~Leshana +/datum/controller/subsystem/machines/proc/get_init_dirs(type, dir) + var/static/list/pipe_init_dirs_cache = list() + if(!pipe_init_dirs_cache[type]) + pipe_init_dirs_cache[type] = list() + + if(!pipe_init_dirs_cache[type]["[dir]"]) + var/obj/machinery/atmospherics/temp = new type(null, dir) + pipe_init_dirs_cache[type]["[dir]"] = temp.get_init_dirs() + qdel(temp) + + return pipe_init_dirs_cache[type]["[dir]"] + + +// +// Meters are special - not like any other pipes or components +// + /obj/item/pipe_meter name = "meter" - desc = "A meter that can be laid on pipes" + desc = "A meter that can be laid on pipes." icon = 'icons/obj/pipe-item.dmi' icon_state = "meter" item_state = "buildpipe" w_class = ITEMSIZE_LARGE + var/piping_layer = PIPING_LAYER_DEFAULT /obj/item/pipe_meter/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) - ..() + if(iswrench(W)) + return wrench_act(user, W) + return ..() - if (!istype(W, /obj/item/weapon/wrench)) - return ..() - if(!locate(/obj/machinery/atmospherics/pipe, src.loc)) - user << "You need to fasten it to a pipe" - return 1 - new/obj/machinery/meter( src.loc ) +/obj/item/pipe_meter/proc/wrench_act(var/mob/living/user, var/obj/item/weapon/wrench/W) + var/obj/machinery/atmospherics/pipe/pipe + for(var/obj/machinery/atmospherics/pipe/P in loc) + if(P.piping_layer == piping_layer) + pipe = P + break + if(!pipe) + to_chat(user, "You need to fasten it to a pipe!") + return TRUE + new /obj/machinery/meter(loc, piping_layer) playsound(src, W.usesound, 50, 1) - user << "You have fastened the meter to the pipe" + to_chat(user, "You fasten the meter to the pipe.") qdel(src) -//not sure why these are necessary -#undef PIPE_SIMPLE_STRAIGHT -#undef PIPE_SIMPLE_BENT -#undef PIPE_HE_STRAIGHT -#undef PIPE_HE_BENT -#undef PIPE_CONNECTOR -#undef PIPE_MANIFOLD -#undef PIPE_JUNCTION -#undef PIPE_UVENT -#undef PIPE_MVALVE -#undef PIPE_PUMP -#undef PIPE_SCRUBBER -#undef PIPE_INSULATED_STRAIGHT -#undef PIPE_INSULATED_BENT -#undef PIPE_GAS_FILTER -#undef PIPE_GAS_MIXER -#undef PIPE_PASSIVE_GATE -#undef PIPE_VOLUME_PUMP -#undef PIPE_OUTLET_INJECT -#undef PIPE_MTVALVE -#undef PIPE_MTVALVEM -#undef PIPE_GAS_FILTER_M -#undef PIPE_GAS_MIXER_T -#undef PIPE_GAS_MIXER_M -#undef PIPE_SUPPLY_STRAIGHT -#undef PIPE_SUPPLY_BENT -#undef PIPE_SCRUBBERS_STRAIGHT -#undef PIPE_SCRUBBERS_BENT -#undef PIPE_SUPPLY_MANIFOLD -#undef PIPE_SCRUBBERS_MANIFOLD -#undef PIPE_UNIVERSAL -//#undef PIPE_MANIFOLD4W + +/obj/item/pipe_meter/dropped() + . = ..() + if(loc) + setAttachLayer(piping_layer) + +/obj/item/pipe_meter/proc/setAttachLayer(new_layer = PIPING_LAYER_DEFAULT) + piping_layer = new_layer diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm index 8bc779adf3..6675a5ca15 100644 --- a/code/game/machinery/pipe/pipe_dispenser.dm +++ b/code/game/machinery/pipe/pipe_dispenser.dm @@ -6,74 +6,32 @@ anchored = 1 var/unwrenched = 0 var/wait = 0 + var/p_layer = PIPING_LAYER_REGULAR -/obj/machinery/pipedispenser/attack_hand(user as mob) - if(..()) +// TODO - Its about time to make this NanoUI don't we think? +/obj/machinery/pipedispenser/attack_hand(var/mob/user as mob) + if((. = ..())) return -///// Z-Level stuff - var/dat = {" -Regular pipes:
-Pipe
-Bent Pipe
-Manifold
-Digital Valve
-Manual Valve
-Pipe Cap
-4-Way Manifold
-Digital T-Valve
-Digital T-Valve - Mirrored
-Manual T-Valve
-Manual T-Valve - Mirrored
-Upward Pipe
-Downward Pipe
-Supply pipes:
-Pipe
-Bent Pipe
-Manifold
-Pipe Cap
-4-Way Manifold
-Upward Pipe
-Downward Pipe
-Scrubbers pipes:
-Pipe
-Bent Pipe
-Manifold
-Pipe Cap
-4-Way Manifold
-Upward Pipe
-Downward Pipe
-Devices:
-Universal pipe adapter
-Connector
-Unary Vent
-Passive Vent
-Gas Pump
-Pressure Regulator
-High Power Gas Pump
-Scrubber
-Meter
-Gas Filter
-Gas Filter - Mirrored
-Gas Mixer
-Gas Mixer - Mirrored
-Gas Mixer - T
-Omni Gas Mixer
-Omni Gas Filter
-Heat exchange:
-Pipe
-Bent Pipe
-Junction
-Heat Exchanger
-Insulated pipes:
-Pipe
-Bent Pipe
+ src.interact(user) -"} -///// Z-Level stuff -//What number the make points to is in the define # at the top of construction.dm in same folder +/obj/machinery/pipedispenser/interact(mob/user) + user.set_machine(src) - user << browse("[src][dat]", "window=pipedispenser") - onclose(user, "pipedispenser") + var/list/lines = list() + for(var/category in atmos_pipe_recipes) + lines += "[category]:
" + if(category == "Pipes") + // Stupid hack. Fix someday. So tired right now. + lines += "Regular " + lines += "Supply " + lines += "Scrubber " + lines += "
" + for(var/datum/pipe_recipe/PI in atmos_pipe_recipes[category]) + lines += PI.Render(src) + var/dat = lines.Join() + var/datum/browser/popup = new(user, "pipedispenser", name, 300, 800, src) + popup.set_content("[dat]") + popup.open() return /obj/machinery/pipedispenser/Topic(href, href_list) @@ -81,20 +39,27 @@ return if(unwrenched || !usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr)) usr << browse(null, "window=pipedispenser") + usr.unset_machine(src) return usr.set_machine(src) src.add_fingerprint(usr) - if(href_list["make"]) + if(href_list["setlayer"]) + var/new_pipe_layer = text2num(href_list["setlayer"]) + if(isnum(new_pipe_layer)) + p_layer = new_pipe_layer + updateDialog() + else if(href_list["makepipe"]) if(!wait) - var/p_type = text2num(href_list["make"]) + var/obj/machinery/atmospherics/p_type = text2path(href_list["makepipe"]) var/p_dir = text2num(href_list["dir"]) - var/obj/item/pipe/P = new (/*usr.loc*/ src.loc, pipe_type=p_type, dir=p_dir) - P.update() + var/pi_type = initial(p_type.construction_type) + var/obj/item/pipe/P = new pi_type(src.loc, p_type, p_dir) + P.setPipingLayer(p_layer) P.add_fingerprint(usr) wait = 1 spawn(10) wait = 0 - if(href_list["makemeter"]) + else if(href_list["makemeter"]) if(!wait) new /obj/item/pipe_meter(/*usr.loc*/ src.loc) wait = 1 diff --git a/code/game/machinery/pipe/pipe_recipes.dm b/code/game/machinery/pipe/pipe_recipes.dm new file mode 100644 index 0000000000..f0ae483055 --- /dev/null +++ b/code/game/machinery/pipe/pipe_recipes.dm @@ -0,0 +1,102 @@ +// +// Recipies for Pipe Dispenser and (someday) the RPD +// + +var/global/list/atmos_pipe_recipes = null + +/hook/startup/proc/init_pipe_recipes() + global.atmos_pipe_recipes = list( + "Pipes" = list( + new /datum/pipe_recipe/pipe("Pipe", /obj/machinery/atmospherics/pipe/simple), + new /datum/pipe_recipe/pipe("Manifold", /obj/machinery/atmospherics/pipe/manifold), + new /datum/pipe_recipe/pipe("Manual Valve", /obj/machinery/atmospherics/valve), + new /datum/pipe_recipe/pipe("Digital Valve", /obj/machinery/atmospherics/valve/digital), + new /datum/pipe_recipe/pipe("Pipe cap", /obj/machinery/atmospherics/pipe/cap), + new /datum/pipe_recipe/pipe("4-Way Manifold", /obj/machinery/atmospherics/pipe/manifold4w), + new /datum/pipe_recipe/pipe("Manual T-Valve", /obj/machinery/atmospherics/tvalve), + new /datum/pipe_recipe/pipe("Digital T-Valve", /obj/machinery/atmospherics/tvalve/digital), + new /datum/pipe_recipe/pipe("Upward Pipe", /obj/machinery/atmospherics/pipe/zpipe/up), + new /datum/pipe_recipe/pipe("Downward Pipe", /obj/machinery/atmospherics/pipe/zpipe/down), + new /datum/pipe_recipe/pipe("Universal Pipe Adaptor", /obj/machinery/atmospherics/pipe/simple/visible/universal), + ), + "Devices" = list( + new /datum/pipe_recipe/pipe("Connector", /obj/machinery/atmospherics/portables_connector), + new /datum/pipe_recipe/pipe("Unary Vent", /obj/machinery/atmospherics/unary/vent_pump), + new /datum/pipe_recipe/pipe("Passive Vent", /obj/machinery/atmospherics/pipe/vent), + new /datum/pipe_recipe/pipe("Injector", /obj/machinery/atmospherics/unary/outlet_injector), + new /datum/pipe_recipe/pipe("Gas Pump", /obj/machinery/atmospherics/binary/pump), + new /datum/pipe_recipe/pipe("Pressure Regulator", /obj/machinery/atmospherics/binary/passive_gate), + new /datum/pipe_recipe/pipe("High Power Gas Pump",/obj/machinery/atmospherics/binary/pump/high_power), + new /datum/pipe_recipe/pipe("Scrubber", /obj/machinery/atmospherics/unary/vent_scrubber), + new /datum/pipe_recipe/meter("Meter"), + new /datum/pipe_recipe/pipe("Gas Filter", /obj/machinery/atmospherics/trinary/atmos_filter), + new /datum/pipe_recipe/pipe("Gas Mixer", /obj/machinery/atmospherics/trinary/mixer), + new /datum/pipe_recipe/pipe("Gas Mixer 'T'", /obj/machinery/atmospherics/trinary/mixer/t_mixer), + new /datum/pipe_recipe/pipe("Omni Gas Mixer", /obj/machinery/atmospherics/omni/mixer), + new /datum/pipe_recipe/pipe("Omni Gas Filter", /obj/machinery/atmospherics/omni/atmos_filter), + ), + "Heat Exchange" = list( + new /datum/pipe_recipe/pipe("Pipe", /obj/machinery/atmospherics/pipe/simple/heat_exchanging), + new /datum/pipe_recipe/pipe("Junction", /obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction), + new /datum/pipe_recipe/pipe("Heat Exchanger", /obj/machinery/atmospherics/unary/heat_exchanger), + ), + "Insulated pipes" = list( + new /datum/pipe_recipe/pipe("Pipe", /obj/machinery/atmospherics/pipe/simple/insulated), + ) + ) + return TRUE + +// +// New method of handling pipe construction. Instead of numeric constants and a giant switch statement of doom +// every pipe type has a datum instance which describes its name, placement rules and construction method, dispensing etc. +// The advantages are obvious, mostly in simplifying the code of the dispenser, and the ability to add new pipes without hassle. +// +/datum/pipe_recipe + var/name = "Abstract Pipe (fixme)" // Recipe name + var/dirtype // If using an RPD, this tells more about what previews to show. + +// Render an HTML link to select this pipe type. Returns text. +/datum/pipe_recipe/proc/Render(dispenser) + return "[name]
" + +// Parameters for the Topic link returned by Render(). Returns text. +/datum/pipe_recipe/proc/Params() + return "" + +// +// Subtype for actual pipes +// +/datum/pipe_recipe/pipe + var/obj/item/pipe/construction_type // The type PATH to the type of pipe fitting object the recipe makes. + var/obj/machinery/atmospherics/pipe_type // The type PATH of what actual pipe the fitting becomes. + +/datum/pipe_recipe/pipe/New(var/label, var/obj/machinery/atmospherics/path) + name = label + pipe_type = path + construction_type = initial(path.construction_type) + dirtype = initial(construction_type.dispenser_class) + +// Render an HTML link to select this pipe type +/datum/pipe_recipe/pipe/Render(dispenser) + var/dat = ..(dispenser) + // Stationary pipe dispensers don't allow you to pre-select pipe directions. + // This makes it impossble to spawn bent versions of bendable pipes. + // We add a "Bent" pipe type with a preset diagonal direction to work around it. + if(istype(dispenser, /obj/machinery/pipedispenser) && (dirtype == PIPE_BENDABLE)) + dat += "Bent [name]
" + return dat + +/datum/pipe_recipe/pipe/Params() + return "makepipe=[pipe_type]" + +// +// Subtype for meters +// +/datum/pipe_recipe/meter + dirtype = PIPE_ONEDIR + +/datum/pipe_recipe/meter/New(label) + name = label + +/datum/pipe_recipe/meter/Params() + return "makemeter=1" diff --git a/code/game/machinery/pipe/pipelayer.dm b/code/game/machinery/pipe/pipelayer.dm index c960879e54..65656929de 100644 --- a/code/game/machinery/pipe/pipelayer.dm +++ b/code/game/machinery/pipe/pipelayer.dm @@ -8,13 +8,18 @@ var/old_dir // Last direction we were facing. var/on = 0 // Pipelaying online? var/a_dis = 0 // Auto-dismantling - If enabled it will remove floor tiles - var/P_type = 0 // Currently selected pipe type + var/P_type = null // Currently selected pipe type var/P_type_t = "" // Name of currently selected pipe type var/max_metal = 50 // Max capacity for internal metal storage var/metal = 0 // Current amount in internal metal storage var/pipe_cost = 0.25 // Cost in steel for each pipe. var/obj/item/weapon/wrench/W // Internal wrench used for wrenching down the pipes - var/list/Pipes = list("regular pipes"=0,"scrubbers pipes"=31,"supply pipes"=29,"heat exchange pipes"=2) + var/list/Pipes = list( + "regular pipes" = /obj/machinery/atmospherics/pipe/simple, + "scrubbers pipes" = /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, + "supply pipes" = /obj/machinery/atmospherics/pipe/simple/hidden/supply, + "heat exchange pipes" = /obj/machinery/atmospherics/pipe/simple/heat_exchanging + ) /obj/machinery/pipelayer/New() W = new(src) @@ -160,17 +165,17 @@ if(!use_metal(pipe_cost)) return reset() var/fdirn = turn(M_Dir, 180) - var/p_type + var/obj/machinery/atmospherics/p_type = P_type + var/p_layer = initial(p_type.piping_layer) var/p_dir - if (fdirn!=old_dir) - p_type=1+P_type p_dir=old_dir+M_Dir else - p_type=0+P_type p_dir=M_Dir - var/obj/item/pipe/P = new (w_turf, pipe_type=p_type, dir=p_dir) + var/pi_type = initial(p_type.construction_type) + var/obj/item/pipe/P = new pi_type(w_turf, p_type, p_dir) + P.setPipingLayer(p_layer) // We used metal to make these, so should be reclaimable! P.matter = list(DEFAULT_WALL_MATERIAL = pipe_cost * SHEET_MATERIAL_AMOUNT) P.attackby(W , src) diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index d4d3cedb47..692e76bf5a 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -115,7 +115,7 @@ H.adjustBrainLoss(-(rand(1,3))) // Also recharge their internal battery. - if(!isnull(H.internal_organs_by_name["cell"]) && H.nutrition < 450) + if(H.isSynthetic() && H.nutrition < 450) H.nutrition = min(H.nutrition+10, 450) cell.use(7000/450*10) @@ -254,7 +254,7 @@ else if(istype(L, /mob/living/carbon/human)) var/mob/living/carbon/human/H = L - if(!isnull(H.internal_organs_by_name["cell"])) + if(H.isSynthetic()) add_fingerprint(H) H.reset_view(src) H.forceMove(src) @@ -264,17 +264,6 @@ else return -/obj/machinery/recharge_station/proc/hascell(var/mob/M) - if(isrobot(M)) - var/mob/living/silicon/robot/R = M - if(R.cell) - return 1 - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(!isnull(H.internal_organs_by_name["cell"])) - return 1 - return 0 - /obj/machinery/recharge_station/proc/go_out() if(!occupant) return @@ -289,7 +278,7 @@ set name = "Eject Recharger" set src in oview(1) - if(usr.incapacitated()) + if(usr.incapacitated() || !isliving(usr)) return go_out() @@ -301,8 +290,9 @@ set name = "Enter Recharger" set src in oview(1) - if(!usr.incapacitated()) + if(usr.incapacitated() || !isliving(usr)) return + go_in(usr) /obj/machinery/recharge_station/ghost_pod_recharger diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 7f76bc978c..7c0ca00f1a 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -588,7 +588,7 @@ //Departments that the cycler can paint suits to look like. var/list/departments = list("Engineering","Mining","Medical","Security","Atmos","HAZMAT","Construction","Biohazard","Emergency Medical Response","Crowd Control") //Species that the suits can be configured to fit. - var/list/species = list("Human","Skrell","Unathi","Tajara", "Teshari") + var/list/species = list(SPECIES_HUMAN,SPECIES_SKRELL,SPECIES_UNATHI,SPECIES_TAJ, SPECIES_TESHARI) var/target_department var/target_species @@ -753,7 +753,7 @@ //Clear the access reqs, disable the safeties, and open up all paintjobs. user << "You run the sequencer across the interface, corrupting the operating protocols." departments = list("Engineering","Mining","Medical","Security","Atmos","HAZMAT","Construction","Biohazard","Crowd Control","Emergency Medical Response","^%###^%$", "Charring") - species = list("Human","Tajara","Skrell","Unathi", "Teshari") + species = list(SPECIES_HUMAN,SPECIES_TAJ,SPECIES_SKRELL,SPECIES_UNATHI, SPECIES_TESHARI) emagged = 1 safeties = 0 @@ -982,7 +982,9 @@ if(suit) suit.name = "engineering voidsuit" suit.icon_state = "rig-engineering" - suit.item_state = "eng_voidsuit" + suit.item_state = "rig-engineering" + suit.item_state_slots[slot_r_hand_str] = "eng_voidsuit" + suit.item_state_slots[slot_l_hand_str] = "eng_voidsuit" if("Mining") if(helmet) helmet.name = "mining voidsuit helmet" @@ -991,7 +993,9 @@ if(suit) suit.name = "mining voidsuit" suit.icon_state = "rig-mining" - suit.item_state = "mining_voidsuit" + suit.item_state = "rig-mining" + suit.item_state_slots[slot_r_hand_str] = "mining_voidsuit" + suit.item_state_slots[slot_l_hand_str] = "mining_voidsuit" if("Medical") if(helmet) helmet.name = "medical voidsuit helmet" @@ -1000,7 +1004,9 @@ if(suit) suit.name = "medical voidsuit" suit.icon_state = "rig-medical" - suit.item_state = "medical_voidsuit" + suit.item_state = "rig-medical" + suit.item_state_slots[slot_r_hand_str] = "medical_voidsuit" + suit.item_state_slots[slot_l_hand_str] = "medical_voidsuit" if("Security") if(helmet) helmet.name = "security voidsuit helmet" @@ -1009,7 +1015,9 @@ if(suit) suit.name = "security voidsuit" suit.icon_state = "rig-sec" - suit.item_state = "sec_voidsuit" + suit.item_state = "rig-sec" + suit.item_state_slots[slot_r_hand_str] = "sec_voidsuit" + suit.item_state_slots[slot_l_hand_str] = "sec_voidsuit" if("Crowd Control") if(helmet) helmet.name = "crowd control voidsuit helmet" @@ -1018,7 +1026,9 @@ if(suit) suit.name = "crowd control voidsuit" suit.icon_state = "rig-sec_riot" - suit.item_state = "sec_voidsuit_riot" + suit.item_state = "rig-sec_riot" + suit.item_state_slots[slot_r_hand_str] = "sec_voidsuit_riot" + suit.item_state_slots[slot_l_hand_str] = "sec_voidsuit_riot" if("Atmos") if(helmet) helmet.name = "atmospherics voidsuit helmet" @@ -1027,7 +1037,9 @@ if(suit) suit.name = "atmospherics voidsuit" suit.icon_state = "rig-atmos" - suit.item_state = "atmos_voidsuit" + suit.item_state = "rig-atmos" + suit.item_state_slots[slot_r_hand_str] = "atmos_voidsuit" + suit.item_state_slots[slot_l_hand_str] = "atmos_voidsuit" if("HAZMAT") if(helmet) helmet.name = "HAZMAT voidsuit helmet" @@ -1036,7 +1048,9 @@ if(suit) suit.name = "HAZMAT voidsuit" suit.icon_state = "rig-engineering_rad" - suit.item_state = "eng_voidsuit_rad" + suit.item_state = "rig-engineering_rad" + suit.item_state_slots[slot_r_hand_str] = "eng_voidsuit_rad" + suit.item_state_slots[slot_l_hand_str] = "eng_voidsuit_rad" if("Construction") if(helmet) helmet.name = "Construction voidsuit helmet" @@ -1045,7 +1059,9 @@ if(suit) suit.name = "Construction voidsuit" suit.icon_state = "rig-engineering_con" - suit.item_state = "eng_voidsuit_con" + suit.item_state = "rig-engineering_con" + suit.item_state_slots[slot_r_hand_str] = "eng_voidsuit_con" + suit.item_state_slots[slot_l_hand_str] = "eng_voidsuit_con" if("Biohazard") if(helmet) helmet.name = "Biohazard voidsuit helmet" @@ -1054,7 +1070,9 @@ if(suit) suit.name = "Biohazard voidsuit" suit.icon_state = "rig-medical_bio" - suit.item_state = "medical_voidsuit_bio" + suit.item_state = "rig-medical_bio" + suit.item_state_slots[slot_r_hand_str] = "medical_voidsuit_bio" + suit.item_state_slots[slot_l_hand_str] = "medical_voidsuit_bio" if("Emergency Medical Response") if(helmet) helmet.name = "emergency medical response voidsuit helmet" @@ -1063,7 +1081,9 @@ if(suit) suit.name = "emergency medical response voidsuit" suit.icon_state = "rig-medical_emt" - suit.item_state = "medical_voidsuit_emt" + suit.item_state = "rig-medical_emt" + suit.item_state_slots[slot_r_hand_str] = "medical_voidsuit_emt" + suit.item_state_slots[slot_l_hand_str] = "medical_voidsuit_emt" if("^%###^%$" || "Mercenary") if(helmet) helmet.name = "blood-red voidsuit helmet" @@ -1071,8 +1091,10 @@ helmet.item_state = "rig0-syndie" if(suit) suit.name = "blood-red voidsuit" - suit.item_state = "syndie_voidsuit" + suit.item_state = "rig-syndie" suit.icon_state = "rig-syndie" + suit.item_state_slots[slot_r_hand_str] = "syndie_voidsuit" + suit.item_state_slots[slot_l_hand_str] = "syndie_voidsuit" if("Charring") if(helmet) helmet.name = "soot-covered voidsuit helmet" @@ -1082,6 +1104,8 @@ suit.name = "soot-covered voidsuit" suit.item_state = "rig-firebug" suit.icon_state = "rig-firebug" + suit.item_state_slots[slot_r_hand_str] = "rig-firebug" + suit.item_state_slots[slot_l_hand_str] = "rig-firebug" if(helmet) helmet.name = "refitted [helmet.name]" if(suit) suit.name = "refitted [suit.name]" diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index 6f6a4f04fb..269346ab71 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -6,7 +6,6 @@ desc = "A generic vending machine." icon = 'icons/obj/vending.dmi' icon_state = "generic" - layer = 2.9 anchored = 1 density = 1 @@ -836,6 +835,7 @@ /obj/item/weapon/storage/fancy/cigarettes/luckystars = 5, /obj/item/weapon/storage/fancy/cigarettes/jerichos = 5, /obj/item/weapon/storage/fancy/cigarettes/menthols = 5, + /obj/item/weapon/storage/rollingpapers = 5, /obj/item/weapon/storage/box/matches = 10, /obj/item/weapon/flame/lighter/random = 4) contraband = list(/obj/item/weapon/flame/lighter/zippo = 4) @@ -848,6 +848,7 @@ /obj/item/weapon/storage/fancy/cigarettes/luckystars = 17, /obj/item/weapon/storage/fancy/cigarettes/jerichos = 22, /obj/item/weapon/storage/fancy/cigarettes/menthols = 18, + /obj/item/weapon/storage/rollingpapers = 10, /obj/item/weapon/storage/box/matches = 1, /obj/item/weapon/flame/lighter/random = 2) @@ -862,7 +863,8 @@ /obj/item/weapon/reagent_containers/glass/bottle/stoxin = 4,/obj/item/weapon/reagent_containers/glass/bottle/toxin = 4, /obj/item/weapon/reagent_containers/syringe/antiviral = 4,/obj/item/weapon/reagent_containers/syringe = 12, /obj/item/device/healthanalyzer = 5,/obj/item/weapon/reagent_containers/glass/beaker = 4, /obj/item/weapon/reagent_containers/dropper = 2, - /obj/item/stack/medical/advanced/bruise_pack = 3, /obj/item/stack/medical/advanced/ointment = 3, /obj/item/stack/medical/splint = 2) + /obj/item/stack/medical/advanced/bruise_pack = 6, /obj/item/stack/medical/advanced/ointment = 6, /obj/item/stack/medical/splint = 4, + /obj/item/weapon/storage/pill_bottle/carbon = 2) contraband = list(/obj/item/weapon/reagent_containers/pill/tox = 3,/obj/item/weapon/reagent_containers/pill/stox = 4,/obj/item/weapon/reagent_containers/pill/antitox = 6) idle_power_usage = 211 //refrigerator - believe it or not, this is actually the average power consumption of a refrigerated vending machine according to NRCan. req_log_access = access_cmo @@ -1084,4 +1086,47 @@ /obj/item/weapon/screwdriver = 5,/obj/item/weapon/crowbar = 5) //everything after the power cell had no amounts, I improvised. -Sayu req_log_access = access_rd - has_logs = 1 \ No newline at end of file + has_logs = 1 + +/obj/machinery/vending/giftvendor + name = "AlliCo Baubles and Confectionaries" + desc = "For that special someone!" + icon_state = "giftvendor" + vend_delay = 15 + products = list(/obj/item/weapon/storage/fancy/heartbox = 5, + /obj/item/toy/bouquet = 5, + /obj/item/toy/bouquet/fake = 4, + /obj/item/weapon/paper/card/smile = 3, + /obj/item/weapon/paper/card/heart = 3, + /obj/item/weapon/paper/card/cat = 3, + /obj/item/weapon/paper/card/flower = 3, + /obj/item/clothing/accessory/bracelet/friendship = 5, + /obj/item/toy/plushie/therapy/red = 2, + /obj/item/toy/plushie/therapy/purple = 2, + /obj/item/toy/plushie/therapy/blue = 2, + /obj/item/toy/plushie/therapy/yellow = 2, + /obj/item/toy/plushie/therapy/orange = 2, + /obj/item/toy/plushie/therapy/green = 2) + contraband = list(/obj/item/weapon/reagent_containers/food/drinks/bottle/champagne = 1 + /* Handbuzzer to be added later */) + premium = list(/obj/item/toy/plushie/nymph = 2, + /obj/item/toy/plushie/mouse = 2, + /obj/item/toy/plushie/kitten = 2, + /obj/item/toy/plushie/lizard = 2, + /obj/item/toy/plushie/spider = 2, + /obj/item/toy/plushie/farwa = 2, + /obj/item/weapon/storage/trinketbox = 2) + prices = list(/obj/item/weapon/storage/fancy/heartbox = 15, + /obj/item/toy/bouquet = 10, + /obj/item/toy/bouquet/fake = 3, + /obj/item/weapon/paper/card/smile = 1, + /obj/item/weapon/paper/card/heart = 1, + /obj/item/weapon/paper/card/cat = 1, + /obj/item/weapon/paper/card/flower = 1, + /obj/item/clothing/accessory/bracelet/friendship = 5, + /obj/item/toy/plushie/therapy/red = 20, + /obj/item/toy/plushie/therapy/purple = 20, + /obj/item/toy/plushie/therapy/blue = 20, + /obj/item/toy/plushie/therapy/yellow = 20, + /obj/item/toy/plushie/therapy/orange = 20, + /obj/item/toy/plushie/therapy/green = 20) \ No newline at end of file diff --git a/code/game/machinery/wall_frames.dm b/code/game/machinery/wall_frames.dm index 3a036eec8e..1765eac3ec 100644 --- a/code/game/machinery/wall_frames.dm +++ b/code/game/machinery/wall_frames.dm @@ -29,7 +29,7 @@ update_type_list() var/datum/frame/frame_types/frame_type if(!build_machine_type) - var/datum/frame/frame_types/response = input(usr, "What kind of frame would you like to make?", "Frame type request", null) in frame_types_floor + var/datum/frame/frame_types/response = input(user, "What kind of frame would you like to make?", "Frame type request", null) in frame_types_floor if(!response || response.name == "Cancel") return frame_type = response @@ -37,10 +37,10 @@ build_machine_type = /obj/structure/frame if(frame_type.frame_size != 5) - new /obj/item/stack/material/steel(usr.loc, (5 - frame_type.frame_size)) + new /obj/item/stack/material/steel(user.loc, (5 - frame_type.frame_size)) var/ndir - ndir = usr.dir + ndir = user.dir if(!(ndir in cardinal)) return @@ -48,13 +48,15 @@ M.fingerprints = fingerprints M.fingerprintshidden = fingerprintshidden M.fingerprintslast = fingerprintslast + if(istype(src.loc, /obj/item/weapon/gripper)) //Typical gripper shenanigans + user.drop_item() qdel(src) /obj/item/frame/proc/try_build(turf/on_wall, mob/user as mob) update_type_list() var/datum/frame/frame_types/frame_type if(!build_machine_type) - var/datum/frame/frame_types/response = input(usr, "What kind of frame would you like to make?", "Frame type request", null) in frame_types_wall + var/datum/frame/frame_types/response = input(user, "What kind of frame would you like to make?", "Frame type request", null) in frame_types_wall if(!response || response.name == "Cancel") return frame_type = response @@ -62,38 +64,40 @@ build_machine_type = /obj/structure/frame if(frame_type.frame_size != 5) - new /obj/item/stack/material/steel(usr.loc, (5 - frame_type.frame_size)) + new /obj/item/stack/material/steel(user.loc, (5 - frame_type.frame_size)) - if(get_dist(on_wall, usr)>1) + if(get_dist(on_wall, user)>1) return var/ndir if(reverse) - ndir = get_dir(usr, on_wall) + ndir = get_dir(user, on_wall) else - ndir = get_dir(on_wall, usr) + ndir = get_dir(on_wall, user) if(!(ndir in cardinal)) return - var/turf/loc = get_turf(usr) + var/turf/loc = get_turf(user) var/area/A = loc.loc if(!istype(loc, /turf/simulated/floor)) - usr << "\The frame cannot be placed on this spot." + to_chat(user, "\The frame cannot be placed on this spot.") return if(A.requires_power == 0 || A.name == "Space") - usr << "\The [src] Alarm cannot be placed in this area." + to_chat(user, "\The [src] Alarm cannot be placed in this area.") return if(gotwallitem(loc, ndir)) - usr << "There's already an item on this wall!" + to_chat(user, "There's already an item on this wall!") return var/obj/machinery/M = new build_machine_type(loc, ndir, 1, frame_type) M.fingerprints = fingerprints M.fingerprintshidden = fingerprintshidden M.fingerprintslast = fingerprintslast + if(istype(src.loc, /obj/item/weapon/gripper)) //Typical gripper shenanigans + user.drop_item() qdel(src) /obj/item/frame/light diff --git a/code/game/mecha/combat/gorilla.dm b/code/game/mecha/combat/gorilla.dm new file mode 100644 index 0000000000..cc5dacebc3 --- /dev/null +++ b/code/game/mecha/combat/gorilla.dm @@ -0,0 +1,213 @@ +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/cannon + name = "8.8cm KwK 47" + desc = "Precision German engineering!" // Why would you ever take this off the mech, anyway? + icon_state = "mecha_uac2" + equip_cooldown = 60 // 6 seconds + projectile = /obj/item/projectile/bullet/cannon + fire_sound = 'sound/weapons/cannon.ogg' + projectiles = 1 + projectile_energy_cost = 1000 + salvageable = 0 // We don't want players ripping this off a dead mech. Could potentially be a prize for beating it if Devs bless me and someone offers a nerf idea. + +/obj/item/projectile/bullet/cannon + name ="armor-piercing shell" + icon = 'icons/obj/projectiles.dmi' + icon_state = "shell" + damage = 1000 // In order to 1-hit any other mech and royally fuck anyone unfortunate enough to get in the way. + +/obj/item/projectile/bullet/cannon/on_hit(var/atom/target, var/blocked = 0) + explosion(target, 0, 0, 2, 4) + return 1 + +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/cannon/weak + name = "8.8 cm KwK 36" + equip_cooldown = 120 // 12 seconds. + projectile = /obj/item/projectile/bullet/cannon/weak + projectile_energy_cost = 400 + salvageable = 1 + +/obj/item/projectile/bullet/cannon/weak + name ="canister shell" + icon_state = "canister" + damage = 120 //Do not get fucking shot. + +/* // GLITCHY UND LAGGY. Will later look into fixing. +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/mg42 + name = "Maschinengewehr 60" + icon_state = "mecha_uac2" + equip_cooldown = 10 + projectile = /obj/item/projectile/bullet/midbullet2 + fire_sound = 'sound/weapons/mg42.ogg' + projectiles = 1000 + projectiles_per_shot = 5 + deviation = 0.3 + projectile_energy_cost = 20 + fire_cooldown = 1 + salvageable = 0 // We don't want players ripping this off a dead mech. +*/ + +/obj/effect/decal/mecha_wreckage/gorilla + name = "Gorilla wreckage" + desc = "... Blitzkrieg?" + icon = 'icons/mecha/mecha64x64.dmi' + icon_state = "pzrwreck" + plane = MOB_PLANE + pixel_x = -16 + anchored = 1 // It's fucking huge. You aren't moving it. + +/obj/mecha/combat/gorilla + name = "Gorilla" + desc = "Blitzkrieg!" //stop using all caps in item descs i will fight you. its redundant with the bold. + icon = 'icons/mecha/mecha64x64.dmi' + icon_state = "pzrmech" + initial_icon = "pzrmech" + pixel_x = -16 + step_in = 10 + health = 5000 + opacity = 0 // Because there's big tall legs to look through. Also it looks fucky if this is set to 1. + deflect_chance = 50 + damage_absorption = list("brute"=0.1,"fire"=0.8,"bullet"=0.1,"laser"=0.6,"energy"=0.7,"bomb"=0.7) //values show how much damage will pass through, not how much will be absorbed. + max_temperature = 35000 //Just a bit better than the Durand. + infra_luminosity = 3 + var/zoom = 0 + var/smoke = 5 + var/smoke_ready = 1 + var/smoke_cooldown = 100 + var/datum/effect/effect/system/smoke_spread/smoke_system = new + wreckage = /obj/effect/decal/mecha_wreckage/gorilla + add_req_access = 0 + internal_damage_threshold = 25 + force = 60 + max_equip = 5 + +/obj/mecha/combat/gorilla/New() + ..() + var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay(src) // This thing basically cannot function without an external power supply. + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/cannon(src) + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/cannon/weak(src) //Saves energy, I suppose. Anti-infantry. + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive(src) + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg(src) + ME.attach(src) + src.smoke_system.set_up(3, 0, src) + src.smoke_system.attach(src) + return + +/obj/mecha/combat/gorilla/mechstep(direction) + var/result = step(src,direction) + playsound(src,"mechstep",40,1) + return result + +/obj/mecha/combat/gorilla/mechturn(direction) + dir = direction + playsound(src,"mechstep",40,1) + + +/obj/mecha/combat/gorilla/relaymove(mob/user,direction) + if(user != src.occupant) + user.loc = get_turf(src) + to_chat(user, "You climb out from [src]") + return 0 + if(!can_move) + return 0 + if(zoom) + if(world.time - last_message > 20) + src.occupant_message("Unable to move while in zoom mode.") + last_message = world.time + return 0 + if(connected_port) + if(world.time - last_message > 20) + src.occupant_message("Unable to move while connected to the air system port") + last_message = world.time + return 0 + if(state || !has_charge(step_energy_drain)) + return 0 + var/tmp_step_in = step_in + var/tmp_step_energy_drain = step_energy_drain + var/move_result = 0 + if(internal_damage&MECHA_INT_CONTROL_LOST) + move_result = mechsteprand() + else if(src.dir!=direction) + move_result = mechturn(direction) + else + move_result = mechstep(direction) + if(move_result) + if(istype(src.loc, /turf/space)) + if(!src.check_for_support()) + src.pr_inertial_movement.start(list(src,direction)) + can_move = 0 + spawn(tmp_step_in) can_move = 1 + use_power(tmp_step_energy_drain) + return 1 + return 0 + +/obj/mecha/combat/gorilla/verb/smoke() + set category = "Exosuit Interface" + set name = "Smoke" + set src = usr.loc + set popup_menu = 0 + if(usr!=src.occupant) + return + if(smoke_ready && smoke>0) + src.smoke_system.start() + smoke-- + smoke_ready = 0 + spawn(smoke_cooldown) + smoke_ready = 1 + return + +/obj/mecha/combat/gorilla/verb/zoom() + set category = "Exosuit Interface" + set name = "Zoom" + set src = usr.loc + set popup_menu = 0 + if(usr!=src.occupant) + return + if(src.occupant.client) + src.zoom = !src.zoom + src.log_message("Toggled zoom mode.") + src.occupant_message("Zoom mode [zoom?"en":"dis"]abled.") + if(zoom) + src.occupant.client.view = 12 + playsound(src.occupant, 'sound/mecha/imag_enh.ogg',50) + else + src.occupant.client.view = world.view//world.view - default mob view size + return + + +/obj/mecha/combat/gorilla/go_out() + if(src.occupant && src.occupant.client) + src.occupant.client.view = world.view + src.zoom = 0 + ..() + return + + +/obj/mecha/combat/gorilla/get_stats_part() + var/output = ..() + output += {"Smoke: [smoke]"} + return output + + +/obj/mecha/combat/gorilla/get_commands() + var/output = {"
+
Special
+ +
+ "} + output += ..() + return output + +/obj/mecha/combat/gorilla/Topic(href, href_list) + ..() + if (href_list["smoke"]) + src.smoke() + if (href_list["toggle_zoom"]) + src.zoom() + return \ No newline at end of file diff --git a/code/game/mecha/equipment/tools/unused_tools.dm b/code/game/mecha/equipment/tools/unused_tools.dm deleted file mode 100644 index c7ef794c4e..0000000000 --- a/code/game/mecha/equipment/tools/unused_tools.dm +++ /dev/null @@ -1,27 +0,0 @@ - - - -/****** Do not tick this file in without looking over this code first ******/ - - - - -/* -/obj/item/mecha_parts/mecha_equipment/book_stocker - - action(var/mob/target) - if(!istype(target)) - return - if(target.search_contents_for(/obj/item/book/WGW)) - target.gib() - target.client.gib() - target.client.mom.monkeyize() - target.client.mom.gib() - for(var/mob/M in range(target, 1000)) - M.gib() - explosion(target.loc,100000,100000,100000) - usr.gib() - world.Reboot() - return 1 - -*/ diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index 50012fe95c..80b417da22 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -117,46 +117,41 @@ projectile = /obj/item/projectile/beam/stun fire_sound = 'sound/weapons/Taser.ogg' -/* + /obj/item/mecha_parts/mecha_equipment/weapon/honker name = "sound emission device" icon_state = "mecha_honker" energy_drain = 300 equip_cooldown = 150 - range = MELEE|RANGED origin_tech = list(TECH_MATERIAL = 2, TECH_COMBAT = 4, TECH_ILLEGAL = 1) - var/ear_safety = 0 - if(iscarbon(M)) +/obj/item/mecha_parts/mecha_equipment/honker/action(target) + if(!chassis) + return 0 + if(energy_drain && chassis.get_charge() < energy_drain) + return 0 + if(!equip_ready) + return 0 + + playsound(chassis, 'sound/effects/bang.ogg', 30, 1, 30) + chassis.occupant_message("You emit a high-pitched noise from the mech.") + for(var/mob/living/carbon/M in ohearers(6, chassis)) + if(istype(M, /mob/living/carbon/human)) + var/ear_safety = 0 ear_safety = M.get_ear_protection() - - action(target) - if(!chassis) - return 0 - if(energy_drain && chassis.get_charge() < energy_drain) - return 0 - if(!equip_ready) - return 0 - - playsound(chassis, 'sound/effects/bang.ogg', 30, 1, 30) - chassis.occupant_message("You emit a high-pitched noise from the mech.") - for(var/mob/living/carbon/M in ohearers(6, chassis)) - if(istype(M, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = M - if(ear_safety > 0) - return - to_chat(M, "\Your ears feel like they're bleeding!") - playsound(M, 'sound/effects/bang.ogg', 70, 1, 30) - M.sleeping = 0 - M.ear_deaf += 30 - M.ear_damage += rand(5, 20) - M.Weaken(3) - M.Stun(5) - chassis.use_power(energy_drain) - log_message("Used a sound emission device.") - do_after_cooldown() - return -*/ + if(ear_safety > 0) + return + to_chat(M, "Your ears feel like they're bleeding!") + playsound(M, 'sound/effects/bang.ogg', 70, 1, 30) + M.sleeping = 0 + M.ear_deaf += 30 + M.ear_damage += rand(5, 20) + M.Weaken(3) + M.Stun(5) + chassis.use_power(energy_drain) + log_message("Used a sound emission device.") + do_after_cooldown() + return /obj/item/mecha_parts/mecha_equipment/weapon/ballistic name = "general ballisic weapon" @@ -361,4 +356,4 @@ if(!action_checks(user) || !active) return user.electrocute_act(shock_damage, src) - return chassis.dynattackby(W,user) \ No newline at end of file + return chassis.dynattackby(W,user) diff --git a/code/game/mecha/mech_bay.dm b/code/game/mecha/mech_bay.dm index 55255d2097..5584590f92 100644 --- a/code/game/mecha/mech_bay.dm +++ b/code/game/mecha/mech_bay.dm @@ -52,22 +52,21 @@ if(charging.loc != src.loc) // Could be qdel or teleport or something stop_charging() return - var/done = 1 - if(charging.cell) + var/done = FALSE + if(charging.cell) var/t = min(charge, charging.cell.maxcharge - charging.cell.charge) if(t > 0) charging.give_power(t) use_power(t * 150) - done = 0 else charging.occupant_message("Fully charged.") + done = TRUE if(repair && charging.health < initial(charging.health)) charging.health = min(charging.health + repair, initial(charging.health)) if(charging.health == initial(charging.health)) charging.occupant_message("Fully repaired.") - else - done = 0 + done = FALSE if(done) stop_charging() return diff --git a/code/game/mecha/mech_sensor.dm b/code/game/mecha/mech_sensor.dm index 87a9863ee8..5173f182ce 100644 --- a/code/game/mecha/mech_sensor.dm +++ b/code/game/mecha/mech_sensor.dm @@ -7,7 +7,7 @@ density = 1 throwpass = 1 use_power = 1 - layer = 3.3 + layer = ON_WINDOW_LAYER power_channel = EQUIP var/on = 0 var/id_tag = null diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm index 9b27cdecbd..0a8a74b8e9 100644 --- a/code/game/objects/buckling.dm +++ b/code/game/objects/buckling.dm @@ -46,7 +46,7 @@ return TRUE /atom/movable/Destroy() - unbuckle_mob() + unbuckle_all_mobs() return ..() diff --git a/code/game/objects/effects/alien/aliens.dm b/code/game/objects/effects/alien/aliens.dm index 2c864f0a56..7a79c21e1e 100644 --- a/code/game/objects/effects/alien/aliens.dm +++ b/code/game/objects/effects/alien/aliens.dm @@ -147,7 +147,8 @@ anchored = 1 density = 0 - layer = 2 + plane = TURF_PLANE + layer = ABOVE_TURF_LAYER var/health = 15 var/obj/effect/alien/weeds/node/linked_node = null @@ -155,7 +156,7 @@ icon_state = "weednode" name = "purple sac" desc = "Weird purple octopus-like thing." - layer = 3 + layer = ABOVE_TURF_LAYER+0.01 light_range = NODERANGE var/node_range = NODERANGE diff --git a/code/game/objects/effects/chem/chemsmoke.dm b/code/game/objects/effects/chem/chemsmoke.dm index be7e759a63..436ebabcc9 100644 --- a/code/game/objects/effects/chem/chemsmoke.dm +++ b/code/game/objects/effects/chem/chemsmoke.dm @@ -161,7 +161,7 @@ if(chemholder.reagents.reagent_list.len) chemholder.reagents.trans_to_obj(smoke, chemholder.reagents.total_volume / dist, copy = 1) //copy reagents to the smoke so mob/breathe() can handle inhaling the reagents smoke.icon = I - smoke.layer = 6 + smoke.plane = ABOVE_PLANE smoke.set_dir(pick(cardinal)) smoke.pixel_x = -32 + rand(-8, 8) smoke.pixel_y = -32 + rand(-8, 8) diff --git a/code/game/objects/effects/decals/Cleanable/fuel.dm b/code/game/objects/effects/decals/Cleanable/fuel.dm index c04540535b..b69226815e 100644 --- a/code/game/objects/effects/decals/Cleanable/fuel.dm +++ b/code/game/objects/effects/decals/Cleanable/fuel.dm @@ -2,7 +2,7 @@ //Liquid fuel is used for things that used to rely on volatile fuels or phoron being contained to a couple tiles. icon = 'icons/effects/effects.dmi' icon_state = "fuel" - layer = TURF_LAYER+0.2 + plane = DIRTY_PLANE anchored = 1 var/amount = 1 diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index 1b38fae182..90f708ff9d 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -10,7 +10,7 @@ var/global/list/image/splatter_cache=list() gender = PLURAL density = 0 anchored = 1 - layer = 2 + plane = BLOOD_PLANE icon = 'icons/effects/blood.dmi' icon_state = "mfloor1" random_icon_states = list("mfloor1", "mfloor2", "mfloor3", "mfloor4", "mfloor5", "mfloor6", "mfloor7") @@ -96,18 +96,18 @@ var/global/list/image/splatter_cache=list() S.overlays.Cut() S.overlays += S.blood_overlay S.blood_DNA |= blood_DNA.Copy() + perp.update_inv_shoes() else if (hasfeet)//Or feet perp.feet_blood_color = basecolor perp.track_blood = max(amount,perp.track_blood) - if(!perp.feet_blood_DNA) - perp.feet_blood_DNA = list() + LAZYINITLIST(perp.feet_blood_DNA) perp.feet_blood_DNA |= blood_DNA.Copy() + perp.update_bloodied() else if (perp.buckled && istype(perp.buckled, /obj/structure/bed/chair/wheelchair)) var/obj/structure/bed/chair/wheelchair/W = perp.buckled W.bloodiness = 4 - perp.update_inv_shoes(1) amount-- /obj/effect/decal/cleanable/blood/proc/dry() @@ -179,7 +179,6 @@ var/global/list/image/splatter_cache=list() gender = PLURAL density = 0 anchored = 1 - layer = 2 icon = 'icons/effects/blood.dmi' icon_state = "gibbl5" random_icon_states = list("gib1", "gib2", "gib3", "gib5", "gib6") @@ -236,7 +235,6 @@ var/global/list/image/splatter_cache=list() gender = PLURAL density = 0 anchored = 1 - layer = 2 icon = 'icons/effects/blood.dmi' icon_state = "mucus" random_icon_states = list("mucus") diff --git a/code/game/objects/effects/decals/Cleanable/misc.dm b/code/game/objects/effects/decals/Cleanable/misc.dm index ab01bfa005..1ef83bc722 100644 --- a/code/game/objects/effects/decals/Cleanable/misc.dm +++ b/code/game/objects/effects/decals/Cleanable/misc.dm @@ -4,7 +4,6 @@ gender = PLURAL density = 0 anchored = 1 - layer = 2 icon = 'icons/obj/objects.dmi' icon_state = "shards" @@ -36,7 +35,6 @@ gender = PLURAL density = 0 anchored = 1 - layer = 2 icon = 'icons/effects/effects.dmi' icon_state = "dirt" mouse_opacity = 0 @@ -47,7 +45,6 @@ gender = PLURAL density = 0 anchored = 1 - layer = 2 icon = 'icons/effects/effects.dmi' icon_state = "flour" @@ -57,7 +54,6 @@ gender = PLURAL density = 0 anchored = 1 - layer = 2 light_range = 1 icon = 'icons/effects/effects.dmi' icon_state = "greenglow" @@ -67,7 +63,7 @@ desc = "Somebody should remove that." density = 0 anchored = 1 - layer = 3 + plane = OBJ_PLANE icon = 'icons/effects/effects.dmi' icon_state = "cobweb1" @@ -76,7 +72,7 @@ desc = "It looks like a melted... something." density = 0 anchored = 1 - layer = 3 + plane = OBJ_PLANE icon = 'icons/obj/chemical.dmi' icon_state = "molten" @@ -85,7 +81,7 @@ desc = "Somebody should remove that." density = 0 anchored = 1 - layer = 3 + plane = OBJ_PLANE icon = 'icons/effects/effects.dmi' icon_state = "cobweb2" @@ -96,7 +92,6 @@ gender = PLURAL density = 0 anchored = 1 - layer = 2 icon = 'icons/effects/blood.dmi' icon_state = "vomit_1" random_icon_states = list("vomit_1", "vomit_2", "vomit_3", "vomit_4") @@ -107,7 +102,6 @@ desc = "It's red." density = 0 anchored = 1 - layer = 2 icon = 'icons/effects/tomatodecal.dmi' random_icon_states = list("tomato_floor1", "tomato_floor2", "tomato_floor3") @@ -116,7 +110,6 @@ desc = "Seems like this one won't hatch." density = 0 anchored = 1 - layer = 2 icon = 'icons/effects/tomatodecal.dmi' random_icon_states = list("smashed_egg1", "smashed_egg2", "smashed_egg3") @@ -125,7 +118,6 @@ desc = "It's pie cream from a cream pie." density = 0 anchored = 1 - layer = 2 icon = 'icons/effects/tomatodecal.dmi' random_icon_states = list("smashed_pie") @@ -134,7 +126,6 @@ desc = "Some kind of fruit smear." density = 0 anchored = 1 - layer = 2 icon = 'icons/effects/blood.dmi' icon_state = "mfloor1" random_icon_states = list("mfloor1", "mfloor2", "mfloor3", "mfloor4", "mfloor5", "mfloor6", "mfloor7") diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm index 2db1e5e948..f7965e092d 100644 --- a/code/game/objects/effects/decals/cleanable.dm +++ b/code/game/objects/effects/decals/cleanable.dm @@ -1,4 +1,5 @@ /obj/effect/decal/cleanable + plane = DIRTY_PLANE var/list/random_icon_states = list() /obj/effect/decal/cleanable/clean_blood(var/ignore = 0) diff --git a/code/game/objects/effects/decals/crayon.dm b/code/game/objects/effects/decals/crayon.dm index 20047ced12..55bb54b803 100644 --- a/code/game/objects/effects/decals/crayon.dm +++ b/code/game/objects/effects/decals/crayon.dm @@ -2,7 +2,7 @@ name = "rune" desc = "A rune drawn in crayon." icon = 'icons/obj/rune.dmi' - layer = 2.1 + plane = DIRTY_PLANE anchored = 1 New(location,main = "#FFFFFF",shade = "#000000",var/type = "rune") diff --git a/code/game/objects/effects/decals/misc.dm b/code/game/objects/effects/decals/misc.dm index 964a1301b8..f3a75ce3c2 100644 --- a/code/game/objects/effects/decals/misc.dm +++ b/code/game/objects/effects/decals/misc.dm @@ -3,7 +3,7 @@ desc = "It's an arrow hanging in mid-air. There may be a wizard about." icon = 'icons/mob/screen1.dmi' icon_state = "arrow" - layer = 16.0 + plane = ABOVE_PLANE anchored = 1 mouse_opacity = 0 @@ -11,4 +11,4 @@ /obj/effect/decal/spraystill density = 0 anchored = 1 - layer = 50 \ No newline at end of file + plane = ABOVE_PLANE \ No newline at end of file diff --git a/code/game/objects/effects/decals/posters/bs12.dm b/code/game/objects/effects/decals/posters/bs12.dm index 6b5ad182c4..7aadcb2ead 100644 --- a/code/game/objects/effects/decals/posters/bs12.dm +++ b/code/game/objects/effects/decals/posters/bs12.dm @@ -217,7 +217,7 @@ /datum/poster/bay_44 icon_state="bsposter44" name = "Time for a drink?" - desc = "This poster depicts a friendly-looking Tajara holding a tray of drinks." + desc = "This poster depicts a friendly-looking Tajaran holding a tray of drinks." /datum/poster/bay_45 icon_state="bsposter45" diff --git a/code/game/objects/effects/decals/posters/polarisposters.dm b/code/game/objects/effects/decals/posters/polarisposters.dm index 9295b754c9..958ceb66be 100644 --- a/code/game/objects/effects/decals/posters/polarisposters.dm +++ b/code/game/objects/effects/decals/posters/polarisposters.dm @@ -26,12 +26,12 @@ /datum/poster/pol_6 icon_state="polposter6" name = "Walk!" - desc = "This poster depicts a man walking, presumably to encourage you to not run in the halls." + desc = "This poster depicts a man walking, presumably to encourage you not to run in the halls." /datum/poster/pol_7 icon_state="polposter7" name = "Place your signs!" - desc = "A safety poster reminding custodial stuff to place wet floor signs where needed. This reminder's rarely heeded." + desc = "A safety poster reminding custodial staff to place wet floor signs where needed. This reminder's rarely heeded." /datum/poster/pol_8 icon_state="polposter8" diff --git a/code/game/objects/effects/decals/warning_stripes.dm b/code/game/objects/effects/decals/warning_stripes.dm index e22acfad74..db7c4bf74f 100644 --- a/code/game/objects/effects/decals/warning_stripes.dm +++ b/code/game/objects/effects/decals/warning_stripes.dm @@ -1,6 +1,5 @@ /obj/effect/decal/warning_stripes icon = 'icons/effects/warning_stripes.dmi' - layer = 2 /obj/effect/decal/warning_stripes/New() . = ..() diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm index 47fa55be1a..a1a6623ff1 100644 --- a/code/game/objects/effects/mines.dm +++ b/code/game/objects/effects/mines.dm @@ -208,7 +208,7 @@ /obj/item/weapon/mine/attack_self(mob/user as mob) // You do not want to move or throw a land mine while priming it... Explosives + Sudden Movement = Bad Times add_fingerprint(user) - msg_admin_attack("[user.name] ([user.ckey]) primed \a [src] (JMP)") + msg_admin_attack("[key_name_admin(user)] primed \a [src]") user.visible_message("[user] starts priming \the [src.name].", "You start priming \the [src.name]. Hold still!") if(do_after(user, 10 SECONDS)) playsound(loc, 'sound/weapons/armbomb.ogg', 75, 1, -3) diff --git a/code/game/objects/effects/misc.dm b/code/game/objects/effects/misc.dm index 349400226a..aaebab4355 100644 --- a/code/game/objects/effects/misc.dm +++ b/code/game/objects/effects/misc.dm @@ -26,7 +26,8 @@ desc = "Something swinging really wide." icon = 'icons/effects/96x96.dmi' icon_state = "cleave" - layer = 6 + plane = MOB_PLANE + layer = ABOVE_MOB_LAYER time_to_die = 6 alpha = 140 mouse_opacity = 0 diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm index 2cc8b7a64f..9f4f0fa118 100644 --- a/code/game/objects/effects/overlays.dm +++ b/code/game/objects/effects/overlays.dm @@ -17,7 +17,8 @@ icon = 'icons/misc/beach2.dmi' icon_state = "palm1" density = 1 - layer = 5 + plane = MOB_PLANE + layer = ABOVE_MOB_LAYER anchored = 1 /obj/effect/overlay/palmtree_l @@ -25,7 +26,8 @@ icon = 'icons/misc/beach2.dmi' icon_state = "palm2" density = 1 - layer = 5 + plane = MOB_PLANE + layer = ABOVE_MOB_LAYER anchored = 1 /obj/effect/overlay/coconut @@ -37,7 +39,7 @@ name = "Bluespace" icon = 'icons/turf/space.dmi' icon_state = "bluespacify" - layer = 10 + plane = ABOVE_PLANE /obj/effect/overlay/wallrot name = "wallrot" @@ -45,7 +47,8 @@ icon = 'icons/effects/wallrot.dmi' anchored = 1 density = 1 - layer = 5 + plane = MOB_PLANE + layer = ABOVE_MOB_LAYER mouse_opacity = 0 /obj/effect/overlay/wallrot/New() @@ -70,7 +73,9 @@ /obj/effect/overlay/snow/floor icon_state = "snowfloor" - layer = 2.01 //Just above floor + plane = TURF_PLANE + layer = ABOVE_TURF_LAYER + mouse_opacity = 0 //Don't block underlying tile interactions /obj/effect/overlay/snow/floor/edges icon_state = "snow_edges" @@ -80,11 +85,12 @@ /obj/effect/overlay/snow/airlock icon_state = "snowairlock" - layer = 3.2 //Just above airlocks + layer = DOOR_CLOSED_LAYER+0.01 /obj/effect/overlay/snow/floor/pointy icon_state = "snowfloorpointy" /obj/effect/overlay/snow/wall icon_state = "snowwall" - layer = 5 //Same as lights so humans can stand under it + plane = MOB_PLANE + layer = ABOVE_MOB_LAYER diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm index a26c1169d5..d3b9853e06 100644 --- a/code/game/objects/effects/spiders.dm +++ b/code/game/objects/effects/spiders.dm @@ -123,7 +123,7 @@ desc = "It never stays still for long." icon_state = "spiderling" anchored = 0 - layer = 2.7 + layer = HIDING_LAYER health = 3 var/last_itch = 0 var/amount_grown = -1 diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index c5840eaed2..748a203cc4 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -69,7 +69,7 @@ /* Species-specific sprites, concept stolen from Paradise//vg/. ex: sprite_sheets = list( - "Tajara" = 'icons/cat/are/bad' + SPECIES_TAJ = 'icons/cat/are/bad' ) If index term exists and icon_override is not set, this sprite sheet will be used. */ @@ -84,6 +84,9 @@ var/reach = 1 // Length of tiles it can reach, 1 is adjacent. var/addblends // Icon overlay for ADD highlights when applicable. + var/icon/default_worn_icon //Default on-mob icon + var/worn_layer //Default on-mob layer + /obj/item/New() ..() if(embed_chance < 0) @@ -280,6 +283,7 @@ // note this isn't called during the initial dressing of a player /obj/item/proc/equipped(var/mob/user, var/slot) hud_layerise() + user.position_hud_item(src,slot) if(user.client) user.client.screen |= src if(user.pulling == src) user.stop_pulling() return @@ -382,14 +386,14 @@ var/list/global/slot_flags_enumeration = list( if(!allow) return 0 if(slot_tie) - if(!H.w_uniform && (slot_w_uniform in mob_equip)) + var/allow = 0 + for(var/obj/item/clothing/C in H.worn_clothing) //Runs through everything you're wearing, returns if you can't attach the thing + if(C.can_attach_accessory(src)) + allow = 1 + break + if(!allow) if(!disable_warning) - H << "You need a jumpsuit before you can attach this [name]." - return 0 - var/obj/item/clothing/under/uniform = H.w_uniform - if(uniform.accessories.len && !uniform.can_attach_accessory(src)) - if (!disable_warning) - H << "You already have an accessory of this type attached to your [uniform]." + H << "You're not wearing anything you can attach this [name] to." return 0 return 1 @@ -476,9 +480,7 @@ var/list/global/slot_flags_enumeration = list( visible_message("[U] attempts to stab [M] in the eyes, but misses!") return - user.attack_log += "\[[time_stamp()]\] Attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])" - M.attack_log += "\[[time_stamp()]\] Attacked by [user.name] ([user.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])" - msg_admin_attack("[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (JMP)") //BS12 EDIT ALG + add_attack_logs(user,M,"Attack eyes with [name]") user.setClickCooldown(user.get_attack_speed()) user.do_attack_animation(M) @@ -678,4 +680,119 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. // My best guess as to why this is here would be that it does so little. Still, keep it under all the procs, for sanity's sake. /obj/item/device - icon = 'icons/obj/device.dmi' \ No newline at end of file + icon = 'icons/obj/device.dmi' + +//Worn icon generation for on-mob sprites +/obj/item/proc/make_worn_icon(var/body_type,var/slot_name,var/inhands,var/default_icon,var/default_layer) + //Get the required information about the base icon + var/icon/icon2use = get_worn_icon_file(body_type = body_type, slot_name = slot_name, default_icon = default_icon, inhands = inhands) + var/state2use = get_worn_icon_state(slot_name = slot_name) + var/layer2use = get_worn_layer(default_layer = default_layer) + + //Snowflakey inhand icons in a specific slot + if(inhands && icon2use == icon_override) + switch(slot_name) + if(slot_r_hand_str) + state2use += "_r" + if(slot_l_hand_str) + state2use += "_l" + + // testing("[src] (\ref[src]) - Slot: [slot_name], Inhands: [inhands], Worn Icon:[icon2use], Worn State:[state2use], Worn Layer:[layer2use]") + + //Generate the base onmob icon + var/icon/standing_icon = icon(icon = icon2use, icon_state = state2use) + + if(!inhands) + apply_custom(standing_icon) //Pre-image overridable proc to customize the thing + apply_addblends(icon2use,standing_icon) //Some items have ICON_ADD blend shaders + + var/image/standing = image(standing_icon) + standing.alpha = alpha + standing.color = color + standing.layer = layer2use + + //Apply any special features + if(!inhands) + apply_blood(standing) //Some items show blood when bloodied + apply_accessories(standing) //Some items sport accessories like webbing + + //Return our icon + return standing + +//Returns the icon object that should be used for the worn icon +/obj/item/proc/get_worn_icon_file(var/body_type,var/slot_name,var/default_icon,var/inhands) + + //1: icon_override var + if(icon_override) + return icon_override + + //2: species-specific sprite sheets (skipped for inhands) + if(LAZYLEN(sprite_sheets)) + var/sheet = sprite_sheets[body_type] + if(sheet && !inhands) + return sheet + + //3: slot-specific sprite sheets + if(LAZYLEN(item_icons)) + var/sheet = item_icons[slot_name] + if(sheet) + return sheet + + //4: item's default icon + if(default_worn_icon) + return default_worn_icon + + //5: provided default_icon + if(default_icon) + return default_icon + + //6: give up + return + +//Returns the state that should be used for the worn icon +/obj/item/proc/get_worn_icon_state(var/slot_name) + + //1: slot-specific sprite sheets + if(LAZYLEN(item_state_slots)) + var/state = item_state_slots[slot_name] + if(state) + return state + + //2: item_state variable + if(item_state) + return item_state + + //3: icon_state variable + if(icon_state) + return icon_state + +//Returns the layer that should be used for the worn icon (as a FLOAT_LAYER layer, so negative) +/obj/item/proc/get_worn_layer(var/default_layer = 0) + + //1: worn_layer variable + if(!isnull(worn_layer)) //Can be zero, so... + return BODY_LAYER+worn_layer + + //2: your default + return BODY_LAYER+default_layer + +//Apply the addblend blends onto the icon +/obj/item/proc/apply_addblends(var/source_icon, var/icon/standing_icon) + + //If we have addblends, blend them onto the provided icon + if(addblends && standing_icon && source_icon) + var/addblend_icon = icon("icon" = source_icon, "icon_state" = addblends) + standing_icon.Blend(addblend_icon, ICON_ADD) + +//STUB +/obj/item/proc/apply_custom(var/icon/standing_icon) + return standing_icon + +//STUB +/obj/item/proc/apply_blood(var/image/standing) + return standing + +//STUB +/obj/item/proc/apply_accessories(var/image/standing) + return standing + diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm index a23abb5b06..302c7df568 100644 --- a/code/game/objects/items/bodybag.dm +++ b/code/game/objects/items/bodybag.dm @@ -145,7 +145,7 @@ var/obj/item/weapon/reagent_containers/syringe/syringe /obj/structure/closet/body_bag/cryobag/New() - tank = new /obj/item/weapon/tank/emergency/oxygen(null) //It's in nullspace to prevent ejection when the bag is opened. + tank = new /obj/item/weapon/tank/emergency/oxygen/double(null) //It's in nullspace to prevent ejection when the bag is opened. ..() /obj/structure/closet/body_bag/cryobag/Destroy() diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index 31bb9160f8..2ad51ca887 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -46,11 +46,11 @@ if(colour != "#FFFFFF" && shadeColour != "#000000") colour = "#FFFFFF" shadeColour = "#000000" - user << "You will now draw in white and black with this crayon." + to_chat(usr,"You will now draw in white and black with this crayon.") else colour = "#000000" shadeColour = "#FFFFFF" - user << "You will now draw in black and white with this crayon." + to_chat(usr,"You will now draw in black and white with this crayon.") return /obj/item/weapon/pen/crayon/rainbow @@ -72,22 +72,22 @@ switch(drawtype) if("letter") drawtype = input("Choose the letter.", "Crayon scribbles") in list("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z") - user << "You start drawing a letter on the [target.name]." + to_chat(usr,"You start drawing a letter on the [target.name].") if("graffiti") - user << "You start drawing graffiti on the [target.name]." + to_chat(usr,"You start drawing graffiti on the [target.name].") if("rune") - user << "You start drawing a rune on the [target.name]." + to_chat(usr,"You start drawing a rune on the [target.name].") if("arrow") drawtype = input("Choose the arrow.", "Crayon scribbles") in list("left", "right", "up", "down") - user << "You start drawing an arrow on the [target.name]." + to_chat(usr,"You start drawing an arrow on the [target.name].") if(instant || do_after(user, 50)) new /obj/effect/decal/cleanable/crayon(target,colour,shadeColour,drawtype) - user << "You finish drawing." + to_chat(usr,"You finish drawing.") target.add_fingerprint(user) // Adds their fingerprints to the floor the crayon is drawn on. if(uses) uses-- if(!uses) - user << "You used up your crayon!" + to_chat(usr,"You used up your crayon!") qdel(src) return @@ -99,7 +99,93 @@ if(uses) uses -= 5 if(uses <= 0) - user << "You ate your crayon!" + to_chat(user,"You ate your crayon!") qdel(src) else ..() + +/obj/item/weapon/pen/crayon/marker/black + icon_state = "markerblack" + colour = "#2D2D2D" + shadeColour = "#000000" + colourName = "black" + +/obj/item/weapon/pen/crayon/marker/red + icon_state = "markerred" + colour = "#DA0000" + shadeColour = "#810C0C" + colourName = "red" + +/obj/item/weapon/pen/crayon/marker/orange + icon_state = "markerorange" + colour = "#FF9300" + shadeColour = "#A55403" + colourName = "orange" + +/obj/item/weapon/pen/crayon/marker/yellow + icon_state = "markeryellow" + colour = "#FFF200" + shadeColour = "#886422" + colourName = "yellow" + +/obj/item/weapon/pen/crayon/marker/green + icon_state = "markergreen" + colour = "#A8E61D" + shadeColour = "#61840F" + colourName = "green" + +/obj/item/weapon/pen/crayon/marker/blue + icon_state = "markerblue" + colour = "#00B7EF" + shadeColour = "#0082A8" + colourName = "blue" + +/obj/item/weapon/pen/crayon/marker/purple + icon_state = "markerpurple" + colour = "#DA00FF" + shadeColour = "#810CFF" + colourName = "purple" + +/obj/item/weapon/pen/crayon/marker/mime + icon_state = "markermime" + desc = "A very sad-looking marker." + colour = "#FFFFFF" + shadeColour = "#000000" + colourName = "mime" + uses = 0 + +/obj/item/weapon/pen/crayon/marker/mime/attack_self(mob/living/user as mob) //inversion + if(colour != "#FFFFFF" && shadeColour != "#000000") + colour = "#FFFFFF" + shadeColour = "#000000" + to_chat(usr,"You will now draw in white and black with this marker.") + else + colour = "#000000" + shadeColour = "#FFFFFF" + to_chat(usr,"You will now draw in black and white with this marker.") + return + +/obj/item/weapon/pen/crayon/marker/rainbow + icon_state = "markerrainbow" + colour = "#FFF000" + shadeColour = "#000FFF" + colourName = "rainbow" + uses = 0 + +/obj/item/weapon/pen/crayon/marker/rainbow/attack_self(mob/living/user as mob) + colour = input(user, "Please select the main colour.", "Marker colour") as color + shadeColour = input(user, "Please select the shade colour.", "Marker colour") as color + return + +/obj/item/weapon/pen/crayon/marker/attack(mob/M as mob, mob/user as mob) + if(M == user) + to_chat(usr,"You take a bite of the marker and swallow it.") + user.nutrition += 1 + user.reagents.add_reagent("marker_ink",6) + if(uses) + uses -= 5 + if(uses <= 0) + to_chat(user,"You ate the marker!") + qdel(src) + else + ..() \ No newline at end of file diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 7f1d83cc4a..78ee749ceb 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -11,7 +11,7 @@ var/global/list/obj/item/device/pda/PDAs = list() item_state = "electronic" w_class = ITEMSIZE_SMALL slot_flags = SLOT_ID | SLOT_BELT - sprite_sheets = list("Teshari" = 'icons/mob/species/seromi/id.dmi') + sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/seromi/id.dmi') //Main variables var/pdachoice = 1 @@ -1169,7 +1169,7 @@ var/global/list/obj/item/device/pda/PDAs = list() var/reception_message = "\icon[src] Message from [sender] ([sender_job]), \"[message]\" ([reply ? "Reply" : "Unable to Reply"])" new_info(message_silent, ttone, reception_message) - log_pda("[usr] (PDA: [sending_unit]) sent \"[message]\" to [name]") + log_pda("(PDA: [sending_unit]) sent \"[message]\" to [name]", usr) new_message = 1 update_icon() @@ -1181,7 +1181,7 @@ var/global/list/obj/item/device/pda/PDAs = list() var/reception_message = "\icon[src] Message from [sender] ([sender_job]), \"[message]\" (Reply) [track]" new_info(message_silent, newstone, reception_message) - log_pda("[usr] (PDA: [sending_unit]) sent \"[message]\" to [name]") + log_pda("(PDA: [sending_unit]) sent \"[message]\" to [name]",usr) new_message = 1 /obj/item/device/pda/verb/verb_reset_pda() @@ -1247,20 +1247,17 @@ var/global/list/obj/item/device/pda/PDAs = list() if(issilicon(usr)) return - if (can_use(usr) && !isnull(cartridge)) - var/turf/T = get_turf(src) - cartridge.loc = T - if (ismob(loc)) + if(can_use(usr) && !isnull(cartridge)) + cartridge.forceMove(get_turf(src)) + if(ismob(loc)) var/mob/M = loc M.put_in_hands(cartridge) - else - cartridge.loc = get_turf(src) mode = 0 scanmode = 0 if (cartridge.radio) cartridge.radio.hostpda = null - cartridge = null to_chat(usr, "You remove \the [cartridge] from the [name].") + cartridge = null else to_chat(usr, "You cannot do this while restrained.") @@ -1379,14 +1376,12 @@ var/global/list/obj/item/device/pda/PDAs = list() to_chat(user, "Blood type: [C:blood_DNA[blood]]\nDNA: [blood]") if(4) - for (var/mob/O in viewers(C, null)) - O.show_message("\The [user] has analyzed [C]'s radiation levels!", 1) - - user.show_message("Analyzing Results for [C]:") + user.visible_message("\The [user] has analyzed [C]'s radiation levels!", 1) + to_chat(user, "Analyzing Results for [C]:") if(C.radiation) - user.show_message("Radiation Level: [C.radiation]") + to_chat(user, "Radiation Level: [C.radiation]") else - user.show_message("No radiation detected.") + to_chat(user, "No radiation detected.") /obj/item/device/pda/afterattack(atom/A as mob|obj|turf|area, mob/user as mob, proximity) if(!proximity) return diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm index b77d73a262..4b088f51b8 100644 --- a/code/game/objects/items/devices/PDA/cart.dm +++ b/code/game/objects/items/devices/PDA/cart.dm @@ -265,8 +265,6 @@ var/list/civilian_cartridges = list( if(loc) var/obj/item/PDA = loc var/mob/user = PDA.fingerprintslast - if(istype(PDA.loc,/mob/living)) - name = PDA.loc log_admin("STATUS: [user] set status screen with [PDA]. Message: [data1] [data2]") message_admins("STATUS: [user] set status screen with [PDA]. Message: [data1] [data2]") diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm index ab893415ac..ebad249bde 100644 --- a/code/game/objects/items/devices/aicard.dm +++ b/code/game/objects/items/devices/aicard.dm @@ -61,7 +61,7 @@ if (href_list["wipe"]) var/confirm = alert("Are you sure you want to disable this core's power? This cannot be undone once started.", "Confirm Shutdown", "Yes", "No") if(confirm == "Yes" && (CanUseTopic(user, state) == STATUS_INTERACTIVE)) - admin_attack_log(user, carded_ai, "Purged using \the [src.name]", "Was purged with \the [src.name]", "used \the [src.name] to purge") + add_attack_logs(user,carded_ai,"Purged from AI Card") flush = 1 carded_ai.suiciding = 1 carded_ai << "Your power has been disabled!" @@ -110,7 +110,7 @@ new /obj/structure/AIcore/deactivated(get_turf(ai)) ai.carded = 1 - admin_attack_log(user, ai, "Extracted with [src.name]", "Was extracted with [src.name]", "used the [src.name] to extract") + add_attack_logs(user,ai,"Extracted into AI Card") src.name = "[initial(name)] - [ai.name]" ai.loc = src diff --git a/code/game/objects/items/devices/communicator/UI.dm b/code/game/objects/items/devices/communicator/UI.dm index 5df153c663..f2d3fd39b6 100644 --- a/code/game/objects/items/devices/communicator/UI.dm +++ b/code/game/objects/items/devices/communicator/UI.dm @@ -69,16 +69,17 @@ im_list_ui[++im_list_ui.len] = list("address" = I["address"], "to_address" = I["to_address"], "im" = I["im"]) //Weather reports. - for(var/datum/planet/planet in planet_controller.planets) - if(planet.weather_holder && planet.weather_holder.current_weather) - var/list/W = list( - "Planet" = planet.name, - "Time" = planet.current_time.show_time("hh:mm"), - "Weather" = planet.weather_holder.current_weather.name, - "Temperature" = planet.weather_holder.temperature - T0C, - "High" = planet.weather_holder.current_weather.temp_high - T0C, - "Low" = planet.weather_holder.current_weather.temp_low - T0C) - weather[++weather.len] = W + if(planet_controller) + for(var/datum/planet/planet in planet_controller.planets) + if(planet.weather_holder && planet.weather_holder.current_weather) + var/list/W = list( + "Planet" = planet.name, + "Time" = planet.current_time.show_time("hh:mm"), + "Weather" = planet.weather_holder.current_weather.name, + "Temperature" = planet.weather_holder.temperature - T0C, + "High" = planet.weather_holder.current_weather.temp_high - T0C, + "Low" = planet.weather_holder.current_weather.temp_low - T0C) + weather[++weather.len] = W injection = "
Test
" @@ -133,11 +134,7 @@ if(href_list["rename"]) var/new_name = sanitizeSafe(input(usr,"Please enter your name.","Communicator",usr.name) ) if(new_name) - owner = new_name - name = "[owner]'s [initial(name)]" - if(camera) - camera.name = name - camera.c_tag = name + register_device(new_name) if(href_list["toggle_visibility"]) switch(network_visibility) @@ -188,7 +185,7 @@ if(text) exonet.send_message(their_address, "text", text) im_list += list(list("address" = exonet.address, "to_address" = their_address, "im" = text)) - log_pda("[usr] (COMM: [src]) sent \"[text]\" to [exonet.get_atom_from_address(their_address)]") + log_pda("(COMM: [src]) sent \"[text]\" to [exonet.get_atom_from_address(their_address)]", usr) for(var/mob/M in player_list) if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears)) if(istype(M, /mob/new_player) || M.forbid_seeing_deadchat) @@ -251,4 +248,4 @@ set_light(fon * flum) nanomanager.update_uis(src) - add_fingerprint(usr) \ No newline at end of file + add_fingerprint(usr) diff --git a/code/game/objects/items/devices/communicator/communicator.dm b/code/game/objects/items/devices/communicator/communicator.dm index cac80c84d0..7342988916 100644 --- a/code/game/objects/items/devices/communicator/communicator.dm +++ b/code/game/objects/items/devices/communicator/communicator.dm @@ -75,12 +75,12 @@ var/global/list/obj/item/device/communicator/all_communicators = list() //This is a pretty terrible way of doing this. spawn(5 SECONDS) //Wait for our mob to finish spawning. if(ismob(loc)) - register_device(loc) + register_device(loc.name) initialize_exonet(loc) else if(istype(loc, /obj/item/weapon/storage)) var/obj/item/weapon/storage/S = loc if(ismob(S.loc)) - register_device(S.loc) + register_device(S.loc.name) initialize_exonet(S.loc) // Proc: examine() @@ -268,12 +268,12 @@ var/global/list/obj/item/device/communicator/all_communicators = list() // Proc: register_device() // Parameters: 1 (user - the person to use their name for) // Description: Updates the owner's name and the device's name. -/obj/item/device/communicator/proc/register_device(mob/user) - if(!user) +/obj/item/device/communicator/proc/register_device(new_name) + if(!new_name) return - owner = user.name + owner = new_name - name = "[owner]'s [initial(name)]" + name = "[new_name]'s [initial(name)]" if(camera) camera.name = name camera.c_tag = name @@ -287,17 +287,20 @@ var/global/list/obj/item/device/communicator/all_communicators = list() to_chat(voice, "\icon[src] Connection timed out with remote host.") qdel(voice) close_connection(reason = "Connection timed out") + + //Clean up all references we might have to others communicating.Cut() voice_requests.Cut() voice_invites.Cut() + node = null + + //Clean up references that might point at us all_communicators -= src processing_objects -= src listening_objects.Remove(src) - qdel(camera) - camera = null - if(exonet) - exonet.remove_address() - exonet = null + qdel_null(camera) + qdel_null(exonet) + return ..() // Proc: update_icon() diff --git a/code/game/objects/items/devices/communicator/messaging.dm b/code/game/objects/items/devices/communicator/messaging.dm index 3419985a71..d600f96a0f 100644 --- a/code/game/objects/items/devices/communicator/messaging.dm +++ b/code/game/objects/items/devices/communicator/messaging.dm @@ -136,7 +136,7 @@ to_chat(src, "You have sent '[text_message]' to [chosen_communicator].") exonet_messages.Add("To [chosen_communicator]:
[text_message]") - log_pda("[usr] (COMM: [src]) sent \"[text_message]\" to [chosen_communicator]") + log_pda("(DCOMM: [src]) sent \"[text_message]\" to [chosen_communicator]", src) for(var/mob/M in player_list) if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears)) if(istype(M, /mob/new_player) || M.forbid_seeing_deadchat) diff --git a/code/game/objects/items/devices/defib.dm b/code/game/objects/items/devices/defib.dm index 9eb4991f69..af9d697d63 100644 --- a/code/game/objects/items/devices/defib.dm +++ b/code/game/objects/items/devices/defib.dm @@ -475,7 +475,7 @@ if(burn_damage > 15 && H.can_feel_pain()) H.emote("scream") - admin_attack_log(user, H, "Electrocuted using \a [src]", "Was electrocuted with \a [src]", "used \a [src] to electrocute") + add_attack_logs(user,H,"Shocked using [name]") /obj/item/weapon/shockpaddles/proc/make_alive(mob/living/carbon/human/M) //This revives the mob var/deadtime = world.time - M.timeofdeath @@ -487,7 +487,6 @@ M.timeofdeath = 0 M.stat = UNCONSCIOUS //Life() can bring them back to consciousness if it needs to. - M.regenerate_icons() M.failed_last_breath = 0 //So mobs that died of oxyloss don't revive and have perpetual out of breath. M.reload_fullscreen() diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm index 6027976134..ac62201fc5 100644 --- a/code/game/objects/items/devices/flash.dm +++ b/code/game/objects/items/devices/flash.dm @@ -59,9 +59,7 @@ /obj/item/device/flash/attack(mob/living/M, mob/living/user, var/target_zone) if(!user || !M) return //sanity - M.attack_log += text("\[[time_stamp()]\] Has been flashed (attempt) with [src.name] by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to flash [M.name] ([M.ckey])") - msg_admin_attack("[user.name] ([user.ckey]) Used the [src.name] to flash [M.name] ([M.ckey]) (JMP)") + add_attack_logs(user,M,"Flashed (attempt) with [src]") user.setClickCooldown(user.get_attack_speed(src)) user.do_attack_animation(M) diff --git a/code/game/objects/items/devices/gps.dm b/code/game/objects/items/devices/gps.dm index 30d4195355..78f385a8aa 100644 --- a/code/game/objects/items/devices/gps.dm +++ b/code/game/objects/items/devices/gps.dm @@ -104,16 +104,16 @@ var/list/GPS_list = list() if(istype(their_area, /area/submap)) area_name = "Unknown Area" // Avoid spoilers. var/Z_name = using_map.get_zlevel_name(T.z) - var/direction = uppertext(dir2text(get_dir(curr, T))) + var/direction = get_adir(curr, T) + var/distX = T.x - curr.x + var/distY = T.y - curr.y var/distance = get_dist(curr, T) var/local = curr.z == T.z ? TRUE : FALSE - if(!direction) - direction = "CENTER" - if(istype(T, /obj/item/device/gps/internal/poi)) - signals += " [G.gps_tag]: [area_name] [local ? "Dist: [round(distance, 10)]m [direction])" : "in \the [Z_name]"]" + if(istype(gps, /obj/item/device/gps/internal/poi)) + signals += " [G.gps_tag]: [area_name] - [local ? "[direction] Dist: [round(distance, 10)]m" : "in \the [Z_name]"]" else - signals += " [G.gps_tag]: [area_name] [local ? "Dist: [round(distance, 10)]m [direction])" : "in \the [Z_name]"]" + signals += " [G.gps_tag]: [area_name], ([T.x], [T.y]) - [local ? "[direction] Dist: [distX ? "[abs(round(distX, 1))]m [(distX > 0) ? "E" : "W"], " : ""][distY ? "[abs(round(distY, 1))]m [(distY > 0) ? "N" : "S"]" : ""]" : "in \the [Z_name]"]" if(signals.len) dat += "Detected signals;" @@ -250,12 +250,9 @@ var/list/GPS_list = list() var/Z_name = using_map.get_zlevel_name(T.z) var/coord = "[T.x], [T.y], [Z_name]" var/degrees = round(Get_Angle(curr, T)) - var/direction = uppertext(dir2text(get_dir(curr, T))) + var/direction = get_adir(curr, T) var/distance = get_dist(curr, T) var/local = curr.z == T.z ? TRUE : FALSE - if(!direction) - direction = "CENTER" - degrees = "N/A" signals += " [G.gps_tag]: [area_name] ([coord]) [local ? "Dist: [distance]m Dir: [degrees]° ([direction])":""]" diff --git a/code/game/objects/items/devices/modkit.dm b/code/game/objects/items/devices/modkit.dm index ca7ace1a59..6ff95fe17d 100644 --- a/code/game/objects/items/devices/modkit.dm +++ b/code/game/objects/items/devices/modkit.dm @@ -7,7 +7,7 @@ desc = "A kit containing all the needed tools and parts to modify a hardsuit for another user." icon_state = "modkit" var/parts = MODKIT_FULL - var/target_species = "Human" + var/target_species = SPECIES_HUMAN var/list/permitted_types = list( /obj/item/clothing/head/helmet/space/void, @@ -69,4 +69,4 @@ /obj/item/device/modkit/tajaran name = "tajaran hardsuit modification kit" desc = "A kit containing all the needed tools and parts to modify a hardsuit for another user. This one looks like it's meant for Tajaran." - target_species = "Tajara" + target_species = SPECIES_TAJ diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index 3b703f703b..105eb3aa8f 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -3,11 +3,12 @@ desc = "An updated, modular intercom that fits over the head. Takes encryption keys" var/radio_desc = "" icon_state = "headset" + item_state = null //To remove the radio's state matter = list(DEFAULT_WALL_MATERIAL = 75) subspace_transmission = 1 canhear_range = 0 // can't hear headsets from very far away slot_flags = SLOT_EARS - sprite_sheets = list("Teshari" = 'icons/mob/species/seromi/ears.dmi') + sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/seromi/ears.dmi') var/translate_binary = 0 var/translate_hive = 0 @@ -63,6 +64,17 @@ return ..(freq, level) return -1 +/obj/item/device/radio/headset/get_worn_icon_state(var/slot_name) + var/append = "" + if(icon_override) + switch(slot_name) + if(slot_l_ear_str) + append = "_l" + if(slot_r_ear_str) + append = "_r" + + return "[..()][append]" + /obj/item/device/radio/headset/syndicate origin_tech = list(TECH_ILLEGAL = 3) syndie = 1 @@ -92,77 +104,66 @@ name = "security radio headset" desc = "This is used by your elite security force." icon_state = "sec_headset" - item_state = "headset" ks2type = /obj/item/device/encryptionkey/headset_sec /obj/item/device/radio/headset/headset_sec/alt name = "security bowman headset" desc = "This is used by your elite security force." icon_state = "sec_headset_alt" - item_state = "headset" ks2type = /obj/item/device/encryptionkey/headset_sec /obj/item/device/radio/headset/headset_eng name = "engineering radio headset" desc = "When the engineers wish to chat like girls." icon_state = "eng_headset" - item_state = "headset" ks2type = /obj/item/device/encryptionkey/headset_eng /obj/item/device/radio/headset/headset_eng/alt name = "engineering bowman headset" desc = "When the engineers wish to chat like girls." icon_state = "eng_headset_alt" - item_state = "headset" ks2type = /obj/item/device/encryptionkey/headset_eng /obj/item/device/radio/headset/headset_rob name = "robotics radio headset" desc = "Made specifically for the roboticists who cannot decide between departments." icon_state = "rob_headset" - item_state = "headset" ks2type = /obj/item/device/encryptionkey/headset_rob /obj/item/device/radio/headset/headset_med name = "medical radio headset" desc = "A headset for the trained staff of the medbay." icon_state = "med_headset" - item_state = "headset" ks2type = /obj/item/device/encryptionkey/headset_med /obj/item/device/radio/headset/headset_med/alt name = "medical bowman headset" desc = "A headset for the trained staff of the medbay." icon_state = "med_headset_alt" - item_state = "headset" ks2type = /obj/item/device/encryptionkey/headset_med /obj/item/device/radio/headset/headset_sci name = "science radio headset" desc = "A sciency headset. Like usual." icon_state = "com_headset" - item_state = "headset" ks2type = /obj/item/device/encryptionkey/headset_sci /obj/item/device/radio/headset/headset_medsci name = "medical research radio headset" desc = "A headset that is a result of the mating between medical and science." icon_state = "med_headset" - item_state = "headset" ks2type = /obj/item/device/encryptionkey/headset_medsci /obj/item/device/radio/headset/headset_com name = "command radio headset" desc = "A headset with a commanding channel." icon_state = "com_headset" - item_state = "headset" ks2type = /obj/item/device/encryptionkey/headset_com /obj/item/device/radio/headset/headset_com/alt name = "command bowman headset" desc = "A headset with a commanding channel." icon_state = "com_headset_alt" - item_state = "headset" ks2type = /obj/item/device/encryptionkey/headset_com @@ -170,21 +171,18 @@ name = "colony director's headset" desc = "The headset of the boss." icon_state = "com_headset" - item_state = "headset" ks2type = /obj/item/device/encryptionkey/heads/captain /obj/item/device/radio/headset/heads/captain/alt name = "colony director's bowman headset" desc = "The headset of the boss." icon_state = "com_headset_alt" - item_state = "headset" ks2type = /obj/item/device/encryptionkey/heads/captain /obj/item/device/radio/headset/heads/captain/sfr name = "SFR headset" desc = "A headset belonging to a Sif Free Radio DJ. SFR, best tunes in the wilderness." icon_state = "com_headset_alt" - item_state = "headset" ks2type = /obj/item/device/encryptionkey/heads/captain /obj/item/device/radio/headset/heads/ai_integrated //No need to care about icons, it should be hidden inside the AI anyway. @@ -206,105 +204,91 @@ name = "research director's headset" desc = "Headset of the researching God." icon_state = "com_headset" - item_state = "headset" ks2type = /obj/item/device/encryptionkey/heads/rd /obj/item/device/radio/headset/heads/rd/alt name = "research director's bowman headset" desc = "Headset of the researching God." icon_state = "com_headset_alt" - item_state = "headset" ks2type = /obj/item/device/encryptionkey/heads/rd /obj/item/device/radio/headset/heads/hos name = "head of security's headset" desc = "The headset of the man who protects your worthless lifes." icon_state = "com_headset" - item_state = "headset" ks2type = /obj/item/device/encryptionkey/heads/hos /obj/item/device/radio/headset/heads/hos/alt name = "head of security's bowman headset" desc = "The headset of the man who protects your worthless lifes." icon_state = "com_headset_alt" - item_state = "headset" ks2type = /obj/item/device/encryptionkey/heads/hos /obj/item/device/radio/headset/heads/ce name = "chief engineer's headset" desc = "The headset of the guy who is in charge of morons" icon_state = "com_headset" - item_state = "headset" ks2type = /obj/item/device/encryptionkey/heads/ce /obj/item/device/radio/headset/heads/ce/alt name = "chief engineer's bowman headset" desc = "The headset of the guy who is in charge of morons" icon_state = "com_headset_alt" - item_state = "headset" ks2type = /obj/item/device/encryptionkey/heads/ce /obj/item/device/radio/headset/heads/cmo name = "chief medical officer's headset" desc = "The headset of the highly trained medical chief." icon_state = "com_headset" - item_state = "headset" ks2type = /obj/item/device/encryptionkey/heads/cmo /obj/item/device/radio/headset/heads/cmo/alt name = "chief medical officer's bowman headset" desc = "The headset of the highly trained medical chief." icon_state = "com_headset_alt" - item_state = "headset" ks2type = /obj/item/device/encryptionkey/heads/cmo /obj/item/device/radio/headset/heads/hop name = "head of personnel's headset" desc = "The headset of the guy who will one day be Colony Director." icon_state = "com_headset" - item_state = "headset" ks2type = /obj/item/device/encryptionkey/heads/hop /obj/item/device/radio/headset/heads/hop/alt name = "head of personnel's bowman headset" desc = "The headset of the guy who will one day be Colony Director." icon_state = "com_headset_alt" - item_state = "headset" ks2type = /obj/item/device/encryptionkey/heads/hop -/* + /obj/item/device/radio/headset/headset_mine name = "mining radio headset" - desc = "Headset used by miners. How useless. To access the mining channel, use :d." + desc = "Headset used by miners. Has inbuilt short-band radio for when comms are down." icon_state = "mine_headset" - item_state = "headset" - keyslot2 = new /obj/item/device/encryptionkey/headset_mine -*/ + adhoc_fallback = TRUE + ks2type = /obj/item/device/encryptionkey/headset_cargo + /obj/item/device/radio/headset/headset_cargo name = "supply radio headset" desc = "A headset used by the QM and his slaves." icon_state = "cargo_headset" - item_state = "headset" ks2type = /obj/item/device/encryptionkey/headset_cargo /obj/item/device/radio/headset/headset_cargo/alt name = "supply bowman headset" desc = "A bowman headset used by the QM and his slaves." icon_state = "cargo_headset_alt" - item_state = "headset" ks2type = /obj/item/device/encryptionkey/headset_cargo /obj/item/device/radio/headset/headset_service name = "service radio headset" desc = "Headset used by the service staff, tasked with keeping the station full, happy and clean." icon_state = "srv_headset" - item_state = "headset" ks2type = /obj/item/device/encryptionkey/headset_service /obj/item/device/radio/headset/ert name = "emergency response team radio headset" desc = "The headset of the boss's boss." icon_state = "com_headset" - item_state = "headset" centComm = 1 // freerange = 1 ks2type = /obj/item/device/encryptionkey/ert @@ -313,7 +297,6 @@ name = "emergency response team bowman headset" desc = "The headset of the boss's boss." icon_state = "com_headset_alt" - item_state = "headset" // freerange = 1 ks2type = /obj/item/device/encryptionkey/ert @@ -324,7 +307,6 @@ name = "internal affair's headset" desc = "The headset of your worst enemy." icon_state = "com_headset" - item_state = "headset" ks2type = /obj/item/device/encryptionkey/heads/hos /obj/item/device/radio/headset/mmi_radio diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm index 9aa65bb54e..81e3227022 100644 --- a/code/game/objects/items/devices/radio/intercom.dm +++ b/code/game/objects/items/devices/radio/intercom.dm @@ -49,6 +49,12 @@ name = "entertainment intercom" frequency = ENT_FREQ +/obj/item/device/radio/intercom/omni + name = "global announcer" +/obj/item/device/radio/intercom/omni/initialize() + channels = radiochannels.Copy() + return ..() + /obj/item/device/radio/intercom/New() ..() processing_objects += src diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index b6f62f27dc..f5f85fe8f5 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -53,14 +53,13 @@ var/global/list/default_medbay_channels = list( var/const/FREQ_LISTENING = 1 var/list/internal_channels -/obj/item/device/radio var/datum/radio_frequency/radio_connection var/list/datum/radio_frequency/secure_radio_connections = new - proc/set_frequency(new_frequency) - radio_controller.remove_object(src, frequency) - frequency = new_frequency - radio_connection = radio_controller.add_object(src, frequency, RADIO_CHAT) +/obj/item/device/radio/proc/set_frequency(new_frequency) + radio_controller.remove_object(src, frequency) + frequency = new_frequency + radio_connection = radio_controller.add_object(src, frequency, RADIO_CHAT) /obj/item/device/radio/New() ..() diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index ae255d2f7b..feed24510b 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -3,9 +3,10 @@ CONTAINS: T-RAY DETECTIVE SCANNER HEALTH ANALYZER -GAS ANALYZER +GAS ANALYZER - Analyzes atmosphere, container MASS SPECTROMETER REAGENT SCANNER +HALOGEN COUNTER - Radcount on mobs */ @@ -41,29 +42,30 @@ REAGENT SCANNER scan_mob(M, user) /obj/item/device/healthanalyzer/proc/scan_mob(mob/living/M, mob/living/user) + var/dat = "" if ((CLUMSY in user.mutations) && prob(50)) - user << text("You try to analyze the floor's vitals!") - for(var/mob/O in viewers(M, null)) - O.show_message("\The [user] has analyzed the floor's vitals!", 1) - user.show_message("Analyzing Results for The floor:", 1) - user.show_message("Overall Status: Healthy", 1) - user.show_message(" Damage Specifics: 0-0-0-0", 1) - user.show_message("Key: Suffocation/Toxin/Burns/Brute", 1) - user.show_message("Body Temperature: ???", 1) + user.visible_message("\The [user] has analyzed the floor's vitals!", "You try to analyze the floor's vitals!") + dat += "Analyzing Results for the floor:
" + dat += "Overall Status: Healthy
" + dat += "\tDamage Specifics: 0-0-0-0
" + dat += "Key: Suffocation/Toxin/Burns/Brute
" + dat += "Body Temperature: ???" + user.show_message("[dat]", 1) return - if (!(istype(usr, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") - usr << "You don't have the dexterity to do this!" + if (!(ishuman(user) || ticker) && ticker.mode.name != "monkey") + to_chat(user, "You don't have the dexterity to do this!") return user.visible_message("[user] has analyzed [M]'s vitals.","You have analyzed [M]'s vitals.") - if (!istype(M,/mob/living/carbon/human) || M.isSynthetic()) + if (!ishuman(M) || M.isSynthetic()) //these sensors are designed for organic life - user.show_message("Analyzing Results for ERROR:\n\t Overall Status: ERROR") - user.show_message(" Key: Suffocation/Toxin/Burns/Brute", 1) - user.show_message(" Damage Specifics: ? - ? - ? - ?") - user.show_message("Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1) - user.show_message("Warning: Blood Level ERROR: --% --cl. Type: ERROR") - user.show_message("Subject's pulse: -- bpm.") + dat += "Analyzing Results for ERROR:\n\tOverall Status: ERROR
" + dat += "\tKey: Suffocation/Toxin/Burns/Brute
" + dat += "\tDamage Specifics: ? - ? - ? - ?
" + dat += "Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)

" + dat += "Warning: Blood Level ERROR: --% --cl. Type: ERROR
" + dat += "Subject's pulse: -- bpm." + user.show_message(dat, 1) return var/fake_oxy = max(rand(1,40), M.getOxyLoss(), (300 - (M.getToxLoss() + M.getFireLoss() + M.getBruteLoss()))) @@ -73,52 +75,52 @@ REAGENT SCANNER var/BR = M.getBruteLoss() > 50 ? "[M.getBruteLoss()]" : M.getBruteLoss() if(M.status_flags & FAKEDEATH) OX = fake_oxy > 50 ? "[fake_oxy]" : fake_oxy - user.show_message("Analyzing Results for [M]:") - user.show_message("Overall Status: dead") + dat += "Analyzing Results for [M]:
" + dat += "Overall Status: dead
" else - user.show_message("Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "dead" : "[round((M.health/M.getMaxHealth())*100) ]% healthy"]") - user.show_message(" Key: Suffocation/Toxin/Burns/Brute", 1) - user.show_message(" Damage Specifics: [OX] - [TX] - [BU] - [BR]") - user.show_message("Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1) + dat += "Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "dead" : "[round((M.health/M.getMaxHealth())*100) ]% healthy"]
" + dat += "\tKey: Suffocation/Toxin/Burns/Brute
" + dat += "\tDamage Specifics: [OX] - [TX] - [BU] - [BR]
" + dat += "Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)

" if(M.tod && (M.stat == DEAD || (M.status_flags & FAKEDEATH))) - user.show_message("Time of Death: [M.tod]") + dat += "Time of Death: [M.tod]
" if(istype(M, /mob/living/carbon/human) && mode == 1) var/mob/living/carbon/human/H = M var/list/damaged = H.get_damaged_organs(1,1) - user.show_message("Localized Damage, Brute/Burn:",1) + dat += "Localized Damage, Brute/Burn:
" if(length(damaged)>0) for(var/obj/item/organ/external/org in damaged) if(org.robotic >= ORGAN_ROBOT) continue else - user.show_message(text(" []: [][] - []", - capitalize(org.name), - (org.brute_dam > 0) ? "[org.brute_dam]" : 0, - (org.status & ORGAN_BLEEDING)?"\[Bleeding\]":"", - (org.burn_dam > 0) ? "[org.burn_dam]" : 0),1) + dat += " [capitalize(org.name)]: [(org.brute_dam > 0) ? "[org.brute_dam]" : 0]" + dat += "[(org.status & ORGAN_BLEEDING)?"\[Bleeding\]":""] - " + dat += "[(org.burn_dam > 0) ? "[org.burn_dam]" : 0]
" else - user.show_message(" Limbs are OK.",1) + dat += " Limbs are OK.
" - OX = M.getOxyLoss() > 50 ? "Severe oxygen deprivation detected" : "Subject bloodstream oxygen level normal" - TX = M.getToxLoss() > 50 ? "Dangerous amount of toxins detected" : "Subject bloodstream toxin level minimal" - BU = M.getFireLoss() > 50 ? "Severe burn damage detected" : "Subject burn injury status O.K" + OX = M.getOxyLoss() > 50 ? "Severe oxygen deprivation detected" : "Subject bloodstream oxygen level normal" + TX = M.getToxLoss() > 50 ? "Dangerous amount of toxins detected" : "Subject bloodstream toxin level minimal" + BU = M.getFireLoss() > 50 ? "Severe burn damage detected" : "Subject burn injury status O.K" BR = M.getBruteLoss() > 50 ? "Severe anatomical damage detected" : "Subject brute-force injury status O.K" if(M.status_flags & FAKEDEATH) OX = fake_oxy > 50 ? "Severe oxygen deprivation detected" : "Subject bloodstream oxygen level normal" - user.show_message("[OX] | [TX] | [BU] | [BR]") + dat += "[OX] | [TX] | [BU] | [BR]
" if(M.radiation) if(advscan >= 2 && showadvscan == 1) + var/severity = "" if(M.radiation >= 75) - user.show_message("Critical levels of radiation detected. Immediate treatment advised.") + severity = "Critical" else if(M.radiation >= 50) - user.show_message("Severe levels of radiation detected.") + severity = "Severe" else if(M.radiation >= 25) - user.show_message("Moderate levels of radiation detected.") + severity = "Moderate" else if(M.radiation >= 1) - user.show_message("Low levels of radiation detected.") + severity = "Low" + dat += "[severity] levels of radiation detected. [(severity == "Critical") ? " Immediate treatment advised." : ""]
" else - user.show_message("Radiation detected.") - if(istype(M, /mob/living/carbon)) + dat += "Radiation detected.
" + if(iscarbon(M)) var/mob/living/carbon/C = M if(C.reagents.total_volume) var/unknown = 0 @@ -127,21 +129,21 @@ REAGENT SCANNER for(var/A in C.reagents.reagent_list) var/datum/reagent/R = A if(R.scannable) - reagentdata["[R.id]"] = " [round(C.reagents.get_reagent_amount(R.id), 1)]u [R.name]" + reagentdata["[R.id]"] = "\t[round(C.reagents.get_reagent_amount(R.id), 1)]u [R.name]
" else unknown++ - unknownreagents["[R.id]"] = " [round(C.reagents.get_reagent_amount(R.id), 1)]u [R.name]" + unknownreagents["[R.id]"] = "\t[round(C.reagents.get_reagent_amount(R.id), 1)]u [R.name]
" if(reagentdata.len) - user.show_message("Beneficial reagents detected in subject's blood:") + dat += "Beneficial reagents detected in subject's blood:
" for(var/d in reagentdata) - user.show_message(reagentdata[d]) + dat += reagentdata[d] if(unknown) if(advscan >= 3 && showadvscan == 1) - user.show_message("Warning: Non-medical reagent[(unknown>1)?"s":""] detected in subject's blood:") + dat += "Warning: Non-medical reagent[(unknown>1)?"s":""] detected in subject's blood:
" for(var/d in unknownreagents) - user.show_message(unknownreagents[d]) + dat += unknownreagents[d] else - user.show_message("Warning: Unknown substance[(unknown>1)?"s":""] detected in subject's blood.") + dat += "Warning: Unknown substance[(unknown>1)?"s":""] detected in subject's blood.
" if(C.ingested && C.ingested.total_volume) var/unknown = 0 var/stomachreagentdata[0] @@ -149,100 +151,104 @@ REAGENT SCANNER for(var/B in C.ingested.reagent_list) var/datum/reagent/T = B if(T.scannable) - stomachreagentdata["[T.id]"] = " [round(C.ingested.get_reagent_amount(T.id), 1)]u [T.name]" + stomachreagentdata["[T.id]"] = "\t[round(C.ingested.get_reagent_amount(T.id), 1)]u [T.name]
" if (advscan == 0 || showadvscan == 0) - user.show_message("[T.name] found in subject's stomach.") + dat += "[T.name] found in subject's stomach.
" else ++unknown - stomachunknownreagents["[T.id]"] = " [round(C.ingested.get_reagent_amount(T.id), 1)]u [T.name]" + stomachunknownreagents["[T.id]"] = "\t[round(C.ingested.get_reagent_amount(T.id), 1)]u [T.name]
" if(advscan >= 1 && showadvscan == 1) - user.show_message("Beneficial reagents detected in subject's stomach:") + dat += "Beneficial reagents detected in subject's stomach:
" for(var/d in stomachreagentdata) - user.show_message(stomachreagentdata[d]) + dat += stomachreagentdata[d] if(unknown) if(advscan >= 3 && showadvscan == 1) - user.show_message("Warning: Non-medical reagent[(unknown > 1)?"s":""] found in subject's stomach:") + dat += "Warning: Non-medical reagent[(unknown > 1)?"s":""] found in subject's stomach:
" for(var/d in stomachunknownreagents) - user.show_message(stomachunknownreagents[d]) + dat += stomachunknownreagents[d] else - user.show_message("Unknown substance[(unknown > 1)?"s":""] found in subject's stomach.") + dat += "Unknown substance[(unknown > 1)?"s":""] found in subject's stomach.
" if(C.virus2.len) for (var/ID in C.virus2) if (ID in virusDB) var/datum/data/record/V = virusDB[ID] - user.show_message("Warning: Pathogen [V.fields["name"]] detected in subject's blood. Known antigen : [V.fields["antigen"]]") + dat += "Warning: Pathogen [V.fields["name"]] detected in subject's blood. Known antigen : [V.fields["antigen"]]
" else - user.show_message("Warning: Unknown pathogen detected in subject's blood.") + dat += "Warning: Unknown pathogen detected in subject's blood.
" if (M.getCloneLoss()) - user.show_message("Subject appears to have been imperfectly cloned.") + dat += "Subject appears to have been imperfectly cloned.
" // if (M.reagents && M.reagents.get_reagent_amount("inaprovaline")) // user.show_message("Bloodstream Analysis located [M.reagents:get_reagent_amount("inaprovaline")] units of rejuvenation chemicals.") if (M.has_brain_worms()) - user.show_message("Subject suffering from aberrant brain activity. Recommend further scanning.") + dat += "Subject suffering from aberrant brain activity. Recommend further scanning.
" else if (M.getBrainLoss() >= 60 || !M.has_brain()) - user.show_message("Subject is brain dead.") + dat += "Subject is brain dead.
" else if (M.getBrainLoss() >= 25) - user.show_message("Severe brain damage detected. Subject likely to have a traumatic brain injury.") + dat += "Severe brain damage detected. Subject likely to have a traumatic brain injury.
" else if (M.getBrainLoss() >= 10) - user.show_message("Significant brain damage detected. Subject may have had a concussion.") + dat += "Significant brain damage detected. Subject may have had a concussion.
" else if (M.getBrainLoss() >= 1 && advscan >= 2 && showadvscan == 1) - user.show_message("Minor brain damage detected.") + dat += "Minor brain damage detected.
" if(ishuman(M)) var/mob/living/carbon/human/H = M - for(var/name_i in H.internal_organs_by_name) - var/obj/item/organ/internal/i = H.internal_organs_by_name[name_i] - if(istype(i, /obj/item/organ/internal/appendix)) - var/obj/item/organ/internal/appendix/a = H.internal_organs_by_name[name_i] - if(a.inflamed > 3) - user.show_message(text("Severe inflammation detected in subject [a.name]."), 1) - else if(a.inflamed > 2) - user.show_message(text("Moderate inflammation detected in subject [a.name]."), 1) - else if(a.inflamed >= 1) - user.show_message(text("Mild inflammation detected in subject [a.name]."), 1) - - - for(var/name in H.organs_by_name) - var/obj/item/organ/external/e = H.organs_by_name[name] - if(!e) - continue - var/limb = e.name - if(e.status & ORGAN_BROKEN) - if(((e.name == "l_arm") || (e.name == "r_arm") || (e.name == "l_leg") || (e.name == "r_leg")) && (!e.splinted)) - to_chat(user, "Unsecured fracture in subject [limb]. Splinting recommended for transport.") - if(e.has_infected_wound()) - to_chat(user, "Infected wound detected in subject [limb]. Disinfection recommended.") - - for(var/name in H.organs_by_name) - var/obj/item/organ/external/e = H.organs_by_name[name] - if(e && e.status & ORGAN_BROKEN) - if(advscan >= 1 && showadvscan == 1) - user.show_message(text("Bone fractures detected in subject [e.name]."), 1) - else - user.show_message(text("Bone fractures detected. Advanced scanner required for location."), 1) - break + for(var/obj/item/organ/internal/appendix/a in H.internal_organs) + var/severity = "" + if(a.inflamed > 3) + severity = "Severe" + else if(a.inflamed > 2) + severity = "Moderate" + else if(a.inflamed >= 1) + severity = "Mild" + if(severity) + dat += "[severity] inflammation detected in subject [a.name].
" + // Infections, fractures, and IB + var/basic_fracture = 0 // If it's a basic scanner + var/basic_ib = 0 // If it's a basic scanner + var/fracture_dat = "" // All the fractures + var/infection_dat = "" // All the infections + var/ib_dat = "" // All the IB for(var/obj/item/organ/external/e in H.organs) if(!e) continue - for(var/datum/wound/W in e.wounds) if(W.internal) - if(advscan >= 1 && showadvscan == 1) - user.show_message(text("Internal bleeding detected in subject [e.name]."), 1) + // Broken limbs + if(e.status & ORGAN_BROKEN) + if((e.name in list("l_arm", "r_arm", "l_leg", "r_leg")) && (!e.splinted)) + fracture_dat += "Unsecured fracture in subject [e.name]. Splinting recommended for transport.
" + else if(advscan >= 1 && showadvscan == 1) + fracture_dat += "Bone fractures detected in subject [e.name].
" else - user.show_message(text("Internal bleeding detected. Advanced scanner required for location."), 1) - break - break + basic_fracture = 1 + // Infections + if(e.has_infected_wound()) + dat += "Infected wound detected in subject [e.name]. Disinfection recommended.
" + // IB + for(var/datum/wound/W in e.wounds) + if(W.internal) + if(advscan >= 1 && showadvscan == 1) + ib_dat += "Internal bleeding detected in subject [e.name].
" + else + basic_ib = 1 + if(basic_fracture) + fracture_dat += "Bone fractures detected. Advanced scanner required for location.
" + if(basic_ib) + ib_dat += "Internal bleeding detected. Advanced scanner required for location.
" + dat += fracture_dat + dat += infection_dat + dat += ib_dat + // Blood level if(M:vessel) var/blood_volume = H.vessel.get_reagent_amount("blood") var/blood_percent = round((blood_volume / H.species.blood_volume)*100) var/blood_type = H.dna.b_type - if((blood_percent <= BLOOD_VOLUME_SAFE) && (blood_percent > BLOOD_VOLUME_BAD)) - user.show_message("Warning: Blood Level LOW: [blood_percent]% [blood_volume]cl. Type: [blood_type]") - else if(blood_percent <= BLOOD_VOLUME_BAD) - user.show_message("Warning: Blood Level CRITICAL: [blood_percent]% [blood_volume]cl. Type: [blood_type]") + if(blood_percent <= BLOOD_VOLUME_BAD) + dat += "Warning: Blood Level CRITICAL: [blood_percent]% [blood_volume]cl. Type: [blood_type]
" + else if(blood_percent <= BLOOD_VOLUME_SAFE) + dat += "Warning: Blood Level LOW: [blood_percent]% [blood_volume]cl. Type: [blood_type]
" else - user.show_message("Blood Level Normal: [blood_percent]% [blood_volume]cl. Type: [blood_type]") - user.show_message("Subject's pulse: [H.get_pulse(GETPULSE_TOOL)] bpm.") - + dat += "Blood Level Normal: [blood_percent]% [blood_volume]cl. Type: [blood_type]
" + dat += "Subject's pulse: [H.get_pulse(GETPULSE_TOOL)] bpm." + user.show_message(dat, 1) /obj/item/device/healthanalyzer/verb/toggle_mode() set name = "Switch Verbosity" @@ -266,15 +272,15 @@ REAGENT SCANNER if(0) to_chat(usr, "The scanner will now perform a basic analysis.") -/obj/item/device/healthanalyzer/advanced //reports bone fractures, IB, quantity of beneficial reagents in stomach; also regular health analyzer stuff - name = "advanced health analyzer" +/obj/item/device/healthanalyzer/improved //reports bone fractures, IB, quantity of beneficial reagents in stomach; also regular health analyzer stuff + name = "improved health analyzer" desc = "A miracle of medical technology, this handheld scanner can produce an accurate and specific report of a patient's biosigns." advscan = 1 origin_tech = list(TECH_MAGNET = 5, TECH_BIO = 6) icon_state = "health1" -/obj/item/device/healthanalyzer/enhanced //reports all of the above, as well as radiation severity and minor brain damage - name = "enhanced health analyzer" +/obj/item/device/healthanalyzer/advanced //reports all of the above, as well as radiation severity and minor brain damage + name = "advanced health analyzer" desc = "An even more advanced handheld health scanner, complete with a full biosign monitor and on-board radiation and neurological analysis suites." advscan = 2 origin_tech = list(TECH_MAGNET = 6, TECH_BIO = 7) @@ -311,16 +317,21 @@ REAGENT SCANNER return atmosanalyzer_scan(src, air, user) /obj/item/device/analyzer/attack_self(mob/user as mob) - if (user.stat) return - if (!(istype(usr, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") + if (!(ishuman(user) || ticker) && ticker.mode.name != "monkey") to_chat(usr, "You don't have the dexterity to do this!") return analyze_gases(src, user) return +/obj/item/device/analyzer/afterattack(var/obj/O, var/mob/user, var/proximity) + if(proximity) + analyze_gases(O, user) + return + + /obj/item/device/mass_spectrometer name = "mass spectrometer" desc = "A hand-held mass spectrometer which identifies trace chemicals in a blood sample." @@ -353,7 +364,7 @@ REAGENT SCANNER /obj/item/device/mass_spectrometer/attack_self(mob/user as mob) if (user.stat) return - if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") + if (!(ishuman(user) || ticker) && ticker.mode.name != "monkey") to_chat(user, "You don't have the dexterity to do this!") return if(reagents.total_volume) @@ -400,15 +411,11 @@ REAGENT SCANNER var/recent_fail = 0 /obj/item/device/reagent_scanner/afterattack(obj/O, mob/user as mob, proximity) - if(!proximity) - return - if (user.stat) + if(!proximity || user.stat || !istype(O)) return if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") to_chat(user, "You don't have the dexterity to do this!") return - if(!istype(O)) - return if(!isnull(O.reagents)) var/dat = "" @@ -419,9 +426,9 @@ REAGENT SCANNER if(dat) to_chat(user, "Chemicals found: [dat]") else - user << "No active chemical agents found in [O]." + to_chat(user, "No active chemical agents found in [O].") else - user << "No significant chemical agents found in [O]." + to_chat(user, "No significant chemical agents found in [O].") return @@ -445,24 +452,17 @@ REAGENT SCANNER /obj/item/device/slime_scanner/attack(mob/living/M as mob, mob/living/user as mob) if(!isslime(M)) - user << "This device can only scan slimes!" + to_chat(user, "This device can only scan slimes!") return var/mob/living/simple_animal/slime/S = M - user.show_message("Slime scan results:") - user.show_message(text("[S.slime_color] [] slime", S.is_adult ? "adult" : "baby")) - - user.show_message("Health: [S.health]") - user.show_message("Mutation Probability: [S.mutation_chance]") + user.show_message("Slime scan results:
[S.slime_color] [S.is_adult ? "adult" : "baby"] slime
Health: [S.health]
Mutation Probability: [S.mutation_chance]") var/list/mutations = list() for(var/potential_color in S.slime_mutation) var/mob/living/simple_animal/slime/slime = potential_color mutations.Add(initial(slime.slime_color)) + user.show_message("Potental to mutate into [english_list(mutations)] colors.
Extract potential: [S.cores]
Nutrition: [S.nutrition]/[S.get_max_nutrition()]") - user.show_message("Potental to mutate into [english_list(mutations)] colors.") - user.show_message("Extract potential: [S.cores]") - - user.show_message(text("Nutrition: [S.nutrition]/[]", S.get_max_nutrition())) if (S.nutrition < S.get_starve_nutrition()) user.show_message("Warning: Subject is starving!") else if (S.nutrition < S.get_hunger_nutrition()) @@ -479,3 +479,25 @@ REAGENT SCANNER user.show_message("Subject is friendly to other slime colors.") user.show_message("Growth progress: [S.amount_grown]/10") + +/obj/item/device/halogen_counter + name = "halogen counter" + icon_state = "eftpos" + desc = "A hand-held halogen counter, used to detect the level of irradiation of living beings." + w_class = ITEMSIZE_SMALL + flags = CONDUCT + origin_tech = list(TECH_MAGNET = 1, TECH_BIO = 2) + throwforce = 0 + throw_speed = 3 + throw_range = 7 + +/obj/item/device/halogen_counter/attack(mob/living/M as mob, mob/living/user as mob) + if(!iscarbon(M)) + to_chat(user, "This device can only scan organic beings!") + return + user.visible_message("\The [user] has analyzed [M]'s radiation levels!", "Analyzing Results for [M]:") + if(M.radiation) + to_chat(user, "Radiation Level: [M.radiation]") + else + to_chat(user, "No radiation detected.") + return diff --git a/code/game/objects/items/devices/spy_bug.dm b/code/game/objects/items/devices/spy_bug.dm index 159134f83c..ce145fed9e 100644 --- a/code/game/objects/items/devices/spy_bug.dm +++ b/code/game/objects/items/devices/spy_bug.dm @@ -16,11 +16,12 @@ // var/obj/item/device/radio/bug/radio var/obj/machinery/camera/bug/camera + var/camtype = /obj/machinery/camera/bug /obj/item/device/camerabug/New() ..() // radio = new(src) - camera = new(src) + camera = new camtype(src) /obj/item/device/camerabug/attack_self(mob/user) if(user.a_intent == I_HURT) @@ -40,7 +41,7 @@ linkedmonitor.unpair(src) linkedmonitor = null qdel(camera) - camera = new(src) + camera = new camtype(src) to_chat(usr, "You turn the [src] off and on again, delinking it from any monitors.") /obj/item/brokenbug @@ -83,6 +84,7 @@ w_class = ITEMSIZE_TINY slot_flags = SLOT_EARS origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1, TECH_ILLEGAL = 3) + camtype = /obj/machinery/camera/bug/spy /obj/item/device/camerabug/examine(mob/user) . = ..(user, 0) diff --git a/code/game/objects/items/devices/suit_cooling.dm b/code/game/objects/items/devices/suit_cooling.dm index a2d6ce3341..2040f22a99 100644 --- a/code/game/objects/items/devices/suit_cooling.dm +++ b/code/game/objects/items/devices/suit_cooling.dm @@ -46,9 +46,15 @@ var/mob/living/carbon/human/H = loc - var/efficiency = 1 - H.get_pressure_weakness() //you need to have a good seal for effective cooling - var/env_temp = get_environment_temperature() //wont save you from a fire - var/temp_adj = min(H.bodytemperature - max(thermostat, env_temp), max_cooling) + var/efficiency = 1 - H.get_pressure_weakness() // You need to have a good seal for effective cooling + var/temp_adj = 0 // How much the unit cools you. Adjusted later on. + var/env_temp = get_environment_temperature() // This won't save you from a fire + var/thermal_protection = H.get_heat_protection(env_temp) // ... unless you've got a good suit. + + if(thermal_protection < 0.99) //For some reason, < 1 returns false if the value is 1. + temp_adj = min(H.bodytemperature - max(thermostat, env_temp), max_cooling) + else + temp_adj = min(H.bodytemperature - thermostat, max_cooling) if (temp_adj < 0.5) //only cools, doesn't heat, also we don't need extreme precision return diff --git a/code/game/objects/items/devices/traitordevices.dm b/code/game/objects/items/devices/traitordevices.dm index 126a4871c9..7820d0c4ea 100644 --- a/code/game/objects/items/devices/traitordevices.dm +++ b/code/game/objects/items/devices/traitordevices.dm @@ -35,9 +35,9 @@ effective or pretty fucking useless. user << "The mind batterer has been burnt out!" return - user.attack_log += text("\[[time_stamp()]\] Used [src] to knock down people in the area.") - + var/list/affected = list() for(var/mob/living/carbon/human/M in orange(10, user)) + affected += M spawn() if(prob(50)) @@ -49,6 +49,8 @@ effective or pretty fucking useless. else M << "You feel a sudden, electric jolt travel through your head." + add_attack_logs(user,affected,"Used a [name]") + playsound(src.loc, 'sound/misc/interference.ogg', 50, 1) user << "You trigger [src]." times_used += 1 diff --git a/code/game/objects/items/devices/translator.dm b/code/game/objects/items/devices/translator.dm index 5de1ba1396..fc6352de29 100644 --- a/code/game/objects/items/devices/translator.dm +++ b/code/game/objects/items/devices/translator.dm @@ -4,7 +4,7 @@ desc = "This handy device appears to translate the languages it hears into onscreen text for a user." icon = 'icons/obj/device.dmi' icon_state = "translator" - w_class = ITEMSIZE_SMALL + w_class = ITEMSIZE_NORMAL origin_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 3) var/mult_icons = 1 //Changes sprite when it translates var/visual = 1 //If you need to see to get the message diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index 9a56cf94a7..2fa9ea63c7 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -106,13 +106,13 @@ if (M.use(1)) var/obj/item/weapon/secbot_assembly/ed209_assembly/B = new /obj/item/weapon/secbot_assembly/ed209_assembly B.loc = get_turf(src) - user << "You armed the robot frame." + to_chat(user, "You armed the robot frame.") if (user.get_inactive_hand()==src) user.remove_from_mob(src) user.put_in_inactive_hand(B) qdel(src) else - user << "You need one sheet of metal to arm the robot frame." + to_chat(user, "You need one sheet of metal to arm the robot frame.") if(istype(W, /obj/item/robot_parts/l_leg)) if(src.l_leg) return user.drop_item() @@ -149,9 +149,9 @@ src.chest = W src.updateicon() else if(!W:wires) - user << "You need to attach wires to it first!" + to_chat(user, "You need to attach wires to it first!") else - user << "You need to attach a cell to it first!" + to_chat(user, "You need to attach a cell to it first!") if(istype(W, /obj/item/robot_parts/head)) if(src.head) return @@ -161,16 +161,16 @@ src.head = W src.updateicon() else - user << "You need to attach a flash to it first!" + to_chat(user, "You need to attach a flash to it first!") if(istype(W, /obj/item/device/mmi)) var/obj/item/device/mmi/M = W if(check_completion()) if(!istype(loc,/turf)) - user << "You can't put \the [W] in, the frame has to be standing on the ground to be perfectly precise." + to_chat(user, "You can't put \the [W] in, the frame has to be standing on the ground to be perfectly precise.") return if(!M.brainmob) - user << "Sticking an empty [W] into the frame would sort of defeat the purpose." + to_chat(user, "Sticking an empty [W] into the frame would sort of defeat the purpose.") return if(!M.brainmob.key) var/ghost_can_reenter = 0 @@ -181,15 +181,15 @@ to_chat(user, "\The [W] is completely unresponsive; though it may be able to auto-resuscitate.") //Jamming a ghosted brain into a borg is likely detrimental, and may result in some problems. return if(!ghost_can_reenter) - user << "\The [W] is completely unresponsive; there's no point." + to_chat(user, "\The [W] is completely unresponsive; there's no point.") return if(M.brainmob.stat == DEAD) - user << "Sticking a dead [W] into the frame would sort of defeat the purpose." + to_chat(user, "Sticking a dead [W] into the frame would sort of defeat the purpose.") return if(jobban_isbanned(M.brainmob, "Cyborg")) - user << "This [W] does not seem to fit." + to_chat(user, "This [W] does not seem to fit.") return var/mob/living/silicon/robot/O = new /mob/living/silicon/robot(get_turf(loc), unfinished = 1) @@ -228,7 +228,7 @@ qdel(src) else - user << "The MMI must go in after everything else!" + to_chat(user, "The MMI must go in after everything else!") if (istype(W, /obj/item/weapon/pen)) var/t = sanitizeSafe(input(user, "Enter new robot name", src.name, src.created_name), MAX_NAME_LEN) @@ -245,22 +245,22 @@ ..() if(istype(W, /obj/item/weapon/cell)) if(src.cell) - user << "You have already inserted a cell!" + to_chat(user, "You have already inserted a cell!") return else user.drop_item() W.loc = src src.cell = W - user << "You insert the cell!" + to_chat(user, "You insert the cell!") if(istype(W, /obj/item/stack/cable_coil)) if(src.wires) - user << "You have already inserted wire!" + to_chat(user, "You have already inserted wire!") return else var/obj/item/stack/cable_coil/coil = W coil.use(1) src.wires = 1.0 - user << "You insert the wire!" + to_chat(user, "You insert the wire!") return /obj/item/robot_parts/head/attackby(obj/item/W as obj, mob/user as mob) @@ -269,14 +269,14 @@ if(istype(user,/mob/living/silicon/robot)) var/current_module = user.get_active_hand() if(current_module == W) - user << "How do you propose to do that?" + to_chat(user, "How do you propose to do that?") return else add_flashes(W,user) else add_flashes(W,user) else if(istype(W, /obj/item/weapon/stock_parts/manipulator)) - user << "You install some manipulators and modify the head, creating a functional spider-bot!" + to_chat(user, "You install some manipulators and modify the head, creating a functional spider-bot!") new /mob/living/simple_animal/spiderbot(get_turf(loc)) user.drop_item() qdel(W) @@ -286,24 +286,24 @@ /obj/item/robot_parts/head/proc/add_flashes(obj/item/W as obj, mob/user as mob) //Made into a seperate proc to avoid copypasta if(src.flash1 && src.flash2) - user << "You have already inserted the eyes!" + to_chat(user, "You have already inserted the eyes!") return else if(src.flash1) user.drop_item() W.loc = src src.flash2 = W - user << "You insert the flash into the eye socket!" + to_chat(user, "You insert the flash into the eye socket!") else user.drop_item() W.loc = src src.flash1 = W - user << "You insert the flash into the eye socket!" + to_chat(user, "You insert the flash into the eye socket!") /obj/item/robot_parts/emag_act(var/remaining_charges, var/mob/user) if(sabotaged) - user << "[src] is already sabotaged!" + to_chat(user, "[src] is already sabotaged!") else - user << "You short out the safeties." + to_chat(user, "You short out the safeties.") sabotaged = 1 return 1 diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index eed9d9dc49..63a2ea474e 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -134,7 +134,7 @@ return 1 /obj/item/borg/upgrade/jetpack - name = "mining robot jetpack" + name = "robot jetpack" desc = "A carbon dioxide jetpack suitable for low-gravity operations." icon_state = "cyborg_upgrade3" item_state = "cyborg_upgrade" @@ -149,7 +149,7 @@ if(!T) T = locate() in R.module.modules if(!T) - R.module.modules += new/obj/item/weapon/tank/jetpack/carbondioxide + R.module.modules += new/obj/item/weapon/tank/jetpack/carbondioxide(R.module) for(var/obj/item/weapon/tank/jetpack/carbondioxide in R.module.modules) R.internals = src return 1 @@ -174,7 +174,7 @@ if(!T) T = locate() in R.module.modules if(!T) - R.module.modules += new/obj/item/device/healthanalyzer/advanced + R.module.modules += new/obj/item/device/healthanalyzer/advanced(R.module) return 1 if(T) to_chat(R, "Upgrade mounting error! No suitable hardpoint detected!") @@ -210,9 +210,12 @@ R.add_language(LANGUAGE_TRADEBAND, 1) R.add_language(LANGUAGE_UNATHI, 1) R.add_language(LANGUAGE_SIIK, 1) + R.add_language(LANGUAGE_AKHANI, 1) R.add_language(LANGUAGE_SKRELLIAN, 1) + R.add_language(LANGUAGE_SKRELLIANFAR, 0) R.add_language(LANGUAGE_GUTTER, 1) R.add_language(LANGUAGE_SCHECHI, 1) R.add_language(LANGUAGE_ROOTLOCAL, 1) + R.add_language(LANGUAGE_TERMINUS, 1) - return 1 \ No newline at end of file + return 1 diff --git a/code/game/objects/items/shooting_range.dm b/code/game/objects/items/shooting_range.dm index f1c9aa2d14..e24a727b99 100644 --- a/code/game/objects/items/shooting_range.dm +++ b/code/game/objects/items/shooting_range.dm @@ -104,7 +104,6 @@ bmark.pixel_x = p_x bmark.pixel_y = p_y bmark.icon = 'icons/effects/effects.dmi' - bmark.layer = 3.5 bmark.icon_state = "scorch" if(decaltype == 1) diff --git a/code/game/objects/items/stacks/fifty_spawner.dm b/code/game/objects/items/stacks/fifty_spawner.dm index 1977427ebb..0be33e5829 100644 --- a/code/game/objects/items/stacks/fifty_spawner.dm +++ b/code/game/objects/items/stacks/fifty_spawner.dm @@ -8,13 +8,17 @@ var/obj/item/stack/type_to_spawn = null /obj/fiftyspawner/New() - //spawns the 50-stack and qdels self - ..() -// var/obj_path = text2path("/obj/item/stack/[material]") - var/obj/item/stack/M = new type_to_spawn(src.loc) - M.amount = M.max_amount //some stuff spawns with 60, we're still calling it fifty - M.update_icon() // Some stacks have different sprites depending on how full they are. - qdel(src) + spawn() + //spawns the 50-stack and qdels self + ..() + if(istype(src.loc, /obj/structure/loot_pile)) //Spawning from a lootpile is weird, need to wait until we're out of it to do our work. + while(istype(src.loc, /obj/structure/loot_pile)) + sleep(1) + // var/obj_path = text2path("/obj/item/stack/[material]") + var/obj/item/stack/M = new type_to_spawn(src.loc) + M.amount = M.max_amount //some stuff spawns with 60, we're still calling it fifty + M.update_icon() // Some stacks have different sprites depending on how full they are. + qdel(src) /obj/fiftyspawner/rods name = "stack of rods" //this needs to be defined for cargo diff --git a/code/game/objects/items/stacks/marker_beacons.dm b/code/game/objects/items/stacks/marker_beacons.dm index 9978ef6b0d..2194b84fbd 100644 --- a/code/game/objects/items/stacks/marker_beacons.dm +++ b/code/game/objects/items/stacks/marker_beacons.dm @@ -25,6 +25,7 @@ var/list/marker_beacon_colors = list( icon_state = "marker" max_amount = 100 no_variants = TRUE + w_class = ITEMSIZE_SMALL var/picked_color = "random" /obj/item/stack/marker_beacon/ten diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index eb62b5d674..b5ff773e8b 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -111,6 +111,7 @@ user.visible_message("\The [user] places a bandaid over \a [W.desc] on [M]'s [affecting.name].", \ "You place a bandaid over \a [W.desc] on [M]'s [affecting.name]." ) W.bandage() + W.disinfect() used++ affecting.update_damages() if(used == amount) diff --git a/code/game/objects/items/stacks/rods.dm b/code/game/objects/items/stacks/rods.dm index ff680ab468..b2477ae9ff 100644 --- a/code/game/objects/items/stacks/rods.dm +++ b/code/game/objects/items/stacks/rods.dm @@ -61,8 +61,7 @@ var/global/list/datum/stack_recipe/rods_recipes = list( \ return if (istype(W, /obj/item/weapon/tape_roll)) - var/obj/item/stack/medical/splint/ghetto/new_splint = new(user.loc) - new_splint.loc = src.loc + var/obj/item/stack/medical/splint/ghetto/new_splint = new(get_turf(user)) new_splint.add_fingerprint(user) user.visible_message("\The [user] constructs \a [new_splint] out of a [singular_name].", \ diff --git a/code/game/objects/items/stacks/tiles/fifty_spawner_tiles.dm b/code/game/objects/items/stacks/tiles/fifty_spawner_tiles.dm index 3d89b5e786..256d2c8582 100644 --- a/code/game/objects/items/stacks/tiles/fifty_spawner_tiles.dm +++ b/code/game/objects/items/stacks/tiles/fifty_spawner_tiles.dm @@ -8,13 +8,17 @@ name = "stack of wood" type_to_spawn = /obj/item/stack/tile/wood +/obj/fiftyspawner/wood/sif + name = "stack of alien wood" + type_to_spawn = /obj/item/stack/tile/wood/sif + /obj/fiftyspawner/carpet name = "stack of carpet" type_to_spawn = /obj/item/stack/tile/carpet -/obj/fiftyspawner/bluecarpet - name = "stack of blue carpet" - type_to_spawn = /obj/item/stack/tile/carpet/blue +/obj/fiftyspawner/tealcarpet + name = "stack of teal carpet" + type_to_spawn = /obj/item/stack/tile/carpet/teal /obj/fiftyspawner/floor name = "stack of floor tiles" diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm index 32a4580c7e..5c17634ae2 100644 --- a/code/game/objects/items/stacks/tiles/tile_types.dm +++ b/code/game/objects/items/stacks/tiles/tile_types.dm @@ -37,9 +37,6 @@ flags = 0 origin_tech = list(TECH_BIO = 1) no_variants = FALSE - -/obj/item/stack/tile/grass/fifty - amount = 50 /* * Wood */ @@ -55,8 +52,11 @@ flags = 0 no_variants = FALSE -/obj/item/stack/tile/wood/fifty - amount = 50 +/obj/item/stack/tile/wood/sif + name = "alien wood tile" + singular_name = "alien wood tile" + desc = "An easy to fit wooden floor tile. It's blue!" + icon_state = "tile-sifwood" /obj/item/stack/tile/wood/cyborg name = "wood floor tile synthesizer" @@ -81,11 +81,11 @@ flags = 0 no_variants = FALSE -/obj/item/stack/tile/carpet/blue - name = "blue carpet" - singular_name = "blue carpet" - desc = "A piece of blue carpet. It is the same size as a normal floor tile!" - icon_state = "tile-bluecarpet" +/obj/item/stack/tile/carpet/teal + name = "teal carpet" + singular_name = "teal carpet" + desc = "A piece of teal carpet. It is the same size as a normal floor tile!" + icon_state = "tile-tealcarpet" no_variants = FALSE // TODO - Add descriptions to these @@ -107,7 +107,7 @@ /obj/item/stack/tile/floor name = "floor tile" singular_name = "floor tile" - desc = "Those could work as a pretty decent throwing weapon" //why? + desc = "A metal tile fit for covering a section of floor." icon_state = "tile" force = 6.0 matter = list(DEFAULT_WALL_MATERIAL = SHEET_MATERIAL_AMOUNT / 4) diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index c86993fa31..3931bec8ef 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -17,6 +17,7 @@ * Plushies * Toy cult sword * Bouquets + Stick Horse */ @@ -503,207 +504,324 @@ /* * Action figures */ - /obj/item/toy/figure - name = "Completely Glitched action figure" - desc = "A \"Space Life\" brand... wait, what the hell is this thing? It seems to be requesting the sweet release of death." - icon_state = "assistant" + name = "Non-Specific Action Figure action figure" + desc = "A \"Space Life\" brand... wait, what the hell is this thing?" icon = 'icons/obj/toy.dmi' + icon_state = "nuketoy" + var/cooldown = 0 + var/toysay = "What the fuck did you do?" + +/obj/item/toy/figure/New() + ..() + desc = "A \"Space Life\" brand [name]" + +/obj/item/toy/figure/attack_self(mob/user as mob) + if(cooldown < world.time) + cooldown = (world.time + 30) //3 second cooldown + user.visible_message("The [src] says \"[toysay]\".") + playsound(user, 'sound/machines/click.ogg', 20, 1) /obj/item/toy/figure/cmo name = "Chief Medical Officer action figure" desc = "A \"Space Life\" brand Chief Medical Officer action figure." icon_state = "cmo" + toysay = "Suit sensors!" /obj/item/toy/figure/assistant name = "Assistant action figure" desc = "A \"Space Life\" brand Assistant action figure." icon_state = "assistant" + toysay = "Grey tide station wide!" /obj/item/toy/figure/atmos name = "Atmospheric Technician action figure" desc = "A \"Space Life\" brand Atmospheric Technician action figure." icon_state = "atmos" + toysay = "Glory to Atmosia!" /obj/item/toy/figure/bartender name = "Bartender action figure" desc = "A \"Space Life\" brand Bartender action figure." icon_state = "bartender" + toysay = "Where's my monkey?" /obj/item/toy/figure/borg name = "Drone action figure" desc = "A \"Space Life\" brand Drone action figure." icon_state = "borg" + toysay = "I. LIVE. AGAIN." /obj/item/toy/figure/gardener name = "Gardener action figure" desc = "A \"Space Life\" brand Gardener action figure." icon_state = "botanist" + toysay = "Dude, I see colors..." /obj/item/toy/figure/captain name = "Colony Director action figure" desc = "A \"Space Life\" brand Colony Director action figure." icon_state = "captain" + toysay = "How do I open this display case?" /obj/item/toy/figure/cargotech name = "Cargo Technician action figure" desc = "A \"Space Life\" brand Cargo Technician action figure." icon_state = "cargotech" + toysay = "For Cargonia!" /obj/item/toy/figure/ce name = "Chief Engineer action figure" desc = "A \"Space Life\" brand Chief Engineer action figure." icon_state = "ce" + toysay = "Wire the solars!" /obj/item/toy/figure/chaplain name = "Chaplain action figure" desc = "A \"Space Life\" brand Chaplain action figure." icon_state = "chaplain" + toysay = "Gods make me a killing machine please!" /obj/item/toy/figure/chef name = "Chef action figure" desc = "A \"Space Life\" brand Chef action figure." icon_state = "chef" + toysay = "I swear it's not human meat." /obj/item/toy/figure/chemist name = "Chemist action figure" desc = "A \"Space Life\" brand Chemist action figure." icon_state = "chemist" + toysay = "Get your pills!" /obj/item/toy/figure/clown name = "Clown action figure" desc = "A \"Space Life\" brand Clown action figure." icon_state = "clown" + toysay = "Honk!" /obj/item/toy/figure/corgi name = "Corgi action figure" desc = "A \"Space Life\" brand Corgi action figure." icon_state = "ian" + toysay = "Arf!" /obj/item/toy/figure/detective name = "Detective action figure" desc = "A \"Space Life\" brand Detective action figure." icon_state = "detective" + toysay = "This airlock has grey jumpsuit and insulated glove fibers on it." /obj/item/toy/figure/dsquad name = "Space Commando action figure" desc = "A \"Space Life\" brand Space Commando action figure." icon_state = "dsquad" + toysay = "Eliminate all threats!" /obj/item/toy/figure/engineer name = "Engineer action figure" desc = "A \"Space Life\" brand Engineer action figure." icon_state = "engineer" + toysay = "Oh god, the engine is gonna go!" /obj/item/toy/figure/geneticist name = "Geneticist action figure" desc = "A \"Space Life\" brand Geneticist action figure, which was recently dicontinued." icon_state = "geneticist" + toysay = "I'm not qualified for this job." /obj/item/toy/figure/hop name = "Head of Personnel action figure" desc = "A \"Space Life\" brand Head of Personnel action figure." icon_state = "hop" + toysay = "Giving out all access!" /obj/item/toy/figure/hos name = "Head of Security action figure" desc = "A \"Space Life\" brand Head of Security action figure." icon_state = "hos" + toysay = "I'm here to win, anything else is secondary." /obj/item/toy/figure/qm name = "Quartermaster action figure" desc = "A \"Space Life\" brand Quartermaster action figure." icon_state = "qm" + toysay = "Hail Cargonia!" /obj/item/toy/figure/janitor name = "Janitor action figure" desc = "A \"Space Life\" brand Janitor action figure." icon_state = "janitor" + toysay = "Look at the signs, you idiot." /obj/item/toy/figure/agent name = "Internal Affairs Agent action figure" desc = "A \"Space Life\" brand Internal Affairs Agent action figure." icon_state = "agent" + toysay = "Standard Operating Procedure says they're guilty! Hacking is proof they're an Enemy of the Corporation!" /obj/item/toy/figure/librarian name = "Librarian action figure" desc = "A \"Space Life\" brand Librarian action figure." icon_state = "librarian" + toysay = "One day while..." /obj/item/toy/figure/md name = "Medical Doctor action figure" desc = "A \"Space Life\" brand Medical Doctor action figure." icon_state = "md" + toysay = "The patient is already dead!" /obj/item/toy/figure/mime name = "Mime action figure" desc = "A \"Space Life\" brand Mime action figure." icon_state = "mime" + toysay = "..." /obj/item/toy/figure/miner name = "Shaft Miner action figure" desc = "A \"Space Life\" brand Shaft Miner action figure." icon_state = "miner" + toysay = "Oh god, it's eating my intestines!" /obj/item/toy/figure/ninja name = "Space Ninja action figure" desc = "A \"Space Life\" brand Space Ninja action figure." icon_state = "ninja" + toysay = "Oh god! Stop shooting, I'm friendly!" /obj/item/toy/figure/wizard name = "Wizard action figure" desc = "A \"Space Life\" brand Wizard action figure." icon_state = "wizard" + toysay = "Ei Nath!" /obj/item/toy/figure/rd name = "Research Director action figure" desc = "A \"Space Life\" brand Research Director action figure." icon_state = "rd" + toysay = "Blowing all of the borgs!" /obj/item/toy/figure/roboticist name = "Roboticist action figure" desc = "A \"Space Life\" brand Roboticist action figure." icon_state = "roboticist" + toysay = "He asked to be borged!" /obj/item/toy/figure/scientist name = "Scientist action figure" desc = "A \"Space Life\" brand Scientist action figure." icon_state = "scientist" + toysay = "Someone else must have made those bombs!" /obj/item/toy/figure/syndie name = "Doom Operative action figure" desc = "A \"Space Life\" brand Doom Operative action figure." icon_state = "syndie" + toysay = "Get that fucking disk!" /obj/item/toy/figure/secofficer name = "Security Officer action figure" desc = "A \"Space Life\" brand Security Officer action figure." icon_state = "secofficer" + toysay = "I am the law!" + +/obj/item/toy/figure/virologist + name = "Virologist action figure" + desc = "A \"Space Life\" brand Virologist action figure." + icon_state = "virologist" + toysay = "The cure is potassium!" /obj/item/toy/figure/warden name = "Warden action figure" desc = "A \"Space Life\" brand Warden action figure." icon_state = "warden" + toysay = "Execute him for breaking in!" /obj/item/toy/figure/psychologist name = "Psychologist action figure" desc = "A \"Space Life\" brand Psychologist action figure." icon_state = "psychologist" + toysay = "The analyzer says you're fine!" /obj/item/toy/figure/paramedic name = "Paramedic action figure" desc = "A \"Space Life\" brand Paramedic action figure." icon_state = "paramedic" + toysay = "WHERE ARE YOU??" /obj/item/toy/figure/ert name = "Emergency Response Team Commander action figure" desc = "A \"Space Life\" brand Emergency Response Team Commander action figure." icon_state = "ert" + toysay = "We're probably the good guys!" /* * Plushies */ +/* + * Carp plushie + */ + +/obj/item/toy/plushie/carp + name = "space carp plushie" + desc = "An adorable stuffed toy that resembles a space carp." + icon = 'icons/obj/toy.dmi' + icon_state = "plushie/carp" + attack_verb = list("bitten", "eaten", "fin slapped") + var/bitesound = 'sound/weapons/bite.ogg' + +// Attack mob +/obj/item/toy/plushie/carp/attack(mob/M as mob, mob/user as mob) + playsound(loc, bitesound, 20, 1) // Play bite sound in local area + return ..() + +// Attack self +/obj/item/toy/plushie/carp/attack_self(mob/user as mob) + playsound(src.loc, bitesound, 20, 1) + return ..() + + +/obj/random/carp_plushie + name = "Random Carp Plushie" + desc = "This is a random plushie" + icon = 'icons/obj/toy.dmi' + icon_state = "plushie/carp" + +/obj/random/carp_plushie/item_to_spawn() + return pick(typesof(/obj/item/toy/plushie/carp)) //can pick any carp plushie, even the original. + +/obj/item/toy/plushie/carp/ice + icon_state = "icecarp" + +/obj/item/toy/plushie/carp/silent + icon_state = "silentcarp" + +/obj/item/toy/plushie/carp/electric + icon_state = "electriccarp" + +/obj/item/toy/plushie/carp/gold + icon_state = "goldcarp" + +/obj/item/toy/plushie/carp/toxin + icon_state = "toxincarp" + +/obj/item/toy/plushie/carp/dragon + icon_state = "dragoncarp" + +/obj/item/toy/plushie/carp/pink + icon_state = "pinkcarp" + +/obj/item/toy/plushie/carp/candy + icon_state = "candycarp" + +/obj/item/toy/plushie/carp/nebula + icon_state = "nebulacarp" + +/obj/item/toy/plushie/carp/void + icon_state = "voidcarp" + //Large plushies. /obj/structure/plushie name = "generic plush" @@ -726,6 +844,7 @@ user.visible_message("\The [user] pokes the [src].","You poke the [src].") visible_message("[src] says, \"[phrase]\"") + /obj/structure/plushie/ian name = "plush corgi" desc = "A plushie of an adorable corgi! Don't you just want to hug it and squeeze it and call it \"Ian\"?" @@ -787,6 +906,12 @@ to_chat(M, "You name the plushie [input], giving it a hug for good luck.") return 1 +/obj/item/toy/plushie/attackby(obj/item/I as obj, mob/user as mob) + if(istype(I, /obj/item/toy/plushie) || istype(I, /obj/item/organ/external/head)) + user.visible_message("[user] makes \the [I] kiss \the [src]!.", \ + "You make \the [I] kiss \the [src]!.") + return ..() + /obj/item/toy/plushie/nymph name = "diona nymph plush" desc = "A plushie of an adorable diona nymph! While its level of self-awareness is still being debated, its level of cuteness is not." @@ -817,6 +942,96 @@ desc = "A farwa plush doll. It's soft and comforting!" icon_state = "farwaplushie" +/obj/item/toy/plushie/corgi + name = "corgi plushie" + icon_state = "corgi" + +/obj/item/toy/plushie/girly_corgi + name = "corgi plushie" + icon_state = "girlycorgi" + +/obj/item/toy/plushie/robo_corgi + name = "borgi plushie" + icon_state = "robotcorgi" + +/obj/item/toy/plushie/octopus + name = "octopus plushie" + icon_state = "loveable" + +/obj/item/toy/plushie/face_hugger + name = "facehugger plushie" + icon_state = "huggable" + +//foxes are basically the best + +/obj/item/toy/plushie/red_fox + name = "red fox plushie" + icon_state = "redfox" + +/obj/item/toy/plushie/black_fox + name = "black fox plushie" + icon_state = "blackfox" + +/obj/item/toy/plushie/marble_fox + name = "marble fox plushie" + icon_state = "marblefox" + +/obj/item/toy/plushie/blue_fox + name = "blue fox plushie" + icon_state = "bluefox" + +/obj/item/toy/plushie/orange_fox + name = "orange fox plushie" + icon_state = "orangefox" + +/obj/item/toy/plushie/coffee_fox + name = "coffee fox plushie" + icon_state = "coffeefox" + +/obj/item/toy/plushie/pink_fox + name = "pink fox plushie" + icon_state = "pinkfox" + +/obj/item/toy/plushie/purple_fox + name = "purple fox plushie" + icon_state = "purplefox" + +/obj/item/toy/plushie/crimson_fox + name = "crimson fox plushie" + icon_state = "crimsonfox" + +/obj/item/toy/plushie/deer + name = "deer plushie" + icon_state = "deer" + +/obj/item/toy/plushie/black_cat + name = "black cat plushie" + icon_state = "blackcat" + +/obj/item/toy/plushie/grey_cat + name = "grey cat plushie" + icon_state = "greycat" + +/obj/item/toy/plushie/white_cat + name = "white cat plushie" + icon_state = "whitecat" + +/obj/item/toy/plushie/orange_cat + name = "orange cat plushie" + icon_state = "orangecat" + +/obj/item/toy/plushie/siamese_cat + name = "siamese cat plushie" + icon_state = "siamesecat" + +/obj/item/toy/plushie/tabby_cat + name = "tabby cat plushie" + icon_state = "tabbycat" + +/obj/item/toy/plushie/tuxedo_cat + name = "tuxedo cat plushie" + icon_state = "tuxedocat" + /obj/item/toy/plushie/therapy/red name = "red therapy doll" desc = "A toy for therapeutic and recreational purposes. This one is red." @@ -886,6 +1101,147 @@ name = "plastic bouquet" desc = "A cheap plastic bouquet of flowers. Smells like cheap, toxic plastic." +/obj/item/toy/stickhorse + name = "stick horse" + desc = "A pretend horse on a stick for any aspiring little cowboy to ride." + icon = 'icons/obj/toy.dmi' + icon_state = "stickhorse" + w_class = ITEMSIZE_LARGE + +////////////////////////////////////////////////////// +// Magic 8-Ball / Conch // +////////////////////////////////////////////////////// + +/obj/item/toy/eight_ball + name = "\improper Magic 8-Ball" + desc = "Mystical! Magical! Ages 8+!" + icon = 'icons/obj/toy.dmi' + icon_state = "eight-ball" + var/use_action = "shakes the ball" + var/cooldown = 0 + var/list/possible_answers = list("Definitely.", "All signs point to yes.", "Most likely.", "Yes.", "Ask again later.", "Better not tell you now.", "Future unclear.", "Maybe.", "Doubtful.", "No.", "Don't count on it.", "Never.") + +/obj/item/toy/eight_ball/attack_self(mob/user as mob) + if(!cooldown) + var/answer = pick(possible_answers) + user.visible_message("[user] focuses on their question and [use_action]...") + user.visible_message("The [src] says \"[answer]\"") + spawn(30) + cooldown = 0 + return + +/obj/item/toy/eight_ball/conch + name = "Magic Conch shell" + desc = "All hail the Magic Conch!" + icon_state = "conch" + use_action = "pulls the string" + possible_answers = list("Yes.", "No.", "Try asking again.", "Nothing.", "I don't think so.", "Neither.", "Maybe someday.") + +// DND Character minis. Use the naming convention (type)character for the icon states. +/obj/item/toy/character + icon = 'icons/obj/toy.dmi' + w_class = ITEMSIZE_SMALL + pixel_z = 5 + +/obj/item/toy/character/alien + name = "xenomorph xiniature" + desc = "A miniature xenomorph. Scary!" + icon_state = "aliencharacter" +/obj/item/toy/character/cleric + name = "cleric miniature" + desc = "A wee little cleric, with his wee little staff." + icon_state = "clericcharacter" +/obj/item/toy/character/warrior + name = "warrior miniature" + desc = "That sword would make a decent toothpick." + icon_state = "warriorcharacter" +/obj/item/toy/character/thief + name = "thief miniature" + desc = "Hey, where did my wallet go!?" + icon_state = "thiefcharacter" +/obj/item/toy/character/wizard + name = "wizard miniature" + desc = "MAGIC!" + icon_state = "wizardcharacter" +/obj/item/toy/character/voidone + name = "void one miniature" + desc = "The dark lord has risen!" + icon_state = "darkmastercharacter" +/obj/item/toy/character/lich + name = "lich miniature" + desc = "Murderboner extraordinaire." + icon_state = "lichcharacter" +/obj/item/weapon/storage/box/characters + name = "box of miniatures" + desc = "The nerd's best friends." + icon_state = "box" +/obj/item/weapon/storage/box/characters/starts_with = list( +// /obj/item/toy/character/alien, + /obj/item/toy/character/cleric, + /obj/item/toy/character/warrior, + /obj/item/toy/character/thief, + /obj/item/toy/character/wizard, + /obj/item/toy/character/voidone, + /obj/item/toy/character/lich + ) + +/obj/item/toy/AI + name = "toy AI" + desc = "A little toy model AI core!"// with real law announcing action!" //Alas, requires a rewrite of how ion laws work. + icon = 'icons/obj/toy.dmi' + icon_state = "AI" + w_class = ITEMSIZE_SMALL + var/cooldown = 0 +/* +/obj/item/toy/AI/attack_self(mob/user) + if(!cooldown) //for the sanity of everyone + var/message = generate_ion_law() + to_chat(user, "You press the button on [src].") + playsound(user, 'sound/machines/click.ogg', 20, 1) + visible_message("[message]") + cooldown = 1 + spawn(30) cooldown = 0 + return + ..() +*/ +/obj/item/toy/owl + name = "owl action figure" + desc = "An action figure modeled after 'The Owl', defender of justice." + icon = 'icons/obj/toy.dmi' + icon_state = "owlprize" + w_class = ITEMSIZE_SMALL + var/cooldown = 0 + +/obj/item/toy/owl/attack_self(mob/user) + if(!cooldown) //for the sanity of everyone + var/message = pick("You won't get away this time, Griffin!", "Stop right there, criminal!", "Hoot! Hoot!", "I am the night!") + to_chat(user, "You pull the string on the [src].") + //playsound(user, 'sound/misc/hoot.ogg', 25, 1) + visible_message("[message]") + cooldown = 1 + spawn(30) cooldown = 0 + return + ..() + +/obj/item/toy/griffin + name = "griffin action figure" + desc = "An action figure modeled after 'The Griffin', criminal mastermind." + icon = 'icons/obj/toy.dmi' + icon_state = "griffinprize" + w_class = ITEMSIZE_SMALL + var/cooldown = 0 + +/obj/item/toy/griffin/attack_self(mob/user) + if(!cooldown) //for the sanity of everyone + var/message = pick("You can't stop me, Owl!", "My plan is flawless! The vault is mine!", "Caaaawwww!", "You will never catch me!") + to_chat(user, "You pull the string on the [src].") + //playsound(user, 'sound/misc/caw.ogg', 25, 1) + visible_message("[message]") + cooldown = 1 + spawn(30) cooldown = 0 + return + ..() + /* NYET. /obj/item/weapon/toddler icon_state = "toddler" diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm index 8f5719b8e8..196f8d4a74 100644 --- a/code/game/objects/items/weapons/RCD.dm +++ b/code/game/objects/items/weapons/RCD.dm @@ -103,7 +103,7 @@ build_delay = 50 build_type = "airlock" build_other = /obj/machinery/door/airlock - else if(!deconstruct && (istype(T,/turf/space) || istype(T,get_base_turf_by_area(T)))) + else if(!deconstruct && isturf(T) && (istype(T,/turf/space) || istype(T,get_base_turf_by_area(T)))) build_cost = 1 build_type = "floor" build_turf = /turf/simulated/floor/airless diff --git a/code/game/objects/items/weapons/candle.dm b/code/game/objects/items/weapons/candle.dm index 7bc0398b72..3f861b86d4 100644 --- a/code/game/objects/items/weapons/candle.dm +++ b/code/game/objects/items/weapons/candle.dm @@ -8,7 +8,7 @@ var/wax = 2000 /obj/item/weapon/flame/candle/New() - wax = rand(800, 1000) // Enough for 27-33 minutes. 30 minutes on average. + wax -= rand(800, 1000) // Enough for 27-33 minutes. 30 minutes on average. ..() /obj/item/weapon/flame/candle/update_icon() @@ -26,7 +26,7 @@ if(istype(W, /obj/item/weapon/weldingtool)) var/obj/item/weapon/weldingtool/WT = W if(WT.isOn()) //Badasses dont get blinded by lighting their candle with a welding tool - light("\The [user] casually lights the [name] with [W].") + light("\The [user] casually lights the [src] with [W].") else if(istype(W, /obj/item/weapon/flame/lighter)) var/obj/item/weapon/flame/lighter/L = W if(L.lit) @@ -41,16 +41,13 @@ light() -/obj/item/weapon/flame/candle/proc/light(var/flavor_text = "\The [usr] lights the [name].") - if(!src.lit) - src.lit = 1 - //src.damtype = "fire" - for(var/mob/O in viewers(usr, null)) - O.show_message(flavor_text, 1) +/obj/item/weapon/flame/candle/proc/light(var/flavor_text = "\The [usr] lights the [src].") + if(!lit) + lit = TRUE + visible_message(flavor_text) set_light(CANDLE_LUM) processing_objects.Add(src) - /obj/item/weapon/flame/candle/process() if(!lit) return @@ -88,23 +85,13 @@ /obj/item/weapon/flame/candle/everburn wax = 99999 -/obj/item/weapon/flame/candle/everburn/New() - if(!src.lit) - src.lit = 1 - //src.damtype = "fire" - for(var/mob/O in viewers(usr, null)) - O.show_message("\The [name] mysteriously lights itself!.", 1) - set_light(CANDLE_LUM) - processing_objects.Add(src) +/obj/item/weapon/flame/candle/everburn/initialize() + . = ..() + light("\The [src] mysteriously lights itself!.") /obj/item/weapon/flame/candle/candelabra/everburn wax = 99999 -/obj/item/weapon/flame/candle/candelabra/everburn/New() - if(!src.lit) - src.lit = 1 - //src.damtype = "fire" - for(var/mob/O in viewers(usr, null)) - O.show_message("\The [name] mysteriously lights itself!.", 1) - set_light(CANDLE_LUM) - processing_objects.Add(src) +/obj/item/weapon/flame/candle/candelabra/everburn/initialize() + . = ..() + light("\The [src] mysteriously lights itself!.") diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm index c8d4eed3ad..5d60c8485b 100644 --- a/code/game/objects/items/weapons/cigs_lighters.dm +++ b/code/game/objects/items/weapons/cigs_lighters.dm @@ -6,6 +6,7 @@ MATCHES CIGARETTES CIGARS SMOKING PIPES +CUSTOM CIGS CHEAP LIGHTERS ZIPPO @@ -88,6 +89,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM var/weldermes = "USER lights NAME with FLAME" var/ignitermes = "USER lights NAME with FLAME" var/brand + blood_sprite_state = null //Can't bloody these /obj/item/clothing/mask/smokable/New() ..() @@ -454,6 +456,41 @@ CIGARETTE PACKETS ARE IN FANCY.DM item_state = "cobpipe" chem_volume = 35 +/////////////// +//CUSTOM CIGS// +/////////////// +//and by custom cigs i mean craftable joints. smoke weed every day + +/obj/item/clothing/mask/smokable/cigarette/joint + name = "joint" + desc = "This probably shouldn't ever show up." + icon_state = "joint" + max_smoketime = 500 + smoketime = 500 + nicotine_amt = 0 + +/obj/item/weapon/rollingpaper + name = "rolling paper" + desc = "A small, thin piece of easily flammable paper, commonly used for rolling and smoking various dried plants." + icon = 'icons/obj/cigarettes.dmi' + icon_state = "cig paper" + +/obj/item/weapon/rollingpaper/attackby(obj/item/weapon/W as obj, mob/user as mob) + if (istype(W, /obj/item/weapon/reagent_containers/food/snacks)) + var/obj/item/weapon/reagent_containers/food/snacks/grown/G = W + if (!G.dry) + user << "[G] must be dried before you roll it into [src]." + return + var/obj/item/clothing/mask/smokable/cigarette/joint/J = new /obj/item/clothing/mask/smokable/cigarette/joint(user.loc) + to_chat(usr,"You roll the [G.name] into a joint!") + J.add_fingerprint(user) + if(G.reagents) + G.reagents.trans_to_obj(J, G.reagents.total_volume) + J.name = "[G.name] joint" + J.desc = "A joint lovingly rolled and filled with [G.name]. Blaze it." + qdel(G) + qdel(src) + ///////// //ZIPPO// ///////// @@ -525,7 +562,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM if(lit == 1) M.IgniteMob() - msg_admin_attack("[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] and lit them on fire (INTENT: [uppertext(user.a_intent)]) (JMP)") + add_attack_logs(user,M,"Lit on fire with [src]") if(istype(M.wear_mask, /obj/item/clothing/mask/smokable/cigarette) && user.zone_sel.selecting == O_MOUTH && lit) var/obj/item/clothing/mask/smokable/cigarette/cig = M.wear_mask diff --git a/code/game/objects/items/weapons/circuitboards/computer/computer.dm b/code/game/objects/items/weapons/circuitboards/computer/computer.dm index 2b3631ddbf..71d6e2d867 100644 --- a/code/game/objects/items/weapons/circuitboards/computer/computer.dm +++ b/code/game/objects/items/weapons/circuitboards/computer/computer.dm @@ -100,6 +100,7 @@ /obj/item/weapon/circuitboard/turbine_control name = T_BOARD("turbine control console") build_path = /obj/machinery/computer/turbine_computer + origin_tech = list(TECH_DATA = 2, TECH_POWER = 2) /obj/item/weapon/circuitboard/solar_control name = T_BOARD("solar control console") diff --git a/code/game/objects/items/weapons/dna_injector.dm b/code/game/objects/items/weapons/dna_injector.dm index 33b93f6210..ac0a93941b 100644 --- a/code/game/objects/items/weapons/dna_injector.dm +++ b/code/game/objects/items/weapons/dna_injector.dm @@ -67,6 +67,7 @@ if(istype(M,/mob/living)) var/mob/living/L = M L.apply_effect(rand(5,20), IRRADIATE, check_protection = 0) + L.apply_damage(max(2,L.getCloneLoss()), CLONE) if (!(NOCLONE in M.mutations)) // prevents drained people from having their DNA changed if (buf.types & DNA2_BUF_UI) @@ -129,10 +130,7 @@ if((buf.types & DNA2_BUF_SE) && (block ? (GetState() && block == MONKEYBLOCK) : GetState(MONKEYBLOCK))) injected_with_monkey = " (MONKEY)" - M.attack_log += text("\[[time_stamp()]\] Has been injected with [name] by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Used the [name] to inject [M.name] ([M.ckey])") - log_attack("[user.name] ([user.ckey]) used the [name] to inject [M.name] ([M.ckey])") - message_admins("[key_name_admin(user)] injected [key_name_admin(M)] with \the [src][injected_with_monkey]") + add_attack_logs(user,M,"[injected_with_monkey] used the [name] on") // Apply the DNA shit. inject(M, user) diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm index 1e1565a2ae..b49a76c5a9 100644 --- a/code/game/objects/items/weapons/explosives.dm +++ b/code/game/objects/items/weapons/explosives.dm @@ -55,11 +55,8 @@ loc = null if (ismob(target)) - add_logs(user, target, "planted [name] on") + add_attack_logs(user, target, "planted [name] on with [timer] second fuse") user.visible_message("[user.name] finished planting an explosive on [target.name]!") - message_admins("[key_name(user, user.client)](?) planted [src.name] on [key_name(target)](?) with [timer] second fuse",0,1) - log_game("[key_name(user)] planted [src.name] on [key_name(target)] with [timer] second fuse") - else message_admins("[key_name(user, user.client)](?) planted [src.name] on [target.name] at ([target.x],[target.y],[target.z] - JMP) with [timer] second fuse",0,1) log_game("[key_name(user)] planted [src.name] on [target.name] at ([target.x],[target.y],[target.z]) with [timer] second fuse") diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm index 46543b901b..bef0f8fcd9 100644 --- a/code/game/objects/items/weapons/gift_wrappaper.dm +++ b/code/game/objects/items/weapons/gift_wrappaper.dm @@ -179,10 +179,7 @@ H.loc = present - H.attack_log += text("\[[time_stamp()]\] Has been wrapped with [src.name] by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to wrap [H.name] ([H.ckey])") - msg_admin_attack("[key_name(user)] used [src] to wrap [key_name(H)]") - + add_attack_logs(user,H,"Wrapped with [src]") else user << "You need more paper." else diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm index 0eaf073cfa..92de17d994 100644 --- a/code/game/objects/items/weapons/grenades/chem_grenade.dm +++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm @@ -43,7 +43,7 @@ if(stage > 1 && !active && clown_check(user)) user << "You prime \the [name]!" - msg_admin_attack("[user.name] ([user.ckey]) primed \a [src]. (JMP)") + msg_admin_attack("[key_name_admin(user)] primed \a [src]") activate() add_fingerprint(user) @@ -136,7 +136,7 @@ icon_state = initial(icon_state) + "_active" if(user) - msg_admin_attack("[user.name] ([user.ckey]) primed \a [src] (JMP)") + msg_admin_attack("[key_name_admin(user)] primed \a [src.name]") return diff --git a/code/game/objects/items/weapons/grenades/flashbang.dm b/code/game/objects/items/weapons/grenades/flashbang.dm index 5588089cef..e917745e0e 100644 --- a/code/game/objects/items/weapons/grenades/flashbang.dm +++ b/code/game/objects/items/weapons/grenades/flashbang.dm @@ -5,92 +5,89 @@ origin_tech = list(TECH_MATERIAL = 2, TECH_COMBAT = 1) var/banglet = 0 - prime() - ..() - for(var/obj/structure/closet/L in hear(7, get_turf(src))) - if(locate(/mob/living/carbon/, L)) - for(var/mob/living/carbon/M in L) - bang(get_turf(src), M) +/obj/item/weapon/grenade/flashbang/prime() + ..() + for(var/obj/structure/closet/L in hear(7, get_turf(src))) + if(locate(/mob/living/carbon/, L)) + for(var/mob/living/carbon/M in L) + bang(get_turf(src), M) + for(var/mob/living/carbon/M in hear(7, get_turf(src))) + bang(get_turf(src), M) - for(var/mob/living/carbon/M in hear(7, get_turf(src))) - bang(get_turf(src), M) + for(var/obj/structure/blob/B in hear(8,get_turf(src))) //Blob damage here + var/damage = round(30/(get_dist(B,get_turf(src))+1)) + if(B.overmind) + damage *= B.overmind.blob_type.burn_multiplier + B.adjust_integrity(-damage) - for(var/obj/structure/blob/B in hear(8,get_turf(src))) //Blob damage here - var/damage = round(30/(get_dist(B,get_turf(src))+1)) - if(B.overmind) - damage *= B.overmind.blob_type.burn_multiplier - B.adjust_integrity(-damage) + new/obj/effect/effect/sparks(src.loc) + new/obj/effect/effect/smoke/illumination(src.loc, 5, range=30, power=30, color="#FFFFFF") + qdel(src) + return - new/obj/effect/effect/sparks(src.loc) - new/obj/effect/effect/smoke/illumination(src.loc, 5, range=30, power=30, color="#FFFFFF") - qdel(src) - return - - proc/bang(var/turf/T , var/mob/living/carbon/M) // Added a new proc called 'bang' that takes a location and a person to be banged. - M << "BANG" // Called during the loop that bangs people in lockers/containers and when banging - playsound(src.loc, 'sound/effects/bang.ogg', 50, 1, 30) // people in normal view. Could theroetically be called during other explosions. +/obj/item/weapon/grenade/flashbang/proc/bang(var/turf/T , var/mob/living/carbon/M) // Added a new proc called 'bang' that takes a location and a person to be banged. + to_chat(M, "BANG") // Called during the loop that bangs people in lockers/containers and when banging + playsound(src.loc, 'sound/effects/bang.ogg', 50, 1, 30) // people in normal view. Could theroetically be called during other explosions. // -- Polymorph -//Checking for protections - var/eye_safety = 0 - var/ear_safety = 0 - if(iscarbon(M)) - eye_safety = M.eyecheck() - ear_safety = M.get_ear_protection() + //Checking for protections + var/eye_safety = 0 + var/ear_safety = 0 + if(iscarbon(M)) + eye_safety = M.eyecheck() + ear_safety = M.get_ear_protection() -//Flashing everyone - if(eye_safety < 1) - M.flash_eyes() - M.Stun(2) - M.Weaken(10) + //Flashing everyone + if(eye_safety < 1) + M.flash_eyes() + M.Confuse(2) + M.Weaken(5) - - -//Now applying sound - if((get_dist(M, T) <= 2 || src.loc == M.loc || src.loc == M)) - if(ear_safety > 0) - M.Stun(2) - M.Weaken(1) - else - M.Stun(10) - M.Weaken(3) - if ((prob(14) || (M == src.loc && prob(70)))) - M.ear_damage += rand(1, 10) - else - M.ear_damage += rand(0, 5) - M.ear_deaf = max(M.ear_deaf,15) - - else if(get_dist(M, T) <= 5) - if(!ear_safety) - M.Stun(8) - M.ear_damage += rand(0, 3) - M.ear_deaf = max(M.ear_deaf,10) - - else if(!ear_safety) - M.Stun(4) - M.ear_damage += rand(0, 1) - M.ear_deaf = max(M.ear_deaf,5) - -//This really should be in mob not every check - if(ishuman(M)) - var/mob/living/carbon/human/H = M - var/obj/item/organ/internal/eyes/E = H.internal_organs_by_name[O_EYES] - if (E && E.damage >= E.min_bruised_damage) - M << "Your eyes start to burn badly!" - if(!banglet && !(istype(src , /obj/item/weapon/grenade/flashbang/clusterbang))) - if (E.damage >= E.min_broken_damage) - M << "You can't see anything!" - if (M.ear_damage >= 15) - M << "Your ears start to ring badly!" - if(!banglet && !(istype(src , /obj/item/weapon/grenade/flashbang/clusterbang))) - if (prob(M.ear_damage - 10 + 5)) - M << "You can't hear anything!" - M.sdisabilities |= DEAF + //Now applying sound + if((get_dist(M, T) <= 2 || src.loc == M.loc || src.loc == M)) + if(ear_safety > 0) + M.Confuse(2) + M.Weaken(1) else - if (M.ear_damage >= 5) - M << "Your ears start to ring!" - M.update_icons() //Forces matrix transform to proc if they are now laying, I guess? + M.Confuse(10) + M.Weaken(3) + if ((prob(14) || (M == src.loc && prob(70)))) + M.ear_damage += rand(1, 10) + else + M.ear_damage += rand(0, 5) + M.ear_deaf = max(M.ear_deaf,15) + + else if(get_dist(M, T) <= 5) + if(!ear_safety) + M.Confuse(8) + M.ear_damage += rand(0, 3) + M.ear_deaf = max(M.ear_deaf,10) + + else if(!ear_safety) + M.Confuse(4) + M.ear_damage += rand(0, 1) + M.ear_deaf = max(M.ear_deaf,5) + + //This really should be in mob not every check + if(ishuman(M)) + var/mob/living/carbon/human/H = M + var/obj/item/organ/internal/eyes/E = H.internal_organs_by_name[O_EYES] + if (E && E.damage >= E.min_bruised_damage) + M << "Your eyes start to burn badly!" + if(!banglet && !(istype(src , /obj/item/weapon/grenade/flashbang/clusterbang))) + if (E.damage >= E.min_broken_damage) + M << "You can't see anything!" + if (M.ear_damage >= 15) + to_chat(M, "Your ears start to ring badly!") + if(!banglet && !(istype(src , /obj/item/weapon/grenade/flashbang/clusterbang))) + if (prob(M.ear_damage - 10 + 5)) + to_chat(M, "You can't hear anything!") + M.sdisabilities |= DEAF + else if(M.ear_damage >= 5) + to_chat(M, "Your ears start to ring!") + + M.update_icons() //Forces matrix transform to proc if they are now laying, I guess? /obj/item/weapon/grenade/flashbang/Destroy() walk(src, 0) // Because we might have called walk_away, we must stop the walk loop or BYOND keeps an internal reference to us forever. diff --git a/code/game/objects/items/weapons/grenades/grenade.dm b/code/game/objects/items/weapons/grenades/grenade.dm index b46d987b4c..5854e02cac 100644 --- a/code/game/objects/items/weapons/grenades/grenade.dm +++ b/code/game/objects/items/weapons/grenades/grenade.dm @@ -72,7 +72,7 @@ return if(user) - msg_admin_attack("[user.name] ([user.ckey]) primed \a [src] (JMP)") + msg_admin_attack("[key_name_admin(user)] primed \a [src.name]") icon_state = initial(icon_state) + "_active" active = 1 diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm index ea838cce0b..46ebb3bd40 100644 --- a/code/game/objects/items/weapons/handcuffs.dm +++ b/code/game/objects/items/weapons/handcuffs.dm @@ -18,7 +18,13 @@ var/cuff_sound = 'sound/weapons/handcuffs.ogg' var/cuff_type = "handcuffs" var/use_time = 30 - sprite_sheets = list("Teshari" = 'icons/mob/species/seromi/handcuffs.dmi') + sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/seromi/handcuffs.dmi') + +/obj/item/weapon/handcuffs/get_worn_icon_state(var/slot_name) + if(slot_name == slot_handcuffed_str) + return "handcuff1" //Simple + + return ..() /obj/item/weapon/handcuffs/attack(var/mob/living/carbon/C, var/mob/living/user) @@ -76,9 +82,7 @@ if(!can_place(target, user)) //victim may have resisted out of the grab in the meantime return 0 - H.attack_log += text("\[[time_stamp()]\] Has been handcuffed (attempt) by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Attempted to handcuff [H.name] ([H.ckey])") - msg_admin_attack("[key_name(user)] attempted to handcuff [key_name(H)]") + add_attack_logs(user,H,"Handcuffed (attempt)") feedback_add_details("handcuffs","H") user.setClickCooldown(user.get_attack_speed(src)) @@ -97,6 +101,13 @@ target.update_inv_handcuffed() return 1 +/obj/item/weapon/handcuffs/equipped(var/mob/living/user,var/slot) + . = ..() + if(slot == slot_handcuffed) + user.drop_r_hand() + user.drop_l_hand() + user.stop_pulling() + var/last_chew = 0 /mob/living/carbon/human/RestrainedClickOn(var/atom/A) if (A != src) return ..() @@ -113,11 +124,10 @@ var/last_chew = 0 if (!O) return var/datum/gender/T = gender_datums[H.get_visible_gender()] - + var/s = "[H.name] chews on [T.his] [O.name]!" H.visible_message(s, "You chew on your [O.name]!") - H.attack_log += text("\[[time_stamp()]\] [s] ([H.ckey])") - log_attack("[s] ([H.ckey])") + add_attack_logs(H,H,"chewed own [O.name]") if(O.take_damage(3,0,1,1,"teeth marks")) H:UpdateDamageIcon() @@ -210,6 +220,12 @@ var/last_chew = 0 breakouttime = 30 cuff_sound = 'sound/weapons/towelwipe.ogg' //Is there anything this sound can't do? +/obj/item/weapon/handcuffs/legcuffs/get_worn_icon_state(var/slot_name) + if(slot_name == slot_legcuffed_str) + return "legcuff1" + + return ..() + /obj/item/weapon/handcuffs/legcuffs/bola/can_place(var/mob/target, var/mob/user) if(user) //A ranged legcuff, until proper implementation as items it remains a projectile-only thing. return 1 @@ -283,9 +299,7 @@ var/last_chew = 0 if(!can_place(target, user)) //victim may have resisted out of the grab in the meantime return 0 - H.attack_log += text("\[[time_stamp()]\] Has been legcuffed (attempt) by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Attempted to legcuff [H.name] ([H.ckey])") - msg_admin_attack("[key_name(user)] attempted to legcuff [key_name(H)]") + add_attack_logs(user,H,"Legcuffed (attempt)") feedback_add_details("legcuffs","H") user.setClickCooldown(user.get_attack_speed(src)) @@ -303,3 +317,11 @@ var/last_chew = 0 target.legcuffed = lcuffs target.update_inv_legcuffed() return 1 + +/obj/item/weapon/handcuffs/legcuffs/equipped(var/mob/living/user,var/slot) + . = ..() + if(slot == slot_legcuffed) + if(user.m_intent != "walk") + user.m_intent = "walk" + if(user.hud_used && user.hud_used.move_intent) + user.hud_used.move_intent.icon_state = "walking" diff --git a/code/game/objects/items/weapons/id cards/cards.dm b/code/game/objects/items/weapons/id cards/cards.dm index b5654dade7..d0b2534463 100644 --- a/code/game/objects/items/weapons/id cards/cards.dm +++ b/code/game/objects/items/weapons/id cards/cards.dm @@ -46,7 +46,6 @@ name = "\proper the coordinates to clown planet" icon_state = "data" item_state = "card-id" - layer = 3 level = 2 desc = "This card contains coordinates to the fabled Clown Planet. Handle with care." function = "teleporter" diff --git a/code/game/objects/items/weapons/id cards/station_ids.dm b/code/game/objects/items/weapons/id cards/station_ids.dm index 0e80dfa16b..314320ffe7 100644 --- a/code/game/objects/items/weapons/id cards/station_ids.dm +++ b/code/game/objects/items/weapons/id cards/station_ids.dm @@ -5,7 +5,7 @@ item_state = "card-id" sprite_sheets = list( - "Teshari" = 'icons/mob/species/seromi/id.dmi' + SPECIES_TESHARI = 'icons/mob/species/seromi/id.dmi' ) var/access = list() @@ -55,8 +55,8 @@ name = "[src.registered_name]'s ID Card ([src.assignment])" /obj/item/weapon/card/id/proc/set_id_photo(var/mob/M) - front = getFlatIcon(M, SOUTH, always_use_defdir = 1) - side = getFlatIcon(M, WEST, always_use_defdir = 1) + front = getFlatIcon(M, SOUTH) + side = getFlatIcon(M, WEST) /mob/proc/set_id_info(var/obj/item/weapon/card/id/id_card) id_card.age = 0 @@ -112,6 +112,12 @@ usr << "The fingerprint hash on the card is [fingerprint_hash]." return +/obj/item/weapon/card/id/get_worn_icon_state(var/slot_name) + if(slot_name == slot_wear_id_str) + return "id" //Legacy, just how it is. There's only one sprite. + + return ..() + /obj/item/weapon/card/id/initialize() . = ..() var/datum/job/J = job_master.GetJob(rank) @@ -147,7 +153,7 @@ job_access_type = /datum/job/captain /obj/item/weapon/card/id/gold/captain/spare - name = "colony director's spare ID" + name = "\improper Colony Director's spare ID" desc = "The spare ID of the High Lord himself." registered_name = "Colony Director" job_access_type = /datum/job/captain @@ -410,4 +416,4 @@ desc = "An identification card of some sort. It does not look like it is issued by NT." icon_state = "permit" primary_color = rgb(142,94,0) - secondary_color = rgb(191,159,95) \ No newline at end of file + secondary_color = rgb(191,159,95) diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm index 1d515e863b..3e656b844b 100644 --- a/code/game/objects/items/weapons/implants/implant.dm +++ b/code/game/objects/items/weapons/implants/implant.dm @@ -52,7 +52,9 @@ /obj/item/weapon/implant/Destroy() if(part) part.implants.Remove(src) + listening_objects.Remove(src) part = null + imp_in = null return ..() /obj/item/weapon/implant/attackby(obj/item/I, mob/user) @@ -69,7 +71,7 @@ /obj/item/weapon/implant/tracking name = "tracking implant" - desc = "Track with this." + desc = "An implant normally given to dangerous criminals. Allows security to track your location." var/id = 1 var/degrade_time = 10 MINUTES //How long before the implant stops working outside of a living body. @@ -82,7 +84,6 @@ /obj/item/weapon/implant/tracking/implanted(var/mob/source) processing_objects.Add(src) - listening_objects |= src return 1 /obj/item/weapon/implant/tracking/Destroy() @@ -451,6 +452,7 @@ the implant may become unstable and either pre-maturely inject the subject or si /obj/item/weapon/implant/death_alarm name = "death alarm implant" desc = "An alarm which monitors host vital signs and transmits a radio message upon death." + origin_tech = list(TECH_MATERIAL = 1, TECH_BIO = 2, TECH_DATA = 1) var/mobname = "Will Robinson" /obj/item/weapon/implant/death_alarm/get_data() @@ -534,6 +536,7 @@ the implant may become unstable and either pre-maturely inject the subject or si icon_state = "implant_evil" var/activation_emote = "sigh" var/obj/item/scanned = null + origin_tech = list(TECH_MATERIAL = 4, TECH_BIO = 2, TECH_ILLEGAL = 2) /obj/item/weapon/implant/compressed/get_data() var/dat = {" diff --git a/code/game/objects/items/weapons/implants/implanter.dm b/code/game/objects/items/weapons/implants/implanter.dm index 87a76305c6..8052b19de6 100644 --- a/code/game/objects/items/weapons/implants/implanter.dm +++ b/code/game/objects/items/weapons/implants/implanter.dm @@ -54,7 +54,7 @@ if(user && M && (get_turf(M) == T1) && src && src.imp) M.visible_message("[M] has been implanted by [user].") - admin_attack_log(user, M, "Implanted using \the [src.name] ([src.imp.name])", "Implanted with \the [src.name] ([src.imp.name])", "used an implanter, [src.name] ([src.imp.name]), on") + add_attack_logs(user,M,"Implanted with [imp.name] using [name]") if(src.imp.implanted(M)) src.imp.loc = M diff --git a/code/game/objects/items/weapons/material/misc.dm b/code/game/objects/items/weapons/material/misc.dm index 97cf8b33db..87bfb0454d 100644 --- a/code/game/objects/items/weapons/material/misc.dm +++ b/code/game/objects/items/weapons/material/misc.dm @@ -100,7 +100,7 @@ user.put_in_hands(S) else visible_message("[user] starts compacting the snowball.", "You start compacting the snowball.") - if(do_after(user, 2000)) + if(do_after(user, 2 SECONDS)) var/atom/S = new /obj/item/weapon/material/snow/snowball/reinforced(user.loc) del(src) user.put_in_hands(S) @@ -108,6 +108,6 @@ /obj/item/weapon/material/snow/snowball/reinforced name = "snowball" desc = "A well-formed and fun snowball. It looks kind of dangerous." - icon_state = "snowball-reinf" + //icon_state = "reinf-snowball" force_divisor = 0.20 - thrown_force_divisor = 0.25 \ No newline at end of file + thrown_force_divisor = 0.25 diff --git a/code/game/objects/items/weapons/melee/misc.dm b/code/game/objects/items/weapons/melee/misc.dm index a7f6565a2d..81f233cdec 100644 --- a/code/game/objects/items/weapons/melee/misc.dm +++ b/code/game/objects/items/weapons/melee/misc.dm @@ -14,3 +14,77 @@ var/datum/gender/T = gender_datums[user.get_visible_gender()] user.visible_message(span("danger", "\The [user] [T.is] strangling [T.himself] with \the [src]! It looks like [T.he] [T.is] trying to commit suicide."), span("danger", "You start to strangle yourself with \the [src]!"), span("danger", "You hear the sound of someone choking!")) return (OXYLOSS) + +/obj/item/weapon/melee/umbrella + name = "umbrella" + desc = "To keep the rain off you. Use with caution on windy days." + icon = 'icons/obj/items.dmi' + icon_state = "umbrella_closed" + addblends = "umbrella_closed_a" + flags = CONDUCT + slot_flags = SLOT_BELT + force = 5 + throwforce = 5 + w_class = ITEMSIZE_NORMAL + var/open = FALSE + +/obj/item/weapon/melee/umbrella/New() + ..() + update_icon() + +/obj/item/weapon/melee/umbrella/attack_self() + src.toggle_umbrella() + +/obj/item/weapon/melee/umbrella/proc/toggle_umbrella() + open = !open + icon_state = "umbrella_[open ? "open" : "closed"]" + addblends = icon_state + "_a" + item_state = icon_state + update_icon() + if(ishuman(src.loc)) + var/mob/living/carbon/human/H = src.loc + H.update_inv_l_hand(0) + H.update_inv_r_hand() + ..() + +// Randomizes color +/obj/item/weapon/melee/umbrella/random/New() + color = "#"+get_random_colour() + ..() + +/obj/item/weapon/melee/cursedblade + name = "crystal blade" + desc = "The red crystal blade's polished surface glints in the light, giving off a faint glow." + icon_state = "soulblade" + slot_flags = SLOT_BELT | SLOT_BACK + force = 30 + throwforce = 10 + w_class = ITEMSIZE_NORMAL + sharp = 1 + edge = 1 + attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + hitsound = 'sound/weapons/bladeslice.ogg' + can_speak = 1 + var/list/voice_mobs = list() //The curse of the sword is that it has someone trapped inside. + + +/obj/item/weapon/melee/cursedblade/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") + if(default_parry_check(user, attacker, damage_source) && prob(50)) + user.visible_message("\The [user] parries [attack_text] with \the [src]!") + playsound(user.loc, 'sound/weapons/punchmiss.ogg', 50, 1) + return 1 + return 0 + +/obj/item/weapon/melee/cursedblade/proc/ghost_inhabit(var/mob/candidate) + if(!isobserver(candidate)) + return + //Handle moving the ghost into the new shell. + announce_ghost_joinleave(candidate, 0, "They are occupying a cursed sword now.") + var/mob/living/voice/new_voice = new /mob/living/voice(src) //Make the voice mob the ghost is going to be. + new_voice.transfer_identity(candidate) //Now make the voice mob load from the ghost's active character in preferences. + new_voice.mind = candidate.mind //Transfer the mind, if any. + new_voice.ckey = candidate.ckey //Finally, bring the client over. + new_voice.name = "cursed sword" //Cursed swords shouldn't be known characters. + new_voice.real_name = "cursed sword" + voice_mobs.Add(new_voice) + listening_objects |= src \ No newline at end of file diff --git a/code/game/objects/items/weapons/policetape.dm b/code/game/objects/items/weapons/policetape.dm index a355be251a..43183d45f4 100644 --- a/code/game/objects/items/weapons/policetape.dm +++ b/code/game/objects/items/weapons/policetape.dm @@ -17,9 +17,9 @@ var/turf/T = get_turf(src) if(!T) return - var/obj/machinery/door/airlock/airlock = locate(/obj/machinery/door/airlock) in T - if(airlock) - afterattack(airlock, null, TRUE) + var/obj/machinery/door/door = locate(/obj/machinery/door) in T + if((door == /obj/machinery/door/airlock) || (door == /obj/machinery/door/firedoor)) + afterattack(door, null, TRUE) return INITIALIZE_HINT_QDEL @@ -30,7 +30,7 @@ var/list/tape_roll_applications = list() name = "tape" icon = 'icons/policetape.dmi' anchored = 1 - layer = 3.2 + layer = WINDOW_LAYER var/lifted = 0 var/crumpled = 0 var/tape_dir = 0 @@ -250,14 +250,14 @@ var/list/tape_roll_applications = list() if(!proximity) return - if (istype(A, /obj/machinery/door/airlock)) + if (istype(A, /obj/machinery/door)) var/turf/T = get_turf(A) if(locate(/obj/item/tape, A.loc)) user << "There's already tape over that door!" else var/obj/item/tape/P = new tape_type(T) P.update_icon() - P.layer = 3.2 + P.layer = WINDOW_LAYER user << "You finish placing \the [src]." if (istype(A, /turf/simulated/floor) ||istype(A, /turf/unsimulated/floor)) @@ -307,10 +307,11 @@ var/list/tape_roll_applications = list() /obj/item/tape/proc/lift(time) lifted = 1 - layer = 8 + plane = MOB_PLANE + layer = ABOVE_MOB_LAYER spawn(time) lifted = 0 - layer = initial(layer) + reset_plane_and_layer() // Returns a list of all tape objects connected to src, including itself. /obj/item/tape/proc/gettapeline() diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm index c564ebe466..cee423a627 100644 --- a/code/game/objects/items/weapons/storage/backpack.dm +++ b/code/game/objects/items/weapons/storage/backpack.dm @@ -8,7 +8,7 @@ icon = 'icons/obj/clothing/backpack.dmi' icon_state = "backpack" sprite_sheets = list( - "Teshari" = 'icons/mob/species/seromi/back.dmi' + SPECIES_TESHARI = 'icons/mob/species/seromi/back.dmi' ) w_class = ITEMSIZE_LARGE slot_flags = SLOT_BACK @@ -47,22 +47,18 @@ max_storage_space = ITEMSIZE_COST_NORMAL * 14 // 56 storage_cost = INVENTORY_STANDARD_SPACE + 1 - New() - ..() +/obj/item/weapon/storage/backpack/holding/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W, /obj/item/weapon/storage/backpack/holding)) + user << "The Bluespace interfaces of the two devices conflict and malfunction." + qdel(W) return + . = ..() - attackby(obj/item/weapon/W as obj, mob/user as mob) - if(istype(W, /obj/item/weapon/storage/backpack/holding)) - user << "The Bluespace interfaces of the two devices conflict and malfunction." - qdel(W) - return - ..() - - //Please don't clutter the parent storage item with stupid hacks. - can_be_inserted(obj/item/W as obj, stop_messages = 0) - if(istype(W, /obj/item/weapon/storage/backpack/holding)) - return 1 - return ..() +//Please don't clutter the parent storage item with stupid hacks. +/obj/item/weapon/storage/backpack/holding/can_be_inserted(obj/item/W as obj, stop_messages = 0) + if(istype(W, /obj/item/weapon/storage/backpack/holding)) + return 1 + return ..() /obj/item/weapon/storage/backpack/santabag name = "\improper Santa's gift bag" @@ -142,18 +138,18 @@ /obj/item/weapon/storage/backpack/dufflebag/syndie name = "black dufflebag" - desc = "A large dufflebag for holding extra tactical supplies." + desc = "A large dufflebag for holding extra tactical supplies. This one appears to be made out of lighter material than usual." icon_state = "duffle_syndie" slowdown = 0 /obj/item/weapon/storage/backpack/dufflebag/syndie/med name = "medical dufflebag" - desc = "A large dufflebag for holding extra tactical medical supplies." + desc = "A large dufflebag for holding extra tactical medical supplies. This one appears to be made out of lighter material than usual." icon_state = "duffle_syndiemed" /obj/item/weapon/storage/backpack/dufflebag/syndie/ammo name = "ammunition dufflebag" - desc = "A large dufflebag for holding extra weapons ammunition and supplies." + desc = "A large dufflebag for holding extra weapons ammunition and supplies. This one appears to be made out of lighter material than usual." icon_state = "duffle_syndieammo" /obj/item/weapon/storage/backpack/dufflebag/captain @@ -197,9 +193,7 @@ item_state_slots = list(slot_r_hand_str = "briefcase", slot_l_hand_str = "briefcase") /obj/item/weapon/storage/backpack/satchel/withwallet - New() - ..() - new /obj/item/weapon/storage/wallet/random( src ) + starts_with = list(/obj/item/weapon/storage/wallet/random) /obj/item/weapon/storage/backpack/satchel/norm name = "satchel" @@ -423,4 +417,4 @@ else H.visible_message("\The [src] decides not to unpack \the [src]!", \ "You decide not to unpack \the [src]!") - return \ No newline at end of file + return diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm index 01ca1c7796..5b20553430 100644 --- a/code/game/objects/items/weapons/storage/bags.dm +++ b/code/game/objects/items/weapons/storage/bags.dm @@ -68,6 +68,9 @@ // ----------------------------- // Mining Satchel // ----------------------------- +/* + * Mechoid - Orebags are the most common quick-gathering thing, and also have tons of lag associated with it. Their checks are going to be hyper-simplified due to this, and their INCREDIBLY singular target contents. + */ /obj/item/weapon/storage/bag/ore name = "mining satchel" @@ -79,7 +82,80 @@ max_storage_space = ITEMSIZE_COST_NORMAL * 25 max_w_class = ITEMSIZE_NORMAL can_hold = list(/obj/item/weapon/ore) + var/stored_ore = list() + var/last_update = 0 +/obj/item/weapon/storage/bag/ore/remove_from_storage(obj/item/W as obj, atom/new_location) + if(!istype(W)) return 0 + + if(new_location) + if(ismob(loc)) + W.dropped(usr) + if(ismob(new_location)) + W.hud_layerise() + else + W.reset_plane_and_layer() + W.forceMove(new_location) + else + W.forceMove(get_turf(src)) + + W.on_exit_storage(src) + update_icon() + return 1 + +/obj/item/weapon/storage/bag/ore/gather_all(turf/T as turf, mob/user as mob, var/silent = 0) + var/success = 0 + var/failure = 0 + for(var/obj/item/weapon/ore/I in T) //Only ever grabs ores. Doesn't do any extraneous checks, as all ore is the same size. Tons of checks means it causes hanging for up to three seconds. + if(contents.len >= max_storage_space) + failure = 1 + break + I.forceMove(src) + success = 1 + if(success && !failure && !silent) + to_chat(user, "You put everything in [src].") + else if(success && (!silent || (silent && contents.len >= max_storage_space))) + to_chat(user, "You fill the [src].") + else if(!silent) + to_chat(user, "You fail to pick anything up with \the [src].") + +/obj/item/weapon/storage/bag/ore/examine(mob/user) + ..() + + if(!Adjacent(user)) //Can only check the contents of ore bags if you can physically reach them. + return + + if(istype(user, /mob/living)) + add_fingerprint(user) + + if(!contents.len) + to_chat(user, "It is empty.") + return + + if(world.time > last_update + 10) + update_ore_count() + last_update = world.time + + to_chat(user, "It holds:") + for(var/ore in stored_ore) + to_chat(user, "- [stored_ore[ore]] [ore]") + return + +/obj/item/weapon/storage/bag/ore/open(mob/user as mob) //No opening it for the weird UI of having shit-tons of ore inside it. + if(world.time > last_update + 10) + update_ore_count() + last_update = world.time + examine(user) + +/obj/item/weapon/storage/bag/ore/proc/update_ore_count() //Stolen from ore boxes. + + stored_ore = list() + + for(var/obj/item/weapon/ore/O in contents) + if(stored_ore[O.name]) + stored_ore[O.name]++ + else + stored_ore[O.name] = 1 // ----------------------------- // Plant bag @@ -112,121 +188,116 @@ storage_slots = 7 allow_quick_empty = 1 // this function is superceded - New() - ..() - //verbs -= /obj/item/weapon/storage/verb/quick_empty - //verbs += /obj/item/weapon/storage/bag/sheetsnatcher/quick_empty - can_be_inserted(obj/item/W as obj, stop_messages = 0) - if(!istype(W,/obj/item/stack/material)) - if(!stop_messages) - usr << "The snatcher does not accept [W]." - return 0 - var/current = 0 - for(var/obj/item/stack/material/S in contents) - current += S.amount - if(capacity == current)//If it's full, you're done - if(!stop_messages) - usr << "The snatcher is full." - return 0 - return 1 +/obj/item/weapon/storage/bag/sheetsnatcher/can_be_inserted(obj/item/W as obj, stop_messages = 0) + if(!istype(W,/obj/item/stack/material)) + if(!stop_messages) + usr << "The snatcher does not accept [W]." + return 0 + var/current = 0 + for(var/obj/item/stack/material/S in contents) + current += S.amount + if(capacity == current)//If it's full, you're done + if(!stop_messages) + usr << "The snatcher is full." + return 0 + return 1 // Modified handle_item_insertion. Would prefer not to, but... - handle_item_insertion(obj/item/W as obj, prevent_warning = 0) - var/obj/item/stack/material/S = W - if(!istype(S)) return 0 +/obj/item/weapon/storage/bag/sheetsnatcher/handle_item_insertion(obj/item/W as obj, prevent_warning = 0) + var/obj/item/stack/material/S = W + if(!istype(S)) return 0 - var/amount - var/inserted = 0 - var/current = 0 - for(var/obj/item/stack/material/S2 in contents) - current += S2.amount - if(capacity < current + S.amount)//If the stack will fill it up - amount = capacity - current + var/amount + var/inserted = 0 + var/current = 0 + for(var/obj/item/stack/material/S2 in contents) + current += S2.amount + if(capacity < current + S.amount)//If the stack will fill it up + amount = capacity - current + else + amount = S.amount + + for(var/obj/item/stack/material/sheet in contents) + if(S.type == sheet.type) // we are violating the amount limitation because these are not sane objects + sheet.amount += amount // they should only be removed through procs in this file, which split them up. + S.amount -= amount + inserted = 1 + break + + if(!inserted || !S.amount) + usr.remove_from_mob(S) + usr.update_icons() //update our overlays + if (usr.client && usr.s_active != src) + usr.client.screen -= S + S.dropped(usr) + if(!S.amount) + qdel(S) else - amount = S.amount + S.loc = src - for(var/obj/item/stack/material/sheet in contents) - if(S.type == sheet.type) // we are violating the amount limitation because these are not sane objects - sheet.amount += amount // they should only be removed through procs in this file, which split them up. - S.amount -= amount - inserted = 1 - break - - if(!inserted || !S.amount) - usr.remove_from_mob(S) - usr.update_icons() //update our overlays - if (usr.client && usr.s_active != src) - usr.client.screen -= S - S.dropped(usr) - if(!S.amount) - qdel(S) - else - S.loc = src - - orient2hud(usr) - if(usr.s_active) - usr.s_active.show_to(usr) - update_icon() - return 1 + orient2hud(usr) + if(usr.s_active) + usr.s_active.show_to(usr) + update_icon() + return 1 // Sets up numbered display to show the stack size of each stored mineral // NOTE: numbered display is turned off currently because it's broken - orient2hud(mob/user as mob) - var/adjusted_contents = contents.len +/obj/item/weapon/storage/bag/sheetsnatcher/orient2hud(mob/user as mob) + var/adjusted_contents = contents.len - //Numbered contents display - var/list/datum/numbered_display/numbered_contents - if(display_contents_with_number) - numbered_contents = list() - adjusted_contents = 0 - for(var/obj/item/stack/material/I in contents) - adjusted_contents++ - var/datum/numbered_display/D = new/datum/numbered_display(I) - D.number = I.amount - numbered_contents.Add( D ) - - var/row_num = 0 - var/col_count = min(7,storage_slots) -1 - if (adjusted_contents > 7) - row_num = round((adjusted_contents-1) / 7) // 7 is the maximum allowed width. - src.slot_orient_objs(row_num, col_count, numbered_contents) - return + //Numbered contents display + var/list/datum/numbered_display/numbered_contents + if(display_contents_with_number) + numbered_contents = list() + adjusted_contents = 0 + for(var/obj/item/stack/material/I in contents) + adjusted_contents++ + var/datum/numbered_display/D = new/datum/numbered_display(I) + D.number = I.amount + numbered_contents.Add( D ) + var/row_num = 0 + var/col_count = min(7,storage_slots) -1 + if (adjusted_contents > 7) + row_num = round((adjusted_contents-1) / 7) // 7 is the maximum allowed width. + src.slot_orient_objs(row_num, col_count, numbered_contents) + return // Modified quick_empty verb drops appropriate sized stacks - quick_empty() - var/location = get_turf(src) - for(var/obj/item/stack/material/S in contents) - while(S.amount) - var/obj/item/stack/material/N = new S.type(location) - var/stacksize = min(S.amount,N.max_amount) - N.amount = stacksize - S.amount -= stacksize - if(!S.amount) - qdel(S) // todo: there's probably something missing here - orient2hud(usr) - if(usr.s_active) - usr.s_active.show_to(usr) - update_icon() +/obj/item/weapon/storage/bag/sheetsnatcher/quick_empty() + var/location = get_turf(src) + for(var/obj/item/stack/material/S in contents) + while(S.amount) + var/obj/item/stack/material/N = new S.type(location) + var/stacksize = min(S.amount,N.max_amount) + N.amount = stacksize + S.amount -= stacksize + if(!S.amount) + qdel(S) // todo: there's probably something missing here + orient2hud(usr) + if(usr.s_active) + usr.s_active.show_to(usr) + update_icon() // Instead of removing - remove_from_storage(obj/item/W as obj, atom/new_location) - var/obj/item/stack/material/S = W - if(!istype(S)) return 0 +/obj/item/weapon/storage/bag/sheetsnatcher/remove_from_storage(obj/item/W as obj, atom/new_location) + var/obj/item/stack/material/S = W + if(!istype(S)) return 0 - //I would prefer to drop a new stack, but the item/attack_hand code - // that calls this can't recieve a different object than you clicked on. - //Therefore, make a new stack internally that has the remainder. - // -Sayu + //I would prefer to drop a new stack, but the item/attack_hand code + // that calls this can't recieve a different object than you clicked on. + //Therefore, make a new stack internally that has the remainder. + // -Sayu - if(S.amount > S.max_amount) - var/obj/item/stack/material/temp = new S.type(src) - temp.amount = S.amount - S.max_amount - S.amount = S.max_amount + if(S.amount > S.max_amount) + var/obj/item/stack/material/temp = new S.type(src) + temp.amount = S.amount - S.max_amount + S.amount = S.max_amount - return ..(S,new_location) + return ..(S,new_location) // ----------------------------- // Sheet Snatcher (Cyborg) diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index 9e98fe58ec..e4482932b1 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -8,7 +8,7 @@ max_w_class = ITEMSIZE_NORMAL slot_flags = SLOT_BELT attack_verb = list("whipped", "lashed", "disciplined") - sprite_sheets = list("Teshari" = 'icons/mob/species/seromi/belt.dmi') + sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/seromi/belt.dmi') var/show_above_suit = 0 @@ -22,6 +22,16 @@ show_above_suit = !show_above_suit update_icon() +//Some belts have sprites to show icons +/obj/item/weapon/storage/belt/make_worn_icon(var/body_type,var/slot_name,var/inhands,var/default_icon,var/default_layer = 0) + var/image/standing = ..() + if(!inhands && contents.len) + for(var/obj/item/i in contents) + var/i_state = i.item_state + if(!i_state) i_state = i.icon_state + standing.add_overlay(image(icon = INV_BELT_DEF_ICON, icon_state = i_state)) + return standing + /obj/item/weapon/storage/update_icon() if (ismob(src.loc)) var/mob/M = src.loc @@ -59,23 +69,25 @@ /obj/item/device/integrated_electronics/wirer, ) -/obj/item/weapon/storage/belt/utility/full/New() - ..() - new /obj/item/weapon/screwdriver(src) - new /obj/item/weapon/wrench(src) - new /obj/item/weapon/weldingtool(src) - new /obj/item/weapon/crowbar(src) - new /obj/item/weapon/wirecutters(src) - new /obj/item/stack/cable_coil(src,30,pick("red","yellow","orange")) +/obj/item/weapon/storage/belt/utility/full + starts_with = list( + /obj/item/weapon/screwdriver, + /obj/item/weapon/wrench, + /obj/item/weapon/weldingtool, + /obj/item/weapon/crowbar, + /obj/item/weapon/wirecutters, + /obj/item/stack/cable_coil/random_belt + ) -/obj/item/weapon/storage/belt/utility/atmostech/New() - ..() - new /obj/item/weapon/screwdriver(src) - new /obj/item/weapon/wrench(src) - new /obj/item/weapon/weldingtool(src) - new /obj/item/weapon/crowbar(src) - new /obj/item/weapon/wirecutters(src) - new /obj/item/device/t_scanner(src) +/obj/item/weapon/storage/belt/utility/atmostech + starts_with = list( + /obj/item/weapon/screwdriver, + /obj/item/weapon/wrench, + /obj/item/weapon/weldingtool, + /obj/item/weapon/crowbar, + /obj/item/weapon/wirecutters, + /obj/item/device/t_scanner + ) /obj/item/weapon/storage/belt/utility/chief name = "chief engineer's toolbelt" @@ -83,15 +95,16 @@ icon_state = "utilitybelt_ce" item_state = "utility_ce" -/obj/item/weapon/storage/belt/utility/chief/full/New() - ..() - new /obj/item/weapon/screwdriver/power(src) - new /obj/item/weapon/crowbar/power(src) - new /obj/item/weapon/weldingtool/experimental(src) - new /obj/item/device/multitool(src) - new /obj/item/stack/cable_coil(src,30,pick("red","yellow","orange")) - new /obj/item/weapon/extinguisher/mini(src) - new /obj/item/device/analyzer(src) +/obj/item/weapon/storage/belt/utility/chief/full + starts_with = list( + /obj/item/weapon/screwdriver/power, + /obj/item/weapon/crowbar/power, + /obj/item/weapon/weldingtool/experimental, + /obj/item/device/multitool, + /obj/item/stack/cable_coil/random_belt, + /obj/item/weapon/extinguisher/mini, + /obj/item/device/analyzer + ) /obj/item/weapon/storage/belt/medical name = "medical belt" @@ -121,7 +134,8 @@ /obj/item/weapon/crowbar, /obj/item/device/flashlight, /obj/item/weapon/cell/device, - /obj/item/weapon/extinguisher/mini + /obj/item/weapon/extinguisher/mini, + /obj/item/weapon/storage/quickdraw/syringe_case ) /obj/item/weapon/storage/belt/medical/emt @@ -216,14 +230,8 @@ /obj/item/device/soulstone ) -/obj/item/weapon/storage/belt/soulstone/full/New() - ..() - new /obj/item/device/soulstone(src) - new /obj/item/device/soulstone(src) - new /obj/item/device/soulstone(src) - new /obj/item/device/soulstone(src) - new /obj/item/device/soulstone(src) - new /obj/item/device/soulstone(src) +/obj/item/weapon/storage/belt/soulstone/full + starts_with = list(/obj/item/device/soulstone = 6) /obj/item/weapon/storage/belt/utility/alien name = "alien belt" @@ -232,15 +240,16 @@ icon_state = "belt" item_state = "security" -/obj/item/weapon/storage/belt/utility/alien/full/New() - ..() - new /obj/item/weapon/screwdriver/alien(src) - new /obj/item/weapon/wrench/alien(src) - new /obj/item/weapon/weldingtool/alien(src) - new /obj/item/weapon/crowbar/alien(src) - new /obj/item/weapon/wirecutters/alien(src) - new /obj/item/device/multitool/alien(src) - new /obj/item/stack/cable_coil/alien(src) +/obj/item/weapon/storage/belt/utility/alien/full + starts_with = list( + /obj/item/weapon/screwdriver/alien, + /obj/item/weapon/wrench/alien, + /obj/item/weapon/weldingtool/alien, + /obj/item/weapon/crowbar/alien, + /obj/item/weapon/wirecutters/alien, + /obj/item/device/multitool/alien, + /obj/item/stack/cable_coil/alien + ) /obj/item/weapon/storage/belt/medical/alien name = "alien belt" @@ -277,16 +286,17 @@ /obj/item/weapon/surgical ) -/obj/item/weapon/storage/belt/medical/alien/New() - ..() - new /obj/item/weapon/surgical/scalpel/alien(src) - new /obj/item/weapon/surgical/hemostat/alien(src) - new /obj/item/weapon/surgical/retractor/alien(src) - new /obj/item/weapon/surgical/circular_saw/alien(src) - new /obj/item/weapon/surgical/FixOVein/alien(src) - new /obj/item/weapon/surgical/bone_clamp/alien(src) - new /obj/item/weapon/surgical/cautery/alien(src) - new /obj/item/weapon/surgical/surgicaldrill/alien(src) +/obj/item/weapon/storage/belt/medical/alien + starts_with = list( + /obj/item/weapon/surgical/scalpel/alien, + /obj/item/weapon/surgical/hemostat/alien, + /obj/item/weapon/surgical/retractor/alien, + /obj/item/weapon/surgical/circular_saw/alien, + /obj/item/weapon/surgical/FixOVein/alien, + /obj/item/weapon/surgical/bone_clamp/alien, + /obj/item/weapon/surgical/cautery/alien, + /obj/item/weapon/surgical/surgicaldrill/alien + ) /obj/item/weapon/storage/belt/champion name = "championship belt" @@ -363,7 +373,9 @@ /obj/item/weapon/storage/excavation, /obj/item/weapon/anobattery, /obj/item/device/ano_scanner, - /obj/item/weapon/pickaxe/hand + /obj/item/weapon/pickaxe/hand, + /obj/item/device/xenoarch_multi_tool, + /obj/item/weapon/pickaxe/excavationdrill ) /obj/item/weapon/storage/belt/fannypack diff --git a/code/game/objects/items/weapons/storage/bible.dm b/code/game/objects/items/weapons/storage/bible.dm index 933970b335..783d8cd74a 100644 --- a/code/game/objects/items/weapons/storage/bible.dm +++ b/code/game/objects/items/weapons/storage/bible.dm @@ -14,12 +14,13 @@ icon_state ="bible" /obj/item/weapon/storage/bible/booze/New() - ..() - new /obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer(src) - new /obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer(src) - new /obj/item/weapon/spacecash/c100(src) - new /obj/item/weapon/spacecash/c100(src) - new /obj/item/weapon/spacecash/c100(src) + starts_with = list( + /obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer, + /obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer, + /obj/item/weapon/spacecash/c100, + /obj/item/weapon/spacecash/c100, + /obj/item/weapon/spacecash/c100 + ) /obj/item/weapon/storage/bible/afterattack(atom/A, mob/user as mob, proximity) if(!proximity) return diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index 31547916b1..f7e43ac718 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -23,7 +23,7 @@ name = "box" desc = "It's just an ordinary box." icon_state = "box" - item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit") + item_state = "syringe_kit" var/foldable = /obj/item/stack/material/cardboard // BubbleWrap - if set, can be folded (when empty) into a sheet of cardboard max_w_class = ITEMSIZE_SMALL max_storage_space = INVENTORY_BOX_SPACE @@ -52,412 +52,278 @@ new foldable(get_turf(src)) qdel(src) -/obj/item/weapon/storage/box/survival/New() - ..() - new /obj/item/clothing/mask/breath(src) - new /obj/item/weapon/tank/emergency/oxygen(src) +/obj/item/weapon/storage/box/survival + name = "emergency supply box" + desc = "A survival box issued to crew members for use in emergency situations." + starts_with = list( + /obj/item/clothing/mask/breath + ) -/obj/item/weapon/storage/box/vox/New() - ..() - new /obj/item/clothing/mask/breath(src) - new /obj/item/weapon/tank/emergency/phoron(src) +/obj/item/weapon/storage/box/survival/synth + name = "synthetic supply box" + desc = "A survival box issued to synthetic crew members for use in emergency situations." + starts_with = list() -/obj/item/weapon/storage/box/engineer/New() - ..() - new /obj/item/clothing/mask/breath(src) - new /obj/item/weapon/tank/emergency/oxygen/engi(src) +/obj/item/weapon/storage/box/survival/comp + name = "emergency supply box" + desc = "A comprehensive survival box issued to crew members for use in emergency situations. Contains additional supplies." + icon_state = "survival" + starts_with = list( + /obj/item/weapon/reagent_containers/hypospray/autoinjector, + /obj/item/stack/medical/bruise_pack, + /obj/item/device/flashlight/glowstick, + /obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar, + /obj/item/clothing/mask/breath + ) /obj/item/weapon/storage/box/gloves name = "box of latex gloves" desc = "Contains white gloves." icon_state = "latex" - -/obj/item/weapon/storage/box/gloves/New() - ..() - for(var/i = 1 to 7) - new /obj/item/clothing/gloves/sterile/latex(src) + starts_with = list(/obj/item/clothing/gloves/sterile/latex = 7) /obj/item/weapon/storage/box/masks name = "box of sterile masks" desc = "This box contains masks of sterility." icon_state = "sterile" - -/obj/item/weapon/storage/box/masks/New() - ..() - for(var/i = 1 to 7) - new /obj/item/clothing/mask/surgical(src) + starts_with = list(/obj/item/clothing/mask/surgical = 7) /obj/item/weapon/storage/box/syringes name = "box of syringes" desc = "A box full of syringes." icon_state = "syringe" - -/obj/item/weapon/storage/box/syringes/New() - ..() - for(var/i = 1 to 7) - new /obj/item/weapon/reagent_containers/syringe(src) + starts_with = list(/obj/item/weapon/reagent_containers/syringe = 7) /obj/item/weapon/storage/box/syringegun name = "box of syringe gun cartridges" desc = "A box full of compressed gas cartridges." icon_state = "syringe" - -/obj/item/weapon/storage/box/syringegun/New() - ..() - for(var/i = 1 to 7) - new /obj/item/weapon/syringe_cartridge(src) + starts_with = list(/obj/item/weapon/syringe_cartridge = 7) /obj/item/weapon/storage/box/beakers name = "box of beakers" icon_state = "beaker" - -/obj/item/weapon/storage/box/beakers/New() - ..() - for(var/i = 1 to 7) - new /obj/item/weapon/reagent_containers/glass/beaker(src) + starts_with = list(/obj/item/weapon/reagent_containers/glass/beaker = 7) /obj/item/weapon/storage/box/injectors name = "box of DNA injectors" desc = "This box contains injectors it seems." - -/obj/item/weapon/storage/box/injectors/New() - ..() - for(var/i = 1 to 3) - new /obj/item/weapon/dnainjector/h2m(src) - for(var/i = 1 to 3) - new /obj/item/weapon/dnainjector/m2h(src) + starts_with = list( + /obj/item/weapon/dnainjector/h2m = 3, + /obj/item/weapon/dnainjector/m2h = 3 + ) /obj/item/weapon/storage/box/blanks name = "box of blank shells" desc = "It has a picture of a gun and several warning symbols on the front." icon_state = "blankshot_box" item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit") + starts_with = list(/obj/item/ammo_casing/a12g/blank = 8) -/obj/item/weapon/storage/box/blanks/New() - ..() - for(var/i = 1 to 8) - new /obj/item/ammo_casing/a12g/blank(src) - -/obj/item/weapon/storage/box/blanks/large/New() - ..() - for(var/i = 1 to 8) - new /obj/item/ammo_casing/a12g/blank(src) +/obj/item/weapon/storage/box/blanks/large + starts_with = list(/obj/item/ammo_casing/a12g/blank = 16) /obj/item/weapon/storage/box/beanbags name = "box of beanbag shells" desc = "It has a picture of a gun and several warning symbols on the front.
WARNING: Live ammunition. Misuse may result in serious injury or death." icon_state = "beanshot_box" item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit") - -/obj/item/weapon/storage/box/beanbags/New() - ..() - for(var/i = 1 to 8) - new /obj/item/ammo_casing/a12g/beanbag(src) + starts_with = list(/obj/item/ammo_casing/a12g/beanbag = 8) /obj/item/weapon/storage/box/beanbags/large/New() - ..() - for(var/i = 1 to 8) - new /obj/item/ammo_casing/a12g/beanbag(src) + starts_with = list(/obj/item/ammo_casing/a12g/beanbag = 16) /obj/item/weapon/storage/box/shotgunammo name = "box of shotgun slugs" desc = "It has a picture of a gun and several warning symbols on the front.
WARNING: Live ammunition. Misuse may result in serious injury or death." icon_state = "lethalshellshot_box" item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit") + starts_with = list(/obj/item/ammo_casing/a12g = 8) -/obj/item/weapon/storage/box/shotgunammo/New() - ..() - for(var/i = 1 to 8) - new /obj/item/ammo_casing/a12g(src) - -/obj/item/weapon/storage/box/shotgunammo/large/New() - ..() - for(var/i = 1 to 8) - new /obj/item/ammo_casing/a12g(src) +/obj/item/weapon/storage/box/shotgunammo/large + starts_with = list(/obj/item/ammo_casing/a12g = 16) /obj/item/weapon/storage/box/shotgunshells name = "box of shotgun shells" desc = "It has a picture of a gun and several warning symbols on the front.
WARNING: Live ammunition. Misuse may result in serious injury or death." icon_state = "lethalslug_box" item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit") + starts_with = list(/obj/item/ammo_casing/a12g/pellet = 8) -/obj/item/weapon/storage/box/shotgunshells/New() - ..() - for(var/i = 1 to 8) - new /obj/item/ammo_casing/a12g/pellet(src) - -/obj/item/weapon/storage/box/shotgunshells/large/New() - ..() - for(var/i = 1 to 8) - new /obj/item/ammo_casing/a12g/pellet(src) +/obj/item/weapon/storage/box/shotgunshells/large + starts_with = list(/obj/item/ammo_casing/a12g/pellet = 16) /obj/item/weapon/storage/box/flashshells name = "box of illumination shells" desc = "It has a picture of a gun and several warning symbols on the front.
WARNING: Live ammunition. Misuse may result in serious injury or death." icon_state = "illumshot_box" item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit") + starts_with = list(/obj/item/ammo_casing/a12g/flash = 8) -/obj/item/weapon/storage/box/flashshells/New() - ..() - for(var/i = 1 to 8) - new /obj/item/ammo_casing/a12g/flash(src) - -/obj/item/weapon/storage/box/flashshells/large/New() - ..() - for(var/i = 1 to 8) - new /obj/item/ammo_casing/a12g/flash(src) +/obj/item/weapon/storage/box/flashshells/large + starts_with = list(/obj/item/ammo_casing/a12g/flash = 16) /obj/item/weapon/storage/box/stunshells name = "box of stun shells" desc = "It has a picture of a gun and several warning symbols on the front.
WARNING: Live ammunition. Misuse may result in serious injury or death." icon_state = "stunshot_box" item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit") + starts_with = list(/obj/item/ammo_casing/a12g/stunshell = 8) -/obj/item/weapon/storage/box/stunshells/New() - ..() - for(var/i = 1 to 8) - new /obj/item/ammo_casing/a12g/stunshell(src) - -/obj/item/weapon/storage/box/stunshells/large/New() - ..() - for(var/i = 1 to 8) - new /obj/item/ammo_casing/a12g/stunshell(src) +/obj/item/weapon/storage/box/stunshells/large + starts_with = list(/obj/item/ammo_casing/a12g/stunshell = 16) /obj/item/weapon/storage/box/practiceshells name = "box of practice shells" desc = "It has a picture of a gun and several warning symbols on the front.
WARNING: Live ammunition. Misuse may result in serious injury or death." icon_state = "blankshot_box" item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit") + starts_with = list(/obj/item/ammo_casing/a12g/practice = 8) -/obj/item/weapon/storage/box/practiceshells/New() - ..() - for(var/i = 1 to 8) - new /obj/item/ammo_casing/a12g/practice(src) - -/obj/item/weapon/storage/box/practiceshells/large/New() - ..() - for(var/i = 1 to 8) - new /obj/item/ammo_casing/a12g/practice(src) +/obj/item/weapon/storage/box/practiceshells/large + starts_with = list(/obj/item/ammo_casing/a12g/practice = 16) /obj/item/weapon/storage/box/empshells name = "box of emp shells" desc = "It has a picture of a gun and several warning symbols on the front." icon_state = "empshot_box" item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit") + starts_with = list(/obj/item/ammo_casing/a12g/emp = 8) -/obj/item/weapon/storage/box/empshells/New() - ..() - for(var/i = 1 to 8) - new /obj/item/ammo_casing/a12g/emp(src) - -/obj/item/weapon/storage/box/empshells/large/New() - ..() - for(var/i = 1 to 8) - new /obj/item/ammo_casing/a12g/emp(src) +/obj/item/weapon/storage/box/empshells/large + starts_with = list(/obj/item/ammo_casing/a12g/emp = 16) /obj/item/weapon/storage/box/sniperammo name = "box of 14.5mm shells" desc = "It has a picture of a gun and several warning symbols on the front.
WARNING: Live ammunition. Misuse may result in serious injury or death." - -/obj/item/weapon/storage/box/sniperammo/New() - ..() - for(var/i = 1 to 7) - new /obj/item/ammo_casing/a145(src) + starts_with = list(/obj/item/ammo_casing/a145 = 7) /obj/item/weapon/storage/box/flashbangs name = "box of flashbangs (WARNING)" desc = "WARNING: These devices are extremely dangerous and can cause blindness or deafness in repeated use." icon_state = "flashbang" - -/obj/item/weapon/storage/box/flashbangs/New() - ..() - for(var/i = 1 to 7) - new /obj/item/weapon/grenade/flashbang(src) + starts_with = list(/obj/item/weapon/grenade/flashbang = 7) /obj/item/weapon/storage/box/emps name = "box of emp grenades" desc = "A box containing 5 military grade EMP grenades.
WARNING: Do not use near unshielded electronics or biomechanical augmentations, death or permanent paralysis may occur." icon_state = "emp" - -/obj/item/weapon/storage/box/emps/New() - ..() - for(var/i = 1 to 7) - new /obj/item/weapon/grenade/empgrenade(src) + starts_with = list(/obj/item/weapon/grenade/empgrenade = 7) /obj/item/weapon/storage/box/empslite name = "box of low yield emp grenades" desc = "A box containing 5 low yield EMP grenades.
WARNING: Do not use near unshielded electronics or biomechanical augmentations, death or permanent paralysis may occur." icon_state = "emp" - -/obj/item/weapon/storage/box/empslite/New() - ..() - for(var/i = 1 to 7) - new /obj/item/weapon/grenade/empgrenade/low_yield(src) + starts_with = list(/obj/item/weapon/grenade/empgrenade/low_yield = 7) /obj/item/weapon/storage/box/smokes name = "box of smoke bombs" desc = "A box containing 7 smoke bombs." icon_state = "flashbang" - -/obj/item/weapon/storage/box/smokes/New() - ..() - for(var/i = 1 to 7) - new /obj/item/weapon/grenade/smokebomb(src) + starts_with = list(/obj/item/weapon/grenade/smokebomb = 7) /obj/item/weapon/storage/box/anti_photons name = "box of anti-photon grenades" desc = "A box containing 7 experimental photon disruption grenades." icon_state = "flashbang" - -/obj/item/weapon/storage/box/anti_photons/New() - ..() - for(var/i = 1 to 7) - new /obj/item/weapon/grenade/anti_photon(src) + starts_with = list(/obj/item/weapon/grenade/anti_photon = 7) /obj/item/weapon/storage/box/frags name = "box of fragmentation grenades (WARNING)" desc = "A box containing 7 military grade fragmentation grenades.
WARNING: These devices are extremely dangerous and can cause limb loss or death in repeated use." icon_state = "frag" - -/obj/item/weapon/storage/box/frags/New() - ..() - for(var/i = 1 to 7) - new /obj/item/weapon/grenade/explosive(src) + starts_with = list(/obj/item/weapon/grenade/explosive = 7) /obj/item/weapon/storage/box/frags_half_box name = "box of fragmentation grenades (WARNING)" desc = "A box containing 4 military grade fragmentation grenades.
WARNING: These devices are extremely dangerous and can cause limb loss or death in repeated use." icon_state = "frag" - -/obj/item/weapon/storage/box/frags_half_box/New() - ..() - for(var/i = 1 to 4) - new /obj/item/weapon/grenade/explosive(src) + starts_with = list(/obj/item/weapon/grenade/explosive = 4) /obj/item/weapon/storage/box/metalfoam name = "box of metal foam grenades." desc = "A box containing 7 metal foam grenades." icon_state = "flashbang" - -/obj/item/weapon/storage/box/metalfoam/New() - ..() - for(var/i = 1 to 7) - new /obj/item/weapon/grenade/chem_grenade/metalfoam(src) + starts_with = list(/obj/item/weapon/grenade/chem_grenade/metalfoam = 7) /obj/item/weapon/storage/box/teargas name = "box of teargas grenades" desc = "A box containing 7 teargas grenades." icon_state = "flashbang" - -/obj/item/weapon/storage/box/teargas/New() - ..() - for(var/i = 1 to 7) - new /obj/item/weapon/grenade/chem_grenade/teargas(src) + starts_with = list(/obj/item/weapon/grenade/chem_grenade/teargas = 7) /obj/item/weapon/storage/box/flare name = "box of flares" desc = "A box containing 4 flares." - -/obj/item/weapon/storage/box/flare/New() - ..() - for(var/i = 1 to 4) - new /obj/item/device/flashlight/flare(src) + starts_with = list(/obj/item/device/flashlight/flare = 4) /obj/item/weapon/storage/box/trackimp name = "boxed tracking implant kit" desc = "Box full of scum-bag tracking utensils." icon_state = "implant" - -/obj/item/weapon/storage/box/trackimp/New() - ..() - for(var/i = 1 to 4) - new /obj/item/weapon/implantcase/tracking(src) - new /obj/item/weapon/implanter(src) - new /obj/item/weapon/implantpad(src) - new /obj/item/weapon/locator(src) + starts_with = list( + /obj/item/weapon/implantcase/tracking = 4, + /obj/item/weapon/implanter, + /obj/item/weapon/implantpad, + /obj/item/weapon/locator + ) /obj/item/weapon/storage/box/chemimp name = "boxed chemical implant kit" desc = "Box of stuff used to implant chemicals." icon_state = "implant" - -/obj/item/weapon/storage/box/chemimp/New() - ..() - for(var/i = 1 to 5) - new /obj/item/weapon/implantcase/chem(src) - new /obj/item/weapon/implanter(src) - new /obj/item/weapon/implantpad(src) + starts_with = list( + /obj/item/weapon/implantcase/chem = 5, + /obj/item/weapon/implanter, + /obj/item/weapon/implantpad + ) /obj/item/weapon/storage/box/camerabug name = "mobile camera pod box" desc = "A box containing some mobile camera pods." icon_state = "pda" - -/obj/item/weapon/storage/box/camerabug/New() - ..() - for(var/i = 1 to 6) - new /obj/item/device/camerabug(src) - new /obj/item/device/bug_monitor(src) + starts_with = list( + /obj/item/device/camerabug = 6, + /obj/item/device/bug_monitor + ) /obj/item/weapon/storage/box/rxglasses name = "box of prescription glasses" desc = "This box contains nerd glasses." icon_state = "glasses" - -/obj/item/weapon/storage/box/rxglasses/New() - ..() - for(var/i = 1 to 7) - new /obj/item/clothing/glasses/regular(src) + starts_with = list(/obj/item/clothing/glasses/regular = 7) /obj/item/weapon/storage/box/cdeathalarm_kit name = "death alarm kit" desc = "Box of stuff used to implant death alarms." icon_state = "implant" item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit") - -/obj/item/weapon/storage/box/cdeathalarm_kit/New() - ..() - for(var/i = 1 to 7) - new /obj/item/weapon/implantcase/death_alarm(src) - new /obj/item/weapon/implanter(src) + starts_with = list( + /obj/item/weapon/implantcase/death_alarm = 7, + /obj/item/weapon/implanter + ) /obj/item/weapon/storage/box/condimentbottles name = "box of condiment bottles" desc = "It has a large ketchup smear on it." - -/obj/item/weapon/storage/box/condimentbottles/New() - ..() - for(var/i = 1 to 7) - new /obj/item/weapon/reagent_containers/food/condiment(src) + starts_with = list(/obj/item/weapon/reagent_containers/food/condiment = 7) /obj/item/weapon/storage/box/cups name = "box of paper cups" desc = "It has pictures of paper cups on the front." - -/obj/item/weapon/storage/box/cups/New() - ..() - for(var/i = 1 to 7) - new /obj/item/weapon/reagent_containers/food/drinks/sillycup(src) + starts_with = list(/obj/item/weapon/reagent_containers/food/drinks/sillycup = 7) /obj/item/weapon/storage/box/donkpockets name = "box of donk-pockets" desc = "Instructions: Heat in microwave. Product will cool if not eaten within seven minutes." icon_state = "donk_kit" - -/obj/item/weapon/storage/box/donkpockets/New() - ..() - for(var/i = 1 to 7) - new /obj/item/weapon/reagent_containers/food/snacks/donkpocket(src) + starts_with = list(/obj/item/weapon/reagent_containers/food/snacks/donkpocket = 7) /obj/item/weapon/storage/box/sinpockets name = "box of sin-pockets" desc = "Instructions: Crush bottom of package to initiate chemical heating. Wait for 20 seconds before consumption. Product will cool if not eaten within seven minutes." icon_state = "donk_kit" - -/obj/item/weapon/storage/box/sinpockets/New() - ..() - for(var/i = 1 to 7) - new /obj/item/weapon/reagent_containers/food/snacks/donkpocket/sinpocket(src) + starts_with = list(/obj/item/weapon/reagent_containers/food/snacks/donkpocket/sinpocket = 7) /obj/item/weapon/storage/box/monkeycubes name = "monkey cube box" @@ -465,88 +331,51 @@ icon = 'icons/obj/food.dmi' icon_state = "monkeycubebox" can_hold = list(/obj/item/weapon/reagent_containers/food/snacks/monkeycube) - -/obj/item/weapon/storage/box/monkeycubes/New() - ..() - if(type == /obj/item/weapon/storage/box/monkeycubes) - for(var/i = 1 to 4) - new /obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped(src) + starts_with = list(/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped = 4) /obj/item/weapon/storage/box/monkeycubes/farwacubes name = "farwa cube box" desc = "Drymate brand farwa cubes, shipped from Meralar. Just add water!" - -/obj/item/weapon/storage/box/monkeycubes/farwacubes/New() - ..() - for(var/i = 1 to 4) - new /obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/farwacube(src) + starts_with = list(/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/farwacube = 4) /obj/item/weapon/storage/box/monkeycubes/stokcubes name = "stok cube box" desc = "Drymate brand stok cubes, shipped from Moghes. Just add water!" - -/obj/item/weapon/storage/box/monkeycubes/stokcubes/New() - ..() - for(var/i = 1 to 4) - new /obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/stokcube(src) + starts_with = list(/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/stokcube = 4) /obj/item/weapon/storage/box/monkeycubes/neaeracubes name = "neaera cube box" desc = "Drymate brand neaera cubes, shipped from Jargon 4. Just add water!" - -/obj/item/weapon/storage/box/monkeycubes/neaeracubes/New() - ..() - for(var/i = 1 to 4) - new /obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/neaeracube(src) + starts_with = list(/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/neaeracube = 4) /obj/item/weapon/storage/box/ids name = "box of spare IDs" desc = "Has so many empty IDs." icon_state = "id" - -/obj/item/weapon/storage/box/ids/New() - ..() - for(var/i = 1 to 7) - new /obj/item/weapon/card/id(src) + starts_with = list(/obj/item/weapon/card/id = 7) /obj/item/weapon/storage/box/seccarts name = "box of spare R.O.B.U.S.T. Cartridges" desc = "A box full of R.O.B.U.S.T. Cartridges, used by Security." icon_state = "pda" - -/obj/item/weapon/storage/box/seccarts/New() - ..() - for(var/i = 1 to 7) - new /obj/item/weapon/cartridge/security(src) + starts_with = list(/obj/item/weapon/cartridge/security = 7) /obj/item/weapon/storage/box/handcuffs name = "box of spare handcuffs" desc = "A box full of handcuffs." icon_state = "handcuff" - -/obj/item/weapon/storage/box/handcuffs/New() - ..() - for(var/i = 1 to 7) - new /obj/item/weapon/handcuffs(src) + starts_with = list(/obj/item/weapon/handcuffs = 7) /obj/item/weapon/storage/box/mousetraps name = "box of Pest-B-Gon mousetraps" desc = "WARNING: Keep out of reach of children." icon_state = "mousetraps" - -/obj/item/weapon/storage/box/mousetraps/New() - ..() - for(var/i = 1 to 7) - new /obj/item/device/assembly/mousetrap(src) + starts_with = list(/obj/item/device/assembly/mousetrap = 7) /obj/item/weapon/storage/box/pillbottles name = "box of pill bottles" desc = "It has pictures of pill bottles on its front." - -/obj/item/weapon/storage/box/pillbottles/New() - ..() - for(var/i = 1 to 7) - new /obj/item/weapon/storage/pill_bottle(src) + starts_with = list(/obj/item/weapon/storage/pill_bottle = 7) /obj/item/weapon/storage/box/snappops name = "snap pop box" @@ -554,11 +383,7 @@ icon = 'icons/obj/toy.dmi' icon_state = "spbox" can_hold = list(/obj/item/toy/snappop) - -/obj/item/weapon/storage/box/snappops/New() - ..() - for(var/i = 1 to 8) - new /obj/item/toy/snappop(src) + starts_with = list(/obj/item/toy/snappop = 8) /obj/item/weapon/storage/box/matches name = "matchbox" @@ -568,11 +393,7 @@ w_class = ITEMSIZE_TINY slot_flags = SLOT_BELT can_hold = list(/obj/item/weapon/flame/match) - -/obj/item/weapon/storage/box/matches/New() - ..() - for(var/i=1 to 10) - new /obj/item/weapon/flame/match(src) + starts_with = list(/obj/item/weapon/flame/match = 10) /obj/item/weapon/storage/box/matches/attackby(obj/item/weapon/flame/match/W as obj, mob/user as mob) if(istype(W) && !W.lit && !W.burnt) @@ -587,11 +408,7 @@ name = "box of injectors" desc = "Contains autoinjectors." icon_state = "syringe" - -/obj/item/weapon/storage/box/autoinjectors/New() - ..() - for (var/i = 1 to 7) - new /obj/item/weapon/reagent_containers/hypospray/autoinjector(src) + starts_with = list(/obj/item/weapon/reagent_containers/hypospray/autoinjector = 7) /obj/item/weapon/storage/box/lights name = "box of replacement bulbs" @@ -604,30 +421,21 @@ max_storage_space = ITEMSIZE_COST_SMALL * 24 //holds 24 items of w_class 2 use_to_pickup = 1 // for picking up broken bulbs, not that most people will try -/obj/item/weapon/storage/box/lights/bulbs/New() - ..() - for(var/i = 1 to 24) - new /obj/item/weapon/light/bulb(src) +/obj/item/weapon/storage/box/lights/bulbs + starts_with = list(/obj/item/weapon/light/bulb = 24) /obj/item/weapon/storage/box/lights/tubes name = "box of replacement tubes" icon_state = "lighttube" - -/obj/item/weapon/storage/box/lights/tubes/New() - ..() - for(var/i = 1 to 24) - new /obj/item/weapon/light/tube(src) + starts_with = list(/obj/item/weapon/light/tube = 24) /obj/item/weapon/storage/box/lights/mixed name = "box of replacement lights" icon_state = "lightmixed" - -/obj/item/weapon/storage/box/lights/mixed/New() - ..() - for(var/i = 1 to 16) - new /obj/item/weapon/light/tube(src) - for(var/i = 1 to 8) - new /obj/item/weapon/light/bulb(src) + starts_with = list( + /obj/item/weapon/light/tube = 16, + /obj/item/weapon/light/bulb = 8 + ) /obj/item/weapon/storage/box/freezer name = "portable freezer" @@ -660,17 +468,9 @@ /obj/item/weapon/storage/box/ambrosia name = "ambrosia seeds box" desc = "Contains the seeds you need to get a little high." - -/obj/item/weapon/storage/box/ambrosia/New() - ..() - for(var/i = 1 to 7) - new /obj/item/seeds/ambrosiavulgarisseed(src) + starts_with = list(/obj/item/seeds/ambrosiavulgarisseed = 7) /obj/item/weapon/storage/box/ambrosiadeus name = "ambrosia deus seeds box" desc = "Contains the seeds you need to get a proper healthy high." - -/obj/item/weapon/storage/box/ambrosiadeus/New() - ..() - for(var/i = 1 to 7) - new /obj/item/seeds/ambrosiadeusseed(src) + starts_with = list(/obj/item/seeds/ambrosiadeusseed = 7) diff --git a/code/game/objects/items/weapons/storage/fancy.dm b/code/game/objects/items/weapons/storage/fancy.dm index 8cc10444ef..762720e390 100644 --- a/code/game/objects/items/weapons/storage/fancy.dm +++ b/code/game/objects/items/weapons/storage/fancy.dm @@ -52,12 +52,7 @@ /obj/item/weapon/reagent_containers/food/snacks/egg, /obj/item/weapon/reagent_containers/food/snacks/boiledegg ) - -/obj/item/weapon/storage/fancy/egg_box/New() - ..() - for(var/i=1 to storage_slots) - new /obj/item/weapon/reagent_containers/food/snacks/egg(src) - return + starts_with = list(/obj/item/weapon/reagent_containers/food/snacks/egg = 12) /* * Candle Box @@ -72,12 +67,7 @@ item_state = "candlebox5" throwforce = 2 slot_flags = SLOT_BELT - -/obj/item/weapon/storage/fancy/candle_box/New() - ..() - for(var/i=1 to 5) - new /obj/item/weapon/flame/candle(src) - return + starts_with = list(/obj/item/weapon/flame/candle = 5) /* * Crayon Box @@ -93,31 +83,76 @@ can_hold = list( /obj/item/weapon/pen/crayon ) + starts_with = list( + /obj/item/weapon/pen/crayon/red, + /obj/item/weapon/pen/crayon/orange, + /obj/item/weapon/pen/crayon/yellow, + /obj/item/weapon/pen/crayon/green, + /obj/item/weapon/pen/crayon/blue, + /obj/item/weapon/pen/crayon/purple + ) -/obj/item/weapon/storage/fancy/crayons/New() - ..() - new /obj/item/weapon/pen/crayon/red(src) - new /obj/item/weapon/pen/crayon/orange(src) - new /obj/item/weapon/pen/crayon/yellow(src) - new /obj/item/weapon/pen/crayon/green(src) - new /obj/item/weapon/pen/crayon/blue(src) - new /obj/item/weapon/pen/crayon/purple(src) +/obj/item/weapon/storage/fancy/crayons/initialize() + . = ..() update_icon() /obj/item/weapon/storage/fancy/crayons/update_icon() - overlays = list() //resets list - overlays += image('icons/obj/crayons.dmi',"crayonbox") + var/mutable_appearance/ma = new(src) + ma.overlays = list() for(var/obj/item/weapon/pen/crayon/crayon in contents) - overlays += image('icons/obj/crayons.dmi',crayon.colourName) + ma.overlays += image('icons/obj/crayons.dmi',crayon.colourName) + appearance = ma /obj/item/weapon/storage/fancy/crayons/attackby(obj/item/W as obj, mob/user as mob) if(istype(W,/obj/item/weapon/pen/crayon)) switch(W:colourName) if("mime") - usr << "This crayon is too sad to be contained in this box." + to_chat(usr,"This crayon is too sad to be contained in this box.") return if("rainbow") - usr << "This crayon is too powerful to be contained in this box." + to_chat(usr,"This crayon is too powerful to be contained in this box.") + return + ..() + +/obj/item/weapon/storage/fancy/markers + name = "box of markers" + desc = "A very professional looking box of permanent markers." + icon = 'icons/obj/crayons.dmi' + icon_state = "markerbox" + w_class = ITEMSIZE_SMALL + icon_type = "marker" + can_hold = list( + /obj/item/weapon/pen/crayon/marker + ) + starts_with = list( + /obj/item/weapon/pen/crayon/marker/black, + /obj/item/weapon/pen/crayon/marker/red, + /obj/item/weapon/pen/crayon/marker/orange, + /obj/item/weapon/pen/crayon/marker/yellow, + /obj/item/weapon/pen/crayon/marker/green, + /obj/item/weapon/pen/crayon/marker/blue, + /obj/item/weapon/pen/crayon/marker/purple + ) + +/obj/item/weapon/storage/fancy/markers/initialize() + . = ..() + update_icon() + +/obj/item/weapon/storage/fancy/markers/update_icon() + var/mutable_appearance/ma = new(src) + ma.overlays = list() + for(var/obj/item/weapon/pen/crayon/marker/marker in contents) + ma.overlays += image('icons/obj/crayons.dmi',"m"+marker.colourName) + appearance = ma + +/obj/item/weapon/storage/fancy/markers/attackby(obj/item/W as obj, mob/user as mob) + if(istype(W,/obj/item/weapon/pen/crayon/marker)) + switch(W:colourName) + if("mime") + to_chat(usr,"This marker is too depressing to be contained in this box.") + return + if("rainbow") + to_chat(usr,"This marker is too childish to be contained in this box.") return ..() @@ -136,13 +171,12 @@ storage_slots = 6 can_hold = list(/obj/item/clothing/mask/smokable/cigarette, /obj/item/weapon/flame/lighter) icon_type = "cigarette" + starts_with = list(/obj/item/clothing/mask/smokable/cigarette = 6) var/brand = "\improper Trans-Stellar Duty-free" -/obj/item/weapon/storage/fancy/cigarettes/New() - ..() +/obj/item/weapon/storage/fancy/cigarettes/initialize() + . = ..() flags |= NOREACT - for(var/i = 1 to storage_slots) - new /obj/item/clothing/mask/smokable/cigarette(src) create_reagents(15 * storage_slots)//so people can inject cigarettes without opening a packet, now with being able to inject the whole one flags |= OPENCONTAINER if(brand) @@ -201,10 +235,6 @@ icon_state = "Bpacket" brand = "\improper Acme Co. cigarette" -// New() -// ..() -// fill_cigarre_package(src,list("fuel" = 15)) - // New exciting ways to kill your lungs! - Earthcrusher // /obj/item/weapon/storage/fancy/cigarettes/luckystars @@ -248,12 +278,11 @@ storage_slots = 7 can_hold = list(/obj/item/clothing/mask/smokable/cigarette/cigar) icon_type = "cigar" + starts_with = list(/obj/item/clothing/mask/smokable/cigarette/cigar = 7) -/obj/item/weapon/storage/fancy/cigar/New() - ..() +/obj/item/weapon/storage/fancy/cigar/initialize() + . = ..() flags |= NOREACT - for(var/i = 1 to storage_slots) - new /obj/item/clothing/mask/smokable/cigarette/cigar(src) create_reagents(15 * storage_slots) /obj/item/weapon/storage/fancy/cigar/update_icon() @@ -261,10 +290,22 @@ return /obj/item/weapon/storage/fancy/cigar/remove_from_storage(obj/item/W as obj, atom/new_location) - var/obj/item/clothing/mask/smokable/cigarette/cigar/C = W - if(!istype(C)) return - reagents.trans_to_obj(C, (reagents.total_volume/contents.len)) - ..() + var/obj/item/clothing/mask/smokable/cigarette/cigar/C = W + if(!istype(C)) return + reagents.trans_to_obj(C, (reagents.total_volume/contents.len)) + ..() + +/obj/item/weapon/storage/rollingpapers + name = "rolling paper pack" + desc = "A small cardboard pack containing several folded rolling papers." + icon_state = "paperbox" + icon = 'icons/obj/cigarettes.dmi' + w_class = ITEMSIZE_TINY + throwforce = 2 + slot_flags = SLOT_BELT + storage_slots = 14 + can_hold = list(/obj/item/weapon/rollingpaper) + starts_with = list(/obj/item/weapon/rollingpaper = 14) /* * Vial Box @@ -277,12 +318,7 @@ name = "vial storage box" storage_slots = 6 can_hold = list(/obj/item/weapon/reagent_containers/glass/beaker/vial) - -/obj/item/weapon/storage/fancy/vials/New() - ..() - for(var/i=1 to 6) - new /obj/item/weapon/reagent_containers/glass/beaker/vial(src) - return + starts_with = list(/obj/item/weapon/reagent_containers/glass/beaker/vial = 6) /obj/item/weapon/storage/lockbox/vials name = "secure vial storage box" @@ -296,8 +332,8 @@ storage_slots = 6 req_access = list(access_virology) -/obj/item/weapon/storage/lockbox/vials/New() - ..() +/obj/item/weapon/storage/lockbox/vials/initialize() + . = ..() update_icon() /obj/item/weapon/storage/lockbox/vials/update_icon(var/itemremoved = 0) @@ -323,6 +359,8 @@ /obj/item/weapon/storage/fancy/heartbox icon_state = "heartbox" name = "box of chocolates" + icon_type = "chocolate" + var/startswith = 6 max_storage_space = ITEMSIZE_COST_SMALL * 6 can_hold = list( @@ -330,19 +368,19 @@ /obj/item/weapon/reagent_containers/food/snacks/chocolatepiece/white, /obj/item/weapon/reagent_containers/food/snacks/chocolatepiece/truffle ) + starts_with = list( + /obj/item/weapon/reagent_containers/food/snacks/chocolatepiece, + /obj/item/weapon/reagent_containers/food/snacks/chocolatepiece, + /obj/item/weapon/reagent_containers/food/snacks/chocolatepiece, + /obj/item/weapon/reagent_containers/food/snacks/chocolatepiece/white, + /obj/item/weapon/reagent_containers/food/snacks/chocolatepiece/white, + /obj/item/weapon/reagent_containers/food/snacks/chocolatepiece/truffle + ) -/obj/item/weapon/storage/fancy/heartbox/New() - ..() - new /obj/item/weapon/reagent_containers/food/snacks/chocolatepiece(src) - new /obj/item/weapon/reagent_containers/food/snacks/chocolatepiece(src) - new /obj/item/weapon/reagent_containers/food/snacks/chocolatepiece(src) - new /obj/item/weapon/reagent_containers/food/snacks/chocolatepiece/white(src) - new /obj/item/weapon/reagent_containers/food/snacks/chocolatepiece/white(src) - new /obj/item/weapon/reagent_containers/food/snacks/chocolatepiece/truffle(src) +/obj/item/weapon/storage/fancy/heartbox/initialize() + . = ..() update_icon() - return /obj/item/weapon/storage/fancy/heartbox/update_icon(var/itemremoved = 0) if (contents.len == 0) icon_state = "heartbox_empty" - return \ No newline at end of file diff --git a/code/game/objects/items/weapons/storage/firstaid.dm b/code/game/objects/items/weapons/storage/firstaid.dm index 43b7c9e22b..9c4a44d76d 100644 --- a/code/game/objects/items/weapons/storage/firstaid.dm +++ b/code/game/objects/items/weapons/storage/firstaid.dm @@ -13,158 +13,147 @@ icon_state = "firstaid" throw_speed = 2 throw_range = 8 - var/empty = 0 max_storage_space = ITEMSIZE_COST_SMALL * 7 // 14 + var/list/icon_variety +/obj/item/weapon/storage/firstaid/initialize() + . = ..() + if(icon_variety) + icon_state = pick(icon_variety) + icon_variety = null /obj/item/weapon/storage/firstaid/fire name = "fire first aid kit" desc = "It's an emergency medical kit for when the toxins lab spontaneously burns down." icon_state = "ointment" item_state_slots = list(slot_r_hand_str = "firstaid-ointment", slot_l_hand_str = "firstaid-ointment") - - New() - ..() - if (empty) return - - icon_state = pick("ointment","firefirstaid") - - new /obj/item/device/healthanalyzer( src ) - new /obj/item/weapon/reagent_containers/hypospray/autoinjector( src ) - new /obj/item/stack/medical/ointment( src ) - new /obj/item/stack/medical/ointment( src ) - new /obj/item/weapon/reagent_containers/pill/kelotane( src ) - new /obj/item/weapon/reagent_containers/pill/kelotane( src ) - new /obj/item/weapon/reagent_containers/pill/kelotane( src ) //Replaced ointment with these since they actually work --Errorage - return - + icon_variety = list("ointment","firefirstaid") + starts_with = list( + /obj/item/device/healthanalyzer, + /obj/item/weapon/reagent_containers/hypospray/autoinjector, + /obj/item/stack/medical/ointment, + /obj/item/stack/medical/ointment, + /obj/item/weapon/reagent_containers/pill/kelotane, + /obj/item/weapon/reagent_containers/pill/kelotane, + /obj/item/weapon/reagent_containers/pill/kelotane + ) /obj/item/weapon/storage/firstaid/regular icon_state = "firstaid" - - New() - ..() - if (empty) return - new /obj/item/stack/medical/bruise_pack(src) - new /obj/item/stack/medical/bruise_pack(src) - new /obj/item/stack/medical/bruise_pack(src) - new /obj/item/stack/medical/ointment(src) - new /obj/item/stack/medical/ointment(src) - new /obj/item/device/healthanalyzer(src) - new /obj/item/weapon/reagent_containers/hypospray/autoinjector( src ) - return + starts_with = list( + /obj/item/stack/medical/bruise_pack, + /obj/item/stack/medical/bruise_pack, + /obj/item/stack/medical/bruise_pack, + /obj/item/stack/medical/ointment, + /obj/item/stack/medical/ointment, + /obj/item/device/healthanalyzer, + /obj/item/weapon/reagent_containers/hypospray/autoinjector + ) /obj/item/weapon/storage/firstaid/toxin name = "poison first aid kit" //IRL the term used would be poison first aid kit. desc = "Used to treat when one has a high amount of toxins in their body." icon_state = "antitoxin" item_state_slots = list(slot_r_hand_str = "firstaid-toxin", slot_l_hand_str = "firstaid-toxin") - - New() - ..() - if (empty) return - - icon_state = pick("antitoxin","antitoxfirstaid","antitoxfirstaid2","antitoxfirstaid3") - - new /obj/item/weapon/reagent_containers/syringe/antitoxin( src ) - new /obj/item/weapon/reagent_containers/syringe/antitoxin( src ) - new /obj/item/weapon/reagent_containers/syringe/antitoxin( src ) - new /obj/item/weapon/reagent_containers/pill/antitox( src ) - new /obj/item/weapon/reagent_containers/pill/antitox( src ) - new /obj/item/weapon/reagent_containers/pill/antitox( src ) - new /obj/item/device/healthanalyzer( src ) - return + icon_variety = list("antitoxin","antitoxfirstaid","antitoxfirstaid2","antitoxfirstaid3") + starts_with = list( + /obj/item/weapon/reagent_containers/syringe/antitoxin, + /obj/item/weapon/reagent_containers/syringe/antitoxin, + /obj/item/weapon/reagent_containers/syringe/antitoxin, + /obj/item/weapon/reagent_containers/pill/antitox, + /obj/item/weapon/reagent_containers/pill/antitox, + /obj/item/weapon/reagent_containers/pill/antitox, + /obj/item/device/healthanalyzer + ) /obj/item/weapon/storage/firstaid/o2 name = "oxygen deprivation first aid kit" desc = "A box full of oxygen goodies." icon_state = "o2" item_state_slots = list(slot_r_hand_str = "firstaid-o2", slot_l_hand_str = "firstaid-o2") - - New() - ..() - if (empty) return - new /obj/item/weapon/reagent_containers/pill/dexalin( src ) - new /obj/item/weapon/reagent_containers/pill/dexalin( src ) - new /obj/item/weapon/reagent_containers/pill/dexalin( src ) - new /obj/item/weapon/reagent_containers/pill/dexalin( src ) - new /obj/item/weapon/reagent_containers/hypospray/autoinjector( src ) - new /obj/item/weapon/reagent_containers/syringe/inaprovaline( src ) - new /obj/item/device/healthanalyzer( src ) - return + starts_with = list( + /obj/item/weapon/reagent_containers/pill/dexalin, + /obj/item/weapon/reagent_containers/pill/dexalin, + /obj/item/weapon/reagent_containers/pill/dexalin, + /obj/item/weapon/reagent_containers/pill/dexalin, + /obj/item/weapon/reagent_containers/hypospray/autoinjector, + /obj/item/weapon/reagent_containers/syringe/inaprovaline, + /obj/item/device/healthanalyzer + ) /obj/item/weapon/storage/firstaid/adv name = "advanced first aid kit" desc = "Contains advanced medical treatments, for serious boo-boos." icon_state = "advfirstaid" item_state_slots = list(slot_r_hand_str = "firstaid-advanced", slot_l_hand_str = "firstaid-advanced") - -/obj/item/weapon/storage/firstaid/adv/New() - ..() - if (empty) return - new /obj/item/weapon/reagent_containers/hypospray/autoinjector( src ) - new /obj/item/stack/medical/advanced/bruise_pack(src) - new /obj/item/stack/medical/advanced/bruise_pack(src) - new /obj/item/stack/medical/advanced/bruise_pack(src) - new /obj/item/stack/medical/advanced/ointment(src) - new /obj/item/stack/medical/advanced/ointment(src) - new /obj/item/stack/medical/splint(src) - return + starts_with = list( + /obj/item/weapon/reagent_containers/hypospray/autoinjector, + /obj/item/stack/medical/advanced/bruise_pack, + /obj/item/stack/medical/advanced/bruise_pack, + /obj/item/stack/medical/advanced/bruise_pack, + /obj/item/stack/medical/advanced/ointment, + /obj/item/stack/medical/advanced/ointment, + /obj/item/stack/medical/splint + ) /obj/item/weapon/storage/firstaid/combat name = "combat medical kit" desc = "Contains advanced medical treatments." icon_state = "bezerk" item_state_slots = list(slot_r_hand_str = "firstaid-advanced", slot_l_hand_str = "firstaid-advanced") - -/obj/item/weapon/storage/firstaid/combat/New() - ..() - if (empty) return - new /obj/item/weapon/storage/pill_bottle/bicaridine(src) - new /obj/item/weapon/storage/pill_bottle/dermaline(src) - new /obj/item/weapon/storage/pill_bottle/dexalin_plus(src) - new /obj/item/weapon/storage/pill_bottle/dylovene(src) - new /obj/item/weapon/storage/pill_bottle/tramadol(src) - new /obj/item/weapon/storage/pill_bottle/spaceacillin(src) - new /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/clotting(src) - new /obj/item/stack/medical/splint(src) - new /obj/item/device/healthanalyzer/advanced(src) - return + starts_with = list( + /obj/item/weapon/storage/pill_bottle/bicaridine, + /obj/item/weapon/storage/pill_bottle/dermaline, + /obj/item/weapon/storage/pill_bottle/dexalin_plus, + /obj/item/weapon/storage/pill_bottle/dylovene, + /obj/item/weapon/storage/pill_bottle/tramadol, + /obj/item/weapon/storage/pill_bottle/spaceacillin, + /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/clotting, + /obj/item/stack/medical/splint, + /obj/item/device/healthanalyzer/advanced + ) /obj/item/weapon/storage/firstaid/surgery name = "surgery kit" - desc = "Contains tools for surgery." - max_storage_space = ITEMSIZE_COST_NORMAL * 6 // Formally 21. Odd numbers should be avoided for a system based on exponents of 2. + desc = "Contains tools for surgery. Has precise foam fitting for safe transport and automatically sterilizes the content between uses." + icon_state = "surgerykit" + item_state = "firstaid-surgery" max_w_class = ITEMSIZE_NORMAL -/obj/item/weapon/storage/firstaid/surgery/New() - ..() - if (empty) return - new /obj/item/weapon/surgical/bonesetter(src) - new /obj/item/weapon/surgical/cautery(src) - new /obj/item/weapon/surgical/circular_saw(src) - new /obj/item/weapon/surgical/hemostat(src) - new /obj/item/weapon/surgical/retractor(src) - new /obj/item/weapon/surgical/scalpel(src) - new /obj/item/weapon/surgical/surgicaldrill(src) - new /obj/item/weapon/surgical/bonegel(src) - new /obj/item/weapon/surgical/FixOVein(src) - new /obj/item/stack/medical/advanced/bruise_pack(src) - new /obj/item/device/healthanalyzer/enhanced(src) - return + can_hold = list( + /obj/item/weapon/surgical/bonesetter, + /obj/item/weapon/surgical/cautery, + /obj/item/weapon/surgical/circular_saw, + /obj/item/weapon/surgical/hemostat, + /obj/item/weapon/surgical/retractor, + /obj/item/weapon/surgical/scalpel, + /obj/item/weapon/surgical/surgicaldrill, + /obj/item/weapon/surgical/bonegel, + /obj/item/weapon/surgical/FixOVein, + /obj/item/stack/medical/advanced/bruise_pack, + /obj/item/stack/nanopaste, + /obj/item/device/healthanalyzer/advanced + ) + + starts_with = list( + /obj/item/weapon/surgical/bonesetter, + /obj/item/weapon/surgical/cautery, + /obj/item/weapon/surgical/circular_saw, + /obj/item/weapon/surgical/hemostat, + /obj/item/weapon/surgical/retractor, + /obj/item/weapon/surgical/scalpel, + /obj/item/weapon/surgical/surgicaldrill, + /obj/item/weapon/surgical/bonegel, + /obj/item/weapon/surgical/FixOVein, + /obj/item/stack/medical/advanced/bruise_pack, + /obj/item/device/healthanalyzer/advanced + ) /obj/item/weapon/storage/firstaid/clotting name = "clotting kit" desc = "Contains chemicals to stop bleeding." max_storage_space = ITEMSIZE_COST_SMALL * 7 - -/obj/item/weapon/storage/firstaid/clotting/New() - ..() - if (empty) - return - for(var/i = 1 to 8) - new /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/clotting(src) - return + starts_with = list(/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/clotting = 8) /* * Pill Bottles @@ -184,170 +173,99 @@ max_storage_space = ITEMSIZE_COST_TINY * 14 max_w_class = ITEMSIZE_TINY + var/label_text = "" + var/base_name = " " + var/base_desc = " " + +/obj/item/weapon/storage/pill_bottle/New() + ..() + base_name = name + base_desc = desc + +/obj/item/weapon/storage/pill_bottle/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W, /obj/item/weapon/pen) || istype(W, /obj/item/device/flashlight/pen)) + var/tmp_label = sanitizeSafe(input(user, "Enter a label for [name]", "Label", label_text), MAX_NAME_LEN) + if(length(tmp_label) > 50) + to_chat(user, "The label can be at most 50 characters long.") + else if(length(tmp_label) > 10) + to_chat(user, "You set the label.") + label_text = tmp_label + update_name_label() + else + to_chat(user, "You set the label to \"[tmp_label]\".") + label_text = tmp_label + update_name_label() + else + ..() + +/obj/item/weapon/storage/pill_bottle/proc/update_name_label() + if(!label_text) + name = base_name + desc = base_desc + return + else if(length(label_text) > 10) + var/short_label_text = copytext(label_text, 1, 11) + name = "[base_name] ([short_label_text]...)" + else + name = "[base_name] ([label_text])" + desc = "[base_desc] It is labeled \"[label_text]\"." + /obj/item/weapon/storage/pill_bottle/antitox name = "bottle of Dylovene pills" desc = "Contains pills used to counter toxins." - -/obj/item/weapon/storage/pill_bottle/antitox/New() //25u each - ..() - new /obj/item/weapon/reagent_containers/pill/antitox(src) - new /obj/item/weapon/reagent_containers/pill/antitox(src) - new /obj/item/weapon/reagent_containers/pill/antitox(src) - new /obj/item/weapon/reagent_containers/pill/antitox(src) - new /obj/item/weapon/reagent_containers/pill/antitox(src) - new /obj/item/weapon/reagent_containers/pill/antitox(src) - new /obj/item/weapon/reagent_containers/pill/antitox(src) + starts_with = list(/obj/item/weapon/reagent_containers/pill/antitox = 7) /obj/item/weapon/storage/pill_bottle/bicaridine name = "bottle of Bicaridine pills" desc = "Contains pills used to stabilize the severely injured." - -/obj/item/weapon/storage/pill_bottle/bicaridine/New() - ..() - new /obj/item/weapon/reagent_containers/pill/bicaridine(src) - new /obj/item/weapon/reagent_containers/pill/bicaridine(src) - new /obj/item/weapon/reagent_containers/pill/bicaridine(src) - new /obj/item/weapon/reagent_containers/pill/bicaridine(src) - new /obj/item/weapon/reagent_containers/pill/bicaridine(src) - new /obj/item/weapon/reagent_containers/pill/bicaridine(src) - new /obj/item/weapon/reagent_containers/pill/bicaridine(src) + starts_with = list(/obj/item/weapon/reagent_containers/pill/bicaridine = 7) /obj/item/weapon/storage/pill_bottle/dexalin_plus name = "bottle of Dexalin Plus pills" desc = "Contains pills used to treat extreme cases of oxygen deprivation." - -/obj/item/weapon/storage/pill_bottle/dexalin_plus/New() - ..() - new /obj/item/weapon/reagent_containers/pill/dexalin_plus(src) - new /obj/item/weapon/reagent_containers/pill/dexalin_plus(src) - new /obj/item/weapon/reagent_containers/pill/dexalin_plus(src) - new /obj/item/weapon/reagent_containers/pill/dexalin_plus(src) - new /obj/item/weapon/reagent_containers/pill/dexalin_plus(src) - new /obj/item/weapon/reagent_containers/pill/dexalin_plus(src) - new /obj/item/weapon/reagent_containers/pill/dexalin_plus(src) + starts_with = list(/obj/item/weapon/reagent_containers/pill/dexalin_plus = 7) /obj/item/weapon/storage/pill_bottle/dermaline name = "bottle of Dermaline pills" desc = "Contains pills used to treat burn wounds." - -/obj/item/weapon/storage/pill_bottle/dermaline/New() - ..() - new /obj/item/weapon/reagent_containers/pill/dermaline(src) - new /obj/item/weapon/reagent_containers/pill/dermaline(src) - new /obj/item/weapon/reagent_containers/pill/dermaline(src) - new /obj/item/weapon/reagent_containers/pill/dermaline(src) - new /obj/item/weapon/reagent_containers/pill/dermaline(src) - new /obj/item/weapon/reagent_containers/pill/dermaline(src) - new /obj/item/weapon/reagent_containers/pill/dermaline(src) + starts_with = list(/obj/item/weapon/reagent_containers/pill/dermaline = 7) /obj/item/weapon/storage/pill_bottle/dylovene name = "bottle of Dylovene pills" desc = "Contains pills used to treat toxic substances in the blood." - -/obj/item/weapon/storage/pill_bottle/dylovene/New() //15u each - ..() - new /obj/item/weapon/reagent_containers/pill/dylovene(src) - new /obj/item/weapon/reagent_containers/pill/dylovene(src) - new /obj/item/weapon/reagent_containers/pill/dylovene(src) - new /obj/item/weapon/reagent_containers/pill/dylovene(src) - new /obj/item/weapon/reagent_containers/pill/dylovene(src) - new /obj/item/weapon/reagent_containers/pill/dylovene(src) - new /obj/item/weapon/reagent_containers/pill/dylovene(src) + starts_with = list(/obj/item/weapon/reagent_containers/pill/dylovene = 7) /obj/item/weapon/storage/pill_bottle/inaprovaline name = "bottle of Inaprovaline pills" desc = "Contains pills used to stabilize patients." - -/obj/item/weapon/storage/pill_bottle/inaprovaline/New() - ..() - new /obj/item/weapon/reagent_containers/pill/inaprovaline(src) - new /obj/item/weapon/reagent_containers/pill/inaprovaline(src) - new /obj/item/weapon/reagent_containers/pill/inaprovaline(src) - new /obj/item/weapon/reagent_containers/pill/inaprovaline(src) - new /obj/item/weapon/reagent_containers/pill/inaprovaline(src) - new /obj/item/weapon/reagent_containers/pill/inaprovaline(src) - new /obj/item/weapon/reagent_containers/pill/inaprovaline(src) + starts_with = list(/obj/item/weapon/reagent_containers/pill/inaprovaline = 7) /obj/item/weapon/storage/pill_bottle/kelotane name = "bottle of kelotane pills" desc = "Contains pills used to treat burns." - -/obj/item/weapon/storage/pill_bottle/kelotane/New() - ..() - new /obj/item/weapon/reagent_containers/pill/kelotane(src) - new /obj/item/weapon/reagent_containers/pill/kelotane(src) - new /obj/item/weapon/reagent_containers/pill/kelotane(src) - new /obj/item/weapon/reagent_containers/pill/kelotane(src) - new /obj/item/weapon/reagent_containers/pill/kelotane(src) - new /obj/item/weapon/reagent_containers/pill/kelotane(src) - new /obj/item/weapon/reagent_containers/pill/kelotane(src) + starts_with = list(/obj/item/weapon/reagent_containers/pill/kelotane = 7) /obj/item/weapon/storage/pill_bottle/spaceacillin name = "bottle of Spaceacillin pills" desc = "A theta-lactam antibiotic. Effective against many diseases likely to be encountered in space." - -/obj/item/weapon/storage/pill_bottle/spaceacillin/New() - ..() - new /obj/item/weapon/reagent_containers/pill/spaceacillin(src) - new /obj/item/weapon/reagent_containers/pill/spaceacillin(src) - new /obj/item/weapon/reagent_containers/pill/spaceacillin(src) - new /obj/item/weapon/reagent_containers/pill/spaceacillin(src) - new /obj/item/weapon/reagent_containers/pill/spaceacillin(src) - new /obj/item/weapon/reagent_containers/pill/spaceacillin(src) - new /obj/item/weapon/reagent_containers/pill/spaceacillin(src) + starts_with = list(/obj/item/weapon/reagent_containers/pill/spaceacillin = 7) /obj/item/weapon/storage/pill_bottle/tramadol name = "bottle of Tramadol pills" desc = "Contains pills used to relieve pain." - -/obj/item/weapon/storage/pill_bottle/tramadol/New() - ..() - new /obj/item/weapon/reagent_containers/pill/tramadol(src) - new /obj/item/weapon/reagent_containers/pill/tramadol(src) - new /obj/item/weapon/reagent_containers/pill/tramadol(src) - new /obj/item/weapon/reagent_containers/pill/tramadol(src) - new /obj/item/weapon/reagent_containers/pill/tramadol(src) - new /obj/item/weapon/reagent_containers/pill/tramadol(src) - new /obj/item/weapon/reagent_containers/pill/tramadol(src) + starts_with = list(/obj/item/weapon/reagent_containers/pill/tramadol = 7) /obj/item/weapon/storage/pill_bottle/citalopram name = "bottle of Citalopram pills" desc = "Contains pills used to stabilize a patient's mood." - -/obj/item/weapon/storage/pill_bottle/citalopram/New() - ..() - new /obj/item/weapon/reagent_containers/pill/citalopram(src) - new /obj/item/weapon/reagent_containers/pill/citalopram(src) - new /obj/item/weapon/reagent_containers/pill/citalopram(src) - new /obj/item/weapon/reagent_containers/pill/citalopram(src) - new /obj/item/weapon/reagent_containers/pill/citalopram(src) - new /obj/item/weapon/reagent_containers/pill/citalopram(src) - new /obj/item/weapon/reagent_containers/pill/citalopram(src) + starts_with = list(/obj/item/weapon/reagent_containers/pill/citalopram = 7) /obj/item/weapon/storage/pill_bottle/carbon name = "bottle of Carbon pills" desc = "Contains pills used to neutralise chemicals in the stomach." - -/obj/item/weapon/storage/pill_bottle/carbon/New() - ..() - new /obj/item/weapon/reagent_containers/pill/carbon(src) - new /obj/item/weapon/reagent_containers/pill/carbon(src) - new /obj/item/weapon/reagent_containers/pill/carbon(src) - new /obj/item/weapon/reagent_containers/pill/carbon(src) - new /obj/item/weapon/reagent_containers/pill/carbon(src) - new /obj/item/weapon/reagent_containers/pill/carbon(src) - new /obj/item/weapon/reagent_containers/pill/carbon(src) + starts_with = list(/obj/item/weapon/reagent_containers/pill/carbon = 7) /obj/item/weapon/storage/pill_bottle/iron name = "bottle of Iron pills" desc = "Contains pills used to aid in blood regeneration." - -/obj/item/weapon/storage/pill_bottle/iron/New() - ..() - new /obj/item/weapon/reagent_containers/pill/iron(src) - new /obj/item/weapon/reagent_containers/pill/iron(src) - new /obj/item/weapon/reagent_containers/pill/iron(src) - new /obj/item/weapon/reagent_containers/pill/iron(src) - new /obj/item/weapon/reagent_containers/pill/iron(src) - new /obj/item/weapon/reagent_containers/pill/iron(src) - new /obj/item/weapon/reagent_containers/pill/iron(src) \ No newline at end of file + starts_with = list(/obj/item/weapon/reagent_containers/pill/iron = 7) diff --git a/code/game/objects/items/weapons/storage/lockbox.dm b/code/game/objects/items/weapons/storage/lockbox.dm index e52ad4d812..e9527b2313 100644 --- a/code/game/objects/items/weapons/storage/lockbox.dm +++ b/code/game/objects/items/weapons/storage/lockbox.dm @@ -77,36 +77,28 @@ /obj/item/weapon/storage/lockbox/loyalty name = "lockbox of loyalty implants" req_access = list(access_security) - - New() - ..() - new /obj/item/weapon/implantcase/loyalty(src) - new /obj/item/weapon/implantcase/loyalty(src) - new /obj/item/weapon/implantcase/loyalty(src) - new /obj/item/weapon/implanter/loyalty(src) - + starts_with = list( + /obj/item/weapon/implantcase/loyalty = 3, + /obj/item/weapon/implanter/loyalty + ) /obj/item/weapon/storage/lockbox/clusterbang name = "lockbox of clusterbangs" desc = "You have a bad feeling about opening this." req_access = list(access_security) - - New() - ..() - new /obj/item/weapon/grenade/flashbang/clusterbang(src) + starts_with = list(/obj/item/weapon/grenade/flashbang/clusterbang) /obj/item/weapon/storage/lockbox/medal name = "lockbox of medals" desc = "A lockbox filled with commemorative medals, it has the NanoTrasen logo stamped on it." req_access = list(access_heads) storage_slots = 7 - - New() - ..() - new /obj/item/clothing/accessory/medal/conduct(src) - new /obj/item/clothing/accessory/medal/bronze_heart(src) - new /obj/item/clothing/accessory/medal/nobel_science(src) - new /obj/item/clothing/accessory/medal/silver/valor(src) - new /obj/item/clothing/accessory/medal/silver/security(src) - new /obj/item/clothing/accessory/medal/gold/captain(src) - new /obj/item/clothing/accessory/medal/gold/heroism(src) \ No newline at end of file + starts_with = list( + /obj/item/clothing/accessory/medal/conduct, + /obj/item/clothing/accessory/medal/bronze_heart, + /obj/item/clothing/accessory/medal/nobel_science, + /obj/item/clothing/accessory/medal/silver/valor, + /obj/item/clothing/accessory/medal/silver/security, + /obj/item/clothing/accessory/medal/gold/captain, + /obj/item/clothing/accessory/medal/gold/heroism + ) diff --git a/code/game/objects/items/weapons/storage/misc.dm b/code/game/objects/items/weapons/storage/misc.dm index 64952046a5..d103fbc6ef 100644 --- a/code/game/objects/items/weapons/storage/misc.dm +++ b/code/game/objects/items/weapons/storage/misc.dm @@ -6,17 +6,14 @@ icon = 'icons/obj/food.dmi' icon_state = "donutbox" name = "donut box" - var/startswith = 6 max_storage_space = ITEMSIZE_COST_SMALL * 6 can_hold = list(/obj/item/weapon/reagent_containers/food/snacks/donut) foldable = /obj/item/stack/material/cardboard + starts_with = list(/obj/item/weapon/reagent_containers/food/snacks/donut/normal = 6) -/obj/item/weapon/storage/box/donut/New() - ..() - for(var/i=1 to startswith) - new /obj/item/weapon/reagent_containers/food/snacks/donut/normal(src) +/obj/item/weapon/storage/box/donut/initialize() + . = ..() update_icon() - return /obj/item/weapon/storage/box/donut/update_icon() overlays.Cut() @@ -26,4 +23,4 @@ i++ /obj/item/weapon/storage/box/donut/empty - startswith = 0 + empty = TRUE diff --git a/code/game/objects/items/weapons/storage/quickdraw.dm b/code/game/objects/items/weapons/storage/quickdraw.dm new file mode 100644 index 0000000000..86d7c76ca2 --- /dev/null +++ b/code/game/objects/items/weapons/storage/quickdraw.dm @@ -0,0 +1,80 @@ +// ----------------------------- +// Quickdraw storage +// ----------------------------- +//These items are pouches and cases made to be kept in belts or pockets to quickly draw objects from +//Largely inspired by the vest pouches on Colonial Marines + +/obj/item/weapon/storage/quickdraw + name = "quickdraw" + desc = "This object should not appear" + + //Quickmode + //When set to 0, this storage will operate as a regular storage, and clicking on it while equipped will open it as a storage + //When set to 1, a click while it is equipped will instead move the first item inside it to your hand + var/quickmode = 0 + +/obj/item/weapon/storage/quickdraw/attack_hand(mob/user as mob) + if(src.loc == user) //If they aren't holding us, we do nothing special + if(ishuman(user)) + var/mob/living/carbon/human/H = user + if(quickmode) + var/first_item = contents[1] + if(first_item && !H.get_active_hand()) //Do we have anything to give you? + H.put_in_hands(first_item) + return + + if(H.l_store == src && !H.get_active_hand()) //overrides + src.open(user) + return + if(H.r_store == src && !H.get_active_hand()) + src.open(user) + return + ..() //Nothing special happened, go call the other proc + + +/obj/item/weapon/storage/quickdraw/verb/toggle_quickdraw() + set name = "Switch Quickdraw Mode" + set category = "Object" + + quickmode = !quickmode + switch (quickmode) + if(1) + to_chat(usr, "[src] now draws the first object inside.") + if(0) + to_chat(usr, "[src] now opens as a container.") + +/obj/item/weapon/storage/quickdraw/AltClick(mob/user) + ..() + if(src.loc == user) //Are they carrying us? + toggle_quickdraw() + + +// If we start adding more of these, we'll need to make them their own folder. 'til then, this one should be fine. + +// ----------------------------- +// Syringe case +// ----------------------------- + +/obj/item/weapon/storage/quickdraw/syringe_case + name = "syringe case" + desc = "A small case for safely carrying sharps around." + icon_state = "syringe_case" + + w_class = ITEMSIZE_SMALL + max_w_class = ITEMSIZE_TINY + max_storage_space = ITEMSIZE_TINY * 6 //Capable of holding six syringes + + //Can hold syringes and autoinjectors, but also pills if you really wanted. Syringe-shaped objects like pens and cigarettes also fit, but why would you do that? + can_hold = list(/obj/item/weapon/reagent_containers/syringe, /obj/item/weapon/reagent_containers/hypospray/autoinjector, + /obj/item/weapon/reagent_containers/pill, /obj/item/weapon/pen, /obj/item/device/flashlight/pen, /obj/item/clothing/mask/smokable/cigarette) + + quickmode = 1 //Starts in quickdraw mode + //Preloaded for your convenience! + starts_with = list( + /obj/item/weapon/reagent_containers/syringe, + /obj/item/weapon/reagent_containers/syringe, + /obj/item/weapon/reagent_containers/syringe, + /obj/item/weapon/reagent_containers/syringe, + /obj/item/weapon/reagent_containers/syringe, + /obj/item/weapon/reagent_containers/syringe + ) \ No newline at end of file diff --git a/code/game/objects/items/weapons/storage/secure.dm b/code/game/objects/items/weapons/storage/secure.dm index 4d9be129f7..78a2d940ad 100644 --- a/code/game/objects/items/weapons/storage/secure.dm +++ b/code/game/objects/items/weapons/storage/secure.dm @@ -184,15 +184,10 @@ anchored = 1.0 density = 0 cant_hold = list(/obj/item/weapon/storage/secure/briefcase) + starts_with = list( + /obj/item/weapon/paper, + /obj/item/weapon/pen + ) - New() - ..() - new /obj/item/weapon/paper(src) - new /obj/item/weapon/pen(src) - - attack_hand(mob/user as mob) - return attack_self(user) - -/obj/item/weapon/storage/secure/safe/HoS/New() - ..() - //new /obj/item/weapon/storage/lockbox/clusterbang(src) This item is currently broken... and probably shouldnt exist to begin with (even though it's cool) +/obj/item/weapon/storage/secure/safe/attack_hand(mob/user as mob) + return attack_self(user) diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index c95f0ac49e..03ad104810 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -35,6 +35,8 @@ var/allow_quick_gather //Set this variable to allow the object to have the 'toggle mode' verb, which quickly collects all items from a tile. var/collection_mode = 1; //0 = pick one at a time, 1 = pick all on tile var/use_sound = "rustle" //sound played when used. null for no sound. + var/list/starts_with //Things to spawn on the box on spawn + var/empty //Mapper override to spawn an empty version of a container that usually has stuff /obj/item/weapon/storage/Destroy() close_all() @@ -52,7 +54,7 @@ if(!canremove) return - if (ishuman(usr) || issmall(usr) || isanimal(usr)) //so monkeys can take off their backpacks -- Urist + if (isliving(usr) || isobserver(usr)) if (istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech. why? return @@ -139,7 +141,7 @@ is_seeing -= user /obj/item/weapon/storage/proc/open(mob/user as mob) - if (src.use_sound) + if (src.use_sound && !isobserver(user)) playsound(src.loc, src.use_sound, 50, 1, -5) orient2hud(user) @@ -352,12 +354,10 @@ //such as when picking up all the items on a tile with one click. /obj/item/weapon/storage/proc/handle_item_insertion(obj/item/W as obj, prevent_warning = 0) if(!istype(W)) return 0 + if(usr) - usr.remove_from_mob(W) - usr.update_icons() //update our overlays - W.forceMove(src) - W.on_enter_storage(src) - if(usr) + usr.remove_from_mob(W,target = src) //If given a target, handles forceMove() + W.on_enter_storage(src) if (usr.client && usr.s_active != src) usr.client.screen -= W W.dropped(usr) @@ -375,6 +375,10 @@ src.orient2hud(usr) if(usr.s_active) usr.s_active.show_to(usr) + else + W.forceMove(src) + W.on_enter_storage(src) + update_icon() return 1 @@ -523,7 +527,8 @@ for(var/obj/item/I in contents) remove_from_storage(I, T) -/obj/item/weapon/storage/New() +/obj/item/weapon/storage/initialize() + . = ..() if(allow_quick_empty) verbs += /obj/item/weapon/storage/verb/quick_empty @@ -535,12 +540,6 @@ else verbs -= /obj/item/weapon/storage/verb/toggle_gathering_mode - spawn(5) - var/total_storage_space = 0 - for(var/obj/item/I in contents) - total_storage_space += I.get_storage_cost() - max_storage_space = max(total_storage_space,max_storage_space) //Prevents spawned containers from being too small for their contents. - src.boxes = new /obj/screen/storage( ) src.boxes.name = "storage" src.boxes.master = src @@ -579,7 +578,22 @@ src.closer.icon_state = "storage_close" src.closer.hud_layerise() orient2hud() - return + + if(LAZYLEN(starts_with) && !empty) + for(var/newtype in starts_with) + var/count = starts_with[newtype] || 1 //Could have left it blank. + while(count) + count-- + new newtype(src) + starts_with = null //Reduce list count. + + calibrate_size() + +/obj/item/weapon/storage/proc/calibrate_size() + var/total_storage_space = 0 + for(var/obj/item/I in contents) + total_storage_space += I.get_storage_cost() + max_storage_space = max(total_storage_space,max_storage_space) //Prevents spawned containers from being too small for their contents. /obj/item/weapon/storage/emp_act(severity) if(!istype(src.loc, /mob/living)) @@ -658,3 +672,60 @@ can_hold[I.type]++ max_w_class = max(I.w_class, max_w_class) max_storage_space += I.get_storage_cost() + +/* + * Trinket Box - READDING SOON + */ +/obj/item/weapon/storage/trinketbox + name = "trinket box" + desc = "A box that can hold small trinkets, such as a ring." + icon = 'icons/obj/items.dmi' + icon_state = "trinketbox" + var/open = 0 + storage_slots = 1 + can_hold = list( + /obj/item/clothing/gloves/ring, + /obj/item/weapon/coin, + /obj/item/clothing/accessory/medal + ) + var/open_state + var/closed_state + +/obj/item/weapon/storage/trinketbox/update_icon() + overlays.Cut() + if(open) + icon_state = open_state + + if(contents.len >= 1) + var/contained_image = null + if(istype(contents[1], /obj/item/clothing/gloves/ring)) + contained_image = "ring_trinket" + else if(istype(contents[1], /obj/item/weapon/coin)) + contained_image = "coin_trinket" + else if(istype(contents[1], /obj/item/clothing/accessory/medal)) + contained_image = "medal_trinket" + if(contained_image) + overlays += contained_image + else + icon_state = closed_state + +/obj/item/weapon/storage/trinketbox/New() + if(!open_state) + open_state = "[initial(icon_state)]_open" + if(!closed_state) + closed_state = "[initial(icon_state)]" + ..() + +/obj/item/weapon/storage/trinketbox/attack_self() + open = !open + update_icon() + ..() + +/obj/item/weapon/storage/trinketbox/examine(mob/user) + ..() + if(open && contents.len) + var/display_item = contents[1] + to_chat(user, "\The [src] contains \the [display_item]!") + +/obj/item/weapon/storage/AllowDrop() + return TRUE diff --git a/code/game/objects/items/weapons/storage/toolbox.dm b/code/game/objects/items/weapons/storage/toolbox.dm index 21bebfa399..c4174eb4c0 100644 --- a/code/game/objects/items/weapons/storage/toolbox.dm +++ b/code/game/objects/items/weapons/storage/toolbox.dm @@ -19,48 +19,50 @@ name = "emergency toolbox" icon_state = "red" item_state_slots = list(slot_r_hand_str = "toolbox_red", slot_l_hand_str = "toolbox_red") - -/obj/item/weapon/storage/toolbox/emergency/New() - ..() - new /obj/item/weapon/crowbar/red(src) - new /obj/item/weapon/extinguisher/mini(src) + starts_with = list( + /obj/item/weapon/crowbar/red, + /obj/item/weapon/extinguisher/mini, + /obj/item/device/radio + ) +/obj/item/weapon/storage/toolbox/emergency/initialize() if(prob(50)) new /obj/item/device/flashlight(src) else new /obj/item/device/flashlight/flare(src) - new /obj/item/device/radio(src) + . = ..() /obj/item/weapon/storage/toolbox/mechanical name = "mechanical toolbox" icon_state = "blue" item_state_slots = list(slot_r_hand_str = "toolbox_blue", slot_l_hand_str = "toolbox_blue") - -/obj/item/weapon/storage/toolbox/mechanical/New() - ..() - new /obj/item/weapon/screwdriver(src) - new /obj/item/weapon/wrench(src) - new /obj/item/weapon/weldingtool(src) - new /obj/item/weapon/crowbar(src) - new /obj/item/device/analyzer(src) - new /obj/item/weapon/wirecutters(src) + starts_with = list( + /obj/item/weapon/screwdriver, + /obj/item/weapon/wrench, + /obj/item/weapon/weldingtool, + /obj/item/weapon/crowbar, + /obj/item/device/analyzer, + /obj/item/weapon/wirecutters + ) /obj/item/weapon/storage/toolbox/electrical name = "electrical toolbox" icon_state = "yellow" item_state_slots = list(slot_r_hand_str = "toolbox_yellow", slot_l_hand_str = "toolbox_yellow") - -/obj/item/weapon/storage/toolbox/electrical/New() - ..() - new /obj/item/weapon/screwdriver(src) - new /obj/item/weapon/wirecutters(src) - new /obj/item/device/t_scanner(src) - new /obj/item/weapon/crowbar(src) - new /obj/item/stack/cable_coil/random(src,30) - new /obj/item/stack/cable_coil/random(src,30) + starts_with = list( + /obj/item/weapon/screwdriver, + /obj/item/weapon/wirecutters, + /obj/item/device/t_scanner, + /obj/item/weapon/crowbar, + /obj/item/stack/cable_coil/random_belt, + /obj/item/stack/cable_coil/random_belt + ) +/obj/item/weapon/storage/toolbox/electrical/initialize() + . = ..() if(prob(5)) new /obj/item/clothing/gloves/yellow(src) else new /obj/item/stack/cable_coil/random(src,30) + calibrate_size() /obj/item/weapon/storage/toolbox/syndicate name = "black and red toolbox" @@ -68,29 +70,26 @@ item_state_slots = list(slot_r_hand_str = "toolbox_syndi", slot_l_hand_str = "toolbox_syndi") origin_tech = list(TECH_COMBAT = 1, TECH_ILLEGAL = 1) force = 14 - var/powertools = FALSE + starts_with = list( + /obj/item/clothing/gloves/yellow, + /obj/item/weapon/screwdriver, + /obj/item/weapon/wrench, + /obj/item/weapon/weldingtool, + /obj/item/weapon/crowbar, + /obj/item/weapon/wirecutters, + /obj/item/device/multitool + ) /obj/item/weapon/storage/toolbox/syndicate/powertools - powertools = TRUE - -/obj/item/weapon/storage/toolbox/syndicate/New() // This is found in maint, so it should have the basics, plus some gloves. - ..() //all storage items need this to work properly! - if(powertools) - new /obj/item/clothing/gloves/yellow(src) - new /obj/item/weapon/screwdriver/power(src) - new /obj/item/weapon/weldingtool/experimental(src) - new /obj/item/weapon/crowbar/power(src) - new /obj/item/device/multitool(src) - new /obj/item/stack/cable_coil/random(src,30) - new /obj/item/device/analyzer(src) - else - new /obj/item/clothing/gloves/yellow(src) - new /obj/item/weapon/screwdriver(src) - new /obj/item/weapon/wrench(src) - new /obj/item/weapon/weldingtool(src) - new /obj/item/weapon/crowbar(src) - new /obj/item/weapon/wirecutters(src) - new /obj/item/device/multitool(src) + starts_with = list( + /obj/item/clothing/gloves/yellow, + /obj/item/weapon/screwdriver/power, + /obj/item/weapon/weldingtool/experimental, + /obj/item/weapon/crowbar/power, + /obj/item/device/multitool, + /obj/item/stack/cable_coil/random_belt, + /obj/item/device/analyzer + ) /obj/item/weapon/storage/toolbox/lunchbox max_storage_space = ITEMSIZE_COST_SMALL * 4 //slightly smaller than a toolbox @@ -103,8 +102,7 @@ var/filled = FALSE attack_verb = list("lunched") -/obj/item/weapon/storage/toolbox/lunchbox/New() - ..() +/obj/item/weapon/storage/toolbox/lunchbox/initialize() if(filled) var/list/lunches = lunchables_lunches() var/lunch = lunches[pick(lunches)] @@ -117,6 +115,7 @@ var/list/drinks = lunchables_drinks() var/drink = drinks[pick(drinks)] new drink(src) + . = ..() /obj/item/weapon/storage/toolbox/lunchbox/filled filled = TRUE diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm index f82feb91dd..5c0f837340 100644 --- a/code/game/objects/items/weapons/storage/uplink_kits.dm +++ b/code/game/objects/items/weapons/storage/uplink_kits.dm @@ -1,76 +1,66 @@ -/obj/item/weapon/storage/box/syndicate/ - New() - ..() - switch (pickweight(list("bloodyspai" = 1, "stealth" = 1, "screwed" = 1, "guns" = 1, "murder" = 1, "freedom" = 1, "hacker" = 1, "lordsingulo" = 1, "smoothoperator" = 1))) - if("bloodyspai") - new /obj/item/clothing/under/chameleon(src) - new /obj/item/clothing/mask/gas/voice(src) - new /obj/item/weapon/card/id/syndicate(src) - new /obj/item/clothing/shoes/syndigaloshes(src) - return +/obj/item/weapon/storage/box/syndicate/initialize() + switch (pickweight(list("bloodyspai" = 1, "stealth" = 1, "screwed" = 1, "guns" = 1, "murder" = 1, "freedom" = 1, "hacker" = 1, "lordsingulo" = 1, "smoothoperator" = 1))) + if("bloodyspai") + new /obj/item/clothing/under/chameleon(src) + new /obj/item/clothing/mask/gas/voice(src) + new /obj/item/weapon/card/id/syndicate(src) + new /obj/item/clothing/shoes/syndigaloshes(src) - if("stealth") - new /obj/item/weapon/gun/energy/crossbow(src) - new /obj/item/weapon/pen/reagent/paralysis(src) - new /obj/item/device/chameleon(src) - return + if("stealth") + new /obj/item/weapon/gun/energy/crossbow(src) + new /obj/item/weapon/pen/reagent/paralysis(src) + new /obj/item/device/chameleon(src) - if("screwed") - new /obj/effect/spawner/newbomb/timer/syndicate(src) - new /obj/effect/spawner/newbomb/timer/syndicate(src) - new /obj/item/device/powersink(src) - new /obj/item/clothing/suit/space/syndicate(src) - new /obj/item/clothing/head/helmet/space/syndicate(src) - new /obj/item/clothing/mask/gas/syndicate(src) - new /obj/item/weapon/tank/emergency/oxygen/double(src) - return + if("screwed") + new /obj/effect/spawner/newbomb/timer/syndicate(src) + new /obj/effect/spawner/newbomb/timer/syndicate(src) + new /obj/item/device/powersink(src) + new /obj/item/clothing/suit/space/syndicate(src) + new /obj/item/clothing/head/helmet/space/syndicate(src) + new /obj/item/clothing/mask/gas/syndicate(src) + new /obj/item/weapon/tank/emergency/oxygen/double(src) - if("guns") - new /obj/item/weapon/gun/projectile/revolver(src) - new /obj/item/ammo_magazine/s357(src) - new /obj/item/weapon/card/emag(src) - new /obj/item/weapon/plastique(src) - new /obj/item/weapon/plastique(src) - return + if("guns") + new /obj/item/weapon/gun/projectile/revolver(src) + new /obj/item/ammo_magazine/s357(src) + new /obj/item/weapon/card/emag(src) + new /obj/item/weapon/plastique(src) + new /obj/item/weapon/plastique(src) - if("murder") - new /obj/item/weapon/melee/energy/sword(src) - new /obj/item/clothing/glasses/thermal/syndi(src) - new /obj/item/weapon/card/emag(src) - new /obj/item/clothing/shoes/syndigaloshes(src) - return + if("murder") + new /obj/item/weapon/melee/energy/sword(src) + new /obj/item/clothing/glasses/thermal/syndi(src) + new /obj/item/weapon/card/emag(src) + new /obj/item/clothing/shoes/syndigaloshes(src) - if("freedom") - var/obj/item/weapon/implanter/O = new /obj/item/weapon/implanter(src) - O.imp = new /obj/item/weapon/implant/freedom(O) - var/obj/item/weapon/implanter/U = new /obj/item/weapon/implanter(src) - U.imp = new /obj/item/weapon/implant/uplink(U) - return + if("freedom") + var/obj/item/weapon/implanter/O = new /obj/item/weapon/implanter(src) + O.imp = new /obj/item/weapon/implant/freedom(O) + var/obj/item/weapon/implanter/U = new /obj/item/weapon/implanter(src) + U.imp = new /obj/item/weapon/implant/uplink(U) - if("hacker") - new /obj/item/device/encryptionkey/syndicate(src) - new /obj/item/weapon/aiModule/syndicate(src) - new /obj/item/weapon/card/emag(src) - new /obj/item/device/encryptionkey/binary(src) - return + if("hacker") + new /obj/item/device/encryptionkey/syndicate(src) + new /obj/item/weapon/aiModule/syndicate(src) + new /obj/item/weapon/card/emag(src) + new /obj/item/device/encryptionkey/binary(src) - if("lordsingulo") - new /obj/item/device/radio/beacon/syndicate(src) - new /obj/item/clothing/suit/space/syndicate(src) - new /obj/item/clothing/head/helmet/space/syndicate(src) - new /obj/item/clothing/mask/gas/syndicate(src) - new /obj/item/weapon/tank/emergency/oxygen/double(src) - new /obj/item/weapon/card/emag(src) - return + if("lordsingulo") + new /obj/item/device/radio/beacon/syndicate(src) + new /obj/item/clothing/suit/space/syndicate(src) + new /obj/item/clothing/head/helmet/space/syndicate(src) + new /obj/item/clothing/mask/gas/syndicate(src) + new /obj/item/weapon/tank/emergency/oxygen/double(src) + new /obj/item/weapon/card/emag(src) - if("smoothoperator") - new /obj/item/weapon/storage/box/syndie_kit/g9mm(src) - new /obj/item/weapon/storage/bag/trash(src) - new /obj/item/weapon/soap/syndie(src) - new /obj/item/bodybag(src) - new /obj/item/clothing/under/suit_jacket(src) - new /obj/item/clothing/shoes/laceup(src) - return + if("smoothoperator") + new /obj/item/weapon/storage/box/syndie_kit/g9mm(src) + new /obj/item/weapon/storage/bag/trash(src) + new /obj/item/weapon/soap/syndie(src) + new /obj/item/bodybag(src) + new /obj/item/clothing/under/suit_jacket(src) + new /obj/item/clothing/shoes/laceup(src) + . = ..() /obj/item/weapon/storage/box/syndie_kit name = "box" @@ -80,118 +70,97 @@ /obj/item/weapon/storage/box/syndie_kit/imp_freedom name = "boxed freedom implant (with injector)" -/obj/item/weapon/storage/box/syndie_kit/imp_freedom/New() - ..() +/obj/item/weapon/storage/box/syndie_kit/imp_freedom/initialize() var/obj/item/weapon/implanter/O = new(src) O.imp = new /obj/item/weapon/implant/freedom(O) O.update() - return + . = ..() /obj/item/weapon/storage/box/syndie_kit/imp_compress name = "box (C)" - -/obj/item/weapon/storage/box/syndie_kit/imp_compress/New() - new /obj/item/weapon/implanter/compressed(src) - ..() - return + starts_with = list(/obj/item/weapon/implanter/compressed) /obj/item/weapon/storage/box/syndie_kit/imp_explosive name = "box (E)" - -/obj/item/weapon/storage/box/syndie_kit/imp_explosive/New() - new /obj/item/weapon/implanter/explosive(src) - ..() - return + starts_with = list(/obj/item/weapon/implanter/explosive) /obj/item/weapon/storage/box/syndie_kit/imp_uplink name = "boxed uplink implant (with injector)" -/obj/item/weapon/storage/box/syndie_kit/imp_uplink/New() - ..() +/obj/item/weapon/storage/box/syndie_kit/imp_uplink/initialize() var/obj/item/weapon/implanter/O = new(src) O.imp = new /obj/item/weapon/implant/uplink(O) O.update() - return + . = ..() /obj/item/weapon/storage/box/syndie_kit/space name = "boxed space suit and helmet" - -/obj/item/weapon/storage/box/syndie_kit/space/New() - ..() - new /obj/item/clothing/suit/space/syndicate(src) - new /obj/item/clothing/head/helmet/space/syndicate(src) - new /obj/item/clothing/mask/gas/syndicate(src) - new /obj/item/weapon/tank/emergency/oxygen/double(src) - return + starts_with = list( + /obj/item/clothing/suit/space/syndicate, + /obj/item/clothing/head/helmet/space/syndicate, + /obj/item/clothing/mask/gas/syndicate, + /obj/item/weapon/tank/emergency/oxygen/double + ) /obj/item/weapon/storage/box/syndie_kit/chameleon name = "chameleon kit" desc = "Comes with all the clothes you need to impersonate most people. Acting lessons sold seperately." - -/obj/item/weapon/storage/box/syndie_kit/chameleon/New() - ..() - new /obj/item/clothing/under/chameleon(src) - new /obj/item/clothing/head/chameleon(src) - new /obj/item/clothing/suit/chameleon(src) - new /obj/item/clothing/shoes/chameleon(src) - new /obj/item/weapon/storage/backpack/chameleon(src) - new /obj/item/clothing/gloves/chameleon(src) - new /obj/item/clothing/mask/chameleon(src) - new /obj/item/clothing/glasses/chameleon(src) - new /obj/item/clothing/accessory/chameleon(src) - new /obj/item/weapon/gun/energy/chameleon(src) + starts_with = list( + /obj/item/clothing/under/chameleon, + /obj/item/clothing/head/chameleon, + /obj/item/clothing/suit/chameleon, + /obj/item/clothing/shoes/chameleon, + /obj/item/weapon/storage/backpack/chameleon, + /obj/item/clothing/gloves/chameleon, + /obj/item/clothing/mask/chameleon, + /obj/item/clothing/glasses/chameleon, + /obj/item/clothing/accessory/chameleon, + /obj/item/weapon/gun/energy/chameleon + ) /obj/item/weapon/storage/box/syndie_kit/clerical name = "clerical kit" desc = "Comes with all you need to fake paperwork. Assumes you have passed basic writing lessons." - -/obj/item/weapon/storage/box/syndie_kit/clerical/New() - ..() - new /obj/item/weapon/stamp/chameleon(src) - new /obj/item/weapon/pen/chameleon(src) - new /obj/item/device/destTagger(src) - new /obj/item/weapon/packageWrap(src) - new /obj/item/weapon/hand_labeler(src) + starts_with = list( + /obj/item/weapon/stamp/chameleon, + /obj/item/weapon/pen/chameleon, + /obj/item/device/destTagger, + /obj/item/weapon/packageWrap, + /obj/item/weapon/hand_labeler + ) /obj/item/weapon/storage/box/syndie_kit/spy name = "spy kit" desc = "For when you want to conduct voyeurism from afar." - -/obj/item/weapon/storage/box/syndie_kit/spy/New() - ..() - new /obj/item/device/camerabug/spy(src) - new /obj/item/device/camerabug/spy(src) - new /obj/item/device/camerabug/spy(src) - new /obj/item/device/camerabug/spy(src) - new /obj/item/device/camerabug/spy(src) - new /obj/item/device/camerabug/spy(src) - new /obj/item/device/bug_monitor/spy(src) + starts_with = list( + /obj/item/device/camerabug/spy = 6, + /obj/item/device/bug_monitor/spy + ) /obj/item/weapon/storage/box/syndie_kit/g9mm name = "\improper Smooth operator" desc = "Compact 9mm with silencer kit." - -/obj/item/weapon/storage/box/syndie_kit/g9mm/New() - ..() - new /obj/item/weapon/gun/projectile/pistol(src) - new /obj/item/weapon/silencer(src) + starts_with = list( + /obj/item/weapon/gun/projectile/pistol, + /obj/item/weapon/silencer + ) /obj/item/weapon/storage/box/syndie_kit/toxin name = "toxin kit" desc = "An apple will not be enough to keep the doctor away after this." - -/obj/item/weapon/storage/box/syndie_kit/toxin/New() - ..() - new /obj/item/weapon/reagent_containers/glass/beaker/vial/random/toxin(src) - new /obj/item/weapon/reagent_containers/syringe(src) + starts_with = list( + /obj/item/weapon/reagent_containers/glass/beaker/vial/random/toxin, + /obj/item/weapon/reagent_containers/syringe + ) /obj/item/weapon/storage/box/syndie_kit/cigarette name = "\improper Tricky smokes" desc = "Comes with the following brands of cigarettes, in this order: 2xFlash, 2xSmoke, 1xMindBreaker, 1xTricordrazine. Avoid mixing them up." -/obj/item/weapon/storage/box/syndie_kit/cigarette/New() - ..() +/obj/item/weapon/storage/box/syndie_kit/cigarette/initialize() + . = ..() var/obj/item/weapon/storage/fancy/cigarettes/pack + pack = new /obj/item/weapon/storage/fancy/cigarettes(src) fill_cigarre_package(pack, list("aluminum" = 5, "potassium" = 5, "sulfur" = 5)) pack.desc += " 'F' has been scribbled on it." @@ -222,6 +191,8 @@ new /obj/item/weapon/flame/lighter/zippo(src) + calibrate_size() + /proc/fill_cigarre_package(var/obj/item/weapon/storage/fancy/cigarettes/C, var/list/reagents) for(var/reagent in reagents) C.reagents.add_reagent(reagent, reagents[reagent] * C.storage_slots) @@ -229,72 +200,52 @@ /obj/item/weapon/storage/box/syndie_kit/ewar_voice name = "Electrowarfare and Voice Synthesiser kit" desc = "Kit for confounding organic and synthetic entities alike." - -/obj/item/weapon/storage/box/syndie_kit/ewar_voice/New() - ..() - new /obj/item/rig_module/electrowarfare_suite(src) - new /obj/item/rig_module/voice(src) - + starts_with = list( + /obj/item/rig_module/electrowarfare_suite, + /obj/item/rig_module/voice + ) /obj/item/weapon/storage/secure/briefcase/money name = "suspicious briefcase" desc = "An ominous briefcase that has the unmistakeable smell of old, stale, cigarette smoke, and gives those who look at it a bad feeling." - - - - -/obj/item/weapon/storage/secure/briefcase/money/New() - ..() - new /obj/item/weapon/spacecash/c1000(src) - new /obj/item/weapon/spacecash/c1000(src) - new /obj/item/weapon/spacecash/c1000(src) - new /obj/item/weapon/spacecash/c1000(src) - new /obj/item/weapon/spacecash/c1000(src) - new /obj/item/weapon/spacecash/c1000(src) - new /obj/item/weapon/spacecash/c1000(src) - new /obj/item/weapon/spacecash/c1000(src) - new /obj/item/weapon/spacecash/c1000(src) - new /obj/item/weapon/spacecash/c1000(src) + starts_with = list(/obj/item/weapon/spacecash/c1000 = 10) /obj/item/weapon/storage/box/syndie_kit/combat_armor name = "combat armor kit" desc = "Contains a full set of combat armor." + starts_with = list( + /obj/item/clothing/head/helmet/combat, + /obj/item/clothing/suit/armor/combat, + /obj/item/clothing/gloves/arm_guard/combat, + /obj/item/clothing/shoes/leg_guard/combat + ) -/obj/item/weapon/storage/box/syndie_kit/combat_armor/New() - ..() - new /obj/item/clothing/head/helmet/combat(src) - new /obj/item/clothing/suit/armor/combat(src) - new /obj/item/clothing/gloves/arm_guard/combat(src) - new /obj/item/clothing/shoes/leg_guard/combat(src) - return +/obj/item/weapon/storage/box/syndie_kit/demolitions + starts_with = list( + /obj/item/weapon/syndie/c4explosive, + /obj/item/weapon/screwdriver + ) -/obj/item/weapon/storage/box/syndie_kit/demolitions/New() - ..() - new /obj/item/weapon/syndie/c4explosive(src) - new /obj/item/weapon/screwdriver(src) - -/obj/item/weapon/storage/box/syndie_kit/demolitions_heavy/New() - ..() - new /obj/item/weapon/syndie/c4explosive/heavy(src) - new /obj/item/weapon/screwdriver(src) - -/obj/item/weapon/storage/box/syndie_kit/demolitions_super_heavy/New() - ..() - new /obj/item/weapon/syndie/c4explosive/heavy/super_heavy(src) - new /obj/item/weapon/screwdriver(src) +/obj/item/weapon/storage/box/syndie_kit/demolitions_heavy + starts_with = list( + /obj/item/weapon/syndie/c4explosive/heavy, + /obj/item/weapon/screwdriver + ) +/obj/item/weapon/storage/box/syndie_kit/demolitions_super_heavy + starts_with = list( + /obj/item/weapon/syndie/c4explosive/heavy/super_heavy, + /obj/item/weapon/screwdriver + ) /obj/item/weapon/storage/secure/briefcase/rifle name = "secure briefcase" - -/obj/item/weapon/storage/secure/briefcase/rifle/New() - ..() - new /obj/item/sniper_rifle_part/barrel(src) - new /obj/item/sniper_rifle_part/stock(src) - new /obj/item/sniper_rifle_part/trigger_group(src) - - for(var/i = 1 to 4) - new /obj/item/ammo_casing/a145(src) + starts_with = list( + /obj/item/sniper_rifle_part/barrel, + /obj/item/sniper_rifle_part/stock, + /obj/item/sniper_rifle_part/trigger_group, + /obj/item/ammo_casing/a145 = 4 + ) /obj/item/weapon/storage/secure/briefcase/fuelrod name = "heavy briefcase" @@ -303,14 +254,12 @@ description_antag = "This case will likely contain a charged fuel rod gun, and a few fuel rods to go with it. It can only hold the fuel rod gun, fuel rods, batteries, a screwdriver, and stock machine parts." force = 12 //Anti-rad lined i.e. Lead, probably gonna hurt a bit if you get bashed with it. can_hold = list(/obj/item/weapon/gun/magnetic/fuelrod, /obj/item/weapon/fuel_assembly, /obj/item/weapon/cell, /obj/item/weapon/stock_parts, /obj/item/weapon/screwdriver) - - -/obj/item/weapon/storage/secure/briefcase/fuelrod/New() - ..() - new /obj/item/weapon/gun/magnetic/fuelrod(src) - new /obj/item/weapon/fuel_assembly/deuterium(src) - new /obj/item/weapon/fuel_assembly/deuterium(src) - new /obj/item/weapon/fuel_assembly/tritium(src) - new /obj/item/weapon/fuel_assembly/tritium(src) - new /obj/item/weapon/fuel_assembly/phoron(src) - new /obj/item/weapon/screwdriver(src) + starts_with = list( + /obj/item/weapon/gun/magnetic/fuelrod, + /obj/item/weapon/fuel_assembly/deuterium, + /obj/item/weapon/fuel_assembly/deuterium, + /obj/item/weapon/fuel_assembly/tritium, + /obj/item/weapon/fuel_assembly/tritium, + /obj/item/weapon/fuel_assembly/phoron, + /obj/item/weapon/screwdriver + ) diff --git a/code/game/objects/items/weapons/storage/wallets.dm b/code/game/objects/items/weapons/storage/wallets.dm index 30d81e1ba9..cb376787ab 100644 --- a/code/game/objects/items/weapons/storage/wallets.dm +++ b/code/game/objects/items/weapons/storage/wallets.dm @@ -10,6 +10,9 @@ /obj/item/weapon/card, /obj/item/clothing/mask/smokable/cigarette/, /obj/item/device/flashlight/pen, + /obj/item/device/tape, + /obj/item/weapon/cartridge, + /obj/item/device/encryptionkey, /obj/item/seeds, /obj/item/stack/medical, /obj/item/weapon/coin, @@ -18,13 +21,21 @@ /obj/item/weapon/implanter, /obj/item/weapon/flame/lighter, /obj/item/weapon/flame/match, + /obj/item/weapon/forensics, + /obj/item/weapon/glass_extra, + /obj/item/weapon/haircomb, + /obj/item/weapon/hand, + /obj/item/weapon/key, + /obj/item/weapon/lipstick, /obj/item/weapon/paper, /obj/item/weapon/pen, /obj/item/weapon/photo, /obj/item/weapon/reagent_containers/dropper, + /obj/item/weapon/sample, /obj/item/weapon/screwdriver, /obj/item/weapon/stamp, - /obj/item/clothing/accessory/permit + /obj/item/clothing/accessory/permit, + /obj/item/clothing/accessory/badge ) slot_flags = SLOT_ID @@ -118,4 +129,4 @@ name = "women's wallet" desc = "A stylish wallet typically used by women." icon_state = "girl_wallet" - item_state_slots = list(slot_r_hand_str = "wowallet", slot_l_hand_str = "wowallet") \ No newline at end of file + item_state_slots = list(slot_r_hand_str = "wowallet", slot_l_hand_str = "wowallet") diff --git a/code/game/objects/items/weapons/syndie.dm b/code/game/objects/items/weapons/syndie.dm index 5d0d1f3863..c47489272b 100644 --- a/code/game/objects/items/weapons/syndie.dm +++ b/code/game/objects/items/weapons/syndie.dm @@ -13,20 +13,29 @@ desc = "A small wrapped package." w_class = ITEMSIZE_NORMAL - var/power = 1 /*Size of the explosion.*/ + var/devastate = 1 + var/heavy_impact = 2 + var/light_impact = 4 + var/flash_range = 5 var/size = "small" /*Used for the icon, this one will make c-4small_0 for the off state.*/ /obj/item/weapon/syndie/c4explosive/heavy icon_state = "c-4large_0" item_state = "radio" desc = "A mysterious package, it's quite heavy." - power = 2 + devastate = 1 + heavy_impact = 3 + light_impact = 5 + flash_range = 7 size = "large" /obj/item/weapon/syndie/c4explosive/heavy/super_heavy name = "large-sized package" desc = "A mysterious package, it's quite exceptionally heavy." - power = 3 + devastate = 2 + heavy_impact = 5 + light_impact = 7 + flash_range = 7 /obj/item/weapon/syndie/c4explosive/New() var/K = rand(1,2000) @@ -43,7 +52,7 @@ for(var/mob/O in hearers(src, null)) O.show_message("\icon[src] The [src.name] beeps! ") sleep(50) - explosion(get_turf(src), power, power*2, power*3, power*4, power*5) + explosion(get_turf(src), devastate, heavy_impact, light_impact, flash_range) for(var/dirn in cardinal) //This is to guarantee that C4 at least breaks down all immediately adjacent walls and doors. var/turf/simulated/wall/T = get_step(src,dirn) if(locate(/obj/machinery/door/airlock) in T) @@ -54,6 +63,12 @@ T.dismantle_wall(1) qdel(src) +/obj/item/weapon/syndie/c4explosive/attackby(obj/item/weapon/W, mob/user) + if(istype(W, /obj/item/weapon/flame/lighter/zippo/c4detonator)) + var/obj/item/weapon/flame/lighter/zippo/c4detonator/D = W + D.bomb = src + return + ..() /*Detonator, disguised as a lighter*/ /*Click it when closed to open, when open to bring up a prompt asking you if you want to close it or press the button.*/ diff --git a/code/game/objects/items/weapons/tanks/tank_types.dm b/code/game/objects/items/weapons/tanks/tank_types.dm index 0ff657e9cc..efacad4942 100644 --- a/code/game/objects/items/weapons/tanks/tank_types.dm +++ b/code/game/objects/items/weapons/tanks/tank_types.dm @@ -186,8 +186,8 @@ src.air_contents.adjust_gas("phoron", (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) /obj/item/weapon/tank/emergency/phoron/double - name = "double emergency nitrogen tank" - icon_state = "emergency_double_nitrogen" + name = "double emergency phoron tank" + icon_state = "emergency_double_nitro" gauge_icon = "indicator_emergency_double" volume = 10 diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm index d17cb21472..49608c649a 100644 --- a/code/game/objects/items/weapons/tanks/tanks.dm +++ b/code/game/objects/items/weapons/tanks/tanks.dm @@ -8,7 +8,7 @@ var/list/global/tank_gauge_cache = list() name = "tank" icon = 'icons/obj/tank.dmi' sprite_sheets = list( - "Teshari" = 'icons/mob/species/seromi/back.dmi' + SPECIES_TESHARI = 'icons/mob/species/seromi/back.dmi' ) var/gauge_icon = "indicator_tank" diff --git a/code/game/objects/items/weapons/tape.dm b/code/game/objects/items/weapons/tape.dm index 30257a2b84..83e944f593 100644 --- a/code/game/objects/items/weapons/tape.dm +++ b/code/game/objects/items/weapons/tape.dm @@ -131,7 +131,7 @@ icon = 'icons/obj/bureaucracy.dmi' icon_state = "tape" w_class = ITEMSIZE_TINY - layer = 4 + plane = MOB_PLANE anchored = 1 //it's sticky, no you cant move it var/obj/item/weapon/stuck = null diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index e3d38b8774..62b3d9b1bb 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -236,7 +236,7 @@ ..() /obj/item/weapon/wirecutters/attack(mob/living/carbon/C as mob, mob/user as mob) - if(user.a_intent == I_HELP && (C.handcuffed) && (istype(C.handcuffed, /obj/item/weapon/handcuffs/cable))) + if(istype(C) && user.a_intent == I_HELP && (C.handcuffed) && (istype(C.handcuffed, /obj/item/weapon/handcuffs/cable))) usr.visible_message("\The [usr] cuts \the [C]'s restraints with \the [src]!",\ "You cut \the [C]'s restraints with \the [src]!",\ "You hear cable being cut.") diff --git a/code/game/objects/items/weapons/trays.dm b/code/game/objects/items/weapons/trays.dm index c2ea991d98..8d9977cc17 100644 --- a/code/game/objects/items/weapons/trays.dm +++ b/code/game/objects/items/weapons/trays.dm @@ -52,9 +52,7 @@ if (istype(location, /turf/simulated)) location.add_blood(H) ///Plik plik, the sound of blood - M.attack_log += text("\[[time_stamp()]\] Has been attacked with [src.name] by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to attack [M.name] ([M.ckey])") - msg_admin_attack("[user.name] ([user.ckey]) used the [src.name] to attack [M.name] ([M.ckey]) (JMP)") + add_attack_logs(user,M,"Hit with [src]") if(prob(15)) M.Weaken(3) @@ -190,7 +188,7 @@ carrying.Add(I) Img.icon = I.icon Img.icon_state = I.icon_state - Img.layer = 30 + I.layer + Img.layer = layer + I.layer*0.01 if(istype(I, /obj/item/weapon/material)) var/obj/item/weapon/material/O = I if(O.applies_material_colour) diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index 8938e611c0..b5ae0912e9 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -17,10 +17,7 @@ /obj/item/weapon/nullrod/attack(mob/M as mob, mob/living/user as mob) //Paste from old-code to decult with a null rod. - M.attack_log += text("\[[time_stamp()]\] Has been attacked with [src.name] by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to attack [M.name] ([M.ckey])") - - msg_admin_attack("[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (JMP)") + add_attack_logs(user,M,"Hit with [src] (nullrod)") user.setClickCooldown(user.get_attack_speed(src)) user.do_attack_animation(M) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 84f9f88602..3835b2a24b 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -1,4 +1,6 @@ /obj + layer = OBJ_LAYER + plane = OBJ_PLANE //Used to store information about the contents of the object. var/list/matter var/w_class // Size of the object. @@ -13,6 +15,9 @@ var/armor_penetration = 0 var/show_messages var/preserve_item = 0 //whether this object is preserved when its owner goes into cryo-storage, gateway, etc + var/can_speak = 0 //For MMIs and admin trickery. If an object has a brainmob in its contents, set this to 1 to allow it to speak. + + var/show_examine = TRUE // Does this pop up on a mob when the mob is examined? /obj/Destroy() processing_objects -= src diff --git a/code/game/objects/random/_random.dm b/code/game/objects/random/_random.dm new file mode 100644 index 0000000000..29272a7247 --- /dev/null +++ b/code/game/objects/random/_random.dm @@ -0,0 +1,138 @@ +/obj/random + name = "random object" + desc = "This item type is used to spawn random objects at round-start" + icon = 'icons/misc/mark.dmi' + icon_state = "rup" + var/spawn_nothing_percentage = 0 // this variable determines the likelyhood that this random object will not spawn anything + +// creates a new object and deletes itself +/obj/random/New() + ..() + spawn() + if(istype(src.loc, /obj/structure/loot_pile)) //Spawning from a lootpile is weird, need to wait until we're out of it to do our work. + while(istype(src.loc, /obj/structure/loot_pile)) + sleep(1) + if (!prob(spawn_nothing_percentage)) + spawn_item() + qdel(src) + +// this function should return a specific item to spawn +/obj/random/proc/item_to_spawn() + return 0 + +// creates the random item +/obj/random/proc/spawn_item() + var/build_path = item_to_spawn() + + var/atom/A = new build_path(src.loc) + if(pixel_x || pixel_y) + A.pixel_x = pixel_x + A.pixel_y = pixel_y + +var/list/random_junk_ +var/list/random_useful_ +/proc/get_random_useful_type() + if(!random_useful_) + random_useful_ = subtypesof(/obj/item/weapon/pen/crayon) + random_useful_ += /obj/item/weapon/pen + random_useful_ += /obj/item/weapon/pen/blue + random_useful_ += /obj/item/weapon/pen/red + random_useful_ += /obj/item/weapon/pen/multi + random_useful_ += /obj/item/weapon/storage/box/matches + random_useful_ += /obj/item/stack/material/cardboard + return pick(random_useful_) + +/proc/get_random_junk_type() + if(prob(20)) // Misc. clutter + return /obj/effect/decal/cleanable/generic + if(prob(70)) // Misc. junk + if(!random_junk_) + random_junk_ = subtypesof(/obj/item/trash) + random_junk_ += typesof(/obj/item/weapon/cigbutt) + random_junk_ += /obj/effect/decal/cleanable/spiderling_remains + random_junk_ += /obj/effect/decal/remains/mouse + random_junk_ += /obj/effect/decal/remains/robot + random_junk_ += /obj/item/weapon/paper/crumpled + random_junk_ += /obj/item/inflatable/torn + random_junk_ += /obj/effect/decal/cleanable/molten_item + random_junk_ += /obj/item/weapon/material/shard + + random_junk_ -= /obj/item/trash/plate + random_junk_ -= /obj/item/trash/snack_bowl + random_junk_ -= /obj/item/trash/syndi_cakes + random_junk_ -= /obj/item/trash/tray + return pick(random_junk_) + // Misc. actually useful stuff + return get_random_useful_type() + +///////////////////////////////////////////////////////////////////////// + +/obj/random/single + name = "randomly spawned object" + desc = "This item type is used to randomly spawn a given object at round-start" + icon_state = "x3" + var/spawn_object = null + +/obj/random/single/item_to_spawn() + return ispath(spawn_object) ? spawn_object : text2path(spawn_object) + +//Multiple Object Spawn + +/obj/random/multiple + +/obj/random/multiple/spawn_item() + var/list/things_to_make = item_to_spawn() + for(var/new_type in things_to_make) + new new_type(src.loc) + +/* +// Multi Point Spawn +// Selects one spawn point out of a group of points with the same ID and asks it to generate its items +*/ +var/list/multi_point_spawns + +/obj/random_multi + name = "random object spawn point" + desc = "This item type is used to spawn random objects at round-start. Only one spawn point for a given group id is selected." + icon = 'icons/misc/mark.dmi' + icon_state = "x3" + invisibility = INVISIBILITY_MAXIMUM + var/id // Group id + var/weight // Probability weight for this spawn point + +/obj/random_multi/initialize() + . = ..() + weight = max(1, round(weight)) + + if(!multi_point_spawns) + multi_point_spawns = list() + var/list/spawnpoints = multi_point_spawns[id] + if(!spawnpoints) + spawnpoints = list() + multi_point_spawns[id] = spawnpoints + spawnpoints[src] = weight + +/obj/random_multi/Destroy() + var/list/spawnpoints = multi_point_spawns[id] + spawnpoints -= src + if(!spawnpoints.len) + multi_point_spawns -= id + . = ..() + +/obj/random_multi/proc/generate_items() + return + +/obj/random_multi/single_item + var/item_path // Item type to spawn + +/obj/random_multi/single_item/generate_items() + new item_path(loc) + +/hook/roundstart/proc/generate_multi_spawn_items() + for(var/id in multi_point_spawns) + var/list/spawn_points = multi_point_spawns[id] + var/obj/random_multi/rm = pickweight(spawn_points) + rm.generate_items() + for(var/entry in spawn_points) + qdel(entry) + return 1 \ No newline at end of file diff --git a/code/game/objects/random/guns_and_ammo.dm b/code/game/objects/random/guns_and_ammo.dm new file mode 100644 index 0000000000..a910881a76 --- /dev/null +++ b/code/game/objects/random/guns_and_ammo.dm @@ -0,0 +1,129 @@ +/obj/random/energy + name = "Random Energy Weapon" + desc = "This is a random security weapon." + icon = 'icons/obj/gun.dmi' + icon_state = "energykill100" + +/obj/random/energy/item_to_spawn() + return pick(prob(3);/obj/item/weapon/gun/energy/laser, + prob(4);/obj/item/weapon/gun/energy/gun, + prob(3);/obj/item/weapon/gun/energy/gun/burst, + prob(1);/obj/item/weapon/gun/energy/gun/nuclear, + prob(2);/obj/item/weapon/gun/energy/retro, + prob(2);/obj/item/weapon/gun/energy/lasercannon, + prob(3);/obj/item/weapon/gun/energy/xray, + prob(1);/obj/item/weapon/gun/energy/sniperrifle, + prob(1);/obj/item/weapon/gun/energy/plasmastun, + prob(2);/obj/item/weapon/gun/energy/ionrifle, + prob(2);/obj/item/weapon/gun/energy/ionrifle/pistol, + prob(3);/obj/item/weapon/gun/energy/toxgun, + prob(4);/obj/item/weapon/gun/energy/taser, + prob(2);/obj/item/weapon/gun/energy/crossbow/largecrossbow, + prob(4);/obj/item/weapon/gun/energy/stunrevolver) + +/obj/random/energy/sec + name = "Random Security Energy Weapon" + desc = "This is a random security weapon." + icon = 'icons/obj/gun.dmi' + icon_state = "energykill100" + +/obj/random/energy/sec/item_to_spawn() + return pick(prob(2);/obj/item/weapon/gun/energy/laser, + prob(2);/obj/item/weapon/gun/energy/gun) + +/obj/random/projectile + name = "Random Projectile Weapon" + desc = "This is a random projectile weapon." + icon = 'icons/obj/gun.dmi' + icon_state = "revolver" + +/obj/random/projectile/item_to_spawn() + return pick(prob(3);/obj/item/weapon/gun/projectile/automatic/wt550, + prob(3);/obj/item/weapon/gun/projectile/automatic/mini_uzi, + prob(3);/obj/item/weapon/gun/projectile/automatic/tommygun, + prob(2);/obj/item/weapon/gun/projectile/automatic/c20r, + prob(2);/obj/item/weapon/gun/projectile/automatic/sts35, + prob(2);/obj/item/weapon/gun/projectile/automatic/z8, + prob(4);/obj/item/weapon/gun/projectile/colt, + prob(2);/obj/item/weapon/gun/projectile/deagle, + prob(1);/obj/item/weapon/gun/projectile/deagle/camo, + prob(1);/obj/item/weapon/gun/projectile/deagle/gold, + prob(3);/obj/item/weapon/gun/projectile/derringer, + prob(1);/obj/item/weapon/gun/projectile/heavysniper, + prob(4);/obj/item/weapon/gun/projectile/luger, + prob(3);/obj/item/weapon/gun/projectile/luger/brown, + prob(4);/obj/item/weapon/gun/projectile/sec, + prob(3);/obj/item/weapon/gun/projectile/sec/wood, + prob(4);/obj/item/weapon/gun/projectile/p92x, + prob(3);/obj/item/weapon/gun/projectile/p92x/brown, + prob(4);/obj/item/weapon/gun/projectile/pistol, + prob(5);/obj/item/weapon/gun/projectile/pirate, + prob(2);/obj/item/weapon/gun/projectile/revolver, + prob(4);/obj/item/weapon/gun/projectile/revolver/deckard, + prob(4);/obj/item/weapon/gun/projectile/revolver/detective, + prob(2);/obj/item/weapon/gun/projectile/revolver/judge, + prob(3);/obj/item/weapon/gun/projectile/revolver/lemat, + prob(2);/obj/item/weapon/gun/projectile/revolver/mateba, + prob(4);/obj/item/weapon/gun/projectile/shotgun/doublebarrel, + prob(3);/obj/item/weapon/gun/projectile/shotgun/doublebarrel/sawn, + prob(3);/obj/item/weapon/gun/projectile/shotgun/pump, + prob(2);/obj/item/weapon/gun/projectile/shotgun/pump/combat, + prob(4);/obj/item/weapon/gun/projectile/shotgun/pump/rifle, + prob(3);/obj/item/weapon/gun/projectile/shotgun/pump/rifle/lever, + prob(2);/obj/item/weapon/gun/projectile/silenced) + +/obj/random/projectile/sec + name = "Random Security Projectile Weapon" + desc = "This is a random security weapon." + icon = 'icons/obj/gun.dmi' + icon_state = "revolver" + +/obj/random/projectile/sec/item_to_spawn() + return pick(prob(3);/obj/item/weapon/gun/projectile/shotgun/pump, + prob(2);/obj/item/weapon/gun/projectile/automatic/wt550, + prob(1);/obj/item/weapon/gun/projectile/shotgun/pump/combat) + +/obj/random/handgun + name = "Random Handgun" + desc = "This is a random sidearm." + icon = 'icons/obj/gun.dmi' + icon_state = "secgundark" + +/obj/random/handgun/item_to_spawn() + return pick(prob(4);/obj/item/weapon/gun/projectile/sec, + prob(4);/obj/item/weapon/gun/projectile/p92x, + prob(3);/obj/item/weapon/gun/projectile/sec/wood, + prob(3);/obj/item/weapon/gun/projectile/p92x/brown, + prob(3);/obj/item/weapon/gun/projectile/colt, + prob(2);/obj/item/weapon/gun/projectile/luger, + prob(2);/obj/item/weapon/gun/energy/gun, + prob(2);/obj/item/weapon/gun/projectile/pistol, + prob(1);/obj/item/weapon/gun/energy/retro, + prob(1);/obj/item/weapon/gun/projectile/luger/brown) + +/obj/random/handgun/sec + name = "Random Security Handgun" + desc = "This is a random security sidearm." + icon = 'icons/obj/gun.dmi' + icon_state = "secgundark" + +/obj/random/handgun/sec/item_to_spawn() + return pick(prob(3);/obj/item/weapon/gun/projectile/sec, + prob(1);/obj/item/weapon/gun/projectile/sec/wood) + +/obj/random/ammo + name = "Random Ammunition" + desc = "This is random security ammunition." + icon = 'icons/obj/ammo.dmi' + icon_state = "45-10" + +/obj/random/ammo/item_to_spawn() + return pick(prob(6);/obj/item/weapon/storage/box/beanbags, + prob(2);/obj/item/weapon/storage/box/shotgunammo, + prob(4);/obj/item/weapon/storage/box/shotgunshells, + prob(1);/obj/item/weapon/storage/box/stunshells, + prob(2);/obj/item/ammo_magazine/m45, + prob(4);/obj/item/ammo_magazine/m45/rubber, + prob(4);/obj/item/ammo_magazine/m45/flash, + prob(2);/obj/item/ammo_magazine/m9mmt, + prob(6);/obj/item/ammo_magazine/m9mmt/rubber) \ No newline at end of file diff --git a/code/game/objects/random/maintenance.dm b/code/game/objects/random/maintenance.dm new file mode 100644 index 0000000000..e7e45a8791 --- /dev/null +++ b/code/game/objects/random/maintenance.dm @@ -0,0 +1,309 @@ +/obj/random/maintenance //Clutter and loot for maintenance and away missions + name = "random maintenance item" + desc = "This is a random maintenance item." + icon = 'icons/obj/items.dmi' + icon_state = "gift1" + +/obj/random/maintenance/item_to_spawn() + return pick(prob(300);/obj/random/tech_supply, + prob(200);/obj/random/medical, + prob(100);/obj/random/firstaid, + prob(10);/obj/random/contraband, + prob(50);/obj/random/action_figure, + prob(50);/obj/random/plushie, + prob(200);/obj/random/junk, + prob(200);/obj/random/material, + prob(50);/obj/random/toy, + prob(100);/obj/random/tank, + prob(50);/obj/random/soap, + prob(60);/obj/random/drinkbottle, + prob(500);/obj/random/maintenance/clean) + +/obj/random/maintenance/clean +/*Maintenance loot lists without the trash, for use inside things. +Individual items to add to the maintenance list should go here, if you add +something, make sure it's not in one of the other lists.*/ + name = "random clean maintenance item" + desc = "This is a random clean maintenance item." + icon = 'icons/obj/items.dmi' + icon_state = "gift1" + +/obj/random/maintenance/clean/item_to_spawn() + return pick(prob(10);/obj/random/contraband, + prob(2);/obj/item/device/flashlight/flare, + prob(2);/obj/item/device/flashlight/glowstick, + prob(2);/obj/item/device/flashlight/glowstick/blue, + prob(1);/obj/item/device/flashlight/glowstick/orange, + prob(1);/obj/item/device/flashlight/glowstick/red, + prob(1);/obj/item/device/flashlight/glowstick/yellow, + prob(1);/obj/item/device/flashlight/pen, + prob(4);/obj/item/weapon/cell, + prob(4);/obj/item/weapon/cell/device, + prob(3);/obj/item/weapon/cell/high, + prob(2);/obj/item/weapon/cell/super, + prob(5);/obj/random/cigarettes, + prob(3);/obj/item/clothing/mask/gas, + prob(2);/obj/item/clothing/mask/gas/half, + prob(4);/obj/item/clothing/mask/breath, + prob(2);/obj/item/weapon/reagent_containers/glass/rag, + prob(4);/obj/item/weapon/reagent_containers/food/snacks/liquidfood, + prob(2);/obj/item/weapon/storage/secure/briefcase, + prob(4);/obj/item/weapon/storage/briefcase, + prob(5);/obj/item/weapon/storage/backpack, + prob(5);/obj/item/weapon/storage/backpack/satchel/norm, + prob(4);/obj/item/weapon/storage/backpack/satchel, + prob(3);/obj/item/weapon/storage/backpack/dufflebag, + prob(1);/obj/item/weapon/storage/backpack/dufflebag/syndie, + prob(5);/obj/item/weapon/storage/box, + prob(3);/obj/item/weapon/storage/box/donkpockets, + prob(2);/obj/item/weapon/storage/box/sinpockets, + prob(1);/obj/item/weapon/storage/box/cups, + prob(3);/obj/item/weapon/storage/box/mousetraps, + prob(3);/obj/item/weapon/storage/wallet, + prob(1);/obj/item/device/paicard, + prob(2);/obj/item/clothing/shoes/galoshes, + prob(1);/obj/item/clothing/shoes/syndigaloshes, + prob(4);/obj/item/clothing/shoes/black, + prob(4);/obj/item/clothing/shoes/laceup, + prob(4);/obj/item/clothing/shoes/black, + prob(4);/obj/item/clothing/shoes/leather, + prob(1);/obj/item/clothing/gloves/yellow, + prob(3);/obj/item/clothing/gloves/botanic_leather, + prob(2);/obj/item/clothing/gloves/sterile/latex, + prob(5);/obj/item/clothing/gloves/white, + prob(5);/obj/item/clothing/gloves/rainbow, + prob(2);/obj/item/clothing/gloves/fyellow, + prob(1);/obj/item/clothing/glasses/sunglasses, + prob(3);/obj/item/clothing/glasses/meson, + prob(2);/obj/item/clothing/glasses/meson/prescription, + prob(1);/obj/item/clothing/glasses/welding, + prob(1);/obj/item/clothing/head/bio_hood/general, + prob(4);/obj/item/clothing/head/hardhat, + prob(3);/obj/item/clothing/head/hardhat/red, + prob(1);/obj/item/clothing/head/ushanka, + prob(2);/obj/item/clothing/head/welding, + prob(4);/obj/item/clothing/suit/storage/hazardvest, + prob(1);/obj/item/clothing/suit/space/emergency, + prob(3);/obj/item/clothing/suit/storage/toggle/bomber, + prob(1);/obj/item/clothing/suit/bio_suit/general, + prob(3);/obj/item/clothing/suit/storage/toggle/hoodie/black, + prob(3);/obj/item/clothing/suit/storage/toggle/hoodie/blue, + prob(3);/obj/item/clothing/suit/storage/toggle/hoodie/red, + prob(3);/obj/item/clothing/suit/storage/toggle/hoodie/yellow, + prob(3);/obj/item/clothing/suit/storage/toggle/brown_jacket, + prob(3);/obj/item/clothing/suit/storage/toggle/leather_jacket, + prob(1);/obj/item/clothing/suit/storage/vest/press, + prob(3);/obj/item/clothing/suit/storage/apron, + prob(4);/obj/item/clothing/under/color/grey, + prob(2);/obj/item/clothing/under/syndicate/tacticool, + prob(2);/obj/item/clothing/under/pants/camo, + prob(1);/obj/item/clothing/under/harness, + prob(1);/obj/item/clothing/under/tactical, + prob(3);/obj/item/clothing/accessory/storage/webbing, + prob(3);/obj/item/weapon/camera_assembly, + prob(4);/obj/item/weapon/caution, + prob(3);/obj/item/weapon/caution/cone, + prob(1);/obj/item/weapon/card/emag_broken, + prob(2);/obj/item/device/camera, + prob(3);/obj/item/device/pda, + prob(3);/obj/item/device/radio/headset) + +/obj/random/maintenance/security +/*Maintenance loot list. This one is for around security areas*/ + name = "random security maintenance item" + desc = "This is a random security maintenance item." + icon = 'icons/obj/items.dmi' + icon_state = "gift1" + +/obj/random/maintenance/security/item_to_spawn() + return pick(prob(320);/obj/random/maintenance/clean, + prob(2);/obj/item/device/flashlight/maglight, + prob(2);/obj/item/device/flash, + prob(1);/obj/item/weapon/cell/device/weapon, + prob(1);/obj/item/clothing/mask/gas/swat, + prob(1);/obj/item/clothing/mask/gas/syndicate, + prob(2);/obj/item/clothing/mask/balaclava, + prob(1);/obj/item/clothing/mask/balaclava/tactical, + prob(3);/obj/item/weapon/storage/backpack/security, + prob(3);/obj/item/weapon/storage/backpack/satchel/sec, + prob(2);/obj/item/weapon/storage/backpack/messenger/sec, + prob(2);/obj/item/weapon/storage/backpack/dufflebag/sec, + prob(1);/obj/item/weapon/storage/backpack/dufflebag/syndie/ammo, + prob(1);/obj/item/weapon/storage/backpack/dufflebag/syndie/med, + prob(2);/obj/item/weapon/storage/box/swabs, + prob(2);/obj/item/weapon/storage/belt/security, + prob(1);/obj/item/weapon/grenade/flashbang, + prob(1);/obj/item/weapon/melee/baton, + prob(1);/obj/item/weapon/reagent_containers/spray/pepper, + prob(3);/obj/item/clothing/shoes/boots/jackboots, + prob(1);/obj/item/clothing/shoes/boots/swat, + prob(1);/obj/item/clothing/shoes/boots/combat, + prob(1);/obj/item/clothing/gloves/swat, + prob(1);/obj/item/clothing/gloves/combat, + prob(1);/obj/item/clothing/glasses/sunglasses/big, + prob(2);/obj/item/clothing/glasses/hud/security, + prob(1);/obj/item/clothing/glasses/sunglasses/sechud, + prob(1);/obj/item/clothing/glasses/sunglasses/sechud/aviator, + prob(1);/obj/item/clothing/glasses/sunglasses/sechud/tactical, + prob(3);/obj/item/clothing/head/beret/sec, + prob(3);/obj/item/clothing/head/beret/sec/corporate/officer, + prob(3);/obj/item/clothing/head/beret/sec/navy/officer, + prob(2);/obj/item/clothing/head/helmet, + prob(4);/obj/item/clothing/head/soft/sec, + prob(4);/obj/item/clothing/head/soft/sec/corp, + prob(3);/obj/item/clothing/suit/armor/vest, + prob(2);/obj/item/clothing/suit/armor/vest/security, + prob(2);/obj/item/clothing/suit/storage/vest/officer, + prob(1);/obj/item/clothing/suit/storage/vest/detective, + prob(1);/obj/item/clothing/suit/storage/vest/press, + prob(2);/obj/item/clothing/accessory/storage/black_vest, + prob(2);/obj/item/clothing/accessory/storage/black_drop_pouches, + prob(1);/obj/item/clothing/accessory/holster/leg, + prob(1);/obj/item/clothing/accessory/holster/hip, + prob(1);/obj/item/clothing/accessory/holster/waist, + prob(1);/obj/item/clothing/accessory/holster/armpit, + prob(2);/obj/item/clothing/ears/earmuffs, + prob(2);/obj/item/weapon/handcuffs,) + +/obj/random/maintenance/medical +/*Maintenance loot list. This one is for around medical areas*/ + name = "random medical maintenance item" + desc = "This is a random medical maintenance item." + icon = 'icons/obj/items.dmi' + icon_state = "gift1" + +/obj/random/maintenance/medical/item_to_spawn() + return pick(prob(320);/obj/random/maintenance/clean, + prob(25);/obj/random/medical/lite, + prob(2);/obj/item/clothing/mask/breath/medical, + prob(2);/obj/item/clothing/mask/surgical, + prob(5);/obj/item/weapon/storage/backpack/medic, + prob(5);/obj/item/weapon/storage/backpack/satchel/med, + prob(5);/obj/item/weapon/storage/backpack/messenger/med, + prob(3);/obj/item/weapon/storage/backpack/dufflebag/med, + prob(1);/obj/item/weapon/storage/backpack/dufflebag/syndie/med, + prob(2);/obj/item/weapon/storage/box/autoinjectors, + prob(3);/obj/item/weapon/storage/box/beakers, + prob(2);/obj/item/weapon/storage/box/bodybags, + prob(3);/obj/item/weapon/storage/box/syringes, + prob(3);/obj/item/weapon/storage/box/gloves, + prob(2);/obj/item/weapon/storage/belt/medical/emt, + prob(2);/obj/item/weapon/storage/belt/medical, + prob(1);/obj/item/clothing/shoes/boots/combat, + prob(3);/obj/item/clothing/shoes/white, + prob(2);/obj/item/clothing/gloves/sterile/nitrile, + prob(5);/obj/item/clothing/gloves/white, + prob(2);/obj/item/clothing/glasses/hud/health, + prob(1);/obj/item/clothing/glasses/hud/health/prescription, + prob(1);/obj/item/clothing/head/bio_hood/virology, + prob(4);/obj/item/clothing/suit/storage/toggle/labcoat, + prob(1);/obj/item/clothing/suit/bio_suit/general, + prob(2);/obj/item/clothing/under/rank/medical/paramedic, + prob(2);/obj/item/clothing/accessory/storage/black_vest, + prob(2);/obj/item/clothing/accessory/storage/white_vest, + prob(1);/obj/item/clothing/accessory/storage/white_drop_pouches, + prob(1);/obj/item/clothing/accessory/storage/black_drop_pouches, + prob(2);/obj/item/clothing/accessory/stethoscope) + +/obj/random/maintenance/engineering +/*Maintenance loot list. This one is for around medical areas*/ + name = "random engineering maintenance item" + desc = "This is a random engineering maintenance item." + icon = 'icons/obj/items.dmi' + icon_state = "gift1" + +/obj/random/maintenance/engineering/item_to_spawn() + return pick(prob(320);/obj/random/maintenance/clean, + prob(2);/obj/item/device/flashlight/maglight, + prob(3);/obj/item/clothing/mask/gas/half, + prob(2);/obj/item/clothing/mask/balaclava, + prob(2);/obj/item/weapon/storage/briefcase/inflatable, + prob(5);/obj/item/weapon/storage/backpack/industrial, + prob(5);/obj/item/weapon/storage/backpack/satchel/eng, + prob(5);/obj/item/weapon/storage/backpack/messenger/engi, + prob(3);/obj/item/weapon/storage/backpack/dufflebag/eng, + prob(5);/obj/item/weapon/storage/box, + prob(2);/obj/item/weapon/storage/belt/utility/full, + prob(3);/obj/item/weapon/storage/belt/utility, + prob(3);/obj/item/clothing/head/beret/engineering, + prob(3);/obj/item/clothing/head/soft/yellow, + prob(2);/obj/item/clothing/head/orangebandana, + prob(2);/obj/item/clothing/head/hardhat/dblue, + prob(2);/obj/item/clothing/head/hardhat/orange, + prob(1);/obj/item/clothing/glasses/welding, + prob(2);/obj/item/clothing/head/welding, + prob(4);/obj/item/clothing/suit/storage/hazardvest, + prob(2);/obj/item/clothing/under/overalls, + prob(3);/obj/item/clothing/shoes/boots/workboots, + prob(1);/obj/item/clothing/shoes/magboots, + prob(2);/obj/item/clothing/accessory/storage/black_vest, + prob(2);/obj/item/clothing/accessory/storage/brown_vest, + prob(1);/obj/item/clothing/accessory/storage/brown_drop_pouches, + prob(3);/obj/item/clothing/ears/earmuffs, + prob(1);/obj/item/weapon/beartrap, + prob(2);/obj/item/weapon/handcuffs) + +/obj/random/maintenance/research +/*Maintenance loot list. This one is for around medical areas*/ + name = "random research maintenance item" + desc = "This is a random research maintenance item." + icon = 'icons/obj/items.dmi' + icon_state = "gift1" + +/obj/random/maintenance/research/item_to_spawn() + return pick(prob(320);/obj/random/maintenance/clean, + prob(3);/obj/item/device/analyzer/plant_analyzer, + prob(1);/obj/item/device/flash/synthetic, + prob(2);/obj/item/weapon/bucket_sensor, + prob(1);/obj/item/weapon/cell/device/weapon, + prob(5);/obj/item/weapon/storage/backpack/toxins, + prob(5);/obj/item/weapon/storage/backpack/satchel/tox, + prob(5);/obj/item/weapon/storage/backpack/messenger/tox, + prob(2);/obj/item/weapon/storage/excavation, + prob(1);/obj/item/weapon/storage/backpack/holding, + prob(3);/obj/item/weapon/storage/box/beakers, + prob(3);/obj/item/weapon/storage/box/syringes, + prob(3);/obj/item/weapon/storage/box/gloves, + prob(2);/obj/item/clothing/gloves/sterile/latex, + prob(4);/obj/item/clothing/glasses/science, + prob(3);/obj/item/clothing/glasses/material, + prob(1);/obj/item/clothing/head/beret/purple, + prob(1);/obj/item/clothing/head/bio_hood/scientist, + prob(4);/obj/item/clothing/suit/storage/toggle/labcoat, + prob(4);/obj/item/clothing/suit/storage/toggle/labcoat/science, + prob(1);/obj/item/clothing/suit/bio_suit/scientist, + prob(4);/obj/item/clothing/under/rank/scientist, + prob(2);/obj/item/clothing/under/rank/scientist_new) + +/obj/random/maintenance/cargo +/*Maintenance loot list. This one is for around cargo areas*/ + name = "random cargo maintenance item" + desc = "This is a random cargo maintenance item." + icon = 'icons/obj/items.dmi' + icon_state = "gift1" + +/obj/random/maintenance/cargo/item_to_spawn() + return pick(prob(320);/obj/random/maintenance/clean, + prob(3);/obj/item/device/flashlight/lantern, + prob(4);/obj/item/weapon/pickaxe, + prob(5);/obj/item/weapon/storage/backpack/industrial, + prob(5);/obj/item/weapon/storage/backpack/satchel/norm, + prob(3);/obj/item/weapon/storage/backpack/dufflebag, + prob(1);/obj/item/weapon/storage/backpack/dufflebag/syndie/ammo, + prob(1);/obj/item/weapon/storage/toolbox/syndicate, + prob(1);/obj/item/weapon/storage/belt/utility/full, + prob(2);/obj/item/weapon/storage/belt/utility, + prob(4);/obj/item/device/toner, + prob(1);/obj/item/device/destTagger, + prob(3);/obj/item/clothing/glasses/material, + prob(3);/obj/item/clothing/head/soft/yellow, + prob(4);/obj/item/clothing/suit/storage/hazardvest, + prob(3);/obj/item/clothing/suit/storage/apron/overalls, + prob(4);/obj/item/clothing/suit/storage/apron, + prob(2);/obj/item/clothing/under/syndicate/tacticool, + prob(1);/obj/item/clothing/under/syndicate/combat, + prob(2);/obj/item/clothing/accessory/storage/black_vest, + prob(2);/obj/item/clothing/accessory/storage/brown_vest, + prob(3);/obj/item/clothing/ears/earmuffs, + prob(1);/obj/item/weapon/beartrap, + prob(2);/obj/item/weapon/handcuffs,) diff --git a/code/game/objects/random/mapping.dm b/code/game/objects/random/mapping.dm new file mode 100644 index 0000000000..57ff7acdcd --- /dev/null +++ b/code/game/objects/random/mapping.dm @@ -0,0 +1,395 @@ +/* +// Least descriptive filename? +// This is where all of the things that aren't really loot should go. +// Barricades, mines, etc. +*/ + +/obj/random/junk //Broken items, or stuff that could be picked up + name = "random junk" + desc = "This is some random junk." + icon = 'icons/obj/trash.dmi' + icon_state = "trashbag3" + +/obj/random/junk/item_to_spawn() + return get_random_junk_type() + +/obj/random/trash //Mostly remains and cleanable decals. Stuff a janitor could clean up + name = "random trash" + desc = "This is some random trash." + icon = 'icons/effects/effects.dmi' + icon_state = "greenglow" + +/obj/random/trash/item_to_spawn() + return pick(/obj/effect/decal/remains/lizard, + /obj/effect/decal/cleanable/blood/gibs/robot, + /obj/effect/decal/cleanable/blood/oil, + /obj/effect/decal/cleanable/blood/oil/streak, + /obj/effect/decal/cleanable/spiderling_remains, + /obj/effect/decal/remains/mouse, + /obj/effect/decal/cleanable/vomit, + /obj/effect/decal/cleanable/blood/splatter, + /obj/effect/decal/cleanable/ash, + /obj/effect/decal/cleanable/generic, + /obj/effect/decal/cleanable/flour, + /obj/effect/decal/cleanable/dirt, + /obj/effect/decal/remains/robot) + +/obj/random/obstruction //Large objects to block things off in maintenance + name = "random obstruction" + desc = "This is a random obstruction." + icon = 'icons/obj/cult.dmi' + icon_state = "cultgirder" + +/obj/random/obstruction/item_to_spawn() + return pick(/obj/structure/barricade, + /obj/structure/girder, + /obj/structure/girder/displaced, + /obj/structure/girder/reinforced, + /obj/structure/grille, + /obj/structure/grille/broken, + /obj/structure/foamedmetal, + /obj/structure/inflatable, + /obj/structure/inflatable/door) + +/obj/random/landmine + name = "Random Land Mine" + desc = "This is a random land mine." + icon = 'icons/obj/weapons.dmi' + icon_state = "uglymine" + spawn_nothing_percentage = 25 + +/obj/random/landmine/item_to_spawn() + return pick(prob(30);/obj/effect/mine, + prob(25);/obj/effect/mine/frag, + prob(25);/obj/effect/mine/emp, + prob(10);/obj/effect/mine/stun, + prob(10);/obj/effect/mine/incendiary,) + +/obj/random_multi/single_item/captains_spare_id + name = "Multi Point - Captain's Spare" + id = "Captain's spare id" + item_path = /obj/item/weapon/card/id/gold/captain/spare + +/obj/random_multi/single_item/sfr_headset + name = "Multi Point - headset" + id = "SFR headset" + item_path = /obj/random/sfr + +// This is in here because it's spawned by the SFR Headset randomizer +/obj/random/sfr + name = "random SFR headset" + desc = "This is a headset spawn." + icon = 'icons/misc/mark.dmi' + icon_state = "rup" + +/obj/random/sfr/item_to_spawn() + return pick(prob(25);/obj/item/device/radio/headset/heads/captain/sfr, + prob(25);/obj/item/device/radio/headset/headset_cargo/alt, + prob(25);/obj/item/device/radio/headset/headset_com/alt, + prob(25);/obj/item/device/radio/headset) + +// Mining Goodies +/obj/random/multiple/minevault + name = "random vault loot" + desc = "Loot for mine vaults." + icon = 'icons/misc/mark.dmi' + icon_state = "rup" + +/obj/random/multiple/minevault/item_to_spawn() + return pick( + prob(5);list( + /obj/item/clothing/mask/smokable/pipe, + /obj/item/weapon/reagent_containers/food/drinks/bottle/rum, + /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, + /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus, + /obj/item/weapon/flame/lighter/zippo, + /obj/structure/closet/crate/hydroponics + ), + prob(5);list( + /obj/item/weapon/pickaxe/drill, + /obj/item/clothing/suit/space/void/mining, + /obj/item/clothing/head/helmet/space/void/mining, + /obj/structure/closet/crate/engineering + ), + prob(5);list( + /obj/item/weapon/pickaxe/drill, + /obj/item/clothing/suit/space/void/mining/alt, + /obj/item/clothing/head/helmet/space/void/mining/alt, + /obj/structure/closet/crate/engineering + ), + prob(5);list( + /obj/item/weapon/reagent_containers/glass/beaker/bluespace, + /obj/item/weapon/reagent_containers/glass/beaker/bluespace, + /obj/item/weapon/reagent_containers/glass/beaker/bluespace, + /obj/structure/closet/crate/science + ), + prob(5);list( + /obj/item/weapon/ore/diamond, + /obj/item/weapon/ore/diamond, + /obj/item/weapon/ore/diamond, + /obj/item/weapon/ore/diamond, + /obj/item/weapon/ore/diamond, + /obj/item/weapon/ore/diamond, + /obj/item/weapon/ore/diamond, + /obj/item/weapon/ore/diamond, + /obj/item/weapon/ore/diamond, + /obj/item/weapon/ore/diamond, + /obj/item/weapon/ore/gold, + /obj/item/weapon/ore/gold, + /obj/item/weapon/ore/gold, + /obj/item/weapon/ore/gold, + /obj/item/weapon/ore/gold, + /obj/item/weapon/ore/gold, + /obj/item/weapon/ore/gold, + /obj/item/weapon/ore/gold, + /obj/item/weapon/ore/gold, + /obj/item/weapon/ore/gold, + /obj/structure/closet/crate/engineering + ), + prob(5);list( + /obj/item/weapon/pickaxe/drill, + /obj/item/clothing/glasses/material, + /obj/structure/ore_box, + /obj/structure/closet/crate + ), + prob(5);list( + /obj/item/weapon/reagent_containers/glass/beaker/noreact, + /obj/item/weapon/reagent_containers/glass/beaker/noreact, + /obj/item/weapon/reagent_containers/glass/beaker/noreact, + /obj/structure/closet/crate/science + ), + prob(5);list( + /obj/item/weapon/storage/secure/briefcase/money, + /obj/structure/closet/crate/freezer/rations + ), + prob(5);list( + /obj/item/clothing/accessory/tie/horrible, + /obj/item/clothing/accessory/tie/horrible, + /obj/item/clothing/accessory/tie/horrible, + /obj/item/clothing/accessory/tie/horrible, + /obj/item/clothing/accessory/tie/horrible, + /obj/item/clothing/accessory/tie/horrible, + /obj/structure/closet/crate + ), + prob(5);list( + /obj/item/weapon/melee/baton, + /obj/item/weapon/melee/baton, + /obj/item/weapon/melee/baton, + /obj/item/weapon/melee/baton, + /obj/structure/closet/crate + ), + prob(5);list( + /obj/item/clothing/under/shorts/red, + /obj/item/clothing/under/shorts/blue, + /obj/structure/closet/crate + ), + prob(2);list( + /obj/item/weapon/melee/baton/cattleprod, + /obj/item/weapon/melee/baton/cattleprod, + /obj/item/weapon/cell/high, + /obj/item/weapon/cell/high, + /obj/structure/closet/crate + ), + prob(2);list( + /obj/item/latexballon, + /obj/item/latexballon, + /obj/structure/closet/crate + ), + prob(2);list( + /obj/item/toy/syndicateballoon, + /obj/item/toy/syndicateballoon, + /obj/structure/closet/crate + ), + prob(2);list( + /obj/item/weapon/rig/industrial/equipped, + /obj/item/weapon/storage/bag/ore, + /obj/structure/closet/crate/engineering + ), + prob(2);list( + /obj/item/clothing/head/kitty, + /obj/item/clothing/head/kitty, + /obj/item/clothing/head/kitty, + /obj/item/clothing/head/kitty, + /obj/structure/closet/crate + ), + prob(2);list( + /obj/random/coin, + /obj/random/coin, + /obj/random/coin, + /obj/random/coin, + /obj/random/coin, + /obj/structure/closet/crate/plastic + ), + prob(2);list( + /obj/random/multiple/voidsuit, + /obj/random/multiple/voidsuit, + /obj/structure/closet/crate/engineering + ), + prob(2);list( + /obj/item/clothing/suit/space/syndicate/black/red, + /obj/item/clothing/head/helmet/space/syndicate/black/red, + /obj/item/clothing/suit/space/syndicate/black/red, + /obj/item/clothing/head/helmet/space/syndicate/black/red, + /obj/item/weapon/gun/projectile/automatic/mini_uzi, + /obj/item/weapon/gun/projectile/automatic/mini_uzi, + /obj/item/ammo_magazine/m45uzi, + /obj/item/ammo_magazine/m45uzi, + /obj/item/ammo_magazine/m45uzi/empty, + /obj/item/ammo_magazine/m45uzi/empty, + /obj/structure/closet/crate/plastic + ), + prob(2);list( + /obj/item/clothing/suit/ianshirt, + /obj/item/clothing/suit/ianshirt, + /obj/item/weapon/bedsheet/ian, + /obj/structure/closet/crate/plastic + ), + prob(2);list( + /obj/item/clothing/suit/armor/vest, + /obj/item/clothing/suit/armor/vest, + /obj/item/weapon/gun/projectile/garand, + /obj/item/weapon/gun/projectile/garand, + /obj/item/ammo_magazine/m762garand, + /obj/item/ammo_magazine/m762garand, + /obj/structure/closet/crate/plastic + ), + prob(2);list( + /obj/mecha/working/ripley/mining + ), + prob(2);list( + /obj/mecha/working/hoverpod/combatpod + ), + prob(2);list( + /obj/item/weapon/pickaxe/silver, + /obj/item/weapon/storage/bag/ore, + /obj/item/clothing/glasses/material, + /obj/structure/closet/crate/engineering + ), + prob(2);list( + /obj/item/weapon/pickaxe/drill, + /obj/item/weapon/storage/bag/ore, + /obj/item/clothing/glasses/material, + /obj/structure/closet/crate/engineering + ), + prob(2);list( + /obj/item/weapon/pickaxe/jackhammer, + /obj/item/weapon/storage/bag/ore, + /obj/item/clothing/glasses/material, + /obj/structure/closet/crate/engineering + ), + prob(2);list( + /obj/item/weapon/pickaxe/diamond, + /obj/item/weapon/storage/bag/ore, + /obj/item/clothing/glasses/material, + /obj/structure/closet/crate/engineering + ), + prob(2);list( + /obj/item/weapon/pickaxe/diamonddrill, + /obj/item/weapon/storage/bag/ore, + /obj/item/clothing/glasses/material, + /obj/structure/closet/crate/engineering + ), + prob(2);list( + /obj/item/weapon/pickaxe/gold, + /obj/item/weapon/storage/bag/ore, + /obj/item/clothing/glasses/material, + /obj/structure/closet/crate/engineering + ), + prob(2);list( + /obj/item/weapon/pickaxe/plasmacutter, + /obj/item/weapon/storage/bag/ore, + /obj/item/clothing/glasses/material, + /obj/structure/closet/crate/engineering + ), + prob(2);list( + /obj/item/weapon/material/sword/katana, + /obj/item/weapon/material/sword/katana, + /obj/structure/closet/crate + ), + prob(2);list( + /obj/item/weapon/material/sword, + /obj/item/weapon/material/sword, + /obj/structure/closet/crate + ), + prob(1);list( + /obj/item/clothing/mask/balaclava, + /obj/item/weapon/material/star, + /obj/item/weapon/material/star, + /obj/item/weapon/material/star, + /obj/item/weapon/material/star, + /obj/structure/closet/crate + ), + prob(1);list( + /obj/item/weed_extract, + /obj/item/xenos_claw, + /obj/structure/closet/crate/science + ), + prob(1);list( + /obj/item/clothing/head/bearpelt, + /obj/item/clothing/under/soviet, + /obj/item/clothing/under/soviet, + /obj/item/weapon/gun/projectile/shotgun/pump/rifle/ceremonial, + /obj/item/weapon/gun/projectile/shotgun/pump/rifle/ceremonial, + /obj/structure/closet/crate + ), + prob(1);list( + /obj/item/weapon/gun/projectile/revolver/detective, + /obj/item/weapon/gun/projectile/contender, + /obj/item/weapon/gun/projectile/p92x, + /obj/item/weapon/gun/projectile/derringer, + /obj/structure/closet/crate + ), + prob(1);list( + /obj/item/weapon/melee/cultblade, + /obj/item/clothing/suit/cultrobes, + /obj/item/clothing/head/culthood, + /obj/item/device/soulstone, + /obj/structure/closet/crate + ), + prob(1);list( + /obj/item/weapon/vampiric, + /obj/item/weapon/vampiric, + /obj/structure/closet/crate/science + ), + prob(1);list( + /obj/item/weapon/archaeological_find + ), + prob(1);list( + /obj/item/weapon/melee/energy/sword, + /obj/item/weapon/melee/energy/sword, + /obj/item/weapon/melee/energy/sword, + /obj/item/weapon/shield/energy, + /obj/item/weapon/shield/energy, + /obj/structure/closet/crate/science + ), + prob(1);list( + /obj/item/weapon/storage/backpack/clown, + /obj/item/clothing/under/rank/clown, + /obj/item/clothing/shoes/clown_shoes, + /obj/item/device/pda/clown, + /obj/item/clothing/mask/gas/clown_hat, + /obj/item/weapon/bikehorn, + /obj/item/toy/waterflower, + /obj/item/weapon/pen/crayon/rainbow, + /obj/structure/closet/crate + ), + prob(1);list( + /obj/item/clothing/under/mime, + /obj/item/clothing/shoes/black, + /obj/item/device/pda/mime, + /obj/item/clothing/gloves/white, + /obj/item/clothing/mask/gas/mime, + /obj/item/clothing/head/beret, + /obj/item/clothing/suit/suspenders, + /obj/item/weapon/pen/crayon/mime, + /obj/item/weapon/reagent_containers/food/drinks/bottle/bottleofnothing, + /obj/structure/closet/crate + ), + prob(1);list( + /obj/item/weapon/storage/belt/champion, + /obj/item/clothing/mask/luchador, + /obj/item/clothing/mask/luchador/rudos, + /obj/item/clothing/mask/luchador/tecnicos, + /obj/structure/closet/crate + ) + ) diff --git a/code/game/objects/random/misc.dm b/code/game/objects/random/misc.dm new file mode 100644 index 0000000000..29b597d460 --- /dev/null +++ b/code/game/objects/random/misc.dm @@ -0,0 +1,490 @@ +/* +// This is going to get so incredibly bloated. +// But this is where all of the "Loot" goes. Anything fun or useful that doesn't deserve its own file, pile in. +*/ + +/obj/random/tool + name = "random tool" + desc = "This is a random tool" + icon = 'icons/obj/tools.dmi' + icon_state = "welder" + +/obj/random/tool/item_to_spawn() + return pick(/obj/item/weapon/screwdriver, + /obj/item/weapon/wirecutters, + /obj/item/weapon/weldingtool, + /obj/item/weapon/weldingtool/largetank, + /obj/item/weapon/crowbar, + /obj/item/weapon/wrench, + /obj/item/device/flashlight, + /obj/item/device/multitool) + +/obj/random/tool/powermaint + name = "random powertool" + desc = "This is a random rare powertool for maintenance" + icon_state = "jaws_pry" + +/obj/random/tool/powermaint/item_to_spawn() + return pick(prob(320);/obj/random/tool, + prob(1);/obj/item/weapon/screwdriver/power, + prob(1);/obj/item/weapon/wirecutters/power, + prob(15);/obj/item/weapon/weldingtool/electric, + prob(5);/obj/item/weapon/weldingtool/experimental) + +/obj/random/tool/power + name = "random powertool" + desc = "This is a random powertool" + icon_state = "jaws_pry" + +/obj/random/tool/power/item_to_spawn() + return pick(/obj/item/weapon/screwdriver/power, + /obj/item/weapon/wirecutters/power, + /obj/item/weapon/weldingtool/electric, + /obj/item/weapon/weldingtool/experimental) + +/obj/random/tool/alien + name = "random alien tool" + desc = "This is a random tool" + icon = 'icons/obj/abductor.dmi' + icon_state = "welder" + +/obj/random/tool/alien/item_to_spawn() + return pick(/obj/item/weapon/screwdriver/alien, + /obj/item/weapon/wirecutters/alien, + /obj/item/weapon/weldingtool/alien, + /obj/item/weapon/crowbar/alien, + /obj/item/weapon/wrench/alien, + /obj/item/stack/cable_coil/alien, + /obj/item/device/multitool/alien) + +/obj/random/technology_scanner + name = "random scanner" + desc = "This is a random technology scanner." + icon = 'icons/obj/device.dmi' + icon_state = "atmos" + +/obj/random/technology_scanner/item_to_spawn() + return pick(prob(5);/obj/item/device/t_scanner, + prob(2);/obj/item/device/radio, + prob(5);/obj/item/device/analyzer) + +/obj/random/powercell + name = "random powercell" + desc = "This is a random powercell." + icon = 'icons/obj/power.dmi' + icon_state = "cell" + +/obj/random/powercell/item_to_spawn() + return pick(prob(40);/obj/item/weapon/cell, + prob(25);/obj/item/weapon/cell/device, + prob(25);/obj/item/weapon/cell/high, + prob(9);/obj/item/weapon/cell/super, + prob(1);/obj/item/weapon/cell/hyper) + + +/obj/random/bomb_supply + name = "bomb supply" + desc = "This is a random bomb supply." + icon = 'icons/obj/assemblies/new_assemblies.dmi' + icon_state = "signaller" + +/obj/random/bomb_supply/item_to_spawn() + return pick(/obj/item/device/assembly/igniter, + /obj/item/device/assembly/prox_sensor, + /obj/item/device/assembly/signaler, + /obj/item/device/assembly/timer, + /obj/item/device/multitool) + + +/obj/random/toolbox + name = "random toolbox" + desc = "This is a random toolbox." + icon = 'icons/obj/storage.dmi' + icon_state = "red" + +/obj/random/toolbox/item_to_spawn() + return pick(prob(6);/obj/item/weapon/storage/toolbox/mechanical, + prob(6);/obj/item/weapon/storage/toolbox/electrical, + prob(2);/obj/item/weapon/storage/toolbox/emergency, + prob(1);/obj/item/weapon/storage/toolbox/syndicate) + + +/obj/random/tech_supply + name = "random tech supply" + desc = "This is a random piece of technology supplies." + icon = 'icons/obj/power.dmi' + icon_state = "cell" + spawn_nothing_percentage = 25 + +/obj/random/tech_supply/item_to_spawn() + return pick(prob(3);/obj/random/powercell, + prob(2);/obj/random/technology_scanner, + prob(1);/obj/item/weapon/packageWrap, + prob(2);/obj/random/bomb_supply, + prob(1);/obj/item/weapon/extinguisher, + prob(1);/obj/item/clothing/gloves/fyellow, + prob(3);/obj/item/stack/cable_coil/random, + prob(2);/obj/random/toolbox, + prob(2);/obj/item/weapon/storage/belt/utility, + prob(1);/obj/item/weapon/storage/belt/utility/full, + prob(5);/obj/random/tool, + prob(2);/obj/item/weapon/tape_roll, + prob(2);/obj/item/taperoll/engineering, + prob(1);/obj/item/taperoll/atmos, + prob(1);/obj/item/device/flashlight/maglight) + +/obj/random/tech_supply/component + name = "random tech component" + desc = "This is a random machine component." + icon = 'icons/obj/items.dmi' + icon_state = "portable_analyzer" + +/obj/random/tech_supply/component/item_to_spawn() + return pick(prob(3);/obj/item/weapon/stock_parts/gear, + prob(2);/obj/item/weapon/stock_parts/console_screen, + prob(1);/obj/item/weapon/stock_parts/spring, + prob(3);/obj/item/weapon/stock_parts/capacitor, + prob(2);/obj/item/weapon/stock_parts/capacitor/adv, + prob(1);/obj/item/weapon/stock_parts/capacitor/super, + prob(3);/obj/item/weapon/stock_parts/manipulator, + prob(2);/obj/item/weapon/stock_parts/manipulator/nano, + prob(1);/obj/item/weapon/stock_parts/manipulator/pico, + prob(3);/obj/item/weapon/stock_parts/matter_bin, + prob(2);/obj/item/weapon/stock_parts/matter_bin/adv, + prob(1);/obj/item/weapon/stock_parts/matter_bin/super, + prob(3);/obj/item/weapon/stock_parts/scanning_module, + prob(2);/obj/item/weapon/stock_parts/scanning_module/adv, + prob(1);/obj/item/weapon/stock_parts/scanning_module/phasic) + +/obj/random/medical + name = "Random Medicine" + desc = "This is a random medical item." + icon = 'icons/obj/items.dmi' + icon_state = "advfirstaid" + +/obj/random/medical/item_to_spawn() + return pick(prob(21);/obj/random/medical/lite, + prob(5);/obj/random/medical/pillbottle, + prob(1);/obj/item/weapon/storage/pill_bottle/tramadol, + prob(1);/obj/item/weapon/storage/pill_bottle/antitox, + prob(1);/obj/item/weapon/storage/pill_bottle/carbon, + prob(3);/obj/item/bodybag/cryobag, + prob(5);/obj/item/weapon/reagent_containers/syringe/antitoxin, + prob(3);/obj/item/weapon/reagent_containers/syringe/antiviral, + prob(5);/obj/item/weapon/reagent_containers/syringe/inaprovaline, + prob(1);/obj/item/weapon/reagent_containers/hypospray, + prob(1);/obj/item/weapon/storage/box/freezer, + prob(2);/obj/item/stack/nanopaste) + +/obj/random/medical/pillbottle + name = "Random Pill Bottle" + desc = "This is a random pill bottle." + icon = 'icons/obj/chemical.dmi' + icon_state = "pill_canister" + +/obj/random/medical/pillbottle/item_to_spawn() + return pick(prob(1);/obj/item/weapon/storage/pill_bottle/spaceacillin, + prob(1);/obj/item/weapon/storage/pill_bottle/dermaline, + prob(1);/obj/item/weapon/storage/pill_bottle/dexalin_plus, + prob(1);/obj/item/weapon/storage/pill_bottle/bicaridine, + prob(1);/obj/item/weapon/storage/pill_bottle/iron) + +/obj/random/medical/lite + name = "Random Medicine" + desc = "This is a random simple medical item." + icon = 'icons/obj/items.dmi' + icon_state = "brutepack" + spawn_nothing_percentage = 25 + +/obj/random/medical/lite/item_to_spawn() + return pick(prob(4);/obj/item/stack/medical/bruise_pack, + prob(4);/obj/item/stack/medical/ointment, + prob(2);/obj/item/stack/medical/advanced/bruise_pack, + prob(2);/obj/item/stack/medical/advanced/ointment, + prob(1);/obj/item/stack/medical/splint, + prob(4);/obj/item/device/healthanalyzer, + prob(1);/obj/item/bodybag, + prob(3);/obj/item/weapon/reagent_containers/hypospray/autoinjector, + prob(2);/obj/item/weapon/storage/pill_bottle/kelotane, + prob(2);/obj/item/weapon/storage/pill_bottle/antitox) + +/obj/random/firstaid + name = "Random First Aid Kit" + desc = "This is a random first aid kit." + icon = 'icons/obj/storage.dmi' + icon_state = "firstaid" + +/obj/random/firstaid/item_to_spawn() + return pick(prob(10);/obj/item/weapon/storage/firstaid/regular, + prob(8);/obj/item/weapon/storage/firstaid/toxin, + prob(8);/obj/item/weapon/storage/firstaid/o2, + prob(6);/obj/item/weapon/storage/firstaid/adv, + prob(8);/obj/item/weapon/storage/firstaid/fire, + prob(1);/obj/item/weapon/storage/firstaid/combat) + +/obj/random/contraband + name = "Random Illegal Item" + desc = "Hot Stuff." + icon = 'icons/obj/items.dmi' + icon_state = "purplecomb" + spawn_nothing_percentage = 50 +/obj/random/contraband/item_to_spawn() + return pick(prob(6);/obj/item/weapon/storage/pill_bottle/tramadol, + prob(8);/obj/item/weapon/haircomb, + prob(4);/obj/item/weapon/storage/pill_bottle/happy, + prob(4);/obj/item/weapon/storage/pill_bottle/zoom, + prob(10);/obj/item/weapon/contraband/poster, + prob(4);/obj/item/weapon/material/butterfly, + prob(6);/obj/item/weapon/material/butterflyblade, + prob(6);/obj/item/weapon/material/butterflyhandle, + prob(6);/obj/item/weapon/material/wirerod, + prob(2);/obj/item/weapon/material/butterfly/switchblade, + prob(2);/obj/item/clothing/gloves/knuckledusters, + prob(1);/obj/item/weapon/material/knife/tacknife, + prob(1);/obj/item/clothing/suit/storage/vest/heavy/merc, + prob(1);/obj/item/weapon/beartrap, + prob(1);/obj/item/weapon/handcuffs, + prob(1);/obj/item/weapon/handcuffs/legcuffs, + prob(2);/obj/item/weapon/reagent_containers/syringe/drugs, + prob(1);/obj/item/weapon/reagent_containers/syringe/steroid) + +/obj/random/cash + name = "random currency" + desc = "LOADSAMONEY!" + icon = 'icons/obj/items.dmi' + icon_state = "spacecash1" + +/obj/random/cash/item_to_spawn() + return pick(prob(320);/obj/random/maintenance/clean, + prob(12);/obj/item/weapon/spacecash/c1, + prob(8);/obj/item/weapon/spacecash/c10, + prob(4);/obj/item/weapon/spacecash/c20, + prob(1);/obj/item/weapon/spacecash/c50, + prob(1);/obj/item/weapon/spacecash/c100) + +/obj/random/soap + name = "Random Soap" + desc = "This is a random bar of soap." + icon = 'icons/obj/items.dmi' + icon_state = "soap" + +/obj/random/soap/item_to_spawn() + return pick(prob(3);/obj/item/weapon/soap, + prob(2);/obj/item/weapon/soap/nanotrasen, + prob(2);/obj/item/weapon/soap/deluxe, + prob(1);/obj/item/weapon/soap/syndie) + + +/obj/random/drinkbottle + name = "random drink" + desc = "This is a random drink." + icon = 'icons/obj/drinks.dmi' + icon_state = "whiskeybottle" + +/obj/random/drinkbottle/item_to_spawn() + return pick(/obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, + /obj/item/weapon/reagent_containers/food/drinks/bottle/gin, + /obj/item/weapon/reagent_containers/food/drinks/bottle/specialwhiskey, + /obj/item/weapon/reagent_containers/food/drinks/bottle/vodka, + /obj/item/weapon/reagent_containers/food/drinks/bottle/tequilla, + /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe, + /obj/item/weapon/reagent_containers/food/drinks/bottle/wine, + /obj/item/weapon/reagent_containers/food/drinks/bottle/cognac, + /obj/item/weapon/reagent_containers/food/drinks/bottle/rum, + /obj/item/weapon/reagent_containers/food/drinks/bottle/patron) + +/obj/random/material //Random materials for building stuff + name = "random material" + desc = "This is a random material." + icon = 'icons/obj/items.dmi' + icon_state = "sheet-metal" + +/obj/random/material/item_to_spawn() + return pick(/obj/item/stack/material/steel{amount = 10}, + /obj/item/stack/material/glass{amount = 10}, + /obj/item/stack/material/glass/reinforced{amount = 10}, + /obj/item/stack/material/plastic{amount = 10}, + /obj/item/stack/material/wood{amount = 10}, + /obj/item/stack/material/cardboard{amount = 10}, + /obj/item/stack/rods{amount = 10}, + /obj/item/stack/material/plasteel{amount = 10}) + +/obj/random/tank + name = "random tank" + desc = "This is a tank." + icon = 'icons/obj/tank.dmi' + icon_state = "canister" + +/obj/random/tank/item_to_spawn() + return pick(prob(5);/obj/item/weapon/tank/oxygen, + prob(4);/obj/item/weapon/tank/oxygen/yellow, + prob(4);/obj/item/weapon/tank/oxygen/red, + prob(3);/obj/item/weapon/tank/air, + prob(4);/obj/item/weapon/tank/emergency/oxygen, + prob(3);/obj/item/weapon/tank/emergency/oxygen/engi, + prob(2);/obj/item/weapon/tank/emergency/oxygen/double, + prob(1);/obj/item/device/suit_cooling_unit) + +/obj/random/cigarettes + name = "random cigarettes" + desc = "This is a cigarette." + icon = 'icons/obj/cigarettes.dmi' + icon_state = "cigpacket" + +/obj/random/cigarettes/item_to_spawn() + return pick(prob(5);/obj/item/weapon/storage/fancy/cigarettes, + prob(4);/obj/item/weapon/storage/fancy/cigarettes/dromedaryco, + prob(3);/obj/item/weapon/storage/fancy/cigarettes/killthroat, + prob(3);/obj/item/weapon/storage/fancy/cigarettes/luckystars, + prob(3);/obj/item/weapon/storage/fancy/cigarettes/jerichos, + prob(3);/obj/item/weapon/storage/fancy/cigarettes/menthols, + prob(3);/obj/item/weapon/storage/fancy/cigarettes/carcinomas, + prob(3);/obj/item/weapon/storage/fancy/cigarettes/professionals, + prob(1);/obj/item/weapon/storage/fancy/cigar, + prob(1);/obj/item/clothing/mask/smokable/cigarette/cigar, + prob(1);/obj/item/clothing/mask/smokable/cigarette/cigar/cohiba, + prob(1);/obj/item/clothing/mask/smokable/cigarette/cigar/havana) + +/obj/random/coin + name = "random coin" + desc = "This is a coin spawn." + icon = 'icons/misc/mark.dmi' + icon_state = "rup" + +/obj/random/coin/item_to_spawn() + return pick(prob(5);/obj/item/weapon/coin/silver, + prob(3);/obj/item/weapon/coin/iron, + prob(4);/obj/item/weapon/coin/gold, + prob(3);/obj/item/weapon/coin/phoron, + prob(1);/obj/item/weapon/coin/uranium, + prob(2);/obj/item/weapon/coin/platinum, + prob(1);/obj/item/weapon/coin/diamond) + +/obj/random/action_figure + name = "random action figure" + desc = "This is a random action figure." + icon = 'icons/obj/toy.dmi' + icon_state = "assistant" + +/obj/random/action_figure/item_to_spawn() + return pick(/obj/item/toy/figure/cmo, + /obj/item/toy/figure/assistant, + /obj/item/toy/figure/atmos, + /obj/item/toy/figure/bartender, + /obj/item/toy/figure/borg, + /obj/item/toy/figure/gardener, + /obj/item/toy/figure/captain, + /obj/item/toy/figure/cargotech, + /obj/item/toy/figure/ce, + /obj/item/toy/figure/chaplain, + /obj/item/toy/figure/chef, + /obj/item/toy/figure/chemist, + /obj/item/toy/figure/clown, + /obj/item/toy/figure/corgi, + /obj/item/toy/figure/detective, + /obj/item/toy/figure/dsquad, + /obj/item/toy/figure/engineer, + /obj/item/toy/figure/geneticist, + /obj/item/toy/figure/hop, + /obj/item/toy/figure/hos, + /obj/item/toy/figure/qm, + /obj/item/toy/figure/janitor, + /obj/item/toy/figure/agent, + /obj/item/toy/figure/librarian, + /obj/item/toy/figure/md, + /obj/item/toy/figure/mime, + /obj/item/toy/figure/miner, + /obj/item/toy/figure/ninja, + /obj/item/toy/figure/wizard, + /obj/item/toy/figure/rd, + /obj/item/toy/figure/roboticist, + /obj/item/toy/figure/scientist, + /obj/item/toy/figure/syndie, + /obj/item/toy/figure/secofficer, + /obj/item/toy/figure/warden, + /obj/item/toy/figure/psychologist, + /obj/item/toy/figure/paramedic, + /obj/item/toy/figure/ert) + +/obj/random/plushie + name = "random plushie" + desc = "This is a random plushie." + icon = 'icons/obj/toy.dmi' + icon_state = "nymphplushie" + +/obj/random/plushie/item_to_spawn() + return pick(/obj/item/toy/plushie/nymph, + /obj/item/toy/plushie/mouse, + /obj/item/toy/plushie/kitten, + /obj/item/toy/plushie/lizard, + /obj/item/toy/plushie/black_cat, + /obj/item/toy/plushie/black_fox, + /obj/item/toy/plushie/blue_fox, + /obj/random/carp_plushie, + /obj/item/toy/plushie/coffee_fox, + /obj/item/toy/plushie/corgi, + /obj/item/toy/plushie/crimson_fox, + /obj/item/toy/plushie/deer, + /obj/item/toy/plushie/girly_corgi, + /obj/item/toy/plushie/grey_cat, + /obj/item/toy/plushie/marble_fox, + /obj/item/toy/plushie/octopus, + /obj/item/toy/plushie/orange_cat, + /obj/item/toy/plushie/orange_fox, + /obj/item/toy/plushie/pink_fox, + /obj/item/toy/plushie/purple_fox, + /obj/item/toy/plushie/red_fox, + /obj/item/toy/plushie/robo_corgi, + /obj/item/toy/plushie/siamese_cat, + /obj/item/toy/plushie/spider, + /obj/item/toy/plushie/tabby_cat, + /obj/item/toy/plushie/tuxedo_cat, + /obj/item/toy/plushie/white_cat) + +/obj/random/plushielarge + name = "random large plushie" + desc = "This is a randomn large plushie." + icon = 'icons/obj/toy.dmi' + icon_state = "droneplushie" + +/obj/random/plushielarge/item_to_spawn() + return pick(/obj/structure/plushie/ian, + /obj/structure/plushie/drone, + /obj/structure/plushie/carp, + /obj/structure/plushie/beepsky) + +/obj/random/toy + name = "random toy" + desc = "This is a random toy." + icon = 'icons/obj/toy.dmi' + icon_state = "ship" + +/obj/random/toy/item_to_spawn() + return pick(/obj/item/toy/bosunwhistle, + /obj/item/toy/plushie/therapy/red, + /obj/item/toy/plushie/therapy/purple, + /obj/item/toy/plushie/therapy/blue, + /obj/item/toy/plushie/therapy/yellow, + /obj/item/toy/plushie/therapy/orange, + /obj/item/toy/plushie/therapy/green, + /obj/item/toy/cultsword, + /obj/item/toy/katana, + /obj/item/toy/snappop, + /obj/item/toy/sword, + /obj/item/toy/balloon, + /obj/item/toy/crossbow, + /obj/item/toy/blink, + /obj/item/toy/waterflower, + /obj/item/toy/eight_ball, + /obj/item/toy/eight_ball/conch, + /obj/item/toy/prize/ripley, + /obj/item/toy/prize/fireripley, + /obj/item/toy/prize/deathripley, + /obj/item/toy/prize/gygax, + /obj/item/toy/prize/durand, + /obj/item/toy/prize/honk, + /obj/item/toy/prize/marauder, + /obj/item/toy/prize/seraph, + /obj/item/toy/prize/mauler, + /obj/item/toy/prize/odysseus, + /obj/item/toy/prize/phazon) \ No newline at end of file diff --git a/code/game/objects/random/mob.dm b/code/game/objects/random/mob.dm new file mode 100644 index 0000000000..2043ef0240 --- /dev/null +++ b/code/game/objects/random/mob.dm @@ -0,0 +1,159 @@ +/* + * Random Mobs + */ + +/obj/random/mob + name = "Random Animal" + desc = "This is a random animal." + icon = 'icons/mob/animal.dmi' + icon_state = "chicken_white" + + var/overwrite_hostility = 0 + + var/mob_faction = null + var/mob_returns_home = 0 + var/mob_wander = 1 + var/mob_wander_distance = 3 + var/mob_hostile = 0 + var/mob_retaliate = 0 + +/obj/random/mob/item_to_spawn() + return pick(prob(10);/mob/living/simple_animal/lizard, + prob(6);/mob/living/simple_animal/retaliate/diyaab, + prob(10);/mob/living/simple_animal/cat/fluff, + prob(6);/mob/living/simple_animal/cat/kitten, + prob(10);/mob/living/simple_animal/corgi, + prob(6);/mob/living/simple_animal/corgi/puppy, + prob(10);/mob/living/simple_animal/crab, + prob(10);/mob/living/simple_animal/chicken, + prob(6);/mob/living/simple_animal/chick, + prob(10);/mob/living/simple_animal/cow, + prob(6);/mob/living/simple_animal/retaliate/goat, + prob(10);/mob/living/simple_animal/penguin, + prob(10);/mob/living/simple_animal/mouse, + prob(10);/mob/living/simple_animal/yithian, + prob(10);/mob/living/simple_animal/tindalos, + prob(10);/mob/living/simple_animal/corgi/tamaskan, + prob(3);/mob/living/simple_animal/parrot, + prob(1);/mob/living/simple_animal/giant_crab) + +/obj/random/mob/spawn_item() //These should only ever have simple mobs. + var/build_path = item_to_spawn() + + var/mob/living/simple_animal/M = new build_path(src.loc) + M.ai_inactive = 1 //Don't fight eachother while we're still setting up! + if(mob_faction) + M.faction = mob_faction + M.returns_home = mob_returns_home + M.wander = mob_wander + M.wander_distance = mob_wander_distance + if(overwrite_hostility) + M.hostile = mob_hostile + M.retaliate = mob_retaliate + M.ai_inactive = 0 //Now you can kill eachother if your faction didn't override. + + if(pixel_x || pixel_y) + M.pixel_x = pixel_x + M.pixel_y = pixel_y + +/obj/random/mob/sif + name = "Random Sif Animal" + desc = "This is a random cold weather animal." + icon_state = "penguin" + + mob_returns_home = 1 + mob_wander_distance = 10 + +/obj/random/mob/sif/item_to_spawn() + return pick(prob(30);/mob/living/simple_animal/retaliate/diyaab, + prob(15);/mob/living/simple_animal/crab, + prob(15);/mob/living/simple_animal/penguin, + prob(15);/mob/living/simple_animal/mouse, + prob(15);/mob/living/simple_animal/corgi/tamaskan, + prob(2);/mob/living/simple_animal/hostile/giant_spider/frost, + prob(1);/mob/living/simple_animal/hostile/goose, + prob(20);/mob/living/simple_animal/giant_crab) + +/obj/random/mob/sif/hostile + name = "Random Hostile Sif Animal" + desc = "This is a random hostile cold weather animal." + icon_state = "frost" + +/obj/random/mob/sif/hostile/item_to_spawn() + return pick(prob(22);/mob/living/simple_animal/hostile/savik, + prob(33);/mob/living/simple_animal/hostile/giant_spider/frost, + prob(45);/mob/living/simple_animal/hostile/shantak) + +/obj/random/mob/spider + name = "Random Spider" //Spiders should patrol where they spawn. + desc = "This is a random boring spider." + icon_state = "guard" + + mob_returns_home = 1 + mob_wander_distance = 4 + +/obj/random/mob/spider/item_to_spawn() + return pick(prob(22);/mob/living/simple_animal/hostile/giant_spider/nurse, + prob(33);/mob/living/simple_animal/hostile/giant_spider/hunter, + prob(45);/mob/living/simple_animal/hostile/giant_spider) + +/obj/random/mob/spider/mutant + name = "Random Mutant Spider" + desc = "This is a random mutated spider." + icon_state = "phoron" + +/obj/random/mob/spider/mutant/item_to_spawn() + return pick(prob(5);/obj/random/mob/spider, + prob(10);/mob/living/simple_animal/hostile/giant_spider/webslinger, + prob(10);/mob/living/simple_animal/hostile/giant_spider/carrier, + prob(33);/mob/living/simple_animal/hostile/giant_spider/lurker, + prob(33);/mob/living/simple_animal/hostile/giant_spider/tunneler, + prob(40);/mob/living/simple_animal/hostile/giant_spider/pepper, + prob(20);/mob/living/simple_animal/hostile/giant_spider/thermic, + prob(40);/mob/living/simple_animal/hostile/giant_spider/electric, + prob(1);/mob/living/simple_animal/hostile/giant_spider/phorogenic, + prob(40);/mob/living/simple_animal/hostile/giant_spider/frost) + +/obj/random/mob/robotic + name = "Random Robot Mob" + desc = "This is a random robot." + icon_state = "drone_dead" + + overwrite_hostility = 1 + + mob_faction = "malf_drone" + mob_returns_home = 1 + mob_wander = 1 + mob_wander_distance = 5 + mob_hostile = 1 + mob_retaliate = 1 + +/obj/random/mob/robotic/item_to_spawn() //Hivebots have a total number of 'lots' equal to the lesser drone, at 60. + return pick(prob(60);/mob/living/simple_animal/hostile/malf_drone/lesser, + prob(50);/mob/living/simple_animal/hostile/malf_drone, + prob(15);/mob/living/simple_animal/hostile/mecha/malf_drone, + prob(10);/mob/living/simple_animal/hostile/hivebot, + prob(15);/mob/living/simple_animal/hostile/hivebot/swarm, + prob(10);/mob/living/simple_animal/hostile/hivebot/range, + prob(5);/mob/living/simple_animal/hostile/hivebot/range/rapid, + prob(5);/mob/living/simple_animal/hostile/hivebot/range/ion, + prob(5);/mob/living/simple_animal/hostile/hivebot/range/laser, + prob(5);/mob/living/simple_animal/hostile/hivebot/range/strong, + prob(5);/mob/living/simple_animal/hostile/hivebot/range/guard) + +/obj/random/mob/robotic/hivebot + name = "Random Hivebot" + desc = "This is a random hivebot." + icon_state = "drone3" + + mob_faction = "hivebot" + +/obj/random/mob/robotic/hivebot/item_to_spawn() + return pick(prob(10);/mob/living/simple_animal/hostile/hivebot, + prob(15);/mob/living/simple_animal/hostile/hivebot/swarm, + prob(10);/mob/living/simple_animal/hostile/hivebot/range, + prob(5);/mob/living/simple_animal/hostile/hivebot/range/rapid, + prob(5);/mob/living/simple_animal/hostile/hivebot/range/ion, + prob(5);/mob/living/simple_animal/hostile/hivebot/range/laser, + prob(5);/mob/living/simple_animal/hostile/hivebot/range/strong, + prob(5);/mob/living/simple_animal/hostile/hivebot/range/guard) diff --git a/code/game/objects/random/random.dm b/code/game/objects/random/random.dm deleted file mode 100644 index 05ba702853..0000000000 --- a/code/game/objects/random/random.dm +++ /dev/null @@ -1,1140 +0,0 @@ -/obj/random - name = "random object" - desc = "This item type is used to spawn random objects at round-start" - icon = 'icons/misc/mark.dmi' - icon_state = "rup" - var/spawn_nothing_percentage = 0 // this variable determines the likelyhood that this random object will not spawn anything - - -// creates a new object and deletes itself -/obj/random/New() - ..() - if (!prob(spawn_nothing_percentage)) - spawn_item() - qdel(src) - - -// this function should return a specific item to spawn -/obj/random/proc/item_to_spawn() - return 0 - - -// creates the random item -/obj/random/proc/spawn_item() - var/build_path = item_to_spawn() - - var/atom/A = new build_path(src.loc) - if(pixel_x || pixel_y) - A.pixel_x = pixel_x - A.pixel_y = pixel_y - - -/obj/random/single - name = "randomly spawned object" - desc = "This item type is used to randomly spawn a given object at round-start" - icon_state = "x3" - var/spawn_object = null - -/obj/random/single/item_to_spawn() - return ispath(spawn_object) ? spawn_object : text2path(spawn_object) - - -/obj/random/tool - name = "random tool" - desc = "This is a random tool" - icon = 'icons/obj/items.dmi' - icon_state = "welder" - -/obj/random/tool/item_to_spawn() - return pick(/obj/item/weapon/screwdriver, - /obj/item/weapon/wirecutters, - /obj/item/weapon/weldingtool, - /obj/item/weapon/weldingtool/largetank, - /obj/item/weapon/crowbar, - /obj/item/weapon/wrench, - /obj/item/device/flashlight, - /obj/item/device/multitool) - -/obj/random/technology_scanner - name = "random scanner" - desc = "This is a random technology scanner." - icon = 'icons/obj/device.dmi' - icon_state = "atmos" - -/obj/random/technology_scanner/item_to_spawn() - return pick(prob(5);/obj/item/device/t_scanner, - prob(2);/obj/item/device/radio, - prob(5);/obj/item/device/analyzer) - -/obj/random/powercell - name = "random powercell" - desc = "This is a random powercell." - icon = 'icons/obj/power.dmi' - icon_state = "cell" - -/obj/random/powercell/item_to_spawn() - return pick(prob(40);/obj/item/weapon/cell, - prob(25);/obj/item/weapon/cell/device, - prob(25);/obj/item/weapon/cell/high, - prob(9);/obj/item/weapon/cell/super, - prob(1);/obj/item/weapon/cell/hyper) - - -/obj/random/bomb_supply - name = "bomb supply" - desc = "This is a random bomb supply." - icon = 'icons/obj/assemblies/new_assemblies.dmi' - icon_state = "signaller" - -/obj/random/bomb_supply/item_to_spawn() - return pick(/obj/item/device/assembly/igniter, - /obj/item/device/assembly/prox_sensor, - /obj/item/device/assembly/signaler, - /obj/item/device/assembly/timer, - /obj/item/device/multitool) - - -/obj/random/toolbox - name = "random toolbox" - desc = "This is a random toolbox." - icon = 'icons/obj/storage.dmi' - icon_state = "red" - -/obj/random/toolbox/item_to_spawn() - return pick(prob(6);/obj/item/weapon/storage/toolbox/mechanical, - prob(6);/obj/item/weapon/storage/toolbox/electrical, - prob(2);/obj/item/weapon/storage/toolbox/emergency, - prob(1);/obj/item/weapon/storage/toolbox/syndicate) - - -/obj/random/tech_supply - name = "random tech supply" - desc = "This is a random piece of technology supplies." - icon = 'icons/obj/power.dmi' - icon_state = "cell" - spawn_nothing_percentage = 25 - -/obj/random/tech_supply/item_to_spawn() - return pick(prob(3);/obj/random/powercell, - prob(2);/obj/random/technology_scanner, - prob(1);/obj/item/weapon/packageWrap, - prob(2);/obj/random/bomb_supply, - prob(1);/obj/item/weapon/extinguisher, - prob(1);/obj/item/clothing/gloves/fyellow, - prob(3);/obj/item/stack/cable_coil/random, - prob(2);/obj/random/toolbox, - prob(2);/obj/item/weapon/storage/belt/utility, - prob(1);/obj/item/weapon/storage/belt/utility/full, - prob(5);/obj/random/tool, - prob(2);/obj/item/weapon/tape_roll, - prob(2);/obj/item/taperoll/engineering, - prob(1);/obj/item/taperoll/atmos, - prob(1);/obj/item/device/flashlight/maglight) - -/obj/random/medical - name = "Random Medicine" - desc = "This is a random medical item." - icon = 'icons/obj/items.dmi' - icon_state = "traumakit" - -/obj/random/medical/item_to_spawn() - return pick(prob(21);/obj/random/medical/lite, - prob(5);/obj/random/medical/pillbottle, - prob(1);/obj/item/weapon/storage/pill_bottle/tramadol, - prob(1);/obj/item/weapon/storage/pill_bottle/antitox, - prob(1);/obj/item/weapon/storage/pill_bottle/carbon, - prob(3);/obj/item/bodybag/cryobag, - prob(5);/obj/item/weapon/reagent_containers/syringe/antitoxin, - prob(3);/obj/item/weapon/reagent_containers/syringe/antiviral, - prob(5);/obj/item/weapon/reagent_containers/syringe/inaprovaline, - prob(1);/obj/item/weapon/reagent_containers/hypospray, - prob(1);/obj/item/weapon/storage/box/freezer, - prob(2);/obj/item/stack/nanopaste) - -/obj/random/medical/pillbottle - name = "Random Pill Bottle" - desc = "This is a random pill bottle." - icon = 'icons/obj/chemical.dmi' - icon_state = "pill_canister" - -/obj/random/medical/pillbottle/item_to_spawn() - return pick(prob(1);/obj/item/weapon/storage/pill_bottle/spaceacillin, - prob(1);/obj/item/weapon/storage/pill_bottle/dermaline, - prob(1);/obj/item/weapon/storage/pill_bottle/dexalin_plus, - prob(1);/obj/item/weapon/storage/pill_bottle/bicaridine, - prob(1);/obj/item/weapon/storage/pill_bottle/iron) - -/obj/random/medical/lite - name = "Random Medicine" - desc = "This is a random simple medical item." - icon = 'icons/obj/items.dmi' - icon_state = "brutepack" - spawn_nothing_percentage = 25 - -/obj/random/medical/lite/item_to_spawn() - return pick(prob(4);/obj/item/stack/medical/bruise_pack, - prob(4);/obj/item/stack/medical/ointment, - prob(2);/obj/item/stack/medical/advanced/bruise_pack, - prob(2);/obj/item/stack/medical/advanced/ointment, - prob(1);/obj/item/stack/medical/splint, - prob(4);/obj/item/device/healthanalyzer, - prob(1);/obj/item/bodybag, - prob(3);/obj/item/weapon/reagent_containers/hypospray/autoinjector, - prob(2);/obj/item/weapon/storage/pill_bottle/kelotane, - prob(2);/obj/item/weapon/storage/pill_bottle/antitox) - -/obj/random/firstaid - name = "Random First Aid Kit" - desc = "This is a random first aid kit." - icon = 'icons/obj/storage.dmi' - icon_state = "firstaid" - -/obj/random/firstaid/item_to_spawn() - return pick(prob(4);/obj/item/weapon/storage/firstaid/regular, - prob(3);/obj/item/weapon/storage/firstaid/toxin, - prob(3);/obj/item/weapon/storage/firstaid/o2, - prob(2);/obj/item/weapon/storage/firstaid/adv, - prob(3);/obj/item/weapon/storage/firstaid/fire, - prob(1);/obj/item/weapon/storage/firstaid/combat) - -/obj/random/contraband - name = "Random Illegal Item" - desc = "Hot Stuff." - icon = 'icons/obj/items.dmi' - icon_state = "purplecomb" - spawn_nothing_percentage = 50 -/obj/random/contraband/item_to_spawn() - return pick(prob(6);/obj/item/weapon/storage/pill_bottle/tramadol, - prob(8);/obj/item/weapon/haircomb, - prob(4);/obj/item/weapon/storage/pill_bottle/happy, - prob(4);/obj/item/weapon/storage/pill_bottle/zoom, - prob(10);/obj/item/weapon/contraband/poster, - prob(4);/obj/item/weapon/material/butterfly, - prob(6);/obj/item/weapon/material/butterflyblade, - prob(6);/obj/item/weapon/material/butterflyhandle, - prob(6);/obj/item/weapon/material/wirerod, - prob(2);/obj/item/weapon/material/butterfly/switchblade, - prob(2);/obj/item/clothing/gloves/knuckledusters, - prob(1);/obj/item/weapon/material/knife/tacknife, - prob(1);/obj/item/clothing/suit/storage/vest/heavy/merc, - prob(1);/obj/item/weapon/beartrap, - prob(1);/obj/item/weapon/handcuffs, - prob(1);/obj/item/weapon/handcuffs/legcuffs, - prob(2);/obj/item/weapon/reagent_containers/syringe/drugs, - prob(1);/obj/item/weapon/reagent_containers/syringe/steroid) - -/obj/random/soap - name = "Random Soap" - desc = "This is a random bar of soap." - icon = 'icons/obj/items.dmi' - icon_state = "soap" - -/obj/random/soap/item_to_spawn() - return pick(prob(3);/obj/item/weapon/soap, - prob(2);/obj/item/weapon/soap/nanotrasen, - prob(2);/obj/item/weapon/soap/deluxe, - prob(1);/obj/item/weapon/soap/syndie,) - - -/obj/random/drinkbottle - name = "random drink" - desc = "This is a random drink." - icon = 'icons/obj/drinks.dmi' - icon_state = "whiskeybottle" - -/obj/random/drinkbottle/item_to_spawn() - return pick(/obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, - /obj/item/weapon/reagent_containers/food/drinks/bottle/gin, - /obj/item/weapon/reagent_containers/food/drinks/bottle/specialwhiskey, - /obj/item/weapon/reagent_containers/food/drinks/bottle/vodka, - /obj/item/weapon/reagent_containers/food/drinks/bottle/tequilla, - /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe, - /obj/item/weapon/reagent_containers/food/drinks/bottle/wine, - /obj/item/weapon/reagent_containers/food/drinks/bottle/cognac, - /obj/item/weapon/reagent_containers/food/drinks/bottle/rum, - /obj/item/weapon/reagent_containers/food/drinks/bottle/patron) - -/obj/random/energy - name = "Random Energy Weapon" - desc = "This is a random security weapon." - icon = 'icons/obj/gun.dmi' - icon_state = "energykill100" - -/obj/random/energy/item_to_spawn() - return pick(prob(3);/obj/item/weapon/gun/energy/laser, - prob(4);/obj/item/weapon/gun/energy/gun, - prob(3);/obj/item/weapon/gun/energy/gun/burst, - prob(1);/obj/item/weapon/gun/energy/gun/nuclear, - prob(2);/obj/item/weapon/gun/energy/retro, - prob(2);/obj/item/weapon/gun/energy/lasercannon, - prob(3);/obj/item/weapon/gun/energy/xray, - prob(1);/obj/item/weapon/gun/energy/sniperrifle, - prob(1);/obj/item/weapon/gun/energy/plasmastun, - prob(2);/obj/item/weapon/gun/energy/ionrifle, - prob(2);/obj/item/weapon/gun/energy/ionrifle/pistol, - prob(3);/obj/item/weapon/gun/energy/toxgun, - prob(4);/obj/item/weapon/gun/energy/taser, - prob(2);/obj/item/weapon/gun/energy/crossbow/largecrossbow, - prob(4);/obj/item/weapon/gun/energy/stunrevolver) - -/obj/random/energy/sec - name = "Random Security Energy Weapon" - desc = "This is a random security weapon." - icon = 'icons/obj/gun.dmi' - icon_state = "energykill100" - -/obj/random/energy/sec/item_to_spawn() - return pick(prob(2);/obj/item/weapon/gun/energy/laser, - prob(2);/obj/item/weapon/gun/energy/gun) - -/obj/random/projectile - name = "Random Projectile Weapon" - desc = "This is a random projectile weapon." - icon = 'icons/obj/gun.dmi' - icon_state = "revolver" - -/obj/random/projectile/item_to_spawn() - return pick(prob(3);/obj/item/weapon/gun/projectile/automatic/wt550, - prob(3);/obj/item/weapon/gun/projectile/automatic/mini_uzi, - prob(3);/obj/item/weapon/gun/projectile/automatic/tommygun, - prob(2);/obj/item/weapon/gun/projectile/automatic/c20r, - prob(2);/obj/item/weapon/gun/projectile/automatic/sts35, - prob(2);/obj/item/weapon/gun/projectile/automatic/z8, - prob(4);/obj/item/weapon/gun/projectile/colt, - prob(2);/obj/item/weapon/gun/projectile/deagle, - prob(1);/obj/item/weapon/gun/projectile/deagle/camo, - prob(1);/obj/item/weapon/gun/projectile/deagle/gold, - prob(3);/obj/item/weapon/gun/projectile/derringer, - prob(1);/obj/item/weapon/gun/projectile/heavysniper, - prob(4);/obj/item/weapon/gun/projectile/luger, - prob(3);/obj/item/weapon/gun/projectile/luger/brown, - prob(4);/obj/item/weapon/gun/projectile/sec, - prob(3);/obj/item/weapon/gun/projectile/sec/wood, - prob(4);/obj/item/weapon/gun/projectile/p92x, - prob(3);/obj/item/weapon/gun/projectile/p92x/brown, - prob(4);/obj/item/weapon/gun/projectile/pistol, - prob(5);/obj/item/weapon/gun/projectile/pirate, - prob(2);/obj/item/weapon/gun/projectile/revolver, - prob(4);/obj/item/weapon/gun/projectile/revolver/deckard, - prob(4);/obj/item/weapon/gun/projectile/revolver/detective, - prob(2);/obj/item/weapon/gun/projectile/revolver/judge, - prob(3);/obj/item/weapon/gun/projectile/revolver/lemat, - prob(2);/obj/item/weapon/gun/projectile/revolver/mateba, - prob(4);/obj/item/weapon/gun/projectile/shotgun/doublebarrel, - prob(3);/obj/item/weapon/gun/projectile/shotgun/doublebarrel/sawn, - prob(3);/obj/item/weapon/gun/projectile/shotgun/pump, - prob(2);/obj/item/weapon/gun/projectile/shotgun/pump/combat, - prob(4);/obj/item/weapon/gun/projectile/shotgun/pump/rifle, - prob(3);/obj/item/weapon/gun/projectile/shotgun/pump/rifle/lever, - prob(2);/obj/item/weapon/gun/projectile/silenced) - -/obj/random/projectile/sec - name = "Random Security Projectile Weapon" - desc = "This is a random security weapon." - icon = 'icons/obj/gun.dmi' - icon_state = "revolver" - -/obj/random/projectile/sec/item_to_spawn() - return pick(prob(3);/obj/item/weapon/gun/projectile/shotgun/pump, - prob(2);/obj/item/weapon/gun/projectile/automatic/wt550, - prob(1);/obj/item/weapon/gun/projectile/shotgun/pump/combat) - -/obj/random/handgun - name = "Random Handgun" - desc = "This is a random sidearm." - icon = 'icons/obj/gun.dmi' - icon_state = "secgundark" - -/obj/random/handgun/item_to_spawn() - return pick(prob(4);/obj/item/weapon/gun/projectile/sec, - prob(4);/obj/item/weapon/gun/projectile/p92x, - prob(3);/obj/item/weapon/gun/projectile/sec/wood, - prob(3);/obj/item/weapon/gun/projectile/p92x/brown, - prob(3);/obj/item/weapon/gun/projectile/colt, - prob(2);/obj/item/weapon/gun/projectile/luger, - prob(2);/obj/item/weapon/gun/energy/gun, - prob(2);/obj/item/weapon/gun/projectile/pistol, - prob(1);/obj/item/weapon/gun/energy/retro, - prob(1);/obj/item/weapon/gun/projectile/luger/brown) - -/obj/random/handgun/sec - name = "Random Security Handgun" - desc = "This is a random security sidearm." - icon = 'icons/obj/gun.dmi' - icon_state = "secgundark" - -/obj/random/handgun/sec/item_to_spawn() - return pick(prob(3);/obj/item/weapon/gun/projectile/sec, - prob(1);/obj/item/weapon/gun/projectile/sec/wood) - -/obj/random/ammo - name = "Random Ammunition" - desc = "This is random security ammunition." - icon = 'icons/obj/ammo.dmi' - icon_state = "45-10" - -/obj/random/ammo/item_to_spawn() - return pick(prob(6);/obj/item/weapon/storage/box/beanbags, - prob(2);/obj/item/weapon/storage/box/shotgunammo, - prob(4);/obj/item/weapon/storage/box/shotgunshells, - prob(1);/obj/item/weapon/storage/box/stunshells, - prob(2);/obj/item/ammo_magazine/m45, - prob(4);/obj/item/ammo_magazine/m45/rubber, - prob(4);/obj/item/ammo_magazine/m45/flash, - prob(2);/obj/item/ammo_magazine/m9mmt, - prob(6);/obj/item/ammo_magazine/m9mmt/rubber) - - -/obj/random/action_figure - name = "random action figure" - desc = "This is a random action figure." - icon = 'icons/obj/toy.dmi' - icon_state = "assistant" - -/obj/random/action_figure/item_to_spawn() - return pick(/obj/item/toy/figure/cmo, - /obj/item/toy/figure/assistant, - /obj/item/toy/figure/atmos, - /obj/item/toy/figure/bartender, - /obj/item/toy/figure/borg, - /obj/item/toy/figure/gardener, - /obj/item/toy/figure/captain, - /obj/item/toy/figure/cargotech, - /obj/item/toy/figure/ce, - /obj/item/toy/figure/chaplain, - /obj/item/toy/figure/chef, - /obj/item/toy/figure/chemist, - /obj/item/toy/figure/clown, - /obj/item/toy/figure/corgi, - /obj/item/toy/figure/detective, - /obj/item/toy/figure/dsquad, - /obj/item/toy/figure/engineer, - /obj/item/toy/figure/geneticist, - /obj/item/toy/figure/hop, - /obj/item/toy/figure/hos, - /obj/item/toy/figure/qm, - /obj/item/toy/figure/janitor, - /obj/item/toy/figure/agent, - /obj/item/toy/figure/librarian, - /obj/item/toy/figure/md, - /obj/item/toy/figure/mime, - /obj/item/toy/figure/miner, - /obj/item/toy/figure/ninja, - /obj/item/toy/figure/wizard, - /obj/item/toy/figure/rd, - /obj/item/toy/figure/roboticist, - /obj/item/toy/figure/scientist, - /obj/item/toy/figure/syndie, - /obj/item/toy/figure/secofficer, - /obj/item/toy/figure/warden, - /obj/item/toy/figure/psychologist, - /obj/item/toy/figure/paramedic, - /obj/item/toy/figure/ert) - -/obj/random/plushie - name = "random plushie" - desc = "This is a random plushie." - icon = 'icons/obj/toy.dmi' - icon_state = "nymphplushie" - -/obj/random/plushie/item_to_spawn() - return pick(/obj/structure/plushie/ian, - /obj/structure/plushie/drone, - /obj/structure/plushie/carp, - /obj/structure/plushie/beepsky, - /obj/item/toy/plushie/nymph, - /obj/item/toy/plushie/mouse, - /obj/item/toy/plushie/kitten, - /obj/item/toy/plushie/lizard) - -/obj/random/junk //Broken items, or stuff that could be picked up - name = "random junk" - desc = "This is some random junk." - icon = 'icons/obj/trash.dmi' - icon_state = "trashbag3" - -/obj/random/junk/item_to_spawn() - return get_random_junk_type() - -/obj/random/trash //Mostly remains and cleanable decals. Stuff a janitor could clean up - name = "random trash" - desc = "This is some random trash." - icon = 'icons/effects/effects.dmi' - icon_state = "greenglow" - -/obj/random/trash/item_to_spawn() - return pick(/obj/effect/decal/remains/lizard, - /obj/effect/decal/cleanable/blood/gibs/robot, - /obj/effect/decal/cleanable/blood/oil, - /obj/effect/decal/cleanable/blood/oil/streak, - /obj/effect/decal/cleanable/spiderling_remains, - /obj/effect/decal/remains/mouse, - /obj/effect/decal/cleanable/vomit, - /obj/effect/decal/cleanable/blood/splatter, - /obj/effect/decal/cleanable/ash, - /obj/effect/decal/cleanable/generic, - /obj/effect/decal/cleanable/flour, - /obj/effect/decal/cleanable/dirt, - /obj/effect/decal/remains/robot) - -/obj/random/obstruction //Large objects to block things off in maintenance - name = "random obstruction" - desc = "This is a random obstruction." - icon = 'icons/obj/cult.dmi' - icon_state = "cultgirder" - -/obj/random/obstruction/item_to_spawn() - return pick(/obj/structure/barricade, - /obj/structure/girder, - /obj/structure/girder/displaced, - /obj/structure/girder/reinforced, - /obj/structure/grille, - /obj/structure/grille/broken, - /obj/structure/foamedmetal, - /obj/structure/inflatable, - /obj/structure/inflatable/door) - -/obj/random/material //Random materials for building stuff - name = "random material" - desc = "This is a random material." - icon = 'icons/obj/items.dmi' - icon_state = "sheet-metal" - -/obj/random/material/item_to_spawn() - return pick(/obj/item/stack/material/steel{amount = 10}, - /obj/item/stack/material/glass{amount = 10}, - /obj/item/stack/material/glass/reinforced{amount = 10}, - /obj/item/stack/material/plastic{amount = 10}, - /obj/item/stack/material/wood{amount = 10}, - /obj/item/stack/material/cardboard{amount = 10}, - /obj/item/stack/rods{amount = 10}, - /obj/item/stack/material/plasteel{amount = 10}) - -/obj/random/toy - name = "random toy" - desc = "This is a random toy." - icon = 'icons/obj/toy.dmi' - icon_state = "ship" - -/obj/random/toy/item_to_spawn() - return pick(/obj/item/toy/bosunwhistle, - /obj/item/toy/plushie/therapy/red, - /obj/item/toy/plushie/therapy/purple, - /obj/item/toy/plushie/therapy/blue, - /obj/item/toy/plushie/therapy/yellow, - /obj/item/toy/plushie/therapy/orange, - /obj/item/toy/plushie/therapy/green, - /obj/item/toy/cultsword, - /obj/item/toy/katana, - /obj/item/toy/snappop, - /obj/item/toy/sword, - /obj/item/toy/balloon, - /obj/item/toy/crossbow, - /obj/item/toy/blink, - /obj/item/toy/waterflower, - /obj/item/toy/prize/ripley, - /obj/item/toy/prize/fireripley, - /obj/item/toy/prize/deathripley, - /obj/item/toy/prize/gygax, - /obj/item/toy/prize/durand, - /obj/item/toy/prize/honk, - /obj/item/toy/prize/marauder, - /obj/item/toy/prize/seraph, - /obj/item/toy/prize/mauler, - /obj/item/toy/prize/odysseus, - /obj/item/toy/prize/phazon) - -/obj/random/tank - name = "random tank" - desc = "This is a tank." - icon = 'icons/obj/tank.dmi' - icon_state = "canister" - -/obj/random/tank/item_to_spawn() - return pick(prob(5);/obj/item/weapon/tank/oxygen, - prob(4);/obj/item/weapon/tank/oxygen/yellow, - prob(4);/obj/item/weapon/tank/oxygen/red, - prob(3);/obj/item/weapon/tank/air, - prob(4);/obj/item/weapon/tank/emergency/oxygen, - prob(3);/obj/item/weapon/tank/emergency/oxygen/engi, - prob(2);/obj/item/weapon/tank/emergency/oxygen/double, - prob(1);/obj/item/device/suit_cooling_unit) - -/obj/random/cigarettes - name = "random cigarettes" - desc = "This is a cigarette." - icon = 'icons/obj/cigarettes.dmi' - icon_state = "cigpacket" - -/obj/random/cigarettes/item_to_spawn() - return pick(prob(5);/obj/item/weapon/storage/fancy/cigarettes, - prob(4);/obj/item/weapon/storage/fancy/cigarettes/dromedaryco, - prob(3);/obj/item/weapon/storage/fancy/cigarettes/killthroat, - prob(3);/obj/item/weapon/storage/fancy/cigarettes/luckystars, - prob(3);/obj/item/weapon/storage/fancy/cigarettes/jerichos, - prob(3);/obj/item/weapon/storage/fancy/cigarettes/menthols, - prob(3);/obj/item/weapon/storage/fancy/cigarettes/carcinomas, - prob(3);/obj/item/weapon/storage/fancy/cigarettes/professionals, - prob(1);/obj/item/weapon/storage/fancy/cigar, - prob(1);/obj/item/clothing/mask/smokable/cigarette/cigar, - prob(1);/obj/item/clothing/mask/smokable/cigarette/cigar/cohiba, - prob(1);/obj/item/clothing/mask/smokable/cigarette/cigar/havana) - -/obj/random/maintenance //Clutter and loot for maintenance and away missions - name = "random maintenance item" - desc = "This is a random maintenance item." - icon = 'icons/obj/items.dmi' - icon_state = "gift1" - -/obj/random/maintenance/item_to_spawn() - return pick(prob(300);/obj/random/tech_supply, - prob(200);/obj/random/medical, - prob(100);/obj/random/firstaid, - prob(10);/obj/random/contraband, - prob(50);/obj/random/action_figure, - prob(50);/obj/random/plushie, - prob(200);/obj/random/junk, - prob(200);/obj/random/material, - prob(50);/obj/random/toy, - prob(100);/obj/random/tank, - prob(50);/obj/random/soap, - prob(60);/obj/random/drinkbottle, - prob(500);/obj/random/maintenance/clean) - -/obj/random/maintenance/clean -/*Maintenance loot lists without the trash, for use inside things. -Individual items to add to the maintenance list should go here, if you add -something, make sure it's not in one of the other lists.*/ - name = "random clean maintenance item" - desc = "This is a random clean maintenance item." - icon = 'icons/obj/items.dmi' - icon_state = "gift1" - -/obj/random/maintenance/clean/item_to_spawn() - return pick(prob(10);/obj/random/contraband, - prob(2);/obj/item/device/flashlight/flare, - prob(2);/obj/item/device/flashlight/glowstick, - prob(2);/obj/item/device/flashlight/glowstick/blue, - prob(1);/obj/item/device/flashlight/glowstick/orange, - prob(1);/obj/item/device/flashlight/glowstick/red, - prob(1);/obj/item/device/flashlight/glowstick/yellow, - prob(1);/obj/item/device/flashlight/pen, - prob(4);/obj/item/weapon/cell, - prob(4);/obj/item/weapon/cell/device, - prob(3);/obj/item/weapon/cell/high, - prob(2);/obj/item/weapon/cell/super, - prob(5);/obj/random/cigarettes, - prob(3);/obj/item/clothing/mask/gas, - prob(2);/obj/item/clothing/mask/gas/half, - prob(4);/obj/item/clothing/mask/breath, - prob(2);/obj/item/weapon/reagent_containers/glass/rag, - prob(4);/obj/item/weapon/reagent_containers/food/snacks/liquidfood, - prob(2);/obj/item/weapon/storage/secure/briefcase, - prob(4);/obj/item/weapon/storage/briefcase, - prob(5);/obj/item/weapon/storage/backpack, - prob(5);/obj/item/weapon/storage/backpack/satchel/norm, - prob(4);/obj/item/weapon/storage/backpack/satchel, - prob(3);/obj/item/weapon/storage/backpack/dufflebag, - prob(1);/obj/item/weapon/storage/backpack/dufflebag/syndie, - prob(5);/obj/item/weapon/storage/box, - prob(3);/obj/item/weapon/storage/box/donkpockets, - prob(2);/obj/item/weapon/storage/box/sinpockets, - prob(1);/obj/item/weapon/storage/box/cups, - prob(3);/obj/item/weapon/storage/box/mousetraps, - prob(3);/obj/item/weapon/storage/box/engineer, - prob(3);/obj/item/weapon/storage/wallet, - prob(1);/obj/item/device/paicard, - prob(2);/obj/item/clothing/shoes/galoshes, - prob(1);/obj/item/clothing/shoes/syndigaloshes, - prob(4);/obj/item/clothing/shoes/black, - prob(4);/obj/item/clothing/shoes/laceup, - prob(4);/obj/item/clothing/shoes/black, - prob(4);/obj/item/clothing/shoes/leather, - prob(1);/obj/item/clothing/gloves/yellow, - prob(3);/obj/item/clothing/gloves/botanic_leather, - prob(2);/obj/item/clothing/gloves/sterile/latex, - prob(5);/obj/item/clothing/gloves/white, - prob(5);/obj/item/clothing/gloves/rainbow, - prob(2);/obj/item/clothing/gloves/fyellow, - prob(1);/obj/item/clothing/glasses/sunglasses, - prob(3);/obj/item/clothing/glasses/meson, - prob(2);/obj/item/clothing/glasses/meson/prescription, - prob(1);/obj/item/clothing/glasses/welding, - prob(1);/obj/item/clothing/head/bio_hood/general, - prob(4);/obj/item/clothing/head/hardhat, - prob(3);/obj/item/clothing/head/hardhat/red, - prob(1);/obj/item/clothing/head/ushanka, - prob(2);/obj/item/clothing/head/welding, - prob(4);/obj/item/clothing/suit/storage/hazardvest, - prob(1);/obj/item/clothing/suit/space/emergency, - prob(3);/obj/item/clothing/suit/storage/toggle/bomber, - prob(1);/obj/item/clothing/suit/bio_suit/general, - prob(3);/obj/item/clothing/suit/storage/toggle/hoodie/black, - prob(3);/obj/item/clothing/suit/storage/toggle/hoodie/blue, - prob(3);/obj/item/clothing/suit/storage/toggle/hoodie/red, - prob(3);/obj/item/clothing/suit/storage/toggle/hoodie/yellow, - prob(3);/obj/item/clothing/suit/storage/toggle/brown_jacket, - prob(3);/obj/item/clothing/suit/storage/toggle/leather_jacket, - prob(1);/obj/item/clothing/suit/storage/vest/press, - prob(3);/obj/item/clothing/suit/storage/apron, - prob(4);/obj/item/clothing/under/color/grey, - prob(2);/obj/item/clothing/under/syndicate/tacticool, - prob(2);/obj/item/clothing/under/pants/camo, - prob(1);/obj/item/clothing/under/harness, - prob(1);/obj/item/clothing/under/tactical, - prob(3);/obj/item/clothing/accessory/storage/webbing, - prob(4);/obj/item/weapon/spacecash/c1, - prob(3);/obj/item/weapon/spacecash/c10, - prob(3);/obj/item/weapon/spacecash/c20, - prob(1);/obj/item/weapon/spacecash/c50, - prob(1);/obj/item/weapon/spacecash/c100, - prob(3);/obj/item/weapon/camera_assembly, - prob(4);/obj/item/weapon/caution, - prob(3);/obj/item/weapon/caution/cone, - prob(1);/obj/item/weapon/card/emag_broken, - prob(2);/obj/item/device/camera, - prob(3);/obj/item/device/pda, - prob(3);/obj/item/device/radio/headset) - -/obj/random/maintenance/security -/*Maintenance loot list. This one is for around security areas*/ - name = "random security maintenance item" - desc = "This is a random security maintenance item." - icon = 'icons/obj/items.dmi' - icon_state = "gift1" - -/obj/random/maintenance/security/item_to_spawn() - return pick(prob(320);/obj/random/maintenance/clean, - prob(2);/obj/item/device/flashlight/maglight, - prob(2);/obj/item/device/flash, - prob(1);/obj/item/weapon/cell/device/weapon, - prob(1);/obj/item/clothing/mask/gas/swat, - prob(1);/obj/item/clothing/mask/gas/syndicate, - prob(2);/obj/item/clothing/mask/balaclava, - prob(1);/obj/item/clothing/mask/balaclava/tactical, - prob(3);/obj/item/weapon/storage/backpack/security, - prob(3);/obj/item/weapon/storage/backpack/satchel/sec, - prob(2);/obj/item/weapon/storage/backpack/messenger/sec, - prob(2);/obj/item/weapon/storage/backpack/dufflebag/sec, - prob(1);/obj/item/weapon/storage/backpack/dufflebag/syndie/ammo, - prob(1);/obj/item/weapon/storage/backpack/dufflebag/syndie/med, - prob(2);/obj/item/weapon/storage/box/swabs, - prob(2);/obj/item/weapon/storage/belt/security, - prob(1);/obj/item/weapon/grenade/flashbang, - prob(1);/obj/item/weapon/melee/baton, - prob(1);/obj/item/weapon/reagent_containers/spray/pepper, - prob(3);/obj/item/clothing/shoes/boots/jackboots, - prob(1);/obj/item/clothing/shoes/boots/swat, - prob(1);/obj/item/clothing/shoes/boots/combat, - prob(1);/obj/item/clothing/gloves/swat, - prob(1);/obj/item/clothing/gloves/combat, - prob(1);/obj/item/clothing/glasses/sunglasses/big, - prob(2);/obj/item/clothing/glasses/hud/security, - prob(1);/obj/item/clothing/glasses/sunglasses/sechud, - prob(1);/obj/item/clothing/glasses/sunglasses/sechud/aviator, - prob(1);/obj/item/clothing/glasses/sunglasses/sechud/tactical, - prob(3);/obj/item/clothing/head/beret/sec, - prob(3);/obj/item/clothing/head/beret/sec/corporate/officer, - prob(3);/obj/item/clothing/head/beret/sec/navy/officer, - prob(2);/obj/item/clothing/head/helmet, - prob(4);/obj/item/clothing/head/soft/sec, - prob(4);/obj/item/clothing/head/soft/sec/corp, - prob(3);/obj/item/clothing/suit/armor/vest, - prob(2);/obj/item/clothing/suit/armor/vest/security, - prob(2);/obj/item/clothing/suit/storage/vest/officer, - prob(1);/obj/item/clothing/suit/storage/vest/detective, - prob(1);/obj/item/clothing/suit/storage/vest/press, - prob(2);/obj/item/clothing/accessory/storage/black_vest, - prob(2);/obj/item/clothing/accessory/storage/black_drop_pouches, - prob(1);/obj/item/clothing/accessory/holster/leg, - prob(1);/obj/item/clothing/accessory/holster/hip, - prob(1);/obj/item/clothing/accessory/holster/waist, - prob(1);/obj/item/clothing/accessory/holster/armpit, - prob(2);/obj/item/clothing/ears/earmuffs, - prob(2);/obj/item/weapon/handcuffs,) - -/obj/random/maintenance/medical -/*Maintenance loot list. This one is for around medical areas*/ - name = "random medical maintenance item" - desc = "This is a random medical maintenance item." - icon = 'icons/obj/items.dmi' - icon_state = "gift1" - -/obj/random/maintenance/medical/item_to_spawn() - return pick(prob(320);/obj/random/maintenance/clean, - prob(25);/obj/random/medical/lite, - prob(2);/obj/item/clothing/mask/breath/medical, - prob(2);/obj/item/clothing/mask/surgical, - prob(5);/obj/item/weapon/storage/backpack/medic, - prob(5);/obj/item/weapon/storage/backpack/satchel/med, - prob(5);/obj/item/weapon/storage/backpack/messenger/med, - prob(3);/obj/item/weapon/storage/backpack/dufflebag/med, - prob(1);/obj/item/weapon/storage/backpack/dufflebag/syndie/med, - prob(2);/obj/item/weapon/storage/box/autoinjectors, - prob(3);/obj/item/weapon/storage/box/beakers, - prob(2);/obj/item/weapon/storage/box/bodybags, - prob(3);/obj/item/weapon/storage/box/syringes, - prob(3);/obj/item/weapon/storage/box/gloves, - prob(2);/obj/item/weapon/storage/belt/medical/emt, - prob(2);/obj/item/weapon/storage/belt/medical, - prob(1);/obj/item/clothing/shoes/boots/combat, - prob(3);/obj/item/clothing/shoes/white, - prob(2);/obj/item/clothing/gloves/sterile/nitrile, - prob(5);/obj/item/clothing/gloves/white, - prob(2);/obj/item/clothing/glasses/hud/health, - prob(1);/obj/item/clothing/glasses/hud/health/prescription, - prob(1);/obj/item/clothing/head/bio_hood/virology, - prob(4);/obj/item/clothing/suit/storage/toggle/labcoat, - prob(1);/obj/item/clothing/suit/bio_suit/general, - prob(2);/obj/item/clothing/under/rank/medical/paramedic, - prob(2);/obj/item/clothing/accessory/storage/black_vest, - prob(2);/obj/item/clothing/accessory/storage/white_vest, - prob(1);/obj/item/clothing/accessory/storage/white_drop_pouches, - prob(1);/obj/item/clothing/accessory/storage/black_drop_pouches, - prob(2);/obj/item/clothing/accessory/stethoscope) - -/obj/random/maintenance/engineering -/*Maintenance loot list. This one is for around medical areas*/ - name = "random engineering maintenance item" - desc = "This is a random engineering maintenance item." - icon = 'icons/obj/items.dmi' - icon_state = "gift1" - -/obj/random/maintenance/engineering/item_to_spawn() - return pick(prob(320);/obj/random/maintenance/clean, - prob(2);/obj/item/device/flashlight/maglight, - prob(3);/obj/item/clothing/mask/gas/half, - prob(2);/obj/item/clothing/mask/balaclava, - prob(2);/obj/item/weapon/storage/briefcase/inflatable, - prob(5);/obj/item/weapon/storage/backpack/industrial, - prob(5);/obj/item/weapon/storage/backpack/satchel/eng, - prob(5);/obj/item/weapon/storage/backpack/messenger/engi, - prob(3);/obj/item/weapon/storage/backpack/dufflebag/eng, - prob(5);/obj/item/weapon/storage/box, - prob(3);/obj/item/weapon/storage/box/engineer, - prob(2);/obj/item/weapon/storage/belt/utility/full, - prob(3);/obj/item/weapon/storage/belt/utility, - prob(3);/obj/item/clothing/head/beret/engineering, - prob(3);/obj/item/clothing/head/soft/yellow, - prob(2);/obj/item/clothing/head/orangebandana, - prob(2);/obj/item/clothing/head/hardhat/dblue, - prob(2);/obj/item/clothing/head/hardhat/orange, - prob(1);/obj/item/clothing/glasses/welding, - prob(2);/obj/item/clothing/head/welding, - prob(4);/obj/item/clothing/suit/storage/hazardvest, - prob(2);/obj/item/clothing/under/overalls, - prob(3);/obj/item/clothing/shoes/boots/workboots, - prob(1);/obj/item/clothing/shoes/magboots, - prob(2);/obj/item/clothing/accessory/storage/black_vest, - prob(2);/obj/item/clothing/accessory/storage/brown_vest, - prob(1);/obj/item/clothing/accessory/storage/brown_drop_pouches, - prob(3);/obj/item/clothing/ears/earmuffs, - prob(1);/obj/item/weapon/beartrap, - prob(2);/obj/item/weapon/handcuffs) - -/obj/random/maintenance/research -/*Maintenance loot list. This one is for around medical areas*/ - name = "random research maintenance item" - desc = "This is a random research maintenance item." - icon = 'icons/obj/items.dmi' - icon_state = "gift1" - -/obj/random/maintenance/research/item_to_spawn() - return pick(prob(320);/obj/random/maintenance/clean, - prob(3);/obj/item/device/analyzer/plant_analyzer, - prob(1);/obj/item/device/flash/synthetic, - prob(2);/obj/item/weapon/bucket_sensor, - prob(1);/obj/item/weapon/cell/device/weapon, - prob(5);/obj/item/weapon/storage/backpack/toxins, - prob(5);/obj/item/weapon/storage/backpack/satchel/tox, - prob(5);/obj/item/weapon/storage/backpack/messenger/tox, - prob(2);/obj/item/weapon/storage/excavation, - prob(1);/obj/item/weapon/storage/backpack/holding, - prob(3);/obj/item/weapon/storage/box/beakers, - prob(3);/obj/item/weapon/storage/box/syringes, - prob(3);/obj/item/weapon/storage/box/gloves, - prob(2);/obj/item/clothing/gloves/sterile/latex, - prob(4);/obj/item/clothing/glasses/science, - prob(3);/obj/item/clothing/glasses/material, - prob(1);/obj/item/clothing/head/beret/purple, - prob(1);/obj/item/clothing/head/bio_hood/scientist, - prob(4);/obj/item/clothing/suit/storage/toggle/labcoat, - prob(4);/obj/item/clothing/suit/storage/toggle/labcoat/science, - prob(1);/obj/item/clothing/suit/bio_suit/scientist, - prob(4);/obj/item/clothing/under/rank/scientist, - prob(2);/obj/item/clothing/under/rank/scientist_new) - -/obj/random/maintenance/cargo -/*Maintenance loot list. This one is for around cargo areas*/ - name = "random cargo maintenance item" - desc = "This is a random cargo maintenance item." - icon = 'icons/obj/items.dmi' - icon_state = "gift1" - -/obj/random/maintenance/cargo/item_to_spawn() - return pick(prob(320);/obj/random/maintenance/clean, - prob(3);/obj/item/device/flashlight/lantern, - prob(4);/obj/item/weapon/pickaxe, - prob(5);/obj/item/weapon/storage/backpack/industrial, - prob(5);/obj/item/weapon/storage/backpack/satchel/norm, - prob(3);/obj/item/weapon/storage/backpack/dufflebag, - prob(1);/obj/item/weapon/storage/backpack/dufflebag/syndie/ammo, - prob(1);/obj/item/weapon/storage/toolbox/syndicate, - prob(1);/obj/item/weapon/storage/belt/utility/full, - prob(2);/obj/item/weapon/storage/belt/utility, - prob(4);/obj/item/device/toner, - prob(1);/obj/item/device/destTagger, - prob(3);/obj/item/clothing/glasses/material, - prob(3);/obj/item/clothing/head/soft/yellow, - prob(4);/obj/item/clothing/suit/storage/hazardvest, - prob(3);/obj/item/clothing/suit/storage/apron/overalls, - prob(4);/obj/item/clothing/suit/storage/apron, - prob(2);/obj/item/clothing/under/syndicate/tacticool, - prob(1);/obj/item/clothing/under/syndicate/combat, - prob(2);/obj/item/clothing/accessory/storage/black_vest, - prob(2);/obj/item/clothing/accessory/storage/brown_vest, - prob(3);/obj/item/clothing/ears/earmuffs, - prob(1);/obj/item/weapon/beartrap, - prob(2);/obj/item/weapon/handcuffs,) - -/obj/random/sfr - name = "random SFR headset" - desc = "This is a headset spawn." - icon = 'icons/misc/mark.dmi' - icon_state = "rup" - -/obj/random/sfr/item_to_spawn() - return pick(prob(25);/obj/item/device/radio/headset/heads/captain/sfr, - prob(25);/obj/item/device/radio/headset/headset_cargo/alt, - prob(25);/obj/item/device/radio/headset/headset_com/alt, - prob(25);/obj/item/device/radio/headset) - -/obj/random/rigsuit - name = "Random rigsuit" - desc = "This is a random rigsuit." - icon = 'icons/obj/rig_modules.dmi' - icon_state = "generic" - -/obj/random/rigsuit/item_to_spawn() - return pick(prob(4);/obj/item/weapon/rig/light/hacker, - prob(5);/obj/item/weapon/rig/industrial, - prob(5);/obj/item/weapon/rig/eva, - prob(4);/obj/item/weapon/rig/light/stealth, - prob(3);/obj/item/weapon/rig/hazard, - prob(1);/obj/item/weapon/rig/merc/empty) - -var/list/random_junk_ -var/list/random_useful_ -/proc/get_random_useful_type() - if(!random_useful_) - random_useful_ = subtypesof(/obj/item/weapon/pen/crayon) - random_useful_ += /obj/item/weapon/pen - random_useful_ += /obj/item/weapon/pen/blue - random_useful_ += /obj/item/weapon/pen/red - random_useful_ += /obj/item/weapon/pen/multi - random_useful_ += /obj/item/weapon/storage/box/matches - random_useful_ += /obj/item/stack/material/cardboard - return pick(random_useful_) - -/proc/get_random_junk_type() - if(prob(20)) // Misc. clutter - return /obj/effect/decal/cleanable/generic - if(prob(70)) // Misc. junk - if(!random_junk_) - random_junk_ = subtypesof(/obj/item/trash) - random_junk_ += typesof(/obj/item/weapon/cigbutt) - random_junk_ += /obj/effect/decal/cleanable/spiderling_remains - random_junk_ += /obj/effect/decal/remains/mouse - random_junk_ += /obj/effect/decal/remains/robot - random_junk_ += /obj/item/weapon/paper/crumpled - random_junk_ += /obj/item/inflatable/torn - random_junk_ += /obj/effect/decal/cleanable/molten_item - random_junk_ += /obj/item/weapon/material/shard - - random_junk_ -= /obj/item/trash/plate - random_junk_ -= /obj/item/trash/snack_bowl - random_junk_ -= /obj/item/trash/syndi_cakes - random_junk_ -= /obj/item/trash/tray - return pick(random_junk_) - // Misc. actually useful stuff - return get_random_useful_type() - -/* - Selects one spawn point out of a group of points with the same ID and asks it to generate its items -*/ -var/list/multi_point_spawns - -/obj/random_multi - name = "random object spawn point" - desc = "This item type is used to spawn random objects at round-start. Only one spawn point for a given group id is selected." - icon = 'icons/misc/mark.dmi' - icon_state = "x3" - invisibility = INVISIBILITY_MAXIMUM - var/id // Group id - var/weight // Probability weight for this spawn point - -/obj/random_multi/initialize() - . = ..() - weight = max(1, round(weight)) - - if(!multi_point_spawns) - multi_point_spawns = list() - var/list/spawnpoints = multi_point_spawns[id] - if(!spawnpoints) - spawnpoints = list() - multi_point_spawns[id] = spawnpoints - spawnpoints[src] = weight - -/obj/random_multi/Destroy() - var/list/spawnpoints = multi_point_spawns[id] - spawnpoints -= src - if(!spawnpoints.len) - multi_point_spawns -= id - . = ..() - -/obj/random_multi/proc/generate_items() - return - -/obj/random_multi/single_item - var/item_path // Item type to spawn - -/obj/random_multi/single_item/generate_items() - new item_path(loc) - -/hook/roundstart/proc/generate_multi_spawn_items() - for(var/id in multi_point_spawns) - var/list/spawn_points = multi_point_spawns[id] - var/obj/random_multi/rm = pickweight(spawn_points) - rm.generate_items() - for(var/entry in spawn_points) - qdel(entry) - return 1 - -/obj/random_multi/single_item/captains_spare_id - name = "Multi Point - Captain's Spare" - id = "Captain's spare id" - item_path = /obj/item/weapon/card/id/gold/captain/spare - -/obj/random_multi/single_item/sfr_headset - name = "Multi Point - headset" - id = "SFR headset" - item_path = /obj/random/sfr - -//Multiple Object Spawn - -/obj/random/multiple - -/obj/random/multiple/spawn_item() - var/list/things_to_make = item_to_spawn() - for(var/new_type in things_to_make) - new new_type(src.loc) - -/obj/random/multiple/voidsuit - name = "Random Voidsuit" - desc = "This is a random voidsuit." - icon = 'icons/obj/clothing/suits.dmi' - icon_state = "void" - -/obj/random/multiple/voidsuit/item_to_spawn() - return pick( - prob(5);list( - /obj/item/clothing/suit/space/void, - /obj/item/clothing/head/helmet/space/void - ), - prob(5);list( - /obj/item/clothing/suit/space/void/atmos, - /obj/item/clothing/head/helmet/space/void/atmos - ), - prob(5);list( - /obj/item/clothing/suit/space/void/atmos/alt, - /obj/item/clothing/head/helmet/space/void/atmos/alt - ), - prob(5);list( - /obj/item/clothing/suit/space/void/engineering, - /obj/item/clothing/head/helmet/space/void/engineering - ), - prob(5);list( - /obj/item/clothing/suit/space/void/engineering/alt, - /obj/item/clothing/head/helmet/space/void/engineering/alt - ), - prob(5);list( - /obj/item/clothing/suit/space/void/engineering/construction, - /obj/item/clothing/head/helmet/space/void/engineering/construction - ), - prob(5);list( - /obj/item/clothing/suit/space/void/engineering/salvage, - /obj/item/clothing/head/helmet/space/void/engineering/salvage - ), - prob(5);list( - /obj/item/clothing/suit/space/void/medical, - /obj/item/clothing/head/helmet/space/void/medical - ), - prob(5);list( - /obj/item/clothing/suit/space/void/medical/alt, - /obj/item/clothing/head/helmet/space/void/medical/alt - ), - prob(5);list( - /obj/item/clothing/suit/space/void/medical/bio, - /obj/item/clothing/head/helmet/space/void/medical/bio - ), - prob(5);list( - /obj/item/clothing/suit/space/void/medical/emt, - /obj/item/clothing/head/helmet/space/void/medical/emt - ), - prob(5);list( - /obj/item/clothing/suit/space/void/merc, - /obj/item/clothing/head/helmet/space/void/merc - ), - prob(5);list( - /obj/item/clothing/suit/space/void/mining, - /obj/item/clothing/head/helmet/space/void/mining - ), - prob(5);list( - /obj/item/clothing/suit/space/void/mining/alt, - /obj/item/clothing/head/helmet/space/void/mining/alt - ), - prob(5);list( - /obj/item/clothing/suit/space/void/security, - /obj/item/clothing/head/helmet/space/void/security - ), - prob(5);list( - /obj/item/clothing/suit/space/void/security/alt, - /obj/item/clothing/head/helmet/space/void/security/alt - ), - prob(5);list( - /obj/item/clothing/suit/space/void/security/riot, - /obj/item/clothing/head/helmet/space/void/security/riot - ) - ) - -/obj/random/multiple/voidsuit/mining - name = "Random Mining Voidsuit" - desc = "This is a random mining voidsuit." - icon = 'icons/obj/clothing/suits.dmi' - icon_state = "rig-mining" - -/obj/random/multiple/voidsuit/mining/item_to_spawn() - return pick( - prob(5);list( - /obj/item/clothing/suit/space/void/mining, - /obj/item/clothing/head/helmet/space/void/mining - ), - prob(1);list( - /obj/item/clothing/suit/space/void/mining/alt, - /obj/item/clothing/head/helmet/space/void/mining/alt - ) - ) - -/obj/random/landmine - name = "Random Land Mine" - desc = "This is a random land mine." - icon = 'icons/obj/weapons.dmi' - icon_state = "uglymine" - spawn_nothing_percentage = 25 - -/obj/random/landmine/item_to_spawn() - return pick(prob(30);/obj/effect/mine, - prob(25);/obj/effect/mine/frag, - prob(25);/obj/effect/mine/emp, - prob(10);/obj/effect/mine/stun, - prob(10);/obj/effect/mine/incendiary,) \ No newline at end of file diff --git a/code/game/objects/random/spacesuits.dm b/code/game/objects/random/spacesuits.dm new file mode 100644 index 0000000000..cb4ec6d4e9 --- /dev/null +++ b/code/game/objects/random/spacesuits.dm @@ -0,0 +1,113 @@ + +// Spaceproof clothing sets go in here + +/obj/random/multiple/voidsuit + name = "Random Voidsuit" + desc = "This is a random voidsuit." + icon = 'icons/obj/clothing/suits.dmi' + icon_state = "void" + +/obj/random/multiple/voidsuit/item_to_spawn() + return pick( + prob(5);list( + /obj/item/clothing/suit/space/void, + /obj/item/clothing/head/helmet/space/void + ), + prob(5);list( + /obj/item/clothing/suit/space/void/atmos, + /obj/item/clothing/head/helmet/space/void/atmos + ), + prob(5);list( + /obj/item/clothing/suit/space/void/atmos/alt, + /obj/item/clothing/head/helmet/space/void/atmos/alt + ), + prob(5);list( + /obj/item/clothing/suit/space/void/engineering, + /obj/item/clothing/head/helmet/space/void/engineering + ), + prob(5);list( + /obj/item/clothing/suit/space/void/engineering/alt, + /obj/item/clothing/head/helmet/space/void/engineering/alt + ), + prob(5);list( + /obj/item/clothing/suit/space/void/engineering/construction, + /obj/item/clothing/head/helmet/space/void/engineering/construction + ), + prob(5);list( + /obj/item/clothing/suit/space/void/engineering/salvage, + /obj/item/clothing/head/helmet/space/void/engineering/salvage + ), + prob(5);list( + /obj/item/clothing/suit/space/void/medical, + /obj/item/clothing/head/helmet/space/void/medical + ), + prob(5);list( + /obj/item/clothing/suit/space/void/medical/alt, + /obj/item/clothing/head/helmet/space/void/medical/alt + ), + prob(5);list( + /obj/item/clothing/suit/space/void/medical/bio, + /obj/item/clothing/head/helmet/space/void/medical/bio + ), + prob(5);list( + /obj/item/clothing/suit/space/void/medical/emt, + /obj/item/clothing/head/helmet/space/void/medical/emt + ), + prob(5);list( + /obj/item/clothing/suit/space/void/merc, + /obj/item/clothing/head/helmet/space/void/merc + ), + prob(5);list( + /obj/item/clothing/suit/space/void/mining, + /obj/item/clothing/head/helmet/space/void/mining + ), + prob(5);list( + /obj/item/clothing/suit/space/void/mining/alt, + /obj/item/clothing/head/helmet/space/void/mining/alt + ), + prob(5);list( + /obj/item/clothing/suit/space/void/security, + /obj/item/clothing/head/helmet/space/void/security + ), + prob(5);list( + /obj/item/clothing/suit/space/void/security/alt, + /obj/item/clothing/head/helmet/space/void/security/alt + ), + prob(5);list( + /obj/item/clothing/suit/space/void/security/riot, + /obj/item/clothing/head/helmet/space/void/security/riot + ) + ) + +/obj/random/multiple/voidsuit/mining + name = "Random Mining Voidsuit" + desc = "This is a random mining voidsuit." + icon = 'icons/obj/clothing/suits.dmi' + icon_state = "rig-mining" + +/obj/random/multiple/voidsuit/mining/item_to_spawn() + return pick( + prob(5);list( + /obj/item/clothing/suit/space/void/mining, + /obj/item/clothing/head/helmet/space/void/mining + ), + prob(1);list( + /obj/item/clothing/suit/space/void/mining/alt, + /obj/item/clothing/head/helmet/space/void/mining/alt + ) + ) + + +/obj/random/rigsuit + name = "Random rigsuit" + desc = "This is a random rigsuit." + icon = 'icons/obj/rig_modules.dmi' + icon_state = "generic" + +/obj/random/rigsuit/item_to_spawn() + return pick(prob(4);/obj/item/weapon/rig/light/hacker, + prob(5);/obj/item/weapon/rig/industrial, + prob(5);/obj/item/weapon/rig/eva, + prob(4);/obj/item/weapon/rig/light/stealth, + prob(3);/obj/item/weapon/rig/hazard, + prob(1);/obj/item/weapon/rig/merc/empty) \ No newline at end of file diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index 5c3542015c..9b3d866d2b 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -10,7 +10,8 @@ LINEN BINS icon = 'icons/obj/items.dmi' icon_state = "sheet" slot_flags = SLOT_BACK - layer = 4.0 + plane = MOB_PLANE + layer = BELOW_MOB_LAYER throwforce = 1 throw_speed = 1 throw_range = 2 @@ -19,9 +20,9 @@ LINEN BINS /obj/item/weapon/bedsheet/attack_self(mob/user as mob) user.drop_item() if(layer == initial(layer)) - layer = MOB_LAYER + 0.1 + layer = ABOVE_MOB_LAYER else - layer = initial(layer) + reset_plane_and_layer() add_fingerprint(user) return diff --git a/code/game/objects/structures/bonfire.dm b/code/game/objects/structures/bonfire.dm index 1952ddea4f..390ddc88a3 100644 --- a/code/game/objects/structures/bonfire.dm +++ b/code/game/objects/structures/bonfire.dm @@ -10,6 +10,8 @@ var/next_fuel_consumption = 0 // world.time of when next item in fuel list gets eatten to sustain the fire. var/grill = FALSE var/material/material + var/set_temperature = T0C + 30 //K + var/heating_power = 80000 /obj/structure/bonfire/New(newloc, material_name) ..(newloc) @@ -186,9 +188,9 @@ if(burning) var/state switch(get_fuel_amount()) - if(0 to 4) + if(0 to 4.5) state = "bonfire_warm" - if(5 to 10) + if(4.6 to 10) state = "bonfire_hot" var/image/I = image(icon, state) I.appearance_flags = RESET_COLOR @@ -223,6 +225,23 @@ if(!grill) burn() + if(burning) + var/W = get_fuel_amount() + if(W >= 5) + var/datum/gas_mixture/env = loc.return_air() + if(env && abs(env.temperature - set_temperature) > 0.1) + var/transfer_moles = 0.25 * env.total_moles + var/datum/gas_mixture/removed = env.remove(transfer_moles) + + if(removed) + var/heat_transfer = removed.get_thermal_energy_change(set_temperature) + if(heat_transfer > 0) + heat_transfer = min(heat_transfer , heating_power) + + removed.add_thermal_energy(heat_transfer) + + env.merge(removed) + /obj/structure/bonfire/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) ignite() @@ -235,4 +254,163 @@ M.pixel_y += 13 else // Just unbuckled someone M.pixel_y -= 13 - update_icon() \ No newline at end of file + update_icon() + +/obj/structure/fireplace //more like a space heater than a bonfire. A cozier alternative to both. + name = "fireplace" + desc = "The sound of the crackling hearth reminds you of home." + icon = 'icons/obj/structures.dmi' + icon_state = "fireplace" + density = TRUE + anchored = TRUE + var/burning = FALSE + var/next_fuel_consumption = 0 + var/set_temperature = T0C + 20 //K + var/heating_power = 40000 + +/obj/structure/fireplace/attackby(obj/item/W, mob/user) + if(istype(W, /obj/item/stack/material/wood) || istype(W, /obj/item/stack/material/log) ) + add_fuel(W, user) + + else if(W.is_hot()) + ignite() + else + return ..() + +/obj/structure/fireplace/attack_hand(mob/user) + if(get_fuel_amount()) + remove_fuel(user) + +/obj/structure/fireplace/proc/get_fuel_amount() + var/F = 0 + for(var/A in contents) + if(istype(A, /obj/item/stack/material/wood)) + F += 0.5 + if(istype(A, /obj/item/stack/material/log)) + F += 1.0 + return F + +/obj/structure/fireplace/proc/remove_fuel(mob/user) + if(get_fuel_amount()) + var/atom/movable/AM = pop(contents) + AM.forceMove(get_turf(src)) + to_chat(user, "You take \the [AM] out of \the [src] before it has a chance to burn away.") + update_icon() + +/obj/structure/fireplace/proc/add_fuel(atom/movable/new_fuel, mob/user) + if(get_fuel_amount() >= 10) + to_chat(user, "\The [src] already has enough fuel!") + return FALSE + if(istype(new_fuel, /obj/item/stack/material/wood) || istype(new_fuel, /obj/item/stack/material/log) ) + var/obj/item/stack/F = new_fuel + var/obj/item/stack/S = F.split(1) + if(S) + S.forceMove(src) + to_chat(user, "You add \the [new_fuel] to \the [src].") + update_icon() + return TRUE + return FALSE + else + to_chat(user, "\The [src] needs raw wood to burn, \a [new_fuel] won't work.") + return FALSE + +/obj/structure/fireplace/proc/consume_fuel(var/obj/item/stack/consumed_fuel) + if(!istype(consumed_fuel)) + qdel(consumed_fuel) // Don't know, don't care. + return FALSE + + if(istype(consumed_fuel, /obj/item/stack/material/log)) + next_fuel_consumption = world.time + 2 MINUTES + qdel(consumed_fuel) + update_icon() + return TRUE + + else if(istype(consumed_fuel, /obj/item/stack/material/wood)) // One log makes two planks of wood. + next_fuel_consumption = world.time + 1 MINUTE + qdel(consumed_fuel) + update_icon() + return TRUE + return FALSE + +/obj/structure/fireplace/proc/check_oxygen() + var/datum/gas_mixture/G = loc.return_air() + if(G.gas["oxygen"] < 1) + return FALSE + return TRUE + +/obj/structure/fireplace/proc/extinguish() + if(burning) + burning = FALSE + update_icon() + processing_objects -= src + visible_message("\The [src] stops burning.") + +/obj/structure/fireplace/proc/ignite() + if(!burning && get_fuel_amount()) + burning = TRUE + update_icon() + processing_objects += src + visible_message("\The [src] starts burning!") + +/obj/structure/fireplace/proc/burn() + var/turf/current_location = get_turf(src) + current_location.hotspot_expose(1000, 500) + for(var/A in current_location) + if(A == src) + continue + if(isobj(A)) + var/obj/O = A + O.fire_act(null, 1000, 500) + +/obj/structure/fireplace/update_icon() + overlays.Cut() + if(burning) + var/state + switch(get_fuel_amount()) + if(0 to 3.5) + state = "fireplace_warm" + if(3.6 to 6.5) + state = "fireplace_hot" + if(6.6 to 10) + state = "fireplace_intense" //don't need to throw a corpse inside to make it burn hotter. + var/image/I = image(icon, state) + I.appearance_flags = RESET_COLOR + overlays += I + + var/light_strength = max(get_fuel_amount() / 2, 2) + set_light(light_strength, light_strength, "#FF9933") + else + set_light(0) + +/obj/structure/fireplace/process() + if(!check_oxygen()) + extinguish() + return + if(world.time >= next_fuel_consumption) + if(!consume_fuel(pop(contents))) + extinguish() + return + + if(burning) + var/W = get_fuel_amount() + if(W >= 5) + var/datum/gas_mixture/env = loc.return_air() + if(env && abs(env.temperature - set_temperature) > 0.1) + var/transfer_moles = 0.25 * env.total_moles + var/datum/gas_mixture/removed = env.remove(transfer_moles) + + if(removed) + var/heat_transfer = removed.get_thermal_energy_change(set_temperature) + if(heat_transfer > 0) + heat_transfer = min(heat_transfer , heating_power) + + removed.add_thermal_energy(heat_transfer) + + env.merge(removed) + +/obj/structure/fireplace/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) + ignite() + +/obj/structure/fireplace/water_act(amount) + if(prob(amount * 10)) + extinguish() \ No newline at end of file diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 7e922e97bb..e25553d361 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -415,3 +415,6 @@ /obj/structure/closet/onDropInto(var/atom/movable/AM) return + +/obj/structure/closet/AllowDrop() + return TRUE diff --git a/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm b/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm index eb2ab38b52..103867ef88 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm @@ -67,3 +67,34 @@ new /obj/item/clothing/suit/storage/hooded/wintercoat/cargo(src) new /obj/item/clothing/shoes/boots/winter/supply(src) return + +/obj/structure/closet/secure_closet/miner + name = "miner's equipment" + icon_state = "miningsec1" + icon_closed = "miningsec" + icon_locked = "miningsec1" + icon_opened = "miningsecopen" + icon_broken = "miningsecbroken" + icon_off = "miningsecoff" + req_access = list(access_mining) + +/obj/structure/closet/secure_closet/miner/New() + ..() + sleep(2) + if(prob(50)) + new /obj/item/weapon/storage/backpack/industrial(src) + else + new /obj/item/weapon/storage/backpack/satchel/eng(src) + new /obj/item/device/radio/headset/headset_mine(src) + new /obj/item/clothing/under/rank/miner(src) + new /obj/item/clothing/gloves/black(src) + new /obj/item/clothing/shoes/black(src) + new /obj/item/device/analyzer(src) + new /obj/item/weapon/storage/bag/ore(src) + new /obj/item/device/flashlight/lantern(src) + new /obj/item/weapon/shovel(src) + new /obj/item/weapon/pickaxe(src) + new /obj/item/clothing/glasses/material(src) + new /obj/item/clothing/suit/storage/hooded/wintercoat/miner(src) + new /obj/item/clothing/shoes/boots/winter/mining(src) + new /obj/item/stack/marker_beacon/thirty(src) \ No newline at end of file diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 83aa687957..cf70a40920 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -103,12 +103,13 @@ if(prob(50)) new /obj/item/weapon/storage/backpack/dufflebag/sec(src) new /obj/item/clothing/head/helmet/HoS(src) + new /obj/item/clothing/head/helmet/HoS/hat(src) new /obj/item/clothing/suit/storage/vest/hos(src) new /obj/item/clothing/under/rank/head_of_security/jensen(src) new /obj/item/clothing/under/rank/head_of_security/corp(src) new /obj/item/clothing/suit/storage/vest/hoscoat/jensen(src) new /obj/item/clothing/suit/storage/vest/hoscoat(src) - new /obj/item/clothing/head/helmet/HoS/dermal(src) + new /obj/item/clothing/head/helmet/dermal(src) new /obj/item/weapon/cartridge/hos(src) new /obj/item/device/radio/headset/heads/hos(src) new /obj/item/device/radio/headset/heads/hos/alt(src) @@ -161,7 +162,9 @@ new /obj/item/clothing/under/rank/warden/corp(src) new /obj/item/clothing/suit/storage/vest/wardencoat(src) new /obj/item/clothing/suit/storage/vest/wardencoat/alt(src) + new /obj/item/clothing/head/helmet/dermal(src) new /obj/item/clothing/head/helmet/warden(src) + new /obj/item/clothing/head/helmet/warden/hat(src) new /obj/item/weapon/cartridge/security(src) new /obj/item/device/radio/headset/headset_sec(src) new /obj/item/device/radio/headset/headset_sec/alt(src) diff --git a/code/game/objects/structures/flora/trees.dm b/code/game/objects/structures/flora/trees.dm index 0c50bf189d..ef58518e48 100644 --- a/code/game/objects/structures/flora/trees.dm +++ b/code/game/objects/structures/flora/trees.dm @@ -18,6 +18,10 @@ return ..() if(is_stump) + if(istype(W,/obj/item/weapon/shovel)) + if(do_after(user, 5 SECONDS)) + visible_message("\The [user] digs up \the [src] stump with \the [W].") + qdel(src) return visible_message("\The [user] hits \the [src] with \the [W]!") diff --git a/code/game/objects/structures/ghost_pods/ghost_pods.dm b/code/game/objects/structures/ghost_pods/ghost_pods.dm index 02c5f304f3..16dcd2ddb7 100644 --- a/code/game/objects/structures/ghost_pods/ghost_pods.dm +++ b/code/game/objects/structures/ghost_pods/ghost_pods.dm @@ -7,14 +7,17 @@ var/icon_state_opened = null // Icon to switch to when 'used'. var/used = FALSE var/busy = FALSE // Don't spam ghosts by spamclicking. + var/needscharger //For drone pods that want their pod to turn into a charger. // Call this to get a ghost volunteer. -/obj/structure/ghost_pod/proc/trigger() +/obj/structure/ghost_pod/proc/trigger(var/alert, var/adminalert) if(!ghost_query_type) return FALSE if(busy) return FALSE + visible_message(alert) + log_and_message_admins(adminalert) busy = TRUE var/datum/ghost_query/Q = new ghost_query_type() var/list/winner = Q.query() @@ -22,8 +25,10 @@ if(winner.len) var/mob/observer/dead/D = winner[1] create_occupant(D) - new /obj/machinery/recharge_station/ghost_pod_recharger(src.loc) - del(src) + icon_state = icon_state_opened + if(needscharger) + new /obj/machinery/recharge_station/ghost_pod_recharger(src.loc) + del(src) return TRUE else return FALSE @@ -41,7 +46,7 @@ /obj/structure/ghost_pod/manual/attack_hand(var/mob/living/user) if(!used) if(confirm_before_open) - if(alert(user, "Are you sure you want to open \the [src]?", "Confirm", "No", "Yes") == "No") + if(alert(user, "Are you sure you want to touch \the [src]?", "Confirm", "No", "Yes") == "No") return trigger() diff --git a/code/game/objects/structures/ghost_pods/silicon.dm b/code/game/objects/structures/ghost_pods/silicon.dm index a204437bc3..1e7210a1ec 100644 --- a/code/game/objects/structures/ghost_pods/silicon.dm +++ b/code/game/objects/structures/ghost_pods/silicon.dm @@ -10,11 +10,10 @@ density = TRUE ghost_query_type = /datum/ghost_query/lost_drone confirm_before_open = TRUE + needscharger = TRUE /obj/structure/ghost_pod/manual/lost_drone/trigger() - ..() - visible_message("\The [src] appears to be attempting to restart the robot contained inside.") - log_and_message_admins("is attempting to open \a [src].") + ..("\The [src] appears to be attempting to restart the robot contained inside.", "is attempting to open \a [src].") /obj/structure/ghost_pod/manual/lost_drone/create_occupant(var/mob/M) density = FALSE @@ -45,6 +44,7 @@ icon_state_opened = "borg_pod_opened" density = TRUE ghost_query_type = /datum/ghost_query/gravekeeper_drone + needscharger = TRUE /obj/structure/ghost_pod/automatic/gravekeeper_drone/create_occupant(var/mob/M) density = FALSE @@ -58,4 +58,54 @@ R.ckey = M.ckey visible_message("As \the [src] opens, the eyes of the robot flicker as it is activated.") R.Namepick() + ..() + +/obj/structure/ghost_pod/manual/corgi + name = "glowing rune" + desc = "This rune slowly lights up and goes dim in a repeating pattern, like a slow heartbeat. It's almost as if it's calling out to you to touch it..." + description_info = "This will summon some manner of creature through quite dubious means. The creature will be controlled by a player." + icon_state = "corgirune" + icon_state_opened = "corgirune-inert" + density = FALSE + anchored = TRUE + ghost_query_type = /datum/ghost_query/corgi_rune + confirm_before_open = TRUE + +/obj/structure/ghost_pod/manual/corgi/trigger() + ..("\The [usr] places their hand on the rune!", "is attempting to summon a corgi.") + +/obj/structure/ghost_pod/manual/corgi/create_occupant(var/mob/M) + density = FALSE + var/mob/living/simple_animal/corgi/R = new(get_turf(src)) + if(M.mind) + M.mind.transfer_to(R) + to_chat(M, "You are a Corgi! Woof!") + R.ckey = M.ckey + visible_message("With a bright flash of light, \the [src] disappears, and in its place stands a small corgi.") + log_and_message_admins("successfully touched \a [src] and summoned a corgi.") + ..() + +/obj/structure/ghost_pod/manual/cursedblade + name = "abandoned blade" + desc = "A red crystal blade that someone jammed deep into a stone. If you try hard enough, you might be able to remove it." + icon_state = "soulblade-embedded" + icon_state_opened = "soulblade-released" + density = TRUE + anchored = TRUE + ghost_query_type = /datum/ghost_query/cursedblade + confirm_before_open = TRUE + +/obj/structure/ghost_pod/manual/cursedblade/trigger() + ..("\The [usr] attempts to pull out the sword!", "is activating a cursed blade.") + +/obj/structure/ghost_pod/manual/cursedblade/create_occupant(var/mob/M) + density = FALSE + var/obj/item/weapon/melee/cursedblade/R = new(get_turf(src)) + to_chat(M, "You are a Cursed Sword, discovered by a hapless explorer. \ + You were once an explorer yourself, when one day you discovered a strange sword made from a red crystal. As soon as you touched it,\ + your body was reduced to ashes and your soul was cursed to remain trapped in the blade forever. \ + Now it is up to you to decide whether you want to be a faithful companion, or a bitter prisoner of the blade.") + R.ghost_inhabit(M) + visible_message("The blade shines brightly for a brief moment as [usr] pulls it out of the stone!") + log_and_message_admins("successfully acquired a cursed sword.") ..() \ No newline at end of file diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm index a3ff9ac9af..a22bbae0d2 100644 --- a/code/game/objects/structures/girders.dm +++ b/code/game/objects/structures/girders.dm @@ -2,7 +2,7 @@ icon_state = "girder" anchored = 1 density = 1 - layer = 2 + plane = PLATING_PLANE w_class = ITEMSIZE_HUGE var/state = 0 var/health = 200 diff --git a/code/game/objects/structures/gravemarker.dm b/code/game/objects/structures/gravemarker.dm index a10cd0bf6e..e20591b939 100644 --- a/code/game/objects/structures/gravemarker.dm +++ b/code/game/objects/structures/gravemarker.dm @@ -8,7 +8,7 @@ throwpass = 1 climbable = 1 - layer = 3.1 //Above dirt piles + layer = ABOVE_JUNK_LAYER //Maybe make these calculate based on material? var/health = 100 diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index 6fea7e6ece..ee80999916 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -7,7 +7,7 @@ anchored = 1 flags = CONDUCT pressure_resistance = 5*ONE_ATMOSPHERE - layer = 2.9 + layer = UNDER_JUNK_LAYER explosion_resistance = 1 var/health = 10 var/destroyed = 0 diff --git a/code/game/objects/structures/holoplant.dm b/code/game/objects/structures/holoplant.dm new file mode 100644 index 0000000000..1f6473ebdc --- /dev/null +++ b/code/game/objects/structures/holoplant.dm @@ -0,0 +1,105 @@ +/obj/machinery/holoplant + name = "holoplant" + desc = "One of those Ward-Takahashi holoplants! Give your space a bit of the comfort of being outdoors, by buying this blue buddy. A rugged case guarantees that your flower will outlive you, and variety of plant types won't let you to get bored along the way!" + icon = 'icons/obj/holoplants.dmi' + icon_state = "holopot" + light_color = "#3C94C5" + anchored = TRUE + idle_power_usage = 0 + active_power_usage = 5 + var/interference = FALSE + var/icon/plant = null + var/global/list/possible_plants = list( + "plant-1", + "plant-10", + "plant-09", + "plant-15", + "plant-13" + ) + +/obj/machinery/holoplant/initialize() + . = ..() + activate() + +/obj/machinery/holoplant/attack_hand(var/mob/living/user) + if(!istype(user) || interference) + return + + if(!anchored) + to_chat(user,"\The [src] must be anchored before activation!") + return + + if(!plant) + activate() + else + deactivate() + +/obj/machinery/holoplant/attackby(var/obj/item/O as obj, var/mob/user as mob) + if(default_unfasten_wrench(user, O, 10)) + deactivate() + return + + . = ..() + +/obj/machinery/holoplant/proc/activate() + if(!anchored || stat & (NOPOWER|BROKEN)) + return + + plant = prepare_icon(emagged ? "emagged" : null) + overlays += plant + set_light(2) + use_power = 2 + +/obj/machinery/holoplant/proc/deactivate() + overlays -= plant + qdel_null(plant) + set_light(0) + use_power = 0 + +/obj/machinery/holoplant/power_change() + ..() + if(stat & NOPOWER) + deactivate() + else + activate() + +/obj/machinery/holoplant/proc/flicker() + interference = TRUE + spawn(0) + overlays -= plant + set_light(0) + sleep(rand(2,4)) + overlays += plant + set_light(2) + sleep(rand(2,4)) + overlays -= plant + set_light(0) + sleep(rand(2,4)) + overlays += plant + set_light(2) + interference = FALSE + +/obj/machinery/holoplant/proc/prepare_icon(var/state) + if(!state) + state = pick(possible_plants) + var/plant_icon = icon(icon, state) + return getHologramIcon(plant_icon, 0) + +/obj/machinery/holoplant/emag_act() + if(emagged) + return + + emagged = TRUE + if(plant) + deactivate() + activate() + +/obj/machinery/holoplant/Crossed(var/mob/living/L) + if(!interference && plant && istype(L)) + flicker() + + +/obj/machinery/holoplant/shipped + anchored = FALSE +/obj/machinery/holoplant/shipped/initialize() + . = ..() \ No newline at end of file diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm index c042b8fc9a..d9ec122c55 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -6,7 +6,7 @@ density = 0 anchored = 1.0 w_class = ITEMSIZE_NORMAL - layer = 2.3 //under pipes + plane = PLATING_PLANE // flags = CONDUCT /obj/structure/lattice/initialize() diff --git a/code/game/objects/structures/loot_piles.dm b/code/game/objects/structures/loot_piles.dm index c9565dc90a..353dbe31a7 100644 --- a/code/game/objects/structures/loot_piles.dm +++ b/code/game/objects/structures/loot_piles.dm @@ -22,6 +22,8 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh density = FALSE anchored = TRUE + var/list/icon_states_to_use = list() // List of icon states the pile can choose from on initialization. If empty or null, it will stay the initial icon_state. + var/list/searched_by = list() // Keys that have searched this loot pile, with values of searched time. var/allow_multiple_looting = FALSE // If true, the same person can loot multiple times. Mostly for debugging. var/busy = FALSE // Used so you can't spamclick to loot. @@ -113,12 +115,9 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh var/path = pick(rare_loot) return new path(src) - -/obj/structure/loot_pile/maint - var/list/icon_states_to_use = list() - -/obj/structure/loot_pile/maint/initialize() - icon_state = pick(icon_states_to_use) +/obj/structure/loot_pile/initialize() + if(icon_states_to_use && icon_states_to_use.len) + icon_state = pick(icon_states_to_use) . = ..() // Has large amounts of possible items, most of which may or may not be useful. @@ -278,7 +277,6 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh /obj/item/weapon/storage/box/donut, /obj/item/weapon/storage/box/donut/empty, /obj/item/weapon/storage/box/evidence, - /obj/item/weapon/storage/box/engineer, /obj/item/weapon/storage/box/lights/mixed, /obj/item/weapon/storage/box/lights/tubes, /obj/item/weapon/storage/box/lights/bulbs, @@ -439,7 +437,7 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh // Base type for alien piles. /obj/structure/loot_pile/surface/alien name = "alien pod" - desc = "A pod which looks bigger on the inside. Something quiet shiny might be inside?" + desc = "A pod which looks bigger on the inside. Something quite shiny might be inside?" icon_state = "alien_pile1" /obj/structure/loot_pile/surface/alien @@ -569,3 +567,266 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh /obj/item/weapon/gun/launcher/crossbow ) +// Subtype for mecha and mecha accessories. These might not always be on the surface. +/obj/structure/loot_pile/mecha + name = "pod wreckage" + desc = "The ruins of some unfortunate pod. Perhaps something is salvageable." + icon = 'icons/mecha/mecha.dmi' + icon_state = "engineering_pod-broken" + density = TRUE + + chance_uncommon = 20 + chance_rare = 10 + + loot_depletion = TRUE + loot_left = 9 + + common_loot = list( + /obj/random/tool, + /obj/random/tool, + /obj/random/tool, + /obj/random/tool, + /obj/item/stack/cable_coil/random, + /obj/random/tank, + /obj/random/tech_supply/component, + /obj/random/tech_supply/component, + /obj/random/tech_supply/component, + /obj/effect/decal/remains/lizard, + /obj/effect/decal/remains/mouse, + /obj/effect/decal/remains/robot, + /obj/item/stack/material/steel{amount = 40} + ) + + uncommon_loot = list( + /obj/item/mecha_parts/mecha_equipment/weapon/energy/taser, + /obj/item/mecha_parts/mecha_equipment/weapon/energy/riggedlaser, + /obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp, + /obj/item/mecha_parts/mecha_equipment/tool/drill, + /obj/item/mecha_parts/mecha_equipment/generator + ) + + rare_loot = list( + /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser, + /obj/item/mecha_parts/mecha_equipment/generator/nuclear, + /obj/item/mecha_parts/mecha_equipment/tool/jetpack + ) + +//Stuff you may find attached to a ripley. +/obj/structure/loot_pile/mecha/ripley + name = "ripley wreckage" + desc = "The ruins of some unfortunate ripley. Perhaps something is salvageable." + icon_states_to_use = list("ripley-broken", "firefighter-broken", "ripley-broken-old") + + common_loot = list( + /obj/random/tool, + /obj/item/stack/cable_coil/random, + /obj/random/tank, + /obj/random/tech_supply/component, + /obj/item/stack/material/steel{amount = 25}, + /obj/item/stack/material/glass{amount = 10}, + /obj/item/stack/material/plasteel{amount = 5}, + /obj/item/mecha_parts/chassis/ripley, + /obj/item/mecha_parts/part/ripley_torso, + /obj/item/mecha_parts/part/ripley_left_arm, + /obj/item/mecha_parts/part/ripley_right_arm, + /obj/item/mecha_parts/part/ripley_left_leg, + /obj/item/mecha_parts/part/ripley_right_leg, + /obj/item/device/kit/paint/ripley, + /obj/item/device/kit/paint/ripley/flames_red, + /obj/item/device/kit/paint/ripley/flames_blue + ) + + uncommon_loot = list( + /obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp, + /obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill, + /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster, + /obj/item/mecha_parts/mecha_equipment/tool/extinguisher, + ) + + rare_loot = list( + /obj/item/mecha_parts/mecha_equipment/gravcatapult, + /obj/item/mecha_parts/mecha_equipment/tool/rcd, + /obj/item/mecha_parts/mecha_equipment/weapon/energy/flamer/rigged + ) + +//Death-Ripley, same common, but more combat-exosuit-based +/obj/structure/loot_pile/mecha/deathripley + name = "strange ripley wreckage" + icon_state = "deathripley-broken" + + common_loot = list( + /obj/random/tool, + /obj/item/stack/cable_coil/random, + /obj/random/tank, + /obj/random/tech_supply/component, + /obj/item/stack/material/steel{amount = 40}, + /obj/item/stack/material/glass{amount = 20}, + /obj/item/stack/material/plasteel{amount = 10}, + /obj/item/mecha_parts/chassis/ripley, + /obj/item/mecha_parts/part/ripley_torso, + /obj/item/mecha_parts/part/ripley_left_arm, + /obj/item/mecha_parts/part/ripley_right_arm, + /obj/item/mecha_parts/part/ripley_left_leg, + /obj/item/mecha_parts/part/ripley_right_leg, + /obj/item/device/kit/paint/ripley/death + ) + + uncommon_loot = list( + /obj/item/mecha_parts/mecha_equipment/tool/safety_clamp, + /obj/item/mecha_parts/mecha_equipment/weapon/energy/riggedlaser, + /obj/item/mecha_parts/mecha_equipment/repair_droid, + /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay + ) + + rare_loot = list( + /obj/item/mecha_parts/mecha_equipment/tool/rcd, + /obj/item/mecha_parts/mecha_equipment/wormhole_generator, + /obj/item/mecha_parts/mecha_equipment/weapon/energy/flamer/rigged + ) + +/obj/structure/loot_pile/mecha/odysseus + name = "odysseus wreckage" + desc = "The ruins of some unfortunate odysseus. Perhaps something is salvageable." + icon_state = "odysseus-broken" + + common_loot = list( + /obj/random/tool, + /obj/item/stack/cable_coil/random, + /obj/random/tank, + /obj/random/tech_supply/component, + /obj/item/stack/material/steel{amount = 25}, + /obj/item/stack/material/glass{amount = 10}, + /obj/item/stack/material/plasteel{amount = 5}, + /obj/item/mecha_parts/chassis/odysseus, + /obj/item/mecha_parts/part/odysseus_head, + /obj/item/mecha_parts/part/odysseus_torso, + /obj/item/mecha_parts/part/odysseus_left_arm, + /obj/item/mecha_parts/part/odysseus_right_arm, + /obj/item/mecha_parts/part/odysseus_left_leg, + /obj/item/mecha_parts/part/odysseus_right_leg + ) + + uncommon_loot = list( + /obj/item/mecha_parts/mecha_equipment/tool/sleeper, + /obj/item/mecha_parts/mecha_equipment/tool/syringe_gun, + /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flare, + /obj/item/mecha_parts/mecha_equipment/tool/extinguisher, + ) + + rare_loot = list( + /obj/item/mecha_parts/mecha_equipment/gravcatapult, + /obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster, + /obj/item/mecha_parts/mecha_equipment/shocker + ) + +/obj/structure/loot_pile/mecha/gygax + name = "gygax wreckage" + desc = "The ruins of some unfortunate gygax. Perhaps something is salvageable." + icon_state = "gygax-broken" + + common_loot = list( + /obj/random/tool, + /obj/item/stack/cable_coil/random, + /obj/random/tank, + /obj/random/tech_supply/component, + /obj/item/stack/material/steel{amount = 25}, + /obj/item/stack/material/glass{amount = 10}, + /obj/item/stack/material/plasteel{amount = 5}, + /obj/item/mecha_parts/chassis/gygax, + /obj/item/mecha_parts/part/gygax_head, + /obj/item/mecha_parts/part/gygax_torso, + /obj/item/mecha_parts/part/gygax_left_arm, + /obj/item/mecha_parts/part/gygax_right_arm, + /obj/item/mecha_parts/part/gygax_left_leg, + /obj/item/mecha_parts/part/gygax_right_leg, + /obj/item/mecha_parts/part/gygax_armour + ) + + uncommon_loot = list( + /obj/item/mecha_parts/mecha_equipment/shocker, + /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang, + /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser, + /obj/item/mecha_parts/mecha_equipment/weapon/energy/taser, + /obj/item/device/kit/paint/gygax, + /obj/item/device/kit/paint/gygax/darkgygax, + /obj/item/device/kit/paint/gygax/recitence + ) + + rare_loot = list( + /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay, + /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg, + /obj/item/mecha_parts/mecha_equipment/repair_droid, + /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy + ) + +/obj/structure/loot_pile/mecha/durand + name = "durand wreckage" + desc = "The ruins of some unfortunate durand. Perhaps something is salvageable." + icon_state = "durand-broken" + + common_loot = list( + /obj/random/tool, + /obj/item/stack/cable_coil/random, + /obj/random/tank, + /obj/random/tech_supply/component, + /obj/item/stack/material/steel{amount = 25}, + /obj/item/stack/material/glass{amount = 10}, + /obj/item/stack/material/plasteel{amount = 5}, + /obj/item/mecha_parts/chassis/durand, + /obj/item/mecha_parts/part/durand_head, + /obj/item/mecha_parts/part/durand_torso, + /obj/item/mecha_parts/part/durand_left_arm, + /obj/item/mecha_parts/part/durand_right_arm, + /obj/item/mecha_parts/part/durand_left_leg, + /obj/item/mecha_parts/part/durand_right_leg, + /obj/item/mecha_parts/part/durand_armour + ) + + uncommon_loot = list( + /obj/item/mecha_parts/mecha_equipment/shocker, + /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang, + /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser, + /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster, + /obj/item/device/kit/paint/durand, + /obj/item/device/kit/paint/durand/seraph, + /obj/item/device/kit/paint/durand/phazon + ) + + rare_loot = list( + /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay, + /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot, + /obj/item/mecha_parts/mecha_equipment/repair_droid, + /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy + ) + +/obj/structure/loot_pile/mecha/phazon + name = "phazon wreckage" + desc = "The ruins of some unfortunate phazon. Perhaps something is salvageable." + icon_state = "phazon-broken" + + common_loot = list( + /obj/item/weapon/storage/toolbox/syndicate/powertools, + /obj/item/stack/material/plasteel{amount = 20}, + /obj/item/stack/material/durasteel{amount = 10}, + /obj/item/mecha_parts/chassis/phazon, + /obj/item/mecha_parts/part/phazon_head, + /obj/item/mecha_parts/part/phazon_torso, + /obj/item/mecha_parts/part/phazon_left_arm, + /obj/item/mecha_parts/part/phazon_right_arm, + /obj/item/mecha_parts/part/phazon_left_leg, + /obj/item/mecha_parts/part/phazon_right_leg + ) + + uncommon_loot = list( + /obj/item/mecha_parts/mecha_equipment/shocker, + /obj/item/mecha_parts/mecha_equipment/weapon/energy/flamer/rigged, + /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy, + /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster + ) + + rare_loot = list( + /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay, + /obj/item/mecha_parts/mecha_equipment/weapon/energy/ion, + /obj/item/mecha_parts/mecha_equipment/repair_droid, + /obj/item/mecha_parts/mecha_equipment/teleporter + ) diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index 2030167b86..1e8237cdfd 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -123,10 +123,10 @@ /obj/structure/mirror/raider/attack_hand(var/mob/living/carbon/human/user) if(istype(get_area(src),/area/syndicate_mothership)) - if(istype(user) && user.mind && user.mind.special_role == "Raider" && user.species.name != "Vox" && is_alien_whitelisted(user, "Vox")) + if(istype(user) && user.mind && user.mind.special_role == "Raider" && user.species.name != SPECIES_VOX && is_alien_whitelisted(user, SPECIES_VOX)) var/choice = input("Do you wish to become a true Vox of the Shoal? This is not reversible.") as null|anything in list("No","Yes") if(choice && choice == "Yes") - var/mob/living/carbon/human/vox/vox = new(get_turf(src),"Vox") + var/mob/living/carbon/human/vox/vox = new(get_turf(src),SPECIES_VOX) vox.gender = user.gender raiders.equip(vox) if(user.mind) diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index d795d53e3d..d0324c98bf 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -148,7 +148,7 @@ icon = 'icons/obj/stationobjs.dmi' icon_state = "morguet" density = 1 - layer = 2.0 + plane = TURF_PLANE var/obj/structure/morgue/connected = null anchored = 1 throwpass = 1 @@ -306,10 +306,6 @@ if (C.can_feel_pain()) C.emote("scream") - //Logging for this causes runtimes resulting in the cremator locking up. Commenting it out until that's figured out. - //M.attack_log += "\[[time_stamp()]\] Has been cremated by [user]/[user.ckey]" //No point in this when the mob's about to be deleted - //user.attack_log +="\[[time_stamp()]\] Cremated [M]/[M.ckey]" - //log_attack("\[[time_stamp()]\] [user]/[user.ckey] cremated [M]/[M.ckey]") M.death(1) M.ghostize() qdel(M) diff --git a/code/game/objects/structures/railing.dm b/code/game/objects/structures/railing.dm index 27bb902aea..e67750b8f3 100644 --- a/code/game/objects/structures/railing.dm +++ b/code/game/objects/structures/railing.dm @@ -6,7 +6,7 @@ density = 1 throwpass = 1 climbable = 1 - layer = 3.2 //Just above doors + layer = WINDOW_LAYER anchored = 1 flags = ON_BORDER icon_state = "railing0" diff --git a/code/game/objects/structures/safe.dm b/code/game/objects/structures/safe.dm index 7f78e8f0e7..37edb603c1 100644 --- a/code/game/objects/structures/safe.dm +++ b/code/game/objects/structures/safe.dm @@ -172,7 +172,8 @@ obj/structure/safe/ex_act(severity) icon_state = "floorsafe" density = 0 level = 1 //underfloor - layer = 2.5 + plane = TURF_PLANE + layer = ABOVE_UTILITY /obj/structure/safe/floor/initialize() . = ..() diff --git a/code/game/objects/structures/signs.dm b/code/game/objects/structures/signs.dm index 1d68de0d25..33c6d6501c 100644 --- a/code/game/objects/structures/signs.dm +++ b/code/game/objects/structures/signs.dm @@ -3,7 +3,7 @@ anchored = 1 opacity = 0 density = 0 - layer = 3.5 + layer = ABOVE_JUNK_LAYER w_class = ITEMSIZE_NORMAL /obj/structure/sign/ex_act(severity) diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm index ed9c4e0301..390e3c84b9 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm @@ -47,15 +47,17 @@ if(isnull(stool_cache[cache_key])) var/image/I = image(icon, "[base_icon]_armrest") I.layer = MOB_LAYER + 0.1 + I.plane = MOB_PLANE I.color = padding_material.icon_colour stool_cache[cache_key] = I overlays |= stool_cache[cache_key] /obj/structure/bed/chair/proc/update_layer() if(src.dir == NORTH) - src.layer = FLY_LAYER + plane = MOB_PLANE + layer = MOB_LAYER + 0.1 else - src.layer = OBJ_LAYER + reset_plane_and_layer() /obj/structure/bed/chair/set_dir() ..() diff --git a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm index 550b59d112..bb1a62e40b 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm @@ -176,9 +176,7 @@ if(pulling) occupant.visible_message("[pulling] has thrusted \the [name] into \the [A], throwing \the [occupant] out of it!") - pulling.attack_log += "\[[time_stamp()]\] Crashed [occupant.name]'s ([occupant.ckey]) [name] into \a [A]" - occupant.attack_log += "\[[time_stamp()]\] Thrusted into \a [A] by [pulling.name] ([pulling.ckey]) with \the [name]" - msg_admin_attack("[pulling.name] ([pulling.ckey]) has thrusted [occupant.name]'s ([occupant.ckey]) [name] into \a [A] (JMP)") + add_attack_logs(pulling,occupant,"Crashed their [name] into [A]") else occupant.visible_message("[occupant] crashed into \the [A]!") diff --git a/code/game/objects/structures/target_stake.dm b/code/game/objects/structures/target_stake.dm index 83396b363e..646e52218c 100644 --- a/code/game/objects/structures/target_stake.dm +++ b/code/game/objects/structures/target_stake.dm @@ -29,7 +29,7 @@ W.density = 1 user.remove_from_mob(W) W.loc = loc - W.layer = 3.1 + W.layer = ABOVE_JUNK_LAYER pinned_target = W user << "You slide the target into the stake." return diff --git a/code/game/objects/structures/transit_tubes.dm b/code/game/objects/structures/transit_tubes.dm index 0f9b4a603a..c260103a56 100644 --- a/code/game/objects/structures/transit_tubes.dm +++ b/code/game/objects/structures/transit_tubes.dm @@ -7,7 +7,7 @@ icon = 'icons/obj/pipes/transit_tube.dmi' icon_state = "E-W" density = 1 - layer = 3.1 + layer = ABOVE_JUNK_LAYER anchored = 1.0 var/list/tube_dirs = null var/exit_delay = 2 diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index f4f1deff28..36da7485ad 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -5,7 +5,7 @@ density = 1 w_class = ITEMSIZE_NORMAL - layer = 3.2//Just above doors + layer = WINDOW_LAYER pressure_resistance = 4*ONE_ATMOSPHERE anchored = 1.0 flags = ON_BORDER @@ -294,6 +294,21 @@ if(is_fulltile()) mats.amount = 4 qdel(src) + else if(iscoil(W) && reinf && state == 0 && !istype(src, /obj/structure/window/reinforced/polarized)) + var/obj/item/stack/cable_coil/C = W + if (C.use(1)) + playsound(src.loc, 'sound/effects/sparks1.ogg', 75, 1) + user.visible_message( \ + "\The [user] begins to wire \the [src] for electrochromic tinting.", \ + "You begin to wire \the [src] for electrochromic tinting.", \ + "You hear sparks.") + if(do_after(user, 20 * C.toolspeed, src) && state == 0) + playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) + var/obj/structure/window/reinforced/polarized/P = new(loc, dir) + P.health = health + P.state = state + P.anchored = anchored + qdel(src) else if(istype(W,/obj/item/frame) && anchored) var/obj/item/frame/F = W F.try_build(src) @@ -447,7 +462,7 @@ if(ratio > 75) return - var/image/I = image(icon, "damage[ratio]", layer + 0.1) + var/image/I = image(icon, "damage[ratio]", layer = layer + 0.1) overlays += I return @@ -551,6 +566,28 @@ desc = "Adjusts its tint with voltage. Might take a few good hits to shatter it." var/id +/obj/structure/window/reinforced/polarized/full + dir = SOUTHWEST + icon_state = "fwindow" + maxhealth = 80 + +/obj/structure/window/reinforced/polarized/attackby(obj/item/W as obj, mob/user as mob) + if(ismultitool(W) && !anchored) // Only allow programming if unanchored! + var/obj/item/device/multitool/MT = W + // First check if they have a windowtint button buffered + if(istype(MT.connectable, /obj/machinery/button/windowtint)) + var/obj/machinery/button/windowtint/buffered_button = MT.connectable + src.id = buffered_button.id + to_chat(user, "\The [src] is linked to \the [buffered_button].") + return TRUE + // Otherwise fall back to asking them + var/t = sanitizeSafe(input(user, "Enter the ID for the window.", src.name, null), MAX_NAME_LEN) + if (!t && user.get_active_hand() != W && in_range(src, user)) + src.id = t + to_chat(user, "The new ID of \the [src] is [id]") + return TRUE + . = ..() + /obj/structure/window/reinforced/polarized/proc/toggle() if(opacity) animate(src, color="#FFFFFF", time=5) @@ -593,3 +630,20 @@ /obj/machinery/button/windowtint/update_icon() icon_state = "light[active]" + +/obj/machinery/button/windowtint/attackby(obj/item/W as obj, mob/user as mob) + if(ismultitool(W)) + var/obj/item/device/multitool/MT = W + if(!id) + // If no ID is set yet (newly built button?) let them select an ID for first-time use! + var/t = sanitizeSafe(input(user, "Enter an ID for \the [src].", src.name, null), MAX_NAME_LEN) + if (t && user.get_active_hand() != W && in_range(src, user)) + src.id = t + to_chat(user, "The new ID of \the [src] is [id]") + if(id) + // It already has an ID (or they just set one), buffer it for copying to windows. + to_chat(user, "You store \the [src] in \the [MT]'s buffer!") + MT.connectable = src + MT.update_icon() + return TRUE + . = ..() diff --git a/code/game/sound.dm b/code/game/sound.dm index afeeaafcae..2db1e433bd 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -1,107 +1,50 @@ -//Sound environment defines. Reverb preset for sounds played in an area, see sound datum reference for more. -#define GENERIC 0 -#define PADDED_CELL 1 -#define ROOM 2 -#define BATHROOM 3 -#define LIVINGROOM 4 -#define STONEROOM 5 -#define AUDITORIUM 6 -#define CONCERT_HALL 7 -#define CAVE 8 -#define ARENA 9 -#define HANGAR 10 -#define CARPETED_HALLWAY 11 -#define HALLWAY 12 -#define STONE_CORRIDOR 13 -#define ALLEY 14 -#define FOREST 15 -#define CITY 16 -#define MOUNTAINS 17 -#define QUARRY 18 -#define PLAIN 19 -#define PARKING_LOT 20 -#define SEWER_PIPE 21 -#define UNDERWATER 22 -#define DRUGGED 23 -#define DIZZY 24 -#define PSYCHOTIC 25 - -#define STANDARD_STATION STONEROOM -#define LARGE_ENCLOSED HANGAR -#define SMALL_ENCLOSED BATHROOM -#define TUNNEL_ENCLOSED CAVE -#define LARGE_SOFTFLOOR CARPETED_HALLWAY -#define MEDIUM_SOFTFLOOR LIVINGROOM -#define SMALL_SOFTFLOOR ROOM -#define ASTEROID CAVE -#define SPACE UNDERWATER - -var/list/shatter_sound = list('sound/effects/Glassbr1.ogg','sound/effects/Glassbr2.ogg','sound/effects/Glassbr3.ogg') -var/list/explosion_sound = list('sound/effects/Explosion1.ogg','sound/effects/Explosion2.ogg','sound/effects/Explosion3.ogg','sound/effects/Explosion4.ogg','sound/effects/Explosion5.ogg','sound/effects/Explosion6.ogg') -var/list/spark_sound = list('sound/effects/sparks1.ogg','sound/effects/sparks2.ogg','sound/effects/sparks3.ogg','sound/effects/sparks5.ogg','sound/effects/sparks6.ogg','sound/effects/sparks7.ogg') -var/list/rustle_sound = list('sound/effects/rustle1.ogg','sound/effects/rustle2.ogg','sound/effects/rustle3.ogg','sound/effects/rustle4.ogg','sound/effects/rustle5.ogg') -var/list/punch_sound = list('sound/weapons/punch1.ogg','sound/weapons/punch2.ogg','sound/weapons/punch3.ogg','sound/weapons/punch4.ogg') -var/list/clown_sound = list('sound/effects/clownstep1.ogg','sound/effects/clownstep2.ogg') -var/list/swing_hit_sound = list('sound/weapons/genhit1.ogg', 'sound/weapons/genhit2.ogg', 'sound/weapons/genhit3.ogg') -var/list/hiss_sound = list('sound/voice/hiss1.ogg','sound/voice/hiss2.ogg','sound/voice/hiss3.ogg','sound/voice/hiss4.ogg') -var/list/page_sound = list('sound/effects/pageturn1.ogg', 'sound/effects/pageturn2.ogg','sound/effects/pageturn3.ogg') -var/list/fracture_sound = list('sound/effects/bonebreak1.ogg','sound/effects/bonebreak2.ogg','sound/effects/bonebreak3.ogg','sound/effects/bonebreak4.ogg') -var/list/casing_sound = list ('sound/weapons/casingfall1.ogg','sound/weapons/casingfall2.ogg','sound/weapons/casingfall3.ogg') -var/list/keyboard_sound = list ('sound/effects/keyboard/keyboard1.ogg','sound/effects/keyboard/keyboard2.ogg','sound/effects/keyboard/keyboard3.ogg', 'sound/effects/keyboard/keyboard4.ogg') -var/list/mechstep_sound = list('sound/mecha/mechstep1.ogg', 'sound/mecha/mechstep2.ogg') -var/list/bodyfall_sound = list('sound/effects/bodyfall1.ogg','sound/effects/bodyfall2.ogg','sound/effects/bodyfall3.ogg','sound/effects/bodyfall4.ogg') -var/list/can_sound = list('sound/effects/can_open1.ogg','sound/effects/can_open2.ogg','sound/effects/can_open3.ogg','sound/effects/can_open4.ogg') -var/list/geiger_sound = list('sound/items/geiger1.ogg', 'sound/items/geiger2.ogg', 'sound/items/geiger3.ogg', 'sound/items/geiger4.ogg', 'sound/items/geiger5.ogg') -var/list/geiger_weak_sound = list('sound/items/geiger_weak1.ogg', 'sound/items/geiger_weak2.ogg', 'sound/items/geiger_weak3.ogg', 'sound/items/geiger_weak4.ogg') - -//var/list/gun_sound = list('sound/weapons/Gunshot.ogg', 'sound/weapons/Gunshot2.ogg','sound/weapons/Gunshot3.ogg','sound/weapons/Gunshot4.ogg') - -/proc/playsound(var/atom/source, soundin, vol as num, vary, extrarange as num, falloff, var/is_global, var/frequency) - - soundin = get_sfx(soundin) // same sound for everyone - +/proc/playsound(atom/source, soundin, vol as num, vary, extrarange as num, falloff, is_global, frequency = null, channel = 0, pressure_affected = TRUE, ignore_walls = TRUE, preference = null) if(isarea(source)) - error("[source] is an area and is trying to make the sound: [soundin]") + throw EXCEPTION("playsound(): source is an area") return - frequency = isnull(frequency) ? get_rand_frequency() : frequency // Same frequency for everybody var/turf/turf_source = get_turf(source) + //allocate a channel if necessary now so its the same for everyone + channel = channel || open_sound_channel() + // Looping through the player list has the added bonus of working for mobs inside containers - for (var/P in player_list) + var/sound/S = sound(get_sfx(soundin)) + var/maxdistance = (world.view + extrarange) * 3 + var/list/listeners = player_list + if(!ignore_walls) //these sounds don't carry through walls + listeners = listeners & hearers(maxdistance,turf_source) + for(var/P in listeners) var/mob/M = P if(!M || !M.client) continue + var/turf/T = get_turf(M) + var/distance = get_dist(T, turf_source) - var/distance = get_dist(M, turf_source) - if(distance <= (world.view + extrarange) * 3) - var/turf/T = get_turf(M) - + if(distance <= maxdistance) if(T && T.z == turf_source.z) - M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, is_global) + M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, is_global, channel, pressure_affected, S) -var/const/FALLOFF_SOUNDS = 0.5 +/mob/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff, is_global, channel = 0, pressure_affected = TRUE, sound/S, preference) + if(!client || ear_deaf > 0) + return + if(preference && !client.is_preference_enabled(preference)) + return -/mob/proc/playsound_local(var/turf/turf_source, soundin, vol as num, vary, frequency, falloff, is_global) - if(!src.client || ear_deaf > 0) return - soundin = get_sfx(soundin) + if(!S) + S = sound(get_sfx(soundin)) - var/sound/S = sound(soundin) S.wait = 0 //No queue - S.channel = 0 //Any channel + S.channel = channel || open_sound_channel() S.volume = vol - S.environment = -1 - if (vary) + + if(vary) if(frequency) S.frequency = frequency else S.frequency = get_rand_frequency() - //sound volume falloff with pressure - var/pressure_factor = 1.0 - if(isturf(turf_source)) - // 3D sounds, the technology is here! var/turf/T = get_turf(src) //sound volume falloff with distance @@ -109,24 +52,32 @@ var/const/FALLOFF_SOUNDS = 0.5 S.volume -= max(distance - world.view, 0) * 2 //multiplicative falloff to add on top of natural audio falloff. - var/datum/gas_mixture/hearer_env = T.return_air() - var/datum/gas_mixture/source_env = turf_source.return_air() + //Atmosphere affects sound + var/pressure_factor = 1 + if(pressure_affected) + var/datum/gas_mixture/hearer_env = T.return_air() + var/datum/gas_mixture/source_env = turf_source.return_air() - if (hearer_env && source_env) - var/pressure = min(hearer_env.return_pressure(), source_env.return_pressure()) + if(hearer_env && source_env) + var/pressure = min(hearer_env.return_pressure(), source_env.return_pressure()) + if(pressure < ONE_ATMOSPHERE) + pressure_factor = max((pressure - SOUND_MINIMUM_PRESSURE)/(ONE_ATMOSPHERE - SOUND_MINIMUM_PRESSURE), 0) + else //space + pressure_factor = 0 - if (pressure < ONE_ATMOSPHERE) - pressure_factor = max((pressure - SOUND_MINIMUM_PRESSURE)/(ONE_ATMOSPHERE - SOUND_MINIMUM_PRESSURE), 0) - else //in space - pressure_factor = 0 + if(distance <= 1) + pressure_factor = max(pressure_factor, 0.15) //touching the source of the sound - if (distance <= 1) - pressure_factor = max(pressure_factor, 0.15) //hearing through contact + S.volume *= pressure_factor + //End Atmosphere affecting sound - S.volume *= pressure_factor + //Don't bother with doing anything below. + if(S.volume <= 0) + return //No sound - if (S.volume <= 0) - return //no volume means no sound + //Apply a sound environment. + if(!is_global) + S.environment = get_sound_env(pressure_factor) var/dx = turf_source.x - T.x // Hearing from the right/left S.x = dx @@ -136,58 +87,52 @@ var/const/FALLOFF_SOUNDS = 0.5 S.y = 1 S.falloff = (falloff ? falloff : FALLOFF_SOUNDS) - if(!is_global) - - if(istype(src,/mob/living/)) - var/mob/living/M = src - if (M.hallucination) - S.environment = PSYCHOTIC - else if (M.druggy) - S.environment = DRUGGED - else if (M.drowsyness) - S.environment = DIZZY - else if (M.confused) - S.environment = DIZZY - else if (M.sleeping) - S.environment = UNDERWATER - else if (pressure_factor < 0.5) - S.environment = SPACE - else - var/area/A = get_area(src) - S.environment = A.sound_env - - else if (pressure_factor < 0.5) - S.environment = SPACE - else - var/area/A = get_area(src) - S.environment = A.sound_env - src << S +/proc/sound_to_playing_players(sound, volume = 100, vary) + sound = get_sfx(sound) + for(var/M in player_list) + if(ismob(M) && !isnewplayer(M)) + var/mob/MO = M + MO.playsound_local(get_turf(MO), sound, volume, vary, pressure_affected = FALSE) + +/proc/open_sound_channel() + var/static/next_channel = 1 //loop through the available 1024 - (the ones we reserve) channels and pray that its not still being used + . = ++next_channel + if(next_channel > CHANNEL_HIGHEST_AVAILABLE) + next_channel = 1 + +/mob/proc/stop_sound_channel(chan) + src << sound(null, repeat = 0, wait = 0, channel = chan) + +/proc/get_rand_frequency() + return rand(32000, 55000) //Frequency stuff only works with 45kbps oggs. + /client/proc/playtitlemusic() if(!ticker || !ticker.login_music) return if(is_preference_enabled(/datum/client_preference/play_lobby_music)) src << sound(ticker.login_music, repeat = 0, wait = 0, volume = 85, channel = 1) // MAD JAMS -/proc/get_rand_frequency() - return rand(32000, 55000) //Frequency stuff only works with 45kbps oggs. - /proc/get_sfx(soundin) if(istext(soundin)) switch(soundin) - if ("shatter") soundin = pick(shatter_sound) - if ("explosion") soundin = pick(explosion_sound) - if ("sparks") soundin = pick(spark_sound) - if ("rustle") soundin = pick(rustle_sound) - if ("punch") soundin = pick(punch_sound) - if ("clownstep") soundin = pick(clown_sound) - if ("swing_hit") soundin = pick(swing_hit_sound) - if ("hiss") soundin = pick(hiss_sound) - if ("pageturn") soundin = pick(page_sound) - if ("fracture") soundin = pick(fracture_sound) - if ("canopen") soundin = pick(can_sound) - if ("mechstep") soundin = pick(mechstep_sound) - //if ("gunshot") soundin = pick(gun_sound) - if("geiger") soundin = pick(geiger_sound) - if("geiger_weak") soundin = pick(geiger_weak_sound) + if ("shatter") soundin = pick('sound/effects/Glassbr1.ogg','sound/effects/Glassbr2.ogg','sound/effects/Glassbr3.ogg') + if ("explosion") soundin = pick('sound/effects/Explosion1.ogg','sound/effects/Explosion2.ogg','sound/effects/Explosion3.ogg','sound/effects/Explosion4.ogg','sound/effects/Explosion5.ogg','sound/effects/Explosion6.ogg') + if ("sparks") soundin = pick('sound/effects/sparks1.ogg','sound/effects/sparks2.ogg','sound/effects/sparks3.ogg','sound/effects/sparks5.ogg','sound/effects/sparks6.ogg','sound/effects/sparks7.ogg') + if ("rustle") soundin = pick('sound/effects/rustle1.ogg','sound/effects/rustle2.ogg','sound/effects/rustle3.ogg','sound/effects/rustle4.ogg','sound/effects/rustle5.ogg') + if ("punch") soundin = pick('sound/weapons/punch1.ogg','sound/weapons/punch2.ogg','sound/weapons/punch3.ogg','sound/weapons/punch4.ogg') + if ("clownstep") soundin = pick('sound/effects/clownstep1.ogg','sound/effects/clownstep2.ogg') + if ("swing_hit") soundin = pick('sound/weapons/genhit1.ogg', 'sound/weapons/genhit2.ogg', 'sound/weapons/genhit3.ogg') + if ("hiss") soundin = pick('sound/voice/hiss1.ogg','sound/voice/hiss2.ogg','sound/voice/hiss3.ogg','sound/voice/hiss4.ogg') + if ("pageturn") soundin = pick('sound/effects/pageturn1.ogg', 'sound/effects/pageturn2.ogg','sound/effects/pageturn3.ogg') + if ("fracture") soundin = pick('sound/effects/bonebreak1.ogg','sound/effects/bonebreak2.ogg','sound/effects/bonebreak3.ogg','sound/effects/bonebreak4.ogg') + if ("canopen") soundin = pick('sound/effects/can_open1.ogg','sound/effects/can_open2.ogg','sound/effects/can_open3.ogg','sound/effects/can_open4.ogg') + if ("mechstep") soundin = pick('sound/mecha/mechstep1.ogg', 'sound/mecha/mechstep2.ogg') + if ("geiger") soundin = pick('sound/items/geiger1.ogg', 'sound/items/geiger2.ogg', 'sound/items/geiger3.ogg', 'sound/items/geiger4.ogg', 'sound/items/geiger5.ogg') + if ("geiger_weak") soundin = pick('sound/items/geiger_weak1.ogg', 'sound/items/geiger_weak2.ogg', 'sound/items/geiger_weak3.ogg', 'sound/items/geiger_weak4.ogg') return soundin + +//Are these even used? +var/list/casing_sound = list ('sound/weapons/casingfall1.ogg','sound/weapons/casingfall2.ogg','sound/weapons/casingfall3.ogg') +var/list/keyboard_sound = list ('sound/effects/keyboard/keyboard1.ogg','sound/effects/keyboard/keyboard2.ogg','sound/effects/keyboard/keyboard3.ogg', 'sound/effects/keyboard/keyboard4.ogg') +var/list/bodyfall_sound = list('sound/effects/bodyfall1.ogg','sound/effects/bodyfall2.ogg','sound/effects/bodyfall3.ogg','sound/effects/bodyfall4.ogg') diff --git a/code/game/supplyshuttle.dm b/code/game/supplyshuttle.dm index f9331eac1d..3cc0bb8ab9 100644 --- a/code/game/supplyshuttle.dm +++ b/code/game/supplyshuttle.dm @@ -1,8 +1,8 @@ //Config stuff -#define SUPPLY_DOCKZ 2 //Z-level of the Dock. -#define SUPPLY_STATIONZ 1 //Z-level of the Station. -#define SUPPLY_STATION_AREATYPE "/area/supply/station" //Type of the supply shuttle area for station -#define SUPPLY_DOCK_AREATYPE "/area/supply/dock" //Type of the supply shuttle area for dock +#define SUPPLY_DOCKZ 2 //Z-level of the Dock. +#define SUPPLY_STATIONZ 1 //Z-level of the Station. +#define SUPPLY_STATION_AREATYPE "/area/supply/station" //Type of the supply shuttle area for station +#define SUPPLY_DOCK_AREATYPE "/area/supply/dock" //Type of the supply shuttle area for dock //Supply packs are in /code/defines/obj/supplypacks.dm //Computers are in /code/game/machinery/computer/supply.dm @@ -10,304 +10,324 @@ var/datum/controller/supply/supply_controller = new() var/list/mechtoys = list( - /obj/item/toy/prize/ripley, - /obj/item/toy/prize/fireripley, - /obj/item/toy/prize/deathripley, - /obj/item/toy/prize/gygax, - /obj/item/toy/prize/durand, - /obj/item/toy/prize/honk, - /obj/item/toy/prize/marauder, - /obj/item/toy/prize/seraph, - /obj/item/toy/prize/mauler, - /obj/item/toy/prize/odysseus, - /obj/item/toy/prize/phazon + /obj/item/toy/prize/ripley, + /obj/item/toy/prize/fireripley, + /obj/item/toy/prize/deathripley, + /obj/item/toy/prize/gygax, + /obj/item/toy/prize/durand, + /obj/item/toy/prize/honk, + /obj/item/toy/prize/marauder, + /obj/item/toy/prize/seraph, + /obj/item/toy/prize/mauler, + /obj/item/toy/prize/odysseus, + /obj/item/toy/prize/phazon ) /obj/item/weapon/paper/manifest - name = "supply manifest" - var/is_copy = 1 + name = "supply manifest" + var/is_copy = 1 /area/supply/station - name = "Supply Shuttle" - icon_state = "shuttle3" - requires_power = 0 - base_turf = /turf/space + name = "Supply Shuttle" + icon_state = "shuttle3" + requires_power = 0 + base_turf = /turf/space /area/supply/dock - name = "Supply Shuttle" - icon_state = "shuttle3" - requires_power = 0 - base_turf = /turf/space + name = "Supply Shuttle" + icon_state = "shuttle3" + requires_power = 0 + base_turf = /turf/space /obj/structure/plasticflaps //HOW DO YOU CALL THOSE THINGS ANYWAY - name = "\improper plastic flaps" - desc = "Completely impassable - or are they?" - icon = 'icons/obj/stationobjs.dmi' //Change this. - icon_state = "plasticflaps" - density = 0 - anchored = 1 - layer = 4 - explosion_resistance = 5 - var/list/mobs_can_pass = list( - /mob/living/bot, - /mob/living/simple_animal/slime, - /mob/living/simple_animal/mouse, - /mob/living/silicon/robot/drone - ) + name = "\improper plastic flaps" + desc = "Completely impassable - or are they?" + icon = 'icons/obj/stationobjs.dmi' //Change this. + icon_state = "plasticflaps" + density = 0 + anchored = 1 + layer = MOB_LAYER + plane = MOB_PLANE + explosion_resistance = 5 + var/list/mobs_can_pass = list( + /mob/living/bot, + /mob/living/simple_animal/slime, + /mob/living/simple_animal/mouse, + /mob/living/silicon/robot/drone + ) /obj/structure/plasticflaps/attackby(obj/item/P, mob/user) - if(istype(P, /obj/item/weapon/wirecutters)) - playsound(src, P.usesound, 50, 1) - user << "You start to cut the plastic flaps." - if(do_after(user, 10 * P.toolspeed)) - user << "You cut the plastic flaps." - var/obj/item/stack/material/plastic/A = new /obj/item/stack/material/plastic( src.loc ) - A.amount = 4 - qdel(src) - return - else - return + if(istype(P, /obj/item/weapon/wirecutters)) + playsound(src, P.usesound, 50, 1) + user << "You start to cut the plastic flaps." + if(do_after(user, 10 * P.toolspeed)) + user << "You cut the plastic flaps." + var/obj/item/stack/material/plastic/A = new /obj/item/stack/material/plastic( src.loc ) + A.amount = 4 + qdel(src) + return + else + return /obj/structure/plasticflaps/CanPass(atom/A, turf/T) - if(istype(A) && A.checkpass(PASSGLASS)) - return prob(60) + if(istype(A) && A.checkpass(PASSGLASS)) + return prob(60) - var/obj/structure/bed/B = A - if (istype(A, /obj/structure/bed) && B.has_buckled_mobs())//if it's a bed/chair and someone is buckled, it will not pass - return 0 + var/obj/structure/bed/B = A + if (istype(A, /obj/structure/bed) && B.has_buckled_mobs())//if it's a bed/chair and someone is buckled, it will not pass + return 0 - if(istype(A, /obj/vehicle)) //no vehicles - return 0 + if(istype(A, /obj/vehicle)) //no vehicles + return 0 - var/mob/living/M = A - if(istype(M)) - if(M.lying) - return ..() - for(var/mob_type in mobs_can_pass) - if(istype(A, mob_type)) - return ..() - return issmall(M) + var/mob/living/M = A + if(istype(M)) + if(M.lying) + return ..() + for(var/mob_type in mobs_can_pass) + if(istype(A, mob_type)) + return ..() + return issmall(M) - return ..() + return ..() /obj/structure/plasticflaps/ex_act(severity) - switch(severity) - if (1) - qdel(src) - if (2) - if (prob(50)) - qdel(src) - if (3) - if (prob(5)) - qdel(src) + switch(severity) + if (1) + qdel(src) + if (2) + if (prob(50)) + qdel(src) + if (3) + if (prob(5)) + qdel(src) /obj/structure/plasticflaps/mining //A specific type for mining that doesn't allow airflow because of them damn crates - name = "airtight plastic flaps" - desc = "Heavy duty, airtight, plastic flaps." + name = "airtight plastic flaps" + desc = "Heavy duty, airtight, plastic flaps." - New() //set the turf below the flaps to block air - var/turf/T = get_turf(loc) - if(T) - T.blocks_air = 1 - ..() +/obj/structure/plasticflaps/mining/New() //set the turf below the flaps to block air + var/turf/T = get_turf(loc) + if(T) + T.blocks_air = 1 + ..() - Destroy() //lazy hack to set the turf to allow air to pass if it's a simulated floor - var/turf/T = get_turf(loc) - if(T) - if(istype(T, /turf/simulated/floor)) - T.blocks_air = 0 - ..() +/obj/structure/plasticflaps/mining/Destroy() //lazy hack to set the turf to allow air to pass if it's a simulated floor + var/turf/T = get_turf(loc) + if(T && istype(T, /turf/simulated/floor)) + T.blocks_air = 0 + ..() /* /obj/effect/marker/supplymarker - icon_state = "X" - icon = 'icons/misc/mark.dmi' - name = "X" - invisibility = 101 - anchored = 1 - opacity = 0 + icon_state = "X" + icon = 'icons/misc/mark.dmi' + name = "X" + invisibility = 101 + anchored = 1 + opacity = 0 */ /datum/supply_order - var/ordernum - var/datum/supply_packs/object = null - var/orderedby = null - var/comment = null + var/ordernum + var/datum/supply_packs/object = null + var/orderedby = null + var/comment = null + +/datum/exported_crate + var/name + var/value /datum/controller/supply - //supply points - var/points = 50 - var/points_per_process = 1.5 - var/points_per_slip = 2 - var/points_per_platinum = 5 // 5 points per sheet - var/points_per_phoron = 5 - var/points_per_money = 0.02 - //control - var/ordernum - var/list/shoppinglist = list() - var/list/requestlist = list() - var/list/supply_packs = list() - //shuttle movement - var/movetime = 1200 - var/datum/shuttle/ferry/supply/shuttle + //supply points + var/points = 50 + var/points_per_process = 1.5 + var/points_per_slip = 2 + var/points_per_platinum = 5 // 5 points per sheet + var/points_per_phoron = 5 + var/points_per_money = 0.02 + //control + var/ordernum + var/list/shoppinglist = list() + var/list/requestlist = list() + var/list/supply_packs = list() + var/list/exported_crates = list() + //shuttle movement + var/movetime = 1200 + var/datum/shuttle/ferry/supply/shuttle - New() - ordernum = rand(1,9000) +/datum/controller/supply/New() + ordernum = rand(1,9000) - for(var/typepath in (typesof(/datum/supply_packs) - /datum/supply_packs)) - var/datum/supply_packs/P = new typepath() - supply_packs[P.name] = P + for(var/typepath in (typesof(/datum/supply_packs) - /datum/supply_packs)) + var/datum/supply_packs/P = new typepath() + supply_packs[P.name] = P - // Supply shuttle ticker - handles supply point regeneration - // This is called by the process scheduler every thirty seconds - proc/process() - points += points_per_process +// Supply shuttle ticker - handles supply point regeneration +// This is called by the process scheduler every thirty seconds +/datum/controller/supply/proc/process() + points += points_per_process - //To stop things being sent to CentCom which should not be sent to centcomm. Recursively checks for these types. - proc/forbidden_atoms_check(atom/A) - if(istype(A,/mob/living)) - return 1 - if(istype(A,/obj/item/weapon/disk/nuclear)) - return 1 - if(istype(A,/obj/machinery/nuclearbomb)) - return 1 - if(istype(A,/obj/item/device/radio/beacon)) - return 1 +//To stop things being sent to CentCom which should not be sent to centcomm. Recursively checks for these types. +/datum/controller/supply/proc/forbidden_atoms_check(atom/A) + if(isliving(A)) + return 1 + if(istype(A,/obj/item/weapon/disk/nuclear)) + return 1 + if(istype(A,/obj/machinery/nuclearbomb)) + return 1 + if(istype(A,/obj/item/device/radio/beacon)) + return 1 - for(var/i=1, i<=A.contents.len, i++) - var/atom/B = A.contents[i] - if(.(B)) - return 1 + for(var/i=1, i<=A.contents.len, i++) + var/atom/B = A.contents[i] + if(.(B)) + return 1 - //Sellin - proc/sell() - var/area/area_shuttle = shuttle.get_location_area() - if(!area_shuttle) return +//Sellin +/datum/controller/supply/proc/sell() + var/area/area_shuttle = shuttle.get_location_area() + if(!area_shuttle) return - callHook("sell_shuttle", list(area_shuttle)); + callHook("sell_shuttle", list(area_shuttle)); - var/phoron_count = 0 - var/plat_count = 0 - var/money_count = 0 + var/phoron_count = 0 + var/plat_count = 0 + var/money_count = 0 - for(var/atom/movable/MA in area_shuttle) - if(MA.anchored) continue + exported_crates = list() - // Must be in a crate! - if(istype(MA,/obj/structure/closet/crate)) - var/obj/structure/closet/crate/CR = MA - callHook("sell_crate", list(CR, area_shuttle)) + for(var/atom/movable/MA in area_shuttle) + if(MA.anchored) continue - points += CR.points_per_crate - var/find_slip = 1 + // Must be in a crate! + if(istype(MA,/obj/structure/closet/crate)) + var/oldpoints = points + var/oldphoron = phoron_count + var/oldplatinum = plat_count + var/oldmoney = money_count - for(var/atom in CR) - // Sell manifests - var/atom/A = atom - if(find_slip && istype(A,/obj/item/weapon/paper/manifest)) - var/obj/item/weapon/paper/manifest/slip = A - if(!slip.is_copy && slip.stamped && slip.stamped.len) //yes, the clown stamp will work. clown is the highest authority on the station, it makes sense - points += points_per_slip - find_slip = 0 - continue + var/obj/structure/closet/crate/CR = MA + callHook("sell_crate", list(CR, area_shuttle)) - // Sell phoron and platinum - if(istype(A, /obj/item/stack)) - var/obj/item/stack/P = A - switch(P.get_material_name()) - if("phoron") phoron_count += P.get_amount() - if("platinum") plat_count += P.get_amount() + points += CR.points_per_crate + var/find_slip = 1 - //Sell spacebucks - if(istype(A, /obj/item/weapon/spacecash)) - var/obj/item/weapon/spacecash/cashmoney = A - money_count += cashmoney.worth - qdel(MA) + for(var/atom in CR) + // Sell manifests + var/atom/A = atom + if(find_slip && istype(A,/obj/item/weapon/paper/manifest)) + var/obj/item/weapon/paper/manifest/slip = A + if(!slip.is_copy && slip.stamped && slip.stamped.len) //yes, the clown stamp will work. clown is the highest authority on the station, it makes sense + points += points_per_slip + find_slip = 0 + continue - if(phoron_count) - points += phoron_count * points_per_phoron + // Sell phoron and platinum + if(istype(A, /obj/item/stack)) + var/obj/item/stack/P = A + switch(P.get_material_name()) + if("phoron") phoron_count += P.get_amount() + if("platinum") plat_count += P.get_amount() - if(plat_count) - points += plat_count * points_per_platinum + //Sell spacebucks + if(istype(A, /obj/item/weapon/spacecash)) + var/obj/item/weapon/spacecash/cashmoney = A + money_count += cashmoney.worth - if(money_count) - points += money_count * points_per_money + var/datum/exported_crate/EC = new /datum/exported_crate() + EC.name = CR.name + EC.value = points - oldpoints + EC.value += (phoron_count - oldphoron) * points_per_phoron + EC.value += (plat_count - oldplatinum) * points_per_platinum + EC.value += (money_count - oldmoney) * points_per_money + exported_crates += EC - //Buyin - proc/buy() - if(!shoppinglist.len) return + qdel(MA) - var/area/area_shuttle = shuttle.get_location_area() - if(!area_shuttle) return + points += phoron_count * points_per_phoron + points += plat_count * points_per_platinum + points += money_count * points_per_money - var/list/clear_turfs = list() +//Buyin +/datum/controller/supply/proc/buy() + if(!shoppinglist.len) + return - for(var/turf/T in area_shuttle) - if(T.density) continue - var/contcount - for(var/atom/A in T.contents) - if(!A.simulated) - continue - contcount++ - if(contcount) - continue - clear_turfs += T + var/orderedamount = shoppinglist.len - for(var/S in shoppinglist) - if(!clear_turfs.len) break - var/i = rand(1,clear_turfs.len) - var/turf/pickedloc = clear_turfs[i] - clear_turfs.Cut(i,i+1) - shoppinglist -= S + var/area/area_shuttle = shuttle.get_location_area() + if(!area_shuttle) + return - var/datum/supply_order/SO = S - var/datum/supply_packs/SP = SO.object + var/list/clear_turfs = list() - var/obj/A = new SP.containertype(pickedloc) - A.name = "[SP.containername] [SO.comment ? "([SO.comment])":"" ]" + for(var/turf/T in area_shuttle) + if(T.density) + continue + var/contcount + for(var/atom/A in T.contents) + if(!A.simulated) + continue + contcount++ + if(contcount) + continue + clear_turfs += T - //supply manifest generation begin + for(var/S in shoppinglist) + if(!clear_turfs.len) break + var/i = rand(1,clear_turfs.len) + var/turf/pickedloc = clear_turfs[i] + clear_turfs.Cut(i,i+1) + shoppinglist -= S - var/obj/item/weapon/paper/manifest/slip - if(!SP.contraband) - slip = new /obj/item/weapon/paper/manifest(A) - slip.is_copy = 0 - slip.info = "

[command_name()] Shipping Manifest



" - slip.info +="Order #[SO.ordernum]
" - slip.info +="Destination: [station_name()]
" - slip.info +="[shoppinglist.len] PACKAGES IN THIS SHIPMENT
" - slip.info +="CONTENTS:

" + slip.info += "CHECK CONTENTS AND STAMP BELOW THE LINE TO CONFIRM RECEIPT OF GOODS
" + + return diff --git a/code/game/turfs/flooring/flooring.dm b/code/game/turfs/flooring/flooring.dm index 4d708b2944..c845657c74 100644 --- a/code/game/turfs/flooring/flooring.dm +++ b/code/game/turfs/flooring/flooring.dm @@ -1,5 +1,10 @@ var/list/flooring_types +/proc/populate_flooring_types() + flooring_types = list() + for (var/flooring_path in typesof(/decl/flooring)) + flooring_types["[flooring_path]"] = new flooring_path + /proc/get_flooring_data(var/flooring_path) if(!flooring_types) flooring_types = list() @@ -62,6 +67,13 @@ var/list/flooring_types desc = "A layer of many tiny bits of frozen water. It's hard to tell how deep it is." icon = 'icons/turf/snow_new.dmi' icon_base = "snow" + footstep_sounds = list("human" = list( + 'sound/effects/footstep/snow1.ogg', + 'sound/effects/footstep/snow2.ogg', + 'sound/effects/footstep/snow3.ogg', + 'sound/effects/footstep/snow4.ogg', + 'sound/effects/footstep/snow5.ogg')) + /decl/flooring/snow/snow2 name = "snow" @@ -80,6 +92,11 @@ var/list/flooring_types icon_base = "snowyplating" flags = null +/decl/flooring/snow/ice + name = "ice" + desc = "Looks slippery." + icon_base = "ice" + /decl/flooring/snow/plating/drift icon_base = "snowyplayingdrift" @@ -133,6 +150,11 @@ var/list/flooring_types icon_base = "oracarpet" build_type = /obj/item/stack/tile/carpet/oracarpet +/decl/flooring/carpet/tealcarpet + name = "teal carpet" + icon_base = "tealcarpet" + build_type = /obj/item/stack/tile/carpet/teal + /decl/flooring/tiling name = "floor" desc = "Scuffed from the passage of countless greyshirts." @@ -260,7 +282,7 @@ var/list/flooring_types /decl/flooring/wood name = "wooden floor" - desc = "Polished redwood planks." + desc = "Polished wooden planks." icon = 'icons/turf/flooring/wood.dmi' icon_base = "wood" has_damage_range = 6 @@ -275,6 +297,13 @@ var/list/flooring_types 'sound/effects/footstep/wood4.ogg', 'sound/effects/footstep/wood5.ogg')) +/decl/flooring/wood/sif + name = "alien wooden floor" + desc = "Polished alien wood planks." + icon = 'icons/turf/flooring/wood.dmi' + icon_base = "sifwood" + build_type = /obj/item/stack/tile/wood/sif + /decl/flooring/reinforced name = "reinforced floor" desc = "Heavily reinforced with steel rods." diff --git a/code/game/turfs/flooring/flooring_decals.dm b/code/game/turfs/flooring/flooring_decals.dm index 7543d4037a..957cc20389 100644 --- a/code/game/turfs/flooring/flooring_decals.dm +++ b/code/game/turfs/flooring/flooring_decals.dm @@ -6,7 +6,7 @@ var/list/floor_decals = list() /obj/effect/floor_decal name = "floor decal" icon = 'icons/turf/flooring/decals.dmi' - layer = DECALS_LAYER + plane = DECAL_PLANE var/supplied_dir /obj/effect/floor_decal/New(var/newloc, var/newdir, var/newcolour) @@ -14,16 +14,29 @@ var/list/floor_decals = list() if(newcolour) color = newcolour ..(newloc) -// Hack to workaround byond crash bug /obj/effect/floor_decal/initialize() - if(!floor_decals_initialized || !loc || QDELETED(src)) - return add_to_turf_decals() - var/turf/T = get_turf(src) - T.apply_decals() initialized = TRUE return INITIALIZE_HINT_QDEL +// This is a separate proc from initialize() to facilitiate its caching and other stuff. Look into it someday. +/obj/effect/floor_decal/proc/add_to_turf_decals() + if(supplied_dir) + set_dir(supplied_dir) // TODO - Why can't this line be done in initialize/New()? + var/turf/T = get_turf(src) + if(istype(T, /turf/simulated/floor) || istype(T, /turf/unsimulated/floor) || istype(T, /turf/simulated/shuttle/floor)) + var/cache_key = "[alpha]-[color]-[dir]-[icon_state]-[T.layer]" + var/image/I = floor_decals[cache_key] + if(!I) + I = image(icon = icon, icon_state = icon_state, dir = dir) + I.layer = T.layer + I.color = color + I.alpha = alpha + floor_decals[cache_key] = I + LAZYADD(T.decals, I) // Add to its decals list (so it remembers to re-apply after it cuts overlays) + T.add_overlay(I) // Add to its current overlays too. + return T + /obj/effect/floor_decal/reset name = "reset marker" diff --git a/code/game/turfs/flooring/flooring_premade.dm b/code/game/turfs/flooring/flooring_premade.dm index 3f4020c177..559e3ad3a2 100644 --- a/code/game/turfs/flooring/flooring_premade.dm +++ b/code/game/turfs/flooring/flooring_premade.dm @@ -14,6 +14,11 @@ icon_state = "blucarpet" initial_flooring = /decl/flooring/carpet/blucarpet +/turf/simulated/floor/carpet/tealcarpet + name = "teal carpet" + icon_state = "tealcarpet" + initial_flooring = /decl/flooring/carpet/tealcarpet + // Legacy support for existing paths for blue carpet /turf/simulated/floor/carpet/blue name = "blue carpet" @@ -63,6 +68,26 @@ icon_state = "wood" initial_flooring = /decl/flooring/wood +/turf/simulated/floor/wood/broken + icon_state = "wood_broken0" // This gets changed when spawned. + +/turf/simulated/floor/wood/broken/initialize() + break_tile() + return ..() + +/turf/simulated/floor/wood/sif + name = "alien wooden floor" + icon = 'icons/turf/flooring/wood.dmi' + icon_state = "sifwood" + initial_flooring = /decl/flooring/wood/sif + +/turf/simulated/floor/wood/sif/broken + icon_state = "sifwood_broken0" // This gets changed when spawned. + +/turf/simulated/floor/wood/sif/broken/initialize() + break_tile() + return ..() + /turf/simulated/floor/grass name = "grass patch" icon = 'icons/turf/flooring/grass.dmi' @@ -219,9 +244,8 @@ oxygen = 0 nitrogen = 0 -/turf/simulated/floor/reinforced/n20/New() - ..() - sleep(-1) +/turf/simulated/floor/reinforced/n20/initialize() + . = ..() if(!air) make_air() air.adjust_gas("sleeping_agent", ATMOSTANK_NITROUSOXIDE) @@ -400,11 +424,11 @@ . = ..() /turf/snow/update_icon() - overlays.Cut() + cut_overlays() for(var/d in crossed_dirs) var/amt = crossed_dirs[d] for(var/i in 1 to amt) - overlays += icon(icon, "footprint[i]", text2num(d)) + add_overlay(image(icon, "footprint[i]", text2num(d))) //**** Here ends snow **** \ No newline at end of file diff --git a/code/game/turfs/flooring/turf_overlay_holder.dm b/code/game/turfs/flooring/turf_overlay_holder.dm deleted file mode 100644 index c12f727a0b..0000000000 --- a/code/game/turfs/flooring/turf_overlay_holder.dm +++ /dev/null @@ -1,95 +0,0 @@ -// -// Initialize floor decals! Woo! This is crazy. -// - -var/global/floor_decals_initialized = FALSE - -// The Turf Decal Holder -// Since it is unsafe to add overlays to turfs, we hold them here for now. -// Since I want this object to basically not exist, I am modeling it in part after lighting_overlay -/atom/movable/turf_overlay_holder - name = "turf overlay holder" - density = 0 - simulated = 0 - anchored = 1 - layer = TURF_LAYER - icon = null - icon_state = null - mouse_opacity = 0 - // auto_init = 0 - -/atom/movable/turf_overlay_holder/initialize() - // doesn't need special init - initialized = TRUE - return INITIALIZE_HINT_NORMAL - -/atom/movable/turf_overlay_holder/New(var/atom/newloc) - ..() - verbs.Cut() - var/turf/T = loc - T.overlay_holder = src - -/atom/movable/turf_overlay_holder/Destroy() - if(loc) - var/turf/T = loc - if(T.overlay_holder == src) - T.overlay_holder = null - . = ..() - -// Variety of overrides so the overlays don't get affected by weird things. -/atom/movable/turf_overlay_holder/ex_act() - return - -/atom/movable/turf_overlay_holder/singularity_act() - return - -/atom/movable/turf_overlay_holder/singularity_pull() - return - -/atom/movable/turf_overlay_holder/forceMove() - return 0 //should never move - -/atom/movable/turf_overlay_holder/Move() - return 0 - -/atom/movable/turf_overlay_holder/throw_at() - return 0 - -/obj/effect/floor_decal/proc/add_to_turf_decals() - if(src.supplied_dir) src.set_dir(src.supplied_dir) - var/turf/T = get_turf(src) - if(istype(T, /turf/simulated/floor) || istype(T, /turf/unsimulated/floor) || istype(T, /turf/simulated/shuttle/floor)) - var/cache_key = "[src.alpha]-[src.color]-[src.dir]-[src.icon_state]-[T.layer]" - var/image/I = floor_decals[cache_key] - if(!I) - I = image(icon = src.icon, icon_state = src.icon_state, dir = src.dir) - I.layer = T.layer - I.color = src.color - I.alpha = src.alpha - floor_decals[cache_key] = I - if(!T.decals) T.decals = list() - //world.log << "About to add img:\ref[I] onto decals at turf:\ref[T] ([T.x],[T.y],[T.z]) which has appearance:\ref[T.appearance] and decals.len=[T.decals.len]" - T.decals += I - return T - // qdel(D) - src.loc = null - src.tag = null - -// Changes to turf to let us do this -/turf - var/atom/movable/turf_overlay_holder/overlay_holder = null - -// After a turf change, destroy the old overlay holder since we will have lost access to it. -/turf/post_change() - var/atom/movable/turf_overlay_holder/TOH = locate(/atom/movable/turf_overlay_holder, src) - if(TOH) - qdel(TOH) - ..() - -/turf/proc/apply_decals() - if(decals) - if(!overlay_holder) - overlay_holder = new(src) - overlay_holder.overlays = src.decals - else if(overlay_holder) - overlay_holder.overlays.Cut() diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm index 789ec20a17..e156588937 100644 --- a/code/game/turfs/simulated.dm +++ b/code/game/turfs/simulated.dm @@ -21,16 +21,15 @@ spawn(0) wet = wet_val if(wet_overlay) - overlays -= wet_overlay - wet_overlay = null - wet_overlay = image('icons/effects/water.dmi',src,"wet_floor") - overlays += wet_overlay + cut_overlay(wet_overlay) + wet_overlay = image('icons/effects/water.dmi', icon_state = "wet_floor") + add_overlay(wet_overlay) sleep(800) if(wet == 2) sleep(3200) wet = 0 if(wet_overlay) - overlays -= wet_overlay + cut_overlay(wet_overlay) wet_overlay = null /turf/simulated/proc/freeze_floor() @@ -38,14 +37,14 @@ return wet = 3 // icy if(wet_overlay) - overlays -= wet_overlay + cut_overlay(wet_overlay) wet_overlay = null wet_overlay = image('icons/turf/overlays.dmi',src,"snowfloor") - overlays += wet_overlay + add_overlay(wet_overlay) spawn(5 MINUTES) wet = 0 if(wet_overlay) - overlays -= wet_overlay + cut_overlay(wet_overlay) wet_overlay = null /turf/simulated/clean_blood() diff --git a/code/game/turfs/simulated/dungeon/wall.dm b/code/game/turfs/simulated/dungeon/wall.dm index b6a8f53c27..156fddac6a 100644 --- a/code/game/turfs/simulated/dungeon/wall.dm +++ b/code/game/turfs/simulated/dungeon/wall.dm @@ -10,4 +10,28 @@ return /turf/simulated/wall/dungeon/ex_act() + return + +/turf/simulated/wall/solidrock //for more stylish anti-cheese. + icon_state = "bedrock" + var/base_state = "bedrock" + block_tele = TRUE + +/turf/simulated/wall/solidrock/update_icon() + for(var/direction in cardinal) + var/turf/T = get_step(src,direction) + if(istype(T) && !T.density) + var/place_dir = turn(direction, 180) + if(!mining_overlay_cache["rock_side_[place_dir]"]) + mining_overlay_cache["rock_side_[place_dir]"] = image('icons/turf/walls.dmi', "rock_side", dir = place_dir) + T.add_overlay(mining_overlay_cache["rock_side_[place_dir]"]) + +/turf/simulated/wall/solidrock/initialize() + icon_state = base_state + update_icon(1) + +/turf/simulated/wall/solidrock/attackby() + return + +/turf/simulated/wall/solidrock/ex_act() return \ No newline at end of file diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm index 336a34b2fe..f471cc9bc0 100644 --- a/code/game/turfs/simulated/floor.dm +++ b/code/game/turfs/simulated/floor.dm @@ -53,7 +53,7 @@ //This proc auto corrects the grass tiles' siding. /turf/simulated/floor/proc/make_plating(var/place_product, var/defer_icon_update) - overlays.Cut() + cut_overlays() if(islist(decals)) decals.Cut() decals = null diff --git a/code/game/turfs/simulated/floor_attackby.dm b/code/game/turfs/simulated/floor_attackby.dm index ef36121b12..5602eac320 100644 --- a/code/game/turfs/simulated/floor_attackby.dm +++ b/code/game/turfs/simulated/floor_attackby.dm @@ -4,40 +4,15 @@ return 0 if(flooring) - if(istype(C, /obj/item/weapon/crowbar)) - if(broken || burnt) - to_chat(user, "You remove the broken [flooring.descriptor].") - make_plating() - else if(flooring.flags & TURF_IS_FRAGILE) - to_chat(user, "You forcefully pry off the [flooring.descriptor], destroying them in the process.") - make_plating() - else if(flooring.flags & TURF_REMOVE_CROWBAR) - to_chat(user, "You lever off the [flooring.descriptor].") - make_plating(1) - else - return - playsound(src, C.usesound, 80, 1) - return - else if(istype(C, /obj/item/weapon/screwdriver) && (flooring.flags & TURF_REMOVE_SCREWDRIVER)) - if(broken || burnt) - return - to_chat(user, "You unscrew and remove the [flooring.descriptor].") - make_plating(1) - playsound(src, C.usesound, 80, 1) - return - else if(istype(C, /obj/item/weapon/wrench) && (flooring.flags & TURF_REMOVE_WRENCH)) - to_chat(user, "You unwrench and remove the [flooring.descriptor].") - make_plating(1) - playsound(src, C.usesound, 80, 1) - return - else if(istype(C, /obj/item/weapon/shovel) && (flooring.flags & TURF_REMOVE_SHOVEL)) - to_chat(user, "You shovel off the [flooring.descriptor].") - make_plating(1) - playsound(src, 'sound/items/Deconstruct.ogg', 80, 1) + if(istype(C, /obj/item/weapon)) + try_deconstruct_tile(C, user) return else if(istype(C, /obj/item/stack/cable_coil)) to_chat(user, "You must remove the [flooring.descriptor] first.") return + else if(istype(C, /obj/item/stack/tile)) + try_replace_tile(C, user) + return else if(istype(C, /obj/item/stack/cable_coil)) @@ -87,4 +62,48 @@ burnt = null broken = null else - to_chat(user, "You need more welding fuel to complete this task.") \ No newline at end of file + to_chat(user, "You need more welding fuel to complete this task.") + +/turf/simulated/floor/proc/try_deconstruct_tile(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W, /obj/item/weapon/crowbar)) + if(broken || burnt) + to_chat(user, "You remove the broken [flooring.descriptor].") + make_plating() + else if(flooring.flags & TURF_IS_FRAGILE) + to_chat(user, "You forcefully pry off the [flooring.descriptor], destroying them in the process.") + make_plating() + else if(flooring.flags & TURF_REMOVE_CROWBAR) + to_chat(user, "You lever off the [flooring.descriptor].") + make_plating(1) + else + return 0 + playsound(src, W.usesound, 80, 1) + return 1 + else if(istype(W, /obj/item/weapon/screwdriver) && (flooring.flags & TURF_REMOVE_SCREWDRIVER)) + if(broken || burnt) + return 0 + to_chat(user, "You unscrew and remove the [flooring.descriptor].") + make_plating(1) + playsound(src, W.usesound, 80, 1) + return 1 + else if(istype(W, /obj/item/weapon/wrench) && (flooring.flags & TURF_REMOVE_WRENCH)) + to_chat(user, "You unwrench and remove the [flooring.descriptor].") + make_plating(1) + playsound(src, W.usesound, 80, 1) + return 1 + else if(istype(W, /obj/item/weapon/shovel) && (flooring.flags & TURF_REMOVE_SHOVEL)) + to_chat(user, "You shovel off the [flooring.descriptor].") + make_plating(1) + playsound(src, 'sound/items/Deconstruct.ogg', 80, 1) + return 1 + return 0 + +/turf/simulated/floor/proc/try_replace_tile(obj/item/stack/tile/T as obj, mob/user as mob) + if(T.type == flooring.build_type) + return + var/obj/item/weapon/W = user.is_holding_item_of_type(/obj/item/weapon) + if(!try_deconstruct_tile(W, user)) + return + if(flooring) + return + attackby(T, user) \ No newline at end of file diff --git a/code/game/turfs/simulated/floor_icon.dm b/code/game/turfs/simulated/floor_icon.dm index 91ca65259d..e1b49762ec 100644 --- a/code/game/turfs/simulated/floor_icon.dm +++ b/code/game/turfs/simulated/floor_icon.dm @@ -7,7 +7,7 @@ var/image/no_ceiling_image = null return TRUE /proc/cache_no_ceiling_image() - no_ceiling_image = image(icon = 'icons/turf/open_space.dmi', icon_state = "no_ceiling", layer = OVERTURF_LAYER) + no_ceiling_image = image(icon = 'icons/turf/open_space.dmi', icon_state = "no_ceiling") no_ceiling_image.plane = PLANE_MESONS /turf/simulated/floor/update_icon(var/update_neighbors) @@ -15,7 +15,7 @@ var/image/no_ceiling_image = null if(lava) return - overlays.Cut() + cut_overlays() if(flooring) // Set initial icon and strings. @@ -38,17 +38,17 @@ var/image/no_ceiling_image = null var/turf/simulated/floor/T = get_step(src, step_dir) if(!istype(T) || !T.flooring || T.flooring.name != flooring.name) has_border |= step_dir - overlays |= get_flooring_overlay("[flooring.icon_base]-edge-[step_dir]", "[flooring.icon_base]_edges", step_dir) + add_overlay(get_flooring_overlay("[flooring.icon_base]-edge-[step_dir]", "[flooring.icon_base]_edges", step_dir)) // There has to be a concise numerical way to do this but I am too noob. if((has_border & NORTH) && (has_border & EAST)) - overlays |= get_flooring_overlay("[flooring.icon_base]-edge-[NORTHEAST]", "[flooring.icon_base]_edges", NORTHEAST) + add_overlay(get_flooring_overlay("[flooring.icon_base]-edge-[NORTHEAST]", "[flooring.icon_base]_edges", NORTHEAST)) if((has_border & NORTH) && (has_border & WEST)) - overlays |= get_flooring_overlay("[flooring.icon_base]-edge-[NORTHWEST]", "[flooring.icon_base]_edges", NORTHWEST) + add_overlay(get_flooring_overlay("[flooring.icon_base]-edge-[NORTHWEST]", "[flooring.icon_base]_edges", NORTHWEST)) if((has_border & SOUTH) && (has_border & EAST)) - overlays |= get_flooring_overlay("[flooring.icon_base]-edge-[SOUTHEAST]", "[flooring.icon_base]_edges", SOUTHEAST) + add_overlay(get_flooring_overlay("[flooring.icon_base]-edge-[SOUTHEAST]", "[flooring.icon_base]_edges", SOUTHEAST)) if((has_border & SOUTH) && (has_border & WEST)) - overlays |= get_flooring_overlay("[flooring.icon_base]-edge-[SOUTHWEST]", "[flooring.icon_base]_edges", SOUTHWEST) + add_overlay(get_flooring_overlay("[flooring.icon_base]-edge-[SOUTHWEST]", "[flooring.icon_base]_edges", SOUTHWEST)) if(flooring.flags & TURF_HAS_CORNERS) // As above re: concise numerical way to do this. @@ -56,37 +56,36 @@ var/image/no_ceiling_image = null if(!(has_border & EAST)) var/turf/simulated/floor/T = get_step(src, NORTHEAST) if(!(istype(T) && T.flooring && T.flooring.name == flooring.name)) - overlays |= get_flooring_overlay("[flooring.icon_base]-corner-[NORTHEAST]", "[flooring.icon_base]_corners", NORTHEAST) + add_overlay(get_flooring_overlay("[flooring.icon_base]-corner-[NORTHEAST]", "[flooring.icon_base]_corners", NORTHEAST)) if(!(has_border & WEST)) var/turf/simulated/floor/T = get_step(src, NORTHWEST) if(!(istype(T) && T.flooring && T.flooring.name == flooring.name)) - overlays |= get_flooring_overlay("[flooring.icon_base]-corner-[NORTHWEST]", "[flooring.icon_base]_corners", NORTHWEST) + add_overlay(get_flooring_overlay("[flooring.icon_base]-corner-[NORTHWEST]", "[flooring.icon_base]_corners", NORTHWEST)) if(!(has_border & SOUTH)) if(!(has_border & EAST)) var/turf/simulated/floor/T = get_step(src, SOUTHEAST) if(!(istype(T) && T.flooring && T.flooring.name == flooring.name)) - overlays |= get_flooring_overlay("[flooring.icon_base]-corner-[SOUTHEAST]", "[flooring.icon_base]_corners", SOUTHEAST) + add_overlay(get_flooring_overlay("[flooring.icon_base]-corner-[SOUTHEAST]", "[flooring.icon_base]_corners", SOUTHEAST)) if(!(has_border & WEST)) var/turf/simulated/floor/T = get_step(src, SOUTHWEST) if(!(istype(T) && T.flooring && T.flooring.name == flooring.name)) - overlays |= get_flooring_overlay("[flooring.icon_base]-corner-[SOUTHWEST]", "[flooring.icon_base]_corners", SOUTHWEST) + add_overlay(get_flooring_overlay("[flooring.icon_base]-corner-[SOUTHWEST]", "[flooring.icon_base]_corners", SOUTHWEST)) - // Hack workaround to byond crash bug - //if(decals && decals.len) - //overlays |= decals - apply_decals() + // Re-apply floor decals + if(LAZYLEN(decals)) + add_overlay(decals) if(is_plating() && !(isnull(broken) && isnull(burnt))) //temp, todo icon = 'icons/turf/flooring/plating.dmi' icon_state = "dmg[rand(1,4)]" else if(flooring) if(!isnull(broken) && (flooring.flags & TURF_CAN_BREAK)) - overlays |= get_flooring_overlay("[flooring.icon_base]-broken-[broken]","[flooring.icon_base]_broken[broken]") + add_overlay(get_flooring_overlay("[flooring.icon_base]-broken-[broken]","[flooring.icon_base]_broken[broken]")) if(!isnull(burnt) && (flooring.flags & TURF_CAN_BURN)) - overlays |= get_flooring_overlay("[flooring.icon_base]-burned-[burnt]","[flooring.icon_base]_burned[burnt]") + add_overlay(get_flooring_overlay("[flooring.icon_base]-burned-[burnt]","[flooring.icon_base]_burned[burnt]")) if(weather_overlay) - overlays += weather_overlay + add_overlay(weather_overlay) if(update_neighbors) for(var/turf/simulated/floor/F in range(src, 1)) @@ -97,7 +96,7 @@ var/image/no_ceiling_image = null // Show 'ceilingless' overlay. var/turf/above = GetAbove(src) if(above && isopenspace(above) && !istype(src, /turf/simulated/floor/outdoors)) // This won't apply to outdoor turfs since its assumed they don't have a ceiling anyways. - overlays |= no_ceiling_image + add_overlay(no_ceiling_image) /turf/simulated/floor/proc/get_flooring_overlay(var/cache_key, var/icon_base, var/icon_dir = 0) if(!flooring_cache[cache_key]) diff --git a/code/game/turfs/simulated/floor_types.dm b/code/game/turfs/simulated/floor_types.dm index 07c686df99..3c4856cf00 100644 --- a/code/game/turfs/simulated/floor_types.dm +++ b/code/game/turfs/simulated/floor_types.dm @@ -15,17 +15,19 @@ var/list/decals New(var/location = null, var/turf/simulated/shuttle/turf) + ..(null) my_turf = turf /obj/landed_holder/proc/land_on(var/turf/T) //Gather destination information - var/old_dest_type = T.type - var/old_dest_dir = T.dir - var/old_dest_icon_state = T.icon_state - var/old_dest_icon = T.icon - var/list/old_dest_overlays = T.overlays.Copy() - var/list/old_dest_underlays = T.underlays.Copy() - var/list/old_dest_decals = T.decals ? T.decals.Copy() : null + var/obj/landed_holder/new_holder = new(null) + new_holder.turf_type = T.type + new_holder.dir = T.dir + new_holder.icon = T.icon + new_holder.icon_state = T.icon_state + new_holder.copy_overlays(T, TRUE) + new_holder.underlays = T.underlays.Copy() + new_holder.decals = T.decals ? T.decals.Copy() : null //Set the destination to be like us T.Destroy() @@ -33,7 +35,7 @@ new_dest.set_dir(my_turf.dir) new_dest.icon_state = my_turf.icon_state new_dest.icon = my_turf.icon - new_dest.overlays = my_turf.overlays + new_dest.copy_overlays(my_turf, TRUE) new_dest.underlays = my_turf.underlays new_dest.decals = my_turf.decals //Shuttle specific stuff @@ -43,18 +45,9 @@ new_dest.join_flags = my_turf.join_flags new_dest.join_group = my_turf.join_group - if(new_dest.decals) - new_dest.apply_decals() - - //Tell the new turf about what was there before - new_dest.landed_holder = new(turf = new_dest) - new_dest.landed_holder.turf_type = old_dest_type - new_dest.landed_holder.dir = old_dest_dir - new_dest.landed_holder.icon = old_dest_icon - new_dest.landed_holder.icon_state = old_dest_icon_state - new_dest.landed_holder.overlays = old_dest_overlays - new_dest.landed_holder.underlays = old_dest_underlays - new_dest.landed_holder.decals = old_dest_decals + // Associate the holder with the new turf. + new_holder.my_turf = new_dest + new_dest.landed_holder = new_holder //Update underlays if necessary (interior corners won't have changed). if(new_dest.takes_underlays && !new_dest.interior_corner) @@ -70,11 +63,9 @@ new_source.set_dir(dir) new_source.icon_state = icon_state new_source.icon = icon - new_source.overlays = overlays + new_source.copy_overlays(src, TRUE) new_source.underlays = underlays new_source.decals = decals - if(new_source.decals) - new_source.apply_decals() else new_source = my_turf.ChangeTurf(get_base_turf_by_area(my_turf),,1) diff --git a/code/game/turfs/simulated/outdoors/outdoors.dm b/code/game/turfs/simulated/outdoors/outdoors.dm index 86e6b117bb..34a07ef9c4 100644 --- a/code/game/turfs/simulated/outdoors/outdoors.dm +++ b/code/game/turfs/simulated/outdoors/outdoors.dm @@ -44,7 +44,9 @@ var/list/outdoor_turfs = list() planet_controller.unallocateTurf(src) else // This is happening during map gen, if there's no planet_controller (hopefully). outdoor_turfs -= src - qdel(weather_overlay) + if(weather_overlay) + cut_overlay(weather_overlay) + qdel_null(weather_overlay) update_icon() /turf/simulated/post_change() @@ -67,15 +69,14 @@ var/list/outdoor_turfs = list() var/image/I = image(icon = 'icons/turf/outdoors_edge.dmi', icon_state = "[T.get_edge_icon_state()]-edge", dir = checkdir) I.plane = 0 turf_edge_cache[cache_key] = I - overlays += turf_edge_cache[cache_key] + add_overlay(turf_edge_cache[cache_key]) /turf/simulated/proc/get_edge_icon_state() return icon_state /turf/simulated/floor/outdoors/update_icon() - overlays.Cut() - update_icon_edge() ..() + update_icon_edge() /turf/simulated/floor/outdoors/mud name = "mud" diff --git a/code/game/turfs/simulated/outdoors/snow.dm b/code/game/turfs/simulated/outdoors/snow.dm index 398fa0dc47..5fed8af66b 100644 --- a/code/game/turfs/simulated/outdoors/snow.dm +++ b/code/game/turfs/simulated/outdoors/snow.dm @@ -3,12 +3,14 @@ icon_state = "snow" edge_blending_priority = 6 movement_cost = 2 + initial_flooring = /decl/flooring/snow turf_layers = list( /turf/simulated/floor/outdoors/rocks, /turf/simulated/floor/outdoors/dirt ) var/list/crossed_dirs = list() + /turf/simulated/floor/outdoors/snow/Entered(atom/A) if(isliving(A)) var/mdir = "[A.dir]" @@ -17,10 +19,9 @@ . = ..() /turf/simulated/floor/outdoors/snow/update_icon() - overlays.Cut() ..() for(var/d in crossed_dirs) - overlays += image(icon = 'icons/turf/outdoors.dmi', icon_state = "snow_footprints", dir = text2num(d)) + add_overlay(image(icon = 'icons/turf/outdoors.dmi', icon_state = "snow_footprints", dir = text2num(d))) /turf/simulated/floor/outdoors/snow/attackby(var/obj/item/W, var/mob/user) if(istype(W, /obj/item/weapon/shovel)) @@ -40,4 +41,17 @@ var/obj/S = new /obj/item/stack/material/snow(user.loc) user.put_in_hands(S) visible_message("[user] scoops up a pile of snow.", "You scoop up a pile of snow.") - return \ No newline at end of file + return + +/turf/simulated/floor/outdoors/ice + name = "ice" + icon_state = "ice" + desc = "Looks slippery." + +/turf/simulated/floor/outdoors/ice/Entered(var/mob/living/M) + sleep(1 * world.tick_lag) + if(istype(M, /mob/living)) + if(M.stunned == 0) + to_chat(M, "You slide across the ice!") + M.SetStunned(1) + step(M,M.dir) diff --git a/code/game/turfs/simulated/wall_icon.dm b/code/game/turfs/simulated/wall_icon.dm index 2dac063723..b8a0980de4 100644 --- a/code/game/turfs/simulated/wall_icon.dm +++ b/code/game/turfs/simulated/wall_icon.dm @@ -47,36 +47,36 @@ if(!damage_overlays[1]) //list hasn't been populated generate_overlays() - overlays.Cut() + cut_overlays() var/image/I if(!density) I = image('icons/turf/wall_masks.dmi', "[material.icon_base]fwall_open") I.color = material.icon_colour - overlays += I + add_overlay(I) return for(var/i = 1 to 4) I = image('icons/turf/wall_masks.dmi', "[material.icon_base][wall_connections[i]]", dir = 1<<(i-1)) I.color = material.icon_colour - overlays += I + add_overlay(I) if(reinf_material) if(construction_stage != null && construction_stage < 6) I = image('icons/turf/wall_masks.dmi', "reinf_construct-[construction_stage]") I.color = reinf_material.icon_colour - overlays += I + add_overlay(I) else if("[reinf_material.icon_reinf]0" in icon_states('icons/turf/wall_masks.dmi')) // Directional icon for(var/i = 1 to 4) I = image('icons/turf/wall_masks.dmi', "[reinf_material.icon_reinf][wall_connections[i]]", dir = 1<<(i-1)) I.color = reinf_material.icon_colour - overlays += I + add_overlay(I) else I = image('icons/turf/wall_masks.dmi', reinf_material.icon_reinf) I.color = reinf_material.icon_colour - overlays += I + add_overlay(I) if(damage != 0) var/integrity = material.integrity @@ -87,7 +87,7 @@ if(overlay > damage_overlays.len) overlay = damage_overlays.len - overlays += damage_overlays[overlay] + add_overlay(damage_overlays[overlay]) return /turf/simulated/wall/proc/generate_overlays() diff --git a/code/game/turfs/simulated/wall_types.dm b/code/game/turfs/simulated/wall_types.dm index f187a54c8f..eae30c6cb4 100644 --- a/code/game/turfs/simulated/wall_types.dm +++ b/code/game/turfs/simulated/wall_types.dm @@ -224,7 +224,7 @@ /turf/simulated/shuttle/wall/voidcraft/update_icon() if(stripe_color) - overlays.Cut() + cut_overlays() var/image/I = image(icon = src.icon, icon_state = "o_[icon_state]") I.color = stripe_color - overlays.Add(I) + add_overlay(I) diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index 21fd9492f0..e5bb57ad9e 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -252,7 +252,7 @@ O.icon_state = "2" O.anchored = 1 O.density = 1 - O.layer = 5 + O.plane = ABOVE_PLANE if(girder_material.integrity >= 150 && !girder_material.is_brittle()) //Strong girders will remain in place when a wall is melted. dismantle_wall(1,1) diff --git a/code/game/turfs/simulated/water.dm b/code/game/turfs/simulated/water.dm index a47578f102..e4b762d733 100644 --- a/code/game/turfs/simulated/water.dm +++ b/code/game/turfs/simulated/water.dm @@ -16,7 +16,6 @@ update_icon() /turf/simulated/floor/water/update_icon() - overlays.Cut() ..() // To get the edges. icon_state = water_state var/image/floorbed_sprite = image(icon = 'icons/turf/outdoors.dmi', icon_state = under_state) @@ -129,16 +128,16 @@ var/list/shoreline_icon_cache = list() // Water sprites are really annoying, so let BYOND sort it out. /turf/simulated/floor/water/shoreline/update_icon() underlays.Cut() - overlays.Cut() + cut_overlays() ..() // Get the underlay first. var/cache_string = "[initial(icon_state)]_[water_state]_[dir]" if(cache_string in shoreline_icon_cache) // Check to see if an icon already exists. - overlays += shoreline_icon_cache[cache_string] + add_overlay(shoreline_icon_cache[cache_string]) else // If not, make one, but only once. var/icon/shoreline_water = icon(src.icon, "shoreline_water", src.dir) var/icon/shoreline_subtract = icon(src.icon, "[initial(icon_state)]_subtract", src.dir) shoreline_water.Blend(shoreline_subtract,ICON_SUBTRACT) shoreline_icon_cache[cache_string] = shoreline_water - overlays += shoreline_icon_cache[cache_string] + add_overlay(shoreline_icon_cache[cache_string]) diff --git a/code/game/turfs/snow/snow.dm b/code/game/turfs/snow/snow.dm index b09275ca41..a8ccd5b63b 100644 --- a/code/game/turfs/snow/snow.dm +++ b/code/game/turfs/snow/snow.dm @@ -26,12 +26,12 @@ . = ..() /turf/snow/update_icon() - overlays.Cut() + cut_overlays() for(var/d in crossed_dirs) var/amt = crossed_dirs[d] for(var/i in 1 to amt) - overlays += icon(icon, "footprint[i]", text2num(d)) + add_overlay(image(icon, "footprint[i]", text2num(d))) /turf/snow/snow2 name = "snow" diff --git a/code/game/turfs/space/cracked_asteroid.dm b/code/game/turfs/space/cracked_asteroid.dm index b9f43af82e..dae0d5a129 100644 --- a/code/game/turfs/space/cracked_asteroid.dm +++ b/code/game/turfs/space/cracked_asteroid.dm @@ -10,7 +10,8 @@ /turf/space/cracked_asteroid/is_space() // So people don't start floating when standing on it. return FALSE -/turf/space/cracked_asteroid/New() - ..() - spawn(2 SECONDS) - overlays.Cut() \ No newline at end of file +// u wot m8? ~Leshana +// /turf/space/cracked_asteroid/New() +// ..() +// spawn(2 SECONDS) +// overlays.Cut() diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index d3abc04352..100c3b5a31 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -1,5 +1,7 @@ /turf icon = 'icons/turf/floors.dmi' + layer = TURF_LAYER + plane = TURF_PLANE level = 1 var/holy = 0 @@ -101,6 +103,12 @@ turf/attackby(obj/item/weapon/W as obj, mob/user as mob) return if (do_after(user, 25 + (5 * user.weakened)) && !(user.stat)) step_towards(O, src) + if(ismob(O)) + animate(O, transform = turn(O.transform, 20), time = 2) + sleep(2) + animate(O, transform = turn(O.transform, -40), time = 4) + sleep(4) + animate(O, transform = turn(O.transform, 20), time = 2) /turf/Enter(atom/movable/mover as mob|obj, atom/forget as mob|obj|turf|area) if(movement_disabled && usr.ckey != movement_disabled_exception) @@ -277,3 +285,6 @@ var/const/enterloopsanity = 100 if(isliving(AM)) var/mob/living/M = AM M.turf_collision(src, speed) + +/turf/AllowDrop() + return TRUE diff --git a/code/game/turfs/unsimulated/beach.dm b/code/game/turfs/unsimulated/beach.dm index bcbb4b133f..82206926cf 100644 --- a/code/game/turfs/unsimulated/beach.dm +++ b/code/game/turfs/unsimulated/beach.dm @@ -17,7 +17,7 @@ /turf/unsimulated/beach/water/New() ..() - overlays += image("icon"='icons/misc/beach.dmi',"icon_state"="water2","layer"=MOB_LAYER+0.1) + add_overlay(image("icon"='icons/misc/beach.dmi',"icon_state"="water2","layer"=MOB_LAYER+0.1)) /turf/simulated/floor/beach name = "Beach" @@ -44,4 +44,4 @@ /turf/simulated/floor/beach/water/New() ..() - overlays += image("icon"='icons/misc/beach.dmi',"icon_state"="water5","layer"=MOB_LAYER+0.1) + add_overlay(image("icon"='icons/misc/beach.dmi',"icon_state"="water5","layer"=MOB_LAYER+0.1)) diff --git a/code/game/turfs/unsimulated/shuttle.dm b/code/game/turfs/unsimulated/shuttle.dm index 99f5bc15bd..cb70c6c36d 100644 --- a/code/game/turfs/unsimulated/shuttle.dm +++ b/code/game/turfs/unsimulated/shuttle.dm @@ -3,7 +3,6 @@ icon = 'icons/turf/shuttle_white.dmi' thermal_conductivity = 0.05 heat_capacity = 0 - layer = 2 /turf/unsimulated/shuttle/wall name = "wall" diff --git a/code/game/verbs/ooc.dm b/code/game/verbs/ooc.dm index 8fafb555a3..11aa51eb90 100644 --- a/code/game/verbs/ooc.dm +++ b/code/game/verbs/ooc.dm @@ -35,7 +35,7 @@ message_admins("[key_name_admin(src)] has attempted to advertise in OOC: [msg]") return - log_ooc("[mob.name]/[key] : [msg]") + log_ooc(msg, src) if(msg) handle_spam_prevention(MUTE_OOC) @@ -108,7 +108,7 @@ message_admins("[key_name_admin(src)] has attempted to advertise in OOC: [msg]") return - log_ooc("(LOCAL) [mob.name]/[key] : [msg]") + log_looc(msg,src) if(msg) handle_spam_prevention(MUTE_OOC) diff --git a/code/global.dm b/code/global.dm index 3bf111ef4f..1f6124602a 100644 --- a/code/global.dm +++ b/code/global.dm @@ -21,7 +21,10 @@ var/global/list/global_map = null // Noises made when hit while typing. var/list/hit_appends = list("-OOF", "-ACK", "-UGH", "-HRNK", "-HURGH", "-GLORF") +var/log_path = "data/logs/" //See world.dm for the full calculated path var/diary = null +var/error_log = null +var/debug_log = null var/href_logfile = null // var/station_name = "Northern Star" // var/const/station_orig = "Northern Star" //station_name can't be const due to event prefix/suffix @@ -184,7 +187,7 @@ var/static/list/scarySounds = list( var/max_explosion_range = 14 // Announcer intercom, because too much stuff creates an intercom for one message then hard del()s it. -var/global/obj/item/device/radio/intercom/global_announcer = new /obj/item/device/radio/intercom{channels=list("Engineering")}(null) +var/global/obj/item/device/radio/intercom/omni/global_announcer = new /obj/item/device/radio/intercom/omni(null) var/list/station_departments = list("Command", "Medical", "Engineering", "Science", "Security", "Cargo", "Civilian") diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm index 39926e1414..e28c4fd570 100644 --- a/code/modules/admin/IsBanned.dm +++ b/code/modules/admin/IsBanned.dm @@ -6,13 +6,13 @@ world/IsBanned(key,address,computer_id) //Guest Checking if(!config.guests_allowed && IsGuestKey(key)) - log_access("Failed Login: [key] - Guests not allowed") + log_adminwarn("Failed Login: [key] - Guests not allowed") message_admins("Failed Login: [key] - Guests not allowed") return list("reason"="guest", "desc"="\nReason: Guests not allowed. Please sign in with a byond account.") //check if the IP address is a known TOR node if(config && config.ToRban && ToRban_isbanned(address)) - log_access("Failed Login: [src] - Banned: ToR") + log_adminwarn("Failed Login: [src] - Banned: ToR") message_admins("Failed Login: [src] - Banned: ToR") //ban their computer_id and ckey for posterity AddBan(ckey(key), computer_id, "Use of ToR", "Automated Ban", 0, 0) @@ -24,7 +24,7 @@ world/IsBanned(key,address,computer_id) //Ban Checking . = CheckBan( ckey(key), computer_id, address ) if(.) - log_access("Failed Login: [key] [computer_id] [address] - Banned [.["reason"]]") + log_adminwarn("Failed Login: [key] [computer_id] [address] - Banned [.["reason"]]") message_admins("Failed Login: [key] id:[computer_id] ip:[address] - Banned [.["reason"]]") return . diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 61f2d174ac..08b16efa60 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -6,13 +6,13 @@ var/global/floorIsLava = 0 //////////////////////////////// /proc/message_admins(var/msg) msg = "ADMIN LOG: [msg]" - log_adminwarn(msg) + //log_adminwarn(msg) //log_and_message_admins is for this + for(var/client/C in admins) if((R_ADMIN|R_MOD) & C.holder.rights) C << msg /proc/msg_admin_attack(var/text) //Toggleable Attack Messages - log_attack(text) var/rendered = "ATTACK: [text]" for(var/client/C in admins) if((R_ADMIN|R_MOD) & C.holder.rights) @@ -380,7 +380,7 @@ proc/admin_notice(var/message, var/rights) if(3) dat+={" Creating new Feed Message... -
Receiving Channel: [src.admincaster_feed_channel.channel_name]
" //MARK +
Receiving Channel: [src.admincaster_feed_channel.channel_name]
Message Author: [src.admincaster_signature]
Message Body: [src.admincaster_feed_message.body]

Submit

Cancel
@@ -674,10 +674,7 @@ proc/admin_notice(var/message, var/rights) set desc = "Send an intercom message, like an arrivals announcement." if(!check_rights(0)) return - //This is basically how death alarms do it - var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset/omni(null) - - var/channel = input("Channel for message:","Channel", null) as null|anything in (list("Common") + a.keyslot2.channels) // + a.keyslot1.channels + var/channel = input("Channel for message:","Channel", null) as null|anything in radiochannels if(channel) //They picked a channel var/sender = input("Name of sender (max 75):", "Announcement", "Announcement Computer") as null|text @@ -688,11 +685,94 @@ proc/admin_notice(var/message, var/rights) if(message) //They put a message message = sanitize(message, 500, extra = 0) - a.autosay("[message]", "[sender]", "[channel == "Common" ? null : channel]") //Common is a weird case, as it's not a "channel", it's just talking into a radio without a channel set. + global_announcer.autosay("[message]", "[sender]", "[channel == "Common" ? null : channel]") //Common is a weird case, as it's not a "channel", it's just talking into a radio without a channel set. log_admin("Intercom: [key_name(usr)] : [sender]:[message]") - qdel(a) + feedback_add_details("admin_verb","IN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/datum/admins/proc/intercom_convo() + set category = "Fun" + set name = "Intercom Convo" + set desc = "Send an intercom conversation, like several uses of the Intercom Msg verb." + set waitfor = FALSE //Why bother? We have some sleeps. You can leave tho! + if(!check_rights(0)) return + + var/channel = input("Channel for message:","Channel", null) as null|anything in radiochannels + + if(!channel) //They picked a channel + return + + to_chat(usr,"Intercom Convo Directions
Start the conversation with the sender, a pipe (|), and then the message on one line. Then hit enter to \ + add another line, and type a (whole) number of seconds to pause between that message, and the next message, then repeat the message syntax up to 20 times. For example:
\ + --- --- ---
\ + Some Guy|Hello guys, what's up?
\ + 5
\ + Other Guy|Hey, good to see you.
\ + 5
\ + Some Guy|Yeah, you too.
\ + --- --- ---
\ + The above will result in those messages playing, with a 5 second gap between each. Maximum of 20 messages allowed.
") + + var/list/decomposed + var/message = input(usr,"See your chat box for instructions. Keep a copy elsewhere in case it is rejected when you click OK.", "Input Conversation", "") as null|message + + if(!message) + return + + //Split on pipe or \n + decomposed = splittext(message,regex("\\||$","m")) + decomposed += "0" //Tack on a final 0 sleep to make 3-per-message evenly + + //Time to find how they screwed up. + //Wasn't the right length + if((decomposed.len) % 3) //+1 to accomidate the lack of a wait time for the last message + to_chat(usr,"You passed [decomposed.len] segments (senders+messages+pauses). You must pass a multiple of 3, minus 1 (no pause after the last message). That means a sender and message on every other line (starting on the first), separated by a pipe character (|), and a number every other line that is a pause in seconds.") + return + + //Too long a conversation + if((decomposed.len / 3) > 20) + to_chat(usr,"This conversation is too long! 20 messages maximum, please.") + return + + //Missed some sleeps, or sanitized to nothing. + for(var/i = 1; i < decomposed.len; i++) + + //Sanitize sender + var/clean_sender = sanitize(decomposed[i]) + if(!clean_sender) + to_chat(usr,"One part of your conversation was not able to be sanitized. It was the sender of the [(i+2)/3]\th message.") + return + decomposed[i] = clean_sender + + //Sanitize message + var/clean_message = sanitize(decomposed[++i]) + if(!clean_message) + to_chat(usr,"One part of your conversation was not able to be sanitized. It was the body of the [(i+2)/3]\th message.") + return + decomposed[i] = clean_message + + //Sanitize wait time + var/clean_time = text2num(decomposed[++i]) + if(!isnum(clean_time)) + to_chat(usr,"One part of your conversation was not able to be sanitized. It was the wait time after the [(i+2)/3]\th message.") + return + if(clean_time > 60) + to_chat(usr,"Max 60 second wait time between messages for sanity's sake please.") + return + decomposed[i] = clean_time + + log_admin("Intercom convo started by: [key_name(usr)] : [sanitize(message)]") + feedback_add_details("admin_verb","IN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + + //Sanitized AND we still have a chance to send it? Wow! + if(LAZYLEN(decomposed)) + for(var/i = 1; i < decomposed.len; i++) + var/this_sender = decomposed[i] + var/this_message = decomposed[++i] + var/this_wait = decomposed[++i] + global_announcer.autosay("[this_message]", "[this_sender]", "[channel == "Common" ? null : channel]") //Common is a weird case, as it's not a "channel", it's just talking into a radio without a channel set. + sleep(this_wait SECONDS) + /datum/admins/proc/toggleooc() set category = "Server" set desc="Globally Toggles OOC" diff --git a/code/modules/admin/admin_attack_log.dm b/code/modules/admin/admin_attack_log.dm index 967a4375da..f04bdf3b61 100644 --- a/code/modules/admin/admin_attack_log.dm +++ b/code/modules/admin/admin_attack_log.dm @@ -16,7 +16,7 @@ proc/log_and_message_admins_many(var/list/mob/users, var/message) log_admin("[english_list(user_keys)] [message]") message_admins("[english_list(user_keys)] [message]") - +/* Old procs proc/admin_attack_log(var/mob/attacker, var/mob/victim, var/attacker_message, var/victim_message, var/admin_message) if(victim) victim.attack_log += text("\[[time_stamp()]\] [key_name(attacker)] - [victim_message]") @@ -42,3 +42,4 @@ proc/admin_inject_log(mob/attacker, mob/victim, obj/item/weapon, reagents, amoun "used \the [weapon] to [violent]inject - [reagents] - [amount_transferred]u transferred", "was [violent]injected with \the [weapon] - [reagents] - [amount_transferred]u transferred", "used \the [weapon] to [violent]inject [reagents] ([amount_transferred]u transferred) into") +*/ diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm index 12c00aa708..772c1886a8 100644 --- a/code/modules/admin/admin_ranks.dm +++ b/code/modules/admin/admin_ranks.dm @@ -6,6 +6,10 @@ var/list/admin_ranks = list() //list of all ranks with associated rights var/previous_rights = 0 + //Clear profile access + for(var/A in world.GetConfig("admin")) + world.SetConfig("APP/admin", A, null) + //load text from file var/list/Lines = file2list("config/admin_ranks.txt") diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 04740237f1..6b038aca4e 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -26,6 +26,7 @@ var/list/admin_verbs_admin = list( /datum/admins/proc/toggleguests, //toggles whether guests can join the current game, /datum/admins/proc/announce, //priority announce something to all clients., /datum/admins/proc/intercom, //send a fake intercom message, like an arrivals announcement, + /datum/admins/proc/intercom_convo, //send a fake intercom conversation, like an ATC exchange, /client/proc/colorooc, //allows us to set a custom colour for everythign we say in ooc, /client/proc/admin_ghost, //allows us to ghost/reenter body at will, /client/proc/toggle_view_range, //changes how far we can see, @@ -192,6 +193,8 @@ var/list/admin_verbs_debug = list( /client/proc/cmd_debug_del_all, /client/proc/cmd_debug_tog_aliens, /client/proc/cmd_display_del_log, + /client/proc/cmd_display_init_log, + /client/proc/cmd_display_overlay_log, /client/proc/air_report, /client/proc/reload_admins, /client/proc/reload_eventMs, diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm index 4f0cba95c4..2d74b43433 100644 --- a/code/modules/admin/holder2.dm +++ b/code/modules/admin/holder2.dm @@ -23,6 +23,8 @@ var/list/admin_datums = list() rank = initial_rank rights = initial_rights admin_datums[ckey] = src + if(rights & R_DEBUG) //grant profile access + world.SetConfig("APP/admin", ckey, "role=admin") /datum/admins/proc/associate(client/C) if(istype(C)) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 81c709f6d8..358df91af6 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1001,11 +1001,6 @@ //strip their stuff and stick it in the crate for(var/obj/item/I in M) M.drop_from_inventory(I, locker) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - H.update_icons_layers() //Cheaper - else - M.update_icons() //so they black out before warping M.Paralyse(5) @@ -1188,10 +1183,8 @@ usr << "This can only be used on instances of type /mob/living/carbon/human" return var/block=text2num(href_list["block"]) - //testing("togmutate([href_list["block"]] -> [block])") usr.client.cmd_admin_toggle_block(H,block) show_player_panel(H) - //H.regenerate_icons() else if(href_list["adminplayeropts"]) var/mob/M = locate(href_list["adminplayeropts"]) @@ -1228,7 +1221,7 @@ if(ismob(M)) var/take_msg = "ADMINHELP: [key_name(usr.client)] is attending to [key_name(M)]'s adminhelp, please don't dogpile them." for(var/client/X in admins) - if((R_ADMIN|R_MOD|R_EVENT) & X.holder.rights) + if((R_ADMIN|R_MOD|R_EVENT|R_SERVER) & X.holder.rights) to_chat(X, take_msg) to_chat(M, "Your adminhelp is being attended to by [usr.client]. Thanks for your patience!") else diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index dcaa745485..4ff94877f4 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -104,7 +104,7 @@ if(C.is_preference_enabled(/datum/client_preference/holder/play_adminhelp_ping)) C << 'sound/effects/adminhelp.ogg' - log_admin("PM: [key_name(src)]->[key_name(C)]: [msg]") + log_adminpm(msg,src,C) send2adminirc("Reply: [key_name(src)]->[key_name(C)]: [html_decode(msg)]") //we don't use message_admins here because the sender/receiver might get it too diff --git a/code/modules/admin/verbs/adminsay.dm b/code/modules/admin/verbs/adminsay.dm index 264e5ad64e..0fdc158227 100644 --- a/code/modules/admin/verbs/adminsay.dm +++ b/code/modules/admin/verbs/adminsay.dm @@ -9,7 +9,7 @@ if(!msg) return - log_admin("ADMIN: [key_name(src)] : [msg]") + log_adminsay(msg,src) if(check_rights(R_ADMIN,0)) for(var/client/C in admins) @@ -27,7 +27,7 @@ return msg = sanitize(msg) - log_admin("MOD: [key_name(src)] : [msg]") + log_modsay(msg,src) if (!msg) return @@ -50,7 +50,7 @@ return msg = sanitize(msg) - log_admin("EVENT: [key_name(src)] : [msg]") + log_eventsay(msg,src) if (!msg) return diff --git a/code/modules/admin/verbs/antag-ooc.dm b/code/modules/admin/verbs/antag-ooc.dm index f3a6ffc77c..22689f1718 100644 --- a/code/modules/admin/verbs/antag-ooc.dm +++ b/code/modules/admin/verbs/antag-ooc.dm @@ -39,4 +39,4 @@ if((M.mind && M.mind.special_role && A && A.can_use_aooc) || isobserver(M)) // Antags must have their type be allowed to AOOC to see AOOC. This prevents, say, ERT from seeing AOOC. to_chat(M, "[create_text_tag("aooc", "Antag-OOC:", M.client)] [player_display]: [msg]") - log_ooc("(ANTAG) [key] : [msg]") \ No newline at end of file + log_aooc(msg,src) \ No newline at end of file diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 56617c8399..326a317bfd 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -327,6 +327,36 @@ usr << browse(dellog.Join(), "window=dellog") +/client/proc/cmd_display_init_log() + set category = "Debug" + set name = "Display Initialize() Log" + set desc = "Displays a list of things that didn't handle Initialize() properly" + + if(!check_rights(R_DEBUG)) return + src << browse(replacetext(SSatoms.InitLog(), "\n", "
"), "window=initlog") + +/client/proc/cmd_display_overlay_log() + set category = "Debug" + set name = "Display overlay Log" + set desc = "Display SSoverlays log of everything that's passed through it." + + if(!check_rights(R_DEBUG)) return + render_stats(SSoverlays.stats, src) + +// Render stats list for round-end statistics. +/proc/render_stats(list/stats, user, sort = /proc/cmp_generic_stat_item_time) + sortTim(stats, sort, TRUE) + + var/list/lines = list() + for (var/entry in stats) + var/list/data = stats[entry] + lines += "[entry] => [num2text(data[STAT_ENTRY_TIME], 10)]ms ([data[STAT_ENTRY_COUNT]]) (avg:[num2text(data[STAT_ENTRY_TIME]/(data[STAT_ENTRY_COUNT] || 1), 99)])" + + if (user) + user << browse("
  1. [lines.Join("
  2. ")]
", "window=[url_encode("stats:\ref[stats]")]") + else + . = lines.Join("\n") + /client/proc/cmd_admin_grantfullaccess(var/mob/M in mob_list) set category = "Admin" set name = "Grant Full Access" diff --git a/code/modules/admin/verbs/getlogs.dm b/code/modules/admin/verbs/getlogs.dm index eac11fcac0..3f6e4c9e74 100644 --- a/code/modules/admin/verbs/getlogs.dm +++ b/code/modules/admin/verbs/getlogs.dm @@ -85,7 +85,7 @@ set name = "Show Server Log" set desc = "Shows today's server log." - var/path = "data/logs/[time2text(world.realtime,"YYYY/MM-Month/DD-Day")].log" + var/path = "[log_path].log" if( fexists(path) ) src << run( file(path) ) else @@ -99,7 +99,10 @@ set category = "Admin" set name = "Show Server Attack Log" set desc = "Shows today's server attack log." + + to_chat(usr,"This verb doesn't actually do anything.") + /* var/path = "data/logs/[time2text(world.realtime,"YYYY/MM-Month/DD-Day")] Attack.log" if( fexists(path) ) src << run( file(path) ) @@ -109,3 +112,5 @@ usr << run( file(path) ) feedback_add_details("admin_verb","SSAL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! return + */ + \ No newline at end of file diff --git a/code/modules/admin/verbs/possess.dm b/code/modules/admin/verbs/possess.dm index 6de30853ce..aa100623ff 100644 --- a/code/modules/admin/verbs/possess.dm +++ b/code/modules/admin/verbs/possess.dm @@ -37,7 +37,6 @@ if(ishuman(usr)) var/mob/living/carbon/human/H = usr H.name = H.get_visible_name() -// usr.regenerate_icons() //So the name is updated properly usr.loc = O.loc // Appear where the object you were controlling is -- TLE usr.client.eye = usr diff --git a/code/modules/admin/view_variables/view_variables.dm b/code/modules/admin/view_variables/view_variables.dm index e624d2df05..cb110d4e86 100644 --- a/code/modules/admin/view_variables/view_variables.dm +++ b/code/modules/admin/view_variables/view_variables.dm @@ -143,7 +143,12 @@ vtext = "\ref[C] - [C] ([C.type])" else if(islist(value)) var/list/L = value - vtext = "/list ([L.len])" + var/removed = 0 + if(varname == "contents") + var/list/original = value + L = original.Copy() //We'll take a copy to manipulate + removed = D.view_variables_filter_contents(L) + vtext = "/list ([L.len]+[removed]H)" if(!(varname in view_variables_dont_expand) && L.len > 0 && L.len < 100) extra = "