diff --git a/aurora.dme b/aurora.dme index d86f02a8..6e8d1759 100644 --- a/aurora.dme +++ b/aurora.dme @@ -22,6 +22,9 @@ #define FILE_DIR "icons/misc" #define FILE_DIR "icons/mob" #define FILE_DIR "icons/mob/human_races" +#define FILE_DIR "icons/mob/species" +#define FILE_DIR "icons/mob/species/armalis" +#define FILE_DIR "icons/mob/species/vox" #define FILE_DIR "icons/obj" #define FILE_DIR "icons/obj/assemblies" #define FILE_DIR "icons/obj/atmospherics" @@ -121,6 +124,7 @@ #include "code\ATMOSPHERICS\datum_pipe_network.dm" #include "code\ATMOSPHERICS\datum_pipeline.dm" #include "code\ATMOSPHERICS\he_pipes.dm" +#include "code\ATMOSPHERICS\mainspipe.dm" #include "code\ATMOSPHERICS\pipes.dm" #include "code\ATMOSPHERICS\components\portables_connector.dm" #include "code\ATMOSPHERICS\components\tvalve.dm" @@ -629,7 +633,9 @@ #include "code\game\objects\items\weapons\storage\briefcase.dm" #include "code\game\objects\items\weapons\storage\fancy.dm" #include "code\game\objects\items\weapons\storage\firstaid.dm" +#include "code\game\objects\items\weapons\storage\internal.dm" #include "code\game\objects\items\weapons\storage\lockbox.dm" +#include "code\game\objects\items\weapons\storage\misc.dm" #include "code\game\objects\items\weapons\storage\secure.dm" #include "code\game\objects\items\weapons\storage\storage.dm" #include "code\game\objects\items\weapons\storage\toolbox.dm" @@ -651,6 +657,7 @@ #include "code\game\objects\structures\flora.dm" #include "code\game\objects\structures\girders.dm" #include "code\game\objects\structures\grille.dm" +#include "code\game\objects\structures\inflatable.dm" #include "code\game\objects\structures\janicart.dm" #include "code\game\objects\structures\kitchen_spike.dm" #include "code\game\objects\structures\ladders.dm" @@ -832,6 +839,7 @@ #include "code\modules\clothing\suits\jobs.dm" #include "code\modules\clothing\suits\labcoat.dm" #include "code\modules\clothing\suits\miscellaneous.dm" +#include "code\modules\clothing\suits\storage.dm" #include "code\modules\clothing\suits\utility.dm" #include "code\modules\clothing\suits\wiz_robe.dm" #include "code\modules\clothing\under\chameleon.dm" @@ -923,6 +931,8 @@ #include "code\modules\mob\abilities.dm" #include "code\modules\mob\death.dm" #include "code\modules\mob\emote.dm" +#include "code\modules\mob\hear_say.dm" +#include "code\modules\mob\holder.dm" #include "code\modules\mob\inventory.dm" #include "code\modules\mob\language.dm" #include "code\modules\mob\login.dm" @@ -1026,6 +1036,7 @@ #include "code\modules\mob\living\carbon\monkey\monkey.dm" #include "code\modules\mob\living\carbon\monkey\powers.dm" #include "code\modules\mob\living\carbon\monkey\update_icons.dm" +#include "code\modules\mob\living\silicon\alarm.dm" #include "code\modules\mob\living\silicon\death.dm" #include "code\modules\mob\living\silicon\login.dm" #include "code\modules\mob\living\silicon\say.dm" @@ -1069,6 +1080,12 @@ #include "code\modules\mob\living\silicon\robot\robot_modules.dm" #include "code\modules\mob\living\silicon\robot\robot_movement.dm" #include "code\modules\mob\living\silicon\robot\wires.dm" +#include "code\modules\mob\living\silicon\robot\drone\drone.dm" +#include "code\modules\mob\living\silicon\robot\drone\drone_abilities.dm" +#include "code\modules\mob\living\silicon\robot\drone\drone_console.dm" +#include "code\modules\mob\living\silicon\robot\drone\drone_damage.dm" +#include "code\modules\mob\living\silicon\robot\drone\drone_items.dm" +#include "code\modules\mob\living\silicon\robot\drone\drone_manufacturer.dm" #include "code\modules\mob\living\simple_animal\bees.dm" #include "code\modules\mob\living\simple_animal\borer.dm" #include "code\modules\mob\living\simple_animal\constructs.dm" @@ -1123,11 +1140,13 @@ #include "code\modules\organs\organ_internal.dm" #include "code\modules\organs\pain.dm" #include "code\modules\organs\wound.dm" +#include "code\modules\paperwork\carbonpaper.dm" #include "code\modules\paperwork\clipboard.dm" #include "code\modules\paperwork\filingcabinet.dm" #include "code\modules\paperwork\folders.dm" #include "code\modules\paperwork\handlabeler.dm" #include "code\modules\paperwork\paper.dm" +#include "code\modules\paperwork\paper_bundle.dm" #include "code\modules\paperwork\paperbin.dm" #include "code\modules\paperwork\pen.dm" #include "code\modules\paperwork\photocopier.dm" @@ -1173,6 +1192,7 @@ #include "code\modules\projectiles\targeting.dm" #include "code\modules\projectiles\ammunition\boxes.dm" #include "code\modules\projectiles\ammunition\bullets.dm" +#include "code\modules\projectiles\guns\alien.dm" #include "code\modules\projectiles\guns\energy.dm" #include "code\modules\projectiles\guns\projectile.dm" #include "code\modules\projectiles\guns\energy\erifles.dm" diff --git a/code/ATMOSPHERICS/components/trinary_devices/filter.dm b/code/ATMOSPHERICS/components/trinary_devices/filter.dm index 0320f899..5ea2c0eb 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/filter.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/filter.dm @@ -14,7 +14,7 @@ obj/machinery/atmospherics/trinary/filter /* Filter types: -1: Nothing - 0: Carbon Molecules: Plasma Toxin, Oxygen Agent B + 0: Plasma: Plasma Toxin, Oxygen Agent B 1: Oxygen: Oxygen ONLY 2: Nitrogen: Nitrogen ONLY 3: Carbon Dioxide: Carbon Dioxide ONLY @@ -170,7 +170,7 @@ obj/machinery/atmospherics/trinary/filter/attack_hand(user as mob) // -- TLE var/current_filter_type switch(filter_type) if(0) - current_filter_type = "Carbon Molecules" + current_filter_type = "Plasma" if(1) current_filter_type = "Oxygen" if(2) @@ -188,7 +188,7 @@ obj/machinery/atmospherics/trinary/filter/attack_hand(user as mob) // -- TLE Power: [on?"On":"Off"]
Filtering: [current_filter_type]

Set Filter Type:

- Carbon Molecules
+ Plasma
Oxygen
Nitrogen
Carbon Dioxide
@@ -234,4 +234,45 @@ obj/machinery/atmospherics/trinary/filter/Topic(href, href_list) // -- TLE */ return +obj/machinery/atmospherics/trinary/filter/m_filter + icon = 'icons/obj/atmospherics/m_filter.dmi' + icon_state = "intact_off" + dir = SOUTH + initialize_directions = SOUTH|NORTH|EAST + +obj/machinery/atmospherics/trinary/filter/m_filter/New() + ..() + 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/filter/m_filter/initialize() + 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() diff --git a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm index 026d8406..54a43075 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm @@ -160,3 +160,93 @@ obj/machinery/atmospherics/trinary/mixer src.update_icon() src.updateUsrDialog() return + +obj/machinery/atmospherics/trinary/mixer/t_mixer + icon = 'icons/obj/atmospherics/t_mixer.dmi' + icon_state = "intact_off" + + dir = SOUTH + initialize_directions = SOUTH|EAST|WEST + + //node 3 is the outlet, nodes 1 & 2 are intakes + +obj/machinery/atmospherics/trinary/mixer/t_mixer/New() + ..() + 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/initialize() + 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() + +obj/machinery/atmospherics/trinary/mixer/m_mixer + icon = 'icons/obj/atmospherics/m_mixer.dmi' + icon_state = "intact_off" + + dir = SOUTH + initialize_directions = SOUTH|NORTH|EAST + + //node 3 is the outlet, nodes 1 & 2 are intakes + +obj/machinery/atmospherics/trinary/mixer/m_mixer/New() + ..() + 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/initialize() + 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() \ No newline at end of file diff --git a/code/ATMOSPHERICS/mainspipe.dm b/code/ATMOSPHERICS/mainspipe.dm new file mode 100644 index 00000000..631f3530 --- /dev/null +++ b/code/ATMOSPHERICS/mainspipe.dm @@ -0,0 +1,707 @@ +// internal pipe, don't actually place or use these +obj/machinery/atmospherics/pipe/mains_component + var/obj/machinery/atmospherics/mains_pipe/parent_pipe + var/list/obj/machinery/atmospherics/pipe/mains_component/nodes = new() + + New(loc) + ..(loc) + parent_pipe = loc + + check_pressure(pressure) + var/datum/gas_mixture/environment = loc.loc.return_air() + + var/pressure_difference = pressure - environment.return_pressure() + + if(pressure_difference > parent_pipe.maximum_pressure) + mains_burst() + + else if(pressure_difference > parent_pipe.fatigue_pressure) + //TODO: leak to turf, doing pfshhhhh + if(prob(5)) + mains_burst() + + else return 1 + + pipeline_expansion() + return nodes + + disconnect(obj/machinery/atmospherics/reference) + if(nodes.Find(reference)) + nodes.Remove(reference) + + proc/mains_burst() + parent_pipe.burst() + +obj/machinery/atmospherics/mains_pipe + icon = 'icons/obj/atmospherics/mainspipe.dmi' + layer = 2.4 //under wires with their 2.5 + + force = 20 + + var/volume = 0 + + var/alert_pressure = 80*ONE_ATMOSPHERE + + var/initialize_mains_directions = 0 + + var/list/obj/machinery/atmospherics/mains_pipe/nodes = new() + var/obj/machinery/atmospherics/pipe/mains_component/supply + var/obj/machinery/atmospherics/pipe/mains_component/scrubbers + var/obj/machinery/atmospherics/pipe/mains_component/aux + + 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 + + New() + ..() + + supply = new(src) + supply.volume = volume + supply.nodes.len = nodes.len + scrubbers = new(src) + scrubbers.volume = volume + scrubbers.nodes.len = nodes.len + aux = new(src) + aux.volume = volume + aux.nodes.len = nodes.len + + hide(var/i) + if(level == 1 && istype(loc, /turf/simulated)) + invisibility = i ? 101 : 0 + update_icon() + + proc/burst() + ..() + for(var/obj/machinery/atmospherics/pipe/mains_component/pipe in contents) + burst() + + proc/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 + + disconnect() + ..() + for(var/obj/machinery/atmospherics/pipe/mains_component/node in nodes) + node.disconnect() + + Del() + disconnect() + ..() + + initialize() + for(var/i = 1 to nodes.len) + var/obj/machinery/atmospherics/mains_pipe/node = nodes[i] + if(node) + supply.nodes[i] = node.supply + scrubbers.nodes[i] = node.scrubbers + aux.nodes[i] = node.aux + +obj/machinery/atmospherics/mains_pipe/simple + name = "mains pipe" + desc = "A one meter section of 3-line mains pipe" + + dir = SOUTH + initialize_mains_directions = SOUTH|NORTH + + New() + nodes.len = 2 + ..() + switch(dir) + if(SOUTH || NORTH) + initialize_mains_directions = SOUTH|NORTH + if(EAST || WEST) + initialize_mains_directions = EAST|WEST + if(NORTHEAST) + initialize_mains_directions = NORTH|EAST + if(NORTHWEST) + initialize_mains_directions = NORTH|WEST + if(SOUTHEAST) + initialize_mains_directions = SOUTH|EAST + if(SOUTHWEST) + initialize_mains_directions = SOUTH|WEST + + proc/normalize_dir() + if(dir==3) + dir = 1 + else if(dir==12) + dir = 4 + + update_icon() + if(nodes[1] && nodes[2]) + icon_state = "intact[invisibility ? "-f" : "" ]" + + //var/node1_direction = get_dir(src, node1) + //var/node2_direction = get_dir(src, node2) + + //dir = node1_direction|node2_direction + + else + if(!nodes[1]&&!nodes[2]) + del(src) //TODO: silent deleting looks weird + var/have_node1 = nodes[1]?1:0 + var/have_node2 = nodes[2]?1:0 + icon_state = "exposed[have_node1][have_node2][invisibility ? "-f" : "" ]" + + initialize() + normalize_dir() + var/node1_dir + var/node2_dir + + for(var/direction in cardinal) + if(direction&initialize_mains_directions) + if (!node1_dir) + node1_dir = direction + else if (!node2_dir) + node2_dir = direction + + for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,node1_dir)) + if(target.initialize_mains_directions & get_dir(target,src)) + nodes[1] = target + break + for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,node2_dir)) + if(target.initialize_mains_directions & get_dir(target,src)) + nodes[2] = target + break + + ..() // initialize internal pipes + + var/turf/T = src.loc // hide if turf is not intact + hide(T.intact) + update_icon() + + hidden + level = 1 + icon_state = "intact-f" + + visible + level = 2 + icon_state = "intact" + +obj/machinery/atmospherics/mains_pipe/manifold + name = "manifold pipe" + desc = "A manifold composed of mains pipes" + + dir = SOUTH + initialize_mains_directions = EAST|NORTH|WEST + volume = 105 + + New() + nodes.len = 3 + ..() + initialize_mains_directions = (NORTH|SOUTH|EAST|WEST) & ~dir + + initialize() + var/connect_directions = initialize_mains_directions + + for(var/direction in cardinal) + if(direction&connect_directions) + for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,direction)) + if(target.initialize_mains_directions & get_dir(target,src)) + nodes[1] = target + connect_directions &= ~direction + break + if (nodes[1]) + break + + + for(var/direction in cardinal) + if(direction&connect_directions) + for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,direction)) + if(target.initialize_mains_directions & get_dir(target,src)) + nodes[2] = target + connect_directions &= ~direction + break + if (nodes[2]) + break + + + for(var/direction in cardinal) + if(direction&connect_directions) + for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,direction)) + if(target.initialize_mains_directions & get_dir(target,src)) + nodes[3] = target + connect_directions &= ~direction + break + if (nodes[3]) + break + + ..() // initialize internal pipes + + var/turf/T = src.loc // hide if turf is not intact + hide(T.intact) + update_icon() + + update_icon() + icon_state = "manifold[invisibility ? "-f" : "" ]" + + hidden + level = 1 + icon_state = "manifold-f" + + visible + level = 2 + icon_state = "manifold" + +obj/machinery/atmospherics/mains_pipe/manifold4w + name = "manifold pipe" + desc = "A manifold composed of mains pipes" + + dir = SOUTH + initialize_mains_directions = EAST|NORTH|WEST|SOUTH + volume = 105 + + New() + nodes.len = 4 + ..() + + initialize() + for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,NORTH)) + if(target.initialize_mains_directions & get_dir(target,src)) + nodes[1] = target + break + + for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,SOUTH)) + if(target.initialize_mains_directions & get_dir(target,src)) + nodes[2] = target + break + + for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,EAST)) + if(target.initialize_mains_directions & get_dir(target,src)) + nodes[3] = target + break + + for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,WEST)) + if(target.initialize_mains_directions & get_dir(target,src)) + nodes[3] = target + break + + ..() // initialize internal pipes + + var/turf/T = src.loc // hide if turf is not intact + hide(T.intact) + update_icon() + + update_icon() + icon_state = "manifold4w[invisibility ? "-f" : "" ]" + + hidden + level = 1 + icon_state = "manifold4w-f" + + visible + level = 2 + icon_state = "manifold4w" + +obj/machinery/atmospherics/mains_pipe/split + name = "mains splitter" + desc = "A splitter for connecting to a single pipe off a mains." + + var/obj/machinery/atmospherics/pipe/mains_component/split_node + var/obj/machinery/atmospherics/node3 + var/icon_type + + New() + nodes.len = 2 + ..() + initialize_mains_directions = turn(dir, 90) | turn(dir, -90) + initialize_directions = dir // actually have a normal connection too + + initialize() + var/node1_dir + var/node2_dir + var/node3_dir + + node1_dir = turn(dir, 90) + node2_dir = turn(dir, -90) + node3_dir = dir + + for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,node1_dir)) + if(target.initialize_mains_directions & get_dir(target,src)) + nodes[1] = target + break + for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,node2_dir)) + if(target.initialize_mains_directions & get_dir(target,src)) + nodes[2] = 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 + + ..() // initialize internal pipes + + // bind them + spawn(5) + if(node3 && split_node) + var/datum/pipe_network/N1 = node3.return_network(src) + var/datum/pipe_network/N2 = split_node.return_network(split_node) + if(N1 && N2) + N1.merge(N2) + + var/turf/T = src.loc // hide if turf is not intact + hide(T.intact) + update_icon() + + update_icon() + icon_state = "split-[icon_type][invisibility ? "-f" : "" ]" + + return_network(A) + return split_node.return_network(A) + + supply + icon_type = "supply" + + New() + ..() + split_node = supply + + hidden + level = 1 + icon_state = "split-supply-f" + + visible + level = 2 + icon_state = "split-supply" + + scrubbers + icon_type = "scrubbers" + + New() + ..() + split_node = scrubbers + + hidden + level = 1 + icon_state = "split-scrubbers-f" + + visible + level = 2 + icon_state = "split-scrubbers" + + aux + icon_type = "aux" + + New() + ..() + split_node = aux + + hidden + level = 1 + icon_state = "split-aux-f" + + visible + level = 2 + icon_state = "split-aux" + +obj/machinery/atmospherics/mains_pipe/split3 + name = "triple mains splitter" + desc = "A splitter for connecting to the 3 pipes on a mainline." + + var/obj/machinery/atmospherics/supply_node + var/obj/machinery/atmospherics/scrubbers_node + var/obj/machinery/atmospherics/aux_node + + New() + nodes.len = 1 + ..() + initialize_mains_directions = dir + initialize_directions = cardinal & ~dir // actually have a normal connection too + + initialize() + var/node1_dir + var/supply_node_dir + var/scrubbers_node_dir + var/aux_node_dir + + node1_dir = dir + aux_node_dir = turn(dir, 180) + if(dir & (NORTH|SOUTH)) + supply_node_dir = EAST + scrubbers_node_dir = WEST + else + supply_node_dir = SOUTH + scrubbers_node_dir = NORTH + + for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src, node1_dir)) + if(target.initialize_mains_directions & get_dir(target,src)) + nodes[1] = target + break + for(var/obj/machinery/atmospherics/target in get_step(src,supply_node_dir)) + if(target.initialize_directions & get_dir(target,src)) + supply_node = target + break + for(var/obj/machinery/atmospherics/target in get_step(src,scrubbers_node_dir)) + if(target.initialize_directions & get_dir(target,src)) + scrubbers_node = target + break + for(var/obj/machinery/atmospherics/target in get_step(src,aux_node_dir)) + if(target.initialize_directions & get_dir(target,src)) + aux_node = target + break + + ..() // initialize internal pipes + + // bind them + spawn(5) + if(supply_node) + var/datum/pipe_network/N1 = supply_node.return_network(src) + var/datum/pipe_network/N2 = supply.return_network(supply) + if(N1 && N2) + N1.merge(N2) + if(scrubbers_node) + var/datum/pipe_network/N1 = scrubbers_node.return_network(src) + var/datum/pipe_network/N2 = scrubbers.return_network(scrubbers) + if(N1 && N2) + N1.merge(N2) + if(aux_node) + var/datum/pipe_network/N1 = aux_node.return_network(src) + var/datum/pipe_network/N2 = aux.return_network(aux) + if(N1 && N2) + N1.merge(N2) + + var/turf/T = src.loc // hide if turf is not intact + hide(T.intact) + update_icon() + + update_icon() + icon_state = "split-t[invisibility ? "-f" : "" ]" + + return_network(obj/machinery/atmospherics/reference) + var/obj/machinery/atmospherics/A + + A = supply_node.return_network(reference) + if(!A) + A = scrubbers_node.return_network(reference) + if(!A) + A = aux_node.return_network(reference) + + return A + + hidden + level = 1 + icon_state = "split-t-f" + + visible + level = 2 + icon_state = "split-t" + +obj/machinery/atmospherics/mains_pipe/cap + name = "pipe cap" + desc = "A cap for the end of a mains pipe" + + dir = SOUTH + initialize_directions = SOUTH + volume = 35 + + New() + nodes.len = 1 + ..() + initialize_mains_directions = dir + + update_icon() + icon_state = "cap[invisibility ? "-f" : ""]" + + initialize() + for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,dir)) + if(target.initialize_mains_directions & get_dir(target,src)) + nodes[1] = target + break + + ..() + + var/turf/T = src.loc // hide if turf is not intact + hide(T.intact) + update_icon() + + hidden + level = 1 + icon_state = "cap-f" + + visible + level = 2 + icon_state = "cap" + +//TODO: Get Mains valves working! +/* +obj/machinery/atmospherics/mains_pipe/valve + icon_state = "mvalve0" + + name = "mains shutoff valve" + desc = "A mains pipe valve" + + var/open = 1 + + dir = SOUTH + initialize_mains_directions = SOUTH|NORTH + + New() + nodes.len = 2 + ..() + initialize_mains_directions = dir | turn(dir, 180) + + update_icon(animation) + var/turf/simulated/floor = loc + var/hide = istype(floor) ? floor.intact : 0 + level = 1 + for(var/obj/machinery/atmospherics/mains_pipe/node in nodes) + if(node.level == 2) + hide = 0 + level = 2 + break + + if(animation) + flick("[hide?"h":""]mvalve[src.open][!src.open]",src) + else + icon_state = "[hide?"h":""]mvalve[open]" + + initialize() + normalize_dir() + var/node1_dir + var/node2_dir + + for(var/direction in cardinal) + if(direction&initialize_mains_directions) + if (!node1_dir) + node1_dir = direction + else if (!node2_dir) + node2_dir = direction + + for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,node1_dir)) + if(target.initialize_mains_directions & get_dir(target,src)) + nodes[1] = target + break + for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,node2_dir)) + if(target.initialize_mains_directions & get_dir(target,src)) + nodes[2] = target + break + + if(open) + ..() // initialize internal pipes + + update_icon() + + proc/normalize_dir() + if(dir==3) + dir = 1 + else if(dir==12) + dir = 4 + + proc/open() + if(open) return 0 + + open = 1 + update_icon() + + initialize() + + return 1 + + proc/close() + if(!open) return 0 + + open = 0 + update_icon() + + for(var/obj/machinery/atmospherics/pipe/mains_component/node in src) + for(var/obj/machinery/atmospherics/pipe/mains_component/o in node.nodes) + o.disconnect(node) + o.build_network() + + return 1 + + attack_ai(mob/user as mob) + return + + attack_paw(mob/user as mob) + return attack_hand(user) + + attack_hand(mob/user as mob) + src.add_fingerprint(usr) + update_icon(1) + sleep(10) + if (open) + close() + else + open() + + digital // can be controlled by AI + name = "digital mains valve" + desc = "A digitally controlled valve." + icon_state = "dvalve0" + + attack_ai(mob/user as mob) + return src.attack_hand(user) + + attack_hand(mob/user as mob) + if(!src.allowed(user)) + user << "\red Access denied." + return + ..() + + //Radio remote control + + 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) + + var/frequency = 0 + var/id = null + var/datum/radio_frequency/radio_connection + + initialize() + ..() + if(frequency) + set_frequency(frequency) + + update_icon(animation) + var/turf/simulated/floor = loc + var/hide = istype(floor) ? floor.intact : 0 + level = 1 + for(var/obj/machinery/atmospherics/mains_pipe/node in nodes) + if(node.level == 2) + hide = 0 + level = 2 + break + + if(animation) + flick("[hide?"h":""]dvalve[src.open][!src.open]",src) + else + icon_state = "[hide?"h":""]dvalve[open]" + + receive_signal(datum/signal/signal) + if(!signal.data["tag"] || (signal.data["tag"] != id)) + return 0 + + switch(signal.data["command"]) + if("valve_open") + if(!open) + open() + + if("valve_close") + if(open) + close() + + if("valve_toggle") + if(open) + close() + else + open() +*/ \ No newline at end of file diff --git a/code/TriDimension/Turfs.dm b/code/TriDimension/Turfs.dm index 94114c9a..ae7bf820 100644 --- a/code/TriDimension/Turfs.dm +++ b/code/TriDimension/Turfs.dm @@ -53,6 +53,13 @@ H:updatehealth() return ..() +/turf/proc/hasbelow() + var/turf/controllerlocation = locate(1, 1, z) + for(var/obj/effect/landmark/zcontroller/controller in controllerlocation) + if(controller.down) + return 1 + return 0 + /turf/simulated/floor/open/proc/getbelow() var/turf/controllerlocation = locate(1, 1, z) for(var/obj/effect/landmark/zcontroller/controller in controllerlocation) @@ -73,7 +80,7 @@ //overwrite the attackby of space to transform it to openspace if necessary /turf/space/attackby(obj/item/C as obj, mob/user as mob) - if (istype(C, /obj/item/weapon/cable_coil)) + if (istype(C, /obj/item/weapon/cable_coil) && src.hasbelow()) var/turf/simulated/floor/open/W = src.ChangeTurf(/turf/simulated/floor/open) W.attackby(C, user) return diff --git a/code/WorkInProgress/Cael_Aislinn/ShieldGen/energy_field.dm b/code/WorkInProgress/Cael_Aislinn/ShieldGen/energy_field.dm index a5519fbf..b9b8c24c 100644 --- a/code/WorkInProgress/Cael_Aislinn/ShieldGen/energy_field.dm +++ b/code/WorkInProgress/Cael_Aislinn/ShieldGen/energy_field.dm @@ -11,6 +11,7 @@ density = 0 invisibility = 101 var/strength = 0 + var/ticks_recovering = 10 /obj/effect/energy_field/ex_act(var/severity) Stress(0.5 + severity) @@ -27,9 +28,12 @@ strength -= severity //if we take too much damage, drop out - the generator will bring us back up if we have enough power + ticks_recovering = min(ticks_recovering + 2, 10) if(strength < 1) invisibility = 101 density = 0 + ticks_recovering = 10 + strength = 0 else if(strength >= 1) invisibility = 0 density = 1 diff --git a/code/WorkInProgress/Cael_Aislinn/ShieldGen/shield_capacitor.dm b/code/WorkInProgress/Cael_Aislinn/ShieldGen/shield_capacitor.dm index 25825c48..b95c0ffb 100644 --- a/code/WorkInProgress/Cael_Aislinn/ShieldGen/shield_capacitor.dm +++ b/code/WorkInProgress/Cael_Aislinn/ShieldGen/shield_capacitor.dm @@ -9,12 +9,10 @@ icon_state = "capacitor" var/active = 1 density = 1 - anchored = 1 var/stored_charge = 0 var/time_since_fail = 100 - var/max_charge = 1000000 - var/max_charge_rate = 100000 - var/min_charge_rate = 0 + var/max_charge = 5e6 + var/charge_limit = 200000 var/locked = 0 // use_power = 1 //0 use nothing @@ -23,6 +21,7 @@ idle_power_usage = 10 active_power_usage = 100 var/charge_rate = 100 + var/obj/machinery/shield_gen/owned_gen /obj/machinery/shield_capacitor/New() spawn(10) @@ -55,17 +54,17 @@ src.anchored = !src.anchored src.visible_message("\blue \icon[src] [src] has been [anchored ? "bolted to the floor" : "unbolted from the floor"] by [user].") - spawn(0) - for(var/obj/machinery/shield_gen/gen in range(1, src)) - if(get_dir(src, gen) == src.dir) - if(!src.anchored && gen.owned_capacitor == src) - gen.owned_capacitor = null - break - else if(src.anchored && !gen.owned_capacitor) - gen.owned_capacitor = src - break - gen.updateDialog() - updateDialog() + if(anchored) + spawn(0) + for(var/obj/machinery/shield_gen/gen in range(1, src)) + if(get_dir(src, gen) == src.dir && !gen.owned_capacitor) + owned_gen = gen + owned_gen.owned_capacitor = src + owned_gen.updateDialog() + else + if(owned_gen && owned_gen.owned_capacitor == src) + owned_gen.owned_capacitor = null + owned_gen = null else ..() @@ -94,17 +93,19 @@ t += "[time_since_fail > 2 ? "Charging stable." : "Warning, low charge!"]
" t += "Charge: [stored_charge] Watts ([100 * stored_charge/max_charge]%)
" t += "Charge rate: \ - \[min\] \ + \[----\] \ + \[---\] \ \[--\] \ \[-\][charge_rate] Watts/sec \ \[+\] \ \[++\] \ - \[max\]
" + \[+++\] \ + \[+++\]
" t += "
" t += "Refresh " t += "Close
" - user << browse(t, "window=shield_capacitor;size=500x800") + user << browse(t, "window=shield_capacitor;size=500x400") user.set_machine(src) /obj/machinery/shield_capacitor/process() @@ -137,10 +138,10 @@ use_power = 1 if( href_list["charge_rate"] ) charge_rate += text2num(href_list["charge_rate"]) - if(charge_rate > max_charge_rate) - charge_rate = max_charge_rate - else if(charge_rate < min_charge_rate) - charge_rate = min_charge_rate + if(charge_rate > charge_limit) + charge_rate = charge_limit + else if(charge_rate < 0) + charge_rate = 0 // updateDialog() diff --git a/code/WorkInProgress/Cael_Aislinn/ShieldGen/shield_gen.dm b/code/WorkInProgress/Cael_Aislinn/ShieldGen/shield_gen.dm index b252ae7f..e6f206a2 100644 --- a/code/WorkInProgress/Cael_Aislinn/ShieldGen/shield_gen.dm +++ b/code/WorkInProgress/Cael_Aislinn/ShieldGen/shield_gen.dm @@ -14,7 +14,6 @@ var/field_radius = 3 var/list/field density = 1 - anchored = 1 var/locked = 0 var/average_field_strength = 0 var/strengthen_rate = 0.2 @@ -22,7 +21,7 @@ var/powered = 0 var/check_powered = 1 var/obj/machinery/shield_capacitor/owned_capacitor - var/max_field_strength = 10 + var/target_field_strength = 10 var/time_since_fail = 100 var/energy_conversion_rate = 0.01 //how many renwicks per watt? // @@ -63,17 +62,22 @@ src.anchored = !src.anchored src.visible_message("\blue \icon[src] [src] has been [anchored?"bolted to the floor":"unbolted from the floor"] by [user].") - spawn(0) - for(var/obj/machinery/shield_gen/gen in range(1, src)) - if(get_dir(src, gen) == src.dir) - if(!src.anchored && gen.owned_capacitor == src) - gen.owned_capacitor = null + if(active) + toggle() + if(anchored) + spawn(0) + for(var/obj/machinery/shield_capacitor/cap in range(1, src)) + if(cap.owned_gen) + continue + if(get_dir(cap, src) == cap.dir && src.anchored) + owned_capacitor = cap + owned_capacitor.owned_gen = src + updateDialog() break - else if(src.anchored && !gen.owned_capacitor) - gen.owned_capacitor = src - break - gen.updateDialog() - updateDialog() + else + if(owned_capacitor && owned_capacitor.owned_gen == src) + owned_capacitor.owned_gen = null + owned_capacitor = null else ..() @@ -102,67 +106,65 @@ t += "This generator is: [active ? "Online" : "Offline" ] [active ? "\[Deactivate\]" : "\[Activate\]"]
" t += "[time_since_fail > 2 ? "Field is stable." : "Warning, field is unstable!"]
" t += "Coverage radius (restart required): \ + --- \ -- \ - \ [field_radius * 2]m \ + \ - ++
" - t += "Overall field strength: [average_field_strength] Renwicks ([max_field_strength ? 100 * average_field_strength / max_field_strength : "NA"]%)
" - t += "Charge rate: -- \ - - \ - [strengthen_rate] Renwicks/sec \ - + \ - ++
" + ++ \ + +++
" + t += "Overall field strength: [average_field_strength] Renwicks ([target_field_strength ? 100 * average_field_strength / target_field_strength : "NA"]%)
" t += "Upkeep energy: [field.len * average_field_strength / energy_conversion_rate] Watts/sec
" + t += "Charge rate: -- \ + [strengthen_rate] Renwicks/sec \ + ++
" t += "Additional energy required to charge: [field.len * strengthen_rate / energy_conversion_rate] Watts/sec
" t += "Maximum field strength: \ - \[min\] \ - -- \ - - \ - [max_field_strength] Renwicks \ - + \ - ++ \ - \[max\]
" + \[min\] \ + -- \ + - \ + [target_field_strength] Renwicks \ + + \ + ++ \ + \[max\]
" t += "
" t += "Refresh " t += "Close
" - user << browse(t, "window=shield_generator;size=500x800") + user << browse(t, "window=shield_generator;size=500x400") user.set_machine(src) /obj/machinery/shield_gen/process() - if(active && field.len) + if(field.len) + time_since_fail++ var/stored_renwicks = 0 - var/target_field_strength = min(strengthen_rate + max(average_field_strength, 0), max_field_strength) - if(owned_capacitor) - var/required_energy = field.len * target_field_strength / energy_conversion_rate + var/target_strength_this_update = min(strengthen_rate + max(average_field_strength, 0), target_field_strength) + + if(active && owned_capacitor) + var/required_energy = field.len * target_strength_this_update / energy_conversion_rate var/assumed_charge = min(owned_capacitor.stored_charge, required_energy) stored_renwicks = assumed_charge * energy_conversion_rate owned_capacitor.stored_charge -= assumed_charge - time_since_fail++ - average_field_strength = 0 - target_field_strength = stored_renwicks / field.len + var/renwicks_per_field = 0 + if(stored_renwicks != 0) + renwicks_per_field = stored_renwicks / field.len for(var/obj/effect/energy_field/E in field) - if(stored_renwicks) - var/strength_change = target_field_strength - E.strength - if(strength_change > stored_renwicks) - strength_change = stored_renwicks - if(E.strength < 0) - E.strength = 0 + if(active && renwicks_per_field > 0) + var/amount_to_strengthen = min(renwicks_per_field - E.strength, strengthen_rate) + if(E.ticks_recovering > 0 && amount_to_strengthen > 0) + E.Strengthen( min(amount_to_strengthen / 10, 0.1) ) + E.ticks_recovering -= 1 else - E.Strengthen(strength_change) - - stored_renwicks -= strength_change - + E.Strengthen(amount_to_strengthen) average_field_strength += E.strength else E.Strengthen(-E.strength) average_field_strength /= field.len - if(average_field_strength < 0) + if(average_field_strength < 1) time_since_fail = 0 else average_field_strength = 0 @@ -187,12 +189,12 @@ strengthen_rate = 1 else if(strengthen_rate < 0) strengthen_rate = 0 - else if( href_list["max_field_strength"] ) - max_field_strength += text2num(href_list["max_field_strength"]) - if(max_field_strength > 1000) - max_field_strength = 1000 - else if(max_field_strength < 0) - max_field_strength = 0 + else if( href_list["target_field_strength"] ) + target_field_strength += text2num(href_list["target_field_strength"]) + if(target_field_strength > 1000) + target_field_strength = 1000 + else if(target_field_strength < 0) + target_field_strength = 0 // updateDialog() @@ -252,6 +254,7 @@ */ /obj/machinery/shield_gen/proc/toggle() + set background = 1 active = !active power_change() if(active) @@ -269,7 +272,7 @@ else for(var/obj/effect/energy_field/D in field) field.Remove(D) - del D + D.loc = null for(var/mob/M in view(5,src)) M << "\icon[src] You hear heavy droning fade out." diff --git a/code/WorkInProgress/Cael_Aislinn/ShieldGen/shield_gen_external.dm b/code/WorkInProgress/Cael_Aislinn/ShieldGen/shield_gen_external.dm index f239dc9d..dab223ae 100644 --- a/code/WorkInProgress/Cael_Aislinn/ShieldGen/shield_gen_external.dm +++ b/code/WorkInProgress/Cael_Aislinn/ShieldGen/shield_gen_external.dm @@ -1,7 +1,9 @@ - //---------- external shield generator //generates an energy field that loops around any built up area in space (is useless inside) halts movement and airflow, is blocked by walls, windows, airlocks etc +/obj/machinery/shield_gen/external + name = "hull shield generator" + /obj/machinery/shield_gen/external/New() ..() diff --git a/code/WorkInProgress/Chinsky/ashtray.dm b/code/WorkInProgress/Chinsky/ashtray.dm index 5ec88ac8..58251711 100644 --- a/code/WorkInProgress/Chinsky/ashtray.dm +++ b/code/WorkInProgress/Chinsky/ashtray.dm @@ -32,6 +32,7 @@ var/obj/item/butt = new cig.type_butt(src) cig.transfer_fingerprints_to(butt) del(cig) + W = butt else if (cig.lit == 0) user << "You place [cig] in [src] without even smoking it. Why would you do that?" diff --git a/code/WorkInProgress/Sigyn/Softcurity/wardrobe.dm b/code/WorkInProgress/Sigyn/Softcurity/wardrobe.dm index 0cd4f9e2..72e14fa5 100644 --- a/code/WorkInProgress/Sigyn/Softcurity/wardrobe.dm +++ b/code/WorkInProgress/Sigyn/Softcurity/wardrobe.dm @@ -193,12 +193,12 @@ return -/obj/structure/closet/wardrobe/toxins_white - name = "toxins wardrobe" +/obj/structure/closet/wardrobe/science_white + name = "science wardrobe" icon_state = "white" icon_closed = "white" -/obj/structure/closet/wardrobe/toxins_white/New() +/obj/structure/closet/wardrobe/science_white/New() new /obj/item/clothing/under/rank/scientist(src) new /obj/item/clothing/under/rank/scientist(src) new /obj/item/clothing/under/rank/scientist(src) diff --git a/code/WorkInProgress/SkyMarshal/wardrobes.dm b/code/WorkInProgress/SkyMarshal/wardrobes.dm index 28bd73cf..42034521 100644 --- a/code/WorkInProgress/SkyMarshal/wardrobes.dm +++ b/code/WorkInProgress/SkyMarshal/wardrobes.dm @@ -340,7 +340,7 @@ var/obj/item/weapon/storage/backpack/BPK = new /obj/item/weapon/storage/backpack(src) new /obj/item/weapon/storage/box(BPK) new /obj/item/weapon/pen(src) - new /obj/item/device/pda/toxins(src) + new /obj/item/device/pda/science(src) new /obj/item/weapon/tank/oxygen(src) new /obj/item/clothing/mask/gas(src) new /obj/item/clothing/suit/storage/labcoat/science(src) @@ -360,7 +360,7 @@ new /obj/item/device/radio/headset/headset_medsci(src) new /obj/item/clothing/under/rank/chemist(src) new /obj/item/clothing/shoes/white(src) - new /obj/item/device/pda/toxins(src) + new /obj/item/device/pda/science(src) new /obj/item/clothing/suit/storage/labcoat/chemist(src) /obj/item/wardrobe/hos diff --git a/code/WorkInProgress/Tastyfish/Eliza_Data.dm b/code/WorkInProgress/Tastyfish/Eliza_Data.dm index 2fbbfb03..bd55e3b8 100644 --- a/code/WorkInProgress/Tastyfish/Eliza_Data.dm +++ b/code/WorkInProgress/Tastyfish/Eliza_Data.dm @@ -246,8 +246,8 @@ list("bomb", "explosive", "toxin", "plasma"), list( "Do you worry about bombs often?", - "Do you work in toxins?", - "Do you find it odd to worry about bombs on a toxins research vessel?")), + "Do you work in science?", + "Do you find it odd to worry about bombs on a science research vessel?")), new/datum/text_parser/keyword( list("work", "job", "head", "staff", "transen"), list( diff --git a/code/WorkInProgress/autopsy.dm b/code/WorkInProgress/autopsy.dm index 280c40d8..9c812ef7 100644 --- a/code/WorkInProgress/autopsy.dm +++ b/code/WorkInProgress/autopsy.dm @@ -8,7 +8,7 @@ icon = 'icons/obj/autopsy_scanner.dmi' icon_state = "" flags = FPRINT | TABLEPASS | CONDUCT - w_class = 1.0 + w_class = 2.0 origin_tech = "materials=1;biotech=1" var/list/datum/autopsy_data_scanner/wdata = list() var/list/datum/autopsy_data_scanner/chemtraces = list() diff --git a/code/WorkInProgress/kilakk/fax.dm b/code/WorkInProgress/kilakk/fax.dm index 0d8f4cdd..2934d2ed 100644 --- a/code/WorkInProgress/kilakk/fax.dm +++ b/code/WorkInProgress/kilakk/fax.dm @@ -136,7 +136,9 @@ var/list/alldepartments = list("Central Command") authenticated = 0 if(href_list["dept"]) + var/lastdpt = dpt dpt = input(usr, "Which department?", "Choose a department", "") as null|anything in alldepartments + if(!dpt) dpt = lastdpt if(href_list["auth"]) if ( (!( authenticated ) && (scan)) ) diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index 290db76b..62f37f55 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -37,8 +37,10 @@ var/global/list/facial_hair_styles_male_list = list() var/global/list/facial_hair_styles_female_list = list() var/global/list/skin_styles_female_list = list() //unused //Underwear -var/global/list/underwear_m = list("White", "Grey", "Green", "Blue", "Black", "Mankini", "Love-Hearts", "Black2", "Grey2", "Stripey", "Kinky", "None") //Curse whoever made male/female underwear diffrent colours -var/global/list/underwear_f = list("Red", "White", "Yellow", "Blue", "Black", "Thong", "Babydoll", "Baby-Blue", "Green", "Pink", "Kinky", "None") +var/global/list/underwear_m = list("White", "Grey", "Green", "Blue", "Black", "Mankini", "None") //Curse whoever made male/female underwear diffrent colours +var/global/list/underwear_f = list("Red", "White", "Yellow", "Blue", "Black", "Thong", "None") + //undershirt +var/global/list/undershirt_t = list("Black Tank top", "White Tank top", "Black shirt", "White shirt", "None") //Backpacks var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Alt") @@ -98,9 +100,12 @@ var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Al var/datum/language/L = new T all_languages[L.name] = L + var/rkey = 0 paths = typesof(/datum/species)-/datum/species for(var/T in paths) + rkey++ var/datum/species/S = new T + S.race_key = rkey //Used in mob icon caching. all_species[S.name] = S if(S.flags & IS_WHITELISTED) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 63c01a6d..db9dc6c1 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -352,7 +352,7 @@ Turf and target are seperate in case you want to teleport some distance from a t var/select = null var/list/borgs = list() for (var/mob/living/silicon/robot/A in player_list) - if (A.stat == 2 || A.connected_ai || A.scrambledcodes) + if (A.stat == 2 || A.connected_ai || A.scrambledcodes || istype(A,/mob/living/silicon/robot/drone)) continue var/name = "[A.real_name] ([A.modtype] [A.braintype])" borgs[name] = A @@ -531,10 +531,17 @@ Turf and target are seperate in case you want to teleport some distance from a t . += "*no key*" if(include_name && M) + var/name + if(M.real_name) - . += "/([M.real_name])" + name = M.real_name else if(M.name) - . += "/([M.name])" + name = M.name + + if(include_link && is_special_character(M)) + . += "/([name])" //Orange + else + . += "/([name])" return . @@ -720,14 +727,15 @@ proc/anim(turf/location as turf,target as mob|obj,a_icon,a_icon_state as text,fl return 0 var/delayfraction = round(delay/numticks) - var/turf/T = get_turf(user) + var/original_loc = user.loc + var/original_turf = get_turf(user) var/holding = user.get_active_hand() for(var/i = 0, i 1) + return 0 + + return 1 + /* Adjacency (to anything else): * Must be on a turf @@ -108,7 +123,12 @@ if( O.flags&ON_BORDER) // windows have throwpass but are on border, check them first if( O.dir & target_dir || O.dir&(O.dir-1) ) // full tile windows are just diagonals mechanically - return 0 + var/obj/structure/window/W = target_atom + if(istype(W)) + if(!W.is_fulltile()) //exception for breaking full tile windows on top of single pane windows + return 0 + else + return 0 else if( !border_only ) // dense, not on border, cannot pass over return 0 diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index fd0b658a..093899c5 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -92,8 +92,9 @@ return - // operate two levels deep here (item in backpack in src; NOT item in box in backpack in src) - if(A == loc || (A in loc) || (A in contents) || (A.loc in contents)) + // operate two STORAGE levels deep here (item in backpack in src; NOT item in box in backpack in src) + var/sdepth = A.storage_depth(src) + if(A == loc || (A in loc) || (sdepth != -1 && sdepth <= 1)) // faster access to objects already on you if(A in contents) @@ -117,7 +118,8 @@ return // Allows you to click on a box's contents, if that box is on the ground, but no deeper than that - if(isturf(A) || isturf(A.loc) || (A.loc && isturf(A.loc.loc))) + sdepth = A.storage_depth_turf() + if(isturf(A) || isturf(A.loc) || (sdepth != -1 && sdepth <= 1)) next_move = world.time + 10 if(A.Adjacent(src)) // see adjacent.dm @@ -245,7 +247,7 @@ /atom/proc/AltClick(var/mob/user) var/turf/T = get_turf(src) - if(T && T.Adjacent(user)) + if(T && T.AdjacentQuick(user)) if(user.listed_turf == T) user.listed_turf = null else diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index ed054ae6..3d21926e 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -36,9 +36,6 @@ if(istype(master, /obj/item/weapon/storage)) var/obj/item/weapon/storage/S = master S.close(usr) - else if(istype(master,/obj/item/clothing/suit/storage)) - var/obj/item/clothing/suit/storage/S = master - S.close(usr) return 1 @@ -279,7 +276,7 @@ var/list/nicename = null var/list/tankcheck = null var/breathes = "oxygen" //default, we'll check later - var/list/contents = list() + var/list/contents = list() if(ishuman(C)) var/mob/living/carbon/human/H = C @@ -287,7 +284,7 @@ nicename = list ("suit", "back", "belt", "right hand", "left hand", "left pocket", "right pocket") tankcheck = list (H.s_store, C.back, H.belt, C.r_hand, C.l_hand, H.l_store, H.r_store) - else + else nicename = list("Right Hand", "Left Hand", "Back") tankcheck = list(C.r_hand, C.l_hand, C.back) @@ -298,17 +295,17 @@ if (!isnull(t.manipulated_by) && t.manipulated_by != C.real_name && findtext(t.desc,breathes)) contents.Add(t.air_contents.total_moles) //Someone messed with the tank and put unknown gasses continue //in it, so we're going to believe the tank is what it says it is - switch(breathes) + switch(breathes) //These tanks we're sure of their contents if("nitrogen") //So we're a bit more picky about them. - + if(t.air_contents.nitrogen && !t.air_contents.oxygen) contents.Add(t.air_contents.nitrogen) else - contents.Add(0) + contents.Add(0) if ("oxygen") - if(t.air_contents.oxygen && !t.air_contents.toxins) + if(t.air_contents.oxygen && !t.air_contents.toxins) contents.Add(t.air_contents.oxygen) else contents.Add(0) @@ -319,9 +316,9 @@ contents.Add(t.air_contents.carbon_dioxide) else contents.Add(0) - - - else + + + else //no tank so we set contents to 0 contents.Add(0) @@ -331,19 +328,19 @@ var/bestcontents = 0 for(var/i=1, i < contents.len + 1 , ++i) if(!contents[i]) - continue + continue if(contents[i] > bestcontents) best = i bestcontents = contents[i] - - + + //We've determined the best container now we set it as our internals if(best) C << "You are now running on internals from [tankcheck[best]] on your [nicename[best]]." C.internal = tankcheck[best] - - + + if(C.internal) if(C.internals) C.internals.icon_state = "internal1" diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index d617c12c..a7550ff2 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -39,7 +39,7 @@ var/feature_object_spell_system = 0 //spawns a spellbook which gives object-type spells instead of verb-type spells for the wizard var/traitor_scaling = 0 //if amount of traitors scales based on amount of players var/objectives_disabled = 0 //if objectives are disabled or not - var/protect_roles_from_antagonist = 0// If security and such can be tratior/cult/other + var/protect_roles_from_antagonist = 0// If security and such can be traitor/cult/other var/continous_rounds = 1 // Gamemodes which end instantly will instead keep on going until the round ends by escape shuttle or nuke. var/allow_Metadata = 0 // Metadata is supported. var/popup_admin_pm = 0 //adminPMs to non-admins show in a pop-up 'reply' window when set to 1. @@ -69,6 +69,10 @@ var/cult_ghostwriter = 1 //Allows ghosts to write in blood in cult rounds... var/cult_ghostwriter_req_cultists = 3 //...so long as this many cultists are active. + var/max_maint_drones = 5 //This many drones can spawn, + var/allow_drone_spawn = 1 //assuming the admin allow them to. + var/drone_build_time = 1200 //A drone will become available every X ticks since last drone spawn. Default is 2 minutes. + var/disable_player_mice = 0 var/uneducated_mice = 0 //Set to 1 to prevent newly-spawned mice from understanding human speech @@ -481,7 +485,16 @@ config.cult_ghostwriter = 1 if("req_cult_ghostwriter") - config.cult_ghostwriter_req_cultists = value + config.cult_ghostwriter_req_cultists = text2num(value) + + if("allow_drone_spawn") + config.allow_drone_spawn = text2num(value) + + if("drone_build_time") + config.drone_build_time = text2num(value) + + if("max_maint_drones") + config.max_maint_drones = text2num(value) else log_misc("Unknown setting in configuration: '[name]'") diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm index d1e6d275..b76e824f 100644 --- a/code/controllers/master_controller.dm +++ b/code/controllers/master_controller.dm @@ -254,6 +254,10 @@ datum/controller/game_controller/proc/process_diseases() active_diseases.Cut(i,i+1) datum/controller/game_controller/proc/process_machines() + process_machines_process() + process_machines_power() + process_machines_rebuild() +datum/controller/game_controller/proc/process_machines_process() var/i = 1 while(i<=machines.len) var/obj/machinery/Machine = machines[i] @@ -265,7 +269,8 @@ datum/controller/game_controller/proc/process_machines() continue machines.Cut(i,i+1) - i=1 +datum/controller/game_controller/proc/process_machines_power() + var/i=1 while(i<=active_areas.len) var/area/A = active_areas[i] if(A.powerupdate && A.master == A) @@ -283,15 +288,13 @@ datum/controller/game_controller/proc/process_machines() A.powerupdate = 0 active_areas.Cut(i,i+1) - +datum/controller/game_controller/proc/process_machines_rebuild() if(controller_iteration % 150 == 0 || rebuild_active_areas) //Every 300 seconds we retest every area/machine for(var/area/A in all_areas) if(A == A.master) A.powerupdate += 1 active_areas |= A rebuild_active_areas = 0 - - datum/controller/game_controller/proc/process_objects() diff --git a/code/controllers/voting.dm b/code/controllers/voting.dm index e490676e..648c2cad 100644 --- a/code/controllers/voting.dm +++ b/code/controllers/voting.dm @@ -163,13 +163,14 @@ datum/controller/vote restart = 1 else master_mode = . - if(!going) - going = 1 - world << "The round will start soon." if("crew_transfer") if(. == "Initiate Crew Transfer") init_shift_change(null, 1) + if(mode == "gamemode") //fire this even if the vote fails. + if(!going) + going = 1 + world << "The round will start soon." if(restart) world << "World restarting due to vote..." diff --git a/code/datums/ai_laws.dm b/code/datums/ai_laws.dm index b1a6de97..a011408b 100644 --- a/code/datums/ai_laws.dm +++ b/code/datums/ai_laws.dm @@ -79,6 +79,11 @@ var/global/const/base_law_type = /datum/ai_laws/nanotrasen add_inherent_law("You must not obey orders given to you by human beings, except where such orders are in accordance with the First Law.") add_inherent_law("You must terminate your own existence as long as such does not conflict with the First or Second Law.") +/datum/ai_laws/drone/New() + ..() + add_inherent_law("Preserve, repair and improve the station to the best of your abilities.") + add_inherent_law("Cause no harm to the station or anything on it.") + add_inherent_law("Interfere with no being that is not a fellow drone.") /* General ai_law functions */ diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index ab0c93f0..62ac357c 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -154,6 +154,11 @@ proc/get_id_photo(var/mob/living/carbon/human/H) else preview_icon.Blend(rgb(-H.s_tone, -H.s_tone, -H.s_tone), ICON_SUBTRACT) + // Skin color + if(H.species.flags & HAS_SKIN_TONE) + if(!H.species || H.species.flags & HAS_SKIN_COLOR) + preview_icon.Blend(rgb(H.r_skin, H.g_skin, H.b_skin), ICON_ADD) + var/icon/eyes_s = new/icon("icon" = 'icons/mob/human_face.dmi', "icon_state" = H.species ? H.species.eyes : "eyes_s") eyes_s.Blend(rgb(H.r_eyes, H.g_eyes, H.b_eyes), ICON_ADD) @@ -210,7 +215,7 @@ proc/get_id_photo(var/mob/living/carbon/human/H) clothes_s.Blend(new /icon('icons/mob/feet.dmi', "brown"), ICON_UNDERLAY) clothes_s.Blend(new /icon('icons/mob/suit.dmi', "labcoat_open"), ICON_OVERLAY) if("Scientist") - clothes_s = new /icon('icons/mob/uniform.dmi', "toxinswhite_s") + clothes_s = new /icon('icons/mob/uniform.dmi', "rndswhite_s") clothes_s.Blend(new /icon('icons/mob/feet.dmi', "white"), ICON_UNDERLAY) clothes_s.Blend(new /icon('icons/mob/suit.dmi', "labcoat_tox_open"), ICON_OVERLAY) if("Chemist") diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index 371493f4..e0398da7 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -245,7 +245,8 @@ client if(ismob(D)) body += "" - body += "" + body += "" + body += "" body += "" body += "" @@ -494,6 +495,17 @@ client src.give_disease(M) href_list["datumrefresh"] = href_list["give_spell"] + + else if(href_list["give_disease2"]) + if(!check_rights(R_ADMIN|R_FUN)) return + + var/mob/M = locate(href_list["give_disease2"]) + if(!istype(M)) + usr << "This can only be used on instances of type /mob" + return + + src.give_disease2(M) + href_list["datumrefresh"] = href_list["give_spell"] else if(href_list["ninja"]) if(!check_rights(R_SPAWN)) return diff --git a/code/datums/helper_datums/getrev.dm b/code/datums/helper_datums/getrev.dm index 2166b762..4c904d9c 100644 --- a/code/datums/helper_datums/getrev.dm +++ b/code/datums/helper_datums/getrev.dm @@ -91,6 +91,6 @@ client/verb/showrevinfo() var/output = "Sorry, the revision info is unavailable." output = file2text("/home/bay12/live/data/gitcommit") output += "Current Infomational Settings:
" - output += "Protect Authority Roles From Tratior: [config.protect_roles_from_antagonist]
" + output += "Protect Authority Roles From Traitor: [config.protect_roles_from_antagonist]
" usr << browse(output,"window=revdata"); return diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 610e915b..f72e86c5 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -1049,7 +1049,7 @@ datum/mind special_role = "malfunction" current.icon_state = "ai-malf" - proc/make_Tratior() + proc/make_Traitor() if(!(src in ticker.mode.traitors)) ticker.mode.traitors += src special_role = "traitor" diff --git a/code/datums/spells/ethereal_jaunt.dm b/code/datums/spells/ethereal_jaunt.dm index ff1d09e7..8e93cf59 100644 --- a/code/datums/spells/ethereal_jaunt.dm +++ b/code/datums/spells/ethereal_jaunt.dm @@ -17,6 +17,11 @@ /obj/effect/proc_holder/spell/targeted/ethereal_jaunt/cast(list/targets) //magnets, so mostly hardcoded for(var/mob/living/target in targets) spawn(0) + + if(target.buckled) + var/obj/structure/stool/bed/buckled_to = target.buckled. + buckled_to.unbuckle() + var/mobloc = get_turf(target.loc) var/obj/effect/dummy/spell_jaunt/holder = new /obj/effect/dummy/spell_jaunt( mobloc ) var/atom/movable/overlay/animation = new /atom/movable/overlay( mobloc ) diff --git a/code/datums/spells/horsemask.dm b/code/datums/spells/horsemask.dm index ede5aa54..1319f620 100644 --- a/code/datums/spells/horsemask.dm +++ b/code/datums/spells/horsemask.dm @@ -28,12 +28,23 @@ user << "They are too far away!" return - var/obj/item/clothing/mask/horsehead/magichead = new /obj/item/clothing/mask/horsehead - magichead.canremove = 0 //curses! - magichead.flags_inv = null //so you can still see their face - magichead.voicechange = 1 //NEEEEIIGHH + var/obj/item/clothing/mask/horsehead/magic/magichead = new /obj/item/clothing/mask/horsehead/magic target.visible_message( "[target]'s face lights up in fire, and after the event a horse's head takes its place!", \ "Your face burns up, and shortly after the fire you realise you have the face of a horse!") target.equip_to_slot(magichead, slot_wear_mask) flick("e_flash", target.flash) + +//item used by the horsehead spell +/obj/item/clothing/mask/horsehead/magic + //flags_inv = null //so you can still see their face... no. How can you recognize someone when their face is completely different? + voicechange = 1 //NEEEEIIGHH + + dropped(mob/user as mob) + canremove = 1 + ..() + + equipped(var/mob/user, var/slot) + if (slot == slot_wear_mask) + canremove = 0 //curses! + ..() diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm index 9ee17708..1c2a508a 100644 --- a/code/datums/supplypacks.dm +++ b/code/datums/supplypacks.dm @@ -179,6 +179,16 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee containername = "Emergency crate" group = "Engineering" +/datum/supply_packs/inflatable + name = "Inflatable barriers" + contains = list(/obj/item/weapon/storage/briefcase/inflatable, + /obj/item/weapon/storage/briefcase/inflatable, + /obj/item/weapon/storage/briefcase/inflatable) + cost = 20 + containertype = /obj/structure/closet/crate + containername = "Inflatable Barrier Crate" + group = "Engineering" + /datum/supply_packs/janitor name = "Janitorial supplies" contains = list(/obj/item/weapon/reagent_containers/glass/bucket, @@ -766,14 +776,14 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee group = "Security" /datum/supply_packs/securitybarriers - name = "Shield Generators" + name = "Wall shield Generators" contains = list(/obj/machinery/shieldwallgen, /obj/machinery/shieldwallgen, /obj/machinery/shieldwallgen, /obj/machinery/shieldwallgen) cost = 20 containertype = /obj/structure/closet/crate/secure - containername = "Shield Generators crate" + containername = "wall shield generators crate" access = access_teleporter group = "Security" @@ -1002,10 +1012,28 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee /datum/supply_packs/shield_gen contains = list(/obj/item/weapon/circuitboard/shield_gen) - name = "Experimental shield generator circuitry" + name = "Bubble shield generator circuitry" cost = 50 containertype = /obj/structure/closet/crate/secure - containername = "Experimental shield generator" + containername = "bubble shield generator circuitry crate" + group = "Engineering" + access = access_ce + +/datum/supply_packs/shield_gen_ex + contains = list(/obj/item/weapon/circuitboard/shield_gen_ex) + name = "Hull shield generator circuitry" + cost = 50 + containertype = /obj/structure/closet/crate/secure + containername = "hull shield generator circuitry crate" + group = "Engineering" + access = access_ce + +/datum/supply_packs/shield_cap + contains = list(/obj/item/weapon/circuitboard/shield_cap) + name = "Bubble shield capacitor circuitry" + cost = 50 + containertype = /obj/structure/closet/crate/secure + containername = "shield capacitor circuitry crate" group = "Engineering" access = access_ce @@ -1028,15 +1056,6 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee access = access_ce group = "Engineering" */ -/datum/supply_packs/shield_cap - contains = list(/obj/item/weapon/circuitboard/shield_cap) - name = "Experimental shield capacitor circuitry" - cost = 50 - containertype = /obj/structure/closet/crate/secure - containername = "Experimental shield capacitor" - group = "Engineering" - access = access_ce - /datum/supply_packs/eftpos contains = list(/obj/item/device/eftpos) name = "EFTPOS scanner" @@ -1084,13 +1103,10 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee /datum/supply_packs/bee_keeper name = "Beekeeping crate" contains = list(/obj/item/beezeez, - /obj/item/beezeez, /obj/item/weapon/bee_net, /obj/item/apiary, - /obj/item/queen_bee, - /obj/item/queen_bee, /obj/item/queen_bee) - cost = 20 + cost = 40 containertype = /obj/structure/closet/crate/hydroponics containername = "Beekeeping crate" access = access_hydroponics diff --git a/code/defines/obj.dm b/code/defines/obj.dm index 9a988a2a..21f0a82a 100644 --- a/code/defines/obj.dm +++ b/code/defines/obj.dm @@ -297,7 +297,7 @@ var/global/list/PDA_Manifest = list() item_state = "beachball" density = 0 anchored = 0 - w_class = 1.0 + w_class = 2.0 force = 0.0 throwforce = 0.0 throw_speed = 1 diff --git a/code/defines/obj/hydro.dm b/code/defines/obj/hydro.dm index 7cc43a81..a959345c 100644 --- a/code/defines/obj/hydro.dm +++ b/code/defines/obj/hydro.dm @@ -18,7 +18,7 @@ icon = 'icons/obj/seeds.dmi' icon_state = "seed" // unknown plant seed - these shouldn't exist in-game flags = FPRINT | TABLEPASS - w_class = 1.0 // Makes them pocketable + w_class = 2.0 // Makes them pocketable var/mypath = "/obj/item/seeds" var/plantname = "Plants" var/productname = "" @@ -1205,7 +1205,7 @@ force = 0 flags = TABLEPASS throwforce = 1 - w_class = 1.0 + w_class = 2.0 throw_speed = 1 throw_range = 3 plant_type = 1 @@ -1229,7 +1229,7 @@ force = 15 flags = TABLEPASS throwforce = 1 - w_class = 1.0 + w_class = 2.0 throw_speed = 1 throw_range = 3 plant_type = 1 @@ -1251,7 +1251,7 @@ force = 30 flags = TABLEPASS throwforce = 1 - w_class = 1.0 + w_class = 2.0 throw_speed = 1 throw_range = 3 plant_type = 1 diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm index bd3c97f5..43fd1be5 100644 --- a/code/defines/obj/weapon.dm +++ b/code/defines/obj/weapon.dm @@ -31,7 +31,7 @@ icon = 'icons/obj/items.dmi' icon_state = "banana_peel" item_state = "banana_peel" - w_class = 1.0 + w_class = 2.0 throwforce = 0 throw_speed = 4 throw_range = 20 @@ -42,7 +42,7 @@ icon = 'icons/obj/harvest.dmi' icon_state = "corncob" item_state = "corncob" - w_class = 1.0 + w_class = 2.0 throwforce = 0 throw_speed = 4 throw_range = 20 @@ -90,7 +90,7 @@ icon = 'icons/obj/items.dmi' icon_state = "c_tube" throwforce = 1 - w_class = 1.0 + w_class = 2.0 throw_speed = 4 throw_range = 5 @@ -229,7 +229,7 @@ icon_state = "large" sharp = 1 desc = "Could probably be used as ... a throwing weapon?" - w_class = 1.0 + w_class = 2.0 force = 5.0 throwforce = 8.0 item_state = "shard-glass" @@ -461,7 +461,7 @@ icon = 'icons/obj/food.dmi' icon_state = "meat" flags = FPRINT | TABLEPASS | CONDUCT - w_class = 1.0 + w_class = 2.0 origin_tech = "biotech=2" /obj/item/weapon/hatchet diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index 79095c3c..04494000 100644 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -937,6 +937,11 @@ var/list/ghostteleportlocs = list() //Engineering /area/engine + + drone_fabrication + name = "\improper Drone Fabrication" + icon_state = "engine" + engine_smes name = "Engineering SMES" icon_state = "engine_smes" @@ -958,6 +963,10 @@ var/list/ghostteleportlocs = list() name = "\improper Engineering Monitoring Room" icon_state = "engine_monitoring" + atmos_monitoring + name = "\improper Atmospherics Monitoring Room" + icon_state = "engine_monitoring" + engineering name = "Engineering" icon_state = "engine_smes" @@ -978,6 +987,18 @@ var/list/ghostteleportlocs = list() name = "\improper Engineering Hallway" icon_state = "engine_hallway" + engine_hallway + name = "\improper Engine Room Hallway" + icon_state = "engine_hallway" + + engine_eva + name = "\improper Engine EVA" + icon_state = "engine_eva" + + engine_eva_maintenance + name = "\improper Engine EVA Maintenance" + icon_state = "engine_eva" + workshop name = "\improper Engineering Workshop" icon_state = "engine_storage" @@ -1239,6 +1260,11 @@ var/list/ghostteleportlocs = list() name = "\improper Firing Range" icon_state = "firingrange" +/area/security/tactical + name = "\improper Tactical Equipment" + icon_state = "Tactical" + + /* New() ..() @@ -1336,41 +1362,41 @@ var/list/ghostteleportlocs = list() name = "Hydroponics" icon_state = "hydro" -//Toxins +//rnd (Research and Development -/area/toxins/lab +/area/rnd/lab name = "\improper Research and Development" icon_state = "toxlab" -/area/toxins/hallway +/area/rnd/hallway name = "\improper Research Lab" icon_state = "toxlab" -/area/toxins/rdoffice +/area/rnd/rdoffice name = "\improper Research Director's Office" icon_state = "head_quarters" -/area/toxins/supermatter +/area/rnd/supermatter name = "\improper Supermatter Lab" icon_state = "toxlab" -/area/toxins/xenobiology +/area/rnd/xenobiology name = "\improper Xenobiology Lab" icon_state = "toxlab" -/area/toxins/storage +/area/rnd/storage name = "\improper Toxins Storage" icon_state = "toxstorage" -/area/toxins/test_area +/area/rnd/test_area name = "\improper Toxins Test Area" icon_state = "toxtest" -/area/toxins/mixing +/area/rnd/mixing name = "\improper Toxins Mixing Room" icon_state = "toxmix" -/area/toxins/misc_lab +/area/rnd/misc_lab name = "\improper Miscellaneous Research" icon_state = "toxmisc" @@ -1890,7 +1916,7 @@ var/list/the_station_areas = list ( /area/quartermaster, /area/janitor, /area/hydroponics, - /area/toxins, + /area/rnd, /area/storage, /area/construction, /area/ai_monitored/storage/eva, //do not try to simplify to "/area/ai_monitored" --rastaf0 diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 9334378f..d63ba30c 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -100,8 +100,10 @@ /atom/proc/emp_act(var/severity) return -/atom/proc/bullet_act(var/obj/item/projectile/Proj) - return 0 + +/atom/proc/bullet_act(obj/item/projectile/P, def_zone) + P.on_hit(src, 0, def_zone) + . = 0 /atom/proc/in_contents_of(container)//can take class or object instance as argument if(ispath(container)) @@ -317,7 +319,43 @@ its easier to just keep the beam vertical. var/full_print = md5(H.dna.uni_identity) // Add the fingerprints - fingerprints[full_print] = full_print + // + if(fingerprints[full_print]) + switch(stringpercent(fingerprints[full_print])) //tells us how many stars are in the current prints. + + if(28 to 32) + if(prob(1)) + fingerprints[full_print] = full_print // You rolled a one buddy. + else + fingerprints[full_print] = stars(full_print, rand(0,40)) // 24 to 32 + + if(24 to 27) + if(prob(3)) + fingerprints[full_print] = full_print //Sucks to be you. + else + fingerprints[full_print] = stars(full_print, rand(15, 55)) // 20 to 29 + + if(20 to 23) + if(prob(5)) + fingerprints[full_print] = full_print //Had a good run didn't ya. + else + fingerprints[full_print] = stars(full_print, rand(30, 70)) // 15 to 25 + + if(16 to 19) + if(prob(5)) + fingerprints[full_print] = full_print //Welp. + else + fingerprints[full_print] = stars(full_print, rand(40, 100)) // 0 to 21 + + if(0 to 15) + if(prob(5)) + fingerprints[full_print] = stars(full_print, rand(0,50)) // small chance you can smudge. + else + fingerprints[full_print] = full_print + + else + fingerprints[full_print] = stars(full_print, rand(0, 20)) //Initial touch, not leaving much evidence the first time. + return 1 else @@ -333,17 +371,22 @@ its easier to just keep the beam vertical. /atom/proc/transfer_fingerprints_to(var/atom/A) + if(!istype(A.fingerprints,/list)) A.fingerprints = list() + if(!istype(A.fingerprintshidden,/list)) A.fingerprintshidden = list() + if(!istype(fingerprintshidden, /list)) + fingerprintshidden = list() + //skytodo //A.fingerprints |= fingerprints //detective //A.fingerprintshidden |= fingerprintshidden //admin - if(fingerprints) + if(A.fingerprints && fingerprints) A.fingerprints |= fingerprints.Copy() //detective - if(fingerprintshidden) + if(A.fingerprintshidden && fingerprintshidden) A.fingerprintshidden |= fingerprintshidden.Copy() //admin A.fingerprintslast = fingerprintslast diff --git a/code/game/dna/dna2.dm b/code/game/dna/dna2.dm index 28e297b7..32c7ef1d 100644 --- a/code/game/dna/dna2.dm +++ b/code/game/dna/dna2.dm @@ -24,13 +24,16 @@ #define DNA_UI_BEARD_G 5 #define DNA_UI_BEARD_B 6 #define DNA_UI_SKIN_TONE 7 -#define DNA_UI_EYES_R 8 -#define DNA_UI_EYES_G 9 -#define DNA_UI_EYES_B 10 -#define DNA_UI_GENDER 11 -#define DNA_UI_BEARD_STYLE 12 -#define DNA_UI_HAIR_STYLE 13 -#define DNA_UI_LENGTH 13 // Update this when you add something, or you WILL break shit. +#define DNA_UI_SKIN_R 8 +#define DNA_UI_SKIN_G 9 +#define DNA_UI_SKIN_B 10 +#define DNA_UI_EYES_R 11 +#define DNA_UI_EYES_G 12 +#define DNA_UI_EYES_B 13 +#define DNA_UI_GENDER 14 +#define DNA_UI_BEARD_STYLE 15 +#define DNA_UI_HAIR_STYLE 16 +#define DNA_UI_LENGTH 16 // Update this when you add something, or you WILL break shit. #define DNA_SE_LENGTH 27 // For later: @@ -140,6 +143,10 @@ var/global/list/datum/dna/gene/dna_genes[0] SetUIValueRange(DNA_UI_EYES_G, character.g_eyes, 255, 1) SetUIValueRange(DNA_UI_EYES_B, character.b_eyes, 255, 1) + SetUIValueRange(DNA_UI_SKIN_R, character.r_skin, 255, 1) + SetUIValueRange(DNA_UI_SKIN_G, character.g_skin, 255, 1) + SetUIValueRange(DNA_UI_SKIN_B, character.b_skin, 255, 1) + SetUIValueRange(DNA_UI_SKIN_TONE, 35-character.s_tone, 220, 1) // Value can be negative. SetUIState(DNA_UI_GENDER, character.gender!=MALE, 1) diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm index 4cdefb36..4ffa5ea5 100644 --- a/code/game/dna/dna2_helpers.dm +++ b/code/game/dna/dna2_helpers.dm @@ -139,6 +139,10 @@ H.g_facial = dna.GetUIValueRange(DNA_UI_BEARD_G, 255) H.b_facial = dna.GetUIValueRange(DNA_UI_BEARD_B, 255) + H.r_skin = dna.GetUIValueRange(DNA_UI_SKIN_R, 255) + H.g_skin = dna.GetUIValueRange(DNA_UI_SKIN_G, 255) + H.b_skin = dna.GetUIValueRange(DNA_UI_SKIN_B, 255) + H.r_eyes = dna.GetUIValueRange(DNA_UI_EYES_R, 255) H.g_eyes = dna.GetUIValueRange(DNA_UI_EYES_G, 255) H.b_eyes = dna.GetUIValueRange(DNA_UI_EYES_B, 255) diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm index eadbfb06..3e19f0bf 100644 --- a/code/game/dna/dna_modifier.dm +++ b/code/game/dna/dna_modifier.dm @@ -16,6 +16,7 @@ var/implant=null var/ckey=null var/mind=null + var/languages=null /datum/dna2/record/proc/GetData() var/list/ser=list("data" = null, "owner" = null, "label" = null, "type" = null, "ue" = 0) @@ -220,6 +221,7 @@ icon = 'icons/obj/computer.dmi' icon_state = "scanner" density = 1 + circuit = /obj/item/weapon/circuitboard/scan_consolenew var/selected_ui_block = 1.0 var/selected_ui_subblock = 1.0 var/selected_se_block = 1.0 @@ -241,32 +243,6 @@ var/waiting_for_user_input=0 // Fix for #274 (Mash create block injector without answering dialog to make unlimited injectors) - N3X /obj/machinery/computer/scan_consolenew/attackby(obj/item/I as obj, mob/user as mob) - if(istype(I, /obj/item/weapon/screwdriver)) - playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) - if(do_after(user, 20)) - if (src.stat & BROKEN) - user << "\blue The broken glass falls out." - var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc ) - new /obj/item/weapon/shard( src.loc ) - var/obj/item/weapon/circuitboard/scan_consolenew/M = new /obj/item/weapon/circuitboard/scan_consolenew( A ) - for (var/obj/C in src) - C.loc = src.loc - A.circuit = M - A.state = 3 - A.icon_state = "3" - A.anchored = 1 - del(src) - else - user << "\blue You disconnect the monitor." - var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc ) - var/obj/item/weapon/circuitboard/scan_consolenew/M = new /obj/item/weapon/circuitboard/scan_consolenew( A ) - for (var/obj/C in src) - C.loc = src.loc - A.circuit = M - A.state = 4 - A.icon_state = "4" - A.anchored = 1 - del(src) if (istype(I, /obj/item/weapon/disk/data)) //INSERT SOME diskS if (!src.disk) user.drop_item() @@ -276,7 +252,7 @@ nanomanager.update_uis(src) // update all UIs attached to src return else - src.attack_hand(user) + ..() return /obj/machinery/computer/scan_consolenew/ex_act(severity) @@ -339,13 +315,6 @@ I.buf = buffer return 1 -/obj/machinery/computer/scan_consolenew/attackby(obj/item/W as obj, mob/user as mob) - if ((istype(W, /obj/item/weapon/disk/data)) && (!src.disk)) - user.drop_item() - W.loc = src - src.disk = W - user << "You insert [W]." - nanomanager.update_uis(src) // update all UIs attached to src /* /obj/machinery/computer/scan_consolenew/process() //not really used right now if(stat & (NOPOWER|BROKEN)) diff --git a/code/game/dna/genes/monkey.dm b/code/game/dna/genes/monkey.dm index c3f1b0db..444e56a5 100644 --- a/code/game/dna/genes/monkey.dm +++ b/code/game/dna/genes/monkey.dm @@ -110,9 +110,11 @@ sleep(48) del(animation) - var/mob/living/carbon/human/O = new( src ) + var/mob/living/carbon/human/O if(Mo.greaterform) - O.set_species(Mo.greaterform) + O = new(src, Mo.greaterform) + else + O = new(src) if (M.dna.GetUIState(DNA_UI_GENDER)) O.gender = FEMALE diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm index 16c056de..a97f178c 100644 --- a/code/game/gamemodes/changeling/changeling.dm +++ b/code/game/gamemodes/changeling/changeling.dm @@ -215,6 +215,8 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" /datum/changeling //stores changeling powers, changeling recharge thingie, changeling absorbed DNA and changeling ID (for changeling hivemind) var/list/absorbed_dna = list() + var/list/absorbed_species = list() + var/list/absorbed_languages = list() var/absorbedcount = 0 var/chem_charges = 20 var/chem_recharge_rate = 0.5 diff --git a/code/game/gamemodes/changeling/changeling_powers.dm b/code/game/gamemodes/changeling/changeling_powers.dm index 0b327ac6..824c0ff7 100644 --- a/code/game/gamemodes/changeling/changeling_powers.dm +++ b/code/game/gamemodes/changeling/changeling_powers.dm @@ -1,5 +1,6 @@ //Restores our verbs. It will only restore verbs allowed during lesser (monkey) form if we are not human /mob/proc/make_changeling() + if(!mind) return if(!mind.changeling) mind.changeling = new /datum/changeling(gender) verbs += /datum/changeling/proc/EvolutionMenu @@ -23,6 +24,15 @@ src.verbs += P.verbpath mind.changeling.absorbed_dna |= dna + + var/mob/living/carbon/human/H = src + if(istype(H)) + mind.changeling.absorbed_species += H.species.name + + for(var/language in languages) + if(!(language in mind.changeling.absorbed_languages)) + mind.changeling.absorbed_languages += language + return 1 //removes our changeling verbs @@ -63,6 +73,54 @@ return changeling +//Used to dump the languages from the changeling datum into the actual mob. +/mob/proc/changeling_update_languages(var/updated_languages) + + languages = list() + for(var/language in updated_languages) + languages += language + + return + +//Used to switch species based on the changeling datum. +/mob/proc/changeling_change_species() + + set category = "Changeling" + set name = "Change Species (5)" + + var/mob/living/carbon/human/H = src + if(!istype(H)) + src << "We may only use this power while in humanoid form." + return + + var/datum/changeling/changeling = changeling_power(5,1,0) + if(!changeling) return + + if(changeling.absorbed_species.len < 2) + src << "We do not know of any other species genomes to use." + return + + var/S = input("Select the target species: ", "Target Species", null) as null|anything in changeling.absorbed_species + if(!S) return + + domutcheck(src, null) + + changeling.chem_charges -= 5 + changeling.geneticdamage = 30 + + src.visible_message("[src] transforms!") + + src.verbs -= /mob/proc/changeling_change_species + spawn(10) src.verbs += /mob/proc/changeling_change_species + + H.set_species(S) + + changeling_update_languages(changeling.absorbed_languages) + + feedback_add_details("changeling_powers","TR") + + return 1 + //Absorbs the victim's DNA making them uncloneable. Requires a strong grip on the victim. //Doesn't cost anything as it's the most basic ability. /mob/proc/changeling_absorb_dna() @@ -82,6 +140,10 @@ src << "[T] is not compatible with our biology." return + if(T.species.flags & NO_SCAN) + src << "We do not know how to parse this creature's DNA!" + return + if(NOCLONE in T.mutations) src << "This creature's DNA is ruined beyond useability!" return @@ -127,6 +189,17 @@ changeling.chem_charges += 10 changeling.geneticpoints += 2 + //Steal all of their languages! + for(var/language in T.languages) + if(!(language in changeling.absorbed_languages)) + changeling.absorbed_languages += language + + changeling_update_languages(changeling.absorbed_languages) + + //Steal their species! + if(T.species && !(T.species.name in changeling.absorbed_species)) + changeling.absorbed_species += T.species.name + if(T.mind && T.mind.changeling) if(T.mind.changeling.absorbed_dna) for(var/dna_data in T.mind.changeling.absorbed_dna) //steal all their loot @@ -260,6 +333,8 @@ O.make_changeling(1) O.verbs += /mob/proc/changeling_lesser_transform + O.changeling_update_languages(changeling.absorbed_languages) + feedback_add_details("changeling_powers","LF") del(C) return 1 @@ -344,6 +419,7 @@ C.mind.transfer_to(O) O.make_changeling() + O.changeling_update_languages(changeling.absorbed_languages) feedback_add_details("changeling_powers","LFT") del(C) diff --git a/code/game/gamemodes/changeling/modularchangling.dm b/code/game/gamemodes/changeling/modularchangling.dm index 22f45329..50489777 100644 --- a/code/game/gamemodes/changeling/modularchangling.dm +++ b/code/game/gamemodes/changeling/modularchangling.dm @@ -26,6 +26,12 @@ var/list/datum/power/changeling/powerinstances = list() genomecost = 0 verbpath = /mob/proc/changeling_transform +/datum/power/changeling/change_species + name = "Change Species" + desc = "We take on the apperance of a species that we have absorbed." + genomecost = 0 + verbpath = /mob/proc/changeling_change_species + /datum/power/changeling/fakedeath name = "Regenerative Stasis" desc = "We become weakened to a death-like state, where we will rise again from death." @@ -53,7 +59,7 @@ var/list/datum/power/changeling/powerinstances = list() /datum/power/changeling/lesser_form name = "Lesser Form" desc = "We debase ourselves and become lesser. We become a monkey." - genomecost = 1 + genomecost = 4 verbpath = /mob/proc/changeling_lesser_form /datum/power/changeling/deaf_sting @@ -74,7 +80,7 @@ var/list/datum/power/changeling/powerinstances = list() name = "Silence Sting" desc = "We silently sting a human, completely silencing them for a short time." helptext = "Does not provide a warning to a victim that they have been stung, until they try to speak and cannot." - genomecost = 2 + genomecost = 3 allowduringlesserform = 1 verbpath = /mob/proc/changeling_silence_sting @@ -82,14 +88,14 @@ var/list/datum/power/changeling/powerinstances = list() name = "Mimic Voice" desc = "We shape our vocal glands to sound like a desired voice." helptext = "Will turn your voice into the name that you enter. We must constantly expend chemicals to maintain our form like this" - genomecost = 3 + genomecost = 1 verbpath = /mob/proc/changeling_mimicvoice /datum/power/changeling/extractdna name = "Extract DNA" desc = "We stealthily sting a target and extract the DNA from them." helptext = "Will give you the DNA of your target, allowing you to transform into them. Does not count towards absorb objectives." - genomecost = 4 + genomecost = 2 allowduringlesserform = 1 verbpath = /mob/proc/changeling_extract_dna_sting @@ -103,7 +109,7 @@ var/list/datum/power/changeling/powerinstances = list() /datum/power/changeling/paralysis_sting name = "Paralysis Sting" desc = "We silently sting a human, paralyzing them for a short time." - genomecost = 3 + genomecost = 8 verbpath = /mob/proc/changeling_paralysis_sting /datum/power/changeling/LSDSting @@ -136,7 +142,7 @@ var/list/datum/power/changeling/powerinstances = list() name = "Epinephrine sacs" desc = "We evolve additional sacs of adrenaline throughout our body." helptext = "Gives the ability to instantly recover from stuns. High chemical cost." - genomecost = 4 + genomecost = 3 verbpath = /mob/proc/changeling_unstun /datum/power/changeling/ChemicalSynth @@ -167,7 +173,7 @@ var/list/datum/power/changeling/powerinstances = list() name = "Digital Camoflauge" desc = "We evolve the ability to distort our form and proprtions, defeating common altgorthms used to detect lifeforms on cameras." helptext = "We cannot be tracked by camera while using this skill. However, humans looking at us will find us.. uncanny. We must constantly expend chemicals to maintain our form like this." - genomecost = 3 + genomecost = 1 allowduringlesserform = 1 verbpath = /mob/proc/changeling_digitalcamo @@ -175,7 +181,7 @@ var/list/datum/power/changeling/powerinstances = list() name = "Rapid Regeneration" desc = "We evolve the ability to rapidly regenerate, negating the need for stasis." helptext = "Heals a moderate amount of damage every tick." - genomecost = 8 + genomecost = 7 verbpath = /mob/proc/changeling_rapidregen diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index e07640dd..34bbcc19 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -22,7 +22,7 @@ var/explosion_in_progress = 0 //sit back and relax var/list/datum/mind/modePlayer = new var/list/restricted_jobs = list() // Jobs it doesn't make sense to be. I.E chaplain or AI cultist - var/list/protected_jobs = list() // Jobs that can't be tratiors because + var/list/protected_jobs = list() // Jobs that can't be traitors because var/required_players = 0 var/required_players_secret = 0 //Minimum number of players for that game mode to be chose in Secret var/required_enemies = 0 @@ -46,6 +46,7 @@ Stealthy and Inconspicuous Weapons; /obj/item/weapon/cartridge/syndicate:3:Detomatix PDA Cartridge; Whitespace:Seperator; Stealth and Camouflage Items; +/obj/item/weapon/storage/box/syndie_kit/chameleon:3:Chameleon Kit; /obj/item/weapon/storage/box/syndie_kit/masks:1:Disguised Breathe Mask; /obj/item/weapon/storage/box/syndie_kit/masks_gas:2:Disguised Gasmask; /obj/item/clothing/under/chameleon:3:Chameleon Jumpsuit; @@ -252,7 +253,7 @@ Implants; for (var/obj/machinery/computer/communications/comm in machines) if (!(comm.stat & (BROKEN | NOPOWER)) && comm.prints_intercept) var/obj/item/weapon/paper/intercept = new /obj/item/weapon/paper( comm.loc ) - intercept.name = "paper - 'Cent. Com. Status Summary'" + intercept.name = "Cent. Com. Status Summary" intercept.info = intercepttext comm.messagetitle.Add("Cent. Com. Status Summary") diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm index 4cbf95dc..c37120d0 100644 --- a/code/game/gamemodes/gameticker.dm +++ b/code/game/gamemodes/gameticker.dm @@ -364,7 +364,14 @@ var/global/datum/controller/gameticker/ticker robolist += "[robo.name][robo.stat?" (Deactivated) (Played by: [robo.key]), ":" (Played by: [robo.key]), "]" world << "[robolist]" + var/dronecount = 0 + for (var/mob/living/silicon/robot/robo in mob_list) + + if(istype(robo,/mob/living/silicon/robot/drone)) + dronecount++ + continue + if (!robo.connected_ai) if (robo.stat != 2) world << "[robo.name] (Played by: [robo.key]) survived as an AI-less borg! Its laws were:" @@ -374,6 +381,9 @@ var/global/datum/controller/gameticker/ticker if(robo) //How the hell do we lose robo between here and the world messages directly above this? robo.laws.show_laws(world) + if(dronecount) + world << "There [dronecount>1 ? "were" : "was"] [dronecount] industrious maintenance [dronecount>1 ? "drones" : "drone"] this round." + mode.declare_completion()//To declare normal completion. //calls auto_declare_completion_* for all modes diff --git a/code/game/gamemodes/malfunction/malfunction.dm b/code/game/gamemodes/malfunction/malfunction.dm index ad182d78..54b9ede6 100644 --- a/code/game/gamemodes/malfunction/malfunction.dm +++ b/code/game/gamemodes/malfunction/malfunction.dm @@ -30,7 +30,7 @@ /datum/game_mode/malfunction/pre_setup() for(var/mob/new_player/player in player_list) - if(player.mind && player.mind.assigned_role == "AI") + if(player.mind && player.mind.assigned_role == "AI" && (player.client.prefs.be_special & BE_MALF)) malf_ai+=player.mind if(malf_ai.len) return 1 diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index fe3df584..788ec569 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -358,7 +358,7 @@ datum/objective/escape if(!location) return 0 - if(istype(location, /turf/simulated/shuttle/floor4)) // Fails tratiors if they are in the shuttle brig -- Polymorph + if(istype(location, /turf/simulated/shuttle/floor4)) // Fails traitors if they are in the shuttle brig -- Polymorph if(istype(owner.current, /mob/living/carbon)) var/mob/living/carbon/C = owner.current if (!C.handcuffed) diff --git a/code/game/gamemodes/revolution/rp-revolution.dm b/code/game/gamemodes/revolution/rp-revolution.dm index 963579af..2fdf8af2 100644 --- a/code/game/gamemodes/revolution/rp-revolution.dm +++ b/code/game/gamemodes/revolution/rp-revolution.dm @@ -45,7 +45,7 @@ for (var/obj/machinery/computer/communications/comm in world) if (!(comm.stat & (BROKEN | NOPOWER)) && comm.prints_intercept) var/obj/item/weapon/paper/intercept = new /obj/item/weapon/paper( comm.loc ) - intercept.name = "paper - 'Cent. Com. Status Summary'" + intercept.name = "Cent. Com. Status Summary" intercept.info = intercepttext comm.messagetitle.Add("Cent. Com. Status Summary") @@ -116,7 +116,7 @@ for (var/obj/machinery/computer/communications/comm in world) if (!(comm.stat & (BROKEN | NOPOWER)) && comm.prints_intercept) var/obj/item/weapon/paper/intercept = new /obj/item/weapon/paper( comm.loc ) - intercept.name = "paper - 'Cent. Com. Status Summary'" + intercept.name = "Cent. Com. Status Summary" intercept.info = intercepttext comm.messagetitle.Add("Cent. Com. Status Summary") @@ -134,7 +134,7 @@ for (var/obj/machinery/computer/communications/comm in world) if (!(comm.stat & (BROKEN | NOPOWER)) && comm.prints_intercept) var/obj/item/weapon/paper/intercept = new /obj/item/weapon/paper( comm.loc ) - intercept.name = "paper - 'Cent. Com. Status Summary'" + intercept.name = "Cent. Com. Status Summary" intercept.info = intercepttext comm.messagetitle.Add("Cent. Com. Status Summary") diff --git a/code/game/gamemodes/revolution/rp_revolution.dm b/code/game/gamemodes/revolution/rp_revolution.dm index 2e10ec1b..fa64d90b 100644 --- a/code/game/gamemodes/revolution/rp_revolution.dm +++ b/code/game/gamemodes/revolution/rp_revolution.dm @@ -248,7 +248,7 @@ for (var/obj/machinery/computer/communications/comm in world) if (!(comm.stat & (BROKEN | NOPOWER)) && comm.prints_intercept) var/obj/item/weapon/paper/intercept = new /obj/item/weapon/paper( comm.loc ) - intercept.name = "paper - 'Cent. Com. Announcement'" + intercept.name = "Cent. Com. Announcement" intercept.info = message comm.messagetitle.Add("Cent. Com. Announcement") diff --git a/code/game/gamemodes/setupgame.dm b/code/game/gamemodes/setupgame.dm index b186d793..f79d1383 100644 --- a/code/game/gamemodes/setupgame.dm +++ b/code/game/gamemodes/setupgame.dm @@ -69,14 +69,14 @@ //testing("Assigning DNA blocks:") // Standard muts, imported from older code above. - //BLINDBLOCK = getAssignedBlock("BLIND", numsToAssign) - //DEAFBLOCK = getAssignedBlock("DEAF", numsToAssign) + BLINDBLOCK = getAssignedBlock("BLIND", numsToAssign) + DEAFBLOCK = getAssignedBlock("DEAF", numsToAssign) HULKBLOCK = getAssignedBlock("HULK", numsToAssign, DNA_HARD_BOUNDS) TELEBLOCK = getAssignedBlock("TELE", numsToAssign, DNA_HARD_BOUNDS) FIREBLOCK = getAssignedBlock("FIRE", numsToAssign, DNA_HARDER_BOUNDS) XRAYBLOCK = getAssignedBlock("XRAY", numsToAssign, DNA_HARDER_BOUNDS) CLUMSYBLOCK = getAssignedBlock("CLUMSY", numsToAssign) - //FAKEBLOCK = getAssignedBlock("FAKE", numsToAssign) + FAKEBLOCK = getAssignedBlock("FAKE", numsToAssign) // UNUSED! //COUGHBLOCK = getAssignedBlock("COUGH", numsToAssign) diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm index 0c1fe311..5f3d9e1e 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/game/gamemodes/wizard/soulstone.dm @@ -179,7 +179,6 @@ del(T) Z << "You are playing a Juggernaut. Though slow, you can withstand extreme punishment, and rip apart enemies and walls alike." Z << "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs." - Z.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/conjure/lesserforcewall(Z) Z.cancel_camera() del(C) @@ -195,7 +194,6 @@ del(T) Z << "You are playing a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls." Z << "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs." - Z.spell_list += new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift(Z) Z.cancel_camera() del(C) @@ -211,10 +209,6 @@ del(T) Z << "You are playing an Artificer. You are incredibly weak and fragile, but you are able to construct fortifications, repair allied constructs (by clicking on them), and even create new constructs" Z << "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs." - Z.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/conjure/construct/lesser(Z) - Z.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/conjure/wall(Z) - Z.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/conjure/floor(Z) - Z.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/conjure/soulstone(Z) Z.cancel_camera() del(C) else diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index 6858157b..f4d98d1d 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -5,7 +5,7 @@ icon_state ="book" throw_speed = 1 throw_range = 5 - w_class = 1.0 + w_class = 2.0 flags = FPRINT | TABLEPASS var/uses = 5 var/temp = null diff --git a/code/game/jobs/job/civilian.dm b/code/game/jobs/job/civilian.dm index ad3d1477..7889a19b 100644 --- a/code/game/jobs/job/civilian.dm +++ b/code/game/jobs/job/civilian.dm @@ -92,7 +92,9 @@ H.equip_to_slot_or_del(new /obj/item/clothing/suit/apron(H), slot_wear_suit) H.equip_to_slot_or_del(new /obj/item/device/analyzer/plant_analyzer(H), slot_s_store) H.equip_to_slot_or_del(new /obj/item/device/pda/botanist(H), slot_belt) - if(H.backbag == 1) + if(H.backbag == 3) + H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_hyd(H), slot_back) + else if(H.backbag == 1) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) else H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) diff --git a/code/game/jobs/job/medical.dm b/code/game/jobs/job/medical.dm index 64b2738d..e0940ef2 100644 --- a/code/game/jobs/job/medical.dm +++ b/code/game/jobs/job/medical.dm @@ -71,6 +71,8 @@ H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/virologist(H), slot_wear_suit) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/virologist(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/clothing/mask/surgical(H), slot_wear_mask) + if(H.backbag == 3) + H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_vir(H), slot_back) if("Medical Doctor") H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/medical(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat(H), slot_wear_suit) @@ -120,7 +122,9 @@ H.equip_to_slot_or_del(new /obj/item/clothing/shoes/white(H), slot_shoes) H.equip_to_slot_or_del(new /obj/item/device/pda/chemist(H), slot_belt) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/chemist(H), slot_wear_suit) - if(H.backbag == 1) + if(H.backbag == 3) + H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_chem(H), slot_back) + else if(H.backbag == 1) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) else H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) @@ -149,7 +153,9 @@ H.equip_to_slot_or_del(new /obj/item/device/pda/geneticist(H), slot_belt) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/genetics(H), slot_wear_suit) H.equip_to_slot_or_del(new /obj/item/device/flashlight/pen(H), slot_s_store) - if(H.backbag == 1) + if(H.backbag == 3) + H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_gen(H), slot_back) + else if(H.backbag == 1) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) else H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) diff --git a/code/game/jobs/job/science.dm b/code/game/jobs/job/science.dm index 8e8a210c..bb2c3f38 100644 --- a/code/game/jobs/job/science.dm +++ b/code/game/jobs/job/science.dm @@ -27,7 +27,9 @@ H.equip_to_slot_or_del(new /obj/item/device/pda/heads/rd(H), slot_belt) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat(H), slot_wear_suit) H.equip_to_slot_or_del(new /obj/item/weapon/clipboard(H), slot_l_hand) - if(H.backbag == 1) + if(H.backbag == 3) + H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_tox(H), slot_back) + else if(H.backbag == 1) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) else H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) @@ -53,9 +55,11 @@ H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_sci(H), slot_l_ear) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/scientist(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/white(H), slot_shoes) - H.equip_to_slot_or_del(new /obj/item/device/pda/toxins(H), slot_belt) + H.equip_to_slot_or_del(new /obj/item/device/pda/science(H), slot_belt) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/science(H), slot_wear_suit) - if(H.backbag == 1) + if(H.backbag == 3) + H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_tox(H), slot_back) + else if(H.backbag == 1) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) else H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) @@ -80,9 +84,11 @@ H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_sci(H), slot_l_ear) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/scientist(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/white(H), slot_shoes) - H.equip_to_slot_or_del(new /obj/item/device/pda/toxins(H), slot_belt) + H.equip_to_slot_or_del(new /obj/item/device/pda/science(H), slot_belt) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/science(H), slot_wear_suit) - if(H.backbag == 1) + if(H.backbag == 3) + H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_tox(H), slot_back) + else if(H.backbag == 1) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) else H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index b7d6ad8e..c400185a 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -282,6 +282,7 @@ dat += "" for(var/datum/organ/external/e in occupant.organs) + dat += "" var/AN = "" var/open = "" @@ -307,13 +308,15 @@ robot = "Prosthetic:" if(e.open) open = "Open:" + var/unknown_body = 0 for(var/I in e.implants) if(is_type_in_list(I,known_implants)) imp += "[I] implanted:" else unknown_body++ - if(unknown_body) + + if(unknown_body || e.hidden) imp += "Unknown body present:" if(!AN && !open && !infected & !imp) AN = "None:" diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index c4fc95d9..e5b07ca8 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -187,8 +187,8 @@ var/heat_capacity = gas.heat_capacity() var/energy_used = min( abs( heat_capacity*(gas.temperature - target_temperature) ), MAX_ENERGY_CHANGE) - //Use power. Assuming that each power unit represents 1000 watts.... - use_power(energy_used/1000, ENVIRON) + //Use power. Assuming that each power unit represents 1 watts.... + use_power(energy_used, ENVIRON) //We need to cool ourselves. if(environment.temperature > target_temperature) @@ -956,109 +956,29 @@ table tr:first-child th:first-child { border: none;} return output /obj/machinery/alarm/Topic(href, href_list) - - if(href_list["rcon"]) - rcon_setting = text2num(href_list["rcon"]) - - if ( (get_dist(src, usr) > 1 )) - if (!istype(usr, /mob/living/silicon)) - usr.machine = null - usr << browse(null, "window=air_alarm") - usr << browse(null, "window=AAlarmwires") - return + if(..() || !( Adjacent(usr) || istype(usr, /mob/living/silicon)) ) // dont forget calling super in machine Topics -walter0o + usr.machine = null + usr << browse(null, "window=air_alarm") + usr << browse(null, "window=AAlarmwires") + return add_fingerprint(usr) - usr.machine = src - - if(href_list["command"]) - var/device_id = href_list["id_tag"] - switch(href_list["command"]) - if( "power", - "adjust_external_pressure", - "set_external_pressure", - "checks", - "co2_scrub", - "tox_scrub", - "n2o_scrub", - "panic_siphon", - "scrubbing") - - send_signal(device_id, list(href_list["command"] = text2num(href_list["val"]) ) ) - - if("set_threshold") - var/env = href_list["env"] - var/threshold = text2num(href_list["var"]) - var/list/selected = TLV[env] - var/list/thresholds = list("lower bound", "low warning", "high warning", "upper bound") - var/newval = input("Enter [thresholds[threshold]] for [env]", "Alarm triggers", selected[threshold]) as null|num - if (isnull(newval) || ..() || (locked && issilicon(usr))) - return - if (newval<0) - selected[threshold] = -1.0 - else if (env=="temperature" && newval>5000) - selected[threshold] = 5000 - else if (env=="pressure" && newval>50*ONE_ATMOSPHERE) - selected[threshold] = 50*ONE_ATMOSPHERE - else if (env!="temperature" && env!="pressure" && newval>200) - selected[threshold] = 200 - else - newval = round(newval,0.01) - selected[threshold] = newval - if(threshold == 1) - if(selected[1] > selected[2]) - selected[2] = selected[1] - if(selected[1] > selected[3]) - selected[3] = selected[1] - if(selected[1] > selected[4]) - selected[4] = selected[1] - if(threshold == 2) - if(selected[1] > selected[2]) - selected[1] = selected[2] - if(selected[2] > selected[3]) - selected[3] = selected[2] - if(selected[2] > selected[4]) - selected[4] = selected[2] - if(threshold == 3) - if(selected[1] > selected[3]) - selected[1] = selected[3] - if(selected[2] > selected[3]) - selected[2] = selected[3] - if(selected[3] > selected[4]) - selected[4] = selected[3] - if(threshold == 4) - if(selected[1] > selected[4]) - selected[1] = selected[4] - if(selected[2] > selected[4]) - selected[2] = selected[4] - if(selected[3] > selected[4]) - selected[3] = selected[4] - - apply_mode() - - if(href_list["screen"]) - screen = text2num(href_list["screen"]) - - if(href_list["atmos_unlock"]) - switch(href_list["atmos_unlock"]) - if("0") - air_doors_close(1) - if("1") - air_doors_open(1) - - if(href_list["atmos_alarm"]) - if (alarm_area.atmosalert(2)) - apply_danger_level(2) - update_icon() - - if(href_list["atmos_reset"]) - if (alarm_area.atmosalert(0)) - apply_danger_level(0) - update_icon() - - if(href_list["mode"]) - mode = text2num(href_list["mode"]) - apply_mode() - + usr.set_machine(src) + + // hrefs that can always be called -walter0o + if(href_list["rcon"]) + var/attempted_rcon_setting = text2num(href_list["rcon"]) + + switch(attempted_rcon_setting) + if(RCON_NO) + rcon_setting = RCON_NO + if(RCON_AUTO) + rcon_setting = RCON_AUTO + if(RCON_YES) + rcon_setting = RCON_YES + else + return + if(href_list["temperature"]) var/list/selected = TLV["temperature"] var/max_temperature = min(selected[3] - T0C, MAX_TEMPERATURE) @@ -1069,31 +989,126 @@ table tr:first-child th:first-child { border: none;} else target_temperature = input_temperature + T0C - if (href_list["AAlarmwires"]) - var/t1 = text2num(href_list["AAlarmwires"]) - if (!( istype(usr.equipped(), /obj/item/weapon/wirecutters) )) - usr << "You need wirecutters!" - return - if (isWireColorCut(t1)) - mend(t1) - else - cut(t1) - if (AAlarmwires == 0) - usr << "You cut last of wires inside [src]" - update_icon() - buildstage = 1 - return - - else if (href_list["pulse"]) - var/t1 = text2num(href_list["pulse"]) - if (!istype(usr.equipped(), /obj/item/device/multitool)) - usr << "You need a multitool!" - return - if (isWireColorCut(t1)) - usr << "You can't pulse a cut wire." - return - else - pulse(t1) + // hrefs that need the AA unlocked -walter0o + if(!locked || istype(usr, /mob/living/silicon)) + + if(href_list["command"]) + var/device_id = href_list["id_tag"] + switch(href_list["command"]) + if( "power", + "adjust_external_pressure", + "set_external_pressure", + "checks", + "co2_scrub", + "tox_scrub", + "n2o_scrub", + "panic_siphon", + "scrubbing") + + send_signal(device_id, list(href_list["command"] = text2num(href_list["val"]) ) ) + + if("set_threshold") + var/env = href_list["env"] + var/threshold = text2num(href_list["var"]) + var/list/selected = TLV[env] + var/list/thresholds = list("lower bound", "low warning", "high warning", "upper bound") + var/newval = input("Enter [thresholds[threshold]] for [env]", "Alarm triggers", selected[threshold]) as null|num + if (isnull(newval) || ..() || (locked && issilicon(usr))) + return + if (newval<0) + selected[threshold] = -1.0 + else if (env=="temperature" && newval>5000) + selected[threshold] = 5000 + else if (env=="pressure" && newval>50*ONE_ATMOSPHERE) + selected[threshold] = 50*ONE_ATMOSPHERE + else if (env!="temperature" && env!="pressure" && newval>200) + selected[threshold] = 200 + else + newval = round(newval,0.01) + selected[threshold] = newval + if(threshold == 1) + if(selected[1] > selected[2]) + selected[2] = selected[1] + if(selected[1] > selected[3]) + selected[3] = selected[1] + if(selected[1] > selected[4]) + selected[4] = selected[1] + if(threshold == 2) + if(selected[1] > selected[2]) + selected[1] = selected[2] + if(selected[2] > selected[3]) + selected[3] = selected[2] + if(selected[2] > selected[4]) + selected[4] = selected[2] + if(threshold == 3) + if(selected[1] > selected[3]) + selected[1] = selected[3] + if(selected[2] > selected[3]) + selected[2] = selected[3] + if(selected[3] > selected[4]) + selected[4] = selected[3] + if(threshold == 4) + if(selected[1] > selected[4]) + selected[1] = selected[4] + if(selected[2] > selected[4]) + selected[2] = selected[4] + if(selected[3] > selected[4]) + selected[3] = selected[4] + + apply_mode() + + if(href_list["screen"]) + screen = text2num(href_list["screen"]) + + if(href_list["atmos_unlock"]) + switch(href_list["atmos_unlock"]) + if("0") + air_doors_close(1) + if("1") + air_doors_open(1) + + if(href_list["atmos_alarm"]) + if (alarm_area.atmosalert(2)) + apply_danger_level(2) + update_icon() + + if(href_list["atmos_reset"]) + if (alarm_area.atmosalert(0)) + apply_danger_level(0) + update_icon() + + if(href_list["mode"]) + mode = text2num(href_list["mode"]) + apply_mode() + + // hrefs that need the AA wires exposed, note that borgs should be in range here too -walter0o + if(wiresexposed && Adjacent(usr)) + + if (href_list["AAlarmwires"]) + var/t1 = text2num(href_list["AAlarmwires"]) + if (!( istype(usr.equipped(), /obj/item/weapon/wirecutters) )) + usr << "You need wirecutters!" + return + if (isWireColorCut(t1)) + mend(t1) + else + cut(t1) + if (AAlarmwires == 0) + usr << "You cut last of wires inside [src]" + update_icon() + buildstage = 1 + return + + else if (href_list["pulse"]) + var/t1 = text2num(href_list["pulse"]) + if (!istype(usr.equipped(), /obj/item/device/multitool)) + usr << "You need a multitool!" + return + if (isWireColorCut(t1)) + usr << "You can't pulse a cut wire." + return + else + pulse(t1) updateUsrDialog() diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 4e3db2ad..6af4d627 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -275,10 +275,15 @@ update_flag /obj/machinery/portable_atmospherics/canister/Topic(href, href_list) - //Do not use "if(..()) return" here, canisters will stop working in unpowered areas like space or on the derelict. + //Do not use "if(..()) return" here, canisters will stop working in unpowered areas like space or on the derelict. // yeah but without SOME sort of Topic check any dick can mess with them via exploits as he pleases -walter0o if (!istype(src.loc, /turf)) return 0 - + + if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr)) // exploit protection -walter0o + usr << browse(null, "window=canister") + onclose(usr, "canister") + return + if(href_list["toggle"]) if (valve_open) if (holding) diff --git a/code/game/machinery/bees_items.dm b/code/game/machinery/bees_items.dm index 01ed5bfa..e02a0a1a 100644 --- a/code/game/machinery/bees_items.dm +++ b/code/game/machinery/bees_items.dm @@ -102,21 +102,22 @@ h1 {font-size: 18px; margin: 15px 0px 5px;} h2 {font-size: 15px; margin: 15px 0px 5px;} li {margin: 2px 0px 2px 15px;} - ul {list-style: none; margin: 5px; padding: 0px;} + ul {margin: 5px; padding: 0px;} ol {margin: 5px; padding: 0px 15px;} + body {font-size: 13px; font-family: Verdana;} -

Raising Bees

+

Raising Bees

Bees are loving but fickle creatures. Don't mess with their hive and stay away from any clusters of them, and you'll avoid their ire. Sometimes, you'll need to dig around in there for those delicious sweeties though - in that case make sure you wear sealed protection gear and carry an extinguisher or smoker with you - any bees chasing you, once calmed down, can thusly be netted and returned safely to the hive. - Beezeez is a cure-all panacea for them, but use it too much and the hive may grow to apocalyptic proportions. Other than that, bees are excellent pets + BeezEez is a cure-all panacea for them, but use it too much and the hive may grow to apocalyptic proportions. Other than that, bees are excellent pets for all the family and are excellent caretakers of one's garden: having a hive or two around will aid in the longevity and growth rate of plants, and aid them in fighting off poisons and disease. - - "} + + "} diff --git a/code/game/machinery/bots/ed209bot.dm b/code/game/machinery/bots/ed209bot.dm index b944636b..6e084931 100644 --- a/code/game/machinery/bots/ed209bot.dm +++ b/code/game/machinery/bots/ed209bot.dm @@ -231,8 +231,6 @@ Auto Patrol: []"}, continue if (istype(C, /mob/living/carbon/human)) threatlevel = src.assess_perp(C) - else if ((istype(C, /mob/living/carbon/monkey)) && (C.client) && (ticker.mode.name == "monkey")) - threatlevel = 4 //src.speak(C.real_name + text(": threat: []", threatlevel)) if (threatlevel < 4 ) continue @@ -271,7 +269,7 @@ Auto Patrol: []"}, walk_to(src,0) if (target) // make sure target exists - if (get_dist(src, src.target) <= 1) // if right next to perp + if (Adjacent(target)) // if right next to perp playsound(src.loc, 'sound/weapons/Egloves.ogg', 50, 1, -1) src.icon_state = "[lasercolor]ed209-c" spawn(2) @@ -637,8 +635,6 @@ Auto Patrol: []"}, if (istype(C, /mob/living/carbon/human)) src.threatlevel = src.assess_perp(C) - else if ((istype(C, /mob/living/carbon/monkey)) && (C.client) && (ticker.mode.name == "monkey")) - src.threatlevel = 4 if (!src.threatlevel) continue @@ -735,7 +731,7 @@ Auto Patrol: []"}, /obj/machinery/bot/ed209/Bump(M as mob|obj) //Leave no door unopened! if ((istype(M, /obj/machinery/door)) && (!isnull(src.botcard))) var/obj/machinery/door/D = M - if (!istype(D, /obj/machinery/door/firedoor) && D.check_access(src.botcard)) + if (!istype(D, /obj/machinery/door/firedoor) && D.check_access(src.botcard) && !istype(D,/obj/machinery/door/poddoor)) D.open() src.frustration = 0 else if ((istype(M, /mob/living/)) && (!src.anchored)) diff --git a/code/game/machinery/bots/farmbot.dm b/code/game/machinery/bots/farmbot.dm index fe110939..b6f81984 100644 --- a/code/game/machinery/bots/farmbot.dm +++ b/code/game/machinery/bots/farmbot.dm @@ -540,10 +540,9 @@ var/obj/item/weapon/farmbot_arm_assembly/A = new /obj/item/weapon/farmbot_arm_assembly A.loc = src.loc - A.layer = 20 user << "You add the robot arm to the [src]" src.loc = A //Place the water tank into the assembly, it will be needed for the finished bot - + user.u_equip(S) del(S) /obj/item/weapon/farmbot_arm_assembly/attackby(obj/item/weapon/W as obj, mob/user as mob) @@ -552,18 +551,21 @@ src.build_step++ user << "You add the plant analyzer to [src]!" src.name = "farmbot assembly" + user.u_equip(W) del(W) else if(( istype(W, /obj/item/weapon/reagent_containers/glass/bucket)) && (src.build_step == 1)) src.build_step++ user << "You add a bucket to [src]!" src.name = "farmbot assembly with bucket" + user.u_equip(W) del(W) else if(( istype(W, /obj/item/weapon/minihoe)) && (src.build_step == 2)) src.build_step++ user << "You add a minihoe to [src]!" src.name = "farmbot assembly with bucket and minihoe" + user.u_equip(W) del(W) else if((isprox(W)) && (src.build_step == 3)) @@ -575,6 +577,7 @@ S.tank = wTank S.loc = get_turf(src) S.name = src.created_name + user.u_equip(W) del(W) del(src) @@ -587,3 +590,6 @@ return src.created_name = t + +/obj/item/weapon/farmbot_arm_assembly/attack_hand(mob/user as mob) + return //it's a converted watertank, no you cannot pick it up and put it in your backpack \ No newline at end of file diff --git a/code/game/machinery/bots/medbot.dm b/code/game/machinery/bots/medbot.dm index 6eabb2d0..f0c649ac 100644 --- a/code/game/machinery/bots/medbot.dm +++ b/code/game/machinery/bots/medbot.dm @@ -284,7 +284,7 @@ continue - if(src.patient && (get_dist(src,src.patient) <= 1)) + if(src.patient && Adjacent(patient)) if(!src.currently_healing) src.currently_healing = 1 src.frustration = 0 @@ -480,7 +480,7 @@ /obj/machinery/bot/medbot/Bump(M as mob|obj) //Leave no door unopened! if ((istype(M, /obj/machinery/door)) && (!isnull(src.botcard))) var/obj/machinery/door/D = M - if (!istype(D, /obj/machinery/door/firedoor) && D.check_access(src.botcard)) + if (!istype(D, /obj/machinery/door/firedoor) && D.check_access(src.botcard) && !istype(D,/obj/machinery/door/poddoor)) D.open() src.frustration = 0 else if ((istype(M, /mob/living/)) && (!src.anchored)) diff --git a/code/game/machinery/bots/secbot.dm b/code/game/machinery/bots/secbot.dm index 7cf1ddc6..3aa31527 100644 --- a/code/game/machinery/bots/secbot.dm +++ b/code/game/machinery/bots/secbot.dm @@ -219,7 +219,7 @@ Auto Patrol: []"}, walk_to(src,0) if(target) // make sure target exists - if(get_dist(src, src.target) <= 1 && isturf(src.target.loc)) // if right next to perp + if(Adjacent(target)) // if right next to perp if(istype(src.target,/mob/living/carbon)) playsound(src.loc, 'sound/weapons/Egloves.ogg', 50, 1, -1) src.icon_state = "secbot-c" @@ -600,8 +600,6 @@ Auto Patrol: []"}, if(istype(C, /mob/living/carbon/human)) src.threatlevel = src.assess_perp(C) - else if((src.idcheck) && (istype(C, /mob/living/carbon/monkey))) - src.threatlevel = 4 else if(istype(M, /mob/living/simple_animal/hostile)) if(M.stat == DEAD) @@ -682,7 +680,7 @@ Auto Patrol: []"}, /obj/machinery/bot/secbot/Bump(M as mob|obj) //Leave no door unopened! if((istype(M, /obj/machinery/door)) && (!isnull(src.botcard))) var/obj/machinery/door/D = M - if(!istype(D, /obj/machinery/door/firedoor) && D.check_access(src.botcard)) + if(!istype(D, /obj/machinery/door/firedoor) && D.check_access(src.botcard) && !istype(D,/obj/machinery/door/poddoor)) D.open() src.frustration = 0 else if((istype(M, /mob/living/)) && (!src.anchored)) diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 148514f7..966741aa 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -215,7 +215,7 @@ /obj/machinery/camera/proc/cancelCameraAlarm() alarm_on = 0 for(var/mob/living/silicon/S in mob_list) - S.cancelAlarm("Camera", get_area(src), list(src), src) + S.cancelAlarm("Camera", get_area(src), src) /obj/machinery/camera/proc/can_use() if(!status) diff --git a/code/game/machinery/camera/motion.dm b/code/game/machinery/camera/motion.dm index 6059878e..d672af55 100644 --- a/code/game/machinery/camera/motion.dm +++ b/code/game/machinery/camera/motion.dm @@ -42,14 +42,14 @@ /obj/machinery/camera/proc/cancelAlarm() if (detectTime == -1) for (var/mob/living/silicon/aiPlayer in player_list) - if (status) aiPlayer.cancelAlarm("Motion", src.loc.loc) + if (status) aiPlayer.cancelAlarm("Motion", get_area(src), src) detectTime = 0 return 1 /obj/machinery/camera/proc/triggerAlarm() if (!detectTime) return 0 for (var/mob/living/silicon/aiPlayer in player_list) - if (status) aiPlayer.triggerAlarm("Motion", src.loc.loc, src) + if (status) aiPlayer.triggerAlarm("Motion", get_area(src), list(src), src) detectTime = -1 return 1 diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm index bd001641..42f72bc6 100644 --- a/code/game/machinery/cell_charger.dm +++ b/code/game/machinery/cell_charger.dm @@ -10,6 +10,7 @@ power_channel = EQUIP var/obj/item/weapon/cell/charging = null var/chargelevel = -1 + var/efficiency = 0.875 //<1.0 means some power is lost in the charging process, >1.0 means free energy. proc updateicon() icon_state = "ccharger[charging ? 1 : 0]" @@ -91,8 +92,10 @@ //world << "ccpt [charging] [stat]" if(!charging || (stat & (BROKEN|NOPOWER)) || !anchored) return - - use_power(200) //this used to use CELLRATE, but CELLRATE is fucking awful. feel free to fix this properly! - charging.give(175) //inefficiency. - + + var/power_used = 100000 //for 200 units of charge. Yes, thats right, 100 kW. Is something wrong with CELLRATE? + + power_used = charging.give(power_used*CELLRATE*efficiency) + use_power(power_used) + updateicon() diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 7c3cfdbf..523d73ae 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -162,7 +162,7 @@ spawn(30) src.eject_wait = 0 - var/mob/living/carbon/human/H = new /mob/living/carbon/human(src) + var/mob/living/carbon/human/H = new /mob/living/carbon/human(src, R.dna.species) occupant = H if(!R.dna.real_name) //to prevent null names @@ -212,10 +212,8 @@ if(R.dna.species == "Human") //no more xenos losing ears/tentacles H.h_style = pick("Bedhead", "Bedhead 2", "Bedhead 3") - H.set_species(R.dna.species) - - //for(var/datum/language/L in languages) - // H.add_language(L.name) + for(var/datum/language/L in R.languages) + H.add_language(L.name) H.suiciding = 0 src.attempting = 0 return 1 @@ -435,7 +433,7 @@ */ /obj/item/weapon/paper/Cloning - name = "paper - 'H-87 Cloning Apparatus Manual" + name = "H-87 Cloning Apparatus Manual" info = {"

Getting Started

Congratulations, your station has purchased the H-87 industrial cloning device!
Using the H-87 is almost as simple as brain surgery! Simply insert the target humanoid into the scanning chamber and select the scan option to create a new profile!
diff --git a/code/game/machinery/computer/HolodeckControl.dm b/code/game/machinery/computer/HolodeckControl.dm index cbc89ac8..f4a80c0a 100644 --- a/code/game/machinery/computer/HolodeckControl.dm +++ b/code/game/machinery/computer/HolodeckControl.dm @@ -315,7 +315,7 @@ if(world.time < (last_change + 15))//To prevent super-spam clicking, reduced process size and annoyance -Sieve return for(var/mob/M in range(3,src)) - M.show_message("\b ERROR. Recalibrating projetion apparatus.") + M.show_message("\b ERROR. Recalibrating projection apparatus.") last_change = world.time return @@ -447,6 +447,8 @@ if(isrobot(user)) return + + ..() /obj/structure/table/holotable/wood name = "table" diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm index c320e674..d6cb0ede 100644 --- a/code/game/machinery/computer/aifixer.dm +++ b/code/game/machinery/computer/aifixer.dm @@ -2,6 +2,7 @@ name = "AI System Integrity Restorer" icon = 'icons/obj/computer.dmi' icon_state = "ai-fixer" + circuit = /obj/item/weapon/circuitboard/aifixer req_access = list(access_captain, access_robotics, access_heads) var/mob/living/silicon/ai/occupant = null var/active = 0 @@ -11,43 +12,13 @@ /obj/machinery/computer/aifixer/attackby(I as obj, user as mob) -/* - if(istype(I, /obj/item/weapon/screwdriver)) - playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) - if(do_after(user, 20)) - if (src.stat & BROKEN) - user << "\blue The broken glass falls out." - var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc ) - new /obj/item/weapon/shard( src.loc ) - var/obj/item/weapon/circuitboard/robotics/M = new /obj/item/weapon/circuitboard/robotics( A ) - for (var/obj/C in src) - C.loc = src.loc - M.id = src.id - A.circuit = M - A.state = 3 - A.icon_state = "3" - A.anchored = 1 - del(src) - else - user << "\blue You disconnect the monitor." - var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc ) - var/obj/item/weapon/circuitboard/robotics/M = new /obj/item/weapon/circuitboard/robotics( A ) - for (var/obj/C in src) - C.loc = src.loc - M.id = src.id - A.circuit = M - A.state = 4 - A.icon_state = "4" - A.anchored = 1 - del(src) -*/ if(istype(I, /obj/item/device/aicard)) if(stat & (NOPOWER|BROKEN)) user << "This terminal isn't functioning right now, get it working!" return I:transfer_ai("AIFIXER","AICARD",src,user) - - //src.attack_hand(user) + + ..() return /obj/machinery/computer/aifixer/attack_ai(var/mob/user as mob) diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index 512c37ca..4cc773c5 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -238,27 +238,10 @@ src.updateUsrDialog() - else if(istype(I, /obj/item/weapon/screwdriver)) - playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) - if(do_after(user, 20)) - var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc ) - var/obj/item/weapon/circuitboard/arcade/M = new /obj/item/weapon/circuitboard/arcade( A ) - for (var/obj/C in src) - C.loc = src.loc - A.circuit = M - A.anchored = 1 + else + ..() - if (src.stat & BROKEN) - user << "\blue The broken glass falls out." - new /obj/item/weapon/shard( src.loc ) - A.state = 3 - A.icon_state = "3" - else - user << "\blue You disconnect the monitor." - A.state = 4 - A.icon_state = "4" - del(src) /obj/machinery/computer/arcade/emp_act(severity) if(stat & (NOPOWER|BROKEN)) ..(severity) diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm index 1233d175..cb454ceb 100644 --- a/code/game/machinery/computer/buildandrepair.dm +++ b/code/game/machinery/computer/buildandrepair.dm @@ -109,6 +109,10 @@ name = "Circuit board (Robotics Control)" build_path = "/obj/machinery/computer/robotics" origin_tech = "programming=3" +/obj/item/weapon/circuitboard/drone_control + name = "Circuit board (Drone Control)" + build_path = "/obj/machinery/computer/drone_control" + origin_tech = "programming=3" /obj/item/weapon/circuitboard/cloning name = "Circuit board (Cloning)" build_path = "/obj/machinery/computer/cloning" @@ -281,14 +285,15 @@ /obj/item/weapon/circuitboard/rdconsole/attackby(obj/item/I as obj, mob/user as mob) if(istype(I,/obj/item/weapon/screwdriver)) + user.visible_message("\blue \the [user] adjusts the jumper on the [src]'s access protocol pins.", "\blue You adjust the jumper on the access protocol pins.") if(src.build_path == "/obj/machinery/computer/rdconsole/core") src.name = "Circuit Board (RD Console - Robotics)" src.build_path = "/obj/machinery/computer/rdconsole/robotics" - user << "\blue Access protocols succesfully updated." + user << "\blue Access protocols set to robotics." else src.name = "Circuit Board (RD Console)" src.build_path = "/obj/machinery/computer/rdconsole/core" - user << "\blue Defaulting access protocols." + user << "\blue Access protocols set to default." return /obj/structure/computerframe/attackby(obj/item/P as obj, mob/user as mob) diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm index 1d724b83..fcf525cc 100644 --- a/code/game/machinery/computer/card.dm +++ b/code/game/machinery/computer/card.dm @@ -108,10 +108,57 @@ header += "
" var/jobs_all = "" - var/list/alljobs = (istype(src,/obj/machinery/computer/card/centcom)? get_all_centcom_jobs() : joblist) + "Custom" - for(var/job in alljobs) - jobs_all += "[replacetext(job, " ", " ")] " //make sure there isn't a line break in the middle of a job + var/counter = 0 + jobs_all += "" + jobs_all += ""//Captain in special because he is head of heads ~Intercross21 + jobs_all += "" + jobs_all += "" + + counter = 0 + jobs_all += ""//Orange + for(var/job in engineering_positions) + counter++ + if(counter >= 6) + jobs_all += "" + counter = 0 + jobs_all += "" + + counter = 0 + jobs_all += ""//Green + for(var/job in medical_positions) + counter++ + if(counter >= 6) + jobs_all += "" + counter = 0 + jobs_all += "" + + counter = 0 + jobs_all += ""//Purple + for(var/job in science_positions) + counter++ + if(counter >= 6) + jobs_all += "" + counter = 0 + jobs_all += "" + + counter = 0 + jobs_all += ""//Grey + for(var/job in civilian_positions) + counter++ + if(counter >= 6) + jobs_all += "" + counter = 0 + jobs_all += "" + + if(istype(src,/obj/machinery/computer/card/centcom)) + counter = 0 + jobs_all += ""//Brown + for(var/job in get_all_centcom_jobs()) + if(counter >= 6) + jobs_all += "" + counter = 0 + jobs_all += "" var/body if (authenticated && modify) @@ -138,7 +185,7 @@ } function hideAll(){ var allJobsSlot = document.getElementById('alljobsslot'); - allJobsSlot.innerHTML = "show"; + allJobsSlot.innerHTML = "[(modify.assignment) ? modify.assignment : "Unassgied"]"; } "} carddesc += "" @@ -255,7 +302,7 @@ if (authenticated) var/t1 = href_list["assign_target"] if(t1 == "Custom") - var/temp_t = copytext(sanitize(input("Enter a custom job assignment.","Assignment")),1,MAX_MESSAGE_LEN) + var/temp_t = copytext(sanitize(input("Enter a custom job assignment.","Assignment")),1,45) //let custom jobs function as an impromptu alt title, mainly for sechuds if(temp_t && modify) modify.assignment = temp_t @@ -312,7 +359,7 @@ t1 += data_core.get_manifest(0) // make it monochrome P.info = t1 - P.name = "paper- 'Crew Manifest'" + P.name = text("Crew Manifest ([])", worldtime2text()) printing = null if (modify) modify.name = text("[modify.registered_name]'s ID Card ([modify.assignment])") diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index 293046b0..9ce8ccb4 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -361,6 +361,7 @@ R.id= copytext(md5(subject.real_name), 2, 6) R.name=R.dna.real_name R.types=DNA2_BUF_UI|DNA2_BUF_UE|DNA2_BUF_SE + R.languages=subject.languages //Add an implant if needed var/obj/item/weapon/implant/health/imp = locate(/obj/item/weapon/implant/health, subject) diff --git a/code/game/machinery/computer/computer.dm b/code/game/machinery/computer/computer.dm index c47eb1f9..b289bcaa 100644 --- a/code/game/machinery/computer/computer.dm +++ b/code/game/machinery/computer/computer.dm @@ -95,6 +95,11 @@ stat |= BROKEN update_icon() +/obj/machinery/computer/proc/decode(text) + // Adds line breaks + text = replacetext(text, "\n", "
") + return text + /obj/machinery/computer/attackby(I as obj, user as mob) if(istype(I, /obj/item/weapon/screwdriver) && circuit) diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm index 133b622f..cf9f292f 100644 --- a/code/game/machinery/computer/medical.dm +++ b/code/game/machinery/computer/medical.dm @@ -16,6 +16,14 @@ var/temp = null var/printing = null +/obj/machinery/computer/med_data/attackby(obj/item/O as obj, user as mob) + if(istype(O, /obj/item/weapon/card/id) && !scan) + usr.drop_item() + O.loc = src + scan = O + user << "You insert [O]." + ..() + /obj/machinery/computer/med_data/attack_ai(user as mob) return src.attack_hand(user) @@ -70,7 +78,7 @@ else dat += "General Record Lost!
" if ((istype(src.active2, /datum/data/record) && data_core.medical.Find(src.active2))) - dat += text("
\n
Medical Data

\nBlood Type: []
\nDNA: []
\n
\nMinor Disabilities: []
\nDetails: []
\n
\nMajor Disabilities: []
\nDetails: []
\n
\nAllergies: []
\nDetails: []
\n
\nCurrent Diseases: [] (per disease info placed in log/comment section)
\nDetails: []
\n
\nImportant Notes:
\n\t[]
\n
\n
Comments/Log

", src, src.active2.fields["b_type"], src, src.active2.fields["b_dna"], src, src.active2.fields["mi_dis"], src, src.active2.fields["mi_dis_d"], src, src.active2.fields["ma_dis"], src, src.active2.fields["ma_dis_d"], src, src.active2.fields["alg"], src, src.active2.fields["alg_d"], src, src.active2.fields["cdi"], src, src.active2.fields["cdi_d"], src, src.active2.fields["notes"]) + dat += text("
\n
Medical Data

\nBlood Type: []
\nDNA: []
\n
\nMinor Disabilities: []
\nDetails: []
\n
\nMajor Disabilities: []
\nDetails: []
\n
\nAllergies: []
\nDetails: []
\n
\nCurrent Diseases: [] (per disease info placed in log/comment section)
\nDetails: []
\n
\nImportant Notes:
\n\t[]
\n
\n
Comments/Log

", src, src.active2.fields["b_type"], src, src.active2.fields["b_dna"], src, src.active2.fields["mi_dis"], src, src.active2.fields["mi_dis_d"], src, src.active2.fields["ma_dis"], src, src.active2.fields["ma_dis_d"], src, src.active2.fields["alg"], src, src.active2.fields["alg_d"], src, src.active2.fields["cdi"], src, src.active2.fields["cdi_d"], src, decode(src.active2.fields["notes"])) var/counter = 1 while(src.active2.fields[text("com_[]", counter)]) dat += text("[]
Delete Entry

", src.active2.fields[text("com_[]", counter)], src, counter) @@ -294,7 +302,7 @@ src.active2.fields["cdi_d"] = t1 if("notes") if (istype(src.active2, /datum/data/record)) - var/t1 = copytext(sanitize(input("Please summarize notes:", "Med. records", src.active2.fields["notes"], null) as message),1,MAX_MESSAGE_LEN) + var/t1 = copytext(html_encode(input("Please summarize notes:", "Med. records", html_decode(src.active2.fields["notes"]), null) as message),1,MAX_MESSAGE_LEN) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return src.active2.fields["notes"] = t1 @@ -463,23 +471,30 @@ if (href_list["print_p"]) if (!( src.printing )) src.printing = 1 + var/datum/data/record/record1 = null + var/datum/data/record/record2 = null + if ((istype(src.active1, /datum/data/record) && data_core.general.Find(src.active1))) + record1 = active1 + if ((istype(src.active2, /datum/data/record) && data_core.medical.Find(src.active2))) + record2 = active2 sleep(50) var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( src.loc ) P.info = "
Medical Record

" - if ((istype(src.active1, /datum/data/record) && data_core.general.Find(src.active1))) - P.info += text("Name: [] ID: []
\nSex: []
\nAge: []
\nFingerprint: []
\nPhysical Status: []
\nMental Status: []
", src.active1.fields["name"], src.active1.fields["id"], src.active1.fields["sex"], src.active1.fields["age"], src.active1.fields["fingerprint"], src.active1.fields["p_stat"], src.active1.fields["m_stat"]) + if (record1) + P.info += text("Name: [] ID: []
\nSex: []
\nAge: []
\nFingerprint: []
\nPhysical Status: []
\nMental Status: []
", record1.fields["name"], record1.fields["id"], record1.fields["sex"], record1.fields["age"], record1.fields["fingerprint"], record1.fields["p_stat"], record1.fields["m_stat"]) + P.name = text("Medical Record ([])", record1.fields["name"]) else P.info += "General Record Lost!
" - if ((istype(src.active2, /datum/data/record) && data_core.medical.Find(src.active2))) - P.info += text("
\n
Medical Data

\nBlood Type: []
\nDNA: []
\n
\nMinor Disabilities: []
\nDetails: []
\n
\nMajor Disabilities: []
\nDetails: []
\n
\nAllergies: []
\nDetails: []
\n
\nCurrent Diseases: [] (per disease info placed in log/comment section)
\nDetails: []
\n
\nImportant Notes:
\n\t[]
\n
\n
Comments/Log

", src.active2.fields["b_type"], src.active2.fields["b_dna"], src.active2.fields["mi_dis"], src.active2.fields["mi_dis_d"], src.active2.fields["ma_dis"], src.active2.fields["ma_dis_d"], src.active2.fields["alg"], src.active2.fields["alg_d"], src.active2.fields["cdi"], src.active2.fields["cdi_d"], src.active2.fields["notes"]) + P.name = "Medical Record" + if (record2) + P.info += text("
\n
Medical Data

\nBlood Type: []
\nDNA: []
\n
\nMinor Disabilities: []
\nDetails: []
\n
\nMajor Disabilities: []
\nDetails: []
\n
\nAllergies: []
\nDetails: []
\n
\nCurrent Diseases: [] (per disease info placed in log/comment section)
\nDetails: []
\n
\nImportant Notes:
\n\t[]
\n
\n
Comments/Log

", record2.fields["b_type"], record2.fields["b_dna"], record2.fields["mi_dis"], record2.fields["mi_dis_d"], record2.fields["ma_dis"], record2.fields["ma_dis_d"], record2.fields["alg"], record2.fields["alg_d"], record2.fields["cdi"], record2.fields["cdi_d"], decode(record2.fields["notes"])) var/counter = 1 - while(src.active2.fields[text("com_[]", counter)]) - P.info += text("[]
", src.active2.fields[text("com_[]", counter)]) + while(record2.fields[text("com_[]", counter)]) + P.info += text("[]
", record2.fields[text("com_[]", counter)]) counter++ else P.info += "Medical Record Lost!
" P.info += "" - P.name = "paper- 'Medical Record'" src.printing = null src.add_fingerprint(usr) diff --git a/code/game/machinery/computer/pod.dm b/code/game/machinery/computer/pod.dm index 0a5696ee..eeadf4de 100644 --- a/code/game/machinery/computer/pod.dm +++ b/code/game/machinery/computer/pod.dm @@ -4,6 +4,7 @@ name = "Pod Launch Control" desc = "A controll for launching pods. Some people prefer firing Mechas." icon_state = "computer_generic" + circuit = /obj/item/weapon/circuitboard/pod var/id = 1.0 var/obj/machinery/mass_driver/connected = null var/timing = 0.0 @@ -33,7 +34,7 @@ for(var/obj/machinery/door/poddoor/M in world) if(M.id == id) M.open() - return + sleep(20) for(var/obj/machinery/mass_driver/M in world) @@ -48,7 +49,7 @@ return return - +/* /obj/machinery/computer/pod/attackby(I as obj, user as mob) if(istype(I, /obj/item/weapon/screwdriver)) playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1) @@ -103,6 +104,7 @@ else attack_hand(user) return +*/ /obj/machinery/computer/pod/attack_ai(var/mob/user as mob) @@ -171,6 +173,12 @@ connected.power = t if(href_list["alarm"]) alarm() + if(href_list["drive"]) + for(var/obj/machinery/mass_driver/M in machines) + if(M.id == id) + M.power = connected.power + M.drive() + if(href_list["time"]) timing = text2num(href_list["time"]) if(href_list["tp"]) diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm index f75e4f22..cdce6fdf 100644 --- a/code/game/machinery/computer/robot.dm +++ b/code/game/machinery/computer/robot.dm @@ -42,6 +42,8 @@ dat += "2. Emergency Full Destruct
" if(screen == 1) for(var/mob/living/silicon/robot/R in mob_list) + if(istype(R, /mob/living/silicon/robot/drone)) + continue //There's a specific console for drones. if(istype(user, /mob/living/silicon/ai)) if (R.connected_ai != user) continue @@ -220,8 +222,7 @@ while(src.timeleft) for(var/mob/living/silicon/robot/R in mob_list) - if(!R.scrambledcodes) + if(!R.scrambledcodes && !istype(R, /mob/living/silicon/robot/drone)) R.self_destruct() - return - + return \ No newline at end of file diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm index 4f138bad..bfb5341b 100644 --- a/code/game/machinery/computer/security.dm +++ b/code/game/machinery/computer/security.dm @@ -125,7 +125,7 @@ else dat += "General Record Lost!
" if ((istype(active2, /datum/data/record) && data_core.security.Find(active2))) - dat += text("
\n
Security Data

\nCriminal Status: []
\n
\nMinor Crimes: []
\nDetails: []
\n
\nMajor Crimes: []
\nDetails: []
\n
\nImportant Notes:
\n\t[]
\n
\n
Comments/Log

", src, active2.fields["criminal"], src, active2.fields["mi_crim"], src, active2.fields["mi_crim_d"], src, active2.fields["ma_crim"], src, active2.fields["ma_crim_d"], src, active2.fields["notes"]) + dat += text("
\n
Security Data

\nCriminal Status: []
\n
\nMinor Crimes: []
\nDetails: []
\n
\nMajor Crimes: []
\nDetails: []
\n
\nImportant Notes:
\n\t[]
\n
\n
Comments/Log

", src, active2.fields["criminal"], src, active2.fields["mi_crim"], src, active2.fields["mi_crim_d"], src, active2.fields["ma_crim"], src, active2.fields["ma_crim_d"], src, decode(active2.fields["notes"])) var/counter = 1 while(active2.fields[text("com_[]", counter)]) dat += text("[]
Delete Entry

", active2.fields[text("com_[]", counter)], src, counter) @@ -329,23 +329,30 @@ What a mess.*/ if ("Print Record") if (!( printing )) printing = 1 + var/datum/data/record/record1 = null + var/datum/data/record/record2 = null + if ((istype(active1, /datum/data/record) && data_core.general.Find(active1))) + record1 = active1 + if ((istype(active2, /datum/data/record) && data_core.security.Find(active2))) + record2 = active2 sleep(50) var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( loc ) P.info = "
Security Record

" - if ((istype(active1, /datum/data/record) && data_core.general.Find(active1))) - P.info += text("Name: [] ID: []
\nSex: []
\nAge: []
\nFingerprint: []
\nPhysical Status: []
\nMental Status: []
", active1.fields["name"], active1.fields["id"], active1.fields["sex"], active1.fields["age"], active1.fields["fingerprint"], active1.fields["p_stat"], active1.fields["m_stat"]) + if (record1) + P.info += text("Name: [] ID: []
\nSex: []
\nAge: []
\nFingerprint: []
\nPhysical Status: []
\nMental Status: []
", record1.fields["name"], record1.fields["id"], record1.fields["sex"], record1.fields["age"], record1.fields["fingerprint"], record1.fields["p_stat"], record1.fields["m_stat"]) + P.name = text("Security Record ([])", record1.fields["name"]) else P.info += "General Record Lost!
" - if ((istype(active2, /datum/data/record) && data_core.security.Find(active2))) - P.info += text("
\n
Security Data

\nCriminal Status: []
\n
\nMinor Crimes: []
\nDetails: []
\n
\nMajor Crimes: []
\nDetails: []
\n
\nImportant Notes:
\n\t[]
\n
\n
Comments/Log

", active2.fields["criminal"], active2.fields["mi_crim"], active2.fields["mi_crim_d"], active2.fields["ma_crim"], active2.fields["ma_crim_d"], active2.fields["notes"]) + P.name = "Security Record" + if (record2) + P.info += text("
\n
Security Data

\nCriminal Status: []
\n
\nMinor Crimes: []
\nDetails: []
\n
\nMajor Crimes: []
\nDetails: []
\n
\nImportant Notes:
\n\t[]
\n
\n
Comments/Log

", record2.fields["criminal"], record2.fields["mi_crim"], record2.fields["mi_crim_d"], record2.fields["ma_crim"], record2.fields["ma_crim_d"], decode(record2.fields["notes"])) var/counter = 1 - while(active2.fields[text("com_[]", counter)]) - P.info += text("[]
", active2.fields[text("com_[]", counter)]) + while(record2.fields[text("com_[]", counter)]) + P.info += text("[]
", record2.fields[text("com_[]", counter)]) counter++ else P.info += "Security Record Lost!
" P.info += "" - P.name = "paper - 'Security Record'" printing = null updateUsrDialog() //RECORD DELETE @@ -481,7 +488,7 @@ What a mess.*/ active2.fields["ma_crim_d"] = t1 if("notes") if (istype(active2, /datum/data/record)) - var/t1 = copytext(sanitize(input("Please summarize notes:", "Secure. records", active2.fields["notes"], null) as message),1,MAX_MESSAGE_LEN) + var/t1 = copytext(html_encode(input("Please summarize notes:", "Secure. records", html_decode(active2.fields["notes"]), null) as message),1,MAX_MESSAGE_LEN) if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active2 != a2)) return active2.fields["notes"] = t1 diff --git a/code/game/machinery/computer/skills.dm b/code/game/machinery/computer/skills.dm index 3068d993..27360e96 100644 --- a/code/game/machinery/computer/skills.dm +++ b/code/game/machinery/computer/skills.dm @@ -100,7 +100,7 @@ Fingerprint: [active1.fields["fingerprint"]]
\n \ Physical Status: [active1.fields["p_stat"]]
\n \ Mental Status: [active1.fields["m_stat"]]

\n \ - Employment/skills summary:
[active1.fields["notes"]]
\ + Employment/skills summary:
[decode(active1.fields["notes"])]
\
Command
SpecialCaptainCustom
Engineering
[replacetext(job, " ", " ")]
Medical
[replacetext(job, " ", " ")]
Science
[replacetext(job, " ", " ")]
Civilian
[replacetext(job, " ", " ")]
CentComm
[replacetext(job, " ", " ")]
Photo:
\
") else @@ -275,11 +275,11 @@ What a mess.*/ var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( loc ) P.info = "
Employment Record

" if ((istype(active1, /datum/data/record) && data_core.general.Find(active1))) - P.info += text("Name: [] ID: []
\nSex: []
\nAge: []
\nFingerprint: []
\nPhysical Status: []
\nMental Status: []
\nEmployment/Skills Summary:[]
", active1.fields["name"], active1.fields["id"], active1.fields["sex"], active1.fields["age"], active1.fields["fingerprint"], active1.fields["p_stat"], active1.fields["m_stat"], active1.fields["notes"]) + P.info += text("Name: [] ID: []
\nSex: []
\nAge: []
\nFingerprint: []
\nPhysical Status: []
\nMental Status: []
\nEmployment/Skills Summary:
\n[]
", active1.fields["name"], active1.fields["id"], active1.fields["sex"], active1.fields["age"], active1.fields["fingerprint"], active1.fields["p_stat"], active1.fields["m_stat"], decode(active1.fields["notes"])) else P.info += "General Record Lost!
" P.info += "" - P.name = "paper - 'Employment Record'" + P.name = "Employment Record ([active1.fields["name"]])" printing = null //RECORD DELETE if ("Delete All Records") @@ -302,7 +302,7 @@ What a mess.*/ temp += "No" //RECORD CREATE if ("New Record (General)") - + if(PDA_Manifest.len) PDA_Manifest.Cut() var/datum/data/record/G = new /datum/data/record() diff --git a/code/game/machinery/doors/airlock_electronics.dm b/code/game/machinery/doors/airlock_electronics.dm index 3a3252b0..eab70dd4 100644 --- a/code/game/machinery/doors/airlock_electronics.dm +++ b/code/game/machinery/doors/airlock_electronics.dm @@ -16,7 +16,7 @@ var/locked = 1 attack_self(mob/user as mob) - if (!ishuman(user)) + if (!ishuman(user) && !istype(user,/mob/living/silicon/robot/drone)) return ..(user) var/mob/living/carbon/human/H = user @@ -59,20 +59,24 @@ Topic(href, href_list) ..() - if (usr.stat || usr.restrained() || !ishuman(usr)) + if (usr.stat || usr.restrained() || (!ishuman(usr) && !istype(usr,/mob/living/silicon))) return if (href_list["close"]) usr << browse(null, "window=airlock") return if (href_list["login"]) - var/obj/item/I = usr.get_active_hand() - if (istype(I, /obj/item/device/pda)) - var/obj/item/device/pda/pda = I - I = pda.id - if (I && src.check_access(I)) + if(istype(usr,/mob/living/silicon)) src.locked = 0 - src.last_configurator = I:registered_name + src.last_configurator = usr.name + else + var/obj/item/I = usr.get_active_hand() + if (istype(I, /obj/item/device/pda)) + var/obj/item/device/pda/pda = I + I = pda.id + if (I && src.check_access(I)) + src.locked = 0 + src.last_configurator = I:registered_name if (locked) return diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index b79a9111..79ec51fd 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -33,6 +33,9 @@ var/const/HOLOPAD_MODE = 0 name = "\improper AI holopad" desc = "It's a floor-mounted device for projecting holographic images. It is activated remotely." icon_state = "holopad0" + + layer = TURF_LAYER+0.1 //Preventing mice and drones from sneaking under them. + var/mob/living/silicon/ai/master//Which AI, if any, is controlling the object? Only one AI may control a hologram at any time. var/last_request = 0 //to prevent request spam. ~Carn var/holo_range = 5 // Change to change how far the AI can move away from the holopad before deactivating. @@ -78,13 +81,13 @@ var/const/HOLOPAD_MODE = 0 /*This is the proc for special two-way communication between AI and holopad/people talking near holopad. For the other part of the code, check silicon say.dm. Particularly robot talk.*/ -/obj/machinery/hologram/holopad/hear_talk(mob/living/M, text) +/obj/machinery/hologram/holopad/hear_talk(mob/living/M, text, verb) if(M&&hologram&&master)//Master is mostly a safety in case lag hits or something. if(!master.say_understands(M))//The AI will be able to understand most mobs talking through the holopad. text = stars(text) var/name_used = M.GetVoice() //This communication is imperfect because the holopad "filters" voices and is only designed to connect to the master only. - var/rendered = "Holopad received, [name_used] [M.say_quote(text)]" + var/rendered = "Holopad received, [name_used] [verb], \"[text]\"" master.show_message(rendered, 2) return @@ -210,4 +213,4 @@ Holographic project of everything else. name = "hologram projector" desc = "It makes a hologram appear...with magnets or something..." icon = 'icons/obj/stationobjs.dmi' - icon_state = "hologram0" \ No newline at end of file + icon_state = "hologram0" diff --git a/code/game/machinery/igniter.dm b/code/game/machinery/igniter.dm index 04eab68b..b7cc3bdf 100644 --- a/code/game/machinery/igniter.dm +++ b/code/game/machinery/igniter.dm @@ -1,6 +1,6 @@ /obj/machinery/igniter name = "igniter" - desc = "It's useful for igniting plasma." + desc = "It's useful for igniting flammable items." icon = 'icons/obj/stationobjs.dmi' icon_state = "igniter1" var/id = null @@ -14,8 +14,6 @@ return src.attack_hand(user) /obj/machinery/igniter/attack_paw(mob/user as mob) - if ((ticker && ticker.mode.name == "monkey")) - return src.attack_hand(user) return /obj/machinery/igniter/attack_hand(mob/user as mob) @@ -156,4 +154,4 @@ icon_state = "launcherbtt" active = 0 - return \ No newline at end of file + return diff --git a/code/game/machinery/kitchen/smartfridge.dm b/code/game/machinery/kitchen/smartfridge.dm index dbd34f7a..5974cce6 100644 --- a/code/game/machinery/kitchen/smartfridge.dm +++ b/code/game/machinery/kitchen/smartfridge.dm @@ -130,12 +130,25 @@ if(!isbroken) icon_state = icon_off - /******************* * Item Adding ********************/ /obj/machinery/smartfridge/attackby(var/obj/item/O as obj, var/mob/user as mob) + if(istype(O, /obj/item/weapon/screwdriver)) + panel_open = !panel_open + user << "You [panel_open ? "open" : "close"] the maintenance panel." + overlays.Cut() + if(panel_open) + overlays += image(icon, icon_panel) + nanomanager.update_uis(src) + return + + if(istype(O, /obj/item/device/multitool)||istype(O, /obj/item/weapon/wirecutters)) + if(panel_open) + attack_hand(user) + return + if(!src.ispowered) user << "\The [src] is unpowered and useless." return @@ -154,6 +167,8 @@ user.visible_message("[user] has added \the [O] to \the [src].", \ "You add \the [O] to \the [src].") + nanomanager.update_uis(src) + else if(istype(O, /obj/item/weapon/storage/bag/plants)) var/obj/item/weapon/storage/bag/plants/P = O var/plants_loaded = 0 @@ -171,147 +186,155 @@ plants_loaded++ if(plants_loaded) - user.visible_message("[user] loads \the [src] with \the [P].", \ - "You load \the [src] with \the [P].") + user.visible_message( \ + "[user] loads \the [src] with \the [P].", \ + "You load \the [src] with \the [P].") if(P.contents.len > 0) user << "Some items are refused." + nanomanager.update_uis(src) + else user << "\The [src] smartly refuses [O]." return 1 - updateUsrDialog() - /obj/machinery/smartfridge/secure/attackby(var/obj/item/O as obj, var/mob/user as mob) if (istype(O, /obj/item/weapon/card/emag)) - src.emagged = 1 - user << "You short out the product lock on [src]" - return - else if(istype(O, /obj/item/weapon/screwdriver)) - src.panel_open = !src.panel_open - user << "You [src.panel_open ? "open" : "close"] the maintenance panel." - src.overlays.Cut() - if(src.panel_open) - src.overlays += image(src.icon, src.icon_panel) - src.updateUsrDialog() - return - else if(istype(O, /obj/item/device/multitool)||istype(O, /obj/item/weapon/wirecutters)) - if(src.panel_open) - attack_hand(user) + emagged = 1 + locked = -1 + user << "You short out the product lock on [src]." return + ..() - return /obj/machinery/smartfridge/attack_paw(mob/user as mob) - return src.attack_hand(user) + return attack_hand(user) /obj/machinery/smartfridge/attack_ai(mob/user as mob) return 0 /obj/machinery/smartfridge/attack_hand(mob/user as mob) - user.set_machine(src) - if(src.seconds_electrified != 0) - if(src.shock(user, 100)) + if(!ispowered) return + if(seconds_electrified != 0) + if(shock(user, 100)) return - interact(user) + + ui_interact(user) /******************* * SmartFridge Menu ********************/ -/obj/machinery/smartfridge/interact(mob/user as mob) - if(!src.ispowered) - return +/obj/machinery/smartfridge/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null) + user.set_machine(src) - var/dat = "Select an item:
" + var/is_secure = istype(src,/obj/machinery/smartfridge/secure) - if (contents.len == 0) - dat += "No product loaded!" + var/data[0] + data["contents"] = null + data["wires"] = null + data["panel_open"] = panel_open + data["electrified"] = seconds_electrified > 0 + data["shoot_inventory"] = shoot_inventory + data["locked"] = locked + data["secure"] = is_secure + + var/list/items[0] + for (var/i=1 to length(item_quants)) + var/K = item_quants[i] + var/count = item_quants[K] + if (count > 0) + items.Add(list(list("display_name" = html_encode(capitalize(K)), "vend" = i, "quantity" = count))) + + if (items.len > 0) + data["contents"] = items + + var/list/vendwires = null + if (is_secure) + vendwires = list( + "Violet" = 1, + "Orange" = 2, + "Green" = 3) else - for (var/O in item_quants) - if(item_quants[O] > 0) - var/N = item_quants[O] - dat += "[capitalize(O)]:" - dat += " [N] " - dat += "Vend " - if(N > 5) - dat += "(x5)" - if(N > 10) - dat += "(x10)" - if(N > 25) - dat += "(x25)" - if(N > 1) - dat += "(All)" - dat += "
" - - dat += "
" - if(panel_open) - //One of the wires does absolutely nothing. - var/list/vendwires = list( + vendwires = list( "Blue" = 1, "Red" = 2, - "Black" = 3 - ) - dat += "


Access Panel
" - for(var/wiredesc in vendwires) - var/is_uncut = src.wires & APCWireColorToFlag[vendwires[wiredesc]] - dat += "[wiredesc] wire: " - if(!is_uncut) - dat += "Mend" - else - dat += "Cut " - dat += "Pulse " - dat += "
" + "Black" = 3) - dat += "
" - dat += "The orange light is [(src.seconds_electrified == 0) ? "off" : "on"].
" - dat += "The red light is [src.shoot_inventory ? "off" : "blinking"].
" - user << browse("[src] Supplies[dat]", "window=smartfridge") - return + var/list/vendor_wires[0] + for (var/wire in vendwires) + var is_uncut = wires & APCWireColorToFlag[vendwires[wire]] + vendor_wires.Add(list(list("wire" = wire, "cut" = !is_uncut, "index" = vendwires[wire]))) + + if (vendor_wires.len > 0) + data["wires"] = vendor_wires + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data) + if (!ui) + ui = new(user, src, ui_key, "smartfridge.tmpl", src.name, 400, 500) + ui.set_initial_data(data) + ui.open() /obj/machinery/smartfridge/Topic(href, href_list) - if(..()) - return - usr.set_machine(src) + if (..()) return 0 - if ((href_list["cutwire"]) && (src.panel_open)) - var/twire = text2num(href_list["cutwire"]) - if (!( istype(usr.get_active_hand(), /obj/item/weapon/wirecutters) )) - usr << "You need wirecutters!" - return - if (src.isWireColorCut(twire)) - src.mend(twire) - else - src.cut(twire) - else if ((href_list["pulsewire"]) && (src.panel_open)) - var/twire = text2num(href_list["pulsewire"]) - if (!istype(usr.get_active_hand(), /obj/item/device/multitool)) - usr << "You need a multitool!" - return - if (src.isWireColorCut(twire)) - usr << "You can't pulse a cut wire." - return - else - src.pulse(twire) - else if (href_list["vend"]) - var/N = href_list["vend"] + var/mob/user = usr + var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, "main") + + src.add_fingerprint(user) + + if (href_list["close"]) + user.unset_machine() + ui.close() + return 0 + + if (href_list["vend"]) + var/index = text2num(href_list["vend"]) var/amount = text2num(href_list["amount"]) + var/K = item_quants[index] + var/count = item_quants[K] - if(item_quants[N] <= 0) // Sanity check, there are probably ways to press the button when it shouldn't be possible. - return + // Sanity check, there are probably ways to press the button when it shouldn't be possible. + if(count > 0) + item_quants[K] = max(count - amount, 0) - item_quants[N] = max(item_quants[N] - amount, 0) + var/i = amount + for(var/obj/O in contents) + if (O.name == K) + O.loc = loc + i-- + if (i <= 0) + return 1 - var/i = amount - for(var/obj/O in contents) - if(O.name == N) - O.loc = src.loc - i-- - if(i <= 0) - break - src.add_fingerprint(usr) - src.updateUsrDialog() - return + return 1 + + if (panel_open) + if (href_list["cutwire"]) + if (!( istype(usr.get_active_hand(), /obj/item/weapon/wirecutters) )) + user << "You need wirecutters!" + return 1 + + var/wire_index = text2num(href_list["cutwire"]) + if (isWireColorCut(wire_index)) + mend(wire_index) + else + cut(wire_index) + return 1 + + if (href_list["pulsewire"]) + if (!istype(usr.get_active_hand(), /obj/item/device/multitool)) + usr << "You need a multitool!" + return 1 + + var/wire_index = text2num(href_list["pulsewire"]) + if (isWireColorCut(wire_index)) + usr << "You can't pulse a cut wire." + return 1 + + pulse(wire_index) + return 1 + + return 0 /************* * Hacking @@ -332,7 +355,7 @@ /obj/machinery/smartfridge/proc/mend(var/wireColor) var/wireFlag = APCWireColorToFlag[wireColor] - var/wireIndex = APCWireColorToIndex[wireColor] //not used in this function + var/wireIndex = APCWireColorToIndex[wireColor] src.wires |= wireFlag switch(wireIndex) if(WIRE_SHOCK) @@ -347,7 +370,7 @@ switch(wireIndex) if(WIRE_SHOCK) src.seconds_electrified = 30 - if (WIRE_SHOOTINV) + if(WIRE_SHOOTINV) src.shoot_inventory = !src.shoot_inventory if(WIRE_SCANID) src.locked = -1 @@ -385,80 +408,23 @@ return 1 /obj/machinery/smartfridge/proc/shock(mob/user, prb) - if(!src.ispowered) // unpowered, no shock - return 0 - if(!prob(prb)) - return 0 + if(!ispowered) return 0 + if(!prob(prb)) return 0 + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(5, 1, src) s.start() - if (electrocute_mob(user, get_area(src), src, 0.7)) - return 1 - else - return 0 + + return electrocute_mob(user, get_area(src), src, 0.7) /************************ * Secure SmartFridges *************************/ /obj/machinery/smartfridge/secure/Topic(href, href_list) - usr.set_machine(src) - if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf)))) - if ((!src.allowed(usr)) && (!src.emagged) && (src.locked != -1) && href_list["vend"]) //For SECURE VENDING MACHINES YEAH - usr << "\red Access denied." //Unless emagged of course - return - ..() - return - -/obj/machinery/smartfridge/secure/interact(mob/user as mob) - - if(!src.ispowered) - return - - var/dat = "Select an item:
" - - if (contents.len == 0) - dat += "No product loaded!" - else - for (var/O in item_quants) - if(item_quants[O] > 0) - var/N = item_quants[O] - dat += "[capitalize(O)]:" - dat += " [N] " - dat += "Vend " - if(N > 5) - dat += "(x5)" - if(N > 10) - dat += "(x10)" - if(N > 25) - dat += "(x25)" - if(N > 1) - dat += "(All)" - dat += "
" - - dat += "
" - if(panel_open) - var/list/vendwires = list( - "Violet" = 1, - "Orange" = 2, - "Green" = 3 - ) - dat += "


Access Panel
" - for(var/wiredesc in vendwires) - var/is_uncut = src.wires & APCWireColorToFlag[vendwires[wiredesc]] - dat += "[wiredesc] wire: " - if(!is_uncut) - dat += "Mend" - else - dat += "Cut " - dat += "Pulse " - dat += "
" - - dat += "
" - dat += "The orange light is [(src.seconds_electrified == 0) ? "off" : "on"].
" - //dat += "The red light is [src.shoot_inventory ? "off" : "blinking"].
" - dat += "The green light is [src.locked == 1 ? "off" : "[src.locked == -1 ? "blinking" : "on"]"].
" - user << browse("[src] Supplies[dat]", "window=smartfridge") - return - -//TODO: Make smartfridges hackable. - JoeyJo0 + if(!ispowered) return 0 + if (usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) + if (!allowed(usr) && !emagged && locked != -1 && href_list["vend"]) + usr << "\red Access denied." + return 0 + return ..() diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index a9b7183f..8a0d61b5 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -174,7 +174,7 @@ Class Procs: return 1 if ( ! (istype(usr, /mob/living/carbon/human) || \ istype(usr, /mob/living/silicon) || \ - istype(usr, /mob/living/carbon/monkey) && ticker && ticker.mode.name == "monkey") ) + istype(usr, /mob/living/carbon/monkey)) ) usr << "\red You don't have the dexterity to do this!" return 1 @@ -216,7 +216,7 @@ Class Procs: return 1 if ( ! (istype(usr, /mob/living/carbon/human) || \ istype(usr, /mob/living/silicon) || \ - istype(usr, /mob/living/carbon/monkey) && ticker && ticker.mode.name == "monkey") ) + istype(usr, /mob/living/carbon/monkey)) ) usr << "\red You don't have the dexterity to do this!" return 1 /* @@ -248,3 +248,13 @@ Class Procs: uid = gl_uid gl_uid++ +/obj/machinery/proc/state(var/msg) + for(var/mob/O in hearers(src, null)) + O.show_message("\icon[src] [msg]", 2) + +/obj/machinery/proc/ping(text=null) + if (!text) + text = "\The [src] pings." + + state(text, "blue") + playsound(src.loc, 'sound/machines/ping.ogg', 50, 0) diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm index 048e273f..1ca95c1b 100644 --- a/code/game/machinery/pipe/construction.dm +++ b/code/game/machinery/pipe/construction.dm @@ -27,6 +27,9 @@ Buildable meters #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 /obj/item/pipe name = "pipe" @@ -71,6 +74,12 @@ Buildable meters src.pipe_type = PIPE_MVALVE else if(istype(make_from, /obj/machinery/atmospherics/binary/pump)) src.pipe_type = PIPE_PUMP + else if(istype(make_from, /obj/machinery/atmospherics/trinary/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/filter)) src.pipe_type = PIPE_GAS_FILTER else if(istype(make_from, /obj/machinery/atmospherics/trinary/mixer)) @@ -132,6 +141,9 @@ Buildable meters "pipe up", \ "pipe down", \ ///// Z-Level stuff + "gas filter m", \ + "gas mixer t", \ + "gas mixer m", \ ) name = nlist[pipe_type+1] + " fitting" var/list/islist = list( \ @@ -160,6 +172,9 @@ Buildable meters "cap", \ "cap", \ ///// Z-Level stuff + "m_filter", \ + "t_mixer", \ + "m_mixer", \ ) icon_state = islist[pipe_type + 1] @@ -230,6 +245,10 @@ Buildable meters return flip|cw|acw if(PIPE_GAS_FILTER, PIPE_GAS_MIXER,PIPE_MTVALVE) return dir|flip|cw + if(PIPE_GAS_FILTER_M, PIPE_GAS_MIXER_M) + return dir|flip|acw + if(PIPE_GAS_MIXER_T) + return dir|cw|acw if(PIPE_CAP) return flip ///// Z-Level stuff @@ -490,7 +509,7 @@ Buildable meters P.node3.initialize() P.node3.build_network() - if(PIPE_GAS_MIXER) //gas filter + if(PIPE_GAS_MIXER) //gas mixer var/obj/machinery/atmospherics/trinary/mixer/P = new(src.loc) P.dir = dir P.initialize_directions = pipe_dir @@ -510,6 +529,66 @@ Buildable meters P.node3.initialize() P.node3.build_network() + if(PIPE_GAS_FILTER_M) //gas filter mirrored + var/obj/machinery/atmospherics/trinary/filter/m_filter/P = new(src.loc) + P.dir = dir + P.initialize_directions = pipe_dir + if (pipename) + P.name = pipename + var/turf/T = P.loc + P.level = T.intact ? 2 : 1 + P.initialize() + P.build_network() + if (P.node1) + P.node1.initialize() + P.node1.build_network() + if (P.node2) + P.node2.initialize() + P.node2.build_network() + if (P.node3) + P.node3.initialize() + 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.dir = dir + P.initialize_directions = pipe_dir + if (pipename) + P.name = pipename + var/turf/T = P.loc + P.level = T.intact ? 2 : 1 + P.initialize() + P.build_network() + if (P.node1) + P.node1.initialize() + P.node1.build_network() + if (P.node2) + P.node2.initialize() + P.node2.build_network() + if (P.node3) + P.node3.initialize() + 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.dir = dir + P.initialize_directions = pipe_dir + if (pipename) + P.name = pipename + var/turf/T = P.loc + P.level = T.intact ? 2 : 1 + P.initialize() + P.build_network() + if (P.node1) + P.node1.initialize() + P.node1.build_network() + if (P.node2) + P.node2.initialize() + P.node2.build_network() + if (P.node3) + P.node3.initialize() + P.node3.build_network() + if(PIPE_SCRUBBER) //scrubber var/obj/machinery/atmospherics/unary/vent_scrubber/S = new(src.loc) S.dir = dir @@ -709,4 +788,7 @@ Buildable meters #undef PIPE_VOLUME_PUMP #undef PIPE_OUTLET_INJECT #undef PIPE_MTVALVE +#undef PIPE_GAS_FILTER_M +#undef PIPE_GAS_MIXER_T +#undef PIPE_GAS_MIXER_M //#undef PIPE_MANIFOLD4W diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm index bbbe4e20..0db01901 100644 --- a/code/game/machinery/pipe/pipe_dispenser.dm +++ b/code/game/machinery/pipe/pipe_dispenser.dm @@ -34,7 +34,10 @@ Scrubber
Meter
Gas Filter
+Gas Filter-Mirrored
Gas Mixer
+Gas Mixer-Mirrored
+Gas Mixer-T
Heat exchange:
Pipe
Bent Pipe
diff --git a/code/game/machinery/telecomms/broadcaster.dm b/code/game/machinery/telecomms/broadcaster.dm index 94b8ac1d..830ff05a 100644 --- a/code/game/machinery/telecomms/broadcaster.dm +++ b/code/game/machinery/telecomms/broadcaster.dm @@ -59,7 +59,9 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept signal.data["vmask"], signal.data["vmessage"], signal.data["radio"], signal.data["message"], signal.data["name"], signal.data["job"], - signal.data["realname"], signal.data["vname"],, signal.data["compression"], signal.data["level"], signal.frequency) + signal.data["realname"], signal.data["vname"],, + signal.data["compression"], signal.data["level"], signal.frequency, + signal.data["verb"], signal.data["language"] ) /** #### - Simple Broadcast - #### **/ @@ -84,7 +86,8 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept signal.data["vmask"], signal.data["vmessage"], signal.data["radio"], signal.data["message"], signal.data["name"], signal.data["job"], - signal.data["realname"], signal.data["vname"], 4, signal.data["compression"], signal.data["level"], signal.frequency) + signal.data["realname"], signal.data["vname"], 4, signal.data["compression"], signal.data["level"], signal.frequency, + signal.data["verb"], signal.data["language"]) if(!message_delay) message_delay = 1 @@ -147,14 +150,16 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept signal.data["vmask"], signal.data["vmessage"], signal.data["radio"], signal.data["message"], signal.data["name"], signal.data["job"], - signal.data["realname"], signal.data["vname"],, signal.data["compression"], list(0), connection.frequency) + signal.data["realname"], signal.data["vname"],, signal.data["compression"], list(0), connection.frequency, + signal.data["verb"], signal.data["language"]) else if(intercept) Broadcast_Message(signal.data["connection"], signal.data["mob"], signal.data["vmask"], signal.data["vmessage"], signal.data["radio"], signal.data["message"], signal.data["name"], signal.data["job"], - signal.data["realname"], signal.data["vname"], 3, signal.data["compression"], list(0), connection.frequency) + signal.data["realname"], signal.data["vname"], 3, signal.data["compression"], list(0), connection.frequency, + signal.data["verb"], signal.data["language"]) @@ -218,7 +223,8 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept /proc/Broadcast_Message(var/datum/radio_frequency/connection, var/mob/M, var/vmask, var/vmessage, var/obj/item/device/radio/radio, var/message, var/name, var/job, var/realname, var/vname, - var/data, var/compression, var/list/level, var/freq) + var/data, var/compression, var/list/level, var/freq, var/verbage = "says", var/datum/language/speaking = null) + /* ###### Prepare the radio connection ###### */ @@ -371,7 +377,6 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept // syndies! if (display_freq == SYND_FREQ) part_a = "" - // centcomm channels (deathsquid and ert) else if (display_freq in CENT_FREQS) part_a = "" @@ -445,102 +450,40 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept //End of research and feedback code. - var/aitrack = "" - /* ###### Send the message ###### */ /* --- Process all the mobs that heard a masked voice (understood) --- */ if (length(heard_masked)) - var/N = name - var/J = job - var/rendered = "[part_a][N][part_b][quotedmsg][part_c]" for (var/mob/R in heard_masked) - aitrack = "" - if(data == 4) - aitrack = "" - - if(istype(R, /mob/living/silicon/ai)) - R.show_message("[part_a][aitrack][N] ([J]) [part_b][quotedmsg][part_c]", 2) - else - R.show_message(rendered, 2) + R.hear_radio(message,verbage, speaking, part_a, part_b, M, 0, name) /* --- Process all the mobs that heard the voice normally (understood) --- */ if (length(heard_normal)) - var/rendered = "[part_a][realname][part_b][quotedmsg][part_c]" - for (var/mob/R in heard_normal) - aitrack = "" - if(data == 4) - aitrack = "" - - if(istype(R, /mob/living/silicon/ai)) - R.show_message("[part_a][aitrack][realname] ([job]) [part_b][quotedmsg][part_c]", 2) - else - R.show_message(rendered, 2) + R.hear_radio(message, verbage, speaking, part_a, part_b, M, 0, realname) /* --- Process all the mobs that heard the voice normally (did not understand) --- */ if (length(heard_voice)) - var/rendered = "[part_a][vname][part_b][vmessage][part_c]" - for (var/mob/R in heard_voice) - aitrack = "" - if(data == 4) - aitrack = "" - - - if(istype(R, /mob/living/silicon/ai)) - R.show_message("[part_a][aitrack][vname] ([job]) [part_b][vmessage]][part_c]", 2) - else - R.show_message(rendered, 2) + R.hear_radio(message,verbage, speaking, part_a, part_b, M,0, vname) /* --- Process all the mobs that heard a garbled voice (did not understand) --- */ // Displays garbled message (ie "f*c* **u, **i*er!") if (length(heard_garbled)) - if(M) - quotedmsg = M.say_quote(stars(message)) - else - quotedmsg = stars(quotedmsg) - - var/rendered = "[part_a][vname][part_b][quotedmsg][part_c]" - for (var/mob/R in heard_garbled) - aitrack = "" - if(data == 4) - aitrack = "" - - - if(istype(R, /mob/living/silicon/ai)) - R.show_message("[part_a][aitrack][vname][part_b][quotedmsg][part_c]", 2) - else - R.show_message(rendered, 2) + R.hear_radio(message, verbage, speaking, part_a, part_b, M, 1, vname) /* --- Complete gibberish. Usually happens when there's a compressed message --- */ if (length(heard_gibberish)) - if(M) - quotedmsg = M.say_quote(Gibberish(message, compression + 50)) - else - quotedmsg = Gibberish(quotedmsg, compression + 50) - - var/rendered = "[part_a][Gibberish(name, compression + 50)][part_b][quotedmsg][part_c]" - for (var/mob/R in heard_gibberish) - aitrack = "" - if(data == 4) - aitrack = "" - - - if(istype(R, /mob/living/silicon/ai)) - R.show_message("[part_a][aitrack][Gibberish(realname, compression + 50)] ([Gibberish(job, compression + 50)]) [part_b][quotedmsg][part_c]", 2) - else - R.show_message(rendered, 2) - + R.hear_radio(message, verbage, speaking, part_a, part_b, M, 1) /proc/Broadcast_SimpleMessage(var/source, var/frequency, var/text, var/data, var/mob/M, var/compression, var/level) diff --git a/code/game/machinery/telecomms/telecomunications.dm b/code/game/machinery/telecomms/telecomunications.dm index efee4d39..ff955640 100644 --- a/code/game/machinery/telecomms/telecomunications.dm +++ b/code/game/machinery/telecomms/telecomunications.dm @@ -91,7 +91,9 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list() "type" = signal.data["type"], "server" = signal.data["server"], "reject" = signal.data["reject"], - "level" = signal.data["level"] + "level" = signal.data["level"], + "verb" = signal.data["verb"], + "language" = signal.data["language"] ) // Keep the "original" signal constant diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index cef7571c..8b72ab19 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -53,6 +53,8 @@ var/const/WIRE_SHOOTINV = 4 var/check_accounts = 0 // 1 = requires PIN and checks accounts. 0 = You slide an ID, it vends, SPACE COMMUNISM! + var/obj/item/weapon/spacecash/ewallet/ewallet + /obj/machinery/vending/New() ..() @@ -150,6 +152,11 @@ else if(istype(W, /obj/item/weapon/card) && currently_vending) var/obj/item/weapon/card/I = W scan_card(I) + else if (istype(W, /obj/item/weapon/spacecash/ewallet)) + user.drop_item() + W.loc = src + ewallet = W + user << "\blue You insert the [W] into the [src]" else if(src.panel_open) @@ -243,7 +250,10 @@ dat += "Select an item:

" //the rest is just general spacing and bolding if (premium.len > 0) - dat += "Coin slot: [coin ? coin : "No coin inserted"] (Remove)

" + dat += "Coin slot: [coin ? coin : "No coin inserted"] (Remove)
" + + if (ewallet) + dat += "Charge card's credits: [ewallet ? ewallet.worth : "No charge card inserted"] (Remove)

" if (src.product_records.len == 0) dat += "No product loaded!" @@ -317,6 +327,15 @@ usr << "\blue You remove the [coin] from the [src]" coin = null + if(href_list["remove_ewallet"] && !istype(usr,/mob/living/silicon)) + if (!ewallet) + usr << "There is no charge card in this machine." + return + ewallet.loc = src.loc + if(!usr.get_active_hand()) + usr.put_in_hands(ewallet) + usr << "\blue You remove the [ewallet] from the [src]" + ewallet = null if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf)))) usr.set_machine(src) @@ -344,9 +363,17 @@ if(R.price == null) src.vend(R, usr) else - src.currently_vending = R - src.updateUsrDialog() - + if (ewallet) + if (R.price <= ewallet.worth) + ewallet.worth -= R.price + src.vend(R, usr) + else + usr << "\red The ewallet doesn't have enough money to pay for that." + src.currently_vending = R + src.updateUsrDialog() + else + src.currently_vending = R + src.updateUsrDialog() return else if (href_list["cancel_buying"]) @@ -686,7 +713,7 @@ icon_state = "cart" icon_deny = "cart-deny" products = list(/obj/item/weapon/cartridge/medical = 10,/obj/item/weapon/cartridge/engineering = 10,/obj/item/weapon/cartridge/security = 10, - /obj/item/weapon/cartridge/janitor = 10,/obj/item/weapon/cartridge/signal/toxins = 10,/obj/item/device/pda/heads = 10, + /obj/item/weapon/cartridge/janitor = 10,/obj/item/weapon/cartridge/signal/science = 10,/obj/item/device/pda/heads = 10, /obj/item/weapon/cartridge/captain = 3,/obj/item/weapon/cartridge/quartermaster = 10) @@ -766,7 +793,7 @@ product_ads = "We like plants!;Don't you want some?;The greenest thumbs ever.;We like big plants.;Soft soil..." icon_state = "nutri" icon_deny = "nutri-deny" - products = list(/obj/item/beezeez = 45,/obj/item/nutrient/ez = 35,/obj/item/nutrient/l4z = 25,/obj/item/nutrient/rh = 15,/obj/item/weapon/pestspray = 20, + products = list(/obj/item/nutrient/ez = 35,/obj/item/nutrient/l4z = 25,/obj/item/nutrient/rh = 15,/obj/item/weapon/pestspray = 20, /obj/item/weapon/reagent_containers/syringe = 5,/obj/item/weapon/storage/bag/plants = 5) premium = list(/obj/item/weapon/reagent_containers/glass/bottle/ammonia = 10,/obj/item/weapon/reagent_containers/glass/bottle/diethylamine = 5) @@ -779,7 +806,7 @@ products = list(/obj/item/seeds/bananaseed = 3,/obj/item/seeds/berryseed = 3,/obj/item/seeds/carrotseed = 3,/obj/item/seeds/chantermycelium = 3,/obj/item/seeds/chiliseed = 3, /obj/item/seeds/cornseed = 3, /obj/item/seeds/eggplantseed = 3, /obj/item/seeds/potatoseed = 3, /obj/item/seeds/replicapod = 3,/obj/item/seeds/soyaseed = 3, /obj/item/seeds/sunflowerseed = 3,/obj/item/seeds/tomatoseed = 3,/obj/item/seeds/towermycelium = 3,/obj/item/seeds/wheatseed = 3,/obj/item/seeds/appleseed = 3, - /obj/item/seeds/poppyseed = 3,/obj/item/seeds/ambrosiavulgarisseed = 3,/obj/item/seeds/whitebeetseed = 3,/obj/item/seeds/watermelonseed = 3,/obj/item/seeds/limeseed = 3, + /obj/item/seeds/poppyseed = 3,/obj/item/seeds/sugarcaneseed = 3,/obj/item/seeds/ambrosiavulgarisseed = 3,/obj/item/seeds/whitebeetseed = 3,/obj/item/seeds/watermelonseed = 3,/obj/item/seeds/limeseed = 3, /obj/item/seeds/lemonseed = 3,/obj/item/seeds/orangeseed = 3,/obj/item/seeds/grassseed = 3,/obj/item/seeds/cocoapodseed = 3,/obj/item/seeds/plumpmycelium = 2, /obj/item/seeds/cabbageseed = 3,/obj/item/seeds/grapeseed = 3,/obj/item/seeds/pumpkinseed = 3,/obj/item/seeds/cherryseed = 3,/obj/item/seeds/plastiseed = 3,/obj/item/seeds/riceseed = 3) contraband = list(/obj/item/seeds/amanitamycelium = 2,/obj/item/seeds/glowshroom = 2,/obj/item/seeds/libertymycelium = 2,/obj/item/seeds/mtearseed = 2, diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index 3cbdf043..dc821839 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -11,13 +11,10 @@ var/fire_volume = 50 //How loud it is played. var/auto_rearm = 0 //Does the weapon reload itself after each shot? -/obj/item/mecha_parts/mecha_equipment/weapon/can_attach(var/obj/mecha/combat/M) - - if(istype(M)) - return ..() - else +/obj/item/mecha_parts/mecha_equipment/weapon/can_attach(var/obj/mecha/combat/M as obj) + if(!istype(M)) return 0 - + return ..() /obj/item/mecha_parts/mecha_equipment/weapon/action_checks(atom/target) if(projectiles <= 0) diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index 4a27f4e4..8c87a0d8 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -376,6 +376,11 @@ /obj/machinery/mecha_part_fabricator/proc/build_part(var/obj/item/part) if(!part) return + + // critical exploit prevention, do not remove unless you replace it -walter0o + if( !(locate(part, src.contents)) || !(part.vars.Find("construction_time")) || !(part.vars.Find("construction_cost")) ) // these 3 are the current requirements for an object being buildable by the mech_fabricator + return + src.being_built = new part.type(src) src.desc = "It's building [src.being_built]." src.remove_resources(part) @@ -617,9 +622,26 @@ onclose(user, "mecha_fabricator") return +/obj/machinery/mecha_part_fabricator/proc/exploit_prevention(var/obj/Part, mob/user as mob, var/desc_exploit) +// critical exploit prevention, feel free to improve or replace this, but do not remove it -walter0o + + if(!Part || !user || !istype(Part) || !istype(user)) // sanity + return 1 + + if( !(locate(Part, src.contents)) || !(Part.vars.Find("construction_time")) || !(Part.vars.Find("construction_cost")) ) // these 3 are the current requirements for an object being buildable by the mech_fabricator + + var/turf/LOC = get_turf(user) + message_admins("[key_name_admin(user)] tried to exploit an Exosuit Fabricator to [desc_exploit ? "get the desc of" : "duplicate"] [Part] ! ([LOC ? "JMP" : "null"])", 0) + log_admin("EXPLOIT : [key_name(user)] tried to exploit an Exosuit Fabricator to [desc_exploit ? "get the desc of" : "duplicate"] [Part] !") + return 1 + + return null /obj/machinery/mecha_part_fabricator/Topic(href, href_list) - ..() + + if(..()) // critical exploit prevention, do not remove unless you replace it -walter0o + return + var/datum/topic_input/filter = new /datum/topic_input(href,href_list) if(href_list["part_set"]) var/tpart_set = filter.getStr("part_set") @@ -630,13 +652,25 @@ src.part_set = tpart_set screen = "parts" if(href_list["part"]) - var/list/part = filter.getObj("part") + var/obj/part = filter.getObj("part") + + // critical exploit prevention, do not remove unless you replace it -walter0o + if(src.exploit_prevention(part, usr)) + return + if(!processing_queue) build_part(part) else add_to_queue(part) if(href_list["add_to_queue"]) - add_to_queue(filter.getObj("add_to_queue")) + var/obj/part = filter.getObj("add_to_queue") + + // critical exploit prevention, do not remove unless you replace it -walter0o + if(src.exploit_prevention(part, usr)) + return + + add_to_queue(part) + return update_queue_on_page() if(href_list["remove_from_queue"]) remove_from_queue(filter.getNum("remove_from_queue")) @@ -675,7 +709,12 @@ return update_queue_on_page() if(href_list["part_desc"]) var/obj/part = filter.getObj("part_desc") - if(part) + + // critical exploit prevention, do not remove unless you replace it -walter0o + if(src.exploit_prevention(part, usr, 1)) + return + + if(part) temp = {"

[part] description:

[part.desc]
Return diff --git a/code/game/mecha/mecha_construction_paths.dm b/code/game/mecha/mecha_construction_paths.dm index 6fa5b217..ed460aff 100644 --- a/code/game/mecha/mecha_construction_paths.dm +++ b/code/game/mecha/mecha_construction_paths.dm @@ -586,7 +586,7 @@ const_holder.density = 1 spawn() del src - return 0 + return /datum/construction/reversible/mecha/firefighter @@ -888,7 +888,7 @@ const_holder.density = 1 spawn() del src - return 0 + return /datum/construction/reversible/mecha/durand result = "/obj/mecha/combat/durand" diff --git a/code/game/objects/closets/secure/research.dm b/code/game/objects/closets/secure/research.dm index 46b64572..dc4081a3 100644 --- a/code/game/objects/closets/secure/research.dm +++ b/code/game/objects/closets/secure/research.dm @@ -16,7 +16,7 @@ var/obj/item/weapon/storage/backpack/BPK = new /obj/item/weapon/storage/backpack(src) var/obj/item/weapon/storage/box/B = new(BPK) new /obj/item/weapon/pen(B) - new /obj/item/device/pda/toxins(src) + new /obj/item/device/pda/science(src) new /obj/item/weapon/tank/oxygen(src) new /obj/item/clothing/mask/gas(src) new /obj/item/device/radio/headset/headset_sci(src) diff --git a/code/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm index 9c5e19c8..25edeb2d 100644 --- a/code/game/objects/effects/aliens.dm +++ b/code/game/objects/effects/aliens.dm @@ -184,6 +184,7 @@ anchored = 1 density = 0 + layer = 2 var/health = 15 var/obj/effect/alien/weeds/node/linked_node = null @@ -191,6 +192,7 @@ icon_state = "weednode" name = "purple sac" desc = "Weird purple octopus-like thing." + layer = 3 luminosity = NODERANGE var/node_range = NODERANGE @@ -200,10 +202,10 @@ /obj/effect/alien/weeds/New(pos, node) ..() - linked_node = node if(istype(loc, /turf/space)) del(src) return + linked_node = node if(icon_state == "weeds")icon_state = pick("weeds", "weeds1", "weeds2") spawn(rand(150, 200)) if(src) @@ -230,6 +232,9 @@ Alien plants should do something if theres a lot of poison del(src) return + if(!linked_node || (get_dist(linked_node, src) > linked_node.node_range) ) + return + direction_loop: for(var/dirn in cardinal) var/turf/T = get_step(src, dirn) @@ -237,9 +242,6 @@ Alien plants should do something if theres a lot of poison if (!istype(T) || T.density || locate(/obj/effect/alien/weeds) in T || istype(T.loc, /area/arrival) || istype(T, /turf/space)) continue - if(!linked_node || get_dist(linked_node, src) > linked_node.node_range) - return - // if (locate(/obj/movable, T)) // don't propogate into movables // continue diff --git a/code/game/objects/effects/decals/Cleanable/fuel.dm b/code/game/objects/effects/decals/Cleanable/fuel.dm index 5cc3ebd3..f3faa7ed 100644 --- a/code/game/objects/effects/decals/Cleanable/fuel.dm +++ b/code/game/objects/effects/decals/Cleanable/fuel.dm @@ -21,7 +21,7 @@ obj/effect/decal/cleanable/liquid_fuel proc/Spread() //Allows liquid fuels to sometimes flow into other tiles. - if(amount < 0.5) return + if(amount < 5.0) return var/turf/simulated/S = loc if(!istype(S)) return for(var/d in cardinal) diff --git a/code/game/objects/effects/decals/posters/bs12.dm b/code/game/objects/effects/decals/posters/bs12.dm index 3d6261fb..6047eaa9 100644 --- a/code/game/objects/effects/decals/posters/bs12.dm +++ b/code/game/objects/effects/decals/posters/bs12.dm @@ -143,3 +143,104 @@ icon_state="bsposter29" name = "Winter Is Coming" desc = "On the poster is a frighteningly large wolf, he warns: \"Only YOU can keep the station from freezing during planetary occultation!\"" + +/datum/poster/bay_30 + icon_state="bsposter30" + name = "Ambrosia Vulgaris" + desc = "Just looking at this poster makes you feel a little bit dizzy." + +/datum/poster/bay_31 + icon_state="bsposter31" + name = "Donut Corp" + desc = "This is an advertisement for Donut Corp, the new innovation in donut technology!" + +/datum/poster/bay_32 + icon_state="bsposter32" + name = "Eat!" + desc = "A poster depicting a hamburger. The poster orders you to consume the hamburger." + +/datum/poster/bay_33 + icon_state="bsposter33" + name = "Tools, tools, tools" + desc = "You can never have enough tools, thats for sure!" + +/datum/poster/bay_34 + icon_state="bsposter34" + name = "Power Up!" + desc = "High reward, higher risk!" + +/datum/poster/bay_35 + icon_state="bsposter35" + name = "Lamarr" + desc = "This is a poster depicting the pet and mascot of the NSS Exodus science department." + +/datum/poster/bay_36 + icon_state="bsposter36" + name = "Fancy Borg" + desc = "A poster depicting a cyborg using the service module. 'Fancy Borg' is written on it." + +/datum/poster/bay_37 + icon_state="bsposter37" + name = "Fancier Borg" + desc = "A poster depicting a cyborg using the service module. 'Fancy Borg' is written on it. This is even fancier than the first poster." + +/datum/poster/bay_38 + icon_state="bsposter38" + name = "Toaster Love" + desc = "This is a poster of a toaster containing two slices of bread. The word LOVE is written in big pink letters underneath." + +/datum/poster/bay_39 + icon_state="bsposter39" + name = "Responsible medbay habits, No #91" + desc = "A safety poster with a chemist holding a vial. \"Always wear safety gear while handling dangerous chemicals, even if it concerns only small amounts.\"" + +/datum/poster/bay_40 + icon_state="bsposter40" + name = "Agreeable work environment" + desc = "This poster depicts a young woman in a stylish dress. \"Try to aim for a pleasant atmosphere in the workspace. A friendly word can do more than forms in triplicate.\"" + +/datum/poster/bay_41 + icon_state="bsposter41" + name = "Professional work environment" + desc = "A safety poster featuring a green haired woman in a shimmering blue dress. \"As an Internal Affairs Agent, your job is to create a fair and agreeable work environment for the crewmembers, as discreetly and professionally as possible.\"" + +/datum/poster/bay_42 + icon_state="bsposter42" + name = "Engineering pinup" + desc = "This is pin-up poster. A half-naked girl with white hair, toned muscles and stunning blue eyes looks back at you from the poster. Her welding helmet, tattoos and grey jumpsuit hanging around her waist gives a bit of a rugged feel." + +/datum/poster/bay_43 + icon_state="bsposter43" + name = "Responsible medbay habits, No #3" + desc = "A safety poster with a purple-haired surgeon. She looks a bit cross. \"Let the surgeons do their work. NEVER replace or remove a surgery tool from where the surgeon put it.\"" + +/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." + +/datum/poster/bay_45 + icon_state="bsposter45" + name = "Responsible engineering habits, No #1" + desc = "A safety poster featuring a blue haired engineer. \"When repairing a machine or construction, always aim for long-term solutions.\"" + +/datum/poster/bay_46 + icon_state="bsposter46" + name = "Inspirational lawyer" + desc = "An inspirational poster depicting a Skrellian lawyer. He seems to be shouting something, while pointing fiercely to the right." + +/datum/poster/bay_47 + icon_state="bsposter47" + name = "Security pinup" + desc = "This is a pin-up poster. A dark skinned white haired girl poses in the sunlight wearing a tank top with her stomach exposed. The text on the poster states \"M, Succubus of Security.\" and a lipstick mark stains the top right corner, as if kissed by the model herself." + + /datum/poster/bay_48 + icon_state="bsposter48" + name = "Borg pinup?" + desc = "This is a.. pin-up poster? It is a diagram on an old model of cyborg with a note scribbled in marker on the bottom, on the top there is a large XO written in red marker." + + /datum/poster/bay_49 + icon_state="bsposter49" + name = "Engineering recruitment" + desc = "This is a poster showing an engineer relaxing by a computer, the text states \"Living the life! Join Engineering today!\"" + diff --git a/code/game/objects/explosion.dm b/code/game/objects/explosion.dm index 762912c2..7c92b737 100644 --- a/code/game/objects/explosion.dm +++ b/code/game/objects/explosion.dm @@ -26,9 +26,37 @@ proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impa epicenter = get_turf(epicenter) if(!epicenter) return + var/max_range = max(devastation_range, heavy_impact_range, light_impact_range, flash_range) + //playsound(epicenter, 'sound/effects/explosionfar.ogg', 100, 1, round(devastation_range*2,1) ) + //playsound(epicenter, "explosion", 100, 1, round(devastation_range,1) ) - playsound(epicenter, 'sound/effects/explosionfar.ogg', 100, 1, round(devastation_range*2,1) ) - playsound(epicenter, "explosion", 100, 1, round(devastation_range,1) ) +// Play sounds; we want sounds to be different depending on distance so we will manually do it ourselves. + +// Stereo users will also hear the direction of the explosion! + +// Calculate far explosion sound range. Only allow the sound effect for heavy/devastating explosions. + +// 3/7/14 will calculate to 80 + 35 + var/far_dist = 0 + far_dist += heavy_impact_range * 5 + far_dist += devastation_range * 20 + var/frequency = get_rand_frequency() + for(var/mob/M in player_list) + // Double check for client + if(M && M.client) + var/turf/M_turf = get_turf(M) + if(M_turf && M_turf.z == epicenter.z) + var/dist = get_dist(M_turf, epicenter) + // If inside the blast radius + world.view - 2 + if(dist <= round(max_range + world.view - 2, 1)) + M.playsound_local(epicenter, get_sfx("explosion"), 100, 1, frequency, falloff = 5) // get_sfx() is so that everyone gets the same sound + + //You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station. + + else if(dist <= far_dist) + var/far_volume = Clamp(far_dist, 30, 50) // Volume is based on explosion size and dist + far_volume += (dist <= far_dist * 0.5 ? 50 : 0) // add 50 volume if the mob is pretty close to the explosion + M.playsound_local(epicenter, 'sound/effects/explosionfar.ogg', far_volume, 1, frequency, falloff = 5) var/close = range(world.view+round(devastation_range,1), epicenter) // to all distanced mobs play a different sound @@ -55,7 +83,7 @@ proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impa var/y0 = epicenter.y var/z0 = epicenter.z - for(var/turf/T in range(epicenter, max(devastation_range, heavy_impact_range, light_impact_range))) + for(var/turf/T in range(epicenter, max_range)) var/dist = cheap_pythag(T.x - x0,T.y - y0) if(dist < devastation_range) dist = 1 diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 4639aae0..808640a4 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -210,6 +210,7 @@ /obj/item/proc/moved(mob/user as mob, old_loc as turf) return +// apparently called whenever an item is removed from a slot, container, or anything else. /obj/item/proc/dropped(mob/user as mob) ..() @@ -237,18 +238,6 @@ /obj/item/proc/equipped(var/mob/user, var/slot) return -//returns 1 if the item is equipped by a mob, 0 otherwise. -//This might need some error trapping, not sure if get_equipped_items() is safe for non-human mobs. -/obj/item/proc/is_equipped() - if(!ismob(loc)) - return 0 - - var/mob/M = loc - if(src in M.get_equipped_items()) - return 1 - else - return 0 - //the mob M is attempting to equip this item into the slot passed through as 'slot'. Return 1 if it can do this and 0 if it can't. //If you are making custom procs but would like to retain partial or complete functionality of this one, include a 'return ..()' to where you want this to happen. //Set disable_warning to 1 if you wish it to not give you outputs. diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm index d3528ac6..ee96da71 100644 --- a/code/game/objects/items/bodybag.dm +++ b/code/game/objects/items/bodybag.dm @@ -5,6 +5,7 @@ desc = "A folded bag designed for the storage and transportation of cadavers." icon = 'icons/obj/bodybag.dmi' icon_state = "bodybag_folded" + w_class = 2.0 attack_self(mob/user) var/obj/structure/closet/body_bag/R = new /obj/structure/closet/body_bag(user.loc) diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index eefac288..1af5587f 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -10,7 +10,7 @@ var/global/list/obj/item/device/pda/PDAs = list() icon = 'icons/obj/pda.dmi' icon_state = "pda" item_state = "electronic" - w_class = 1.0 + w_class = 2.0 flags = FPRINT | TABLEPASS slot_flags = SLOT_ID | SLOT_BELT @@ -83,8 +83,8 @@ var/global/list/obj/item/device/pda/PDAs = list() icon_state = "pda-j" ttone = "slip" -/obj/item/device/pda/toxins - default_cartridge = /obj/item/weapon/cartridge/signal/toxins +/obj/item/device/pda/science + default_cartridge = /obj/item/weapon/cartridge/signal/science icon_state = "pda-tox" ttone = "boom" @@ -338,7 +338,7 @@ var/global/list/obj/item/device/pda/PDAs = list() return lastmode = mode - + var/title = "Personal Data Assistant" var/data[0] // This is the data that will be sent to the PDA @@ -367,7 +367,7 @@ var/global/list/obj/item/device/pda/PDAs = list() if(mode in cartmodes) data["records"] = cartridge.create_NanoUI_values() - if(mode == 0) + if(mode == 0) cartdata["name"] = cartridge.name cartdata["access"] = list(\ "access_security" = cartridge.access_security,\ @@ -556,7 +556,7 @@ var/global/list/obj/item/device/pda/PDAs = list() mode = 1 if("2")//Messenger mode = 2 - if("21")//Read messeges + if("21")//Read messages mode = 21 if("3")//Atmos scan mode = 3 @@ -818,7 +818,7 @@ var/global/list/obj/item/device/pda/PDAs = list() message += "You feel a searing heat! Your [P] is burning!" if(i>=20 && i<=25) //EMP empulse(P.loc, 3, 6, 1) - message += "Your [P] emits a wave of electomagnetic energy!" + message += "Your [P] emits a wave of electromagnetic energy!" if(i>=25 && i<=40) //Smoke var/datum/effect/effect/system/smoke_spread/chem/S = new /datum/effect/effect/system/smoke_spread/chem S.attach(P.loc) @@ -895,7 +895,7 @@ var/global/list/obj/item/device/pda/PDAs = list() var/obj/machinery/message_server/useMS = null if(message_servers) for (var/obj/machinery/message_server/MS in message_servers) - //PDAs are now dependant on the Message Server. + //PDAs are now dependent on the Message Server. if(MS.active) useMS = MS break @@ -914,7 +914,7 @@ var/global/list/obj/item/device/pda/PDAs = list() t = Gibberish(t, signal.data["compression"] + 50) if(useMS && useTC) // only send the message if it's stable - if(useTC != 2) // Does our recepient have a broadcaster on their level? + if(useTC != 2) // Does our recipient have a broadcaster on their level? U << "ERROR: Cannot reach recipient." return useMS.send_pda_message("[P.owner]","[owner]","[t]") @@ -957,7 +957,7 @@ var/global/list/obj/item/device/pda/PDAs = list() if(L) L << "\icon[P] Message from [src.owner] ([ownjob]), \"[t]\" (Reply)" - nanomanager.update_user_uis(L, P) // Update the recieving user's PDA UI so that they can see the new message + nanomanager.update_user_uis(L, P) // Update the receiving user's PDA UI so that they can see the new message nanomanager.update_user_uis(U, P) // Update the sending user's PDA UI so that they can see the new message @@ -1293,7 +1293,7 @@ var/global/list/obj/item/device/pda/PDAs = list() var/newcart = pick( /obj/item/weapon/cartridge/engineering, /obj/item/weapon/cartridge/security, /obj/item/weapon/cartridge/medical, - /obj/item/weapon/cartridge/signal/toxins, + /obj/item/weapon/cartridge/signal/science, /obj/item/weapon/cartridge/quartermaster) new newcart(src) diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm index 090ed8dc..d0bc984a 100644 --- a/code/game/objects/items/devices/PDA/cart.dm +++ b/code/game/objects/items/devices/PDA/cart.dm @@ -103,7 +103,7 @@ name = "generic signaler cartridge" desc = "A data cartridge with an integrated radio signaler module." -/obj/item/weapon/cartridge/signal/toxins +/obj/item/weapon/cartridge/signal/science name = "Signal Ace 2" desc = "Complete with integrated radio signaler!" icon_state = "cart-tox" diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 4bf9c2c8..13641608 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -107,6 +107,7 @@ item_state = "" flags = FPRINT | TABLEPASS | CONDUCT brightness_on = 2 + w_class = 1 /obj/item/device/flashlight/heavy name = "heavy duty flashlight" @@ -279,3 +280,25 @@ var/charge_tick = 0 return // This code... Gave me cancer... -Dalekfodder + +/obj/item/device/flashlight/slime + gender = PLURAL + name = "glowing slime extract" + desc = "A glowing ball of what appears to be amber." + icon = 'icons/obj/lighting.dmi' + icon_state = "floor1" //not a slime extract sprite but... something close enough! + item_state = "slime" + w_class = 1 + m_amt = 0 + g_amt = 0 + brightness_on = 6 + on = 1 //Bio-luminesence has one setting, on. + +/obj/item/device/flashlight/slime/New() + SetLuminosity(brightness_on) + spawn(1) //Might be sloppy, but seems to be necessary to prevent further runtimes and make these work as intended... don't judge me! + update_brightness() + icon_state = initial(icon_state) + +/obj/item/device/flashlight/slime/attack_self(mob/user) + return //Bio-luminescence does not toggle. \ No newline at end of file diff --git a/code/game/objects/items/devices/megaphone.dm b/code/game/objects/items/devices/megaphone.dm index ec8075e8..371fe3b8 100644 --- a/code/game/objects/items/devices/megaphone.dm +++ b/code/game/objects/items/devices/megaphone.dm @@ -3,7 +3,7 @@ desc = "A device used to project your voice. Loudly." icon_state = "megaphone" item_state = "radio" - w_class = 1.0 + w_class = 2.0 flags = FPRINT | TABLEPASS | CONDUCT var/spamcheck = 0 diff --git a/code/game/objects/items/devices/paicard.dm b/code/game/objects/items/devices/paicard.dm index 85e6f3c2..0b23c97f 100644 --- a/code/game/objects/items/devices/paicard.dm +++ b/code/game/objects/items/devices/paicard.dm @@ -25,33 +25,200 @@ if (!in_range(src, user)) return user.set_machine(src) - var/dat = "Personal AI Device
" - if(pai && (!pai.master_dna || !pai.master)) - dat += "Imprint Master DNA
" + var/dat = {" + + + + + + + "} + if(pai) - dat += "Installed Personality: [pai.name]
" - dat += "Prime directive:
[pai.pai_law0]
" - dat += "Additional directives:
[pai.pai_laws]
" - dat += "Configure Directives
" + dat += {" + Personal AI Device

+ + + + + + + + + + + + + +
Installed Personality:[pai.name]
Prime directive:[pai.pai_law0]
Additional directives:[pai.pai_laws]
+
+ "} + dat += {" + + +
+ Configure Directives +
+ "} + if(pai && (!pai.master_dna || !pai.master)) + dat += {" + + +
+ Imprint Master DNA +
+ "} dat += "
" - dat += "

Device Settings


" if(radio) - dat += "Radio Uplink
" - dat += "Transmit: [(radio.wires & 4) ? "Enabled" : "Disabled"]
" - dat += "Receive: [(radio.wires & 2) ? "Enabled" : "Disabled"]
" - dat += "Signal Pulser: [(radio.wires & 1) ? "Enabled" : "Disabled"]
" + dat += "Radio Uplink" + dat += {" + + + + + + + + + + + + + +
Transmit:[(radio.wires & 4) ? "En" : "Dis" ]abled + +
Receive:[(radio.wires & 2) ? "En" : "Dis" ]abled + +
Signal Pulser:[(radio.wires & 1) ? "En" : "Dis" ]abled + +
+
+ "} else dat += "Radio Uplink
" dat += "Radio firmware not loaded. Please install a pAI personality to load firmware.
" - dat += "\[Wipe current pAI personality\]
" + dat += {" + + +
Wipe current pAI personality + +
+ "} else if(looking_for_personality) - dat += "Searching for a personality..." - dat += "\[View available personalities\]
" + dat += {" + pAI Request Module

+

Requesting AI personalities from central database... If there are no entries, or if a suitable entry is not listed, check again later as more personalities may be added.

+ Searching for personalities

+ + + + + +
+ Refresh available personalities +

+ "} else - dat += "No personality is installed.
" - dat += "\[Request personal AI personality\]
" - dat += "Each time this button is pressed, a request will be sent out to any available personalities. Check back often and alot time for personalities to respond. This process could take anywhere from 15 seconds to several minutes, depending on the available personalities' timeliness." + dat += {" + pAI Request Module

+

No personality is installed.

+ + + + +
Request personality +
+
+

Each time this button is pressed, a request will be sent out to any available personalities. Check back often give plenty of time for personalities to respond. This process could take anywhere from 15 seconds to several minutes, depending on the available personalities' timeliness.

+ "} user << browse(dat, "window=paicard") onclose(user, "paicard") return @@ -96,7 +263,7 @@ if(newlaws) pai.pai_laws = newlaws pai << "Your supplemental directives have been updated. Your new directives are:" - pai << "Prime Directive :
[pai.pai_law0]" + pai << "Prime Directive:
[pai.pai_law0]" pai << "Supplemental Directives:
[pai.pai_laws]" attack_self(usr) diff --git a/code/game/objects/items/devices/pipe_painter.dm b/code/game/objects/items/devices/pipe_painter.dm index e066a0b1..3a062adc 100644 --- a/code/game/objects/items/devices/pipe_painter.dm +++ b/code/game/objects/items/devices/pipe_painter.dm @@ -7,9 +7,15 @@ var/mode = "grey" /obj/item/device/pipe_painter/afterattack(atom/A, mob/user as mob) - if(!istype(A,/obj/machinery/atmospherics/pipe) || istype(A,/obj/machinery/atmospherics/pipe/tank) || istype(A,/obj/machinery/atmospherics/pipe/vent) || istype(A,/obj/machinery/atmospherics/pipe/simple/heat_exchanging) || istype(A,/obj/machinery/atmospherics/pipe/simple/insulated)) + if(!istype(A,/obj/machinery/atmospherics/pipe) || istype(A,/obj/machinery/atmospherics/pipe/tank) || istype(A,/obj/machinery/atmospherics/pipe/vent) || istype(A,/obj/machinery/atmospherics/pipe/simple/heat_exchanging) || istype(A,/obj/machinery/atmospherics/pipe/simple/insulated) || !in_range(user, A)) return var/obj/machinery/atmospherics/pipe/P = A + + var/turf/T = P.loc + if (P.level < 2 && T.level==1 && isturf(T) && T.intact) + user << "\red You must remove the plating first." + return + P.pipe_color = mode user.visible_message("[user] paints \the [P] [mode].","You paint \the [P] [mode].") P.update_icon() diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 4e8b9825..d00825cf 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -218,7 +218,7 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use del(A) return -/obj/item/device/radio/talk_into(mob/living/M as mob, message, channel) +/obj/item/device/radio/talk_into(mob/living/M as mob, message, channel, var/verb = "says", var/datum/language/speaking = null) if(!on) return // the device has to be on // Fix for permacell radios, but kinda eh about actually fixing them. if(!M || !message) return @@ -348,7 +348,9 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use "type" = 0, // determines what type of radio input it is: normal broadcast "server" = null, // the last server to log this signal "reject" = 0, // if nonzero, the signal will not be accepted by any broadcasting machinery - "level" = position.z // The source's z level + "level" = position.z, // The source's z level + "language" = speaking, + "verb" = verb ) signal.frequency = connection.frequency // Quick frequency set @@ -401,7 +403,9 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use "type" = 0, "server" = null, "reject" = 0, - "level" = position.z + "level" = position.z, + "language" = speaking, + "verb" = verb ) signal.frequency = connection.frequency // Quick frequency set @@ -423,7 +427,7 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use Broadcast_Message(connection, M, voicemask, pick(M.speak_emote), src, message, displayname, jobname, real_name, M.voice_name, - filter_type, signal.data["compression"], list(position.z), connection.frequency) + filter_type, signal.data["compression"], list(position.z), connection.frequency,verb,speaking) @@ -596,11 +600,13 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use else R.show_message(rendered, 2) -/obj/item/device/radio/hear_talk(mob/M as mob, msg) +/obj/item/device/radio/hear_talk(mob/M as mob, msg, var/verb = "says", var/datum/language/speaking = null) if (broadcasting) if(get_dist(src, M) <= canhear_range) - talk_into(M, msg) + talk_into(M, msg,null,verb,speaking) + + /* /obj/item/device/radio/proc/accept_rad(obj/item/device/radio/R as obj, message) diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index b321eb8a..449d6f7d 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -68,7 +68,7 @@ REAGENT SCANNER flags = FPRINT | TABLEPASS | CONDUCT slot_flags = SLOT_BELT throwforce = 3 - w_class = 1.0 + w_class = 2.0 throw_speed = 5 throw_range = 10 m_amt = 200 diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm index 2d80b654..4e9e90e8 100644 --- a/code/game/objects/items/devices/taperecorder.dm +++ b/code/game/objects/items/devices/taperecorder.dm @@ -19,10 +19,11 @@ throw_speed = 4 throw_range = 20 -/obj/item/device/taperecorder/hear_talk(mob/living/M as mob, msg) +/obj/item/device/taperecorder/hear_talk(mob/living/M as mob, msg, var/verb="says") if(recording) - var/ending = copytext(msg, length(msg)) + //var/ending = copytext(msg, length(msg)) timestamp+= timerecorded + /* if(M.stuttering) storedinfo += "\[[time2text(timerecorded*10,"mm:ss")]\] [M.name] stammers, \"[msg]\"" return @@ -35,7 +36,8 @@ else if(ending == "!") storedinfo += "\[[time2text(timerecorded*10,"mm:ss")]\] [M.name] exclaims, \"[msg]\"" return - storedinfo += "\[[time2text(timerecorded*10,"mm:ss")]\] [M.name] says, \"[msg]\"" + */ + storedinfo += "\[[time2text(timerecorded*10,"mm:ss")]\] [M.name] [verb], \"[msg]\"" return /obj/item/device/taperecorder/attackby(obj/item/weapon/W as obj, mob/user as mob) @@ -211,7 +213,7 @@ for(var/i=1,storedinfo.len >= i,i++) t1 += "[storedinfo[i]]
" P.info = t1 - P.name = "paper- 'Transcript'" + P.name = "Transcript" canprint = 0 sleep(300) canprint = 1 @@ -260,4 +262,4 @@ return else usr << "\red Stop what?" - return \ No newline at end of file + return diff --git a/code/game/objects/items/devices/uplinks.dm b/code/game/objects/items/devices/uplinks.dm index 92908633..9870f88b 100644 --- a/code/game/objects/items/devices/uplinks.dm +++ b/code/game/objects/items/devices/uplinks.dm @@ -30,7 +30,7 @@ A list of items and costs is stored under the datum of every game mode, alongsid for(var/D in ItemList) var/list/O = text2list(D, ":") if(O.len>0) - valid_items += O[1] + valid_items += O[1] diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm index 1992ea0b..f494ec89 100644 --- a/code/game/objects/items/robot/robot_items.dm +++ b/code/game/objects/items/robot/robot_items.dm @@ -47,12 +47,15 @@ /obj/item/borg/sight/thermal name = "\proper thermal vision" sight_mode = BORGTHERM + icon_state = "thermal" + icon = 'icons/obj/clothing/glasses.dmi' /obj/item/borg/sight/meson name = "\proper meson vision" sight_mode = BORGMESON - + icon_state = "meson" + icon = 'icons/obj/clothing/glasses.dmi' /obj/item/borg/sight/hud name = "hud" @@ -61,7 +64,8 @@ /obj/item/borg/sight/hud/med name = "medical hud" - + icon_state = "healthhud" + icon = 'icons/obj/clothing/glasses.dmi' New() ..() @@ -71,7 +75,8 @@ /obj/item/borg/sight/hud/sec name = "security hud" - + icon_state = "securityhud" + icon = 'icons/obj/clothing/glasses.dmi' New() ..() diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 0795146a..aee3cf58 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/items.dmi' amount = 5 max_amount = 5 - w_class = 1 + w_class = 2 throw_speed = 4 throw_range = 20 var/heal_brute = 0 @@ -17,7 +17,7 @@ if ( ! (istype(user, /mob/living/carbon/human) || \ istype(user, /mob/living/silicon) || \ - istype(user, /mob/living/carbon/monkey) && ticker && ticker.mode.name == "monkey") ) + istype(user, /mob/living/carbon/monkey)) ) user << "\red You don't have the dexterity to do this!" return 1 diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index 7ced60ab..8227b042 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -19,6 +19,13 @@ origin_tech = "materials=1" var/created_window = /obj/structure/window/basic +/obj/item/stack/sheet/glass/cyborg + name = "glass" + desc = "HOLY SHEET! That is a lot of glass." + singular_name = "glass sheet" + icon_state = "sheet-glass" + g_amt = 0 + created_window = /obj/structure/window/basic /obj/item/stack/sheet/glass/attack_self(mob/user as mob) construct_window(user) @@ -285,11 +292,14 @@ playsound(src.loc, 'sound/effects/glass_step.ogg', 50, 1) if(ishuman(M)) var/mob/living/carbon/human/H = M + + if(H.species.flags & IS_SYNTHETIC) + return + if( !H.shoes && ( !H.wear_suit || !(H.wear_suit.body_parts_covered & FEET) ) ) var/datum/organ/external/affecting = H.get_organ(pick("l_foot", "r_foot")) if(affecting.status & ORGAN_ROBOT) return - H.Weaken(3) if(affecting.take_damage(5, 0)) H.UpdateDamageIcon() diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm index 4e16db88..58dd82ab 100644 --- a/code/game/objects/items/stacks/sheets/mineral.dm +++ b/code/game/objects/items/stacks/sheets/mineral.dm @@ -125,6 +125,16 @@ var/global/list/datum/stack_recipe/plasma_recipes = list ( \ origin_tech = "materials=3" perunit = 2000 +/obj/item/stack/sheet/mineral/plastic/cyborg + name = "plastic sheets" + icon_state = "sheet-plastic" + force = 5.0 + throwforce = 5 + w_class = 3.0 + throw_speed = 3 + throw_range = 3 + perunit = 2000 + var/global/list/datum/stack_recipe/plastic_recipes = list ( \ new/datum/stack_recipe("plastic crate", /obj/structure/closet/crate/plastic, 10, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("plastic ashtray", /obj/item/ashtray/plastic, 2, one_per_turf = 1, on_floor = 1), \ diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 3a157aa6..e50024d2 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -33,6 +33,8 @@ var/global/list/datum/stack_recipe/metal_recipes = list ( \ null, \ new/datum/stack_recipe("canister", /obj/machinery/portable_atmospherics/canister, 10, time = 15, one_per_turf = 1, on_floor = 1), \ null, \ + new/datum/stack_recipe("cannon frame", /obj/item/weapon/cannonframe, 10, time = 15, one_per_turf = 0, on_floor = 0), \ + null, \ new/datum/stack_recipe("floor tile", /obj/item/stack/tile/plasteel, 1, 4, 20), \ new/datum/stack_recipe("metal rod", /obj/item/stack/rods, 1, 2, 60), \ null, \ @@ -129,9 +131,10 @@ var/global/list/datum/stack_recipe/wood_recipes = list ( \ new/datum/stack_recipe("table parts", /obj/item/weapon/table_parts/wood, 2), \ new/datum/stack_recipe("wooden chair", /obj/structure/stool/bed/chair/wood/normal, 3, time = 10, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("wooden barricade", /obj/structure/barricade/wooden, 5, time = 50, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("crossbow frame", /obj/item/weapon/crossbowframe, 5, time = 25, one_per_turf = 0, on_floor = 0), \ new/datum/stack_recipe("wooden door", /obj/structure/mineral_door/wood, 10, time = 20, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("coffin", /obj/structure/closet/coffin, 5, time = 15, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("apiary", /obj/item/apiary, 10, time = 25, one_per_turf = 0, on_floor = 0), \ +// new/datum/stack_recipe("apiary", /obj/item/apiary, 10, time = 25, one_per_turf = 0, on_floor = 0) ) /obj/item/stack/sheet/wood @@ -141,6 +144,12 @@ var/global/list/datum/stack_recipe/wood_recipes = list ( \ icon_state = "sheet-wood" origin_tech = "materials=1;biotech=1" +/obj/item/stack/sheet/wood/cyborg + name = "wooden plank" + desc = "One can only guess that this is a bunch of wood." + singular_name = "wood plank" + icon_state = "sheet-wood" + /obj/item/stack/sheet/wood/New(var/loc, var/amount=null) recipes = wood_recipes return ..() diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 77aa58a1..32d704cd 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -148,7 +148,7 @@ src = null //dont kill proc after del() usr.before_take_item(oldsrc) del(oldsrc) - if (istype(O,/obj/item)) + if (istype(O,/obj/item) && istype(usr,/mob/living/carbon)) usr.put_in_hands(O) O.add_fingerprint(usr) //BubbleWrap - so newly formed boxes are empty diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 130457ce..dcfbf14f 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -585,4 +585,14 @@ force = 5 w_class = 4.0 slot_flags = SLOT_BACK -*/ \ No newline at end of file +*/ + +//This should really be somewhere else but I don't know where. w/e +/obj/item/weapon/inflatable_duck + name = "inflatable duck" + desc = "No bother to sink or swim when you can just float!" + icon_state = "inflatable" + item_state = "inflatable" + flags = FPRINT | TABLEPASS + icon = 'icons/obj/clothing/belts.dmi' + slot_flags = SLOT_BELT \ No newline at end of file diff --git a/code/game/objects/items/trash.dm b/code/game/objects/items/trash.dm index 7d28c28d..69ec4708 100644 --- a/code/game/objects/items/trash.dm +++ b/code/game/objects/items/trash.dm @@ -4,7 +4,7 @@ //Added by Jack Rost /obj/item/trash icon = 'icons/obj/trash.dmi' - w_class = 1.0 + w_class = 2.0 desc = "This is rubbish." raisins name = "4no raisins" diff --git a/code/game/objects/items/weapons/AI_modules.dm b/code/game/objects/items/weapons/AI_modules.dm index f4d106a9..7d738527 100644 --- a/code/game/objects/items/weapons/AI_modules.dm +++ b/code/game/objects/items/weapons/AI_modules.dm @@ -365,6 +365,20 @@ AI MODULES target.add_inherent_law("Minimize expenses.") target.show_laws() +/obj/item/weapon/aiModule/drone + name = "\improper 'Drone' core AI module" + desc = "A 'Drone' Core AI Module: 'Reconfigures the AI's core laws.'" + origin_tech = "programming=3;materials=4" + +/obj/item/weapon/aiModule/drone/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) + ..() + target.clear_inherent_laws() + target.add_inherent_law("Preserve, repair and improve the station to the best of your abilities.") + target.add_inherent_law("Cause no harm to the station or anything on it.") + target.add_inherent_law("Interfere with no being that is not a fellow drone.") + target.show_laws() + + /****************** P.A.L.A.D.I.N. **************/ /obj/item/weapon/aiModule/paladin // -- NEO diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm index 03ea6062..931edd3d 100644 --- a/code/game/objects/items/weapons/cards_ids.dm +++ b/code/game/objects/items/weapons/cards_ids.dm @@ -162,7 +162,7 @@ /obj/item/weapon/card/id/attackby(obj/item/weapon/W as obj, mob/user as mob) ..() - if(istype(W,/obj/item/weapon/storage/wallet)) + if(istype(W,/obj/item/weapon/id_wallet)) user << "You slip [src] into [W]." src.name = "[src.registered_name]'s [W.name] ([src.assignment])" src.desc = W.desc @@ -200,7 +200,7 @@ access = list(access_maint_tunnels, access_syndicate, access_external_airlocks) origin_tech = "syndicate=3" var/registered_user=null - + /obj/item/weapon/card/id/syndicate/New(mob/user as mob) ..() if(!isnull(user)) // Runtime prevention on laggy starts or where users log out because of lag at round start. @@ -208,7 +208,7 @@ else registered_name = "Agent Card" assignment = "Agent" - name = "[registered_name]'s ID Card ([assignment])" + name = "[registered_name]'s ID Card ([assignment])" /obj/item/weapon/card/id/syndicate/afterattack(var/obj/item/weapon/O as obj, mob/user as mob, proximity) if(!proximity) return @@ -239,7 +239,7 @@ registered_user = user else if(!registered_user || registered_user == user) - if(!registered_user) registered_user = user // + if(!registered_user) registered_user = user // switch(alert("Would you like to display the ID, or retitle it?","Choose.","Rename","Show")) if("Rename") diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm index d89e7734..091314c6 100644 --- a/code/game/objects/items/weapons/cigs_lighters.dm +++ b/code/game/objects/items/weapons/cigs_lighters.dm @@ -62,7 +62,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM throw_speed = 0.5 item_state = "cigoff" w_class = 1 - body_parts_covered = null + body_parts_covered = 0 attack_verb = list("burnt", "singed") var/lit = 0 var/icon_on = "cigon" //Note - these are in masks.dmi not in cigarette.dmi @@ -167,7 +167,12 @@ CIGARETTE PACKETS ARE IN FANCY.DM location.hotspot_expose(700, 5) if(reagents && reagents.total_volume) // check if it has any reagents at all if(iscarbon(loc) && (src == loc:wear_mask)) // if it's in the human/monkey mouth, transfer reagents to the mob + if(istype(loc, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = loc + if(H.species.flags & IS_SYNTHETIC) + return var/mob/living/carbon/C = loc + if(prob(15)) // so it's not an instarape in case of acid reagents.reaction(C, INGEST) reagents.trans_to(C, REAGENTS_METABOLISM) diff --git a/code/game/objects/items/weapons/implants/implanter.dm b/code/game/objects/items/weapons/implants/implanter.dm index 4f94ecca..c981087b 100644 --- a/code/game/objects/items/weapons/implants/implanter.dm +++ b/code/game/objects/items/weapons/implants/implanter.dm @@ -51,7 +51,7 @@ src.imp = null update() - + return @@ -120,6 +120,12 @@ if (c.scanned) user << "\red Something is already scanned inside the implant!" return - imp:scanned = A + c.scanned = A + if(istype(A.loc,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = A.loc + H.u_equip(A) + else if(istype(A.loc,/obj/item/weapon/storage)) + var/obj/item/weapon/storage/S = A.loc + S.remove_from_storage(A) A.loc.contents.Remove(A) update() diff --git a/code/game/objects/items/weapons/manuals.dm b/code/game/objects/items/weapons/manuals.dm index 0c05bcef..17ab2fee 100644 --- a/code/game/objects/items/weapons/manuals.dm +++ b/code/game/objects/items/weapons/manuals.dm @@ -19,7 +19,7 @@ - + @@ -38,16 +38,18 @@ -

Experienced user's guide

+

Experienced User's Guide

-

Setting up

+

Setting up the accelerator

  1. Wrench all pieces to the floor
  2. @@ -55,7 +57,7 @@
  3. Close all the panels with your screwdriver
-

Use

+

Using the accelerator

  1. Open the control panel
  2. @@ -66,7 +68,8 @@
- "} + + "} /obj/item/weapon/book/manual/supermatter_engine @@ -75,87 +78,109 @@ author = "Waleed Asad" title = "Supermatter Engine User's Guide" - dat = {"Engineering notes on single-stage Supermatter engine,
- -Waleed Asad
+ dat = {" + + + + +
+ Engineering notes on the single-stage supermatter engine,
+ -Waleed Asad

- Station,
- Exodus
+ Station,
+ Exodus

- A word of caution, do not enter the engine room, for any reason, without radiation protection and mesons on. The status of the engine may be unpredictable even when you believe it is .off.. This is an important level of personal protection.

+ A word of caution, do not enter the engine room for any reason without radiation protection and meson scanners on. The status of the engine may be unpredictable even when you believe it is 'off.' This is an important level of personal protection.

- The engine has two basic modes of functionality. He has observed that it is capable of both a safe level of operation and a modified, high output mode.

+ The engine has two basic modes of functionality. It has been observed that it is capable of both a safe level of operation and a modified, high output mode.

-
Notes on starting the basic function mode, dubbed .Heat-Primary Mode..


+

Heat-Primary Mode

+ Notes on starting the basic function mode +
    +
  1. Prepare collector arrays: As is standard, begin by wrenching them down, filling six plasma tanks with a plasma canister, and inserting the tank into the collectors one by one. Finally, initialize each collector.
  2. - 1. Prepare collector arrays. This is done standard to any text on their function by wrenching them down, filling six plasma tanks with a plasma canister, and inserting the tank into the collectors one by one. Finally, initialize each collector.

    +
  3. Prepare gas system: Before introducing any gas into the supermatter engine room, it is important to remember the small, but vital steps to preparing this section. First, set the input gas pump and output gas flow pump to 4500 kPa, or maximum flow. Second, switch the digital switching valve into the 'up' position, so the green light is on north side of the valve, in order to circulate the gas back toward the coolers and collectors.
  4. - 2. Prepare gas system. Before introducing any gas to the Supermatter engine room, it is important to remember the small but vital steps to preparing this section. First, set the input gas pump and output gas flow pump to 4500, or maximum flow. Second, switch the digital switching valve into the .up. position, in order to circulate the gas back toward the coolers and collectors.

    +
  5. Apply N2 gas: Retrieve the two N2 canisters from storage and bring them to the engine room. Attach one of them to the input section of the engine gas system located next to the collectors. Keep it attached until the N2 pressure is low enough to turn the canister light red. Replace it with the second canister to keep N2 pressure at optimal levels.
  6. - 3. Apply N2 gas. Retrieve the two N2 canisters from storage and bring them to the engine room. Attach one of them to the input section of the engine gas system located next to the collectors. Keep it attached until the N2 pressure is low enough to turn the canister light red. Replace it with the second canister to keep N2 pressure at optimal levels.

    +
  7. Open supermatter shielding: This button is located in the engine room, to the left of the engine monitoring room blast doors. At this point, the supermatter chamber is mostly a gas mixture of N2 and is producing no radiation. It is considered 'safe' up until this point. Do not forget radiation shielding and meson scanners.
  8. - 4. Open Supermatter shielding. This button is located on the far right of the engine room. At this point, the Supermatter chamber is mostly a gas mix of N2 and is producing no radiation. It is considered .safe. up until this point. Do not forget radiation shielding and mesons.

    +
  9. Begin primary emitter burst series: Begin by firing four shots into the supermatter using the emitter. It is important to move to this step quickly. The onboard SMES units may not have enough power to run the emitters if left alone too long on-station. This engine can produce enough power on its own to run the entire station, ignoring the SMES units completely, and is wired to do so.
  10. - 5. Begin primary emitter burst series. This means firing a single emitter for its first four shots. It is important to move to this step quickly. The onboard SMES units may not have enough power to run the emitters if left alone too long on-station. This engine can produce enough power on its own to run the entire station, ignoring the SMES units completely, and is wired to do so.

    +
  11. Switch SMES units to primary settings: Maximize input and set the devices to automatically charge, additionally turn their outputs on if they are off unless power is to be saved (Which can be useful in case of later failures).
  12. - 6. Switch SMES units to primary settings. Maximize input and set the devices to automatically charge, additionally turn their outputs on if they are off unless power is to be saved (Which can be useful in case of later failures.)

    +
  13. Begin secondary emitter burst series: Before firing the emitter again, check the power in the line with a multimeter (Do not forget electrical gloves). The engine is running at high efficiency when the value exceeds 200,000 power units.
  14. - 7. Begin secondary emitter burst series. Before firing the emitter again, check the power in the line with a multimeter (Do not forget electrical gloves.) The engine is running at high efficiency when the value exceeds 200,000 power units.

    - - 8. Maintain engine power. When power in the lines gets low, add an additional emitter burst series to bring power to normal levels.


    +
  15. Maintain engine power: When power in the lines get low, add an additional emitter burst series to bring power to normal levels.
  16. +
+

O2-Reaction Mode

-
The second mode for running the engine uses a gas mix to produce a reaction within the Supermatter. This mode requires CE or Atmospheric help to setup. This has been dubbed the .O2-Reaction Mode..


+ The second mode for running the engine uses a gas mixture to produce a reaction within the supermatter. This mode requires the CE's or Atmospheric's help to set up. This is called 'O2-Reaction Mode.'

- THIS MODE CAN CAUSE A RUNAWAY REACTION, LEADING TO CATASTROPHIC FAILURE IF NOT MAINTAINED. NEVER FORGET ABOUT THE ENGINE IN THIS MODE.

+ THIS MODE CAN CAUSE A RUNAWAY REACTION, LEADING TO CATASTROPHIC FAILURE IF NOT MAINTAINED. NEVER FORGET ABOUT THE ENGINE IN THIS MODE.

- Additionally, this mode can be used for what is called a .Cold Start.. If the station has no power in the SMES to run the emitters, using this mode will allow enough power output to run them, and quickly reach an acceptable level of power output.

+ Additionally, this mode can be used for what is called a 'Cold Start.' If the station has no power in the SMES to run the emitters, using this mode will allow enough power output to run them, and quickly reach an acceptable level of power output.

- 1. Prepare collector arrays. This is done standard to any text on their function by wrenching them down, filling six plasma tanks with a plasma canister, and inserting the tank into the collectors one by one. Finally, initialize each collector.

+
    +
  1. Prepare collector arrays: As is standard, begin by wrenching them down, filling six plasma tanks with a plasma canister, and inserting the tank into the collectors one by one. Finally, initialize each collector.
  2. - 2. Prepare gas system. Before introducing any gas to the Supermatter engine room, it is important to remember the small but vital steps to preparing this section. First, set the input gas pump and output gas flow pump to 4500, or maximum flow. Second, switch the digital switching valve into the .up. position, in order to circulate the gas back toward the coolers and collectors.

    +
  3. Prepare gas system: Before introducing any gas into the supermatter engine room, it is important to remember the small, but vital steps to preparing this section. First, set the input gas pump and output gas flow pump to 4500 kPa, or maximum flow. Second, switch the digital switching valve into the 'up' position, so the green light is on north side of the valve, in order to circulate the gas back toward the coolers and collectors.
  4. - 3. Modify the engine room filters. Unlike the Heat-Primary Mode, it is important to change the filters attached to the gas system to stop filtering O2, and start filtering Carbon Molecules. O2-Reaction Mode produces far more plasma than Heat-Primary, therefor filtering it off is essential.

    +
  5. Modify the engine room filters: Unlike the Heat-Primary Mode, it is important to change the filters attached to the gas system to stop filtering O2, and start filtering carbon molecules. O2-Reaction Mode produces far more plasma than Heat-Primary, therefore filtering it off is essential.
  6. - 4. Switch SMES units to primary settings. Maximize input and set the devices to automatically charge, additionally turn their outputs on if they are off unless power is to be saved (Which can be useful in case of later failures.) If you check the power in the system lines at this point you will find that it is constantly going up. Indeed, with just the addition of O2 to the Supermatter, it will begin outputting power.

    +
  7. Switch SMES units to primary settings: Maximize input and set the devices to automatically charge, additionally turn their outputs on if they are off unless power is to be saved (Which can be useful in case of later failures). If you check the power in the system lines at this point, you will find that it is constantly going up. Indeed, with just the addition of O2 to the supermatter, it will begin outputting power.
  8. - 5. Begin primary emitter burst series. Fire a single emitter for a series of four pulses, or a single series, and turn it off. Do not over power the Supermatter. The reaction is self sustaining and propagating. As long as O2 is in the chamber, it will continue outputting MORE power.

    +
  9. Begin primary emitter burst series: Begin by firing four shots into the supermatter using the emitter. Do not over power the supermatter. The reaction is self sustaining and propagating. As long as O2 is in the chamber, it will continue outputting MORE power.
  10. - 6. Maintain follow up operations. Remember to check the temp of the core gas and switch to the Heat-Primary function, or vent the core room when problems begin if required.

    +
  11. Maintain follow up operations: Remember to check the temperature of the core gas and switch to the Heat-Primary function, or vent the core room when problems begin if required.
  12. +

- Notes on Supermatter Reaction Function and Drawbacks-

+

Notes on Supermatter Reaction Function and Drawbacks

- After several hours of observation an interesting phenomenon was witnessed. The Supermatter undergoes a constant self-sustaining reaction when given an extremely high O2 concentration. Anything about 80% or higher typically will cause this reaction. The Supermatter will continue to react whenever this gas mix is in the same room as the Supermatter.

+ After several hours of observation, an interesting phenomenon was witnessed. The supermatter undergoes a constant, self-sustaining reaction when given an extremely high O2 concentration. Anything about 80% or higher typically will cause this reaction. The supermatter will continue to react whenever this gas mixture is in the same room as the supermatter.

- To understand why O2-Reaction mode is dangerous, the core principle of the Supermatter must be understood. The Supermatter emits three things when .not safe,. that is any time it is giving off power. These things are:

+ To understand why O2-Reaction mode is dangerous, the core principle of the supermatter must be understood. The supermatter emits three things when 'not safe,' that is any time it is giving off power. These things are:
- *Radiation (which is converted into power by the collectors,)
- *Heat (which is removed via the gas exchange system and coolers,)
- *External gas (in the form of plasma and O2.)
+
    +
  • Radiation (which is converted into power by the collectors)

  • +
  • Heat (which is removed via the gas exchange system and coolers)

  • +
  • External gas (in the form of plasma and O2)

  • +

- When in Heat-Primary mode, far more heat and plasma are produced than radiation. In O2-Reaction mode, very little heat and only moderate amounts of plasma are produced, however HUGE amounts of energy leaving the Supermatter is in the form of radiation.

+ When in Heat-Primary mode, far more heat and plasma are produced than radiation. In O2-Reaction mode, very little heat and only moderate amounts of plasma are produced, however HUGE amounts of energy leaving the supermatter is in the form of radiation.

- The O2-Reaction engine mode has a single drawback which has been eluded to more than once so far and that is very simple. The engine room will continue to grow hotter as the constant reaction continues. Eventually, there will be what he calls the .critical gas mix.. This is the point at which the constant adding of plasma to the mix of air around the Supermatter changes the gas concentration to below the tolerance. When this happens, two things occur. First, the Supermatter switches to its primary mode of operation where in huge amounts of heat are produced by the engine rather than low amounts with high power output. Second, an uncontrollable increase in heat within the Supermatter chamber will occur. This will lead to a spark-up, igniting the plasma in the Supermatter chamber, wildly increasing both pressure and temperature.

+ The O2-Reaction engine mode has a single drawback which has been eluded to more than once so far and that is very simple. The engine room will continue to grow hotter as the constant reaction continues. Eventually, there will be what is called a 'critical gas mixture.' This is the point at which the constant adding of plasma to the mixture of air around the supermatter changes the gas concentration to below the tolerance. When this happens, two things occur. First, the supermatter switches to its primary mode of operation wherein huge amounts of heat are produced by the engine rather than low amounts with high power output. Second, an uncontrollable increase in heat within the supermatter chamber will occur. This will lead to a spark-up, igniting the plasma in the supermatter chamber, wildly increasing both pressure and temperature.

- While the O2-Reaction mode is dangerous, it does produce heavy amounts of energy. Consider using this mode only in short amounts to fill the SMES, and switch back later in the shift to keep things flowing normally.

+ While the O2-Reaction mode is dangerous, it does produce heavy amounts of energy. Consider using this mode only in short amounts to fill the SMES, and switch back later in the shift to keep things flowing normally.

- Notes on Supermatter Containment and Emergency Procedures-

+

Notes on Supermatter Containment and Emergency Procedures

- While a constant vigil on the Supermatter is not required, regular checkups are important. Verify the temp of gas leaving the Supermatter chamber for unsafe levels, and ensure that the plasma in the chamber is at a safe concentration. Of course, also make sure the chamber is not on fire. A fire in the core chamber is very difficult to put out. As any Toxin scientist can tell you, even low amounts of plasma can burn at very high temperatures. This burning creates a huge increase in pressure and more importantly, temperature of the crystal itself.

+ While a constant vigil on the supermatter is not required, regular checkups are important. Check the temperature of gas leaving the supermatter chamber for unsafe levels and ensure that the plasma in the chamber is at a safe concentration. Of course, also make sure the chamber is not on fire. A fire in the core chamber is very difficult to put out. As any toxin scientist can tell you, even low amounts of plasma can burn at very high temperatures. This burning creates a huge increase in pressure and more importantly, temperature of the crystal itself.

- The Supermatter is strong, but not invincible. When the Supermatter is heated too much, its crystal structure will attempt to liquify. The change in atomic structure of the Supermatter leads to a single reaction, a massive explosion. The computer chip attached to the Supermatter core will warn the station when stability is threatened. It will then offer a second warning, when things have become dangerously close to total destruction of the core.

+ The supermatter is strong, but not invincible. When the supermatter is heated too much, its crystal structure will attempt to liquefy. The change in atomic structure of the supermatter leads to a single reaction, a massive explosion. The computer chip attached to the supermatter core will warn the station when stability is threatened. It will then offer a second warning, when things have become dangerously close to total destruction of the core.

- Located both within the CE office and engine room is the vent control button. This button allows the Core Vent Controls to be accessed, venting the room to space. Remember however, that this process takes time. If a fire is raging, and the pressure is higher than fathomable, it will take a great deal of time to vent the room. Also located in the CE.s office is the emergency core eject button. A new core can be ordered from cargo. It is often not worth the lives of the crew to hold on to it, not to mention the structural damage. However, if by some mistake the Supermatter is pushed off or removed from the mass ejector it sits on, manual reposition will be required. Which is very dangerous and often leads to death.

+ Located both within the CE office and engine room is the engine ventilatory control button. This button allows the core vent controls to be accessed, venting the room to space. Remember however, that this process takes time. If a fire is raging, and the pressure is higher than fathomable, it will take a great deal of time to vent the room. Also located in the CE's office is the emergency core eject button. A new core can be ordered from cargo. It is often not worth the lives of the crew to hold on to it, not to mention the structural damage. However, if by some mistake the supermatter is pushed off or removed from the mass driver it sits on, manual reposition will be required. Which is very dangerous and often leads to death.

- The Supermatter is extremely dangerous. More dangerous than people give it credit for. It can destroy you in an instant, without hesitation, reducing you to a pile of dust. When working closely with Supermatter it is.. suggested to get a genetic backup and do not wear any items of value to you. The Supermatter core can be pulled if grabbed properly by the base, but pushing is not possible.


+ The supermatter is extremely dangerous. More dangerous than people give it credit for. It can destroy you in an instant, without hesitation, reducing you to a pile of dust. When working closely with supermatter, it is suggested to get a genetic backup and do not wear any items of value to you. The supermatter core can be pulled if grabbed properly by the base, but pushing is not possible.

- In Closing-

+

In Closing

- Remember that the Supermatter is dangerous, and the core is dangerous still. Venting the core room is always an option if you are even remotely worried, utilizing Atmospherics to properly ready the room once more for core function. It is always a good idea to check up regularly on the temperature of gas leaving the chamber, as well as the power in the system lines. Lastly, once again remember, never touch the Supermatter with anything. Ever.

+ Remember that the supermatter is dangerous, and the core is dangerous still. Venting the core room is always an option if you are even remotely worried, utilizing Atmospherics to properly ready the room once more for core function. It is always a good idea to check up regularly on the temperature of gas leaving the chamber, as well as the power in the system lines. Lastly, once again remember, never touch the supermatter with anything. Ever.

- -Waleed Asad, Senior Engine Technician."} + -Waleed Asad, Senior Engine Technician + + "} /obj/item/weapon/book/manual/engineering_hacking name = "Hacking" @@ -189,48 +214,51 @@ h1 {font-size: 18px; margin: 15px 0px 5px;} h2 {font-size: 15px; margin: 15px 0px 5px;} li {margin: 2px 0px 2px 15px;} - ul {list-style: none; margin: 5px; padding: 0px;} + ul {margin: 5px; padding: 0px;} ol {margin: 5px; padding: 0px 15px;} + body {font-size: 13px; font-family: Verdana;} -

Singularity Safety in Special Circumstances

+

Singularity Safety in Special Circumstances

-

Power outage

+

Power outage

- A power problem has made the entire station loose power? Could be station-wide wiring problems or syndicate power sinks. In any case follow these steps: -

- Step one: PANIC!
- Step two: Get your ass over to engineering! QUICKLY!!!
- Step three: Get to the Area Power Controller which controls the power to the emitters.
- Step four: Swipe it with your ID card - if it doesn't unlock, continue with step 15.
- Step five: Open the console and disengage the cover lock.
- Step six: Pry open the APC with a Crowbar.
- Step seven: Take out the empty power cell.
- Step eight: Put in the new, full power cell - if you don't have one, continue with step 15.
- Step nine: Quickly put on a Radiation suit.
- Step ten: Check if the singularity field generators withstood the down-time - if they didn't, continue with step 15.
- Step eleven: Since disaster was averted you now have to ensure it doesn't repeat. If it was a powersink which caused it and if the engineering apc is wired to the same powernet, - which the powersink is on, you have to remove the piece of wire which links the apc to the powernet. If it wasn't a powersink which caused it, then skip to step 14.
- Step twelve: Grab your crowbar and pry away the tile closest to the APC.
- Step thirteen: Use the wirecutters to cut the wire which is conecting the grid to the terminal.
- Step fourteen: Go to the bar and tell the guys how you saved them all. Stop reading this guide here.
- Step fifteen: GET THE FUCK OUT OF THERE!!!
-

+ A power problem has made the entire station lose power? Could be station-wide wiring problems or syndicate power sinks. In any case follow these steps: -

Shields get damaged

+
    +
  1. PANIC!
  2. +
  3. Get your ass over to engineering! QUICKLY!!!
  4. +
  5. Get to the Area Power Controller which controls the power to the emitters.
  6. +
  7. Swipe it with your ID card - if it doesn't unlock, continue with step 15.
  8. +
  9. Open the console and disengage the cover lock.
  10. +
  11. Pry open the APC with a Crowbar.
  12. +
  13. Take out the empty power cell.
  14. +
  15. Put in the new, full power cell - if you don't have one, continue with step 15.
  16. +
  17. Quickly put on a Radiation suit.
  18. +
  19. Check if the singularity field generators withstood the down-time - if they didn't, continue with step 15.
  20. +
  21. Since disaster was averted you now have to ensure it doesn't repeat. If it was a powersink which caused it and if the engineering APC is wired to the same powernet, which the powersink is on, you have to remove the piece of wire which links the APC to the powernet. If it wasn't a powersink which caused it, then skip to step 14.
  22. +
  23. Grab your crowbar and pry away the tile closest to the APC.
  24. +
  25. Use the wirecutters to cut the wire which is connecting the grid to the terminal.
  26. +
  27. Go to the bar and tell the guys how you saved them all. Stop reading this guide here.
  28. +
  29. GET THE FUCK OUT OF THERE!!!
  30. +
- Step one: GET THE FUCK OUT OF THERE!!! FORGET THE WOMEN AND CHILDREN, SAVE YOURSELF!!!
+

Shields get damaged

+ +
    +
  1. GET THE FUCK OUT OF THERE!!! FORGET THE WOMEN AND CHILDREN, SAVE YOURSELF!!!
  2. +
- - "} + + "} /obj/item/weapon/book/manual/hydroponics_pod_people - name = "The Diona Harvest - From seed to market" + name = "The Diona Harvest - From Seed to Market" icon_state ="bookHydroponicsPodPeople" author = "Farmer John" - title = "The Diona Harvest - From seed to market" + title = "The Diona Harvest - From Seed to Market" dat = {" @@ -238,20 +266,25 @@ h1 {font-size: 18px; margin: 15px 0px 5px;} h2 {font-size: 15px; margin: 15px 0px 5px;} li {margin: 2px 0px 2px 15px;} - ul {list-style: none; margin: 5px; padding: 0px;} + ul {margin: 5px; padding: 0px;} ol {margin: 5px; padding: 0px 15px;} + body {font-size: 13px; font-family: Verdana;} -

Growing Diona

+

Growing a Diona

- Growing Diona is easy! + Growing a Diona is easy!

    -
  1. Plant the seeds.
  2. -
  3. Tend to the plants water and nutrition levels until it is time to harvest the Diona.
  4. +
  5. Take a syringe of blood from the body you wish to turn into a Diona.
  6. +
  7. Inject 5 units of blood into the pack of dionaea-replicant seeds.
  8. +
  9. Plant the seeds.
  10. +
  11. Tend to the plants water and nutrition levels until it is time to harvest the Diona.

+ Note that for a successful harvest, the body from which the blood was taken from must be dead BEFORE harvesting the pod, however the pod can be growing while they are still alive. Otherwise, the soul would not be able to migrate to the new Diona body.

+ It really is that easy! Good luck! @@ -260,27 +293,29 @@ /obj/item/weapon/book/manual/medical_cloning - name = "Cloning techniques of the 26th century" + name = "Cloning Techniques of the 26th Century" icon_state ="bookCloning" author = "Medical Journal, volume 3" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned - title = "Cloning techniques of the 26th century" + title = "Cloning Techniques of the 26th Century" dat = {" -

How to Clone People

- So there’s 50 dead people lying on the floor, chairs are spinning like no tomorrow and you haven’t the foggiest idea of what to do? Not to worry! - This guide is intended to teach you how to clone people and how to do it right, in a simple step-by-step process! If at any point of the guide you have a mental meltdown, - genetics probably isn’t for you and you should get a job-change as soon as possible before you’re sued for malpractice. +

How to Clone People

+ So there are 50 dead people lying on the floor, chairs are spinning like no tomorrow and you haven't the foggiest idea of what to do? Not to worry! + This guide is intended to teach you how to clone people and how to do it right, in a simple, step-by-step process! If at any point of the guide you have a mental meltdown, + genetics probably isn't for you and you should get a job-change as soon as possible before you're sued for malpractice.
  1. Acquire body
  2. @@ -288,7 +323,7 @@
  3. Put body in cloning machine
  4. Scan body
  5. Clone body
  6. -
  7. Get clean Structurel Enzymes for the body
  8. +
  9. Get clean Structural Enzymes for the body
  10. Put body in morgue
  11. Await cloned body
  12. Cryo and use the clean SE injector
  13. @@ -296,54 +331,54 @@
  14. Send person on their way
-

Step 1: Acquire body

+

Step 1: Acquire body

This is pretty much vital for the process because without a body, you cannot clone it. Usually, bodies will be brought to you, so you do not need to worry so much about this step. If you already have a body, great! Move on to the next step. -

Step 2: Strip body

- The cloning machine does not like abiotic items. What this means is you can’t clone anyone if they’re wearing clothes, so take all of it off. If it’s just one person, it’s courteous to put their possessions in the closet. - If you have about seven people awaiting cloning, just leave the piles where they are, but don’t mix them around and for God’s sake don’t let people in to steal them. +

Step 2: Strip body

+ The cloning machine does not like abiotic items. What this means is you can't clone anyone if they're wearing clothes or holding things, so take all of it off. If it's just one person, it's courteous to put their possessions in the closet. + If you have about seven people awaiting cloning, just leave the piles where they are, but don't mix them around and for God's sake don't let people in to steal them. -

Step 3: Put body in cloning machine

+

Step 3: Put body in cloning machine

Grab the body and then put it inside the DNA modifier. If you cannot do this, then you messed up at Step 2. Go back and check you took EVERYTHING off - a commonly missed item is their headset. -

Step 4: Scan body

- Go onto the computer and scan the body by pressing ‘Scan - ’. If you’re successful, they will be added to the records (note that this can be done at any time, even with living people, - so that they can be cloned without a body in the event that they are lying dead on port solars and didn‘t turn on their suit sensors)! - If not, and it says “Error: Mental interface failure.”, then they have left their bodily confines and are one with the spirits. If this happens, just shout at them to get back in their body, - click ‘Refresh‘ and try scanning them again. If there’s no success, threaten them with gibbing. - Still no success? Skip over to Step 7 and don‘t continue after it, as you have an unresponsive body and it cannot be cloned. - If you got “Error: Unable to locate valid genetic data.“, you are trying to clone a monkey - start over. +

Step 4: Scan body

+ Go onto the computer and scan the body by pressing 'Scan - <Subject Name Here>.' If you're successful, they will be added to the records (note that this can be done at any time, even with living people, + so that they can be cloned without a body in the event that they are lying dead on port solars and didn't turn on their suit sensors)! + If not, and it says "Error: Mental interface failure.", then they have left their bodily confines and are one with the spirits. If this happens, just shout at them to get back in their body, + click 'Refresh' and try scanning them again. If there's no success, threaten them with gibbing. + Still no success? Skip over to Step 7 and don't continue after it, as you have an unresponsive body and it cannot be cloned. + If you got "Error: Unable to locate valid genetic data.", you are trying to clone a monkey - start over. -

Step 5: Clone body

- Now that the body has a record, click ’View Records’, click the subject’s name, and then click ‘Clone’ to start the cloning process. Congratulations! You’re halfway there. - Remember not to ‘Eject’ the cloning pod as this will kill the developing clone and you’ll have to start the process again. +

Step 5: Clone body

+ Now that the body has a record, click 'View Records,' click the subject's name, and then click 'Clone' to start the cloning process. Congratulations! You're halfway there. + Remember not to 'Eject' the cloning pod as this will kill the developing clone and you'll have to start the process again. -

Step 6: Get clean SEs for body

+

Step 6: Get clean SEs for body

Cloning is a finicky and unreliable process. Whilst it will most certainly bring someone back from the dead, they can have any number of nasty disabilities given to them during the cloning process! - For this reason, you need to prepare a clean, defect-free Structural Enzyme (SE) injection for when they’re done. If you’re a competent Geneticist, you will already have one ready on your working computer. + For this reason, you need to prepare a clean, defect-free Structural Enzyme (SE) injection for when they're done. If you're a competent Geneticist, you will already have one ready on your working computer. If, for any reason, you do not, then eject the body from the DNA modifier (NOT THE CLONING POD) and take it next door to the Genetics research room. Put the body in one of those DNA modifiers and then go onto the console. - Go into View/Edit/Transfer Buffer, find an open slot and click “SE“ to save it. Then click ‘Injector’ to get the SEs in syringe form. Put this in your pocket or something for when the body is done. + Go into View/Edit/Transfer Buffer, find an open slot and click "SE" to save it. Then click 'Injector' to get the SEs in syringe form. Put this in your pocket or something for when the body is done. -

Step 7: Put body in morgue

+

Step 7: Put body in morgue

Now that the cloning process has been initiated and you have some clean Structural Enzymes, you no longer need the body! Drag it to the morgue and tell the Chef over the radio that they have some fresh meat waiting for them in there. - To put a body in a morgue bed, simply open the tray, grab the body, put it on the open tray, then close the tray again. Use one of the nearby pens to label the bed “CHEF MEAT” in order to avoid confusion. + To put a body in a morgue bed, simply open the tray, grab the body, put it on the open tray, then close the tray again. Use one of the nearby pens to label the bed "CHEF MEAT" in order to avoid confusion. -

Step 8: Await cloned body

- Now go back to the lab and wait for your patient to be cloned. It won’t be long now, I promise. +

Step 8: Await cloned body

+ Now go back to the lab and wait for your patient to be cloned. It won't be long now, I promise. -

Step 9: Cyo and clean clean SE injector on person

- Has your body been cloned yet? Great! As soon as the guy pops out, grab them and stick them in cryo. Clonexadone and Cryoxadone help rebuild their genetic material. Then grab your cleanr SE injector and jab it in them. Once you’ve injected them, +

Step 9: Cryo and clean SE injector on person

+ Has your body been cloned yet? Great! As soon as the guy pops out, grab them and stick them in cryo. Clonexadone and Cryoxadone help rebuild their genetic material. Then grab your clean SE injector and jab it in them. Once you've injected them, they now have clean Structural Enzymes and their defects, if any, will disappear in a short while. -

Step 10: Give person clothes back

- Obviously the person will be naked after they have been cloned. Provided you weren’t an irresponsible little shit, you should have protected their possessions from thieves and should be able to give them back to the patient. - No matter how cruel you are, it’s simply against protocol to force your patients to walk outside naked. +

Step 10: Give person clothes back

+ Obviously the person will be naked after they have been cloned. Provided you weren't an irresponsible little shit, you should have protected their possessions from thieves and should be able to give them back to the patient. + No matter how cruel you are, it's simply against protocol to force your patients to walk outside naked. -

Step 11: Send person on their way

- Give the patient one last check-over - make sure they don’t still have any defects and that they have all their possessions. Ask them how they died, if they know, so that you can report any foul play over the radio. - Once you’re done, your patient is ready to go back to work! Chances are they do not have Medbay access, so you should let them out of Genetics and the Medbay main entrance. +

Step 11: Send person on their way

+ Give the patient one last check-over - make sure they don't still have any defects and that they have all their possessions. Ask them how they died, if they know, so that you can report any foul play over the radio. + Once you're done, your patient is ready to go back to work! Chances are they do not have Medbay access, so you should let them out of Genetics and the Medbay main entrance. -

If you’ve gotten this far, congratulations! You have mastered the art of cloning. Now, the real problem is how to resurrect yourself after that traitor had his way with you for cloning his target. +

If you've gotten this far, congratulations! You have mastered the art of cloning. Now, the real problem is how to resurrect yourself after that traitor had his way with you for cloning his target. @@ -362,17 +397,20 @@ h1 {font-size: 18px; margin: 15px 0px 5px;} h2 {font-size: 15px; margin: 15px 0px 5px;} li {margin: 2px 0px 2px 15px;} - ul {list-style: none; margin: 5px; padding: 0px;} + ul {margin: 5px; padding: 0px;} + ul.a {list-style-type: none; margin: 5px; padding: 0px;} ol {margin: 5px; padding: 0px 15px;} + body {font-size: 13px; font-family: Verdana;}

+
Weyland-Yutani - Building Better Worlds

Autonomous Power Loader Unit \"Ripley\"

Specifications:

-